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

Cache object: 1c48bd3f53c9626c733aa3fb108034ff


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