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 /*      $OpenBSD: in6.c,v 1.259 2022/12/06 22:19:39 mvs Exp $   */
    2 /*      $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $   */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the project nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Copyright (c) 1982, 1986, 1991, 1993
   35  *      The Regents of the University of California.  All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. Neither the name of the University nor the names of its contributors
   46  *    may be used to endorse or promote products derived from this software
   47  *    without specific prior written permission.
   48  *
   49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59  * SUCH DAMAGE.
   60  *
   61  *      @(#)in.c        8.2 (Berkeley) 11/15/93
   62  */
   63 
   64 #include "carp.h"
   65 
   66 #include <sys/param.h>
   67 #include <sys/ioctl.h>
   68 #include <sys/errno.h>
   69 #include <sys/malloc.h>
   70 #include <sys/socket.h>
   71 #include <sys/socketvar.h>
   72 #include <sys/sockio.h>
   73 #include <sys/mbuf.h>
   74 #include <sys/systm.h>
   75 #include <sys/time.h>
   76 #include <sys/kernel.h>
   77 #include <sys/syslog.h>
   78 
   79 #include <net/if.h>
   80 #include <net/if_dl.h>
   81 #include <net/if_types.h>
   82 #include <net/route.h>
   83 
   84 #include <netinet/in.h>
   85 #include <netinet/if_ether.h>
   86 
   87 #include <netinet6/in6_var.h>
   88 #include <netinet/ip6.h>
   89 #include <netinet6/ip6_var.h>
   90 #include <netinet6/nd6.h>
   91 #include <netinet6/mld6_var.h>
   92 #ifdef MROUTING
   93 #include <netinet6/ip6_mroute.h>
   94 #endif
   95 #include <netinet6/in6_ifattach.h>
   96 #if NCARP > 0
   97 #include <netinet/ip_carp.h>
   98 #endif
   99 
  100 /*
  101  * Definitions of some constant IP6 addresses.
  102  */
  103 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
  104 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
  105 const struct in6_addr in6addr_intfacelocal_allnodes =
  106         IN6ADDR_INTFACELOCAL_ALLNODES_INIT;
  107 const struct in6_addr in6addr_linklocal_allnodes =
  108         IN6ADDR_LINKLOCAL_ALLNODES_INIT;
  109 const struct in6_addr in6addr_linklocal_allrouters =
  110         IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
  111 
  112 const struct in6_addr in6mask0 = IN6MASK0;
  113 const struct in6_addr in6mask32 = IN6MASK32;
  114 const struct in6_addr in6mask64 = IN6MASK64;
  115 const struct in6_addr in6mask96 = IN6MASK96;
  116 const struct in6_addr in6mask128 = IN6MASK128;
  117 
  118 int in6_ioctl(u_long, caddr_t, struct ifnet *, int);
  119 int in6_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *);
  120 int in6_ioctl_get(u_long, caddr_t, struct ifnet *);
  121 int in6_check_embed_scope(struct sockaddr_in6 *, unsigned int);
  122 int in6_clear_scope_id(struct sockaddr_in6 *, unsigned int);
  123 int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int);
  124 void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
  125 
  126 const struct sockaddr_in6 sa6_any = {
  127         sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0
  128 };
  129 
  130 int
  131 in6_mask2len(struct in6_addr *mask, u_char *lim0)
  132 {
  133         int x = 0, y;
  134         u_char *lim = lim0, *p;
  135 
  136         /* ignore the scope_id part */
  137         if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask))
  138                 lim = (u_char *)mask + sizeof(*mask);
  139         for (p = (u_char *)mask; p < lim; x++, p++) {
  140                 if (*p != 0xff)
  141                         break;
  142         }
  143         y = 0;
  144         if (p < lim) {
  145                 for (y = 0; y < 8; y++) {
  146                         if ((*p & (0x80 >> y)) == 0)
  147                                 break;
  148                 }
  149         }
  150 
  151         /*
  152          * when the limit pointer is given, do a stricter check on the
  153          * remaining bits.
  154          */
  155         if (p < lim) {
  156                 if (y != 0 && (*p & (0x00ff >> y)) != 0)
  157                         return (-1);
  158                 for (p = p + 1; p < lim; p++)
  159                         if (*p != 0)
  160                                 return (-1);
  161         }
  162 
  163         return x * 8 + y;
  164 }
  165 
  166 int
  167 in6_nam2sin6(const struct mbuf *nam, struct sockaddr_in6 **sin6)
  168 {
  169         struct sockaddr *sa = mtod(nam, struct sockaddr *);
  170 
  171         if (nam->m_len < offsetof(struct sockaddr, sa_data))
  172                 return EINVAL;
  173         if (sa->sa_family != AF_INET6)
  174                 return EAFNOSUPPORT;
  175         if (sa->sa_len != nam->m_len)
  176                 return EINVAL;
  177         if (sa->sa_len != sizeof(struct sockaddr_in6))
  178                 return EINVAL;
  179         *sin6 = satosin6(sa);
  180 
  181         return 0;
  182 }
  183 
  184 int
  185 in6_sa2sin6(struct sockaddr *sa, struct sockaddr_in6 **sin6)
  186 {
  187         if (sa->sa_family != AF_INET6)
  188                 return EAFNOSUPPORT;
  189         if (sa->sa_len != sizeof(struct sockaddr_in6))
  190                 return EINVAL;
  191         *sin6 = satosin6(sa);
  192 
  193         return 0;
  194 }
  195 
  196 int
  197 in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
  198 {
  199         int privileged;
  200         int error;
  201 
  202         privileged = 0;
  203         if ((so->so_state & SS_PRIV) != 0)
  204                 privileged++;
  205 
  206         switch (cmd) {
  207 #ifdef MROUTING
  208         case SIOCGETSGCNT_IN6:
  209         case SIOCGETMIFCNT_IN6:
  210                 KERNEL_LOCK();
  211                 error = mrt6_ioctl(so, cmd, data);
  212                 KERNEL_UNLOCK();
  213                 break;
  214 #endif /* MROUTING */
  215         default:
  216                 error = in6_ioctl(cmd, data, ifp, privileged);
  217                 break;
  218         }
  219 
  220         return error;
  221 }
  222 
  223 int
  224 in6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
  225 {
  226         if (ifp == NULL)
  227                 return (ENXIO);
  228 
  229         switch (cmd) {
  230         case SIOCGIFINFO_IN6:
  231         case SIOCGNBRINFO_IN6:
  232                 return (nd6_ioctl(cmd, data, ifp));
  233         case SIOCGIFDSTADDR_IN6:
  234         case SIOCGIFNETMASK_IN6:
  235         case SIOCGIFAFLAG_IN6:
  236         case SIOCGIFALIFETIME_IN6:
  237                 return (in6_ioctl_get(cmd, data, ifp));
  238         case SIOCAIFADDR_IN6:
  239         case SIOCDIFADDR_IN6:
  240                 if (!privileged)
  241                         return (EPERM);
  242                 return (in6_ioctl_change_ifaddr(cmd, data, ifp));
  243         case SIOCSIFADDR:
  244         case SIOCSIFDSTADDR:
  245         case SIOCSIFBRDADDR:
  246         case SIOCSIFNETMASK:
  247                 /*
  248                  * Do not pass those ioctl to driver handler since they are not
  249                  * properly set up. Instead just error out.
  250                  */
  251                 return (EINVAL);
  252         default:
  253                 return (EOPNOTSUPP);
  254         }
  255 }
  256 
  257 int
  258 in6_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
  259 {
  260         struct  in6_ifaddr *ia6 = NULL;
  261         struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
  262         struct  sockaddr *sa;
  263         struct  sockaddr_in6 *sa6 = NULL;
  264         int     error = 0, newifaddr = 0, plen;
  265 
  266         /*
  267          * Find address for this interface, if it exists.
  268          *
  269          * In netinet code, we have checked ifra_addr in SIOCSIF*ADDR operation
  270          * only, and used the first interface address as the target of other
  271          * operations (without checking ifra_addr).  This was because netinet
  272          * code/API assumed at most 1 interface address per interface.
  273          * Since IPv6 allows a node to assign multiple addresses
  274          * on a single interface, we almost always look and check the
  275          * presence of ifra_addr, and reject invalid ones here.
  276          * It also decreases duplicated code among SIOC*_IN6 operations.
  277          *
  278          * We always require users to specify a valid IPv6 address for
  279          * the corresponding operation.
  280          */
  281         switch (cmd) {
  282         case SIOCAIFADDR_IN6:
  283                 sa = sin6tosa(&ifra->ifra_addr);
  284                 break;
  285         case SIOCDIFADDR_IN6:
  286                 sa = sin6tosa(&((struct in6_ifreq *)data)->ifr_addr);
  287                 break;
  288         default:
  289                 panic("%s: invalid ioctl %lu", __func__, cmd);
  290         }
  291         if (sa->sa_family == AF_INET6) {
  292                 error = in6_sa2sin6(sa, &sa6);
  293                 if (error)
  294                         return (error);
  295         }
  296 
  297         KERNEL_LOCK();
  298         NET_LOCK();
  299 
  300         if (sa6 != NULL) {
  301                 error = in6_check_embed_scope(sa6, ifp->if_index);
  302                 if (error)
  303                         goto err;
  304                 error = in6_clear_scope_id(sa6, ifp->if_index);
  305                 if (error)
  306                         goto err;
  307                 ia6 = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
  308         }
  309 
  310         switch (cmd) {
  311         case SIOCDIFADDR_IN6:
  312                 /*
  313                  * for IPv4, we look for existing in_ifaddr here to allow
  314                  * "ifconfig if0 delete" to remove the first IPv4 address on
  315                  * the interface.  For IPv6, as the spec allows multiple
  316                  * interface address from the day one, we consider "remove the
  317                  * first one" semantics to be not preferable.
  318                  */
  319                 if (ia6 == NULL) {
  320                         error = EADDRNOTAVAIL;
  321                         break;
  322                 }
  323                 in6_purgeaddr(&ia6->ia_ifa);
  324                 if_addrhooks_run(ifp);
  325                 break;
  326 
  327         case SIOCAIFADDR_IN6:
  328                 if (ifra->ifra_addr.sin6_family != AF_INET6 ||
  329                     ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6)) {
  330                         error = EAFNOSUPPORT;
  331                         break;
  332                 }
  333 
  334                 /* reject read-only flags */
  335                 if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
  336                     (ifra->ifra_flags & IN6_IFF_DETACHED) != 0 ||
  337                     (ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) {
  338                         error = EINVAL;
  339                         break;
  340                 }
  341 
  342                 if (ia6 == NULL)
  343                         newifaddr = 1;
  344 
  345                 /*
  346                  * Make the address tentative before joining multicast
  347                  * addresses, so that corresponding MLD responses would
  348                  * not have a tentative source address.
  349                  */
  350                 if (newifaddr && in6if_do_dad(ifp))
  351                         ifra->ifra_flags |= IN6_IFF_TENTATIVE;
  352 
  353                 /*
  354                  * first, make or update the interface address structure,
  355                  * and link it to the list. try to enable inet6 if there
  356                  * is no link-local yet.
  357                  */
  358                 error = in6_ifattach(ifp);
  359                 if (error)
  360                         break;
  361                 error = in6_update_ifa(ifp, ifra, ia6);
  362                 if (error)
  363                         break;
  364 
  365                 ia6 = NULL;
  366                 if (sa6 != NULL)
  367                         ia6 = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
  368                 if (ia6 == NULL) {
  369                         /*
  370                          * this can happen when the user specify the 0 valid
  371                          * lifetime.
  372                          */
  373                         break;
  374                 }
  375 
  376                 /* Perform DAD, if needed. */
  377                 if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
  378                         nd6_dad_start(&ia6->ia_ifa);
  379 
  380                 if (!newifaddr) {
  381                         if_addrhooks_run(ifp);
  382                         break;
  383                 }
  384 
  385                 plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
  386                 if ((ifp->if_flags & IFF_LOOPBACK) || plen == 128) {
  387                         if_addrhooks_run(ifp);
  388                         break;  /* No need to install a connected route. */
  389                 }
  390 
  391                 error = rt_ifa_add(&ia6->ia_ifa,
  392                     RTF_CLONING | RTF_CONNECTED | RTF_MPATH,
  393                     ia6->ia_ifa.ifa_addr, ifp->if_rdomain);
  394                 if (error) {
  395                         in6_purgeaddr(&ia6->ia_ifa);
  396                         break;
  397                 }
  398                 if_addrhooks_run(ifp);
  399                 break;
  400         }
  401 
  402 err:
  403         NET_UNLOCK();
  404         KERNEL_UNLOCK();
  405         return (error);
  406 }
  407 
  408 int
  409 in6_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
  410 {
  411         struct  in6_ifreq *ifr = (struct in6_ifreq *)data;
  412         struct  in6_ifaddr *ia6 = NULL;
  413         struct  sockaddr *sa;
  414         struct  sockaddr_in6 *sa6 = NULL;
  415         int     error = 0;
  416 
  417         sa = sin6tosa(&ifr->ifr_addr);
  418         if (sa->sa_family == AF_INET6) {
  419                 sa->sa_len = sizeof(struct sockaddr_in6);
  420                 error = in6_sa2sin6(sa, &sa6);
  421                 if (error)
  422                         return (error);
  423         }
  424 
  425         NET_LOCK_SHARED();
  426 
  427         if (sa6 != NULL) {
  428                 error = in6_check_embed_scope(sa6, ifp->if_index);
  429                 if (error)
  430                         goto err;
  431                 error = in6_clear_scope_id(sa6, ifp->if_index);
  432                 if (error)
  433                         goto err;
  434                 ia6 = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
  435         }
  436 
  437         /* must think again about its semantics */
  438         if (ia6 == NULL) {
  439                 error = EADDRNOTAVAIL;
  440                 goto err;
  441         }
  442 
  443         switch (cmd) {
  444         case SIOCGIFDSTADDR_IN6:
  445                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
  446                         error = EINVAL;
  447                         break;
  448                 }
  449                 /*
  450                  * XXX: should we check if ifa_dstaddr is NULL and return
  451                  * an error?
  452                  */
  453                 ifr->ifr_dstaddr = ia6->ia_dstaddr;
  454                 break;
  455 
  456         case SIOCGIFNETMASK_IN6:
  457                 ifr->ifr_addr = ia6->ia_prefixmask;
  458                 break;
  459 
  460         case SIOCGIFAFLAG_IN6:
  461                 ifr->ifr_ifru.ifru_flags6 = ia6->ia6_flags;
  462                 break;
  463 
  464         case SIOCGIFALIFETIME_IN6:
  465                 ifr->ifr_ifru.ifru_lifetime = ia6->ia6_lifetime;
  466                 if (ia6->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
  467                         time_t expire, maxexpire;
  468                         struct in6_addrlifetime *retlt =
  469                             &ifr->ifr_ifru.ifru_lifetime;
  470 
  471                         /*
  472                          * XXX: adjust expiration time assuming time_t is
  473                          * signed.
  474                          */
  475                         maxexpire =
  476                             (time_t)~(1ULL << ((sizeof(maxexpire) * 8) - 1));
  477                         if (ia6->ia6_lifetime.ia6t_vltime <
  478                             maxexpire - ia6->ia6_updatetime) {
  479                                 expire = ia6->ia6_updatetime +
  480                                     ia6->ia6_lifetime.ia6t_vltime;
  481                                 if (expire != 0) {
  482                                         expire -= getuptime();
  483                                         expire += gettime();
  484                                 }
  485                                 retlt->ia6t_expire = expire;
  486                         } else
  487                                 retlt->ia6t_expire = maxexpire;
  488                 }
  489                 if (ia6->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
  490                         time_t expire, maxexpire;
  491                         struct in6_addrlifetime *retlt =
  492                             &ifr->ifr_ifru.ifru_lifetime;
  493 
  494                         /*
  495                          * XXX: adjust expiration time assuming time_t is
  496                          * signed.
  497                          */
  498                         maxexpire =
  499                             (time_t)~(1ULL << ((sizeof(maxexpire) * 8) - 1));
  500                         if (ia6->ia6_lifetime.ia6t_pltime <
  501                             maxexpire - ia6->ia6_updatetime) {
  502                                 expire = ia6->ia6_updatetime +
  503                                     ia6->ia6_lifetime.ia6t_pltime;
  504                                 if (expire != 0) {
  505                                         expire -= getuptime();
  506                                         expire += gettime();
  507                                 }
  508                                 retlt->ia6t_preferred = expire;
  509                         } else
  510                                 retlt->ia6t_preferred = maxexpire;
  511                 }
  512                 break;
  513 
  514         default:
  515                 panic("%s: invalid ioctl %lu", __func__, cmd);
  516         }
  517 
  518 err:
  519         NET_UNLOCK_SHARED();
  520         return (error);
  521 }
  522 
  523 int
  524 in6_check_embed_scope(struct sockaddr_in6 *sa6, unsigned int ifidx)
  525 {
  526         if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
  527                 if (sa6->sin6_addr.s6_addr16[1] == 0) {
  528                         /* link ID is not embedded by the user */
  529                         sa6->sin6_addr.s6_addr16[1] = htons(ifidx);
  530                 } else if (sa6->sin6_addr.s6_addr16[1] != htons(ifidx))
  531                         return EINVAL;  /* link ID contradicts */
  532         }
  533         return 0;
  534 }
  535 
  536 int
  537 in6_clear_scope_id(struct sockaddr_in6 *sa6, unsigned int ifidx)
  538 {
  539         if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
  540                 if (sa6->sin6_scope_id) {
  541                         if (sa6->sin6_scope_id != (u_int32_t)ifidx)
  542                                 return EINVAL;
  543                         sa6->sin6_scope_id = 0; /* XXX: good way? */
  544                 }
  545         }
  546         return 0;
  547 }
  548 
  549 /*
  550  * Update parameters of an IPv6 interface address.
  551  * If necessary, a new entry is created and linked into address chains.
  552  * This function is separated from in6_control().
  553  */
  554 int
  555 in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
  556     struct in6_ifaddr *ia6)
  557 {
  558         int error = 0, hostIsNew = 0, plen = -1;
  559         struct sockaddr_in6 dst6;
  560         struct in6_addrlifetime *lt;
  561         struct in6_multi_mship *imm;
  562         struct rtentry *rt;
  563         char addr[INET6_ADDRSTRLEN];
  564 
  565         NET_ASSERT_LOCKED();
  566 
  567         /* Validate parameters */
  568         if (ifp == NULL || ifra == NULL) /* this maybe redundant */
  569                 return (EINVAL);
  570 
  571         /*
  572          * The destination address for a p2p link must have a family
  573          * of AF_UNSPEC or AF_INET6.
  574          */
  575         if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
  576             ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
  577             ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
  578                 return (EAFNOSUPPORT);
  579 
  580         /*
  581          * validate ifra_prefixmask.  don't check sin6_family, netmask
  582          * does not carry fields other than sin6_len.
  583          */
  584         if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
  585                 return (EINVAL);
  586         /*
  587          * Because the IPv6 address architecture is classless, we require
  588          * users to specify a (non 0) prefix length (mask) for a new address.
  589          * We also require the prefix (when specified) mask is valid, and thus
  590          * reject a non-consecutive mask.
  591          */
  592         if (ia6 == NULL && ifra->ifra_prefixmask.sin6_len == 0)
  593                 return (EINVAL);
  594         if (ifra->ifra_prefixmask.sin6_len != 0) {
  595                 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
  596                     (u_char *)&ifra->ifra_prefixmask +
  597                     ifra->ifra_prefixmask.sin6_len);
  598                 if (plen <= 0)
  599                         return (EINVAL);
  600         } else {
  601                 /*
  602                  * In this case, ia6 must not be NULL.  We just use its prefix
  603                  * length.
  604                  */
  605                 plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
  606         }
  607         /*
  608          * If the destination address on a p2p interface is specified,
  609          * and the address is a scoped one, validate/set the scope
  610          * zone identifier.
  611          */
  612         dst6 = ifra->ifra_dstaddr;
  613         if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
  614             (dst6.sin6_family == AF_INET6)) {
  615                 error = in6_check_embed_scope(&dst6, ifp->if_index);
  616                 if (error)
  617                         return error;
  618         }
  619         /*
  620          * The destination address can be specified only for a p2p or a
  621          * loopback interface.  If specified, the corresponding prefix length
  622          * must be 128.
  623          */
  624         if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
  625                 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0)
  626                         return (EINVAL);
  627                 if (plen != 128)
  628                         return (EINVAL);
  629         }
  630         /* lifetime consistency check */
  631         lt = &ifra->ifra_lifetime;
  632         if (lt->ia6t_pltime > lt->ia6t_vltime)
  633                 return (EINVAL);
  634         if (lt->ia6t_vltime == 0) {
  635                 /*
  636                  * the following log might be noisy, but this is a typical
  637                  * configuration mistake or a tool's bug.
  638                  */
  639                 nd6log((LOG_INFO, "%s: valid lifetime is 0 for %s\n", __func__,
  640                     inet_ntop(AF_INET6, &ifra->ifra_addr.sin6_addr,
  641                     addr, sizeof(addr))));
  642 
  643                 if (ia6 == NULL)
  644                         return (0); /* there's nothing to do */
  645         }
  646 
  647         /*
  648          * If this is a new address, allocate a new ifaddr and link it
  649          * into chains.
  650          */
  651         if (ia6 == NULL) {
  652                 hostIsNew = 1;
  653                 ia6 = malloc(sizeof(*ia6), M_IFADDR, M_WAITOK | M_ZERO);
  654                 refcnt_init_trace(&ia6->ia_ifa.ifa_refcnt,
  655                     DT_REFCNT_IDX_IFADDR);
  656                 LIST_INIT(&ia6->ia6_memberships);
  657                 /* Initialize the address and masks, and put time stamp */
  658                 ia6->ia_ifa.ifa_addr = sin6tosa(&ia6->ia_addr);
  659                 ia6->ia_addr.sin6_family = AF_INET6;
  660                 ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr);
  661                 ia6->ia6_updatetime = getuptime();
  662                 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
  663                         /*
  664                          * XXX: some functions expect that ifa_dstaddr is not
  665                          * NULL for p2p interfaces.
  666                          */
  667                         ia6->ia_ifa.ifa_dstaddr = sin6tosa(&ia6->ia_dstaddr);
  668                 } else {
  669                         ia6->ia_ifa.ifa_dstaddr = NULL;
  670                 }
  671                 ia6->ia_ifa.ifa_netmask = sin6tosa(&ia6->ia_prefixmask);
  672 
  673                 ia6->ia_ifp = ifp;
  674                 ia6->ia_addr = ifra->ifra_addr;
  675                 ifa_add(ifp, &ia6->ia_ifa);
  676         }
  677 
  678         /* set prefix mask */
  679         if (ifra->ifra_prefixmask.sin6_len) {
  680                 /*
  681                  * We prohibit changing the prefix length of an existing
  682                  * address, because
  683                  * + such an operation should be rare in IPv6, and
  684                  * + the operation would confuse prefix management.
  685                  */
  686                 if (ia6->ia_prefixmask.sin6_len &&
  687                     in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL) != plen) {
  688                         error = EINVAL;
  689                         goto unlink;
  690                 }
  691                 ia6->ia_prefixmask = ifra->ifra_prefixmask;
  692         }
  693 
  694         /*
  695          * If a new destination address is specified, scrub the old one and
  696          * install the new destination.  Note that the interface must be
  697          * p2p or loopback (see the check above.)
  698          */
  699         if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 &&
  700             !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {
  701                 struct ifaddr *ifa = &ia6->ia_ifa;
  702 
  703                 if ((ia6->ia_flags & IFA_ROUTE) != 0 &&
  704                     rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr,
  705                      ifp->if_rdomain) != 0) {
  706                         nd6log((LOG_ERR, "%s: failed to remove a route "
  707                             "to the old destination: %s\n", __func__,
  708                             inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr,
  709                             addr, sizeof(addr))));
  710                         /* proceed anyway... */
  711                 } else
  712                         ia6->ia_flags &= ~IFA_ROUTE;
  713                 ia6->ia_dstaddr = dst6;
  714         }
  715 
  716         /*
  717          * Set lifetimes.  We do not refer to ia6t_expire and ia6t_preferred
  718          * to see if the address is deprecated or invalidated, but initialize
  719          * these members for applications.
  720          */
  721         ia6->ia6_updatetime = getuptime();
  722         ia6->ia6_lifetime = ifra->ifra_lifetime;
  723         if (ia6->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
  724                 ia6->ia6_lifetime.ia6t_expire =
  725                     getuptime() + ia6->ia6_lifetime.ia6t_vltime;
  726         } else
  727                 ia6->ia6_lifetime.ia6t_expire = 0;
  728         if (ia6->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
  729                 ia6->ia6_lifetime.ia6t_preferred =
  730                     getuptime() + ia6->ia6_lifetime.ia6t_pltime;
  731         } else
  732                 ia6->ia6_lifetime.ia6t_preferred = 0;
  733 
  734         /* reset the interface and routing table appropriately. */
  735         if ((error = in6_ifinit(ifp, ia6, hostIsNew)) != 0)
  736                 goto unlink;
  737 
  738         /* re-run DAD */
  739         if (ia6->ia6_flags & (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED))
  740                 ifra->ifra_flags |= IN6_IFF_TENTATIVE;
  741         /*
  742          * configure address flags.
  743          */
  744         ia6->ia6_flags = ifra->ifra_flags;
  745 
  746         nd6_expire_timer_update(ia6);
  747 
  748         /*
  749          * We are done if we have simply modified an existing address.
  750          */
  751         if (!hostIsNew)
  752                 return (error);
  753 
  754         /*
  755          * Beyond this point, we should call in6_purgeaddr upon an error,
  756          * not just go to unlink.
  757          */
  758 
  759         /* join necessary multiast groups */
  760         if ((ifp->if_flags & IFF_MULTICAST) != 0) {
  761                 struct sockaddr_in6 mltaddr, mltmask;
  762 
  763                 /* join solicited multicast addr for new host id */
  764                 struct sockaddr_in6 llsol;
  765 
  766                 bzero(&llsol, sizeof(llsol));
  767                 llsol.sin6_family = AF_INET6;
  768                 llsol.sin6_len = sizeof(llsol);
  769                 llsol.sin6_addr.s6_addr16[0] = htons(0xff02);
  770                 llsol.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
  771                 llsol.sin6_addr.s6_addr32[1] = 0;
  772                 llsol.sin6_addr.s6_addr32[2] = htonl(1);
  773                 llsol.sin6_addr.s6_addr32[3] =
  774                     ifra->ifra_addr.sin6_addr.s6_addr32[3];
  775                 llsol.sin6_addr.s6_addr8[12] = 0xff;
  776                 imm = in6_joingroup(ifp, &llsol.sin6_addr, &error);
  777                 if (!imm)
  778                         goto cleanup;
  779                 LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
  780 
  781                 bzero(&mltmask, sizeof(mltmask));
  782                 mltmask.sin6_len = sizeof(struct sockaddr_in6);
  783                 mltmask.sin6_family = AF_INET6;
  784                 mltmask.sin6_addr = in6mask32;
  785 
  786                 /*
  787                  * join link-local all-nodes address
  788                  */
  789                 bzero(&mltaddr, sizeof(mltaddr));
  790                 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
  791                 mltaddr.sin6_family = AF_INET6;
  792                 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
  793                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
  794                 mltaddr.sin6_scope_id = 0;
  795 
  796                 /*
  797                  * XXX: do we really need this automatic routes?
  798                  * We should probably reconsider this stuff.  Most applications
  799                  * actually do not need the routes, since they usually specify
  800                  * the outgoing interface.
  801                  */
  802                 rt = rtalloc(sin6tosa(&mltaddr), 0, ifp->if_rdomain);
  803                 if (rt) {
  804                         /* 32bit came from "mltmask" */
  805                         if (memcmp(&mltaddr.sin6_addr,
  806                             &satosin6(rt_key(rt))->sin6_addr,
  807                             32 / 8)) {
  808                                 rtfree(rt);
  809                                 rt = NULL;
  810                         }
  811                 }
  812                 if (!rt) {
  813                         struct rt_addrinfo info;
  814 
  815                         bzero(&info, sizeof(info));
  816                         info.rti_ifa = &ia6->ia_ifa;
  817                         info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
  818                         info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
  819                         info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
  820                         info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
  821                         info.rti_flags = RTF_MULTICAST;
  822                         error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, NULL,
  823                             ifp->if_rdomain);
  824                         if (error)
  825                                 goto cleanup;
  826                 } else {
  827                         rtfree(rt);
  828                 }
  829                 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
  830                 if (!imm)
  831                         goto cleanup;
  832                 LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
  833 
  834                 /*
  835                  * join interface-local all-nodes address.
  836                  * (ff01::1%ifN, and ff01::%ifN/32)
  837                  */
  838                 bzero(&mltaddr, sizeof(mltaddr));
  839                 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
  840                 mltaddr.sin6_family = AF_INET6;
  841                 mltaddr.sin6_addr = in6addr_intfacelocal_allnodes;
  842                 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
  843                 mltaddr.sin6_scope_id = 0;
  844 
  845                 /* XXX: again, do we really need the route? */
  846                 rt = rtalloc(sin6tosa(&mltaddr), 0, ifp->if_rdomain);
  847                 if (rt) {
  848                         /* 32bit came from "mltmask" */
  849                         if (memcmp(&mltaddr.sin6_addr,
  850                             &satosin6(rt_key(rt))->sin6_addr,
  851                             32 / 8)) {
  852                                 rtfree(rt);
  853                                 rt = NULL;
  854                         }
  855                 }
  856                 if (!rt) {
  857                         struct rt_addrinfo info;
  858 
  859                         bzero(&info, sizeof(info));
  860                         info.rti_ifa = &ia6->ia_ifa;
  861                         info.rti_info[RTAX_DST] = sin6tosa(&mltaddr);
  862                         info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr);
  863                         info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask);
  864                         info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr);
  865                         info.rti_flags = RTF_MULTICAST;
  866                         error = rtrequest(RTM_ADD, &info, RTP_CONNECTED, NULL,
  867                             ifp->if_rdomain);
  868                         if (error)
  869                                 goto cleanup;
  870                 } else {
  871                         rtfree(rt);
  872                 }
  873                 imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
  874                 if (!imm)
  875                         goto cleanup;
  876                 LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
  877         }
  878 
  879         return (error);
  880 
  881   unlink:
  882         /*
  883          * XXX: if a change of an existing address failed, keep the entry
  884          * anyway.
  885          */
  886         if (hostIsNew)
  887                 in6_unlink_ifa(ia6, ifp);
  888         return (error);
  889 
  890   cleanup:
  891         in6_purgeaddr(&ia6->ia_ifa);
  892         return error;
  893 }
  894 
  895 void
  896 in6_purgeaddr(struct ifaddr *ifa)
  897 {
  898         struct ifnet *ifp = ifa->ifa_ifp;
  899         struct in6_ifaddr *ia6 = ifatoia6(ifa);
  900         struct in6_multi_mship *imm;
  901 
  902         /* stop DAD processing */
  903         nd6_dad_stop(ifa);
  904 
  905         /*
  906          * delete route to the destination of the address being purged.
  907          * The interface must be p2p or loopback in this case.
  908          */
  909         if ((ifp->if_flags & IFF_POINTOPOINT) && (ia6->ia_flags & IFA_ROUTE) &&
  910             ia6->ia_dstaddr.sin6_len != 0) {
  911                 int e;
  912 
  913                 e = rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr,
  914                     ifp->if_rdomain);
  915                 if (e != 0) {
  916                         char addr[INET6_ADDRSTRLEN];
  917                         log(LOG_ERR, "in6_purgeaddr: failed to remove "
  918                             "a route to the p2p destination: %s on %s, "
  919                             "errno=%d\n",
  920                             inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr,
  921                                 addr, sizeof(addr)),
  922                             ifp->if_xname, e);
  923                         /* proceed anyway... */
  924                 } else
  925                         ia6->ia_flags &= ~IFA_ROUTE;
  926         }
  927 
  928         /* Remove ownaddr's loopback rtentry, if it exists. */
  929         rt_ifa_dellocal(&(ia6->ia_ifa));
  930 
  931         /*
  932          * leave from multicast groups we have joined for the interface
  933          */
  934         while (!LIST_EMPTY(&ia6->ia6_memberships)) {
  935                 imm = LIST_FIRST(&ia6->ia6_memberships);
  936                 LIST_REMOVE(imm, i6mm_chain);
  937                 in6_leavegroup(imm);
  938         }
  939 
  940         in6_unlink_ifa(ia6, ifp);
  941 }
  942 
  943 void
  944 in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp)
  945 {
  946         struct ifaddr *ifa = &ia6->ia_ifa;
  947         int plen;
  948 
  949         NET_ASSERT_LOCKED();
  950 
  951         /* Release the reference to the base prefix. */
  952         plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
  953         if ((ifp->if_flags & IFF_LOOPBACK) == 0 && plen != 128) {
  954                 rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED,
  955                     ifa->ifa_addr, ifp->if_rdomain);
  956         }
  957 
  958         rt_ifa_purge(ifa);
  959         ifa_del(ifp, ifa);
  960 
  961         ia6->ia_ifp = NULL;
  962         ifafree(ifa);
  963 }
  964 
  965 /*
  966  * Initialize an interface's inet6 address
  967  * and routing table entry.
  968  */
  969 int
  970 in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia6, int newhost)
  971 {
  972         int     error = 0, plen, ifacount = 0;
  973         struct ifaddr *ifa;
  974 
  975         NET_ASSERT_LOCKED();
  976 
  977         /*
  978          * Give the interface a chance to initialize
  979          * if this is its first address (or it is a CARP interface)
  980          * and to validate the address if necessary.
  981          */
  982         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
  983                 if (ifa->ifa_addr->sa_family != AF_INET6)
  984                         continue;
  985                 ifacount++;
  986         }
  987 
  988         if ((ifacount <= 1 || ifp->if_type == IFT_CARP ||
  989             (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))) &&
  990             (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia6))) {
  991                 return (error);
  992         }
  993 
  994         ia6->ia_ifa.ifa_metric = ifp->if_metric;
  995 
  996         /* we could do in(6)_socktrim here, but just omit it at this moment. */
  997 
  998         /*
  999          * Special case:
 1000          * If the destination address is specified for a point-to-point
 1001          * interface, install a route to the destination as an interface
 1002          * direct route.
 1003          */
 1004         plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL); /* XXX */
 1005         if ((ifp->if_flags & IFF_POINTOPOINT) && plen == 128 &&
 1006             ia6->ia_dstaddr.sin6_family == AF_INET6) {
 1007                 ifa = &ia6->ia_ifa;
 1008                 error = rt_ifa_add(ifa, RTF_HOST | RTF_MPATH,
 1009                     ifa->ifa_dstaddr, ifp->if_rdomain);
 1010                 if (error != 0)
 1011                         return (error);
 1012                 ia6->ia_flags |= IFA_ROUTE;
 1013         }
 1014 
 1015         if (newhost)
 1016                 error = rt_ifa_addlocal(&(ia6->ia_ifa));
 1017 
 1018         return (error);
 1019 }
 1020 
 1021 /*
 1022  * Add an address to the list of IP6 multicast addresses for a
 1023  * given interface.
 1024  */
 1025 struct in6_multi *
 1026 in6_addmulti(struct in6_addr *maddr6, struct ifnet *ifp, int *errorp)
 1027 {
 1028         struct  in6_ifreq ifr;
 1029         struct  in6_multi *in6m;
 1030 
 1031         NET_ASSERT_LOCKED();
 1032 
 1033         *errorp = 0;
 1034         /*
 1035          * See if address already in list.
 1036          */
 1037         IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
 1038         if (in6m != NULL) {
 1039                 /*
 1040                  * Found it; just increment the reference count.
 1041                  */
 1042                 in6m->in6m_refcnt++;
 1043         } else {
 1044                 /*
 1045                  * New address; allocate a new multicast record
 1046                  * and link it into the interface's multicast list.
 1047                  */
 1048                 in6m = malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT | M_ZERO);
 1049                 if (in6m == NULL) {
 1050                         *errorp = ENOBUFS;
 1051                         return (NULL);
 1052                 }
 1053 
 1054                 in6m->in6m_sin.sin6_len = sizeof(struct sockaddr_in6);
 1055                 in6m->in6m_sin.sin6_family = AF_INET6;
 1056                 in6m->in6m_sin.sin6_addr = *maddr6;
 1057                 in6m->in6m_refcnt = 1;
 1058                 in6m->in6m_ifidx = ifp->if_index;
 1059                 in6m->in6m_ifma.ifma_addr = sin6tosa(&in6m->in6m_sin);
 1060 
 1061                 /*
 1062                  * Ask the network driver to update its multicast reception
 1063                  * filter appropriately for the new address.
 1064                  */
 1065                 memcpy(&ifr.ifr_addr, &in6m->in6m_sin, sizeof(in6m->in6m_sin));
 1066                 KERNEL_LOCK();
 1067                 *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr);
 1068                 KERNEL_UNLOCK();
 1069                 if (*errorp) {
 1070                         free(in6m, M_IPMADDR, sizeof(*in6m));
 1071                         return (NULL);
 1072                 }
 1073 
 1074                 TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &in6m->in6m_ifma,
 1075                     ifma_list);
 1076 
 1077                 /*
 1078                  * Let MLD6 know that we have joined a new IP6 multicast
 1079                  * group.
 1080                  */
 1081                 mld6_start_listening(in6m);
 1082         }
 1083 
 1084         return (in6m);
 1085 }
 1086 
 1087 /*
 1088  * Delete a multicast address record.
 1089  */
 1090 void
 1091 in6_delmulti(struct in6_multi *in6m)
 1092 {
 1093         struct  in6_ifreq ifr;
 1094         struct  ifnet *ifp;
 1095 
 1096         NET_ASSERT_LOCKED();
 1097 
 1098         if (--in6m->in6m_refcnt == 0) {
 1099                 /*
 1100                  * No remaining claims to this record; let MLD6 know
 1101                  * that we are leaving the multicast group.
 1102                  */
 1103                 mld6_stop_listening(in6m);
 1104                 ifp = if_get(in6m->in6m_ifidx);
 1105 
 1106                 /*
 1107                  * Notify the network driver to update its multicast
 1108                  * reception filter.
 1109                  */
 1110                 if (ifp != NULL) {
 1111                         bzero(&ifr.ifr_addr, sizeof(struct sockaddr_in6));
 1112                         ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
 1113                         ifr.ifr_addr.sin6_family = AF_INET6;
 1114                         ifr.ifr_addr.sin6_addr = in6m->in6m_addr;
 1115                         KERNEL_LOCK();
 1116                         (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
 1117                         KERNEL_UNLOCK();
 1118 
 1119                         TAILQ_REMOVE(&ifp->if_maddrlist, &in6m->in6m_ifma,
 1120                             ifma_list);
 1121                 }
 1122                 if_put(ifp);
 1123 
 1124                 free(in6m, M_IPMADDR, sizeof(*in6m));
 1125         }
 1126 }
 1127 
 1128 /*
 1129  * Return 1 if the multicast group represented by ``maddr6'' has been
 1130  * joined by interface ``ifp'', 0 otherwise.
 1131  */
 1132 int
 1133 in6_hasmulti(struct in6_addr *maddr6, struct ifnet *ifp)
 1134 {
 1135         struct in6_multi *in6m;
 1136         int joined;
 1137 
 1138         IN6_LOOKUP_MULTI(*maddr6, ifp, in6m);
 1139         joined = (in6m != NULL);
 1140 
 1141         return (joined);
 1142 }
 1143 
 1144 struct in6_multi_mship *
 1145 in6_joingroup(struct ifnet *ifp, struct in6_addr *addr, int *errorp)
 1146 {
 1147         struct in6_multi_mship *imm;
 1148 
 1149         imm = malloc(sizeof(*imm), M_IPMADDR, M_NOWAIT);
 1150         if (!imm) {
 1151                 *errorp = ENOBUFS;
 1152                 return NULL;
 1153         }
 1154         imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp);
 1155         if (!imm->i6mm_maddr) {
 1156                 /* *errorp is already set */
 1157                 free(imm, M_IPMADDR, sizeof(*imm));
 1158                 return NULL;
 1159         }
 1160         return imm;
 1161 }
 1162 
 1163 void
 1164 in6_leavegroup(struct in6_multi_mship *imm)
 1165 {
 1166 
 1167         if (imm->i6mm_maddr)
 1168                 in6_delmulti(imm->i6mm_maddr);
 1169         free(imm,  M_IPMADDR, sizeof(*imm));
 1170 }
 1171 
 1172 /*
 1173  * Find an IPv6 interface link-local address specific to an interface.
 1174  */
 1175 struct in6_ifaddr *
 1176 in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
 1177 {
 1178         struct ifaddr *ifa;
 1179 
 1180         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1181                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1182                         continue;
 1183                 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
 1184                         if ((ifatoia6(ifa)->ia6_flags & ignoreflags) != 0)
 1185                                 continue;
 1186                         break;
 1187                 }
 1188         }
 1189 
 1190         return (ifatoia6(ifa));
 1191 }
 1192 
 1193 
 1194 /*
 1195  * find the internet address corresponding to a given interface and address.
 1196  */
 1197 struct in6_ifaddr *
 1198 in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
 1199 {
 1200         struct ifaddr *ifa;
 1201 
 1202         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1203                 if (ifa->ifa_addr->sa_family != AF_INET6)
 1204                         continue;
 1205                 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
 1206                         break;
 1207         }
 1208 
 1209         return (ifatoia6(ifa));
 1210 }
 1211 
 1212 /*
 1213  * Get a scope of the address. Node-local, link-local, site-local or global.
 1214  */
 1215 int
 1216 in6_addrscope(struct in6_addr *addr)
 1217 {
 1218         int scope;
 1219 
 1220         if (addr->s6_addr8[0] == 0xfe) {
 1221                 scope = addr->s6_addr8[1] & 0xc0;
 1222 
 1223                 switch (scope) {
 1224                 case 0x80:
 1225                         return __IPV6_ADDR_SCOPE_LINKLOCAL;
 1226                         break;
 1227                 case 0xc0:
 1228                         return __IPV6_ADDR_SCOPE_SITELOCAL;
 1229                         break;
 1230                 default:
 1231                         return __IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
 1232                         break;
 1233                 }
 1234         }
 1235 
 1236 
 1237         if (addr->s6_addr8[0] == 0xff) {
 1238                 scope = addr->s6_addr8[1] & 0x0f;
 1239 
 1240                 /*
 1241                  * due to other scope such as reserved,
 1242                  * return scope doesn't work.
 1243                  */
 1244                 switch (scope) {
 1245                 case __IPV6_ADDR_SCOPE_INTFACELOCAL:
 1246                         return __IPV6_ADDR_SCOPE_INTFACELOCAL;
 1247                         break;
 1248                 case __IPV6_ADDR_SCOPE_LINKLOCAL:
 1249                         return __IPV6_ADDR_SCOPE_LINKLOCAL;
 1250                         break;
 1251                 case __IPV6_ADDR_SCOPE_SITELOCAL:
 1252                         return __IPV6_ADDR_SCOPE_SITELOCAL;
 1253                         break;
 1254                 default:
 1255                         return __IPV6_ADDR_SCOPE_GLOBAL;
 1256                         break;
 1257                 }
 1258         }
 1259 
 1260         if (bcmp(&in6addr_loopback, addr, sizeof(*addr) - 1) == 0) {
 1261                 if (addr->s6_addr8[15] == 1) /* loopback */
 1262                         return __IPV6_ADDR_SCOPE_INTFACELOCAL;
 1263                 if (addr->s6_addr8[15] == 0) /* unspecified */
 1264                         return __IPV6_ADDR_SCOPE_LINKLOCAL;
 1265         }
 1266 
 1267         return __IPV6_ADDR_SCOPE_GLOBAL;
 1268 }
 1269 
 1270 int
 1271 in6_addr2scopeid(unsigned int ifidx, struct in6_addr *addr)
 1272 {
 1273         int scope = in6_addrscope(addr);
 1274 
 1275         switch(scope) {
 1276         case __IPV6_ADDR_SCOPE_INTFACELOCAL:
 1277         case __IPV6_ADDR_SCOPE_LINKLOCAL:
 1278                 /* XXX: we do not distinguish between a link and an I/F. */
 1279                 return (ifidx);
 1280 
 1281         case __IPV6_ADDR_SCOPE_SITELOCAL:
 1282                 return (0);     /* XXX: invalid. */
 1283 
 1284         default:
 1285                 return (0);     /* XXX: treat as global. */
 1286         }
 1287 }
 1288 
 1289 /*
 1290  * return length of part which dst and src are equal
 1291  * hard coding...
 1292  */
 1293 int
 1294 in6_matchlen(struct in6_addr *src, struct in6_addr *dst)
 1295 {
 1296         int match = 0;
 1297         u_char *s = (u_char *)src, *d = (u_char *)dst;
 1298         u_char *lim = s + 16, r;
 1299 
 1300         while (s < lim)
 1301                 if ((r = (*d++ ^ *s++)) != 0) {
 1302                         while (r < 128) {
 1303                                 match++;
 1304                                 r <<= 1;
 1305                         }
 1306                         break;
 1307                 } else
 1308                         match += 8;
 1309         return match;
 1310 }
 1311 
 1312 void
 1313 in6_prefixlen2mask(struct in6_addr *maskp, int len)
 1314 {
 1315         u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
 1316         int bytelen, bitlen, i;
 1317 
 1318         /* sanity check */
 1319         if (0 > len || len > 128) {
 1320                 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
 1321                     len);
 1322                 return;
 1323         }
 1324 
 1325         bzero(maskp, sizeof(*maskp));
 1326         bytelen = len / 8;
 1327         bitlen = len % 8;
 1328         for (i = 0; i < bytelen; i++)
 1329                 maskp->s6_addr[i] = 0xff;
 1330         /* len == 128 is ok because bitlen == 0 then */
 1331         if (bitlen)
 1332                 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
 1333 }
 1334 
 1335 /*
 1336  * return the best address out of the same scope
 1337  */
 1338 struct in6_ifaddr *
 1339 in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain)
 1340 {
 1341         int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
 1342         int blen = -1;
 1343         struct ifaddr *ifa;
 1344         struct ifnet *ifp;
 1345         struct in6_ifaddr *ia6_best = NULL;
 1346 
 1347         if (oifp == NULL) {
 1348                 printf("%s: output interface is not specified\n", __func__);
 1349                 return (NULL);
 1350         }
 1351 
 1352         /* We search for all addresses on all interfaces from the beginning. */
 1353         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1354                 if (ifp->if_rdomain != rdomain)
 1355                         continue;
 1356 #if NCARP > 0
 1357                 /*
 1358                  * Never use a carp address of an interface which is not
 1359                  * the master.
 1360                  */
 1361                 if (ifp->if_type == IFT_CARP && !carp_iamatch(ifp))
 1362                         continue;
 1363 #endif
 1364 
 1365                 /*
 1366                  * We can never take an address that breaks the scope zone
 1367                  * of the destination.
 1368                  */
 1369                 if (in6_addr2scopeid(ifp->if_index, dst) !=
 1370                     in6_addr2scopeid(oifp->if_index, dst))
 1371                         continue;
 1372 
 1373                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1374                         int tlen = -1;
 1375 
 1376                         if (ifa->ifa_addr->sa_family != AF_INET6)
 1377                                 continue;
 1378 
 1379                         src_scope = in6_addrscope(IFA_IN6(ifa));
 1380 
 1381                         /*
 1382                          * Don't use an address before completing DAD
 1383                          * nor a duplicated address.
 1384                          */
 1385                         if (ifatoia6(ifa)->ia6_flags &
 1386                             (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED))
 1387                                 continue;
 1388 
 1389                         /*
 1390                          * RFC 6724 allows anycast addresses as source address
 1391                          * because the restriction was removed in RFC 4291.
 1392                          * However RFC 4443 states that ICMPv6 responses
 1393                          * MUST use a unicast source address.
 1394                          *
 1395                          * XXX Skip anycast addresses for now since
 1396                          * icmp6_reflect() uses this function for source
 1397                          * address selection.
 1398                          */
 1399                         if (ifatoia6(ifa)->ia6_flags & IN6_IFF_ANYCAST)
 1400                                 continue;
 1401 
 1402                         if (ifatoia6(ifa)->ia6_flags & IN6_IFF_DETACHED)
 1403                                 continue;
 1404 
 1405                         /*
 1406                          * If this is the first address we find,
 1407                          * keep it anyway.
 1408                          */
 1409                         if (ia6_best == NULL)
 1410                                 goto replace;
 1411 
 1412                         /*
 1413                          * ia6_best is never NULL beyond this line except
 1414                          * within the block labeled "replace".
 1415                          */
 1416 
 1417                         /*
 1418                          * Rule 2: Prefer appropriate scope.
 1419                          * Find the address with the smallest scope that is
 1420                          * bigger (or equal) to the scope of the destination
 1421                          * address.
 1422                          * Accept an address with smaller scope than the
 1423                          * destination if non exists with bigger scope.
 1424                          */
 1425                         if (best_scope < src_scope) {
 1426                                 if (best_scope < dst_scope)
 1427                                         goto replace;
 1428                                 else
 1429                                         continue;
 1430                         } else if (src_scope < best_scope) {
 1431                                 if (src_scope < dst_scope)
 1432                                         continue;
 1433                                 else
 1434                                         goto replace;
 1435                         }
 1436 
 1437                         /* Rule 3: Avoid deprecated addresses. */
 1438                         if (ifatoia6(ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
 1439                                 /*
 1440                                  * Ignore any deprecated addresses if
 1441                                  * specified by configuration.
 1442                                  */
 1443                                 if (!ip6_use_deprecated)
 1444                                         continue;
 1445 
 1446                                 /*
 1447                                  * If we have already found a non-deprecated
 1448                                  * candidate, just ignore deprecated addresses.
 1449                                  */
 1450                                 if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED)
 1451                                     == 0)
 1452                                         continue;
 1453                         } else if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED))
 1454                                 goto replace;
 1455 
 1456                         /*
 1457                          * Rule 4: Prefer home addresses.
 1458                          * We do not support home addresses.
 1459                          */
 1460 
 1461                         /* Rule 5: Prefer outgoing interface */
 1462                         if (ia6_best->ia_ifp == oifp && ifp != oifp)
 1463                                 continue;
 1464                         if (ia6_best->ia_ifp != oifp && ifp == oifp)
 1465                                 goto replace;
 1466 
 1467                         /*
 1468                          * Rule 5.5: Prefer addresses in a prefix advertised
 1469                          * by the next-hop.
 1470                          * We do not track this information.
 1471                          */
 1472 
 1473                         /*
 1474                          * Rule 6: Prefer matching label.
 1475                          * We do not implement policy tables.
 1476                          */
 1477 
 1478                         /* Rule 7: Prefer temporary addresses. */
 1479                         if ((ia6_best->ia6_flags & IN6_IFF_TEMPORARY) &&
 1480                             !(ifatoia6(ifa)->ia6_flags & IN6_IFF_TEMPORARY))
 1481                                 continue;
 1482                         if (!(ia6_best->ia6_flags & IN6_IFF_TEMPORARY) &&
 1483                             (ifatoia6(ifa)->ia6_flags & IN6_IFF_TEMPORARY))
 1484                                 goto replace;
 1485 
 1486                         /* Rule 8: Use longest matching prefix. */
 1487                         tlen = in6_matchlen(IFA_IN6(ifa), dst);
 1488                         if (tlen > blen) {
 1489 #if NCARP > 0
 1490                                 /*
 1491                                  * Don't let carp interfaces win a tie against
 1492                                  * the output interface based on matchlen.
 1493                                  * We should only use a carp address if no
 1494                                  * other interface has a usable address.
 1495                                  * Otherwise, when communicating from a carp
 1496                                  * master to a carp backup, the backup system
 1497                                  * won't respond since the carp address is also
 1498                                  * configured as a local address on the backup.
 1499                                  * Note that carp interfaces in backup state
 1500                                  * were already skipped above.
 1501                                  */
 1502                                 if (ifp->if_type == IFT_CARP &&
 1503                                     oifp->if_type != IFT_CARP)
 1504                                         continue;
 1505 #endif
 1506                                 goto replace;
 1507                         } else if (tlen < blen)
 1508                                 continue;
 1509 
 1510                         /*
 1511                          * If the eight rules fail to choose a single address,
 1512                          * the tiebreaker is implementation-specific.
 1513                          */
 1514 
 1515                          /* Prefer address with highest pltime. */
 1516                         if (ia6_best->ia6_updatetime +
 1517                             ia6_best->ia6_lifetime.ia6t_pltime <
 1518                             ifatoia6(ifa)->ia6_updatetime +
 1519                             ifatoia6(ifa)->ia6_lifetime.ia6t_pltime)
 1520                                 goto replace;
 1521                         else if (ia6_best->ia6_updatetime +
 1522                             ia6_best->ia6_lifetime.ia6t_pltime >
 1523                             ifatoia6(ifa)->ia6_updatetime +
 1524                             ifatoia6(ifa)->ia6_lifetime.ia6t_pltime)
 1525                                 continue;
 1526 
 1527                         /* Prefer address with highest vltime. */
 1528                         if (ia6_best->ia6_updatetime +
 1529                             ia6_best->ia6_lifetime.ia6t_vltime <
 1530                             ifatoia6(ifa)->ia6_updatetime +
 1531                             ifatoia6(ifa)->ia6_lifetime.ia6t_vltime)
 1532                                 goto replace;
 1533                         else if (ia6_best->ia6_updatetime +
 1534                             ia6_best->ia6_lifetime.ia6t_vltime >
 1535                             ifatoia6(ifa)->ia6_updatetime +
 1536                             ifatoia6(ifa)->ia6_lifetime.ia6t_vltime)
 1537                                 continue;
 1538 
 1539                         continue;
 1540                   replace:
 1541                         ia6_best = ifatoia6(ifa);
 1542                         blen = tlen >= 0 ? tlen :
 1543                             in6_matchlen(IFA_IN6(ifa), dst);
 1544                         best_scope =
 1545                             in6_addrscope(&ia6_best->ia_addr.sin6_addr);
 1546                 }
 1547         }
 1548 
 1549         /* count statistics for future improvements */
 1550         if (ia6_best == NULL)
 1551                 ip6stat_inc(ip6s_sources_none);
 1552         else {
 1553                 if (oifp == ia6_best->ia_ifp)
 1554                         ip6stat_inc(ip6s_sources_sameif + best_scope);
 1555                 else
 1556                         ip6stat_inc(ip6s_sources_otherif + best_scope);
 1557 
 1558                 if (best_scope == dst_scope)
 1559                         ip6stat_inc(ip6s_sources_samescope + best_scope);
 1560                 else
 1561                         ip6stat_inc(ip6s_sources_otherscope + best_scope);
 1562 
 1563                 if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
 1564                         ip6stat_inc(ip6s_sources_deprecated + best_scope);
 1565         }
 1566 
 1567         return (ia6_best);
 1568 }
 1569 
 1570 int
 1571 in6if_do_dad(struct ifnet *ifp)
 1572 {
 1573         if ((ifp->if_flags & IFF_LOOPBACK) != 0)
 1574                 return (0);
 1575 
 1576         switch (ifp->if_type) {
 1577 #if NCARP > 0
 1578         case IFT_CARP:
 1579                 /*
 1580                  * XXX: DAD does not work currently on carp(4)
 1581                  * so disable it for now.
 1582                  */
 1583                 return (0);
 1584 #endif
 1585         default:
 1586                 /*
 1587                  * Our DAD routine requires the interface up and running.
 1588                  * However, some interfaces can be up before the RUNNING
 1589                  * status.  Additionally, users may try to assign addresses
 1590                  * before the interface becomes up (or running).
 1591                  * We simply skip DAD in such a case as a work around.
 1592                  * XXX: we should rather mark "tentative" on such addresses,
 1593                  * and do DAD after the interface becomes ready.
 1594                  */
 1595                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
 1596                     (IFF_UP|IFF_RUNNING))
 1597                         return (0);
 1598 
 1599                 return (1);
 1600         }
 1601 }

Cache object: d96c760ac625b45180d02a32010b2e9f


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