Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/ipv6: Expand and rename accept_unsolicited_na to accept_untracked_na

RFC 9131 changes default behaviour of handling RX of NA messages when the
corresponding entry is absent in the neighbour cache. The current
implementation is limited to accept just unsolicited NAs. However, the
RFC is more generic where it also accepts solicited NAs. Both types
should result in adding a STALE entry for this case.

Expand accept_untracked_na behaviour to also accept solicited NAs to
be compliant with the RFC and rename the sysctl knob to
accept_untracked_na.

Fixes: f9a2fb73318e ("net/ipv6: Introduce accept_unsolicited_na knob to implement router-side changes for RFC9131")
Signed-off-by: Arun Ajith S <aajith@arista.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20220530101414.65439-1-aajith@arista.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Arun Ajith S and committed by
Paolo Abeni
3e0b8f52 4a1f14df

+50 -48
+9 -14
Documentation/networking/ip-sysctl.rst
··· 2474 2474 2475 2475 By default this is turned off. 2476 2476 2477 - accept_unsolicited_na - BOOLEAN 2478 - Add a new neighbour cache entry in STALE state for routers on receiving an 2479 - unsolicited neighbour advertisement with target link-layer address option 2480 - specified. This is as per router-side behavior documented in RFC9131. 2481 - This has lower precedence than drop_unsolicited_na. 2477 + accept_untracked_na - BOOLEAN 2478 + Add a new neighbour cache entry in STALE state for routers on receiving a 2479 + neighbour advertisement (either solicited or unsolicited) with target 2480 + link-layer address option specified if no neighbour entry is already 2481 + present for the advertised IPv6 address. Without this knob, NAs received 2482 + for untracked addresses (absent in neighbour cache) are silently ignored. 2482 2483 2483 - ==== ====== ====== ============================================== 2484 - drop accept fwding behaviour 2485 - ---- ------ ------ ---------------------------------------------- 2486 - 1 X X Drop NA packet and don't pass up the stack 2487 - 0 0 X Pass NA packet up the stack, don't update NC 2488 - 0 1 0 Pass NA packet up the stack, don't update NC 2489 - 0 1 1 Pass NA packet up the stack, and add a STALE 2490 - NC entry 2491 - ==== ====== ====== ============================================== 2484 + This is as per router-side behaviour documented in RFC9131. 2485 + 2486 + This has lower precedence than drop_unsolicited_na. 2492 2487 2493 2488 This will optimize the return path for the initial off-link communication 2494 2489 that is initiated by a directly connected host, by ensuring that
+1 -1
include/linux/ipv6.h
··· 61 61 __s32 suppress_frag_ndisc; 62 62 __s32 accept_ra_mtu; 63 63 __s32 drop_unsolicited_na; 64 - __s32 accept_unsolicited_na; 64 + __s32 accept_untracked_na; 65 65 struct ipv6_stable_secret { 66 66 bool initialized; 67 67 struct in6_addr secret;
+1 -1
include/uapi/linux/ipv6.h
··· 194 194 DEVCONF_IOAM6_ID, 195 195 DEVCONF_IOAM6_ID_WIDE, 196 196 DEVCONF_NDISC_EVICT_NOCARRIER, 197 - DEVCONF_ACCEPT_UNSOLICITED_NA, 197 + DEVCONF_ACCEPT_UNTRACKED_NA, 198 198 DEVCONF_MAX 199 199 }; 200 200
+3 -3
net/ipv6/addrconf.c
··· 5586 5586 array[DEVCONF_IOAM6_ID] = cnf->ioam6_id; 5587 5587 array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; 5588 5588 array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; 5589 - array[DEVCONF_ACCEPT_UNSOLICITED_NA] = cnf->accept_unsolicited_na; 5589 + array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; 5590 5590 } 5591 5591 5592 5592 static inline size_t inet6_ifla6_size(void) ··· 7038 7038 .extra2 = (void *)SYSCTL_ONE, 7039 7039 }, 7040 7040 { 7041 - .procname = "accept_unsolicited_na", 7042 - .data = &ipv6_devconf.accept_unsolicited_na, 7041 + .procname = "accept_untracked_na", 7042 + .data = &ipv6_devconf.accept_untracked_na, 7043 7043 .maxlen = sizeof(int), 7044 7044 .mode = 0644, 7045 7045 .proc_handler = proc_dointvec_minmax,
+25 -17
net/ipv6/ndisc.c
··· 979 979 struct inet6_dev *idev = __in6_dev_get(dev); 980 980 struct inet6_ifaddr *ifp; 981 981 struct neighbour *neigh; 982 - bool create_neigh; 982 + u8 new_state; 983 983 984 984 if (skb->len < sizeof(struct nd_msg)) { 985 985 ND_PRINTK(2, warn, "NA: packet too short\n"); ··· 1000 1000 /* For some 802.11 wireless deployments (and possibly other networks), 1001 1001 * there will be a NA proxy and unsolicitd packets are attacks 1002 1002 * and thus should not be accepted. 1003 - * drop_unsolicited_na takes precedence over accept_unsolicited_na 1003 + * drop_unsolicited_na takes precedence over accept_untracked_na 1004 1004 */ 1005 1005 if (!msg->icmph.icmp6_solicited && idev && 1006 1006 idev->cnf.drop_unsolicited_na) ··· 1041 1041 in6_ifa_put(ifp); 1042 1042 return; 1043 1043 } 1044 + 1045 + neigh = neigh_lookup(&nd_tbl, &msg->target, dev); 1046 + 1044 1047 /* RFC 9131 updates original Neighbour Discovery RFC 4861. 1045 - * An unsolicited NA can now create a neighbour cache entry 1046 - * on routers if it has Target LL Address option. 1048 + * NAs with Target LL Address option without a corresponding 1049 + * entry in the neighbour cache can now create a STALE neighbour 1050 + * cache entry on routers. 1047 1051 * 1048 - * drop accept fwding behaviour 1049 - * ---- ------ ------ ---------------------------------------------- 1050 - * 1 X X Drop NA packet and don't pass up the stack 1051 - * 0 0 X Pass NA packet up the stack, don't update NC 1052 - * 0 1 0 Pass NA packet up the stack, don't update NC 1053 - * 0 1 1 Pass NA packet up the stack, and add a STALE 1054 - * NC entry 1052 + * entry accept fwding solicited behaviour 1053 + * ------- ------ ------ --------- ---------------------- 1054 + * present X X 0 Set state to STALE 1055 + * present X X 1 Set state to REACHABLE 1056 + * absent 0 X X Do nothing 1057 + * absent 1 0 X Do nothing 1058 + * absent 1 1 X Add a new STALE entry 1059 + * 1055 1060 * Note that we don't do a (daddr == all-routers-mcast) check. 1056 1061 */ 1057 - create_neigh = !msg->icmph.icmp6_solicited && lladdr && 1058 - idev && idev->cnf.forwarding && 1059 - idev->cnf.accept_unsolicited_na; 1060 - neigh = __neigh_lookup(&nd_tbl, &msg->target, dev, create_neigh); 1062 + new_state = msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE; 1063 + if (!neigh && lladdr && 1064 + idev && idev->cnf.forwarding && 1065 + idev->cnf.accept_untracked_na) { 1066 + neigh = neigh_create(&nd_tbl, &msg->target, dev); 1067 + new_state = NUD_STALE; 1068 + } 1061 1069 1062 - if (neigh) { 1070 + if (neigh && !IS_ERR(neigh)) { 1063 1071 u8 old_flags = neigh->flags; 1064 1072 struct net *net = dev_net(dev); 1065 1073 ··· 1087 1079 } 1088 1080 1089 1081 ndisc_update(dev, neigh, lladdr, 1090 - msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE, 1082 + new_state, 1091 1083 NEIGH_UPDATE_F_WEAK_OVERRIDE| 1092 1084 (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)| 1093 1085 NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
+11 -12
tools/testing/selftests/net/ndisc_unsolicited_na_test.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 - # This test is for the accept_unsolicited_na feature to 4 + # This test is for the accept_untracked_na feature to 5 5 # enable RFC9131 behaviour. The following is the test-matrix. 6 6 # drop accept fwding behaviour 7 7 # ---- ------ ------ ---------------------------------------------- 8 - # 1 X X Drop NA packet and don't pass up the stack 9 - # 0 0 X Pass NA packet up the stack, don't update NC 10 - # 0 1 0 Pass NA packet up the stack, don't update NC 11 - # 0 1 1 Pass NA packet up the stack, and add a STALE 12 - # NC entry 8 + # 1 X X Don't update NC 9 + # 0 0 X Don't update NC 10 + # 0 1 0 Don't update NC 11 + # 0 1 1 Add a STALE NC entry 13 12 14 13 ret=0 15 14 # Kselftest framework requirement - SKIP code is 4. ··· 71 72 set -e 72 73 73 74 local drop_unsolicited_na=$1 74 - local accept_unsolicited_na=$2 75 + local accept_untracked_na=$2 75 76 local forwarding=$3 76 77 77 78 # Setup two namespaces and a veth tunnel across them. ··· 92 93 ${IP_ROUTER_EXEC} sysctl -qw \ 93 94 ${ROUTER_CONF}.drop_unsolicited_na=${drop_unsolicited_na} 94 95 ${IP_ROUTER_EXEC} sysctl -qw \ 95 - ${ROUTER_CONF}.accept_unsolicited_na=${accept_unsolicited_na} 96 + ${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na} 96 97 ${IP_ROUTER_EXEC} sysctl -qw ${ROUTER_CONF}.disable_ipv6=0 97 98 ${IP_ROUTER} addr add ${ROUTER_ADDR_WITH_MASK} dev ${ROUTER_INTF} 98 99 ··· 143 144 144 145 verify_ndisc() { 145 146 local drop_unsolicited_na=$1 146 - local accept_unsolicited_na=$2 147 + local accept_untracked_na=$2 147 148 local forwarding=$3 148 149 149 150 neigh_show_output=$(${IP_ROUTER} neigh show \ 150 151 to ${HOST_ADDR} dev ${ROUTER_INTF} nud stale) 151 152 if [ ${drop_unsolicited_na} -eq 0 ] && \ 152 - [ ${accept_unsolicited_na} -eq 1 ] && \ 153 + [ ${accept_untracked_na} -eq 1 ] && \ 153 154 [ ${forwarding} -eq 1 ]; then 154 155 # Neighbour entry expected to be present for 011 case 155 156 [[ ${neigh_show_output} ]] ··· 178 179 test_unsolicited_na_common $1 $2 $3 179 180 test_msg=("test_unsolicited_na: " 180 181 "drop_unsolicited_na=$1 " 181 - "accept_unsolicited_na=$2 " 182 + "accept_untracked_na=$2 " 182 183 "forwarding=$3") 183 184 log_test $? 0 "${test_msg[*]}" 184 185 cleanup 185 186 } 186 187 187 188 test_unsolicited_na_combinations() { 188 - # Args: drop_unsolicited_na accept_unsolicited_na forwarding 189 + # Args: drop_unsolicited_na accept_untracked_na forwarding 189 190 190 191 # Expect entry 191 192 test_unsolicited_na_combination 0 1 1