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