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 /*      $OpenBSD: if.c,v 1.683 2022/11/23 16:57:37 kn Exp $     */
    2 /*      $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $  */
    3 
    4 /*
    5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the project nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Copyright (c) 1980, 1986, 1993
   35  *      The Regents of the University of California.  All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. Neither the name of the University nor the names of its contributors
   46  *    may be used to endorse or promote products derived from this software
   47  *    without specific prior written permission.
   48  *
   49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59  * SUCH DAMAGE.
   60  *
   61  *      @(#)if.c        8.3 (Berkeley) 1/4/94
   62  */
   63 
   64 #include "bpfilter.h"
   65 #include "bridge.h"
   66 #include "carp.h"
   67 #include "ether.h"
   68 #include "pf.h"
   69 #include "pfsync.h"
   70 #include "ppp.h"
   71 #include "pppoe.h"
   72 #include "if_wg.h"
   73 
   74 #include <sys/param.h>
   75 #include <sys/systm.h>
   76 #include <sys/mbuf.h>
   77 #include <sys/socket.h>
   78 #include <sys/socketvar.h>
   79 #include <sys/timeout.h>
   80 #include <sys/protosw.h>
   81 #include <sys/kernel.h>
   82 #include <sys/ioctl.h>
   83 #include <sys/domain.h>
   84 #include <sys/task.h>
   85 #include <sys/atomic.h>
   86 #include <sys/percpu.h>
   87 #include <sys/proc.h>
   88 #include <sys/stdint.h> /* uintptr_t */
   89 #include <sys/rwlock.h>
   90 #include <sys/smr.h>
   91 
   92 #include <net/if.h>
   93 #include <net/if_dl.h>
   94 #include <net/if_types.h>
   95 #include <net/route.h>
   96 #include <net/netisr.h>
   97 
   98 #include <netinet/in.h>
   99 #include <netinet/if_ether.h>
  100 #include <netinet/igmp.h>
  101 #ifdef MROUTING
  102 #include <netinet/ip_mroute.h>
  103 #endif
  104 
  105 #ifdef INET6
  106 #include <netinet6/in6_var.h>
  107 #include <netinet6/in6_ifattach.h>
  108 #include <netinet6/nd6.h>
  109 #include <netinet/ip6.h>
  110 #include <netinet6/ip6_var.h>
  111 #endif
  112 
  113 #ifdef MPLS
  114 #include <netmpls/mpls.h>
  115 #endif
  116 
  117 #if NBPFILTER > 0
  118 #include <net/bpf.h>
  119 #endif
  120 
  121 #if NBRIDGE > 0
  122 #include <net/if_bridge.h>
  123 #endif
  124 
  125 #if NCARP > 0
  126 #include <netinet/ip_carp.h>
  127 #endif
  128 
  129 #if NPF > 0
  130 #include <net/pfvar.h>
  131 #endif
  132 
  133 #include <sys/device.h>
  134 
  135 void    if_attachsetup(struct ifnet *);
  136 void    if_attach_common(struct ifnet *);
  137 void    if_remove(struct ifnet *);
  138 int     if_createrdomain(int, struct ifnet *);
  139 int     if_setrdomain(struct ifnet *, int);
  140 void    if_slowtimo(void *);
  141 
  142 void    if_detached_qstart(struct ifqueue *);
  143 int     if_detached_ioctl(struct ifnet *, u_long, caddr_t);
  144 
  145 int     ifioctl_get(u_long, caddr_t);
  146 int     ifconf(caddr_t);
  147 static int
  148         if_sffpage_check(const caddr_t);
  149 
  150 int     if_getgroup(caddr_t, struct ifnet *);
  151 int     if_getgroupmembers(caddr_t);
  152 int     if_getgroupattribs(caddr_t);
  153 int     if_setgroupattribs(caddr_t);
  154 int     if_getgrouplist(caddr_t);
  155 
  156 void    if_linkstate(struct ifnet *);
  157 void    if_linkstate_task(void *);
  158 
  159 int     if_clone_list(struct if_clonereq *);
  160 struct if_clone *if_clone_lookup(const char *, int *);
  161 
  162 int     if_group_egress_build(void);
  163 
  164 void    if_watchdog_task(void *);
  165 
  166 void    if_netisr(void *);
  167 
  168 #ifdef DDB
  169 void    ifa_print_all(void);
  170 #endif
  171 
  172 void    if_qstart_compat(struct ifqueue *);
  173 
  174 /*
  175  * interface index map
  176  *
  177  * the kernel maintains a mapping of interface indexes to struct ifnet
  178  * pointers.
  179  *
  180  * the map is an array of struct ifnet pointers prefixed by an if_map
  181  * structure. the if_map structure stores the length of its array.
  182  *
  183  * as interfaces are attached to the system, the map is grown on demand
  184  * up to USHRT_MAX entries.
  185  *
  186  * interface index 0 is reserved and represents no interface. this
  187  * supports the use of the interface index as the scope for IPv6 link
  188  * local addresses, where scope 0 means no scope has been specified.
  189  * it also supports the use of interface index as the unique identifier
  190  * for network interfaces in SNMP applications as per RFC2863. therefore
  191  * if_get(0) returns NULL.
  192  */
  193 
  194 struct ifnet *if_ref(struct ifnet *);
  195 
  196 /*
  197  * struct if_idxmap
  198  *
  199  * infrastructure to manage updates and accesses to the current if_map.
  200  *
  201  * interface index 0 is special and represents "no interface", so we
  202  * use the 0th slot in map to store the length of the array.
  203  */
  204 
  205 struct if_idxmap {
  206         unsigned int              serial;
  207         unsigned int              count;
  208         struct ifnet            **map;          /* SMR protected */
  209         struct rwlock             lock;
  210         unsigned char            *usedidx;      /* bitmap of indices in use */
  211 };
  212 
  213 struct if_idxmap_dtor {
  214         struct smr_entry          smr;
  215         struct ifnet            **map;
  216 };
  217 
  218 void    if_idxmap_init(unsigned int);
  219 void    if_idxmap_free(void *);
  220 void    if_idxmap_alloc(struct ifnet *);
  221 void    if_idxmap_insert(struct ifnet *);
  222 void    if_idxmap_remove(struct ifnet *);
  223 
  224 TAILQ_HEAD(, ifg_group) ifg_head =
  225     TAILQ_HEAD_INITIALIZER(ifg_head);   /* [N] list of interface groups */
  226 
  227 LIST_HEAD(, if_clone) if_cloners =
  228     LIST_HEAD_INITIALIZER(if_cloners);  /* [I] list of clonable interfaces */
  229 int if_cloners_count;   /* [I] number of clonable interfaces */
  230 
  231 struct rwlock if_cloners_lock = RWLOCK_INITIALIZER("clonelk");
  232 
  233 /* hooks should only be added, deleted, and run from a process context */
  234 struct mutex if_hooks_mtx = MUTEX_INITIALIZER(IPL_NONE);
  235 void    if_hooks_run(struct task_list *);
  236 
  237 int     ifq_congestion;
  238 
  239 int              netisr;
  240 
  241 #define NET_TASKQ       4
  242 struct taskq    *nettqmp[NET_TASKQ];
  243 
  244 struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL);
  245 
  246 /*
  247  * Serialize socket operations to ensure no new sleeping points
  248  * are introduced in IP output paths.
  249  */
  250 struct rwlock netlock = RWLOCK_INITIALIZER("netlock");
  251 
  252 /*
  253  * Network interface utility routines.
  254  */
  255 void
  256 ifinit(void)
  257 {
  258         unsigned int    i;
  259 
  260         /*
  261          * most machines boot with 4 or 5 interfaces, so size the initial map
  262          * to accommodate this
  263          */
  264         if_idxmap_init(8); /* 8 is a nice power of 2 for malloc */
  265 
  266         for (i = 0; i < NET_TASKQ; i++) {
  267                 nettqmp[i] = taskq_create("softnet", 1, IPL_NET, TASKQ_MPSAFE);
  268                 if (nettqmp[i] == NULL)
  269                         panic("unable to create network taskq %d", i);
  270         }
  271 }
  272 
  273 static struct if_idxmap if_idxmap;
  274 
  275 struct ifnet_head ifnetlist = TAILQ_HEAD_INITIALIZER(ifnetlist);
  276 
  277 static inline unsigned int
  278 if_idxmap_limit(struct ifnet **if_map)
  279 {
  280         return ((uintptr_t)if_map[0]);
  281 }
  282 
  283 static inline size_t
  284 if_idxmap_usedidx_size(unsigned int limit)
  285 {
  286         return (max(howmany(limit, NBBY), sizeof(struct if_idxmap_dtor)));
  287 }
  288 
  289 void
  290 if_idxmap_init(unsigned int limit)
  291 {
  292         struct ifnet **if_map;
  293 
  294         rw_init(&if_idxmap.lock, "idxmaplk");
  295         if_idxmap.serial = 1; /* skip ifidx 0 */
  296 
  297         if_map = mallocarray(limit, sizeof(*if_map), M_IFADDR,
  298             M_WAITOK | M_ZERO);
  299 
  300         if_map[0] = (struct ifnet *)(uintptr_t)limit;
  301 
  302         if_idxmap.usedidx = malloc(if_idxmap_usedidx_size(limit),
  303             M_IFADDR, M_WAITOK | M_ZERO);
  304         setbit(if_idxmap.usedidx, 0); /* blacklist ifidx 0 */
  305 
  306         /* this is called early so there's nothing to race with */
  307         SMR_PTR_SET_LOCKED(&if_idxmap.map, if_map);
  308 }
  309 
  310 void
  311 if_idxmap_alloc(struct ifnet *ifp)
  312 {
  313         struct ifnet **if_map;
  314         unsigned int limit;
  315         unsigned int index, i;
  316 
  317         refcnt_init(&ifp->if_refcnt);
  318 
  319         rw_enter_write(&if_idxmap.lock);
  320 
  321         if (++if_idxmap.count >= USHRT_MAX)
  322                 panic("too many interfaces");
  323 
  324         if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
  325         limit = if_idxmap_limit(if_map);
  326 
  327         index = if_idxmap.serial++ & USHRT_MAX;
  328 
  329         if (index >= limit) {
  330                 struct if_idxmap_dtor *dtor;
  331                 struct ifnet **oif_map;
  332                 unsigned int olimit;
  333                 unsigned char *nusedidx;
  334 
  335                 oif_map = if_map;
  336                 olimit = limit;
  337 
  338                 limit = olimit * 2;
  339                 if_map = mallocarray(limit, sizeof(*if_map), M_IFADDR,
  340                     M_WAITOK | M_ZERO);
  341                 if_map[0] = (struct ifnet *)(uintptr_t)limit;
  342                 
  343                 for (i = 1; i < olimit; i++) {
  344                         struct ifnet *oifp = SMR_PTR_GET_LOCKED(&oif_map[i]);
  345                         if (oifp == NULL)
  346                                 continue;
  347 
  348                         /*
  349                          * nif_map isn't visible yet, so don't need
  350                          * SMR_PTR_SET_LOCKED and its membar.
  351                          */
  352                         if_map[i] = if_ref(oifp);
  353                 }
  354 
  355                 nusedidx = malloc(if_idxmap_usedidx_size(limit),
  356                     M_IFADDR, M_WAITOK | M_ZERO);
  357                 memcpy(nusedidx, if_idxmap.usedidx, howmany(olimit, NBBY));
  358 
  359                 /* use the old usedidx bitmap as an smr_entry for the if_map */
  360                 dtor = (struct if_idxmap_dtor *)if_idxmap.usedidx;
  361                 if_idxmap.usedidx = nusedidx;
  362 
  363                 SMR_PTR_SET_LOCKED(&if_idxmap.map, if_map);
  364 
  365                 dtor->map = oif_map;
  366                 smr_init(&dtor->smr);
  367                 smr_call(&dtor->smr, if_idxmap_free, dtor);
  368         }
  369 
  370         /* pick the next free index */
  371         for (i = 0; i < USHRT_MAX; i++) {
  372                 if (index != 0 && isclr(if_idxmap.usedidx, index))
  373                         break;
  374 
  375                 index = if_idxmap.serial++ & USHRT_MAX;
  376         }
  377         KASSERT(index != 0 && index < limit);
  378         KASSERT(isclr(if_idxmap.usedidx, index));
  379 
  380         setbit(if_idxmap.usedidx, index);
  381         ifp->if_index = index;
  382 
  383         rw_exit_write(&if_idxmap.lock);
  384 }
  385 
  386 void
  387 if_idxmap_free(void *arg)
  388 {
  389         struct if_idxmap_dtor *dtor = arg;
  390         struct ifnet **oif_map = dtor->map;
  391         unsigned int olimit = if_idxmap_limit(oif_map);
  392         unsigned int i;
  393 
  394         for (i = 1; i < olimit; i++)
  395                 if_put(oif_map[i]);
  396 
  397         free(oif_map, M_IFADDR, olimit * sizeof(*oif_map));
  398         free(dtor, M_IFADDR, if_idxmap_usedidx_size(olimit));
  399 }
  400 
  401 void
  402 if_idxmap_insert(struct ifnet *ifp)
  403 {
  404         struct ifnet **if_map;
  405         unsigned int index = ifp->if_index;
  406 
  407         rw_enter_write(&if_idxmap.lock);
  408 
  409         if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
  410 
  411         KASSERTMSG(index != 0 && index < if_idxmap_limit(if_map),
  412             "%s(%p) index %u vs limit %u", ifp->if_xname, ifp, index,
  413             if_idxmap_limit(if_map));
  414         KASSERT(SMR_PTR_GET_LOCKED(&if_map[index]) == NULL);
  415         KASSERT(isset(if_idxmap.usedidx, index));
  416 
  417         /* commit */
  418         SMR_PTR_SET_LOCKED(&if_map[index], if_ref(ifp));
  419 
  420         rw_exit_write(&if_idxmap.lock);
  421 }
  422 
  423 void
  424 if_idxmap_remove(struct ifnet *ifp)
  425 {
  426         struct ifnet **if_map;
  427         unsigned int index = ifp->if_index;
  428 
  429         rw_enter_write(&if_idxmap.lock);
  430 
  431         if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
  432 
  433         KASSERT(index != 0 && index < if_idxmap_limit(if_map));
  434         KASSERT(SMR_PTR_GET_LOCKED(&if_map[index]) == ifp);
  435         KASSERT(isset(if_idxmap.usedidx, index));
  436 
  437         SMR_PTR_SET_LOCKED(&if_map[index], NULL);
  438 
  439         if_idxmap.count--;
  440         clrbit(if_idxmap.usedidx, index);
  441         /* end of if_idxmap modifications */
  442 
  443         rw_exit_write(&if_idxmap.lock);
  444 
  445         smr_barrier();
  446         if_put(ifp);
  447 }
  448 
  449 /*
  450  * Attach an interface to the
  451  * list of "active" interfaces.
  452  */
  453 void
  454 if_attachsetup(struct ifnet *ifp)
  455 {
  456         unsigned long ifidx;
  457 
  458         NET_ASSERT_LOCKED();
  459 
  460         if_addgroup(ifp, IFG_ALL);
  461 
  462 #ifdef INET6
  463         nd6_ifattach(ifp);
  464 #endif
  465 
  466 #if NPF > 0
  467         pfi_attach_ifnet(ifp);
  468 #endif
  469 
  470         timeout_set(&ifp->if_slowtimo, if_slowtimo, ifp);
  471         if_slowtimo(ifp);
  472 
  473         if_idxmap_insert(ifp);
  474         KASSERT(if_get(0) == NULL);
  475 
  476         ifidx = ifp->if_index;
  477 
  478         task_set(&ifp->if_watchdogtask, if_watchdog_task, (void *)ifidx);
  479         task_set(&ifp->if_linkstatetask, if_linkstate_task, (void *)ifidx);
  480 
  481         /* Announce the interface. */
  482         rtm_ifannounce(ifp, IFAN_ARRIVAL);
  483 }
  484 
  485 /*
  486  * Allocate the link level name for the specified interface.  This
  487  * is an attachment helper.  It must be called after ifp->if_addrlen
  488  * is initialized, which may not be the case when if_attach() is
  489  * called.
  490  */
  491 void
  492 if_alloc_sadl(struct ifnet *ifp)
  493 {
  494         unsigned int socksize;
  495         int namelen, masklen;
  496         struct sockaddr_dl *sdl;
  497 
  498         /*
  499          * If the interface already has a link name, release it
  500          * now.  This is useful for interfaces that can change
  501          * link types, and thus switch link names often.
  502          */
  503         if_free_sadl(ifp);
  504 
  505         namelen = strlen(ifp->if_xname);
  506         masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
  507         socksize = masklen + ifp->if_addrlen;
  508 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
  509         if (socksize < sizeof(*sdl))
  510                 socksize = sizeof(*sdl);
  511         socksize = ROUNDUP(socksize);
  512         sdl = malloc(socksize, M_IFADDR, M_WAITOK|M_ZERO);
  513         sdl->sdl_len = socksize;
  514         sdl->sdl_family = AF_LINK;
  515         bcopy(ifp->if_xname, sdl->sdl_data, namelen);
  516         sdl->sdl_nlen = namelen;
  517         sdl->sdl_alen = ifp->if_addrlen;
  518         sdl->sdl_index = ifp->if_index;
  519         sdl->sdl_type = ifp->if_type;
  520         ifp->if_sadl = sdl;
  521 }
  522 
  523 /*
  524  * Free the link level name for the specified interface.  This is
  525  * a detach helper.  This is called from if_detach() or from
  526  * link layer type specific detach functions.
  527  */
  528 void
  529 if_free_sadl(struct ifnet *ifp)
  530 {
  531         if (ifp->if_sadl == NULL)
  532                 return;
  533 
  534         free(ifp->if_sadl, M_IFADDR, ifp->if_sadl->sdl_len);
  535         ifp->if_sadl = NULL;
  536 }
  537 
  538 void
  539 if_attachhead(struct ifnet *ifp)
  540 {
  541         if_attach_common(ifp);
  542         NET_LOCK();
  543         TAILQ_INSERT_HEAD(&ifnetlist, ifp, if_list);
  544         if_attachsetup(ifp);
  545         NET_UNLOCK();
  546 }
  547 
  548 void
  549 if_attach(struct ifnet *ifp)
  550 {
  551         if_attach_common(ifp);
  552         NET_LOCK();
  553         TAILQ_INSERT_TAIL(&ifnetlist, ifp, if_list);
  554         if_attachsetup(ifp);
  555         NET_UNLOCK();
  556 }
  557 
  558 void
  559 if_attach_queues(struct ifnet *ifp, unsigned int nqs)
  560 {
  561         struct ifqueue **map;
  562         struct ifqueue *ifq;
  563         int i;
  564 
  565         KASSERT(ifp->if_ifqs == ifp->if_snd.ifq_ifqs);
  566         KASSERT(nqs != 0);
  567 
  568         map = mallocarray(sizeof(*map), nqs, M_DEVBUF, M_WAITOK);
  569 
  570         ifp->if_snd.ifq_softc = NULL;
  571         map[0] = &ifp->if_snd;
  572 
  573         for (i = 1; i < nqs; i++) {
  574                 ifq = malloc(sizeof(*ifq), M_DEVBUF, M_WAITOK|M_ZERO);
  575                 ifq_set_maxlen(ifq, ifp->if_snd.ifq_maxlen);
  576                 ifq_init(ifq, ifp, i);
  577                 map[i] = ifq;
  578         }
  579 
  580         ifp->if_ifqs = map;
  581         ifp->if_nifqs = nqs;
  582 }
  583 
  584 void
  585 if_attach_iqueues(struct ifnet *ifp, unsigned int niqs)
  586 {
  587         struct ifiqueue **map;
  588         struct ifiqueue *ifiq;
  589         unsigned int i;
  590 
  591         KASSERT(niqs != 0);
  592 
  593         map = mallocarray(niqs, sizeof(*map), M_DEVBUF, M_WAITOK);
  594 
  595         ifp->if_rcv.ifiq_softc = NULL;
  596         map[0] = &ifp->if_rcv;
  597 
  598         for (i = 1; i < niqs; i++) {
  599                 ifiq = malloc(sizeof(*ifiq), M_DEVBUF, M_WAITOK|M_ZERO);
  600                 ifiq_init(ifiq, ifp, i);
  601                 map[i] = ifiq;
  602         }
  603 
  604         ifp->if_iqs = map;
  605         ifp->if_niqs = niqs;
  606 }
  607 
  608 void
  609 if_attach_common(struct ifnet *ifp)
  610 {
  611         KASSERT(ifp->if_ioctl != NULL);
  612 
  613         TAILQ_INIT(&ifp->if_addrlist);
  614         TAILQ_INIT(&ifp->if_maddrlist);
  615         TAILQ_INIT(&ifp->if_groups);
  616 
  617         if (!ISSET(ifp->if_xflags, IFXF_MPSAFE)) {
  618                 KASSERTMSG(ifp->if_qstart == NULL,
  619                     "%s: if_qstart set without MPSAFE set", ifp->if_xname);
  620                 ifp->if_qstart = if_qstart_compat;
  621         } else {
  622                 KASSERTMSG(ifp->if_start == NULL,
  623                     "%s: if_start set with MPSAFE set", ifp->if_xname);
  624                 KASSERTMSG(ifp->if_qstart != NULL,
  625                     "%s: if_qstart not set with MPSAFE set", ifp->if_xname);
  626         }
  627 
  628         if_idxmap_alloc(ifp);
  629 
  630         ifq_init(&ifp->if_snd, ifp, 0);
  631 
  632         ifp->if_snd.ifq_ifqs[0] = &ifp->if_snd;
  633         ifp->if_ifqs = ifp->if_snd.ifq_ifqs;
  634         ifp->if_nifqs = 1;
  635         if (ifp->if_txmit == 0)
  636                 ifp->if_txmit = IF_TXMIT_DEFAULT;
  637 
  638         ifiq_init(&ifp->if_rcv, ifp, 0);
  639 
  640         ifp->if_rcv.ifiq_ifiqs[0] = &ifp->if_rcv;
  641         ifp->if_iqs = ifp->if_rcv.ifiq_ifiqs;
  642         ifp->if_niqs = 1;
  643 
  644         TAILQ_INIT(&ifp->if_addrhooks);
  645         TAILQ_INIT(&ifp->if_linkstatehooks);
  646         TAILQ_INIT(&ifp->if_detachhooks);
  647 
  648         if (ifp->if_rtrequest == NULL)
  649                 ifp->if_rtrequest = if_rtrequest_dummy;
  650         if (ifp->if_enqueue == NULL)
  651                 ifp->if_enqueue = if_enqueue_ifq;
  652 #if NBPFILTER > 0
  653         if (ifp->if_bpf_mtap == NULL)
  654                 ifp->if_bpf_mtap = bpf_mtap_ether;
  655 #endif
  656         ifp->if_llprio = IFQ_DEFPRIO;
  657 }
  658 
  659 void
  660 if_attach_ifq(struct ifnet *ifp, const struct ifq_ops *newops, void *args)
  661 {
  662         /*
  663          * only switch the ifq_ops on the first ifq on an interface.
  664          *
  665          * the only ifq_ops we provide priq and hfsc, and hfsc only
  666          * works on a single ifq. because the code uses the ifq_ops
  667          * on the first ifq (if_snd) to select a queue for an mbuf,
  668          * by switching only the first one we change both the algorithm
  669          * and force the routing of all new packets to it.
  670          */
  671         ifq_attach(&ifp->if_snd, newops, args);
  672 }
  673 
  674 void
  675 if_start(struct ifnet *ifp)
  676 {
  677         KASSERT(ifp->if_qstart == if_qstart_compat);
  678         if_qstart_compat(&ifp->if_snd);
  679 }
  680 void
  681 if_qstart_compat(struct ifqueue *ifq)
  682 {
  683         struct ifnet *ifp = ifq->ifq_if;
  684         int s;
  685 
  686         /*
  687          * the stack assumes that an interface can have multiple
  688          * transmit rings, but a lot of drivers are still written
  689          * so that interfaces and send rings have a 1:1 mapping.
  690          * this provides compatibility between the stack and the older
  691          * drivers by translating from the only queue they have
  692          * (ifp->if_snd) back to the interface and calling if_start.
  693          */
  694 
  695         KERNEL_LOCK();
  696         s = splnet();
  697         (*ifp->if_start)(ifp);
  698         splx(s);
  699         KERNEL_UNLOCK();
  700 }
  701 
  702 int
  703 if_enqueue(struct ifnet *ifp, struct mbuf *m)
  704 {
  705         CLR(m->m_pkthdr.csum_flags, M_TIMESTAMP);
  706 
  707 #if NPF > 0
  708         if (m->m_pkthdr.pf.delay > 0)
  709                 return (pf_delay_pkt(m, ifp->if_index));
  710 #endif
  711 
  712 #if NBRIDGE > 0
  713         if (ifp->if_bridgeidx && (m->m_flags & M_PROTO1) == 0) {
  714                 int error;
  715 
  716                 error = bridge_enqueue(ifp, m);
  717                 return (error);
  718         }
  719 #endif
  720 
  721 #if NPF > 0
  722         pf_pkt_addr_changed(m);
  723 #endif  /* NPF > 0 */
  724 
  725         return ((*ifp->if_enqueue)(ifp, m));
  726 }
  727 
  728 int
  729 if_enqueue_ifq(struct ifnet *ifp, struct mbuf *m)
  730 {
  731         struct ifqueue *ifq = &ifp->if_snd;
  732         int error;
  733 
  734         if (ifp->if_nifqs > 1) {
  735                 unsigned int idx;
  736 
  737                 /*
  738                  * use the operations on the first ifq to pick which of
  739                  * the array gets this mbuf.
  740                  */
  741 
  742                 idx = ifq_idx(&ifp->if_snd, ifp->if_nifqs, m);
  743                 ifq = ifp->if_ifqs[idx];
  744         }
  745 
  746         error = ifq_enqueue(ifq, m);
  747         if (error)
  748                 return (error);
  749 
  750         ifq_start(ifq);
  751 
  752         return (0);
  753 }
  754 
  755 void
  756 if_input(struct ifnet *ifp, struct mbuf_list *ml)
  757 {
  758         ifiq_input(&ifp->if_rcv, ml);
  759 }
  760 
  761 int
  762 if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
  763 {
  764         int keepflags;
  765 
  766 #if NBPFILTER > 0
  767         /*
  768          * Only send packets to bpf if they are destined to local
  769          * addresses.
  770          *
  771          * if_input_local() is also called for SIMPLEX interfaces to
  772          * duplicate packets for local use.  But don't dup them to bpf.
  773          */
  774         if (ifp->if_flags & IFF_LOOPBACK) {
  775                 caddr_t if_bpf = ifp->if_bpf;
  776 
  777                 if (if_bpf)
  778                         bpf_mtap_af(if_bpf, af, m, BPF_DIRECTION_OUT);
  779         }
  780 #endif
  781         keepflags = m->m_flags & (M_BCAST|M_MCAST);
  782         m_resethdr(m);
  783         m->m_flags |= M_LOOP | keepflags;
  784         m->m_pkthdr.ph_ifidx = ifp->if_index;
  785         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
  786 
  787         ifp->if_opackets++;
  788         ifp->if_obytes += m->m_pkthdr.len;
  789 
  790         ifp->if_ipackets++;
  791         ifp->if_ibytes += m->m_pkthdr.len;
  792 
  793         switch (af) {
  794         case AF_INET:
  795                 ipv4_input(ifp, m);
  796                 break;
  797 #ifdef INET6
  798         case AF_INET6:
  799                 ipv6_input(ifp, m);
  800                 break;
  801 #endif /* INET6 */
  802 #ifdef MPLS
  803         case AF_MPLS:
  804                 mpls_input(ifp, m);
  805                 break;
  806 #endif /* MPLS */
  807         default:
  808                 printf("%s: can't handle af%d\n", ifp->if_xname, af);
  809                 m_freem(m);
  810                 return (EAFNOSUPPORT);
  811         }
  812 
  813         return (0);
  814 }
  815 
  816 int
  817 if_output_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
  818 {
  819         struct ifiqueue *ifiq;
  820         unsigned int flow = 0;
  821 
  822         m->m_pkthdr.ph_family = af;
  823         m->m_pkthdr.ph_ifidx = ifp->if_index;
  824         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
  825 
  826         if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID))
  827                 flow = m->m_pkthdr.ph_flowid;
  828 
  829         ifiq = ifp->if_iqs[flow % ifp->if_niqs];
  830 
  831         return (ifiq_enqueue(ifiq, m) == 0 ? 0 : ENOBUFS);
  832 }
  833 
  834 void
  835 if_input_process(struct ifnet *ifp, struct mbuf_list *ml)
  836 {
  837         struct mbuf *m;
  838 
  839         if (ml_empty(ml))
  840                 return;
  841 
  842         if (!ISSET(ifp->if_xflags, IFXF_CLONED))
  843                 enqueue_randomness(ml_len(ml) ^ (uintptr_t)MBUF_LIST_FIRST(ml));
  844 
  845         /*
  846          * We grab the shared netlock for packet processing in the softnet
  847          * threads.  Packets can regrab the exclusive lock via queues.
  848          * ioctl, sysctl, and socket syscall may use shared lock if access is
  849          * read only or MP safe.  Usually they hold the exclusive net lock.
  850          */
  851 
  852         NET_LOCK_SHARED();
  853         while ((m = ml_dequeue(ml)) != NULL)
  854                 (*ifp->if_input)(ifp, m);
  855         NET_UNLOCK_SHARED();
  856 }
  857 
  858 void
  859 if_vinput(struct ifnet *ifp, struct mbuf *m)
  860 {
  861 #if NBPFILTER > 0
  862         caddr_t if_bpf;
  863 #endif
  864 
  865         m->m_pkthdr.ph_ifidx = ifp->if_index;
  866         m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
  867 
  868         counters_pkt(ifp->if_counters,
  869             ifc_ipackets, ifc_ibytes, m->m_pkthdr.len);
  870 
  871 #if NPF > 0
  872         pf_pkt_addr_changed(m);
  873 #endif
  874 
  875 #if NBPFILTER > 0
  876         if_bpf = ifp->if_bpf;
  877         if (if_bpf) {
  878                 if ((*ifp->if_bpf_mtap)(if_bpf, m, BPF_DIRECTION_IN)) {
  879                         m_freem(m);
  880                         return;
  881                 }
  882         }
  883 #endif
  884 
  885         if (__predict_true(!ISSET(ifp->if_xflags, IFXF_MONITOR)))
  886                 (*ifp->if_input)(ifp, m);
  887         else
  888                 m_freem(m);
  889 }
  890 
  891 void
  892 if_netisr(void *unused)
  893 {
  894         int n, t = 0;
  895 
  896         NET_LOCK();
  897 
  898         while ((n = netisr) != 0) {
  899                 /* Like sched_pause() but with a rwlock dance. */
  900                 if (curcpu()->ci_schedstate.spc_schedflags & SPCF_SHOULDYIELD) {
  901                         NET_UNLOCK();
  902                         yield();
  903                         NET_LOCK();
  904                 }
  905 
  906                 atomic_clearbits_int(&netisr, n);
  907 
  908 #if NETHER > 0
  909                 if (n & (1 << NETISR_ARP)) {
  910                         KERNEL_LOCK();
  911                         arpintr();
  912                         KERNEL_UNLOCK();
  913                 }
  914 #endif
  915                 if (n & (1 << NETISR_IP))
  916                         ipintr();
  917 #ifdef INET6
  918                 if (n & (1 << NETISR_IPV6))
  919                         ip6intr();
  920 #endif
  921 #if NPPP > 0
  922                 if (n & (1 << NETISR_PPP)) {
  923                         KERNEL_LOCK();
  924                         pppintr();
  925                         KERNEL_UNLOCK();
  926                 }
  927 #endif
  928 #if NBRIDGE > 0
  929                 if (n & (1 << NETISR_BRIDGE))
  930                         bridgeintr();
  931 #endif
  932 #ifdef PIPEX
  933                 if (n & (1 << NETISR_PIPEX))
  934                         pipexintr();
  935 #endif
  936 #if NPPPOE > 0
  937                 if (n & (1 << NETISR_PPPOE)) {
  938                         KERNEL_LOCK();
  939                         pppoeintr();
  940                         KERNEL_UNLOCK();
  941                 }
  942 #endif
  943                 t |= n;
  944         }
  945 
  946 #if NPFSYNC > 0
  947         if (t & (1 << NETISR_PFSYNC)) {
  948                 KERNEL_LOCK();
  949                 pfsyncintr();
  950                 KERNEL_UNLOCK();
  951         }
  952 #endif
  953 
  954         NET_UNLOCK();
  955 }
  956 
  957 void
  958 if_hooks_run(struct task_list *hooks)
  959 {
  960         struct task *t, *nt;
  961         struct task cursor = { .t_func = NULL };
  962         void (*func)(void *);
  963         void *arg;
  964 
  965         mtx_enter(&if_hooks_mtx);
  966         for (t = TAILQ_FIRST(hooks); t != NULL; t = nt) {
  967                 if (t->t_func == NULL) { /* skip cursors */
  968                         nt = TAILQ_NEXT(t, t_entry);
  969                         continue;
  970                 }
  971                 func = t->t_func;
  972                 arg = t->t_arg;
  973 
  974                 TAILQ_INSERT_AFTER(hooks, t, &cursor, t_entry);
  975                 mtx_leave(&if_hooks_mtx);
  976 
  977                 (*func)(arg);
  978 
  979                 mtx_enter(&if_hooks_mtx);
  980                 nt = TAILQ_NEXT(&cursor, t_entry); /* avoid _Q_INVALIDATE */
  981                 TAILQ_REMOVE(hooks, &cursor, t_entry);
  982         }
  983         mtx_leave(&if_hooks_mtx);
  984 }
  985 
  986 void
  987 if_remove(struct ifnet *ifp)
  988 {
  989         /* Remove the interface from the list of all interfaces. */
  990         NET_LOCK();
  991         TAILQ_REMOVE(&ifnetlist, ifp, if_list);
  992         NET_UNLOCK();
  993 
  994         /* Remove the interface from the interface index map. */
  995         if_idxmap_remove(ifp);
  996 
  997         /* Sleep until the last reference is released. */
  998         refcnt_finalize(&ifp->if_refcnt, "ifrm");
  999 }
 1000 
 1001 void
 1002 if_deactivate(struct ifnet *ifp)
 1003 {
 1004         /*
 1005          * Call detach hooks from head to tail.  To make sure detach
 1006          * hooks are executed in the reverse order they were added, all
 1007          * the hooks have to be added to the head!
 1008          */
 1009 
 1010         NET_LOCK();
 1011         if_hooks_run(&ifp->if_detachhooks);
 1012         NET_UNLOCK();
 1013 }
 1014 
 1015 void
 1016 if_detachhook_add(struct ifnet *ifp, struct task *t)
 1017 {
 1018         mtx_enter(&if_hooks_mtx);
 1019         TAILQ_INSERT_HEAD(&ifp->if_detachhooks, t, t_entry);
 1020         mtx_leave(&if_hooks_mtx);
 1021 }
 1022 
 1023 void
 1024 if_detachhook_del(struct ifnet *ifp, struct task *t)
 1025 {
 1026         mtx_enter(&if_hooks_mtx);
 1027         TAILQ_REMOVE(&ifp->if_detachhooks, t, t_entry);
 1028         mtx_leave(&if_hooks_mtx);
 1029 }
 1030 
 1031 /*
 1032  * Detach an interface from everything in the kernel.  Also deallocate
 1033  * private resources.
 1034  */
 1035 void
 1036 if_detach(struct ifnet *ifp)
 1037 {
 1038         struct ifaddr *ifa;
 1039         struct ifg_list *ifg;
 1040         int i, s;
 1041 
 1042         /* Undo pseudo-driver changes. */
 1043         if_deactivate(ifp);
 1044 
 1045         /* Other CPUs must not have a reference before we start destroying. */
 1046         if_remove(ifp);
 1047 
 1048         ifp->if_qstart = if_detached_qstart;
 1049 
 1050         /* Wait until the start routines finished. */
 1051         ifq_barrier(&ifp->if_snd);
 1052         ifq_clr_oactive(&ifp->if_snd);
 1053 
 1054 #if NBPFILTER > 0
 1055         bpfdetach(ifp);
 1056 #endif
 1057 
 1058         NET_LOCK();
 1059         s = splnet();
 1060         ifp->if_ioctl = if_detached_ioctl;
 1061         ifp->if_watchdog = NULL;
 1062 
 1063         /* Remove the watchdog timeout & task */
 1064         timeout_del(&ifp->if_slowtimo);
 1065         task_del(net_tq(ifp->if_index), &ifp->if_watchdogtask);
 1066 
 1067         /* Remove the link state task */
 1068         task_del(net_tq(ifp->if_index), &ifp->if_linkstatetask);
 1069 
 1070         rti_delete(ifp);
 1071 #if NETHER > 0 && defined(NFSCLIENT)
 1072         if (ifp->if_index == revarp_ifidx)
 1073                 revarp_ifidx = 0;
 1074 #endif
 1075 #ifdef MROUTING
 1076         vif_delete(ifp);
 1077 #endif
 1078         in_ifdetach(ifp);
 1079 #ifdef INET6
 1080         in6_ifdetach(ifp);
 1081 #endif
 1082 #if NPF > 0
 1083         pfi_detach_ifnet(ifp);
 1084 #endif
 1085 
 1086         while ((ifg = TAILQ_FIRST(&ifp->if_groups)) != NULL)
 1087                 if_delgroup(ifp, ifg->ifgl_group->ifg_group);
 1088 
 1089         if_free_sadl(ifp);
 1090 
 1091         /* We should not have any address left at this point. */
 1092         if (!TAILQ_EMPTY(&ifp->if_addrlist)) {
 1093 #ifdef DIAGNOSTIC
 1094                 printf("%s: address list non empty\n", ifp->if_xname);
 1095 #endif
 1096                 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
 1097                         ifa_del(ifp, ifa);
 1098                         ifa->ifa_ifp = NULL;
 1099                         ifafree(ifa);
 1100                 }
 1101         }
 1102 
 1103         KASSERT(TAILQ_EMPTY(&ifp->if_addrhooks));
 1104         KASSERT(TAILQ_EMPTY(&ifp->if_linkstatehooks));
 1105         KASSERT(TAILQ_EMPTY(&ifp->if_detachhooks));
 1106 
 1107 #ifdef INET6
 1108         nd6_ifdetach(ifp);
 1109 #endif
 1110 
 1111         /* Announce that the interface is gone. */
 1112         rtm_ifannounce(ifp, IFAN_DEPARTURE);
 1113         splx(s);
 1114         NET_UNLOCK();
 1115 
 1116         if (ifp->if_counters != NULL)
 1117                 if_counters_free(ifp);
 1118 
 1119         for (i = 0; i < ifp->if_nifqs; i++)
 1120                 ifq_destroy(ifp->if_ifqs[i]);
 1121         if (ifp->if_ifqs != ifp->if_snd.ifq_ifqs) {
 1122                 for (i = 1; i < ifp->if_nifqs; i++) {
 1123                         free(ifp->if_ifqs[i], M_DEVBUF,
 1124                             sizeof(struct ifqueue));
 1125                 }
 1126                 free(ifp->if_ifqs, M_DEVBUF,
 1127                     sizeof(struct ifqueue *) * ifp->if_nifqs);
 1128         }
 1129 
 1130         for (i = 0; i < ifp->if_niqs; i++)
 1131                 ifiq_destroy(ifp->if_iqs[i]);
 1132         if (ifp->if_iqs != ifp->if_rcv.ifiq_ifiqs) {
 1133                 for (i = 1; i < ifp->if_niqs; i++) {
 1134                         free(ifp->if_iqs[i], M_DEVBUF,
 1135                             sizeof(struct ifiqueue));
 1136                 }
 1137                 free(ifp->if_iqs, M_DEVBUF,
 1138                     sizeof(struct ifiqueue *) * ifp->if_niqs);
 1139         }
 1140 }
 1141 
 1142 /*
 1143  * Returns true if ``ifp0'' is connected to the interface with index ``ifidx''.
 1144  */
 1145 int
 1146 if_isconnected(const struct ifnet *ifp0, unsigned int ifidx)
 1147 {
 1148         struct ifnet *ifp;
 1149         int connected = 0;
 1150 
 1151         ifp = if_get(ifidx);
 1152         if (ifp == NULL)
 1153                 return (0);
 1154 
 1155         if (ifp0->if_index == ifp->if_index)
 1156                 connected = 1;
 1157 
 1158 #if NBRIDGE > 0
 1159         if (ifp0->if_bridgeidx != 0 && ifp0->if_bridgeidx == ifp->if_bridgeidx)
 1160                 connected = 1;
 1161 #endif
 1162 #if NCARP > 0
 1163         if ((ifp0->if_type == IFT_CARP &&
 1164             ifp0->if_carpdevidx == ifp->if_index) ||
 1165             (ifp->if_type == IFT_CARP && ifp->if_carpdevidx == ifp0->if_index))
 1166                 connected = 1;
 1167 #endif
 1168 
 1169         if_put(ifp);
 1170         return (connected);
 1171 }
 1172 
 1173 /*
 1174  * Create a clone network interface.
 1175  */
 1176 int
 1177 if_clone_create(const char *name, int rdomain)
 1178 {
 1179         struct if_clone *ifc;
 1180         struct ifnet *ifp;
 1181         int unit, ret;
 1182 
 1183         ifc = if_clone_lookup(name, &unit);
 1184         if (ifc == NULL)
 1185                 return (EINVAL);
 1186 
 1187         rw_enter_write(&if_cloners_lock);
 1188 
 1189         if ((ifp = if_unit(name)) != NULL) {
 1190                 ret = EEXIST;
 1191                 goto unlock;
 1192         }
 1193 
 1194         ret = (*ifc->ifc_create)(ifc, unit);
 1195 
 1196         if (ret != 0 || (ifp = if_unit(name)) == NULL)
 1197                 goto unlock;
 1198 
 1199         NET_LOCK();
 1200         if_addgroup(ifp, ifc->ifc_name);
 1201         if (rdomain != 0)
 1202                 if_setrdomain(ifp, rdomain);
 1203         NET_UNLOCK();
 1204 unlock:
 1205         rw_exit_write(&if_cloners_lock);
 1206         if_put(ifp);
 1207 
 1208         return (ret);
 1209 }
 1210 
 1211 /*
 1212  * Destroy a clone network interface.
 1213  */
 1214 int
 1215 if_clone_destroy(const char *name)
 1216 {
 1217         struct if_clone *ifc;
 1218         struct ifnet *ifp;
 1219         int ret;
 1220 
 1221         ifc = if_clone_lookup(name, NULL);
 1222         if (ifc == NULL)
 1223                 return (EINVAL);
 1224 
 1225         if (ifc->ifc_destroy == NULL)
 1226                 return (EOPNOTSUPP);
 1227 
 1228         rw_enter_write(&if_cloners_lock);
 1229 
 1230         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1231                 if (strcmp(ifp->if_xname, name) == 0)
 1232                         break;
 1233         }
 1234         if (ifp == NULL) {
 1235                 rw_exit_write(&if_cloners_lock);
 1236                 return (ENXIO);
 1237         }
 1238 
 1239         NET_LOCK();
 1240         if (ifp->if_flags & IFF_UP) {
 1241                 int s;
 1242                 s = splnet();
 1243                 if_down(ifp);
 1244                 splx(s);
 1245         }
 1246         NET_UNLOCK();
 1247         ret = (*ifc->ifc_destroy)(ifp);
 1248 
 1249         rw_exit_write(&if_cloners_lock);
 1250 
 1251         return (ret);
 1252 }
 1253 
 1254 /*
 1255  * Look up a network interface cloner.
 1256  */
 1257 struct if_clone *
 1258 if_clone_lookup(const char *name, int *unitp)
 1259 {
 1260         struct if_clone *ifc;
 1261         const char *cp;
 1262         int unit;
 1263 
 1264         /* separate interface name from unit */
 1265         for (cp = name;
 1266             cp - name < IFNAMSIZ && *cp && (*cp < '' || *cp > '9');
 1267             cp++)
 1268                 continue;
 1269 
 1270         if (cp == name || cp - name == IFNAMSIZ || !*cp)
 1271                 return (NULL);  /* No name or unit number */
 1272 
 1273         if (cp - name < IFNAMSIZ-1 && *cp == '' && cp[1] != '\0')
 1274                 return (NULL);  /* unit number 0 padded */
 1275 
 1276         LIST_FOREACH(ifc, &if_cloners, ifc_list) {
 1277                 if (strlen(ifc->ifc_name) == cp - name &&
 1278                     !strncmp(name, ifc->ifc_name, cp - name))
 1279                         break;
 1280         }
 1281 
 1282         if (ifc == NULL)
 1283                 return (NULL);
 1284 
 1285         unit = 0;
 1286         while (cp - name < IFNAMSIZ && *cp) {
 1287                 if (*cp < '' || *cp > '9' ||
 1288                     unit > (INT_MAX - (*cp - '')) / 10) {
 1289                         /* Bogus unit number. */
 1290                         return (NULL);
 1291                 }
 1292                 unit = (unit * 10) + (*cp++ - '');
 1293         }
 1294 
 1295         if (unitp != NULL)
 1296                 *unitp = unit;
 1297         return (ifc);
 1298 }
 1299 
 1300 /*
 1301  * Register a network interface cloner.
 1302  */
 1303 void
 1304 if_clone_attach(struct if_clone *ifc)
 1305 {
 1306         /*
 1307          * we are called at kernel boot by main(), when pseudo devices are
 1308          * being attached. The main() is the only guy which may alter the
 1309          * if_cloners. While system is running and main() is done with
 1310          * initialization, the if_cloners becomes immutable.
 1311          */
 1312         KASSERT(pdevinit_done == 0);
 1313         LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
 1314         if_cloners_count++;
 1315 }
 1316 
 1317 /*
 1318  * Provide list of interface cloners to userspace.
 1319  */
 1320 int
 1321 if_clone_list(struct if_clonereq *ifcr)
 1322 {
 1323         char outbuf[IFNAMSIZ], *dst;
 1324         struct if_clone *ifc;
 1325         int count, error = 0;
 1326 
 1327         if ((dst = ifcr->ifcr_buffer) == NULL) {
 1328                 /* Just asking how many there are. */
 1329                 ifcr->ifcr_total = if_cloners_count;
 1330                 return (0);
 1331         }
 1332 
 1333         if (ifcr->ifcr_count < 0)
 1334                 return (EINVAL);
 1335 
 1336         ifcr->ifcr_total = if_cloners_count;
 1337         count = MIN(if_cloners_count, ifcr->ifcr_count);
 1338 
 1339         LIST_FOREACH(ifc, &if_cloners, ifc_list) {
 1340                 if (count == 0)
 1341                         break;
 1342                 bzero(outbuf, sizeof outbuf);
 1343                 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
 1344                 error = copyout(outbuf, dst, IFNAMSIZ);
 1345                 if (error)
 1346                         break;
 1347                 count--;
 1348                 dst += IFNAMSIZ;
 1349         }
 1350 
 1351         return (error);
 1352 }
 1353 
 1354 /*
 1355  * set queue congestion marker
 1356  */
 1357 void
 1358 if_congestion(void)
 1359 {
 1360         extern int ticks;
 1361 
 1362         ifq_congestion = ticks;
 1363 }
 1364 
 1365 int
 1366 if_congested(void)
 1367 {
 1368         extern int ticks;
 1369         int diff;
 1370 
 1371         diff = ticks - ifq_congestion;
 1372         if (diff < 0) {
 1373                 ifq_congestion = ticks - hz;
 1374                 return (0);
 1375         }
 1376 
 1377         return (diff <= (hz / 100));
 1378 }
 1379 
 1380 #define equal(a1, a2)   \
 1381         (bcmp((caddr_t)(a1), (caddr_t)(a2),     \
 1382         (a1)->sa_len) == 0)
 1383 
 1384 /*
 1385  * Locate an interface based on a complete address.
 1386  */
 1387 struct ifaddr *
 1388 ifa_ifwithaddr(struct sockaddr *addr, u_int rtableid)
 1389 {
 1390         struct ifnet *ifp;
 1391         struct ifaddr *ifa;
 1392         u_int rdomain;
 1393 
 1394         rdomain = rtable_l2(rtableid);
 1395         KERNEL_LOCK();
 1396         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1397                 if (ifp->if_rdomain != rdomain)
 1398                         continue;
 1399 
 1400                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1401                         if (ifa->ifa_addr->sa_family != addr->sa_family)
 1402                                 continue;
 1403 
 1404                         if (equal(addr, ifa->ifa_addr)) {
 1405                                 KERNEL_UNLOCK();
 1406                                 return (ifa);
 1407                         }
 1408                 }
 1409         }
 1410         KERNEL_UNLOCK();
 1411         return (NULL);
 1412 }
 1413 
 1414 /*
 1415  * Locate the point to point interface with a given destination address.
 1416  */
 1417 struct ifaddr *
 1418 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain)
 1419 {
 1420         struct ifnet *ifp;
 1421         struct ifaddr *ifa;
 1422 
 1423         rdomain = rtable_l2(rdomain);
 1424         KERNEL_LOCK();
 1425         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1426                 if (ifp->if_rdomain != rdomain)
 1427                         continue;
 1428                 if (ifp->if_flags & IFF_POINTOPOINT) {
 1429                         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1430                                 if (ifa->ifa_addr->sa_family !=
 1431                                     addr->sa_family || ifa->ifa_dstaddr == NULL)
 1432                                         continue;
 1433                                 if (equal(addr, ifa->ifa_dstaddr)) {
 1434                                         KERNEL_UNLOCK();
 1435                                         return (ifa);
 1436                                 }
 1437                         }
 1438                 }
 1439         }
 1440         KERNEL_UNLOCK();
 1441         return (NULL);
 1442 }
 1443 
 1444 /*
 1445  * Find an interface address specific to an interface best matching
 1446  * a given address.
 1447  */
 1448 struct ifaddr *
 1449 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
 1450 {
 1451         struct ifaddr *ifa;
 1452         char *cp, *cp2, *cp3;
 1453         char *cplim;
 1454         struct ifaddr *ifa_maybe = NULL;
 1455         u_int af = addr->sa_family;
 1456 
 1457         if (af >= AF_MAX)
 1458                 return (NULL);
 1459         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1460                 if (ifa->ifa_addr->sa_family != af)
 1461                         continue;
 1462                 if (ifa_maybe == NULL)
 1463                         ifa_maybe = ifa;
 1464                 if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) {
 1465                         if (equal(addr, ifa->ifa_addr) ||
 1466                             (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
 1467                                 return (ifa);
 1468                         continue;
 1469                 }
 1470                 cp = addr->sa_data;
 1471                 cp2 = ifa->ifa_addr->sa_data;
 1472                 cp3 = ifa->ifa_netmask->sa_data;
 1473                 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
 1474                 for (; cp3 < cplim; cp3++)
 1475                         if ((*cp++ ^ *cp2++) & *cp3)
 1476                                 break;
 1477                 if (cp3 == cplim)
 1478                         return (ifa);
 1479         }
 1480         return (ifa_maybe);
 1481 }
 1482 
 1483 void
 1484 if_rtrequest_dummy(struct ifnet *ifp, int req, struct rtentry *rt)
 1485 {
 1486 }
 1487 
 1488 /*
 1489  * Default action when installing a local route on a point-to-point
 1490  * interface.
 1491  */
 1492 void
 1493 p2p_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
 1494 {
 1495         struct ifnet *lo0ifp;
 1496         struct ifaddr *ifa, *lo0ifa;
 1497 
 1498         switch (req) {
 1499         case RTM_ADD:
 1500                 if (!ISSET(rt->rt_flags, RTF_LOCAL))
 1501                         break;
 1502 
 1503                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 1504                         if (memcmp(rt_key(rt), ifa->ifa_addr,
 1505                             rt_key(rt)->sa_len) == 0)
 1506                                 break;
 1507                 }
 1508 
 1509                 if (ifa == NULL)
 1510                         break;
 1511 
 1512                 KASSERT(ifa == rt->rt_ifa);
 1513 
 1514                 lo0ifp = if_get(rtable_loindex(ifp->if_rdomain));
 1515                 KASSERT(lo0ifp != NULL);
 1516                 TAILQ_FOREACH(lo0ifa, &lo0ifp->if_addrlist, ifa_list) {
 1517                         if (lo0ifa->ifa_addr->sa_family ==
 1518                             ifa->ifa_addr->sa_family)
 1519                                 break;
 1520                 }
 1521                 if_put(lo0ifp);
 1522 
 1523                 if (lo0ifa == NULL)
 1524                         break;
 1525 
 1526                 rt->rt_flags &= ~RTF_LLINFO;
 1527                 break;
 1528         case RTM_DELETE:
 1529         case RTM_RESOLVE:
 1530         default:
 1531                 break;
 1532         }
 1533 }
 1534 
 1535 int
 1536 p2p_bpf_mtap(caddr_t if_bpf, const struct mbuf *m, u_int dir)
 1537 {
 1538 #if NBPFILTER > 0
 1539         return (bpf_mtap_af(if_bpf, m->m_pkthdr.ph_family, m, dir));
 1540 #else
 1541         return (0);
 1542 #endif
 1543 }
 1544 
 1545 void
 1546 p2p_input(struct ifnet *ifp, struct mbuf *m)
 1547 {
 1548         void (*input)(struct ifnet *, struct mbuf *);
 1549 
 1550         switch (m->m_pkthdr.ph_family) {
 1551         case AF_INET:
 1552                 input = ipv4_input;
 1553                 break;
 1554 #ifdef INET6
 1555         case AF_INET6:
 1556                 input = ipv6_input;
 1557                 break;
 1558 #endif
 1559 #ifdef MPLS
 1560         case AF_MPLS:
 1561                 input = mpls_input;
 1562                 break;
 1563 #endif
 1564         default:
 1565                 m_freem(m);
 1566                 return;
 1567         }
 1568 
 1569         (*input)(ifp, m);
 1570 }
 1571 
 1572 /*
 1573  * Bring down all interfaces
 1574  */
 1575 void
 1576 if_downall(void)
 1577 {
 1578         struct ifreq ifrq;      /* XXX only partly built */
 1579         struct ifnet *ifp;
 1580 
 1581         NET_LOCK();
 1582         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1583                 if ((ifp->if_flags & IFF_UP) == 0)
 1584                         continue;
 1585                 if_down(ifp);
 1586                 ifrq.ifr_flags = ifp->if_flags;
 1587                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
 1588         }
 1589         NET_UNLOCK();
 1590 }
 1591 
 1592 /*
 1593  * Mark an interface down and notify protocols of
 1594  * the transition.
 1595  */
 1596 void
 1597 if_down(struct ifnet *ifp)
 1598 {
 1599         NET_ASSERT_LOCKED();
 1600 
 1601         ifp->if_flags &= ~IFF_UP;
 1602         getmicrotime(&ifp->if_lastchange);
 1603         ifq_purge(&ifp->if_snd);
 1604 
 1605         if_linkstate(ifp);
 1606 }
 1607 
 1608 /*
 1609  * Mark an interface up and notify protocols of
 1610  * the transition.
 1611  */
 1612 void
 1613 if_up(struct ifnet *ifp)
 1614 {
 1615         NET_ASSERT_LOCKED();
 1616 
 1617         ifp->if_flags |= IFF_UP;
 1618         getmicrotime(&ifp->if_lastchange);
 1619 
 1620 #ifdef INET6
 1621         /* Userland expects the kernel to set ::1 on default lo(4). */
 1622         if (ifp->if_index == rtable_loindex(ifp->if_rdomain))
 1623                 in6_ifattach(ifp);
 1624 #endif
 1625 
 1626         if_linkstate(ifp);
 1627 }
 1628 
 1629 /*
 1630  * Notify userland, the routing table and hooks owner of
 1631  * a link-state transition.
 1632  */
 1633 void
 1634 if_linkstate_task(void *xifidx)
 1635 {
 1636         unsigned int ifidx = (unsigned long)xifidx;
 1637         struct ifnet *ifp;
 1638 
 1639         KERNEL_LOCK();
 1640         NET_LOCK();
 1641 
 1642         ifp = if_get(ifidx);
 1643         if (ifp != NULL)
 1644                 if_linkstate(ifp);
 1645         if_put(ifp);
 1646 
 1647         NET_UNLOCK();
 1648         KERNEL_UNLOCK();
 1649 }
 1650 
 1651 void
 1652 if_linkstate(struct ifnet *ifp)
 1653 {
 1654         NET_ASSERT_LOCKED();
 1655 
 1656         rtm_ifchg(ifp);
 1657         rt_if_track(ifp);
 1658 
 1659         if_hooks_run(&ifp->if_linkstatehooks);
 1660 }
 1661 
 1662 void
 1663 if_linkstatehook_add(struct ifnet *ifp, struct task *t)
 1664 {
 1665         mtx_enter(&if_hooks_mtx);
 1666         TAILQ_INSERT_HEAD(&ifp->if_linkstatehooks, t, t_entry);
 1667         mtx_leave(&if_hooks_mtx);
 1668 }
 1669 
 1670 void
 1671 if_linkstatehook_del(struct ifnet *ifp, struct task *t)
 1672 {
 1673         mtx_enter(&if_hooks_mtx);
 1674         TAILQ_REMOVE(&ifp->if_linkstatehooks, t, t_entry);
 1675         mtx_leave(&if_hooks_mtx);
 1676 }
 1677 
 1678 /*
 1679  * Schedule a link state change task.
 1680  */
 1681 void
 1682 if_link_state_change(struct ifnet *ifp)
 1683 {
 1684         task_add(net_tq(ifp->if_index), &ifp->if_linkstatetask);
 1685 }
 1686 
 1687 /*
 1688  * Handle interface watchdog timer routine.  Called
 1689  * from softclock, we decrement timer (if set) and
 1690  * call the appropriate interface routine on expiration.
 1691  */
 1692 void
 1693 if_slowtimo(void *arg)
 1694 {
 1695         struct ifnet *ifp = arg;
 1696         int s = splnet();
 1697 
 1698         if (ifp->if_watchdog) {
 1699                 if (ifp->if_timer > 0 && --ifp->if_timer == 0)
 1700                         task_add(net_tq(ifp->if_index), &ifp->if_watchdogtask);
 1701                 timeout_add_sec(&ifp->if_slowtimo, IFNET_SLOWTIMO);
 1702         }
 1703         splx(s);
 1704 }
 1705 
 1706 void
 1707 if_watchdog_task(void *xifidx)
 1708 {
 1709         unsigned int ifidx = (unsigned long)xifidx;
 1710         struct ifnet *ifp;
 1711         int s;
 1712 
 1713         ifp = if_get(ifidx);
 1714         if (ifp == NULL)
 1715                 return;
 1716 
 1717         KERNEL_LOCK();
 1718         s = splnet();
 1719         if (ifp->if_watchdog)
 1720                 (*ifp->if_watchdog)(ifp);
 1721         splx(s);
 1722         KERNEL_UNLOCK();
 1723 
 1724         if_put(ifp);
 1725 }
 1726 
 1727 /*
 1728  * Map interface name to interface structure pointer.
 1729  */
 1730 struct ifnet *
 1731 if_unit(const char *name)
 1732 {
 1733         struct ifnet *ifp;
 1734 
 1735         KERNEL_ASSERT_LOCKED();
 1736 
 1737         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 1738                 if (strcmp(ifp->if_xname, name) == 0) {
 1739                         if_ref(ifp);
 1740                         return (ifp);
 1741                 }
 1742         }
 1743 
 1744         return (NULL);
 1745 }
 1746 
 1747 /*
 1748  * Map interface index to interface structure pointer.
 1749  */
 1750 struct ifnet *
 1751 if_get(unsigned int index)
 1752 {
 1753         struct ifnet **if_map;
 1754         struct ifnet *ifp = NULL;
 1755 
 1756         if (index == 0)
 1757                 return (NULL);
 1758 
 1759         smr_read_enter();
 1760         if_map = SMR_PTR_GET(&if_idxmap.map);
 1761         if (index < if_idxmap_limit(if_map)) {
 1762                 ifp = SMR_PTR_GET(&if_map[index]);
 1763                 if (ifp != NULL) {
 1764                         KASSERT(ifp->if_index == index);
 1765                         if_ref(ifp);
 1766                 }
 1767         }
 1768         smr_read_leave();
 1769 
 1770         return (ifp);
 1771 }
 1772 
 1773 struct ifnet *
 1774 if_ref(struct ifnet *ifp)
 1775 {
 1776         refcnt_take(&ifp->if_refcnt);
 1777 
 1778         return (ifp);
 1779 }
 1780 
 1781 void
 1782 if_put(struct ifnet *ifp)
 1783 {
 1784         if (ifp == NULL)
 1785                 return;
 1786 
 1787         refcnt_rele_wake(&ifp->if_refcnt);
 1788 }
 1789 
 1790 int
 1791 if_setlladdr(struct ifnet *ifp, const uint8_t *lladdr)
 1792 {
 1793         if (ifp->if_sadl == NULL)
 1794                 return (EINVAL);
 1795 
 1796         memcpy(((struct arpcom *)ifp)->ac_enaddr, lladdr, ETHER_ADDR_LEN);
 1797         memcpy(LLADDR(ifp->if_sadl), lladdr, ETHER_ADDR_LEN);
 1798 
 1799         return (0);
 1800 }
 1801 
 1802 int
 1803 if_createrdomain(int rdomain, struct ifnet *ifp)
 1804 {
 1805         int error;
 1806         struct ifnet *loifp;
 1807         char loifname[IFNAMSIZ];
 1808         unsigned int unit = rdomain;
 1809 
 1810         if ((error = rtable_add(rdomain)) != 0)
 1811                 return (error);
 1812         if (!rtable_empty(rdomain))
 1813                 return (EEXIST);
 1814 
 1815         /* Create rdomain including its loopback if with unit == rdomain */
 1816         snprintf(loifname, sizeof(loifname), "lo%u", unit);
 1817         error = if_clone_create(loifname, 0);
 1818         if ((loifp = if_unit(loifname)) == NULL)
 1819                 return (ENXIO);
 1820         if (error && (ifp != loifp || error != EEXIST)) {
 1821                 if_put(loifp);
 1822                 return (error);
 1823         }
 1824 
 1825         rtable_l2set(rdomain, rdomain, loifp->if_index);
 1826         loifp->if_rdomain = rdomain;
 1827         if_put(loifp);
 1828 
 1829         return (0);
 1830 }
 1831 
 1832 int
 1833 if_setrdomain(struct ifnet *ifp, int rdomain)
 1834 {
 1835         struct ifreq ifr;
 1836         int error, up = 0, s;
 1837 
 1838         if (rdomain < 0 || rdomain > RT_TABLEID_MAX)
 1839                 return (EINVAL);
 1840 
 1841         if (rdomain != ifp->if_rdomain &&
 1842             (ifp->if_flags & IFF_LOOPBACK) &&
 1843             (ifp->if_index == rtable_loindex(ifp->if_rdomain)))
 1844                 return (EPERM);
 1845 
 1846         if (!rtable_exists(rdomain))
 1847                 return (ESRCH);
 1848 
 1849         /* make sure that the routing table is a real rdomain */
 1850         if (rdomain != rtable_l2(rdomain))
 1851                 return (EINVAL);
 1852 
 1853         if (rdomain != ifp->if_rdomain) {
 1854                 s = splnet();
 1855                 /*
 1856                  * We are tearing down the world.
 1857                  * Take down the IF so:
 1858                  * 1. everything that cares gets a message
 1859                  * 2. the automagic IPv6 bits are recreated
 1860                  */
 1861                 if (ifp->if_flags & IFF_UP) {
 1862                         up = 1;
 1863                         if_down(ifp);
 1864                 }
 1865                 rti_delete(ifp);
 1866 #ifdef MROUTING
 1867                 vif_delete(ifp);
 1868 #endif
 1869                 in_ifdetach(ifp);
 1870 #ifdef INET6
 1871                 in6_ifdetach(ifp);
 1872 #endif
 1873                 splx(s);
 1874         }
 1875 
 1876         /* Let devices like enc(4) or mpe(4) know about the change */
 1877         ifr.ifr_rdomainid = rdomain;
 1878         if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFRDOMAIN,
 1879             (caddr_t)&ifr)) != ENOTTY)
 1880                 return (error);
 1881         error = 0;
 1882 
 1883         /* Add interface to the specified rdomain */
 1884         ifp->if_rdomain = rdomain;
 1885 
 1886         /* If we took down the IF, bring it back */
 1887         if (up) {
 1888                 s = splnet();
 1889                 if_up(ifp);
 1890                 splx(s);
 1891         }
 1892 
 1893         return (0);
 1894 }
 1895 
 1896 /*
 1897  * Interface ioctls.
 1898  */
 1899 int
 1900 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
 1901 {
 1902         struct ifnet *ifp;
 1903         struct ifreq *ifr = (struct ifreq *)data;
 1904         struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
 1905         struct if_afreq *ifar = (struct if_afreq *)data;
 1906         char ifdescrbuf[IFDESCRSIZE];
 1907         char ifrtlabelbuf[RTLABEL_LEN];
 1908         int s, error = 0, oif_xflags;
 1909         size_t bytesdone;
 1910         unsigned short oif_flags;
 1911 
 1912         switch (cmd) {
 1913         case SIOCIFCREATE:
 1914                 if ((error = suser(p)) != 0)
 1915                         return (error);
 1916                 KERNEL_LOCK();
 1917                 error = if_clone_create(ifr->ifr_name, 0);
 1918                 KERNEL_UNLOCK();
 1919                 return (error);
 1920         case SIOCIFDESTROY:
 1921                 if ((error = suser(p)) != 0)
 1922                         return (error);
 1923                 KERNEL_LOCK();
 1924                 error = if_clone_destroy(ifr->ifr_name);
 1925                 KERNEL_UNLOCK();
 1926                 return (error);
 1927         case SIOCSIFGATTR:
 1928                 if ((error = suser(p)) != 0)
 1929                         return (error);
 1930                 KERNEL_LOCK();
 1931                 NET_LOCK();
 1932                 error = if_setgroupattribs(data);
 1933                 NET_UNLOCK();
 1934                 KERNEL_UNLOCK();
 1935                 return (error);
 1936         case SIOCGIFCONF:
 1937         case SIOCIFGCLONERS:
 1938         case SIOCGIFGMEMB:
 1939         case SIOCGIFGATTR:
 1940         case SIOCGIFGLIST:
 1941         case SIOCGIFFLAGS:
 1942         case SIOCGIFXFLAGS:
 1943         case SIOCGIFMETRIC:
 1944         case SIOCGIFMTU:
 1945         case SIOCGIFHARDMTU:
 1946         case SIOCGIFDATA:
 1947         case SIOCGIFDESCR:
 1948         case SIOCGIFRTLABEL:
 1949         case SIOCGIFPRIORITY:
 1950         case SIOCGIFRDOMAIN:
 1951         case SIOCGIFGROUP:
 1952         case SIOCGIFLLPRIO:
 1953                 error = ifioctl_get(cmd, data);
 1954                 return (error);
 1955         }
 1956 
 1957         KERNEL_LOCK();
 1958 
 1959         ifp = if_unit(ifr->ifr_name);
 1960         if (ifp == NULL) {
 1961                 KERNEL_UNLOCK();
 1962                 return (ENXIO);
 1963         }
 1964         oif_flags = ifp->if_flags;
 1965         oif_xflags = ifp->if_xflags;
 1966 
 1967         switch (cmd) {
 1968         case SIOCIFAFATTACH:
 1969         case SIOCIFAFDETACH:
 1970                 if ((error = suser(p)) != 0)
 1971                         break;
 1972                 NET_LOCK();
 1973                 switch (ifar->ifar_af) {
 1974                 case AF_INET:
 1975                         /* attach is a noop for AF_INET */
 1976                         if (cmd == SIOCIFAFDETACH)
 1977                                 in_ifdetach(ifp);
 1978                         break;
 1979 #ifdef INET6
 1980                 case AF_INET6:
 1981                         if (cmd == SIOCIFAFATTACH)
 1982                                 error = in6_ifattach(ifp);
 1983                         else
 1984                                 in6_ifdetach(ifp);
 1985                         break;
 1986 #endif /* INET6 */
 1987                 default:
 1988                         error = EAFNOSUPPORT;
 1989                 }
 1990                 NET_UNLOCK();
 1991                 break;
 1992 
 1993         case SIOCSIFXFLAGS:
 1994                 if ((error = suser(p)) != 0)
 1995                         break;
 1996 
 1997                 NET_LOCK();
 1998 #ifdef INET6
 1999                 if ((ISSET(ifr->ifr_flags, IFXF_AUTOCONF6) ||
 2000                     ISSET(ifr->ifr_flags, IFXF_AUTOCONF6TEMP)) &&
 2001                     !ISSET(ifp->if_xflags, IFXF_AUTOCONF6) &&
 2002                     !ISSET(ifp->if_xflags, IFXF_AUTOCONF6TEMP)) {
 2003                         error = in6_ifattach(ifp);
 2004                         if (error != 0) {
 2005                                 NET_UNLOCK();
 2006                                 break;
 2007                         }
 2008                 }
 2009 
 2010                 if (ISSET(ifr->ifr_flags, IFXF_INET6_NOSOII) &&
 2011                     !ISSET(ifp->if_xflags, IFXF_INET6_NOSOII))
 2012                         ifp->if_xflags |= IFXF_INET6_NOSOII;
 2013 
 2014                 if (!ISSET(ifr->ifr_flags, IFXF_INET6_NOSOII) &&
 2015                     ISSET(ifp->if_xflags, IFXF_INET6_NOSOII))
 2016                         ifp->if_xflags &= ~IFXF_INET6_NOSOII;
 2017 
 2018 #endif  /* INET6 */
 2019 
 2020 #ifdef MPLS
 2021                 if (ISSET(ifr->ifr_flags, IFXF_MPLS) &&
 2022                     !ISSET(ifp->if_xflags, IFXF_MPLS)) {
 2023                         s = splnet();
 2024                         ifp->if_xflags |= IFXF_MPLS;
 2025                         ifp->if_ll_output = ifp->if_output;
 2026                         ifp->if_output = mpls_output;
 2027                         splx(s);
 2028                 }
 2029                 if (ISSET(ifp->if_xflags, IFXF_MPLS) &&
 2030                     !ISSET(ifr->ifr_flags, IFXF_MPLS)) {
 2031                         s = splnet();
 2032                         ifp->if_xflags &= ~IFXF_MPLS;
 2033                         ifp->if_output = ifp->if_ll_output;
 2034                         ifp->if_ll_output = NULL;
 2035                         splx(s);
 2036                 }
 2037 #endif  /* MPLS */
 2038 
 2039 #ifndef SMALL_KERNEL
 2040                 if (ifp->if_capabilities & IFCAP_WOL) {
 2041                         if (ISSET(ifr->ifr_flags, IFXF_WOL) &&
 2042                             !ISSET(ifp->if_xflags, IFXF_WOL)) {
 2043                                 s = splnet();
 2044                                 ifp->if_xflags |= IFXF_WOL;
 2045                                 error = ifp->if_wol(ifp, 1);
 2046                                 splx(s);
 2047                         }
 2048                         if (ISSET(ifp->if_xflags, IFXF_WOL) &&
 2049                             !ISSET(ifr->ifr_flags, IFXF_WOL)) {
 2050                                 s = splnet();
 2051                                 ifp->if_xflags &= ~IFXF_WOL;
 2052                                 error = ifp->if_wol(ifp, 0);
 2053                                 splx(s);
 2054                         }
 2055                 } else if (ISSET(ifr->ifr_flags, IFXF_WOL)) {
 2056                         ifr->ifr_flags &= ~IFXF_WOL;
 2057                         error = ENOTSUP;
 2058                 }
 2059 
 2060                 if (ISSET(ifp->if_capabilities, IFCAP_TSO) &&
 2061                     ISSET(ifr->ifr_flags, IFXF_TSO) !=
 2062                     ISSET(ifp->if_xflags, IFXF_TSO)) {
 2063                         struct ifreq ifrq;
 2064 
 2065                         s = splnet();
 2066 
 2067                         if (ISSET(ifr->ifr_flags, IFXF_TSO))
 2068                                 ifp->if_xflags |= IFXF_TSO;
 2069                         else
 2070                                 ifp->if_xflags &= ~IFXF_TSO;
 2071 
 2072                         NET_ASSERT_LOCKED();    /* for ioctl */
 2073                         KERNEL_ASSERT_LOCKED(); /* for if_flags */
 2074 
 2075                         if (ISSET(ifp->if_flags, IFF_UP)) {
 2076                                 /* go down for a moment... */
 2077                                 ifp->if_flags &= ~IFF_UP;
 2078                                 ifrq.ifr_flags = ifp->if_flags;
 2079                                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
 2080                                     (caddr_t)&ifrq);
 2081 
 2082                                 /* ... and up again */
 2083                                 ifp->if_flags |= IFF_UP;
 2084                                 ifrq.ifr_flags = ifp->if_flags;
 2085                                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
 2086                                     (caddr_t)&ifrq);
 2087                         }
 2088 
 2089                         splx(s);
 2090                 } else if (!ISSET(ifp->if_capabilities, IFCAP_TSO) &&
 2091                     ISSET(ifr->ifr_flags, IFXF_TSO)) {
 2092                         ifr->ifr_flags &= ~IFXF_TSO;
 2093                         error = ENOTSUP;
 2094                 }
 2095 #endif
 2096 
 2097                 if (error == 0)
 2098                         ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
 2099                                 (ifr->ifr_flags & ~IFXF_CANTCHANGE);
 2100 
 2101                 if (!ISSET(ifp->if_flags, IFF_UP) &&
 2102                     ((!ISSET(oif_xflags, IFXF_AUTOCONF4) &&
 2103                     ISSET(ifp->if_xflags, IFXF_AUTOCONF4)) ||
 2104                     (!ISSET(oif_xflags, IFXF_AUTOCONF6) &&
 2105                     ISSET(ifp->if_xflags, IFXF_AUTOCONF6)) ||
 2106                     (!ISSET(oif_xflags, IFXF_AUTOCONF6TEMP) &&
 2107                     ISSET(ifp->if_xflags, IFXF_AUTOCONF6TEMP)))) {
 2108                         ifr->ifr_flags = ifp->if_flags | IFF_UP;
 2109                         goto forceup;
 2110                 }
 2111 
 2112                 NET_UNLOCK();
 2113                 break;
 2114 
 2115         case SIOCSIFFLAGS:
 2116                 if ((error = suser(p)) != 0)
 2117                         break;
 2118 
 2119                 NET_LOCK();
 2120 forceup:
 2121                 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
 2122                         (ifr->ifr_flags & ~IFF_CANTCHANGE);
 2123                 error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, data);
 2124                 if (error != 0) {
 2125                         ifp->if_flags = oif_flags;
 2126                         if (cmd == SIOCSIFXFLAGS)
 2127                                 ifp->if_xflags = oif_xflags;
 2128                 } else if (ISSET(oif_flags ^ ifp->if_flags, IFF_UP)) {
 2129                         s = splnet();
 2130                         if (ISSET(ifp->if_flags, IFF_UP))
 2131                                 if_up(ifp);
 2132                         else
 2133                                 if_down(ifp);
 2134                         splx(s);
 2135                 }
 2136                 NET_UNLOCK();
 2137                 break;
 2138 
 2139         case SIOCSIFMETRIC:
 2140                 if ((error = suser(p)) != 0)
 2141                         break;
 2142                 NET_LOCK();
 2143                 ifp->if_metric = ifr->ifr_metric;
 2144                 NET_UNLOCK();
 2145                 break;
 2146 
 2147         case SIOCSIFMTU:
 2148                 if ((error = suser(p)) != 0)
 2149                         break;
 2150                 NET_LOCK();
 2151                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 2152                 NET_UNLOCK();
 2153                 if (error == 0)
 2154                         rtm_ifchg(ifp);
 2155                 break;
 2156 
 2157         case SIOCSIFDESCR:
 2158                 if ((error = suser(p)) != 0)
 2159                         break;
 2160                 error = copyinstr(ifr->ifr_data, ifdescrbuf,
 2161                     IFDESCRSIZE, &bytesdone);
 2162                 if (error == 0) {
 2163                         (void)memset(ifp->if_description, 0, IFDESCRSIZE);
 2164                         strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE);
 2165                 }
 2166                 break;
 2167 
 2168         case SIOCSIFRTLABEL:
 2169                 if ((error = suser(p)) != 0)
 2170                         break;
 2171                 error = copyinstr(ifr->ifr_data, ifrtlabelbuf,
 2172                     RTLABEL_LEN, &bytesdone);
 2173                 if (error == 0) {
 2174                         rtlabel_unref(ifp->if_rtlabelid);
 2175                         ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf);
 2176                 }
 2177                 break;
 2178 
 2179         case SIOCSIFPRIORITY:
 2180                 if ((error = suser(p)) != 0)
 2181                         break;
 2182                 if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) {
 2183                         error = EINVAL;
 2184                         break;
 2185                 }
 2186                 ifp->if_priority = ifr->ifr_metric;
 2187                 break;
 2188 
 2189         case SIOCSIFRDOMAIN:
 2190                 if ((error = suser(p)) != 0)
 2191                         break;
 2192                 error = if_createrdomain(ifr->ifr_rdomainid, ifp);
 2193                 if (!error || error == EEXIST) {
 2194                         NET_LOCK();
 2195                         error = if_setrdomain(ifp, ifr->ifr_rdomainid);
 2196                         NET_UNLOCK();
 2197                 }
 2198                 break;
 2199 
 2200         case SIOCAIFGROUP:
 2201                 if ((error = suser(p)))
 2202                         break;
 2203                 NET_LOCK();
 2204                 error = if_addgroup(ifp, ifgr->ifgr_group);
 2205                 if (error == 0) {
 2206                         error = (*ifp->if_ioctl)(ifp, cmd, data);
 2207                         if (error == ENOTTY)
 2208                                 error = 0;
 2209                 }
 2210                 NET_UNLOCK();
 2211                 break;
 2212 
 2213         case SIOCDIFGROUP:
 2214                 if ((error = suser(p)))
 2215                         break;
 2216                 NET_LOCK();
 2217                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 2218                 if (error == ENOTTY)
 2219                         error = 0;
 2220                 if (error == 0)
 2221                         error = if_delgroup(ifp, ifgr->ifgr_group);
 2222                 NET_UNLOCK();
 2223                 break;
 2224 
 2225         case SIOCSIFLLADDR:
 2226                 if ((error = suser(p)))
 2227                         break;
 2228                 if ((ifp->if_sadl == NULL) ||
 2229                     (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) ||
 2230                     (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data))) {
 2231                         error = EINVAL;
 2232                         break;
 2233                 }
 2234                 NET_LOCK();
 2235                 switch (ifp->if_type) {
 2236                 case IFT_ETHER:
 2237                 case IFT_CARP:
 2238                 case IFT_XETHER:
 2239                 case IFT_ISO88025:
 2240                         error = (*ifp->if_ioctl)(ifp, cmd, data);
 2241                         if (error == ENOTTY)
 2242                                 error = 0;
 2243                         if (error == 0)
 2244                                 error = if_setlladdr(ifp,
 2245                                     ifr->ifr_addr.sa_data);
 2246                         break;
 2247                 default:
 2248                         error = ENODEV;
 2249                 }
 2250 
 2251                 if (error == 0)
 2252                         ifnewlladdr(ifp);
 2253                 NET_UNLOCK();
 2254                 if (error == 0)
 2255                         rtm_ifchg(ifp);
 2256                 break;
 2257 
 2258         case SIOCSIFLLPRIO:
 2259                 if ((error = suser(p)))
 2260                         break;
 2261                 if (ifr->ifr_llprio < IFQ_MINPRIO ||
 2262                     ifr->ifr_llprio > IFQ_MAXPRIO) {
 2263                         error = EINVAL;
 2264                         break;
 2265                 }
 2266                 NET_LOCK();
 2267                 ifp->if_llprio = ifr->ifr_llprio;
 2268                 NET_UNLOCK();
 2269                 break;
 2270 
 2271         case SIOCGIFSFFPAGE:
 2272                 error = suser(p);
 2273                 if (error != 0)
 2274                         break;
 2275 
 2276                 error = if_sffpage_check(data);
 2277                 if (error != 0)
 2278                         break;
 2279 
 2280                 /* don't take NET_LOCK because i2c reads take a long time */
 2281                 error = ((*ifp->if_ioctl)(ifp, cmd, data));
 2282                 break;
 2283 
 2284         case SIOCSIFMEDIA:
 2285                 if ((error = suser(p)) != 0)
 2286                         break;
 2287                 /* FALLTHROUGH */
 2288         case SIOCGIFMEDIA:
 2289                 /* net lock is not needed */
 2290                 error = ((*ifp->if_ioctl)(ifp, cmd, data));
 2291                 break;
 2292 
 2293         case SIOCSETKALIVE:
 2294         case SIOCDIFPHYADDR:
 2295         case SIOCSLIFPHYADDR:
 2296         case SIOCSLIFPHYRTABLE:
 2297         case SIOCSLIFPHYTTL:
 2298         case SIOCSLIFPHYDF:
 2299         case SIOCSLIFPHYECN:
 2300         case SIOCADDMULTI:
 2301         case SIOCDELMULTI:
 2302         case SIOCSVNETID:
 2303         case SIOCDVNETID:
 2304         case SIOCSVNETFLOWID:
 2305         case SIOCSTXHPRIO:
 2306         case SIOCSRXHPRIO:
 2307         case SIOCSIFPAIR:
 2308         case SIOCSIFPARENT:
 2309         case SIOCDIFPARENT:
 2310         case SIOCSETMPWCFG:
 2311         case SIOCSETLABEL:
 2312         case SIOCDELLABEL:
 2313         case SIOCSPWE3CTRLWORD:
 2314         case SIOCSPWE3FAT:
 2315         case SIOCSPWE3NEIGHBOR:
 2316         case SIOCDPWE3NEIGHBOR:
 2317 #if NBRIDGE > 0
 2318         case SIOCBRDGADD:
 2319         case SIOCBRDGDEL:
 2320         case SIOCBRDGSIFFLGS:
 2321         case SIOCBRDGSCACHE:
 2322         case SIOCBRDGADDS:
 2323         case SIOCBRDGDELS:
 2324         case SIOCBRDGSADDR:
 2325         case SIOCBRDGSTO:
 2326         case SIOCBRDGDADDR:
 2327         case SIOCBRDGFLUSH:
 2328         case SIOCBRDGADDL:
 2329         case SIOCBRDGSIFPROT:
 2330         case SIOCBRDGARL:
 2331         case SIOCBRDGFRL:
 2332         case SIOCBRDGSPRI:
 2333         case SIOCBRDGSHT:
 2334         case SIOCBRDGSFD:
 2335         case SIOCBRDGSMA:
 2336         case SIOCBRDGSIFPRIO:
 2337         case SIOCBRDGSIFCOST:
 2338         case SIOCBRDGSTXHC:
 2339         case SIOCBRDGSPROTO:
 2340 #endif
 2341                 if ((error = suser(p)) != 0)
 2342                         break;
 2343                 /* FALLTHROUGH */
 2344         default:
 2345                 error = pru_control(so, cmd, data, ifp);
 2346                 if (error != EOPNOTSUPP)
 2347                         break;
 2348                 switch (cmd) {
 2349                 case SIOCAIFADDR:
 2350                 case SIOCDIFADDR:
 2351                 case SIOCSIFADDR:
 2352                 case SIOCSIFNETMASK:
 2353                 case SIOCSIFDSTADDR:
 2354                 case SIOCSIFBRDADDR:
 2355 #ifdef INET6
 2356                 case SIOCAIFADDR_IN6:
 2357                 case SIOCDIFADDR_IN6:
 2358 #endif
 2359                         error = suser(p);
 2360                         break;
 2361                 default:
 2362                         error = 0;
 2363                         break;
 2364                 }
 2365                 if (error)
 2366                         break;
 2367                 NET_LOCK();
 2368                 error = ((*ifp->if_ioctl)(ifp, cmd, data));
 2369                 NET_UNLOCK();
 2370                 break;
 2371         }
 2372 
 2373         if (oif_flags != ifp->if_flags || oif_xflags != ifp->if_xflags) {
 2374                 /* if_up() and if_down() already sent an update, skip here */
 2375                 if (((oif_flags ^ ifp->if_flags) & IFF_UP) == 0)
 2376                         rtm_ifchg(ifp);
 2377         }
 2378 
 2379         if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
 2380                 getmicrotime(&ifp->if_lastchange);
 2381 
 2382         KERNEL_UNLOCK();
 2383 
 2384         if_put(ifp);
 2385 
 2386         return (error);
 2387 }
 2388 
 2389 int
 2390 ifioctl_get(u_long cmd, caddr_t data)
 2391 {
 2392         struct ifnet *ifp;
 2393         struct ifreq *ifr = (struct ifreq *)data;
 2394         char ifdescrbuf[IFDESCRSIZE];
 2395         char ifrtlabelbuf[RTLABEL_LEN];
 2396         int error = 0;
 2397         size_t bytesdone;
 2398         const char *label;
 2399 
 2400         switch(cmd) {
 2401         case SIOCGIFCONF:
 2402                 NET_LOCK_SHARED();
 2403                 error = ifconf(data);
 2404                 NET_UNLOCK_SHARED();
 2405                 return (error);
 2406         case SIOCIFGCLONERS:
 2407                 error = if_clone_list((struct if_clonereq *)data);
 2408                 return (error);
 2409         case SIOCGIFGMEMB:
 2410                 NET_LOCK_SHARED();
 2411                 error = if_getgroupmembers(data);
 2412                 NET_UNLOCK_SHARED();
 2413                 return (error);
 2414         case SIOCGIFGATTR:
 2415                 NET_LOCK_SHARED();
 2416                 error = if_getgroupattribs(data);
 2417                 NET_UNLOCK_SHARED();
 2418                 return (error);
 2419         case SIOCGIFGLIST:
 2420                 NET_LOCK_SHARED();
 2421                 error = if_getgrouplist(data);
 2422                 NET_UNLOCK_SHARED();
 2423                 return (error);
 2424         }
 2425 
 2426         KERNEL_LOCK();
 2427 
 2428         ifp = if_unit(ifr->ifr_name);
 2429         if (ifp == NULL) {
 2430                 KERNEL_UNLOCK();
 2431                 return (ENXIO);
 2432         }
 2433 
 2434         NET_LOCK_SHARED();
 2435 
 2436         switch(cmd) {
 2437         case SIOCGIFFLAGS:
 2438                 ifr->ifr_flags = ifp->if_flags;
 2439                 if (ifq_is_oactive(&ifp->if_snd))
 2440                         ifr->ifr_flags |= IFF_OACTIVE;
 2441                 break;
 2442 
 2443         case SIOCGIFXFLAGS:
 2444                 ifr->ifr_flags = ifp->if_xflags & ~(IFXF_MPSAFE|IFXF_CLONED);
 2445                 break;
 2446 
 2447         case SIOCGIFMETRIC:
 2448                 ifr->ifr_metric = ifp->if_metric;
 2449                 break;
 2450 
 2451         case SIOCGIFMTU:
 2452                 ifr->ifr_mtu = ifp->if_mtu;
 2453                 break;
 2454 
 2455         case SIOCGIFHARDMTU:
 2456                 ifr->ifr_hardmtu = ifp->if_hardmtu;
 2457                 break;
 2458 
 2459         case SIOCGIFDATA: {
 2460                 struct if_data ifdata;
 2461                 if_getdata(ifp, &ifdata);
 2462                 error = copyout(&ifdata, ifr->ifr_data, sizeof(ifdata));
 2463                 break;
 2464         }
 2465 
 2466         case SIOCGIFDESCR:
 2467                 strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
 2468                 error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
 2469                     &bytesdone);
 2470                 break;
 2471 
 2472         case SIOCGIFRTLABEL:
 2473                 if (ifp->if_rtlabelid &&
 2474                     (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
 2475                         strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
 2476                         error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
 2477                             RTLABEL_LEN, &bytesdone);
 2478                 } else
 2479                         error = ENOENT;
 2480                 break;
 2481 
 2482         case SIOCGIFPRIORITY:
 2483                 ifr->ifr_metric = ifp->if_priority;
 2484                 break;
 2485 
 2486         case SIOCGIFRDOMAIN:
 2487                 ifr->ifr_rdomainid = ifp->if_rdomain;
 2488                 break;
 2489 
 2490         case SIOCGIFGROUP:
 2491                 error = if_getgroup(data, ifp);
 2492                 break;
 2493 
 2494         case SIOCGIFLLPRIO:
 2495                 ifr->ifr_llprio = ifp->if_llprio;
 2496                 break;
 2497 
 2498         default:
 2499                 panic("invalid ioctl %lu", cmd);
 2500         }
 2501 
 2502         NET_UNLOCK_SHARED();
 2503 
 2504         KERNEL_UNLOCK();
 2505 
 2506         if_put(ifp);
 2507 
 2508         return (error);
 2509 }
 2510 
 2511 static int
 2512 if_sffpage_check(const caddr_t data)
 2513 {
 2514         const struct if_sffpage *sff = (const struct if_sffpage *)data;
 2515 
 2516         switch (sff->sff_addr) {
 2517         case IFSFF_ADDR_EEPROM:
 2518         case IFSFF_ADDR_DDM:
 2519                 break;
 2520         default:
 2521                 return (EINVAL);
 2522         }
 2523 
 2524         return (0);
 2525 }
 2526 
 2527 int
 2528 if_txhprio_l2_check(int hdrprio)
 2529 {
 2530         switch (hdrprio) {
 2531         case IF_HDRPRIO_PACKET:
 2532                 return (0);
 2533         default:
 2534                 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
 2535                         return (0);
 2536                 break;
 2537         }
 2538 
 2539         return (EINVAL);
 2540 }
 2541 
 2542 int
 2543 if_txhprio_l3_check(int hdrprio)
 2544 {
 2545         switch (hdrprio) {
 2546         case IF_HDRPRIO_PACKET:
 2547         case IF_HDRPRIO_PAYLOAD:
 2548                 return (0);
 2549         default:
 2550                 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
 2551                         return (0);
 2552                 break;
 2553         }
 2554 
 2555         return (EINVAL);
 2556 }
 2557 
 2558 int
 2559 if_rxhprio_l2_check(int hdrprio)
 2560 {
 2561         switch (hdrprio) {
 2562         case IF_HDRPRIO_PACKET:
 2563         case IF_HDRPRIO_OUTER:
 2564                 return (0);
 2565         default:
 2566                 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
 2567                         return (0);
 2568                 break;
 2569         }
 2570 
 2571         return (EINVAL);
 2572 }
 2573 
 2574 int
 2575 if_rxhprio_l3_check(int hdrprio)
 2576 {
 2577         switch (hdrprio) {
 2578         case IF_HDRPRIO_PACKET:
 2579         case IF_HDRPRIO_PAYLOAD:
 2580         case IF_HDRPRIO_OUTER:
 2581                 return (0);
 2582         default:
 2583                 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
 2584                         return (0);
 2585                 break;
 2586         }
 2587 
 2588         return (EINVAL);
 2589 }
 2590 
 2591 /*
 2592  * Return interface configuration
 2593  * of system.  List may be used
 2594  * in later ioctl's (above) to get
 2595  * other information.
 2596  */
 2597 int
 2598 ifconf(caddr_t data)
 2599 {
 2600         struct ifconf *ifc = (struct ifconf *)data;
 2601         struct ifnet *ifp;
 2602         struct ifaddr *ifa;
 2603         struct ifreq ifr, *ifrp;
 2604         int space = ifc->ifc_len, error = 0;
 2605 
 2606         /* If ifc->ifc_len is 0, fill it in with the needed size and return. */
 2607         if (space == 0) {
 2608                 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 2609                         struct sockaddr *sa;
 2610 
 2611                         if (TAILQ_EMPTY(&ifp->if_addrlist))
 2612                                 space += sizeof (ifr);
 2613                         else
 2614                                 TAILQ_FOREACH(ifa,
 2615                                     &ifp->if_addrlist, ifa_list) {
 2616                                         sa = ifa->ifa_addr;
 2617                                         if (sa->sa_len > sizeof(*sa))
 2618                                                 space += sa->sa_len -
 2619                                                     sizeof(*sa);
 2620                                         space += sizeof(ifr);
 2621                                 }
 2622                 }
 2623                 ifc->ifc_len = space;
 2624                 return (0);
 2625         }
 2626 
 2627         ifrp = ifc->ifc_req;
 2628         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 2629                 if (space < sizeof(ifr))
 2630                         break;
 2631                 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
 2632                 if (TAILQ_EMPTY(&ifp->if_addrlist)) {
 2633                         bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
 2634                         error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 2635                             sizeof(ifr));
 2636                         if (error)
 2637                                 break;
 2638                         space -= sizeof (ifr), ifrp++;
 2639                 } else
 2640                         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 2641                                 struct sockaddr *sa = ifa->ifa_addr;
 2642 
 2643                                 if (space < sizeof(ifr))
 2644                                         break;
 2645                                 if (sa->sa_len <= sizeof(*sa)) {
 2646                                         ifr.ifr_addr = *sa;
 2647                                         error = copyout((caddr_t)&ifr,
 2648                                             (caddr_t)ifrp, sizeof (ifr));
 2649                                         ifrp++;
 2650                                 } else {
 2651                                         space -= sa->sa_len - sizeof(*sa);
 2652                                         if (space < sizeof (ifr))
 2653                                                 break;
 2654                                         error = copyout((caddr_t)&ifr,
 2655                                             (caddr_t)ifrp,
 2656                                             sizeof(ifr.ifr_name));
 2657                                         if (error == 0)
 2658                                                 error = copyout((caddr_t)sa,
 2659                                                     (caddr_t)&ifrp->ifr_addr,
 2660                                                     sa->sa_len);
 2661                                         ifrp = (struct ifreq *)(sa->sa_len +
 2662                                             (caddr_t)&ifrp->ifr_addr);
 2663                                 }
 2664                                 if (error)
 2665                                         break;
 2666                                 space -= sizeof (ifr);
 2667                         }
 2668         }
 2669         ifc->ifc_len -= space;
 2670         return (error);
 2671 }
 2672 
 2673 void
 2674 if_counters_alloc(struct ifnet *ifp)
 2675 {
 2676         KASSERT(ifp->if_counters == NULL);
 2677 
 2678         ifp->if_counters = counters_alloc(ifc_ncounters);
 2679 }
 2680 
 2681 void
 2682 if_counters_free(struct ifnet *ifp)
 2683 {
 2684         KASSERT(ifp->if_counters != NULL);
 2685 
 2686         counters_free(ifp->if_counters, ifc_ncounters);
 2687         ifp->if_counters = NULL;
 2688 }
 2689 
 2690 void
 2691 if_getdata(struct ifnet *ifp, struct if_data *data)
 2692 {
 2693         unsigned int i;
 2694 
 2695         *data = ifp->if_data;
 2696 
 2697         if (ifp->if_counters != NULL) {
 2698                 uint64_t counters[ifc_ncounters];
 2699 
 2700                 counters_read(ifp->if_counters, counters, nitems(counters));
 2701 
 2702                 data->ifi_ipackets += counters[ifc_ipackets];
 2703                 data->ifi_ierrors += counters[ifc_ierrors];
 2704                 data->ifi_opackets += counters[ifc_opackets];
 2705                 data->ifi_oerrors += counters[ifc_oerrors];
 2706                 data->ifi_collisions += counters[ifc_collisions];
 2707                 data->ifi_ibytes += counters[ifc_ibytes];
 2708                 data->ifi_obytes += counters[ifc_obytes];
 2709                 data->ifi_imcasts += counters[ifc_imcasts];
 2710                 data->ifi_omcasts += counters[ifc_omcasts];
 2711                 data->ifi_iqdrops += counters[ifc_iqdrops];
 2712                 data->ifi_oqdrops += counters[ifc_oqdrops];
 2713                 data->ifi_noproto += counters[ifc_noproto];
 2714         }
 2715 
 2716         for (i = 0; i < ifp->if_nifqs; i++) {
 2717                 struct ifqueue *ifq = ifp->if_ifqs[i];
 2718 
 2719                 ifq_add_data(ifq, data);
 2720         }
 2721 
 2722         for (i = 0; i < ifp->if_niqs; i++) {
 2723                 struct ifiqueue *ifiq = ifp->if_iqs[i];
 2724 
 2725                 ifiq_add_data(ifiq, data);
 2726         }
 2727 }
 2728 
 2729 /*
 2730  * Dummy functions replaced in ifnet during detach (if protocols decide to
 2731  * fiddle with the if during detach.
 2732  */
 2733 void
 2734 if_detached_qstart(struct ifqueue *ifq)
 2735 {
 2736         ifq_purge(ifq);
 2737 }
 2738 
 2739 int
 2740 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
 2741 {
 2742         return ENODEV;
 2743 }
 2744 
 2745 /*
 2746  * Create interface group without members
 2747  */
 2748 struct ifg_group *
 2749 if_creategroup(const char *groupname)
 2750 {
 2751         struct ifg_group        *ifg;
 2752 
 2753         if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL)
 2754                 return (NULL);
 2755 
 2756         strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
 2757         ifg->ifg_refcnt = 1;
 2758         ifg->ifg_carp_demoted = 0;
 2759         TAILQ_INIT(&ifg->ifg_members);
 2760 #if NPF > 0
 2761         pfi_attach_ifgroup(ifg);
 2762 #endif
 2763         TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next);
 2764 
 2765         return (ifg);
 2766 }
 2767 
 2768 /*
 2769  * Add a group to an interface
 2770  */
 2771 int
 2772 if_addgroup(struct ifnet *ifp, const char *groupname)
 2773 {
 2774         struct ifg_list         *ifgl;
 2775         struct ifg_group        *ifg = NULL;
 2776         struct ifg_member       *ifgm;
 2777         size_t                   namelen;
 2778 
 2779         namelen = strlen(groupname);
 2780         if (namelen == 0 || namelen >= IFNAMSIZ ||
 2781             (groupname[namelen - 1] >= '' && groupname[namelen - 1] <= '9'))
 2782                 return (EINVAL);
 2783 
 2784         TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
 2785                 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
 2786                         return (EEXIST);
 2787 
 2788         if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL)
 2789                 return (ENOMEM);
 2790 
 2791         if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
 2792                 free(ifgl, M_TEMP, sizeof(*ifgl));
 2793                 return (ENOMEM);
 2794         }
 2795 
 2796         TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 2797                 if (!strcmp(ifg->ifg_group, groupname))
 2798                         break;
 2799 
 2800         if (ifg == NULL) {
 2801                 ifg = if_creategroup(groupname);
 2802                 if (ifg == NULL) {
 2803                         free(ifgl, M_TEMP, sizeof(*ifgl));
 2804                         free(ifgm, M_TEMP, sizeof(*ifgm));
 2805                         return (ENOMEM);
 2806                 }
 2807         } else
 2808                 ifg->ifg_refcnt++;
 2809         KASSERT(ifg->ifg_refcnt != 0);
 2810 
 2811         ifgl->ifgl_group = ifg;
 2812         ifgm->ifgm_ifp = ifp;
 2813 
 2814         TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
 2815         TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
 2816 
 2817 #if NPF > 0
 2818         pfi_group_addmember(groupname);
 2819 #endif
 2820 
 2821         return (0);
 2822 }
 2823 
 2824 /*
 2825  * Remove a group from an interface
 2826  */
 2827 int
 2828 if_delgroup(struct ifnet *ifp, const char *groupname)
 2829 {
 2830         struct ifg_list         *ifgl;
 2831         struct ifg_member       *ifgm;
 2832 
 2833         TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
 2834                 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
 2835                         break;
 2836         if (ifgl == NULL)
 2837                 return (ENOENT);
 2838 
 2839         TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
 2840 
 2841         TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
 2842                 if (ifgm->ifgm_ifp == ifp)
 2843                         break;
 2844 
 2845         if (ifgm != NULL) {
 2846                 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
 2847                 free(ifgm, M_TEMP, sizeof(*ifgm));
 2848         }
 2849 
 2850 #if NPF > 0
 2851         pfi_group_delmember(groupname);
 2852 #endif
 2853 
 2854         KASSERT(ifgl->ifgl_group->ifg_refcnt != 0);
 2855         if (--ifgl->ifgl_group->ifg_refcnt == 0) {
 2856                 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
 2857 #if NPF > 0
 2858                 pfi_detach_ifgroup(ifgl->ifgl_group);
 2859 #endif
 2860                 free(ifgl->ifgl_group, M_TEMP, sizeof(*ifgl->ifgl_group));
 2861         }
 2862 
 2863         free(ifgl, M_TEMP, sizeof(*ifgl));
 2864 
 2865         return (0);
 2866 }
 2867 
 2868 /*
 2869  * Stores all groups from an interface in memory pointed
 2870  * to by data
 2871  */
 2872 int
 2873 if_getgroup(caddr_t data, struct ifnet *ifp)
 2874 {
 2875         int                      len, error;
 2876         struct ifg_list         *ifgl;
 2877         struct ifg_req           ifgrq, *ifgp;
 2878         struct ifgroupreq       *ifgr = (struct ifgroupreq *)data;
 2879 
 2880         if (ifgr->ifgr_len == 0) {
 2881                 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
 2882                         ifgr->ifgr_len += sizeof(struct ifg_req);
 2883                 return (0);
 2884         }
 2885 
 2886         len = ifgr->ifgr_len;
 2887         ifgp = ifgr->ifgr_groups;
 2888         TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
 2889                 if (len < sizeof(ifgrq))
 2890                         return (EINVAL);
 2891                 bzero(&ifgrq, sizeof ifgrq);
 2892                 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
 2893                     sizeof(ifgrq.ifgrq_group));
 2894                 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
 2895                     sizeof(struct ifg_req))))
 2896                         return (error);
 2897                 len -= sizeof(ifgrq);
 2898                 ifgp++;
 2899         }
 2900 
 2901         return (0);
 2902 }
 2903 
 2904 /*
 2905  * Stores all members of a group in memory pointed to by data
 2906  */
 2907 int
 2908 if_getgroupmembers(caddr_t data)
 2909 {
 2910         struct ifgroupreq       *ifgr = (struct ifgroupreq *)data;
 2911         struct ifg_group        *ifg;
 2912         struct ifg_member       *ifgm;
 2913         struct ifg_req           ifgrq, *ifgp;
 2914         int                      len, error;
 2915 
 2916         TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 2917                 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
 2918                         break;
 2919         if (ifg == NULL)
 2920                 return (ENOENT);
 2921 
 2922         if (ifgr->ifgr_len == 0) {
 2923                 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
 2924                         ifgr->ifgr_len += sizeof(ifgrq);
 2925                 return (0);
 2926         }
 2927 
 2928         len = ifgr->ifgr_len;
 2929         ifgp = ifgr->ifgr_groups;
 2930         TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
 2931                 if (len < sizeof(ifgrq))
 2932                         return (EINVAL);
 2933                 bzero(&ifgrq, sizeof ifgrq);
 2934                 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
 2935                     sizeof(ifgrq.ifgrq_member));
 2936                 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
 2937                     sizeof(struct ifg_req))))
 2938                         return (error);
 2939                 len -= sizeof(ifgrq);
 2940                 ifgp++;
 2941         }
 2942 
 2943         return (0);
 2944 }
 2945 
 2946 int
 2947 if_getgroupattribs(caddr_t data)
 2948 {
 2949         struct ifgroupreq       *ifgr = (struct ifgroupreq *)data;
 2950         struct ifg_group        *ifg;
 2951 
 2952         TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 2953                 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
 2954                         break;
 2955         if (ifg == NULL)
 2956                 return (ENOENT);
 2957 
 2958         ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted;
 2959 
 2960         return (0);
 2961 }
 2962 
 2963 int
 2964 if_setgroupattribs(caddr_t data)
 2965 {
 2966         struct ifgroupreq       *ifgr = (struct ifgroupreq *)data;
 2967         struct ifg_group        *ifg;
 2968         struct ifg_member       *ifgm;
 2969         int                      demote;
 2970 
 2971         TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 2972                 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
 2973                         break;
 2974         if (ifg == NULL)
 2975                 return (ENOENT);
 2976 
 2977         demote = ifgr->ifgr_attrib.ifg_carp_demoted;
 2978         if (demote + ifg->ifg_carp_demoted > 0xff ||
 2979             demote + ifg->ifg_carp_demoted < 0)
 2980                 return (EINVAL);
 2981 
 2982         ifg->ifg_carp_demoted += demote;
 2983 
 2984         TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
 2985                 ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, SIOCSIFGATTR, data);
 2986 
 2987         return (0);
 2988 }
 2989 
 2990 /*
 2991  * Stores all groups in memory pointed to by data
 2992  */
 2993 int
 2994 if_getgrouplist(caddr_t data)
 2995 {
 2996         struct ifgroupreq       *ifgr = (struct ifgroupreq *)data;
 2997         struct ifg_group        *ifg;
 2998         struct ifg_req           ifgrq, *ifgp;
 2999         int                      len, error;
 3000 
 3001         if (ifgr->ifgr_len == 0) {
 3002                 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 3003                         ifgr->ifgr_len += sizeof(ifgrq);
 3004                 return (0);
 3005         }
 3006 
 3007         len = ifgr->ifgr_len;
 3008         ifgp = ifgr->ifgr_groups;
 3009         TAILQ_FOREACH(ifg, &ifg_head, ifg_next) {
 3010                 if (len < sizeof(ifgrq))
 3011                         return (EINVAL);
 3012                 bzero(&ifgrq, sizeof ifgrq);
 3013                 strlcpy(ifgrq.ifgrq_group, ifg->ifg_group,
 3014                     sizeof(ifgrq.ifgrq_group));
 3015                 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
 3016                     sizeof(struct ifg_req))))
 3017                         return (error);
 3018                 len -= sizeof(ifgrq);
 3019                 ifgp++;
 3020         }
 3021 
 3022         return (0);
 3023 }
 3024 
 3025 void
 3026 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask)
 3027 {
 3028         switch (dst->sa_family) {
 3029         case AF_INET:
 3030                 if (satosin(dst)->sin_addr.s_addr == INADDR_ANY &&
 3031                     mask && (mask->sa_len == 0 ||
 3032                     satosin(mask)->sin_addr.s_addr == INADDR_ANY))
 3033                         if_group_egress_build();
 3034                 break;
 3035 #ifdef INET6
 3036         case AF_INET6:
 3037                 if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr,
 3038                     &in6addr_any) && mask && (mask->sa_len == 0 ||
 3039                     IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr,
 3040                     &in6addr_any)))
 3041                         if_group_egress_build();
 3042                 break;
 3043 #endif
 3044         }
 3045 }
 3046 
 3047 int
 3048 if_group_egress_build(void)
 3049 {
 3050         struct ifnet            *ifp;
 3051         struct ifg_group        *ifg;
 3052         struct ifg_member       *ifgm, *next;
 3053         struct sockaddr_in       sa_in;
 3054 #ifdef INET6
 3055         struct sockaddr_in6      sa_in6;
 3056 #endif
 3057         struct rtentry          *rt;
 3058 
 3059         TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
 3060                 if (!strcmp(ifg->ifg_group, IFG_EGRESS))
 3061                         break;
 3062 
 3063         if (ifg != NULL)
 3064                 TAILQ_FOREACH_SAFE(ifgm, &ifg->ifg_members, ifgm_next, next)
 3065                         if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS);
 3066 
 3067         bzero(&sa_in, sizeof(sa_in));
 3068         sa_in.sin_len = sizeof(sa_in);
 3069         sa_in.sin_family = AF_INET;
 3070         rt = rtable_lookup(0, sintosa(&sa_in), sintosa(&sa_in), NULL, RTP_ANY);
 3071         while (rt != NULL) {
 3072                 ifp = if_get(rt->rt_ifidx);
 3073                 if (ifp != NULL) {
 3074                         if_addgroup(ifp, IFG_EGRESS);
 3075                         if_put(ifp);
 3076                 }
 3077                 rt = rtable_iterate(rt);
 3078         }
 3079 
 3080 #ifdef INET6
 3081         bcopy(&sa6_any, &sa_in6, sizeof(sa_in6));
 3082         rt = rtable_lookup(0, sin6tosa(&sa_in6), sin6tosa(&sa_in6), NULL,
 3083             RTP_ANY);
 3084         while (rt != NULL) {
 3085                 ifp = if_get(rt->rt_ifidx);
 3086                 if (ifp != NULL) {
 3087                         if_addgroup(ifp, IFG_EGRESS);
 3088                         if_put(ifp);
 3089                 }
 3090                 rt = rtable_iterate(rt);
 3091         }
 3092 #endif /* INET6 */
 3093 
 3094         return (0);
 3095 }
 3096 
 3097 /*
 3098  * Set/clear promiscuous mode on interface ifp based on the truth value
 3099  * of pswitch.  The calls are reference counted so that only the first
 3100  * "on" request actually has an effect, as does the final "off" request.
 3101  * Results are undefined if the "off" and "on" requests are not matched.
 3102  */
 3103 int
 3104 ifpromisc(struct ifnet *ifp, int pswitch)
 3105 {
 3106         struct ifreq ifr;
 3107         unsigned short oif_flags;
 3108         int oif_pcount, error;
 3109 
 3110         NET_ASSERT_LOCKED(); /* modifying if_flags and if_pcount */
 3111 
 3112         oif_flags = ifp->if_flags;
 3113         oif_pcount = ifp->if_pcount;
 3114         if (pswitch) {
 3115                 if (ifp->if_pcount++ != 0)
 3116                         return (0);
 3117                 ifp->if_flags |= IFF_PROMISC;
 3118         } else {
 3119                 if (--ifp->if_pcount > 0)
 3120                         return (0);
 3121                 ifp->if_flags &= ~IFF_PROMISC;
 3122         }
 3123 
 3124         if ((ifp->if_flags & IFF_UP) == 0)
 3125                 return (0);
 3126 
 3127         memset(&ifr, 0, sizeof(ifr));
 3128         ifr.ifr_flags = ifp->if_flags;
 3129         error = ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
 3130         if (error) {
 3131                 ifp->if_flags = oif_flags;
 3132                 ifp->if_pcount = oif_pcount;
 3133         }
 3134 
 3135         return (error);
 3136 }
 3137 
 3138 void
 3139 ifa_add(struct ifnet *ifp, struct ifaddr *ifa)
 3140 {
 3141         TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
 3142 }
 3143 
 3144 void
 3145 ifa_del(struct ifnet *ifp, struct ifaddr *ifa)
 3146 {
 3147         TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
 3148 }
 3149 
 3150 void
 3151 ifa_update_broadaddr(struct ifnet *ifp, struct ifaddr *ifa, struct sockaddr *sa)
 3152 {
 3153         if (ifa->ifa_broadaddr->sa_len != sa->sa_len)
 3154                 panic("ifa_update_broadaddr does not support dynamic length");
 3155         bcopy(sa, ifa->ifa_broadaddr, sa->sa_len);
 3156 }
 3157 
 3158 #ifdef DDB
 3159 /* debug function, can be called from ddb> */
 3160 void
 3161 ifa_print_all(void)
 3162 {
 3163         struct ifnet *ifp;
 3164         struct ifaddr *ifa;
 3165 
 3166         TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
 3167                 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
 3168                         char addr[INET6_ADDRSTRLEN];
 3169 
 3170                         switch (ifa->ifa_addr->sa_family) {
 3171                         case AF_INET:
 3172                                 printf("%s", inet_ntop(AF_INET,
 3173                                     &satosin(ifa->ifa_addr)->sin_addr,
 3174                                     addr, sizeof(addr)));
 3175                                 break;
 3176 #ifdef INET6
 3177                         case AF_INET6:
 3178                                 printf("%s", inet_ntop(AF_INET6,
 3179                                     &(satosin6(ifa->ifa_addr))->sin6_addr,
 3180                                     addr, sizeof(addr)));
 3181                                 break;
 3182 #endif
 3183                         }
 3184                         printf(" on %s\n", ifp->if_xname);
 3185                 }
 3186         }
 3187 }
 3188 #endif /* DDB */
 3189 
 3190 void
 3191 ifnewlladdr(struct ifnet *ifp)
 3192 {
 3193 #ifdef INET6
 3194         struct ifaddr *ifa;
 3195 #endif
 3196         struct ifreq ifrq;
 3197         short up;
 3198 
 3199         NET_ASSERT_LOCKED();    /* for ioctl and in6 */
 3200         KERNEL_ASSERT_LOCKED(); /* for if_flags */
 3201 
 3202         up = ifp->if_flags & IFF_UP;
 3203 
 3204         if (up) {
 3205                 /* go down for a moment... */
 3206                 ifp->if_flags &= ~IFF_UP;
 3207                 ifrq.ifr_flags = ifp->if_flags;
 3208                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
 3209         }
 3210 
 3211         ifp->if_flags |= IFF_UP;
 3212         ifrq.ifr_flags = ifp->if_flags;
 3213         (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
 3214 
 3215 #ifdef INET6
 3216         /*
 3217          * Update the link-local address.  Don't do it if we're
 3218          * a router to avoid confusing hosts on the network.
 3219          */
 3220         if (!ip6_forwarding) {
 3221                 ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
 3222                 if (ifa) {
 3223                         in6_purgeaddr(ifa);
 3224                         if_hooks_run(&ifp->if_addrhooks);
 3225                         in6_ifattach(ifp);
 3226                 }
 3227         }
 3228 #endif
 3229         if (!up) {
 3230                 /* go back down */
 3231                 ifp->if_flags &= ~IFF_UP;
 3232                 ifrq.ifr_flags = ifp->if_flags;
 3233                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
 3234         }
 3235 }
 3236 
 3237 void
 3238 if_addrhook_add(struct ifnet *ifp, struct task *t)
 3239 {
 3240         mtx_enter(&if_hooks_mtx);
 3241         TAILQ_INSERT_TAIL(&ifp->if_addrhooks, t, t_entry);
 3242         mtx_leave(&if_hooks_mtx);
 3243 }
 3244 
 3245 void
 3246 if_addrhook_del(struct ifnet *ifp, struct task *t)
 3247 {
 3248         mtx_enter(&if_hooks_mtx);
 3249         TAILQ_REMOVE(&ifp->if_addrhooks, t, t_entry);
 3250         mtx_leave(&if_hooks_mtx);
 3251 }
 3252 
 3253 void
 3254 if_addrhooks_run(struct ifnet *ifp)
 3255 {
 3256         if_hooks_run(&ifp->if_addrhooks);
 3257 }
 3258 
 3259 void
 3260 if_rxr_init(struct if_rxring *rxr, u_int lwm, u_int hwm)
 3261 {
 3262         extern int ticks;
 3263 
 3264         memset(rxr, 0, sizeof(*rxr));
 3265 
 3266         rxr->rxr_adjusted = ticks;
 3267         rxr->rxr_cwm = rxr->rxr_lwm = lwm;
 3268         rxr->rxr_hwm = hwm;
 3269 }
 3270 
 3271 static inline void
 3272 if_rxr_adjust_cwm(struct if_rxring *rxr)
 3273 {
 3274         extern int ticks;
 3275 
 3276         if (rxr->rxr_alive >= rxr->rxr_lwm)
 3277                 return;
 3278         else if (rxr->rxr_cwm < rxr->rxr_hwm)
 3279                 rxr->rxr_cwm++;
 3280 
 3281         rxr->rxr_adjusted = ticks;
 3282 }
 3283 
 3284 void
 3285 if_rxr_livelocked(struct if_rxring *rxr)
 3286 {
 3287         extern int ticks;
 3288 
 3289         if (ticks - rxr->rxr_adjusted >= 1) {
 3290                 if (rxr->rxr_cwm > rxr->rxr_lwm)
 3291                         rxr->rxr_cwm--;
 3292 
 3293                 rxr->rxr_adjusted = ticks;
 3294         }
 3295 }
 3296 
 3297 u_int
 3298 if_rxr_get(struct if_rxring *rxr, u_int max)
 3299 {
 3300         extern int ticks;
 3301         u_int diff;
 3302 
 3303         if (ticks - rxr->rxr_adjusted >= 1) {
 3304                 /* we're free to try for an adjustment */
 3305                 if_rxr_adjust_cwm(rxr);
 3306         }
 3307 
 3308         if (rxr->rxr_alive >= rxr->rxr_cwm)
 3309                 return (0);
 3310 
 3311         diff = min(rxr->rxr_cwm - rxr->rxr_alive, max);
 3312         rxr->rxr_alive += diff;
 3313 
 3314         return (diff);
 3315 }
 3316 
 3317 int
 3318 if_rxr_info_ioctl(struct if_rxrinfo *uifri, u_int t, struct if_rxring_info *e)
 3319 {
 3320         struct if_rxrinfo kifri;
 3321         int error;
 3322         u_int n;
 3323 
 3324         error = copyin(uifri, &kifri, sizeof(kifri));
 3325         if (error)
 3326                 return (error);
 3327 
 3328         n = min(t, kifri.ifri_total);
 3329         kifri.ifri_total = t;
 3330 
 3331         if (n > 0) {
 3332                 error = copyout(e, kifri.ifri_entries, sizeof(*e) * n);
 3333                 if (error)
 3334                         return (error);
 3335         }
 3336 
 3337         return (copyout(&kifri, uifri, sizeof(kifri)));
 3338 }
 3339 
 3340 int
 3341 if_rxr_ioctl(struct if_rxrinfo *ifri, const char *name, u_int size,
 3342     struct if_rxring *rxr)
 3343 {
 3344         struct if_rxring_info ifr;
 3345 
 3346         memset(&ifr, 0, sizeof(ifr));
 3347 
 3348         if (name != NULL)
 3349                 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 3350 
 3351         ifr.ifr_size = size;
 3352         ifr.ifr_info = *rxr;
 3353 
 3354         return (if_rxr_info_ioctl(ifri, 1, &ifr));
 3355 }
 3356 
 3357 /*
 3358  * Network stack input queues.
 3359  */
 3360 
 3361 void
 3362 niq_init(struct niqueue *niq, u_int maxlen, u_int isr)
 3363 {
 3364         mq_init(&niq->ni_q, maxlen, IPL_NET);
 3365         niq->ni_isr = isr;
 3366 }
 3367 
 3368 int
 3369 niq_enqueue(struct niqueue *niq, struct mbuf *m)
 3370 {
 3371         int rv;
 3372 
 3373         rv = mq_enqueue(&niq->ni_q, m);
 3374         if (rv == 0)
 3375                 schednetisr(niq->ni_isr);
 3376         else
 3377                 if_congestion();
 3378 
 3379         return (rv);
 3380 }
 3381 
 3382 int
 3383 niq_enlist(struct niqueue *niq, struct mbuf_list *ml)
 3384 {
 3385         int rv;
 3386 
 3387         rv = mq_enlist(&niq->ni_q, ml);
 3388         if (rv == 0)
 3389                 schednetisr(niq->ni_isr);
 3390         else
 3391                 if_congestion();
 3392 
 3393         return (rv);
 3394 }
 3395 
 3396 __dead void
 3397 unhandled_af(int af)
 3398 {
 3399         panic("unhandled af %d", af);
 3400 }
 3401 
 3402 struct taskq *
 3403 net_tq(unsigned int ifindex)
 3404 {
 3405         struct taskq *t = NULL;
 3406         static int nettaskqs;
 3407 
 3408         if (nettaskqs == 0)
 3409                 nettaskqs = min(NET_TASKQ, ncpus);
 3410 
 3411         t = nettqmp[ifindex % nettaskqs];
 3412 
 3413         return (t);
 3414 }

Cache object: 87cefc890a38912d68c23b5e0bd921f3


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