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: Jaehee Park <jhpark1013@gmail.com> Suggested-by: Roopa Prabhu <roopa@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
e68c5dcf0a
commit
aaa5f515b1
3 changed files with 51 additions and 23 deletions
|
@ -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
|
|
||||||
for untracked addresses (absent in neighbour cache) are silently ignored.
|
|
||||||
|
|
||||||
This is as per router-side behaviour documented in RFC9131.
|
- 0 - (default) Do not accept unsolicited and untracked neighbor
|
||||||
|
advertisements.
|
||||||
|
|
||||||
This has lower precedence than drop_unsolicited_na.
|
- 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 will optimize the return path for the initial off-link communication
|
This is as per router-side behavior documented in RFC9131.
|
||||||
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.
|
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
|
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[] = {
|
||||||
.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 @@ out:
|
||||||
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)
|
||||||
* 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)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue