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

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

    1 /*      $NetBSD: if.h,v 1.304 2022/11/25 08:39:32 knakahara Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by William Studenmund and Jason R. Thorpe.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1982, 1986, 1989, 1993
   34  *      The Regents of the University of California.  All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. Neither the name of the University nor the names of its contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   58  * SUCH DAMAGE.
   59  *
   60  *      @(#)if.h        8.3 (Berkeley) 2/9/95
   61  */
   62 
   63 #ifndef _NET_IF_H_
   64 #define _NET_IF_H_
   65 
   66 #if !defined(_KERNEL) && !defined(_STANDALONE)
   67 #include <stdbool.h>
   68 #endif
   69 
   70 #include <sys/featuretest.h>
   71 
   72 /*
   73  * Length of interface external name, including terminating '\0'.
   74  * Note: this is the same size as a generic device's external name.
   75  */
   76 #define IF_NAMESIZE 16
   77 
   78 /*
   79  * Length of interface description, including terminating '\0'.
   80  */
   81 #define IFDESCRSIZE     64
   82 
   83 #if defined(_NETBSD_SOURCE)
   84 
   85 #include <sys/socket.h>
   86 #include <sys/queue.h>
   87 #include <sys/mutex.h>
   88 #include <sys/hook.h>
   89 
   90 #include <net/dlt.h>
   91 #include <net/pfil.h>
   92 #ifdef _KERNEL
   93 #include <net/pktqueue.h>
   94 #include <sys/pslist.h>
   95 #include <sys/pserialize.h>
   96 #include <sys/psref.h>
   97 #include <sys/module_hook.h>
   98 #endif
   99 
  100 /*
  101  * Always include ALTQ glue here -- we use the ALTQ interface queue
  102  * structure even when ALTQ is not configured into the kernel so that
  103  * the size of struct ifnet does not changed based on the option.  The
  104  * ALTQ queue structure is API-compatible with the legacy ifqueue.
  105  */
  106 #include <altq/if_altq.h>
  107 
  108 /*
  109  * Structures defining a network interface, providing a packet
  110  * transport mechanism (ala level 0 of the PUP protocols).
  111  *
  112  * Each interface accepts output datagrams of a specified maximum
  113  * length, and provides higher level routines with input datagrams
  114  * received from its medium.
  115  *
  116  * Output occurs when the routine if_output is called, with four parameters:
  117  *      (*ifp->if_output)(ifp, m, dst, rt)
  118  * Here m is the mbuf chain to be sent and dst is the destination address.
  119  * The output routine encapsulates the supplied datagram if necessary,
  120  * and then transmits it on its medium.
  121  *
  122  * On input, each interface unwraps the data received by it, and either
  123  * places it on the input queue of a internetwork datagram routine
  124  * and posts the associated software interrupt, or passes the datagram to a raw
  125  * packet input routine.
  126  *
  127  * Routines exist for locating interfaces by their addresses
  128  * or for locating a interface on a certain network, as well as more general
  129  * routing and gateway routines maintaining information used to locate
  130  * interfaces.  These routines live in the files if.c and route.c
  131  */
  132 #include <sys/time.h>
  133 
  134 #if defined(_KERNEL_OPT)
  135 #include "opt_compat_netbsd.h"
  136 #include "opt_gateway.h"
  137 #endif
  138 
  139 struct mbuf;
  140 struct proc;
  141 struct rtentry;
  142 struct socket;
  143 struct ether_header;
  144 struct ifaddr;
  145 struct ifnet;
  146 struct rt_addrinfo;
  147 
  148 #define IFNAMSIZ        IF_NAMESIZE
  149 
  150 /*
  151  * Structure describing a `cloning' interface.
  152  */
  153 struct if_clone {
  154         LIST_ENTRY(if_clone) ifc_list;  /* on list of cloners */
  155         const char *ifc_name;           /* name of device, e.g. `gif' */
  156         size_t ifc_namelen;             /* length of name */
  157 
  158         int     (*ifc_create)(struct if_clone *, int);
  159         int     (*ifc_destroy)(struct ifnet *);
  160 };
  161 
  162 #define IF_CLONE_INITIALIZER(name, create, destroy)                     \
  163         { { NULL, NULL }, name, sizeof(name) - 1, create, destroy }
  164 
  165 /*
  166  * Structure used to query names of interface cloners.
  167  */
  168 struct if_clonereq {
  169         int     ifcr_total;             /* total cloners (out) */
  170         int     ifcr_count;             /* room for this many in user buffer */
  171         char    *ifcr_buffer;           /* buffer for cloner names */
  172 };
  173 
  174 /*
  175  * Structure defining statistics and other data kept regarding a network
  176  * interface.
  177  *
  178  * Only used for exporting data from the interface.
  179  */
  180 struct if_data {
  181         /* generic interface information */
  182         u_char  ifi_type;               /* ethernet, tokenring, etc. */
  183         u_char  ifi_addrlen;            /* media address length */
  184         u_char  ifi_hdrlen;             /* media header length */
  185         int     ifi_link_state;         /* current link state */
  186         uint64_t ifi_mtu;               /* maximum transmission unit */
  187         uint64_t ifi_metric;            /* routing metric (external only) */
  188         uint64_t ifi_baudrate;          /* linespeed */
  189         /* volatile statistics */
  190         uint64_t ifi_ipackets;          /* packets received on interface */
  191         uint64_t ifi_ierrors;           /* input errors on interface */
  192         uint64_t ifi_opackets;          /* packets sent on interface */
  193         uint64_t ifi_oerrors;           /* output errors on interface */
  194         uint64_t ifi_collisions;        /* collisions on csma interfaces */
  195         uint64_t ifi_ibytes;            /* total number of octets received */
  196         uint64_t ifi_obytes;            /* total number of octets sent */
  197         uint64_t ifi_imcasts;           /* packets received via multicast */
  198         uint64_t ifi_omcasts;           /* packets sent via multicast */
  199         uint64_t ifi_iqdrops;           /* dropped on input, this interface */
  200         uint64_t ifi_noproto;           /* destined for unsupported protocol */
  201         struct  timespec ifi_lastchange;/* last operational state change */
  202 };
  203 
  204 /*
  205  * Values for if_link_state.
  206  */
  207 #define LINK_STATE_UNKNOWN      0       /* link invalid/unknown */
  208 #define LINK_STATE_DOWN         1       /* link is down */
  209 #define LINK_STATE_UP           2       /* link is up */
  210 
  211 /*
  212  * Status bit descriptions for the various interface types.
  213  */
  214 struct if_status_description {
  215         unsigned char   ifs_type;
  216         unsigned char   ifs_state;
  217         const char      *ifs_string;
  218 };
  219 
  220 #define LINK_STATE_DESC_MATCH(_ifs, _t, _s)                             \
  221         (((_ifs)->ifs_type == (_t) || (_ifs)->ifs_type == 0) &&         \
  222             (_ifs)->ifs_state == (_s))
  223 
  224 #define LINK_STATE_DESCRIPTIONS {                                       \
  225         { IFT_ETHER, LINK_STATE_DOWN, "no carrier" },                   \
  226         { IFT_IEEE80211, LINK_STATE_DOWN, "no network" },               \
  227         { IFT_PPP, LINK_STATE_DOWN, "no carrier" },                     \
  228         { IFT_CARP, LINK_STATE_DOWN, "backup" },                        \
  229         { IFT_CARP, LINK_STATE_UP, "master" },                          \
  230         { 0, LINK_STATE_UP, "active" },                                 \
  231         { 0, LINK_STATE_UNKNOWN, "unknown" },                           \
  232         { 0, LINK_STATE_DOWN, "down" },                                 \
  233         { 0, 0, NULL }                                                  \
  234 }
  235 
  236 /*
  237  * Structure defining a queue for a network interface.
  238  */
  239 struct ifqueue {
  240         struct          mbuf *ifq_head;
  241         struct          mbuf *ifq_tail;
  242         int             ifq_len;
  243         int             ifq_maxlen;
  244         uint64_t        ifq_drops;
  245         kmutex_t        *ifq_lock;
  246 };
  247 
  248 #ifdef _KERNEL
  249 #include <sys/percpu.h>
  250 #include <sys/callout.h>
  251 #include <sys/rwlock.h>
  252 #include <sys/workqueue.h>
  253 
  254 #endif /* _KERNEL */
  255 
  256 /*
  257  * Structure defining a queue for a network interface.
  258  *
  259  * (Would like to call this struct ``if'', but C isn't PL/1.)
  260  */
  261 TAILQ_HEAD(ifnet_head, ifnet);          /* the actual queue head */
  262 
  263 struct bridge_softc;
  264 struct bridge_iflist;
  265 struct callout;
  266 struct krwlock;
  267 struct if_percpuq;
  268 struct if_deferred_start;
  269 struct in6_multi;
  270 
  271 typedef unsigned short if_index_t;
  272 
  273 /*
  274  * Interface.  Field markings and the corresponding locks:
  275  *
  276  * i:   IFNET_LOCK (a.k.a., if_ioctl_lock)
  277  * q:   ifq_lock (struct ifaltq)
  278  * a:   if_afdata_lock
  279  * 6:   in6_multilock (global lock)
  280  * ::   unlocked, stable
  281  * ?:   unknown, maybe unsafe
  282  *
  283  * Lock order: IFNET_LOCK => in6_multilock => if_afdata_lock => ifq_lock
  284  *   Note that currently if_afdata_lock and ifq_lock aren't held
  285  *   at the same time, but define the order anyway.
  286  *
  287  * Lock order of IFNET_LOCK with other locks:
  288  *     softnet_lock => solock => IFNET_LOCK => ND6_LOCK, in_multilock
  289  */
  290 typedef struct ifnet {
  291         void            *if_softc;      /* :: lower-level data for this if */
  292         /* DEPRECATED. Keep it to avoid breaking kvm(3) users */
  293         TAILQ_ENTRY(ifnet)
  294                         if_list;        /* i: all struct ifnets are chained */
  295         TAILQ_HEAD(, ifaddr)
  296                         if_addrlist;    /* i: linked list of addresses per if */
  297         char            if_xname[IFNAMSIZ];
  298                                         /* :: external name (name + unit) */
  299         int             if_pcount;      /* i: number of promiscuous listeners */
  300         struct bpf_if   *if_bpf;        /* :: packet filter structure */
  301         if_index_t      if_index;       /* :: numeric abbreviation for this if */
  302         short           if_timer;       /* ?: time 'til if_slowtimo called */
  303         unsigned short  if_flags;       /* i: up/down, broadcast, etc. */
  304         short           if_extflags;    /* :: if_output MP-safe, etc. */
  305         u_char          if_type;        /* :: ethernet, tokenring, etc. */
  306         u_char          if_addrlen;     /* :: media address length */
  307         u_char          if_hdrlen;      /* :: media header length */
  308         /* XXX audit :? fields here. */
  309         int             if_link_state;  /* :? current link state */
  310         uint64_t        if_mtu;         /* :? maximum transmission unit */
  311         uint64_t        if_metric;      /* :? routing metric (external only) */
  312         uint64_t        if_baudrate;    /* :? linespeed */
  313         struct timespec if_lastchange;  /* :? last operational state change */
  314 #ifdef _KERNEL
  315         percpu_t        *if_stats;      /* :: statistics */
  316 #else
  317         void            *if_stats;      /* opaque to user-space */
  318 #endif /* _KERNEL */
  319         /*
  320          * Procedure handles.  If you add more of these, don't forget the
  321          * corresponding NULL stub in if.c.
  322          */
  323         int             (*if_output)    /* :: output routine (enqueue) */
  324                             (struct ifnet *, struct mbuf *, const struct sockaddr *,
  325                              const struct rtentry *);
  326         void            (*_if_input)    /* :: input routine (from h/w driver) */
  327                             (struct ifnet *, struct mbuf *);
  328         void            (*if_start)     /* :: initiate output routine */
  329                             (struct ifnet *);
  330         int             (*if_transmit)  /* :: output routine, must be MP-safe */
  331                             (struct ifnet *, struct mbuf *);
  332         int             (*if_ioctl)     /* :: ioctl routine */
  333                             (struct ifnet *, u_long, void *);
  334         int             (*if_init)      /* :: init routine */
  335                             (struct ifnet *);
  336         void            (*if_stop)      /* :: stop routine */
  337                             (struct ifnet *, int);
  338         void            (*if_slowtimo)  /* :: timer routine */
  339                             (struct ifnet *);
  340 #define if_watchdog     if_slowtimo
  341         void            (*if_drain)     /* :: routine to release resources */
  342                             (struct ifnet *);
  343         void            (*if_bpf_mtap)  /* :: bpf routine */
  344                             (struct bpf_if *, struct mbuf *, u_int);
  345         struct ifaltq   if_snd;         /* q: output queue (includes altq) */
  346         struct ifaddr   *if_dl;         /* i: identity of this interface. */
  347         const struct sockaddr_dl
  348                         *if_sadl;       /* i: pointer to sockaddr_dl of if_dl */
  349         /*
  350          * May be NULL.  If not NULL, it is the address assigned
  351          * to the interface by the manufacturer, so it very likely
  352          * to be unique.  It MUST NOT be deleted.  It is highly
  353          * suitable for deriving the EUI64 for the interface.
  354          */
  355         struct ifaddr   *if_hwdl;       /* i: h/w identity */
  356         const uint8_t   *if_broadcastaddr;
  357                                         /* :: linklevel broadcast bytestring */
  358         struct bridge_softc
  359                         *if_bridge;     /* i: bridge glue */
  360         struct bridge_iflist
  361                         *if_bridgeif;   /* i: shortcut to interface list entry */
  362         int             if_dlt;         /* :: data link type (<net/dlt.h>) */
  363         pfil_head_t *   if_pfil;        /* :: filtering point */
  364         uint64_t        if_capabilities;
  365                                         /* i: interface capabilities */
  366         uint64_t        if_capenable;   /* i: capabilities enabled */
  367         union {
  368                 void *          carp_s; /* carp structure (used by !carp ifs) */
  369                 struct ifnet    *carp_d;/* ptr to carpdev (used by carp ifs) */
  370         }               if_carp_ptr;    /* ?: */
  371 #define if_carp         if_carp_ptr.carp_s
  372 #define if_carpdev      if_carp_ptr.carp_d
  373         /*
  374          * These are pre-computed based on an interfaces enabled
  375          * capabilities, for speed elsewhere.
  376          */
  377         int             if_csum_flags_tx;
  378                                         /* i: M_CSUM_* flags for Tx */
  379         int             if_csum_flags_rx;
  380                                         /* i: M_CSUM_* flags for Rx */
  381 
  382         void            *if_afdata[AF_MAX];
  383                                         /* a: */
  384         struct mowner   *if_mowner;     /* ?: who owns mbufs for this interface */
  385 
  386         void            *if_lagg;       /* :: lagg or agr structure */
  387         void            *if_npf_private;/* ?: associated NPF context */
  388 
  389         /*
  390          * pf specific data, used only when #if NPF > 0.
  391          */
  392         void            *if_pf_kif;     /* ?: pf interface abstraction */
  393         void            *if_pf_groups;  /* ?: pf interface groups */
  394         /*
  395          * During an ifnet's lifetime, it has only one if_index, but
  396          * an if_index is not sufficient to identify an ifnet
  397          * because during the lifetime of the system, many ifnets may occupy a
  398          * given if_index.  Let us tell different ifnets at the same
  399          * if_index apart by their if_index_gen, a unique number that each ifnet
  400          * is assigned when it if_attach()s.  Now, the kernel can use the
  401          * pair (if_index, if_index_gen) as a weak reference to an ifnet.
  402          */
  403         uint64_t        if_index_gen;   /* :: generation number for the ifnet
  404                                          * at if_index: if two ifnets' index
  405                                          * and generation number are both the
  406                                          * same, they are the same ifnet.
  407                                          */
  408         struct sysctllog
  409                         *if_sysctl_log; /* :: */
  410         int             (*if_initaddr)  /* :: */
  411                             (struct ifnet *, struct ifaddr *, bool);
  412         int             (*if_setflags)  /* :: */
  413                             (struct ifnet *, const u_short);
  414         kmutex_t        *if_ioctl_lock; /* :: */
  415         char            *if_description;        /* i: interface description */
  416 #ifdef _KERNEL /* XXX kvm(3) */
  417         struct if_slowtimo_data *if_slowtimo_data; /* :: */
  418         struct krwlock  *if_afdata_lock;/* :: */
  419         struct if_percpuq
  420                         *if_percpuq;    /* :: we should remove it in the future */
  421         struct work     if_link_work;   /* q: linkage on link state work queue */
  422         uint16_t        if_link_queue;  /* q: masked link state change queue */
  423                                         /* q: is link state work scheduled? */
  424         bool            if_link_scheduled;
  425         struct pslist_entry
  426                         if_pslist_entry;/* i: */
  427         struct psref_target
  428                         if_psref;       /* :: */
  429         struct pslist_head
  430                         if_addr_pslist; /* i: */
  431         struct if_deferred_start
  432                         *if_deferred_start;
  433                                         /* :: */
  434         /* XXX should be protocol independent */
  435         LIST_HEAD(, in6_multi)
  436                         if_multiaddrs;  /* 6: */
  437         khook_list_t    *if_linkstate_hooks;    /* :: */
  438 #endif
  439 } ifnet_t;
  440 
  441 #include <net/if_stats.h>
  442 
  443 #define if_name(ifp)    ((ifp)->if_xname)
  444 
  445 #define IFF_UP          0x0001          /* interface is up */
  446 #define IFF_BROADCAST   0x0002          /* broadcast address valid */
  447 #define IFF_DEBUG       0x0004          /* turn on debugging */
  448 #define IFF_LOOPBACK    0x0008          /* is a loopback net */
  449 #define IFF_POINTOPOINT 0x0010          /* interface is point-to-point link */
  450 #if 0
  451 /*                      0x0020             was IFF_NOTRAILERS */
  452 #else
  453 /*
  454  * sys/compat/svr4 is remvoed on 19 Dec 2018.
  455  * And then, IFF_NOTRAILERS itself is removed by if.h:r1.268 on 5 Feb 2019.
  456  */
  457 #define IFF_UNNUMBERED  0x0020          /* explicit unnumbered */
  458 #endif
  459 #define IFF_RUNNING     0x0040          /* resources allocated */
  460 #define IFF_NOARP       0x0080          /* no address resolution protocol */
  461 #define IFF_PROMISC     0x0100          /* receive all packets */
  462 #define IFF_ALLMULTI    0x0200          /* receive all multicast packets */
  463 #define IFF_OACTIVE     0x0400          /* transmission in progress */
  464 #define IFF_SIMPLEX     0x0800          /* can't hear own transmissions */
  465 #define IFF_LINK0       0x1000          /* per link layer defined bit */
  466 #define IFF_LINK1       0x2000          /* per link layer defined bit */
  467 #define IFF_LINK2       0x4000          /* per link layer defined bit */
  468 #define IFF_MULTICAST   0x8000          /* supports multicast */
  469 
  470 #define IFEF_MPSAFE                     __BIT(0)        /* handlers can run in parallel (see below) */
  471 
  472 /*
  473  * The guidelines for converting an interface to IFEF_MPSAFE are as follows
  474  *
  475  * Enabling IFEF_MPSAFE on an interface suppresses taking KERNEL_LOCK when
  476  * calling the following handlers:
  477  * - if_start
  478  *   - Note that if_transmit is always called without KERNEL_LOCK
  479  * - if_output
  480  * - if_ioctl
  481  * - if_init
  482  * - if_stop
  483  *
  484  * This means that an interface with IFEF_MPSAFE must make the above handlers
  485  * MP-safe or take KERNEL_LOCK by itself inside handlers that aren't MP-safe
  486  * yet.
  487  *
  488  * There are some additional restrictions to access member variables of struct
  489  * ifnet:
  490  * - if_flags
  491  *   - Must be updated with holding IFNET_LOCK
  492  *   - You cannot use the flag in Tx/Rx paths anymore because there is no
  493  *     synchronization on the flag except for IFNET_LOCK
  494  *   - Note that IFNET_LOCK can't be taken in softint because it's known
  495  *     that it causes a deadlock
  496  *     - Some synchronization mechanisms such as pserialize_perform are called
  497  *       with IFNET_LOCK and also require context switches on every CPUs
  498  *       that mean softints finish so trying to take IFNET_LOCK in softint
  499  *       might block on IFNET_LOCK and prevent such synchronization mechanisms
  500  *       from being completed
  501  *     - Currently the deadlock occurs only if NET_MPSAFE is enabled, however,
  502  *       we should deal with the restriction because NET_MPSAFE will be enabled
  503  *       by default in the future
  504  * - if_watchdog and if_timer
  505  *   - The watchdog framework works only for non-IFEF_MPSAFE interfaces
  506  *     that rely on KERNEL_LOCK
  507  *   - Interfaces with IFEF_MPSAFE have to provide its own watchdog mechanism
  508  *     if needed
  509  *     - Keep if_watchdog NULL when calling if_attach
  510  */
  511 
  512 #ifdef _KERNEL
  513 static __inline bool
  514 if_is_mpsafe(struct ifnet *ifp)
  515 {
  516 
  517         return ((ifp->if_extflags & IFEF_MPSAFE) != 0);
  518 }
  519 
  520 static __inline int
  521 if_output_lock(struct ifnet *cifp, struct ifnet *ifp, struct mbuf *m,
  522     const struct sockaddr *dst, const struct rtentry *rt)
  523 {
  524 
  525         if (if_is_mpsafe(cifp)) {
  526                 return (*cifp->if_output)(ifp, m, dst, rt);
  527         } else {
  528                 int ret;
  529 
  530                 KERNEL_LOCK(1, NULL);
  531                 ret = (*cifp->if_output)(ifp, m, dst, rt);
  532                 KERNEL_UNLOCK_ONE(NULL);
  533                 return ret;
  534         }
  535 }
  536 
  537 static __inline void
  538 if_start_lock(struct ifnet *ifp)
  539 {
  540 
  541         if (if_is_mpsafe(ifp)) {
  542                 (*ifp->if_start)(ifp);
  543         } else {
  544                 KERNEL_LOCK(1, NULL);
  545                 (*ifp->if_start)(ifp);
  546                 KERNEL_UNLOCK_ONE(NULL);
  547         }
  548 }
  549 
  550 #define KERNEL_LOCK_IF_IFP_MPSAFE(ifp)                                  \
  551         do { if (if_is_mpsafe(ifp)) { KERNEL_LOCK(1, NULL); } } while (0)
  552 #define KERNEL_UNLOCK_IF_IFP_MPSAFE(ifp)                                \
  553         do { if (if_is_mpsafe(ifp)) { KERNEL_UNLOCK_ONE(NULL); } } while (0)
  554 
  555 #define KERNEL_LOCK_UNLESS_IFP_MPSAFE(ifp)                              \
  556         do { if (!if_is_mpsafe(ifp)) { KERNEL_LOCK(1, NULL); } } while (0)
  557 #define KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(ifp)                            \
  558         do { if (!if_is_mpsafe(ifp)) { KERNEL_UNLOCK_ONE(NULL); } } while (0)
  559 
  560 #ifdef _KERNEL_OPT
  561 #include "opt_net_mpsafe.h"
  562 #endif
  563 
  564 /* XXX explore a better place to define */
  565 #ifdef NET_MPSAFE
  566 
  567 #define KERNEL_LOCK_UNLESS_NET_MPSAFE()         do { } while (0)
  568 #define KERNEL_UNLOCK_UNLESS_NET_MPSAFE()       do { } while (0)
  569 
  570 #define SOFTNET_LOCK_UNLESS_NET_MPSAFE()        do { } while (0)
  571 #define SOFTNET_UNLOCK_UNLESS_NET_MPSAFE()      do { } while (0)
  572 
  573 #define SOFTNET_LOCK_IF_NET_MPSAFE()                                    \
  574         do { mutex_enter(softnet_lock); } while (0)
  575 #define SOFTNET_UNLOCK_IF_NET_MPSAFE()                                  \
  576         do { mutex_exit(softnet_lock); } while (0)
  577 
  578 #else /* NET_MPSAFE */
  579 
  580 #define KERNEL_LOCK_UNLESS_NET_MPSAFE()                                 \
  581         do { KERNEL_LOCK(1, NULL); } while (0)
  582 #define KERNEL_UNLOCK_UNLESS_NET_MPSAFE()                               \
  583         do { KERNEL_UNLOCK_ONE(NULL); } while (0)
  584 
  585 #define SOFTNET_LOCK_UNLESS_NET_MPSAFE()                                \
  586         do { mutex_enter(softnet_lock); } while (0)
  587 #define SOFTNET_UNLOCK_UNLESS_NET_MPSAFE()                              \
  588         do { mutex_exit(softnet_lock); } while (0)
  589 
  590 #define SOFTNET_LOCK_IF_NET_MPSAFE()            do { } while (0)
  591 #define SOFTNET_UNLOCK_IF_NET_MPSAFE()          do { } while (0)
  592 
  593 #endif /* NET_MPSAFE */
  594 
  595 #define SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE()                         \
  596         do {                                                            \
  597                 SOFTNET_LOCK_UNLESS_NET_MPSAFE();                       \
  598                 KERNEL_LOCK_UNLESS_NET_MPSAFE();                        \
  599         } while (0)
  600 
  601 #define SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE()                       \
  602         do {                                                            \
  603                 KERNEL_UNLOCK_UNLESS_NET_MPSAFE();                      \
  604                 SOFTNET_UNLOCK_UNLESS_NET_MPSAFE();                     \
  605         } while (0)
  606 
  607 #endif /* _KERNEL */
  608 
  609 #define IFFBITS \
  610     "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6UNNUMBERED" \
  611     "\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX" \
  612     "\15LINK0\16LINK1\17LINK2\20MULTICAST"
  613 
  614 /* flags set internally only: */
  615 #define IFF_CANTCHANGE \
  616         (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
  617             IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC)
  618 
  619 /*
  620  * Some convenience macros used for setting ifi_baudrate.
  621  */
  622 #define IF_Kbps(x)      ((x) * 1000ULL)                 /* kilobits/sec. */
  623 #define IF_Mbps(x)      (IF_Kbps((x) * 1000ULL))        /* megabits/sec. */
  624 #define IF_Gbps(x)      (IF_Mbps((x) * 1000ULL))        /* gigabits/sec. */
  625 
  626 /* Capabilities that interfaces can advertise. */
  627                                         /* 0x01 .. 0x40 were previously used */
  628 #define IFCAP_TSOv4             0x00080 /* can do TCPv4 segmentation offload */
  629 #define IFCAP_CSUM_IPv4_Rx      0x00100 /* can do IPv4 header checksums (Rx) */
  630 #define IFCAP_CSUM_IPv4_Tx      0x00200 /* can do IPv4 header checksums (Tx) */
  631 #define IFCAP_CSUM_TCPv4_Rx     0x00400 /* can do IPv4/TCP checksums (Rx) */
  632 #define IFCAP_CSUM_TCPv4_Tx     0x00800 /* can do IPv4/TCP checksums (Tx) */
  633 #define IFCAP_CSUM_UDPv4_Rx     0x01000 /* can do IPv4/UDP checksums (Rx) */
  634 #define IFCAP_CSUM_UDPv4_Tx     0x02000 /* can do IPv4/UDP checksums (Tx) */
  635 #define IFCAP_CSUM_TCPv6_Rx     0x04000 /* can do IPv6/TCP checksums (Rx) */
  636 #define IFCAP_CSUM_TCPv6_Tx     0x08000 /* can do IPv6/TCP checksums (Tx) */
  637 #define IFCAP_CSUM_UDPv6_Rx     0x10000 /* can do IPv6/UDP checksums (Rx) */
  638 #define IFCAP_CSUM_UDPv6_Tx     0x20000 /* can do IPv6/UDP checksums (Tx) */
  639 #define IFCAP_TSOv6             0x40000 /* can do TCPv6 segmentation offload */
  640 #define IFCAP_LRO               0x80000 /* can do Large Receive Offload */
  641 #define IFCAP_MASK              0xfff80 /* currently valid capabilities */
  642 
  643 #define IFCAPBITS               \
  644         "\020"                  \
  645         "\10TSO4"               \
  646         "\11IP4CSUM_Rx"         \
  647         "\12IP4CSUM_Tx"         \
  648         "\13TCP4CSUM_Rx"        \
  649         "\14TCP4CSUM_Tx"        \
  650         "\15UDP4CSUM_Rx"        \
  651         "\16UDP4CSUM_Tx"        \
  652         "\17TCP6CSUM_Rx"        \
  653         "\20TCP6CSUM_Tx"        \
  654         "\21UDP6CSUM_Rx"        \
  655         "\22UDP6CSUM_Tx"        \
  656         "\23TSO6"               \
  657         "\24LRO"                \
  658 
  659 #define IF_AFDATA_LOCK_INIT(ifp)        \
  660         do {(ifp)->if_afdata_lock = rw_obj_alloc();} while (0)
  661 
  662 #define IF_AFDATA_LOCK_DESTROY(ifp)     rw_obj_free((ifp)->if_afdata_lock)
  663 
  664 #define IF_AFDATA_WLOCK(ifp)    rw_enter((ifp)->if_afdata_lock, RW_WRITER)
  665 #define IF_AFDATA_RLOCK(ifp)    rw_enter((ifp)->if_afdata_lock, RW_READER)
  666 #define IF_AFDATA_WUNLOCK(ifp)  rw_exit((ifp)->if_afdata_lock)
  667 #define IF_AFDATA_RUNLOCK(ifp)  rw_exit((ifp)->if_afdata_lock)
  668 #define IF_AFDATA_LOCK(ifp)     IF_AFDATA_WLOCK(ifp)
  669 #define IF_AFDATA_UNLOCK(ifp)   IF_AFDATA_WUNLOCK(ifp)
  670 #define IF_AFDATA_TRYLOCK(ifp)  rw_tryenter((ifp)->if_afdata_lock, RW_WRITER)
  671 
  672 #define IF_AFDATA_LOCK_ASSERT(ifp)      \
  673         KASSERT(rw_lock_held((ifp)->if_afdata_lock))
  674 #define IF_AFDATA_RLOCK_ASSERT(ifp)     \
  675         KASSERT(rw_read_held((ifp)->if_afdata_lock))
  676 #define IF_AFDATA_WLOCK_ASSERT(ifp)     \
  677         KASSERT(rw_write_held((ifp)->if_afdata_lock))
  678 
  679 /*
  680  * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
  681  * input routines have queues of messages stored on ifqueue structures
  682  * (defined above).  Entries are added to and deleted from these structures
  683  * by these macros, which should be called with ipl raised to splnet().
  684  */
  685 #define IF_QFULL(ifq)           ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
  686 #define IF_DROP(ifq)            ((ifq)->ifq_drops++)
  687 #define IF_ENQUEUE(ifq, m) do { \
  688         (m)->m_nextpkt = 0; \
  689         if ((ifq)->ifq_tail == 0) \
  690                 (ifq)->ifq_head = m; \
  691         else \
  692                 (ifq)->ifq_tail->m_nextpkt = m; \
  693         (ifq)->ifq_tail = m; \
  694         (ifq)->ifq_len++; \
  695 } while (/*CONSTCOND*/0)
  696 #define IF_PREPEND(ifq, m) do { \
  697         (m)->m_nextpkt = (ifq)->ifq_head; \
  698         if ((ifq)->ifq_tail == 0) \
  699                 (ifq)->ifq_tail = (m); \
  700         (ifq)->ifq_head = (m); \
  701         (ifq)->ifq_len++; \
  702 } while (/*CONSTCOND*/0)
  703 #define IF_DEQUEUE(ifq, m) do { \
  704         (m) = (ifq)->ifq_head; \
  705         if (m) { \
  706                 if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \
  707                         (ifq)->ifq_tail = 0; \
  708                 (m)->m_nextpkt = 0; \
  709                 (ifq)->ifq_len--; \
  710         } \
  711 } while (/*CONSTCOND*/0)
  712 #define IF_POLL(ifq, m)         ((m) = (ifq)->ifq_head)
  713 #define IF_PURGE(ifq)                                                   \
  714 do {                                                                    \
  715         struct mbuf *__m0;                                              \
  716                                                                         \
  717         for (;;) {                                                      \
  718                 IF_DEQUEUE((ifq), __m0);                                \
  719                 if (__m0 == NULL)                                       \
  720                         break;                                          \
  721                 else                                                    \
  722                         m_freem(__m0);                                  \
  723         }                                                               \
  724 } while (/*CONSTCOND*/ 0)
  725 #define IF_IS_EMPTY(ifq)        ((ifq)->ifq_len == 0)
  726 
  727 #ifndef IFQ_MAXLEN
  728 #define IFQ_MAXLEN      256
  729 #endif
  730 #define IFNET_SLOWHZ    1               /* granularity is 1 second */
  731 
  732 /*
  733  * Structure defining statistics and other data kept regarding an address
  734  * on a network interface.
  735  */
  736 struct ifaddr_data {
  737         int64_t ifad_inbytes;
  738         int64_t ifad_outbytes;
  739 };
  740 
  741 /*
  742  * The ifaddr structure contains information about one address
  743  * of an interface.  They are maintained by the different address families,
  744  * are allocated and attached when an address is set, and are linked
  745  * together so all addresses for an interface can be located.
  746  */
  747 struct ifaddr {
  748         struct  sockaddr *ifa_addr;     /* address of interface */
  749         struct  sockaddr *ifa_dstaddr;  /* other end of p-to-p link */
  750 #define ifa_broadaddr   ifa_dstaddr     /* broadcast address interface */
  751         struct  sockaddr *ifa_netmask;  /* used to determine subnet */
  752         struct  ifnet *ifa_ifp;         /* back-pointer to interface */
  753         TAILQ_ENTRY(ifaddr) ifa_list;   /* list of addresses for interface */
  754         struct  ifaddr_data     ifa_data;       /* statistics on the address */
  755         void    (*ifa_rtrequest)        /* check or clean routes (+ or -)'d */
  756                         (int, struct rtentry *, const struct rt_addrinfo *);
  757         u_int   ifa_flags;              /* mostly rt_flags for cloning */
  758         int     ifa_refcnt;             /* count of references */
  759         int     ifa_metric;             /* cost of going out this interface */
  760         struct ifaddr   *(*ifa_getifa)(struct ifaddr *,
  761                                        const struct sockaddr *);
  762         uint32_t        *ifa_seqno;
  763         int16_t ifa_preference; /* preference level for this address */
  764 #ifdef _KERNEL
  765         struct pslist_entry     ifa_pslist_entry;
  766         struct psref_target     ifa_psref;
  767 #endif
  768 };
  769 #define IFA_ROUTE       RTF_UP  /* (0x01) route installed */
  770 #define IFA_DESTROYING  0x2
  771 
  772 /*
  773  * Message format for use in obtaining information about interfaces from
  774  * sysctl and the routing socket.  We need to force 64-bit alignment if we
  775  * aren't using compatibility definitions.
  776  */
  777 #if !defined(_KERNEL) || !defined(COMPAT_RTSOCK)
  778 #define __align64       __aligned(sizeof(uint64_t))
  779 #else
  780 #define __align64
  781 #endif
  782 struct if_msghdr {
  783         u_short ifm_msglen __align64;
  784                                 /* to skip over non-understood messages */
  785         u_char  ifm_version;    /* future binary compatibility */
  786         u_char  ifm_type;       /* message type */
  787         int     ifm_addrs;      /* like rtm_addrs */
  788         int     ifm_flags;      /* value of if_flags */
  789         u_short ifm_index;      /* index for associated ifp */
  790         struct  if_data ifm_data __align64;
  791                                 /* statistics and other data about if */
  792 };
  793 
  794 /*
  795  * Message format for use in obtaining information about interface addresses
  796  * from sysctl and the routing socket.
  797  */
  798 struct ifa_msghdr {
  799         u_short ifam_msglen __align64;
  800                                 /* to skip over non-understood messages */
  801         u_char  ifam_version;   /* future binary compatibility */
  802         u_char  ifam_type;      /* message type */
  803         u_short ifam_index;     /* index for associated ifp */
  804         int     ifam_flags;     /* value of ifa_flags */
  805         int     ifam_addrs;     /* like rtm_addrs */
  806         pid_t   ifam_pid;       /* identify sender */
  807         int     ifam_addrflags; /* family specific address flags */
  808         int     ifam_metric;    /* value of ifa_metric */
  809 };
  810 
  811 /*
  812  * Message format announcing the arrival or departure of a network interface.
  813  */
  814 struct if_announcemsghdr {
  815         u_short ifan_msglen __align64;
  816                                 /* to skip over non-understood messages */
  817         u_char  ifan_version;   /* future binary compatibility */
  818         u_char  ifan_type;      /* message type */
  819         u_short ifan_index;     /* index for associated ifp */
  820         char    ifan_name[IFNAMSIZ]; /* if name, e.g. "en0" */
  821         u_short ifan_what;      /* what type of announcement */
  822 };
  823 
  824 #define IFAN_ARRIVAL    0       /* interface arrival */
  825 #define IFAN_DEPARTURE  1       /* interface departure */
  826 
  827 #undef __align64
  828 
  829 /*
  830  * Interface request structure used for socket
  831  * ioctl's.  All interface ioctl's must have parameter
  832  * definitions which begin with ifr_name.  The
  833  * remainder may be interface specific.
  834  */
  835 struct  ifreq {
  836         char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */
  837         union {
  838                 struct  sockaddr ifru_addr;
  839                 struct  sockaddr ifru_dstaddr;
  840                 struct  sockaddr ifru_broadaddr;
  841                 struct  sockaddr_storage ifru_space;
  842                 short   ifru_flags;
  843                 int     ifru_addrflags;
  844                 int     ifru_metric;
  845                 int     ifru_mtu;
  846                 int     ifru_dlt;
  847                 u_int   ifru_value;
  848                 void *  ifru_data;
  849                 struct {
  850                         uint32_t        b_buflen;
  851                         void            *b_buf;
  852                 } ifru_b;
  853         } ifr_ifru;
  854 #define ifr_addr        ifr_ifru.ifru_addr      /* address */
  855 #define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
  856 #define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */
  857 #define ifr_space       ifr_ifru.ifru_space     /* sockaddr_storage */
  858 #define ifr_flags       ifr_ifru.ifru_flags     /* flags */
  859 #define ifr_addrflags   ifr_ifru.ifru_addrflags /* addr flags */
  860 #define ifr_metric      ifr_ifru.ifru_metric    /* metric */
  861 #define ifr_mtu         ifr_ifru.ifru_mtu       /* mtu */
  862 #define ifr_dlt         ifr_ifru.ifru_dlt       /* data link type (DLT_*) */
  863 #define ifr_value       ifr_ifru.ifru_value     /* generic value */
  864 #define ifr_media       ifr_ifru.ifru_metric    /* media options (overload) */
  865 #define ifr_data        ifr_ifru.ifru_data      /* for use by interface
  866                                                  * XXX deprecated
  867                                                  */
  868 #define ifr_buf         ifr_ifru.ifru_b.b_buf   /* new interface ioctls */
  869 #define ifr_buflen      ifr_ifru.ifru_b.b_buflen
  870 #define ifr_index       ifr_ifru.ifru_value     /* interface index, BSD */
  871 #define ifr_ifindex     ifr_index               /* interface index, linux */
  872 };
  873 
  874 #ifdef _KERNEL
  875 #define ifreq_setdstaddr        ifreq_setaddr
  876 #define ifreq_setbroadaddr      ifreq_setaddr
  877 #define ifreq_getdstaddr        ifreq_getaddr
  878 #define ifreq_getbroadaddr      ifreq_getaddr
  879 
  880 static __inline const struct sockaddr *
  881 /*ARGSUSED*/
  882 ifreq_getaddr(u_long cmd, const struct ifreq *ifr)
  883 {
  884         return &ifr->ifr_addr;
  885 }
  886 #endif /* _KERNEL */
  887 
  888 struct ifcapreq {
  889         char            ifcr_name[IFNAMSIZ];    /* if name, e.g. "en0" */
  890         uint64_t        ifcr_capabilities;      /* supported capabiliites */
  891         uint64_t        ifcr_capenable;         /* capabilities enabled */
  892 };
  893 
  894 struct ifaliasreq {
  895         char    ifra_name[IFNAMSIZ];            /* if name, e.g. "en0" */
  896         struct  sockaddr ifra_addr;
  897         struct  sockaddr ifra_dstaddr;
  898 #define ifra_broadaddr  ifra_dstaddr
  899         struct  sockaddr ifra_mask;
  900 };
  901 
  902 struct ifdatareq {
  903         char    ifdr_name[IFNAMSIZ];            /* if name, e.g. "en0" */
  904         struct  if_data ifdr_data;
  905 };
  906 
  907 struct ifmediareq {
  908         char    ifm_name[IFNAMSIZ];     /* if name, e.g. "en0" */
  909         int     ifm_current;            /* IFMWD: current media options */
  910         int     ifm_mask;               /* IFMWD: don't care mask */
  911         int     ifm_status;             /* media status */
  912         int     ifm_active;             /* IFMWD: active options */
  913         int     ifm_count;              /* # entries in ifm_ulist
  914                                            array */
  915         int     *ifm_ulist;             /* array of ifmedia word */
  916 };
  917 
  918 
  919 struct  ifdrv {
  920         char            ifd_name[IFNAMSIZ];     /* if name, e.g. "en0" */
  921         unsigned long   ifd_cmd;
  922         size_t          ifd_len;
  923         void            *ifd_data;
  924 };
  925 #define IFLINKSTR_QUERYLEN      0x01
  926 #define IFLINKSTR_UNSET         0x02
  927 
  928 /*
  929  * Structure used in SIOCGIFCONF request.
  930  * Used to retrieve interface configuration
  931  * for machine (useful for programs which
  932  * must know all networks accessible).
  933  */
  934 struct  ifconf {
  935         int     ifc_len;                /* size of associated buffer */
  936         union {
  937                 void *  ifcu_buf;
  938                 struct  ifreq *ifcu_req;
  939         } ifc_ifcu;
  940 #define ifc_buf ifc_ifcu.ifcu_buf       /* buffer address */
  941 #define ifc_req ifc_ifcu.ifcu_req       /* array of structures returned */
  942 };
  943 
  944 /*
  945  * Structure for SIOC[AGD]LIFADDR
  946  */
  947 struct if_laddrreq {
  948         char iflr_name[IFNAMSIZ];
  949         unsigned int flags;
  950 #define IFLR_PREFIX     0x8000  /* in: prefix given  out: kernel fills id */
  951 #define IFLR_ACTIVE     0x4000  /* in/out: link-layer address activation */
  952 #define IFLR_FACTORY    0x2000  /* in/out: factory link-layer address */
  953         unsigned int prefixlen;         /* in/out */
  954         struct sockaddr_storage addr;   /* in/out */
  955         struct sockaddr_storage dstaddr; /* out */
  956 };
  957 
  958 /*
  959  * Structure for SIOC[SG]IFADDRPREF
  960  */
  961 struct if_addrprefreq {
  962         char                    ifap_name[IFNAMSIZ];
  963         int16_t                 ifap_preference;        /* in/out */
  964         struct sockaddr_storage ifap_addr;              /* in/out */
  965 };
  966 
  967 #include <net/if_arp.h>
  968 
  969 #endif /* _NETBSD_SOURCE */
  970 
  971 #ifdef _KERNEL
  972 #ifdef ALTQ
  973 #define IFQ_ENQUEUE(ifq, m, err)                                        \
  974 do {                                                                    \
  975         mutex_enter((ifq)->ifq_lock);                                   \
  976         if (ALTQ_IS_ENABLED(ifq))                                       \
  977                 ALTQ_ENQUEUE((ifq), (m), (err));                        \
  978         else {                                                          \
  979                 if (IF_QFULL(ifq)) {                                    \
  980                         m_freem(m);                                     \
  981                         (err) = ENOBUFS;                                \
  982                 } else {                                                \
  983                         IF_ENQUEUE((ifq), (m));                         \
  984                         (err) = 0;                                      \
  985                 }                                                       \
  986         }                                                               \
  987         if ((err))                                                      \
  988                 (ifq)->ifq_drops++;                                     \
  989         mutex_exit((ifq)->ifq_lock);                                    \
  990 } while (/*CONSTCOND*/ 0)
  991 
  992 #define IFQ_DEQUEUE(ifq, m)                                             \
  993 do {                                                                    \
  994         mutex_enter((ifq)->ifq_lock);                                   \
  995         if (TBR_IS_ENABLED(ifq))                                        \
  996                 (m) = tbr_dequeue((ifq), ALTDQ_REMOVE);                 \
  997         else if (ALTQ_IS_ENABLED(ifq))                                  \
  998                 ALTQ_DEQUEUE((ifq), (m));                               \
  999         else                                                            \
 1000                 IF_DEQUEUE((ifq), (m));                                 \
 1001         mutex_exit((ifq)->ifq_lock);                                    \
 1002 } while (/*CONSTCOND*/ 0)
 1003 
 1004 #define IFQ_POLL(ifq, m)                                                \
 1005 do {                                                                    \
 1006         mutex_enter((ifq)->ifq_lock);                                   \
 1007         if (TBR_IS_ENABLED(ifq))                                        \
 1008                 (m) = tbr_dequeue((ifq), ALTDQ_POLL);                   \
 1009         else if (ALTQ_IS_ENABLED(ifq))                                  \
 1010                 ALTQ_POLL((ifq), (m));                                  \
 1011         else                                                            \
 1012                 IF_POLL((ifq), (m));                                    \
 1013         mutex_exit((ifq)->ifq_lock);                                    \
 1014 } while (/*CONSTCOND*/ 0)
 1015 
 1016 #define IFQ_PURGE(ifq)                                                  \
 1017 do {                                                                    \
 1018         mutex_enter((ifq)->ifq_lock);                                   \
 1019         if (ALTQ_IS_ENABLED(ifq))                                       \
 1020                 ALTQ_PURGE(ifq);                                        \
 1021         else                                                            \
 1022                 IF_PURGE(ifq);                                          \
 1023         mutex_exit((ifq)->ifq_lock);                                    \
 1024 } while (/*CONSTCOND*/ 0)
 1025 
 1026 #define IFQ_SET_READY(ifq)                                              \
 1027 do {                                                                    \
 1028         (ifq)->altq_flags |= ALTQF_READY;                               \
 1029 } while (/*CONSTCOND*/ 0)
 1030 
 1031 #define IFQ_CLASSIFY(ifq, m, af)                                        \
 1032 do {                                                                    \
 1033         KASSERT(((m)->m_flags & M_PKTHDR) != 0);                        \
 1034         mutex_enter((ifq)->ifq_lock);                                   \
 1035         if (ALTQ_IS_ENABLED(ifq)) {                                     \
 1036                 if (ALTQ_NEEDS_CLASSIFY(ifq))                           \
 1037                         (m)->m_pkthdr.pattr_class = (*(ifq)->altq_classify) \
 1038                                 ((ifq)->altq_clfier, (m), (af));        \
 1039                 (m)->m_pkthdr.pattr_af = (af);                          \
 1040                 (m)->m_pkthdr.pattr_hdr = mtod((m), void *);            \
 1041         }                                                               \
 1042         mutex_exit((ifq)->ifq_lock);                                    \
 1043 } while (/*CONSTCOND*/ 0)
 1044 #else /* ! ALTQ */
 1045 #define IFQ_ENQUEUE(ifq, m, err)                                        \
 1046 do {                                                                    \
 1047         mutex_enter((ifq)->ifq_lock);                                   \
 1048         if (IF_QFULL(ifq)) {                                            \
 1049                 m_freem(m);                                             \
 1050                 (err) = ENOBUFS;                                        \
 1051         } else {                                                        \
 1052                 IF_ENQUEUE((ifq), (m));                                 \
 1053                 (err) = 0;                                              \
 1054         }                                                               \
 1055         if (err)                                                        \
 1056                 (ifq)->ifq_drops++;                                     \
 1057         mutex_exit((ifq)->ifq_lock);                                    \
 1058 } while (/*CONSTCOND*/ 0)
 1059 
 1060 #define IFQ_DEQUEUE(ifq, m)                                             \
 1061 do {                                                                    \
 1062         mutex_enter((ifq)->ifq_lock);                                   \
 1063         IF_DEQUEUE((ifq), (m));                                         \
 1064         mutex_exit((ifq)->ifq_lock);                                    \
 1065 } while (/*CONSTCOND*/ 0)
 1066 
 1067 #define IFQ_POLL(ifq, m)                                                \
 1068 do {                                                                    \
 1069         mutex_enter((ifq)->ifq_lock);                                   \
 1070         IF_POLL((ifq), (m));                                            \
 1071         mutex_exit((ifq)->ifq_lock);                                    \
 1072 } while (/*CONSTCOND*/ 0)
 1073 
 1074 #define IFQ_PURGE(ifq)                                                  \
 1075 do {                                                                    \
 1076         mutex_enter((ifq)->ifq_lock);                                   \
 1077         IF_PURGE(ifq);                                                  \
 1078         mutex_exit((ifq)->ifq_lock);                                    \
 1079 } while (/*CONSTCOND*/ 0)
 1080 
 1081 #define IFQ_SET_READY(ifq)      /* nothing */
 1082 
 1083 #define IFQ_CLASSIFY(ifq, m, af) /* nothing */
 1084 
 1085 #endif /* ALTQ */
 1086 
 1087 #define IFQ_LOCK_INIT(ifq)      (ifq)->ifq_lock =                       \
 1088             mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET)
 1089 #define IFQ_LOCK_DESTROY(ifq)   mutex_obj_free((ifq)->ifq_lock)
 1090 #define IFQ_LOCK(ifq)           mutex_enter((ifq)->ifq_lock)
 1091 #define IFQ_UNLOCK(ifq)         mutex_exit((ifq)->ifq_lock)
 1092 
 1093 #define IFQ_IS_EMPTY(ifq)               IF_IS_EMPTY(ifq)
 1094 #define IFQ_INC_LEN(ifq)                ((ifq)->ifq_len++)
 1095 #define IFQ_DEC_LEN(ifq)                (--(ifq)->ifq_len)
 1096 #define IFQ_INC_DROPS(ifq)              ((ifq)->ifq_drops++)
 1097 #define IFQ_SET_MAXLEN(ifq, len)        ((ifq)->ifq_maxlen = (len))
 1098 
 1099 #include <sys/mallocvar.h>
 1100 MALLOC_DECLARE(M_IFADDR);
 1101 MALLOC_DECLARE(M_IFMADDR);
 1102 
 1103 int ifreq_setaddr(u_long, struct ifreq *, const struct sockaddr *);
 1104 
 1105 struct ifnet *if_alloc(u_char);
 1106 void if_free(struct ifnet *);
 1107 void if_initname(struct ifnet *, const char *, int);
 1108 struct ifaddr *if_dl_create(const struct ifnet *, const struct sockaddr_dl **);
 1109 void if_activate_sadl(struct ifnet *, struct ifaddr *,
 1110     const struct sockaddr_dl *);
 1111 void    if_set_sadl(struct ifnet *, const void *, u_char, bool);
 1112 void    if_alloc_sadl(struct ifnet *);
 1113 void    if_free_sadl(struct ifnet *, int);
 1114 void    if_initialize(struct ifnet *);
 1115 void    if_register(struct ifnet *);
 1116 void    if_attach(struct ifnet *); /* Deprecated. Use if_initialize and if_register */
 1117 void    if_attachdomain(void);
 1118 void    if_deactivate(struct ifnet *);
 1119 bool    if_is_deactivated(const struct ifnet *);
 1120 void    if_export_if_data(struct ifnet *, struct if_data *, bool);
 1121 void    if_purgeaddrs(struct ifnet *, int, void (*)(struct ifaddr *));
 1122 void    if_detach(struct ifnet *);
 1123 void    if_down(struct ifnet *);
 1124 void    if_down_locked(struct ifnet *);
 1125 void    if_link_state_change(struct ifnet *, int);
 1126 void    if_domain_link_state_change(struct ifnet *, int);
 1127 void    if_up(struct ifnet *);
 1128 void    ifinit(void);
 1129 void    ifinit1(void);
 1130 void    ifinit_post(void);
 1131 int     ifaddrpref_ioctl(struct socket *, u_long, void *, struct ifnet *);
 1132 extern int (*ifioctl)(struct socket *, u_long, void *, struct lwp *);
 1133 int     ifioctl_common(struct ifnet *, u_long, void *);
 1134 int     ifpromisc(struct ifnet *, int);
 1135 int     ifpromisc_locked(struct ifnet *, int);
 1136 int     if_addr_init(ifnet_t *, struct ifaddr *, bool);
 1137 int     if_do_dad(struct ifnet *);
 1138 int     if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
 1139 int     if_flags_set(struct ifnet *, const u_short);
 1140 int     if_clone_list(int, char *, int *);
 1141 
 1142 int     if_ioctl(struct ifnet *, u_long, void *);
 1143 int     if_init(struct ifnet *);
 1144 void    if_stop(struct ifnet *, int);
 1145 
 1146 struct  ifnet *ifunit(const char *);
 1147 struct  ifnet *if_get(const char *, struct psref *);
 1148 ifnet_t *if_byindex(u_int);
 1149 ifnet_t *_if_byindex(u_int);
 1150 ifnet_t *if_get_byindex(u_int, struct psref *);
 1151 ifnet_t *if_get_bylla(const void *, unsigned char, struct psref *);
 1152 void    if_put(const struct ifnet *, struct psref *);
 1153 void    if_acquire(struct ifnet *, struct psref *);
 1154 #define if_release      if_put
 1155 
 1156 int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, int);
 1157 percpu_t *if_tunnel_alloc_ro_percpu(void);
 1158 void if_tunnel_free_ro_percpu(percpu_t *);
 1159 void if_tunnel_ro_percpu_rtcache_free(percpu_t *);
 1160 
 1161 struct tunnel_ro {
 1162         struct route *tr_ro;
 1163         kmutex_t *tr_lock;
 1164 };
 1165 
 1166 static inline void
 1167 if_tunnel_get_ro(percpu_t *ro_percpu, struct route **ro, kmutex_t **lock)
 1168 {
 1169         struct tunnel_ro *tro;
 1170 
 1171         tro = percpu_getref(ro_percpu);
 1172         *ro = tro->tr_ro;
 1173         *lock = tro->tr_lock;
 1174         mutex_enter(*lock);
 1175 }
 1176 
 1177 static inline void
 1178 if_tunnel_put_ro(percpu_t *ro_percpu, kmutex_t *lock)
 1179 {
 1180 
 1181         mutex_exit(lock);
 1182         percpu_putref(ro_percpu);
 1183 }
 1184 
 1185 static __inline if_index_t
 1186 if_get_index(const struct ifnet *ifp)
 1187 {
 1188 
 1189         return ifp != NULL ? ifp->if_index : 0;
 1190 }
 1191 
 1192 bool    if_held(struct ifnet *);
 1193 
 1194 void    if_input(struct ifnet *, struct mbuf *);
 1195 
 1196 struct if_percpuq *
 1197         if_percpuq_create(struct ifnet *);
 1198 void    if_percpuq_destroy(struct if_percpuq *);
 1199 void
 1200         if_percpuq_enqueue(struct if_percpuq *, struct mbuf *);
 1201 
 1202 void    if_deferred_start_init(struct ifnet *, void (*)(struct ifnet *));
 1203 void    if_schedule_deferred_start(struct ifnet *);
 1204 
 1205 void ifa_insert(struct ifnet *, struct ifaddr *);
 1206 void ifa_remove(struct ifnet *, struct ifaddr *);
 1207 
 1208 void    ifa_psref_init(struct ifaddr *);
 1209 void    ifa_acquire(struct ifaddr *, struct psref *);
 1210 void    ifa_release(struct ifaddr *, struct psref *);
 1211 bool    ifa_held(struct ifaddr *);
 1212 bool    ifa_is_destroying(struct ifaddr *);
 1213 
 1214 void    ifaref(struct ifaddr *);
 1215 void    ifafree(struct ifaddr *);
 1216 
 1217 struct  ifaddr *ifa_ifwithaddr(const struct sockaddr *);
 1218 struct  ifaddr *ifa_ifwithaddr_psref(const struct sockaddr *, struct psref *);
 1219 struct  ifaddr *ifa_ifwithaf(int);
 1220 struct  ifaddr *ifa_ifwithdstaddr(const struct sockaddr *);
 1221 struct  ifaddr *ifa_ifwithdstaddr_psref(const struct sockaddr *,
 1222             struct psref *);
 1223 struct  ifaddr *ifa_ifwithnet(const struct sockaddr *);
 1224 struct  ifaddr *ifa_ifwithnet_psref(const struct sockaddr *, struct psref *);
 1225 struct  ifaddr *ifa_ifwithladdr(const struct sockaddr *);
 1226 struct  ifaddr *ifa_ifwithladdr_psref(const struct sockaddr *, struct psref *);
 1227 struct  ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *);
 1228 struct  ifaddr *ifaof_ifpforaddr_psref(const struct sockaddr *, struct ifnet *,
 1229             struct psref *);
 1230 void    link_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
 1231 void    p2p_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
 1232 
 1233 void    if_clone_attach(struct if_clone *);
 1234 void    if_clone_detach(struct if_clone *);
 1235 
 1236 int     if_transmit_lock(struct ifnet *, struct mbuf *);
 1237 
 1238 int     ifq_enqueue(struct ifnet *, struct mbuf *);
 1239 int     ifq_enqueue2(struct ifnet *, struct ifqueue *, struct mbuf *);
 1240 
 1241 int     loioctl(struct ifnet *, u_long, void *);
 1242 void    loopattach(int);
 1243 void    loopinit(void);
 1244 int     looutput(struct ifnet *,
 1245            struct mbuf *, const struct sockaddr *, const struct rtentry *);
 1246 
 1247 void *  if_linkstate_change_establish(struct ifnet *,
 1248             void (*)(void *), void *);
 1249 void    if_linkstate_change_disestablish(struct ifnet *,
 1250             void *, kmutex_t *);
 1251 
 1252 /*
 1253  * These are exported because they're an easy way to tell if
 1254  * an interface is going away without having to burn a flag.
 1255  */
 1256 int     if_nulloutput(struct ifnet *, struct mbuf *,
 1257             const struct sockaddr *, const struct rtentry *);
 1258 void    if_nullinput(struct ifnet *, struct mbuf *);
 1259 void    if_nullstart(struct ifnet *);
 1260 int     if_nulltransmit(struct ifnet *, struct mbuf *);
 1261 int     if_nullioctl(struct ifnet *, u_long, void *);
 1262 int     if_nullinit(struct ifnet *);
 1263 void    if_nullstop(struct ifnet *, int);
 1264 void    if_nullslowtimo(struct ifnet *);
 1265 #define if_nullwatchdog if_nullslowtimo
 1266 void    if_nulldrain(struct ifnet *);
 1267 #else
 1268 struct if_nameindex {
 1269         unsigned int    if_index;       /* 1, 2, ... */
 1270         char            *if_name;       /* null terminated name: "le0", ... */
 1271 };
 1272 
 1273 #include <sys/cdefs.h>
 1274 __BEGIN_DECLS
 1275 unsigned int if_nametoindex(const char *);
 1276 char *  if_indextoname(unsigned int, char *);
 1277 struct  if_nameindex * if_nameindex(void);
 1278 void    if_freenameindex(struct if_nameindex *);
 1279 __END_DECLS
 1280 #endif /* _KERNEL */ /* XXX really ALTQ? */
 1281 
 1282 #ifdef _KERNEL
 1283 
 1284 #define IFADDR_FIRST(__ifp)             TAILQ_FIRST(&(__ifp)->if_addrlist)
 1285 #define IFADDR_NEXT(__ifa)              TAILQ_NEXT((__ifa), ifa_list)
 1286 #define IFADDR_FOREACH(__ifa, __ifp)    TAILQ_FOREACH(__ifa, \
 1287                                             &(__ifp)->if_addrlist, ifa_list)
 1288 #define IFADDR_FOREACH_SAFE(__ifa, __ifp, __nifa) \
 1289                                             TAILQ_FOREACH_SAFE(__ifa, \
 1290                                             &(__ifp)->if_addrlist, ifa_list, __nifa)
 1291 #define IFADDR_EMPTY(__ifp)             TAILQ_EMPTY(&(__ifp)->if_addrlist)
 1292 
 1293 #define IFADDR_ENTRY_INIT(__ifa)                                        \
 1294         PSLIST_ENTRY_INIT((__ifa), ifa_pslist_entry)
 1295 #define IFADDR_ENTRY_DESTROY(__ifa)                                     \
 1296         PSLIST_ENTRY_DESTROY((__ifa), ifa_pslist_entry)
 1297 #define IFADDR_READER_EMPTY(__ifp)                                      \
 1298         (PSLIST_READER_FIRST(&(__ifp)->if_addr_pslist, struct ifaddr,   \
 1299                              ifa_pslist_entry) == NULL)
 1300 #define IFADDR_READER_FIRST(__ifp)                                      \
 1301         PSLIST_READER_FIRST(&(__ifp)->if_addr_pslist, struct ifaddr,    \
 1302                             ifa_pslist_entry)
 1303 #define IFADDR_READER_NEXT(__ifa)                                       \
 1304         PSLIST_READER_NEXT((__ifa), struct ifaddr, ifa_pslist_entry)
 1305 #define IFADDR_READER_FOREACH(__ifa, __ifp)                             \
 1306         PSLIST_READER_FOREACH((__ifa), &(__ifp)->if_addr_pslist, struct ifaddr,\
 1307                               ifa_pslist_entry)
 1308 #define IFADDR_WRITER_INSERT_HEAD(__ifp, __ifa)                         \
 1309         PSLIST_WRITER_INSERT_HEAD(&(__ifp)->if_addr_pslist, (__ifa),    \
 1310                                   ifa_pslist_entry)
 1311 #define IFADDR_WRITER_REMOVE(__ifa)                                     \
 1312         PSLIST_WRITER_REMOVE((__ifa), ifa_pslist_entry)
 1313 #define IFADDR_WRITER_FOREACH(__ifa, __ifp)                             \
 1314         PSLIST_WRITER_FOREACH((__ifa), &(__ifp)->if_addr_pslist, struct ifaddr,\
 1315                               ifa_pslist_entry)
 1316 #define IFADDR_WRITER_NEXT(__ifp)                                       \
 1317         PSLIST_WRITER_NEXT((__ifp), struct ifaddr, ifa_pslist_entry)
 1318 #define IFADDR_WRITER_INSERT_AFTER(__ifp, __new)                        \
 1319         PSLIST_WRITER_INSERT_AFTER((__ifp), (__new), ifa_pslist_entry)
 1320 #define IFADDR_WRITER_EMPTY(__ifp)                                      \
 1321         (PSLIST_WRITER_FIRST(&(__ifp)->if_addr_pslist, struct ifaddr,   \
 1322                              ifa_pslist_entry) == NULL)
 1323 #define IFADDR_WRITER_INSERT_TAIL(__ifp, __new)                         \
 1324         do {                                                            \
 1325                 if (IFADDR_WRITER_EMPTY(__ifp)) {                       \
 1326                         IFADDR_WRITER_INSERT_HEAD((__ifp), (__new));    \
 1327                 } else {                                                \
 1328                         struct ifaddr *__ifa;                           \
 1329                         IFADDR_WRITER_FOREACH(__ifa, (__ifp)) {         \
 1330                                 if (IFADDR_WRITER_NEXT(__ifa) == NULL) {\
 1331                                         IFADDR_WRITER_INSERT_AFTER(__ifa,\
 1332                                             (__new));                   \
 1333                                         break;                          \
 1334                                 }                                       \
 1335                         }                                               \
 1336                 }                                                       \
 1337         } while (0)
 1338 
 1339 #define IFNET_GLOBAL_LOCK()                     mutex_enter(&ifnet_mtx)
 1340 #define IFNET_GLOBAL_UNLOCK()                   mutex_exit(&ifnet_mtx)
 1341 #define IFNET_GLOBAL_LOCKED()                   mutex_owned(&ifnet_mtx)
 1342 
 1343 #define IFNET_READER_EMPTY() \
 1344         (PSLIST_READER_FIRST(&ifnet_pslist, struct ifnet, if_pslist_entry) == NULL)
 1345 #define IFNET_READER_FIRST() \
 1346         PSLIST_READER_FIRST(&ifnet_pslist, struct ifnet, if_pslist_entry)
 1347 #define IFNET_READER_NEXT(__ifp) \
 1348         PSLIST_READER_NEXT((__ifp), struct ifnet, if_pslist_entry)
 1349 #define IFNET_READER_FOREACH(__ifp) \
 1350         PSLIST_READER_FOREACH((__ifp), &ifnet_pslist, struct ifnet, \
 1351                               if_pslist_entry)
 1352 #define IFNET_WRITER_INSERT_HEAD(__ifp) \
 1353         PSLIST_WRITER_INSERT_HEAD(&ifnet_pslist, (__ifp), if_pslist_entry)
 1354 #define IFNET_WRITER_REMOVE(__ifp) \
 1355         PSLIST_WRITER_REMOVE((__ifp), if_pslist_entry)
 1356 #define IFNET_WRITER_FOREACH(__ifp) \
 1357         PSLIST_WRITER_FOREACH((__ifp), &ifnet_pslist, struct ifnet, \
 1358                               if_pslist_entry)
 1359 #define IFNET_WRITER_NEXT(__ifp) \
 1360         PSLIST_WRITER_NEXT((__ifp), struct ifnet, if_pslist_entry)
 1361 #define IFNET_WRITER_INSERT_AFTER(__ifp, __new) \
 1362         PSLIST_WRITER_INSERT_AFTER((__ifp), (__new), if_pslist_entry)
 1363 #define IFNET_WRITER_EMPTY() \
 1364         (PSLIST_WRITER_FIRST(&ifnet_pslist, struct ifnet, if_pslist_entry) == NULL)
 1365 #define IFNET_WRITER_INSERT_TAIL(__new)                                 \
 1366         do {                                                            \
 1367                 if (IFNET_WRITER_EMPTY()) {                             \
 1368                         IFNET_WRITER_INSERT_HEAD(__new);                \
 1369                 } else {                                                \
 1370                         struct ifnet *__ifp;                            \
 1371                         IFNET_WRITER_FOREACH(__ifp) {                   \
 1372                                 if (IFNET_WRITER_NEXT(__ifp) == NULL) { \
 1373                                         IFNET_WRITER_INSERT_AFTER(__ifp,\
 1374                                             (__new));                   \
 1375                                         break;                          \
 1376                                 }                                       \
 1377                         }                                               \
 1378                 }                                                       \
 1379         } while (0)
 1380 
 1381 #define IFNET_LOCK(ifp)         mutex_enter((ifp)->if_ioctl_lock)
 1382 #define IFNET_UNLOCK(ifp)       mutex_exit((ifp)->if_ioctl_lock)
 1383 #define IFNET_LOCKED(ifp)       mutex_owned((ifp)->if_ioctl_lock)
 1384 
 1385 #define IFNET_ASSERT_UNLOCKED(ifp)      \
 1386         KDASSERT(mutex_ownable((ifp)->if_ioctl_lock))
 1387 
 1388 extern struct pslist_head ifnet_pslist;
 1389 extern kmutex_t ifnet_mtx;
 1390 
 1391 extern struct ifnet *lo0ifp;
 1392 
 1393 /*
 1394  * ifq sysctl support
 1395  */
 1396 int     sysctl_ifq(int *name, u_int namelen, void *oldp,
 1397                        size_t *oldlenp, void *newp, size_t newlen,
 1398                        struct ifqueue *ifq);
 1399 /* symbolic names for terminal (per-protocol) CTL_IFQ_ nodes */
 1400 #define IFQCTL_LEN      1
 1401 #define IFQCTL_MAXLEN   2
 1402 #define IFQCTL_PEAK     3
 1403 #define IFQCTL_DROPS    4
 1404 
 1405 /*
 1406  * Hook for if_vlan - needed by if_agr
 1407  */
 1408 MODULE_HOOK(if_vlan_vlan_input_hook,
 1409     struct mbuf *, (struct ifnet *, struct mbuf *));
 1410 
 1411 #endif /* _KERNEL */
 1412 
 1413 #endif /* !_NET_IF_H_ */

Cache object: 996a280ac1f2534cef1c3878feb8d29b


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