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