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/net/if.c

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

    1 /*      $NetBSD: if.c,v 1.230.4.4 2011/02/16 20:37:47 bouyer Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by William Studenmund and Jason R. Thorpe.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
   34  * All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. Neither the name of the project nor the names of its contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   58  * SUCH DAMAGE.
   59  */
   60 
   61 /*
   62  * Copyright (c) 1980, 1986, 1993
   63  *      The Regents of the University of California.  All rights reserved.
   64  *
   65  * Redistribution and use in source and binary forms, with or without
   66  * modification, are permitted provided that the following conditions
   67  * are met:
   68  * 1. Redistributions of source code must retain the above copyright
   69  *    notice, this list of conditions and the following disclaimer.
   70  * 2. Redistributions in binary form must reproduce the above copyright
   71  *    notice, this list of conditions and the following disclaimer in the
   72  *    documentation and/or other materials provided with the distribution.
   73  * 3. Neither the name of the University nor the names of its contributors
   74  *    may be used to endorse or promote products derived from this software
   75  *    without specific prior written permission.
   76  *
   77  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   78  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   79  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   80  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   81  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   82  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   83  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   84  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   85  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   86  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   87  * SUCH DAMAGE.
   88  *
   89  *      @(#)if.c        8.5 (Berkeley) 1/9/95
   90  */
   91 
   92 #include <sys/cdefs.h>
   93 __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.230.4.4 2011/02/16 20:37:47 bouyer Exp $");
   94 
   95 #include "opt_inet.h"
   96 
   97 #include "opt_atalk.h"
   98 #include "opt_natm.h"
   99 #include "opt_pfil_hooks.h"
  100 
  101 #include <sys/param.h>
  102 #include <sys/mbuf.h>
  103 #include <sys/systm.h>
  104 #include <sys/callout.h>
  105 #include <sys/proc.h>
  106 #include <sys/socket.h>
  107 #include <sys/socketvar.h>
  108 #include <sys/domain.h>
  109 #include <sys/protosw.h>
  110 #include <sys/kernel.h>
  111 #include <sys/ioctl.h>
  112 #include <sys/sysctl.h>
  113 #include <sys/syslog.h>
  114 #include <sys/kauth.h>
  115 
  116 #include <net/if.h>
  117 #include <net/if_dl.h>
  118 #include <net/if_ether.h>
  119 #include <net/if_media.h>
  120 #include <net80211/ieee80211.h>
  121 #include <net80211/ieee80211_ioctl.h>
  122 #include <net/if_types.h>
  123 #include <net/radix.h>
  124 #include <net/route.h>
  125 #include <net/netisr.h>
  126 #ifdef NETATALK
  127 #include <netatalk/at_extern.h>
  128 #include <netatalk/at.h>
  129 #endif
  130 #include <net/pfil.h>
  131 
  132 #ifdef INET6
  133 #include <netinet/in.h>
  134 #include <netinet6/in6_var.h>
  135 #include <netinet6/nd6.h>
  136 #endif
  137 
  138 #include "carp.h"
  139 #if NCARP > 0
  140 #include <netinet/ip_carp.h>
  141 #endif
  142 
  143 #include <compat/sys/sockio.h>
  144 #include <compat/sys/socket.h>
  145 
  146 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
  147 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
  148 
  149 int     ifqmaxlen = IFQ_MAXLEN;
  150 callout_t if_slowtimo_ch;
  151 
  152 int netisr;                     /* scheduling bits for network */
  153 
  154 static int      if_rt_walktree(struct rtentry *, void *);
  155 
  156 static struct if_clone *if_clone_lookup(const char *, int *);
  157 static int      if_clone_list(struct if_clonereq *);
  158 
  159 static LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
  160 static int if_cloners_count;
  161 
  162 #ifdef PFIL_HOOKS
  163 struct pfil_head if_pfil;       /* packet filtering hook for interfaces */
  164 #endif
  165 
  166 static void if_detach_queues(struct ifnet *, struct ifqueue *);
  167 
  168 /*
  169  * Network interface utility routines.
  170  *
  171  * Routines with ifa_ifwith* names take sockaddr *'s as
  172  * parameters.
  173  */
  174 void
  175 ifinit(void)
  176 {
  177 
  178         callout_init(&if_slowtimo_ch, 0);
  179         if_slowtimo(NULL);
  180 }
  181 
  182 /*
  183  * XXX Initialization before configure().
  184  * XXX hack to get pfil_add_hook working in autoconf.
  185  */
  186 void
  187 ifinit1(void)
  188 {
  189 
  190 #ifdef PFIL_HOOKS
  191         if_pfil.ph_type = PFIL_TYPE_IFNET;
  192         if_pfil.ph_ifnet = NULL;
  193         if (pfil_head_register(&if_pfil) != 0)
  194                 printf("WARNING: unable to register pfil hook\n");
  195 #endif
  196 }
  197 
  198 struct ifnet *
  199 if_alloc(u_char type)
  200 {
  201         return malloc(sizeof(struct ifnet), M_DEVBUF, M_WAITOK|M_ZERO);
  202 }
  203 
  204 void
  205 if_initname(struct ifnet *ifp, const char *name, int unit)
  206 {
  207         (void)snprintf(ifp->if_xname, sizeof(ifp->if_xname),
  208             "%s%d", name, unit);
  209 }
  210 
  211 /*
  212  * Null routines used while an interface is going away.  These routines
  213  * just return an error.
  214  */
  215 
  216 int
  217 if_nulloutput(struct ifnet *ifp, struct mbuf *m,
  218     const struct sockaddr *so, struct rtentry *rt)
  219 {
  220 
  221         return ENXIO;
  222 }
  223 
  224 void
  225 if_nullinput(struct ifnet *ifp, struct mbuf *m)
  226 {
  227 
  228         /* Nothing. */
  229 }
  230 
  231 void
  232 if_nullstart(struct ifnet *ifp)
  233 {
  234 
  235         /* Nothing. */
  236 }
  237 
  238 int
  239 if_nullioctl(struct ifnet *ifp, u_long cmd, void *data)
  240 {
  241 
  242         return ENXIO;
  243 }
  244 
  245 int
  246 if_nullinit(struct ifnet *ifp)
  247 {
  248 
  249         return ENXIO;
  250 }
  251 
  252 void
  253 if_nullstop(struct ifnet *ifp, int disable)
  254 {
  255 
  256         /* Nothing. */
  257 }
  258 
  259 void
  260 if_nullwatchdog(struct ifnet *ifp)
  261 {
  262 
  263         /* Nothing. */
  264 }
  265 
  266 void
  267 if_nulldrain(struct ifnet *ifp)
  268 {
  269 
  270         /* Nothing. */
  271 }
  272 
  273 static u_int if_index = 1;
  274 struct ifnet_head ifnet;
  275 size_t if_indexlim = 0;
  276 struct ifaddr **ifnet_addrs = NULL;
  277 struct ifnet **ifindex2ifnet = NULL;
  278 struct ifnet *lo0ifp;
  279 
  280 void
  281 if_set_sadl(struct ifnet *ifp, const void *lla, u_char addrlen)
  282 {
  283         struct ifaddr *ifa;
  284         struct sockaddr_dl *sdl;
  285 
  286         ifp->if_addrlen = addrlen;
  287         if_alloc_sadl(ifp);
  288         ifa = ifp->if_dl;
  289         sdl = satosdl(ifa->ifa_addr);
  290 
  291         (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen);
  292         /* TBD routing socket */
  293 }
  294 
  295 struct ifaddr *
  296 if_dl_create(const struct ifnet *ifp, const struct sockaddr_dl **sdlp)
  297 {
  298         unsigned socksize, ifasize;
  299         int addrlen, namelen;
  300         struct sockaddr_dl *mask, *sdl;
  301         struct ifaddr *ifa;
  302 
  303         namelen = strlen(ifp->if_xname);
  304         addrlen = ifp->if_addrlen;
  305         socksize = roundup(sockaddr_dl_measure(namelen, addrlen), sizeof(long));
  306         ifasize = sizeof(*ifa) + 2 * socksize;
  307         ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO);
  308 
  309         sdl = (struct sockaddr_dl *)(ifa + 1);
  310         mask = (struct sockaddr_dl *)(socksize + (char *)sdl);
  311 
  312         sockaddr_dl_init(sdl, socksize, ifp->if_index, ifp->if_type,
  313             ifp->if_xname, namelen, NULL, addrlen);
  314         mask->sdl_len = sockaddr_dl_measure(namelen, 0);
  315         memset(&mask->sdl_data[0], 0xff, namelen);
  316         ifa->ifa_rtrequest = link_rtrequest;
  317         ifa->ifa_addr = (struct sockaddr *)sdl;
  318         ifa->ifa_netmask = (struct sockaddr *)mask;
  319 
  320         *sdlp = sdl;
  321 
  322         return ifa;
  323 }
  324 
  325 static void
  326 if_sadl_setrefs(struct ifnet *ifp, struct ifaddr *ifa)
  327 {
  328         const struct sockaddr_dl *sdl;
  329         ifnet_addrs[ifp->if_index] = ifa;
  330         IFAREF(ifa);
  331         ifp->if_dl = ifa;
  332         IFAREF(ifa);
  333         sdl = satosdl(ifa->ifa_addr);
  334         ifp->if_sadl = sdl;
  335 }
  336 
  337 /*
  338  * Allocate the link level name for the specified interface.  This
  339  * is an attachment helper.  It must be called after ifp->if_addrlen
  340  * is initialized, which may not be the case when if_attach() is
  341  * called.
  342  */
  343 void
  344 if_alloc_sadl(struct ifnet *ifp)
  345 {
  346         struct ifaddr *ifa;
  347         const struct sockaddr_dl *sdl;
  348 
  349         /*
  350          * If the interface already has a link name, release it
  351          * now.  This is useful for interfaces that can change
  352          * link types, and thus switch link names often.
  353          */
  354         if (ifp->if_sadl != NULL)
  355                 if_free_sadl(ifp);
  356 
  357         ifa = if_dl_create(ifp, &sdl);
  358 
  359         ifa_insert(ifp, ifa);
  360         if_sadl_setrefs(ifp, ifa);
  361 }
  362 
  363 static void
  364 if_deactivate_sadl(struct ifnet *ifp)
  365 {
  366         struct ifaddr *ifa;
  367 
  368         KASSERT(ifp->if_dl != NULL);
  369 
  370         ifa = ifp->if_dl;
  371 
  372         ifp->if_sadl = NULL;
  373 
  374         ifnet_addrs[ifp->if_index] = NULL;
  375         IFAFREE(ifa);
  376         ifp->if_dl = NULL;
  377         IFAFREE(ifa);
  378 }
  379 
  380 void
  381 if_activate_sadl(struct ifnet *ifp, struct ifaddr *ifa,
  382     const struct sockaddr_dl *sdl)
  383 {
  384         int s;
  385 
  386         s = splnet();
  387 
  388         if_deactivate_sadl(ifp);
  389 
  390         if_sadl_setrefs(ifp, ifa);
  391         splx(s);
  392         rt_ifmsg(ifp);
  393 }
  394 
  395 /*
  396  * Free the link level name for the specified interface.  This is
  397  * a detach helper.  This is called from if_detach() or from
  398  * link layer type specific detach functions.
  399  */
  400 void
  401 if_free_sadl(struct ifnet *ifp)
  402 {
  403         struct ifaddr *ifa;
  404         int s;
  405 
  406         ifa = ifnet_addrs[ifp->if_index];
  407         if (ifa == NULL) {
  408                 KASSERT(ifp->if_sadl == NULL);
  409                 KASSERT(ifp->if_dl == NULL);
  410                 return;
  411         }
  412 
  413         KASSERT(ifp->if_sadl != NULL);
  414         KASSERT(ifp->if_dl != NULL);
  415 
  416         s = splnet();
  417         rtinit(ifa, RTM_DELETE, 0);
  418         ifa_remove(ifp, ifa);
  419 
  420         if_deactivate_sadl(ifp);
  421         splx(s);
  422 }
  423 
  424 /*
  425  * Attach an interface to the
  426  * list of "active" interfaces.
  427  */
  428 void
  429 if_attach(struct ifnet *ifp)
  430 {
  431         int indexlim = 0;
  432 
  433         if (if_indexlim == 0) {
  434                 TAILQ_INIT(&ifnet);
  435                 if_indexlim = 8;
  436         }
  437         TAILQ_INIT(&ifp->if_addrlist);
  438         TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
  439         ifp->if_index = if_index;
  440         if (ifindex2ifnet == NULL)
  441                 if_index++;
  442         else
  443                 while (ifp->if_index < if_indexlim &&
  444                     ifindex2ifnet[ifp->if_index] != NULL) {
  445                         ++if_index;
  446                         if (if_index == 0)
  447                                 if_index = 1;
  448                         /*
  449                          * If we hit USHRT_MAX, we skip back to 0 since
  450                          * there are a number of places where the value
  451                          * of if_index or if_index itself is compared
  452                          * to or stored in an unsigned short.  By
  453                          * jumping back, we won't botch those assignments
  454                          * or comparisons.
  455                          */
  456                         else if (if_index == USHRT_MAX) {
  457                                 /*
  458                                  * However, if we have to jump back to
  459                                  * zero *twice* without finding an empty
  460                                  * slot in ifindex2ifnet[], then there
  461                                  * there are too many (>65535) interfaces.
  462                                  */
  463                                 if (indexlim++)
  464                                         panic("too many interfaces");
  465                                 else
  466                                         if_index = 1;
  467                         }
  468                         ifp->if_index = if_index;
  469                 }
  470 
  471         /*
  472          * We have some arrays that should be indexed by if_index.
  473          * since if_index will grow dynamically, they should grow too.
  474          *      struct ifadd **ifnet_addrs
  475          *      struct ifnet **ifindex2ifnet
  476          */
  477         if (ifnet_addrs == NULL || ifindex2ifnet == NULL ||
  478             ifp->if_index >= if_indexlim) {
  479                 size_t m, n, oldlim;
  480                 void *q;
  481 
  482                 oldlim = if_indexlim;
  483                 while (ifp->if_index >= if_indexlim)
  484                         if_indexlim <<= 1;
  485 
  486                 /* grow ifnet_addrs */
  487                 m = oldlim * sizeof(struct ifaddr *);
  488                 n = if_indexlim * sizeof(struct ifaddr *);
  489                 q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
  490                 if (ifnet_addrs != NULL) {
  491                         memcpy(q, ifnet_addrs, m);
  492                         free(ifnet_addrs, M_IFADDR);
  493                 }
  494                 ifnet_addrs = (struct ifaddr **)q;
  495 
  496                 /* grow ifindex2ifnet */
  497                 m = oldlim * sizeof(struct ifnet *);
  498                 n = if_indexlim * sizeof(struct ifnet *);
  499                 q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
  500                 if (ifindex2ifnet != NULL) {
  501                         memcpy(q, ifindex2ifnet, m);
  502                         free(ifindex2ifnet, M_IFADDR);
  503                 }
  504                 ifindex2ifnet = (struct ifnet **)q;
  505         }
  506 
  507         ifindex2ifnet[ifp->if_index] = ifp;
  508 
  509         /*
  510          * Link level name is allocated later by a separate call to
  511          * if_alloc_sadl().
  512          */
  513 
  514         if (ifp->if_snd.ifq_maxlen == 0)
  515                 ifp->if_snd.ifq_maxlen = ifqmaxlen;
  516         ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
  517 
  518         ifp->if_link_state = LINK_STATE_UNKNOWN;
  519 
  520         ifp->if_capenable = 0;
  521         ifp->if_csum_flags_tx = 0;
  522         ifp->if_csum_flags_rx = 0;
  523 
  524 #ifdef ALTQ
  525         ifp->if_snd.altq_type = 0;
  526         ifp->if_snd.altq_disc = NULL;
  527         ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
  528         ifp->if_snd.altq_tbr  = NULL;
  529         ifp->if_snd.altq_ifp  = ifp;
  530 #endif
  531 
  532 #ifdef PFIL_HOOKS
  533         ifp->if_pfil.ph_type = PFIL_TYPE_IFNET;
  534         ifp->if_pfil.ph_ifnet = ifp;
  535         if (pfil_head_register(&ifp->if_pfil) != 0)
  536                 printf("%s: WARNING: unable to register pfil hook\n",
  537                     ifp->if_xname);
  538         (void)pfil_run_hooks(&if_pfil,
  539             (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
  540 #endif
  541 
  542         if (!STAILQ_EMPTY(&domains))
  543                 if_attachdomain1(ifp);
  544 
  545         /* Announce the interface. */
  546         rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
  547 }
  548 
  549 void
  550 if_attachdomain(void)
  551 {
  552         struct ifnet *ifp;
  553         int s;
  554 
  555         s = splnet();
  556         IFNET_FOREACH(ifp)
  557                 if_attachdomain1(ifp);
  558         splx(s);
  559 }
  560 
  561 void
  562 if_attachdomain1(struct ifnet *ifp)
  563 {
  564         struct domain *dp;
  565         int s;
  566 
  567         s = splnet();
  568 
  569         /* address family dependent data region */
  570         memset(ifp->if_afdata, 0, sizeof(ifp->if_afdata));
  571         DOMAIN_FOREACH(dp) {
  572                 if (dp->dom_ifattach != NULL)
  573                         ifp->if_afdata[dp->dom_family] =
  574                             (*dp->dom_ifattach)(ifp);
  575         }
  576 
  577         splx(s);
  578 }
  579 
  580 /*
  581  * Deactivate an interface.  This points all of the procedure
  582  * handles at error stubs.  May be called from interrupt context.
  583  */
  584 void
  585 if_deactivate(struct ifnet *ifp)
  586 {
  587         int s;
  588 
  589         s = splnet();
  590 
  591         ifp->if_output   = if_nulloutput;
  592         ifp->if_input    = if_nullinput;
  593         ifp->if_start    = if_nullstart;
  594         ifp->if_ioctl    = if_nullioctl;
  595         ifp->if_init     = if_nullinit;
  596         ifp->if_stop     = if_nullstop;
  597         ifp->if_watchdog = if_nullwatchdog;
  598         ifp->if_drain    = if_nulldrain;
  599 
  600         /* No more packets may be enqueued. */
  601         ifp->if_snd.ifq_maxlen = 0;
  602 
  603         splx(s);
  604 }
  605 
  606 void
  607 if_purgeaddrs(struct ifnet *ifp, int family, void (*purgeaddr)(struct ifaddr *))
  608 {
  609         struct ifaddr *ifa, *nifa;
  610 
  611         for (ifa = IFADDR_FIRST(ifp); ifa != NULL; ifa = nifa) {
  612                 nifa = IFADDR_NEXT(ifa);
  613                 if (ifa->ifa_addr->sa_family != family)
  614                         continue;
  615                 (*purgeaddr)(ifa);
  616         }
  617 }
  618 
  619 /*
  620  * Detach an interface from the list of "active" interfaces,
  621  * freeing any resources as we go along.
  622  *
  623  * NOTE: This routine must be called with a valid thread context,
  624  * as it may block.
  625  */
  626 void
  627 if_detach(struct ifnet *ifp)
  628 {
  629         struct socket so;
  630         struct ifaddr *ifa;
  631 #ifdef IFAREF_DEBUG
  632         struct ifaddr *last_ifa = NULL;
  633 #endif
  634         struct domain *dp;
  635         const struct protosw *pr;
  636         int s, i, family, purged;
  637 
  638         /*
  639          * XXX It's kind of lame that we have to have the
  640          * XXX socket structure...
  641          */
  642         memset(&so, 0, sizeof(so));
  643 
  644         s = splnet();
  645 
  646         /*
  647          * Do an if_down() to give protocols a chance to do something.
  648          */
  649         if_down(ifp);
  650 
  651 #ifdef ALTQ
  652         if (ALTQ_IS_ENABLED(&ifp->if_snd))
  653                 altq_disable(&ifp->if_snd);
  654         if (ALTQ_IS_ATTACHED(&ifp->if_snd))
  655                 altq_detach(&ifp->if_snd);
  656 #endif
  657 
  658 
  659 #if NCARP > 0
  660         /* Remove the interface from any carp group it is a part of.  */
  661         if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP)
  662                 carp_ifdetach(ifp);
  663 #endif
  664 
  665         /*
  666          * Rip all the addresses off the interface.  This should make
  667          * all of the routes go away.
  668          *
  669          * pr_usrreq calls can remove an arbitrary number of ifaddrs
  670          * from the list, including our "cursor", ifa.  For safety,
  671          * and to honor the TAILQ abstraction, I just restart the
  672          * loop after each removal.  Note that the loop will exit
  673          * when all of the remaining ifaddrs belong to the AF_LINK
  674          * family.  I am counting on the historical fact that at
  675          * least one pr_usrreq in each address domain removes at
  676          * least one ifaddr.
  677          */
  678 again:
  679         IFADDR_FOREACH(ifa, ifp) {
  680                 family = ifa->ifa_addr->sa_family;
  681 #ifdef IFAREF_DEBUG
  682                 printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
  683                     ifa, family, ifa->ifa_refcnt);
  684                 if (last_ifa != NULL && ifa == last_ifa)
  685                         panic("if_detach: loop detected");
  686                 last_ifa = ifa;
  687 #endif
  688                 if (family == AF_LINK)
  689                         continue;
  690                 dp = pffinddomain(family);
  691 #ifdef DIAGNOSTIC
  692                 if (dp == NULL)
  693                         panic("if_detach: no domain for AF %d",
  694                             family);
  695 #endif
  696                 /*
  697                  * XXX These PURGEIF calls are redundant with the
  698                  * purge-all-families calls below, but are left in for
  699                  * now both to make a smaller change, and to avoid
  700                  * unplanned interactions with clearing of
  701                  * ifp->if_addrlist.
  702                  */
  703                 purged = 0;
  704                 for (pr = dp->dom_protosw;
  705                      pr < dp->dom_protoswNPROTOSW; pr++) {
  706                         so.so_proto = pr;
  707                         if (pr->pr_usrreq != NULL) {
  708                                 (void) (*pr->pr_usrreq)(&so,
  709                                     PRU_PURGEIF, NULL, NULL,
  710                                     (struct mbuf *) ifp, curlwp);
  711                                 purged = 1;
  712                         }
  713                 }
  714                 if (purged == 0) {
  715                         /*
  716                          * XXX What's really the best thing to do
  717                          * XXX here?  --thorpej@NetBSD.org
  718                          */
  719                         printf("if_detach: WARNING: AF %d not purged\n",
  720                             family);
  721                         ifa_remove(ifp, ifa);
  722                 }
  723                 goto again;
  724         }
  725 
  726         if_free_sadl(ifp);
  727 
  728         /* Walk the routing table looking for stragglers. */
  729         for (i = 0; i <= AF_MAX; i++)
  730                 (void)rt_walktree(i, if_rt_walktree, ifp);
  731 
  732         DOMAIN_FOREACH(dp) {
  733                 if (dp->dom_ifdetach != NULL && ifp->if_afdata[dp->dom_family])
  734                         (*dp->dom_ifdetach)(ifp,
  735                             ifp->if_afdata[dp->dom_family]);
  736 
  737                 /*
  738                  * One would expect multicast memberships (INET and
  739                  * INET6) on UDP sockets to be purged by the PURGEIF
  740                  * calls above, but if all addresses were removed from
  741                  * the interface prior to destruction, the calls will
  742                  * not be made (e.g. ppp, for which pppd(8) generally
  743                  * removes addresses before destroying the interface).
  744                  * Because there is no invariant that multicast
  745                  * memberships only exist for interfaces with IPv4
  746                  * addresses, we must call PURGEIF regardless of
  747                  * addresses.  (Protocols which might store ifnet
  748                  * pointers are marked with PR_PURGEIF.)
  749                  */
  750                 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
  751                         so.so_proto = pr;
  752                         if (pr->pr_usrreq != NULL && pr->pr_flags & PR_PURGEIF)
  753                                 (void)(*pr->pr_usrreq)(&so, PRU_PURGEIF, NULL,
  754                                     NULL, (struct mbuf *)ifp, curlwp);
  755                 }
  756         }
  757 
  758 #ifdef PFIL_HOOKS
  759         (void)pfil_run_hooks(&if_pfil,
  760             (struct mbuf **)PFIL_IFNET_DETACH, ifp, PFIL_IFNET);
  761         (void)pfil_head_unregister(&ifp->if_pfil);
  762 #endif
  763 
  764         /* Announce that the interface is gone. */
  765         rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
  766 
  767         ifindex2ifnet[ifp->if_index] = NULL;
  768 
  769         TAILQ_REMOVE(&ifnet, ifp, if_list);
  770 
  771         /*
  772          * remove packets that came from ifp, from software interrupt queues.
  773          */
  774         DOMAIN_FOREACH(dp) {
  775                 for (i = 0; i < __arraycount(dp->dom_ifqueues); i++) {
  776                         if (dp->dom_ifqueues[i] == NULL)
  777                                 break;
  778                         if_detach_queues(ifp, dp->dom_ifqueues[i]);
  779                 }
  780         }
  781 
  782         splx(s);
  783 }
  784 
  785 static void
  786 if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
  787 {
  788         struct mbuf *m, *prev, *next;
  789 
  790         prev = NULL;
  791         for (m = q->ifq_head; m != NULL; m = next) {
  792                 next = m->m_nextpkt;
  793 #ifdef DIAGNOSTIC
  794                 if ((m->m_flags & M_PKTHDR) == 0) {
  795                         prev = m;
  796                         continue;
  797                 }
  798 #endif
  799                 if (m->m_pkthdr.rcvif != ifp) {
  800                         prev = m;
  801                         continue;
  802                 }
  803 
  804                 if (prev != NULL)
  805                         prev->m_nextpkt = m->m_nextpkt;
  806                 else
  807                         q->ifq_head = m->m_nextpkt;
  808                 if (q->ifq_tail == m)
  809                         q->ifq_tail = prev;
  810                 q->ifq_len--;
  811 
  812                 m->m_nextpkt = NULL;
  813                 m_freem(m);
  814                 IF_DROP(q);
  815         }
  816 }
  817 
  818 /*
  819  * Callback for a radix tree walk to delete all references to an
  820  * ifnet.
  821  */
  822 static int
  823 if_rt_walktree(struct rtentry *rt, void *v)
  824 {
  825         struct ifnet *ifp = (struct ifnet *)v;
  826         int error;
  827 
  828         if (rt->rt_ifp != ifp)
  829                 return 0;
  830 
  831         /* Delete the entry. */
  832         ++rt->rt_refcnt;
  833         error = rtrequest(RTM_DELETE, rt_getkey(rt), rt->rt_gateway,
  834             rt_mask(rt), rt->rt_flags, NULL);
  835         KASSERT((rt->rt_flags & RTF_UP) == 0);
  836         rt->rt_ifp = NULL;
  837         RTFREE(rt);
  838         if (error != 0)
  839                 printf("%s: warning: unable to delete rtentry @ %p, "
  840                     "error = %d\n", ifp->if_xname, rt, error);
  841         return 0;
  842 }
  843 
  844 /*
  845  * Create a clone network interface.
  846  */
  847 int
  848 if_clone_create(const char *name)
  849 {
  850         struct if_clone *ifc;
  851         int unit;
  852 
  853         ifc = if_clone_lookup(name, &unit);
  854         if (ifc == NULL)
  855                 return EINVAL;
  856 
  857         if (ifunit(name) != NULL)
  858                 return EEXIST;
  859 
  860         return (*ifc->ifc_create)(ifc, unit);
  861 }
  862 
  863 /*
  864  * Destroy a clone network interface.
  865  */
  866 int
  867 if_clone_destroy(const char *name)
  868 {
  869         struct if_clone *ifc;
  870         struct ifnet *ifp;
  871 
  872         ifc = if_clone_lookup(name, NULL);
  873         if (ifc == NULL)
  874                 return EINVAL;
  875 
  876         ifp = ifunit(name);
  877         if (ifp == NULL)
  878                 return ENXIO;
  879 
  880         if (ifc->ifc_destroy == NULL)
  881                 return EOPNOTSUPP;
  882 
  883         return (*ifc->ifc_destroy)(ifp);
  884 }
  885 
  886 /*
  887  * Look up a network interface cloner.
  888  */
  889 static struct if_clone *
  890 if_clone_lookup(const char *name, int *unitp)
  891 {
  892         struct if_clone *ifc;
  893         const char *cp;
  894         int unit;
  895 
  896         /* separate interface name from unit */
  897         for (cp = name;
  898             cp - name < IFNAMSIZ && *cp && (*cp < '' || *cp > '9');
  899             cp++)
  900                 continue;
  901 
  902         if (cp == name || cp - name == IFNAMSIZ || !*cp)
  903                 return NULL;    /* No name or unit number */
  904 
  905         LIST_FOREACH(ifc, &if_cloners, ifc_list) {
  906                 if (strlen(ifc->ifc_name) == cp - name &&
  907                     strncmp(name, ifc->ifc_name, cp - name) == 0)
  908                         break;
  909         }
  910 
  911         if (ifc == NULL)
  912                 return NULL;
  913 
  914         unit = 0;
  915         while (cp - name < IFNAMSIZ && *cp) {
  916                 if (*cp < '' || *cp > '9' || unit > INT_MAX / 10) {
  917                         /* Bogus unit number. */
  918                         return NULL;
  919                 }
  920                 unit = (unit * 10) + (*cp++ - '');
  921         }
  922 
  923         if (unitp != NULL)
  924                 *unitp = unit;
  925         return ifc;
  926 }
  927 
  928 /*
  929  * Register a network interface cloner.
  930  */
  931 void
  932 if_clone_attach(struct if_clone *ifc)
  933 {
  934 
  935         LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
  936         if_cloners_count++;
  937 }
  938 
  939 /*
  940  * Unregister a network interface cloner.
  941  */
  942 void
  943 if_clone_detach(struct if_clone *ifc)
  944 {
  945 
  946         LIST_REMOVE(ifc, ifc_list);
  947         if_cloners_count--;
  948 }
  949 
  950 /*
  951  * Provide list of interface cloners to userspace.
  952  */
  953 static int
  954 if_clone_list(struct if_clonereq *ifcr)
  955 {
  956         char outbuf[IFNAMSIZ], *dst;
  957         struct if_clone *ifc;
  958         int count, error = 0;
  959 
  960         ifcr->ifcr_total = if_cloners_count;
  961         if ((dst = ifcr->ifcr_buffer) == NULL) {
  962                 /* Just asking how many there are. */
  963                 return 0;
  964         }
  965 
  966         if (ifcr->ifcr_count < 0)
  967                 return EINVAL;
  968 
  969         count = (if_cloners_count < ifcr->ifcr_count) ?
  970             if_cloners_count : ifcr->ifcr_count;
  971 
  972         for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
  973              ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
  974                 (void)strncpy(outbuf, ifc->ifc_name, sizeof(outbuf));
  975                 if (outbuf[sizeof(outbuf) - 1] != '\0')
  976                         return ENAMETOOLONG;
  977                 error = copyout(outbuf, dst, sizeof(outbuf));
  978                 if (error != 0)
  979                         break;
  980         }
  981 
  982         return error;
  983 }
  984 
  985 void
  986 ifa_insert(struct ifnet *ifp, struct ifaddr *ifa)
  987 {
  988         ifa->ifa_ifp = ifp;
  989         TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
  990         IFAREF(ifa);
  991 }
  992 
  993 void
  994 ifa_remove(struct ifnet *ifp, struct ifaddr *ifa)
  995 {
  996         KASSERT(ifa->ifa_ifp == ifp);
  997         TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
  998         IFAFREE(ifa);
  999 }
 1000 
 1001 static inline int
 1002 equal(const struct sockaddr *sa1, const struct sockaddr *sa2)
 1003 {
 1004         return sockaddr_cmp(sa1, sa2) == 0;
 1005 }
 1006 
 1007 /*
 1008  * Locate an interface based on a complete address.
 1009  */
 1010 /*ARGSUSED*/
 1011 struct ifaddr *
 1012 ifa_ifwithaddr(const struct sockaddr *addr)
 1013 {
 1014         struct ifnet *ifp;
 1015         struct ifaddr *ifa;
 1016 
 1017         IFNET_FOREACH(ifp) {
 1018                 if (ifp->if_output == if_nulloutput)
 1019                         continue;
 1020                 IFADDR_FOREACH(ifa, ifp) {
 1021                         if (ifa->ifa_addr->sa_family != addr->sa_family)
 1022                                 continue;
 1023                         if (equal(addr, ifa->ifa_addr))
 1024                                 return ifa;
 1025                         if ((ifp->if_flags & IFF_BROADCAST) &&
 1026                             ifa->ifa_broadaddr &&
 1027                             /* IP6 doesn't have broadcast */
 1028                             ifa->ifa_broadaddr->sa_len != 0 &&
 1029                             equal(ifa->ifa_broadaddr, addr))
 1030                                 return ifa;
 1031                 }
 1032         }
 1033         return NULL;
 1034 }
 1035 
 1036 /*
 1037  * Locate the point to point interface with a given destination address.
 1038  */
 1039 /*ARGSUSED*/
 1040 struct ifaddr *
 1041 ifa_ifwithdstaddr(const struct sockaddr *addr)
 1042 {
 1043         struct ifnet *ifp;
 1044         struct ifaddr *ifa;
 1045 
 1046         IFNET_FOREACH(ifp) {
 1047                 if (ifp->if_output == if_nulloutput)
 1048                         continue;
 1049                 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
 1050                         continue;
 1051                 IFADDR_FOREACH(ifa, ifp) {
 1052                         if (ifa->ifa_addr->sa_family != addr->sa_family ||
 1053                             ifa->ifa_dstaddr == NULL)
 1054                                 continue;
 1055                         if (equal(addr, ifa->ifa_dstaddr))
 1056                                 return ifa;
 1057                 }
 1058         }
 1059         return NULL;
 1060 }
 1061 
 1062 /*
 1063  * Find an interface on a specific network.  If many, choice
 1064  * is most specific found.
 1065  */
 1066 struct ifaddr *
 1067 ifa_ifwithnet(const struct sockaddr *addr)
 1068 {
 1069         struct ifnet *ifp;
 1070         struct ifaddr *ifa;
 1071         const struct sockaddr_dl *sdl;
 1072         struct ifaddr *ifa_maybe = 0;
 1073         u_int af = addr->sa_family;
 1074         const char *addr_data = addr->sa_data, *cplim;
 1075 
 1076         if (af == AF_LINK) {
 1077                 sdl = satocsdl(addr);
 1078                 if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
 1079                     ifindex2ifnet[sdl->sdl_index] &&
 1080                     ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput)
 1081                         return ifnet_addrs[sdl->sdl_index];
 1082         }
 1083 #ifdef NETATALK
 1084         if (af == AF_APPLETALK) {
 1085                 const struct sockaddr_at *sat, *sat2;
 1086                 sat = (const struct sockaddr_at *)addr;
 1087                 IFNET_FOREACH(ifp) {
 1088                         if (ifp->if_output == if_nulloutput)
 1089                                 continue;
 1090                         ifa = at_ifawithnet((const struct sockaddr_at *)addr, ifp);
 1091                         if (ifa == NULL)
 1092                                 continue;
 1093                         sat2 = (struct sockaddr_at *)ifa->ifa_addr;
 1094                         if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
 1095                                 return ifa; /* exact match */
 1096                         if (ifa_maybe == NULL) {
 1097                                 /* else keep the if with the right range */
 1098                                 ifa_maybe = ifa;
 1099                         }
 1100                 }
 1101                 return ifa_maybe;
 1102         }
 1103 #endif
 1104         IFNET_FOREACH(ifp) {
 1105                 if (ifp->if_output == if_nulloutput)
 1106                         continue;
 1107                 IFADDR_FOREACH(ifa, ifp) {
 1108                         const char *cp, *cp2, *cp3;
 1109 
 1110                         if (ifa->ifa_addr->sa_family != af ||
 1111                             ifa->ifa_netmask == NULL)
 1112  next:                          continue;
 1113                         cp = addr_data;
 1114                         cp2 = ifa->ifa_addr->sa_data;
 1115                         cp3 = ifa->ifa_netmask->sa_data;
 1116                         cplim = (const char *)ifa->ifa_netmask +
 1117                             ifa->ifa_netmask->sa_len;
 1118                         while (cp3 < cplim) {
 1119                                 if ((*cp++ ^ *cp2++) & *cp3++) {
 1120                                         /* want to continue for() loop */
 1121                                         goto next;
 1122                                 }
 1123                         }
 1124                         if (ifa_maybe == NULL ||
 1125                             rn_refines((void *)ifa->ifa_netmask,
 1126                             (void *)ifa_maybe->ifa_netmask))
 1127                                 ifa_maybe = ifa;
 1128                 }
 1129         }
 1130         return ifa_maybe;
 1131 }
 1132 
 1133 /*
 1134  * Find the interface of the addresss.
 1135  */
 1136 struct ifaddr *
 1137 ifa_ifwithladdr(const struct sockaddr *addr)
 1138 {
 1139         struct ifaddr *ia;
 1140 
 1141         if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
 1142             (ia = ifa_ifwithnet(addr)))
 1143                 return ia;
 1144         return NULL;
 1145 }
 1146 
 1147 /*
 1148  * Find an interface using a specific address family
 1149  */
 1150 struct ifaddr *
 1151 ifa_ifwithaf(int af)
 1152 {
 1153         struct ifnet *ifp;
 1154         struct ifaddr *ifa;
 1155 
 1156         IFNET_FOREACH(ifp) {
 1157                 if (ifp->if_output == if_nulloutput)
 1158                         continue;
 1159                 IFADDR_FOREACH(ifa, ifp) {
 1160                         if (ifa->ifa_addr->sa_family == af)
 1161                                 return ifa;
 1162                 }
 1163         }
 1164         return NULL;
 1165 }
 1166 
 1167 /*
 1168  * Find an interface address specific to an interface best matching
 1169  * a given address.
 1170  */
 1171 struct ifaddr *
 1172 ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp)
 1173 {
 1174         struct ifaddr *ifa;
 1175         const char *cp, *cp2, *cp3;
 1176         const char *cplim;
 1177         struct ifaddr *ifa_maybe = 0;
 1178         u_int af = addr->sa_family;
 1179 
 1180         if (ifp->if_output == if_nulloutput)
 1181                 return NULL;
 1182 
 1183         if (af >= AF_MAX)
 1184                 return NULL;
 1185 
 1186         IFADDR_FOREACH(ifa, ifp) {
 1187                 if (ifa->ifa_addr->sa_family != af)
 1188                         continue;
 1189                 ifa_maybe = ifa;
 1190                 if (ifa->ifa_netmask == NULL) {
 1191                         if (equal(addr, ifa->ifa_addr) ||
 1192                             (ifa->ifa_dstaddr &&
 1193                              equal(addr, ifa->ifa_dstaddr)))
 1194                                 return ifa;
 1195                         continue;
 1196                 }
 1197                 cp = addr->sa_data;
 1198                 cp2 = ifa->ifa_addr->sa_data;
 1199                 cp3 = ifa->ifa_netmask->sa_data;
 1200                 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
 1201                 for (; cp3 < cplim; cp3++) {
 1202                         if ((*cp++ ^ *cp2++) & *cp3)
 1203                                 break;
 1204                 }
 1205                 if (cp3 == cplim)
 1206                         return ifa;
 1207         }
 1208         return ifa_maybe;
 1209 }
 1210 
 1211 /*
 1212  * Default action when installing a route with a Link Level gateway.
 1213  * Lookup an appropriate real ifa to point to.
 1214  * This should be moved to /sys/net/link.c eventually.
 1215  */
 1216 void
 1217 link_rtrequest(int cmd, struct rtentry *rt, const struct rt_addrinfo *info)
 1218 {
 1219         struct ifaddr *ifa;
 1220         const struct sockaddr *dst;
 1221         struct ifnet *ifp;
 1222 
 1223         if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL ||
 1224             (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL)
 1225                 return;
 1226         if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
 1227                 rt_replace_ifa(rt, ifa);
 1228                 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
 1229                         ifa->ifa_rtrequest(cmd, rt, info);
 1230         }
 1231 }
 1232 
 1233 /*
 1234  * Handle a change in the interface link state.
 1235  */
 1236 void
 1237 if_link_state_change(struct ifnet *ifp, int link_state)
 1238 {
 1239         if (ifp->if_link_state == link_state)
 1240                 return;
 1241         ifp->if_link_state = link_state;
 1242         /* Notify that the link state has changed. */
 1243         rt_ifmsg(ifp);
 1244 #if NCARP > 0
 1245         if (ifp->if_carp)
 1246                 carp_carpdev_state(ifp);
 1247 #endif
 1248 }
 1249 
 1250 /*
 1251  * Mark an interface down and notify protocols of
 1252  * the transition.
 1253  * NOTE: must be called at splsoftnet or equivalent.
 1254  */
 1255 void
 1256 if_down(struct ifnet *ifp)
 1257 {
 1258         struct ifaddr *ifa;
 1259 
 1260         ifp->if_flags &= ~IFF_UP;
 1261         microtime(&ifp->if_lastchange);
 1262         IFADDR_FOREACH(ifa, ifp)
 1263                 pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
 1264         IFQ_PURGE(&ifp->if_snd);
 1265 #if NCARP > 0
 1266         if (ifp->if_carp)
 1267                 carp_carpdev_state(ifp);
 1268 #endif
 1269         rt_ifmsg(ifp);
 1270 }
 1271 
 1272 /*
 1273  * Mark an interface up and notify protocols of
 1274  * the transition.
 1275  * NOTE: must be called at splsoftnet or equivalent.
 1276  */
 1277 void
 1278 if_up(struct ifnet *ifp)
 1279 {
 1280 #ifdef notyet
 1281         struct ifaddr *ifa;
 1282 #endif
 1283 
 1284         ifp->if_flags |= IFF_UP;
 1285         microtime(&ifp->if_lastchange);
 1286 #ifdef notyet
 1287         /* this has no effect on IP, and will kill all ISO connections XXX */
 1288         IFADDR_FOREACH(ifa, ifp)
 1289                 pfctlinput(PRC_IFUP, ifa->ifa_addr);
 1290 #endif
 1291 #if NCARP > 0
 1292         if (ifp->if_carp)
 1293                 carp_carpdev_state(ifp);
 1294 #endif
 1295         rt_ifmsg(ifp);
 1296 #ifdef INET6
 1297         in6_if_up(ifp);
 1298 #endif
 1299 }
 1300 
 1301 /*
 1302  * Handle interface watchdog timer routines.  Called
 1303  * from softclock, we decrement timers (if set) and
 1304  * call the appropriate interface routine on expiration.
 1305  */
 1306 void
 1307 if_slowtimo(void *arg)
 1308 {
 1309         struct ifnet *ifp;
 1310         int s = splnet();
 1311 
 1312         IFNET_FOREACH(ifp) {
 1313                 if (ifp->if_timer == 0 || --ifp->if_timer)
 1314                         continue;
 1315                 if (ifp->if_watchdog != NULL)
 1316                         (*ifp->if_watchdog)(ifp);
 1317         }
 1318         splx(s);
 1319         callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, if_slowtimo, NULL);
 1320 }
 1321 
 1322 /*
 1323  * Set/clear promiscuous mode on interface ifp based on the truth value
 1324  * of pswitch.  The calls are reference counted so that only the first
 1325  * "on" request actually has an effect, as does the final "off" request.
 1326  * Results are undefined if the "off" and "on" requests are not matched.
 1327  */
 1328 int
 1329 ifpromisc(struct ifnet *ifp, int pswitch)
 1330 {
 1331         int pcount, ret;
 1332         short flags;
 1333         struct ifreq ifr;
 1334 
 1335         pcount = ifp->if_pcount;
 1336         flags = ifp->if_flags;
 1337         if (pswitch) {
 1338                 /*
 1339                  * Allow the device to be "placed" into promiscuous
 1340                  * mode even if it is not configured up.  It will
 1341                  * consult IFF_PROMISC when it is is brought up.
 1342                  */
 1343                 if (ifp->if_pcount++ != 0)
 1344                         return 0;
 1345                 ifp->if_flags |= IFF_PROMISC;
 1346                 if ((ifp->if_flags & IFF_UP) == 0)
 1347                         return 0;
 1348         } else {
 1349                 if (--ifp->if_pcount > 0)
 1350                         return 0;
 1351                 ifp->if_flags &= ~IFF_PROMISC;
 1352                 /*
 1353                  * If the device is not configured up, we should not need to
 1354                  * turn off promiscuous mode (device should have turned it
 1355                  * off when interface went down; and will look at IFF_PROMISC
 1356                  * again next time interface comes up).
 1357                  */
 1358                 if ((ifp->if_flags & IFF_UP) == 0)
 1359                         return 0;
 1360         }
 1361         memset(&ifr, 0, sizeof(ifr));
 1362         ifr.ifr_flags = ifp->if_flags;
 1363         ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr);
 1364         /* Restore interface state if not successful. */
 1365         if (ret != 0) {
 1366                 ifp->if_pcount = pcount;
 1367                 ifp->if_flags = flags;
 1368         }
 1369         return ret;
 1370 }
 1371 
 1372 /*
 1373  * Map interface name to
 1374  * interface structure pointer.
 1375  */
 1376 struct ifnet *
 1377 ifunit(const char *name)
 1378 {
 1379         struct ifnet *ifp;
 1380         const char *cp = name;
 1381         u_int unit = 0;
 1382         u_int i;
 1383 
 1384         /*
 1385          * If the entire name is a number, treat it as an ifindex.
 1386          */
 1387         for (i = 0; i < IFNAMSIZ && *cp >= '' && *cp <= '9'; i++, cp++) {
 1388                 unit = unit * 10 + (*cp - '');
 1389         }
 1390 
 1391         /*
 1392          * If the number took all of the name, then it's a valid ifindex.
 1393          */
 1394         if (i == IFNAMSIZ || (cp != name && *cp == '\0')) {
 1395                 if (unit >= if_indexlim)
 1396                         return NULL;
 1397                 ifp = ifindex2ifnet[unit];
 1398                 if (ifp == NULL || ifp->if_output == if_nulloutput)
 1399                         return NULL;
 1400                 return ifp;
 1401         }
 1402 
 1403         IFNET_FOREACH(ifp) {
 1404                 if (ifp->if_output == if_nulloutput)
 1405                         continue;
 1406                 if (strcmp(ifp->if_xname, name) == 0)
 1407                         return ifp;
 1408         }
 1409         return NULL;
 1410 }
 1411 
 1412 /* common */
 1413 int
 1414 ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
 1415 {
 1416         int s;
 1417         struct ifreq *ifr;
 1418         struct ifcapreq *ifcr;
 1419         struct ifdatareq *ifdr;
 1420 
 1421         switch (cmd) {
 1422         case SIOCSIFCAP:
 1423                 ifcr = data;
 1424                 if ((ifcr->ifcr_capenable & ~ifp->if_capabilities) != 0)
 1425                         return EINVAL;
 1426 
 1427                 if (ifcr->ifcr_capenable == ifp->if_capenable)
 1428                         return 0;
 1429 
 1430                 ifp->if_capenable = ifcr->ifcr_capenable;
 1431 
 1432                 /* Pre-compute the checksum flags mask. */
 1433                 ifp->if_csum_flags_tx = 0;
 1434                 ifp->if_csum_flags_rx = 0;
 1435                 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) {
 1436                         ifp->if_csum_flags_tx |= M_CSUM_IPv4;
 1437                 }
 1438                 if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) {
 1439                         ifp->if_csum_flags_rx |= M_CSUM_IPv4;
 1440                 }
 1441 
 1442                 if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) {
 1443                         ifp->if_csum_flags_tx |= M_CSUM_TCPv4;
 1444                 }
 1445                 if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) {
 1446                         ifp->if_csum_flags_rx |= M_CSUM_TCPv4;
 1447                 }
 1448 
 1449                 if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) {
 1450                         ifp->if_csum_flags_tx |= M_CSUM_UDPv4;
 1451                 }
 1452                 if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) {
 1453                         ifp->if_csum_flags_rx |= M_CSUM_UDPv4;
 1454                 }
 1455 
 1456                 if (ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) {
 1457                         ifp->if_csum_flags_tx |= M_CSUM_TCPv6;
 1458                 }
 1459                 if (ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) {
 1460                         ifp->if_csum_flags_rx |= M_CSUM_TCPv6;
 1461                 }
 1462 
 1463                 if (ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) {
 1464                         ifp->if_csum_flags_tx |= M_CSUM_UDPv6;
 1465                 }
 1466                 if (ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) {
 1467                         ifp->if_csum_flags_rx |= M_CSUM_UDPv6;
 1468                 }
 1469                 if (ifp->if_flags & IFF_UP)
 1470                         return ENETRESET;
 1471                 return 0;
 1472         case SIOCSIFFLAGS:
 1473                 ifr = data;
 1474                 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
 1475                         s = splnet();
 1476                         if_down(ifp);
 1477                         splx(s);
 1478                 }
 1479                 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
 1480                         s = splnet();
 1481                         if_up(ifp);
 1482                         splx(s);
 1483                 }
 1484                 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
 1485                         (ifr->ifr_flags &~ IFF_CANTCHANGE);
 1486                 break;
 1487         case SIOCGIFFLAGS:
 1488                 ifr = data;
 1489                 ifr->ifr_flags = ifp->if_flags;
 1490                 break;
 1491 
 1492         case SIOCGIFMETRIC:
 1493                 ifr = data;
 1494                 ifr->ifr_metric = ifp->if_metric;
 1495                 break;
 1496 
 1497         case SIOCGIFMTU:
 1498                 ifr = data;
 1499                 ifr->ifr_mtu = ifp->if_mtu;
 1500                 break;
 1501 
 1502         case SIOCGIFDLT:
 1503                 ifr = data;
 1504                 ifr->ifr_dlt = ifp->if_dlt;
 1505                 break;
 1506 
 1507         case SIOCGIFCAP:
 1508                 ifcr = data;
 1509                 ifcr->ifcr_capabilities = ifp->if_capabilities;
 1510                 ifcr->ifcr_capenable = ifp->if_capenable;
 1511                 break;
 1512 
 1513         case SIOCSIFMETRIC:
 1514                 ifr = data;
 1515                 ifp->if_metric = ifr->ifr_metric;
 1516                 break;
 1517 
 1518         case SIOCGIFDATA:
 1519                 ifdr = data;
 1520                 ifdr->ifdr_data = ifp->if_data;
 1521                 break;
 1522 
 1523         case SIOCZIFDATA:
 1524                 ifdr = data;
 1525                 ifdr->ifdr_data = ifp->if_data;
 1526                 /*
 1527                  * Assumes that the volatile counters that can be
 1528                  * zero'ed are at the end of if_data.
 1529                  */
 1530                 memset(&ifp->if_data.ifi_ipackets, 0, sizeof(ifp->if_data) -
 1531                     offsetof(struct if_data, ifi_ipackets));
 1532                 break;
 1533         case SIOCSIFMTU:
 1534                 ifr = data;
 1535                 if (ifp->if_mtu == ifr->ifr_mtu)
 1536                         break;
 1537                 ifp->if_mtu = ifr->ifr_mtu;
 1538                 /*
 1539                  * If the link MTU changed, do network layer specific procedure.
 1540                  */
 1541 #ifdef INET6
 1542                 nd6_setmtu(ifp);
 1543 #endif
 1544                 return ENETRESET;
 1545         default:
 1546                 return ENOTTY;
 1547         }
 1548         return 0;
 1549 }
 1550 
 1551 /*
 1552  * Interface ioctls.
 1553  */
 1554 int
 1555 ifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l)
 1556 {
 1557         struct ifnet *ifp;
 1558         struct ifreq *ifr;
 1559         struct ifcapreq *ifcr;
 1560         struct ifdatareq *ifdr;
 1561         int error = 0;
 1562 #if defined(COMPAT_OSOCK) || defined(COMPAT_OIFREQ)
 1563         u_long ocmd = cmd;
 1564 #endif
 1565         short oif_flags;
 1566 #ifdef COMPAT_OIFREQ
 1567         struct ifreq ifrb;
 1568         struct oifreq *oifr = NULL;
 1569 #endif
 1570 
 1571         switch (cmd) {
 1572 #ifdef COMPAT_OIFREQ
 1573         case OSIOCGIFCONF:
 1574         case OOSIOCGIFCONF:
 1575                 return compat_ifconf(cmd, data);
 1576 #endif
 1577         case SIOCGIFCONF:
 1578                 return ifconf(cmd, data);
 1579         }
 1580 
 1581 #ifdef COMPAT_OIFREQ
 1582         cmd = compat_cvtcmd(cmd);
 1583         if (cmd != ocmd) {
 1584                 oifr = data;
 1585                 data = ifr = &ifrb;
 1586                 ifreqo2n(oifr, ifr);
 1587         } else
 1588 #endif
 1589                 ifr = data;
 1590         ifcr = data;
 1591         ifdr = data;
 1592 
 1593         ifp = ifunit(ifr->ifr_name);
 1594 
 1595         switch (cmd) {
 1596         case SIOCIFCREATE:
 1597         case SIOCIFDESTROY:
 1598                 if (l != NULL) {
 1599                         error = kauth_authorize_network(l->l_cred,
 1600                             KAUTH_NETWORK_INTERFACE,
 1601                             KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
 1602                             (void *)cmd, NULL);
 1603                         if (error != 0)
 1604                                 return error;
 1605                 }
 1606                 return (cmd == SIOCIFCREATE) ?
 1607                         if_clone_create(ifr->ifr_name) :
 1608                         if_clone_destroy(ifr->ifr_name);
 1609 
 1610         case SIOCIFGCLONERS:
 1611                 return if_clone_list((struct if_clonereq *)data);
 1612         }
 1613 
 1614         if (ifp == NULL)
 1615                 return ENXIO;
 1616 
 1617         switch (cmd) {
 1618         case SIOCALIFADDR:
 1619         case SIOCDLIFADDR:
 1620         case SIOCSIFADDRPREF:
 1621         case SIOCSIFFLAGS:
 1622         case SIOCSIFCAP:
 1623         case SIOCSIFMETRIC:
 1624         case SIOCZIFDATA:
 1625         case SIOCSIFMTU:
 1626         case SIOCSIFPHYADDR:
 1627         case SIOCDIFPHYADDR:
 1628 #ifdef INET6
 1629         case SIOCSIFPHYADDR_IN6:
 1630 #endif
 1631         case SIOCSLIFPHYADDR:
 1632         case SIOCADDMULTI:
 1633         case SIOCDELMULTI:
 1634         case SIOCSIFMEDIA:
 1635         case SIOCSDRVSPEC:
 1636         case SIOCG80211:
 1637         case SIOCS80211:
 1638         case SIOCS80211NWID:
 1639         case SIOCS80211NWKEY:
 1640         case SIOCS80211POWER:
 1641         case SIOCS80211BSSID:
 1642         case SIOCS80211CHANNEL:
 1643                 if (l != NULL) {
 1644                         error = kauth_authorize_network(l->l_cred,
 1645                             KAUTH_NETWORK_INTERFACE,
 1646                             KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
 1647                             (void *)cmd, NULL);
 1648                         if (error != 0)
 1649                                 return error;
 1650                 }
 1651         }
 1652 
 1653         oif_flags = ifp->if_flags;
 1654         switch (cmd) {
 1655 
 1656         case SIOCSIFFLAGS:
 1657                 ifioctl_common(ifp, cmd, data);
 1658                 if (ifp->if_ioctl)
 1659                         (void)(*ifp->if_ioctl)(ifp, cmd, data);
 1660                 break;
 1661 
 1662         case SIOCSIFPHYADDR:
 1663         case SIOCDIFPHYADDR:
 1664 #ifdef INET6
 1665         case SIOCSIFPHYADDR_IN6:
 1666 #endif
 1667         case SIOCSLIFPHYADDR:
 1668         case SIOCADDMULTI:
 1669         case SIOCDELMULTI:
 1670         case SIOCSIFMEDIA:
 1671         case SIOCGIFPSRCADDR:
 1672         case SIOCGIFPDSTADDR:
 1673         case SIOCGLIFPHYADDR:
 1674         case SIOCGIFMEDIA:
 1675         case SIOCG80211:
 1676         case SIOCS80211:
 1677         case SIOCS80211NWID:
 1678         case SIOCS80211NWKEY:
 1679         case SIOCS80211POWER:
 1680         case SIOCS80211BSSID:
 1681         case SIOCS80211CHANNEL:
 1682         case SIOCSIFCAP:
 1683         case SIOCSIFMTU:
 1684                 if (ifp->if_ioctl == NULL)
 1685                         return EOPNOTSUPP;
 1686                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 1687                 break;
 1688 
 1689         default:
 1690                 error = ifioctl_common(ifp, cmd, data);
 1691                 if (error != ENOTTY)
 1692                         break;
 1693                 if (so->so_proto == NULL)
 1694                         return EOPNOTSUPP;
 1695 #ifdef COMPAT_OSOCK
 1696                 error = compat_ifioctl(so, ocmd, cmd, data, l);
 1697 #else
 1698                 error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
 1699                     (struct mbuf *)cmd, (struct mbuf *)data,
 1700                     (struct mbuf *)ifp, l);
 1701 #endif
 1702                 break;
 1703         }
 1704 
 1705         if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
 1706 #ifdef INET6
 1707                 if ((ifp->if_flags & IFF_UP) != 0) {
 1708                         int s = splnet();
 1709                         in6_if_up(ifp);
 1710                         splx(s);
 1711                 }
 1712 #endif
 1713         }
 1714 #ifdef COMPAT_OIFREQ
 1715         if (cmd != ocmd)
 1716                 ifreqn2o(ifr, oifr);
 1717 #endif
 1718 
 1719         return error;
 1720 }
 1721 
 1722 /*
 1723  * Return interface configuration
 1724  * of system.  List may be used
 1725  * in later ioctl's (above) to get
 1726  * other information.
 1727  *
 1728  * Each record is a struct ifreq.  Before the addition of
 1729  * sockaddr_storage, the API rule was that sockaddr flavors that did
 1730  * not fit would extend beyond the struct ifreq, with the next struct
 1731  * ifreq starting sa_len beyond the struct sockaddr.  Because the
 1732  * union in struct ifreq includes struct sockaddr_storage, every kind
 1733  * of sockaddr must fit.  Thus, there are no longer any overlength
 1734  * records.
 1735  *
 1736  * Records are added to the user buffer if they fit, and ifc_len is
 1737  * adjusted to the length that was written.  Thus, the user is only
 1738  * assured of getting the complete list if ifc_len on return is at
 1739  * least sizeof(struct ifreq) less than it was on entry.
 1740  *
 1741  * If the user buffer pointer is NULL, this routine copies no data and
 1742  * returns the amount of space that would be needed.
 1743  *
 1744  * Invariants:
 1745  * ifrp points to the next part of the user's buffer to be used.  If
 1746  * ifrp != NULL, space holds the number of bytes remaining that we may
 1747  * write at ifrp.  Otherwise, space holds the number of bytes that
 1748  * would have been written had there been adequate space.
 1749  */
 1750 /*ARGSUSED*/
 1751 int
 1752 ifconf(u_long cmd, void *data)
 1753 {
 1754         struct ifconf *ifc = (struct ifconf *)data;
 1755         struct ifnet *ifp;
 1756         struct ifaddr *ifa;
 1757         struct ifreq ifr, *ifrp;
 1758         int space, error = 0;
 1759         const int sz = (int)sizeof(struct ifreq);
 1760 
 1761         if ((ifrp = ifc->ifc_req) == NULL)
 1762                 space = 0;
 1763         else
 1764                 space = ifc->ifc_len;
 1765         IFNET_FOREACH(ifp) {
 1766                 (void)strncpy(ifr.ifr_name, ifp->if_xname,
 1767                     sizeof(ifr.ifr_name));
 1768                 if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
 1769                         return ENAMETOOLONG;
 1770                 if (IFADDR_EMPTY(ifp)) {
 1771                         /* Interface with no addresses - send zero sockaddr. */
 1772                         memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
 1773                         if (ifrp == NULL) {
 1774                                 space += sz;
 1775                                 continue;
 1776                         }
 1777                         if (space >= sz) {
 1778                                 error = copyout(&ifr, ifrp, sz);
 1779                                 if (error != 0)
 1780                                         return error;
 1781                                 ifrp++;
 1782                                 space -= sz;
 1783                         }
 1784                 }
 1785 
 1786                 IFADDR_FOREACH(ifa, ifp) {
 1787                         struct sockaddr *sa = ifa->ifa_addr;
 1788                         /* all sockaddrs must fit in sockaddr_storage */
 1789                         KASSERT(sa->sa_len <= sizeof(ifr.ifr_ifru));
 1790 
 1791                         if (ifrp == NULL) {
 1792                                 space += sz;
 1793                                 continue;
 1794                         }
 1795                         memcpy(&ifr.ifr_space, sa, sa->sa_len);
 1796                         if (space >= sz) {
 1797                                 error = copyout(&ifr, ifrp, sz);
 1798                                 if (error != 0)
 1799                                         return (error);
 1800                                 ifrp++; space -= sz;
 1801                         }
 1802                 }
 1803         }
 1804         if (ifrp != NULL) {
 1805                 KASSERT(0 <= space && space <= ifc->ifc_len);
 1806                 ifc->ifc_len -= space;
 1807         } else {
 1808                 KASSERT(space >= 0);
 1809                 ifc->ifc_len = space;
 1810         }
 1811         return (0);
 1812 }
 1813 
 1814 int
 1815 ifreq_setaddr(u_long cmd, struct ifreq *ifr, const struct sockaddr *sa)
 1816 {
 1817         uint8_t len;
 1818 #ifdef COMPAT_OIFREQ
 1819         struct ifreq ifrb;
 1820         struct oifreq *oifr = NULL;
 1821         u_long ocmd = cmd;
 1822         cmd = compat_cvtcmd(cmd);
 1823         if (cmd != ocmd) {
 1824                 oifr = (struct oifreq *)(void *)ifr;
 1825                 ifr = &ifrb;
 1826                 ifreqo2n(oifr, ifr);
 1827                 len = sizeof(oifr->ifr_addr);
 1828         } else
 1829 #endif
 1830                 len = sizeof(ifr->ifr_ifru.ifru_space);
 1831 
 1832         if (len < sa->sa_len)
 1833                 return EFBIG;
 1834 
 1835         memset(&ifr->ifr_addr, 0, len);
 1836         sockaddr_copy(&ifr->ifr_addr, len, sa);
 1837 
 1838 #ifdef COMPAT_OIFREQ
 1839         if (cmd != ocmd)
 1840                 ifreqn2o(oifr, ifr);
 1841 #endif
 1842         return 0;
 1843 }
 1844 
 1845 /*
 1846  * Queue message on interface, and start output if interface
 1847  * not yet active.
 1848  */
 1849 int
 1850 ifq_enqueue(struct ifnet *ifp, struct mbuf *m
 1851     ALTQ_COMMA ALTQ_DECL(struct altq_pktattr *pktattr))
 1852 {
 1853         int len = m->m_pkthdr.len;
 1854         int mflags = m->m_flags;
 1855         int s = splnet();
 1856         int error;
 1857 
 1858         IFQ_ENQUEUE(&ifp->if_snd, m, pktattr, error);
 1859         if (error != 0)
 1860                 goto out;
 1861         ifp->if_obytes += len;
 1862         if (mflags & M_MCAST)
 1863                 ifp->if_omcasts++;
 1864         if ((ifp->if_flags & IFF_OACTIVE) == 0)
 1865                 (*ifp->if_start)(ifp);
 1866 out:
 1867         splx(s);
 1868         return error;
 1869 }
 1870 
 1871 /*
 1872  * Queue message on interface, possibly using a second fast queue
 1873  */
 1874 int
 1875 ifq_enqueue2(struct ifnet *ifp, struct ifqueue *ifq, struct mbuf *m
 1876     ALTQ_COMMA ALTQ_DECL(struct altq_pktattr *pktattr))
 1877 {
 1878         int error = 0;
 1879 
 1880         if (ifq != NULL
 1881 #ifdef ALTQ
 1882             && ALTQ_IS_ENABLED(&ifp->if_snd) == 0
 1883 #endif
 1884             ) {
 1885                 if (IF_QFULL(ifq)) {
 1886                         IF_DROP(&ifp->if_snd);
 1887                         m_freem(m);
 1888                         if (error == 0)
 1889                                 error = ENOBUFS;
 1890                 } else
 1891                         IF_ENQUEUE(ifq, m);
 1892         } else
 1893                 IFQ_ENQUEUE(&ifp->if_snd, m, pktattr, error);
 1894         if (error != 0) {
 1895                 ++ifp->if_oerrors;
 1896                 return error;
 1897         }
 1898         return 0;
 1899 }
 1900 
 1901 
 1902 #if defined(INET) || defined(INET6)
 1903 static void
 1904 sysctl_net_ifq_setup(struct sysctllog **clog,
 1905                      int pf, const char *pfname,
 1906                      int ipn, const char *ipname,
 1907                      int qid, struct ifqueue *ifq)
 1908 {
 1909 
 1910         sysctl_createv(clog, 0, NULL, NULL,
 1911                        CTLFLAG_PERMANENT,
 1912                        CTLTYPE_NODE, "net", NULL,
 1913                        NULL, 0, NULL, 0,
 1914                        CTL_NET, CTL_EOL);
 1915         sysctl_createv(clog, 0, NULL, NULL,
 1916                        CTLFLAG_PERMANENT,
 1917                        CTLTYPE_NODE, pfname, NULL,
 1918                        NULL, 0, NULL, 0,
 1919                        CTL_NET, pf, CTL_EOL);
 1920         sysctl_createv(clog, 0, NULL, NULL,
 1921                        CTLFLAG_PERMANENT,
 1922                        CTLTYPE_NODE, ipname, NULL,
 1923                        NULL, 0, NULL, 0,
 1924                        CTL_NET, pf, ipn, CTL_EOL);
 1925         sysctl_createv(clog, 0, NULL, NULL,
 1926                        CTLFLAG_PERMANENT,
 1927                        CTLTYPE_NODE, "ifq",
 1928                        SYSCTL_DESCR("Protocol input queue controls"),
 1929                        NULL, 0, NULL, 0,
 1930                        CTL_NET, pf, ipn, qid, CTL_EOL);
 1931 
 1932         sysctl_createv(clog, 0, NULL, NULL,
 1933                        CTLFLAG_PERMANENT,
 1934                        CTLTYPE_INT, "len",
 1935                        SYSCTL_DESCR("Current input queue length"),
 1936                        NULL, 0, &ifq->ifq_len, 0,
 1937                        CTL_NET, pf, ipn, qid, IFQCTL_LEN, CTL_EOL);
 1938         sysctl_createv(clog, 0, NULL, NULL,
 1939                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1940                        CTLTYPE_INT, "maxlen",
 1941                        SYSCTL_DESCR("Maximum allowed input queue length"),
 1942                        NULL, 0, &ifq->ifq_maxlen, 0,
 1943                        CTL_NET, pf, ipn, qid, IFQCTL_MAXLEN, CTL_EOL);
 1944 #ifdef notyet
 1945         sysctl_createv(clog, 0, NULL, NULL,
 1946                        CTLFLAG_PERMANENT,
 1947                        CTLTYPE_INT, "peak",
 1948                        SYSCTL_DESCR("Highest input queue length"),
 1949                        NULL, 0, &ifq->ifq_peak, 0,
 1950                        CTL_NET, pf, ipn, qid, IFQCTL_PEAK, CTL_EOL);
 1951 #endif
 1952         sysctl_createv(clog, 0, NULL, NULL,
 1953                        CTLFLAG_PERMANENT,
 1954                        CTLTYPE_INT, "drops",
 1955                        SYSCTL_DESCR("Packets dropped due to full input queue"),
 1956                        NULL, 0, &ifq->ifq_drops, 0,
 1957                        CTL_NET, pf, ipn, qid, IFQCTL_DROPS, CTL_EOL);
 1958 }
 1959 
 1960 #ifdef INET
 1961 SYSCTL_SETUP(sysctl_net_inet_ip_ifq_setup,
 1962              "sysctl net.inet.ip.ifq subtree setup")
 1963 {
 1964         extern struct ifqueue ipintrq;
 1965 
 1966         sysctl_net_ifq_setup(clog, PF_INET, "inet", IPPROTO_IP, "ip",
 1967                              IPCTL_IFQ, &ipintrq);
 1968 }
 1969 #endif /* INET */
 1970 
 1971 #ifdef INET6
 1972 SYSCTL_SETUP(sysctl_net_inet6_ip6_ifq_setup,
 1973              "sysctl net.inet6.ip6.ifq subtree setup")
 1974 {
 1975         extern struct ifqueue ip6intrq;
 1976 
 1977         sysctl_net_ifq_setup(clog, PF_INET6, "inet6", IPPROTO_IPV6, "ip6",
 1978                              IPV6CTL_IFQ, &ip6intrq);
 1979 }
 1980 #endif /* INET6 */
 1981 #endif /* INET || INET6 */

Cache object: 9055b9f96a382a623d34fd87822abdc2


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