The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/in.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1982, 1986, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      @(#)in.c        8.4 (Berkeley) 1/9/95
   30  * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.14 2002/11/08 00:45:50 suz Exp $
   31  */
   32 
   33 #include "opt_bootp.h"
   34 #include "opt_carp.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/sockio.h>
   39 #include <sys/malloc.h>
   40 #include <sys/proc.h>
   41 #include <sys/priv.h>
   42 #include <sys/msgport.h>
   43 #include <sys/socket.h>
   44 
   45 #include <sys/kernel.h>
   46 #include <sys/sysctl.h>
   47 #include <sys/thread2.h>
   48 
   49 #include <net/if.h>
   50 #include <net/if_types.h>
   51 #include <net/route.h>
   52 #include <net/netmsg2.h>
   53 #include <net/netisr2.h>
   54 
   55 #include <netinet/in.h>
   56 #include <netinet/in_var.h>
   57 #include <netinet/in_pcb.h>
   58 #include <netinet/udp_var.h>
   59 
   60 #include <netinet/igmp_var.h>
   61 
   62 MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
   63 
   64 static int in_mask2len (struct in_addr *);
   65 static void in_len2mask (struct in_addr *, int);
   66 static int in_lifaddr_ioctl (struct socket *, u_long, caddr_t,
   67         struct ifnet *, struct thread *);
   68 
   69 static void     in_socktrim (struct sockaddr_in *);
   70 static int      in_ifinit(struct ifnet *, struct in_ifaddr *,
   71                     const struct sockaddr_in *, int);
   72 
   73 static int      in_control_internal(u_long, caddr_t, struct ifnet *,
   74                     struct thread *);
   75 static int      in_control_redispatch(u_long, caddr_t, struct ifnet *,
   76                     struct thread *);
   77 
   78 static int      in_addprefix(struct in_ifaddr *, int);
   79 static void     in_scrubprefix(struct in_ifaddr *);
   80 
   81 static int subnetsarelocal = 0;
   82 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
   83     &subnetsarelocal, 0,
   84     "Count all internet addresses of subnets of the local net as local");
   85 
   86 struct in_multihead in_multihead; /* XXX BSS initialization */
   87 
   88 extern struct inpcbinfo ripcbinfo;
   89 
   90 /*
   91  * Return 1 if an internet address is for a ``local'' host
   92  * (one to which we have a connection).  If subnetsarelocal
   93  * is true, this includes other subnets of the local net.
   94  * Otherwise, it includes only the directly-connected (sub)nets.
   95  */
   96 int
   97 in_localaddr(struct in_addr in)
   98 {
   99         u_long i = ntohl(in.s_addr);
  100         struct in_ifaddr_container *iac;
  101         struct in_ifaddr *ia;
  102 
  103         if (subnetsarelocal) {
  104                 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
  105                         ia = iac->ia;
  106 
  107                         if ((i & ia->ia_netmask) == ia->ia_net)
  108                                 return (1);
  109                 }
  110         } else {
  111                 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
  112                         ia = iac->ia;
  113 
  114                         if ((i & ia->ia_subnetmask) == ia->ia_subnet)
  115                                 return (1);
  116                 }
  117         }
  118         return (0);
  119 }
  120 
  121 /*
  122  * Determine whether an IP address is in a reserved set of addresses
  123  * that may not be forwarded, or whether datagrams to that destination
  124  * may be forwarded.
  125  */
  126 int
  127 in_canforward(struct in_addr in)
  128 {
  129         u_long i = ntohl(in.s_addr);
  130         u_long net;
  131 
  132         if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
  133                 return (0);
  134         if (IN_CLASSA(i)) {
  135                 net = i & IN_CLASSA_NET;
  136                 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
  137                         return (0);
  138         }
  139         return (1);
  140 }
  141 
  142 /*
  143  * Trim a mask in a sockaddr
  144  */
  145 static void
  146 in_socktrim(struct sockaddr_in *ap)
  147 {
  148     char *cplim = (char *) &ap->sin_addr;
  149     char *cp = (char *) (&ap->sin_addr + 1);
  150 
  151     ap->sin_len = 0;
  152     while (--cp >= cplim)
  153         if (*cp) {
  154             (ap)->sin_len = cp - (char *) (ap) + 1;
  155             break;
  156         }
  157 }
  158 
  159 static int
  160 in_mask2len(struct in_addr *mask)
  161 {
  162         int x, y;
  163         u_char *p;
  164 
  165         p = (u_char *)mask;
  166         for (x = 0; x < sizeof *mask; x++) {
  167                 if (p[x] != 0xff)
  168                         break;
  169         }
  170         y = 0;
  171         if (x < sizeof *mask) {
  172                 for (y = 0; y < 8; y++) {
  173                         if ((p[x] & (0x80 >> y)) == 0)
  174                                 break;
  175                 }
  176         }
  177         return x * 8 + y;
  178 }
  179 
  180 static void
  181 in_len2mask(struct in_addr *mask, int len)
  182 {
  183         int i;
  184         u_char *p;
  185 
  186         p = (u_char *)mask;
  187         bzero(mask, sizeof *mask);
  188         for (i = 0; i < len / 8; i++)
  189                 p[i] = 0xff;
  190         if (len % 8)
  191                 p[i] = (0xff00 >> (len % 8)) & 0xff;
  192 }
  193 
  194 static int in_interfaces;       /* number of external internet interfaces */
  195 
  196 void
  197 in_control_dispatch(netmsg_t msg)
  198 {
  199         int error;
  200 
  201         error = in_control_redispatch(msg->control.nm_cmd,
  202                                       msg->control.nm_data,
  203                                       msg->control.nm_ifp,
  204                                       msg->control.nm_td);
  205         lwkt_replymsg(&msg->lmsg, error);
  206 }
  207 
  208 static void
  209 in_control_internal_dispatch(netmsg_t msg)
  210 {
  211         int error;
  212 
  213         error = in_control_internal(msg->control.nm_cmd,
  214                                     msg->control.nm_data,
  215                                     msg->control.nm_ifp,
  216                                     msg->control.nm_td);
  217         lwkt_replymsg(&msg->lmsg, error);
  218 }
  219 
  220 static int
  221 in_control_redispatch(u_long cmd, caddr_t data, struct ifnet *ifp,
  222                       struct thread *td)
  223 {
  224         struct netmsg_pru_control msg;
  225         int error;
  226 
  227         /*
  228          * IFADDR alterations are serialized by netisr0
  229          */
  230         switch (cmd) {
  231         case SIOCSIFDSTADDR:
  232         case SIOCSIFBRDADDR:
  233         case SIOCSIFADDR:
  234         case SIOCSIFNETMASK:
  235         case SIOCAIFADDR:
  236         case SIOCDIFADDR:
  237                 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
  238                             0, in_control_internal_dispatch);
  239                 msg.nm_cmd = cmd;
  240                 msg.nm_data = data;
  241                 msg.nm_ifp = ifp;
  242                 msg.nm_td = td;
  243                 lwkt_domsg(netisr_cpuport(0), &msg.base.lmsg, 0);
  244                 error = msg.base.lmsg.ms_error;
  245                 break;
  246 
  247         default:
  248                 error = in_control_internal(cmd, data, ifp, td);
  249                 break;
  250         }
  251         return error;
  252 }
  253 
  254 /*
  255  * Generic internet control operations (ioctl's).
  256  * Ifp is 0 if not an interface-specific ioctl.
  257  *
  258  * NOTE! td might be NULL.
  259  */
  260 /* ARGSUSED */
  261 int
  262 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
  263            struct thread *td)
  264 {
  265         int error;
  266 
  267         switch (cmd) {
  268         case SIOCALIFADDR:
  269         case SIOCDLIFADDR:
  270                 if (td && (error = priv_check(td, PRIV_ROOT)) != 0)
  271                         return error;
  272                 /* FALLTHROUGH */
  273         case SIOCGLIFADDR:
  274                 if (!ifp)
  275                         return EINVAL;
  276                 return in_lifaddr_ioctl(so, cmd, data, ifp, td);
  277         }
  278 
  279         KASSERT(cmd != SIOCALIFADDR && cmd != SIOCDLIFADDR,
  280                 ("recursive SIOC%cLIFADDR!",
  281                  cmd == SIOCDLIFADDR ? 'D' : 'A'));
  282 
  283         return in_control_redispatch(cmd, data, ifp, td);
  284 }
  285 
  286 static void
  287 in_ialink_dispatch(netmsg_t msg)
  288 {
  289         struct in_ifaddr *ia = msg->lmsg.u.ms_resultp;
  290         struct ifaddr_container *ifac;
  291         struct in_ifaddr_container *iac;
  292         int cpu = mycpuid;
  293 
  294         crit_enter();
  295 
  296         ifac = &ia->ia_ifa.ifa_containers[cpu];
  297         ASSERT_IFAC_VALID(ifac);
  298         KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD) == 0,
  299                 ("ia is on in_ifaddrheads"));
  300 
  301         ifac->ifa_listmask |= IFA_LIST_IN_IFADDRHEAD;
  302         iac = &ifac->ifa_proto_u.u_in_ifac;
  303         TAILQ_INSERT_TAIL(&in_ifaddrheads[cpu], iac, ia_link);
  304 
  305         crit_exit();
  306 
  307         ifa_forwardmsg(&msg->lmsg, cpu + 1);
  308 }
  309 
  310 static void
  311 in_iaunlink_dispatch(netmsg_t msg)
  312 {
  313         struct in_ifaddr *ia = msg->lmsg.u.ms_resultp;
  314         struct ifaddr_container *ifac;
  315         struct in_ifaddr_container *iac;
  316         int cpu = mycpuid;
  317 
  318         crit_enter();
  319 
  320         ifac = &ia->ia_ifa.ifa_containers[cpu];
  321         ASSERT_IFAC_VALID(ifac);
  322         KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD,
  323                 ("ia is not on in_ifaddrheads"));
  324 
  325         iac = &ifac->ifa_proto_u.u_in_ifac;
  326         TAILQ_REMOVE(&in_ifaddrheads[cpu], iac, ia_link);
  327         ifac->ifa_listmask &= ~IFA_LIST_IN_IFADDRHEAD;
  328 
  329         crit_exit();
  330 
  331         ifa_forwardmsg(&msg->lmsg, cpu + 1);
  332 }
  333 
  334 static void
  335 in_iahashins_dispatch(netmsg_t msg)
  336 {
  337         struct in_ifaddr *ia = msg->lmsg.u.ms_resultp;
  338         struct ifaddr_container *ifac;
  339         struct in_ifaddr_container *iac;
  340         int cpu = mycpuid;
  341 
  342         crit_enter();
  343 
  344         ifac = &ia->ia_ifa.ifa_containers[cpu];
  345         ASSERT_IFAC_VALID(ifac);
  346         KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) == 0,
  347                 ("ia is on in_ifaddrhashtbls"));
  348 
  349         ifac->ifa_listmask |= IFA_LIST_IN_IFADDRHASH;
  350         iac = &ifac->ifa_proto_u.u_in_ifac;
  351         LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
  352                          iac, ia_hash);
  353 
  354         crit_exit();
  355 
  356         ifa_forwardmsg(&msg->lmsg, cpu + 1);
  357 }
  358 
  359 static void
  360 in_iahashrem_dispatch(netmsg_t msg)
  361 {
  362         struct in_ifaddr *ia = msg->lmsg.u.ms_resultp;
  363         struct ifaddr_container *ifac;
  364         struct in_ifaddr_container *iac;
  365         int cpu = mycpuid;
  366 
  367         crit_enter();
  368 
  369         ifac = &ia->ia_ifa.ifa_containers[cpu];
  370         ASSERT_IFAC_VALID(ifac);
  371         KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH,
  372                 ("ia is not on in_ifaddrhashtbls"));
  373 
  374         iac = &ifac->ifa_proto_u.u_in_ifac;
  375         LIST_REMOVE(iac, ia_hash);
  376         ifac->ifa_listmask &= ~IFA_LIST_IN_IFADDRHASH;
  377 
  378         crit_exit();
  379 
  380         ifa_forwardmsg(&msg->lmsg, cpu + 1);
  381 }
  382 
  383 static void
  384 in_ialink(struct in_ifaddr *ia)
  385 {
  386         struct netmsg_base msg;
  387 
  388         netmsg_init(&msg, NULL, &curthread->td_msgport,
  389                     0, in_ialink_dispatch);
  390         msg.lmsg.u.ms_resultp = ia;
  391 
  392         ifa_domsg(&msg.lmsg, 0);
  393 }
  394 
  395 void
  396 in_iaunlink(struct in_ifaddr *ia)
  397 {
  398         struct netmsg_base msg;
  399 
  400         netmsg_init(&msg, NULL, &curthread->td_msgport,
  401                     0, in_iaunlink_dispatch);
  402         msg.lmsg.u.ms_resultp = ia;
  403 
  404         ifa_domsg(&msg.lmsg, 0);
  405 }
  406 
  407 void
  408 in_iahash_insert(struct in_ifaddr *ia)
  409 {
  410         struct netmsg_base msg;
  411 
  412         netmsg_init(&msg, NULL, &curthread->td_msgport,
  413                     0, in_iahashins_dispatch);
  414         msg.lmsg.u.ms_resultp = ia;
  415 
  416         ifa_domsg(&msg.lmsg, 0);
  417 }
  418 
  419 void
  420 in_iahash_remove(struct in_ifaddr *ia)
  421 {
  422         struct netmsg_base msg;
  423 
  424         netmsg_init(&msg, NULL, &curthread->td_msgport,
  425                     0, in_iahashrem_dispatch);
  426         msg.lmsg.u.ms_resultp = ia;
  427 
  428         ifa_domsg(&msg.lmsg, 0);
  429 }
  430 
  431 static __inline struct in_ifaddr *
  432 in_ianext(struct in_ifaddr *oia)
  433 {
  434         struct ifaddr_container *ifac;
  435         struct in_ifaddr_container *iac;
  436 
  437         ifac = &oia->ia_ifa.ifa_containers[mycpuid];
  438         ASSERT_IFAC_VALID(ifac);
  439         KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD,
  440                 ("ia is not on in_ifaddrheads"));
  441 
  442         iac = &ifac->ifa_proto_u.u_in_ifac;
  443         iac = TAILQ_NEXT(iac, ia_link);
  444         if (iac != NULL)
  445                 return iac->ia;
  446         else
  447                 return NULL;
  448 }
  449 
  450 static int
  451 in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
  452                     struct thread *td)
  453 {
  454         struct ifreq *ifr = (struct ifreq *)data;
  455         struct in_ifaddr *ia = NULL;
  456         struct in_addr dst;
  457         struct in_aliasreq *ifra = (struct in_aliasreq *)data;
  458         struct ifaddr_container *ifac;
  459         struct in_ifaddr_container *iac;
  460         struct sockaddr_in oldaddr;
  461         int hostIsNew, iaIsNew, maskIsNew, ifpWasUp;
  462         int error = 0;
  463 
  464         iaIsNew = 0;
  465         ifpWasUp = 0;
  466 
  467         /*
  468          * Find address for this interface, if it exists.
  469          *
  470          * If an alias address was specified, find that one instead of
  471          * the first one on the interface, if possible
  472          */
  473         if (ifp) {
  474                 struct in_ifaddr *iap;
  475 
  476                 dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
  477                 LIST_FOREACH(iac, INADDR_HASH(dst.s_addr), ia_hash) {
  478                         iap = iac->ia;
  479                         if (iap->ia_ifp == ifp &&
  480                             iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
  481                                 ia = iap;
  482                                 break;
  483                         }
  484                 }
  485                 if (ia == NULL) {
  486                         TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
  487                                       ifa_link) {
  488                                 iap = ifatoia(ifac->ifa);
  489                                 if (iap->ia_addr.sin_family == AF_INET) {
  490                                         ia = iap;
  491                                         break;
  492                                 }
  493                         }
  494                 }
  495 
  496                 if (ifp->if_flags & IFF_UP)
  497                         ifpWasUp = 1;
  498         }
  499 
  500         switch (cmd) {
  501         case SIOCAIFADDR:
  502         case SIOCDIFADDR:
  503                 if (ifp == NULL)
  504                         return (EADDRNOTAVAIL);
  505                 if (ifra->ifra_addr.sin_family == AF_INET) {
  506                         while (ia != NULL) {
  507                                 if (ia->ia_ifp == ifp  &&
  508                                     ia->ia_addr.sin_addr.s_addr ==
  509                                     ifra->ifra_addr.sin_addr.s_addr)
  510                                         break;
  511                                 ia = in_ianext(ia);
  512                         }
  513                         if ((ifp->if_flags & IFF_POINTOPOINT) &&
  514                             cmd == SIOCAIFADDR &&
  515                             ifra->ifra_dstaddr.sin_addr.s_addr == INADDR_ANY) {
  516                                 return EDESTADDRREQ;
  517                         }
  518                 }
  519                 if (cmd == SIOCDIFADDR && ia == NULL)
  520                         return (EADDRNOTAVAIL);
  521                 /* FALLTHROUGH */
  522         case SIOCSIFADDR:
  523         case SIOCSIFNETMASK:
  524         case SIOCSIFDSTADDR:
  525                 if (td && (error = priv_check(td, PRIV_ROOT)) != 0)
  526                         return error;
  527 
  528                 if (ifp == NULL)
  529                         return (EADDRNOTAVAIL);
  530 
  531                 if (cmd == SIOCSIFDSTADDR &&
  532                     (ifp->if_flags & IFF_POINTOPOINT) == 0)
  533                         return (EINVAL);
  534 
  535                 if (ia == NULL) {
  536                         struct ifaddr *ifa;
  537                         int i;
  538 
  539                         ia = ifa_create(sizeof(*ia), M_WAITOK);
  540                         ifa = &ia->ia_ifa;
  541 
  542                         /*
  543                          * Setup per-CPU information
  544                          */
  545                         for (i = 0; i < ncpus; ++i) {
  546                                 ifac = &ifa->ifa_containers[i];
  547                                 iac = &ifac->ifa_proto_u.u_in_ifac;
  548                                 iac->ia = ia;
  549                                 iac->ia_ifac = ifac;
  550                         }
  551 
  552                         /*
  553                          * Protect from NETISR_IP traversing address list
  554                          * while we're modifying it.
  555                          */
  556                         crit_enter();
  557 
  558                         in_ialink(ia);
  559                         ifa_iflink(ifa, ifp, 1);
  560 
  561                         ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
  562                         ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
  563                         ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
  564                         ia->ia_sockmask.sin_len = 8;
  565                         ia->ia_sockmask.sin_family = AF_INET;
  566                         if (ifp->if_flags & IFF_BROADCAST) {
  567                                 ia->ia_broadaddr.sin_len = sizeof ia->ia_addr;
  568                                 ia->ia_broadaddr.sin_family = AF_INET;
  569                         }
  570                         ia->ia_ifp = ifp;
  571                         if (!(ifp->if_flags & IFF_LOOPBACK))
  572                                 in_interfaces++;
  573                         iaIsNew = 1;
  574 
  575                         crit_exit();
  576                 }
  577                 break;
  578 
  579         case SIOCSIFBRDADDR:
  580                 if (td && (error = priv_check(td, PRIV_ROOT)) != 0)
  581                         return error;
  582                 /* FALLTHROUGH */
  583 
  584         case SIOCGIFADDR:
  585         case SIOCGIFNETMASK:
  586         case SIOCGIFDSTADDR:
  587         case SIOCGIFBRDADDR:
  588                 if (ia == NULL)
  589                         return (EADDRNOTAVAIL);
  590                 break;
  591         }
  592 
  593         switch (cmd) {
  594         case SIOCGIFADDR:
  595                 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
  596                 return (0);
  597 
  598         case SIOCGIFBRDADDR:
  599                 if ((ifp->if_flags & IFF_BROADCAST) == 0)
  600                         return (EINVAL);
  601                 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
  602                 return (0);
  603 
  604         case SIOCGIFDSTADDR:
  605                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
  606                         return (EINVAL);
  607                 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
  608                 return (0);
  609 
  610         case SIOCGIFNETMASK:
  611                 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
  612                 return (0);
  613 
  614         case SIOCSIFDSTADDR:
  615                 KKASSERT(ifp->if_flags & IFF_POINTOPOINT);
  616 
  617                 oldaddr = ia->ia_dstaddr;
  618                 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
  619                 if (ifp->if_ioctl != NULL) {
  620                         ifnet_serialize_all(ifp);
  621                         error = ifp->if_ioctl(ifp, SIOCSIFDSTADDR, (caddr_t)ia,
  622                                               td->td_proc->p_ucred);
  623                         ifnet_deserialize_all(ifp);
  624                         if (error) {
  625                                 ia->ia_dstaddr = oldaddr;
  626                                 return (error);
  627                         }
  628                 }
  629                 if (ia->ia_flags & IFA_ROUTE) {
  630                         ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
  631                         rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
  632                         ia->ia_ifa.ifa_dstaddr =
  633                                         (struct sockaddr *)&ia->ia_dstaddr;
  634                         rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST | RTF_UP);
  635                 }
  636                 return (0);
  637 
  638         case SIOCSIFBRDADDR:
  639                 if ((ifp->if_flags & IFF_BROADCAST) == 0)
  640                         return (EINVAL);
  641                 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
  642                 return (0);
  643 
  644         case SIOCSIFADDR:
  645                 error = in_ifinit(ifp, ia,
  646                     (const struct sockaddr_in *)&ifr->ifr_addr, 1);
  647                 if (error != 0 && iaIsNew)
  648                         break;
  649                 if (error == 0) {
  650                         EVENTHANDLER_INVOKE(ifaddr_event, ifp,
  651                         iaIsNew ? IFADDR_EVENT_ADD : IFADDR_EVENT_CHANGE,
  652                         &ia->ia_ifa);
  653                 }
  654                 if (!ifpWasUp && (ifp->if_flags & IFF_UP)) {
  655                         /*
  656                          * Interface is brought up by in_ifinit()
  657                          * (via ifp->if_ioctl).  We act as if the
  658                          * interface got IFF_UP flag turned on.
  659                          */
  660                         if_up(ifp);
  661                 }
  662                 return (0);
  663 
  664         case SIOCSIFNETMASK:
  665                 ia->ia_sockmask.sin_addr = ifra->ifra_addr.sin_addr;
  666                 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
  667                 return (0);
  668 
  669         case SIOCAIFADDR:
  670                 maskIsNew = 0;
  671                 hostIsNew = 1;
  672                 error = 0;
  673                 if (ia->ia_addr.sin_family == AF_INET) {
  674                         if (ifra->ifra_addr.sin_len == 0) {
  675                                 ifra->ifra_addr = ia->ia_addr;
  676                                 hostIsNew = 0;
  677                         } else if (ifra->ifra_addr.sin_addr.s_addr ==
  678                                    ia->ia_addr.sin_addr.s_addr) {
  679                                 hostIsNew = 0;
  680                         }
  681                 }
  682                 if (ifra->ifra_mask.sin_len) {
  683                         in_ifscrub(ifp, ia);
  684                         ia->ia_sockmask = ifra->ifra_mask;
  685                         ia->ia_sockmask.sin_family = AF_INET;
  686                         ia->ia_subnetmask =
  687                             ntohl(ia->ia_sockmask.sin_addr.s_addr);
  688                         maskIsNew = 1;
  689                 }
  690                 if ((ifp->if_flags & IFF_POINTOPOINT) &&
  691                     ifra->ifra_dstaddr.sin_family == AF_INET) {
  692                         in_ifscrub(ifp, ia);
  693                         ia->ia_dstaddr = ifra->ifra_dstaddr;
  694                         maskIsNew  = 1; /* We lie; but the effect's the same */
  695                 }
  696                 if (ifra->ifra_addr.sin_family == AF_INET &&
  697                     (hostIsNew || maskIsNew))
  698                         error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
  699 
  700                 if (error != 0 && iaIsNew)
  701                         break;
  702 
  703                 if ((ifp->if_flags & IFF_BROADCAST) &&
  704                     ifra->ifra_broadaddr.sin_family == AF_INET)
  705                         ia->ia_broadaddr = ifra->ifra_broadaddr;
  706                 if (error == 0) {
  707                         EVENTHANDLER_INVOKE(ifaddr_event, ifp,
  708                         iaIsNew ? IFADDR_EVENT_ADD : IFADDR_EVENT_CHANGE,
  709                         &ia->ia_ifa);
  710                 }
  711                 if (!ifpWasUp && (ifp->if_flags & IFF_UP)) {
  712                         /* See the comment in SIOCSIFADDR */
  713                         if_up(ifp);
  714                 }
  715                 return (error);
  716 
  717         case SIOCDIFADDR:
  718                 /*
  719                  * in_ifscrub kills the interface route.
  720                  */
  721                 in_ifscrub(ifp, ia);
  722                 /*
  723                  * in_ifadown gets rid of all the rest of
  724                  * the routes.  This is not quite the right
  725                  * thing to do, but at least if we are running
  726                  * a routing process they will come back.
  727                  */
  728                 in_ifadown(&ia->ia_ifa, 1);
  729                 EVENTHANDLER_INVOKE(ifaddr_event, ifp, IFADDR_EVENT_DELETE,
  730                                     &ia->ia_ifa);
  731                 error = 0;
  732                 break;
  733 
  734         default:
  735                 if (ifp == NULL || ifp->if_ioctl == NULL)
  736                         return (EOPNOTSUPP);
  737                 ifnet_serialize_all(ifp);
  738                 error = ifp->if_ioctl(ifp, cmd, data, td->td_proc->p_ucred);
  739                 ifnet_deserialize_all(ifp);
  740                 return (error);
  741         }
  742 
  743         KKASSERT(cmd == SIOCDIFADDR ||
  744                  ((cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) && iaIsNew));
  745 
  746         ifa_ifunlink(&ia->ia_ifa, ifp);
  747         in_iaunlink(ia);
  748 
  749         if (cmd == SIOCDIFADDR) {
  750                 ifac = &ia->ia_ifa.ifa_containers[mycpuid];
  751                 if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH)
  752                         in_iahash_remove(ia);
  753         }
  754 #ifdef INVARIANTS
  755         else {
  756                 /*
  757                  * If cmd is SIOCSIFADDR or SIOCAIFADDR, in_ifinit() has
  758                  * already taken care of the deletion from hash table
  759                  */
  760                 ifac = &ia->ia_ifa.ifa_containers[mycpuid];
  761                 KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) == 0,
  762                         ("SIOC%cIFADDR failed on new ia, "
  763                          "but the new ia is still in hash table",
  764                          cmd == SIOCSIFADDR ? 'S' : 'A'));
  765         }
  766 #endif
  767 
  768         ifa_destroy(&ia->ia_ifa);
  769 
  770         if ((cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) &&
  771             !ifpWasUp && (ifp->if_flags & IFF_UP)) {
  772                 /*
  773                  * Though the address assignment failed, the
  774                  * interface is brought up by in_ifinit()
  775                  * (via ifp->if_ioctl).  With the hope that
  776                  * the interface has some valid addresses, we
  777                  * act as if IFF_UP flag was just set on the
  778                  * interface.
  779                  *
  780                  * NOTE:
  781                  * This could only be done after the failed
  782                  * address is unlinked from the global address
  783                  * list.
  784                  */
  785                 if_up(ifp);
  786         }
  787 
  788         return (error);
  789 }
  790 
  791 /*
  792  * SIOC[GAD]LIFADDR.
  793  *      SIOCGLIFADDR: get first address. (?!?)
  794  *      SIOCGLIFADDR with IFLR_PREFIX:
  795  *              get first address that matches the specified prefix.
  796  *      SIOCALIFADDR: add the specified address.
  797  *      SIOCALIFADDR with IFLR_PREFIX:
  798  *              EINVAL since we can't deduce hostid part of the address.
  799  *      SIOCDLIFADDR: delete the specified address.
  800  *      SIOCDLIFADDR with IFLR_PREFIX:
  801  *              delete the first address that matches the specified prefix.
  802  * return values:
  803  *      EINVAL on invalid parameters
  804  *      EADDRNOTAVAIL on prefix match failed/specified address not found
  805  *      other values may be returned from in_ioctl()
  806  *
  807  * NOTE! td might be NULL.
  808  */
  809 static int
  810 in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
  811                  struct thread *td)
  812 {
  813         struct if_laddrreq *iflr = (struct if_laddrreq *)data;
  814 
  815         /* sanity checks */
  816         if (!data || !ifp) {
  817                 panic("invalid argument to in_lifaddr_ioctl");
  818                 /*NOTRECHED*/
  819         }
  820 
  821         switch (cmd) {
  822         case SIOCGLIFADDR:
  823                 /* address must be specified on GET with IFLR_PREFIX */
  824                 if ((iflr->flags & IFLR_PREFIX) == 0)
  825                         break;
  826                 /*FALLTHROUGH*/
  827         case SIOCALIFADDR:
  828         case SIOCDLIFADDR:
  829                 /* address must be specified on ADD and DELETE */
  830                 if (iflr->addr.ss_family != AF_INET)
  831                         return EINVAL;
  832                 if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
  833                         return EINVAL;
  834                 /* XXX need improvement */
  835                 if (iflr->dstaddr.ss_family
  836                  && iflr->dstaddr.ss_family != AF_INET)
  837                         return EINVAL;
  838                 if (iflr->dstaddr.ss_family
  839                  && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
  840                         return EINVAL;
  841                 break;
  842         default: /*shouldn't happen*/
  843                 return EOPNOTSUPP;
  844         }
  845         if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
  846                 return EINVAL;
  847 
  848         switch (cmd) {
  849         case SIOCALIFADDR:
  850             {
  851                 struct in_aliasreq ifra;
  852 
  853                 if (iflr->flags & IFLR_PREFIX)
  854                         return EINVAL;
  855 
  856                 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
  857                 bzero(&ifra, sizeof ifra);
  858                 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof ifra.ifra_name);
  859 
  860                 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
  861 
  862                 if (iflr->dstaddr.ss_family) {  /*XXX*/
  863                         bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
  864                                 iflr->dstaddr.ss_len);
  865                 }
  866 
  867                 ifra.ifra_mask.sin_family = AF_INET;
  868                 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
  869                 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
  870 
  871                 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td);
  872             }
  873         case SIOCGLIFADDR:
  874         case SIOCDLIFADDR:
  875             {
  876                 struct ifaddr_container *ifac;
  877                 struct in_ifaddr *ia;
  878                 struct in_addr mask, candidate, match;
  879                 struct sockaddr_in *sin;
  880                 int cmp;
  881 
  882                 bzero(&mask, sizeof mask);
  883                 if (iflr->flags & IFLR_PREFIX) {
  884                         /* lookup a prefix rather than address. */
  885                         in_len2mask(&mask, iflr->prefixlen);
  886 
  887                         sin = (struct sockaddr_in *)&iflr->addr;
  888                         match.s_addr = sin->sin_addr.s_addr;
  889                         match.s_addr &= mask.s_addr;
  890 
  891                         /* if you set extra bits, that's wrong */
  892                         if (match.s_addr != sin->sin_addr.s_addr)
  893                                 return EINVAL;
  894 
  895                         cmp = 1;
  896                 } else {
  897                         if (cmd == SIOCGLIFADDR) {
  898                                 /* on getting an address, take the 1st match */
  899                                 match.s_addr = 0; /* gcc4 warning */
  900                                 cmp = 0;        /*XXX*/
  901                         } else {
  902                                 /* on deleting an address, do exact match */
  903                                 in_len2mask(&mask, 32);
  904                                 sin = (struct sockaddr_in *)&iflr->addr;
  905                                 match.s_addr = sin->sin_addr.s_addr;
  906 
  907                                 cmp = 1;
  908                         }
  909                 }
  910 
  911                 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
  912                         struct ifaddr *ifa = ifac->ifa;
  913 
  914                         if (ifa->ifa_addr->sa_family != AF_INET6)
  915                                 continue;
  916                         if (!cmp)
  917                                 break;
  918                         candidate.s_addr =
  919                         ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
  920                         candidate.s_addr &= mask.s_addr;
  921                         if (candidate.s_addr == match.s_addr)
  922                                 break;
  923                 }
  924                 if (ifac == NULL)
  925                         return EADDRNOTAVAIL;
  926                 ia = (struct in_ifaddr *)(ifac->ifa);
  927 
  928                 if (cmd == SIOCGLIFADDR) {
  929                         /* fill in the if_laddrreq structure */
  930                         bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
  931 
  932                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
  933                                 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
  934                                         ia->ia_dstaddr.sin_len);
  935                         } else
  936                                 bzero(&iflr->dstaddr, sizeof iflr->dstaddr);
  937 
  938                         iflr->prefixlen =
  939                                 in_mask2len(&ia->ia_sockmask.sin_addr);
  940 
  941                         iflr->flags = 0;        /*XXX*/
  942 
  943                         return 0;
  944                 } else {
  945                         struct in_aliasreq ifra;
  946 
  947                         /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
  948                         bzero(&ifra, sizeof ifra);
  949                         bcopy(iflr->iflr_name, ifra.ifra_name,
  950                                 sizeof ifra.ifra_name);
  951 
  952                         bcopy(&ia->ia_addr, &ifra.ifra_addr,
  953                                 ia->ia_addr.sin_len);
  954                         if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
  955                                 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
  956                                         ia->ia_dstaddr.sin_len);
  957                         }
  958                         bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
  959                                 ia->ia_sockmask.sin_len);
  960 
  961                         return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
  962                                           ifp, td);
  963                 }
  964             }
  965         }
  966 
  967         return EOPNOTSUPP;      /*just for safety*/
  968 }
  969 
  970 /*
  971  * Delete any existing route for an interface.
  972  */
  973 void
  974 in_ifscrub(struct ifnet *ifp __unused, struct in_ifaddr *ia)
  975 {
  976         in_scrubprefix(ia);
  977 }
  978 
  979 /*
  980  * Initialize an interface's internet address
  981  * and routing table entry.
  982  */
  983 static int
  984 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia,
  985           const struct sockaddr_in *sin, int scrub)
  986 {
  987         u_long i = ntohl(sin->sin_addr.s_addr);
  988         struct sockaddr_in oldaddr;
  989         struct ifaddr_container *ifac;
  990         int flags = RTF_UP, error = 0;
  991         int was_hash = 0;
  992 
  993         ifac = &ia->ia_ifa.ifa_containers[mycpuid];
  994         oldaddr = ia->ia_addr;
  995 
  996         if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) {
  997                 was_hash = 1;
  998                 in_iahash_remove(ia);
  999         }
 1000 
 1001         ia->ia_addr = *sin;
 1002         if (ia->ia_addr.sin_family == AF_INET)
 1003                 in_iahash_insert(ia);
 1004 
 1005         /*
 1006          * Give the interface a chance to initialize
 1007          * if this is its first address,
 1008          * and to validate the address if necessary.
 1009          */
 1010         if (ifp->if_ioctl != NULL) {
 1011                 ifnet_serialize_all(ifp);
 1012                 error = ifp->if_ioctl(ifp, SIOCSIFADDR, (caddr_t)ia, NULL);
 1013                 ifnet_deserialize_all(ifp);
 1014                 if (error)
 1015                         goto fail;
 1016         }
 1017 
 1018         /*
 1019          * Delete old route, if requested.
 1020          */
 1021         if (scrub) {
 1022                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
 1023                 in_ifscrub(ifp, ia);
 1024                 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
 1025         }
 1026 
 1027         /*
 1028          * Calculate netmask/subnetmask.
 1029          */
 1030         if (IN_CLASSA(i))
 1031                 ia->ia_netmask = IN_CLASSA_NET;
 1032         else if (IN_CLASSB(i))
 1033                 ia->ia_netmask = IN_CLASSB_NET;
 1034         else
 1035                 ia->ia_netmask = IN_CLASSC_NET;
 1036         /*
 1037          * The subnet mask usually includes at least the standard network part,
 1038          * but may may be smaller in the case of supernetting.
 1039          * If it is set, we believe it.
 1040          */
 1041         if (ia->ia_subnetmask == 0) {
 1042                 ia->ia_subnetmask = ia->ia_netmask;
 1043                 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
 1044         } else {
 1045                 ia->ia_netmask &= ia->ia_subnetmask;
 1046         }
 1047         ia->ia_net = i & ia->ia_netmask;
 1048         ia->ia_subnet = i & ia->ia_subnetmask;
 1049         in_socktrim(&ia->ia_sockmask);
 1050 
 1051         /*
 1052          * Add route for the network.
 1053          */
 1054         ia->ia_ifa.ifa_metric = ifp->if_metric;
 1055         if (ifp->if_flags & IFF_BROADCAST) {
 1056                 ia->ia_broadaddr.sin_addr.s_addr =
 1057                         htonl(ia->ia_subnet | ~ia->ia_subnetmask);
 1058                 ia->ia_netbroadcast.s_addr =
 1059                         htonl(ia->ia_net | ~ ia->ia_netmask);
 1060         } else if (ifp->if_flags & IFF_LOOPBACK) {
 1061                 ia->ia_dstaddr = ia->ia_addr;
 1062                 flags |= RTF_HOST;
 1063         } else if (ifp->if_flags & IFF_POINTOPOINT) {
 1064                 if (ia->ia_dstaddr.sin_family != AF_INET)
 1065                         return (0);
 1066                 flags |= RTF_HOST;
 1067         }
 1068 
 1069         /*-
 1070          * Don't add host routes for interface addresses of
 1071          * 0.0.0.0 --> 0.255.255.255 netmask 255.0.0.0.  This makes it
 1072          * possible to assign several such address pairs with consistent
 1073          * results (no host route) and is required by BOOTP.
 1074          *
 1075          * XXX: This is ugly !  There should be a way for the caller to
 1076          *      say that they don't want a host route.
 1077          */
 1078         if (ia->ia_addr.sin_addr.s_addr != INADDR_ANY ||
 1079             ia->ia_netmask != IN_CLASSA_NET ||
 1080             ia->ia_dstaddr.sin_addr.s_addr != htonl(IN_CLASSA_HOST)) {
 1081                 error = in_addprefix(ia, flags);
 1082                 if (error)
 1083                         goto fail;
 1084         }
 1085 
 1086         /*
 1087          * If the interface supports multicast, join the "all hosts"
 1088          * multicast group on that interface.
 1089          */
 1090         if (ifp->if_flags & IFF_MULTICAST) {
 1091                 struct in_addr addr;
 1092 
 1093                 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
 1094                 in_addmulti(&addr, ifp);
 1095         }
 1096         return (0);
 1097 fail:
 1098         if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH)
 1099                 in_iahash_remove(ia);
 1100 
 1101         ia->ia_addr = oldaddr;
 1102         if (was_hash)
 1103                 in_iahash_insert(ia);
 1104         return (error);
 1105 }
 1106 
 1107 #define rtinitflags(x) \
 1108         (((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) \
 1109          ? RTF_HOST : 0)
 1110 
 1111 /*
 1112  * Add a route to prefix ("connected route" in cisco terminology).
 1113  * Do nothing, if there are some interface addresses with the same
 1114  * prefix already.  This function assumes that the 'target' parent
 1115  * interface is UP.
 1116  */
 1117 static int
 1118 in_addprefix(struct in_ifaddr *target, int flags)
 1119 {
 1120         struct in_ifaddr_container *iac;
 1121         struct in_addr prefix, mask;
 1122         int error;
 1123 
 1124 #ifdef CARP
 1125         /*
 1126          * Don't add prefix routes for CARP interfaces.
 1127          * Prefix routes creation is handled by CARP
 1128          * interfaces themselves.
 1129          */
 1130         if (target->ia_ifp->if_type == IFT_CARP)
 1131                 return 0;
 1132 #endif
 1133 
 1134         mask = target->ia_sockmask.sin_addr;
 1135         if (flags & RTF_HOST) {
 1136                 prefix = target->ia_dstaddr.sin_addr;
 1137         } else {
 1138                 prefix = target->ia_addr.sin_addr;
 1139                 prefix.s_addr &= mask.s_addr;
 1140         }
 1141 
 1142         TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
 1143                 struct in_ifaddr *ia = iac->ia;
 1144                 struct in_addr p;
 1145 
 1146                 /* Don't test against self */
 1147                 if (ia == target)
 1148                         continue;
 1149 
 1150                 /* The tested address does not own a route entry */
 1151                 if ((ia->ia_flags & IFA_ROUTE) == 0)
 1152                         continue;
 1153 
 1154                 /* Prefix test */
 1155                 if (rtinitflags(ia)) {
 1156                         p = ia->ia_dstaddr.sin_addr;
 1157                 } else {
 1158                         p = ia->ia_addr.sin_addr;
 1159                         p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
 1160                 }
 1161                 if (prefix.s_addr != p.s_addr)
 1162                         continue;
 1163 
 1164                 /*
 1165                  * If the to-be-added address and the curretly being
 1166                  * tested address are not host addresses, we need to
 1167                  * take subnetmask into consideration.
 1168                  */
 1169                 if (!(flags & RTF_HOST) && !rtinitflags(ia) &&
 1170                     mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
 1171                         continue;
 1172 
 1173                 /*
 1174                  * If we got a matching prefix route inserted by other
 1175                  * interface address, we don't need to bother.
 1176                  */
 1177                 return 0;
 1178         }
 1179 
 1180         /*
 1181          * No one seem to have prefix route; insert it.
 1182          */
 1183         error = rtinit(&target->ia_ifa, RTM_ADD, flags);
 1184         if (!error)
 1185                 target->ia_flags |= IFA_ROUTE;
 1186         return error;
 1187 }
 1188 
 1189 /*
 1190  * Remove a route to prefix ("connected route" in cisco terminology).
 1191  * Re-installs the route by using another interface address, if there's
 1192  * one with the same prefix (otherwise we lose the route mistakenly).
 1193  */
 1194 static void
 1195 in_scrubprefix(struct in_ifaddr *target)
 1196 {
 1197         struct in_ifaddr_container *iac;
 1198         struct in_addr prefix, mask;
 1199         int error;
 1200 
 1201 #ifdef CARP
 1202         /*
 1203          * Don't scrub prefix routes for CARP interfaces.
 1204          * Prefix routes deletion is handled by CARP
 1205          * interfaces themselves.
 1206          */
 1207         if (target->ia_ifp->if_type == IFT_CARP)
 1208                 return;
 1209 #endif
 1210 
 1211         if ((target->ia_flags & IFA_ROUTE) == 0)
 1212                 return;
 1213 
 1214         mask = target->ia_sockmask.sin_addr;
 1215         if (rtinitflags(target)) {
 1216                 prefix = target->ia_dstaddr.sin_addr;
 1217         } else {
 1218                 prefix = target->ia_addr.sin_addr;
 1219                 prefix.s_addr &= mask.s_addr;
 1220         }
 1221 
 1222         TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
 1223                 struct in_ifaddr *ia = iac->ia;
 1224                 struct in_addr p;
 1225 
 1226                 /* Don't test against self */
 1227                 if (ia == target)
 1228                         continue;
 1229 
 1230                 /* The tested address already owns a route entry */
 1231                 if (ia->ia_flags & IFA_ROUTE)
 1232                         continue;
 1233 
 1234                 /*
 1235                  * The prefix route of the tested address should
 1236                  * never be installed if its parent interface is
 1237                  * not UP yet.
 1238                  */
 1239                 if ((ia->ia_ifp->if_flags & IFF_UP) == 0)
 1240                         continue;
 1241 
 1242 #ifdef CARP
 1243                 /*
 1244                  * Don't add prefix routes for CARP interfaces.
 1245                  * Prefix routes creation is handled by CARP
 1246                  * interfaces themselves.
 1247                  */
 1248                 if (ia->ia_ifp->if_type == IFT_CARP)
 1249                         continue;
 1250 #endif
 1251 
 1252                 /* Prefix test */
 1253                 if (rtinitflags(ia)) {
 1254                         p = ia->ia_dstaddr.sin_addr;
 1255                 } else {
 1256                         p = ia->ia_addr.sin_addr;
 1257                         p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
 1258                 }
 1259                 if (prefix.s_addr != p.s_addr)
 1260                         continue;
 1261 
 1262                 /*
 1263                  * We don't need to test subnetmask here, as what we do
 1264                  * in in_addprefix(), since if the the tested address's
 1265                  * parent interface is UP, the tested address should own
 1266                  * a prefix route entry and we would never reach here.
 1267                  */
 1268 
 1269                 /*
 1270                  * If we got a matching prefix route, move IFA_ROUTE to him
 1271                  */
 1272                 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target));
 1273                 target->ia_flags &= ~IFA_ROUTE;
 1274 
 1275                 error = rtinit(&ia->ia_ifa, RTM_ADD, rtinitflags(ia) | RTF_UP);
 1276                 if (!error)
 1277                         ia->ia_flags |= IFA_ROUTE;
 1278                 return;
 1279         }
 1280 
 1281         /*
 1282          * No candidates for this prefix route; just remove it.
 1283          */
 1284         rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target));
 1285         target->ia_flags &= ~IFA_ROUTE;
 1286 }
 1287 
 1288 #undef rtinitflags
 1289 
 1290 /*
 1291  * Return 1 if the address might be a local broadcast address.
 1292  */
 1293 int
 1294 in_broadcast(struct in_addr in, struct ifnet *ifp)
 1295 {
 1296         struct ifaddr_container *ifac;
 1297         u_long t;
 1298 
 1299         if (in.s_addr == INADDR_BROADCAST ||
 1300             in.s_addr == INADDR_ANY)
 1301                 return 1;
 1302         if ((ifp->if_flags & IFF_BROADCAST) == 0)
 1303                 return 0;
 1304         t = ntohl(in.s_addr);
 1305         /*
 1306          * Look through the list of addresses for a match
 1307          * with a broadcast address.
 1308          */
 1309 #define ia ((struct in_ifaddr *)ifa)
 1310         TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
 1311                 struct ifaddr *ifa = ifac->ifa;
 1312 
 1313                 if (ifa->ifa_addr->sa_family == AF_INET &&
 1314                     (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
 1315                      in.s_addr == ia->ia_netbroadcast.s_addr ||
 1316                      /*
 1317                       * Check for old-style (host 0) broadcast.
 1318                       */
 1319                      t == ia->ia_subnet || t == ia->ia_net) &&
 1320                      /*
 1321                       * Check for an all one subnetmask. These
 1322                       * only exist when an interface gets a secondary
 1323                       * address.
 1324                       */
 1325                      ia->ia_subnetmask != (u_long)0xffffffff)
 1326                             return 1;
 1327         }
 1328         return (0);
 1329 #undef ia
 1330 }
 1331 /*
 1332  * Add an address to the list of IP multicast addresses for a given interface.
 1333  */
 1334 struct in_multi *
 1335 in_addmulti(struct in_addr *ap, struct ifnet *ifp)
 1336 {
 1337         struct in_multi *inm;
 1338         int error;
 1339         struct sockaddr_in sin;
 1340         struct ifmultiaddr *ifma;
 1341 
 1342         /*
 1343          * Call generic routine to add membership or increment
 1344          * refcount.  It wants addresses in the form of a sockaddr,
 1345          * so we build one here (being careful to zero the unused bytes).
 1346          */
 1347         bzero(&sin, sizeof sin);
 1348         sin.sin_family = AF_INET;
 1349         sin.sin_len = sizeof sin;
 1350         sin.sin_addr = *ap;
 1351         crit_enter();
 1352         error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
 1353         if (error) {
 1354                 crit_exit();
 1355                 return 0;
 1356         }
 1357 
 1358         /*
 1359          * If ifma->ifma_protospec is null, then if_addmulti() created
 1360          * a new record.  Otherwise, we are done.
 1361          */
 1362         if (ifma->ifma_protospec != 0) {
 1363                 crit_exit();
 1364                 return ifma->ifma_protospec;
 1365         }
 1366 
 1367         /* XXX - if_addmulti uses M_WAITOK.  Can this really be called
 1368            at interrupt time?  If so, need to fix if_addmulti. XXX */
 1369         inm = kmalloc(sizeof *inm, M_IPMADDR, M_WAITOK | M_ZERO);
 1370         inm->inm_addr = *ap;
 1371         inm->inm_ifp = ifp;
 1372         inm->inm_ifma = ifma;
 1373         ifma->ifma_protospec = inm;
 1374         LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
 1375 
 1376         /*
 1377          * Let IGMP know that we have joined a new IP multicast group.
 1378          */
 1379         igmp_joingroup(inm);
 1380         crit_exit();
 1381         return (inm);
 1382 }
 1383 
 1384 /*
 1385  * Delete a multicast address record.
 1386  */
 1387 void
 1388 in_delmulti(struct in_multi *inm)
 1389 {
 1390         struct ifmultiaddr *ifma;
 1391         struct in_multi my_inm;
 1392 
 1393         crit_enter();
 1394         ifma = inm->inm_ifma;
 1395         my_inm.inm_ifp = NULL ; /* don't send the leave msg */
 1396         if (ifma->ifma_refcount == 1) {
 1397                 /*
 1398                  * No remaining claims to this record; let IGMP know that
 1399                  * we are leaving the multicast group.
 1400                  * But do it after the if_delmulti() which might reset
 1401                  * the interface and nuke the packet.
 1402                  */
 1403                 my_inm = *inm ;
 1404                 ifma->ifma_protospec = 0;
 1405                 LIST_REMOVE(inm, inm_link);
 1406                 kfree(inm, M_IPMADDR);
 1407         }
 1408         /* XXX - should be separate API for when we have an ifma? */
 1409         if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
 1410         if (my_inm.inm_ifp != NULL)
 1411                 igmp_leavegroup(&my_inm);
 1412         crit_exit();
 1413 }
 1414 
 1415 void
 1416 in_ifdetach(struct ifnet *ifp)
 1417 {
 1418         in_pcbpurgeif0(LIST_FIRST(&ripcbinfo.pcblisthead), ifp);
 1419 
 1420         udbinfo_lock();
 1421         in_pcbpurgeif0(LIST_FIRST(&udbinfo.pcblisthead), ifp);
 1422         udbinfo_unlock();
 1423 }

Cache object: 2deb95d74d8f35acc9ea5e583d182102


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.