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