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 /*      $FreeBSD: releng/5.2/sys/netinet6/in6.c 122334 2003-11-08 23:36:32Z sam $       */
    2 /*      $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi 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. All advertising materials mentioning features or use of this software
   46  *    must display the following acknowledgement:
   47  *      This product includes software developed by the University of
   48  *      California, Berkeley and its contributors.
   49  * 4. Neither the name of the University nor the names of its contributors
   50  *    may be used to endorse or promote products derived from this software
   51  *    without specific prior written permission.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   63  * SUCH DAMAGE.
   64  *
   65  *      @(#)in.c        8.2 (Berkeley) 11/15/93
   66  */
   67 
   68 #include "opt_inet.h"
   69 #include "opt_inet6.h"
   70 
   71 #include <sys/param.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 <netinet/if_ether.h>
   91 #include <netinet/in_systm.h>
   92 #include <netinet/ip.h>
   93 #include <netinet/in_pcb.h>
   94 
   95 #include <netinet/ip6.h>
   96 #include <netinet6/ip6_var.h>
   97 #include <netinet6/nd6.h>
   98 #include <netinet6/mld6_var.h>
   99 #include <netinet6/ip6_mroute.h>
  100 #include <netinet6/in6_ifattach.h>
  101 #include <netinet6/scope6_var.h>
  102 #include <netinet6/in6_pcb.h>
  103 
  104 #include <net/net_osdep.h>
  105 
  106 MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address");
  107 
  108 /*
  109  * Definitions of some costant IP6 addresses.
  110  */
  111 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
  112 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
  113 const struct in6_addr in6addr_nodelocal_allnodes =
  114         IN6ADDR_NODELOCAL_ALLNODES_INIT;
  115 const struct in6_addr in6addr_linklocal_allnodes =
  116         IN6ADDR_LINKLOCAL_ALLNODES_INIT;
  117 const struct in6_addr in6addr_linklocal_allrouters =
  118         IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
  119 
  120 const struct in6_addr in6mask0 = IN6MASK0;
  121 const struct in6_addr in6mask32 = IN6MASK32;
  122 const struct in6_addr in6mask64 = IN6MASK64;
  123 const struct in6_addr in6mask96 = IN6MASK96;
  124 const struct in6_addr in6mask128 = IN6MASK128;
  125 
  126 const struct sockaddr_in6 sa6_any = {sizeof(sa6_any), AF_INET6,
  127                                      0, 0, IN6ADDR_ANY_INIT, 0};
  128 
  129 static int in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
  130         struct ifnet *, struct thread *));
  131 static int in6_ifinit __P((struct ifnet *, struct in6_ifaddr *,
  132         struct sockaddr_in6 *, int));
  133 static void in6_unlink_ifa __P((struct in6_ifaddr *, struct ifnet *));
  134 
  135 struct in6_multihead in6_multihead;     /* XXX BSS initialization */
  136 int     (*faithprefix_p)(struct in6_addr *);
  137 
  138 /*
  139  * Subroutine for in6_ifaddloop() and in6_ifremloop().
  140  * This routine does actual work.
  141  */
  142 static void
  143 in6_ifloop_request(int cmd, struct ifaddr *ifa)
  144 {
  145         struct sockaddr_in6 all1_sa;
  146         struct rtentry *nrt = NULL;
  147         int e;
  148 
  149         bzero(&all1_sa, sizeof(all1_sa));
  150         all1_sa.sin6_family = AF_INET6;
  151         all1_sa.sin6_len = sizeof(struct sockaddr_in6);
  152         all1_sa.sin6_addr = in6mask128;
  153 
  154         /*
  155          * We specify the address itself as the gateway, and set the
  156          * RTF_LLINFO flag, so that the corresponding host route would have
  157          * the flag, and thus applications that assume traditional behavior
  158          * would be happy.  Note that we assume the caller of the function
  159          * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
  160          * which changes the outgoing interface to the loopback interface.
  161          */
  162         e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr,
  163             (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
  164         if (e != 0) {
  165                 /* XXX need more descriptive message */
  166                 log(LOG_ERR, "in6_ifloop_request: "
  167                     "%s operation failed for %s (errno=%d)\n",
  168                     cmd == RTM_ADD ? "ADD" : "DELETE",
  169                     ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
  170                     e);
  171         }
  172 
  173         if (nrt) {
  174                 RT_LOCK(nrt);
  175                 /*
  176                  * Make sure rt_ifa be equal to IFA, the second argument of
  177                  * the function.  We need this because when we refer to
  178                  * rt_ifa->ia6_flags in ip6_input, we assume that the rt_ifa
  179                  * points to the address instead of the loopback address.
  180                  */
  181                 if (cmd == RTM_ADD && ifa != nrt->rt_ifa) {
  182                         IFAFREE(nrt->rt_ifa);
  183                         IFAREF(ifa);
  184                         nrt->rt_ifa = ifa;
  185                 }
  186 
  187                 /*
  188                  * Report the addition/removal of the address to the routing
  189                  * socket.
  190                  *
  191                  * XXX: since we called rtinit for a p2p interface with a
  192                  *      destination, we end up reporting twice in such a case.
  193                  *      Should we rather omit the second report?
  194                  */
  195                 rt_newaddrmsg(cmd, ifa, e, nrt);
  196                 if (cmd == RTM_DELETE) {
  197                         rtfree(nrt);
  198                 } else {
  199                         /* the cmd must be RTM_ADD here */
  200                         RT_REMREF(nrt);
  201                         RT_UNLOCK(nrt);
  202                 }
  203         }
  204 }
  205 
  206 /*
  207  * Add ownaddr as loopback rtentry.  We previously add the route only if
  208  * necessary (ex. on a p2p link).  However, since we now manage addresses
  209  * separately from prefixes, we should always add the route.  We can't
  210  * rely on the cloning mechanism from the corresponding interface route
  211  * any more.
  212  */
  213 static void
  214 in6_ifaddloop(struct ifaddr *ifa)
  215 {
  216         struct rtentry *rt;
  217         int need_loop;
  218 
  219         /* If there is no loopback entry, allocate one. */
  220         rt = rtalloc1(ifa->ifa_addr, 0, 0);
  221         need_loop = (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
  222             (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0);
  223         if (rt)
  224                 rtfree(rt);
  225         if (need_loop)
  226                 in6_ifloop_request(RTM_ADD, ifa);
  227 }
  228 
  229 /*
  230  * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
  231  * if it exists.
  232  */
  233 static void
  234 in6_ifremloop(struct ifaddr *ifa)
  235 {
  236         struct in6_ifaddr *ia;
  237         struct rtentry *rt;
  238         int ia_count = 0;
  239 
  240         /*
  241          * Some of BSD variants do not remove cloned routes
  242          * from an interface direct route, when removing the direct route
  243          * (see comments in net/net_osdep.h).  Even for variants that do remove
  244          * cloned routes, they could fail to remove the cloned routes when
  245          * we handle multple addresses that share a common prefix.
  246          * So, we should remove the route corresponding to the deleted address
  247          * regardless of the result of in6_is_ifloop_auto().
  248          */
  249 
  250         /*
  251          * Delete the entry only if exact one ifa exists.  More than one ifa
  252          * can exist if we assign a same single address to multiple
  253          * (probably p2p) interfaces.
  254          * XXX: we should avoid such a configuration in IPv6...
  255          */
  256         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
  257                 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ia->ia_addr.sin6_addr)) {
  258                         ia_count++;
  259                         if (ia_count > 1)
  260                                 break;
  261                 }
  262         }
  263 
  264         if (ia_count == 1) {
  265                 /*
  266                  * Before deleting, check if a corresponding loopbacked host
  267                  * route surely exists.  With this check, we can avoid to
  268                  * delete an interface direct route whose destination is same
  269                  * as the address being removed.  This can happen when removing
  270                  * a subnet-router anycast address on an interface attahced
  271                  * to a shared medium.
  272                  */
  273                 rt = rtalloc1(ifa->ifa_addr, 0, 0);
  274                 if (rt != NULL) {
  275                         if ((rt->rt_flags & RTF_HOST) != 0 &&
  276                             (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
  277                                 rtfree(rt);
  278                                 in6_ifloop_request(RTM_DELETE, ifa);
  279                         } else
  280                                 RT_UNLOCK(rt);
  281                 }
  282         }
  283 }
  284 
  285 int
  286 in6_mask2len(mask, lim0)
  287         struct in6_addr *mask;
  288         u_char *lim0;
  289 {
  290         int x = 0, y;
  291         u_char *lim = lim0, *p;
  292 
  293         /* ignore the scope_id part */
  294         if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask))
  295                 lim = (u_char *)mask + sizeof(*mask);
  296         for (p = (u_char *)mask; p < lim; x++, p++) {
  297                 if (*p != 0xff)
  298                         break;
  299         }
  300         y = 0;
  301         if (p < lim) {
  302                 for (y = 0; y < 8; y++) {
  303                         if ((*p & (0x80 >> y)) == 0)
  304                                 break;
  305                 }
  306         }
  307 
  308         /*
  309          * when the limit pointer is given, do a stricter check on the
  310          * remaining bits.
  311          */
  312         if (p < lim) {
  313                 if (y != 0 && (*p & (0x00ff >> y)) != 0)
  314                         return (-1);
  315                 for (p = p + 1; p < lim; p++)
  316                         if (*p != 0)
  317                                 return (-1);
  318         }
  319 
  320         return x * 8 + y;
  321 }
  322 
  323 #define ifa2ia6(ifa)    ((struct in6_ifaddr *)(ifa))
  324 #define ia62ifa(ia6)    (&((ia6)->ia_ifa))
  325 
  326 int
  327 in6_control(so, cmd, data, ifp, td)
  328         struct  socket *so;
  329         u_long cmd;
  330         caddr_t data;
  331         struct ifnet *ifp;
  332         struct thread *td;
  333 {
  334         struct  in6_ifreq *ifr = (struct in6_ifreq *)data;
  335         struct  in6_ifaddr *ia = NULL;
  336         struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
  337         int privileged;
  338 
  339         privileged = 0;
  340         if (td == NULL || !suser(td))
  341                 privileged++;
  342 
  343         switch (cmd) {
  344         case SIOCGETSGCNT_IN6:
  345         case SIOCGETMIFCNT_IN6:
  346                 return (mrt6_ioctl(cmd, data));
  347         }
  348 
  349         switch(cmd) {
  350         case SIOCAADDRCTL_POLICY:
  351         case SIOCDADDRCTL_POLICY:
  352                 if (!privileged)
  353                         return (EPERM);
  354                 return (in6_src_ioctl(cmd, data));
  355         }
  356 
  357         if (ifp == NULL)
  358                 return (EOPNOTSUPP);
  359 
  360         switch (cmd) {
  361         case SIOCSNDFLUSH_IN6:
  362         case SIOCSPFXFLUSH_IN6:
  363         case SIOCSRTRFLUSH_IN6:
  364         case SIOCSDEFIFACE_IN6:
  365         case SIOCSIFINFO_FLAGS:
  366                 if (!privileged)
  367                         return (EPERM);
  368                 /* FALLTHROUGH */
  369         case OSIOCGIFINFO_IN6:
  370         case SIOCGIFINFO_IN6:
  371         case SIOCGDRLST_IN6:
  372         case SIOCGPRLST_IN6:
  373         case SIOCGNBRINFO_IN6:
  374         case SIOCGDEFIFACE_IN6:
  375                 return (nd6_ioctl(cmd, data, ifp));
  376         }
  377 
  378         switch (cmd) {
  379         case SIOCSIFPREFIX_IN6:
  380         case SIOCDIFPREFIX_IN6:
  381         case SIOCAIFPREFIX_IN6:
  382         case SIOCCIFPREFIX_IN6:
  383         case SIOCSGIFPREFIX_IN6:
  384         case SIOCGIFPREFIX_IN6:
  385                 log(LOG_NOTICE,
  386                     "prefix ioctls are now invalidated. "
  387                     "please use ifconfig.\n");
  388                 return (EOPNOTSUPP);
  389         }
  390 
  391         switch (cmd) {
  392         case SIOCSSCOPE6:
  393                 if (!privileged)
  394                         return (EPERM);
  395                 return (scope6_set(ifp,
  396                     (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
  397         case SIOCGSCOPE6:
  398                 return (scope6_get(ifp,
  399                     (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id));
  400         case SIOCGSCOPE6DEF:
  401                 return (scope6_get_default((struct scope6_id *)
  402                     ifr->ifr_ifru.ifru_scope_id));
  403         }
  404 
  405         switch (cmd) {
  406         case SIOCALIFADDR:
  407         case SIOCDLIFADDR:
  408                 if (!privileged)
  409                         return (EPERM);
  410                 /* FALLTHROUGH */
  411         case SIOCGLIFADDR:
  412                 return in6_lifaddr_ioctl(so, cmd, data, ifp, td);
  413         }
  414 
  415         /*
  416          * Find address for this interface, if it exists.
  417          */
  418         if (ifra->ifra_addr.sin6_family == AF_INET6) { /* XXX */
  419                 struct sockaddr_in6 *sa6 =
  420                         (struct sockaddr_in6 *)&ifra->ifra_addr;
  421 
  422                 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
  423                         if (sa6->sin6_addr.s6_addr16[1] == 0) {
  424                                 /* link ID is not embedded by the user */
  425                                 sa6->sin6_addr.s6_addr16[1] =
  426                                     htons(ifp->if_index);
  427                         } else if (sa6->sin6_addr.s6_addr16[1] !=
  428                             htons(ifp->if_index)) {
  429                                 return (EINVAL);        /* link ID contradicts */
  430                         }
  431                         if (sa6->sin6_scope_id) {
  432                                 if (sa6->sin6_scope_id !=
  433                                     (u_int32_t)ifp->if_index)
  434                                         return (EINVAL);
  435                                 sa6->sin6_scope_id = 0; /* XXX: good way? */
  436                         }
  437                 }
  438                 ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
  439         }
  440 
  441         switch (cmd) {
  442         case SIOCSIFADDR_IN6:
  443         case SIOCSIFDSTADDR_IN6:
  444         case SIOCSIFNETMASK_IN6:
  445                 /*
  446                  * Since IPv6 allows a node to assign multiple addresses
  447                  * on a single interface, SIOCSIFxxx ioctls are not suitable
  448                  * and should be unused.
  449                  */
  450                 /* we decided to obsolete this command (20000704) */
  451                 return (EINVAL);
  452 
  453         case SIOCDIFADDR_IN6:
  454                 /*
  455                  * for IPv4, we look for existing in_ifaddr here to allow
  456                  * "ifconfig if0 delete" to remove first IPv4 address on the
  457                  * interface.  For IPv6, as the spec allow multiple interface
  458                  * address from the day one, we consider "remove the first one"
  459                  * semantics to be not preferable.
  460                  */
  461                 if (ia == NULL)
  462                         return (EADDRNOTAVAIL);
  463                 /* FALLTHROUGH */
  464         case SIOCAIFADDR_IN6:
  465                 /*
  466                  * We always require users to specify a valid IPv6 address for
  467                  * the corresponding operation.
  468                  */
  469                 if (ifra->ifra_addr.sin6_family != AF_INET6 ||
  470                     ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6))
  471                         return (EAFNOSUPPORT);
  472                 if (!privileged)
  473                         return (EPERM);
  474 
  475                 break;
  476 
  477         case SIOCGIFADDR_IN6:
  478                 /* This interface is basically deprecated. use SIOCGIFCONF. */
  479                 /* FALLTHROUGH */
  480         case SIOCGIFAFLAG_IN6:
  481         case SIOCGIFNETMASK_IN6:
  482         case SIOCGIFDSTADDR_IN6:
  483         case SIOCGIFALIFETIME_IN6:
  484                 /* must think again about its semantics */
  485                 if (ia == NULL)
  486                         return (EADDRNOTAVAIL);
  487                 break;
  488         case SIOCSIFALIFETIME_IN6:
  489             {
  490                 struct in6_addrlifetime *lt;
  491 
  492                 if (!privileged)
  493                         return (EPERM);
  494                 if (ia == NULL)
  495                         return (EADDRNOTAVAIL);
  496                 /* sanity for overflow - beware unsigned */
  497                 lt = &ifr->ifr_ifru.ifru_lifetime;
  498                 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
  499                  && lt->ia6t_vltime + time_second < time_second) {
  500                         return EINVAL;
  501                 }
  502                 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
  503                  && lt->ia6t_pltime + time_second < time_second) {
  504                         return EINVAL;
  505                 }
  506                 break;
  507             }
  508         }
  509 
  510         switch (cmd) {
  511 
  512         case SIOCGIFADDR_IN6:
  513                 ifr->ifr_addr = ia->ia_addr;
  514                 break;
  515 
  516         case SIOCGIFDSTADDR_IN6:
  517                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
  518                         return (EINVAL);
  519                 /*
  520                  * XXX: should we check if ifa_dstaddr is NULL and return
  521                  * an error?
  522                  */
  523                 ifr->ifr_dstaddr = ia->ia_dstaddr;
  524                 break;
  525 
  526         case SIOCGIFNETMASK_IN6:
  527                 ifr->ifr_addr = ia->ia_prefixmask;
  528                 break;
  529 
  530         case SIOCGIFAFLAG_IN6:
  531                 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
  532                 break;
  533 
  534         case SIOCGIFSTAT_IN6:
  535                 if (ifp == NULL)
  536                         return EINVAL;
  537                 bzero(&ifr->ifr_ifru.ifru_stat,
  538                     sizeof(ifr->ifr_ifru.ifru_stat));
  539                 ifr->ifr_ifru.ifru_stat =
  540                     *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->in6_ifstat;
  541                 break;
  542 
  543         case SIOCGIFSTAT_ICMP6:
  544                 if (ifp == NULL)
  545                         return EINVAL;
  546                 bzero(&ifr->ifr_ifru.ifru_stat,
  547                     sizeof(ifr->ifr_ifru.ifru_icmp6stat));
  548                 ifr->ifr_ifru.ifru_icmp6stat =
  549                     *((struct in6_ifextra *)ifp->if_afdata[AF_INET6])->icmp6_ifstat;
  550                 break;
  551 
  552         case SIOCGIFALIFETIME_IN6:
  553                 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
  554                 break;
  555 
  556         case SIOCSIFALIFETIME_IN6:
  557                 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
  558                 /* for sanity */
  559                 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
  560                         ia->ia6_lifetime.ia6t_expire =
  561                                 time_second + ia->ia6_lifetime.ia6t_vltime;
  562                 } else
  563                         ia->ia6_lifetime.ia6t_expire = 0;
  564                 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
  565                         ia->ia6_lifetime.ia6t_preferred =
  566                                 time_second + ia->ia6_lifetime.ia6t_pltime;
  567                 } else
  568                         ia->ia6_lifetime.ia6t_preferred = 0;
  569                 break;
  570 
  571         case SIOCAIFADDR_IN6:
  572         {
  573                 int i, error = 0;
  574                 struct nd_prefix pr0, *pr;
  575 
  576                 /*
  577                  * first, make or update the interface address structure,
  578                  * and link it to the list.
  579                  */
  580                 if ((error = in6_update_ifa(ifp, ifra, ia)) != 0)
  581                         return (error);
  582 
  583                 /*
  584                  * then, make the prefix on-link on the interface.
  585                  * XXX: we'd rather create the prefix before the address, but
  586                  * we need at least one address to install the corresponding
  587                  * interface route, so we configure the address first.
  588                  */
  589 
  590                 /*
  591                  * convert mask to prefix length (prefixmask has already
  592                  * been validated in in6_update_ifa().
  593                  */
  594                 bzero(&pr0, sizeof(pr0));
  595                 pr0.ndpr_ifp = ifp;
  596                 pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
  597                     NULL);
  598                 if (pr0.ndpr_plen == 128) {
  599                         break;  /* we don't need to install a host route. */
  600                 }
  601                 pr0.ndpr_prefix = ifra->ifra_addr;
  602                 pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
  603                 /* apply the mask for safety. */
  604                 for (i = 0; i < 4; i++) {
  605                         pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
  606                             ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
  607                 }
  608                 /*
  609                  * XXX: since we don't have an API to set prefix (not address)
  610                  * lifetimes, we just use the same lifetimes as addresses.
  611                  * The (temporarily) installed lifetimes can be overridden by
  612                  * later advertised RAs (when accept_rtadv is non 0), which is
  613                  * an intended behavior.
  614                  */
  615                 pr0.ndpr_raf_onlink = 1; /* should be configurable? */
  616                 pr0.ndpr_raf_auto =
  617                     ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
  618                 pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
  619                 pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
  620 
  621                 /* add the prefix if not yet. */
  622                 if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
  623                         /*
  624                          * nd6_prelist_add will install the corresponding
  625                          * interface route.
  626                          */
  627                         if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
  628                                 return (error);
  629                         if (pr == NULL) {
  630                                 log(LOG_ERR, "nd6_prelist_add succeeded but "
  631                                     "no prefix\n");
  632                                 return (EINVAL); /* XXX panic here? */
  633                         }
  634                 }
  635                 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
  636                     == NULL) {
  637                         /* XXX: this should not happen! */
  638                         log(LOG_ERR, "in6_control: addition succeeded, but"
  639                             " no ifaddr\n");
  640                 } else {
  641                         if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
  642                             ia->ia6_ndpr == NULL) { /* new autoconfed addr */
  643                                 ia->ia6_ndpr = pr;
  644                                 pr->ndpr_refcnt++;
  645 
  646                                 /*
  647                                  * If this is the first autoconf address from
  648                                  * the prefix, create a temporary address
  649                                  * as well (when specified).
  650                                  */
  651                                 if (ip6_use_tempaddr &&
  652                                     pr->ndpr_refcnt == 1) {
  653                                         int e;
  654                                         if ((e = in6_tmpifadd(ia, 1)) != 0) {
  655                                                 log(LOG_NOTICE, "in6_control: "
  656                                                     "failed to create a "
  657                                                     "temporary address, "
  658                                                     "errno=%d\n", e);
  659                                         }
  660                                 }
  661                         }
  662 
  663                         /*
  664                          * this might affect the status of autoconfigured
  665                          * addresses, that is, this address might make
  666                          * other addresses detached.
  667                          */
  668                         pfxlist_onlink_check();
  669                 }
  670                 break;
  671         }
  672 
  673         case SIOCDIFADDR_IN6:
  674         {
  675                 int i = 0;
  676                 struct nd_prefix pr0, *pr;
  677 
  678                 /*
  679                  * If the address being deleted is the only one that owns
  680                  * the corresponding prefix, expire the prefix as well.
  681                  * XXX: theoretically, we don't have to worry about such
  682                  * relationship, since we separate the address management
  683                  * and the prefix management.  We do this, however, to provide
  684                  * as much backward compatibility as possible in terms of
  685                  * the ioctl operation.
  686                  */
  687                 bzero(&pr0, sizeof(pr0));
  688                 pr0.ndpr_ifp = ifp;
  689                 pr0.ndpr_plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr,
  690                                              NULL);
  691                 if (pr0.ndpr_plen == 128)
  692                         goto purgeaddr;
  693                 pr0.ndpr_prefix = ia->ia_addr;
  694                 pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
  695                 for (i = 0; i < 4; i++) {
  696                         pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
  697                                 ia->ia_prefixmask.sin6_addr.s6_addr32[i];
  698                 }
  699                 /*
  700                  * The logic of the following condition is a bit complicated.
  701                  * We expire the prefix when
  702                  * 1. the address obeys autoconfiguration and it is the
  703                  *    only owner of the associated prefix, or
  704                  * 2. the address does not obey autoconf and there is no
  705                  *    other owner of the prefix.
  706                  */
  707                 if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
  708                     (((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
  709                       pr->ndpr_refcnt == 1) ||
  710                      ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0 &&
  711                       pr->ndpr_refcnt == 0))) {
  712                         pr->ndpr_expire = 1; /* XXX: just for expiration */
  713                 }
  714 
  715           purgeaddr:
  716                 in6_purgeaddr(&ia->ia_ifa);
  717                 break;
  718         }
  719 
  720         default:
  721                 if (ifp == NULL || ifp->if_ioctl == 0)
  722                         return (EOPNOTSUPP);
  723                 return ((*ifp->if_ioctl)(ifp, cmd, data));
  724         }
  725 
  726         return (0);
  727 }
  728 
  729 /*
  730  * Update parameters of an IPv6 interface address.
  731  * If necessary, a new entry is created and linked into address chains.
  732  * This function is separated from in6_control().
  733  * XXX: should this be performed under splnet()?
  734  */
  735 int
  736 in6_update_ifa(ifp, ifra, ia)
  737         struct ifnet *ifp;
  738         struct in6_aliasreq *ifra;
  739         struct in6_ifaddr *ia;
  740 {
  741         int error = 0, hostIsNew = 0, plen = -1;
  742         struct in6_ifaddr *oia;
  743         struct sockaddr_in6 dst6;
  744         struct in6_addrlifetime *lt;
  745 
  746         /* Validate parameters */
  747         if (ifp == NULL || ifra == NULL) /* this maybe redundant */
  748                 return (EINVAL);
  749 
  750         /*
  751          * The destination address for a p2p link must have a family
  752          * of AF_UNSPEC or AF_INET6.
  753          */
  754         if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
  755             ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
  756             ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
  757                 return (EAFNOSUPPORT);
  758         /*
  759          * validate ifra_prefixmask.  don't check sin6_family, netmask
  760          * does not carry fields other than sin6_len.
  761          */
  762         if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
  763                 return (EINVAL);
  764         /*
  765          * Because the IPv6 address architecture is classless, we require
  766          * users to specify a (non 0) prefix length (mask) for a new address.
  767          * We also require the prefix (when specified) mask is valid, and thus
  768          * reject a non-consecutive mask.
  769          */
  770         if (ia == NULL && ifra->ifra_prefixmask.sin6_len == 0)
  771                 return (EINVAL);
  772         if (ifra->ifra_prefixmask.sin6_len != 0) {
  773                 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
  774                     (u_char *)&ifra->ifra_prefixmask +
  775                     ifra->ifra_prefixmask.sin6_len);
  776                 if (plen <= 0)
  777                         return (EINVAL);
  778         } else {
  779                 /*
  780                  * In this case, ia must not be NULL.  We just use its prefix
  781                  * length.
  782                  */
  783                 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
  784         }
  785         /*
  786          * If the destination address on a p2p interface is specified,
  787          * and the address is a scoped one, validate/set the scope
  788          * zone identifier.
  789          */
  790         dst6 = ifra->ifra_dstaddr;
  791         if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
  792             (dst6.sin6_family == AF_INET6)) {
  793                 int scopeid;
  794 
  795                 if ((error = in6_recoverscope(&dst6,
  796                     &ifra->ifra_dstaddr.sin6_addr, ifp)) != 0)
  797                         return (error);
  798                 if (in6_addr2zoneid(ifp, &dst6.sin6_addr, &scopeid))
  799                         return (EINVAL);
  800                 if (dst6.sin6_scope_id == 0) /* user omit to specify the ID. */
  801                         dst6.sin6_scope_id = scopeid;
  802                 else if (dst6.sin6_scope_id != scopeid)
  803                         return (EINVAL); /* scope ID mismatch. */
  804                 if ((error = in6_embedscope(&dst6.sin6_addr, &dst6, NULL, NULL))
  805                     != 0)
  806                         return (error);
  807                 dst6.sin6_scope_id = 0; /* XXX */
  808         }
  809         /*
  810          * The destination address can be specified only for a p2p or a
  811          * loopback interface.  If specified, the corresponding prefix length
  812          * must be 128.
  813          */
  814         if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
  815                 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
  816                         nd6log((LOG_INFO, "in6_update_ifa: a destination can "
  817                             "be specified for a p2p or a loopback IF only\n"));
  818                         return (EINVAL);
  819                 }
  820                 if (plen != 128) {
  821                         nd6log((LOG_INFO, "in6_update_ifa: prefixlen should "
  822                             "be 128 when dstaddr is specified\n"));
  823                         return (EINVAL);
  824                 }
  825         }
  826         /* lifetime consistency check */
  827         lt = &ifra->ifra_lifetime;
  828         if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
  829             && lt->ia6t_vltime + time_second < time_second) {
  830                 return EINVAL;
  831         }
  832         if (lt->ia6t_vltime == 0) {
  833                 /*
  834                  * the following log might be noisy, but this is a typical
  835                  * configuration mistake or a tool's bug.
  836                  */
  837                 nd6log((LOG_INFO,
  838                     "in6_update_ifa: valid lifetime is 0 for %s\n",
  839                     ip6_sprintf(&ifra->ifra_addr.sin6_addr)));
  840         }
  841         if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
  842             && lt->ia6t_pltime + time_second < time_second) {
  843                 return EINVAL;
  844         }
  845 
  846         /*
  847          * If this is a new address, allocate a new ifaddr and link it
  848          * into chains.
  849          */
  850         if (ia == NULL) {
  851                 hostIsNew = 1;
  852                 /*
  853                  * When in6_update_ifa() is called in a process of a received
  854                  * RA, it is called under an interrupt context.  So, we should
  855                  * call malloc with M_NOWAIT.
  856                  */
  857                 ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR,
  858                     M_NOWAIT);
  859                 if (ia == NULL)
  860                         return (ENOBUFS);
  861                 bzero((caddr_t)ia, sizeof(*ia));
  862                 /* Initialize the address and masks */
  863                 IFA_LOCK_INIT(&ia->ia_ifa);
  864                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
  865                 ia->ia_addr.sin6_family = AF_INET6;
  866                 ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
  867                 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
  868                         /*
  869                          * XXX: some functions expect that ifa_dstaddr is not
  870                          * NULL for p2p interfaces.
  871                          */
  872                         ia->ia_ifa.ifa_dstaddr =
  873                             (struct sockaddr *)&ia->ia_dstaddr;
  874                 } else {
  875                         ia->ia_ifa.ifa_dstaddr = NULL;
  876                 }
  877                 ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
  878 
  879                 ia->ia_ifp = ifp;
  880                 if ((oia = in6_ifaddr) != NULL) {
  881                         for ( ; oia->ia_next; oia = oia->ia_next)
  882                                 continue;
  883                         oia->ia_next = ia;
  884                 } else
  885                         in6_ifaddr = ia;
  886 
  887                 ia->ia_ifa.ifa_refcnt = 1;
  888                 TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
  889         }
  890 
  891         /* set prefix mask */
  892         if (ifra->ifra_prefixmask.sin6_len) {
  893                 /*
  894                  * We prohibit changing the prefix length of an existing
  895                  * address, because
  896                  * + such an operation should be rare in IPv6, and
  897                  * + the operation would confuse prefix management.
  898                  */
  899                 if (ia->ia_prefixmask.sin6_len &&
  900                     in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
  901                         nd6log((LOG_INFO, "in6_update_ifa: the prefix length of an"
  902                             " existing (%s) address should not be changed\n",
  903                             ip6_sprintf(&ia->ia_addr.sin6_addr)));
  904                         error = EINVAL;
  905                         goto unlink;
  906                 }
  907                 ia->ia_prefixmask = ifra->ifra_prefixmask;
  908         }
  909 
  910         /*
  911          * If a new destination address is specified, scrub the old one and
  912          * install the new destination.  Note that the interface must be
  913          * p2p or loopback (see the check above.)
  914          */
  915         if (dst6.sin6_family == AF_INET6 &&
  916             !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia->ia_dstaddr.sin6_addr)) {
  917                 int e;
  918 
  919                 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
  920                     (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST)) != 0) {
  921                         nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
  922                             "a route to the old destination: %s\n",
  923                             ip6_sprintf(&ia->ia_addr.sin6_addr)));
  924                         /* proceed anyway... */
  925                 } else
  926                         ia->ia_flags &= ~IFA_ROUTE;
  927                 ia->ia_dstaddr = dst6;
  928         }
  929 
  930         /* reset the interface and routing table appropriately. */
  931         if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
  932                 goto unlink;
  933 
  934         /*
  935          * Beyond this point, we should call in6_purgeaddr upon an error,
  936          * not just go to unlink.
  937          */
  938 
  939         if ((ifp->if_flags & IFF_MULTICAST) != 0) {
  940                 struct sockaddr_in6 mltaddr, mltmask;
  941                 struct in6_multi *in6m;
  942 
  943                 if (hostIsNew) {
  944                         /* join solicited multicast addr for new host id */
  945                         struct in6_addr llsol;
  946 
  947                         bzero(&llsol, sizeof(struct in6_addr));
  948                         llsol.s6_addr16[0] = htons(0xff02);
  949                         llsol.s6_addr16[1] = htons(ifp->if_index);
  950                         llsol.s6_addr32[1] = 0;
  951                         llsol.s6_addr32[2] = htonl(1);
  952                         llsol.s6_addr32[3] =
  953                                 ifra->ifra_addr.sin6_addr.s6_addr32[3];
  954                         llsol.s6_addr8[12] = 0xff;
  955                         (void)in6_addmulti(&llsol, ifp, &error);
  956                         if (error != 0) {
  957                                 nd6log((LOG_WARNING,
  958                                     "in6_update_ifa: addmulti failed for "
  959                                     "%s on %s (errno=%d)\n",
  960                                     ip6_sprintf(&llsol), if_name(ifp),
  961                                     error));
  962                                 in6_purgeaddr((struct ifaddr *)ia);
  963                                 return (error);
  964                         }
  965                 }
  966 
  967                 bzero(&mltmask, sizeof(mltmask));
  968                 mltmask.sin6_len = sizeof(struct sockaddr_in6);
  969                 mltmask.sin6_family = AF_INET6;
  970                 mltmask.sin6_addr = in6mask32;
  971 
  972                 /*
  973                  * join link-local all-nodes address
  974                  */
  975                 bzero(&mltaddr, sizeof(mltaddr));
  976                 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
  977                 mltaddr.sin6_family = AF_INET6;
  978                 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
  979                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
  980 
  981                 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
  982                 if (in6m == NULL) {
  983                         rtrequest(RTM_ADD,
  984                                   (struct sockaddr *)&mltaddr,
  985                                   (struct sockaddr *)&ia->ia_addr,
  986                                   (struct sockaddr *)&mltmask,
  987                                   RTF_UP|RTF_CLONING,  /* xxx */
  988                                   (struct rtentry **)0);
  989                         (void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error);
  990                         if (error != 0) {
  991                                 nd6log((LOG_WARNING,
  992                                     "in6_update_ifa: addmulti failed for "
  993                                     "%s on %s (errno=%d)\n",
  994                                     ip6_sprintf(&mltaddr.sin6_addr),
  995                                     if_name(ifp), error));
  996                         }
  997                 }
  998 
  999                 /*
 1000                  * join node information group address
 1001                  */
 1002 #define hostnamelen     strlen(hostname)
 1003                 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
 1004                     == 0) {
 1005                         IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
 1006                         if (in6m == NULL && ia != NULL) {
 1007                                 (void)in6_addmulti(&mltaddr.sin6_addr,
 1008                                     ifp, &error);
 1009                                 if (error != 0) {
 1010                                         nd6log((LOG_WARNING, "in6_update_ifa: "
 1011                                             "addmulti failed for "
 1012                                             "%s on %s (errno=%d)\n",
 1013                                             ip6_sprintf(&mltaddr.sin6_addr),
 1014                                             if_name(ifp), error));
 1015                                 }
 1016                         }
 1017                 }
 1018 #undef hostnamelen
 1019 
 1020                 /*
 1021                  * join node-local all-nodes address, on loopback.
 1022                  * XXX: since "node-local" is obsoleted by interface-local,
 1023                  *      we have to join the group on every interface with
 1024                  *      some interface-boundary restriction.
 1025                  */
 1026                 if (ifp->if_flags & IFF_LOOPBACK) {
 1027                         struct in6_ifaddr *ia_loop;
 1028 
 1029                         struct in6_addr loop6 = in6addr_loopback;
 1030                         ia_loop = in6ifa_ifpwithaddr(ifp, &loop6);
 1031 
 1032                         mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
 1033 
 1034                         IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
 1035                         if (in6m == NULL && ia_loop != NULL) {
 1036                                 rtrequest(RTM_ADD,
 1037                                           (struct sockaddr *)&mltaddr,
 1038                                           (struct sockaddr *)&ia_loop->ia_addr,
 1039                                           (struct sockaddr *)&mltmask,
 1040                                           RTF_UP,
 1041                                           (struct rtentry **)0);
 1042                                 (void)in6_addmulti(&mltaddr.sin6_addr, ifp,
 1043                                                    &error);
 1044                                 if (error != 0) {
 1045                                         nd6log((LOG_WARNING, "in6_update_ifa: "
 1046                                             "addmulti failed for %s on %s "
 1047                                             "(errno=%d)\n",
 1048                                             ip6_sprintf(&mltaddr.sin6_addr),
 1049                                             if_name(ifp), error));
 1050                                 }
 1051                         }
 1052                 }
 1053         }
 1054 
 1055         ia->ia6_flags = ifra->ifra_flags;
 1056         ia->ia6_flags &= ~IN6_IFF_DUPLICATED;   /*safety*/
 1057         ia->ia6_flags &= ~IN6_IFF_NODAD;        /* Mobile IPv6 */
 1058 
 1059         ia->ia6_lifetime = ifra->ifra_lifetime;
 1060         /* for sanity */
 1061         if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
 1062                 ia->ia6_lifetime.ia6t_expire =
 1063                         time_second + ia->ia6_lifetime.ia6t_vltime;
 1064         } else
 1065                 ia->ia6_lifetime.ia6t_expire = 0;
 1066         if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
 1067                 ia->ia6_lifetime.ia6t_preferred =
 1068                         time_second + ia->ia6_lifetime.ia6t_pltime;
 1069         } else
 1070                 ia->ia6_lifetime.ia6t_preferred = 0;
 1071 
 1072         /*
 1073          * Perform DAD, if needed.
 1074          * XXX It may be of use, if we can administratively
 1075          * disable DAD.
 1076          */
 1077         if (in6if_do_dad(ifp) && (ifra->ifra_flags & IN6_IFF_NODAD) == 0) {
 1078                 ia->ia6_flags |= IN6_IFF_TENTATIVE;
 1079                 nd6_dad_start((struct ifaddr *)ia, NULL);
 1080         }
 1081 
 1082         return (error);
 1083 
 1084   unlink:
 1085         /*
 1086          * XXX: if a change of an existing address failed, keep the entry
 1087          * anyway.
 1088          */
 1089         if (hostIsNew)
 1090                 in6_unlink_ifa(ia, ifp);
 1091         return (error);
 1092 }
 1093 
 1094 void
 1095 in6_purgeaddr(ifa)
 1096         struct ifaddr *ifa;
 1097 {
 1098         struct ifnet *ifp = ifa->ifa_ifp;
 1099         struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
 1100 
 1101         /* stop DAD processing */
 1102         nd6_dad_stop(ifa);
 1103 
 1104         /*
 1105          * delete route to the destination of the address being purged.
 1106          * The interface must be p2p or loopback in this case.
 1107          */
 1108         if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
 1109                 int e;
 1110 
 1111                 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
 1112                     != 0) {
 1113                         log(LOG_ERR, "in6_purgeaddr: failed to remove "
 1114                             "a route to the p2p destination: %s on %s, "
 1115                             "errno=%d\n",
 1116                             ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
 1117                             e);
 1118                         /* proceed anyway... */
 1119                 } else
 1120                         ia->ia_flags &= ~IFA_ROUTE;
 1121         }
 1122 
 1123         /* Remove ownaddr's loopback rtentry, if it exists. */
 1124         in6_ifremloop(&(ia->ia_ifa));
 1125 
 1126         if (ifp->if_flags & IFF_MULTICAST) {
 1127                 /*
 1128                  * delete solicited multicast addr for deleting host id
 1129                  */
 1130                 struct in6_multi *in6m;
 1131                 struct in6_addr llsol;
 1132                 bzero(&llsol, sizeof(struct in6_addr));
 1133                 llsol.s6_addr16[0] = htons(0xff02);
 1134                 llsol.s6_addr16[1] = htons(ifp->if_index);
 1135                 llsol.s6_addr32[1] = 0;
 1136                 llsol.s6_addr32[2] = htonl(1);
 1137                 llsol.s6_addr32[3] =
 1138                         ia->ia_addr.sin6_addr.s6_addr32[3];
 1139                 llsol.s6_addr8[12] = 0xff;
 1140 
 1141                 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
 1142                 if (in6m)
 1143                         in6_delmulti(in6m);
 1144         }
 1145 
 1146         in6_unlink_ifa(ia, ifp);
 1147 }
 1148 
 1149 static void
 1150 in6_unlink_ifa(ia, ifp)
 1151         struct in6_ifaddr *ia;
 1152         struct ifnet *ifp;
 1153 {
 1154         int plen, iilen;
 1155         struct in6_ifaddr *oia;
 1156         int     s = splnet();
 1157 
 1158         TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list);
 1159 
 1160         oia = ia;
 1161         if (oia == (ia = in6_ifaddr))
 1162                 in6_ifaddr = ia->ia_next;
 1163         else {
 1164                 while (ia->ia_next && (ia->ia_next != oia))
 1165                         ia = ia->ia_next;
 1166                 if (ia->ia_next)
 1167                         ia->ia_next = oia->ia_next;
 1168                 else {
 1169                         /* search failed */
 1170                         printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
 1171                 }
 1172         }
 1173 
 1174         if (oia->ia6_ifpr) {    /* check for safety */
 1175                 plen = in6_mask2len(&oia->ia_prefixmask.sin6_addr, NULL);
 1176                 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) - plen;
 1177                 in6_prefix_remove_ifid(iilen, oia);
 1178         }
 1179 
 1180         /*
 1181          * When an autoconfigured address is being removed, release the
 1182          * reference to the base prefix.  Also, since the release might
 1183          * affect the status of other (detached) addresses, call
 1184          * pfxlist_onlink_check().
 1185          */
 1186         if ((oia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
 1187                 if (oia->ia6_ndpr == NULL) {
 1188                         nd6log((LOG_NOTICE, "in6_unlink_ifa: autoconf'ed address "
 1189                             "%p has no prefix\n", oia));
 1190                 } else {
 1191                         oia->ia6_ndpr->ndpr_refcnt--;
 1192                         oia->ia6_flags &= ~IN6_IFF_AUTOCONF;
 1193                         oia->ia6_ndpr = NULL;
 1194                 }
 1195 
 1196                 pfxlist_onlink_check();
 1197         }
 1198 
 1199         /*
 1200          * release another refcnt for the link from in6_ifaddr.
 1201          * Note that we should decrement the refcnt at least once for all *BSD.
 1202          */
 1203         IFAFREE(&oia->ia_ifa);
 1204 
 1205         splx(s);
 1206 }
 1207 
 1208 void
 1209 in6_purgeif(ifp)
 1210         struct ifnet *ifp;
 1211 {
 1212         struct ifaddr *ifa, *nifa;
 1213 
 1214         for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa) {
 1215                 nifa = TAILQ_NEXT(ifa, ifa_list);
 1216                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1217                         continue;
 1218                 in6_purgeaddr(ifa);
 1219         }
 1220 
 1221         in6_ifdetach(ifp);
 1222 }
 1223 
 1224 /*
 1225  * SIOC[GAD]LIFADDR.
 1226  *      SIOCGLIFADDR: get first address. (?)
 1227  *      SIOCGLIFADDR with IFLR_PREFIX:
 1228  *              get first address that matches the specified prefix.
 1229  *      SIOCALIFADDR: add the specified address.
 1230  *      SIOCALIFADDR with IFLR_PREFIX:
 1231  *              add the specified prefix, filling hostid part from
 1232  *              the first link-local address.  prefixlen must be <= 64.
 1233  *      SIOCDLIFADDR: delete the specified address.
 1234  *      SIOCDLIFADDR with IFLR_PREFIX:
 1235  *              delete the first address that matches the specified prefix.
 1236  * return values:
 1237  *      EINVAL on invalid parameters
 1238  *      EADDRNOTAVAIL on prefix match failed/specified address not found
 1239  *      other values may be returned from in6_ioctl()
 1240  *
 1241  * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
 1242  * this is to accomodate address naming scheme other than RFC2374,
 1243  * in the future.
 1244  * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
 1245  * address encoding scheme. (see figure on page 8)
 1246  */
 1247 static int
 1248 in6_lifaddr_ioctl(so, cmd, data, ifp, td)
 1249         struct socket *so;
 1250         u_long cmd;
 1251         caddr_t data;
 1252         struct ifnet *ifp;
 1253         struct thread *td;
 1254 {
 1255         struct if_laddrreq *iflr = (struct if_laddrreq *)data;
 1256         struct ifaddr *ifa;
 1257         struct sockaddr *sa;
 1258 
 1259         /* sanity checks */
 1260         if (!data || !ifp) {
 1261                 panic("invalid argument to in6_lifaddr_ioctl");
 1262                 /* NOTREACHED */
 1263         }
 1264 
 1265         switch (cmd) {
 1266         case SIOCGLIFADDR:
 1267                 /* address must be specified on GET with IFLR_PREFIX */
 1268                 if ((iflr->flags & IFLR_PREFIX) == 0)
 1269                         break;
 1270                 /* FALLTHROUGH */
 1271         case SIOCALIFADDR:
 1272         case SIOCDLIFADDR:
 1273                 /* address must be specified on ADD and DELETE */
 1274                 sa = (struct sockaddr *)&iflr->addr;
 1275                 if (sa->sa_family != AF_INET6)
 1276                         return EINVAL;
 1277                 if (sa->sa_len != sizeof(struct sockaddr_in6))
 1278                         return EINVAL;
 1279                 /* XXX need improvement */
 1280                 sa = (struct sockaddr *)&iflr->dstaddr;
 1281                 if (sa->sa_family && sa->sa_family != AF_INET6)
 1282                         return EINVAL;
 1283                 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
 1284                         return EINVAL;
 1285                 break;
 1286         default: /* shouldn't happen */
 1287 #if 0
 1288                 panic("invalid cmd to in6_lifaddr_ioctl");
 1289                 /* NOTREACHED */
 1290 #else
 1291                 return EOPNOTSUPP;
 1292 #endif
 1293         }
 1294         if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
 1295                 return EINVAL;
 1296 
 1297         switch (cmd) {
 1298         case SIOCALIFADDR:
 1299             {
 1300                 struct in6_aliasreq ifra;
 1301                 struct in6_addr *hostid = NULL;
 1302                 int prefixlen;
 1303 
 1304                 if ((iflr->flags & IFLR_PREFIX) != 0) {
 1305                         struct sockaddr_in6 *sin6;
 1306 
 1307                         /*
 1308                          * hostid is to fill in the hostid part of the
 1309                          * address.  hostid points to the first link-local
 1310                          * address attached to the interface.
 1311                          */
 1312                         ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
 1313                         if (!ifa)
 1314                                 return EADDRNOTAVAIL;
 1315                         hostid = IFA_IN6(ifa);
 1316 
 1317                         /* prefixlen must be <= 64. */
 1318                         if (64 < iflr->prefixlen)
 1319                                 return EINVAL;
 1320                         prefixlen = iflr->prefixlen;
 1321 
 1322                         /* hostid part must be zero. */
 1323                         sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1324                         if (sin6->sin6_addr.s6_addr32[2] != 0
 1325                          || sin6->sin6_addr.s6_addr32[3] != 0) {
 1326                                 return EINVAL;
 1327                         }
 1328                 } else
 1329                         prefixlen = iflr->prefixlen;
 1330 
 1331                 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
 1332                 bzero(&ifra, sizeof(ifra));
 1333                 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
 1334 
 1335                 bcopy(&iflr->addr, &ifra.ifra_addr,
 1336                     ((struct sockaddr *)&iflr->addr)->sa_len);
 1337                 if (hostid) {
 1338                         /* fill in hostid part */
 1339                         ifra.ifra_addr.sin6_addr.s6_addr32[2] =
 1340                             hostid->s6_addr32[2];
 1341                         ifra.ifra_addr.sin6_addr.s6_addr32[3] =
 1342                             hostid->s6_addr32[3];
 1343                 }
 1344 
 1345                 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /* XXX */
 1346                         bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
 1347                             ((struct sockaddr *)&iflr->dstaddr)->sa_len);
 1348                         if (hostid) {
 1349                                 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
 1350                                     hostid->s6_addr32[2];
 1351                                 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
 1352                                     hostid->s6_addr32[3];
 1353                         }
 1354                 }
 1355 
 1356                 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
 1357                 in6_prefixlen2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
 1358 
 1359                 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
 1360                 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, td);
 1361             }
 1362         case SIOCGLIFADDR:
 1363         case SIOCDLIFADDR:
 1364             {
 1365                 struct in6_ifaddr *ia;
 1366                 struct in6_addr mask, candidate, match;
 1367                 struct sockaddr_in6 *sin6;
 1368                 int cmp;
 1369 
 1370                 bzero(&mask, sizeof(mask));
 1371                 if (iflr->flags & IFLR_PREFIX) {
 1372                         /* lookup a prefix rather than address. */
 1373                         in6_prefixlen2mask(&mask, iflr->prefixlen);
 1374 
 1375                         sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1376                         bcopy(&sin6->sin6_addr, &match, sizeof(match));
 1377                         match.s6_addr32[0] &= mask.s6_addr32[0];
 1378                         match.s6_addr32[1] &= mask.s6_addr32[1];
 1379                         match.s6_addr32[2] &= mask.s6_addr32[2];
 1380                         match.s6_addr32[3] &= mask.s6_addr32[3];
 1381 
 1382                         /* if you set extra bits, that's wrong */
 1383                         if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
 1384                                 return EINVAL;
 1385 
 1386                         cmp = 1;
 1387                 } else {
 1388                         if (cmd == SIOCGLIFADDR) {
 1389                                 /* on getting an address, take the 1st match */
 1390                                 cmp = 0;        /* XXX */
 1391                         } else {
 1392                                 /* on deleting an address, do exact match */
 1393                                 in6_prefixlen2mask(&mask, 128);
 1394                                 sin6 = (struct sockaddr_in6 *)&iflr->addr;
 1395                                 bcopy(&sin6->sin6_addr, &match, sizeof(match));
 1396 
 1397                                 cmp = 1;
 1398                         }
 1399                 }
 1400 
 1401                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1402                         if (ifa->ifa_addr->sa_family != AF_INET6)
 1403                                 continue;
 1404                         if (!cmp)
 1405                                 break;
 1406 
 1407                         bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
 1408                         /*
 1409                          * XXX: this is adhoc, but is necessary to allow
 1410                          * a user to specify fe80::/64 (not /10) for a
 1411                          * link-local address.
 1412                          */
 1413                         if (IN6_IS_ADDR_LINKLOCAL(&candidate))
 1414                                 candidate.s6_addr16[1] = 0;
 1415                         candidate.s6_addr32[0] &= mask.s6_addr32[0];
 1416                         candidate.s6_addr32[1] &= mask.s6_addr32[1];
 1417                         candidate.s6_addr32[2] &= mask.s6_addr32[2];
 1418                         candidate.s6_addr32[3] &= mask.s6_addr32[3];
 1419                         if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
 1420                                 break;
 1421                 }
 1422                 if (!ifa)
 1423                         return EADDRNOTAVAIL;
 1424                 ia = ifa2ia6(ifa);
 1425 
 1426                 if (cmd == SIOCGLIFADDR) {
 1427                         struct sockaddr_in6 *s6;
 1428 
 1429                         /* fill in the if_laddrreq structure */
 1430                         bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
 1431                         s6 = (struct sockaddr_in6 *)&iflr->addr;
 1432                         if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
 1433                                 s6->sin6_addr.s6_addr16[1] = 0;
 1434                                 if (in6_addr2zoneid(ifp, &s6->sin6_addr,
 1435                                     &s6->sin6_scope_id))
 1436                                         return (EINVAL);/* XXX */
 1437                         }
 1438                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
 1439                                 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
 1440                                     ia->ia_dstaddr.sin6_len);
 1441                                 s6 = (struct sockaddr_in6 *)&iflr->dstaddr;
 1442                                 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
 1443                                         s6->sin6_addr.s6_addr16[1] = 0;
 1444                                         if (in6_addr2zoneid(ifp,
 1445                                             &s6->sin6_addr, &s6->sin6_scope_id))
 1446                                                 return (EINVAL); /* EINVAL */
 1447                                 }
 1448                         } else
 1449                                 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
 1450 
 1451                         iflr->prefixlen =
 1452                             in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
 1453 
 1454                         iflr->flags = ia->ia6_flags;    /* XXX */
 1455 
 1456                         return 0;
 1457                 } else {
 1458                         struct in6_aliasreq ifra;
 1459 
 1460                         /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
 1461                         bzero(&ifra, sizeof(ifra));
 1462                         bcopy(iflr->iflr_name, ifra.ifra_name,
 1463                             sizeof(ifra.ifra_name));
 1464 
 1465                         bcopy(&ia->ia_addr, &ifra.ifra_addr,
 1466                             ia->ia_addr.sin6_len);
 1467                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
 1468                                 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
 1469                                     ia->ia_dstaddr.sin6_len);
 1470                         } else {
 1471                                 bzero(&ifra.ifra_dstaddr,
 1472                                     sizeof(ifra.ifra_dstaddr));
 1473                         }
 1474                         bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
 1475                             ia->ia_prefixmask.sin6_len);
 1476 
 1477                         ifra.ifra_flags = ia->ia6_flags;
 1478                         return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
 1479                             ifp, td);
 1480                 }
 1481             }
 1482         }
 1483 
 1484         return EOPNOTSUPP;      /* just for safety */
 1485 }
 1486 
 1487 /*
 1488  * Initialize an interface's intetnet6 address
 1489  * and routing table entry.
 1490  */
 1491 static int
 1492 in6_ifinit(ifp, ia, sin6, newhost)
 1493         struct ifnet *ifp;
 1494         struct in6_ifaddr *ia;
 1495         struct sockaddr_in6 *sin6;
 1496         int newhost;
 1497 {
 1498         int     error = 0, plen, ifacount = 0;
 1499         int     s = splimp();
 1500         struct ifaddr *ifa;
 1501 
 1502         /*
 1503          * Give the interface a chance to initialize
 1504          * if this is its first address,
 1505          * and to validate the address if necessary.
 1506          */
 1507         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1508                 if (ifa->ifa_addr == NULL)
 1509                         continue;       /* just for safety */
 1510                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1511                         continue;
 1512                 ifacount++;
 1513         }
 1514 
 1515         ia->ia_addr = *sin6;
 1516 
 1517         if (ifacount <= 1 && ifp->if_ioctl &&
 1518             (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
 1519                 splx(s);
 1520                 return (error);
 1521         }
 1522         splx(s);
 1523 
 1524         ia->ia_ifa.ifa_metric = ifp->if_metric;
 1525 
 1526         /* we could do in(6)_socktrim here, but just omit it at this moment. */
 1527 
 1528         /*
 1529          * Special case:
 1530          * If the destination address is specified for a point-to-point
 1531          * interface, install a route to the destination as an interface
 1532          * direct route.
 1533          */
 1534         plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
 1535         if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
 1536                 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
 1537                                     RTF_UP | RTF_HOST)) != 0)
 1538                         return (error);
 1539                 ia->ia_flags |= IFA_ROUTE;
 1540         }
 1541         if (plen < 128) {
 1542                 /*
 1543                  * The RTF_CLONING flag is necessary for in6_is_ifloop_auto().
 1544                  */
 1545                 ia->ia_ifa.ifa_flags |= RTF_CLONING;
 1546         }
 1547 
 1548         /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
 1549         if (newhost) {
 1550                 /* set the rtrequest function to create llinfo */
 1551                 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
 1552                 in6_ifaddloop(&(ia->ia_ifa));
 1553         }
 1554 
 1555         return (error);
 1556 }
 1557 
 1558 /*
 1559  * Add an address to the list of IP6 multicast addresses for a
 1560  * given interface.
 1561  */
 1562 struct  in6_multi *
 1563 in6_addmulti(maddr6, ifp, errorp)
 1564         struct in6_addr *maddr6;
 1565         struct ifnet *ifp;
 1566         int *errorp;
 1567 {
 1568         struct  in6_multi *in6m;
 1569         struct sockaddr_in6 sin6;
 1570         struct ifmultiaddr *ifma;
 1571         int     s = splnet();
 1572 
 1573         *errorp = 0;
 1574 
 1575         /*
 1576          * Call generic routine to add membership or increment
 1577          * refcount.  It wants addresses in the form of a sockaddr,
 1578          * so we build one here (being careful to zero the unused bytes).
 1579          */
 1580         bzero(&sin6, sizeof sin6);
 1581         sin6.sin6_family = AF_INET6;
 1582         sin6.sin6_len = sizeof sin6;
 1583         sin6.sin6_addr = *maddr6;
 1584         *errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma);
 1585         if (*errorp) {
 1586                 splx(s);
 1587                 return 0;
 1588         }
 1589 
 1590         /*
 1591          * If ifma->ifma_protospec is null, then if_addmulti() created
 1592          * a new record.  Otherwise, we are done.
 1593          */
 1594         if (ifma->ifma_protospec != 0)
 1595                 return ifma->ifma_protospec;
 1596 
 1597         /* XXX - if_addmulti uses M_WAITOK.  Can this really be called
 1598            at interrupt time?  If so, need to fix if_addmulti. XXX */
 1599         in6m = (struct in6_multi *)malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
 1600         if (in6m == NULL) {
 1601                 splx(s);
 1602                 return (NULL);
 1603         }
 1604 
 1605         bzero(in6m, sizeof *in6m);
 1606         in6m->in6m_addr = *maddr6;
 1607         in6m->in6m_ifp = ifp;
 1608         in6m->in6m_ifma = ifma;
 1609         ifma->ifma_protospec = in6m;
 1610         LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry);
 1611 
 1612         /*
 1613          * Let MLD6 know that we have joined a new IPv6 multicast
 1614          * group.
 1615          */
 1616         mld6_start_listening(in6m);
 1617         splx(s);
 1618         return (in6m);
 1619 }
 1620 
 1621 /*
 1622  * Delete a multicast address record.
 1623  */
 1624 void
 1625 in6_delmulti(in6m)
 1626         struct in6_multi *in6m;
 1627 {
 1628         struct ifmultiaddr *ifma = in6m->in6m_ifma;
 1629         int     s = splnet();
 1630 
 1631         if (ifma->ifma_refcount == 1) {
 1632                 /*
 1633                  * No remaining claims to this record; let MLD6 know
 1634                  * that we are leaving the multicast group.
 1635                  */
 1636                 mld6_stop_listening(in6m);
 1637                 ifma->ifma_protospec = 0;
 1638                 LIST_REMOVE(in6m, in6m_entry);
 1639                 free(in6m, M_IPMADDR);
 1640         }
 1641         /* XXX - should be separate API for when we have an ifma? */
 1642         if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
 1643         splx(s);
 1644 }
 1645 
 1646 /*
 1647  * Find an IPv6 interface link-local address specific to an interface.
 1648  */
 1649 struct in6_ifaddr *
 1650 in6ifa_ifpforlinklocal(ifp, ignoreflags)
 1651         struct ifnet *ifp;
 1652         int ignoreflags;
 1653 {
 1654         struct ifaddr *ifa;
 1655 
 1656         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1657                 if (ifa->ifa_addr == NULL)
 1658                         continue;       /* just for safety */
 1659                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1660                         continue;
 1661                 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
 1662                         if ((((struct in6_ifaddr *)ifa)->ia6_flags &
 1663                              ignoreflags) != 0)
 1664                                 continue;
 1665                         break;
 1666                 }
 1667         }
 1668 
 1669         return ((struct in6_ifaddr *)ifa);
 1670 }
 1671 
 1672 
 1673 /*
 1674  * find the internet address corresponding to a given interface and address.
 1675  */
 1676 struct in6_ifaddr *
 1677 in6ifa_ifpwithaddr(ifp, addr)
 1678         struct ifnet *ifp;
 1679         struct in6_addr *addr;
 1680 {
 1681         struct ifaddr *ifa;
 1682 
 1683         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1684                 if (ifa->ifa_addr == NULL)
 1685                         continue;       /* just for safety */
 1686                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1687                         continue;
 1688                 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
 1689                         break;
 1690         }
 1691 
 1692         return ((struct in6_ifaddr *)ifa);
 1693 }
 1694 
 1695 /*
 1696  * Convert IP6 address to printable (loggable) representation.
 1697  */
 1698 static char digits[] = "0123456789abcdef";
 1699 static int ip6round = 0;
 1700 char *
 1701 ip6_sprintf(addr)
 1702         const struct in6_addr *addr;
 1703 {
 1704         static char ip6buf[8][48];
 1705         int i;
 1706         char *cp;
 1707         const u_short *a = (const u_short *)addr;
 1708         const u_char *d;
 1709         int dcolon = 0;
 1710 
 1711         ip6round = (ip6round + 1) & 7;
 1712         cp = ip6buf[ip6round];
 1713 
 1714         for (i = 0; i < 8; i++) {
 1715                 if (dcolon == 1) {
 1716                         if (*a == 0) {
 1717                                 if (i == 7)
 1718                                         *cp++ = ':';
 1719                                 a++;
 1720                                 continue;
 1721                         } else
 1722                                 dcolon = 2;
 1723                 }
 1724                 if (*a == 0) {
 1725                         if (dcolon == 0 && *(a + 1) == 0) {
 1726                                 if (i == 0)
 1727                                         *cp++ = ':';
 1728                                 *cp++ = ':';
 1729                                 dcolon = 1;
 1730                         } else {
 1731                                 *cp++ = '';
 1732                                 *cp++ = ':';
 1733                         }
 1734                         a++;
 1735                         continue;
 1736                 }
 1737                 d = (const u_char *)a;
 1738                 *cp++ = digits[*d >> 4];
 1739                 *cp++ = digits[*d++ & 0xf];
 1740                 *cp++ = digits[*d >> 4];
 1741                 *cp++ = digits[*d & 0xf];
 1742                 *cp++ = ':';
 1743                 a++;
 1744         }
 1745         *--cp = 0;
 1746         return (ip6buf[ip6round]);
 1747 }
 1748 
 1749 int
 1750 in6_localaddr(in6)
 1751         struct in6_addr *in6;
 1752 {
 1753         struct in6_ifaddr *ia;
 1754 
 1755         if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
 1756                 return 1;
 1757 
 1758         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
 1759                 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
 1760                     &ia->ia_prefixmask.sin6_addr)) {
 1761                         return 1;
 1762                 }
 1763         }
 1764 
 1765         return (0);
 1766 }
 1767 
 1768 int
 1769 in6_is_addr_deprecated(sa6)
 1770         struct sockaddr_in6 *sa6;
 1771 {
 1772         struct in6_ifaddr *ia;
 1773 
 1774         for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
 1775                 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
 1776                                        &sa6->sin6_addr) &&
 1777                     (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0)
 1778                         return (1); /* true */
 1779 
 1780                 /* XXX: do we still have to go thru the rest of the list? */
 1781         }
 1782 
 1783         return (0);             /* false */
 1784 }
 1785 
 1786 /*
 1787  * return length of part which dst and src are equal
 1788  * hard coding...
 1789  */
 1790 int
 1791 in6_matchlen(src, dst)
 1792 struct in6_addr *src, *dst;
 1793 {
 1794         int match = 0;
 1795         u_char *s = (u_char *)src, *d = (u_char *)dst;
 1796         u_char *lim = s + 16, r;
 1797 
 1798         while (s < lim)
 1799                 if ((r = (*d++ ^ *s++)) != 0) {
 1800                         while (r < 128) {
 1801                                 match++;
 1802                                 r <<= 1;
 1803                         }
 1804                         break;
 1805                 } else
 1806                         match += 8;
 1807         return match;
 1808 }
 1809 
 1810 /* XXX: to be scope conscious */
 1811 int
 1812 in6_are_prefix_equal(p1, p2, len)
 1813         struct in6_addr *p1, *p2;
 1814         int len;
 1815 {
 1816         int bytelen, bitlen;
 1817 
 1818         /* sanity check */
 1819         if (0 > len || len > 128) {
 1820                 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
 1821                     len);
 1822                 return (0);
 1823         }
 1824 
 1825         bytelen = len / 8;
 1826         bitlen = len % 8;
 1827 
 1828         if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
 1829                 return (0);
 1830         if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
 1831             p2->s6_addr[bytelen] >> (8 - bitlen))
 1832                 return (0);
 1833 
 1834         return (1);
 1835 }
 1836 
 1837 void
 1838 in6_prefixlen2mask(maskp, len)
 1839         struct in6_addr *maskp;
 1840         int len;
 1841 {
 1842         u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
 1843         int bytelen, bitlen, i;
 1844 
 1845         /* sanity check */
 1846         if (0 > len || len > 128) {
 1847                 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
 1848                     len);
 1849                 return;
 1850         }
 1851 
 1852         bzero(maskp, sizeof(*maskp));
 1853         bytelen = len / 8;
 1854         bitlen = len % 8;
 1855         for (i = 0; i < bytelen; i++)
 1856                 maskp->s6_addr[i] = 0xff;
 1857         if (bitlen)
 1858                 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
 1859 }
 1860 
 1861 /*
 1862  * return the best address out of the same scope. if no address was
 1863  * found, return the first valid address from designated IF.
 1864  */
 1865 struct in6_ifaddr *
 1866 in6_ifawithifp(ifp, dst)
 1867         struct ifnet *ifp;
 1868         struct in6_addr *dst;
 1869 {
 1870         int dst_scope = in6_addrscope(dst), blen = -1, tlen;
 1871         struct ifaddr *ifa;
 1872         struct in6_ifaddr *besta = 0;
 1873         struct in6_ifaddr *dep[2];      /* last-resort: deprecated */
 1874 
 1875         dep[0] = dep[1] = NULL;
 1876 
 1877         /*
 1878          * We first look for addresses in the same scope.
 1879          * If there is one, return it.
 1880          * If two or more, return one which matches the dst longest.
 1881          * If none, return one of global addresses assigned other ifs.
 1882          */
 1883         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1884                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1885                         continue;
 1886                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
 1887                         continue; /* XXX: is there any case to allow anycast? */
 1888                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
 1889                         continue; /* don't use this interface */
 1890                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
 1891                         continue;
 1892                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
 1893                         if (ip6_use_deprecated)
 1894                                 dep[0] = (struct in6_ifaddr *)ifa;
 1895                         continue;
 1896                 }
 1897 
 1898                 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
 1899                         /*
 1900                          * call in6_matchlen() as few as possible
 1901                          */
 1902                         if (besta) {
 1903                                 if (blen == -1)
 1904                                         blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
 1905                                 tlen = in6_matchlen(IFA_IN6(ifa), dst);
 1906                                 if (tlen > blen) {
 1907                                         blen = tlen;
 1908                                         besta = (struct in6_ifaddr *)ifa;
 1909                                 }
 1910                         } else
 1911                                 besta = (struct in6_ifaddr *)ifa;
 1912                 }
 1913         }
 1914         if (besta)
 1915                 return (besta);
 1916 
 1917         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1918                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1919                         continue;
 1920                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
 1921                         continue; /* XXX: is there any case to allow anycast? */
 1922                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
 1923                         continue; /* don't use this interface */
 1924                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
 1925                         continue;
 1926                 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
 1927                         if (ip6_use_deprecated)
 1928                                 dep[1] = (struct in6_ifaddr *)ifa;
 1929                         continue;
 1930                 }
 1931 
 1932                 return (struct in6_ifaddr *)ifa;
 1933         }
 1934 
 1935         /* use the last-resort values, that are, deprecated addresses */
 1936         if (dep[0])
 1937                 return dep[0];
 1938         if (dep[1])
 1939                 return dep[1];
 1940 
 1941         return NULL;
 1942 }
 1943 
 1944 /*
 1945  * perform DAD when interface becomes IFF_UP.
 1946  */
 1947 void
 1948 in6_if_up(ifp)
 1949         struct ifnet *ifp;
 1950 {
 1951         struct ifaddr *ifa;
 1952         struct in6_ifaddr *ia;
 1953         int dad_delay;          /* delay ticks before DAD output */
 1954 
 1955         /*
 1956          * special cases, like 6to4, are handled in in6_ifattach
 1957          */
 1958         in6_ifattach(ifp, NULL);
 1959 
 1960         dad_delay = 0;
 1961         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1962                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1963                         continue;
 1964                 ia = (struct in6_ifaddr *)ifa;
 1965                 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
 1966                         nd6_dad_start(ifa, &dad_delay);
 1967         }
 1968 }
 1969 
 1970 int
 1971 in6if_do_dad(ifp)
 1972         struct ifnet *ifp;
 1973 {
 1974         if ((ifp->if_flags & IFF_LOOPBACK) != 0)
 1975                 return (0);
 1976 
 1977         switch (ifp->if_type) {
 1978 #ifdef IFT_DUMMY
 1979         case IFT_DUMMY:
 1980 #endif
 1981         case IFT_FAITH:
 1982                 /*
 1983                  * These interfaces do not have the IFF_LOOPBACK flag,
 1984                  * but loop packets back.  We do not have to do DAD on such
 1985                  * interfaces.  We should even omit it, because loop-backed
 1986                  * NS would confuse the DAD procedure.
 1987                  */
 1988                 return (0);
 1989         default:
 1990                 /*
 1991                  * Our DAD routine requires the interface up and running.
 1992                  * However, some interfaces can be up before the RUNNING
 1993                  * status.  Additionaly, users may try to assign addresses
 1994                  * before the interface becomes up (or running).
 1995                  * We simply skip DAD in such a case as a work around.
 1996                  * XXX: we should rather mark "tentative" on such addresses,
 1997                  * and do DAD after the interface becomes ready.
 1998                  */
 1999                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
 2000                     (IFF_UP|IFF_RUNNING))
 2001                         return (0);
 2002 
 2003                 return (1);
 2004         }
 2005 }
 2006 
 2007 /*
 2008  * Calculate max IPv6 MTU through all the interfaces and store it
 2009  * to in6_maxmtu.
 2010  */
 2011 void
 2012 in6_setmaxmtu()
 2013 {
 2014         unsigned long maxmtu = 0;
 2015         struct ifnet *ifp;
 2016 
 2017         IFNET_RLOCK();
 2018         for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
 2019                 /* this function can be called during ifnet initialization */
 2020                 if (!ifp->if_afdata[AF_INET6])
 2021                         continue;
 2022                 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
 2023                     IN6_LINKMTU(ifp) > maxmtu)
 2024                         maxmtu = IN6_LINKMTU(ifp);
 2025         }
 2026         IFNET_RUNLOCK();
 2027         if (maxmtu)          /* update only when maxmtu is positive */
 2028                 in6_maxmtu = maxmtu;
 2029 }
 2030 
 2031 void *
 2032 in6_domifattach(ifp)
 2033         struct ifnet *ifp;
 2034 {
 2035         struct in6_ifextra *ext;
 2036 
 2037         ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK);
 2038         bzero(ext, sizeof(*ext));
 2039 
 2040         ext->in6_ifstat = (struct in6_ifstat *)malloc(sizeof(struct in6_ifstat),
 2041             M_IFADDR, M_WAITOK);
 2042         bzero(ext->in6_ifstat, sizeof(*ext->in6_ifstat));
 2043 
 2044         ext->icmp6_ifstat =
 2045             (struct icmp6_ifstat *)malloc(sizeof(struct icmp6_ifstat),
 2046             M_IFADDR, M_WAITOK);
 2047         bzero(ext->icmp6_ifstat, sizeof(*ext->icmp6_ifstat));
 2048 
 2049         ext->nd_ifinfo = nd6_ifattach(ifp);
 2050         ext->scope6_id = scope6_ifattach(ifp);
 2051         return ext;
 2052 }
 2053 
 2054 void
 2055 in6_domifdetach(ifp, aux)
 2056         struct ifnet *ifp;
 2057         void *aux;
 2058 {
 2059         struct in6_ifextra *ext = (struct in6_ifextra *)aux;
 2060 
 2061         scope6_ifdetach(ext->scope6_id);
 2062         nd6_ifdetach(ext->nd_ifinfo);
 2063         free(ext->in6_ifstat, M_IFADDR);
 2064         free(ext->icmp6_ifstat, M_IFADDR);
 2065         free(ext, M_IFADDR);
 2066 }
 2067 
 2068 /*
 2069  * Convert sockaddr_in6 to sockaddr_in.  Original sockaddr_in6 must be
 2070  * v4 mapped addr or v4 compat addr
 2071  */
 2072 void
 2073 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
 2074 {
 2075         bzero(sin, sizeof(*sin));
 2076         sin->sin_len = sizeof(struct sockaddr_in);
 2077         sin->sin_family = AF_INET;
 2078         sin->sin_port = sin6->sin6_port;
 2079         sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
 2080 }
 2081 
 2082 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
 2083 void
 2084 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
 2085 {
 2086         bzero(sin6, sizeof(*sin6));
 2087         sin6->sin6_len = sizeof(struct sockaddr_in6);
 2088         sin6->sin6_family = AF_INET6;
 2089         sin6->sin6_port = sin->sin_port;
 2090         sin6->sin6_addr.s6_addr32[0] = 0;
 2091         sin6->sin6_addr.s6_addr32[1] = 0;
 2092         sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
 2093         sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
 2094 }
 2095 
 2096 /* Convert sockaddr_in6 into sockaddr_in. */
 2097 void
 2098 in6_sin6_2_sin_in_sock(struct sockaddr *nam)
 2099 {
 2100         struct sockaddr_in *sin_p;
 2101         struct sockaddr_in6 sin6;
 2102 
 2103         /*
 2104          * Save original sockaddr_in6 addr and convert it
 2105          * to sockaddr_in.
 2106          */
 2107         sin6 = *(struct sockaddr_in6 *)nam;
 2108         sin_p = (struct sockaddr_in *)nam;
 2109         in6_sin6_2_sin(sin_p, &sin6);
 2110 }
 2111 
 2112 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
 2113 void
 2114 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
 2115 {
 2116         struct sockaddr_in *sin_p;
 2117         struct sockaddr_in6 *sin6_p;
 2118 
 2119         MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
 2120                M_WAITOK);
 2121         sin_p = (struct sockaddr_in *)*nam;
 2122         in6_sin_2_v4mapsin6(sin_p, sin6_p);
 2123         FREE(*nam, M_SONAME);
 2124         *nam = (struct sockaddr *)sin6_p;
 2125 }

Cache object: 2b1b579850dd492be3e60d4f5eaf3aec


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