]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net/ipv6: Expand and rename accept_unsolicited_na to accept_untracked_na
authorArun Ajith S <aajith@arista.com>
Mon, 30 May 2022 10:14:14 +0000 (10:14 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 31 May 2022 09:36:57 +0000 (11:36 +0200)
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: 920b5ae91a69 ("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>
Documentation/networking/ip-sysctl.rst
include/linux/ipv6.h
include/uapi/linux/ipv6.h
net/ipv6/addrconf.c
net/ipv6/ndisc.c
tools/testing/selftests/net/ndisc_unsolicited_na_test.sh

index b882d42385813def4f41c740b8575c08f15691e9..04216564a03cb5951e82a8eb96ffcbd62a76af70 100644 (file)
@@ -2474,21 +2474,16 @@ drop_unsolicited_na - BOOLEAN
 
        By default this is turned off.
 
-accept_unsolicited_na - BOOLEAN
-       Add a new neighbour cache entry in STALE state for routers on receiving an
-       unsolicited neighbour advertisement with target link-layer address option
-       specified. This is as per router-side behavior documented in RFC9131.
-       This has lower precedence than drop_unsolicited_na.
+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.
 
-        ====   ======  ======  ==============================================
-        drop   accept  fwding                   behaviour
-        ----   ------  ------  ----------------------------------------------
-           1        X       X  Drop NA packet and don't pass up the stack
-           0        0       X  Pass NA packet up the stack, don't update NC
-           0        1       0  Pass NA packet up the stack, don't update NC
-           0        1       1  Pass NA packet up the stack, and add a STALE
-                               NC entry
-        ====   ======  ======  ==============================================
+       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
index 38c8203d52cbf39e523c43fe630a7b184b9991aa..37dfdcfcdd542fe0efc9a1df967be3da931635d4 100644 (file)
@@ -61,7 +61,7 @@ struct ipv6_devconf {
        __s32           suppress_frag_ndisc;
        __s32           accept_ra_mtu;
        __s32           drop_unsolicited_na;
-       __s32           accept_unsolicited_na;
+       __s32           accept_untracked_na;
        struct ipv6_stable_secret {
                bool initialized;
                struct in6_addr secret;
index 549ddeaf788b543dac2d8f0df1ed04bf45d8a6a2..03cdbe798fe3c3ed9e6bbeefd4c14b945420bd59 100644 (file)
@@ -194,7 +194,7 @@ enum {
        DEVCONF_IOAM6_ID,
        DEVCONF_IOAM6_ID_WIDE,
        DEVCONF_NDISC_EVICT_NOCARRIER,
-       DEVCONF_ACCEPT_UNSOLICITED_NA,
+       DEVCONF_ACCEPT_UNTRACKED_NA,
        DEVCONF_MAX
 };
 
index ca0aa744593e6e6352cb8d2506b3c83b2d245aba..1b1932502e9e7d858ced4ea5a72b72a7062ee48f 100644 (file)
@@ -5586,7 +5586,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_IOAM6_ID] = cnf->ioam6_id;
        array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide;
        array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier;
-       array[DEVCONF_ACCEPT_UNSOLICITED_NA] = cnf->accept_unsolicited_na;
+       array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na;
 }
 
 static inline size_t inet6_ifla6_size(void)
@@ -7038,8 +7038,8 @@ static const struct ctl_table addrconf_sysctl[] = {
                .extra2         = (void *)SYSCTL_ONE,
        },
        {
-               .procname       = "accept_unsolicited_na",
-               .data           = &ipv6_devconf.accept_unsolicited_na,
+               .procname       = "accept_untracked_na",
+               .data           = &ipv6_devconf.accept_untracked_na,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
index 254addad0dd31cb9af234e99725203fa5457d187..b0dfe97ea4eed99b5321cb30392e7dff867653f7 100644 (file)
@@ -979,7 +979,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
        struct inet6_dev *idev = __in6_dev_get(dev);
        struct inet6_ifaddr *ifp;
        struct neighbour *neigh;
-       bool create_neigh;
+       u8 new_state;
 
        if (skb->len < sizeof(struct nd_msg)) {
                ND_PRINTK(2, warn, "NA: packet too short\n");
@@ -1000,7 +1000,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
        /* For some 802.11 wireless deployments (and possibly other networks),
         * there will be a NA proxy and unsolicitd packets are attacks
         * and thus should not be accepted.
-        * drop_unsolicited_na takes precedence over accept_unsolicited_na
+        * drop_unsolicited_na takes precedence over accept_untracked_na
         */
        if (!msg->icmph.icmp6_solicited && idev &&
            idev->cnf.drop_unsolicited_na)
@@ -1041,25 +1041,33 @@ static void ndisc_recv_na(struct sk_buff *skb)
                in6_ifa_put(ifp);
                return;
        }
+
+       neigh = neigh_lookup(&nd_tbl, &msg->target, dev);
+
        /* RFC 9131 updates original Neighbour Discovery RFC 4861.
-        * An unsolicited NA can now create a neighbour cache entry
-        * on routers if it has Target LL Address option.
+        * NAs with Target LL Address option without a corresponding
+        * entry in the neighbour cache can now create a STALE neighbour
+        * cache entry on routers.
+        *
+        *   entry accept  fwding  solicited        behaviour
+        * ------- ------  ------  ---------    ----------------------
+        * present      X       X         0     Set state to STALE
+        * present      X       X         1     Set state to REACHABLE
+        *  absent      0       X         X     Do nothing
+        *  absent      1       0         X     Do nothing
+        *  absent      1       1         X     Add a new STALE entry
         *
-        * drop   accept  fwding                   behaviour
-        * ----   ------  ------  ----------------------------------------------
-        *    1        X       X  Drop NA packet and don't pass up the stack
-        *    0        0       X  Pass NA packet up the stack, don't update NC
-        *    0        1       0  Pass NA packet up the stack, don't update NC
-        *    0        1       1  Pass NA packet up the stack, and add a STALE
-        *                          NC entry
         * Note that we don't do a (daddr == all-routers-mcast) check.
         */
-       create_neigh = !msg->icmph.icmp6_solicited && lladdr &&
-                      idev && idev->cnf.forwarding &&
-                      idev->cnf.accept_unsolicited_na;
-       neigh = __neigh_lookup(&nd_tbl, &msg->target, dev, create_neigh);
+       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) {
+       if (neigh && !IS_ERR(neigh)) {
                u8 old_flags = neigh->flags;
                struct net *net = dev_net(dev);
 
@@ -1079,7 +1087,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
                }
 
                ndisc_update(dev, neigh, lladdr,
-                            msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,
+                            new_state,
                             NEIGH_UPDATE_F_WEAK_OVERRIDE|
                             (msg->icmph.icmp6_override ? NEIGH_UPDATE_F_OVERRIDE : 0)|
                             NEIGH_UPDATE_F_OVERRIDE_ISROUTER|
index f508657ee126d1a30541c9419a1253391f4cf666..86e621b7b9c7b301a75514faf9a89396a7be445f 100755 (executable)
@@ -1,15 +1,14 @@
 #!/bin/bash
 # SPDX-License-Identifier: GPL-2.0
 
-# This test is for the accept_unsolicited_na feature to
+# This test is for the accept_untracked_na feature to
 # enable RFC9131 behaviour. The following is the test-matrix.
 # drop   accept  fwding                   behaviour
 # ----   ------  ------  ----------------------------------------------
-#    1        X       X  Drop NA packet and don't pass up the stack
-#    0        0       X  Pass NA packet up the stack, don't update NC
-#    0        1       0  Pass NA packet up the stack, don't update NC
-#    0        1       1  Pass NA packet up the stack, and add a STALE
-#                           NC entry
+#    1        X       X  Don't update NC
+#    0        0       X  Don't update NC
+#    0        1       0  Don't update NC
+#    0        1       1  Add a STALE NC entry
 
 ret=0
 # Kselftest framework requirement - SKIP code is 4.
@@ -72,7 +71,7 @@ setup()
        set -e
 
        local drop_unsolicited_na=$1
-       local accept_unsolicited_na=$2
+       local accept_untracked_na=$2
        local forwarding=$3
 
        # Setup two namespaces and a veth tunnel across them.
@@ -93,7 +92,7 @@ setup()
        ${IP_ROUTER_EXEC} sysctl -qw \
                 ${ROUTER_CONF}.drop_unsolicited_na=${drop_unsolicited_na}
        ${IP_ROUTER_EXEC} sysctl -qw \
-                ${ROUTER_CONF}.accept_unsolicited_na=${accept_unsolicited_na}
+                ${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na}
        ${IP_ROUTER_EXEC} sysctl -qw ${ROUTER_CONF}.disable_ipv6=0
        ${IP_ROUTER} addr add ${ROUTER_ADDR_WITH_MASK} dev ${ROUTER_INTF}
 
@@ -144,13 +143,13 @@ link_up() {
 
 verify_ndisc() {
        local drop_unsolicited_na=$1
-       local accept_unsolicited_na=$2
+       local accept_untracked_na=$2
        local forwarding=$3
 
        neigh_show_output=$(${IP_ROUTER} neigh show \
                 to ${HOST_ADDR} dev ${ROUTER_INTF} nud stale)
        if [ ${drop_unsolicited_na} -eq 0 ] && \
-                       [ ${accept_unsolicited_na} -eq 1 ] && \
+                       [ ${accept_untracked_na} -eq 1 ] && \
                        [ ${forwarding} -eq 1 ]; then
                # Neighbour entry expected to be present for 011 case
                [[ ${neigh_show_output} ]]
@@ -179,14 +178,14 @@ test_unsolicited_na_combination() {
        test_unsolicited_na_common $1 $2 $3
        test_msg=("test_unsolicited_na: "
                "drop_unsolicited_na=$1 "
-               "accept_unsolicited_na=$2 "
+               "accept_untracked_na=$2 "
                "forwarding=$3")
        log_test $? 0 "${test_msg[*]}"
        cleanup
 }
 
 test_unsolicited_na_combinations() {
-       # Args: drop_unsolicited_na accept_unsolicited_na forwarding
+       # Args: drop_unsolicited_na accept_untracked_na forwarding
 
        # Expect entry
        test_unsolicited_na_combination 0 1 1