LCOV - code coverage report
Current view: top level - netinet6 - in6.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 648 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13