xref: /openbsd-src/sys/net/if_vlan.c (revision 3374c67d44f9b75b98444cbf63020f777792342e)
1 /*	$OpenBSD: if_vlan.c,v 1.210 2022/08/10 09:01:48 mvs Exp $	*/
2 
3 /*
4  * Copyright 1998 Massachusetts Institute of Technology
5  *
6  * Permission to use, copy, modify, and distribute this software and
7  * its documentation for any purpose and without fee is hereby
8  * granted, provided that both the above copyright notice and this
9  * permission notice appear in all copies, that both the above
10  * copyright notice and this permission notice appear in all
11  * supporting documentation, and that the name of M.I.T. not be used
12  * in advertising or publicity pertaining to distribution of the
13  * software without specific, written prior permission.  M.I.T. makes
14  * no representations about the suitability of this software for any
15  * purpose.  It is provided "as is" without express or implied
16  * warranty.
17  *
18  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
19  * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
22  * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD: src/sys/net/if_vlan.c,v 1.16 2000/03/26 15:21:40 charnier Exp $
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() left on our output queue when it calls
41  * if_start(), rewrite them for use by the real outgoing interface,
42  * and ask it to send them.
43  *
44  * Some devices support 802.1Q tag insertion in firmware.  The
45  * vlan interface behavior changes when the IFCAP_VLAN_HWTAGGING
46  * capability is set on the parent.  In this case, vlan_start()
47  * will not modify the ethernet header.
48  */
49 
50 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/mbuf.h>
54 #include <sys/queue.h>
55 #include <sys/socket.h>
56 #include <sys/sockio.h>
57 #include <sys/systm.h>
58 #include <sys/rwlock.h>
59 #include <sys/percpu.h>
60 #include <sys/refcnt.h>
61 #include <sys/smr.h>
62 
63 #include <net/if.h>
64 #include <net/if_dl.h>
65 #include <net/if_types.h>
66 
67 #include <netinet/in.h>
68 #include <netinet/if_ether.h>
69 
70 #include <net/if_vlan_var.h>
71 
72 #include "bpfilter.h"
73 #if NBPFILTER > 0
74 #include <net/bpf.h>
75 #endif
76 
77 struct vlan_mc_entry {
78 	LIST_ENTRY(vlan_mc_entry)	mc_entries;
79 	union {
80 		struct ether_multi	*mcu_enm;
81 	} mc_u;
82 #define mc_enm	mc_u.mcu_enm
83 	struct sockaddr_storage		mc_addr;
84 };
85 
86 struct vlan_softc {
87 	struct arpcom		 sc_ac;
88 #define	sc_if			 sc_ac.ac_if
89 	unsigned int		 sc_dead;
90 	unsigned int		 sc_ifidx0;	/* parent interface */
91 	int			 sc_txprio;
92 	int			 sc_rxprio;
93 	uint16_t		 sc_proto; /* encapsulation ethertype */
94 	uint16_t		 sc_tag;
95 	uint16_t		 sc_type; /* non-standard ethertype or 0x8100 */
96 	LIST_HEAD(__vlan_mchead, vlan_mc_entry)
97 				 sc_mc_listhead;
98 	SMR_SLIST_ENTRY(vlan_softc) sc_list;
99 	int			 sc_flags;
100 	struct refcnt		 sc_refcnt;
101 	struct task		 sc_ltask;
102 	struct task		 sc_dtask;
103 };
104 
105 SMR_SLIST_HEAD(vlan_list, vlan_softc);
106 
107 #define	IFVF_PROMISC	0x01	/* the parent should be made promisc */
108 #define	IFVF_LLADDR	0x02	/* don't inherit the parents mac */
109 
110 #define TAG_HASH_BITS		5
111 #define TAG_HASH_SIZE		(1 << TAG_HASH_BITS)
112 #define TAG_HASH_MASK		(TAG_HASH_SIZE - 1)
113 #define TAG_HASH(tag)		(tag & TAG_HASH_MASK)
114 struct vlan_list *vlan_tagh, *svlan_tagh;
115 struct rwlock vlan_tagh_lk = RWLOCK_INITIALIZER("vlantag");
116 
117 void	vlanattach(int count);
118 int	vlan_clone_create(struct if_clone *, int);
119 int	vlan_clone_destroy(struct ifnet *);
120 
121 int	vlan_enqueue(struct ifnet *, struct mbuf *);
122 void	vlan_start(struct ifqueue *ifq);
123 int	vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
124 
125 int	vlan_up(struct vlan_softc *);
126 int	vlan_down(struct vlan_softc *);
127 
128 void	vlan_ifdetach(void *);
129 void	vlan_link_hook(void *);
130 void	vlan_link_state(struct vlan_softc *, u_char, uint64_t);
131 
132 int	vlan_set_vnetid(struct vlan_softc *, uint16_t);
133 int	vlan_set_parent(struct vlan_softc *, const char *);
134 int	vlan_del_parent(struct vlan_softc *);
135 int	vlan_inuse(uint16_t, unsigned int, uint16_t);
136 int	vlan_inuse_locked(uint16_t, unsigned int, uint16_t);
137 
138 int	vlan_multi_add(struct vlan_softc *, struct ifreq *);
139 int	vlan_multi_del(struct vlan_softc *, struct ifreq *);
140 void	vlan_multi_apply(struct vlan_softc *, struct ifnet *, u_long);
141 void	vlan_multi_free(struct vlan_softc *);
142 
143 int	vlan_media_get(struct vlan_softc *, struct ifreq *);
144 
145 int	vlan_iff(struct vlan_softc *);
146 int	vlan_setlladdr(struct vlan_softc *, struct ifreq *);
147 
148 int	vlan_set_compat(struct ifnet *, struct ifreq *);
149 int	vlan_get_compat(struct ifnet *, struct ifreq *);
150 
151 struct if_clone vlan_cloner =
152     IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
153 struct if_clone svlan_cloner =
154     IF_CLONE_INITIALIZER("svlan", vlan_clone_create, vlan_clone_destroy);
155 
156 void
157 vlanattach(int count)
158 {
159 	unsigned int i;
160 
161 	/* Normal VLAN */
162 	vlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*vlan_tagh),
163 	    M_DEVBUF, M_NOWAIT);
164 	if (vlan_tagh == NULL)
165 		panic("vlanattach: hashinit");
166 
167 	/* Service-VLAN for QinQ/802.1ad provider bridges */
168 	svlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*svlan_tagh),
169 	    M_DEVBUF, M_NOWAIT);
170 	if (svlan_tagh == NULL)
171 		panic("vlanattach: hashinit");
172 
173 	for (i = 0; i < TAG_HASH_SIZE; i++) {
174 		SMR_SLIST_INIT(&vlan_tagh[i]);
175 		SMR_SLIST_INIT(&svlan_tagh[i]);
176 	}
177 
178 	if_clone_attach(&vlan_cloner);
179 	if_clone_attach(&svlan_cloner);
180 }
181 
182 int
183 vlan_clone_create(struct if_clone *ifc, int unit)
184 {
185 	struct vlan_softc *sc;
186 	struct ifnet *ifp;
187 
188 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
189 	sc->sc_dead = 0;
190 	LIST_INIT(&sc->sc_mc_listhead);
191 	task_set(&sc->sc_ltask, vlan_link_hook, sc);
192 	task_set(&sc->sc_dtask, vlan_ifdetach, sc);
193 	ifp = &sc->sc_if;
194 	ifp->if_softc = sc;
195 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
196 	    unit);
197 	/* NB: flags are not set here */
198 	/* NB: mtu is not set here */
199 
200 	/* Special handling for the IEEE 802.1ad QinQ variant */
201 	if (strcmp("svlan", ifc->ifc_name) == 0)
202 		sc->sc_type = ETHERTYPE_QINQ;
203 	else
204 		sc->sc_type = ETHERTYPE_VLAN;
205 
206 	refcnt_init(&sc->sc_refcnt);
207 	sc->sc_txprio = IF_HDRPRIO_PACKET;
208 	sc->sc_rxprio = IF_HDRPRIO_OUTER;
209 
210 	ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
211 	ifp->if_xflags = IFXF_CLONED|IFXF_MPSAFE;
212 	ifp->if_qstart = vlan_start;
213 	ifp->if_enqueue = vlan_enqueue;
214 	ifp->if_ioctl = vlan_ioctl;
215 	ifp->if_hardmtu = 0xffff;
216 	ifp->if_link_state = LINK_STATE_DOWN;
217 
218 	if_counters_alloc(ifp);
219 	if_attach(ifp);
220 	ether_ifattach(ifp);
221 	ifp->if_hdrlen = EVL_ENCAPLEN;
222 
223 	return (0);
224 }
225 
226 int
227 vlan_clone_destroy(struct ifnet *ifp)
228 {
229 	struct vlan_softc *sc = ifp->if_softc;
230 
231 	NET_LOCK();
232 	sc->sc_dead = 1;
233 
234 	if (ISSET(ifp->if_flags, IFF_RUNNING))
235 		vlan_down(sc);
236 	NET_UNLOCK();
237 
238 	ether_ifdetach(ifp);
239 	if_detach(ifp);
240 	smr_barrier();
241 	refcnt_finalize(&sc->sc_refcnt, "vlanrefs");
242 	vlan_multi_free(sc);
243 	free(sc, M_DEVBUF, sizeof(*sc));
244 
245 	return (0);
246 }
247 
248 void
249 vlan_transmit(struct vlan_softc *sc, struct ifnet *ifp0, struct mbuf *m)
250 {
251 	struct ifnet *ifp = &sc->sc_if;
252 	int txprio = sc->sc_txprio;
253 	uint8_t prio;
254 
255 #if NBPFILTER > 0
256 	if (ifp->if_bpf)
257 		bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
258 #endif /* NBPFILTER > 0 */
259 
260 	prio = (txprio == IF_HDRPRIO_PACKET) ?
261 	    m->m_pkthdr.pf.prio : txprio;
262 
263 	/* IEEE 802.1p has prio 0 and 1 swapped */
264 	if (prio <= 1)
265 		prio = !prio;
266 
267 	/*
268 	 * If the underlying interface cannot do VLAN tag insertion
269 	 * itself, create an encapsulation header.
270 	 */
271 	if ((ifp0->if_capabilities & IFCAP_VLAN_HWTAGGING) &&
272 	    (sc->sc_type == ETHERTYPE_VLAN)) {
273 		m->m_pkthdr.ether_vtag = sc->sc_tag +
274 		    (prio << EVL_PRIO_BITS);
275 		m->m_flags |= M_VLANTAG;
276 	} else {
277 		m = vlan_inject(m, sc->sc_type, sc->sc_tag |
278 		    (prio << EVL_PRIO_BITS));
279 		if (m == NULL) {
280 			counters_inc(ifp->if_counters, ifc_oerrors);
281 			return;
282 		}
283 	}
284 
285 	if (if_enqueue(ifp0, m))
286 		counters_inc(ifp->if_counters, ifc_oerrors);
287 }
288 
289 int
290 vlan_enqueue(struct ifnet *ifp, struct mbuf *m)
291 {
292 	struct ifnet *ifp0;
293 	struct vlan_softc *sc;
294 	int error = 0;
295 
296 	if (!ifq_is_priq(&ifp->if_snd))
297 		return (if_enqueue_ifq(ifp, m));
298 
299 	sc = ifp->if_softc;
300 	ifp0 = if_get(sc->sc_ifidx0);
301 
302 	if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) {
303 		m_freem(m);
304 		error = ENETDOWN;
305 	} else {
306 		counters_pkt(ifp->if_counters,
307 		    ifc_opackets, ifc_obytes, m->m_pkthdr.len);
308 		vlan_transmit(sc, ifp0, m);
309 	}
310 
311 	if_put(ifp0);
312 
313 	return (error);
314 }
315 
316 void
317 vlan_start(struct ifqueue *ifq)
318 {
319 	struct ifnet *ifp = ifq->ifq_if;
320 	struct vlan_softc *sc = ifp->if_softc;
321 	struct ifnet *ifp0;
322 	struct mbuf *m;
323 
324 	ifp0 = if_get(sc->sc_ifidx0);
325 	if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) {
326 		ifq_purge(ifq);
327 		goto leave;
328 	}
329 
330 	while ((m = ifq_dequeue(ifq)) != NULL)
331 		vlan_transmit(sc, ifp0, m);
332 
333 leave:
334 	if_put(ifp0);
335 }
336 
337 struct mbuf *
338 vlan_strip(struct mbuf *m)
339 {
340 	if (ISSET(m->m_flags, M_VLANTAG)) {
341 		CLR(m->m_flags, M_VLANTAG);
342 	} else {
343 		struct ether_vlan_header *evl;
344 
345 		evl = mtod(m, struct ether_vlan_header *);
346 		memmove((caddr_t)evl + EVL_ENCAPLEN, evl,
347 		    offsetof(struct ether_vlan_header, evl_encap_proto));
348 		m_adj(m, EVL_ENCAPLEN);
349 	}
350 
351 	return (m);
352 }
353 
354 struct mbuf *
355 vlan_inject(struct mbuf *m, uint16_t type, uint16_t tag)
356 {
357 	struct ether_vlan_header evh;
358 
359 	m_copydata(m, 0, ETHER_HDR_LEN, &evh);
360 	evh.evl_proto = evh.evl_encap_proto;
361 	evh.evl_encap_proto = htons(type);
362 	evh.evl_tag = htons(tag);
363 	m_adj(m, ETHER_HDR_LEN);
364 	M_PREPEND(m, sizeof(evh) + ETHER_ALIGN, M_DONTWAIT);
365 	if (m == NULL)
366 		return (NULL);
367 
368 	m_adj(m, ETHER_ALIGN);
369 
370 	m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT);
371 	CLR(m->m_flags, M_VLANTAG);
372 
373 	return (m);
374 }
375 
376 struct mbuf *
377 vlan_input(struct ifnet *ifp0, struct mbuf *m, unsigned int *sdelim)
378 {
379 	struct vlan_softc *sc;
380 	struct ifnet *ifp;
381 	struct ether_vlan_header *evl;
382 	struct vlan_list *tagh, *list;
383 	uint16_t vtag, tag;
384 	uint16_t etype;
385 	int rxprio;
386 
387 	if (m->m_flags & M_VLANTAG) {
388 		vtag = m->m_pkthdr.ether_vtag;
389 		etype = ETHERTYPE_VLAN;
390 		tagh = vlan_tagh;
391 	} else {
392 		if (m->m_len < sizeof(*evl)) {
393 			m = m_pullup(m, sizeof(*evl));
394 			if (m == NULL)
395 				return (NULL);
396 		}
397 
398 		evl = mtod(m, struct ether_vlan_header *);
399 		vtag = bemtoh16(&evl->evl_tag);
400 		etype = bemtoh16(&evl->evl_encap_proto);
401 		switch (etype) {
402 		case ETHERTYPE_VLAN:
403 			tagh = vlan_tagh;
404 			break;
405 		case ETHERTYPE_QINQ:
406 			tagh = svlan_tagh;
407 			break;
408 		default:
409 			panic("%s: unexpected etype 0x%04x", __func__, etype);
410 			/* NOTREACHED */
411 		}
412 	}
413 
414 	tag = EVL_VLANOFTAG(vtag);
415 	list = &tagh[TAG_HASH(tag)];
416 	smr_read_enter();
417 	SMR_SLIST_FOREACH(sc, list, sc_list) {
418 		if (ifp0->if_index == sc->sc_ifidx0 && tag == sc->sc_tag &&
419 		    etype == sc->sc_type) {
420 			refcnt_take(&sc->sc_refcnt);
421 			break;
422 		}
423 	}
424 	smr_read_leave();
425 
426 	if (sc == NULL) {
427 		/* VLAN 0 Priority Tagging */
428 		if (tag == 0 && etype == ETHERTYPE_VLAN) {
429 			struct ether_header *eh;
430 
431 			/* XXX we should actually use the prio value? */
432 			m = vlan_strip(m);
433 
434 			eh = mtod(m, struct ether_header *);
435 			if (eh->ether_type == htons(ETHERTYPE_VLAN) ||
436 			    eh->ether_type == htons(ETHERTYPE_QINQ)) {
437 				m_freem(m);
438 				return (NULL);
439 			}
440 		} else
441 			*sdelim = 1;
442 
443 		return (m); /* decline */
444 	}
445 
446 	ifp = &sc->sc_if;
447 	if (!ISSET(ifp->if_flags, IFF_RUNNING)) {
448 		m_freem(m);
449 		goto leave;
450 	}
451 
452 	/*
453 	 * Having found a valid vlan interface corresponding to
454 	 * the given source interface and vlan tag, remove the
455 	 * encapsulation.
456 	 */
457 	m = vlan_strip(m);
458 
459 	rxprio = sc->sc_rxprio;
460 	switch (rxprio) {
461 	case IF_HDRPRIO_PACKET:
462 		break;
463 	case IF_HDRPRIO_OUTER:
464 		m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag);
465 		/* IEEE 802.1p has prio 0 and 1 swapped */
466 		if (m->m_pkthdr.pf.prio <= 1)
467 			m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio;
468 		break;
469 	default:
470 		m->m_pkthdr.pf.prio = rxprio;
471 		break;
472 	}
473 
474 	if_vinput(ifp, m);
475 leave:
476 	refcnt_rele_wake(&sc->sc_refcnt);
477 	return (NULL);
478 }
479 
480 int
481 vlan_up(struct vlan_softc *sc)
482 {
483 	struct vlan_list *tagh, *list;
484 	struct ifnet *ifp = &sc->sc_if;
485 	struct ifnet *ifp0;
486 	int error = 0;
487 	unsigned int hardmtu;
488 
489 	KASSERT(!ISSET(ifp->if_flags, IFF_RUNNING));
490 
491 	tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
492 	list = &tagh[TAG_HASH(sc->sc_tag)];
493 
494 	ifp0 = if_get(sc->sc_ifidx0);
495 	if (ifp0 == NULL)
496 		return (ENXIO);
497 
498 	/* check vlan will work on top of the parent */
499 	if (ifp0->if_type != IFT_ETHER) {
500 		error = EPROTONOSUPPORT;
501 		goto put;
502 	}
503 
504 	hardmtu = ifp0->if_hardmtu;
505 	if (!ISSET(ifp0->if_capabilities, IFCAP_VLAN_MTU))
506 		hardmtu -= EVL_ENCAPLEN;
507 
508 	if (ifp->if_mtu > hardmtu) {
509 		error = ENOBUFS;
510 		goto put;
511 	}
512 
513 	/* parent is fine, let's prepare the sc to handle packets */
514 	ifp->if_hardmtu = hardmtu;
515 	SET(ifp->if_flags, ifp0->if_flags & IFF_SIMPLEX);
516 
517 	if (ISSET(sc->sc_flags, IFVF_PROMISC)) {
518 		error = ifpromisc(ifp0, 1);
519 		if (error != 0)
520 			goto scrub;
521 	}
522 
523 	/*
524 	 * Note: In cases like vio(4) and em(4) where the offsets of the
525 	 * csum can be freely defined, we could actually do csum offload
526 	 * for VLAN and QINQ packets.
527 	 */
528 	if (sc->sc_type != ETHERTYPE_VLAN) {
529 		/*
530 		 * Hardware offload only works with the default VLAN
531 		 * ethernet type (0x8100).
532 		 */
533 		ifp->if_capabilities = 0;
534 	} else if (ISSET(ifp0->if_capabilities, IFCAP_VLAN_HWTAGGING)) {
535 		/*
536 		 * Chips that can do hardware-assisted VLAN encapsulation, can
537 		 * calculate the correct checksum for VLAN tagged packets.
538 		 */
539 		ifp->if_capabilities = ifp0->if_capabilities & IFCAP_CSUM_MASK;
540 	}
541 
542 	/* commit the sc */
543 	error = rw_enter(&vlan_tagh_lk, RW_WRITE | RW_INTR);
544 	if (error != 0)
545 		goto unpromisc;
546 
547 	error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, sc->sc_tag);
548 	if (error != 0)
549 		goto leave;
550 
551 	SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list);
552 	rw_exit(&vlan_tagh_lk);
553 
554 	/* Register callback for physical link state changes */
555 	if_linkstatehook_add(ifp0, &sc->sc_ltask);
556 
557 	/* Register callback if parent wants to unregister */
558 	if_detachhook_add(ifp0, &sc->sc_dtask);
559 
560 	/* configure the parent to handle packets for this vlan */
561 	vlan_multi_apply(sc, ifp0, SIOCADDMULTI);
562 
563 	/* we're running now */
564 	SET(ifp->if_flags, IFF_RUNNING);
565 	vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate);
566 
567 	if_put(ifp0);
568 
569 	return (ENETRESET);
570 
571 leave:
572 	rw_exit(&vlan_tagh_lk);
573 unpromisc:
574 	if (ISSET(sc->sc_flags, IFVF_PROMISC))
575 		(void)ifpromisc(ifp0, 0); /* XXX */
576 scrub:
577 	ifp->if_capabilities = 0;
578 	CLR(ifp->if_flags, IFF_SIMPLEX);
579 	ifp->if_hardmtu = 0xffff;
580 put:
581 	if_put(ifp0);
582 
583 	return (error);
584 }
585 
586 int
587 vlan_down(struct vlan_softc *sc)
588 {
589 	struct vlan_list *tagh, *list;
590 	struct ifnet *ifp = &sc->sc_if;
591 	struct ifnet *ifp0;
592 
593 	tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
594 	list = &tagh[TAG_HASH(sc->sc_tag)];
595 
596 	KASSERT(ISSET(ifp->if_flags, IFF_RUNNING));
597 
598 	vlan_link_state(sc, LINK_STATE_DOWN, 0);
599 	CLR(ifp->if_flags, IFF_RUNNING);
600 
601 	ifq_barrier(&ifp->if_snd);
602 
603 	ifp0 = if_get(sc->sc_ifidx0);
604 	if (ifp0 != NULL) {
605 		if (ISSET(sc->sc_flags, IFVF_PROMISC))
606 			ifpromisc(ifp0, 0);
607 		vlan_multi_apply(sc, ifp0, SIOCDELMULTI);
608 		if_detachhook_del(ifp0, &sc->sc_dtask);
609 		if_linkstatehook_del(ifp0, &sc->sc_ltask);
610 	}
611 	if_put(ifp0);
612 
613 	rw_enter_write(&vlan_tagh_lk);
614 	SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list);
615 	rw_exit_write(&vlan_tagh_lk);
616 
617 	ifp->if_capabilities = 0;
618 	CLR(ifp->if_flags, IFF_SIMPLEX);
619 	ifp->if_hardmtu = 0xffff;
620 
621 	return (0);
622 }
623 
624 void
625 vlan_ifdetach(void *v)
626 {
627 	struct vlan_softc *sc = v;
628 	struct ifnet *ifp = &sc->sc_if;
629 
630 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
631 		vlan_down(sc);
632 		CLR(ifp->if_flags, IFF_UP);
633 	}
634 
635 	sc->sc_ifidx0 = 0;
636 }
637 
638 void
639 vlan_link_hook(void *v)
640 {
641 	struct vlan_softc *sc = v;
642 	struct ifnet *ifp0;
643 
644 	u_char link = LINK_STATE_DOWN;
645 	uint64_t baud = 0;
646 
647 	ifp0 = if_get(sc->sc_ifidx0);
648 	if (ifp0 != NULL) {
649 		link = ifp0->if_link_state;
650 		baud = ifp0->if_baudrate;
651 	}
652 	if_put(ifp0);
653 
654 	vlan_link_state(sc, link, baud);
655 }
656 
657 void
658 vlan_link_state(struct vlan_softc *sc, u_char link, uint64_t baud)
659 {
660 	if (sc->sc_if.if_link_state == link)
661 		return;
662 
663 	sc->sc_if.if_link_state = link;
664 	sc->sc_if.if_baudrate = baud;
665 
666 	if_link_state_change(&sc->sc_if);
667 }
668 
669 int
670 vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
671 {
672 	struct vlan_softc *sc = ifp->if_softc;
673 	struct ifreq *ifr = (struct ifreq *)data;
674 	struct if_parent *parent = (struct if_parent *)data;
675 	struct ifnet *ifp0;
676 	uint16_t tag;
677 	int error = 0;
678 
679 	if (sc->sc_dead)
680 		return (ENXIO);
681 
682 	switch (cmd) {
683 	case SIOCSIFADDR:
684 		ifp->if_flags |= IFF_UP;
685 		/* FALLTHROUGH */
686 
687 	case SIOCSIFFLAGS:
688 		if (ISSET(ifp->if_flags, IFF_UP)) {
689 			if (!ISSET(ifp->if_flags, IFF_RUNNING))
690 				error = vlan_up(sc);
691 			else
692 				error = ENETRESET;
693 		} else {
694 			if (ISSET(ifp->if_flags, IFF_RUNNING))
695 				error = vlan_down(sc);
696 		}
697 		break;
698 
699 	case SIOCSVNETID:
700 		if (ifr->ifr_vnetid < EVL_VLID_MIN ||
701 		    ifr->ifr_vnetid > EVL_VLID_MAX) {
702 			error = EINVAL;
703 			break;
704 		}
705 
706 		tag = ifr->ifr_vnetid;
707 		if (tag == sc->sc_tag)
708 			break;
709 
710 		error = vlan_set_vnetid(sc, tag);
711 		break;
712 
713 	case SIOCGVNETID:
714 		if (sc->sc_tag == EVL_VLID_NULL)
715 			error = EADDRNOTAVAIL;
716 		else
717 			ifr->ifr_vnetid = (int64_t)sc->sc_tag;
718 		break;
719 
720 	case SIOCDVNETID:
721 		error = vlan_set_vnetid(sc, 0);
722 		break;
723 
724 	case SIOCSIFPARENT:
725 		error = vlan_set_parent(sc, parent->ifp_parent);
726 		break;
727 
728 	case SIOCGIFPARENT:
729 		ifp0 = if_get(sc->sc_ifidx0);
730 		if (ifp0 == NULL)
731 			error = EADDRNOTAVAIL;
732 		else {
733 			memcpy(parent->ifp_parent, ifp0->if_xname,
734 			    sizeof(parent->ifp_parent));
735 		}
736 		if_put(ifp0);
737 		break;
738 
739 	case SIOCDIFPARENT:
740 		error = vlan_del_parent(sc);
741 		break;
742 
743 	case SIOCADDMULTI:
744 		error = vlan_multi_add(sc, ifr);
745 		break;
746 
747 	case SIOCDELMULTI:
748 		error = vlan_multi_del(sc, ifr);
749 		break;
750 
751 	case SIOCGIFMEDIA:
752 		error = vlan_media_get(sc, ifr);
753 		break;
754 
755 	case SIOCSIFMEDIA:
756 		error = ENOTTY;
757 		break;
758 
759 	case SIOCSIFLLADDR:
760 		error = vlan_setlladdr(sc, ifr);
761 		break;
762 
763 	case SIOCSETVLAN:
764 		error = vlan_set_compat(ifp, ifr);
765 		break;
766 	case SIOCGETVLAN:
767 		error = vlan_get_compat(ifp, ifr);
768 		break;
769 
770 	case SIOCSTXHPRIO:
771 		error = if_txhprio_l2_check(ifr->ifr_hdrprio);
772 		if (error != 0)
773 			break;
774 
775 		sc->sc_txprio = ifr->ifr_hdrprio;
776 		break;
777 	case SIOCGTXHPRIO:
778 		ifr->ifr_hdrprio = sc->sc_txprio;
779 		break;
780 
781 	case SIOCSRXHPRIO:
782 		error = if_rxhprio_l2_check(ifr->ifr_hdrprio);
783 		if (error != 0)
784 			break;
785 
786 		sc->sc_rxprio = ifr->ifr_hdrprio;
787 		break;
788 	case SIOCGRXHPRIO:
789 		ifr->ifr_hdrprio = sc->sc_rxprio;
790 		break;
791 
792 	default:
793 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
794 		break;
795 	}
796 
797 	if (error == ENETRESET)
798 		error = vlan_iff(sc);
799 
800 	return error;
801 }
802 
803 int
804 vlan_iff(struct vlan_softc *sc)
805 {
806 	struct ifnet *ifp0;
807 	int promisc = 0;
808 	int error = 0;
809 
810 	if (ISSET(sc->sc_if.if_flags, IFF_PROMISC) ||
811 	    ISSET(sc->sc_flags, IFVF_LLADDR))
812 		promisc = IFVF_PROMISC;
813 
814 	if (ISSET(sc->sc_flags, IFVF_PROMISC) == promisc)
815 		return (0);
816 
817 	if (ISSET(sc->sc_if.if_flags, IFF_RUNNING)) {
818 		ifp0 = if_get(sc->sc_ifidx0);
819 		if (ifp0 != NULL)
820 			error = ifpromisc(ifp0, promisc);
821 		if_put(ifp0);
822 	}
823 
824 	if (error == 0) {
825 		CLR(sc->sc_flags, IFVF_PROMISC);
826 		SET(sc->sc_flags, promisc);
827 	}
828 
829 	return (error);
830 }
831 
832 int
833 vlan_setlladdr(struct vlan_softc *sc, struct ifreq *ifr)
834 {
835 	struct ifnet *ifp = &sc->sc_if;
836 	struct ifnet *ifp0;
837 	uint8_t lladdr[ETHER_ADDR_LEN];
838 	int flag;
839 
840 	memcpy(lladdr, ifr->ifr_addr.sa_data, sizeof(lladdr));
841 
842 	/* setting the mac addr to 00:00:00:00:00:00 means reset lladdr */
843 	if (memcmp(lladdr, etheranyaddr, sizeof(lladdr)) == 0) {
844 		ifp0 = if_get(sc->sc_ifidx0);
845 		if (ifp0 != NULL)
846 			memcpy(lladdr, LLADDR(ifp0->if_sadl), sizeof(lladdr));
847 		if_put(ifp0);
848 
849 		flag = 0;
850 	} else
851 		flag = IFVF_LLADDR;
852 
853 	if (memcmp(lladdr, LLADDR(ifp->if_sadl), sizeof(lladdr)) == 0 &&
854 	    ISSET(sc->sc_flags, IFVF_LLADDR) == flag) {
855 		/* nop */
856 		return (0);
857 	}
858 
859 	/* commit */
860 	if_setlladdr(ifp, lladdr);
861 	CLR(sc->sc_flags, IFVF_LLADDR);
862 	SET(sc->sc_flags, flag);
863 
864 	return (ENETRESET);
865 }
866 
867 int
868 vlan_set_vnetid(struct vlan_softc *sc, uint16_t tag)
869 {
870 	struct ifnet *ifp = &sc->sc_if;
871 	struct vlan_list *tagh, *list;
872 	u_char link = ifp->if_link_state;
873 	uint64_t baud = ifp->if_baudrate;
874 	int error;
875 
876 	tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
877 
878 	if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link))
879 		vlan_link_state(sc, LINK_STATE_DOWN, 0);
880 
881 	error = rw_enter(&vlan_tagh_lk, RW_WRITE);
882 	if (error != 0)
883 		return (error);
884 
885 	error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, tag);
886 	if (error != 0)
887 		goto unlock;
888 
889 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
890 		list = &tagh[TAG_HASH(sc->sc_tag)];
891 		SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list);
892 
893 		sc->sc_tag = tag;
894 
895 		list = &tagh[TAG_HASH(sc->sc_tag)];
896 		SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list);
897 	} else
898 		sc->sc_tag = tag;
899 
900 unlock:
901 	rw_exit(&vlan_tagh_lk);
902 
903 	if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link))
904 		vlan_link_state(sc, link, baud);
905 
906 	return (error);
907 }
908 
909 int
910 vlan_set_parent(struct vlan_softc *sc, const char *parent)
911 {
912 	struct ifnet *ifp = &sc->sc_if;
913 	struct ifnet *ifp0;
914 	int error = 0;
915 
916 	ifp0 = if_unit(parent);
917 	if (ifp0 == NULL)
918 		return (EINVAL);
919 
920 	if (ifp0->if_type != IFT_ETHER) {
921 		error = EPROTONOSUPPORT;
922 		goto put;
923 	}
924 
925 	if (sc->sc_ifidx0 == ifp0->if_index) {
926 		/* nop */
927 		goto put;
928 	}
929 
930 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
931 		error = EBUSY;
932 		goto put;
933 	}
934 
935 	error = vlan_inuse(sc->sc_type, ifp0->if_index, sc->sc_tag);
936 	if (error != 0)
937 		goto put;
938 
939 	/* commit */
940 	sc->sc_ifidx0 = ifp0->if_index;
941 	if (!ISSET(sc->sc_flags, IFVF_LLADDR))
942 		if_setlladdr(ifp, LLADDR(ifp0->if_sadl));
943 
944 put:
945 	if_put(ifp0);
946 	return (error);
947 }
948 
949 int
950 vlan_del_parent(struct vlan_softc *sc)
951 {
952 	struct ifnet *ifp = &sc->sc_if;
953 
954 	if (ISSET(ifp->if_flags, IFF_RUNNING))
955 		return (EBUSY);
956 
957 	/* commit */
958 	sc->sc_ifidx0 = 0;
959 	if (!ISSET(sc->sc_flags, IFVF_LLADDR))
960 		if_setlladdr(ifp, etheranyaddr);
961 
962 	return (0);
963 }
964 
965 int
966 vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr)
967 {
968 	struct vlanreq vlr;
969 	struct ifreq req;
970 	struct if_parent parent;
971 
972 	int error;
973 
974 	error = suser(curproc);
975 	if (error != 0)
976 		return (error);
977 
978 	error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
979 	if (error != 0)
980 		return (error);
981 
982 	if (vlr.vlr_parent[0] == '\0')
983 		return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr));
984 
985 	memset(&req, 0, sizeof(req));
986 	memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name));
987 	req.ifr_vnetid = vlr.vlr_tag;
988 
989 	error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req);
990 	if (error != 0)
991 		return (error);
992 
993 	memset(&parent, 0, sizeof(parent));
994 	memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name));
995 	memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent));
996 	error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent);
997 	if (error != 0)
998 		return (error);
999 
1000 	memset(&req, 0, sizeof(req));
1001 	memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name));
1002 	SET(ifp->if_flags, IFF_UP);
1003 	return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req));
1004 }
1005 
1006 int
1007 vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr)
1008 {
1009 	struct vlan_softc *sc = ifp->if_softc;
1010 	struct vlanreq vlr;
1011 	struct ifnet *p;
1012 
1013 	memset(&vlr, 0, sizeof(vlr));
1014 	p = if_get(sc->sc_ifidx0);
1015 	if (p != NULL)
1016 		memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent));
1017 	if_put(p);
1018 
1019 	vlr.vlr_tag = sc->sc_tag;
1020 
1021 	return (copyout(&vlr, ifr->ifr_data, sizeof(vlr)));
1022 }
1023 
1024 /*
1025  * do a quick check of up and running vlans for existing configurations.
1026  *
1027  * NOTE: this does allow the same config on down vlans, but vlan_up()
1028  * will catch them.
1029  */
1030 int
1031 vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag)
1032 {
1033 	int error = 0;
1034 
1035 	error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR);
1036 	if (error != 0)
1037 		return (error);
1038 
1039 	error = vlan_inuse_locked(type, ifidx, tag);
1040 
1041 	rw_exit(&vlan_tagh_lk);
1042 
1043 	return (error);
1044 }
1045 
1046 int
1047 vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag)
1048 {
1049 	struct vlan_list *tagh, *list;
1050 	struct vlan_softc *sc;
1051 
1052 	tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
1053 	list = &tagh[TAG_HASH(tag)];
1054 
1055 	SMR_SLIST_FOREACH_LOCKED(sc, list, sc_list) {
1056 		if (sc->sc_tag == tag &&
1057 		    sc->sc_type == type && /* wat */
1058 		    sc->sc_ifidx0 == ifidx)
1059 			return (EADDRINUSE);
1060 	}
1061 
1062 	return (0);
1063 }
1064 
1065 int
1066 vlan_multi_add(struct vlan_softc *sc, struct ifreq *ifr)
1067 {
1068 	struct ifnet *ifp0;
1069 	struct vlan_mc_entry *mc;
1070 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1071 	int error;
1072 
1073 	error = ether_addmulti(ifr, &sc->sc_ac);
1074 	if (error != ENETRESET)
1075 		return (error);
1076 
1077 	/*
1078 	 * This is new multicast address.  We have to tell parent
1079 	 * about it.  Also, remember this multicast address so that
1080 	 * we can delete them on unconfigure.
1081 	 */
1082 	if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) {
1083 		error = ENOMEM;
1084 		goto alloc_failed;
1085 	}
1086 
1087 	/*
1088 	 * As ether_addmulti() returns ENETRESET, following two
1089 	 * statement shouldn't fail.
1090 	 */
1091 	(void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1092 	ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, mc->mc_enm);
1093 	memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len);
1094 	LIST_INSERT_HEAD(&sc->sc_mc_listhead, mc, mc_entries);
1095 
1096 	ifp0 = if_get(sc->sc_ifidx0);
1097 	error = (ifp0 == NULL) ? 0 :
1098 	    (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr);
1099 	if_put(ifp0);
1100 
1101 	if (error != 0)
1102 		goto ioctl_failed;
1103 
1104 	return (error);
1105 
1106  ioctl_failed:
1107 	LIST_REMOVE(mc, mc_entries);
1108 	free(mc, M_DEVBUF, sizeof(*mc));
1109  alloc_failed:
1110 	(void)ether_delmulti(ifr, &sc->sc_ac);
1111 
1112 	return (error);
1113 }
1114 
1115 int
1116 vlan_multi_del(struct vlan_softc *sc, struct ifreq *ifr)
1117 {
1118 	struct ifnet *ifp0;
1119 	struct ether_multi *enm;
1120 	struct vlan_mc_entry *mc;
1121 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1122 	int error;
1123 
1124 	/*
1125 	 * Find a key to lookup vlan_mc_entry.  We have to do this
1126 	 * before calling ether_delmulti for obvious reason.
1127 	 */
1128 	if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0)
1129 		return (error);
1130 	ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, enm);
1131 	if (enm == NULL)
1132 		return (EINVAL);
1133 
1134 	LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) {
1135 		if (mc->mc_enm == enm)
1136 			break;
1137 	}
1138 
1139 	/* We won't delete entries we didn't add */
1140 	if (mc == NULL)
1141 		return (EINVAL);
1142 
1143 	error = ether_delmulti(ifr, &sc->sc_ac);
1144 	if (error != ENETRESET)
1145 		return (error);
1146 
1147 	if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING))
1148 		goto forget;
1149 
1150 	ifp0 = if_get(sc->sc_ifidx0);
1151 	error = (ifp0 == NULL) ? 0 :
1152 	    (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr);
1153 	if_put(ifp0);
1154 
1155 	if (error != 0) {
1156 		(void)ether_addmulti(ifr, &sc->sc_ac);
1157 		return (error);
1158 	}
1159 
1160 forget:
1161 	/* forget about this address */
1162 	LIST_REMOVE(mc, mc_entries);
1163 	free(mc, M_DEVBUF, sizeof(*mc));
1164 
1165 	return (0);
1166 }
1167 
1168 int
1169 vlan_media_get(struct vlan_softc *sc, struct ifreq *ifr)
1170 {
1171 	struct ifnet *ifp0;
1172 	int error;
1173 
1174 	ifp0 = if_get(sc->sc_ifidx0);
1175 	error = (ifp0 == NULL) ? ENOTTY :
1176 	    (*ifp0->if_ioctl)(ifp0, SIOCGIFMEDIA, (caddr_t)ifr);
1177 	if_put(ifp0);
1178 
1179 	return (error);
1180 }
1181 
1182 void
1183 vlan_multi_apply(struct vlan_softc *sc, struct ifnet *ifp0, u_long cmd)
1184 {
1185 	struct vlan_mc_entry *mc;
1186 	union {
1187 		struct ifreq ifreq;
1188 		struct {
1189 			char			ifr_name[IFNAMSIZ];
1190 			struct sockaddr_storage	ifr_ss;
1191 		} ifreq_storage;
1192 	} ifreq;
1193 	struct ifreq *ifr = &ifreq.ifreq;
1194 
1195 	memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ);
1196 	LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) {
1197 		memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len);
1198 
1199 		(void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr);
1200 	}
1201 }
1202 
1203 void
1204 vlan_multi_free(struct vlan_softc *sc)
1205 {
1206 	struct vlan_mc_entry *mc;
1207 
1208 	while ((mc = LIST_FIRST(&sc->sc_mc_listhead)) != NULL) {
1209 		LIST_REMOVE(mc, mc_entries);
1210 		free(mc, M_DEVBUF, sizeof(*mc));
1211 	}
1212 }
1213