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.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.c,v 1.279 2022/09/01 18:32:17 riastradh Exp $      */
    2 /*      $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun 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.c,v 1.279 2022/09/01 18:32:17 riastradh Exp $");
   35 
   36 #ifdef _KERNEL_OPT
   37 #include "opt_compat_netbsd.h"
   38 #include "opt_net_mpsafe.h"
   39 #endif
   40 
   41 #include "bridge.h"
   42 #include "carp.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/callout.h>
   47 #include <sys/kmem.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/socket.h>
   50 #include <sys/socketvar.h>
   51 #include <sys/sockio.h>
   52 #include <sys/time.h>
   53 #include <sys/kernel.h>
   54 #include <sys/errno.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/syslog.h>
   57 #include <sys/queue.h>
   58 #include <sys/cprng.h>
   59 #include <sys/workqueue.h>
   60 
   61 #include <net/if.h>
   62 #include <net/if_dl.h>
   63 #include <net/if_llatbl.h>
   64 #include <net/if_types.h>
   65 #include <net/nd.h>
   66 #include <net/route.h>
   67 #include <net/if_ether.h>
   68 #include <net/if_arc.h>
   69 
   70 #include <netinet/in.h>
   71 #include <netinet6/in6_var.h>
   72 #include <netinet/ip6.h>
   73 #include <netinet6/ip6_var.h>
   74 #include <netinet6/scope6_var.h>
   75 #include <netinet6/nd6.h>
   76 #include <netinet6/in6_ifattach.h>
   77 #include <netinet/icmp6.h>
   78 #include <netinet6/icmp6_private.h>
   79 
   80 #ifdef COMPAT_90
   81 #include <compat/netinet6/in6_var.h>
   82 #include <compat/netinet6/nd6.h>
   83 #endif
   84 
   85 #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
   86 #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
   87 
   88 /* timer values */
   89 int     nd6_prune       = 1;    /* walk list every 1 seconds */
   90 int     nd6_useloopback = 1;    /* use loopback interface for local traffic */
   91 
   92 /* preventing too many loops in ND option parsing */
   93 int nd6_maxndopt = 10;  /* max # of ND options allowed */
   94 
   95 #ifdef ND6_DEBUG
   96 int nd6_debug = 1;
   97 #else
   98 int nd6_debug = 0;
   99 #endif
  100 
  101 krwlock_t nd6_lock __cacheline_aligned;
  102 
  103 int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
  104 
  105 static void nd6_slowtimo(void *);
  106 static void nd6_free(struct llentry *, int);
  107 static bool nd6_nud_enabled(struct ifnet *);
  108 static unsigned int nd6_llinfo_reachable(struct ifnet *);
  109 static unsigned int nd6_llinfo_retrans(struct ifnet *);
  110 static union l3addr *nd6_llinfo_holdsrc(struct llentry *, union l3addr *);
  111 static void nd6_llinfo_output(struct ifnet *, const union l3addr *,
  112     const union l3addr *, const uint8_t *, const union l3addr *);
  113 static void nd6_llinfo_missed(struct ifnet *, const union l3addr *,
  114     int16_t, struct mbuf *);
  115 static void nd6_timer(void *);
  116 static void nd6_timer_work(struct work *, void *);
  117 static struct nd_opt_hdr *nd6_option(union nd_opts *);
  118 
  119 static callout_t nd6_slowtimo_ch;
  120 static callout_t nd6_timer_ch;
  121 static struct workqueue *nd6_timer_wq;
  122 static struct work      nd6_timer_wk;
  123 
  124 struct nd_domain nd6_nd_domain = {
  125         .nd_family = AF_INET6,
  126         .nd_delay = 5,          /* delay first probe time 5 second */
  127         .nd_mmaxtries = 3,      /* maximum unicast query */
  128         .nd_umaxtries = 3,      /* maximum multicast query */
  129         .nd_retransmultiple = BACKOFF_MULTIPLE,
  130         .nd_maxretrans = MAX_RETRANS_TIMER,
  131         .nd_maxnudhint = 0,     /* max # of subsequent upper layer hints */
  132         .nd_maxqueuelen = 1,    /* max # of packets in unresolved ND entries */
  133         .nd_nud_enabled = nd6_nud_enabled,
  134         .nd_reachable = nd6_llinfo_reachable,
  135         .nd_retrans = nd6_llinfo_retrans,
  136         .nd_holdsrc = nd6_llinfo_holdsrc,
  137         .nd_output = nd6_llinfo_output,
  138         .nd_missed = nd6_llinfo_missed,
  139         .nd_free = nd6_free,
  140 };
  141 
  142 MALLOC_DEFINE(M_IP6NDP, "NDP", "IPv6 Neighbour Discovery");
  143 
  144 void
  145 nd6_init(void)
  146 {
  147         int error;
  148 
  149         nd_attach_domain(&nd6_nd_domain);
  150         nd6_nbr_init();
  151 
  152         rw_init(&nd6_lock);
  153 
  154         callout_init(&nd6_slowtimo_ch, CALLOUT_MPSAFE);
  155         callout_init(&nd6_timer_ch, CALLOUT_MPSAFE);
  156 
  157         error = workqueue_create(&nd6_timer_wq, "nd6_timer",
  158             nd6_timer_work, NULL, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE);
  159         if (error)
  160                 panic("%s: workqueue_create failed (%d)\n", __func__, error);
  161 
  162         /* start timer */
  163         callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
  164             nd6_slowtimo, NULL);
  165         callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
  166 }
  167 
  168 struct nd_kifinfo *
  169 nd6_ifattach(struct ifnet *ifp)
  170 {
  171         struct nd_kifinfo *nd;
  172 
  173         nd = kmem_zalloc(sizeof(*nd), KM_SLEEP);
  174 
  175         nd->chlim = IPV6_DEFHLIM;
  176         nd->basereachable = REACHABLE_TIME;
  177         nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
  178         nd->retrans = RETRANS_TIMER;
  179 
  180         nd->flags = ND6_IFF_PERFORMNUD;
  181 
  182         /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL.
  183          * A bridge interface should not have ND6_IFF_AUTO_LINKLOCAL
  184          * because one of its members should. */
  185         if ((ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) ||
  186             (ifp->if_flags & IFF_LOOPBACK))
  187                 nd->flags |= ND6_IFF_AUTO_LINKLOCAL;
  188 
  189         return nd;
  190 }
  191 
  192 void
  193 nd6_ifdetach(struct ifnet *ifp, struct in6_ifextra *ext)
  194 {
  195 
  196         /* Ensure all IPv6 addresses are purged before calling nd6_purge */
  197         if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
  198         nd6_purge(ifp, ext);
  199         kmem_free(ext->nd_ifinfo, sizeof(struct nd_kifinfo));
  200 }
  201 
  202 void
  203 nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
  204 {
  205 
  206         memset(ndopts, 0, sizeof(*ndopts));
  207         ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
  208         ndopts->nd_opts_last
  209                 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
  210 
  211         if (icmp6len == 0) {
  212                 ndopts->nd_opts_done = 1;
  213                 ndopts->nd_opts_search = NULL;
  214         }
  215 }
  216 
  217 /*
  218  * Take one ND option.
  219  */
  220 static struct nd_opt_hdr *
  221 nd6_option(union nd_opts *ndopts)
  222 {
  223         struct nd_opt_hdr *nd_opt;
  224         int olen;
  225 
  226         KASSERT(ndopts != NULL);
  227         KASSERT(ndopts->nd_opts_last != NULL);
  228 
  229         if (ndopts->nd_opts_search == NULL)
  230                 return NULL;
  231         if (ndopts->nd_opts_done)
  232                 return NULL;
  233 
  234         nd_opt = ndopts->nd_opts_search;
  235 
  236         /* make sure nd_opt_len is inside the buffer */
  237         if ((void *)&nd_opt->nd_opt_len >= (void *)ndopts->nd_opts_last) {
  238                 memset(ndopts, 0, sizeof(*ndopts));
  239                 return NULL;
  240         }
  241 
  242         olen = nd_opt->nd_opt_len << 3;
  243         if (olen == 0) {
  244                 /*
  245                  * Message validation requires that all included
  246                  * options have a length that is greater than zero.
  247                  */
  248                 memset(ndopts, 0, sizeof(*ndopts));
  249                 return NULL;
  250         }
  251 
  252         ndopts->nd_opts_search = (struct nd_opt_hdr *)((char *)nd_opt + olen);
  253         if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
  254                 /* option overruns the end of buffer, invalid */
  255                 memset(ndopts, 0, sizeof(*ndopts));
  256                 return NULL;
  257         } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
  258                 /* reached the end of options chain */
  259                 ndopts->nd_opts_done = 1;
  260                 ndopts->nd_opts_search = NULL;
  261         }
  262         return nd_opt;
  263 }
  264 
  265 /*
  266  * Parse multiple ND options.
  267  * This function is much easier to use, for ND routines that do not need
  268  * multiple options of the same type.
  269  */
  270 int
  271 nd6_options(union nd_opts *ndopts)
  272 {
  273         struct nd_opt_hdr *nd_opt;
  274         int i = 0;
  275 
  276         KASSERT(ndopts != NULL);
  277         KASSERT(ndopts->nd_opts_last != NULL);
  278 
  279         if (ndopts->nd_opts_search == NULL)
  280                 return 0;
  281  
  282         while (1) {
  283                 nd_opt = nd6_option(ndopts);
  284                 if (nd_opt == NULL && ndopts->nd_opts_last == NULL) {
  285                         /*
  286                          * Message validation requires that all included
  287                          * options have a length that is greater than zero.
  288                          */
  289                         ICMP6_STATINC(ICMP6_STAT_ND_BADOPT);
  290                         memset(ndopts, 0, sizeof(*ndopts));
  291                         return -1;
  292                 }
  293 
  294                 if (nd_opt == NULL)
  295                         goto skip1;
  296 
  297                 switch (nd_opt->nd_opt_type) {
  298                 case ND_OPT_SOURCE_LINKADDR:
  299                 case ND_OPT_TARGET_LINKADDR:
  300                 case ND_OPT_MTU:
  301                 case ND_OPT_REDIRECTED_HEADER:
  302                 case ND_OPT_NONCE:
  303                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
  304                                 nd6log(LOG_INFO,
  305                                     "duplicated ND6 option found (type=%d)\n",
  306                                     nd_opt->nd_opt_type);
  307                                 /* XXX bark? */
  308                         } else {
  309                                 ndopts->nd_opt_array[nd_opt->nd_opt_type]
  310                                         = nd_opt;
  311                         }
  312                         break;
  313                 case ND_OPT_PREFIX_INFORMATION:
  314                         if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
  315                                 ndopts->nd_opt_array[nd_opt->nd_opt_type]
  316                                         = nd_opt;
  317                         }
  318                         ndopts->nd_opts_pi_end =
  319                                 (struct nd_opt_prefix_info *)nd_opt;
  320                         break;
  321                 default:
  322                         /*
  323                          * Unknown options must be silently ignored,
  324                          * to accommodate future extension to the protocol.
  325                          */
  326                         nd6log(LOG_DEBUG,
  327                             "nd6_options: unsupported option %d - "
  328                             "option ignored\n", nd_opt->nd_opt_type);
  329                 }
  330 
  331 skip1:
  332                 i++;
  333                 if (i > nd6_maxndopt) {
  334                         ICMP6_STATINC(ICMP6_STAT_ND_TOOMANYOPT);
  335                         nd6log(LOG_INFO, "too many loop in nd opt\n");
  336                         break;
  337                 }
  338 
  339                 if (ndopts->nd_opts_done)
  340                         break;
  341         }
  342 
  343         return 0;
  344 }
  345 
  346 /*
  347  * Gets source address of the first packet in hold queue
  348  * and stores it in @src.
  349  * Returns pointer to @src (if hold queue is not empty) or NULL.
  350  */
  351 static struct in6_addr *
  352 nd6_llinfo_get_holdsrc(struct llentry *ln, struct in6_addr *src)
  353 {
  354         struct ip6_hdr *hip6;
  355 
  356         if (ln == NULL || ln->ln_hold == NULL)
  357                 return NULL;
  358 
  359         /*
  360          * assuming every packet in ln_hold has the same IP header
  361          */
  362         hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
  363         /* XXX pullup? */
  364         if (sizeof(*hip6) < ln->ln_hold->m_len)
  365                 *src = hip6->ip6_src;
  366         else
  367                 src = NULL;
  368 
  369         return src;
  370 }
  371 
  372 static union l3addr *
  373 nd6_llinfo_holdsrc(struct llentry *ln, union l3addr *src)
  374 {
  375 
  376         if (nd6_llinfo_get_holdsrc(ln, &src->addr6) == NULL)
  377                 return NULL;
  378         return src;
  379 }
  380 
  381 static void
  382 nd6_llinfo_output(struct ifnet *ifp, const union l3addr *daddr,
  383     const union l3addr *taddr, __unused const uint8_t *tlladdr,
  384     const union l3addr *hsrc)
  385 {
  386 
  387         nd6_ns_output(ifp,
  388             daddr != NULL ? &daddr->addr6 : NULL,
  389             taddr != NULL ? &taddr->addr6 : NULL,
  390             hsrc != NULL ? &hsrc->addr6 : NULL, NULL);
  391 }
  392 
  393 static bool
  394 nd6_nud_enabled(struct ifnet *ifp)
  395 {
  396         struct nd_kifinfo *ndi = ND_IFINFO(ifp);
  397 
  398         return ndi->flags & ND6_IFF_PERFORMNUD;
  399 }
  400 
  401 static unsigned int
  402 nd6_llinfo_reachable(struct ifnet *ifp)
  403 {
  404         struct nd_kifinfo *ndi = ND_IFINFO(ifp);
  405 
  406         return ndi->reachable;
  407 }
  408 
  409 static unsigned int
  410 nd6_llinfo_retrans(struct ifnet *ifp)
  411 {
  412         struct nd_kifinfo *ndi = ND_IFINFO(ifp);
  413 
  414         return ndi->retrans;
  415 }
  416 
  417 static void
  418 nd6_llinfo_missed(struct ifnet *ifp, const union l3addr *taddr,
  419     int16_t type, struct mbuf *m)
  420 {
  421         struct in6_addr mdaddr6 = zeroin6_addr;
  422         struct sockaddr_in6 dsin6, tsin6;
  423         struct sockaddr *sa;
  424 
  425         if (m != NULL) {
  426                 if (type == ND_LLINFO_PROBE) {
  427                         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
  428 
  429                         /* XXX pullup? */
  430                         if (sizeof(*ip6) < m->m_len)
  431                                 mdaddr6 = ip6->ip6_src;
  432                         m_freem(m);
  433                 } else
  434                         icmp6_error2(m, ICMP6_DST_UNREACH,
  435                             ICMP6_DST_UNREACH_ADDR, 0, ifp, &mdaddr6);
  436         }
  437         if (!IN6_IS_ADDR_UNSPECIFIED(&mdaddr6)) {
  438                 sockaddr_in6_init(&dsin6, &mdaddr6, 0, 0, 0);
  439                 sa = sin6tosa(&dsin6);
  440         } else
  441                 sa = NULL;
  442 
  443         sockaddr_in6_init(&tsin6, &taddr->addr6, 0, 0, 0);
  444         rt_clonedmsg(RTM_MISS, sa, sin6tosa(&tsin6), NULL, ifp);
  445 }
  446 
  447 /*
  448  * ND6 timer routine to expire default route list and prefix list
  449  */
  450 static void
  451 nd6_timer_work(struct work *wk, void *arg)
  452 {
  453         struct in6_ifaddr *ia6, *nia6;
  454         int s, bound;
  455         struct psref psref;
  456 
  457         callout_reset(&nd6_timer_ch, nd6_prune * hz,
  458             nd6_timer, NULL);
  459 
  460         SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE();
  461 
  462         /* expire interface addresses */
  463         bound = curlwp_bind();
  464         s = pserialize_read_enter();
  465         for (ia6 = IN6_ADDRLIST_READER_FIRST(); ia6; ia6 = nia6) {
  466                 nia6 = IN6_ADDRLIST_READER_NEXT(ia6);
  467 
  468                 ia6_acquire(ia6, &psref);
  469                 pserialize_read_exit(s);
  470 
  471                 /* check address lifetime */
  472                 if (IFA6_IS_INVALID(ia6)) {
  473                         struct ifnet *ifp;
  474 
  475                         ifp = ia6->ia_ifa.ifa_ifp;
  476                         IFNET_LOCK(ifp);
  477                         /*
  478                          * Need to take the lock first to prevent if_detach
  479                          * from running in6_purgeaddr concurrently.
  480                          */
  481                         if (!if_is_deactivated(ifp)) {
  482                                 ia6_release(ia6, &psref);
  483                                 in6_purgeaddr(&ia6->ia_ifa);
  484                         } else {
  485                                 /*
  486                                  * ifp is being destroyed, ia6 will be destroyed
  487                                  * by if_detach.
  488                                  */
  489                                 ia6_release(ia6, &psref);
  490                         }
  491                         ia6 = NULL;
  492                         IFNET_UNLOCK(ifp);
  493                 } else if (IFA6_IS_DEPRECATED(ia6)) {
  494                         int oldflags = ia6->ia6_flags;
  495 
  496                         if ((oldflags & IN6_IFF_DEPRECATED) == 0) {
  497                                 ia6->ia6_flags |= IN6_IFF_DEPRECATED;
  498                                 rt_addrmsg(RTM_NEWADDR, (struct ifaddr *)ia6);
  499                         }
  500                 } else {
  501                         /*
  502                          * A new RA might have made a deprecated address
  503                          * preferred.
  504                          */
  505                         if (ia6->ia6_flags & IN6_IFF_DEPRECATED) {
  506                                 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
  507                                 rt_addrmsg(RTM_NEWADDR, (struct ifaddr *)ia6);
  508                         }
  509                 }
  510                 s = pserialize_read_enter();
  511                 ia6_release(ia6, &psref);
  512         }
  513         pserialize_read_exit(s);
  514         curlwp_bindx(bound);
  515 
  516         SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
  517 }
  518 
  519 static void
  520 nd6_timer(void *ignored_arg)
  521 {
  522 
  523         workqueue_enqueue(nd6_timer_wq, &nd6_timer_wk, NULL);
  524 }
  525 
  526 /*
  527  * Nuke neighbor cache/prefix/default router management table, right before
  528  * ifp goes away.
  529  */
  530 void
  531 nd6_purge(struct ifnet *ifp, struct in6_ifextra *ext)
  532 {
  533 
  534         /*
  535          * During detach, the ND info might be already removed, but
  536          * then is explitly passed as argument.
  537          * Otherwise get it from ifp->if_afdata.
  538          */
  539         if (ext == NULL)
  540                 ext = ifp->if_afdata[AF_INET6];
  541         if (ext == NULL)
  542                 return;
  543 
  544         /*
  545          * We may not need to nuke the neighbor cache entries here
  546          * because the neighbor cache is kept in if_afdata[AF_INET6].
  547          * nd6_purge() is invoked by in6_ifdetach() which is called
  548          * from if_detach() where everything gets purged. However
  549          * in6_ifdetach is directly called from vlan(4), so we still
  550          * need to purge entries here.
  551          */
  552         if (ext->lltable != NULL)
  553                 lltable_purge_entries(ext->lltable);
  554 }
  555 
  556 struct llentry *
  557 nd6_lookup(const struct in6_addr *addr6, const struct ifnet *ifp, bool wlock)
  558 {
  559         struct sockaddr_in6 sin6;
  560         struct llentry *ln;
  561 
  562         sockaddr_in6_init(&sin6, addr6, 0, 0, 0);
  563 
  564         IF_AFDATA_RLOCK(ifp);
  565         ln = lla_lookup(LLTABLE6(ifp), wlock ? LLE_EXCLUSIVE : 0,
  566             sin6tosa(&sin6));
  567         IF_AFDATA_RUNLOCK(ifp);
  568 
  569         return ln;
  570 }
  571 
  572 struct llentry *
  573 nd6_create(const struct in6_addr *addr6, const struct ifnet *ifp)
  574 {
  575         struct sockaddr_in6 sin6;
  576         struct llentry *ln;
  577         struct rtentry *rt;
  578 
  579         sockaddr_in6_init(&sin6, addr6, 0, 0, 0);
  580         rt = rtalloc1(sin6tosa(&sin6), 0);
  581 
  582         IF_AFDATA_WLOCK(ifp);
  583         ln = lla_create(LLTABLE6(ifp), LLE_EXCLUSIVE, sin6tosa(&sin6), rt);
  584         IF_AFDATA_WUNLOCK(ifp);
  585 
  586         if (rt != NULL)
  587                 rt_unref(rt);
  588         if (ln != NULL)
  589                 ln->ln_state = ND_LLINFO_NOSTATE;
  590 
  591         return ln;
  592 }
  593 
  594 /*
  595  * Test whether a given IPv6 address is a neighbor or not, ignoring
  596  * the actual neighbor cache.  The neighbor cache is ignored in order
  597  * to not reenter the routing code from within itself.
  598  */
  599 static int
  600 nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
  601 {
  602         struct ifaddr *dstaddr;
  603         int s;
  604 
  605         /*
  606          * A link-local address is always a neighbor.
  607          * XXX: a link does not necessarily specify a single interface.
  608          */
  609         if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
  610                 struct sockaddr_in6 sin6_copy;
  611                 u_int32_t zone;
  612 
  613                 /*
  614                  * We need sin6_copy since sa6_recoverscope() may modify the
  615                  * content (XXX).
  616                  */
  617                 sin6_copy = *addr;
  618                 if (sa6_recoverscope(&sin6_copy))
  619                         return 0; /* XXX: should be impossible */
  620                 if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone))
  621                         return 0;
  622                 if (sin6_copy.sin6_scope_id == zone)
  623                         return 1;
  624                 else
  625                         return 0;
  626         }
  627 
  628         /*
  629          * If the address is assigned on the node of the other side of
  630          * a p2p interface, the address should be a neighbor.
  631          */
  632         s = pserialize_read_enter();
  633         dstaddr = ifa_ifwithdstaddr(sin6tocsa(addr));
  634         if (dstaddr != NULL) {
  635                 if (dstaddr->ifa_ifp == ifp) {
  636                         pserialize_read_exit(s);
  637                         return 1;
  638                 }
  639         }
  640         pserialize_read_exit(s);
  641 
  642         return 0;
  643 }
  644 
  645 /*
  646  * Detect if a given IPv6 address identifies a neighbor on a given link.
  647  * XXX: should take care of the destination of a p2p link?
  648  */
  649 int
  650 nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
  651 {
  652         struct llentry *ln;
  653         struct rtentry *rt;
  654 
  655         /*
  656          * A link-local address is always a neighbor.
  657          * XXX: a link does not necessarily specify a single interface.
  658          */
  659         if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
  660                 struct sockaddr_in6 sin6_copy;
  661                 u_int32_t zone;
  662 
  663                 /*
  664                  * We need sin6_copy since sa6_recoverscope() may modify the
  665                  * content (XXX).
  666                  */
  667                 sin6_copy = *addr;
  668                 if (sa6_recoverscope(&sin6_copy))
  669                         return 0; /* XXX: should be impossible */
  670                 if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone))
  671                         return 0;
  672                 if (sin6_copy.sin6_scope_id == zone)
  673                         return 1;
  674                 else
  675                         return 0;
  676         }
  677 
  678         if (nd6_is_new_addr_neighbor(addr, ifp))
  679                 return 1;
  680 
  681         /*
  682          * Even if the address matches none of our addresses, it might be
  683          * in the neighbor cache or a connected route.
  684          */
  685         ln = nd6_lookup(&addr->sin6_addr, ifp, false);
  686         if (ln != NULL) {
  687                 LLE_RUNLOCK(ln);
  688                 return 1;
  689         }
  690 
  691         rt = rtalloc1(sin6tocsa(addr), 0);
  692         if (rt == NULL)
  693                 return 0;
  694 
  695         if ((rt->rt_flags & RTF_CONNECTED) && (rt->rt_ifp == ifp
  696 #if NBRIDGE > 0
  697             || rt->rt_ifp->if_bridge == ifp->if_bridge
  698 #endif
  699 #if NCARP > 0
  700             || (ifp->if_type == IFT_CARP && rt->rt_ifp == ifp->if_carpdev) ||
  701             (rt->rt_ifp->if_type == IFT_CARP && rt->rt_ifp->if_carpdev == ifp)||
  702             (ifp->if_type == IFT_CARP && rt->rt_ifp->if_type == IFT_CARP &&
  703             rt->rt_ifp->if_carpdev == ifp->if_carpdev)
  704 #endif
  705             )) {
  706                 rt_unref(rt);
  707                 return 1;
  708         }
  709         rt_unref(rt);
  710 
  711         return 0;
  712 }
  713 
  714 /*
  715  * Free an nd6 llinfo entry.
  716  * Since the function would cause significant changes in the kernel, DO NOT
  717  * make it global, unless you have a strong reason for the change, and are sure
  718  * that the change is safe.
  719  */
  720 static void
  721 nd6_free(struct llentry *ln, int gc)
  722 {
  723         struct ifnet *ifp;
  724 
  725         KASSERT(ln != NULL);
  726         LLE_WLOCK_ASSERT(ln);
  727 
  728         /*
  729          * If the reason for the deletion is just garbage collection,
  730          * and the neighbor is an active router, do not delete it.
  731          * Instead, reset the GC timer using the router's lifetime.
  732          * XXX: the check for ln_state should be redundant,
  733          *      but we intentionally keep it just in case.
  734          */
  735         if (!ip6_forwarding && ln->ln_router &&
  736             ln->ln_state == ND_LLINFO_STALE && gc)
  737         {
  738                 nd_set_timer(ln, ND_TIMER_EXPIRE);
  739                 LLE_WUNLOCK(ln);
  740                 return;
  741         }
  742 
  743         ifp = ln->lle_tbl->llt_ifp;
  744 
  745         if (ln->la_flags & LLE_VALID || gc) {
  746                 struct sockaddr_in6 sin6;
  747                 const char *lladdr;
  748 
  749                 sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0);
  750                 lladdr = ln->la_flags & LLE_VALID ?
  751                     (const char *)&ln->ll_addr : NULL;
  752                 rt_clonedmsg(RTM_DELETE, NULL, sin6tosa(&sin6), lladdr, ifp);
  753         }
  754 
  755         /*
  756          * Save to unlock. We still hold an extra reference and will not
  757          * free(9) in llentry_free() if someone else holds one as well.
  758          */
  759         LLE_WUNLOCK(ln);
  760         IF_AFDATA_LOCK(ifp);
  761         LLE_WLOCK(ln);
  762 
  763         lltable_free_entry(LLTABLE6(ifp), ln);
  764 
  765         IF_AFDATA_UNLOCK(ifp);
  766 }
  767 
  768 /*
  769  * Upper-layer reachability hint for Neighbor Unreachability Detection.
  770  *
  771  * XXX cost-effective methods?
  772  */
  773 void
  774 nd6_nud_hint(struct rtentry *rt)
  775 {
  776         struct llentry *ln;
  777         struct ifnet *ifp;
  778 
  779         if (rt == NULL)
  780                 return;
  781 
  782         ifp = rt->rt_ifp;
  783         ln = nd6_lookup(&(satocsin6(rt_getkey(rt)))->sin6_addr, ifp, true);
  784         nd_nud_hint(ln);
  785 }
  786 
  787 struct gc_args {
  788         int gc_entries;
  789         const struct in6_addr *skip_in6;
  790 };
  791 
  792 static int
  793 nd6_purge_entry(struct lltable *llt, struct llentry *ln, void *farg)
  794 {
  795         struct gc_args *args = farg;
  796         int *n = &args->gc_entries;
  797         const struct in6_addr *skip_in6 = args->skip_in6;
  798 
  799         if (*n <= 0)
  800                 return 0;
  801 
  802         if (ND_IS_LLINFO_PERMANENT(ln))
  803                 return 0;
  804 
  805         if (IN6_ARE_ADDR_EQUAL(&ln->r_l3addr.addr6, skip_in6))
  806                 return 0;
  807 
  808         LLE_WLOCK(ln);
  809         if (ln->ln_state > ND_LLINFO_INCOMPLETE)
  810                 ln->ln_state = ND_LLINFO_STALE;
  811         else
  812                 ln->ln_state = ND_LLINFO_PURGE;
  813         nd_set_timer(ln, ND_TIMER_IMMEDIATE);
  814         LLE_WUNLOCK(ln);
  815 
  816         (*n)--;
  817         return 0;
  818 }
  819 
  820 static void
  821 nd6_gc_neighbors(struct lltable *llt, const struct in6_addr *in6)
  822 {
  823 
  824         if (ip6_neighborgcthresh >= 0 &&
  825             lltable_get_entry_count(llt) >= ip6_neighborgcthresh) {
  826                 struct gc_args gc_args = {10, in6};
  827                 /*
  828                  * XXX entries that are "less recently used" should be
  829                  * freed first.
  830                  */
  831                 lltable_foreach_lle(llt, nd6_purge_entry, &gc_args);
  832         }
  833 }
  834 
  835 void
  836 nd6_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
  837 {
  838         struct sockaddr *gate = rt->rt_gateway;
  839         struct ifnet *ifp = rt->rt_ifp;
  840         uint8_t namelen = strlen(ifp->if_xname), addrlen = ifp->if_addrlen;
  841         struct ifaddr *ifa;
  842 
  843         RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  844 
  845         if (req == RTM_LLINFO_UPD) {
  846                 int rc;
  847                 struct in6_addr *in6;
  848                 struct in6_addr in6_all;
  849                 int anycast;
  850 
  851                 if ((ifa = info->rti_ifa) == NULL)
  852                         return;
  853 
  854                 in6 = &ifatoia6(ifa)->ia_addr.sin6_addr;
  855                 anycast = ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST;
  856 
  857                 in6_all = in6addr_linklocal_allnodes;
  858                 if ((rc = in6_setscope(&in6_all, ifa->ifa_ifp, NULL)) != 0) {
  859                         log(LOG_ERR, "%s: failed to set scope %s "
  860                             "(errno=%d)\n", __func__, if_name(ifp), rc);
  861                         return;
  862                 }
  863 
  864                 /* XXX don't set Override for proxy addresses */
  865                 nd6_na_output(ifa->ifa_ifp, &in6_all, in6,
  866                     (anycast ? 0 : ND_NA_FLAG_OVERRIDE)
  867 #if 0
  868                     | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0)
  869 #endif
  870                     , 1, NULL);
  871                 return;
  872         }
  873 
  874         if ((rt->rt_flags & RTF_GATEWAY) != 0) {
  875                 if (req != RTM_ADD)
  876                         return;
  877                 /*
  878                  * linklayers with particular MTU limitation.
  879                  */
  880                 switch(ifp->if_type) {
  881 #if NARCNET > 0
  882                 case IFT_ARCNET:
  883                         if (rt->rt_rmx.rmx_mtu > ARC_PHDS_MAXMTU) /* RFC2497 */
  884                                 rt->rt_rmx.rmx_mtu = ARC_PHDS_MAXMTU;
  885                         break;
  886 #endif
  887                 }
  888                 return;
  889         }
  890 
  891         if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
  892                 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  893                 /*
  894                  * This is probably an interface direct route for a link
  895                  * which does not need neighbor caches (e.g. fe80::%lo0/64).
  896                  * We do not need special treatment below for such a route.
  897                  * Moreover, the RTF_LLINFO flag which would be set below
  898                  * would annoy the ndp(8) command.
  899                  */
  900                 return;
  901         }
  902 
  903         switch (req) {
  904         case RTM_ADD: {
  905                 struct psref psref;
  906 
  907                 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  908                 /*
  909                  * There is no backward compatibility :)
  910                  *
  911                  * if ((rt->rt_flags & RTF_HOST) == 0 &&
  912                  *     SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
  913                  *         rt->rt_flags |= RTF_CLONING;
  914                  */
  915                 /* XXX should move to route.c? */
  916                 if (rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL)) {
  917                         union {
  918                                 struct sockaddr sa;
  919                                 struct sockaddr_dl sdl;
  920                                 struct sockaddr_storage ss;
  921                         } u;
  922                         /*
  923                          * Case 1: This route should come from a route to
  924                          * interface (RTF_CLONING case) or the route should be
  925                          * treated as on-link but is currently not
  926                          * (RTF_LLINFO && ln == NULL case).
  927                          */
  928                         if (sockaddr_dl_init(&u.sdl, sizeof(u.ss),
  929                             ifp->if_index, ifp->if_type,
  930                             NULL, namelen, NULL, addrlen) == NULL) {
  931                                 printf("%s.%d: sockaddr_dl_init(, %zu, ) "
  932                                     "failed on %s\n", __func__, __LINE__,
  933                                     sizeof(u.ss), if_name(ifp));
  934                         }
  935                         rt_setgate(rt, &u.sa);
  936                         gate = rt->rt_gateway;
  937                         RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  938                         if (gate == NULL) {
  939                                 log(LOG_ERR,
  940                                     "%s: rt_setgate failed on %s\n", __func__,
  941                                     if_name(ifp));
  942                                 break;
  943                         }
  944 
  945                         RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  946                         if ((rt->rt_flags & RTF_CONNECTED) != 0)
  947                                 break;
  948                 }
  949                 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  950                 /*
  951                  * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
  952                  * We don't do that here since llinfo is not ready yet.
  953                  *
  954                  * There are also couple of other things to be discussed:
  955                  * - unsolicited NA code needs improvement beforehand
  956                  * - RFC2461 says we MAY send multicast unsolicited NA
  957                  *   (7.2.6 paragraph 4), however, it also says that we
  958                  *   SHOULD provide a mechanism to prevent multicast NA storm.
  959                  *   we don't have anything like it right now.
  960                  *   note that the mechanism needs a mutual agreement
  961                  *   between proxies, which means that we need to implement
  962                  *   a new protocol, or a new kludge.
  963                  * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
  964                  *   we need to check ip6forwarding before sending it.
  965                  *   (or should we allow proxy ND configuration only for
  966                  *   routers?  there's no mention about proxy ND from hosts)
  967                  */
  968 #if 0
  969                 /* XXX it does not work */
  970                 if (rt->rt_flags & RTF_ANNOUNCE)
  971                         nd6_na_output(ifp,
  972                               &satocsin6(rt_getkey(rt))->sin6_addr,
  973                               &satocsin6(rt_getkey(rt))->sin6_addr,
  974                               ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
  975                               1, NULL);
  976 #endif
  977 
  978                 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
  979                         RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  980                         /*
  981                          * Address resolution isn't necessary for a point to
  982                          * point link, so we can skip this test for a p2p link.
  983                          */
  984                         if (gate->sa_family != AF_LINK ||
  985                             gate->sa_len <
  986                             sockaddr_dl_measure(namelen, addrlen)) {
  987                                 log(LOG_DEBUG,
  988                                     "nd6_rtrequest: bad gateway value: %s\n",
  989                                     if_name(ifp));
  990                                 break;
  991                         }
  992                         satosdl(gate)->sdl_type = ifp->if_type;
  993                         satosdl(gate)->sdl_index = ifp->if_index;
  994                         RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  995                 }
  996                 RT_DPRINTF("rt_getkey(rt) = %p\n", rt_getkey(rt));
  997 
  998                 /*
  999                  * When called from rt_ifa_addlocal, we cannot depend on that
 1000                  * the address (rt_getkey(rt)) exits in the address list of the
 1001                  * interface. So check RTF_LOCAL instead.
 1002                  */
 1003                 if (rt->rt_flags & RTF_LOCAL) {
 1004                         if (nd6_useloopback)
 1005                                 rt->rt_ifp = lo0ifp;    /* XXX */
 1006                         break;
 1007                 }
 1008 
 1009                 /*
 1010                  * check if rt_getkey(rt) is an address assigned
 1011                  * to the interface.
 1012                  */
 1013                 ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp,
 1014                     &satocsin6(rt_getkey(rt))->sin6_addr, &psref);
 1015                 if (ifa != NULL) {
 1016                         if (nd6_useloopback) {
 1017                                 rt->rt_ifp = lo0ifp;    /* XXX */
 1018                                 /*
 1019                                  * Make sure rt_ifa be equal to the ifaddr
 1020                                  * corresponding to the address.
 1021                                  * We need this because when we refer
 1022                                  * rt_ifa->ia6_flags in ip6_input, we assume
 1023                                  * that the rt_ifa points to the address instead
 1024                                  * of the loopback address.
 1025                                  */
 1026                                 if (!ISSET(info->rti_flags, RTF_DONTCHANGEIFA)
 1027                                     && ifa != rt->rt_ifa)
 1028                                         rt_replace_ifa(rt, ifa);
 1029                         }
 1030                 } else if (rt->rt_flags & RTF_ANNOUNCE) {
 1031                         /* join solicited node multicast for proxy ND */
 1032                         if (ifp->if_flags & IFF_MULTICAST) {
 1033                                 struct in6_addr llsol;
 1034                                 int error;
 1035 
 1036                                 llsol = satocsin6(rt_getkey(rt))->sin6_addr;
 1037                                 llsol.s6_addr32[0] = htonl(0xff020000);
 1038                                 llsol.s6_addr32[1] = 0;
 1039                                 llsol.s6_addr32[2] = htonl(1);
 1040                                 llsol.s6_addr8[12] = 0xff;
 1041                                 if (in6_setscope(&llsol, ifp, NULL))
 1042                                         goto out;
 1043                                 if (!in6_addmulti(&llsol, ifp, &error, 0)) {
 1044                                         char ip6buf[INET6_ADDRSTRLEN];
 1045                                         nd6log(LOG_ERR, "%s: failed to join "
 1046                                             "%s (errno=%d)\n", if_name(ifp),
 1047                                             IN6_PRINT(ip6buf, &llsol), error);
 1048                                 }
 1049                         }
 1050                 }
 1051         out:
 1052                 ifa_release(ifa, &psref);
 1053                 /*
 1054                  * If we have too many cache entries, initiate immediate
 1055                  * purging for some entries.
 1056                  */
 1057                 if (rt->rt_ifp != NULL)
 1058                         nd6_gc_neighbors(LLTABLE6(rt->rt_ifp), NULL);
 1059                 break;
 1060             }
 1061 
 1062         case RTM_DELETE:
 1063                 /* leave from solicited node multicast for proxy ND */
 1064                 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
 1065                     (ifp->if_flags & IFF_MULTICAST) != 0) {
 1066                         struct in6_addr llsol;
 1067 
 1068                         llsol = satocsin6(rt_getkey(rt))->sin6_addr;
 1069                         llsol.s6_addr32[0] = htonl(0xff020000);
 1070                         llsol.s6_addr32[1] = 0;
 1071                         llsol.s6_addr32[2] = htonl(1);
 1072                         llsol.s6_addr8[12] = 0xff;
 1073                         if (in6_setscope(&llsol, ifp, NULL) == 0)
 1074                                 in6_lookup_and_delete_multi(&llsol, ifp);
 1075                 }
 1076                 break;
 1077         }
 1078 }
 1079 
 1080 static void
 1081 nd6_setifflags(struct ifnet *ifp, uint32_t flags)
 1082 {
 1083         struct nd_kifinfo *ndi = ND_IFINFO(ifp);
 1084         struct ifaddr *ifa;
 1085         struct in6_ifaddr *ia;
 1086         int s;
 1087 
 1088         if (ndi->flags & ND6_IFF_IFDISABLED && !(flags & ND6_IFF_IFDISABLED)) {
 1089                 /*
 1090                  * If the interface is marked as ND6_IFF_IFDISABLED and
 1091                  * has a link-local address with IN6_IFF_DUPLICATED,
 1092                  * do not clear ND6_IFF_IFDISABLED.
 1093                  * See RFC 4862, section 5.4.5.
 1094                  */
 1095                 bool duplicated_linklocal = false;
 1096 
 1097                 s = pserialize_read_enter();
 1098                 IFADDR_READER_FOREACH(ifa, ifp) {
 1099                         if (ifa->ifa_addr->sa_family != AF_INET6)
 1100                                 continue;
 1101                         ia = (struct in6_ifaddr *)ifa;
 1102                         if ((ia->ia6_flags & IN6_IFF_DUPLICATED) &&
 1103                             IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
 1104                         {
 1105                                 duplicated_linklocal = true;
 1106                                 break;
 1107                         }
 1108                 }
 1109                 pserialize_read_exit(s);
 1110 
 1111                 if (duplicated_linklocal) {
 1112                         flags |= ND6_IFF_IFDISABLED;
 1113                         log(LOG_ERR, "%s: Cannot enable an interface"
 1114                             " with a link-local address marked"
 1115                             " duplicate.\n", if_name(ifp));
 1116                 } else {
 1117                         ndi->flags &= ~ND6_IFF_IFDISABLED;
 1118                         if (ifp->if_flags & IFF_UP)
 1119                                 in6_if_up(ifp);
 1120                 }
 1121         } else if (!(ndi->flags & ND6_IFF_IFDISABLED) &&
 1122             (flags & ND6_IFF_IFDISABLED))
 1123         {
 1124                 struct psref psref;
 1125                 int bound = curlwp_bind();
 1126 
 1127                 /* Mark all IPv6 addresses as tentative. */
 1128 
 1129                 ndi->flags |= ND6_IFF_IFDISABLED;
 1130                 s = pserialize_read_enter();
 1131                 IFADDR_READER_FOREACH(ifa, ifp) {
 1132                         if (ifa->ifa_addr->sa_family != AF_INET6)
 1133                                 continue;
 1134                         ifa_acquire(ifa, &psref);
 1135                         pserialize_read_exit(s);
 1136 
 1137                         nd6_dad_stop(ifa);
 1138 
 1139                         ia = (struct in6_ifaddr *)ifa;
 1140                         ia->ia6_flags |= IN6_IFF_TENTATIVE;
 1141 
 1142                         s = pserialize_read_enter();
 1143                         ifa_release(ifa, &psref);
 1144                 }
 1145                 pserialize_read_exit(s);
 1146                 curlwp_bindx(bound);
 1147         }
 1148 
 1149         if (flags & ND6_IFF_AUTO_LINKLOCAL) {
 1150                 if (!(ndi->flags & ND6_IFF_AUTO_LINKLOCAL)) {
 1151                         /* auto_linklocal 0->1 transition */
 1152 
 1153                         ndi->flags |= ND6_IFF_AUTO_LINKLOCAL;
 1154                         in6_ifattach(ifp, NULL);
 1155                 } else if (!(flags & ND6_IFF_IFDISABLED) &&
 1156                     ifp->if_flags & IFF_UP)
 1157                 {
 1158                         /*
 1159                          * When the IF already has
 1160                          * ND6_IFF_AUTO_LINKLOCAL, no link-local
 1161                          * address is assigned, and IFF_UP, try to
 1162                          * assign one.
 1163                          */
 1164                         bool haslinklocal = 0;
 1165 
 1166                         s = pserialize_read_enter();
 1167                         IFADDR_READER_FOREACH(ifa, ifp) {
 1168                                 if (ifa->ifa_addr->sa_family !=AF_INET6)
 1169                                         continue;
 1170                                 ia = (struct in6_ifaddr *)ifa;
 1171                                 if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia))){
 1172                                         haslinklocal = true;
 1173                                         break;
 1174                                 }
 1175                         }
 1176                         pserialize_read_exit(s);
 1177                         if (!haslinklocal)
 1178                                 in6_ifattach(ifp, NULL);
 1179                 }
 1180         }
 1181 
 1182         ndi->flags = flags;
 1183 }
 1184 
 1185 int
 1186 nd6_ioctl(u_long cmd, void *data, struct ifnet *ifp)
 1187 {
 1188 #ifdef OSIOCGIFINFO_IN6_90
 1189         struct in6_ndireq90 *ondi = (struct in6_ndireq90 *)data;
 1190         struct in6_ndifreq90 *ndif = (struct in6_ndifreq90 *)data;
 1191 #define OND     ondi->ndi
 1192 #endif
 1193         struct in6_ndireq *ndi = (struct in6_ndireq *)data;
 1194         struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
 1195         struct nd_kifinfo *ifndi = ND_IFINFO(ifp);
 1196         int error = 0;
 1197 #define ND     ndi->ndi
 1198 
 1199         switch (cmd) {
 1200 #ifdef OSIOCSRTRFLUSH_IN6
 1201         case OSIOCGDRLST_IN6:           /* FALLTHROUGH */
 1202         case OSIOCGPRLST_IN6:           /* FALLTHROUGH */
 1203         case OSIOCSNDFLUSH_IN6:         /* FALLTHROUGH */
 1204         case OSIOCSPFXFLUSH_IN6:        /* FALLTHROUGH */
 1205         case OSIOCSRTRFLUSH_IN6:        /* FALLTHROUGH */
 1206                 break;
 1207         case OSIOCGDEFIFACE_IN6:
 1208                 ndif->ifindex = 0;
 1209                 break;
 1210         case OSIOCSDEFIFACE_IN6:
 1211                 error = ENOTSUP;
 1212                 break;
 1213 #endif
 1214 #ifdef OSIOCGIFINFO_IN6
 1215         case OSIOCGIFINFO_IN6:          /* FALLTHROUGH */
 1216 #endif
 1217 #ifdef OSIOCGIFINFO_IN6_90
 1218         case OSIOCGIFINFO_IN6_90:
 1219                 memset(&OND, 0, sizeof(OND));
 1220                 OND.initialized = 1;
 1221                 OND.chlim = ifndi->chlim;
 1222                 OND.basereachable = ifndi->basereachable;
 1223                 OND.retrans = ifndi->retrans;
 1224                 OND.flags = ifndi->flags;
 1225                 break;
 1226         case OSIOCSIFINFO_IN6_90:
 1227                 /* Allow userland to set Neighour Unreachability Detection
 1228                  * timers. */
 1229                 if (OND.chlim != 0)
 1230                         ifndi->chlim = OND.chlim;
 1231                 if (OND.basereachable != 0 &&
 1232                     OND.basereachable != ifndi->basereachable)
 1233                 {
 1234                         ifndi->basereachable = OND.basereachable;
 1235                         ifndi->reachable = ND_COMPUTE_RTIME(OND.basereachable);
 1236                 }
 1237                 if (OND.retrans != 0)
 1238                         ifndi->retrans = OND.retrans;
 1239                 /* Retain the old behaviour .... */
 1240                 /* FALLTHROUGH */
 1241         case OSIOCSIFINFO_FLAGS_90:
 1242                 nd6_setifflags(ifp, OND.flags);
 1243                 break;
 1244 #undef OND
 1245 #endif
 1246         case SIOCGIFINFO_IN6:
 1247                 ND.chlim = ifndi->chlim;
 1248                 ND.basereachable = ifndi->basereachable;
 1249                 ND.retrans = ifndi->retrans;
 1250                 ND.flags = ifndi->flags;
 1251                 break;
 1252         case SIOCSIFINFO_IN6:
 1253                 /* Allow userland to set Neighour Unreachability Detection
 1254                  * timers. */
 1255                 if (ND.chlim != 0)
 1256                         ifndi->chlim = ND.chlim;
 1257                 if (ND.basereachable != 0 &&
 1258                     ND.basereachable != ifndi->basereachable)
 1259                 {
 1260                         ifndi->basereachable = ND.basereachable;
 1261                         ifndi->reachable = ND_COMPUTE_RTIME(ND.basereachable);
 1262                 }
 1263                 if (ND.retrans != 0)
 1264                         ifndi->retrans = ND.retrans;
 1265                 break;
 1266         case SIOCSIFINFO_FLAGS:
 1267                 nd6_setifflags(ifp, ND.flags);
 1268                 break;
 1269 #undef ND
 1270         case SIOCGNBRINFO_IN6:
 1271         {
 1272                 struct llentry *ln;
 1273                 struct in6_addr nb_addr = nbi->addr; /* make local for safety */
 1274 
 1275                 if ((error = in6_setscope(&nb_addr, ifp, NULL)) != 0)
 1276                         return error;
 1277 
 1278                 ln = nd6_lookup(&nb_addr, ifp, false);
 1279                 if (ln == NULL) {
 1280                         error = EINVAL;
 1281                         break;
 1282                 }
 1283                 nbi->state = ln->ln_state;
 1284                 nbi->asked = ln->ln_asked;
 1285                 nbi->isrouter = ln->ln_router;
 1286                 nbi->expire = ln->ln_expire ?
 1287                     time_mono_to_wall(ln->ln_expire) : 0;
 1288                 LLE_RUNLOCK(ln);
 1289 
 1290                 break;
 1291         }
 1292         }
 1293         return error;
 1294 }
 1295 
 1296 void
 1297 nd6_llinfo_release_pkts(struct llentry *ln, struct ifnet *ifp)
 1298 {
 1299         struct mbuf *m_hold, *m_hold_next;
 1300         struct sockaddr_in6 sin6;
 1301 
 1302         LLE_WLOCK_ASSERT(ln);
 1303 
 1304         sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0);
 1305 
 1306         m_hold = ln->la_hold, ln->la_hold = NULL, ln->la_numheld = 0;
 1307 
 1308         LLE_ADDREF(ln);
 1309         LLE_WUNLOCK(ln);
 1310         for (; m_hold != NULL; m_hold = m_hold_next) {
 1311                 m_hold_next = m_hold->m_nextpkt;
 1312                 m_hold->m_nextpkt = NULL;
 1313 
 1314                 /*
 1315                  * we assume ifp is not a p2p here, so
 1316                  * just set the 2nd argument as the 
 1317                  * 1st one.
 1318                  */
 1319                 ip6_if_output(ifp, ifp, m_hold, &sin6, NULL);
 1320         }
 1321         LLE_WLOCK(ln);
 1322         LLE_REMREF(ln);
 1323 }
 1324 
 1325 /*
 1326  * Create neighbor cache entry and cache link-layer address,
 1327  * on reception of inbound ND6 packets.  (RS/RA/NS/redirect)
 1328  */
 1329 void
 1330 nd6_cache_lladdr(
 1331     struct ifnet *ifp,
 1332     struct in6_addr *from,
 1333     char *lladdr,
 1334     int lladdrlen,
 1335     int type,   /* ICMP6 type */
 1336     int code    /* type dependent information */
 1337 )
 1338 {
 1339         struct llentry *ln = NULL;
 1340         int is_newentry;
 1341         int do_update;
 1342         int olladdr;
 1343         int llchange;
 1344         int newstate = 0;
 1345 
 1346         KASSERT(ifp != NULL);
 1347         KASSERT(from != NULL);
 1348 
 1349         /* nothing must be updated for unspecified address */
 1350         if (IN6_IS_ADDR_UNSPECIFIED(from))
 1351                 return;
 1352 
 1353         /*
 1354          * Validation about ifp->if_addrlen and lladdrlen must be done in
 1355          * the caller.
 1356          *
 1357          * XXX If the link does not have link-layer adderss, what should
 1358          * we do? (ifp->if_addrlen == 0)
 1359          * Spec says nothing in sections for RA, RS and NA.  There's small
 1360          * description on it in NS section (RFC 2461 7.2.3).
 1361          */
 1362 
 1363         ln = nd6_lookup(from, ifp, true);
 1364         if (ln == NULL) {
 1365 #if 0
 1366                 /* nothing must be done if there's no lladdr */
 1367                 if (!lladdr || !lladdrlen)
 1368                         return NULL;
 1369 #endif
 1370 
 1371                 ln = nd6_create(from, ifp);
 1372                 is_newentry = 1;
 1373         } else {
 1374                 /* do nothing if static ndp is set */
 1375                 if (ln->la_flags & LLE_STATIC) {
 1376                         LLE_WUNLOCK(ln);
 1377                         return;
 1378                 }
 1379                 is_newentry = 0;
 1380         }
 1381 
 1382         if (ln == NULL)
 1383                 return;
 1384 
 1385         olladdr = (ln->la_flags & LLE_VALID) ? 1 : 0;
 1386         if (olladdr && lladdr) {
 1387                 llchange = memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen);
 1388         } else
 1389                 llchange = 0;
 1390 
 1391         /*
 1392          * newentry olladdr  lladdr  llchange   (*=record)
 1393          *      0       n       n       --      (1)
 1394          *      0       y       n       --      (2)
 1395          *      0       n       y       --      (3) * STALE
 1396          *      0       y       y       n       (4) *
 1397          *      0       y       y       y       (5) * STALE
 1398          *      1       --      n       --      (6)   NOSTATE(= PASSIVE)
 1399          *      1       --      y       --      (7) * STALE
 1400          */
 1401 
 1402         if (lladdr) {           /* (3-5) and (7) */
 1403                 /*
 1404                  * Record source link-layer address
 1405                  * XXX is it dependent to ifp->if_type?
 1406                  */
 1407                 memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
 1408                 ln->la_flags |= LLE_VALID;
 1409         }
 1410 
 1411         if (!is_newentry) {
 1412                 if ((!olladdr && lladdr) ||             /* (3) */
 1413                     (olladdr && lladdr && llchange)) {  /* (5) */
 1414                         do_update = 1;
 1415                         newstate = ND_LLINFO_STALE;
 1416                 } else                                  /* (1-2,4) */
 1417                         do_update = 0;
 1418         } else {
 1419                 do_update = 1;
 1420                 if (lladdr == NULL)                     /* (6) */
 1421                         newstate = ND_LLINFO_NOSTATE;
 1422                 else                                    /* (7) */
 1423                         newstate = ND_LLINFO_STALE;
 1424         }
 1425 
 1426         if (do_update) {
 1427                 /*
 1428                  * Update the state of the neighbor cache.
 1429                  */
 1430                 ln->ln_state = newstate;
 1431 
 1432                 if (ln->ln_state == ND_LLINFO_STALE) {
 1433                         /*
 1434                          * XXX: since nd6_output() below will cause
 1435                          * state tansition to DELAY and reset the timer,
 1436                          * we must set the timer now, although it is actually
 1437                          * meaningless.
 1438                          */
 1439                         nd_set_timer(ln, ND_TIMER_GC);
 1440 
 1441                         nd6_llinfo_release_pkts(ln, ifp);
 1442                 } else if (ln->ln_state == ND_LLINFO_INCOMPLETE) {
 1443                         /* probe right away */
 1444                         nd_set_timer(ln, ND_TIMER_IMMEDIATE);
 1445                 }
 1446         }
 1447 
 1448         /*
 1449          * ICMP6 type dependent behavior.
 1450          *
 1451          * NS: clear IsRouter if new entry
 1452          * RS: clear IsRouter
 1453          * RA: set IsRouter if there's lladdr
 1454          * redir: clear IsRouter if new entry
 1455          *
 1456          * RA case, (1):
 1457          * The spec says that we must set IsRouter in the following cases:
 1458          * - If lladdr exist, set IsRouter.  This means (1-5).
 1459          * - If it is old entry (!newentry), set IsRouter.  This means (7).
 1460          * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
 1461          * A question arises for (1) case.  (1) case has no lladdr in the
 1462          * neighbor cache, this is similar to (6).
 1463          * This case is rare but we figured that we MUST NOT set IsRouter.
 1464          *
 1465          * newentry olladdr  lladdr  llchange       NS  RS  RA  redir
 1466          *                                                      D R
 1467          *      0       n       n       --      (1)     c   ?     s
 1468          *      0       y       n       --      (2)     c   s     s
 1469          *      0       n       y       --      (3)     c   s     s
 1470          *      0       y       y       n       (4)     c   s     s
 1471          *      0       y       y       y       (5)     c   s     s
 1472          *      1       --      n       --      (6) c   c       c s
 1473          *      1       --      y       --      (7) c   c   s   c s
 1474          *
 1475          *                                      (c=clear s=set)
 1476          */
 1477         switch (type & 0xff) {
 1478         case ND_NEIGHBOR_SOLICIT:
 1479                 /*
 1480                  * New entry must have is_router flag cleared.
 1481                  */
 1482                 if (is_newentry)        /* (6-7) */
 1483                         ln->ln_router = 0;
 1484                 break;
 1485         case ND_REDIRECT:
 1486                 /*
 1487                  * If the icmp is a redirect to a better router, always set the
 1488                  * is_router flag.  Otherwise, if the entry is newly created,
 1489                  * clear the flag.  [RFC 2461, sec 8.3]
 1490                  */
 1491                 if (code == ND_REDIRECT_ROUTER)
 1492                         ln->ln_router = 1;
 1493                 else if (is_newentry) /* (6-7) */
 1494                         ln->ln_router = 0;
 1495                 break;
 1496         case ND_ROUTER_SOLICIT:
 1497                 /*
 1498                  * is_router flag must always be cleared.
 1499                  */
 1500                 ln->ln_router = 0;
 1501                 break;
 1502         case ND_ROUTER_ADVERT:
 1503                 /*
 1504                  * Mark an entry with lladdr as a router.
 1505                  */
 1506                 if ((!is_newentry && (olladdr || lladdr)) ||    /* (2-5) */
 1507                     (is_newentry && lladdr)) {                  /* (7) */
 1508                         ln->ln_router = 1;
 1509                 }
 1510                 break;
 1511         }
 1512 
 1513         if (do_update && lladdr != NULL) {
 1514                 struct sockaddr_in6 sin6;
 1515 
 1516                 sockaddr_in6_init(&sin6, from, 0, 0, 0);
 1517                 rt_clonedmsg(is_newentry ? RTM_ADD : RTM_CHANGE,
 1518                     NULL, sin6tosa(&sin6), lladdr, ifp);
 1519         }
 1520 
 1521         if (ln != NULL)
 1522                 LLE_WUNLOCK(ln);
 1523 
 1524         /*
 1525          * If we have too many cache entries, initiate immediate
 1526          * purging for some entries.
 1527          */
 1528         if (is_newentry)
 1529                 nd6_gc_neighbors(LLTABLE6(ifp), &ln->r_l3addr.addr6);
 1530 }
 1531 
 1532 static void
 1533 nd6_slowtimo(void *ignored_arg)
 1534 {
 1535         struct nd_kifinfo *ndi;
 1536         struct ifnet *ifp;
 1537         struct psref psref;
 1538         int s;
 1539 
 1540         SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE();
 1541         callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
 1542             nd6_slowtimo, NULL);
 1543 
 1544         s = pserialize_read_enter();
 1545         IFNET_READER_FOREACH(ifp) {
 1546                 ndi = ND_IFINFO(ifp);
 1547                 if (ndi->basereachable && /* already initialized */
 1548                     (ndi->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
 1549                         if_acquire(ifp, &psref);
 1550                         pserialize_read_exit(s);
 1551                         /*
 1552                          * Since reachable time rarely changes by router
 1553                          * advertisements, we SHOULD insure that a new random
 1554                          * value gets recomputed at least once every few hours.
 1555                          * (RFC 2461, 6.3.4)
 1556                          */
 1557                         ndi->recalctm = nd6_recalc_reachtm_interval;
 1558                         ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
 1559                         s = pserialize_read_enter();
 1560                         if_release(ifp, &psref);
 1561                 }
 1562         }
 1563         pserialize_read_exit(s);
 1564 
 1565         SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
 1566 }
 1567 
 1568 /*
 1569  * Return 0 if a neighbor cache is found. Return EWOULDBLOCK if a cache is not
 1570  * found and trying to resolve a neighbor; in this case the mbuf is queued in
 1571  * the list. Otherwise return errno after freeing the mbuf.
 1572  */
 1573 int
 1574 nd6_resolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m,
 1575     const struct sockaddr *_dst, uint8_t *lldst, size_t dstsize)
 1576 {
 1577         struct llentry *ln = NULL;
 1578         bool created = false;
 1579         const struct sockaddr_in6 *dst = satocsin6(_dst);
 1580         int error;
 1581         struct nd_kifinfo *ndi = ND_IFINFO(ifp);
 1582 
 1583         /* discard the packet if IPv6 operation is disabled on the interface */
 1584         if (ndi->flags & ND6_IFF_IFDISABLED) {
 1585                 m_freem(m);
 1586                 return ENETDOWN; /* better error? */
 1587         }
 1588 
 1589         /*
 1590          * Address resolution or Neighbor Unreachability Detection
 1591          * for the next hop.
 1592          * At this point, the destination of the packet must be a unicast
 1593          * or an anycast address(i.e. not a multicast).
 1594          */
 1595 
 1596         /* Look up the neighbor cache for the nexthop */
 1597         ln = nd6_lookup(&dst->sin6_addr, ifp, false);
 1598 
 1599         if (ln != NULL && (ln->la_flags & LLE_VALID) != 0 &&
 1600             ln->ln_state == ND_LLINFO_REACHABLE) {
 1601                 /* Fast path */
 1602                 memcpy(lldst, &ln->ll_addr, MIN(dstsize, ifp->if_addrlen));
 1603                 LLE_RUNLOCK(ln);
 1604                 return 0;
 1605         }
 1606         if (ln != NULL)
 1607                 LLE_RUNLOCK(ln);
 1608 
 1609         /* Slow path */
 1610         ln = nd6_lookup(&dst->sin6_addr, ifp, true);
 1611         if (ln == NULL && nd6_is_addr_neighbor(dst, ifp))  {
 1612                 /*
 1613                  * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
 1614                  * the condition below is not very efficient.  But we believe
 1615                  * it is tolerable, because this should be a rare case.
 1616                  */
 1617                 ln = nd6_create(&dst->sin6_addr, ifp);
 1618                 if (ln == NULL) {
 1619                         char ip6buf[INET6_ADDRSTRLEN];
 1620                         log(LOG_DEBUG,
 1621                             "%s: can't allocate llinfo for %s "
 1622                             "(ln=%p, rt=%p)\n", __func__,
 1623                             IN6_PRINT(ip6buf, &dst->sin6_addr), ln, rt);
 1624                         m_freem(m);
 1625                         return ENOBUFS;
 1626                 }
 1627                 created = true;
 1628         }
 1629 
 1630         if (ln == NULL) {
 1631                 m_freem(m);
 1632                 return ENETDOWN; /* better error? */
 1633         }
 1634 
 1635         error = nd_resolve(ln, rt, m, lldst, dstsize);
 1636 
 1637         if (created)
 1638                 nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr);
 1639 
 1640         return error;
 1641 }
 1642 
 1643 int
 1644 nd6_need_cache(struct ifnet *ifp)
 1645 {
 1646         /*
 1647          * XXX: we currently do not make neighbor cache on any interface
 1648          * other than ARCnet, Ethernet, and GIF.
 1649          *
 1650          * RFC2893 says:
 1651          * - unidirectional tunnels needs no ND
 1652          */
 1653         switch (ifp->if_type) {
 1654         case IFT_ARCNET:
 1655         case IFT_ETHER:
 1656         case IFT_IEEE1394:
 1657         case IFT_CARP:
 1658         case IFT_GIF:           /* XXX need more cases? */
 1659         case IFT_PPP:
 1660         case IFT_TUNNEL:
 1661                 return 1;
 1662         default:
 1663                 return 0;
 1664         }
 1665 }
 1666 
 1667 int
 1668 nd6_sysctl(
 1669     int name,
 1670     void *oldp, /* syscall arg, need copyout */
 1671     size_t *oldlenp,
 1672     void *newp, /* syscall arg, need copyin */
 1673     size_t newlen
 1674 )
 1675 {
 1676 
 1677         if (newp)
 1678                 return EPERM;
 1679 
 1680         switch (name) {
 1681 #ifdef COMPAT_90
 1682         case OICMPV6CTL_ND6_DRLIST: /* FALLTHROUGH */
 1683         case OICMPV6CTL_ND6_PRLIST:
 1684                 *oldlenp = 0;
 1685                 return 0;
 1686 #endif
 1687         case ICMPV6CTL_ND6_MAXQLEN:
 1688                 return 0;
 1689         default:
 1690                 return ENOPROTOOPT;
 1691         }
 1692 }

Cache object: 09f1b2b25cd64ed9c8e3d2cfa233bf02


[ 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.