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
 
        __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;
 
        DEVCONF_IOAM6_ID,
        DEVCONF_IOAM6_ID_WIDE,
        DEVCONF_NDISC_EVICT_NOCARRIER,
-       DEVCONF_ACCEPT_UNSOLICITED_NA,
+       DEVCONF_ACCEPT_UNTRACKED_NA,
        DEVCONF_MAX
 };
 
 
        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)
                .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,
 
        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");
        /* 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)
                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);
 
                }
 
                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|
 
 #!/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.
        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.
        ${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}
 
 
 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} ]]
        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