xref: /openbsd/sys/net/if_vlan.c (revision 73471bf0)
1 /*	$OpenBSD: if_vlan.c,v 1.209 2021/08/30 14:44:39 jasper 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 	NET_ASSERT_LOCKED();
680 	if (sc->sc_dead)
681 		return (ENXIO);
682 
683 	switch (cmd) {
684 	case SIOCSIFADDR:
685 		ifp->if_flags |= IFF_UP;
686 		/* FALLTHROUGH */
687 
688 	case SIOCSIFFLAGS:
689 		if (ISSET(ifp->if_flags, IFF_UP)) {
690 			if (!ISSET(ifp->if_flags, IFF_RUNNING))
691 				error = vlan_up(sc);
692 			else
693 				error = ENETRESET;
694 		} else {
695 			if (ISSET(ifp->if_flags, IFF_RUNNING))
696 				error = vlan_down(sc);
697 		}
698 		break;
699 
700 	case SIOCSVNETID:
701 		if (ifr->ifr_vnetid < EVL_VLID_MIN ||
702 		    ifr->ifr_vnetid > EVL_VLID_MAX) {
703 			error = EINVAL;
704 			break;
705 		}
706 
707 		tag = ifr->ifr_vnetid;
708 		if (tag == sc->sc_tag)
709 			break;
710 
711 		error = vlan_set_vnetid(sc, tag);
712 		break;
713 
714 	case SIOCGVNETID:
715 		if (sc->sc_tag == EVL_VLID_NULL)
716 			error = EADDRNOTAVAIL;
717 		else
718 			ifr->ifr_vnetid = (int64_t)sc->sc_tag;
719 		break;
720 
721 	case SIOCDVNETID:
722 		error = vlan_set_vnetid(sc, 0);
723 		break;
724 
725 	case SIOCSIFPARENT:
726 		error = vlan_set_parent(sc, parent->ifp_parent);
727 		break;
728 
729 	case SIOCGIFPARENT:
730 		ifp0 = if_get(sc->sc_ifidx0);
731 		if (ifp0 == NULL)
732 			error = EADDRNOTAVAIL;
733 		else {
734 			memcpy(parent->ifp_parent, ifp0->if_xname,
735 			    sizeof(parent->ifp_parent));
736 		}
737 		if_put(ifp0);
738 		break;
739 
740 	case SIOCDIFPARENT:
741 		error = vlan_del_parent(sc);
742 		break;
743 
744 	case SIOCADDMULTI:
745 		error = vlan_multi_add(sc, ifr);
746 		break;
747 
748 	case SIOCDELMULTI:
749 		error = vlan_multi_del(sc, ifr);
750 		break;
751 
752 	case SIOCGIFMEDIA:
753 		error = vlan_media_get(sc, ifr);
754 		break;
755 
756 	case SIOCSIFMEDIA:
757 		error = ENOTTY;
758 		break;
759 
760 	case SIOCSIFLLADDR:
761 		error = vlan_setlladdr(sc, ifr);
762 		break;
763 
764 	case SIOCSETVLAN:
765 		error = vlan_set_compat(ifp, ifr);
766 		break;
767 	case SIOCGETVLAN:
768 		error = vlan_get_compat(ifp, ifr);
769 		break;
770 
771 	case SIOCSTXHPRIO:
772 		error = if_txhprio_l2_check(ifr->ifr_hdrprio);
773 		if (error != 0)
774 			break;
775 
776 		sc->sc_txprio = ifr->ifr_hdrprio;
777 		break;
778 	case SIOCGTXHPRIO:
779 		ifr->ifr_hdrprio = sc->sc_txprio;
780 		break;
781 
782 	case SIOCSRXHPRIO:
783 		error = if_rxhprio_l2_check(ifr->ifr_hdrprio);
784 		if (error != 0)
785 			break;
786 
787 		sc->sc_rxprio = ifr->ifr_hdrprio;
788 		break;
789 	case SIOCGRXHPRIO:
790 		ifr->ifr_hdrprio = sc->sc_rxprio;
791 		break;
792 
793 	default:
794 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
795 		break;
796 	}
797 
798 	if (error == ENETRESET)
799 		error = vlan_iff(sc);
800 
801 	return error;
802 }
803 
804 int
805 vlan_iff(struct vlan_softc *sc)
806 {
807 	struct ifnet *ifp0;
808 	int promisc = 0;
809 	int error = 0;
810 
811 	if (ISSET(sc->sc_if.if_flags, IFF_PROMISC) ||
812 	    ISSET(sc->sc_flags, IFVF_LLADDR))
813 		promisc = IFVF_PROMISC;
814 
815 	if (ISSET(sc->sc_flags, IFVF_PROMISC) == promisc)
816 		return (0);
817 
818 	if (ISSET(sc->sc_if.if_flags, IFF_RUNNING)) {
819 		ifp0 = if_get(sc->sc_ifidx0);
820 		if (ifp0 != NULL)
821 			error = ifpromisc(ifp0, promisc);
822 		if_put(ifp0);
823 	}
824 
825 	if (error == 0) {
826 		CLR(sc->sc_flags, IFVF_PROMISC);
827 		SET(sc->sc_flags, promisc);
828 	}
829 
830 	return (error);
831 }
832 
833 int
834 vlan_setlladdr(struct vlan_softc *sc, struct ifreq *ifr)
835 {
836 	struct ifnet *ifp = &sc->sc_if;
837 	struct ifnet *ifp0;
838 	uint8_t lladdr[ETHER_ADDR_LEN];
839 	int flag;
840 
841 	memcpy(lladdr, ifr->ifr_addr.sa_data, sizeof(lladdr));
842 
843 	/* setting the mac addr to 00:00:00:00:00:00 means reset lladdr */
844 	if (memcmp(lladdr, etheranyaddr, sizeof(lladdr)) == 0) {
845 		ifp0 = if_get(sc->sc_ifidx0);
846 		if (ifp0 != NULL)
847 			memcpy(lladdr, LLADDR(ifp0->if_sadl), sizeof(lladdr));
848 		if_put(ifp0);
849 
850 		flag = 0;
851 	} else
852 		flag = IFVF_LLADDR;
853 
854 	if (memcmp(lladdr, LLADDR(ifp->if_sadl), sizeof(lladdr)) == 0 &&
855 	    ISSET(sc->sc_flags, IFVF_LLADDR) == flag) {
856 		/* nop */
857 		return (0);
858 	}
859 
860 	/* commit */
861 	if_setlladdr(ifp, lladdr);
862 	CLR(sc->sc_flags, IFVF_LLADDR);
863 	SET(sc->sc_flags, flag);
864 
865 	return (ENETRESET);
866 }
867 
868 int
869 vlan_set_vnetid(struct vlan_softc *sc, uint16_t tag)
870 {
871 	struct ifnet *ifp = &sc->sc_if;
872 	struct vlan_list *tagh, *list;
873 	u_char link = ifp->if_link_state;
874 	uint64_t baud = ifp->if_baudrate;
875 	int error;
876 
877 	tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
878 
879 	if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link))
880 		vlan_link_state(sc, LINK_STATE_DOWN, 0);
881 
882 	error = rw_enter(&vlan_tagh_lk, RW_WRITE);
883 	if (error != 0)
884 		return (error);
885 
886 	error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, tag);
887 	if (error != 0)
888 		goto unlock;
889 
890 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
891 		list = &tagh[TAG_HASH(sc->sc_tag)];
892 		SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list);
893 
894 		sc->sc_tag = tag;
895 
896 		list = &tagh[TAG_HASH(sc->sc_tag)];
897 		SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list);
898 	} else
899 		sc->sc_tag = tag;
900 
901 unlock:
902 	rw_exit(&vlan_tagh_lk);
903 
904 	if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link))
905 		vlan_link_state(sc, link, baud);
906 
907 	return (error);
908 }
909 
910 int
911 vlan_set_parent(struct vlan_softc *sc, const char *parent)
912 {
913 	struct ifnet *ifp = &sc->sc_if;
914 	struct ifnet *ifp0;
915 	int error = 0;
916 
917 	ifp0 = if_unit(parent);
918 	if (ifp0 == NULL)
919 		return (EINVAL);
920 
921 	if (ifp0->if_type != IFT_ETHER) {
922 		error = EPROTONOSUPPORT;
923 		goto put;
924 	}
925 
926 	if (sc->sc_ifidx0 == ifp0->if_index) {
927 		/* nop */
928 		goto put;
929 	}
930 
931 	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
932 		error = EBUSY;
933 		goto put;
934 	}
935 
936 	error = vlan_inuse(sc->sc_type, ifp0->if_index, sc->sc_tag);
937 	if (error != 0)
938 		goto put;
939 
940 	/* commit */
941 	sc->sc_ifidx0 = ifp0->if_index;
942 	if (!ISSET(sc->sc_flags, IFVF_LLADDR))
943 		if_setlladdr(ifp, LLADDR(ifp0->if_sadl));
944 
945 put:
946 	if_put(ifp0);
947 	return (error);
948 }
949 
950 int
951 vlan_del_parent(struct vlan_softc *sc)
952 {
953 	struct ifnet *ifp = &sc->sc_if;
954 
955 	if (ISSET(ifp->if_flags, IFF_RUNNING))
956 		return (EBUSY);
957 
958 	/* commit */
959 	sc->sc_ifidx0 = 0;
960 	if (!ISSET(sc->sc_flags, IFVF_LLADDR))
961 		if_setlladdr(ifp, etheranyaddr);
962 
963 	return (0);
964 }
965 
966 int
967 vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr)
968 {
969 	struct vlanreq vlr;
970 	struct ifreq req;
971 	struct if_parent parent;
972 
973 	int error;
974 
975 	error = suser(curproc);
976 	if (error != 0)
977 		return (error);
978 
979 	error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
980 	if (error != 0)
981 		return (error);
982 
983 	if (vlr.vlr_parent[0] == '\0')
984 		return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr));
985 
986 	memset(&req, 0, sizeof(req));
987 	memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name));
988 	req.ifr_vnetid = vlr.vlr_tag;
989 
990 	error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req);
991 	if (error != 0)
992 		return (error);
993 
994 	memset(&parent, 0, sizeof(parent));
995 	memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name));
996 	memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent));
997 	error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent);
998 	if (error != 0)
999 		return (error);
1000 
1001 	memset(&req, 0, sizeof(req));
1002 	memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name));
1003 	SET(ifp->if_flags, IFF_UP);
1004 	return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req));
1005 }
1006 
1007 int
1008 vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr)
1009 {
1010 	struct vlan_softc *sc = ifp->if_softc;
1011 	struct vlanreq vlr;
1012 	struct ifnet *p;
1013 
1014 	memset(&vlr, 0, sizeof(vlr));
1015 	p = if_get(sc->sc_ifidx0);
1016 	if (p != NULL)
1017 		memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent));
1018 	if_put(p);
1019 
1020 	vlr.vlr_tag = sc->sc_tag;
1021 
1022 	return (copyout(&vlr, ifr->ifr_data, sizeof(vlr)));
1023 }
1024 
1025 /*
1026  * do a quick check of up and running vlans for existing configurations.
1027  *
1028  * NOTE: this does allow the same config on down vlans, but vlan_up()
1029  * will catch them.
1030  */
1031 int
1032 vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag)
1033 {
1034 	int error = 0;
1035 
1036 	error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR);
1037 	if (error != 0)
1038 		return (error);
1039 
1040 	error = vlan_inuse_locked(type, ifidx, tag);
1041 
1042 	rw_exit(&vlan_tagh_lk);
1043 
1044 	return (error);
1045 }
1046 
1047 int
1048 vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag)
1049 {
1050 	struct vlan_list *tagh, *list;
1051 	struct vlan_softc *sc;
1052 
1053 	tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh;
1054 	list = &tagh[TAG_HASH(tag)];
1055 
1056 	SMR_SLIST_FOREACH_LOCKED(sc, list, sc_list) {
1057 		if (sc->sc_tag == tag &&
1058 		    sc->sc_type == type && /* wat */
1059 		    sc->sc_ifidx0 == ifidx)
1060 			return (EADDRINUSE);
1061 	}
1062 
1063 	return (0);
1064 }
1065 
1066 int
1067 vlan_multi_add(struct vlan_softc *sc, struct ifreq *ifr)
1068 {
1069 	struct ifnet *ifp0;
1070 	struct vlan_mc_entry *mc;
1071 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1072 	int error;
1073 
1074 	error = ether_addmulti(ifr, &sc->sc_ac);
1075 	if (error != ENETRESET)
1076 		return (error);
1077 
1078 	/*
1079 	 * This is new multicast address.  We have to tell parent
1080 	 * about it.  Also, remember this multicast address so that
1081 	 * we can delete them on unconfigure.
1082 	 */
1083 	if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) {
1084 		error = ENOMEM;
1085 		goto alloc_failed;
1086 	}
1087 
1088 	/*
1089 	 * As ether_addmulti() returns ENETRESET, following two
1090 	 * statement shouldn't fail.
1091 	 */
1092 	(void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1093 	ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, mc->mc_enm);
1094 	memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len);
1095 	LIST_INSERT_HEAD(&sc->sc_mc_listhead, mc, mc_entries);
1096 
1097 	ifp0 = if_get(sc->sc_ifidx0);
1098 	error = (ifp0 == NULL) ? 0 :
1099 	    (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr);
1100 	if_put(ifp0);
1101 
1102 	if (error != 0)
1103 		goto ioctl_failed;
1104 
1105 	return (error);
1106 
1107  ioctl_failed:
1108 	LIST_REMOVE(mc, mc_entries);
1109 	free(mc, M_DEVBUF, sizeof(*mc));
1110  alloc_failed:
1111 	(void)ether_delmulti(ifr, &sc->sc_ac);
1112 
1113 	return (error);
1114 }
1115 
1116 int
1117 vlan_multi_del(struct vlan_softc *sc, struct ifreq *ifr)
1118 {
1119 	struct ifnet *ifp0;
1120 	struct ether_multi *enm;
1121 	struct vlan_mc_entry *mc;
1122 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1123 	int error;
1124 
1125 	/*
1126 	 * Find a key to lookup vlan_mc_entry.  We have to do this
1127 	 * before calling ether_delmulti for obvious reason.
1128 	 */
1129 	if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0)
1130 		return (error);
1131 	ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, enm);
1132 	if (enm == NULL)
1133 		return (EINVAL);
1134 
1135 	LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) {
1136 		if (mc->mc_enm == enm)
1137 			break;
1138 	}
1139 
1140 	/* We won't delete entries we didn't add */
1141 	if (mc == NULL)
1142 		return (EINVAL);
1143 
1144 	error = ether_delmulti(ifr, &sc->sc_ac);
1145 	if (error != ENETRESET)
1146 		return (error);
1147 
1148 	if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING))
1149 		goto forget;
1150 
1151 	ifp0 = if_get(sc->sc_ifidx0);
1152 	error = (ifp0 == NULL) ? 0 :
1153 	    (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr);
1154 	if_put(ifp0);
1155 
1156 	if (error != 0) {
1157 		(void)ether_addmulti(ifr, &sc->sc_ac);
1158 		return (error);
1159 	}
1160 
1161 forget:
1162 	/* forget about this address */
1163 	LIST_REMOVE(mc, mc_entries);
1164 	free(mc, M_DEVBUF, sizeof(*mc));
1165 
1166 	return (0);
1167 }
1168 
1169 int
1170 vlan_media_get(struct vlan_softc *sc, struct ifreq *ifr)
1171 {
1172 	struct ifnet *ifp0;
1173 	int error;
1174 
1175 	ifp0 = if_get(sc->sc_ifidx0);
1176 	error = (ifp0 == NULL) ? ENOTTY :
1177 	    (*ifp0->if_ioctl)(ifp0, SIOCGIFMEDIA, (caddr_t)ifr);
1178 	if_put(ifp0);
1179 
1180 	return (error);
1181 }
1182 
1183 void
1184 vlan_multi_apply(struct vlan_softc *sc, struct ifnet *ifp0, u_long cmd)
1185 {
1186 	struct vlan_mc_entry *mc;
1187 	union {
1188 		struct ifreq ifreq;
1189 		struct {
1190 			char			ifr_name[IFNAMSIZ];
1191 			struct sockaddr_storage	ifr_ss;
1192 		} ifreq_storage;
1193 	} ifreq;
1194 	struct ifreq *ifr = &ifreq.ifreq;
1195 
1196 	memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ);
1197 	LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) {
1198 		memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len);
1199 
1200 		(void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr);
1201 	}
1202 }
1203 
1204 void
1205 vlan_multi_free(struct vlan_softc *sc)
1206 {
1207 	struct vlan_mc_entry *mc;
1208 
1209 	while ((mc = LIST_FIRST(&sc->sc_mc_listhead)) != NULL) {
1210 		LIST_REMOVE(mc, mc_entries);
1211 		free(mc, M_DEVBUF, sizeof(*mc));
1212 	}
1213 }
1214