Commit aaa5f515 authored by Jaehee Park's avatar Jaehee Park Committed by Jakub Kicinski

net: ipv6: new accept_untracked_na option to accept na only if in-network

This patch adds a third knob, '2', which extends the
accept_untracked_na option to learn a neighbor only if the src ip is
in the same subnet as an address configured on the interface that
received the neighbor advertisement. This is similar to the arp_accept
configuration for ipv4.
Signed-off-by: default avatarJaehee Park <jhpark1013@gmail.com>
Suggested-by: default avatarRoopa Prabhu <roopa@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e68c5dcf
......@@ -2483,27 +2483,36 @@ drop_unsolicited_na - BOOLEAN
By default this is turned off.
accept_untracked_na - BOOLEAN
Add a new neighbour cache entry in STALE state for routers on receiving a
neighbour advertisement (either solicited or unsolicited) with target
link-layer address option specified if no neighbour entry is already
present for the advertised IPv6 address. Without this knob, NAs received
for untracked addresses (absent in neighbour cache) are silently ignored.
This is as per router-side behaviour documented in RFC9131.
This has lower precedence than drop_unsolicited_na.
This will optimize the return path for the initial off-link communication
that is initiated by a directly connected host, by ensuring that
the first-hop router which turns on this setting doesn't have to
buffer the initial return packets to do neighbour-solicitation.
The prerequisite is that the host is configured to send
unsolicited neighbour advertisements on interface bringup.
This setting should be used in conjunction with the ndisc_notify setting
on the host to satisfy this prerequisite.
By default this is turned off.
accept_untracked_na - INTEGER
Define behavior for accepting neighbor advertisements from devices that
are absent in the neighbor cache:
- 0 - (default) Do not accept unsolicited and untracked neighbor
advertisements.
- 1 - Add a new neighbor cache entry in STALE state for routers on
receiving a neighbor advertisement (either solicited or unsolicited)
with target link-layer address option specified if no neighbor entry
is already present for the advertised IPv6 address. Without this knob,
NAs received for untracked addresses (absent in neighbor cache) are
silently ignored.
This is as per router-side behavior documented in RFC9131.
This has lower precedence than drop_unsolicited_na.
This will optimize the return path for the initial off-link
communication that is initiated by a directly connected host, by
ensuring that the first-hop router which turns on this setting doesn't
have to buffer the initial return packets to do neighbor-solicitation.
The prerequisite is that the host is configured to send unsolicited
neighbor advertisements on interface bringup. This setting should be
used in conjunction with the ndisc_notify setting on the host to
satisfy this prerequisite.
- 2 - Extend option (1) to add a new neighbor cache entry only if the
source IP address is in the same subnet as an address configured on
the interface that received the neighbor advertisement.
enhanced_dad - BOOLEAN
Include a nonce option in the IPv6 neighbor solicitation messages used for
......
......@@ -7042,7 +7042,7 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.accept_untracked_na,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.proc_handler = proc_dointvec,
.extra1 = (void *)SYSCTL_ZERO,
.extra2 = (void *)SYSCTL_ONE,
},
......
......@@ -967,6 +967,25 @@ static void ndisc_recv_ns(struct sk_buff *skb)
in6_dev_put(idev);
}
static int accept_untracked_na(struct net_device *dev, struct in6_addr *saddr)
{
struct inet6_dev *idev = __in6_dev_get(dev);
switch (idev->cnf.accept_untracked_na) {
case 0: /* Don't accept untracked na (absent in neighbor cache) */
return 0;
case 1: /* Create new entries from na if currently untracked */
return 1;
case 2: /* Create new entries from untracked na only if saddr is in the
* same subnet as an address configured on the interface that
* received the na
*/
return !!ipv6_chk_prefix(saddr, dev);
default:
return 0;
}
}
static void ndisc_recv_na(struct sk_buff *skb)
{
struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
......@@ -1061,11 +1080,11 @@ static void ndisc_recv_na(struct sk_buff *skb)
* Note that we don't do a (daddr == all-routers-mcast) check.
*/
new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE;
if (!neigh && lladdr &&
idev && idev->cnf.forwarding &&
idev->cnf.accept_untracked_na) {
neigh = neigh_create(&nd_tbl, &msg->target, dev);
new_state = NUD_STALE;
if (!neigh && lladdr && idev && idev->cnf.forwarding) {
if (accept_untracked_na(dev, saddr)) {
neigh = neigh_create(&nd_tbl, &msg->target, dev);
new_state = NUD_STALE;
}
}
if (neigh && !IS_ERR(neigh)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment