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