The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet6/nd6_nbr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: nd6_nbr.c,v 1.182 2021/08/02 12:56:25 andvar Exp $     */
    2 /*      $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the project nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.182 2021/08/02 12:56:25 andvar Exp $");
   35 
   36 #ifdef _KERNEL_OPT
   37 #include "opt_inet.h"
   38 #include "opt_net_mpsafe.h"
   39 #endif
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/kmem.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/socket.h>
   46 #include <sys/socketvar.h>
   47 #include <sys/sockio.h>
   48 #include <sys/time.h>
   49 #include <sys/kernel.h>
   50 #include <sys/errno.h>
   51 #include <sys/ioctl.h>
   52 #include <sys/syslog.h>
   53 #include <sys/queue.h>
   54 #include <sys/callout.h>
   55 #include <sys/cprng.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_types.h>
   59 #include <net/if_dl.h>
   60 #include <net/if_llatbl.h>
   61 #include <net/nd.h>
   62 #include <net/route.h>
   63 
   64 #include <netinet/in.h>
   65 #include <netinet/in_var.h>
   66 #include <netinet6/in6_var.h>
   67 #include <netinet6/in6_ifattach.h>
   68 #include <netinet/ip6.h>
   69 #include <netinet6/ip6_var.h>
   70 #include <netinet6/scope6_var.h>
   71 #include <netinet6/nd6.h>
   72 #include <netinet/icmp6.h>
   73 #include <netinet6/icmp6_private.h>
   74 
   75 #include "carp.h"
   76 #if NCARP > 0
   77 #include <netinet/ip_carp.h>
   78 #endif
   79 
   80 struct dadq;
   81 static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *, bool *);
   82 static bool nd6_dad_ownnonce(struct ifaddr *, struct nd_opt_nonce *nonce);
   83 static void nd6_dad_starttimer(struct dadq *, int);
   84 static void nd6_dad_destroytimer(struct dadq *);
   85 static void nd6_dad_timer(struct dadq *);
   86 static void nd6_dad_ns_output(struct dadq *, struct ifaddr *);
   87 static void nd6_dad_input(struct ifaddr *, struct nd_opt_nonce *,
   88     const struct sockaddr_dl *);
   89 static void nd6_dad_duplicated(struct ifaddr *, struct dadq *,
   90     const struct sockaddr_dl *);
   91 
   92 static int dad_maxtry = 15;     /* max # of *tries* to transmit DAD packet */
   93 
   94 /*
   95  * Input a Neighbor Solicitation Message.
   96  *
   97  * Based on RFC 2461
   98  * Based on RFC 2462 (duplicate address detection)
   99  */
  100 void
  101 nd6_ns_input(struct mbuf *m, int off, int icmp6len)
  102 {
  103         struct ifnet *ifp;
  104         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
  105         struct nd_neighbor_solicit *nd_ns;
  106         struct in6_addr saddr6 = ip6->ip6_src;
  107         struct in6_addr daddr6 = ip6->ip6_dst;
  108         struct in6_addr taddr6;
  109         struct in6_addr myaddr6;
  110         char *lladdr = NULL;
  111         struct ifaddr *ifa = NULL;
  112         int lladdrlen = 0;
  113         int anycast = 0, proxy = 0, tentative = 0;
  114         int router = ip6_forwarding;
  115         int tlladdr;
  116         union nd_opts ndopts;
  117         const struct sockaddr_dl *proxydl = NULL;
  118         struct psref psref;
  119         struct psref psref_ia;
  120         char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
  121 
  122         ifp = m_get_rcvif_psref(m, &psref);
  123         if (ifp == NULL)
  124                 goto freeit;
  125 
  126         IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
  127         if (nd_ns == NULL) {
  128                 ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
  129                 m_put_rcvif_psref(ifp, &psref);
  130                 return;
  131         }
  132         ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
  133         taddr6 = nd_ns->nd_ns_target;
  134         if (in6_setscope(&taddr6, ifp, NULL) != 0)
  135                 goto bad;
  136 
  137         if (ip6->ip6_hlim != 255) {
  138                 nd6log(LOG_ERR, "invalid hlim (%d) from %s to %s on %s\n",
  139                     ip6->ip6_hlim, IN6_PRINT(ip6buf, &ip6->ip6_src),
  140                     IN6_PRINT(ip6buf2, &ip6->ip6_dst), if_name(ifp));
  141                 goto bad;
  142         }
  143 
  144         if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
  145                 /* dst has to be a solicited node multicast address. */
  146                 /* don't check ifindex portion */
  147                 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
  148                     daddr6.s6_addr32[1] == 0 &&
  149                     daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
  150                     daddr6.s6_addr8[12] == 0xff) {
  151                         ; /* good */
  152                 } else {
  153                         nd6log(LOG_INFO, "bad DAD packet (wrong ip6 dst)\n");
  154                         goto bad;
  155                 }
  156         } else {
  157                 struct sockaddr_in6 ssin6;
  158 
  159                 /*
  160                  * Make sure the source address is from a neighbor's address.
  161                  */
  162                 sockaddr_in6_init(&ssin6, &saddr6, 0, 0, 0);
  163                 if (nd6_is_addr_neighbor(&ssin6, ifp) == 0) {
  164                         nd6log(LOG_INFO,
  165                             "NS packet from non-neighbor %s on %s\n",
  166                             IN6_PRINT(ip6buf, &saddr6), if_name(ifp));
  167                         goto bad;
  168                 }
  169         }
  170 
  171         if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
  172                 nd6log(LOG_INFO, "bad NS target (multicast)\n");
  173                 goto bad;
  174         }
  175 
  176         icmp6len -= sizeof(*nd_ns);
  177         nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
  178         if (nd6_options(&ndopts) < 0) {
  179                 nd6log(LOG_INFO, "invalid ND option, ignored\n");
  180                 /* nd6_options have incremented stats */
  181                 goto freeit;
  182         }
  183 
  184         if (ndopts.nd_opts_src_lladdr) {
  185                 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
  186                 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
  187         }
  188 
  189         if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
  190                 nd6log(LOG_INFO,
  191                     "bad DAD packet (link-layer address option)\n");
  192                 goto bad;
  193         }
  194 
  195         /*
  196          * Attaching target link-layer address to the NA?
  197          * (RFC 2461 7.2.4)
  198          *
  199          * NS IP dst is multicast                       MUST add
  200          * Otherwise                                    MAY be omitted
  201          *
  202          * In this implementation, we omit the target link-layer address
  203          * in the "MAY" case.
  204          */
  205 #if 0 /* too much! */
  206         ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6);
  207         if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST))
  208                 tlladdr = 0;
  209         else
  210 #endif
  211         if (!IN6_IS_ADDR_MULTICAST(&daddr6))
  212                 tlladdr = 0;
  213         else
  214                 tlladdr = 1;
  215 
  216         /*
  217          * Target address (taddr6) must be either:
  218          * (1) Valid unicast/anycast address for my receiving interface,
  219          * (2) Unicast address for which I'm offering proxy service, or
  220          * (3) "tentative" address on which DAD is being performed.
  221          */
  222         /* (1) and (3) check. */
  223 #if NCARP > 0
  224         if (ifp->if_carp && ifp->if_type != IFT_CARP) {
  225                 int s = pserialize_read_enter();
  226                 ifa = carp_iamatch6(ifp->if_carp, &taddr6);
  227                 if (ifa != NULL)
  228                         ifa_acquire(ifa, &psref_ia);
  229                 pserialize_read_exit(s);
  230         } else
  231                 ifa = NULL;
  232         if (!ifa)
  233                 ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6,
  234                     &psref_ia);
  235 #else
  236         ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6,
  237             &psref_ia);
  238 #endif
  239 
  240         /* (2) check. */
  241         if (ifa == NULL) {
  242                 struct rtentry *rt;
  243                 struct sockaddr_in6 tsin6;
  244 
  245                 sockaddr_in6_init(&tsin6, &taddr6, 0, 0, 0);
  246 
  247                 rt = rtalloc1(sin6tosa(&tsin6), 0);
  248                 if (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 &&
  249                     rt->rt_gateway->sa_family == AF_LINK) {
  250                         /*
  251                          * proxy NDP for single entry
  252                          */
  253                         ifa = (struct ifaddr *)in6ifa_ifpforlinklocal_psref(ifp,
  254                                 IN6_IFF_NOTREADY|IN6_IFF_ANYCAST, &psref_ia);
  255                         if (ifa) {
  256                                 proxy = 1;
  257                                 proxydl = satocsdl(rt->rt_gateway);
  258                                 router = 0;     /* XXX */
  259                         }
  260                 }
  261                 if (rt)
  262                         rt_unref(rt);
  263         }
  264         if (ifa == NULL) {
  265                 /*
  266                  * We've got an NS packet, and we don't have that address
  267                  * assigned for us.  We MUST silently ignore it.
  268                  * See RFC2461 7.2.3.
  269                  */
  270                 goto freeit;
  271         }
  272         myaddr6 = *IFA_IN6(ifa);
  273         anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
  274         tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
  275         if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
  276                 goto freeit;
  277 
  278         if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
  279                 nd6log(LOG_INFO, "lladdrlen mismatch for %s "
  280                     "(if %d, NS packet %d)\n",
  281                     IN6_PRINT(ip6buf, &taddr6),
  282                     ifp->if_addrlen, lladdrlen - 2);
  283                 goto bad;
  284         }
  285 
  286         if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
  287                 nd6log(LOG_INFO, "duplicate IP6 address %s\n",
  288                     IN6_PRINT(ip6buf, &saddr6));
  289                 goto freeit;
  290         }
  291 
  292         /*
  293          * We have neighbor solicitation packet, with target address equals to
  294          * one of my tentative address.
  295          *
  296          * src addr     how to process?
  297          * ---          ---
  298          * multicast    of course, invalid (rejected in ip6_input)
  299          * unicast      somebody is doing address resolution -> ignore
  300          * unspec       dup address detection
  301          *
  302          * The processing is defined in RFC 2462.
  303          */
  304         if (tentative) {
  305                 /*
  306                  * If source address is unspecified address, it is for
  307                  * duplicate address detection.
  308                  *
  309                  * If not, the packet is for address resolution;
  310                  * silently ignore it.
  311                  */
  312                 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
  313                         struct sockaddr_dl sdl, *sdlp;
  314 
  315                         if (lladdr != NULL)
  316                                 sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
  317                                     ifp->if_index, ifp->if_type,
  318                                     NULL, 0, lladdr, lladdrlen);
  319                         else
  320                                 sdlp = NULL;
  321                         nd6_dad_input(ifa, ndopts.nd_opts_nonce, sdlp);
  322                 }
  323                 goto freeit;
  324         }
  325 
  326         /*
  327          * It looks that sender is performing DAD.
  328          * Check that the nonce is not being used by the same address
  329          * on another interface.
  330          */
  331         if (IN6_IS_ADDR_UNSPECIFIED(&saddr6) && ndopts.nd_opts_nonce != NULL) {
  332                 if (nd6_dad_ownnonce(ifa, ndopts.nd_opts_nonce))
  333                         goto freeit;
  334         }
  335 
  336         ifa_release(ifa, &psref_ia);
  337         ifa = NULL;
  338 
  339         /*
  340          * If the source address is unspecified address, entries must not
  341          * be created or updated.
  342          * It looks that sender is performing DAD.  Output NA toward
  343          * all-node multicast address, to tell the sender that I'm using
  344          * the address.
  345          * S bit ("solicited") must be zero.
  346          */
  347         if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
  348                 struct in6_addr in6_all;
  349 
  350                 in6_all = in6addr_linklocal_allnodes;
  351                 if (in6_setscope(&in6_all, ifp, NULL) != 0)
  352                         goto bad;
  353                 nd6_na_output(ifp, &in6_all, &taddr6,
  354                     ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
  355                     (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0),
  356                     tlladdr, (const struct sockaddr *)proxydl);
  357                 goto freeit;
  358         }
  359 
  360         nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0);
  361 
  362         nd6_na_output(ifp, &saddr6, &taddr6,
  363             ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
  364             (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED,
  365             tlladdr, (const struct sockaddr *)proxydl);
  366  freeit:
  367         ifa_release(ifa, &psref_ia);
  368         m_put_rcvif_psref(ifp, &psref);
  369         m_freem(m);
  370         return;
  371 
  372  bad:
  373         nd6log(LOG_ERR, "src=%s\n", IN6_PRINT(ip6buf, &saddr6));
  374         nd6log(LOG_ERR, "dst=%s\n", IN6_PRINT(ip6buf, &daddr6));
  375         nd6log(LOG_ERR, "tgt=%s\n", IN6_PRINT(ip6buf, &taddr6));
  376         ICMP6_STATINC(ICMP6_STAT_BADNS);
  377         ifa_release(ifa, &psref_ia);
  378         m_put_rcvif_psref(ifp, &psref);
  379         m_freem(m);
  380 }
  381 
  382 /*
  383  * Output a Neighbor Solicitation Message. Caller specifies:
  384  *      - ICMP6 header source IP6 address
  385  *      - ND6 header target IP6 address
  386  *      - ND6 header source datalink address
  387  *
  388  * Based on RFC 2461
  389  * Based on RFC 2462 (duplicate address detection)
  390  */
  391 void
  392 nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6,
  393     const struct in6_addr *taddr6,
  394     const struct in6_addr *hsrc,
  395     const uint8_t *nonce        /* duplicate address detection */)
  396 {
  397         struct mbuf *m;
  398         struct ip6_hdr *ip6;
  399         struct nd_neighbor_solicit *nd_ns;
  400         const struct in6_addr *src;
  401         struct in6_addr src_in;
  402         struct ip6_moptions im6o;
  403         int icmp6len;
  404         int maxlen;
  405         const void *mac;
  406         struct route ro;
  407 
  408         if (IN6_IS_ADDR_MULTICAST(taddr6))
  409                 return;
  410 
  411         memset(&ro, 0, sizeof(ro));
  412 
  413         /* estimate the size of message */
  414         maxlen = sizeof(*ip6) + sizeof(*nd_ns);
  415         maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
  416         KASSERTMSG(max_linkhdr + maxlen <= MCLBYTES,
  417             "max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
  418             max_linkhdr, maxlen, MCLBYTES);
  419 
  420         MGETHDR(m, M_DONTWAIT, MT_DATA);
  421         if (m && max_linkhdr + maxlen >= MHLEN) {
  422                 MCLGET(m, M_DONTWAIT);
  423                 if ((m->m_flags & M_EXT) == 0) {
  424                         m_free(m);
  425                         m = NULL;
  426                 }
  427         }
  428         if (m == NULL)
  429                 return;
  430         m_reset_rcvif(m);
  431 
  432         if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
  433                 m->m_flags |= M_MCAST;
  434                 im6o.im6o_multicast_if_index = if_get_index(ifp);
  435                 im6o.im6o_multicast_hlim = 255;
  436                 im6o.im6o_multicast_loop = 0;
  437         }
  438 
  439         icmp6len = sizeof(*nd_ns);
  440         m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
  441         m->m_data += max_linkhdr;       /* or m_align() equivalent? */
  442 
  443         /* fill neighbor solicitation packet */
  444         ip6 = mtod(m, struct ip6_hdr *);
  445         ip6->ip6_flow = 0;
  446         ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
  447         ip6->ip6_vfc |= IPV6_VERSION;
  448         /* ip6->ip6_plen will be set later */
  449         ip6->ip6_nxt = IPPROTO_ICMPV6;
  450         ip6->ip6_hlim = 255;
  451         if (daddr6)
  452                 ip6->ip6_dst = *daddr6;
  453         else {
  454                 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
  455                 ip6->ip6_dst.s6_addr16[1] = 0;
  456                 ip6->ip6_dst.s6_addr32[1] = 0;
  457                 ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
  458                 ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
  459                 ip6->ip6_dst.s6_addr8[12] = 0xff;
  460                 if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
  461                         goto bad;
  462         }
  463         if (nonce == NULL) {
  464                 int s;
  465                 /*
  466                  * RFC2461 7.2.2:
  467                  * "If the source address of the packet prompting the
  468                  * solicitation is the same as one of the addresses assigned
  469                  * to the outgoing interface, that address SHOULD be placed
  470                  * in the IP Source Address of the outgoing solicitation.
  471                  * Otherwise, any one of the addresses assigned to the
  472                  * interface should be used."
  473                  *
  474                  * We use the source address for the prompting packet
  475                  * (hsrc), if:
  476                  * - hsrc is given from the caller (by giving "ln"), and
  477                  * - hsrc belongs to the outgoing interface.
  478                  * Otherwise, we perform the source address selection as usual.
  479                  */
  480                 s = pserialize_read_enter();
  481                 if (hsrc && in6ifa_ifpwithaddr(ifp, hsrc)) {
  482                         pserialize_read_exit(s);
  483                         src = hsrc;
  484                 } else {
  485                         int error;
  486                         struct sockaddr_in6 dst_sa;
  487 
  488                         pserialize_read_exit(s);
  489 
  490                         sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
  491 
  492                         error = in6_selectsrc(&dst_sa, NULL,
  493                             NULL, &ro, NULL, NULL, NULL, &src_in);
  494                         if (error != 0) {
  495                                 char ip6buf[INET6_ADDRSTRLEN];
  496                                 nd6log(LOG_DEBUG, "source can't be "
  497                                     "determined: dst=%s, error=%d\n",
  498                                     IN6_PRINT(ip6buf, &dst_sa.sin6_addr),
  499                                     error);
  500                                 goto bad;
  501                         }
  502                         src = &src_in;
  503                 }
  504         } else {
  505                 /*
  506                  * Source address for DAD packet must always be IPv6
  507                  * unspecified address. (0::0)
  508                  * We actually don't have to 0-clear the address (we did it
  509                  * above), but we do so here explicitly to make the intention
  510                  * clearer.
  511                  */
  512                 memset(&src_in, 0, sizeof(src_in));
  513                 src = &src_in;
  514         }
  515         ip6->ip6_src = *src;
  516         nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
  517         nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
  518         nd_ns->nd_ns_code = 0;
  519         nd_ns->nd_ns_reserved = 0;
  520         nd_ns->nd_ns_target = *taddr6;
  521         in6_clearscope(&nd_ns->nd_ns_target); /* XXX */
  522 
  523         /*
  524          * Add source link-layer address option.
  525          *
  526          *                              spec            implementation
  527          *                              ---             ---
  528          * DAD packet                   MUST NOT        do not add the option
  529          * there's no link layer address:
  530          *                              impossible      do not add the option
  531          * there's link layer address:
  532          *      Multicast NS            MUST add one    add the option
  533          *      Unicast NS              SHOULD add one  add the option
  534          */
  535         if (nonce == NULL && (mac = nd6_ifptomac(ifp))) {
  536                 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
  537                 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
  538                 /* 8 byte alignments... */
  539                 optlen = (optlen + 7) & ~7;
  540 
  541                 m->m_pkthdr.len += optlen;
  542                 m->m_len += optlen;
  543                 icmp6len += optlen;
  544                 memset((void *)nd_opt, 0, optlen);
  545                 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
  546                 nd_opt->nd_opt_len = optlen >> 3;
  547                 memcpy((void *)(nd_opt + 1), mac, ifp->if_addrlen);
  548         }
  549 
  550         /* Add a nonce option (RFC 3971) to detect looped back NS messages.
  551          * This behavior is documented in RFC 7527. */
  552         if (nonce != NULL) {
  553                 int optlen = sizeof(struct nd_opt_hdr) + ND_OPT_NONCE_LEN;
  554                 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
  555 
  556                 /* 8-byte alignment is required. */
  557                 optlen = (optlen + 7) & ~7;
  558                 m->m_pkthdr.len += optlen;
  559                 m->m_len += optlen;
  560                 icmp6len += optlen;
  561                 memset(nd_opt, 0, optlen);
  562                 nd_opt->nd_opt_type = ND_OPT_NONCE;
  563                 nd_opt->nd_opt_len = optlen >> 3;
  564                 memcpy(nd_opt + 1, nonce, ND_OPT_NONCE_LEN);
  565         }
  566 
  567         ip6->ip6_plen = htons((u_int16_t)icmp6len);
  568         nd_ns->nd_ns_cksum = 0;
  569         nd_ns->nd_ns_cksum =
  570             in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
  571 
  572         ip6_output(m, NULL, &ro, nonce != NULL ? IPV6_UNSPECSRC : 0,
  573             &im6o, NULL, NULL);
  574         icmp6_ifstat_inc(ifp, ifs6_out_msg);
  575         icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
  576         ICMP6_STATINC(ICMP6_STAT_OUTHIST + ND_NEIGHBOR_SOLICIT);
  577 
  578         rtcache_free(&ro);
  579         return;
  580 
  581   bad:
  582         rtcache_free(&ro);
  583         m_freem(m);
  584         return;
  585 }
  586 
  587 /*
  588  * Neighbor advertisement input handling.
  589  *
  590  * Based on RFC 2461
  591  * Based on RFC 2462 (duplicate address detection)
  592  *
  593  * the following items are not implemented yet:
  594  * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
  595  * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
  596  */
  597 void
  598 nd6_na_input(struct mbuf *m, int off, int icmp6len)
  599 {
  600         struct ifnet *ifp;
  601         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
  602         struct nd_neighbor_advert *nd_na;
  603         struct in6_addr saddr6 = ip6->ip6_src;
  604         struct in6_addr daddr6 = ip6->ip6_dst;
  605         struct in6_addr taddr6;
  606         int flags;
  607         int is_router;
  608         int is_solicited;
  609         int is_override;
  610         int rt_cmd;
  611         char *lladdr = NULL;
  612         int lladdrlen = 0;
  613         struct ifaddr *ifa;
  614         struct llentry *ln = NULL;
  615         union nd_opts ndopts;
  616         struct sockaddr_in6 ssin6;
  617         struct psref psref;
  618         struct psref psref_ia;
  619         char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
  620 
  621         ifp = m_get_rcvif_psref(m, &psref);
  622         if (ifp == NULL)
  623                 goto freeit;
  624 
  625         if (ip6->ip6_hlim != 255) {
  626                 nd6log(LOG_ERR,
  627                     "invalid hlim (%d) from %s to %s on %s\n",
  628                     ip6->ip6_hlim, IN6_PRINT(ip6buf, &ip6->ip6_src),
  629                     IN6_PRINT(ip6buf2, &ip6->ip6_dst), if_name(ifp));
  630                 goto bad;
  631         }
  632 
  633         IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
  634         if (nd_na == NULL) {
  635                 m_put_rcvif_psref(ifp, &psref);
  636                 ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
  637                 return;
  638         }
  639 
  640         flags = nd_na->nd_na_flags_reserved;
  641         is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
  642         is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
  643         is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
  644 
  645         taddr6 = nd_na->nd_na_target;
  646         if (in6_setscope(&taddr6, ifp, NULL)) {
  647                 goto bad;
  648         }
  649 
  650         if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
  651                 nd6log(LOG_ERR, "invalid target address %s\n",
  652                     IN6_PRINT(ip6buf, &taddr6));
  653                 goto bad;
  654         }
  655         if (is_solicited && IN6_IS_ADDR_MULTICAST(&daddr6)) {
  656                 nd6log(LOG_ERR, "a solicited adv is multicasted\n");
  657                 goto bad;
  658         }
  659 
  660         icmp6len -= sizeof(*nd_na);
  661         nd6_option_init(nd_na + 1, icmp6len, &ndopts);
  662         if (nd6_options(&ndopts) < 0) {
  663                 nd6log(LOG_INFO, "invalid ND option, ignored\n");
  664                 /* nd6_options have incremented stats */
  665                 goto freeit;
  666         }
  667 
  668         if (ndopts.nd_opts_tgt_lladdr != NULL) {
  669                 struct ifnet *ifp_ll;
  670                 struct psref psref_ll;
  671 
  672                 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
  673                 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
  674 
  675                 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
  676                         nd6log(LOG_INFO, "lladdrlen mismatch for %s "
  677                             "(if %d, NA packet %d)\n", IN6_PRINT(ip6buf, &taddr6),
  678                             ifp->if_addrlen, lladdrlen - 2);
  679                         goto bad;
  680                 }
  681 
  682                 ifp_ll = if_get_bylla(lladdr, ifp->if_addrlen, &psref_ll);
  683                 if (ifp_ll != NULL) {
  684                         /* it's from me, ignore it. */
  685                         if_put(ifp_ll, &psref_ll);
  686                         goto freeit;
  687                 }
  688         }
  689 
  690         ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6, &psref_ia);
  691 
  692         /*
  693          * Target address matches one of my interface address.
  694          *
  695          * If my address is tentative, this means that there's somebody
  696          * already using the same address as mine.  This indicates DAD failure.
  697          * This is defined in RFC 2462.
  698          *
  699          * Otherwise, process as defined in RFC 2461.
  700          */
  701         if (ifa) {
  702                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE) {
  703                         struct sockaddr_dl sdl, *sdlp;
  704 
  705                         if (lladdr != NULL)
  706                                 sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
  707                                     ifp->if_index, ifp->if_type,
  708                                     NULL, 0, lladdr, lladdrlen);
  709                         else
  710                                 sdlp = NULL;
  711                         nd6_dad_input(ifa, NULL, sdlp);
  712                 } else
  713                         log(LOG_ERR,
  714                             "nd6_na_input: duplicate IP6 address %s\n",
  715                             IN6_PRINT(ip6buf, &taddr6));
  716                 ifa_release(ifa, &psref_ia);
  717                 ifa = NULL;
  718                 goto freeit;
  719         }
  720 
  721         /*
  722          * Make sure the source address is from a neighbor's address.
  723          */
  724         sockaddr_in6_init(&ssin6, &saddr6, 0, 0, 0);
  725         if (nd6_is_addr_neighbor(&ssin6, ifp) == 0) {
  726                 nd6log(LOG_INFO, "ND packet from non-neighbor %s on %s\n",
  727                     IN6_PRINT(ip6buf, &saddr6), if_name(ifp));
  728                 goto bad;
  729         }
  730 
  731         /*
  732          * If no neighbor cache entry is found, NA SHOULD silently be
  733          * discarded.
  734          */
  735         ln = nd6_lookup(&taddr6, ifp, true);
  736         if (ln == NULL)
  737                 goto freeit;
  738 
  739         rt_cmd = 0;
  740         if (ln->ln_state <= ND_LLINFO_INCOMPLETE) {
  741                 /*
  742                  * If the link-layer has address, and no lladdr option came,
  743                  * discard the packet.
  744                  */
  745                 if (ifp->if_addrlen && !lladdr)
  746                         goto freeit;
  747 
  748                 /*
  749                  * Record link-layer address, and update the state.
  750                  */
  751                 memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
  752                 ln->la_flags |= LLE_VALID;
  753                 rt_cmd = RTM_ADD;
  754                 if (is_solicited) {
  755                         ln->ln_state = ND_LLINFO_REACHABLE;
  756                         ln->ln_byhint = 0;
  757                         if (!ND_IS_LLINFO_PERMANENT(ln))
  758                                 nd_set_timer(ln, ND_TIMER_REACHABLE);
  759                 } else {
  760                         ln->ln_state = ND_LLINFO_STALE;
  761                         nd_set_timer(ln, ND_TIMER_GC);
  762                 }
  763         } else {
  764                 bool llchange;
  765 
  766                 /*
  767                  * Check if the link-layer address has changed or not.
  768                  */
  769                 if (lladdr == NULL)
  770                         llchange = false;
  771                 else {
  772                         if (ln->la_flags & LLE_VALID) {
  773                                 if (memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen))
  774                                         llchange = true;
  775                                 else
  776                                         llchange = false;
  777                         } else
  778                                 llchange = true;
  779                 }
  780                 if (llchange)
  781                         rt_cmd = RTM_CHANGE;
  782 
  783                 /*
  784                  * This is VERY complex.  Look at it with care.
  785                  *
  786                  * override solicit lladdr llchange     action
  787                  *                                      (L: record lladdr)
  788                  *
  789                  *      0       0       n       --      (2c)
  790                  *      0       0       y       n       (2b) L
  791                  *      0       0       y       y       (1)    REACHABLE->STALE
  792                  *      0       1       n       --      (2c)   *->REACHABLE
  793                  *      0       1       y       n       (2b) L *->REACHABLE
  794                  *      0       1       y       y       (1)    REACHABLE->STALE
  795                  *      1       0       n       --      (2a)
  796                  *      1       0       y       n       (2a) L
  797                  *      1       0       y       y       (2a) L *->STALE
  798                  *      1       1       n       --      (2a)   *->REACHABLE
  799                  *      1       1       y       n       (2a) L *->REACHABLE
  800                  *      1       1       y       y       (2a) L *->REACHABLE
  801                  */
  802                 if (!is_override && lladdr != NULL && llchange) { /* (1) */
  803                         /*
  804                          * If state is REACHABLE, make it STALE.
  805                          * no other updates should be done.
  806                          */
  807                         if (ln->ln_state == ND_LLINFO_REACHABLE) {
  808                                 ln->ln_state = ND_LLINFO_STALE;
  809                                 nd_set_timer(ln, ND_TIMER_GC);
  810                         }
  811                         goto freeit;
  812                 } else if (is_override                             /* (2a) */
  813                     || (!is_override && lladdr != NULL && !llchange) /* (2b) */
  814                     || lladdr == NULL) {                           /* (2c) */
  815                         /*
  816                          * Update link-local address, if any.
  817                          */
  818                         if (lladdr != NULL) {
  819                                 memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
  820                                 ln->la_flags |= LLE_VALID;
  821                         }
  822 
  823                         /*
  824                          * If solicited, make the state REACHABLE.
  825                          * If not solicited and the link-layer address was
  826                          * changed, make it STALE.
  827                          */
  828                         if (is_solicited) {
  829                                 ln->ln_state = ND_LLINFO_REACHABLE;
  830                                 ln->ln_byhint = 0;
  831                                 if (!ND_IS_LLINFO_PERMANENT(ln))
  832                                         nd_set_timer(ln, ND_TIMER_REACHABLE);
  833                         } else {
  834                                 if (lladdr && llchange) {
  835                                         ln->ln_state = ND_LLINFO_STALE;
  836                                         nd_set_timer(ln, ND_TIMER_GC);
  837                                 }
  838                         }
  839                 }
  840                 ln->ln_router = is_router;
  841         }
  842         /*
  843          * XXX: does this matter?
  844          * rt->rt_flags &= ~RTF_REJECT;
  845          */
  846         ln->ln_asked = 0;
  847         nd6_llinfo_release_pkts(ln, ifp);
  848 
  849         if (rt_cmd != 0) {
  850                 struct sockaddr_in6 sin6;
  851 
  852                 sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0);
  853                 rt_clonedmsg(rt_cmd, sin6tosa(&ssin6), sin6tosa(&sin6),
  854                     (char *)&ln->ll_addr, ln->lle_tbl->llt_ifp);
  855         }
  856 
  857  freeit:
  858         if (ln != NULL)
  859                 LLE_WUNLOCK(ln);
  860 
  861         m_put_rcvif_psref(ifp, &psref);
  862         m_freem(m);
  863         return;
  864 
  865  bad:
  866         if (ln != NULL)
  867                 LLE_WUNLOCK(ln);
  868 
  869         ICMP6_STATINC(ICMP6_STAT_BADNA);
  870         m_put_rcvif_psref(ifp, &psref);
  871         m_freem(m);
  872 }
  873 
  874 /*
  875  * Neighbor advertisement output handling.
  876  *
  877  * Based on RFC 2461
  878  *
  879  * the following items are not implemented yet:
  880  * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
  881  * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
  882  */
  883 void
  884 nd6_na_output(
  885         struct ifnet *ifp,
  886         const struct in6_addr *daddr6_0,
  887         const struct in6_addr *taddr6,
  888         u_long flags,
  889         int tlladdr,            /* 1 if include target link-layer address */
  890         const struct sockaddr *sdl0)    /* sockaddr_dl (= proxy NA) or NULL */
  891 {
  892         struct mbuf *m;
  893         struct ip6_hdr *ip6;
  894         struct nd_neighbor_advert *nd_na;
  895         struct ip6_moptions im6o;
  896         struct sockaddr *dst;
  897         union {
  898                 struct sockaddr         dst;
  899                 struct sockaddr_in6     dst6;
  900         } u;
  901         struct in6_addr daddr6;
  902         int icmp6len, maxlen, error;
  903         const void *mac;
  904         struct route ro;
  905 
  906         mac = NULL;
  907         memset(&ro, 0, sizeof(ro));
  908 
  909         daddr6 = *daddr6_0;     /* make a local copy for modification */
  910 
  911         /* estimate the size of message */
  912         maxlen = sizeof(*ip6) + sizeof(*nd_na);
  913         maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
  914         KASSERTMSG(max_linkhdr + maxlen <= MCLBYTES,
  915             "max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
  916             max_linkhdr, maxlen, MCLBYTES);
  917 
  918         MGETHDR(m, M_DONTWAIT, MT_DATA);
  919         if (m && max_linkhdr + maxlen >= MHLEN) {
  920                 MCLGET(m, M_DONTWAIT);
  921                 if ((m->m_flags & M_EXT) == 0) {
  922                         m_free(m);
  923                         m = NULL;
  924                 }
  925         }
  926         if (m == NULL)
  927                 return;
  928         m_reset_rcvif(m);
  929 
  930         if (IN6_IS_ADDR_MULTICAST(&daddr6)) {
  931                 m->m_flags |= M_MCAST;
  932                 im6o.im6o_multicast_if_index = if_get_index(ifp);
  933                 im6o.im6o_multicast_hlim = 255;
  934                 im6o.im6o_multicast_loop = 0;
  935         }
  936 
  937         icmp6len = sizeof(*nd_na);
  938         m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
  939         m->m_data += max_linkhdr;       /* or m_align() equivalent? */
  940 
  941         /* fill neighbor advertisement packet */
  942         ip6 = mtod(m, struct ip6_hdr *);
  943         ip6->ip6_flow = 0;
  944         ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
  945         ip6->ip6_vfc |= IPV6_VERSION;
  946         ip6->ip6_nxt = IPPROTO_ICMPV6;
  947         ip6->ip6_hlim = 255;
  948         if (IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
  949                 /* reply to DAD */
  950                 daddr6.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
  951                 daddr6.s6_addr16[1] = 0;
  952                 daddr6.s6_addr32[1] = 0;
  953                 daddr6.s6_addr32[2] = 0;
  954                 daddr6.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
  955                 if (in6_setscope(&daddr6, ifp, NULL))
  956                         goto bad;
  957 
  958                 flags &= ~ND_NA_FLAG_SOLICITED;
  959         }
  960         ip6->ip6_dst = daddr6;
  961         sockaddr_in6_init(&u.dst6, &daddr6, 0, 0, 0);
  962         dst = &u.dst;
  963         if (rtcache_setdst(&ro, dst) != 0)
  964                 goto bad;
  965 
  966         /*
  967          * Select a source whose scope is the same as that of the dest.
  968          */
  969         error = in6_selectsrc(satosin6(dst), NULL, NULL, &ro, NULL, NULL, NULL,
  970             &ip6->ip6_src);
  971         if (error != 0) {
  972                 char ip6buf[INET6_ADDRSTRLEN];
  973                 nd6log(LOG_DEBUG, "source can't be "
  974                     "determined: dst=%s, error=%d\n",
  975                     IN6_PRINT(ip6buf, &satocsin6(dst)->sin6_addr), error);
  976                 goto bad;
  977         }
  978         nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
  979         nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
  980         nd_na->nd_na_code = 0;
  981         nd_na->nd_na_target = *taddr6;
  982         in6_clearscope(&nd_na->nd_na_target); /* XXX */
  983 
  984         /*
  985          * "tlladdr" indicates NS's condition for adding tlladdr or not.
  986          * see nd6_ns_input() for details.
  987          * Basically, if NS packet is sent to unicast/anycast addr,
  988          * target lladdr option SHOULD NOT be included.
  989          */
  990         if (tlladdr) {
  991                 /*
  992                  * sdl0 != NULL indicates proxy NA.  If we do proxy, use
  993                  * lladdr in sdl0.  If we are not proxying (sending NA for
  994                  * my address) use lladdr configured for the interface.
  995                  */
  996                 if (sdl0 == NULL)
  997                         mac = nd6_ifptomac(ifp);
  998                 else if (sdl0->sa_family == AF_LINK) {
  999                         const struct sockaddr_dl *sdl;
 1000                         sdl = satocsdl(sdl0);
 1001                         if (sdl->sdl_alen == ifp->if_addrlen)
 1002                                 mac = CLLADDR(sdl);
 1003                 }
 1004         }
 1005         if (tlladdr && mac) {
 1006                 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
 1007                 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
 1008 
 1009                 /* roundup to 8 bytes alignment! */
 1010                 optlen = (optlen + 7) & ~7;
 1011 
 1012                 m->m_pkthdr.len += optlen;
 1013                 m->m_len += optlen;
 1014                 icmp6len += optlen;
 1015                 memset((void *)nd_opt, 0, optlen);
 1016                 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
 1017                 nd_opt->nd_opt_len = optlen >> 3;
 1018                 memcpy((void *)(nd_opt + 1), mac, ifp->if_addrlen);
 1019         } else
 1020                 flags &= ~ND_NA_FLAG_OVERRIDE;
 1021 
 1022         ip6->ip6_plen = htons((u_int16_t)icmp6len);
 1023         nd_na->nd_na_flags_reserved = flags;
 1024         nd_na->nd_na_cksum = 0;
 1025         nd_na->nd_na_cksum =
 1026             in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
 1027 
 1028         ip6_output(m, NULL, NULL, 0, &im6o, NULL, NULL);
 1029 
 1030         icmp6_ifstat_inc(ifp, ifs6_out_msg);
 1031         icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
 1032         ICMP6_STATINC(ICMP6_STAT_OUTHIST + ND_NEIGHBOR_ADVERT);
 1033 
 1034         rtcache_free(&ro);
 1035         return;
 1036 
 1037   bad:
 1038         rtcache_free(&ro);
 1039         m_freem(m);
 1040         return;
 1041 }
 1042 
 1043 const void *
 1044 nd6_ifptomac(const struct ifnet *ifp)
 1045 {
 1046         switch (ifp->if_type) {
 1047         case IFT_ARCNET:
 1048         case IFT_ETHER:
 1049         case IFT_IEEE1394:
 1050         case IFT_PROPVIRTUAL:
 1051         case IFT_CARP:
 1052         case IFT_L2VLAN:
 1053         case IFT_IEEE80211:
 1054                 return CLLADDR(ifp->if_sadl);
 1055         default:
 1056                 return NULL;
 1057         }
 1058 }
 1059 
 1060 TAILQ_HEAD(dadq_head, dadq);
 1061 struct dadq {
 1062         TAILQ_ENTRY(dadq) dad_list;
 1063         struct ifaddr *dad_ifa;
 1064         int dad_count;                  /* max NS to send */
 1065         int dad_ns_tcount;              /* # of trials to send NS */
 1066         int dad_ns_ocount;              /* NS sent so far */
 1067         int dad_ns_lcount;              /* looped back NS */
 1068         struct callout dad_timer_ch;
 1069 #define ND_OPT_NONCE_STORE      3       /* dad_count should not exceed this */
 1070         /*
 1071          * The default ip6_dad_count is 1 as specified by RFC 4862 and
 1072          * practically must users won't exceed this.
 1073          * A storage of 3 is defaulted to here, in-case the administrator wants
 1074          * to match the equivalent behaviour in our ARP implementation.
 1075          * This constraint could be removed by sending the on wire nonce as
 1076          * hmac(key, dad_ns_ocount), but that would increase the nonce size
 1077          * sent on the wire.
 1078          */
 1079         uint8_t dad_nonce[ND_OPT_NONCE_STORE][ND_OPT_NONCE_LEN];
 1080 };
 1081 
 1082 static struct dadq_head dadq;
 1083 static kmutex_t nd6_dad_lock;
 1084 
 1085 void
 1086 nd6_nbr_init(void)
 1087 {
 1088 
 1089         TAILQ_INIT(&dadq);
 1090         mutex_init(&nd6_dad_lock, MUTEX_DEFAULT, IPL_NONE);
 1091 }
 1092 
 1093 static struct dadq *
 1094 nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *nonce, bool *found_nonce)
 1095 {
 1096         struct in6_addr *myaddr6, *dadaddr6;
 1097         bool match_ifa;
 1098         struct dadq *dp;
 1099         int i, nonce_max;
 1100 
 1101         KASSERT(mutex_owned(&nd6_dad_lock));
 1102         KASSERT(ifa != NULL);
 1103 
 1104         myaddr6 = IFA_IN6(ifa);
 1105         if (nonce != NULL &&
 1106             nonce->nd_opt_nonce_len != (ND_OPT_NONCE_LEN + 2) / 8)
 1107                 nonce = NULL;
 1108         match_ifa = nonce == NULL || found_nonce == NULL || *found_nonce == false;
 1109         if (found_nonce != NULL)
 1110                 *found_nonce = false;
 1111 
 1112         TAILQ_FOREACH(dp, &dadq, dad_list) {
 1113                 if (match_ifa) {
 1114                         if (dp->dad_ifa != ifa)
 1115                                 continue;
 1116                 } else {
 1117                         dadaddr6 = IFA_IN6(dp->dad_ifa);
 1118                         if (!IN6_ARE_ADDR_EQUAL(myaddr6, dadaddr6))
 1119                                 continue;
 1120                 }
 1121 
 1122                 if (nonce == NULL)
 1123                         break;
 1124 
 1125                 nonce_max = MIN(dp->dad_ns_ocount, ND_OPT_NONCE_STORE);
 1126                 for (i = 0; i < nonce_max; i++) {
 1127                         if (memcmp(nonce->nd_opt_nonce,
 1128                             dp->dad_nonce[i],
 1129                             ND_OPT_NONCE_LEN) == 0)
 1130                                 break;
 1131                 }
 1132                 if (i < nonce_max) {
 1133                         char ip6buf[INET6_ADDRSTRLEN];
 1134 
 1135                         *found_nonce = true;
 1136                         log(LOG_DEBUG,
 1137                             "%s: detected a looped back NS message for %s\n",
 1138                             if_name(ifa->ifa_ifp), IN6_PRINT(ip6buf, myaddr6));
 1139                         dp->dad_ns_lcount++;
 1140                         continue;
 1141                 }
 1142 
 1143                 break;
 1144         }
 1145         return dp;
 1146 }
 1147 
 1148 static bool
 1149 nd6_dad_ownnonce(struct ifaddr *ifa, struct nd_opt_nonce *nonce)
 1150 {
 1151         bool found_nonce = true;
 1152 
 1153         mutex_enter(&nd6_dad_lock);
 1154         nd6_dad_find(ifa, nonce, &found_nonce);
 1155         mutex_exit(&nd6_dad_lock);
 1156 
 1157         return found_nonce;
 1158 }
 1159 
 1160 static void
 1161 nd6_dad_starttimer(struct dadq *dp, int ticks)
 1162 {
 1163 
 1164         callout_reset(&dp->dad_timer_ch, ticks,
 1165             (void (*)(void *))nd6_dad_timer, dp);
 1166 }
 1167 
 1168 static void
 1169 nd6_dad_stoptimer(struct dadq *dp)
 1170 {
 1171 
 1172         KASSERT(mutex_owned(&nd6_dad_lock));
 1173 
 1174         TAILQ_REMOVE(&dadq, dp, dad_list);
 1175         /* Tell the timer that dp is being destroyed. */
 1176         dp->dad_ifa = NULL;
 1177         callout_halt(&dp->dad_timer_ch, &nd6_dad_lock);
 1178 }
 1179 
 1180 static void
 1181 nd6_dad_destroytimer(struct dadq *dp)
 1182 {
 1183 
 1184         KASSERT(dp->dad_ifa == NULL);
 1185         callout_destroy(&dp->dad_timer_ch);
 1186         kmem_intr_free(dp, sizeof(*dp));
 1187 }
 1188 
 1189 /*
 1190  * Start Duplicate Address Detection (DAD) for specified interface address.
 1191  *
 1192  * Note that callout is used when xtick > 0 and not when xtick == 0.
 1193  *
 1194  * xtick: minimum delay ticks for IFF_UP event
 1195  */
 1196 void
 1197 nd6_dad_start(struct ifaddr *ifa, int xtick)
 1198 {
 1199         struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
 1200         struct dadq *dp;
 1201         char ip6buf[INET6_ADDRSTRLEN];
 1202 
 1203         /*
 1204          * If we don't need DAD, don't do it.
 1205          * There are several cases:
 1206          * - DAD is disabled
 1207          * - the interface address is anycast
 1208          */
 1209         if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
 1210                 log(LOG_DEBUG,
 1211                         "nd6_dad_start: called with non-tentative address "
 1212                         "%s(%s)\n",
 1213                         IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
 1214                         if_name(ifa->ifa_ifp));
 1215                 return;
 1216         }
 1217         if (ia->ia6_flags & IN6_IFF_ANYCAST || !ip6_dad_enabled()) {
 1218                 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
 1219                 rt_addrmsg(RTM_NEWADDR, ifa);
 1220                 return;
 1221         }
 1222         if (!(ifa->ifa_ifp->if_flags & IFF_UP))
 1223                 return;
 1224 
 1225         dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP);
 1226 
 1227         mutex_enter(&nd6_dad_lock);
 1228         if (nd6_dad_find(ifa, NULL, NULL) != NULL) {
 1229                 mutex_exit(&nd6_dad_lock);
 1230                 /* DAD already in progress */
 1231                 if (dp != NULL)
 1232                         kmem_intr_free(dp, sizeof(*dp));
 1233                 return;
 1234         }
 1235 
 1236         if (dp == NULL) {
 1237                 mutex_exit(&nd6_dad_lock);
 1238                 log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
 1239                         "%s(%s)\n",
 1240                         IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
 1241                         if_name(ifa->ifa_ifp));
 1242                 return;
 1243         }
 1244 
 1245         /*
 1246          * Send NS packet for DAD, ip6_dad_count times.
 1247          * Note that we must delay the first transmission, if this is the
 1248          * first packet to be sent from the interface after interface
 1249          * (re)initialization.
 1250          */
 1251         callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE);
 1252         dp->dad_ifa = ifa;
 1253         ifaref(ifa);    /* just for safety */
 1254         dp->dad_count = ip6_dad_count;
 1255         dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
 1256         dp->dad_ns_lcount = 0;
 1257         TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
 1258 
 1259         nd6log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
 1260             IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr));
 1261 
 1262         if (xtick == 0) {
 1263                 nd6_dad_ns_output(dp, ifa);
 1264                 nd6_dad_starttimer(dp,
 1265                     (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
 1266         } else
 1267                 nd6_dad_starttimer(dp, xtick);
 1268         mutex_exit(&nd6_dad_lock);
 1269 }
 1270 
 1271 /*
 1272  * terminate DAD unconditionally.  used for address removals.
 1273  */
 1274 void
 1275 nd6_dad_stop(struct ifaddr *ifa)
 1276 {
 1277         struct dadq *dp;
 1278 
 1279         mutex_enter(&nd6_dad_lock);
 1280         dp = nd6_dad_find(ifa, NULL, NULL);
 1281         if (dp == NULL) {
 1282                 mutex_exit(&nd6_dad_lock);
 1283                 /* DAD wasn't started yet */
 1284                 return;
 1285         }
 1286 
 1287         /* Prevent the timer from running anymore. */
 1288         nd6_dad_stoptimer(dp);
 1289 
 1290         mutex_exit(&nd6_dad_lock);
 1291 
 1292         nd6_dad_destroytimer(dp);
 1293         ifafree(ifa);
 1294 }
 1295 
 1296 static void
 1297 nd6_dad_timer(struct dadq *dp)
 1298 {
 1299         struct ifaddr *ifa;
 1300         struct in6_ifaddr *ia;
 1301         char ip6buf[INET6_ADDRSTRLEN];
 1302         bool need_free = false;
 1303 
 1304         KERNEL_LOCK_UNLESS_NET_MPSAFE();
 1305         mutex_enter(&nd6_dad_lock);
 1306 
 1307         ifa = dp->dad_ifa;
 1308         if (ifa == NULL) {
 1309                 /* dp is being destroyed by someone.  Do nothing. */
 1310                 goto done;
 1311         }
 1312 
 1313         ia = (struct in6_ifaddr *)ifa;
 1314         if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
 1315                 log(LOG_ERR, "nd6_dad_timer: called with duplicate address "
 1316                         "%s(%s)\n",
 1317                         IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
 1318                         if_name(ifa->ifa_ifp));
 1319                 goto done;
 1320         }
 1321         if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
 1322                 log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
 1323                         "%s(%s)\n",
 1324                         IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
 1325                         if_name(ifa->ifa_ifp));
 1326                 goto done;
 1327         }
 1328 
 1329         /* timeouted with IFF_{RUNNING,UP} check */
 1330         if (dp->dad_ns_tcount > dad_maxtry) {
 1331                 nd6log(LOG_INFO, "%s: could not run DAD, driver problem?\n",
 1332                         if_name(ifa->ifa_ifp));
 1333 
 1334                 nd6_dad_stoptimer(dp);
 1335                 need_free = true;
 1336                 goto done;
 1337         }
 1338 
 1339         /* Need more checks? */
 1340         if (dp->dad_ns_ocount < dp->dad_count) {
 1341                 /*
 1342                  * We have more NS to go.  Send NS packet for DAD.
 1343                  */
 1344                 nd6_dad_ns_output(dp, ifa);
 1345                 nd6_dad_starttimer(dp,
 1346                     (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
 1347         } else {
 1348                 /*
 1349                  * We are done with DAD.  No NA came, no NS came.
 1350                  * No duplicate address found.
 1351                  */
 1352                 ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
 1353                 rt_addrmsg(RTM_NEWADDR, ifa);
 1354 
 1355                 nd6log(LOG_DEBUG,
 1356                     "%s: DAD complete for %s - no duplicates found\n",
 1357                     if_name(ifa->ifa_ifp),
 1358                     IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr));
 1359 
 1360                 nd6_dad_stoptimer(dp);
 1361                 need_free = true;
 1362         }
 1363 done:
 1364         mutex_exit(&nd6_dad_lock);
 1365 
 1366         if (need_free) {
 1367                 nd6_dad_destroytimer(dp);
 1368                 KASSERT(ifa != NULL);
 1369                 ifafree(ifa);
 1370         }
 1371 
 1372         KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
 1373 }
 1374 
 1375 static void
 1376 nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp,
 1377     const struct sockaddr_dl *from)
 1378 {
 1379         struct in6_ifaddr *ia;
 1380         struct ifnet *ifp;
 1381         char ip6buf[INET6_ADDRSTRLEN], llabuf[LLA_ADDRSTRLEN], *llastr;
 1382 
 1383         KASSERT(mutex_owned(&nd6_dad_lock));
 1384         KASSERT(ifa != NULL);
 1385 
 1386         ifp = ifa->ifa_ifp;
 1387         ia = (struct in6_ifaddr *)ifa;
 1388 
 1389         ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
 1390         ia->ia6_flags |= IN6_IFF_DUPLICATED;
 1391 
 1392         if (__predict_false(from == NULL))
 1393                 llastr = NULL;
 1394         else
 1395                 llastr = lla_snprintf(llabuf, sizeof(llabuf),
 1396                     CLLADDR(from), from->sdl_alen);
 1397 
 1398         log(LOG_ERR, "%s: DAD duplicate address %s from %s\n",
 1399             if_name(ifp), IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), llastr);
 1400 
 1401         /* Inform the routing socket that DAD has completed */
 1402         rt_addrmsg_src(RTM_NEWADDR, ifa, (const struct sockaddr *)from);
 1403 
 1404         /*
 1405          * If the address is a link-local address formed from an interface
 1406          * identifier based on the hardware address which is supposed to be
 1407          * uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP
 1408          * operation on the interface SHOULD be disabled.
 1409          * [rfc2462bis-03 Section 5.4.5]
 1410          */
 1411         if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
 1412                 struct in6_addr in6;
 1413 
 1414                 /*
 1415                  * To avoid over-reaction, we only apply this logic when we are
 1416                  * very sure that hardware addresses are supposed to be unique.
 1417                  */
 1418                 switch (ifp->if_type) {
 1419                 case IFT_ETHER:
 1420                 case IFT_ATM:
 1421                 case IFT_IEEE1394:
 1422                 case IFT_IEEE80211:
 1423                         in6 = ia->ia_addr.sin6_addr;
 1424                         if (in6_get_hw_ifid(ifp, &in6) == 0 &&
 1425                             IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) {
 1426                                 ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
 1427                                 log(LOG_ERR, "%s: possible hardware address "
 1428                                     "duplication detected, disable IPv6\n",
 1429                                     if_name(ifp));
 1430                         }
 1431                         break;
 1432                 }
 1433         }
 1434 }
 1435 
 1436 static void
 1437 nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa)
 1438 {
 1439         struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
 1440         struct ifnet *ifp = ifa->ifa_ifp;
 1441         uint8_t *nonce;
 1442 
 1443         dp->dad_ns_tcount++;
 1444         if ((ifp->if_flags & IFF_UP) == 0) {
 1445 #if 0
 1446                 printf("%s: interface down?\n", if_name(ifp));
 1447 #endif
 1448                 return;
 1449         }
 1450         if ((ifp->if_flags & IFF_RUNNING) == 0) {
 1451 #if 0
 1452                 printf("%s: interface not running?\n", if_name(ifp));
 1453 #endif
 1454                 return;
 1455         }
 1456 
 1457         dp->dad_ns_tcount = 0;
 1458         nonce = dp->dad_nonce[dp->dad_ns_ocount % ND_OPT_NONCE_STORE];
 1459         cprng_fast(nonce, ND_OPT_NONCE_LEN);
 1460         dp->dad_ns_ocount++;
 1461 
 1462         nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, nonce);
 1463 }
 1464 
 1465 static void
 1466 nd6_dad_input(struct ifaddr *ifa, struct nd_opt_nonce *nonce,
 1467     const struct sockaddr_dl *from)
 1468 {
 1469         struct dadq *dp;
 1470         bool found_nonce = false;
 1471 
 1472         KASSERT(ifa != NULL);
 1473 
 1474         mutex_enter(&nd6_dad_lock);
 1475         dp = nd6_dad_find(ifa, nonce, &found_nonce);
 1476         if (!found_nonce) {
 1477                 nd6_dad_duplicated(ifa, dp, from);
 1478                 if (dp != NULL)
 1479                         nd6_dad_stoptimer(dp);
 1480         }
 1481         mutex_exit(&nd6_dad_lock);
 1482         if (dp != NULL) {
 1483                 nd6_dad_destroytimer(dp);
 1484                 ifafree(ifa);
 1485         }
 1486 }

Cache object: a066c3abec8bd1396a3d0b93cd1d1e0f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.