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