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