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