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_vlan.c

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

    1 /*-
    2  * Copyright 1998 Massachusetts Institute of Technology
    3  * Copyright 2012 ADARA Networks, Inc.
    4  * Copyright 2017 Dell EMC Isilon
    5  *
    6  * Portions of this software were developed by Robert N. M. Watson under
    7  * contract to ADARA Networks, Inc.
    8  *
    9  * Permission to use, copy, modify, and distribute this software and
   10  * its documentation for any purpose and without fee is hereby
   11  * granted, provided that both the above copyright notice and this
   12  * permission notice appear in all copies, that both the above
   13  * copyright notice and this permission notice appear in all
   14  * supporting documentation, and that the name of M.I.T. not be used
   15  * in advertising or publicity pertaining to distribution of the
   16  * software without specific, written prior permission.  M.I.T. makes
   17  * no representations about the suitability of this software for any
   18  * purpose.  It is provided "as is" without express or implied
   19  * warranty.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
   22  * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
   23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
   25  * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   29  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs.
   37  * This is sort of sneaky in the implementation, since
   38  * we need to pretend to be enough of an Ethernet implementation
   39  * to make arp work.  The way we do this is by telling everyone
   40  * that we are an Ethernet, and then catch the packets that
   41  * ether_output() sends to us via if_transmit(), rewrite them for
   42  * use by the real outgoing interface, and ask it to send them.
   43  */
   44 
   45 #include <sys/cdefs.h>
   46 __FBSDID("$FreeBSD$");
   47 
   48 #include "opt_inet.h"
   49 #include "opt_inet6.h"
   50 #include "opt_kern_tls.h"
   51 #include "opt_vlan.h"
   52 #include "opt_ratelimit.h"
   53 
   54 #include <sys/param.h>
   55 #include <sys/eventhandler.h>
   56 #include <sys/kernel.h>
   57 #include <sys/lock.h>
   58 #include <sys/malloc.h>
   59 #include <sys/mbuf.h>
   60 #include <sys/module.h>
   61 #include <sys/rmlock.h>
   62 #include <sys/priv.h>
   63 #include <sys/queue.h>
   64 #include <sys/socket.h>
   65 #include <sys/sockio.h>
   66 #include <sys/sysctl.h>
   67 #include <sys/systm.h>
   68 #include <sys/sx.h>
   69 #include <sys/taskqueue.h>
   70 
   71 #include <net/bpf.h>
   72 #include <net/ethernet.h>
   73 #include <net/if.h>
   74 #include <net/if_var.h>
   75 #include <net/if_private.h>
   76 #include <net/if_clone.h>
   77 #include <net/if_dl.h>
   78 #include <net/if_types.h>
   79 #include <net/if_vlan_var.h>
   80 #include <net/route.h>
   81 #include <net/vnet.h>
   82 
   83 #ifdef INET
   84 #include <netinet/in.h>
   85 #include <netinet/if_ether.h>
   86 #endif
   87 
   88 #ifdef INET6
   89 /*
   90  * XXX: declare here to avoid to include many inet6 related files..
   91  * should be more generalized?
   92  */
   93 extern void     nd6_setmtu(struct ifnet *);
   94 #endif
   95 
   96 #define VLAN_DEF_HWIDTH 4
   97 #define VLAN_IFFLAGS    (IFF_BROADCAST | IFF_MULTICAST)
   98 
   99 #define UP_AND_RUNNING(ifp) \
  100     ((ifp)->if_flags & IFF_UP && (ifp)->if_drv_flags & IFF_DRV_RUNNING)
  101 
  102 CK_SLIST_HEAD(ifvlanhead, ifvlan);
  103 
  104 struct ifvlantrunk {
  105         struct  ifnet   *parent;        /* parent interface of this trunk */
  106         struct  mtx     lock;
  107 #ifdef VLAN_ARRAY
  108 #define VLAN_ARRAY_SIZE (EVL_VLID_MASK + 1)
  109         struct  ifvlan  *vlans[VLAN_ARRAY_SIZE]; /* static table */
  110 #else
  111         struct  ifvlanhead *hash;       /* dynamic hash-list table */
  112         uint16_t        hmask;
  113         uint16_t        hwidth;
  114 #endif
  115         int             refcnt;
  116 };
  117 
  118 #if defined(KERN_TLS) || defined(RATELIMIT)
  119 struct vlan_snd_tag {
  120         struct m_snd_tag com;
  121         struct m_snd_tag *tag;
  122 };
  123 
  124 static inline struct vlan_snd_tag *
  125 mst_to_vst(struct m_snd_tag *mst)
  126 {
  127 
  128         return (__containerof(mst, struct vlan_snd_tag, com));
  129 }
  130 #endif
  131 
  132 /*
  133  * This macro provides a facility to iterate over every vlan on a trunk with
  134  * the assumption that none will be added/removed during iteration.
  135  */
  136 #ifdef VLAN_ARRAY
  137 #define VLAN_FOREACH(_ifv, _trunk) \
  138         size_t _i; \
  139         for (_i = 0; _i < VLAN_ARRAY_SIZE; _i++) \
  140                 if (((_ifv) = (_trunk)->vlans[_i]) != NULL)
  141 #else /* VLAN_ARRAY */
  142 #define VLAN_FOREACH(_ifv, _trunk) \
  143         struct ifvlan *_next; \
  144         size_t _i; \
  145         for (_i = 0; _i < (1 << (_trunk)->hwidth); _i++) \
  146                 CK_SLIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next)
  147 #endif /* VLAN_ARRAY */
  148 
  149 /*
  150  * This macro provides a facility to iterate over every vlan on a trunk while
  151  * also modifying the number of vlans on the trunk. The iteration continues
  152  * until some condition is met or there are no more vlans on the trunk.
  153  */
  154 #ifdef VLAN_ARRAY
  155 /* The VLAN_ARRAY case is simple -- just a for loop using the condition. */
  156 #define VLAN_FOREACH_UNTIL_SAFE(_ifv, _trunk, _cond) \
  157         size_t _i; \
  158         for (_i = 0; !(_cond) && _i < VLAN_ARRAY_SIZE; _i++) \
  159                 if (((_ifv) = (_trunk)->vlans[_i]))
  160 #else /* VLAN_ARRAY */
  161 /*
  162  * The hash table case is more complicated. We allow for the hash table to be
  163  * modified (i.e. vlans removed) while we are iterating over it. To allow for
  164  * this we must restart the iteration every time we "touch" something during
  165  * the iteration, since removal will resize the hash table and invalidate our
  166  * current position. If acting on the touched element causes the trunk to be
  167  * emptied, then iteration also stops.
  168  */
  169 #define VLAN_FOREACH_UNTIL_SAFE(_ifv, _trunk, _cond) \
  170         size_t _i; \
  171         bool _touch = false; \
  172         for (_i = 0; \
  173             !(_cond) && _i < (1 << (_trunk)->hwidth); \
  174             _i = (_touch && ((_trunk) != NULL) ? 0 : _i + 1), _touch = false) \
  175                 if (((_ifv) = CK_SLIST_FIRST(&(_trunk)->hash[_i])) != NULL && \
  176                     (_touch = true))
  177 #endif /* VLAN_ARRAY */
  178 
  179 struct vlan_mc_entry {
  180         struct sockaddr_dl              mc_addr;
  181         CK_SLIST_ENTRY(vlan_mc_entry)   mc_entries;
  182         struct epoch_context            mc_epoch_ctx;
  183 };
  184 
  185 struct ifvlan {
  186         struct  ifvlantrunk *ifv_trunk;
  187         struct  ifnet *ifv_ifp;
  188 #define TRUNK(ifv)      ((ifv)->ifv_trunk)
  189 #define PARENT(ifv)     (TRUNK(ifv)->parent)
  190         void    *ifv_cookie;
  191         int     ifv_pflags;     /* special flags we have set on parent */
  192         int     ifv_capenable;
  193         int     ifv_encaplen;   /* encapsulation length */
  194         int     ifv_mtufudge;   /* MTU fudged by this much */
  195         int     ifv_mintu;      /* min transmission unit */
  196         struct  ether_8021q_tag ifv_qtag;
  197 #define ifv_proto       ifv_qtag.proto
  198 #define ifv_vid         ifv_qtag.vid
  199 #define ifv_pcp         ifv_qtag.pcp
  200         struct task lladdr_task;
  201         CK_SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead;
  202 #ifndef VLAN_ARRAY
  203         CK_SLIST_ENTRY(ifvlan) ifv_list;
  204 #endif
  205 };
  206 
  207 /* Special flags we should propagate to parent. */
  208 static struct {
  209         int flag;
  210         int (*func)(struct ifnet *, int);
  211 } vlan_pflags[] = {
  212         {IFF_PROMISC, ifpromisc},
  213         {IFF_ALLMULTI, if_allmulti},
  214         {0, NULL}
  215 };
  216 
  217 VNET_DECLARE(int, vlan_mtag_pcp);
  218 #define V_vlan_mtag_pcp VNET(vlan_mtag_pcp)
  219 
  220 static const char vlanname[] = "vlan";
  221 static MALLOC_DEFINE(M_VLAN, vlanname, "802.1Q Virtual LAN Interface");
  222 
  223 static eventhandler_tag ifdetach_tag;
  224 static eventhandler_tag iflladdr_tag;
  225 static eventhandler_tag ifevent_tag;
  226 
  227 /*
  228  * if_vlan uses two module-level synchronizations primitives to allow concurrent
  229  * modification of vlan interfaces and (mostly) allow for vlans to be destroyed
  230  * while they are being used for tx/rx. To accomplish this in a way that has
  231  * acceptable performance and cooperation with other parts of the network stack
  232  * there is a non-sleepable epoch(9) and an sx(9).
  233  *
  234  * The performance-sensitive paths that warrant using the epoch(9) are
  235  * vlan_transmit and vlan_input. Both have to check for the vlan interface's
  236  * existence using if_vlantrunk, and being in the network tx/rx paths the use
  237  * of an epoch(9) gives a measureable improvement in performance.
  238  *
  239  * The reason for having an sx(9) is mostly because there are still areas that
  240  * must be sleepable and also have safe concurrent access to a vlan interface.
  241  * Since the sx(9) exists, it is used by default in most paths unless sleeping
  242  * is not permitted, or if it is not clear whether sleeping is permitted.
  243  *
  244  */
  245 #define _VLAN_SX_ID ifv_sx
  246 
  247 static struct sx _VLAN_SX_ID;
  248 
  249 #define VLAN_LOCKING_INIT() \
  250         sx_init_flags(&_VLAN_SX_ID, "vlan_sx", SX_RECURSE)
  251 
  252 #define VLAN_LOCKING_DESTROY() \
  253         sx_destroy(&_VLAN_SX_ID)
  254 
  255 #define VLAN_SLOCK()                    sx_slock(&_VLAN_SX_ID)
  256 #define VLAN_SUNLOCK()                  sx_sunlock(&_VLAN_SX_ID)
  257 #define VLAN_XLOCK()                    sx_xlock(&_VLAN_SX_ID)
  258 #define VLAN_XUNLOCK()                  sx_xunlock(&_VLAN_SX_ID)
  259 #define VLAN_SLOCK_ASSERT()             sx_assert(&_VLAN_SX_ID, SA_SLOCKED)
  260 #define VLAN_XLOCK_ASSERT()             sx_assert(&_VLAN_SX_ID, SA_XLOCKED)
  261 #define VLAN_SXLOCK_ASSERT()            sx_assert(&_VLAN_SX_ID, SA_LOCKED)
  262 
  263 /*
  264  * We also have a per-trunk mutex that should be acquired when changing
  265  * its state.
  266  */
  267 #define TRUNK_LOCK_INIT(trunk)          mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF)
  268 #define TRUNK_LOCK_DESTROY(trunk)       mtx_destroy(&(trunk)->lock)
  269 #define TRUNK_WLOCK(trunk)              mtx_lock(&(trunk)->lock)
  270 #define TRUNK_WUNLOCK(trunk)            mtx_unlock(&(trunk)->lock)
  271 #define TRUNK_WLOCK_ASSERT(trunk)       mtx_assert(&(trunk)->lock, MA_OWNED);
  272 
  273 /*
  274  * The VLAN_ARRAY substitutes the dynamic hash with a static array
  275  * with 4096 entries. In theory this can give a boost in processing,
  276  * however in practice it does not. Probably this is because the array
  277  * is too big to fit into CPU cache.
  278  */
  279 #ifndef VLAN_ARRAY
  280 static  void vlan_inithash(struct ifvlantrunk *trunk);
  281 static  void vlan_freehash(struct ifvlantrunk *trunk);
  282 static  int vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv);
  283 static  int vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv);
  284 static  void vlan_growhash(struct ifvlantrunk *trunk, int howmuch);
  285 static __inline struct ifvlan * vlan_gethash(struct ifvlantrunk *trunk,
  286         uint16_t vid);
  287 #endif
  288 static  void trunk_destroy(struct ifvlantrunk *trunk);
  289 
  290 static  void vlan_init(void *foo);
  291 static  void vlan_input(struct ifnet *ifp, struct mbuf *m);
  292 static  int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
  293 #if defined(KERN_TLS) || defined(RATELIMIT)
  294 static  int vlan_snd_tag_alloc(struct ifnet *,
  295     union if_snd_tag_alloc_params *, struct m_snd_tag **);
  296 static  int vlan_snd_tag_modify(struct m_snd_tag *,
  297     union if_snd_tag_modify_params *);
  298 static  int vlan_snd_tag_query(struct m_snd_tag *,
  299     union if_snd_tag_query_params *);
  300 static  void vlan_snd_tag_free(struct m_snd_tag *);
  301 static struct m_snd_tag *vlan_next_snd_tag(struct m_snd_tag *);
  302 static void vlan_ratelimit_query(struct ifnet *,
  303     struct if_ratelimit_query_results *);
  304 #endif
  305 static  void vlan_qflush(struct ifnet *ifp);
  306 static  int vlan_setflag(struct ifnet *ifp, int flag, int status,
  307     int (*func)(struct ifnet *, int));
  308 static  int vlan_setflags(struct ifnet *ifp, int status);
  309 static  int vlan_setmulti(struct ifnet *ifp);
  310 static  int vlan_transmit(struct ifnet *ifp, struct mbuf *m);
  311 #ifdef ALTQ
  312 static void vlan_altq_start(struct ifnet *ifp);
  313 static  int vlan_altq_transmit(struct ifnet *ifp, struct mbuf *m);
  314 #endif
  315 static  int vlan_output(struct ifnet *ifp, struct mbuf *m,
  316     const struct sockaddr *dst, struct route *ro);
  317 static  void vlan_unconfig(struct ifnet *ifp);
  318 static  void vlan_unconfig_locked(struct ifnet *ifp, int departing);
  319 static  int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag,
  320         uint16_t proto);
  321 static  void vlan_link_state(struct ifnet *ifp);
  322 static  void vlan_capabilities(struct ifvlan *ifv);
  323 static  void vlan_trunk_capabilities(struct ifnet *ifp);
  324 
  325 static  struct ifnet *vlan_clone_match_ethervid(const char *, int *);
  326 static  int vlan_clone_match(struct if_clone *, const char *);
  327 static  int vlan_clone_create(struct if_clone *, char *, size_t,
  328     struct ifc_data *, struct ifnet **);
  329 static  int vlan_clone_destroy(struct if_clone *, struct ifnet *, uint32_t);
  330 
  331 static  void vlan_ifdetach(void *arg, struct ifnet *ifp);
  332 static  void vlan_iflladdr(void *arg, struct ifnet *ifp);
  333 static  void vlan_ifevent(void *arg, struct ifnet *ifp, int event);
  334 
  335 static  void vlan_lladdr_fn(void *arg, int pending);
  336 
  337 static struct if_clone *vlan_cloner;
  338 
  339 #ifdef VIMAGE
  340 VNET_DEFINE_STATIC(struct if_clone *, vlan_cloner);
  341 #define V_vlan_cloner   VNET(vlan_cloner)
  342 #endif
  343 
  344 #ifdef RATELIMIT
  345 static const struct if_snd_tag_sw vlan_snd_tag_ul_sw = {
  346         .snd_tag_modify = vlan_snd_tag_modify,
  347         .snd_tag_query = vlan_snd_tag_query,
  348         .snd_tag_free = vlan_snd_tag_free,
  349         .next_snd_tag = vlan_next_snd_tag,
  350         .type = IF_SND_TAG_TYPE_UNLIMITED
  351 };
  352 
  353 static const struct if_snd_tag_sw vlan_snd_tag_rl_sw = {
  354         .snd_tag_modify = vlan_snd_tag_modify,
  355         .snd_tag_query = vlan_snd_tag_query,
  356         .snd_tag_free = vlan_snd_tag_free,
  357         .next_snd_tag = vlan_next_snd_tag,
  358         .type = IF_SND_TAG_TYPE_RATE_LIMIT
  359 };
  360 #endif
  361 
  362 #ifdef KERN_TLS
  363 static const struct if_snd_tag_sw vlan_snd_tag_tls_sw = {
  364         .snd_tag_modify = vlan_snd_tag_modify,
  365         .snd_tag_query = vlan_snd_tag_query,
  366         .snd_tag_free = vlan_snd_tag_free,
  367         .next_snd_tag = vlan_next_snd_tag,
  368         .type = IF_SND_TAG_TYPE_TLS
  369 };
  370 
  371 #ifdef RATELIMIT
  372 static const struct if_snd_tag_sw vlan_snd_tag_tls_rl_sw = {
  373         .snd_tag_modify = vlan_snd_tag_modify,
  374         .snd_tag_query = vlan_snd_tag_query,
  375         .snd_tag_free = vlan_snd_tag_free,
  376         .next_snd_tag = vlan_next_snd_tag,
  377         .type = IF_SND_TAG_TYPE_TLS_RATE_LIMIT
  378 };
  379 #endif
  380 #endif
  381 
  382 static void
  383 vlan_mc_free(struct epoch_context *ctx)
  384 {
  385         struct vlan_mc_entry *mc = __containerof(ctx, struct vlan_mc_entry, mc_epoch_ctx);
  386         free(mc, M_VLAN);
  387 }
  388 
  389 #ifndef VLAN_ARRAY
  390 #define HASH(n, m)      ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
  391 
  392 static void
  393 vlan_inithash(struct ifvlantrunk *trunk)
  394 {
  395         int i, n;
  396 
  397         /*
  398          * The trunk must not be locked here since we call malloc(M_WAITOK).
  399          * It is OK in case this function is called before the trunk struct
  400          * gets hooked up and becomes visible from other threads.
  401          */
  402 
  403         KASSERT(trunk->hwidth == 0 && trunk->hash == NULL,
  404             ("%s: hash already initialized", __func__));
  405 
  406         trunk->hwidth = VLAN_DEF_HWIDTH;
  407         n = 1 << trunk->hwidth;
  408         trunk->hmask = n - 1;
  409         trunk->hash = malloc(sizeof(struct ifvlanhead) * n, M_VLAN, M_WAITOK);
  410         for (i = 0; i < n; i++)
  411                 CK_SLIST_INIT(&trunk->hash[i]);
  412 }
  413 
  414 static void
  415 vlan_freehash(struct ifvlantrunk *trunk)
  416 {
  417 #ifdef INVARIANTS
  418         int i;
  419 
  420         KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
  421         for (i = 0; i < (1 << trunk->hwidth); i++)
  422                 KASSERT(CK_SLIST_EMPTY(&trunk->hash[i]),
  423                     ("%s: hash table not empty", __func__));
  424 #endif
  425         free(trunk->hash, M_VLAN);
  426         trunk->hash = NULL;
  427         trunk->hwidth = trunk->hmask = 0;
  428 }
  429 
  430 static int
  431 vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
  432 {
  433         int i, b;
  434         struct ifvlan *ifv2;
  435 
  436         VLAN_XLOCK_ASSERT();
  437         KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
  438 
  439         b = 1 << trunk->hwidth;
  440         i = HASH(ifv->ifv_vid, trunk->hmask);
  441         CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
  442                 if (ifv->ifv_vid == ifv2->ifv_vid)
  443                         return (EEXIST);
  444 
  445         /*
  446          * Grow the hash when the number of vlans exceeds half of the number of
  447          * hash buckets squared. This will make the average linked-list length
  448          * buckets/2.
  449          */
  450         if (trunk->refcnt > (b * b) / 2) {
  451                 vlan_growhash(trunk, 1);
  452                 i = HASH(ifv->ifv_vid, trunk->hmask);
  453         }
  454         CK_SLIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list);
  455         trunk->refcnt++;
  456 
  457         return (0);
  458 }
  459 
  460 static int
  461 vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
  462 {
  463         int i, b;
  464         struct ifvlan *ifv2;
  465 
  466         VLAN_XLOCK_ASSERT();
  467         KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
  468 
  469         b = 1 << (trunk->hwidth - 1);
  470         i = HASH(ifv->ifv_vid, trunk->hmask);
  471         CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
  472                 if (ifv2 == ifv) {
  473                         trunk->refcnt--;
  474                         CK_SLIST_REMOVE(&trunk->hash[i], ifv2, ifvlan, ifv_list);
  475                         if (trunk->refcnt < (b * b) / 2)
  476                                 vlan_growhash(trunk, -1);
  477                         return (0);
  478                 }
  479 
  480         panic("%s: vlan not found\n", __func__);
  481         return (ENOENT); /*NOTREACHED*/
  482 }
  483 
  484 /*
  485  * Grow the hash larger or smaller if memory permits.
  486  */
  487 static void
  488 vlan_growhash(struct ifvlantrunk *trunk, int howmuch)
  489 {
  490         struct ifvlan *ifv;
  491         struct ifvlanhead *hash2;
  492         int hwidth2, i, j, n, n2;
  493 
  494         VLAN_XLOCK_ASSERT();
  495         KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
  496 
  497         if (howmuch == 0) {
  498                 /* Harmless yet obvious coding error */
  499                 printf("%s: howmuch is 0\n", __func__);
  500                 return;
  501         }
  502 
  503         hwidth2 = trunk->hwidth + howmuch;
  504         n = 1 << trunk->hwidth;
  505         n2 = 1 << hwidth2;
  506         /* Do not shrink the table below the default */
  507         if (hwidth2 < VLAN_DEF_HWIDTH)
  508                 return;
  509 
  510         hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_WAITOK);
  511         if (hash2 == NULL) {
  512                 printf("%s: out of memory -- hash size not changed\n",
  513                     __func__);
  514                 return;         /* We can live with the old hash table */
  515         }
  516         for (j = 0; j < n2; j++)
  517                 CK_SLIST_INIT(&hash2[j]);
  518         for (i = 0; i < n; i++)
  519                 while ((ifv = CK_SLIST_FIRST(&trunk->hash[i])) != NULL) {
  520                         CK_SLIST_REMOVE(&trunk->hash[i], ifv, ifvlan, ifv_list);
  521                         j = HASH(ifv->ifv_vid, n2 - 1);
  522                         CK_SLIST_INSERT_HEAD(&hash2[j], ifv, ifv_list);
  523                 }
  524         NET_EPOCH_WAIT();
  525         free(trunk->hash, M_VLAN);
  526         trunk->hash = hash2;
  527         trunk->hwidth = hwidth2;
  528         trunk->hmask = n2 - 1;
  529 
  530         if (bootverbose)
  531                 if_printf(trunk->parent,
  532                     "VLAN hash table resized from %d to %d buckets\n", n, n2);
  533 }
  534 
  535 static __inline struct ifvlan *
  536 vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid)
  537 {
  538         struct ifvlan *ifv;
  539 
  540         NET_EPOCH_ASSERT();
  541 
  542         CK_SLIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list)
  543                 if (ifv->ifv_vid == vid)
  544                         return (ifv);
  545         return (NULL);
  546 }
  547 
  548 #if 0
  549 /* Debugging code to view the hashtables. */
  550 static void
  551 vlan_dumphash(struct ifvlantrunk *trunk)
  552 {
  553         int i;
  554         struct ifvlan *ifv;
  555 
  556         for (i = 0; i < (1 << trunk->hwidth); i++) {
  557                 printf("%d: ", i);
  558                 CK_SLIST_FOREACH(ifv, &trunk->hash[i], ifv_list)
  559                         printf("%s ", ifv->ifv_ifp->if_xname);
  560                 printf("\n");
  561         }
  562 }
  563 #endif /* 0 */
  564 #else
  565 
  566 static __inline struct ifvlan *
  567 vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid)
  568 {
  569 
  570         return trunk->vlans[vid];
  571 }
  572 
  573 static __inline int
  574 vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
  575 {
  576 
  577         if (trunk->vlans[ifv->ifv_vid] != NULL)
  578                 return EEXIST;
  579         trunk->vlans[ifv->ifv_vid] = ifv;
  580         trunk->refcnt++;
  581 
  582         return (0);
  583 }
  584 
  585 static __inline int
  586 vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv)
  587 {
  588 
  589         trunk->vlans[ifv->ifv_vid] = NULL;
  590         trunk->refcnt--;
  591 
  592         return (0);
  593 }
  594 
  595 static __inline void
  596 vlan_freehash(struct ifvlantrunk *trunk)
  597 {
  598 }
  599 
  600 static __inline void
  601 vlan_inithash(struct ifvlantrunk *trunk)
  602 {
  603 }
  604 
  605 #endif /* !VLAN_ARRAY */
  606 
  607 static void
  608 trunk_destroy(struct ifvlantrunk *trunk)
  609 {
  610         VLAN_XLOCK_ASSERT();
  611 
  612         vlan_freehash(trunk);
  613         trunk->parent->if_vlantrunk = NULL;
  614         TRUNK_LOCK_DESTROY(trunk);
  615         if_rele(trunk->parent);
  616         free(trunk, M_VLAN);
  617 }
  618 
  619 /*
  620  * Program our multicast filter. What we're actually doing is
  621  * programming the multicast filter of the parent. This has the
  622  * side effect of causing the parent interface to receive multicast
  623  * traffic that it doesn't really want, which ends up being discarded
  624  * later by the upper protocol layers. Unfortunately, there's no way
  625  * to avoid this: there really is only one physical interface.
  626  */
  627 static int
  628 vlan_setmulti(struct ifnet *ifp)
  629 {
  630         struct ifnet            *ifp_p;
  631         struct ifmultiaddr      *ifma;
  632         struct ifvlan           *sc;
  633         struct vlan_mc_entry    *mc;
  634         int                     error;
  635 
  636         VLAN_XLOCK_ASSERT();
  637 
  638         /* Find the parent. */
  639         sc = ifp->if_softc;
  640         ifp_p = PARENT(sc);
  641 
  642         CURVNET_SET_QUIET(ifp_p->if_vnet);
  643 
  644         /* First, remove any existing filter entries. */
  645         while ((mc = CK_SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) {
  646                 CK_SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
  647                 (void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr);
  648                 NET_EPOCH_CALL(vlan_mc_free, &mc->mc_epoch_ctx);
  649         }
  650 
  651         /* Now program new ones. */
  652         IF_ADDR_WLOCK(ifp);
  653         CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
  654                 if (ifma->ifma_addr->sa_family != AF_LINK)
  655                         continue;
  656                 mc = malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_NOWAIT);
  657                 if (mc == NULL) {
  658                         IF_ADDR_WUNLOCK(ifp);
  659                         CURVNET_RESTORE();
  660                         return (ENOMEM);
  661                 }
  662                 bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len);
  663                 mc->mc_addr.sdl_index = ifp_p->if_index;
  664                 CK_SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
  665         }
  666         IF_ADDR_WUNLOCK(ifp);
  667         CK_SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) {
  668                 error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr,
  669                     NULL);
  670                 if (error) {
  671                         CURVNET_RESTORE();
  672                         return (error);
  673                 }
  674         }
  675 
  676         CURVNET_RESTORE();
  677         return (0);
  678 }
  679 
  680 /*
  681  * A handler for interface ifnet events.
  682  */
  683 static void
  684 vlan_ifevent(void *arg __unused, struct ifnet *ifp, int event)
  685 {
  686         struct epoch_tracker et;
  687         struct ifvlan *ifv;
  688         struct ifvlantrunk *trunk;
  689 
  690         if (event != IFNET_EVENT_UPDATE_BAUDRATE)
  691                 return;
  692 
  693         NET_EPOCH_ENTER(et);
  694         trunk = ifp->if_vlantrunk;
  695         if (trunk == NULL) {
  696                 NET_EPOCH_EXIT(et);
  697                 return;
  698         }
  699 
  700         TRUNK_WLOCK(trunk);
  701         VLAN_FOREACH(ifv, trunk) {
  702                 ifv->ifv_ifp->if_baudrate = ifp->if_baudrate;
  703         }
  704         TRUNK_WUNLOCK(trunk);
  705         NET_EPOCH_EXIT(et);
  706 }
  707 
  708 /*
  709  * A handler for parent interface link layer address changes.
  710  * If the parent interface link layer address is changed we
  711  * should also change it on all children vlans.
  712  */
  713 static void
  714 vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
  715 {
  716         struct epoch_tracker et;
  717         struct ifvlan *ifv;
  718         struct ifnet *ifv_ifp;
  719         struct ifvlantrunk *trunk;
  720         struct sockaddr_dl *sdl;
  721 
  722         /* Need the epoch since this is run on taskqueue_swi. */
  723         NET_EPOCH_ENTER(et);
  724         trunk = ifp->if_vlantrunk;
  725         if (trunk == NULL) {
  726                 NET_EPOCH_EXIT(et);
  727                 return;
  728         }
  729 
  730         /*
  731          * OK, it's a trunk.  Loop over and change all vlan's lladdrs on it.
  732          * We need an exclusive lock here to prevent concurrent SIOCSIFLLADDR
  733          * ioctl calls on the parent garbling the lladdr of the child vlan.
  734          */
  735         TRUNK_WLOCK(trunk);
  736         VLAN_FOREACH(ifv, trunk) {
  737                 /*
  738                  * Copy new new lladdr into the ifv_ifp, enqueue a task
  739                  * to actually call if_setlladdr. if_setlladdr needs to
  740                  * be deferred to a taskqueue because it will call into
  741                  * the if_vlan ioctl path and try to acquire the global
  742                  * lock.
  743                  */
  744                 ifv_ifp = ifv->ifv_ifp;
  745                 bcopy(IF_LLADDR(ifp), IF_LLADDR(ifv_ifp),
  746                     ifp->if_addrlen);
  747                 sdl = (struct sockaddr_dl *)ifv_ifp->if_addr->ifa_addr;
  748                 sdl->sdl_alen = ifp->if_addrlen;
  749                 taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
  750         }
  751         TRUNK_WUNLOCK(trunk);
  752         NET_EPOCH_EXIT(et);
  753 }
  754 
  755 /*
  756  * A handler for network interface departure events.
  757  * Track departure of trunks here so that we don't access invalid
  758  * pointers or whatever if a trunk is ripped from under us, e.g.,
  759  * by ejecting its hot-plug card.  However, if an ifnet is simply
  760  * being renamed, then there's no need to tear down the state.
  761  */
  762 static void
  763 vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
  764 {
  765         struct ifvlan *ifv;
  766         struct ifvlantrunk *trunk;
  767 
  768         /* If the ifnet is just being renamed, don't do anything. */
  769         if (ifp->if_flags & IFF_RENAMING)
  770                 return;
  771         VLAN_XLOCK();
  772         trunk = ifp->if_vlantrunk;
  773         if (trunk == NULL) {
  774                 VLAN_XUNLOCK();
  775                 return;
  776         }
  777 
  778         /*
  779          * OK, it's a trunk.  Loop over and detach all vlan's on it.
  780          * Check trunk pointer after each vlan_unconfig() as it will
  781          * free it and set to NULL after the last vlan was detached.
  782          */
  783         VLAN_FOREACH_UNTIL_SAFE(ifv, ifp->if_vlantrunk,
  784             ifp->if_vlantrunk == NULL)
  785                 vlan_unconfig_locked(ifv->ifv_ifp, 1);
  786 
  787         /* Trunk should have been destroyed in vlan_unconfig(). */
  788         KASSERT(ifp->if_vlantrunk == NULL, ("%s: purge failed", __func__));
  789         VLAN_XUNLOCK();
  790 }
  791 
  792 /*
  793  * Return the trunk device for a virtual interface.
  794  */
  795 static struct ifnet  *
  796 vlan_trunkdev(struct ifnet *ifp)
  797 {
  798         struct ifvlan *ifv;
  799 
  800         NET_EPOCH_ASSERT();
  801 
  802         if (ifp->if_type != IFT_L2VLAN)
  803                 return (NULL);
  804 
  805         ifv = ifp->if_softc;
  806         ifp = NULL;
  807         if (ifv->ifv_trunk)
  808                 ifp = PARENT(ifv);
  809         return (ifp);
  810 }
  811 
  812 /*
  813  * Return the 12-bit VLAN VID for this interface, for use by external
  814  * components such as Infiniband.
  815  *
  816  * XXXRW: Note that the function name here is historical; it should be named
  817  * vlan_vid().
  818  */
  819 static int
  820 vlan_tag(struct ifnet *ifp, uint16_t *vidp)
  821 {
  822         struct ifvlan *ifv;
  823 
  824         if (ifp->if_type != IFT_L2VLAN)
  825                 return (EINVAL);
  826         ifv = ifp->if_softc;
  827         *vidp = ifv->ifv_vid;
  828         return (0);
  829 }
  830 
  831 static int
  832 vlan_pcp(struct ifnet *ifp, uint16_t *pcpp)
  833 {
  834         struct ifvlan *ifv;
  835 
  836         if (ifp->if_type != IFT_L2VLAN)
  837                 return (EINVAL);
  838         ifv = ifp->if_softc;
  839         *pcpp = ifv->ifv_pcp;
  840         return (0);
  841 }
  842 
  843 /*
  844  * Return a driver specific cookie for this interface.  Synchronization
  845  * with setcookie must be provided by the driver.
  846  */
  847 static void *
  848 vlan_cookie(struct ifnet *ifp)
  849 {
  850         struct ifvlan *ifv;
  851 
  852         if (ifp->if_type != IFT_L2VLAN)
  853                 return (NULL);
  854         ifv = ifp->if_softc;
  855         return (ifv->ifv_cookie);
  856 }
  857 
  858 /*
  859  * Store a cookie in our softc that drivers can use to store driver
  860  * private per-instance data in.
  861  */
  862 static int
  863 vlan_setcookie(struct ifnet *ifp, void *cookie)
  864 {
  865         struct ifvlan *ifv;
  866 
  867         if (ifp->if_type != IFT_L2VLAN)
  868                 return (EINVAL);
  869         ifv = ifp->if_softc;
  870         ifv->ifv_cookie = cookie;
  871         return (0);
  872 }
  873 
  874 /*
  875  * Return the vlan device present at the specific VID.
  876  */
  877 static struct ifnet *
  878 vlan_devat(struct ifnet *ifp, uint16_t vid)
  879 {
  880         struct ifvlantrunk *trunk;
  881         struct ifvlan *ifv;
  882 
  883         NET_EPOCH_ASSERT();
  884 
  885         trunk = ifp->if_vlantrunk;
  886         if (trunk == NULL)
  887                 return (NULL);
  888         ifp = NULL;
  889         ifv = vlan_gethash(trunk, vid);
  890         if (ifv)
  891                 ifp = ifv->ifv_ifp;
  892         return (ifp);
  893 }
  894 
  895 /*
  896  * VLAN support can be loaded as a module.  The only place in the
  897  * system that's intimately aware of this is ether_input.  We hook
  898  * into this code through vlan_input_p which is defined there and
  899  * set here.  No one else in the system should be aware of this so
  900  * we use an explicit reference here.
  901  */
  902 extern  void (*vlan_input_p)(struct ifnet *, struct mbuf *);
  903 
  904 /* For if_link_state_change() eyes only... */
  905 extern  void (*vlan_link_state_p)(struct ifnet *);
  906 
  907 static struct if_clone_addreq vlan_addreq = {
  908         .match_f = vlan_clone_match,
  909         .create_f = vlan_clone_create,
  910         .destroy_f = vlan_clone_destroy,
  911 };
  912 
  913 static int
  914 vlan_modevent(module_t mod, int type, void *data)
  915 {
  916 
  917         switch (type) {
  918         case MOD_LOAD:
  919                 ifdetach_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
  920                     vlan_ifdetach, NULL, EVENTHANDLER_PRI_ANY);
  921                 if (ifdetach_tag == NULL)
  922                         return (ENOMEM);
  923                 iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
  924                     vlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
  925                 if (iflladdr_tag == NULL)
  926                         return (ENOMEM);
  927                 ifevent_tag = EVENTHANDLER_REGISTER(ifnet_event,
  928                     vlan_ifevent, NULL, EVENTHANDLER_PRI_ANY);
  929                 if (ifevent_tag == NULL)
  930                         return (ENOMEM);
  931                 VLAN_LOCKING_INIT();
  932                 vlan_input_p = vlan_input;
  933                 vlan_link_state_p = vlan_link_state;
  934                 vlan_trunk_cap_p = vlan_trunk_capabilities;
  935                 vlan_trunkdev_p = vlan_trunkdev;
  936                 vlan_cookie_p = vlan_cookie;
  937                 vlan_setcookie_p = vlan_setcookie;
  938                 vlan_tag_p = vlan_tag;
  939                 vlan_pcp_p = vlan_pcp;
  940                 vlan_devat_p = vlan_devat;
  941 #ifndef VIMAGE
  942                 vlan_cloner = ifc_attach_cloner(vlanname, &vlan_addreq);
  943 #endif
  944                 if (bootverbose)
  945                         printf("vlan: initialized, using "
  946 #ifdef VLAN_ARRAY
  947                                "full-size arrays"
  948 #else
  949                                "hash tables with chaining"
  950 #endif
  951 
  952                                "\n");
  953                 break;
  954         case MOD_UNLOAD:
  955 #ifndef VIMAGE
  956                 ifc_detach_cloner(vlan_cloner);
  957 #endif
  958                 EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
  959                 EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
  960                 EVENTHANDLER_DEREGISTER(ifnet_event, ifevent_tag);
  961                 vlan_input_p = NULL;
  962                 vlan_link_state_p = NULL;
  963                 vlan_trunk_cap_p = NULL;
  964                 vlan_trunkdev_p = NULL;
  965                 vlan_tag_p = NULL;
  966                 vlan_cookie_p = NULL;
  967                 vlan_setcookie_p = NULL;
  968                 vlan_devat_p = NULL;
  969                 VLAN_LOCKING_DESTROY();
  970                 if (bootverbose)
  971                         printf("vlan: unloaded\n");
  972                 break;
  973         default:
  974                 return (EOPNOTSUPP);
  975         }
  976         return (0);
  977 }
  978 
  979 static moduledata_t vlan_mod = {
  980         "if_vlan",
  981         vlan_modevent,
  982         0
  983 };
  984 
  985 DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  986 MODULE_VERSION(if_vlan, 3);
  987 
  988 #ifdef VIMAGE
  989 static void
  990 vnet_vlan_init(const void *unused __unused)
  991 {
  992         vlan_cloner = ifc_attach_cloner(vlanname, &vlan_addreq);
  993         V_vlan_cloner = vlan_cloner;
  994 }
  995 VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
  996     vnet_vlan_init, NULL);
  997 
  998 static void
  999 vnet_vlan_uninit(const void *unused __unused)
 1000 {
 1001 
 1002         ifc_detach_cloner(V_vlan_cloner);
 1003 }
 1004 VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_INIT_IF, SI_ORDER_ANY,
 1005     vnet_vlan_uninit, NULL);
 1006 #endif
 1007 
 1008 /*
 1009  * Check for <etherif>.<vlan>[.<vlan> ...] style interface names.
 1010  */
 1011 static struct ifnet *
 1012 vlan_clone_match_ethervid(const char *name, int *vidp)
 1013 {
 1014         char ifname[IFNAMSIZ];
 1015         char *cp;
 1016         struct ifnet *ifp;
 1017         int vid;
 1018 
 1019         strlcpy(ifname, name, IFNAMSIZ);
 1020         if ((cp = strrchr(ifname, '.')) == NULL)
 1021                 return (NULL);
 1022         *cp = '\0';
 1023         if ((ifp = ifunit_ref(ifname)) == NULL)
 1024                 return (NULL);
 1025         /* Parse VID. */
 1026         if (*++cp == '\0') {
 1027                 if_rele(ifp);
 1028                 return (NULL);
 1029         }
 1030         vid = 0;
 1031         for(; *cp >= '' && *cp <= '9'; cp++)
 1032                 vid = (vid * 10) + (*cp - '');
 1033         if (*cp != '\0') {
 1034                 if_rele(ifp);
 1035                 return (NULL);
 1036         }
 1037         if (vidp != NULL)
 1038                 *vidp = vid;
 1039 
 1040         return (ifp);
 1041 }
 1042 
 1043 static int
 1044 vlan_clone_match(struct if_clone *ifc, const char *name)
 1045 {
 1046         struct ifnet *ifp;
 1047         const char *cp;
 1048 
 1049         ifp = vlan_clone_match_ethervid(name, NULL);
 1050         if (ifp != NULL) {
 1051                 if_rele(ifp);
 1052                 return (1);
 1053         }
 1054 
 1055         if (strncmp(vlanname, name, strlen(vlanname)) != 0)
 1056                 return (0);
 1057         for (cp = name + 4; *cp != '\0'; cp++) {
 1058                 if (*cp < '' || *cp > '9')
 1059                         return (0);
 1060         }
 1061 
 1062         return (1);
 1063 }
 1064 
 1065 static int
 1066 vlan_clone_create(struct if_clone *ifc, char *name, size_t len,
 1067     struct ifc_data *ifd, struct ifnet **ifpp)
 1068 {
 1069         char *dp;
 1070         bool wildcard = false;
 1071         bool subinterface = false;
 1072         int unit;
 1073         int error;
 1074         int vid = 0;
 1075         uint16_t proto = ETHERTYPE_VLAN;
 1076         struct ifvlan *ifv;
 1077         struct ifnet *ifp;
 1078         struct ifnet *p = NULL;
 1079         struct ifaddr *ifa;
 1080         struct sockaddr_dl *sdl;
 1081         struct vlanreq vlr;
 1082         static const u_char eaddr[ETHER_ADDR_LEN];      /* 00:00:00:00:00:00 */
 1083 
 1084 
 1085         /*
 1086          * There are three ways to specify the cloned device:
 1087          * o pass a parameter block with the clone request.
 1088          * o specify parameters in the text of the clone device name
 1089          * o specify no parameters and get an unattached device that
 1090          *   must be configured separately.
 1091          * The first technique is preferred; the latter two are supported
 1092          * for backwards compatibility.
 1093          *
 1094          * XXXRW: Note historic use of the word "tag" here.  New ioctls may be
 1095          * called for.
 1096          */
 1097 
 1098         if (ifd->params != NULL) {
 1099                 error = ifc_copyin(ifd, &vlr, sizeof(vlr));
 1100                 if (error)
 1101                         return error;
 1102                 vid = vlr.vlr_tag;
 1103                 proto = vlr.vlr_proto;
 1104 
 1105 #ifdef COMPAT_FREEBSD12
 1106                 if (proto == 0)
 1107                         proto = ETHERTYPE_VLAN;
 1108 #endif
 1109                 p = ifunit_ref(vlr.vlr_parent);
 1110                 if (p == NULL)
 1111                         return (ENXIO);
 1112         }
 1113 
 1114         if ((error = ifc_name2unit(name, &unit)) == 0) {
 1115 
 1116                 /*
 1117                  * vlanX interface. Set wildcard to true if the unit number
 1118                  * is not fixed (-1)
 1119                  */
 1120                 wildcard = (unit < 0);
 1121         } else {
 1122                 struct ifnet *p_tmp = vlan_clone_match_ethervid(name, &vid);
 1123                 if (p_tmp != NULL) {
 1124                         error = 0;
 1125                         subinterface = true;
 1126                         unit = IF_DUNIT_NONE;
 1127                         wildcard = false;
 1128                         if (p != NULL) {
 1129                                 if_rele(p_tmp);
 1130                                 if (p != p_tmp)
 1131                                         error = EINVAL;
 1132                         } else
 1133                                 p = p_tmp;
 1134                 } else
 1135                         error = ENXIO;
 1136         }
 1137 
 1138         if (error != 0) {
 1139                 if (p != NULL)
 1140                         if_rele(p);
 1141                 return (error);
 1142         }
 1143 
 1144         if (!subinterface) {
 1145                 /* vlanX interface, mark X as busy or allocate new unit # */
 1146                 error = ifc_alloc_unit(ifc, &unit);
 1147                 if (error != 0) {
 1148                         if (p != NULL)
 1149                                 if_rele(p);
 1150                         return (error);
 1151                 }
 1152         }
 1153 
 1154         /* In the wildcard case, we need to update the name. */
 1155         if (wildcard) {
 1156                 for (dp = name; *dp != '\0'; dp++);
 1157                 if (snprintf(dp, len - (dp-name), "%d", unit) >
 1158                     len - (dp-name) - 1) {
 1159                         panic("%s: interface name too long", __func__);
 1160                 }
 1161         }
 1162 
 1163         ifv = malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO);
 1164         ifp = ifv->ifv_ifp = if_alloc(IFT_ETHER);
 1165         if (ifp == NULL) {
 1166                 if (!subinterface)
 1167                         ifc_free_unit(ifc, unit);
 1168                 free(ifv, M_VLAN);
 1169                 if (p != NULL)
 1170                         if_rele(p);
 1171                 return (ENOSPC);
 1172         }
 1173         CK_SLIST_INIT(&ifv->vlan_mc_listhead);
 1174         ifp->if_softc = ifv;
 1175         /*
 1176          * Set the name manually rather than using if_initname because
 1177          * we don't conform to the default naming convention for interfaces.
 1178          */
 1179         strlcpy(ifp->if_xname, name, IFNAMSIZ);
 1180         ifp->if_dname = vlanname;
 1181         ifp->if_dunit = unit;
 1182 
 1183         ifp->if_init = vlan_init;
 1184 #ifdef ALTQ
 1185         ifp->if_start = vlan_altq_start;
 1186         ifp->if_transmit = vlan_altq_transmit;
 1187         IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
 1188         ifp->if_snd.ifq_drv_maxlen = 0;
 1189         IFQ_SET_READY(&ifp->if_snd);
 1190 #else
 1191         ifp->if_transmit = vlan_transmit;
 1192 #endif
 1193         ifp->if_qflush = vlan_qflush;
 1194         ifp->if_ioctl = vlan_ioctl;
 1195 #if defined(KERN_TLS) || defined(RATELIMIT)
 1196         ifp->if_snd_tag_alloc = vlan_snd_tag_alloc;
 1197         ifp->if_ratelimit_query = vlan_ratelimit_query;
 1198 #endif
 1199         ifp->if_flags = VLAN_IFFLAGS;
 1200         ether_ifattach(ifp, eaddr);
 1201         /* Now undo some of the damage... */
 1202         ifp->if_baudrate = 0;
 1203         ifp->if_type = IFT_L2VLAN;
 1204         ifp->if_hdrlen = ETHER_VLAN_ENCAP_LEN;
 1205         ifa = ifp->if_addr;
 1206         sdl = (struct sockaddr_dl *)ifa->ifa_addr;
 1207         sdl->sdl_type = IFT_L2VLAN;
 1208 
 1209         if (p != NULL) {
 1210                 error = vlan_config(ifv, p, vid, proto);
 1211                 if_rele(p);
 1212                 if (error != 0) {
 1213                         /*
 1214                          * Since we've partially failed, we need to back
 1215                          * out all the way, otherwise userland could get
 1216                          * confused.  Thus, we destroy the interface.
 1217                          */
 1218                         ether_ifdetach(ifp);
 1219                         vlan_unconfig(ifp);
 1220                         if_free(ifp);
 1221                         if (!subinterface)
 1222                                 ifc_free_unit(ifc, unit);
 1223                         free(ifv, M_VLAN);
 1224 
 1225                         return (error);
 1226                 }
 1227         }
 1228         *ifpp = ifp;
 1229 
 1230         return (0);
 1231 }
 1232 
 1233 static int
 1234 vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags)
 1235 {
 1236         struct ifvlan *ifv = ifp->if_softc;
 1237         int unit = ifp->if_dunit;
 1238 
 1239         if (ifp->if_vlantrunk)
 1240                 return (EBUSY);
 1241 
 1242 #ifdef ALTQ
 1243         IFQ_PURGE(&ifp->if_snd);
 1244 #endif
 1245         ether_ifdetach(ifp);    /* first, remove it from system-wide lists */
 1246         vlan_unconfig(ifp);     /* now it can be unconfigured and freed */
 1247         /*
 1248          * We should have the only reference to the ifv now, so we can now
 1249          * drain any remaining lladdr task before freeing the ifnet and the
 1250          * ifvlan.
 1251          */
 1252         taskqueue_drain(taskqueue_thread, &ifv->lladdr_task);
 1253         NET_EPOCH_WAIT();
 1254         if_free(ifp);
 1255         free(ifv, M_VLAN);
 1256         if (unit != IF_DUNIT_NONE)
 1257                 ifc_free_unit(ifc, unit);
 1258 
 1259         return (0);
 1260 }
 1261 
 1262 /*
 1263  * The ifp->if_init entry point for vlan(4) is a no-op.
 1264  */
 1265 static void
 1266 vlan_init(void *foo __unused)
 1267 {
 1268 }
 1269 
 1270 /*
 1271  * The if_transmit method for vlan(4) interface.
 1272  */
 1273 static int
 1274 vlan_transmit(struct ifnet *ifp, struct mbuf *m)
 1275 {
 1276         struct ifvlan *ifv;
 1277         struct ifnet *p;
 1278         int error, len, mcast;
 1279 
 1280         NET_EPOCH_ASSERT();
 1281 
 1282         ifv = ifp->if_softc;
 1283         if (TRUNK(ifv) == NULL) {
 1284                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 1285                 m_freem(m);
 1286                 return (ENETDOWN);
 1287         }
 1288         p = PARENT(ifv);
 1289         len = m->m_pkthdr.len;
 1290         mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0;
 1291 
 1292         BPF_MTAP(ifp, m);
 1293 
 1294 #if defined(KERN_TLS) || defined(RATELIMIT)
 1295         if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) {
 1296                 struct vlan_snd_tag *vst;
 1297                 struct m_snd_tag *mst;
 1298 
 1299                 MPASS(m->m_pkthdr.snd_tag->ifp == ifp);
 1300                 mst = m->m_pkthdr.snd_tag;
 1301                 vst = mst_to_vst(mst);
 1302                 if (vst->tag->ifp != p) {
 1303                         if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 1304                         m_freem(m);
 1305                         return (EAGAIN);
 1306                 }
 1307 
 1308                 m->m_pkthdr.snd_tag = m_snd_tag_ref(vst->tag);
 1309                 m_snd_tag_rele(mst);
 1310         }
 1311 #endif
 1312 
 1313         /*
 1314          * Do not run parent's if_transmit() if the parent is not up,
 1315          * or parent's driver will cause a system crash.
 1316          */
 1317         if (!UP_AND_RUNNING(p)) {
 1318                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 1319                 m_freem(m);
 1320                 return (ENETDOWN);
 1321         }
 1322 
 1323         if (!ether_8021q_frame(&m, ifp, p, &ifv->ifv_qtag)) {
 1324                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 1325                 return (0);
 1326         }
 1327 
 1328         /*
 1329          * Send it, precisely as ether_output() would have.
 1330          */
 1331         error = (p->if_transmit)(p, m);
 1332         if (error == 0) {
 1333                 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 1334                 if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
 1335                 if_inc_counter(ifp, IFCOUNTER_OMCASTS, mcast);
 1336         } else
 1337                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 1338         return (error);
 1339 }
 1340 
 1341 static int
 1342 vlan_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
 1343     struct route *ro)
 1344 {
 1345         struct ifvlan *ifv;
 1346         struct ifnet *p;
 1347 
 1348         NET_EPOCH_ASSERT();
 1349 
 1350         /*
 1351          * Find the first non-VLAN parent interface.
 1352          */
 1353         ifv = ifp->if_softc;
 1354         do {
 1355                 if (TRUNK(ifv) == NULL) {
 1356                         m_freem(m);
 1357                         return (ENETDOWN);
 1358                 }
 1359                 p = PARENT(ifv);
 1360                 ifv = p->if_softc;
 1361         } while (p->if_type == IFT_L2VLAN);
 1362 
 1363         return p->if_output(ifp, m, dst, ro);
 1364 }
 1365 
 1366 #ifdef ALTQ
 1367 static void
 1368 vlan_altq_start(if_t ifp)
 1369 {
 1370         struct ifaltq *ifq = &ifp->if_snd;
 1371         struct mbuf *m;
 1372 
 1373         IFQ_LOCK(ifq);
 1374         IFQ_DEQUEUE_NOLOCK(ifq, m);
 1375         while (m != NULL) {
 1376                 vlan_transmit(ifp, m);
 1377                 IFQ_DEQUEUE_NOLOCK(ifq, m);
 1378         }
 1379         IFQ_UNLOCK(ifq);
 1380 }
 1381 
 1382 static int
 1383 vlan_altq_transmit(if_t ifp, struct mbuf *m)
 1384 {
 1385         int err;
 1386 
 1387         if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
 1388                 IFQ_ENQUEUE(&ifp->if_snd, m, err);
 1389                 if (err == 0)
 1390                         vlan_altq_start(ifp);
 1391         } else
 1392                 err = vlan_transmit(ifp, m);
 1393 
 1394         return (err);
 1395 }
 1396 #endif  /* ALTQ */
 1397 
 1398 /*
 1399  * The ifp->if_qflush entry point for vlan(4) is a no-op.
 1400  */
 1401 static void
 1402 vlan_qflush(struct ifnet *ifp __unused)
 1403 {
 1404 }
 1405 
 1406 static void
 1407 vlan_input(struct ifnet *ifp, struct mbuf *m)
 1408 {
 1409         struct ifvlantrunk *trunk;
 1410         struct ifvlan *ifv;
 1411         struct m_tag *mtag;
 1412         uint16_t vid, tag;
 1413 
 1414         NET_EPOCH_ASSERT();
 1415 
 1416         trunk = ifp->if_vlantrunk;
 1417         if (trunk == NULL) {
 1418                 m_freem(m);
 1419                 return;
 1420         }
 1421 
 1422         if (m->m_flags & M_VLANTAG) {
 1423                 /*
 1424                  * Packet is tagged, but m contains a normal
 1425                  * Ethernet frame; the tag is stored out-of-band.
 1426                  */
 1427                 tag = m->m_pkthdr.ether_vtag;
 1428                 m->m_flags &= ~M_VLANTAG;
 1429         } else {
 1430                 struct ether_vlan_header *evl;
 1431 
 1432                 /*
 1433                  * Packet is tagged in-band as specified by 802.1q.
 1434                  */
 1435                 switch (ifp->if_type) {
 1436                 case IFT_ETHER:
 1437                         if (m->m_len < sizeof(*evl) &&
 1438                             (m = m_pullup(m, sizeof(*evl))) == NULL) {
 1439                                 if_printf(ifp, "cannot pullup VLAN header\n");
 1440                                 return;
 1441                         }
 1442                         evl = mtod(m, struct ether_vlan_header *);
 1443                         tag = ntohs(evl->evl_tag);
 1444 
 1445                         /*
 1446                          * Remove the 802.1q header by copying the Ethernet
 1447                          * addresses over it and adjusting the beginning of
 1448                          * the data in the mbuf.  The encapsulated Ethernet
 1449                          * type field is already in place.
 1450                          */
 1451                         bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
 1452                               ETHER_HDR_LEN - ETHER_TYPE_LEN);
 1453                         m_adj(m, ETHER_VLAN_ENCAP_LEN);
 1454                         break;
 1455 
 1456                 default:
 1457 #ifdef INVARIANTS
 1458                         panic("%s: %s has unsupported if_type %u",
 1459                               __func__, ifp->if_xname, ifp->if_type);
 1460 #endif
 1461                         if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
 1462                         m_freem(m);
 1463                         return;
 1464                 }
 1465         }
 1466 
 1467         vid = EVL_VLANOFTAG(tag);
 1468 
 1469         ifv = vlan_gethash(trunk, vid);
 1470         if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) {
 1471                 if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
 1472                 m_freem(m);
 1473                 return;
 1474         }
 1475 
 1476         if (V_vlan_mtag_pcp) {
 1477                 /*
 1478                  * While uncommon, it is possible that we will find a 802.1q
 1479                  * packet encapsulated inside another packet that also had an
 1480                  * 802.1q header.  For example, ethernet tunneled over IPSEC
 1481                  * arriving over ethernet.  In that case, we replace the
 1482                  * existing 802.1q PCP m_tag value.
 1483                  */
 1484                 mtag = m_tag_locate(m, MTAG_8021Q, MTAG_8021Q_PCP_IN, NULL);
 1485                 if (mtag == NULL) {
 1486                         mtag = m_tag_alloc(MTAG_8021Q, MTAG_8021Q_PCP_IN,
 1487                             sizeof(uint8_t), M_NOWAIT);
 1488                         if (mtag == NULL) {
 1489                                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
 1490                                 m_freem(m);
 1491                                 return;
 1492                         }
 1493                         m_tag_prepend(m, mtag);
 1494                 }
 1495                 *(uint8_t *)(mtag + 1) = EVL_PRIOFTAG(tag);
 1496         }
 1497 
 1498         m->m_pkthdr.rcvif = ifv->ifv_ifp;
 1499         if_inc_counter(ifv->ifv_ifp, IFCOUNTER_IPACKETS, 1);
 1500 
 1501         /* Pass it back through the parent's input routine. */
 1502         (*ifv->ifv_ifp->if_input)(ifv->ifv_ifp, m);
 1503 }
 1504 
 1505 static void
 1506 vlan_lladdr_fn(void *arg, int pending __unused)
 1507 {
 1508         struct ifvlan *ifv;
 1509         struct ifnet *ifp;
 1510 
 1511         ifv = (struct ifvlan *)arg;
 1512         ifp = ifv->ifv_ifp;
 1513 
 1514         CURVNET_SET(ifp->if_vnet);
 1515 
 1516         /* The ifv_ifp already has the lladdr copied in. */
 1517         if_setlladdr(ifp, IF_LLADDR(ifp), ifp->if_addrlen);
 1518 
 1519         CURVNET_RESTORE();
 1520 }
 1521 
 1522 static int
 1523 vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid,
 1524         uint16_t proto)
 1525 {
 1526         struct epoch_tracker et;
 1527         struct ifvlantrunk *trunk;
 1528         struct ifnet *ifp;
 1529         int error = 0;
 1530 
 1531         /*
 1532          * We can handle non-ethernet hardware types as long as
 1533          * they handle the tagging and headers themselves.
 1534          */
 1535         if (p->if_type != IFT_ETHER &&
 1536             p->if_type != IFT_L2VLAN &&
 1537             (p->if_capenable & IFCAP_VLAN_HWTAGGING) == 0)
 1538                 return (EPROTONOSUPPORT);
 1539         if ((p->if_flags & VLAN_IFFLAGS) != VLAN_IFFLAGS)
 1540                 return (EPROTONOSUPPORT);
 1541         /*
 1542          * Don't let the caller set up a VLAN VID with
 1543          * anything except VLID bits.
 1544          * VID numbers 0x0 and 0xFFF are reserved.
 1545          */
 1546         if (vid == 0 || vid == 0xFFF || (vid & ~EVL_VLID_MASK))
 1547                 return (EINVAL);
 1548         if (ifv->ifv_trunk) {
 1549                 trunk = ifv->ifv_trunk;
 1550                 if (trunk->parent != p)
 1551                         return (EBUSY);
 1552 
 1553                 VLAN_XLOCK();
 1554 
 1555                 ifv->ifv_proto = proto;
 1556 
 1557                 if (ifv->ifv_vid != vid) {
 1558                         /* Re-hash */
 1559                         vlan_remhash(trunk, ifv);
 1560                         ifv->ifv_vid = vid;
 1561                         error = vlan_inshash(trunk, ifv);
 1562                 }
 1563                 /* Will unlock */
 1564                 goto done;
 1565         }
 1566 
 1567         VLAN_XLOCK();
 1568         if (p->if_vlantrunk == NULL) {
 1569                 trunk = malloc(sizeof(struct ifvlantrunk),
 1570                     M_VLAN, M_WAITOK | M_ZERO);
 1571                 vlan_inithash(trunk);
 1572                 TRUNK_LOCK_INIT(trunk);
 1573                 TRUNK_WLOCK(trunk);
 1574                 p->if_vlantrunk = trunk;
 1575                 trunk->parent = p;
 1576                 if_ref(trunk->parent);
 1577                 TRUNK_WUNLOCK(trunk);
 1578         } else {
 1579                 trunk = p->if_vlantrunk;
 1580         }
 1581 
 1582         ifv->ifv_vid = vid;     /* must set this before vlan_inshash() */
 1583         ifv->ifv_pcp = 0;       /* Default: best effort delivery. */
 1584         error = vlan_inshash(trunk, ifv);
 1585         if (error)
 1586                 goto done;
 1587         ifv->ifv_proto = proto;
 1588         ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN;
 1589         ifv->ifv_mintu = ETHERMIN;
 1590         ifv->ifv_pflags = 0;
 1591         ifv->ifv_capenable = -1;
 1592 
 1593         /*
 1594          * If the parent supports the VLAN_MTU capability,
 1595          * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames,
 1596          * use it.
 1597          */
 1598         if (p->if_capenable & IFCAP_VLAN_MTU) {
 1599                 /*
 1600                  * No need to fudge the MTU since the parent can
 1601                  * handle extended frames.
 1602                  */
 1603                 ifv->ifv_mtufudge = 0;
 1604         } else {
 1605                 /*
 1606                  * Fudge the MTU by the encapsulation size.  This
 1607                  * makes us incompatible with strictly compliant
 1608                  * 802.1Q implementations, but allows us to use
 1609                  * the feature with other NetBSD implementations,
 1610                  * which might still be useful.
 1611                  */
 1612                 ifv->ifv_mtufudge = ifv->ifv_encaplen;
 1613         }
 1614 
 1615         ifv->ifv_trunk = trunk;
 1616         ifp = ifv->ifv_ifp;
 1617         /*
 1618          * Initialize fields from our parent.  This duplicates some
 1619          * work with ether_ifattach() but allows for non-ethernet
 1620          * interfaces to also work.
 1621          */
 1622         ifp->if_mtu = p->if_mtu - ifv->ifv_mtufudge;
 1623         ifp->if_baudrate = p->if_baudrate;
 1624         ifp->if_input = p->if_input;
 1625         ifp->if_resolvemulti = p->if_resolvemulti;
 1626         ifp->if_addrlen = p->if_addrlen;
 1627         ifp->if_broadcastaddr = p->if_broadcastaddr;
 1628         ifp->if_pcp = ifv->ifv_pcp;
 1629 
 1630         /*
 1631          * We wrap the parent's if_output using vlan_output to ensure that it
 1632          * can't become stale.
 1633          */
 1634         ifp->if_output = vlan_output;
 1635 
 1636         /*
 1637          * Copy only a selected subset of flags from the parent.
 1638          * Other flags are none of our business.
 1639          */
 1640 #define VLAN_COPY_FLAGS (IFF_SIMPLEX)
 1641         ifp->if_flags &= ~VLAN_COPY_FLAGS;
 1642         ifp->if_flags |= p->if_flags & VLAN_COPY_FLAGS;
 1643 #undef VLAN_COPY_FLAGS
 1644 
 1645         ifp->if_link_state = p->if_link_state;
 1646 
 1647         NET_EPOCH_ENTER(et);
 1648         vlan_capabilities(ifv);
 1649         NET_EPOCH_EXIT(et);
 1650 
 1651         /*
 1652          * Set up our interface address to reflect the underlying
 1653          * physical interface's.
 1654          */
 1655         TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
 1656         ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen =
 1657             p->if_addrlen;
 1658 
 1659         /*
 1660          * Do not schedule link address update if it was the same
 1661          * as previous parent's. This helps avoid updating for each
 1662          * associated llentry.
 1663          */
 1664         if (memcmp(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen) != 0) {
 1665                 bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen);
 1666                 taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
 1667         }
 1668 
 1669         /* We are ready for operation now. */
 1670         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 1671 
 1672         /* Update flags on the parent, if necessary. */
 1673         vlan_setflags(ifp, 1);
 1674 
 1675         /*
 1676          * Configure multicast addresses that may already be
 1677          * joined on the vlan device.
 1678          */
 1679         (void)vlan_setmulti(ifp);
 1680 
 1681 done:
 1682         if (error == 0)
 1683                 EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid);
 1684         VLAN_XUNLOCK();
 1685 
 1686         return (error);
 1687 }
 1688 
 1689 static void
 1690 vlan_unconfig(struct ifnet *ifp)
 1691 {
 1692 
 1693         VLAN_XLOCK();
 1694         vlan_unconfig_locked(ifp, 0);
 1695         VLAN_XUNLOCK();
 1696 }
 1697 
 1698 static void
 1699 vlan_unconfig_locked(struct ifnet *ifp, int departing)
 1700 {
 1701         struct ifvlantrunk *trunk;
 1702         struct vlan_mc_entry *mc;
 1703         struct ifvlan *ifv;
 1704         struct ifnet  *parent;
 1705         int error;
 1706 
 1707         VLAN_XLOCK_ASSERT();
 1708 
 1709         ifv = ifp->if_softc;
 1710         trunk = ifv->ifv_trunk;
 1711         parent = NULL;
 1712 
 1713         if (trunk != NULL) {
 1714                 parent = trunk->parent;
 1715 
 1716                 /*
 1717                  * Since the interface is being unconfigured, we need to
 1718                  * empty the list of multicast groups that we may have joined
 1719                  * while we were alive from the parent's list.
 1720                  */
 1721                 while ((mc = CK_SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) {
 1722                         /*
 1723                          * If the parent interface is being detached,
 1724                          * all its multicast addresses have already
 1725                          * been removed.  Warn about errors if
 1726                          * if_delmulti() does fail, but don't abort as
 1727                          * all callers expect vlan destruction to
 1728                          * succeed.
 1729                          */
 1730                         if (!departing) {
 1731                                 error = if_delmulti(parent,
 1732                                     (struct sockaddr *)&mc->mc_addr);
 1733                                 if (error)
 1734                                         if_printf(ifp,
 1735                     "Failed to delete multicast address from parent: %d\n",
 1736                                             error);
 1737                         }
 1738                         CK_SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries);
 1739                         NET_EPOCH_CALL(vlan_mc_free, &mc->mc_epoch_ctx);
 1740                 }
 1741 
 1742                 vlan_setflags(ifp, 0); /* clear special flags on parent */
 1743 
 1744                 vlan_remhash(trunk, ifv);
 1745                 ifv->ifv_trunk = NULL;
 1746 
 1747                 /*
 1748                  * Check if we were the last.
 1749                  */
 1750                 if (trunk->refcnt == 0) {
 1751                         parent->if_vlantrunk = NULL;
 1752                         NET_EPOCH_WAIT();
 1753                         trunk_destroy(trunk);
 1754                 }
 1755         }
 1756 
 1757         /* Disconnect from parent. */
 1758         if (ifv->ifv_pflags)
 1759                 if_printf(ifp, "%s: ifv_pflags unclean\n", __func__);
 1760         ifp->if_mtu = ETHERMTU;
 1761         ifp->if_link_state = LINK_STATE_UNKNOWN;
 1762         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 1763 
 1764         /*
 1765          * Only dispatch an event if vlan was
 1766          * attached, otherwise there is nothing
 1767          * to cleanup anyway.
 1768          */
 1769         if (parent != NULL)
 1770                 EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_vid);
 1771 }
 1772 
 1773 /* Handle a reference counted flag that should be set on the parent as well */
 1774 static int
 1775 vlan_setflag(struct ifnet *ifp, int flag, int status,
 1776              int (*func)(struct ifnet *, int))
 1777 {
 1778         struct ifvlan *ifv;
 1779         int error;
 1780 
 1781         VLAN_SXLOCK_ASSERT();
 1782 
 1783         ifv = ifp->if_softc;
 1784         status = status ? (ifp->if_flags & flag) : 0;
 1785         /* Now "status" contains the flag value or 0 */
 1786 
 1787         /*
 1788          * See if recorded parent's status is different from what
 1789          * we want it to be.  If it is, flip it.  We record parent's
 1790          * status in ifv_pflags so that we won't clear parent's flag
 1791          * we haven't set.  In fact, we don't clear or set parent's
 1792          * flags directly, but get or release references to them.
 1793          * That's why we can be sure that recorded flags still are
 1794          * in accord with actual parent's flags.
 1795          */
 1796         if (status != (ifv->ifv_pflags & flag)) {
 1797                 error = (*func)(PARENT(ifv), status);
 1798                 if (error)
 1799                         return (error);
 1800                 ifv->ifv_pflags &= ~flag;
 1801                 ifv->ifv_pflags |= status;
 1802         }
 1803         return (0);
 1804 }
 1805 
 1806 /*
 1807  * Handle IFF_* flags that require certain changes on the parent:
 1808  * if "status" is true, update parent's flags respective to our if_flags;
 1809  * if "status" is false, forcedly clear the flags set on parent.
 1810  */
 1811 static int
 1812 vlan_setflags(struct ifnet *ifp, int status)
 1813 {
 1814         int error, i;
 1815 
 1816         for (i = 0; vlan_pflags[i].flag; i++) {
 1817                 error = vlan_setflag(ifp, vlan_pflags[i].flag,
 1818                                      status, vlan_pflags[i].func);
 1819                 if (error)
 1820                         return (error);
 1821         }
 1822         return (0);
 1823 }
 1824 
 1825 /* Inform all vlans that their parent has changed link state */
 1826 static void
 1827 vlan_link_state(struct ifnet *ifp)
 1828 {
 1829         struct epoch_tracker et;
 1830         struct ifvlantrunk *trunk;
 1831         struct ifvlan *ifv;
 1832 
 1833         NET_EPOCH_ENTER(et);
 1834         trunk = ifp->if_vlantrunk;
 1835         if (trunk == NULL) {
 1836                 NET_EPOCH_EXIT(et);
 1837                 return;
 1838         }
 1839 
 1840         TRUNK_WLOCK(trunk);
 1841         VLAN_FOREACH(ifv, trunk) {
 1842                 ifv->ifv_ifp->if_baudrate = trunk->parent->if_baudrate;
 1843                 if_link_state_change(ifv->ifv_ifp,
 1844                     trunk->parent->if_link_state);
 1845         }
 1846         TRUNK_WUNLOCK(trunk);
 1847         NET_EPOCH_EXIT(et);
 1848 }
 1849 
 1850 static void
 1851 vlan_capabilities(struct ifvlan *ifv)
 1852 {
 1853         struct ifnet *p;
 1854         struct ifnet *ifp;
 1855         struct ifnet_hw_tsomax hw_tsomax;
 1856         int cap = 0, ena = 0, mena;
 1857         u_long hwa = 0;
 1858 
 1859         NET_EPOCH_ASSERT();
 1860         VLAN_SXLOCK_ASSERT();
 1861 
 1862         p = PARENT(ifv);
 1863         ifp = ifv->ifv_ifp;
 1864 
 1865         /* Mask parent interface enabled capabilities disabled by user. */
 1866         mena = p->if_capenable & ifv->ifv_capenable;
 1867 
 1868         /*
 1869          * If the parent interface can do checksum offloading
 1870          * on VLANs, then propagate its hardware-assisted
 1871          * checksumming flags. Also assert that checksum
 1872          * offloading requires hardware VLAN tagging.
 1873          */
 1874         if (p->if_capabilities & IFCAP_VLAN_HWCSUM)
 1875                 cap |= p->if_capabilities & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
 1876         if (p->if_capenable & IFCAP_VLAN_HWCSUM &&
 1877             p->if_capenable & IFCAP_VLAN_HWTAGGING) {
 1878                 ena |= mena & (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6);
 1879                 if (ena & IFCAP_TXCSUM)
 1880                         hwa |= p->if_hwassist & (CSUM_IP | CSUM_TCP |
 1881                             CSUM_UDP | CSUM_SCTP);
 1882                 if (ena & IFCAP_TXCSUM_IPV6)
 1883                         hwa |= p->if_hwassist & (CSUM_TCP_IPV6 |
 1884                             CSUM_UDP_IPV6 | CSUM_SCTP_IPV6);
 1885         }
 1886 
 1887         /*
 1888          * If the parent interface can do TSO on VLANs then
 1889          * propagate the hardware-assisted flag. TSO on VLANs
 1890          * does not necessarily require hardware VLAN tagging.
 1891          */
 1892         memset(&hw_tsomax, 0, sizeof(hw_tsomax));
 1893         if_hw_tsomax_common(p, &hw_tsomax);
 1894         if_hw_tsomax_update(ifp, &hw_tsomax);
 1895         if (p->if_capabilities & IFCAP_VLAN_HWTSO)
 1896                 cap |= p->if_capabilities & IFCAP_TSO;
 1897         if (p->if_capenable & IFCAP_VLAN_HWTSO) {
 1898                 ena |= mena & IFCAP_TSO;
 1899                 if (ena & IFCAP_TSO)
 1900                         hwa |= p->if_hwassist & CSUM_TSO;
 1901         }
 1902 
 1903         /*
 1904          * If the parent interface can do LRO and checksum offloading on
 1905          * VLANs, then guess it may do LRO on VLANs.  False positive here
 1906          * cost nothing, while false negative may lead to some confusions.
 1907          */
 1908         if (p->if_capabilities & IFCAP_VLAN_HWCSUM)
 1909                 cap |= p->if_capabilities & IFCAP_LRO;
 1910         if (p->if_capenable & IFCAP_VLAN_HWCSUM)
 1911                 ena |= p->if_capenable & IFCAP_LRO;
 1912 
 1913         /*
 1914          * If the parent interface can offload TCP connections over VLANs then
 1915          * propagate its TOE capability to the VLAN interface.
 1916          *
 1917          * All TOE drivers in the tree today can deal with VLANs.  If this
 1918          * changes then IFCAP_VLAN_TOE should be promoted to a full capability
 1919          * with its own bit.
 1920          */
 1921 #define IFCAP_VLAN_TOE IFCAP_TOE
 1922         if (p->if_capabilities & IFCAP_VLAN_TOE)
 1923                 cap |= p->if_capabilities & IFCAP_TOE;
 1924         if (p->if_capenable & IFCAP_VLAN_TOE) {
 1925                 TOEDEV(ifp) = TOEDEV(p);
 1926                 ena |= mena & IFCAP_TOE;
 1927         }
 1928 
 1929         /*
 1930          * If the parent interface supports dynamic link state, so does the
 1931          * VLAN interface.
 1932          */
 1933         cap |= (p->if_capabilities & IFCAP_LINKSTATE);
 1934         ena |= (mena & IFCAP_LINKSTATE);
 1935 
 1936 #ifdef RATELIMIT
 1937         /*
 1938          * If the parent interface supports ratelimiting, so does the
 1939          * VLAN interface.
 1940          */
 1941         cap |= (p->if_capabilities & IFCAP_TXRTLMT);
 1942         ena |= (mena & IFCAP_TXRTLMT);
 1943 #endif
 1944 
 1945         /*
 1946          * If the parent interface supports unmapped mbufs, so does
 1947          * the VLAN interface.  Note that this should be fine even for
 1948          * interfaces that don't support hardware tagging as headers
 1949          * are prepended in normal mbufs to unmapped mbufs holding
 1950          * payload data.
 1951          */
 1952         cap |= (p->if_capabilities & IFCAP_MEXTPG);
 1953         ena |= (mena & IFCAP_MEXTPG);
 1954 
 1955         /*
 1956          * If the parent interface can offload encryption and segmentation
 1957          * of TLS records over TCP, propagate it's capability to the VLAN
 1958          * interface.
 1959          *
 1960          * All TLS drivers in the tree today can deal with VLANs.  If
 1961          * this ever changes, then a new IFCAP_VLAN_TXTLS can be
 1962          * defined.
 1963          */
 1964         if (p->if_capabilities & (IFCAP_TXTLS | IFCAP_TXTLS_RTLMT))
 1965                 cap |= p->if_capabilities & (IFCAP_TXTLS | IFCAP_TXTLS_RTLMT);
 1966         if (p->if_capenable & (IFCAP_TXTLS | IFCAP_TXTLS_RTLMT))
 1967                 ena |= mena & (IFCAP_TXTLS | IFCAP_TXTLS_RTLMT);
 1968 
 1969         ifp->if_capabilities = cap;
 1970         ifp->if_capenable = ena;
 1971         ifp->if_hwassist = hwa;
 1972 }
 1973 
 1974 static void
 1975 vlan_trunk_capabilities(struct ifnet *ifp)
 1976 {
 1977         struct epoch_tracker et;
 1978         struct ifvlantrunk *trunk;
 1979         struct ifvlan *ifv;
 1980 
 1981         VLAN_SLOCK();
 1982         trunk = ifp->if_vlantrunk;
 1983         if (trunk == NULL) {
 1984                 VLAN_SUNLOCK();
 1985                 return;
 1986         }
 1987         NET_EPOCH_ENTER(et);
 1988         VLAN_FOREACH(ifv, trunk)
 1989                 vlan_capabilities(ifv);
 1990         NET_EPOCH_EXIT(et);
 1991         VLAN_SUNLOCK();
 1992 }
 1993 
 1994 static int
 1995 vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1996 {
 1997         struct ifnet *p;
 1998         struct ifreq *ifr;
 1999 #ifdef INET
 2000         struct ifaddr *ifa;
 2001 #endif
 2002         struct ifvlan *ifv;
 2003         struct ifvlantrunk *trunk;
 2004         struct vlanreq vlr;
 2005         int error = 0, oldmtu;
 2006 
 2007         ifr = (struct ifreq *)data;
 2008 #ifdef INET
 2009         ifa = (struct ifaddr *) data;
 2010 #endif
 2011         ifv = ifp->if_softc;
 2012 
 2013         switch (cmd) {
 2014         case SIOCSIFADDR:
 2015                 ifp->if_flags |= IFF_UP;
 2016 #ifdef INET
 2017                 if (ifa->ifa_addr->sa_family == AF_INET)
 2018                         arp_ifinit(ifp, ifa);
 2019 #endif
 2020                 break;
 2021         case SIOCGIFADDR:
 2022                 bcopy(IF_LLADDR(ifp), &ifr->ifr_addr.sa_data[0],
 2023                     ifp->if_addrlen);
 2024                 break;
 2025         case SIOCGIFMEDIA:
 2026                 VLAN_SLOCK();
 2027                 if (TRUNK(ifv) != NULL) {
 2028                         p = PARENT(ifv);
 2029                         if_ref(p);
 2030                         error = (*p->if_ioctl)(p, SIOCGIFMEDIA, data);
 2031                         if_rele(p);
 2032                         /* Limit the result to the parent's current config. */
 2033                         if (error == 0) {
 2034                                 struct ifmediareq *ifmr;
 2035 
 2036                                 ifmr = (struct ifmediareq *)data;
 2037                                 if (ifmr->ifm_count >= 1 && ifmr->ifm_ulist) {
 2038                                         ifmr->ifm_count = 1;
 2039                                         error = copyout(&ifmr->ifm_current,
 2040                                                 ifmr->ifm_ulist,
 2041                                                 sizeof(int));
 2042                                 }
 2043                         }
 2044                 } else {
 2045                         error = EINVAL;
 2046                 }
 2047                 VLAN_SUNLOCK();
 2048                 break;
 2049 
 2050         case SIOCSIFMEDIA:
 2051                 error = EINVAL;
 2052                 break;
 2053 
 2054         case SIOCSIFMTU:
 2055                 /*
 2056                  * Set the interface MTU.
 2057                  */
 2058                 VLAN_SLOCK();
 2059                 trunk = TRUNK(ifv);
 2060                 if (trunk != NULL) {
 2061                         TRUNK_WLOCK(trunk);
 2062                         if (ifr->ifr_mtu >
 2063                              (PARENT(ifv)->if_mtu - ifv->ifv_mtufudge) ||
 2064                             ifr->ifr_mtu <
 2065                              (ifv->ifv_mintu - ifv->ifv_mtufudge))
 2066                                 error = EINVAL;
 2067                         else
 2068                                 ifp->if_mtu = ifr->ifr_mtu;
 2069                         TRUNK_WUNLOCK(trunk);
 2070                 } else
 2071                         error = EINVAL;
 2072                 VLAN_SUNLOCK();
 2073                 break;
 2074 
 2075         case SIOCSETVLAN:
 2076 #ifdef VIMAGE
 2077                 /*
 2078                  * XXXRW/XXXBZ: The goal in these checks is to allow a VLAN
 2079                  * interface to be delegated to a jail without allowing the
 2080                  * jail to change what underlying interface/VID it is
 2081                  * associated with.  We are not entirely convinced that this
 2082                  * is the right way to accomplish that policy goal.
 2083                  */
 2084                 if (ifp->if_vnet != ifp->if_home_vnet) {
 2085                         error = EPERM;
 2086                         break;
 2087                 }
 2088 #endif
 2089                 error = copyin(ifr_data_get_ptr(ifr), &vlr, sizeof(vlr));
 2090                 if (error)
 2091                         break;
 2092                 if (vlr.vlr_parent[0] == '\0') {
 2093                         vlan_unconfig(ifp);
 2094                         break;
 2095                 }
 2096                 p = ifunit_ref(vlr.vlr_parent);
 2097                 if (p == NULL) {
 2098                         error = ENOENT;
 2099                         break;
 2100                 }
 2101 #ifdef COMPAT_FREEBSD12
 2102                 if (vlr.vlr_proto == 0)
 2103                         vlr.vlr_proto = ETHERTYPE_VLAN;
 2104 #endif
 2105                 oldmtu = ifp->if_mtu;
 2106                 error = vlan_config(ifv, p, vlr.vlr_tag, vlr.vlr_proto);
 2107                 if_rele(p);
 2108 
 2109                 /*
 2110                  * VLAN MTU may change during addition of the vlandev.
 2111                  * If it did, do network layer specific procedure.
 2112                  */
 2113                 if (ifp->if_mtu != oldmtu) {
 2114 #ifdef INET6
 2115                         nd6_setmtu(ifp);
 2116 #endif
 2117                         rt_updatemtu(ifp);
 2118                 }
 2119                 break;
 2120 
 2121         case SIOCGETVLAN:
 2122 #ifdef VIMAGE
 2123                 if (ifp->if_vnet != ifp->if_home_vnet) {
 2124                         error = EPERM;
 2125                         break;
 2126                 }
 2127 #endif
 2128                 bzero(&vlr, sizeof(vlr));
 2129                 VLAN_SLOCK();
 2130                 if (TRUNK(ifv) != NULL) {
 2131                         strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname,
 2132                             sizeof(vlr.vlr_parent));
 2133                         vlr.vlr_tag = ifv->ifv_vid;
 2134                         vlr.vlr_proto = ifv->ifv_proto;
 2135                 }
 2136                 VLAN_SUNLOCK();
 2137                 error = copyout(&vlr, ifr_data_get_ptr(ifr), sizeof(vlr));
 2138                 break;
 2139 
 2140         case SIOCSIFFLAGS:
 2141                 /*
 2142                  * We should propagate selected flags to the parent,
 2143                  * e.g., promiscuous mode.
 2144                  */
 2145                 VLAN_XLOCK();
 2146                 if (TRUNK(ifv) != NULL)
 2147                         error = vlan_setflags(ifp, 1);
 2148                 VLAN_XUNLOCK();
 2149                 break;
 2150 
 2151         case SIOCADDMULTI:
 2152         case SIOCDELMULTI:
 2153                 /*
 2154                  * If we don't have a parent, just remember the membership for
 2155                  * when we do.
 2156                  *
 2157                  * XXX We need the rmlock here to avoid sleeping while
 2158                  * holding in6_multi_mtx.
 2159                  */
 2160                 VLAN_XLOCK();
 2161                 trunk = TRUNK(ifv);
 2162                 if (trunk != NULL)
 2163                         error = vlan_setmulti(ifp);
 2164                 VLAN_XUNLOCK();
 2165 
 2166                 break;
 2167         case SIOCGVLANPCP:
 2168 #ifdef VIMAGE
 2169                 if (ifp->if_vnet != ifp->if_home_vnet) {
 2170                         error = EPERM;
 2171                         break;
 2172                 }
 2173 #endif
 2174                 ifr->ifr_vlan_pcp = ifv->ifv_pcp;
 2175                 break;
 2176 
 2177         case SIOCSVLANPCP:
 2178 #ifdef VIMAGE
 2179                 if (ifp->if_vnet != ifp->if_home_vnet) {
 2180                         error = EPERM;
 2181                         break;
 2182                 }
 2183 #endif
 2184                 error = priv_check(curthread, PRIV_NET_SETVLANPCP);
 2185                 if (error)
 2186                         break;
 2187                 if (ifr->ifr_vlan_pcp > VLAN_PCP_MAX) {
 2188                         error = EINVAL;
 2189                         break;
 2190                 }
 2191                 ifv->ifv_pcp = ifr->ifr_vlan_pcp;
 2192                 ifp->if_pcp = ifv->ifv_pcp;
 2193                 /* broadcast event about PCP change */
 2194                 EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_PCP);
 2195                 break;
 2196 
 2197         case SIOCSIFCAP:
 2198                 VLAN_SLOCK();
 2199                 ifv->ifv_capenable = ifr->ifr_reqcap;
 2200                 trunk = TRUNK(ifv);
 2201                 if (trunk != NULL) {
 2202                         struct epoch_tracker et;
 2203 
 2204                         NET_EPOCH_ENTER(et);
 2205                         vlan_capabilities(ifv);
 2206                         NET_EPOCH_EXIT(et);
 2207                 }
 2208                 VLAN_SUNLOCK();
 2209                 break;
 2210 
 2211         default:
 2212                 error = EINVAL;
 2213                 break;
 2214         }
 2215 
 2216         return (error);
 2217 }
 2218 
 2219 #if defined(KERN_TLS) || defined(RATELIMIT)
 2220 static int
 2221 vlan_snd_tag_alloc(struct ifnet *ifp,
 2222     union if_snd_tag_alloc_params *params,
 2223     struct m_snd_tag **ppmt)
 2224 {
 2225         struct epoch_tracker et;
 2226         const struct if_snd_tag_sw *sw;
 2227         struct vlan_snd_tag *vst;
 2228         struct ifvlan *ifv;
 2229         struct ifnet *parent;
 2230         struct m_snd_tag *mst;
 2231         int error;
 2232 
 2233         NET_EPOCH_ENTER(et);
 2234         ifv = ifp->if_softc;
 2235 
 2236         switch (params->hdr.type) {
 2237 #ifdef RATELIMIT
 2238         case IF_SND_TAG_TYPE_UNLIMITED:
 2239                 sw = &vlan_snd_tag_ul_sw;
 2240                 break;
 2241         case IF_SND_TAG_TYPE_RATE_LIMIT:
 2242                 sw = &vlan_snd_tag_rl_sw;
 2243                 break;
 2244 #endif
 2245 #ifdef KERN_TLS
 2246         case IF_SND_TAG_TYPE_TLS:
 2247                 sw = &vlan_snd_tag_tls_sw;
 2248                 break;
 2249         case IF_SND_TAG_TYPE_TLS_RX:
 2250                 sw = NULL;
 2251                 if (params->tls_rx.vlan_id != 0)
 2252                         goto failure;
 2253                 params->tls_rx.vlan_id = ifv->ifv_vid;
 2254                 break;
 2255 #ifdef RATELIMIT
 2256         case IF_SND_TAG_TYPE_TLS_RATE_LIMIT:
 2257                 sw = &vlan_snd_tag_tls_rl_sw;
 2258                 break;
 2259 #endif
 2260 #endif
 2261         default:
 2262                 goto failure;
 2263         }
 2264 
 2265         if (ifv->ifv_trunk != NULL)
 2266                 parent = PARENT(ifv);
 2267         else
 2268                 parent = NULL;
 2269         if (parent == NULL)
 2270                 goto failure;
 2271         if_ref(parent);
 2272         NET_EPOCH_EXIT(et);
 2273 
 2274         if (sw != NULL) {
 2275                 vst = malloc(sizeof(*vst), M_VLAN, M_NOWAIT);
 2276                 if (vst == NULL) {
 2277                         if_rele(parent);
 2278                         return (ENOMEM);
 2279                 }
 2280         } else
 2281                 vst = NULL;
 2282 
 2283         error = m_snd_tag_alloc(parent, params, &mst);
 2284         if_rele(parent);
 2285         if (error) {
 2286                 free(vst, M_VLAN);
 2287                 return (error);
 2288         }
 2289 
 2290         if (sw != NULL) {
 2291                 m_snd_tag_init(&vst->com, ifp, sw);
 2292                 vst->tag = mst;
 2293 
 2294                 *ppmt = &vst->com;
 2295         } else
 2296                 *ppmt = mst;
 2297 
 2298         return (0);
 2299 failure:
 2300         NET_EPOCH_EXIT(et);
 2301         return (EOPNOTSUPP);
 2302 }
 2303 
 2304 static struct m_snd_tag *
 2305 vlan_next_snd_tag(struct m_snd_tag *mst)
 2306 {
 2307         struct vlan_snd_tag *vst;
 2308 
 2309         vst = mst_to_vst(mst);
 2310         return (vst->tag);
 2311 }
 2312 
 2313 static int
 2314 vlan_snd_tag_modify(struct m_snd_tag *mst,
 2315     union if_snd_tag_modify_params *params)
 2316 {
 2317         struct vlan_snd_tag *vst;
 2318 
 2319         vst = mst_to_vst(mst);
 2320         return (vst->tag->sw->snd_tag_modify(vst->tag, params));
 2321 }
 2322 
 2323 static int
 2324 vlan_snd_tag_query(struct m_snd_tag *mst,
 2325     union if_snd_tag_query_params *params)
 2326 {
 2327         struct vlan_snd_tag *vst;
 2328 
 2329         vst = mst_to_vst(mst);
 2330         return (vst->tag->sw->snd_tag_query(vst->tag, params));
 2331 }
 2332 
 2333 static void
 2334 vlan_snd_tag_free(struct m_snd_tag *mst)
 2335 {
 2336         struct vlan_snd_tag *vst;
 2337 
 2338         vst = mst_to_vst(mst);
 2339         m_snd_tag_rele(vst->tag);
 2340         free(vst, M_VLAN);
 2341 }
 2342 
 2343 static void
 2344 vlan_ratelimit_query(struct ifnet *ifp __unused, struct if_ratelimit_query_results *q)
 2345 {
 2346         /*
 2347          * For vlan, we have an indirect
 2348          * interface. The caller needs to
 2349          * get a ratelimit tag on the actual
 2350          * interface the flow will go on.
 2351          */
 2352         q->rate_table = NULL;
 2353         q->flags = RT_IS_INDIRECT;
 2354         q->max_flows = 0;
 2355         q->number_of_rates = 0;
 2356 }
 2357 
 2358 #endif

Cache object: ffa261267b807c6494301a5a121f3467


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