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:
Родитель
e68c5dcf0a
Коммит
aaa5f515b1
|
@ -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.
|
||||
accept_untracked_na - INTEGER
|
||||
Define behavior for accepting neighbor advertisements from devices that
|
||||
are absent in the neighbor cache:
|
||||
|
||||
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
|
||||
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.
|
||||
This is as per router-side behavior documented in RFC9131.
|
||||
|
||||
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
|
||||
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 @@ out:
|
|||
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)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче