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