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