if_vlan.c revision 1.163 1 /* $NetBSD: if_vlan.c,v 1.163 2021/09/30 04:13:42 yamaguchi Exp $ */
2
3 /*
4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran, and by Jason R. Thorpe of Zembu Labs, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright 1998 Massachusetts Institute of Technology
34 *
35 * Permission to use, copy, modify, and distribute this software and
36 * its documentation for any purpose and without fee is hereby
37 * granted, provided that both the above copyright notice and this
38 * permission notice appear in all copies, that both the above
39 * copyright notice and this permission notice appear in all
40 * supporting documentation, and that the name of M.I.T. not be used
41 * in advertising or publicity pertaining to distribution of the
42 * software without specific, written prior permission. M.I.T. makes
43 * no representations about the suitability of this software for any
44 * purpose. It is provided "as is" without express or implied
45 * warranty.
46 *
47 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
48 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
49 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
50 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
51 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
54 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
56 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * from FreeBSD: if_vlan.c,v 1.16 2000/03/26 15:21:40 charnier Exp
61 * via OpenBSD: if_vlan.c,v 1.4 2000/05/15 19:15:00 chris Exp
62 */
63
64 /*
65 * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs. Might be
66 * extended some day to also handle IEEE 802.1P priority tagging. This is
67 * sort of sneaky in the implementation, since we need to pretend to be
68 * enough of an Ethernet implementation to make ARP work. The way we do
69 * this is by telling everyone that we are an Ethernet interface, and then
70 * catch the packets that ether_output() left on our output queue when it
71 * calls if_start(), rewrite them for use by the real outgoing interface,
72 * and ask it to send them.
73 *
74 * TODO:
75 *
76 * - Need some way to notify vlan interfaces when the parent
77 * interface changes MTU.
78 */
79
80 #include <sys/cdefs.h>
81 __KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.163 2021/09/30 04:13:42 yamaguchi Exp $");
82
83 #ifdef _KERNEL_OPT
84 #include "opt_inet.h"
85 #include "opt_net_mpsafe.h"
86 #endif
87
88 #include <sys/param.h>
89 #include <sys/systm.h>
90 #include <sys/kernel.h>
91 #include <sys/mbuf.h>
92 #include <sys/queue.h>
93 #include <sys/socket.h>
94 #include <sys/sockio.h>
95 #include <sys/systm.h>
96 #include <sys/proc.h>
97 #include <sys/kauth.h>
98 #include <sys/mutex.h>
99 #include <sys/kmem.h>
100 #include <sys/cpu.h>
101 #include <sys/pserialize.h>
102 #include <sys/psref.h>
103 #include <sys/pslist.h>
104 #include <sys/atomic.h>
105 #include <sys/device.h>
106 #include <sys/module.h>
107
108 #include <net/bpf.h>
109 #include <net/if.h>
110 #include <net/if_dl.h>
111 #include <net/if_types.h>
112 #include <net/if_ether.h>
113 #include <net/if_vlanvar.h>
114
115 #ifdef INET
116 #include <netinet/in.h>
117 #include <netinet/if_inarp.h>
118 #endif
119 #ifdef INET6
120 #include <netinet6/in6_ifattach.h>
121 #include <netinet6/in6_var.h>
122 #include <netinet6/nd6.h>
123 #endif
124
125 #include "ioconf.h"
126
127 struct vlan_mc_entry {
128 LIST_ENTRY(vlan_mc_entry) mc_entries;
129 /*
130 * A key to identify this entry. The mc_addr below can't be
131 * used since multiple sockaddr may mapped into the same
132 * ether_multi (e.g., AF_UNSPEC).
133 */
134 struct ether_multi *mc_enm;
135 struct sockaddr_storage mc_addr;
136 };
137
138 struct ifvlan_linkmib {
139 struct ifvlan *ifvm_ifvlan;
140 const struct vlan_multisw *ifvm_msw;
141 int ifvm_encaplen; /* encapsulation length */
142 int ifvm_mtufudge; /* MTU fudged by this much */
143 int ifvm_mintu; /* min transmission unit */
144 uint16_t ifvm_proto; /* encapsulation ethertype */
145 uint16_t ifvm_tag; /* tag to apply on packets */
146 struct ifnet *ifvm_p; /* parent interface of this vlan */
147
148 struct psref_target ifvm_psref;
149 };
150
151 struct ifvlan {
152 struct ethercom ifv_ec;
153 struct ifvlan_linkmib *ifv_mib; /*
154 * reader must use vlan_getref_linkmib()
155 * instead of direct dereference
156 */
157 kmutex_t ifv_lock; /* writer lock for ifv_mib */
158 pserialize_t ifv_psz;
159 void *ifv_linkstate_hook;
160 void *ifv_ifdetach_hook;
161
162 LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead;
163 LIST_ENTRY(ifvlan) ifv_list;
164 struct pslist_entry ifv_hash;
165 int ifv_flags;
166 bool ifv_stopping;
167 };
168
169 #define IFVF_PROMISC 0x01 /* promiscuous mode enabled */
170
171 #define ifv_if ifv_ec.ec_if
172
173 #define ifv_msw ifv_mib.ifvm_msw
174 #define ifv_encaplen ifv_mib.ifvm_encaplen
175 #define ifv_mtufudge ifv_mib.ifvm_mtufudge
176 #define ifv_mintu ifv_mib.ifvm_mintu
177 #define ifv_tag ifv_mib.ifvm_tag
178
179 struct vlan_multisw {
180 int (*vmsw_addmulti)(struct ifvlan *, struct ifreq *);
181 int (*vmsw_delmulti)(struct ifvlan *, struct ifreq *);
182 void (*vmsw_purgemulti)(struct ifvlan *);
183 };
184
185 static int vlan_ether_addmulti(struct ifvlan *, struct ifreq *);
186 static int vlan_ether_delmulti(struct ifvlan *, struct ifreq *);
187 static void vlan_ether_purgemulti(struct ifvlan *);
188
189 const struct vlan_multisw vlan_ether_multisw = {
190 .vmsw_addmulti = vlan_ether_addmulti,
191 .vmsw_delmulti = vlan_ether_delmulti,
192 .vmsw_purgemulti = vlan_ether_purgemulti,
193 };
194
195 static int vlan_clone_create(struct if_clone *, int);
196 static int vlan_clone_destroy(struct ifnet *);
197 static int vlan_config(struct ifvlan *, struct ifnet *, uint16_t);
198 static int vlan_ioctl(struct ifnet *, u_long, void *);
199 static void vlan_start(struct ifnet *);
200 static int vlan_transmit(struct ifnet *, struct mbuf *);
201 static void vlan_link_state_changed(void *);
202 static void vlan_ifdetach(void *);
203 static void vlan_unconfig(struct ifnet *);
204 static int vlan_unconfig_locked(struct ifvlan *, struct ifvlan_linkmib *);
205 static void vlan_hash_init(void);
206 static int vlan_hash_fini(void);
207 static int vlan_tag_hash(uint16_t, u_long);
208 static struct ifvlan_linkmib* vlan_getref_linkmib(struct ifvlan *,
209 struct psref *);
210 static void vlan_putref_linkmib(struct ifvlan_linkmib *, struct psref *);
211 static void vlan_linkmib_update(struct ifvlan *, struct ifvlan_linkmib *);
212 static struct ifvlan_linkmib* vlan_lookup_tag_psref(struct ifnet *,
213 uint16_t, struct psref *);
214
215 static struct {
216 kmutex_t lock;
217 LIST_HEAD(vlan_ifvlist, ifvlan) list;
218 } ifv_list __cacheline_aligned;
219
220
221 #if !defined(VLAN_TAG_HASH_SIZE)
222 #define VLAN_TAG_HASH_SIZE 32
223 #endif
224 static struct {
225 kmutex_t lock;
226 struct pslist_head *lists;
227 u_long mask;
228 } ifv_hash __cacheline_aligned = {
229 .lists = NULL,
230 .mask = 0,
231 };
232
233 pserialize_t vlan_psz __read_mostly;
234 static struct psref_class *ifvm_psref_class __read_mostly;
235
236 struct if_clone vlan_cloner =
237 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
238
239 /* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */
240 static char vlan_zero_pad_buff[ETHER_MIN_LEN];
241
242 static inline int
243 vlan_safe_ifpromisc(struct ifnet *ifp, int pswitch)
244 {
245 int e;
246
247 KERNEL_LOCK_UNLESS_NET_MPSAFE();
248 e = ifpromisc(ifp, pswitch);
249 KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
250
251 return e;
252 }
253
254 __unused static inline int
255 vlan_safe_ifpromisc_locked(struct ifnet *ifp, int pswitch)
256 {
257 int e;
258
259 KERNEL_LOCK_UNLESS_NET_MPSAFE();
260 e = ifpromisc_locked(ifp, pswitch);
261 KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
262
263 return e;
264 }
265
266 void
267 vlanattach(int n)
268 {
269
270 /*
271 * Nothing to do here, initialization is handled by the
272 * module initialization code in vlaninit() below.
273 */
274 }
275
276 static void
277 vlaninit(void)
278 {
279 mutex_init(&ifv_list.lock, MUTEX_DEFAULT, IPL_NONE);
280 LIST_INIT(&ifv_list.list);
281
282 mutex_init(&ifv_hash.lock, MUTEX_DEFAULT, IPL_NONE);
283 vlan_psz = pserialize_create();
284 ifvm_psref_class = psref_class_create("vlanlinkmib", IPL_SOFTNET);
285 if_clone_attach(&vlan_cloner);
286
287 vlan_hash_init();
288 MODULE_HOOK_SET(if_vlan_vlan_input_hook, vlan_input);
289 }
290
291 static int
292 vlandetach(void)
293 {
294 bool is_empty;
295 int error;
296
297 mutex_enter(&ifv_list.lock);
298 is_empty = LIST_EMPTY(&ifv_list.list);
299 mutex_exit(&ifv_list.lock);
300
301 if (!is_empty)
302 return EBUSY;
303
304 error = vlan_hash_fini();
305 if (error != 0)
306 return error;
307
308 if_clone_detach(&vlan_cloner);
309 psref_class_destroy(ifvm_psref_class);
310 pserialize_destroy(vlan_psz);
311 mutex_destroy(&ifv_hash.lock);
312 mutex_destroy(&ifv_list.lock);
313
314 MODULE_HOOK_UNSET(if_vlan_vlan_input_hook);
315 return 0;
316 }
317
318 static void
319 vlan_reset_linkname(struct ifnet *ifp)
320 {
321
322 /*
323 * We start out with a "802.1Q VLAN" type and zero-length
324 * addresses. When we attach to a parent interface, we
325 * inherit its type, address length, address, and data link
326 * type.
327 */
328
329 ifp->if_type = IFT_L2VLAN;
330 ifp->if_addrlen = 0;
331 ifp->if_dlt = DLT_NULL;
332 if_alloc_sadl(ifp);
333 }
334
335 static int
336 vlan_clone_create(struct if_clone *ifc, int unit)
337 {
338 struct ifvlan *ifv;
339 struct ifnet *ifp;
340 struct ifvlan_linkmib *mib;
341
342 ifv = malloc(sizeof(struct ifvlan), M_DEVBUF, M_WAITOK | M_ZERO);
343 mib = kmem_zalloc(sizeof(struct ifvlan_linkmib), KM_SLEEP);
344 ifp = &ifv->ifv_if;
345 LIST_INIT(&ifv->ifv_mc_listhead);
346
347 mib->ifvm_ifvlan = ifv;
348 mib->ifvm_p = NULL;
349 psref_target_init(&mib->ifvm_psref, ifvm_psref_class);
350
351 mutex_init(&ifv->ifv_lock, MUTEX_DEFAULT, IPL_NONE);
352 ifv->ifv_psz = pserialize_create();
353 ifv->ifv_mib = mib;
354
355 mutex_enter(&ifv_list.lock);
356 LIST_INSERT_HEAD(&ifv_list.list, ifv, ifv_list);
357 mutex_exit(&ifv_list.lock);
358
359 if_initname(ifp, ifc->ifc_name, unit);
360 ifp->if_softc = ifv;
361 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
362 #ifdef NET_MPSAFE
363 ifp->if_extflags = IFEF_MPSAFE;
364 #endif
365 ifp->if_start = vlan_start;
366 ifp->if_transmit = vlan_transmit;
367 ifp->if_ioctl = vlan_ioctl;
368 IFQ_SET_READY(&ifp->if_snd);
369 if_initialize(ifp);
370 /*
371 * Set the link state to down.
372 * When the parent interface attaches we will use that link state.
373 * When the parent interface link state changes, so will ours.
374 * When the parent interface detaches, set the link state to down.
375 */
376 ifp->if_link_state = LINK_STATE_DOWN;
377
378 vlan_reset_linkname(ifp);
379 if_register(ifp);
380 return 0;
381 }
382
383 static int
384 vlan_clone_destroy(struct ifnet *ifp)
385 {
386 struct ifvlan *ifv = ifp->if_softc;
387
388 mutex_enter(&ifv_list.lock);
389 LIST_REMOVE(ifv, ifv_list);
390 mutex_exit(&ifv_list.lock);
391
392 IFNET_LOCK(ifp);
393 vlan_unconfig(ifp);
394 IFNET_UNLOCK(ifp);
395 if_detach(ifp);
396
397 psref_target_destroy(&ifv->ifv_mib->ifvm_psref, ifvm_psref_class);
398 kmem_free(ifv->ifv_mib, sizeof(struct ifvlan_linkmib));
399 pserialize_destroy(ifv->ifv_psz);
400 mutex_destroy(&ifv->ifv_lock);
401 free(ifv, M_DEVBUF);
402
403 return 0;
404 }
405
406 /*
407 * Configure a VLAN interface.
408 */
409 static int
410 vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag)
411 {
412 struct ifnet *ifp = &ifv->ifv_if;
413 struct ifvlan_linkmib *nmib = NULL;
414 struct ifvlan_linkmib *omib = NULL;
415 struct ifvlan_linkmib *checkmib;
416 struct psref_target *nmib_psref = NULL;
417 const uint16_t vid = EVL_VLANOFTAG(tag);
418 int error = 0;
419 int idx;
420 bool omib_cleanup = false;
421 struct psref psref;
422
423 /* VLAN ID 0 and 4095 are reserved in the spec */
424 if ((vid == 0) || (vid == 0xfff))
425 return EINVAL;
426
427 nmib = kmem_alloc(sizeof(*nmib), KM_SLEEP);
428 mutex_enter(&ifv->ifv_lock);
429 omib = ifv->ifv_mib;
430
431 if (omib->ifvm_p != NULL) {
432 error = EBUSY;
433 goto done;
434 }
435
436 /* Duplicate check */
437 checkmib = vlan_lookup_tag_psref(p, vid, &psref);
438 if (checkmib != NULL) {
439 vlan_putref_linkmib(checkmib, &psref);
440 error = EEXIST;
441 goto done;
442 }
443
444 *nmib = *omib;
445 nmib_psref = &nmib->ifvm_psref;
446
447 psref_target_init(nmib_psref, ifvm_psref_class);
448
449 switch (p->if_type) {
450 case IFT_ETHER:
451 {
452 struct ethercom *ec = (void *)p;
453 struct vlanid_list *vidmem;
454
455 nmib->ifvm_msw = &vlan_ether_multisw;
456 nmib->ifvm_encaplen = ETHER_VLAN_ENCAP_LEN;
457 nmib->ifvm_mintu = ETHERMIN;
458
459 if (ec->ec_nvlans++ == 0) {
460 IFNET_LOCK(p);
461 error = ether_enable_vlan_mtu(p);
462 IFNET_UNLOCK(p);
463 if (error >= 0) {
464 if (error) {
465 ec->ec_nvlans--;
466 goto done;
467 }
468 nmib->ifvm_mtufudge = 0;
469 } else {
470 /*
471 * Fudge the MTU by the encapsulation size. This
472 * makes us incompatible with strictly compliant
473 * 802.1Q implementations, but allows us to use
474 * the feature with other NetBSD
475 * implementations, which might still be useful.
476 */
477 nmib->ifvm_mtufudge = nmib->ifvm_encaplen;
478 }
479 error = 0;
480 }
481 /* Add a vid to the list */
482 vidmem = kmem_alloc(sizeof(struct vlanid_list), KM_SLEEP);
483 vidmem->vid = vid;
484 ETHER_LOCK(ec);
485 SIMPLEQ_INSERT_TAIL(&ec->ec_vids, vidmem, vid_list);
486 ETHER_UNLOCK(ec);
487
488 if (ec->ec_vlan_cb != NULL) {
489 /*
490 * Call ec_vlan_cb(). It will setup VLAN HW filter or
491 * HW tagging function.
492 */
493 error = (*ec->ec_vlan_cb)(ec, vid, true);
494 if (error) {
495 ec->ec_nvlans--;
496 if (ec->ec_nvlans == 0) {
497 IFNET_LOCK(p);
498 (void)ether_disable_vlan_mtu(p);
499 IFNET_UNLOCK(p);
500 }
501 goto done;
502 }
503 }
504 /*
505 * If the parent interface can do hardware-assisted
506 * VLAN encapsulation, then propagate its hardware-
507 * assisted checksumming flags and tcp segmentation
508 * offload.
509 */
510 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
511 ifp->if_capabilities = p->if_capabilities &
512 (IFCAP_TSOv4 | IFCAP_TSOv6 |
513 IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
514 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
515 IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
516 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_TCPv6_Rx |
517 IFCAP_CSUM_UDPv6_Tx | IFCAP_CSUM_UDPv6_Rx);
518 }
519
520 /*
521 * We inherit the parent's Ethernet address.
522 */
523 ether_ifattach(ifp, CLLADDR(p->if_sadl));
524 ifp->if_hdrlen = sizeof(struct ether_vlan_header); /* XXX? */
525 break;
526 }
527
528 default:
529 error = EPROTONOSUPPORT;
530 goto done;
531 }
532
533 nmib->ifvm_p = p;
534 nmib->ifvm_tag = vid;
535 ifv->ifv_if.if_mtu = p->if_mtu - nmib->ifvm_mtufudge;
536 ifv->ifv_if.if_flags = p->if_flags &
537 (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
538
539 /*
540 * Inherit the if_type from the parent. This allows us
541 * to participate in bridges of that type.
542 */
543 ifv->ifv_if.if_type = p->if_type;
544
545 PSLIST_ENTRY_INIT(ifv, ifv_hash);
546 idx = vlan_tag_hash(vid, ifv_hash.mask);
547
548 mutex_enter(&ifv_hash.lock);
549 PSLIST_WRITER_INSERT_HEAD(&ifv_hash.lists[idx], ifv, ifv_hash);
550 mutex_exit(&ifv_hash.lock);
551
552 vlan_linkmib_update(ifv, nmib);
553 nmib = NULL;
554 nmib_psref = NULL;
555 omib_cleanup = true;
556
557 ifv->ifv_ifdetach_hook = ether_ifdetachhook_establish(p,
558 vlan_ifdetach, ifp);
559
560 /*
561 * We inherit the parents link state.
562 */
563 ifv->ifv_linkstate_hook = if_linkstate_change_establish(p,
564 vlan_link_state_changed, ifv);
565 if_link_state_change(&ifv->ifv_if, p->if_link_state);
566
567 done:
568 mutex_exit(&ifv->ifv_lock);
569
570 if (nmib_psref)
571 psref_target_destroy(nmib_psref, ifvm_psref_class);
572 if (nmib)
573 kmem_free(nmib, sizeof(*nmib));
574 if (omib_cleanup)
575 kmem_free(omib, sizeof(*omib));
576
577 return error;
578 }
579
580 /*
581 * Unconfigure a VLAN interface.
582 */
583 static void
584 vlan_unconfig(struct ifnet *ifp)
585 {
586 struct ifvlan *ifv = ifp->if_softc;
587 struct ifvlan_linkmib *nmib = NULL;
588 int error;
589
590 KASSERT(IFNET_LOCKED(ifp));
591
592 nmib = kmem_alloc(sizeof(*nmib), KM_SLEEP);
593
594 mutex_enter(&ifv->ifv_lock);
595 error = vlan_unconfig_locked(ifv, nmib);
596 mutex_exit(&ifv->ifv_lock);
597
598 if (error)
599 kmem_free(nmib, sizeof(*nmib));
600 }
601 static int
602 vlan_unconfig_locked(struct ifvlan *ifv, struct ifvlan_linkmib *nmib)
603 {
604 struct ifnet *p;
605 struct ifnet *ifp = &ifv->ifv_if;
606 struct psref_target *nmib_psref = NULL;
607 struct ifvlan_linkmib *omib;
608 int error = 0;
609
610 KASSERT(IFNET_LOCKED(ifp));
611 KASSERT(mutex_owned(&ifv->ifv_lock));
612
613 if (ifv->ifv_stopping) {
614 error = -1;
615 goto done;
616 }
617
618 ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);
619
620 omib = ifv->ifv_mib;
621 p = omib->ifvm_p;
622
623 if (p == NULL) {
624 error = -1;
625 goto done;
626 }
627
628 *nmib = *omib;
629 nmib_psref = &nmib->ifvm_psref;
630 psref_target_init(nmib_psref, ifvm_psref_class);
631
632 /*
633 * Since the interface is being unconfigured, we need to empty the
634 * list of multicast groups that we may have joined while we were
635 * alive and remove them from the parent's list also.
636 */
637 (*nmib->ifvm_msw->vmsw_purgemulti)(ifv);
638
639 /* Disconnect from parent. */
640 switch (p->if_type) {
641 case IFT_ETHER:
642 {
643 struct ethercom *ec = (void *)p;
644 struct vlanid_list *vlanidp;
645 uint16_t vid = EVL_VLANOFTAG(nmib->ifvm_tag);
646
647 ETHER_LOCK(ec);
648 SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
649 if (vlanidp->vid == vid) {
650 SIMPLEQ_REMOVE(&ec->ec_vids, vlanidp,
651 vlanid_list, vid_list);
652 break;
653 }
654 }
655 ETHER_UNLOCK(ec);
656 if (vlanidp != NULL)
657 kmem_free(vlanidp, sizeof(*vlanidp));
658
659 if (ec->ec_vlan_cb != NULL) {
660 /*
661 * Call ec_vlan_cb(). It will setup VLAN HW filter or
662 * HW tagging function.
663 */
664 (void)(*ec->ec_vlan_cb)(ec, vid, false);
665 }
666 if (--ec->ec_nvlans == 0) {
667 IFNET_LOCK(p);
668 (void)ether_disable_vlan_mtu(p);
669 IFNET_UNLOCK(p);
670 }
671
672 /* XXX ether_ifdetach must not be called with IFNET_LOCK */
673 ifv->ifv_stopping = true;
674 mutex_exit(&ifv->ifv_lock);
675 IFNET_UNLOCK(ifp);
676 ether_ifdetach(ifp);
677 IFNET_LOCK(ifp);
678 mutex_enter(&ifv->ifv_lock);
679 ifv->ifv_stopping = false;
680
681 /* if_free_sadl must be called with IFNET_LOCK */
682 if_free_sadl(ifp, 1);
683
684 /* Restore vlan_ioctl overwritten by ether_ifdetach */
685 ifp->if_ioctl = vlan_ioctl;
686 vlan_reset_linkname(ifp);
687 break;
688 }
689
690 default:
691 panic("%s: impossible", __func__);
692 }
693
694 nmib->ifvm_p = NULL;
695 ifv->ifv_if.if_mtu = 0;
696 ifv->ifv_flags = 0;
697
698 mutex_enter(&ifv_hash.lock);
699 PSLIST_WRITER_REMOVE(ifv, ifv_hash);
700 pserialize_perform(vlan_psz);
701 mutex_exit(&ifv_hash.lock);
702 PSLIST_ENTRY_DESTROY(ifv, ifv_hash);
703 if_linkstate_change_disestablish(p,
704 ifv->ifv_linkstate_hook, NULL);
705
706 vlan_linkmib_update(ifv, nmib);
707 if_link_state_change(ifp, LINK_STATE_DOWN);
708
709 /*XXX ether_ifdetachhook_disestablish must not called with IFNET_LOCK */
710 IFNET_UNLOCK(ifp);
711 ether_ifdetachhook_disestablish(p, ifv->ifv_ifdetach_hook,
712 &ifv->ifv_lock);
713 mutex_exit(&ifv->ifv_lock);
714 IFNET_LOCK(ifp);
715
716 nmib_psref = NULL;
717 kmem_free(omib, sizeof(*omib));
718
719 #ifdef INET6
720 KERNEL_LOCK_UNLESS_NET_MPSAFE();
721 /* To delete v6 link local addresses */
722 if (in6_present)
723 in6_ifdetach(ifp);
724 KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
725 #endif
726
727 if_down_locked(ifp);
728 ifp->if_capabilities = 0;
729 mutex_enter(&ifv->ifv_lock);
730 done:
731 if (nmib_psref)
732 psref_target_destroy(nmib_psref, ifvm_psref_class);
733
734 return error;
735 }
736
737 static void
738 vlan_hash_init(void)
739 {
740
741 ifv_hash.lists = hashinit(VLAN_TAG_HASH_SIZE, HASH_PSLIST, true,
742 &ifv_hash.mask);
743 }
744
745 static int
746 vlan_hash_fini(void)
747 {
748 int i;
749
750 mutex_enter(&ifv_hash.lock);
751
752 for (i = 0; i < ifv_hash.mask + 1; i++) {
753 if (PSLIST_WRITER_FIRST(&ifv_hash.lists[i], struct ifvlan,
754 ifv_hash) != NULL) {
755 mutex_exit(&ifv_hash.lock);
756 return EBUSY;
757 }
758 }
759
760 for (i = 0; i < ifv_hash.mask + 1; i++)
761 PSLIST_DESTROY(&ifv_hash.lists[i]);
762
763 mutex_exit(&ifv_hash.lock);
764
765 hashdone(ifv_hash.lists, HASH_PSLIST, ifv_hash.mask);
766
767 ifv_hash.lists = NULL;
768 ifv_hash.mask = 0;
769
770 return 0;
771 }
772
773 static int
774 vlan_tag_hash(uint16_t tag, u_long mask)
775 {
776 uint32_t hash;
777
778 hash = (tag >> 8) ^ tag;
779 hash = (hash >> 2) ^ hash;
780
781 return hash & mask;
782 }
783
784 static struct ifvlan_linkmib *
785 vlan_getref_linkmib(struct ifvlan *sc, struct psref *psref)
786 {
787 struct ifvlan_linkmib *mib;
788 int s;
789
790 s = pserialize_read_enter();
791 mib = atomic_load_consume(&sc->ifv_mib);
792 if (mib == NULL) {
793 pserialize_read_exit(s);
794 return NULL;
795 }
796 psref_acquire(psref, &mib->ifvm_psref, ifvm_psref_class);
797 pserialize_read_exit(s);
798
799 return mib;
800 }
801
802 static void
803 vlan_putref_linkmib(struct ifvlan_linkmib *mib, struct psref *psref)
804 {
805 if (mib == NULL)
806 return;
807 psref_release(psref, &mib->ifvm_psref, ifvm_psref_class);
808 }
809
810 static struct ifvlan_linkmib *
811 vlan_lookup_tag_psref(struct ifnet *ifp, uint16_t tag, struct psref *psref)
812 {
813 int idx;
814 int s;
815 struct ifvlan *sc;
816
817 idx = vlan_tag_hash(tag, ifv_hash.mask);
818
819 s = pserialize_read_enter();
820 PSLIST_READER_FOREACH(sc, &ifv_hash.lists[idx], struct ifvlan,
821 ifv_hash) {
822 struct ifvlan_linkmib *mib = atomic_load_consume(&sc->ifv_mib);
823 if (mib == NULL)
824 continue;
825 if (mib->ifvm_tag != tag)
826 continue;
827 if (mib->ifvm_p != ifp)
828 continue;
829
830 psref_acquire(psref, &mib->ifvm_psref, ifvm_psref_class);
831 pserialize_read_exit(s);
832 return mib;
833 }
834 pserialize_read_exit(s);
835 return NULL;
836 }
837
838 static void
839 vlan_linkmib_update(struct ifvlan *ifv, struct ifvlan_linkmib *nmib)
840 {
841 struct ifvlan_linkmib *omib = ifv->ifv_mib;
842
843 KASSERT(mutex_owned(&ifv->ifv_lock));
844
845 atomic_store_release(&ifv->ifv_mib, nmib);
846
847 pserialize_perform(ifv->ifv_psz);
848 psref_target_destroy(&omib->ifvm_psref, ifvm_psref_class);
849 }
850
851 /*
852 * Called when a parent interface is detaching; destroy any VLAN
853 * configuration for the parent interface.
854 */
855 static void
856 vlan_ifdetach(void *xifp)
857 {
858 struct ifnet *ifp;
859
860 ifp = (struct ifnet *)xifp;
861
862 /* IFNET_LOCK must be held before ifv_lock. */
863 IFNET_LOCK(ifp);
864 vlan_unconfig(ifp);
865 IFNET_UNLOCK(ifp);
866 }
867
868 static int
869 vlan_set_promisc(struct ifnet *ifp)
870 {
871 struct ifvlan *ifv = ifp->if_softc;
872 struct ifvlan_linkmib *mib;
873 struct psref psref;
874 int error = 0;
875 int bound;
876
877 bound = curlwp_bind();
878 mib = vlan_getref_linkmib(ifv, &psref);
879 if (mib == NULL) {
880 curlwp_bindx(bound);
881 return EBUSY;
882 }
883
884 if ((ifp->if_flags & IFF_PROMISC) != 0) {
885 if ((ifv->ifv_flags & IFVF_PROMISC) == 0) {
886 error = vlan_safe_ifpromisc(mib->ifvm_p, 1);
887 if (error == 0)
888 ifv->ifv_flags |= IFVF_PROMISC;
889 }
890 } else {
891 if ((ifv->ifv_flags & IFVF_PROMISC) != 0) {
892 error = vlan_safe_ifpromisc(mib->ifvm_p, 0);
893 if (error == 0)
894 ifv->ifv_flags &= ~IFVF_PROMISC;
895 }
896 }
897 vlan_putref_linkmib(mib, &psref);
898 curlwp_bindx(bound);
899
900 return error;
901 }
902
903 static int
904 vlan_ioctl(struct ifnet *ifp, u_long cmd, void *data)
905 {
906 struct lwp *l = curlwp;
907 struct ifvlan *ifv = ifp->if_softc;
908 struct ifaddr *ifa = (struct ifaddr *) data;
909 struct ifreq *ifr = (struct ifreq *) data;
910 struct ifnet *pr;
911 struct ifcapreq *ifcr;
912 struct vlanreq vlr;
913 struct ifvlan_linkmib *mib;
914 struct psref psref;
915 int error = 0;
916 int bound;
917
918 switch (cmd) {
919 case SIOCSIFMTU:
920 bound = curlwp_bind();
921 mib = vlan_getref_linkmib(ifv, &psref);
922 if (mib == NULL) {
923 curlwp_bindx(bound);
924 error = EBUSY;
925 break;
926 }
927
928 if (mib->ifvm_p == NULL) {
929 vlan_putref_linkmib(mib, &psref);
930 curlwp_bindx(bound);
931 error = EINVAL;
932 } else if (
933 ifr->ifr_mtu > (mib->ifvm_p->if_mtu - mib->ifvm_mtufudge) ||
934 ifr->ifr_mtu < (mib->ifvm_mintu - mib->ifvm_mtufudge)) {
935 vlan_putref_linkmib(mib, &psref);
936 curlwp_bindx(bound);
937 error = EINVAL;
938 } else {
939 vlan_putref_linkmib(mib, &psref);
940 curlwp_bindx(bound);
941
942 error = ifioctl_common(ifp, cmd, data);
943 if (error == ENETRESET)
944 error = 0;
945 }
946
947 break;
948
949 case SIOCSETVLAN:
950 if ((error = kauth_authorize_network(l->l_cred,
951 KAUTH_NETWORK_INTERFACE,
952 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
953 NULL)) != 0)
954 break;
955 if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0)
956 break;
957
958 if (vlr.vlr_parent[0] == '\0') {
959 bound = curlwp_bind();
960 mib = vlan_getref_linkmib(ifv, &psref);
961 if (mib == NULL) {
962 curlwp_bindx(bound);
963 error = EBUSY;
964 break;
965 }
966
967 if (mib->ifvm_p != NULL &&
968 (ifp->if_flags & IFF_PROMISC) != 0)
969 error = vlan_safe_ifpromisc(mib->ifvm_p, 0);
970
971 vlan_putref_linkmib(mib, &psref);
972 curlwp_bindx(bound);
973
974 vlan_unconfig(ifp);
975 break;
976 }
977 if (vlr.vlr_tag != EVL_VLANOFTAG(vlr.vlr_tag)) {
978 error = EINVAL; /* check for valid tag */
979 break;
980 }
981 if ((pr = ifunit(vlr.vlr_parent)) == NULL) {
982 error = ENOENT;
983 break;
984 }
985
986 error = vlan_config(ifv, pr, vlr.vlr_tag);
987 if (error != 0)
988 break;
989
990 /* Update promiscuous mode, if necessary. */
991 vlan_set_promisc(ifp);
992
993 ifp->if_flags |= IFF_RUNNING;
994 break;
995
996 case SIOCGETVLAN:
997 memset(&vlr, 0, sizeof(vlr));
998 bound = curlwp_bind();
999 mib = vlan_getref_linkmib(ifv, &psref);
1000 if (mib == NULL) {
1001 curlwp_bindx(bound);
1002 error = EBUSY;
1003 break;
1004 }
1005 if (mib->ifvm_p != NULL) {
1006 snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), "%s",
1007 mib->ifvm_p->if_xname);
1008 vlr.vlr_tag = mib->ifvm_tag;
1009 }
1010 vlan_putref_linkmib(mib, &psref);
1011 curlwp_bindx(bound);
1012 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr));
1013 break;
1014
1015 case SIOCSIFFLAGS:
1016 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1017 break;
1018 /*
1019 * For promiscuous mode, we enable promiscuous mode on
1020 * the parent if we need promiscuous on the VLAN interface.
1021 */
1022 bound = curlwp_bind();
1023 mib = vlan_getref_linkmib(ifv, &psref);
1024 if (mib == NULL) {
1025 curlwp_bindx(bound);
1026 error = EBUSY;
1027 break;
1028 }
1029
1030 if (mib->ifvm_p != NULL)
1031 error = vlan_set_promisc(ifp);
1032 vlan_putref_linkmib(mib, &psref);
1033 curlwp_bindx(bound);
1034 break;
1035
1036 case SIOCADDMULTI:
1037 mutex_enter(&ifv->ifv_lock);
1038 mib = ifv->ifv_mib;
1039 if (mib == NULL) {
1040 error = EBUSY;
1041 mutex_exit(&ifv->ifv_lock);
1042 break;
1043 }
1044
1045 error = (mib->ifvm_p != NULL) ?
1046 (*mib->ifvm_msw->vmsw_addmulti)(ifv, ifr) : EINVAL;
1047 mib = NULL;
1048 mutex_exit(&ifv->ifv_lock);
1049 break;
1050
1051 case SIOCDELMULTI:
1052 mutex_enter(&ifv->ifv_lock);
1053 mib = ifv->ifv_mib;
1054 if (mib == NULL) {
1055 error = EBUSY;
1056 mutex_exit(&ifv->ifv_lock);
1057 break;
1058 }
1059 error = (mib->ifvm_p != NULL) ?
1060 (*mib->ifvm_msw->vmsw_delmulti)(ifv, ifr) : EINVAL;
1061 mib = NULL;
1062 mutex_exit(&ifv->ifv_lock);
1063 break;
1064
1065 case SIOCSIFCAP:
1066 ifcr = data;
1067 /* make sure caps are enabled on parent */
1068 bound = curlwp_bind();
1069 mib = vlan_getref_linkmib(ifv, &psref);
1070 if (mib == NULL) {
1071 curlwp_bindx(bound);
1072 error = EBUSY;
1073 break;
1074 }
1075
1076 if (mib->ifvm_p == NULL) {
1077 vlan_putref_linkmib(mib, &psref);
1078 curlwp_bindx(bound);
1079 error = EINVAL;
1080 break;
1081 }
1082 if ((mib->ifvm_p->if_capenable & ifcr->ifcr_capenable) !=
1083 ifcr->ifcr_capenable) {
1084 vlan_putref_linkmib(mib, &psref);
1085 curlwp_bindx(bound);
1086 error = EINVAL;
1087 break;
1088 }
1089
1090 vlan_putref_linkmib(mib, &psref);
1091 curlwp_bindx(bound);
1092
1093 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
1094 error = 0;
1095 break;
1096 case SIOCINITIFADDR:
1097 bound = curlwp_bind();
1098 mib = vlan_getref_linkmib(ifv, &psref);
1099 if (mib == NULL) {
1100 curlwp_bindx(bound);
1101 error = EBUSY;
1102 break;
1103 }
1104
1105 if (mib->ifvm_p == NULL) {
1106 error = EINVAL;
1107 vlan_putref_linkmib(mib, &psref);
1108 curlwp_bindx(bound);
1109 break;
1110 }
1111 vlan_putref_linkmib(mib, &psref);
1112 curlwp_bindx(bound);
1113
1114 ifp->if_flags |= IFF_UP;
1115 #ifdef INET
1116 if (ifa->ifa_addr->sa_family == AF_INET)
1117 arp_ifinit(ifp, ifa);
1118 #endif
1119 break;
1120
1121 default:
1122 error = ether_ioctl(ifp, cmd, data);
1123 }
1124
1125 return error;
1126 }
1127
1128 static int
1129 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr)
1130 {
1131 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr);
1132 struct vlan_mc_entry *mc;
1133 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1134 struct ifvlan_linkmib *mib;
1135 int error;
1136
1137 KASSERT(mutex_owned(&ifv->ifv_lock));
1138
1139 if (sa->sa_len > sizeof(struct sockaddr_storage))
1140 return EINVAL;
1141
1142 error = ether_addmulti(sa, &ifv->ifv_ec);
1143 if (error != ENETRESET)
1144 return error;
1145
1146 /*
1147 * This is a new multicast address. We have to tell parent
1148 * about it. Also, remember this multicast address so that
1149 * we can delete it on unconfigure.
1150 */
1151 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT);
1152 if (mc == NULL) {
1153 error = ENOMEM;
1154 goto alloc_failed;
1155 }
1156
1157 /*
1158 * Since ether_addmulti() returned ENETRESET, the following two
1159 * statements shouldn't fail. Here ifv_ec is implicitly protected
1160 * by the ifv_lock lock.
1161 */
1162 error = ether_multiaddr(sa, addrlo, addrhi);
1163 KASSERT(error == 0);
1164
1165 ETHER_LOCK(&ifv->ifv_ec);
1166 mc->mc_enm = ether_lookup_multi(addrlo, addrhi, &ifv->ifv_ec);
1167 ETHER_UNLOCK(&ifv->ifv_ec);
1168
1169 KASSERT(mc->mc_enm != NULL);
1170
1171 memcpy(&mc->mc_addr, sa, sa->sa_len);
1172 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries);
1173
1174 mib = ifv->ifv_mib;
1175
1176 KERNEL_LOCK_UNLESS_IFP_MPSAFE(mib->ifvm_p);
1177 error = if_mcast_op(mib->ifvm_p, SIOCADDMULTI, sa);
1178 KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(mib->ifvm_p);
1179
1180 if (error != 0)
1181 goto ioctl_failed;
1182 return error;
1183
1184 ioctl_failed:
1185 LIST_REMOVE(mc, mc_entries);
1186 free(mc, M_DEVBUF);
1187
1188 alloc_failed:
1189 (void)ether_delmulti(sa, &ifv->ifv_ec);
1190 return error;
1191 }
1192
1193 static int
1194 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr)
1195 {
1196 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr);
1197 struct ether_multi *enm;
1198 struct vlan_mc_entry *mc;
1199 struct ifvlan_linkmib *mib;
1200 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1201 int error;
1202
1203 KASSERT(mutex_owned(&ifv->ifv_lock));
1204
1205 /*
1206 * Find a key to lookup vlan_mc_entry. We have to do this
1207 * before calling ether_delmulti for obvious reasons.
1208 */
1209 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0)
1210 return error;
1211
1212 ETHER_LOCK(&ifv->ifv_ec);
1213 enm = ether_lookup_multi(addrlo, addrhi, &ifv->ifv_ec);
1214 ETHER_UNLOCK(&ifv->ifv_ec);
1215 if (enm == NULL)
1216 return EINVAL;
1217
1218 LIST_FOREACH(mc, &ifv->ifv_mc_listhead, mc_entries) {
1219 if (mc->mc_enm == enm)
1220 break;
1221 }
1222
1223 /* We woun't delete entries we didn't add */
1224 if (mc == NULL)
1225 return EINVAL;
1226
1227 error = ether_delmulti(sa, &ifv->ifv_ec);
1228 if (error != ENETRESET)
1229 return error;
1230
1231 /* We no longer use this multicast address. Tell parent so. */
1232 mib = ifv->ifv_mib;
1233 error = if_mcast_op(mib->ifvm_p, SIOCDELMULTI, sa);
1234
1235 if (error == 0) {
1236 /* And forget about this address. */
1237 LIST_REMOVE(mc, mc_entries);
1238 free(mc, M_DEVBUF);
1239 } else {
1240 (void)ether_addmulti(sa, &ifv->ifv_ec);
1241 }
1242
1243 return error;
1244 }
1245
1246 /*
1247 * Delete any multicast address we have asked to add from parent
1248 * interface. Called when the vlan is being unconfigured.
1249 */
1250 static void
1251 vlan_ether_purgemulti(struct ifvlan *ifv)
1252 {
1253 struct vlan_mc_entry *mc;
1254 struct ifvlan_linkmib *mib;
1255
1256 KASSERT(mutex_owned(&ifv->ifv_lock));
1257 mib = ifv->ifv_mib;
1258 if (mib == NULL) {
1259 return;
1260 }
1261
1262 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) {
1263 (void)if_mcast_op(mib->ifvm_p, SIOCDELMULTI,
1264 sstocsa(&mc->mc_addr));
1265 LIST_REMOVE(mc, mc_entries);
1266 free(mc, M_DEVBUF);
1267 }
1268 }
1269
1270 static void
1271 vlan_start(struct ifnet *ifp)
1272 {
1273 struct ifvlan *ifv = ifp->if_softc;
1274 struct ifnet *p;
1275 struct ethercom *ec;
1276 struct mbuf *m;
1277 struct ifvlan_linkmib *mib;
1278 struct psref psref;
1279 struct ether_header *eh;
1280 int error;
1281
1282 mib = vlan_getref_linkmib(ifv, &psref);
1283 if (mib == NULL)
1284 return;
1285
1286 if (__predict_false(mib->ifvm_p == NULL)) {
1287 vlan_putref_linkmib(mib, &psref);
1288 return;
1289 }
1290
1291 p = mib->ifvm_p;
1292 ec = (void *)mib->ifvm_p;
1293
1294 ifp->if_flags |= IFF_OACTIVE;
1295
1296 for (;;) {
1297 IFQ_DEQUEUE(&ifp->if_snd, m);
1298 if (m == NULL)
1299 break;
1300
1301 if (m->m_len < sizeof(*eh)) {
1302 m = m_pullup(m, sizeof(*eh));
1303 if (m == NULL) {
1304 if_statinc(ifp, if_oerrors);
1305 continue;
1306 }
1307 }
1308
1309 eh = mtod(m, struct ether_header *);
1310 if (ntohs(eh->ether_type) == ETHERTYPE_VLAN) {
1311 m_freem(m);
1312 if_statinc(ifp, if_noproto);
1313 continue;
1314 }
1315
1316 #ifdef ALTQ
1317 /*
1318 * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE is
1319 * defined.
1320 */
1321 KERNEL_LOCK(1, NULL);
1322 /*
1323 * If ALTQ is enabled on the parent interface, do
1324 * classification; the queueing discipline might
1325 * not require classification, but might require
1326 * the address family/header pointer in the pktattr.
1327 */
1328 if (ALTQ_IS_ENABLED(&p->if_snd)) {
1329 switch (p->if_type) {
1330 case IFT_ETHER:
1331 altq_etherclassify(&p->if_snd, m);
1332 break;
1333 default:
1334 panic("%s: impossible (altq)", __func__);
1335 }
1336 }
1337 KERNEL_UNLOCK_ONE(NULL);
1338 #endif /* ALTQ */
1339
1340 bpf_mtap(ifp, m, BPF_D_OUT);
1341 /*
1342 * If the parent can insert the tag itself, just mark
1343 * the tag in the mbuf header.
1344 */
1345 if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
1346 vlan_set_tag(m, mib->ifvm_tag);
1347 } else {
1348 /*
1349 * insert the tag ourselves
1350 */
1351 M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT);
1352 if (m == NULL) {
1353 printf("%s: unable to prepend encap header",
1354 p->if_xname);
1355 if_statinc(ifp, if_oerrors);
1356 continue;
1357 }
1358
1359 switch (p->if_type) {
1360 case IFT_ETHER:
1361 {
1362 struct ether_vlan_header *evl;
1363
1364 if (m->m_len < sizeof(struct ether_vlan_header))
1365 m = m_pullup(m,
1366 sizeof(struct ether_vlan_header));
1367 if (m == NULL) {
1368 printf("%s: unable to pullup encap "
1369 "header", p->if_xname);
1370 if_statinc(ifp, if_oerrors);
1371 continue;
1372 }
1373
1374 /*
1375 * Transform the Ethernet header into an
1376 * Ethernet header with 802.1Q encapsulation.
1377 */
1378 memmove(mtod(m, void *),
1379 mtod(m, char *) + mib->ifvm_encaplen,
1380 sizeof(struct ether_header));
1381 evl = mtod(m, struct ether_vlan_header *);
1382 evl->evl_proto = evl->evl_encap_proto;
1383 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1384 evl->evl_tag = htons(mib->ifvm_tag);
1385
1386 /*
1387 * To cater for VLAN-aware layer 2 ethernet
1388 * switches which may need to strip the tag
1389 * before forwarding the packet, make sure
1390 * the packet+tag is at least 68 bytes long.
1391 * This is necessary because our parent will
1392 * only pad to 64 bytes (ETHER_MIN_LEN) and
1393 * some switches will not pad by themselves
1394 * after deleting a tag.
1395 */
1396 const size_t min_data_len = ETHER_MIN_LEN -
1397 ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN;
1398 if (m->m_pkthdr.len < min_data_len) {
1399 m_copyback(m, m->m_pkthdr.len,
1400 min_data_len - m->m_pkthdr.len,
1401 vlan_zero_pad_buff);
1402 }
1403 break;
1404 }
1405
1406 default:
1407 panic("%s: impossible", __func__);
1408 }
1409 }
1410
1411 if ((p->if_flags & IFF_RUNNING) == 0) {
1412 m_freem(m);
1413 continue;
1414 }
1415
1416 error = if_transmit_lock(p, m);
1417 if (error) {
1418 /* mbuf is already freed */
1419 if_statinc(ifp, if_oerrors);
1420 continue;
1421 }
1422 if_statinc(ifp, if_opackets);
1423 }
1424
1425 ifp->if_flags &= ~IFF_OACTIVE;
1426
1427 /* Remove reference to mib before release */
1428 vlan_putref_linkmib(mib, &psref);
1429 }
1430
1431 static int
1432 vlan_transmit(struct ifnet *ifp, struct mbuf *m)
1433 {
1434 struct ifvlan *ifv = ifp->if_softc;
1435 struct ifnet *p;
1436 struct ethercom *ec;
1437 struct ifvlan_linkmib *mib;
1438 struct psref psref;
1439 struct ether_header *eh;
1440 int error;
1441 size_t pktlen = m->m_pkthdr.len;
1442 bool mcast = (m->m_flags & M_MCAST) != 0;
1443
1444 if (m->m_len < sizeof(*eh)) {
1445 m = m_pullup(m, sizeof(*eh));
1446 if (m == NULL) {
1447 if_statinc(ifp, if_oerrors);
1448 return ENOBUFS;
1449 }
1450 }
1451
1452 eh = mtod(m, struct ether_header *);
1453 if (ntohs(eh->ether_type) == ETHERTYPE_VLAN) {
1454 m_freem(m);
1455 if_statinc(ifp, if_noproto);
1456 return EPROTONOSUPPORT;
1457 }
1458
1459 mib = vlan_getref_linkmib(ifv, &psref);
1460 if (mib == NULL) {
1461 m_freem(m);
1462 return ENETDOWN;
1463 }
1464
1465 if (__predict_false(mib->ifvm_p == NULL)) {
1466 vlan_putref_linkmib(mib, &psref);
1467 m_freem(m);
1468 return ENETDOWN;
1469 }
1470
1471 p = mib->ifvm_p;
1472 ec = (void *)mib->ifvm_p;
1473
1474 bpf_mtap(ifp, m, BPF_D_OUT);
1475
1476 if ((error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
1477 goto out;
1478 if (m == NULL)
1479 goto out;
1480
1481 /*
1482 * If the parent can insert the tag itself, just mark
1483 * the tag in the mbuf header.
1484 */
1485 if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
1486 vlan_set_tag(m, mib->ifvm_tag);
1487 } else {
1488 /*
1489 * insert the tag ourselves
1490 */
1491 M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT);
1492 if (m == NULL) {
1493 printf("%s: unable to prepend encap header",
1494 p->if_xname);
1495 if_statinc(ifp, if_oerrors);
1496 error = ENOBUFS;
1497 goto out;
1498 }
1499
1500 switch (p->if_type) {
1501 case IFT_ETHER:
1502 {
1503 struct ether_vlan_header *evl;
1504
1505 if (m->m_len < sizeof(struct ether_vlan_header))
1506 m = m_pullup(m,
1507 sizeof(struct ether_vlan_header));
1508 if (m == NULL) {
1509 printf("%s: unable to pullup encap "
1510 "header", p->if_xname);
1511 if_statinc(ifp, if_oerrors);
1512 error = ENOBUFS;
1513 goto out;
1514 }
1515
1516 /*
1517 * Transform the Ethernet header into an
1518 * Ethernet header with 802.1Q encapsulation.
1519 */
1520 memmove(mtod(m, void *),
1521 mtod(m, char *) + mib->ifvm_encaplen,
1522 sizeof(struct ether_header));
1523 evl = mtod(m, struct ether_vlan_header *);
1524 evl->evl_proto = evl->evl_encap_proto;
1525 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1526 evl->evl_tag = htons(mib->ifvm_tag);
1527
1528 /*
1529 * To cater for VLAN-aware layer 2 ethernet
1530 * switches which may need to strip the tag
1531 * before forwarding the packet, make sure
1532 * the packet+tag is at least 68 bytes long.
1533 * This is necessary because our parent will
1534 * only pad to 64 bytes (ETHER_MIN_LEN) and
1535 * some switches will not pad by themselves
1536 * after deleting a tag.
1537 */
1538 const size_t min_data_len = ETHER_MIN_LEN -
1539 ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN;
1540 if (m->m_pkthdr.len < min_data_len) {
1541 m_copyback(m, m->m_pkthdr.len,
1542 min_data_len - m->m_pkthdr.len,
1543 vlan_zero_pad_buff);
1544 }
1545 break;
1546 }
1547
1548 default:
1549 panic("%s: impossible", __func__);
1550 }
1551 }
1552
1553 if ((p->if_flags & IFF_RUNNING) == 0) {
1554 m_freem(m);
1555 error = ENETDOWN;
1556 goto out;
1557 }
1558
1559 error = if_transmit_lock(p, m);
1560 net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
1561 if (error) {
1562 /* mbuf is already freed */
1563 if_statinc_ref(nsr, if_oerrors);
1564 } else {
1565 if_statinc_ref(nsr, if_opackets);
1566 if_statadd_ref(nsr, if_obytes, pktlen);
1567 if (mcast)
1568 if_statinc_ref(nsr, if_omcasts);
1569 }
1570 IF_STAT_PUTREF(ifp);
1571
1572 out:
1573 /* Remove reference to mib before release */
1574 vlan_putref_linkmib(mib, &psref);
1575 return error;
1576 }
1577
1578 /*
1579 * Given an Ethernet frame, find a valid vlan interface corresponding to the
1580 * given source interface and tag, then run the real packet through the
1581 * parent's input routine.
1582 */
1583 void
1584 vlan_input(struct ifnet *ifp, struct mbuf *m)
1585 {
1586 struct ifvlan *ifv;
1587 uint16_t vid;
1588 struct ifvlan_linkmib *mib;
1589 struct psref psref;
1590 bool have_vtag;
1591
1592 have_vtag = vlan_has_tag(m);
1593 if (have_vtag) {
1594 vid = EVL_VLANOFTAG(vlan_get_tag(m));
1595 m->m_flags &= ~M_VLANTAG;
1596 } else {
1597 struct ether_vlan_header *evl;
1598
1599 if (ifp->if_type != IFT_ETHER) {
1600 panic("%s: impossible", __func__);
1601 }
1602
1603 if (m->m_len < sizeof(struct ether_vlan_header) &&
1604 (m = m_pullup(m,
1605 sizeof(struct ether_vlan_header))) == NULL) {
1606 printf("%s: no memory for VLAN header, "
1607 "dropping packet.\n", ifp->if_xname);
1608 return;
1609 }
1610
1611 if (m_makewritable(&m, 0,
1612 sizeof(struct ether_vlan_header), M_DONTWAIT)) {
1613 m_freem(m);
1614 if_statinc(ifp, if_ierrors);
1615 return;
1616 }
1617
1618 evl = mtod(m, struct ether_vlan_header *);
1619 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN);
1620
1621 vid = EVL_VLANOFTAG(ntohs(evl->evl_tag));
1622
1623 /*
1624 * Restore the original ethertype. We'll remove
1625 * the encapsulation after we've found the vlan
1626 * interface corresponding to the tag.
1627 */
1628 evl->evl_encap_proto = evl->evl_proto;
1629 }
1630
1631 mib = vlan_lookup_tag_psref(ifp, vid, &psref);
1632 if (mib == NULL) {
1633 m_freem(m);
1634 if_statinc(ifp, if_noproto);
1635 return;
1636 }
1637 KASSERT(mib->ifvm_encaplen == ETHER_VLAN_ENCAP_LEN);
1638
1639 ifv = mib->ifvm_ifvlan;
1640 if ((ifv->ifv_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
1641 (IFF_UP | IFF_RUNNING)) {
1642 m_freem(m);
1643 if_statinc(ifp, if_noproto);
1644 goto out;
1645 }
1646
1647 /*
1648 * Now, remove the encapsulation header. The original
1649 * header has already been fixed up above.
1650 */
1651 if (!have_vtag) {
1652 memmove(mtod(m, char *) + mib->ifvm_encaplen,
1653 mtod(m, void *), sizeof(struct ether_header));
1654 m_adj(m, mib->ifvm_encaplen);
1655 }
1656
1657 /*
1658 * Drop promiscuously received packets if we are not in
1659 * promiscuous mode
1660 */
1661 if ((m->m_flags & (M_BCAST | M_MCAST)) == 0 &&
1662 (ifp->if_flags & IFF_PROMISC) &&
1663 (ifv->ifv_if.if_flags & IFF_PROMISC) == 0) {
1664 struct ether_header *eh;
1665
1666 eh = mtod(m, struct ether_header *);
1667 if (memcmp(CLLADDR(ifv->ifv_if.if_sadl),
1668 eh->ether_dhost, ETHER_ADDR_LEN) != 0) {
1669 m_freem(m);
1670 if_statinc(&ifv->ifv_if, if_ierrors);
1671 goto out;
1672 }
1673 }
1674
1675 m_set_rcvif(m, &ifv->ifv_if);
1676
1677 if (pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
1678 goto out;
1679 if (m == NULL)
1680 goto out;
1681
1682 m->m_flags &= ~M_PROMISC;
1683 if_input(&ifv->ifv_if, m);
1684 out:
1685 vlan_putref_linkmib(mib, &psref);
1686 }
1687
1688 /*
1689 * If the parent link state changed, the vlan link state should change also.
1690 */
1691 static void
1692 vlan_link_state_changed(void *xifv)
1693 {
1694 struct ifvlan *ifv = xifv;
1695 struct ifnet *ifp, *p;
1696 struct ifvlan_linkmib *mib;
1697 struct psref psref;
1698
1699 mib = vlan_getref_linkmib(ifv, &psref);
1700 if (mib == NULL)
1701 return;
1702
1703 if (mib->ifvm_p == NULL) {
1704 vlan_putref_linkmib(mib, &psref);
1705 return;
1706 }
1707
1708 ifp = &ifv->ifv_if;
1709 p = mib->ifvm_p;
1710 if_link_state_change(ifp, p->if_link_state);
1711
1712 vlan_putref_linkmib(mib, &psref);
1713 }
1714
1715 /*
1716 * Module infrastructure
1717 */
1718 #include "if_module.h"
1719
1720 IF_MODULE(MODULE_CLASS_DRIVER, vlan, NULL)
1721