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/in6.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: in6.c,v 1.91.4.1 2008/10/03 10:43:48 jdc Exp $ */
    2 /*      $KAME: in6.c,v 1.198 2001/07/18 09:12:38 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 /*
   34  * Copyright (c) 1982, 1986, 1991, 1993
   35  *      The Regents of the University of California.  All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. Neither the name of the University nor the names of its contributors
   46  *    may be used to endorse or promote products derived from this software
   47  *    without specific prior written permission.
   48  *
   49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59  * SUCH DAMAGE.
   60  *
   61  *      @(#)in.c        8.2 (Berkeley) 11/15/93
   62  */
   63 
   64 #include <sys/cdefs.h>
   65 __KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.91.4.1 2008/10/03 10:43:48 jdc Exp $");
   66 
   67 #include "opt_inet.h"
   68 #include "opt_pfil_hooks.h"
   69 
   70 #include <sys/param.h>
   71 #include <sys/ioctl.h>
   72 #include <sys/errno.h>
   73 #include <sys/malloc.h>
   74 #include <sys/socket.h>
   75 #include <sys/socketvar.h>
   76 #include <sys/sockio.h>
   77 #include <sys/systm.h>
   78 #include <sys/proc.h>
   79 #include <sys/time.h>
   80 #include <sys/kernel.h>
   81 #include <sys/syslog.h>
   82 
   83 #include <net/if.h>
   84 #include <net/if_types.h>
   85 #include <net/route.h>
   86 #include <net/if_dl.h>
   87 
   88 #include <netinet/in.h>
   89 #include <netinet/in_var.h>
   90 #include <net/if_ether.h>
   91 
   92 #include <netinet/ip6.h>
   93 #include <netinet6/ip6_var.h>
   94 #include <netinet6/nd6.h>
   95 #include <netinet6/mld6_var.h>
   96 #include <netinet6/ip6_mroute.h>
   97 #include <netinet6/in6_ifattach.h>
   98 
   99 #include <net/net_osdep.h>
  100 
  101 #ifdef PFIL_HOOKS
  102 #include <net/pfil.h>
  103 #endif
  104 
  105 MALLOC_DEFINE(M_IP6OPT, "ip6_options", "IPv6 options");
  106 
  107 /* enable backward compatibility code for obsoleted ioctls */
  108 #define COMPAT_IN6IFIOCTL
  109 
  110 /*
  111  * Definitions of some constant IP6 addresses.
  112  */
  113 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
  114 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
  115 const struct in6_addr in6addr_nodelocal_allnodes =
  116         IN6ADDR_NODELOCAL_ALLNODES_INIT;
  117 const struct in6_addr in6addr_linklocal_allnodes =
  118         IN6ADDR_LINKLOCAL_ALLNODES_INIT;
  119 const struct in6_addr in6addr_linklocal_allrouters =
  120         IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
  121 
  122 const struct in6_addr in6mask0 = IN6MASK0;
  123 const struct in6_addr in6mask32 = IN6MASK32;
  124 const struct in6_addr in6mask64 = IN6MASK64;
  125 const struct in6_addr in6mask96 = IN6MASK96;
  126 const struct in6_addr in6mask128 = IN6MASK128;
  127 
  128 const struct sockaddr_in6 sa6_any = {sizeof(sa6_any), AF_INET6,
  129                                      0, 0, IN6ADDR_ANY_INIT, 0};
  130 
  131 static int in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
  132         struct ifnet *, struct proc *));
  133 static int in6_ifinit __P((struct ifnet *, struct in6_ifaddr *,
  134         struct sockaddr_in6 *, int));
  135 static void in6_unlink_ifa __P((struct in6_ifaddr *, struct ifnet *));
  136 
  137 /*
  138  * This structure is used to keep track of in6_multi chains which belong to
  139  * deleted interface addresses.
  140  */
  141 static LIST_HEAD(, multi6_kludge) in6_mk; /* XXX BSS initialization */
  142 
  143 struct multi6_kludge {
  144         LIST_ENTRY(multi6_kludge) mk_entry;
  145         struct ifnet *mk_ifp;
  146         struct in6_multihead mk_head;
  147 };
  148 
  149 /*
  150  * Subroutine for in6_ifaddloop() and in6_ifremloop().
  151  * This routine does actual work.
  152  */
  153 static void
  154 in6_ifloop_request(int cmd, struct ifaddr *ifa)
  155 {
  156         struct sockaddr_in6 lo_sa;
  157         struct sockaddr_in6 all1_sa;
  158         struct rtentry *nrt = NULL;
  159         int e;
  160 
  161         bzero(&lo_sa, sizeof(lo_sa));
  162         bzero(&all1_sa, sizeof(all1_sa));
  163         lo_sa.sin6_family = all1_sa.sin6_family = AF_INET6;
  164         lo_sa.sin6_len = all1_sa.sin6_len = sizeof(struct sockaddr_in6);
  165         lo_sa.sin6_addr = in6addr_loopback;
  166         all1_sa.sin6_addr = in6mask128;
  167 
  168         /*
  169          * We specify the address itself as the gateway, and set the
  170          * RTF_LLINFO flag, so that the corresponding host route would have
  171          * the flag, and thus applications that assume traditional behavior
  172          * would be happy.  Note that we assume the caller of the function
  173          * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
  174          * which changes the outgoing interface to the loopback interface.
  175          */
  176         e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
  177             (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
  178         if (e != 0) {
  179                 log(LOG_ERR, "in6_ifloop_request: "
  180                     "%s operation failed for %s (errno=%d)\n",
  181                     cmd == RTM_ADD ? "ADD" : "DELETE",
  182                     ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
  183                     e);
  184         }
  185 
  186         /*
  187          * Make sure rt_ifa be equal to IFA, the second argument of the
  188          * function.
  189          * We need this because when we refer to rt_ifa->ia6_flags in
  190          * ip6_input, we assume that the rt_ifa points to the address instead
  191          * of the loopback address.
  192          */
  193         if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
  194                 IFAFREE(nrt->rt_ifa);
  195                 IFAREF(ifa);
  196                 nrt->rt_ifa = ifa;
  197         }
  198 
  199         /*
  200          * Report the addition/removal of the address to the routing socket.
  201          * XXX: since we called rtinit for a p2p interface with a destination,
  202          *      we end up reporting twice in such a case.  Should we rather
  203          *      omit the second report?
  204          */
  205         if (nrt) {
  206                 rt_newaddrmsg(cmd, ifa, e, nrt);
  207                 if (cmd == RTM_DELETE) {
  208                         if (nrt->rt_refcnt <= 0) {
  209                                 /* XXX: we should free the entry ourselves. */
  210                                 nrt->rt_refcnt++;
  211                                 rtfree(nrt);
  212                         }
  213                 } else {
  214                         /* the cmd must be RTM_ADD here */
  215                         nrt->rt_refcnt--;
  216                 }
  217         }
  218 }
  219 
  220 /*
  221  * Add ownaddr as loopback rtentry.  We previously add the route only if
  222  * necessary (ex. on a p2p link).  However, since we now manage addresses
  223  * separately from prefixes, we should always add the route.  We can't
  224  * rely on the cloning mechanism from the corresponding interface route
  225  * any more.
  226  */
  227 static void
  228 in6_ifaddloop(struct ifaddr *ifa)
  229 {
  230         struct rtentry *rt;
  231 
  232         /* If there is no loopback entry, allocate one. */
  233         rt = rtalloc1(ifa->ifa_addr, 0);
  234         if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
  235             (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
  236                 in6_ifloop_request(RTM_ADD, ifa);
  237         if (rt)
  238                 rt->rt_refcnt--;
  239 }
  240 
  241 /*
  242  * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
  243  * if it exists.
  244  */
  245 static void
  246 in6_ifremloop(struct ifaddr *ifa)
  247 {
  248         struct in6_ifaddr *ia;
  249         struct rtentry *rt;
  250         int ia_count = 0;
  251 
  252         /*
  253          * Some of BSD variants do not remove cloned routes
  254          * from an interface direct route, when removing the direct route
  255          * (see comments in net/net_osdep.h).  Even for variants that do remove
  256          * cloned routes, they could fail to remove the cloned routes when
  257          * we handle multple addresses that share a common prefix.
  258          * So, we should remove the route corresponding to the deleted address.
  259          */
  260 
  261         /*
  262          * Delete the entry only if exact one ifa exists.  More than one ifa
  263          * can exist if we assign a same single address to multiple
  264          * (probably p2p) interfaces.
  265          * XXX: we should avoid such a configuration in IPv6...
  266          */
  267         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
  268                 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ia->ia_addr.sin6_addr)) {
  269                         ia_count++;
  270                         if (ia_count > 1)
  271                                 break;
  272                 }
  273         }
  274 
  275         if (ia_count == 1) {
  276                 /*
  277                  * Before deleting, check if a corresponding loopbacked host
  278                  * route surely exists.  With this check, we can avoid to
  279                  * delete an interface direct route whose destination is same
  280                  * as the address being removed.  This can happen when removing
  281                  * a subnet-router anycast address on an interface attahced
  282                  * to a shared medium.
  283                  */
  284                 rt = rtalloc1(ifa->ifa_addr, 0);
  285                 if (rt != NULL && (rt->rt_flags & RTF_HOST) != 0 &&
  286                     (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
  287                         rt->rt_refcnt--;
  288                         in6_ifloop_request(RTM_DELETE, ifa);
  289                 }
  290         }
  291 }
  292 
  293 int
  294 in6_mask2len(mask, lim0)
  295         struct in6_addr *mask;
  296         u_char *lim0;
  297 {
  298         int x = 0, y;
  299         u_char *lim = lim0, *p;
  300 
  301         /* ignore the scope_id part */
  302         if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask))
  303                 lim = (u_char *)mask + sizeof(*mask);
  304         for (p = (u_char *)mask; p < lim; x++, p++) {
  305                 if (*p != 0xff)
  306                         break;
  307         }
  308         y = 0;
  309         if (p < lim) {
  310                 for (y = 0; y < 8; y++) {
  311                         if ((*p & (0x80 >> y)) == 0)
  312                                 break;
  313                 }
  314         }
  315 
  316         /*
  317          * when the limit pointer is given, do a stricter check on the
  318          * remaining bits.
  319          */
  320         if (p < lim) {
  321                 if (y != 0 && (*p & (0x00ff >> y)) != 0)
  322                         return (-1);
  323                 for (p = p + 1; p < lim; p++)
  324                         if (*p != 0)
  325                                 return (-1);
  326         }
  327 
  328         return x * 8 + y;
  329 }
  330 
  331 #define ifa2ia6(ifa)    ((struct in6_ifaddr *)(ifa))
  332 #define ia62ifa(ia6)    (&((ia6)->ia_ifa))
  333 
  334 int
  335 in6_control(so, cmd, data, ifp, p)
  336         struct  socket *so;
  337         u_long cmd;
  338         caddr_t data;
  339         struct ifnet *ifp;
  340         struct proc *p;
  341 {
  342         struct  in6_ifreq *ifr = (struct in6_ifreq *)data;
  343         struct  in6_ifaddr *ia = NULL;
  344         struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
  345         struct sockaddr_in6 *sa6;
  346         int privileged;
  347 
  348         privileged = 0;
  349         if (p && !suser(p->p_ucred, &p->p_acflag))
  350                 privileged++;
  351 
  352         switch (cmd) {
  353         case SIOCGETSGCNT_IN6:
  354         case SIOCGETMIFCNT_IN6:
  355                 return (mrt6_ioctl(cmd, data));
  356         }
  357 
  358         if (ifp == NULL)
  359                 return (EOPNOTSUPP);
  360 
  361         switch (cmd) {
  362         case SIOCSNDFLUSH_IN6:
  363         case SIOCSPFXFLUSH_IN6:
  364         case SIOCSRTRFLUSH_IN6:
  365         case SIOCSDEFIFACE_IN6:
  366         case SIOCSIFINFO_FLAGS:
  367                 if (!privileged)
  368                         return (EPERM);
  369                 /* FALLTHROUGH */
  370         case OSIOCGIFINFO_IN6:
  371         case SIOCGIFINFO_IN6:
  372         case SIOCGDRLST_IN6:
  373         case SIOCGPRLST_IN6:
  374         case SIOCGNBRINFO_IN6:
  375         case SIOCGDEFIFACE_IN6:
  376                 return (nd6_ioctl(cmd, data, ifp));
  377         }
  378 
  379         switch (cmd) {
  380         case SIOCSIFPREFIX_IN6:
  381         case SIOCDIFPREFIX_IN6:
  382         case SIOCAIFPREFIX_IN6:
  383         case SIOCCIFPREFIX_IN6:
  384         case SIOCSGIFPREFIX_IN6:
  385         case SIOCGIFPREFIX_IN6:
  386                 log(LOG_NOTICE,
  387                     "prefix ioctls are now invalidated. "
  388                     "please use ifconfig.\n");
  389                 return (EOPNOTSUPP);
  390         }
  391 
  392         switch (cmd) {
  393         case SIOCALIFADDR:
  394         case SIOCDLIFADDR:
  395                 if (!privileged)
  396                         return (EPERM);
  397                 /* FALLTHROUGH */
  398         case SIOCGLIFADDR:
  399                 return in6_lifaddr_ioctl(so, cmd, data, ifp, p);
  400         }
  401 
  402         /*
  403          * Find address for this interface, if it exists.
  404          *
  405          * In netinet code, we have checked ifra_addr in SIOCSIF*ADDR operation
  406          * only, and used the first interface address as the target of other
  407          * operations (without checking ifra_addr).  This was because netinet
  408          * code/API assumed at most 1 interface address per interface.
  409          * Since IPv6 allows a node to assign multiple addresses
  410          * on a single interface, we almost always look and check the
  411          * presence of ifra_addr, and reject invalid ones here.
  412          * It also decreases duplicated code among SIOC*_IN6 operations.
  413          */
  414         switch (cmd) {
  415         case SIOCAIFADDR_IN6:
  416         case SIOCSIFPHYADDR_IN6:
  417                 sa6 = &ifra->ifra_addr;
  418                 break;
  419         case SIOCSIFADDR_IN6:
  420         case SIOCGIFADDR_IN6:
  421         case SIOCSIFDSTADDR_IN6:
  422         case SIOCSIFNETMASK_IN6:
  423         case SIOCGIFDSTADDR_IN6:
  424         case SIOCGIFNETMASK_IN6:
  425         case SIOCDIFADDR_IN6:
  426         case SIOCGIFPSRCADDR_IN6:
  427         case SIOCGIFPDSTADDR_IN6:
  428         case SIOCGIFAFLAG_IN6:
  429         case SIOCSNDFLUSH_IN6:
  430         case SIOCSPFXFLUSH_IN6:
  431         case SIOCSRTRFLUSH_IN6:
  432         case SIOCGIFALIFETIME_IN6:
  433         case SIOCSIFALIFETIME_IN6:
  434         case SIOCGIFSTAT_IN6:
  435         case SIOCGIFSTAT_ICMP6:
  436                 sa6 = &ifr->ifr_addr;
  437                 break;
  438         default:
  439                 sa6 = NULL;
  440                 break;
  441         }
  442         if (sa6 && sa6->sin6_family == AF_INET6) {
  443                 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
  444                         if (sa6->sin6_addr.s6_addr16[1] == 0) {
  445                                 /* link ID is not embedded by the user */
  446                                 sa6->sin6_addr.s6_addr16[1] =
  447                                     htons(ifp->if_index);
  448                         } else if (sa6->sin6_addr.s6_addr16[1] !=
  449                             htons(ifp->if_index)) {
  450                                 return (EINVAL);        /* link ID contradicts */
  451                         }
  452                         if (sa6->sin6_scope_id) {
  453                                 if (sa6->sin6_scope_id !=
  454                                     (u_int32_t)ifp->if_index)
  455                                         return (EINVAL);
  456                                 sa6->sin6_scope_id = 0; /* XXX: good way? */
  457                         }
  458                 }
  459                 ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
  460         } else
  461                 ia = NULL;
  462 
  463         switch (cmd) {
  464         case SIOCSIFADDR_IN6:
  465         case SIOCSIFDSTADDR_IN6:
  466         case SIOCSIFNETMASK_IN6:
  467                 /*
  468                  * Since IPv6 allows a node to assign multiple addresses
  469                  * on a single interface, SIOCSIFxxx ioctls are deprecated.
  470                  */
  471                 return (EINVAL);
  472 
  473         case SIOCDIFADDR_IN6:
  474                 /*
  475                  * for IPv4, we look for existing in_ifaddr here to allow
  476                  * "ifconfig if0 delete" to remove the first IPv4 address on
  477                  * the interface.  For IPv6, as the spec allows multiple
  478                  * interface address from the day one, we consider "remove the
  479                  * first one" semantics to be not preferable.
  480                  */
  481                 if (ia == NULL)
  482                         return (EADDRNOTAVAIL);
  483                 /* FALLTHROUGH */
  484         case SIOCAIFADDR_IN6:
  485                 /*
  486                  * We always require users to specify a valid IPv6 address for
  487                  * the corresponding operation.
  488                  */
  489                 if (ifra->ifra_addr.sin6_family != AF_INET6 ||
  490                     ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6))
  491                         return (EAFNOSUPPORT);
  492                 if (!privileged)
  493                         return (EPERM);
  494 
  495                 break;
  496 
  497         case SIOCGIFADDR_IN6:
  498                 /* This interface is basically deprecated. use SIOCGIFCONF. */
  499                 /* FALLTHROUGH */
  500         case SIOCGIFAFLAG_IN6:
  501         case SIOCGIFNETMASK_IN6:
  502         case SIOCGIFDSTADDR_IN6:
  503         case SIOCGIFALIFETIME_IN6:
  504                 /* must think again about its semantics */
  505                 if (ia == NULL)
  506                         return (EADDRNOTAVAIL);
  507                 break;
  508         case SIOCSIFALIFETIME_IN6:
  509             {
  510                 struct in6_addrlifetime *lt;
  511 
  512                 if (!privileged)
  513                         return (EPERM);
  514                 if (ia == NULL)
  515                         return (EADDRNOTAVAIL);
  516                 /* sanity for overflow - beware unsigned */
  517                 lt = &ifr->ifr_ifru.ifru_lifetime;
  518                 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
  519                  && lt->ia6t_vltime + time.tv_sec < time.tv_sec) {
  520                         return EINVAL;
  521                 }
  522                 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
  523                  && lt->ia6t_pltime + time.tv_sec < time.tv_sec) {
  524                         return EINVAL;
  525                 }
  526                 break;
  527             }
  528         }
  529 
  530         switch (cmd) {
  531 
  532         case SIOCGIFADDR_IN6:
  533                 ifr->ifr_addr = ia->ia_addr;
  534                 break;
  535 
  536         case SIOCGIFDSTADDR_IN6:
  537                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
  538                         return (EINVAL);
  539                 /*
  540                  * XXX: should we check if ifa_dstaddr is NULL and return
  541                  * an error?
  542                  */
  543                 ifr->ifr_dstaddr = ia->ia_dstaddr;
  544                 break;
  545 
  546         case SIOCGIFNETMASK_IN6:
  547                 ifr->ifr_addr = ia->ia_prefixmask;
  548                 break;
  549 
  550         case SIOCGIFAFLAG_IN6:
  551                 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
  552                 break;
  553 
  554         case SIOCGIFSTAT_IN6:
  555                 if (ifp == NULL)
  556                         return EINVAL;
  557                 bzero(&ifr->ifr_ifru.ifru_stat,
  558                     sizeof(ifr->ifr_ifru.ifru_stat));
  559                 ifr->ifr_ifru.ifru_stat =
  560                     *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->in6_ifstat;
  561                 break;
  562 
  563         case SIOCGIFSTAT_ICMP6:
  564                 if (ifp == NULL)
  565                         return EINVAL;
  566                 bzero(&ifr->ifr_ifru.ifru_stat,
  567                     sizeof(ifr->ifr_ifru.ifru_icmp6stat));
  568                 ifr->ifr_ifru.ifru_icmp6stat =
  569                     *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->icmp6_ifstat;
  570                 break;
  571 
  572         case SIOCGIFALIFETIME_IN6:
  573                 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
  574                 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
  575                         time_t maxexpire;
  576                         struct in6_addrlifetime *retlt =
  577                             &ifr->ifr_ifru.ifru_lifetime;
  578 
  579                         /*
  580                          * XXX: adjust expiration time assuming time_t is
  581                          * signed.
  582                          */
  583                         maxexpire = (-1) &
  584                             ~(1 << ((sizeof(maxexpire) * 8) - 1));
  585                         if (ia->ia6_lifetime.ia6t_vltime <
  586                             maxexpire - ia->ia6_updatetime) {
  587                                 retlt->ia6t_expire = ia->ia6_updatetime +
  588                                     ia->ia6_lifetime.ia6t_vltime;
  589                         } else
  590                                 retlt->ia6t_expire = maxexpire;
  591                 }
  592                 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
  593                         time_t maxexpire;
  594                         struct in6_addrlifetime *retlt =
  595                             &ifr->ifr_ifru.ifru_lifetime;
  596 
  597                         /*
  598                          * XXX: adjust expiration time assuming time_t is
  599                          * signed.
  600                          */
  601                         maxexpire = (-1) &
  602                             ~(1 << ((sizeof(maxexpire) * 8) - 1));
  603                         if (ia->ia6_lifetime.ia6t_pltime <
  604                             maxexpire - ia->ia6_updatetime) {
  605                                 retlt->ia6t_preferred = ia->ia6_updatetime +
  606                                     ia->ia6_lifetime.ia6t_pltime;
  607                         } else
  608                                 retlt->ia6t_preferred = maxexpire;
  609                 }
  610                 break;
  611 
  612         case SIOCSIFALIFETIME_IN6:
  613                 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
  614                 /* for sanity */
  615                 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
  616                         ia->ia6_lifetime.ia6t_expire =
  617                                 time.tv_sec + ia->ia6_lifetime.ia6t_vltime;
  618                 } else
  619                         ia->ia6_lifetime.ia6t_expire = 0;
  620                 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
  621                         ia->ia6_lifetime.ia6t_preferred =
  622                                 time.tv_sec + ia->ia6_lifetime.ia6t_pltime;
  623                 } else
  624                         ia->ia6_lifetime.ia6t_preferred = 0;
  625                 break;
  626 
  627         case SIOCAIFADDR_IN6:
  628         {
  629                 int i, error = 0;
  630                 struct nd_prefix pr0, *pr;
  631 
  632                 /* reject read-only flags */
  633                 if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
  634                     (ifra->ifra_flags & IN6_IFF_DETACHED) != 0 ||
  635                     (ifra->ifra_flags & IN6_IFF_NODAD) != 0 ||
  636                     (ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0) {
  637                         return (EINVAL);
  638                 }
  639                 /*
  640                  * first, make or update the interface address structure,
  641                  * and link it to the list.
  642                  */
  643                 if ((error = in6_update_ifa(ifp, ifra, ia)) != 0)
  644                         return (error);
  645                 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
  646                     == NULL) {
  647                         /*
  648                          * this can happen when the user specify the 0 valid
  649                          * lifetime.
  650                          */
  651                         break;
  652                 }
  653 
  654                 /*
  655                  * then, make the prefix on-link on the interface.
  656                  * XXX: we'd rather create the prefix before the address, but
  657                  * we need at least one address to install the corresponding
  658                  * interface route, so we configure the address first.
  659                  */
  660 
  661                 /*
  662                  * convert mask to prefix length (prefixmask has already
  663                  * been validated in in6_update_ifa().
  664                  */
  665                 bzero(&pr0, sizeof(pr0));
  666                 pr0.ndpr_ifp = ifp;
  667                 pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
  668                     NULL);
  669                 if (pr0.ndpr_plen == 128) {
  670                         break;  /* we don't need to install a host route. */
  671                 }
  672                 pr0.ndpr_prefix = ifra->ifra_addr;
  673                 pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
  674                 /* apply the mask for safety. */
  675                 for (i = 0; i < 4; i++) {
  676                         pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
  677                             ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
  678                 }
  679                 /*
  680                  * XXX: since we don't have an API to set prefix (not address)
  681                  * lifetimes, we just use the same lifetimes as addresses.
  682                  * The (temporarily) installed lifetimes can be overridden by
  683                  * later advertised RAs (when accept_rtadv is non 0), which is
  684                  * an intended behavior.
  685                  */
  686                 pr0.ndpr_raf_onlink = 1; /* should be configurable? */
  687                 pr0.ndpr_raf_auto =
  688                     ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
  689                 pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
  690                 pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
  691 
  692                 /* add the prefix if not yet. */
  693                 if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
  694                         /*
  695                          * nd6_prelist_add will install the corresponding
  696                          * interface route.
  697                          */
  698                         if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
  699                                 return (error);
  700                         if (pr == NULL) {
  701                                 log(LOG_ERR, "nd6_prelist_add succeeded but "
  702                                     "no prefix\n");
  703                                 return (EINVAL); /* XXX panic here? */
  704                         }
  705                 }
  706 
  707                 /* relate the address to the prefix */
  708                 if (ia->ia6_ndpr == NULL) {
  709                         ia->ia6_ndpr = pr;
  710                         pr->ndpr_refcnt++;
  711                 }
  712 
  713                 /*
  714                  * this might affect the status of autoconfigured addresses,
  715                  * that is, this address might make other addresses detached.
  716                  */
  717                 pfxlist_onlink_check();
  718 
  719 #ifdef PFIL_HOOKS
  720                 (void)pfil_run_hooks(&if_pfil, (struct mbuf **)SIOCAIFADDR_IN6,
  721                     ifp, PFIL_IFADDR);
  722 #endif
  723 
  724                 break;
  725         }
  726 
  727         case SIOCDIFADDR_IN6:
  728         {
  729                 int i = 0, purgeprefix = 0;
  730                 struct nd_prefix pr0, *pr = NULL;
  731 
  732                 /*
  733                  * If the address being deleted is the only one that owns
  734                  * the corresponding prefix, expire the prefix as well.
  735                  * XXX: theoretically, we don't have to worry about such
  736                  * relationship, since we separate the address management
  737                  * and the prefix management.  We do this, however, to provide
  738                  * as much backward compatibility as possible in terms of
  739                  * the ioctl operation.
  740                  */
  741                 bzero(&pr0, sizeof(pr0));
  742                 pr0.ndpr_ifp = ifp;
  743                 pr0.ndpr_plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr,
  744                     NULL);
  745                 if (pr0.ndpr_plen == 128)
  746                         goto purgeaddr;
  747                 pr0.ndpr_prefix = ia->ia_addr;
  748                 pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
  749                 for (i = 0; i < 4; i++) {
  750                         pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
  751                             ia->ia_prefixmask.sin6_addr.s6_addr32[i];
  752                 }
  753                 if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
  754                     pr == ia->ia6_ndpr) {
  755                         pr->ndpr_refcnt--;
  756                         if (pr->ndpr_refcnt == 0)
  757                                 purgeprefix = 1;
  758                 }
  759 
  760           purgeaddr:
  761                 in6_purgeaddr(&ia->ia_ifa);
  762                 if (pr && purgeprefix)
  763                         prelist_remove(pr);
  764 #ifdef PFIL_HOOKS
  765                 (void)pfil_run_hooks(&if_pfil, (struct mbuf **)SIOCDIFADDR_IN6,
  766                     ifp, PFIL_IFADDR);
  767 #endif
  768                 break;
  769         }
  770 
  771         default:
  772                 if (ifp == NULL || ifp->if_ioctl == 0)
  773                         return (EOPNOTSUPP);
  774                 return ((*ifp->if_ioctl)(ifp, cmd, data));
  775         }
  776 
  777         return (0);
  778 }
  779 
  780 /*
  781  * Update parameters of an IPv6 interface address.
  782  * If necessary, a new entry is created and linked into address chains.
  783  * This function is separated from in6_control().
  784  * XXX: should this be performed under splnet()?
  785  */
  786 int
  787 in6_update_ifa(ifp, ifra, ia)
  788         struct ifnet *ifp;
  789         struct in6_aliasreq *ifra;
  790         struct in6_ifaddr *ia;
  791 {
  792         int error = 0, hostIsNew = 0, plen = -1;
  793         struct in6_ifaddr *oia;
  794         struct sockaddr_in6 dst6;
  795         struct in6_addrlifetime *lt;
  796         struct in6_multi_mship *imm;
  797         struct rtentry *rt;
  798 
  799         /* Validate parameters */
  800         if (ifp == NULL || ifra == NULL) /* this maybe redundant */
  801                 return (EINVAL);
  802 
  803         /*
  804          * The destination address for a p2p link must have a family
  805          * of AF_UNSPEC or AF_INET6.
  806          */
  807         if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
  808             ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
  809             ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
  810                 return (EAFNOSUPPORT);
  811         /*
  812          * validate ifra_prefixmask.  don't check sin6_family, netmask
  813          * does not carry fields other than sin6_len.
  814          */
  815         if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
  816                 return (EINVAL);
  817         /*
  818          * Because the IPv6 address architecture is classless, we require
  819          * users to specify a (non 0) prefix length (mask) for a new address.
  820          * We also require the prefix (when specified) mask is valid, and thus
  821          * reject a non-consecutive mask.
  822          */
  823         if (ia == NULL && ifra->ifra_prefixmask.sin6_len == 0)
  824                 return (EINVAL);
  825         if (ifra->ifra_prefixmask.sin6_len != 0) {
  826                 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
  827                     (u_char *)&ifra->ifra_prefixmask +
  828                     ifra->ifra_prefixmask.sin6_len);
  829                 if (plen <= 0)
  830                         return (EINVAL);
  831         } else {
  832                 /*
  833                  * In this case, ia must not be NULL.  We just use its prefix
  834                  * length.
  835                  */
  836                 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
  837         }
  838         /*
  839          * If the destination address on a p2p interface is specified,
  840          * and the address is a scoped one, validate/set the scope
  841          * zone identifier.
  842          */
  843         dst6 = ifra->ifra_dstaddr;
  844         if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
  845             (dst6.sin6_family == AF_INET6)) {
  846                 /* link-local index check: should be a separate function? */
  847                 if (IN6_IS_ADDR_LINKLOCAL(&dst6.sin6_addr)) {
  848                         if (dst6.sin6_addr.s6_addr16[1] == 0) {
  849                                 /*
  850                                  * interface ID is not embedded by
  851                                  * the user
  852                                  */
  853                                 dst6.sin6_addr.s6_addr16[1] =
  854                                     htons(ifp->if_index);
  855                         } else if (dst6.sin6_addr.s6_addr16[1] !=
  856                             htons(ifp->if_index)) {
  857                                 return (EINVAL);        /* ifid contradicts */
  858                         }
  859                 }
  860         }
  861         /*
  862          * The destination address can be specified only for a p2p or a
  863          * loopback interface.  If specified, the corresponding prefix length
  864          * must be 128.
  865          */
  866         if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
  867 #ifdef FORCE_P2PPLEN
  868                 int i;
  869 #endif
  870 
  871                 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
  872                         /* XXX: noisy message */
  873                         nd6log((LOG_INFO, "in6_update_ifa: a destination can "
  874                             "be specified for a p2p or a loopback IF only\n"));
  875                         return (EINVAL);
  876                 }
  877                 if (plen != 128) {
  878                         nd6log((LOG_INFO, "in6_update_ifa: prefixlen should "
  879                             "be 128 when dstaddr is specified\n"));
  880 #ifdef FORCE_P2PPLEN
  881                         /*
  882                          * To be compatible with old configurations,
  883                          * such as ifconfig gif0 inet6 2001::1 2001::2
  884                          * prefixlen 126, we override the specified
  885                          * prefixmask as if the prefix length was 128.
  886                          */
  887                         ifra->ifra_prefixmask.sin6_len =
  888                             sizeof(struct sockaddr_in6);
  889                         for (i = 0; i < 4; i++)
  890                                 ifra->ifra_prefixmask.sin6_addr.s6_addr32[i] =
  891                                     0xffffffff;
  892                         plen = 128;
  893 #else
  894                         return (EINVAL);
  895 #endif
  896                 }
  897         }
  898         /* lifetime consistency check */
  899         lt = &ifra->ifra_lifetime;
  900         if (lt->ia6t_pltime > lt->ia6t_vltime)
  901                 return (EINVAL);
  902         if (lt->ia6t_vltime == 0) {
  903                 /*
  904                  * the following log might be noisy, but this is a typical
  905                  * configuration mistake or a tool's bug.
  906                  */
  907                 nd6log((LOG_INFO,
  908                     "in6_update_ifa: valid lifetime is 0 for %s\n",
  909                     ip6_sprintf(&ifra->ifra_addr.sin6_addr)));
  910 
  911                 if (ia == NULL)
  912                         return (0); /* there's nothing to do */
  913         }
  914 
  915         /*
  916          * If this is a new address, allocate a new ifaddr and link it
  917          * into chains.
  918          */
  919         if (ia == NULL) {
  920                 hostIsNew = 1;
  921                 /*
  922                  * When in6_update_ifa() is called in a process of a received
  923                  * RA, it is called under an interrupt context.  So, we should
  924                  * call malloc with M_NOWAIT.
  925                  */
  926                 ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR,
  927                     M_NOWAIT);
  928                 if (ia == NULL)
  929                         return (ENOBUFS);
  930                 bzero((caddr_t)ia, sizeof(*ia));
  931                 LIST_INIT(&ia->ia6_memberships);
  932                 /* Initialize the address and masks, and put time stamp */
  933                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
  934                 ia->ia_addr.sin6_family = AF_INET6;
  935                 ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
  936                 ia->ia6_createtime = ia->ia6_updatetime = time.tv_sec;
  937                 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
  938                         /*
  939                          * XXX: some functions expect that ifa_dstaddr is not
  940                          * NULL for p2p interfaces.
  941                          */
  942                         ia->ia_ifa.ifa_dstaddr =
  943                             (struct sockaddr *)&ia->ia_dstaddr;
  944                 } else {
  945                         ia->ia_ifa.ifa_dstaddr = NULL;
  946                 }
  947                 ia->ia_ifa.ifa_netmask =
  948                     (struct sockaddr *)&ia->ia_prefixmask;
  949 
  950                 ia->ia_ifp = ifp;
  951                 if ((oia = in6_ifaddr) != NULL) {
  952                         for ( ; oia->ia_next; oia = oia->ia_next)
  953                                 continue;
  954                         oia->ia_next = ia;
  955                 } else
  956                         in6_ifaddr = ia;
  957                 /* gain a refcnt for the link from in6_ifaddr */
  958                 IFAREF(&ia->ia_ifa);
  959 
  960                 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa,
  961                                   ifa_list);
  962                 /* gain another refcnt for the link from if_addrlist */
  963                 IFAREF(&ia->ia_ifa);
  964         }
  965 
  966         /* set prefix mask */
  967         if (ifra->ifra_prefixmask.sin6_len) {
  968                 /*
  969                  * We prohibit changing the prefix length of an existing
  970                  * address, because
  971                  * + such an operation should be rare in IPv6, and
  972                  * + the operation would confuse prefix management.
  973                  */
  974                 if (ia->ia_prefixmask.sin6_len &&
  975                     in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
  976                         nd6log((LOG_INFO, "in6_update_ifa: the prefix length of an"
  977                             " existing (%s) address should not be changed\n",
  978                             ip6_sprintf(&ia->ia_addr.sin6_addr)));
  979                         error = EINVAL;
  980                         goto unlink;
  981                 }
  982                 ia->ia_prefixmask = ifra->ifra_prefixmask;
  983         }
  984 
  985         /*
  986          * If a new destination address is specified, scrub the old one and
  987          * install the new destination.  Note that the interface must be
  988          * p2p or loopback (see the check above.)
  989          */
  990         if (dst6.sin6_family == AF_INET6 &&
  991             !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia->ia_dstaddr.sin6_addr)) {
  992                 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
  993                     rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST) != 0) {
  994                         nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
  995                             "a route to the old destination: %s\n",
  996                             ip6_sprintf(&ia->ia_addr.sin6_addr)));
  997                         /* proceed anyway... */
  998                 } else
  999                         ia->ia_flags &= ~IFA_ROUTE;
 1000                 ia->ia_dstaddr = dst6;
 1001         }
 1002 
 1003         /*
 1004          * Set lifetimes.  We do not refer to ia6t_expire and ia6t_preferred
 1005          * to see if the address is deprecated or invalidated, but initialize
 1006          * these members for applications.
 1007          */
 1008         ia->ia6_lifetime = ifra->ifra_lifetime;
 1009         if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 1010                 ia->ia6_lifetime.ia6t_expire =
 1011                     time.tv_sec + ia->ia6_lifetime.ia6t_vltime;
 1012         } else
 1013                 ia->ia6_lifetime.ia6t_expire = 0;
 1014         if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
 1015                 ia->ia6_lifetime.ia6t_preferred =
 1016                     time.tv_sec + ia->ia6_lifetime.ia6t_pltime;
 1017         } else
 1018                 ia->ia6_lifetime.ia6t_preferred = 0;
 1019 
 1020         /* reset the interface and routing table appropriately. */
 1021         if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
 1022                 goto unlink;
 1023 
 1024         /*
 1025          * configure address flags.
 1026          */
 1027         ia->ia6_flags = ifra->ifra_flags;
 1028         /*
 1029          * backward compatibility - if IN6_IFF_DEPRECATED is set from the
 1030          * userland, make it deprecated.
 1031          */
 1032         if ((ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) {
 1033                 ia->ia6_lifetime.ia6t_pltime = 0;
 1034                 ia->ia6_lifetime.ia6t_preferred = time.tv_sec;
 1035         }
 1036         /*
 1037          * Make the address tentative before joining multicast addresses,
 1038          * so that corresponding MLD responses would not have a tentative
 1039          * source address.
 1040          */
 1041         ia->ia6_flags &= ~IN6_IFF_DUPLICATED;   /* safety */
 1042         if (hostIsNew && in6if_do_dad(ifp))
 1043                 ia->ia6_flags |= IN6_IFF_TENTATIVE;
 1044 
 1045         /*
 1046          * We are done if we have simply modified an existing address.
 1047          */
 1048         if (!hostIsNew)
 1049                 return (error);
 1050 
 1051         /*
 1052          * Beyond this point, we should call in6_purgeaddr upon an error,
 1053          * not just go to unlink.
 1054          */
 1055 
 1056         /* join necessary multiast groups */
 1057         if ((ifp->if_flags & IFF_MULTICAST) != 0) {
 1058                 struct sockaddr_in6 mltaddr, mltmask;
 1059 #ifndef SCOPEDROUTING
 1060                 u_int32_t zoneid = 0;
 1061 #endif
 1062 
 1063                 /* join solicited multicast addr for new host id */
 1064                 struct sockaddr_in6 llsol;
 1065 
 1066                 bzero(&llsol, sizeof(llsol));
 1067                 llsol.sin6_family = AF_INET6;
 1068                 llsol.sin6_len = sizeof(llsol);
 1069                 llsol.sin6_addr.s6_addr16[0] = htons(0xff02);
 1070                 llsol.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
 1071                 llsol.sin6_addr.s6_addr32[1] = 0;
 1072                 llsol.sin6_addr.s6_addr32[2] = htonl(1);
 1073                 llsol.sin6_addr.s6_addr32[3] =
 1074                     ifra->ifra_addr.sin6_addr.s6_addr32[3];
 1075                 llsol.sin6_addr.s6_addr8[12] = 0xff;
 1076                 imm = in6_joingroup(ifp, &llsol.sin6_addr, &error);
 1077                 if (!imm) {
 1078                         nd6log((LOG_ERR,
 1079                             "in6_update_ifa: addmulti "
 1080                             "failed for %s on %s (errno=%d)\n",
 1081                             ip6_sprintf(&llsol.sin6_addr),
 1082                             if_name(ifp), error));
 1083                         goto cleanup;
 1084                 }
 1085                 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 1086 
 1087                 bzero(&mltmask, sizeof(mltmask));
 1088                 mltmask.sin6_len = sizeof(struct sockaddr_in6);
 1089                 mltmask.sin6_family = AF_INET6;
 1090                 mltmask.sin6_addr = in6mask32;
 1091 
 1092                 /*
 1093                  * join link-local all-nodes address
 1094                  */
 1095                 bzero(&mltaddr, sizeof(mltaddr));
 1096                 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
 1097                 mltaddr.sin6_family = AF_INET6;
 1098                 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
 1099                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
 1100 
 1101                 /*
 1102                  * XXX: do we really need this automatic routes?
 1103                  * We should probably reconsider this stuff.  Most applications
 1104                  * actually do not need the routes, since they usually specify
 1105                  * the outgoing interface.
 1106                  */
 1107                 rt = rtalloc1((struct sockaddr *)&mltaddr, 0);
 1108                 if (rt) {
 1109                         /*
 1110                          * 32bit came from "mltmask"
 1111                          * XXX: only works in !SCOPEDROUTING case.
 1112                          */
 1113                         if (memcmp(&mltaddr.sin6_addr,
 1114                             &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
 1115                             32 / 8)) {
 1116                                 RTFREE(rt);
 1117                                 rt = NULL;
 1118                         }
 1119                 }
 1120                 if (!rt) {
 1121                         struct rt_addrinfo info;
 1122 
 1123                         bzero(&info, sizeof(info));
 1124                         info.rti_info[RTAX_DST] = (struct sockaddr *)&mltaddr;
 1125                         info.rti_info[RTAX_GATEWAY] =
 1126                             (struct sockaddr *)&ia->ia_addr;
 1127                         info.rti_info[RTAX_NETMASK] =
 1128                             (struct sockaddr *)&mltmask;
 1129                         info.rti_info[RTAX_IFA] =
 1130                             (struct sockaddr *)&ia->ia_addr;
 1131                         /* XXX: we need RTF_CLONING to fake nd6_rtrequest */
 1132                         info.rti_flags = RTF_UP | RTF_CLONING;
 1133                         error = rtrequest1(RTM_ADD, &info, NULL);
 1134                         if (error)
 1135                                 goto cleanup;
 1136                 } else {
 1137                         RTFREE(rt);
 1138                 }
 1139 #ifndef SCOPEDROUTING
 1140                 mltaddr.sin6_scope_id = zoneid; /* XXX */
 1141 #endif
 1142                 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
 1143                 if (!imm) {
 1144                         nd6log((LOG_WARNING,
 1145                             "in6_update_ifa: addmulti failed for "
 1146                             "%s on %s (errno=%d)\n",
 1147                             ip6_sprintf(&mltaddr.sin6_addr),
 1148                             if_name(ifp), error));
 1149                         goto cleanup;
 1150                 }
 1151                 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 1152 
 1153                 /*
 1154                  * join node information group address
 1155                  */
 1156                 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr) == 0) {
 1157                         imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
 1158                         if (!imm) {
 1159                                 nd6log((LOG_WARNING, "in6_update_ifa: "
 1160                                     "addmulti failed for %s on %s (errno=%d)\n",
 1161                                     ip6_sprintf(&mltaddr.sin6_addr),
 1162                                     if_name(ifp), error));
 1163                                 /* XXX not very fatal, go on... */
 1164                         } else {
 1165                                 LIST_INSERT_HEAD(&ia->ia6_memberships,
 1166                                     imm, i6mm_chain);
 1167                         }
 1168                 }
 1169 
 1170                 if (ifp->if_flags & IFF_LOOPBACK) {
 1171                         /*
 1172                          * join node-local all-nodes address, on loopback.
 1173                          * (ff01::1%ifN, and ff01::%ifN/32)
 1174                          */
 1175                         mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
 1176 
 1177                         /* XXX: again, do we really need the route? */
 1178                         rt = rtalloc1((struct sockaddr *)&mltaddr, 0);
 1179                         if (rt) {
 1180                                 /* 32bit came from "mltmask" */
 1181                                 if (memcmp(&mltaddr.sin6_addr,
 1182                                     &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
 1183                                     32 / 8)) {
 1184                                         RTFREE(rt);
 1185                                         rt = NULL;
 1186                                 }
 1187                         }
 1188                         if (!rt) {
 1189                                 struct rt_addrinfo info;
 1190 
 1191                                 bzero(&info, sizeof(info));
 1192                                 info.rti_info[RTAX_DST] = (struct sockaddr *)&mltaddr;
 1193                                 info.rti_info[RTAX_GATEWAY] =
 1194                                     (struct sockaddr *)&ia->ia_addr;
 1195                                 info.rti_info[RTAX_NETMASK] =
 1196                                     (struct sockaddr *)&mltmask;
 1197                                 info.rti_info[RTAX_IFA] =
 1198                                     (struct sockaddr *)&ia->ia_addr;
 1199                                 info.rti_flags = RTF_UP | RTF_CLONING;
 1200                                 error = rtrequest1(RTM_ADD, &info, NULL);
 1201                                 if (error)
 1202                                         goto cleanup;
 1203                         } else {
 1204                                 RTFREE(rt);
 1205                         }
 1206                         imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
 1207                         if (!imm) {
 1208                                 nd6log((LOG_WARNING, "in6_update_ifa: "
 1209                                     "addmulti failed for %s on %s (errno=%d)\n",
 1210                                     ip6_sprintf(&mltaddr.sin6_addr),
 1211                                     if_name(ifp), error));
 1212                                 goto cleanup;
 1213                         }
 1214                         LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 1215                 }
 1216         }
 1217 
 1218         /*
 1219          * Perform DAD, if needed.
 1220          * XXX It may be of use, if we can administratively
 1221          * disable DAD.
 1222          */
 1223         if (hostIsNew && in6if_do_dad(ifp) &&
 1224             (ifra->ifra_flags & IN6_IFF_NODAD) == 0)
 1225         {
 1226                 nd6_dad_start((struct ifaddr *)ia, NULL);
 1227         }
 1228 
 1229         return (error);
 1230 
 1231   unlink:
 1232         /*
 1233          * XXX: if a change of an existing address failed, keep the entry
 1234          * anyway.
 1235          */
 1236         if (hostIsNew)
 1237                 in6_unlink_ifa(ia, ifp);
 1238         return (error);
 1239 
 1240   cleanup:
 1241         in6_purgeaddr(&ia->ia_ifa);
 1242         return error;
 1243 }
 1244 
 1245 void
 1246 in6_purgeaddr(ifa)
 1247         struct ifaddr *ifa;
 1248 {
 1249         struct ifnet *ifp = ifa->ifa_ifp;
 1250         struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
 1251         struct in6_multi_mship *imm;
 1252 
 1253         /* stop DAD processing */
 1254         nd6_dad_stop(ifa);
 1255 
 1256         /*
 1257          * delete route to the destination of the address being purged.
 1258          * The interface must be p2p or loopback in this case.
 1259          */
 1260         if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
 1261                 int e;
 1262 
 1263                 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
 1264                     != 0) {
 1265                         log(LOG_ERR, "in6_purgeaddr: failed to remove "
 1266                             "a route to the p2p destination: %s on %s, "
 1267                             "errno=%d\n",
 1268                             ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
 1269                             e);
 1270                         /* proceed anyway... */
 1271                 } else
 1272                         ia->ia_flags &= ~IFA_ROUTE;
 1273         }
 1274 
 1275         /* Remove ownaddr's loopback rtentry, if it exists. */
 1276         in6_ifremloop(&(ia->ia_ifa));
 1277 
 1278         /*
 1279          * leave from multicast groups we have joined for the interface
 1280          */
 1281         while ((imm = ia->ia6_memberships.lh_first) != NULL) {
 1282                 LIST_REMOVE(imm, i6mm_chain);
 1283                 in6_leavegroup(imm);
 1284         }
 1285 
 1286         in6_unlink_ifa(ia, ifp);
 1287 }
 1288 
 1289 static void
 1290 in6_unlink_ifa(ia, ifp)
 1291         struct in6_ifaddr *ia;
 1292         struct ifnet *ifp;
 1293 {
 1294         struct in6_ifaddr *oia;
 1295         int     s = splnet();
 1296 
 1297         TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
 1298         /* release a refcnt for the link from if_addrlist */
 1299         IFAFREE(&ia->ia_ifa);
 1300 
 1301         oia = ia;
 1302         if (oia == (ia = in6_ifaddr))
 1303                 in6_ifaddr = ia->ia_next;
 1304         else {
 1305                 while (ia->ia_next && (ia->ia_next != oia))
 1306                         ia = ia->ia_next;
 1307                 if (ia->ia_next)
 1308                         ia->ia_next = oia->ia_next;
 1309                 else {
 1310                         /* search failed */
 1311                         printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
 1312                 }
 1313         }
 1314 
 1315         if (oia->ia6_multiaddrs.lh_first != NULL) {
 1316                 /*
 1317                  * XXX thorpej@NetBSD.org -- if the interface is going
 1318                  * XXX away, don't save the multicast entries, delete them!
 1319                  */
 1320                 if (oia->ia_ifa.ifa_ifp->if_output == if_nulloutput) {
 1321                         struct in6_multi *in6m;
 1322 
 1323                         while ((in6m =
 1324                             LIST_FIRST(&oia->ia6_multiaddrs)) != NULL)
 1325                                 in6_delmulti(in6m);
 1326                 } else
 1327                         in6_savemkludge(oia);
 1328         }
 1329 
 1330         /*
 1331          * When an autoconfigured address is being removed, release the
 1332          * reference to the base prefix.  Also, since the release might
 1333          * affect the status of other (detached) addresses, call
 1334          * pfxlist_onlink_check().
 1335          */
 1336         if ((oia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
 1337                 if (oia->ia6_ndpr == NULL) {
 1338                         log(LOG_NOTICE, "in6_unlink_ifa: autoconf'ed address "
 1339                             "%p has no prefix\n", oia);
 1340                 } else {
 1341                         oia->ia6_ndpr->ndpr_refcnt--;
 1342                         oia->ia6_flags &= ~IN6_IFF_AUTOCONF;
 1343                         oia->ia6_ndpr = NULL;
 1344                 }
 1345 
 1346                 pfxlist_onlink_check();
 1347         }
 1348 
 1349         /*
 1350          * release another refcnt for the link from in6_ifaddr.
 1351          * Note that we should decrement the refcnt at least once for all *BSD.
 1352          */
 1353         IFAFREE(&oia->ia_ifa);
 1354 
 1355         splx(s);
 1356 }
 1357 
 1358 void
 1359 in6_purgeif(ifp)
 1360         struct ifnet *ifp;
 1361 {
 1362         struct ifaddr *ifa, *nifa;
 1363 
 1364         for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa)
 1365         {
 1366                 nifa = TAILQ_NEXT(ifa, ifa_list);
 1367                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1368                         continue;
 1369                 in6_purgeaddr(ifa);
 1370         }
 1371 
 1372         in6_ifdetach(ifp);
 1373 }
 1374 
 1375 /*
 1376  * SIOC[GAD]LIFADDR.
 1377  *      SIOCGLIFADDR: get first address. (?)
 1378  *      SIOCGLIFADDR with IFLR_PREFIX:
 1379  *              get first address that matches the specified prefix.
 1380  *      SIOCALIFADDR: add the specified address.
 1381  *      SIOCALIFADDR with IFLR_PREFIX:
 1382  *              add the specified prefix, filling hostid part from
 1383  *              the first link-local address.  prefixlen must be <= 64.
 1384  *      SIOCDLIFADDR: delete the specified address.
 1385  *      SIOCDLIFADDR with IFLR_PREFIX:
 1386  *              delete the first address that matches the specified prefix.
 1387  * return values:
 1388  *      EINVAL on invalid parameters
 1389  *      EADDRNOTAVAIL on prefix match failed/specified address not found
 1390  *      other values may be returned from in6_ioctl()
 1391  *
 1392  * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
 1393  * this is to accomodate address naming scheme other than RFC2374,
 1394  * in the future.
 1395  * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
 1396  * address encoding scheme. (see figure on page 8)
 1397  */
 1398 static int
 1399 in6_lifaddr_ioctl(so, cmd, data, ifp, p)
 1400         struct socket *so;
 1401         u_long cmd;
 1402         caddr_t data;
 1403         struct ifnet *ifp;
 1404         struct proc *p;
 1405 {
 1406         struct if_laddrreq *iflr = (struct if_laddrreq *)data;
 1407         struct ifaddr *ifa;
 1408         struct sockaddr *sa;
 1409 
 1410         /* sanity checks */
 1411         if (!data || !ifp) {
 1412                 panic("invalid argument to in6_lifaddr_ioctl");
 1413                 /* NOTREACHED */
 1414         }
 1415 
 1416         switch (cmd) {
 1417         case SIOCGLIFADDR:
 1418                 /* address must be specified on GET with IFLR_PREFIX */
 1419                 if ((iflr->flags & IFLR_PREFIX) == 0)
 1420                         break;
 1421                 /* FALLTHROUGH */
 1422         case SIOCALIFADDR:
 1423         case SIOCDLIFADDR:
 1424                 /* address must be specified on ADD and DELETE */
 1425                 sa = (struct sockaddr *)&iflr->addr;
 1426                 if (sa->sa_family != AF_INET6)
 1427                         return EINVAL;
 1428                 if (sa->sa_len != sizeof(struct sockaddr_in6))
 1429                         return EINVAL;
 1430                 /* XXX need improvement */
 1431                 sa = (struct sockaddr *)&iflr->dstaddr;
 1432                 if (sa->sa_family && sa->sa_family != AF_INET6)
 1433                         return EINVAL;
 1434                 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
 1435                         return EINVAL;
 1436                 break;
 1437         default: /* shouldn't happen */
 1438 #if 0
 1439                 panic("invalid cmd to in6_lifaddr_ioctl");
 1440                 /* NOTREACHED */
 1441 #else
 1442                 return EOPNOTSUPP;
 1443 #endif
 1444         }
 1445         if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
 1446                 return EINVAL;
 1447 
 1448         switch (cmd) {
 1449         case SIOCALIFADDR:
 1450             {
 1451                 struct in6_aliasreq ifra;
 1452                 struct in6_addr *hostid = NULL;
 1453                 int prefixlen;
 1454 
 1455                 if ((iflr->flags & IFLR_PREFIX) != 0) {
 1456                         struct sockaddr_in6 *sin6;
 1457 
 1458                         /*
 1459                          * hostid is to fill in the hostid part of the
 1460                          * address.  hostid points to the first link-local
 1461                          * address attached to the interface.
 1462                          */
 1463                         ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
 1464                         if (!ifa)
 1465                                 return EADDRNOTAVAIL;
 1466                         hostid = IFA_IN6(ifa);
 1467 
 1468                         /* prefixlen must be <= 64. */
 1469                         if (64 < iflr->prefixlen)
 1470                                 return EINVAL;
 1471                         prefixlen = iflr->prefixlen;
 1472 
 1473                         /* hostid part must be zero. */
 1474                         sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1475                         if (sin6->sin6_addr.s6_addr32[2] != 0
 1476                          || sin6->sin6_addr.s6_addr32[3] != 0) {
 1477                                 return EINVAL;
 1478                         }
 1479                 } else
 1480                         prefixlen = iflr->prefixlen;
 1481 
 1482                 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
 1483                 bzero(&ifra, sizeof(ifra));
 1484                 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
 1485 
 1486                 bcopy(&iflr->addr, &ifra.ifra_addr,
 1487                     ((struct sockaddr *)&iflr->addr)->sa_len);
 1488                 if (hostid) {
 1489                         /* fill in hostid part */
 1490                         ifra.ifra_addr.sin6_addr.s6_addr32[2] =
 1491                             hostid->s6_addr32[2];
 1492                         ifra.ifra_addr.sin6_addr.s6_addr32[3] =
 1493                             hostid->s6_addr32[3];
 1494                 }
 1495 
 1496                 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /* XXX */
 1497                         bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
 1498                             ((struct sockaddr *)&iflr->dstaddr)->sa_len);
 1499                         if (hostid) {
 1500                                 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
 1501                                     hostid->s6_addr32[2];
 1502                                 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
 1503                                     hostid->s6_addr32[3];
 1504                         }
 1505                 }
 1506 
 1507                 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
 1508                 in6_prefixlen2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
 1509 
 1510                 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
 1511                 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, p);
 1512             }
 1513         case SIOCGLIFADDR:
 1514         case SIOCDLIFADDR:
 1515             {
 1516                 struct in6_ifaddr *ia;
 1517                 struct in6_addr mask, candidate, match;
 1518                 struct sockaddr_in6 *sin6;
 1519                 int cmp;
 1520 
 1521                 bzero(&mask, sizeof(mask));
 1522                 if (iflr->flags & IFLR_PREFIX) {
 1523                         /* lookup a prefix rather than address. */
 1524                         in6_prefixlen2mask(&mask, iflr->prefixlen);
 1525 
 1526                         sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1527                         bcopy(&sin6->sin6_addr, &match, sizeof(match));
 1528                         match.s6_addr32[0] &= mask.s6_addr32[0];
 1529                         match.s6_addr32[1] &= mask.s6_addr32[1];
 1530                         match.s6_addr32[2] &= mask.s6_addr32[2];
 1531                         match.s6_addr32[3] &= mask.s6_addr32[3];
 1532 
 1533                         /* if you set extra bits, that's wrong */
 1534                         if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
 1535                                 return EINVAL;
 1536 
 1537                         cmp = 1;
 1538                 } else {
 1539                         if (cmd == SIOCGLIFADDR) {
 1540                                 /* on getting an address, take the 1st match */
 1541                                 cmp = 0;        /* XXX */
 1542                         } else {
 1543                                 /* on deleting an address, do exact match */
 1544                                 in6_prefixlen2mask(&mask, 128);
 1545                                 sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1546                                 bcopy(&sin6->sin6_addr, &match, sizeof(match));
 1547 
 1548                                 cmp = 1;
 1549                         }
 1550                 }
 1551 
 1552                 for (ifa = ifp->if_addrlist.tqh_first;
 1553                      ifa;
 1554                      ifa = ifa->ifa_list.tqe_next)
 1555                 {
 1556                         if (ifa->ifa_addr->sa_family != AF_INET6)
 1557                                 continue;
 1558                         if (!cmp)
 1559                                 break;
 1560 
 1561                         bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
 1562                         candidate.s6_addr32[0] &= mask.s6_addr32[0];
 1563                         candidate.s6_addr32[1] &= mask.s6_addr32[1];
 1564                         candidate.s6_addr32[2] &= mask.s6_addr32[2];
 1565                         candidate.s6_addr32[3] &= mask.s6_addr32[3];
 1566                         if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
 1567                                 break;
 1568                 }
 1569                 if (!ifa)
 1570                         return EADDRNOTAVAIL;
 1571                 ia = ifa2ia6(ifa);
 1572 
 1573                 if (cmd == SIOCGLIFADDR) {
 1574                         /* fill in the if_laddrreq structure */
 1575                         bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
 1576                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
 1577                                 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
 1578                                     ia->ia_dstaddr.sin6_len);
 1579                         } else
 1580                                 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
 1581 
 1582                         iflr->prefixlen =
 1583                             in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
 1584 
 1585                         iflr->flags = ia->ia6_flags;    /* XXX */
 1586 
 1587                         return 0;
 1588                 } else {
 1589                         struct in6_aliasreq ifra;
 1590 
 1591                         /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
 1592                         bzero(&ifra, sizeof(ifra));
 1593                         bcopy(iflr->iflr_name, ifra.ifra_name,
 1594                             sizeof(ifra.ifra_name));
 1595 
 1596                         bcopy(&ia->ia_addr, &ifra.ifra_addr,
 1597                             ia->ia_addr.sin6_len);
 1598                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
 1599                                 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
 1600                                     ia->ia_dstaddr.sin6_len);
 1601                         } else {
 1602                                 bzero(&ifra.ifra_dstaddr,
 1603                                     sizeof(ifra.ifra_dstaddr));
 1604                         }
 1605                         bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
 1606                             ia->ia_prefixmask.sin6_len);
 1607 
 1608                         ifra.ifra_flags = ia->ia6_flags;
 1609                         return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
 1610                             ifp, p);
 1611                 }
 1612             }
 1613         }
 1614 
 1615         return EOPNOTSUPP;      /* just for safety */
 1616 }
 1617 
 1618 /*
 1619  * Initialize an interface's intetnet6 address
 1620  * and routing table entry.
 1621  */
 1622 static int
 1623 in6_ifinit(ifp, ia, sin6, newhost)
 1624         struct ifnet *ifp;
 1625         struct in6_ifaddr *ia;
 1626         struct sockaddr_in6 *sin6;
 1627         int newhost;
 1628 {
 1629         int     error = 0, plen, ifacount = 0;
 1630         int     s = splnet();
 1631         struct ifaddr *ifa;
 1632 
 1633         /*
 1634          * Give the interface a chance to initialize
 1635          * if this is its first address,
 1636          * and to validate the address if necessary.
 1637          */
 1638         for (ifa = ifp->if_addrlist.tqh_first; ifa;
 1639              ifa = ifa->ifa_list.tqe_next)
 1640         {
 1641                 if (ifa->ifa_addr == NULL)
 1642                         continue;       /* just for safety */
 1643                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1644                         continue;
 1645                 ifacount++;
 1646         }
 1647 
 1648         ia->ia_addr = *sin6;
 1649 
 1650         if (ifacount <= 1 && ifp->if_ioctl &&
 1651             (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
 1652                 splx(s);
 1653                 return (error);
 1654         }
 1655         splx(s);
 1656 
 1657         ia->ia_ifa.ifa_metric = ifp->if_metric;
 1658 
 1659         /* we could do in(6)_socktrim here, but just omit it at this moment. */
 1660 
 1661         /*
 1662          * Special case:
 1663          * If the destination address is specified for a point-to-point
 1664          * interface, install a route to the destination as an interface
 1665          * direct route.
 1666          */
 1667         plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
 1668         if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
 1669                 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
 1670                                     RTF_UP | RTF_HOST)) != 0)
 1671                         return (error);
 1672                 ia->ia_flags |= IFA_ROUTE;
 1673         }
 1674 
 1675         /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
 1676         if (newhost) {
 1677                 /* set the rtrequest function to create llinfo */
 1678                 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
 1679                 in6_ifaddloop(&(ia->ia_ifa));
 1680         }
 1681 
 1682         if (ifp->if_flags & IFF_MULTICAST)
 1683                 in6_restoremkludge(ia, ifp);
 1684 
 1685         return (error);
 1686 }
 1687 
 1688 /*
 1689  * Multicast address kludge:
 1690  * If there were any multicast addresses attached to this interface address,
 1691  * either move them to another address on this interface, or save them until
 1692  * such time as this interface is reconfigured for IPv6.
 1693  */
 1694 void
 1695 in6_savemkludge(oia)
 1696         struct in6_ifaddr *oia;
 1697 {
 1698         struct in6_ifaddr *ia;
 1699         struct in6_multi *in6m, *next;
 1700 
 1701         IFP_TO_IA6(oia->ia_ifp, ia);
 1702         if (ia) {       /* there is another address */
 1703                 for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
 1704                         next = in6m->in6m_entry.le_next;
 1705                         IFAFREE(&in6m->in6m_ia->ia_ifa);
 1706                         IFAREF(&ia->ia_ifa);
 1707                         in6m->in6m_ia = ia;
 1708                         LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
 1709                 }
 1710         } else {        /* last address on this if deleted, save */
 1711                 struct multi6_kludge *mk;
 1712 
 1713                 for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
 1714                         if (mk->mk_ifp == oia->ia_ifp)
 1715                                 break;
 1716                 }
 1717                 if (mk == NULL) /* this should not happen! */
 1718                         panic("in6_savemkludge: no kludge space");
 1719 
 1720                 for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next){
 1721                         next = in6m->in6m_entry.le_next;
 1722                         IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
 1723                         in6m->in6m_ia = NULL;
 1724                         LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);
 1725                 }
 1726         }
 1727 }
 1728 
 1729 /*
 1730  * Continuation of multicast address hack:
 1731  * If there was a multicast group list previously saved for this interface,
 1732  * then we re-attach it to the first address configured on the i/f.
 1733  */
 1734 void
 1735 in6_restoremkludge(ia, ifp)
 1736         struct in6_ifaddr *ia;
 1737         struct ifnet *ifp;
 1738 {
 1739         struct multi6_kludge *mk;
 1740 
 1741         for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
 1742                 if (mk->mk_ifp == ifp) {
 1743                         struct in6_multi *in6m, *next;
 1744 
 1745                         for (in6m = mk->mk_head.lh_first; in6m; in6m = next) {
 1746                                 next = in6m->in6m_entry.le_next;
 1747                                 in6m->in6m_ia = ia;
 1748                                 IFAREF(&ia->ia_ifa);
 1749                                 LIST_INSERT_HEAD(&ia->ia6_multiaddrs,
 1750                                     in6m, in6m_entry);
 1751                         }
 1752                         LIST_INIT(&mk->mk_head);
 1753                         break;
 1754                 }
 1755         }
 1756 }
 1757 
 1758 /*
 1759  * Allocate space for the kludge at interface initialization time.
 1760  * Formerly, we dynamically allocated the space in in6_savemkludge() with
 1761  * malloc(M_WAITOK).  However, it was wrong since the function could be called
 1762  * under an interrupt context (software timer on address lifetime expiration).
 1763  * Also, we cannot just give up allocating the strucutre, since the group
 1764  * membership structure is very complex and we need to keep it anyway.
 1765  * Of course, this function MUST NOT be called under an interrupt context.
 1766  * Specifically, it is expected to be called only from in6_ifattach(), though
 1767  * it is a global function.
 1768  */
 1769 void
 1770 in6_createmkludge(ifp)
 1771         struct ifnet *ifp;
 1772 {
 1773         struct multi6_kludge *mk;
 1774 
 1775         for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
 1776                 /* If we've already had one, do not allocate. */
 1777                 if (mk->mk_ifp == ifp)
 1778                         return;
 1779         }
 1780 
 1781         mk = malloc(sizeof(*mk), M_IPMADDR, M_WAITOK);
 1782 
 1783         bzero(mk, sizeof(*mk));
 1784         LIST_INIT(&mk->mk_head);
 1785         mk->mk_ifp = ifp;
 1786         LIST_INSERT_HEAD(&in6_mk, mk, mk_entry);
 1787 }
 1788 
 1789 void
 1790 in6_purgemkludge(ifp)
 1791         struct ifnet *ifp;
 1792 {
 1793         struct multi6_kludge *mk;
 1794         struct in6_multi *in6m;
 1795 
 1796         for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) {
 1797                 if (mk->mk_ifp != ifp)
 1798                         continue;
 1799 
 1800                 /* leave from all multicast groups joined */
 1801                 while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL)
 1802                         in6_delmulti(in6m);
 1803                 LIST_REMOVE(mk, mk_entry);
 1804                 free(mk, M_IPMADDR);
 1805                 break;
 1806         }
 1807 }
 1808 
 1809 /*
 1810  * Add an address to the list of IP6 multicast addresses for a
 1811  * given interface.
 1812  */
 1813 struct  in6_multi *
 1814 in6_addmulti(maddr6, ifp, errorp)
 1815         struct in6_addr *maddr6;
 1816         struct ifnet *ifp;
 1817         int *errorp;
 1818 {
 1819         struct  in6_ifaddr *ia;
 1820         struct  in6_ifreq ifr;
 1821         struct  in6_multi *in6m;
 1822         int     s = splsoftnet();
 1823 
 1824         *errorp = 0;
 1825         /*
 1826          * See if address already in list.
 1827          */
 1828         IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
 1829         if (in6m != NULL) {
 1830                 /*
 1831                  * Found it; just increment the refrence count.
 1832                  */
 1833                 in6m->in6m_refcount++;
 1834         } else {
 1835                 /*
 1836                  * New address; allocate a new multicast record
 1837                  * and link it into the interface's multicast list.
 1838                  */
 1839                 in6m = (struct in6_multi *)
 1840                         malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
 1841                 if (in6m == NULL) {
 1842                         splx(s);
 1843                         *errorp = ENOBUFS;
 1844                         return (NULL);
 1845                 }
 1846                 in6m->in6m_addr = *maddr6;
 1847                 in6m->in6m_ifp = ifp;
 1848                 in6m->in6m_refcount = 1;
 1849                 IFP_TO_IA6(ifp, ia);
 1850                 if (ia == NULL) {
 1851                         free(in6m, M_IPMADDR);
 1852                         splx(s);
 1853                         *errorp = EADDRNOTAVAIL; /* appropriate? */
 1854                         return (NULL);
 1855                 }
 1856                 in6m->in6m_ia = ia;
 1857                 IFAREF(&ia->ia_ifa); /* gain a reference */
 1858                 LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
 1859 
 1860                 /*
 1861                  * Ask the network driver to update its multicast reception
 1862                  * filter appropriately for the new address.
 1863                  */
 1864                 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
 1865                 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
 1866                 ifr.ifr_addr.sin6_family = AF_INET6;
 1867                 ifr.ifr_addr.sin6_addr = *maddr6;
 1868                 if (ifp->if_ioctl == NULL)
 1869                         *errorp = ENXIO; /* XXX: appropriate? */
 1870                 else
 1871                         *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI,
 1872                             (caddr_t)&ifr);
 1873                 if (*errorp) {
 1874                         LIST_REMOVE(in6m, in6m_entry);
 1875                         free(in6m, M_IPMADDR);
 1876                         IFAFREE(&ia->ia_ifa);
 1877                         splx(s);
 1878                         return (NULL);
 1879                 }
 1880                 /*
 1881                  * Let MLD6 know that we have joined a new IP6 multicast
 1882                  * group.
 1883                  */
 1884                 mld6_start_listening(in6m);
 1885         }
 1886         splx(s);
 1887         return (in6m);
 1888 }
 1889 
 1890 /*
 1891  * Delete a multicast address record.
 1892  */
 1893 void
 1894 in6_delmulti(in6m)
 1895         struct in6_multi *in6m;
 1896 {
 1897         struct  in6_ifreq ifr;
 1898         struct  in6_ifaddr *ia;
 1899         int     s = splsoftnet();
 1900 
 1901         if (--in6m->in6m_refcount == 0) {
 1902                 /*
 1903                  * No remaining claims to this record; let MLD6 know
 1904                  * that we are leaving the multicast group.
 1905                  */
 1906                 mld6_stop_listening(in6m);
 1907 
 1908                 /*
 1909                  * Unlink from list.
 1910                  */
 1911                 LIST_REMOVE(in6m, in6m_entry);
 1912                 if (in6m->in6m_ia) {
 1913                         IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */
 1914                 }
 1915                 /*
 1916                  * Delete all references of this multicasting group from
 1917                  * the membership arrays
 1918                  */
 1919                 for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
 1920                         struct in6_multi_mship *imm;
 1921                         LIST_FOREACH(imm, &ia->ia6_memberships,
 1922                             i6mm_chain) {
 1923                                 if (imm->i6mm_maddr == in6m)
 1924                                         imm->i6mm_maddr = NULL;
 1925                         }
 1926                 }
 1927 
 1928                 /*
 1929                  * Notify the network driver to update its multicast
 1930                  * reception filter.
 1931                  */
 1932                 bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
 1933                 ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
 1934                 ifr.ifr_addr.sin6_family = AF_INET6;
 1935                 ifr.ifr_addr.sin6_addr = in6m->in6m_addr;
 1936                 (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp,
 1937                                             SIOCDELMULTI, (caddr_t)&ifr);
 1938                 free(in6m, M_IPMADDR);
 1939         }
 1940         splx(s);
 1941 }
 1942 
 1943 struct in6_multi_mship *
 1944 in6_joingroup(ifp, addr, errorp)
 1945         struct ifnet *ifp;
 1946         struct in6_addr *addr;
 1947         int *errorp;
 1948 {
 1949         struct in6_multi_mship *imm;
 1950 
 1951         imm = malloc(sizeof(*imm), M_IPMADDR, M_NOWAIT);
 1952         if (!imm) {
 1953                 *errorp = ENOBUFS;
 1954                 return NULL;
 1955         }
 1956         imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp);
 1957         if (!imm->i6mm_maddr) {
 1958                 /* *errorp is alrady set */
 1959                 free(imm, M_IPMADDR);
 1960                 return NULL;
 1961         }
 1962         return imm;
 1963 }
 1964 
 1965 int
 1966 in6_leavegroup(imm)
 1967         struct in6_multi_mship *imm;
 1968 {
 1969 
 1970         if (imm->i6mm_maddr)
 1971                 in6_delmulti(imm->i6mm_maddr);
 1972         free(imm,  M_IPMADDR);
 1973         return 0;
 1974 }
 1975 
 1976 /*
 1977  * Find an IPv6 interface link-local address specific to an interface.
 1978  */
 1979 struct in6_ifaddr *
 1980 in6ifa_ifpforlinklocal(ifp, ignoreflags)
 1981         struct ifnet *ifp;
 1982         int ignoreflags;
 1983 {
 1984         struct ifaddr *ifa;
 1985 
 1986         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
 1987         {
 1988                 if (ifa->ifa_addr == NULL)
 1989                         continue;       /* just for safety */
 1990                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1991                         continue;
 1992                 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
 1993                         if ((((struct in6_ifaddr *)ifa)->ia6_flags &
 1994                              ignoreflags) != 0)
 1995                                 continue;
 1996                         break;
 1997                 }
 1998         }
 1999 
 2000         return ((struct in6_ifaddr *)ifa);
 2001 }
 2002 
 2003 
 2004 /*
 2005  * find the internet address corresponding to a given interface and address.
 2006  */
 2007 struct in6_ifaddr *
 2008 in6ifa_ifpwithaddr(ifp, addr)
 2009         struct ifnet *ifp;
 2010         struct in6_addr *addr;
 2011 {
 2012         struct ifaddr *ifa;
 2013 
 2014         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
 2015         {
 2016                 if (ifa->ifa_addr == NULL)
 2017                         continue;       /* just for safety */
 2018                 if (ifa->ifa_addr->sa_family != AF_INET6)
 2019                         continue;
 2020                 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
 2021                         break;
 2022         }
 2023 
 2024         return ((struct in6_ifaddr *)ifa);
 2025 }
 2026 
 2027 /*
 2028  * find the internet address on a given interface corresponding to a neighbor's
 2029  * address.
 2030  */
 2031 struct in6_ifaddr *
 2032 in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr)
 2033 {
 2034         struct ifaddr *ifa;
 2035         struct in6_ifaddr *ia;
 2036 
 2037         IFADDR_FOREACH(ifa, ifp) {
 2038                 if (ifa->ifa_addr == NULL)
 2039                         continue;       /* just for safety */
 2040                 if (ifa->ifa_addr->sa_family != AF_INET6)
 2041                         continue;
 2042                 ia = (struct in6_ifaddr *)ifa;
 2043                 if (IN6_ARE_MASKED_ADDR_EQUAL(addr,
 2044                                 &ia->ia_addr.sin6_addr,
 2045                                 &ia->ia_prefixmask.sin6_addr))
 2046                         return ia;
 2047         }
 2048 
 2049         return NULL;
 2050 }
 2051 
 2052 /*
 2053  * Convert IP6 address to printable (loggable) representation.
 2054  */
 2055 static char digits[] = "0123456789abcdef";
 2056 static int ip6round = 0;
 2057 char *
 2058 ip6_sprintf(addr)
 2059         const struct in6_addr *addr;
 2060 {
 2061         static char ip6buf[8][48];
 2062         int i;
 2063         char *cp;
 2064         const u_int16_t *a = (const u_int16_t *)addr;
 2065         const u_int8_t *d;
 2066         int dcolon = 0;
 2067 
 2068         ip6round = (ip6round + 1) & 7;
 2069         cp = ip6buf[ip6round];
 2070 
 2071         for (i = 0; i < 8; i++) {
 2072                 if (dcolon == 1) {
 2073                         if (*a == 0) {
 2074                                 if (i == 7)
 2075                                         *cp++ = ':';
 2076                                 a++;
 2077                                 continue;
 2078                         } else
 2079                                 dcolon = 2;
 2080                 }
 2081                 if (*a == 0) {
 2082                         if (dcolon == 0 && *(a + 1) == 0) {
 2083                                 if (i == 0)
 2084                                         *cp++ = ':';
 2085                                 *cp++ = ':';
 2086                                 dcolon = 1;
 2087                         } else {
 2088                                 *cp++ = '';
 2089                                 *cp++ = ':';
 2090                         }
 2091                         a++;
 2092                         continue;
 2093                 }
 2094                 d = (const u_char *)a;
 2095                 *cp++ = digits[*d >> 4];
 2096                 *cp++ = digits[*d++ & 0xf];
 2097                 *cp++ = digits[*d >> 4];
 2098                 *cp++ = digits[*d & 0xf];
 2099                 *cp++ = ':';
 2100                 a++;
 2101         }
 2102         *--cp = 0;
 2103         return (ip6buf[ip6round]);
 2104 }
 2105 
 2106 /*
 2107  * Determine if an address is on a local network.
 2108  */
 2109 int
 2110 in6_localaddr(in6)
 2111         struct in6_addr *in6;
 2112 {
 2113         struct in6_ifaddr *ia;
 2114 
 2115         if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
 2116                 return (1);
 2117 
 2118         for (ia = in6_ifaddr; ia; ia = ia->ia_next)
 2119                 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
 2120                                               &ia->ia_prefixmask.sin6_addr))
 2121                         return (1);
 2122 
 2123         return (0);
 2124 }
 2125 
 2126 /*
 2127  * Get a scope of the address. Node-local, link-local, site-local or global.
 2128  */
 2129 int
 2130 in6_addrscope (addr)
 2131 struct in6_addr *addr;
 2132 {
 2133         int scope;
 2134 
 2135         if (addr->s6_addr8[0] == 0xfe) {
 2136                 scope = addr->s6_addr8[1] & 0xc0;
 2137 
 2138                 switch (scope) {
 2139                 case 0x80:
 2140                         return IPV6_ADDR_SCOPE_LINKLOCAL;
 2141                 case 0xc0:
 2142                         return IPV6_ADDR_SCOPE_SITELOCAL;
 2143                 default:
 2144                         return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
 2145                 }
 2146         }
 2147 
 2148 
 2149         if (addr->s6_addr8[0] == 0xff) {
 2150                 scope = addr->s6_addr8[1] & 0x0f;
 2151 
 2152                 /*
 2153                  * due to other scope such as reserved,
 2154                  * return scope doesn't work.
 2155                  */
 2156                 switch (scope) {
 2157                 case IPV6_ADDR_SCOPE_NODELOCAL:
 2158                         return IPV6_ADDR_SCOPE_NODELOCAL;
 2159                 case IPV6_ADDR_SCOPE_LINKLOCAL:
 2160                         return IPV6_ADDR_SCOPE_LINKLOCAL;
 2161                 case IPV6_ADDR_SCOPE_SITELOCAL:
 2162                         return IPV6_ADDR_SCOPE_SITELOCAL;
 2163                 default:
 2164                         return IPV6_ADDR_SCOPE_GLOBAL;
 2165                 }
 2166         }
 2167 
 2168         if (bcmp(&in6addr_loopback, addr, sizeof(*addr) - 1) == 0) {
 2169                 if (addr->s6_addr8[15] == 1) /* loopback */
 2170                         return IPV6_ADDR_SCOPE_NODELOCAL;
 2171                 if (addr->s6_addr8[15] == 0) /* unspecified */
 2172                         return IPV6_ADDR_SCOPE_LINKLOCAL;
 2173         }
 2174 
 2175         return IPV6_ADDR_SCOPE_GLOBAL;
 2176 }
 2177 
 2178 int
 2179 in6_addr2scopeid(ifp, addr)
 2180         struct ifnet *ifp;      /* must not be NULL */
 2181         struct in6_addr *addr;  /* must not be NULL */
 2182 {
 2183         int scope = in6_addrscope(addr);
 2184 
 2185         switch (scope) {
 2186         case IPV6_ADDR_SCOPE_NODELOCAL:
 2187                 return (-1);    /* XXX: is this an appropriate value? */
 2188 
 2189         case IPV6_ADDR_SCOPE_LINKLOCAL:
 2190                 /* XXX: we do not distinguish between a link and an I/F. */
 2191                 return (ifp->if_index);
 2192 
 2193         case IPV6_ADDR_SCOPE_SITELOCAL:
 2194                 return (0);     /* XXX: invalid. */
 2195 
 2196         default:
 2197                 return (0);     /* XXX: treat as global. */
 2198         }
 2199 }
 2200 
 2201 int
 2202 in6_is_addr_deprecated(sa6)
 2203         struct sockaddr_in6 *sa6;
 2204 {
 2205         struct in6_ifaddr *ia;
 2206 
 2207         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
 2208                 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
 2209                     &sa6->sin6_addr) &&
 2210 #ifdef SCOPEDROUTING
 2211                     ia->ia_addr.sin6_scope_id == sa6->sin6_scope_id &&
 2212 #endif
 2213                     (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
 2214                         return (1); /* true */
 2215 
 2216                 /* XXX: do we still have to go thru the rest of the list? */
 2217         }
 2218 
 2219         return (0);             /* false */
 2220 }
 2221 
 2222 /*
 2223  * return length of part which dst and src are equal
 2224  * hard coding...
 2225  */
 2226 int
 2227 in6_matchlen(src, dst)
 2228 struct in6_addr *src, *dst;
 2229 {
 2230         int match = 0;
 2231         u_char *s = (u_char *)src, *d = (u_char *)dst;
 2232         u_char *lim = s + 16, r;
 2233 
 2234         while (s < lim)
 2235                 if ((r = (*d++ ^ *s++)) != 0) {
 2236                         while (r < 128) {
 2237                                 match++;
 2238                                 r <<= 1;
 2239                         }
 2240                         break;
 2241                 } else
 2242                         match += 8;
 2243         return match;
 2244 }
 2245 
 2246 /* XXX: to be scope conscious */
 2247 int
 2248 in6_are_prefix_equal(p1, p2, len)
 2249         struct in6_addr *p1, *p2;
 2250         int len;
 2251 {
 2252         int bytelen, bitlen;
 2253 
 2254         /* sanity check */
 2255         if (0 > len || len > 128) {
 2256                 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
 2257                     len);
 2258                 return (0);
 2259         }
 2260 
 2261         bytelen = len / 8;
 2262         bitlen = len % 8;
 2263 
 2264         if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
 2265                 return (0);
 2266         if (bitlen != 0 &&
 2267             p1->s6_addr[bytelen] >> (8 - bitlen) !=
 2268             p2->s6_addr[bytelen] >> (8 - bitlen))
 2269                 return (0);
 2270 
 2271         return (1);
 2272 }
 2273 
 2274 void
 2275 in6_prefixlen2mask(maskp, len)
 2276         struct in6_addr *maskp;
 2277         int len;
 2278 {
 2279         static const u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
 2280         int bytelen, bitlen, i;
 2281 
 2282         /* sanity check */
 2283         if (0 > len || len > 128) {
 2284                 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
 2285                     len);
 2286                 return;
 2287         }
 2288 
 2289         bzero(maskp, sizeof(*maskp));
 2290         bytelen = len / 8;
 2291         bitlen = len % 8;
 2292         for (i = 0; i < bytelen; i++)
 2293                 maskp->s6_addr[i] = 0xff;
 2294         if (bitlen)
 2295                 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
 2296 }
 2297 
 2298 /*
 2299  * return the best address out of the same scope
 2300  */
 2301 struct in6_ifaddr *
 2302 in6_ifawithscope(oifp, dst)
 2303         struct ifnet *oifp;
 2304         struct in6_addr *dst;
 2305 {
 2306         int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
 2307         int blen = -1;
 2308         struct ifaddr *ifa;
 2309         struct ifnet *ifp;
 2310         struct in6_ifaddr *ifa_best = NULL;
 2311 
 2312         if (oifp == NULL) {
 2313                 printf("in6_ifawithscope: output interface is not specified\n");
 2314                 return (NULL);
 2315         }
 2316 
 2317         /*
 2318          * We search for all addresses on all interfaces from the beginning.
 2319          * Comparing an interface with the outgoing interface will be done
 2320          * only at the final stage of tiebreaking.
 2321          */
 2322         for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
 2323         {
 2324                 /*
 2325                  * We can never take an address that breaks the scope zone
 2326                  * of the destination.
 2327                  */
 2328                 if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst))
 2329                         continue;
 2330 
 2331                 for (ifa = ifp->if_addrlist.tqh_first; ifa;
 2332                      ifa = ifa->ifa_list.tqe_next)
 2333                 {
 2334                         int tlen = -1, dscopecmp, bscopecmp, matchcmp;
 2335 
 2336                         if (ifa->ifa_addr->sa_family != AF_INET6)
 2337                                 continue;
 2338 
 2339                         src_scope = in6_addrscope(IFA_IN6(ifa));
 2340 
 2341 #ifdef ADDRSELECT_DEBUG         /* should be removed after stabilization */
 2342                         dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
 2343                         printf("in6_ifawithscope: dst=%s bestaddr=%s, "
 2344                                "newaddr=%s, scope=%x, dcmp=%d, bcmp=%d, "
 2345                                "matchlen=%d, flgs=%x\n",
 2346                                ip6_sprintf(dst),
 2347                                ifa_best ? ip6_sprintf(&ifa_best->ia_addr.sin6_addr) : "none",
 2348                                ip6_sprintf(IFA_IN6(ifa)), src_scope,
 2349                                dscopecmp,
 2350                                ifa_best ? IN6_ARE_SCOPE_CMP(src_scope, best_scope) : -1,
 2351                                in6_matchlen(IFA_IN6(ifa), dst),
 2352                                ((struct in6_ifaddr *)ifa)->ia6_flags);
 2353 #endif
 2354 
 2355                         /*
 2356                          * Don't use an address before completing DAD
 2357                          * nor a duplicated address.
 2358                          */
 2359                         if (((struct in6_ifaddr *)ifa)->ia6_flags &
 2360                             IN6_IFF_NOTREADY)
 2361                                 continue;
 2362 
 2363                         /* XXX: is there any case to allow anycasts? */
 2364                         if (((struct in6_ifaddr *)ifa)->ia6_flags &
 2365                             IN6_IFF_ANYCAST)
 2366                                 continue;
 2367 
 2368                         if (((struct in6_ifaddr *)ifa)->ia6_flags &
 2369                             IN6_IFF_DETACHED)
 2370                                 continue;
 2371 
 2372                         /*
 2373                          * If this is the first address we find,
 2374                          * keep it anyway.
 2375                          */
 2376                         if (ifa_best == NULL)
 2377                                 goto replace;
 2378 
 2379                         /*
 2380                          * ifa_best is never NULL beyond this line except
 2381                          * within the block labeled "replace".
 2382                          */
 2383 
 2384                         /*
 2385                          * If ifa_best has a smaller scope than dst and
 2386                          * the current address has a larger one than
 2387                          * (or equal to) dst, always replace ifa_best.
 2388                          * Also, if the current address has a smaller scope
 2389                          * than dst, ignore it unless ifa_best also has a
 2390                          * smaller scope.
 2391                          */
 2392                         if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
 2393                             IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0)
 2394                                 goto replace;
 2395                         if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
 2396                             IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0)
 2397                                 continue;
 2398 
 2399                         /*
 2400                          * A deprecated address SHOULD NOT be used in new
 2401                          * communications if an alternate (non-deprecated)
 2402                          * address is available and has sufficient scope.
 2403                          * RFC 2462, Section 5.5.4.
 2404                          */
 2405                         if (((struct in6_ifaddr *)ifa)->ia6_flags &
 2406                             IN6_IFF_DEPRECATED) {
 2407                                 /*
 2408                                  * Ignore any deprecated addresses if
 2409                                  * specified by configuration.
 2410                                  */
 2411                                 if (!ip6_use_deprecated)
 2412                                         continue;
 2413 
 2414                                 /*
 2415                                  * If we have already found a non-deprecated
 2416                                  * candidate, just ignore deprecated addresses.
 2417                                  */
 2418                                 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED)
 2419                                     == 0)
 2420                                         continue;
 2421                         }
 2422 
 2423                         /*
 2424                          * A non-deprecated address is always preferred
 2425                          * to a deprecated one regardless of scopes and
 2426                          * address matching.
 2427                          */
 2428                         if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) &&
 2429                             (((struct in6_ifaddr *)ifa)->ia6_flags &
 2430                              IN6_IFF_DEPRECATED) == 0)
 2431                                 goto replace;
 2432 
 2433                         /*
 2434                          * At this point, we have two cases:
 2435                          * 1. we are looking at a non-deprecated address,
 2436                          *    and ifa_best is also non-deprecated.
 2437                          * 2. we are looking at a deprecated address,
 2438                          *    and ifa_best is also deprecated.
 2439                          * Also, we do not have to consider a case where
 2440                          * the scope of if_best is larger(smaller) than dst and
 2441                          * the scope of the current address is smaller(larger)
 2442                          * than dst. Such a case has already been covered.
 2443                          * Tiebreaking is done according to the following
 2444                          * items:
 2445                          * - the scope comparison between the address and
 2446                          *   dst (dscopecmp)
 2447                          * - the scope comparison between the address and
 2448                          *   ifa_best (bscopecmp)
 2449                          * - if the address match dst longer than ifa_best
 2450                          *   (matchcmp)
 2451                          * - if the address is on the outgoing I/F (outI/F)
 2452                          *
 2453                          * Roughly speaking, the selection policy is
 2454                          * - the most important item is scope. The same scope
 2455                          *   is best. Then search for a larger scope.
 2456                          *   Smaller scopes are the last resort.
 2457                          * - A deprecated address is chosen only when we have
 2458                          *   no address that has an enough scope, but is
 2459                          *   prefered to any addresses of smaller scopes.
 2460                          * - Longest address match against dst is considered
 2461                          *   only for addresses that has the same scope of dst.
 2462                          * - If there is no other reasons to choose one,
 2463                          *   addresses on the outgoing I/F are preferred.
 2464                          *
 2465                          * The precise decision table is as follows:
 2466                          * dscopecmp bscopecmp matchcmp outI/F | replace?
 2467                          *    !equal     equal      N/A    Yes |      Yes (1)
 2468                          *    !equal     equal      N/A     No |       No (2)
 2469                          *    larger    larger      N/A    N/A |       No (3)
 2470                          *    larger   smaller      N/A    N/A |      Yes (4)
 2471                          *   smaller    larger      N/A    N/A |      Yes (5)
 2472                          *   smaller   smaller      N/A    N/A |       No (6)
 2473                          *     equal   smaller      N/A    N/A |      Yes (7)
 2474                          *     equal    larger       (already done)
 2475                          *     equal     equal   larger    N/A |      Yes (8)
 2476                          *     equal     equal  smaller    N/A |       No (9)
 2477                          *     equal     equal    equal    Yes |      Yes (a)
 2478                          *     eaual     eqaul    equal     No |       No (b)
 2479                          */
 2480                         dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
 2481                         bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
 2482 
 2483                         if (dscopecmp && bscopecmp == 0) {
 2484                                 if (oifp == ifp) /* (1) */
 2485                                         goto replace;
 2486                                 continue; /* (2) */
 2487                         }
 2488                         if (dscopecmp > 0) {
 2489                                 if (bscopecmp > 0) /* (3) */
 2490                                         continue;
 2491                                 goto replace; /* (4) */
 2492                         }
 2493                         if (dscopecmp < 0) {
 2494                                 if (bscopecmp > 0) /* (5) */
 2495                                         goto replace;
 2496                                 continue; /* (6) */
 2497                         }
 2498 
 2499                         /* now dscopecmp must be 0 */
 2500                         if (bscopecmp < 0)
 2501                                 goto replace; /* (7) */
 2502 
 2503                         /*
 2504                          * At last both dscopecmp and bscopecmp must be 0.
 2505                          * We need address matching against dst for
 2506                          * tiebreaking.
 2507                          */
 2508                         tlen = in6_matchlen(IFA_IN6(ifa), dst);
 2509                         matchcmp = tlen - blen;
 2510                         if (matchcmp > 0) /* (8) */
 2511                                 goto replace;
 2512                         if (matchcmp < 0) /* (9) */
 2513                                 continue;
 2514                         if (oifp == ifp) /* (a) */
 2515                                 goto replace;
 2516                         continue; /* (b) */
 2517 
 2518                   replace:
 2519                         ifa_best = (struct in6_ifaddr *)ifa;
 2520                         blen = tlen >= 0 ? tlen :
 2521                                 in6_matchlen(IFA_IN6(ifa), dst);
 2522                         best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr);
 2523                 }
 2524         }
 2525 
 2526         /* count statistics for future improvements */
 2527         if (ifa_best == NULL)
 2528                 ip6stat.ip6s_sources_none++;
 2529         else {
 2530                 if (oifp == ifa_best->ia_ifp)
 2531                         ip6stat.ip6s_sources_sameif[best_scope]++;
 2532                 else
 2533                         ip6stat.ip6s_sources_otherif[best_scope]++;
 2534 
 2535                 if (best_scope == dst_scope)
 2536                         ip6stat.ip6s_sources_samescope[best_scope]++;
 2537                 else
 2538                         ip6stat.ip6s_sources_otherscope[best_scope]++;
 2539 
 2540                 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
 2541                         ip6stat.ip6s_sources_deprecated[best_scope]++;
 2542         }
 2543 
 2544         return (ifa_best);
 2545 }
 2546 
 2547 /*
 2548  * return the best address out of the same scope. if no address was
 2549  * found, return the first valid address from designated IF.
 2550  */
 2551 struct in6_ifaddr *
 2552 in6_ifawithifp(ifp, dst)
 2553         struct ifnet *ifp;
 2554         struct in6_addr *dst;
 2555 {
 2556         int dst_scope = in6_addrscope(dst), blen = -1, tlen;
 2557         struct ifaddr *ifa;
 2558         struct in6_ifaddr *besta = 0;
 2559         struct in6_ifaddr *dep[2];      /* last-resort: deprecated */
 2560 
 2561         dep[0] = dep[1] = NULL;
 2562 
 2563         /*
 2564          * We first look for addresses in the same scope.
 2565          * If there is one, return it.
 2566          * If two or more, return one which matches the dst longest.
 2567          * If none, return one of global addresses assigned other ifs.
 2568          */
 2569         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
 2570         {
 2571                 if (ifa->ifa_addr->sa_family != AF_INET6)
 2572                         continue;
 2573                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
 2574                         continue; /* XXX: is there any case to allow anycast? */
 2575                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
 2576                         continue; /* don't use this interface */
 2577                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
 2578                         continue;
 2579                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
 2580                         if (ip6_use_deprecated)
 2581                                 dep[0] = (struct in6_ifaddr *)ifa;
 2582                         continue;
 2583                 }
 2584 
 2585                 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
 2586                         /*
 2587                          * call in6_matchlen() as few as possible
 2588                          */
 2589                         if (besta) {
 2590                                 if (blen == -1)
 2591                                         blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
 2592                                 tlen = in6_matchlen(IFA_IN6(ifa), dst);
 2593                                 if (tlen > blen) {
 2594                                         blen = tlen;
 2595                                         besta = (struct in6_ifaddr *)ifa;
 2596                                 }
 2597                         } else
 2598                                 besta = (struct in6_ifaddr *)ifa;
 2599                 }
 2600         }
 2601         if (besta)
 2602                 return (besta);
 2603 
 2604         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
 2605         {
 2606                 if (ifa->ifa_addr->sa_family != AF_INET6)
 2607                         continue;
 2608                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
 2609                         continue; /* XXX: is there any case to allow anycast? */
 2610                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
 2611                         continue; /* don't use this interface */
 2612                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
 2613                         continue;
 2614                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
 2615                         if (ip6_use_deprecated)
 2616                                 dep[1] = (struct in6_ifaddr *)ifa;
 2617                         continue;
 2618                 }
 2619 
 2620                 return (struct in6_ifaddr *)ifa;
 2621         }
 2622 
 2623         /* use the last-resort values, that are, deprecated addresses */
 2624         if (dep[0])
 2625                 return dep[0];
 2626         if (dep[1])
 2627                 return dep[1];
 2628 
 2629         return NULL;
 2630 }
 2631 
 2632 /*
 2633  * perform DAD when interface becomes IFF_UP.
 2634  */
 2635 void
 2636 in6_if_up(ifp)
 2637         struct ifnet *ifp;
 2638 {
 2639         struct ifaddr *ifa;
 2640         struct in6_ifaddr *ia;
 2641         int dad_delay;          /* delay ticks before DAD output */
 2642 
 2643         /*
 2644          * special cases, like 6to4, are handled in in6_ifattach
 2645          */
 2646         in6_ifattach(ifp, NULL);
 2647 
 2648         dad_delay = 0;
 2649         for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next)
 2650         {
 2651                 if (ifa->ifa_addr->sa_family != AF_INET6)
 2652                         continue;
 2653                 ia = (struct in6_ifaddr *)ifa;
 2654                 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
 2655                         nd6_dad_start(ifa, &dad_delay);
 2656         }
 2657 }
 2658 
 2659 int
 2660 in6if_do_dad(ifp)
 2661         struct ifnet *ifp;
 2662 {
 2663         if ((ifp->if_flags & IFF_LOOPBACK) != 0)
 2664                 return (0);
 2665 
 2666         switch (ifp->if_type) {
 2667         case IFT_FAITH:
 2668                 /*
 2669                  * These interfaces do not have the IFF_LOOPBACK flag,
 2670                  * but loop packets back.  We do not have to do DAD on such
 2671                  * interfaces.  We should even omit it, because loop-backed
 2672                  * NS would confuse the DAD procedure.
 2673                  */
 2674                 return (0);
 2675         default:
 2676                 /*
 2677                  * Our DAD routine requires the interface up and running.
 2678                  * However, some interfaces can be up before the RUNNING
 2679                  * status.  Additionaly, users may try to assign addresses
 2680                  * before the interface becomes up (or running).
 2681                  * We simply skip DAD in such a case as a work around.
 2682                  * XXX: we should rather mark "tentative" on such addresses,
 2683                  * and do DAD after the interface becomes ready.
 2684                  */
 2685                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
 2686                     (IFF_UP|IFF_RUNNING))
 2687                         return (0);
 2688 
 2689                 return (1);
 2690         }
 2691 }
 2692 
 2693 /*
 2694  * Calculate max IPv6 MTU through all the interfaces and store it
 2695  * to in6_maxmtu.
 2696  */
 2697 void
 2698 in6_setmaxmtu()
 2699 {
 2700         unsigned long maxmtu = 0;
 2701         struct ifnet *ifp;
 2702 
 2703         for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
 2704         {
 2705                 /* this function can be called during ifnet initialization */
 2706                 if (!ifp->if_afdata[AF_INET6])
 2707                         continue;
 2708                 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
 2709                     IN6_LINKMTU(ifp) > maxmtu)
 2710                         maxmtu = IN6_LINKMTU(ifp);
 2711         }
 2712         if (maxmtu)          /* update only when maxmtu is positive */
 2713                 in6_maxmtu = maxmtu;
 2714 }
 2715 
 2716 void *
 2717 in6_domifattach(ifp)
 2718         struct ifnet *ifp;
 2719 {
 2720         struct in6_ifextra *ext;
 2721 
 2722         ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
 2723         bzero(ext, sizeof(*ext));
 2724 
 2725         ext->in6_ifstat = (struct in6_ifstat *)malloc(sizeof(struct in6_ifstat),
 2726             M_IFADDR, M_WAITOK);
 2727         bzero(ext->in6_ifstat, sizeof(*ext->in6_ifstat));
 2728 
 2729         ext->icmp6_ifstat =
 2730             (struct icmp6_ifstat *)malloc(sizeof(struct icmp6_ifstat),
 2731             M_IFADDR, M_WAITOK);
 2732         bzero(ext->icmp6_ifstat, sizeof(*ext->icmp6_ifstat));
 2733 
 2734         ext->nd_ifinfo = nd6_ifattach(ifp);
 2735         return ext;
 2736 }
 2737 
 2738 void
 2739 in6_domifdetach(ifp, aux)
 2740         struct ifnet *ifp;
 2741         void *aux;
 2742 {
 2743         struct in6_ifextra *ext = (struct in6_ifextra *)aux;
 2744 
 2745         nd6_ifdetach(ext->nd_ifinfo);
 2746         free(ext->in6_ifstat, M_IFADDR);
 2747         free(ext->icmp6_ifstat, M_IFADDR);
 2748         free(ext, M_IFADDR);
 2749 }

Cache object: 527fde2e7526083af16761068ba8cfa7


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