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 ...@@ -2483,27 +2483,36 @@ drop_unsolicited_na - BOOLEAN
By default this is turned off. By default this is turned off.
accept_untracked_na - BOOLEAN accept_untracked_na - INTEGER
Add a new neighbour cache entry in STALE state for routers on receiving a Define behavior for accepting neighbor advertisements from devices that
neighbour advertisement (either solicited or unsolicited) with target are absent in the neighbor cache:
link-layer address option specified if no neighbour entry is already
present for the advertised IPv6 address. Without this knob, NAs received - 0 - (default) Do not accept unsolicited and untracked neighbor
for untracked addresses (absent in neighbour cache) are silently ignored. advertisements.
This is as per router-side behaviour documented in RFC9131. - 1 - Add a new neighbor cache entry in STALE state for routers on
receiving a neighbor advertisement (either solicited or unsolicited)
This has lower precedence than drop_unsolicited_na. with target link-layer address option specified if no neighbor entry
is already present for the advertised IPv6 address. Without this knob,
This will optimize the return path for the initial off-link communication NAs received for untracked addresses (absent in neighbor cache) are
that is initiated by a directly connected host, by ensuring that silently ignored.
the first-hop router which turns on this setting doesn't have to
buffer the initial return packets to do neighbour-solicitation. This is as per router-side behavior documented in RFC9131.
The prerequisite is that the host is configured to send
unsolicited neighbour advertisements on interface bringup. This has lower precedence than drop_unsolicited_na.
This setting should be used in conjunction with the ndisc_notify setting
on the host to satisfy this prerequisite. This will optimize the return path for the initial off-link
communication that is initiated by a directly connected host, by
By default this is turned off. 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 enhanced_dad - BOOLEAN
Include a nonce option in the IPv6 neighbor solicitation messages used for Include a nonce option in the IPv6 neighbor solicitation messages used for
......
...@@ -7042,7 +7042,7 @@ static const struct ctl_table addrconf_sysctl[] = { ...@@ -7042,7 +7042,7 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.accept_untracked_na, .data = &ipv6_devconf.accept_untracked_na,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec_minmax, .proc_handler = proc_dointvec,
.extra1 = (void *)SYSCTL_ZERO, .extra1 = (void *)SYSCTL_ZERO,
.extra2 = (void *)SYSCTL_ONE, .extra2 = (void *)SYSCTL_ONE,
}, },
......
...@@ -967,6 +967,25 @@ static void ndisc_recv_ns(struct sk_buff *skb) ...@@ -967,6 +967,25 @@ static void ndisc_recv_ns(struct sk_buff *skb)
in6_dev_put(idev); 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) static void ndisc_recv_na(struct sk_buff *skb)
{ {
struct nd_msg *msg = (struct nd_msg *)skb_transport_header(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) ...@@ -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. * Note that we don't do a (daddr == all-routers-mcast) check.
*/ */
new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE; new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE;
if (!neigh && lladdr && if (!neigh && lladdr && idev && idev->cnf.forwarding) {
idev && idev->cnf.forwarding && if (accept_untracked_na(dev, saddr)) {
idev->cnf.accept_untracked_na) { neigh = neigh_create(&nd_tbl, &msg->target, dev);
neigh = neigh_create(&nd_tbl, &msg->target, dev); new_state = NUD_STALE;
new_state = NUD_STALE; }
} }
if (neigh && !IS_ERR(neigh)) { 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