if_vlan.c revision 1.97.2.7 1 /* $NetBSD: if_vlan.c,v 1.97.2.7 2017/11/22 14:30:23 martin 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.97.2.7 2017/11/22 14:30:23 martin Exp $");
82
83 #ifdef _KERNEL_OPT
84 #include "opt_inet.h"
85 #endif
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/kernel.h>
90 #include <sys/mbuf.h>
91 #include <sys/queue.h>
92 #include <sys/socket.h>
93 #include <sys/sockio.h>
94 #include <sys/systm.h>
95 #include <sys/proc.h>
96 #include <sys/kauth.h>
97 #include <sys/mutex.h>
98 #include <sys/kmem.h>
99 #include <sys/cpu.h>
100 #include <sys/pserialize.h>
101 #include <sys/psref.h>
102 #include <sys/pslist.h>
103 #include <sys/atomic.h>
104 #include <sys/device.h>
105 #include <sys/module.h>
106
107 #include <net/bpf.h>
108 #include <net/if.h>
109 #include <net/if_dl.h>
110 #include <net/if_types.h>
111 #include <net/if_ether.h>
112 #include <net/if_vlanvar.h>
113
114 #ifdef INET
115 #include <netinet/in.h>
116 #include <netinet/if_inarp.h>
117 #endif
118 #ifdef INET6
119 #include <netinet6/in6_ifattach.h>
120 #include <netinet6/in6_var.h>
121 #endif
122
123 #include "ioconf.h"
124
125 struct vlan_mc_entry {
126 LIST_ENTRY(vlan_mc_entry) mc_entries;
127 /*
128 * A key to identify this entry. The mc_addr below can't be
129 * used since multiple sockaddr may mapped into the same
130 * ether_multi (e.g., AF_UNSPEC).
131 */
132 union {
133 struct ether_multi *mcu_enm;
134 } mc_u;
135 struct sockaddr_storage mc_addr;
136 };
137
138 #define mc_enm mc_u.mcu_enm
139
140
141 struct ifvlan_linkmib {
142 struct ifvlan *ifvm_ifvlan;
143 const struct vlan_multisw *ifvm_msw;
144 int ifvm_encaplen; /* encapsulation length */
145 int ifvm_mtufudge; /* MTU fudged by this much */
146 int ifvm_mintu; /* min transmission unit */
147 uint16_t ifvm_proto; /* encapsulation ethertype */
148 uint16_t ifvm_tag; /* tag to apply on packets */
149 struct ifnet *ifvm_p; /* parent interface of this vlan */
150
151 struct psref_target ifvm_psref;
152 };
153
154 struct ifvlan {
155 union {
156 struct ethercom ifvu_ec;
157 } ifv_u;
158 struct ifvlan_linkmib *ifv_mib; /*
159 * reader must use vlan_getref_linkmib()
160 * instead of direct dereference
161 */
162 kmutex_t ifv_lock; /* writer lock for ifv_mib */
163
164 LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead;
165 LIST_ENTRY(ifvlan) ifv_list;
166 struct pslist_entry ifv_hash;
167 int ifv_flags;
168 };
169
170 #define IFVF_PROMISC 0x01 /* promiscuous mode enabled */
171
172 #define ifv_ec ifv_u.ifvu_ec
173
174 #define ifv_if ifv_ec.ec_if
175
176 #define ifv_msw ifv_mib.ifvm_msw
177 #define ifv_encaplen ifv_mib.ifvm_encaplen
178 #define ifv_mtufudge ifv_mib.ifvm_mtufudge
179 #define ifv_mintu ifv_mib.ifvm_mintu
180 #define ifv_tag ifv_mib.ifvm_tag
181
182 struct vlan_multisw {
183 int (*vmsw_addmulti)(struct ifvlan *, struct ifreq *);
184 int (*vmsw_delmulti)(struct ifvlan *, struct ifreq *);
185 void (*vmsw_purgemulti)(struct ifvlan *);
186 };
187
188 static int vlan_ether_addmulti(struct ifvlan *, struct ifreq *);
189 static int vlan_ether_delmulti(struct ifvlan *, struct ifreq *);
190 static void vlan_ether_purgemulti(struct ifvlan *);
191
192 const struct vlan_multisw vlan_ether_multisw = {
193 vlan_ether_addmulti,
194 vlan_ether_delmulti,
195 vlan_ether_purgemulti,
196 };
197
198 static int vlan_clone_create(struct if_clone *, int);
199 static int vlan_clone_destroy(struct ifnet *);
200 static int vlan_config(struct ifvlan *, struct ifnet *,
201 uint16_t);
202 static int vlan_ioctl(struct ifnet *, u_long, void *);
203 static void vlan_start(struct ifnet *);
204 static int vlan_transmit(struct ifnet *, struct mbuf *);
205 static void vlan_unconfig(struct ifnet *);
206 static int vlan_unconfig_locked(struct ifvlan *,
207 struct ifvlan_linkmib *);
208 static void vlan_hash_init(void);
209 static int vlan_hash_fini(void);
210 static struct ifvlan_linkmib* vlan_getref_linkmib(struct ifvlan *,
211 struct psref *);
212 static void vlan_putref_linkmib(struct ifvlan_linkmib *,
213 struct psref *);
214 static void vlan_linkmib_update(struct ifvlan *,
215 struct ifvlan_linkmib *);
216 static struct ifvlan_linkmib* vlan_lookup_tag_psref(struct ifnet *,
217 uint16_t, struct psref *);
218 static int tag_hash_func(uint16_t, u_long);
219
220 LIST_HEAD(vlan_ifvlist, ifvlan);
221 static struct {
222 kmutex_t lock;
223 struct vlan_ifvlist list;
224 } ifv_list __cacheline_aligned;
225
226
227 #if !defined(VLAN_TAG_HASH_SIZE)
228 #define VLAN_TAG_HASH_SIZE 32
229 #endif
230 static struct {
231 kmutex_t lock;
232 struct pslist_head *lists;
233 u_long mask;
234 } ifv_hash __cacheline_aligned = {
235 .lists = NULL,
236 .mask = 0,
237 };
238
239 pserialize_t vlan_psz __read_mostly;
240 static struct psref_class *ifvm_psref_class __read_mostly;
241
242 struct if_clone vlan_cloner =
243 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy);
244
245 /* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */
246 static char vlan_zero_pad_buff[ETHER_MIN_LEN];
247
248 void
249 vlanattach(int n)
250 {
251
252 /*
253 * Nothing to do here, initialization is handled by the
254 * module initialization code in vlaninit() below).
255 */
256 }
257
258 static void
259 vlaninit(void)
260 {
261 mutex_init(&ifv_list.lock, MUTEX_DEFAULT, IPL_NONE);
262 LIST_INIT(&ifv_list.list);
263
264 mutex_init(&ifv_hash.lock, MUTEX_DEFAULT, IPL_NONE);
265 vlan_psz = pserialize_create();
266 ifvm_psref_class = psref_class_create("vlanlinkmib", IPL_SOFTNET);
267 if_clone_attach(&vlan_cloner);
268
269 vlan_hash_init();
270 }
271
272 static int
273 vlandetach(void)
274 {
275 int error = 0;
276
277 mutex_enter(&ifv_list.lock);
278 if (!LIST_EMPTY(&ifv_list.list)) {
279 mutex_exit(&ifv_list.lock);
280 return EBUSY;
281 }
282 mutex_exit(&ifv_list.lock);
283
284 error = vlan_hash_fini();
285 if (error != 0)
286 return error;
287
288 if_clone_detach(&vlan_cloner);
289 psref_class_destroy(ifvm_psref_class);
290 pserialize_destroy(vlan_psz);
291 mutex_destroy(&ifv_hash.lock);
292 mutex_destroy(&ifv_list.lock);
293
294 return 0;
295 }
296
297 static void
298 vlan_reset_linkname(struct ifnet *ifp)
299 {
300
301 /*
302 * We start out with a "802.1Q VLAN" type and zero-length
303 * addresses. When we attach to a parent interface, we
304 * inherit its type, address length, address, and data link
305 * type.
306 */
307
308 ifp->if_type = IFT_L2VLAN;
309 ifp->if_addrlen = 0;
310 ifp->if_dlt = DLT_NULL;
311 if_alloc_sadl(ifp);
312 }
313
314 static int
315 vlan_clone_create(struct if_clone *ifc, int unit)
316 {
317 struct ifvlan *ifv;
318 struct ifnet *ifp;
319 struct ifvlan_linkmib *mib;
320
321 ifv = malloc(sizeof(struct ifvlan), M_DEVBUF, M_WAITOK|M_ZERO);
322 mib = kmem_zalloc(sizeof(struct ifvlan_linkmib), KM_SLEEP);
323 ifp = &ifv->ifv_if;
324 LIST_INIT(&ifv->ifv_mc_listhead);
325
326 mib->ifvm_ifvlan = ifv;
327 mib->ifvm_p = NULL;
328 psref_target_init(&mib->ifvm_psref, ifvm_psref_class);
329
330 mutex_init(&ifv->ifv_lock, MUTEX_DEFAULT, IPL_NONE);
331 ifv->ifv_mib = mib;
332
333 mutex_enter(&ifv_list.lock);
334 LIST_INSERT_HEAD(&ifv_list.list, ifv, ifv_list);
335 mutex_exit(&ifv_list.lock);
336
337 if_initname(ifp, ifc->ifc_name, unit);
338 ifp->if_softc = ifv;
339 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
340 ifp->if_extflags = IFEF_START_MPSAFE | IFEF_NO_LINK_STATE_CHANGE;
341 ifp->if_start = vlan_start;
342 ifp->if_transmit = vlan_transmit;
343 ifp->if_ioctl = vlan_ioctl;
344 IFQ_SET_READY(&ifp->if_snd);
345
346 if_initialize(ifp);
347 vlan_reset_linkname(ifp);
348 if_register(ifp);
349
350 return (0);
351 }
352
353 static int
354 vlan_clone_destroy(struct ifnet *ifp)
355 {
356 struct ifvlan *ifv = ifp->if_softc;
357
358 mutex_enter(&ifv_list.lock);
359 LIST_REMOVE(ifv, ifv_list);
360 mutex_exit(&ifv_list.lock);
361
362 vlan_unconfig(ifp);
363 if_detach(ifp);
364
365 psref_target_destroy(&ifv->ifv_mib->ifvm_psref, ifvm_psref_class);
366 kmem_free(ifv->ifv_mib, sizeof(struct ifvlan_linkmib));
367 mutex_destroy(&ifv->ifv_lock);
368 free(ifv, M_DEVBUF);
369
370 return (0);
371 }
372
373 /*
374 * Configure a VLAN interface.
375 */
376 static int
377 vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag)
378 {
379 struct ifnet *ifp = &ifv->ifv_if;
380 struct ifvlan_linkmib *nmib = NULL;
381 struct ifvlan_linkmib *omib = NULL;
382 struct ifvlan_linkmib *checkmib = NULL;
383 struct psref_target *nmib_psref = NULL;
384 int error = 0;
385 int idx;
386 bool omib_cleanup = false;
387 struct psref psref;
388
389 nmib = kmem_alloc(sizeof(*nmib), KM_SLEEP);
390
391 mutex_enter(&ifv->ifv_lock);
392 omib = ifv->ifv_mib;
393
394 if (omib->ifvm_p != NULL) {
395 error = EBUSY;
396 goto done;
397 }
398
399 /* Duplicate check */
400 checkmib = vlan_lookup_tag_psref(p, tag, &psref);
401 if (checkmib != NULL) {
402 vlan_putref_linkmib(checkmib, &psref);
403 error = EEXIST;
404 goto done;
405 }
406
407 *nmib = *omib;
408 nmib_psref = &nmib->ifvm_psref;
409
410 psref_target_init(nmib_psref, ifvm_psref_class);
411
412 switch (p->if_type) {
413 case IFT_ETHER:
414 {
415 struct ethercom *ec = (void *) p;
416 nmib->ifvm_msw = &vlan_ether_multisw;
417 nmib->ifvm_encaplen = ETHER_VLAN_ENCAP_LEN;
418 nmib->ifvm_mintu = ETHERMIN;
419
420 if (ec->ec_nvlans++ == 0) {
421 if ((error = ether_enable_vlan_mtu(p)) >= 0) {
422 if (error) {
423 ec->ec_nvlans--;
424 goto done;
425 }
426 nmib->ifvm_mtufudge = 0;
427 } else {
428 /*
429 * Fudge the MTU by the encapsulation size. This
430 * makes us incompatible with strictly compliant
431 * 802.1Q implementations, but allows us to use
432 * the feature with other NetBSD
433 * implementations, which might still be useful.
434 */
435 nmib->ifvm_mtufudge = nmib->ifvm_encaplen;
436 }
437 error = 0;
438 }
439
440 /*
441 * If the parent interface can do hardware-assisted
442 * VLAN encapsulation, then propagate its hardware-
443 * assisted checksumming flags and tcp segmentation
444 * offload.
445 */
446 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
447 ec->ec_capenable |= ETHERCAP_VLAN_HWTAGGING;
448 ifp->if_capabilities = p->if_capabilities &
449 (IFCAP_TSOv4 | IFCAP_TSOv6 |
450 IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_IPv4_Rx|
451 IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_TCPv4_Rx|
452 IFCAP_CSUM_UDPv4_Tx|IFCAP_CSUM_UDPv4_Rx|
453 IFCAP_CSUM_TCPv6_Tx|IFCAP_CSUM_TCPv6_Rx|
454 IFCAP_CSUM_UDPv6_Tx|IFCAP_CSUM_UDPv6_Rx);
455 }
456 /*
457 * We inherit the parent's Ethernet address.
458 */
459 ether_ifattach(ifp, CLLADDR(p->if_sadl));
460 ifp->if_hdrlen = sizeof(struct ether_vlan_header); /* XXX? */
461 break;
462 }
463
464 default:
465 error = EPROTONOSUPPORT;
466 goto done;
467 }
468
469 nmib->ifvm_p = p;
470 nmib->ifvm_tag = tag;
471 ifv->ifv_if.if_mtu = p->if_mtu - nmib->ifvm_mtufudge;
472 ifv->ifv_if.if_flags = p->if_flags &
473 (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
474
475 /*
476 * Inherit the if_type from the parent. This allows us
477 * to participate in bridges of that type.
478 */
479 ifv->ifv_if.if_type = p->if_type;
480
481 PSLIST_ENTRY_INIT(ifv, ifv_hash);
482 idx = tag_hash_func(tag, ifv_hash.mask);
483
484 mutex_enter(&ifv_hash.lock);
485 PSLIST_WRITER_INSERT_HEAD(&ifv_hash.lists[idx], ifv, ifv_hash);
486 mutex_exit(&ifv_hash.lock);
487
488 vlan_linkmib_update(ifv, nmib);
489 nmib = NULL;
490 nmib_psref = NULL;
491 omib_cleanup = true;
492
493 done:
494 mutex_exit(&ifv->ifv_lock);
495
496 if (nmib_psref)
497 psref_target_destroy(nmib_psref, ifvm_psref_class);
498
499 if (nmib)
500 kmem_free(nmib, sizeof(*nmib));
501
502 if (omib_cleanup)
503 kmem_free(omib, sizeof(*omib));
504
505 return error;
506 }
507
508 /*
509 * Unconfigure a VLAN interface.
510 */
511 static void
512 vlan_unconfig(struct ifnet *ifp)
513 {
514 struct ifvlan *ifv = ifp->if_softc;
515 struct ifvlan_linkmib *nmib = NULL;
516 int error;
517
518 nmib = kmem_alloc(sizeof(*nmib), KM_SLEEP);
519
520 mutex_enter(&ifv->ifv_lock);
521 error = vlan_unconfig_locked(ifv, nmib);
522 mutex_exit(&ifv->ifv_lock);
523
524 if (error)
525 kmem_free(nmib, sizeof(*nmib));
526 }
527 static int
528 vlan_unconfig_locked(struct ifvlan *ifv, struct ifvlan_linkmib *nmib)
529 {
530 struct ifnet *p;
531 struct ifnet *ifp = &ifv->ifv_if;
532 struct psref_target *nmib_psref = NULL;
533 struct ifvlan_linkmib *omib;
534 int error = 0;
535
536 KASSERT(mutex_owned(&ifv->ifv_lock));
537
538 omib = ifv->ifv_mib;
539 p = omib->ifvm_p;
540
541 if (p == NULL) {
542 error = -1;
543 goto done;
544 }
545
546 *nmib = *omib;
547 nmib_psref = &nmib->ifvm_psref;
548 psref_target_init(nmib_psref, ifvm_psref_class);
549
550 /*
551 * Since the interface is being unconfigured, we need to empty the
552 * list of multicast groups that we may have joined while we were
553 * alive and remove them from the parent's list also.
554 */
555 (*nmib->ifvm_msw->vmsw_purgemulti)(ifv);
556
557 /* Disconnect from parent. */
558 switch (p->if_type) {
559 case IFT_ETHER:
560 {
561 struct ethercom *ec = (void *)p;
562 if (--ec->ec_nvlans == 0)
563 (void)ether_disable_vlan_mtu(p);
564
565 ether_ifdetach(ifp);
566 /* Restore vlan_ioctl overwritten by ether_ifdetach */
567 ifp->if_ioctl = vlan_ioctl;
568 vlan_reset_linkname(ifp);
569 break;
570 }
571
572 #ifdef DIAGNOSTIC
573 default:
574 panic("vlan_unconfig: impossible");
575 #endif
576 }
577
578 nmib->ifvm_p = NULL;
579 ifv->ifv_if.if_mtu = 0;
580 ifv->ifv_flags = 0;
581
582 mutex_enter(&ifv_hash.lock);
583 PSLIST_WRITER_REMOVE(ifv, ifv_hash);
584 pserialize_perform(vlan_psz);
585 mutex_exit(&ifv_hash.lock);
586 PSLIST_ENTRY_DESTROY(ifv, ifv_hash);
587
588 vlan_linkmib_update(ifv, nmib);
589
590 mutex_exit(&ifv->ifv_lock);
591
592 nmib_psref = NULL;
593 kmem_free(omib, sizeof(*omib));
594
595 #ifdef INET6
596 /* To delete v6 link local addresses */
597 if (in6_present)
598 in6_ifdetach(ifp);
599 #endif
600
601 if ((ifp->if_flags & IFF_PROMISC) != 0)
602 ifpromisc(ifp, 0);
603 if_down(ifp);
604 ifp->if_flags &= ~(IFF_UP|IFF_RUNNING);
605 ifp->if_capabilities = 0;
606 mutex_enter(&ifv->ifv_lock);
607 done:
608
609 if (nmib_psref)
610 psref_target_destroy(nmib_psref, ifvm_psref_class);
611
612 return error;
613 }
614
615 static void
616 vlan_hash_init(void)
617 {
618
619 ifv_hash.lists = hashinit(VLAN_TAG_HASH_SIZE, HASH_PSLIST, true,
620 &ifv_hash.mask);
621 }
622
623 static int
624 vlan_hash_fini(void)
625 {
626 int i;
627
628 mutex_enter(&ifv_hash.lock);
629
630 for (i = 0; i < ifv_hash.mask + 1; i++) {
631 if (PSLIST_WRITER_FIRST(&ifv_hash.lists[i], struct ifvlan,
632 ifv_hash) != NULL) {
633 mutex_exit(&ifv_hash.lock);
634 return EBUSY;
635 }
636 }
637
638 for (i = 0; i < ifv_hash.mask + 1; i++)
639 PSLIST_DESTROY(&ifv_hash.lists[i]);
640
641 mutex_exit(&ifv_hash.lock);
642
643 hashdone(ifv_hash.lists, HASH_PSLIST, ifv_hash.mask);
644
645 ifv_hash.lists = NULL;
646 ifv_hash.mask = 0;
647
648 return 0;
649 }
650
651 static int
652 tag_hash_func(uint16_t tag, u_long mask)
653 {
654 uint32_t hash;
655
656 hash = (tag >> 8) ^ tag;
657 hash = (hash >> 2) ^ hash;
658
659 return hash & mask;
660 }
661
662 static struct ifvlan_linkmib *
663 vlan_getref_linkmib(struct ifvlan *sc, struct psref *psref)
664 {
665 struct ifvlan_linkmib *mib;
666 int s;
667
668 s = pserialize_read_enter();
669 mib = sc->ifv_mib;
670 if (mib == NULL) {
671 pserialize_read_exit(s);
672 return NULL;
673 }
674 membar_datadep_consumer();
675 psref_acquire(psref, &mib->ifvm_psref, ifvm_psref_class);
676 pserialize_read_exit(s);
677
678 return mib;
679 }
680
681 static void
682 vlan_putref_linkmib(struct ifvlan_linkmib *mib, struct psref *psref)
683 {
684 if (mib == NULL)
685 return;
686 psref_release(psref, &mib->ifvm_psref, ifvm_psref_class);
687 }
688
689 static struct ifvlan_linkmib *
690 vlan_lookup_tag_psref(struct ifnet *ifp, uint16_t tag, struct psref *psref)
691 {
692 int idx;
693 int s;
694 struct ifvlan *sc;
695
696 idx = tag_hash_func(tag, ifv_hash.mask);
697
698 s = pserialize_read_enter();
699 PSLIST_READER_FOREACH(sc, &ifv_hash.lists[idx], struct ifvlan,
700 ifv_hash) {
701 struct ifvlan_linkmib *mib = sc->ifv_mib;
702 if (mib == NULL)
703 continue;
704 if (mib->ifvm_tag != tag)
705 continue;
706 if (mib->ifvm_p != ifp)
707 continue;
708
709 psref_acquire(psref, &mib->ifvm_psref, ifvm_psref_class);
710 pserialize_read_exit(s);
711 return mib;
712 }
713 pserialize_read_exit(s);
714 return NULL;
715 }
716
717 static void
718 vlan_linkmib_update(struct ifvlan *ifv, struct ifvlan_linkmib *nmib)
719 {
720 struct ifvlan_linkmib *omib = ifv->ifv_mib;
721
722 KASSERT(mutex_owned(&ifv->ifv_lock));
723
724 membar_producer();
725 ifv->ifv_mib = nmib;
726
727 pserialize_perform(vlan_psz);
728 psref_target_destroy(&omib->ifvm_psref, ifvm_psref_class);
729 }
730
731 /*
732 * Called when a parent interface is detaching; destroy any VLAN
733 * configuration for the parent interface.
734 */
735 void
736 vlan_ifdetach(struct ifnet *p)
737 {
738 struct ifvlan *ifv;
739 struct ifvlan_linkmib *mib, **nmibs;
740 struct psref psref;
741 int error;
742 int bound;
743 int i, cnt = 0;
744
745 bound = curlwp_bind();
746 mutex_enter(&ifv_list.lock);
747 LIST_FOREACH(ifv, &ifv_list.list, ifv_list) {
748 mib = vlan_getref_linkmib(ifv, &psref);
749 if (mib == NULL)
750 continue;
751
752 if (mib->ifvm_p == p)
753 cnt++;
754
755 vlan_putref_linkmib(mib, &psref);
756 }
757 mutex_exit(&ifv_list.lock);
758
759 /*
760 * The value of "cnt" does not increase while ifv_list.lock
761 * and ifv->ifv_lock are released here, because the parent
762 * interface is detaching.
763 */
764 nmibs = kmem_alloc(sizeof(*nmibs) * cnt, KM_SLEEP);
765 for (i=0; i < cnt; i++) {
766 nmibs[i] = kmem_alloc(sizeof(*nmibs[i]), KM_SLEEP);
767 }
768
769 mutex_enter(&ifv_list.lock);
770
771 i = 0;
772 LIST_FOREACH(ifv, &ifv_list.list, ifv_list) {
773 mutex_enter(&ifv->ifv_lock);
774 if (ifv->ifv_mib->ifvm_p == p) {
775 KASSERTMSG(i < cnt, "no memory for unconfig, parent=%s",
776 p->if_xname);
777 error = vlan_unconfig_locked(ifv, nmibs[i]);
778 if (!error) {
779 nmibs[i] = NULL;
780 i++;
781 }
782
783 }
784 mutex_exit(&ifv->ifv_lock);
785 }
786
787 mutex_exit(&ifv_list.lock);
788 curlwp_bindx(bound);
789
790 for (i=0; i < cnt; i++) {
791 if (nmibs[i])
792 kmem_free(nmibs[i], sizeof(*nmibs[i]));
793 }
794
795 kmem_free(nmibs, sizeof(*nmibs) * cnt);
796
797 return;
798 }
799
800 static int
801 vlan_set_promisc(struct ifnet *ifp)
802 {
803 struct ifvlan *ifv = ifp->if_softc;
804 struct ifvlan_linkmib *mib;
805 struct psref psref;
806 int error = 0;
807 int bound;
808
809 bound = curlwp_bind();
810 mib = vlan_getref_linkmib(ifv, &psref);
811 if (mib == NULL) {
812 curlwp_bindx(bound);
813 return EBUSY;
814 }
815
816 if ((ifp->if_flags & IFF_PROMISC) != 0) {
817 if ((ifv->ifv_flags & IFVF_PROMISC) == 0) {
818 error = ifpromisc(mib->ifvm_p, 1);
819 if (error == 0)
820 ifv->ifv_flags |= IFVF_PROMISC;
821 }
822 } else {
823 if ((ifv->ifv_flags & IFVF_PROMISC) != 0) {
824 error = ifpromisc(mib->ifvm_p, 0);
825 if (error == 0)
826 ifv->ifv_flags &= ~IFVF_PROMISC;
827 }
828 }
829 vlan_putref_linkmib(mib, &psref);
830 curlwp_bindx(bound);
831
832 return (error);
833 }
834
835 static int
836 vlan_ioctl(struct ifnet *ifp, u_long cmd, void *data)
837 {
838 struct lwp *l = curlwp; /* XXX */
839 struct ifvlan *ifv = ifp->if_softc;
840 struct ifaddr *ifa = (struct ifaddr *) data;
841 struct ifreq *ifr = (struct ifreq *) data;
842 struct ifnet *pr;
843 struct ifcapreq *ifcr;
844 struct vlanreq vlr;
845 struct ifvlan_linkmib *mib;
846 struct psref psref;
847 int error = 0;
848 int bound;
849
850 switch (cmd) {
851 case SIOCSIFMTU:
852 bound = curlwp_bind();
853 mib = vlan_getref_linkmib(ifv, &psref);
854 if (mib == NULL) {
855 curlwp_bindx(bound);
856 error = EBUSY;
857 break;
858 }
859
860 if (mib->ifvm_p == NULL) {
861 vlan_putref_linkmib(mib, &psref);
862 curlwp_bindx(bound);
863 error = EINVAL;
864 } else if (
865 ifr->ifr_mtu > (mib->ifvm_p->if_mtu - mib->ifvm_mtufudge) ||
866 ifr->ifr_mtu < (mib->ifvm_mintu - mib->ifvm_mtufudge)) {
867 vlan_putref_linkmib(mib, &psref);
868 curlwp_bindx(bound);
869 error = EINVAL;
870 } else {
871 vlan_putref_linkmib(mib, &psref);
872 curlwp_bindx(bound);
873
874 error = ifioctl_common(ifp, cmd, data);
875 if (error == ENETRESET)
876 error = 0;
877 }
878
879 break;
880
881 case SIOCSETVLAN:
882 if ((error = kauth_authorize_network(l->l_cred,
883 KAUTH_NETWORK_INTERFACE,
884 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
885 NULL)) != 0)
886 break;
887 if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0)
888 break;
889
890 if (vlr.vlr_parent[0] == '\0') {
891 bound = curlwp_bind();
892 mib = vlan_getref_linkmib(ifv, &psref);
893 if (mib == NULL) {
894 curlwp_bindx(bound);
895 error = EBUSY;
896 break;
897 }
898
899 if (mib->ifvm_p != NULL &&
900 (ifp->if_flags & IFF_PROMISC) != 0)
901 error = ifpromisc(mib->ifvm_p, 0);
902
903 vlan_putref_linkmib(mib, &psref);
904 curlwp_bindx(bound);
905
906 vlan_unconfig(ifp);
907 break;
908 }
909 if (vlr.vlr_tag != EVL_VLANOFTAG(vlr.vlr_tag)) {
910 error = EINVAL; /* check for valid tag */
911 break;
912 }
913 if ((pr = ifunit(vlr.vlr_parent)) == 0) {
914 error = ENOENT;
915 break;
916 }
917 error = vlan_config(ifv, pr, vlr.vlr_tag);
918 if (error != 0) {
919 break;
920 }
921 ifp->if_flags |= IFF_RUNNING;
922
923 /* Update promiscuous mode, if necessary. */
924 vlan_set_promisc(ifp);
925 break;
926
927 case SIOCGETVLAN:
928 memset(&vlr, 0, sizeof(vlr));
929 bound = curlwp_bind();
930 mib = vlan_getref_linkmib(ifv, &psref);
931 if (mib == NULL) {
932 curlwp_bindx(bound);
933 error = EBUSY;
934 break;
935 }
936 if (mib->ifvm_p != NULL) {
937 snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), "%s",
938 mib->ifvm_p->if_xname);
939 vlr.vlr_tag = mib->ifvm_tag;
940 }
941 vlan_putref_linkmib(mib, &psref);
942 curlwp_bindx(bound);
943 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr));
944 break;
945
946 case SIOCSIFFLAGS:
947 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
948 break;
949 /*
950 * For promiscuous mode, we enable promiscuous mode on
951 * the parent if we need promiscuous on the VLAN interface.
952 */
953 bound = curlwp_bind();
954 mib = vlan_getref_linkmib(ifv, &psref);
955 if (mib == NULL) {
956 curlwp_bindx(bound);
957 error = EBUSY;
958 break;
959 }
960
961 if (mib->ifvm_p != NULL)
962 error = vlan_set_promisc(ifp);
963 vlan_putref_linkmib(mib, &psref);
964 curlwp_bindx(bound);
965 break;
966
967 case SIOCADDMULTI:
968 mutex_enter(&ifv->ifv_lock);
969 mib = ifv->ifv_mib;
970 if (mib == NULL) {
971 error = EBUSY;
972 mutex_exit(&ifv->ifv_lock);
973 break;
974 }
975
976 error = (mib->ifvm_p != NULL) ?
977 (*mib->ifvm_msw->vmsw_addmulti)(ifv, ifr) : EINVAL;
978 mib = NULL;
979 mutex_exit(&ifv->ifv_lock);
980 break;
981
982 case SIOCDELMULTI:
983 mutex_enter(&ifv->ifv_lock);
984 mib = ifv->ifv_mib;
985 if (mib == NULL) {
986 error = EBUSY;
987 mutex_exit(&ifv->ifv_lock);
988 break;
989 }
990 error = (mib->ifvm_p != NULL) ?
991 (*mib->ifvm_msw->vmsw_delmulti)(ifv, ifr) : EINVAL;
992 mib = NULL;
993 mutex_exit(&ifv->ifv_lock);
994 break;
995
996 case SIOCSIFCAP:
997 ifcr = data;
998 /* make sure caps are enabled on parent */
999 bound = curlwp_bind();
1000 mib = vlan_getref_linkmib(ifv, &psref);
1001 if (mib == NULL) {
1002 curlwp_bindx(bound);
1003 error = EBUSY;
1004 break;
1005 }
1006
1007 if (mib->ifvm_p == NULL) {
1008 vlan_putref_linkmib(mib, &psref);
1009 curlwp_bindx(bound);
1010 error = EINVAL;
1011 break;
1012 }
1013 if ((mib->ifvm_p->if_capenable & ifcr->ifcr_capenable) !=
1014 ifcr->ifcr_capenable) {
1015 vlan_putref_linkmib(mib, &psref);
1016 curlwp_bindx(bound);
1017 error = EINVAL;
1018 break;
1019 }
1020
1021 vlan_putref_linkmib(mib, &psref);
1022 curlwp_bindx(bound);
1023
1024 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
1025 error = 0;
1026 break;
1027 case SIOCINITIFADDR:
1028 bound = curlwp_bind();
1029 mib = vlan_getref_linkmib(ifv, &psref);
1030 if (mib == NULL) {
1031 curlwp_bindx(bound);
1032 error = EBUSY;
1033 break;
1034 }
1035
1036 if (mib->ifvm_p == NULL) {
1037 error = EINVAL;
1038 vlan_putref_linkmib(mib, &psref);
1039 curlwp_bindx(bound);
1040 break;
1041 }
1042 vlan_putref_linkmib(mib, &psref);
1043 curlwp_bindx(bound);
1044
1045 ifp->if_flags |= IFF_UP;
1046 #ifdef INET
1047 if (ifa->ifa_addr->sa_family == AF_INET)
1048 arp_ifinit(ifp, ifa);
1049 #endif
1050 break;
1051
1052 default:
1053 error = ether_ioctl(ifp, cmd, data);
1054 }
1055
1056 return (error);
1057 }
1058
1059 static int
1060 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr)
1061 {
1062 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr);
1063 struct vlan_mc_entry *mc;
1064 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1065 struct ifvlan_linkmib *mib;
1066 int error;
1067
1068 KASSERT(mutex_owned(&ifv->ifv_lock));
1069
1070 if (sa->sa_len > sizeof(struct sockaddr_storage))
1071 return (EINVAL);
1072
1073 error = ether_addmulti(sa, &ifv->ifv_ec);
1074 if (error != ENETRESET)
1075 return (error);
1076
1077 /*
1078 * This is new multicast address. We have to tell parent
1079 * about it. Also, remember this multicast address so that
1080 * we can delete them on unconfigure.
1081 */
1082 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT);
1083 if (mc == NULL) {
1084 error = ENOMEM;
1085 goto alloc_failed;
1086 }
1087
1088 /*
1089 * As ether_addmulti() returns ENETRESET, following two
1090 * statement shouldn't fail.
1091 */
1092 (void)ether_multiaddr(sa, addrlo, addrhi);
1093 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, mc->mc_enm);
1094 memcpy(&mc->mc_addr, sa, sa->sa_len);
1095 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries);
1096
1097 mib = ifv->ifv_mib;
1098 error = if_mcast_op(mib->ifvm_p, SIOCADDMULTI, sa);
1099
1100 if (error != 0)
1101 goto ioctl_failed;
1102 return (error);
1103
1104 ioctl_failed:
1105 LIST_REMOVE(mc, mc_entries);
1106 free(mc, M_DEVBUF);
1107 alloc_failed:
1108 (void)ether_delmulti(sa, &ifv->ifv_ec);
1109 return (error);
1110 }
1111
1112 static int
1113 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr)
1114 {
1115 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr);
1116 struct ether_multi *enm;
1117 struct vlan_mc_entry *mc;
1118 struct ifvlan_linkmib *mib;
1119 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
1120 int error;
1121
1122 KASSERT(mutex_owned(&ifv->ifv_lock));
1123
1124 /*
1125 * Find a key to lookup vlan_mc_entry. We have to do this
1126 * before calling ether_delmulti for obvious reason.
1127 */
1128 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0)
1129 return (error);
1130 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, enm);
1131
1132 error = ether_delmulti(sa, &ifv->ifv_ec);
1133 if (error != ENETRESET)
1134 return (error);
1135
1136 /* We no longer use this multicast address. Tell parent so. */
1137 mib = ifv->ifv_mib;
1138 error = if_mcast_op(mib->ifvm_p, SIOCDELMULTI, sa);
1139
1140 if (error == 0) {
1141 /* And forget about this address. */
1142 for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL;
1143 mc = LIST_NEXT(mc, mc_entries)) {
1144 if (mc->mc_enm == enm) {
1145 LIST_REMOVE(mc, mc_entries);
1146 free(mc, M_DEVBUF);
1147 break;
1148 }
1149 }
1150 KASSERT(mc != NULL);
1151 } else
1152 (void)ether_addmulti(sa, &ifv->ifv_ec);
1153 return (error);
1154 }
1155
1156 /*
1157 * Delete any multicast address we have asked to add from parent
1158 * interface. Called when the vlan is being unconfigured.
1159 */
1160 static void
1161 vlan_ether_purgemulti(struct ifvlan *ifv)
1162 {
1163 struct vlan_mc_entry *mc;
1164 struct ifvlan_linkmib *mib;
1165
1166 KASSERT(mutex_owned(&ifv->ifv_lock));
1167 mib = ifv->ifv_mib;
1168 if (mib == NULL) {
1169 return;
1170 }
1171
1172 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) {
1173 (void)if_mcast_op(mib->ifvm_p, SIOCDELMULTI,
1174 (const struct sockaddr *)&mc->mc_addr);
1175 LIST_REMOVE(mc, mc_entries);
1176 free(mc, M_DEVBUF);
1177 }
1178 }
1179
1180 static void
1181 vlan_start(struct ifnet *ifp)
1182 {
1183 struct ifvlan *ifv = ifp->if_softc;
1184 struct ifnet *p;
1185 struct ethercom *ec;
1186 struct mbuf *m;
1187 struct ifvlan_linkmib *mib;
1188 struct psref psref;
1189 int error;
1190
1191 mib = vlan_getref_linkmib(ifv, &psref);
1192 if (mib == NULL)
1193 return;
1194 p = mib->ifvm_p;
1195 ec = (void *)mib->ifvm_p;
1196
1197 ifp->if_flags |= IFF_OACTIVE;
1198
1199 for (;;) {
1200 IFQ_DEQUEUE(&ifp->if_snd, m);
1201 if (m == NULL)
1202 break;
1203
1204 #ifdef ALTQ
1205 /*
1206 * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE is defined.
1207 */
1208 KERNEL_LOCK(1, NULL);
1209 /*
1210 * If ALTQ is enabled on the parent interface, do
1211 * classification; the queueing discipline might
1212 * not require classification, but might require
1213 * the address family/header pointer in the pktattr.
1214 */
1215 if (ALTQ_IS_ENABLED(&p->if_snd)) {
1216 switch (p->if_type) {
1217 case IFT_ETHER:
1218 altq_etherclassify(&p->if_snd, m);
1219 break;
1220 #ifdef DIAGNOSTIC
1221 default:
1222 panic("vlan_start: impossible (altq)");
1223 #endif
1224 }
1225 }
1226 KERNEL_UNLOCK_ONE(NULL);
1227 #endif /* ALTQ */
1228
1229 bpf_mtap(ifp, m);
1230 /*
1231 * If the parent can insert the tag itself, just mark
1232 * the tag in the mbuf header.
1233 */
1234 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
1235 vlan_set_tag(m, mib->ifvm_tag);
1236 } else {
1237 /*
1238 * insert the tag ourselves
1239 */
1240 M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT);
1241 if (m == NULL) {
1242 printf("%s: unable to prepend encap header",
1243 p->if_xname);
1244 ifp->if_oerrors++;
1245 continue;
1246 }
1247
1248 switch (p->if_type) {
1249 case IFT_ETHER:
1250 {
1251 struct ether_vlan_header *evl;
1252
1253 if (m->m_len < sizeof(struct ether_vlan_header))
1254 m = m_pullup(m,
1255 sizeof(struct ether_vlan_header));
1256 if (m == NULL) {
1257 printf("%s: unable to pullup encap "
1258 "header", p->if_xname);
1259 ifp->if_oerrors++;
1260 continue;
1261 }
1262
1263 /*
1264 * Transform the Ethernet header into an
1265 * Ethernet header with 802.1Q encapsulation.
1266 */
1267 memmove(mtod(m, void *),
1268 mtod(m, char *) + mib->ifvm_encaplen,
1269 sizeof(struct ether_header));
1270 evl = mtod(m, struct ether_vlan_header *);
1271 evl->evl_proto = evl->evl_encap_proto;
1272 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1273 evl->evl_tag = htons(mib->ifvm_tag);
1274
1275 /*
1276 * To cater for VLAN-aware layer 2 ethernet
1277 * switches which may need to strip the tag
1278 * before forwarding the packet, make sure
1279 * the packet+tag is at least 68 bytes long.
1280 * This is necessary because our parent will
1281 * only pad to 64 bytes (ETHER_MIN_LEN) and
1282 * some switches will not pad by themselves
1283 * after deleting a tag.
1284 */
1285 if (m->m_pkthdr.len <
1286 (ETHER_MIN_LEN - ETHER_CRC_LEN +
1287 ETHER_VLAN_ENCAP_LEN)) {
1288 m_copyback(m, m->m_pkthdr.len,
1289 (ETHER_MIN_LEN - ETHER_CRC_LEN +
1290 ETHER_VLAN_ENCAP_LEN) -
1291 m->m_pkthdr.len,
1292 vlan_zero_pad_buff);
1293 }
1294 break;
1295 }
1296
1297 #ifdef DIAGNOSTIC
1298 default:
1299 panic("vlan_start: impossible");
1300 #endif
1301 }
1302 }
1303
1304 if ((p->if_flags & IFF_RUNNING) == 0) {
1305 m_freem(m);
1306 continue;
1307 }
1308
1309 error = if_transmit_lock(p, m);
1310 if (error) {
1311 /* mbuf is already freed */
1312 ifp->if_oerrors++;
1313 continue;
1314 }
1315 ifp->if_opackets++;
1316 }
1317
1318 ifp->if_flags &= ~IFF_OACTIVE;
1319
1320 /* Remove reference to mib before release */
1321 p = NULL;
1322 ec = NULL;
1323
1324 vlan_putref_linkmib(mib, &psref);
1325 }
1326
1327 static int
1328 vlan_transmit(struct ifnet *ifp, struct mbuf *m)
1329 {
1330 struct ifvlan *ifv = ifp->if_softc;
1331 struct ifnet *p;
1332 struct ethercom *ec;
1333 struct ifvlan_linkmib *mib;
1334 struct psref psref;
1335 int error;
1336 size_t pktlen = m->m_pkthdr.len;
1337 bool mcast = (m->m_flags & M_MCAST) != 0;
1338
1339 mib = vlan_getref_linkmib(ifv, &psref);
1340 if (mib == NULL) {
1341 m_freem(m);
1342 return ENETDOWN;
1343 }
1344
1345 p = mib->ifvm_p;
1346 ec = (void *)mib->ifvm_p;
1347
1348 bpf_mtap(ifp, m);
1349 /*
1350 * If the parent can insert the tag itself, just mark
1351 * the tag in the mbuf header.
1352 */
1353 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
1354 vlan_set_tag(m, mib->ifvm_tag);
1355 } else {
1356 /*
1357 * insert the tag ourselves
1358 */
1359 M_PREPEND(m, mib->ifvm_encaplen, M_DONTWAIT);
1360 if (m == NULL) {
1361 printf("%s: unable to prepend encap header",
1362 p->if_xname);
1363 ifp->if_oerrors++;
1364 error = ENOBUFS;
1365 goto out;
1366 }
1367
1368 switch (p->if_type) {
1369 case IFT_ETHER:
1370 {
1371 struct ether_vlan_header *evl;
1372
1373 if (m->m_len < sizeof(struct ether_vlan_header))
1374 m = m_pullup(m,
1375 sizeof(struct ether_vlan_header));
1376 if (m == NULL) {
1377 printf("%s: unable to pullup encap "
1378 "header", p->if_xname);
1379 ifp->if_oerrors++;
1380 error = ENOBUFS;
1381 goto out;
1382 }
1383
1384 /*
1385 * Transform the Ethernet header into an
1386 * Ethernet header with 802.1Q encapsulation.
1387 */
1388 memmove(mtod(m, void *),
1389 mtod(m, char *) + mib->ifvm_encaplen,
1390 sizeof(struct ether_header));
1391 evl = mtod(m, struct ether_vlan_header *);
1392 evl->evl_proto = evl->evl_encap_proto;
1393 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1394 evl->evl_tag = htons(mib->ifvm_tag);
1395
1396 /*
1397 * To cater for VLAN-aware layer 2 ethernet
1398 * switches which may need to strip the tag
1399 * before forwarding the packet, make sure
1400 * the packet+tag is at least 68 bytes long.
1401 * This is necessary because our parent will
1402 * only pad to 64 bytes (ETHER_MIN_LEN) and
1403 * some switches will not pad by themselves
1404 * after deleting a tag.
1405 */
1406 if (m->m_pkthdr.len <
1407 (ETHER_MIN_LEN - ETHER_CRC_LEN +
1408 ETHER_VLAN_ENCAP_LEN)) {
1409 m_copyback(m, m->m_pkthdr.len,
1410 (ETHER_MIN_LEN - ETHER_CRC_LEN +
1411 ETHER_VLAN_ENCAP_LEN) -
1412 m->m_pkthdr.len,
1413 vlan_zero_pad_buff);
1414 }
1415 break;
1416 }
1417
1418 #ifdef DIAGNOSTIC
1419 default:
1420 panic("vlan_transmit: impossible");
1421 #endif
1422 }
1423 }
1424
1425 if ((p->if_flags & IFF_RUNNING) == 0) {
1426 m_freem(m);
1427 error = ENETDOWN;
1428 goto out;
1429 }
1430
1431 error = if_transmit_lock(p, m);
1432 if (error) {
1433 /* mbuf is already freed */
1434 ifp->if_oerrors++;
1435 } else {
1436
1437 ifp->if_opackets++;
1438 ifp->if_obytes += pktlen;
1439 if (mcast)
1440 ifp->if_omcasts++;
1441 }
1442
1443 out:
1444 /* Remove reference to mib before release */
1445 p = NULL;
1446 ec = NULL;
1447
1448 vlan_putref_linkmib(mib, &psref);
1449 return error;
1450 }
1451
1452 /*
1453 * Given an Ethernet frame, find a valid vlan interface corresponding to the
1454 * given source interface and tag, then run the real packet through the
1455 * parent's input routine.
1456 */
1457 void
1458 vlan_input(struct ifnet *ifp, struct mbuf *m)
1459 {
1460 struct ifvlan *ifv;
1461 u_int tag;
1462 struct ifvlan_linkmib *mib;
1463 struct psref psref;
1464 bool have_vtag;
1465
1466 have_vtag = vlan_has_tag(m);
1467 if (have_vtag) {
1468 tag = EVL_VLANOFTAG(vlan_get_tag(m));
1469 m->m_flags &= ~M_VLANTAG;
1470 } else {
1471 switch (ifp->if_type) {
1472 case IFT_ETHER:
1473 {
1474 struct ether_vlan_header *evl;
1475
1476 if (m->m_len < sizeof(struct ether_vlan_header) &&
1477 (m = m_pullup(m,
1478 sizeof(struct ether_vlan_header))) == NULL) {
1479 printf("%s: no memory for VLAN header, "
1480 "dropping packet.\n", ifp->if_xname);
1481 return;
1482 }
1483 evl = mtod(m, struct ether_vlan_header *);
1484 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN);
1485
1486 tag = EVL_VLANOFTAG(ntohs(evl->evl_tag));
1487
1488 /*
1489 * Restore the original ethertype. We'll remove
1490 * the encapsulation after we've found the vlan
1491 * interface corresponding to the tag.
1492 */
1493 evl->evl_encap_proto = evl->evl_proto;
1494 break;
1495 }
1496
1497 default:
1498 tag = (u_int) -1; /* XXX GCC */
1499 #ifdef DIAGNOSTIC
1500 panic("vlan_input: impossible");
1501 #endif
1502 }
1503 }
1504
1505 mib = vlan_lookup_tag_psref(ifp, tag, &psref);
1506 if (mib == NULL) {
1507 m_freem(m);
1508 ifp->if_noproto++;
1509 return;
1510 }
1511
1512 ifv = mib->ifvm_ifvlan;
1513 if ((ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) !=
1514 (IFF_UP|IFF_RUNNING)) {
1515 m_freem(m);
1516 ifp->if_noproto++;
1517 goto out;
1518 }
1519
1520 /*
1521 * Now, remove the encapsulation header. The original
1522 * header has already been fixed up above.
1523 */
1524 if (!have_vtag) {
1525 memmove(mtod(m, char *) + mib->ifvm_encaplen,
1526 mtod(m, void *), sizeof(struct ether_header));
1527 m_adj(m, mib->ifvm_encaplen);
1528 }
1529
1530 m_set_rcvif(m, &ifv->ifv_if);
1531 ifv->ifv_if.if_ipackets++;
1532
1533 m->m_flags &= ~M_PROMISC;
1534 if_input(&ifv->ifv_if, m);
1535 out:
1536 vlan_putref_linkmib(mib, &psref);
1537 }
1538
1539 /*
1540 * Module infrastructure
1541 */
1542 #include "if_module.h"
1543
1544 IF_MODULE(MODULE_CLASS_DRIVER, vlan, "")
1545