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