inet6: discard NA messages with a lladdress we own
authorRoy Marples <roy@marples.name>
Thu, 8 Aug 2019 16:41:55 +0000 (17:41 +0100)
committerRoy Marples <roy@marples.name>
Thu, 8 Aug 2019 16:41:55 +0000 (17:41 +0100)
This allows userland to send NA messages for already existing
addresses without the kernel reporting incorrectly that a
duplicate address has been detected.

sys/netinet6/nd6_nbr.c

index 4dbf67b..16fcb0f 100644 (file)
@@ -638,8 +638,22 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
        }
 
        if (ndopts.nd_opts_tgt_lladdr) {
+               struct ifnet *ifp_ll;
+
                lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
                lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
+
+               if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
+                       nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch "
+                           "for %s (if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
+                           ifp->if_addrlen, lladdrlen - 2));
+                       goto bad;
+               }
+
+               /* If it's from me, ignore it. */
+               ifp_ll = if_bylla(lladdr, ifp->if_addrlen);
+               if (ifp_ll != NULL)
+                       goto freeit;
        }
 
        ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
@@ -678,13 +692,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
                }
        }
 
-       if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
-               nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
-                   "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
-                   ifp->if_addrlen, lladdrlen - 2));
-               goto bad;
-       }
-
        /*
         * If no neighbor cache entry is found, NA SHOULD silently be discarded.
         */