1 /*- 2 * Copyright 1998 Massachusetts Institute of Technology 3 * 4 * Permission to use, copy, modify, and distribute this software and 5 * its documentation for any purpose and without fee is hereby 6 * granted, provided that both the above copyright notice and this 7 * permission notice appear in all copies, that both the above 8 * copyright notice and this permission notice appear in all 9 * supporting documentation, and that the name of M.I.T. not be used 10 * in advertising or publicity pertaining to distribution of the 11 * software without specific, written prior permission. M.I.T. makes 12 * no representations about the suitability of this software for any 13 * purpose. It is provided "as is" without express or implied 14 * warranty. 15 * 16 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 17 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 20 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs. 32 * Might be extended some day to also handle IEEE 802.1p priority 33 * tagging. This is sort of sneaky in the implementation, since 34 * we need to pretend to be enough of an Ethernet implementation 35 * to make arp work. The way we do this is by telling everyone 36 * that we are an Ethernet, and then catch the packets that 37 * ether_output() sends to us via if_transmit(), rewrite them for 38 * use by the real outgoing interface, and ask it to send them. 39 */ 40 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD$"); 43 44 #include "opt_inet.h" 45 #include "opt_vlan.h" 46 47 #include <sys/param.h> 48 #include <sys/eventhandler.h> 49 #include <sys/kernel.h> 50 #include <sys/lock.h> 51 #include <sys/malloc.h> 52 #include <sys/mbuf.h> 53 #include <sys/module.h> 54 #include <sys/rwlock.h> 55 #include <sys/queue.h> 56 #include <sys/socket.h> 57 #include <sys/sockio.h> 58 #include <sys/sysctl.h> 59 #include <sys/systm.h> 60 #include <sys/sx.h> 61 62 #include <net/bpf.h> 63 #include <net/ethernet.h> 64 #include <net/if.h> 65 #include <net/if_var.h> 66 #include <net/if_clone.h> 67 #include <net/if_dl.h> 68 #include <net/if_types.h> 69 #include <net/if_vlan_var.h> 70 #include <net/vnet.h> 71 72 #ifdef INET 73 #include <netinet/in.h> 74 #include <netinet/if_ether.h> 75 #endif 76 77 #define VLAN_DEF_HWIDTH 4 78 #define VLAN_IFFLAGS (IFF_BROADCAST | IFF_MULTICAST) 79 80 #define UP_AND_RUNNING(ifp) \ 81 ((ifp)->if_flags & IFF_UP && (ifp)->if_drv_flags & IFF_DRV_RUNNING) 82 83 LIST_HEAD(ifvlanhead, ifvlan); 84 85 struct ifvlantrunk { 86 struct ifnet *parent; /* parent interface of this trunk */ 87 struct rwlock rw; 88 #ifdef VLAN_ARRAY 89 #define VLAN_ARRAY_SIZE (EVL_VLID_MASK + 1) 90 struct ifvlan *vlans[VLAN_ARRAY_SIZE]; /* static table */ 91 #else 92 struct ifvlanhead *hash; /* dynamic hash-list table */ 93 uint16_t hmask; 94 uint16_t hwidth; 95 #endif 96 int refcnt; 97 }; 98 99 struct vlan_mc_entry { 100 struct sockaddr_dl mc_addr; 101 SLIST_ENTRY(vlan_mc_entry) mc_entries; 102 }; 103 104 struct ifvlan { 105 struct ifvlantrunk *ifv_trunk; 106 struct ifnet *ifv_ifp; 107 void *ifv_cookie; 108 #define TRUNK(ifv) ((ifv)->ifv_trunk) 109 #define PARENT(ifv) ((ifv)->ifv_trunk->parent) 110 int ifv_pflags; /* special flags we have set on parent */ 111 struct ifv_linkmib { 112 int ifvm_encaplen; /* encapsulation length */ 113 int ifvm_mtufudge; /* MTU fudged by this much */ 114 int ifvm_mintu; /* min transmission unit */ 115 uint16_t ifvm_proto; /* encapsulation ethertype */ 116 uint16_t ifvm_tag; /* tag to apply on packets leaving if */ 117 } ifv_mib; 118 SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; 119 #ifndef VLAN_ARRAY 120 LIST_ENTRY(ifvlan) ifv_list; 121 #endif 122 }; 123 #define ifv_proto ifv_mib.ifvm_proto 124 #define ifv_vid ifv_mib.ifvm_tag 125 #define ifv_encaplen ifv_mib.ifvm_encaplen 126 #define ifv_mtufudge ifv_mib.ifvm_mtufudge 127 #define ifv_mintu ifv_mib.ifvm_mintu 128 129 /* Special flags we should propagate to parent. */ 130 static struct { 131 int flag; 132 int (*func)(struct ifnet *, int); 133 } vlan_pflags[] = { 134 {IFF_PROMISC, ifpromisc}, 135 {IFF_ALLMULTI, if_allmulti}, 136 {0, NULL} 137 }; 138 139 SYSCTL_DECL(_net_link); 140 static SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, 141 "IEEE 802.1Q VLAN"); 142 static SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, 143 "for consistency"); 144 145 static int soft_pad = 0; 146 SYSCTL_INT(_net_link_vlan, OID_AUTO, soft_pad, CTLFLAG_RW, &soft_pad, 0, 147 "pad short frames before tagging"); 148 149 static const char vlanname[] = "vlan"; 150 static MALLOC_DEFINE(M_VLAN, vlanname, "802.1Q Virtual LAN Interface"); 151 152 static eventhandler_tag ifdetach_tag; 153 static eventhandler_tag iflladdr_tag; 154 155 /* 156 * We have a global mutex, that is used to serialize configuration 157 * changes and isn't used in normal packet delivery. 158 * 159 * We also have a per-trunk rwlock, that is locked shared on packet 160 * processing and exclusive when configuration is changed. 161 * 162 * The VLAN_ARRAY substitutes the dynamic hash with a static array 163 * with 4096 entries. In theory this can give a boost in processing, 164 * however on practice it does not. Probably this is because array 165 * is too big to fit into CPU cache. 166 */ 167 static struct sx ifv_lock; 168 #define VLAN_LOCK_INIT() sx_init(&ifv_lock, "vlan_global") 169 #define VLAN_LOCK_DESTROY() sx_destroy(&ifv_lock) 170 #define VLAN_LOCK_ASSERT() sx_assert(&ifv_lock, SA_LOCKED) 171 #define VLAN_LOCK() sx_xlock(&ifv_lock) 172 #define VLAN_UNLOCK() sx_xunlock(&ifv_lock) 173 #define TRUNK_LOCK_INIT(trunk) rw_init(&(trunk)->rw, vlanname) 174 #define TRUNK_LOCK_DESTROY(trunk) rw_destroy(&(trunk)->rw) 175 #define TRUNK_LOCK(trunk) rw_wlock(&(trunk)->rw) 176 #define TRUNK_UNLOCK(trunk) rw_wunlock(&(trunk)->rw) 177 #define TRUNK_LOCK_ASSERT(trunk) rw_assert(&(trunk)->rw, RA_WLOCKED) 178 #define TRUNK_RLOCK(trunk) rw_rlock(&(trunk)->rw) 179 #define TRUNK_RUNLOCK(trunk) rw_runlock(&(trunk)->rw) 180 #define TRUNK_LOCK_RASSERT(trunk) rw_assert(&(trunk)->rw, RA_RLOCKED) 181 182 #ifndef VLAN_ARRAY 183 static void vlan_inithash(struct ifvlantrunk *trunk); 184 static void vlan_freehash(struct ifvlantrunk *trunk); 185 static int vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv); 186 static int vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv); 187 static void vlan_growhash(struct ifvlantrunk *trunk, int howmuch); 188 static __inline struct ifvlan * vlan_gethash(struct ifvlantrunk *trunk, 189 uint16_t vid); 190 #endif 191 static void trunk_destroy(struct ifvlantrunk *trunk); 192 193 static void vlan_init(void *foo); 194 static void vlan_input(struct ifnet *ifp, struct mbuf *m); 195 static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); 196 static void vlan_qflush(struct ifnet *ifp); 197 static int vlan_setflag(struct ifnet *ifp, int flag, int status, 198 int (*func)(struct ifnet *, int)); 199 static int vlan_setflags(struct ifnet *ifp, int status); 200 static int vlan_setmulti(struct ifnet *ifp); 201 static int vlan_transmit(struct ifnet *ifp, struct mbuf *m); 202 static void vlan_unconfig(struct ifnet *ifp); 203 static void vlan_unconfig_locked(struct ifnet *ifp, int departing); 204 static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag); 205 static void vlan_link_state(struct ifnet *ifp); 206 static void vlan_capabilities(struct ifvlan *ifv); 207 static void vlan_trunk_capabilities(struct ifnet *ifp); 208 209 static struct ifnet *vlan_clone_match_ethervid(struct if_clone *, 210 const char *, int *); 211 static int vlan_clone_match(struct if_clone *, const char *); 212 static int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t); 213 static int vlan_clone_destroy(struct if_clone *, struct ifnet *); 214 215 static void vlan_ifdetach(void *arg, struct ifnet *ifp); 216 static void vlan_iflladdr(void *arg, struct ifnet *ifp); 217 218 static struct if_clone *vlan_cloner; 219 220 #ifdef VIMAGE 221 static VNET_DEFINE(struct if_clone *, vlan_cloner); 222 #define V_vlan_cloner VNET(vlan_cloner) 223 #endif 224 225 #ifndef VLAN_ARRAY 226 #define HASH(n, m) ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m)) 227 228 static void 229 vlan_inithash(struct ifvlantrunk *trunk) 230 { 231 int i, n; 232 233 /* 234 * The trunk must not be locked here since we call malloc(M_WAITOK). 235 * It is OK in case this function is called before the trunk struct 236 * gets hooked up and becomes visible from other threads. 237 */ 238 239 KASSERT(trunk->hwidth == 0 && trunk->hash == NULL, 240 ("%s: hash already initialized", __func__)); 241 242 trunk->hwidth = VLAN_DEF_HWIDTH; 243 n = 1 << trunk->hwidth; 244 trunk->hmask = n - 1; 245 trunk->hash = malloc(sizeof(struct ifvlanhead) * n, M_VLAN, M_WAITOK); 246 for (i = 0; i < n; i++) 247 LIST_INIT(&trunk->hash[i]); 248 } 249 250 static void 251 vlan_freehash(struct ifvlantrunk *trunk) 252 { 253 #ifdef INVARIANTS 254 int i; 255 256 KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); 257 for (i = 0; i < (1 << trunk->hwidth); i++) 258 KASSERT(LIST_EMPTY(&trunk->hash[i]), 259 ("%s: hash table not empty", __func__)); 260 #endif 261 free(trunk->hash, M_VLAN); 262 trunk->hash = NULL; 263 trunk->hwidth = trunk->hmask = 0; 264 } 265 266 static int 267 vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) 268 { 269 int i, b; 270 struct ifvlan *ifv2; 271 272 TRUNK_LOCK_ASSERT(trunk); 273 KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); 274 275 b = 1 << trunk->hwidth; 276 i = HASH(ifv->ifv_vid, trunk->hmask); 277 LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) 278 if (ifv->ifv_vid == ifv2->ifv_vid) 279 return (EEXIST); 280 281 /* 282 * Grow the hash when the number of vlans exceeds half of the number of 283 * hash buckets squared. This will make the average linked-list length 284 * buckets/2. 285 */ 286 if (trunk->refcnt > (b * b) / 2) { 287 vlan_growhash(trunk, 1); 288 i = HASH(ifv->ifv_vid, trunk->hmask); 289 } 290 LIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list); 291 trunk->refcnt++; 292 293 return (0); 294 } 295 296 static int 297 vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv) 298 { 299 int i, b; 300 struct ifvlan *ifv2; 301 302 TRUNK_LOCK_ASSERT(trunk); 303 KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); 304 305 b = 1 << trunk->hwidth; 306 i = HASH(ifv->ifv_vid, trunk->hmask); 307 LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) 308 if (ifv2 == ifv) { 309 trunk->refcnt--; 310 LIST_REMOVE(ifv2, ifv_list); 311 if (trunk->refcnt < (b * b) / 2) 312 vlan_growhash(trunk, -1); 313 return (0); 314 } 315 316 panic("%s: vlan not found\n", __func__); 317 return (ENOENT); /*NOTREACHED*/ 318 } 319 320 /* 321 * Grow the hash larger or smaller if memory permits. 322 */ 323 static void 324 vlan_growhash(struct ifvlantrunk *trunk, int howmuch) 325 { 326 struct ifvlan *ifv; 327 struct ifvlanhead *hash2; 328 int hwidth2, i, j, n, n2; 329 330 TRUNK_LOCK_ASSERT(trunk); 331 KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); 332 333 if (howmuch == 0) { 334 /* Harmless yet obvious coding error */ 335 printf("%s: howmuch is 0\n", __func__); 336 return; 337 } 338 339 hwidth2 = trunk->hwidth + howmuch; 340 n = 1 << trunk->hwidth; 341 n2 = 1 << hwidth2; 342 /* Do not shrink the table below the default */ 343 if (hwidth2 < VLAN_DEF_HWIDTH) 344 return; 345 346 /* M_NOWAIT because we're called with trunk mutex held */ 347 hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_NOWAIT); 348 if (hash2 == NULL) { 349 printf("%s: out of memory -- hash size not changed\n", 350 __func__); 351 return; /* We can live with the old hash table */ 352 } 353 for (j = 0; j < n2; j++) 354 LIST_INIT(&hash2[j]); 355 for (i = 0; i < n; i++) 356 while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) { 357 LIST_REMOVE(ifv, ifv_list); 358 j = HASH(ifv->ifv_vid, n2 - 1); 359 LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list); 360 } 361 free(trunk->hash, M_VLAN); 362 trunk->hash = hash2; 363 trunk->hwidth = hwidth2; 364 trunk->hmask = n2 - 1; 365 366 if (bootverbose) 367 if_printf(trunk->parent, 368 "VLAN hash table resized from %d to %d buckets\n", n, n2); 369 } 370 371 static __inline struct ifvlan * 372 vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid) 373 { 374 struct ifvlan *ifv; 375 376 TRUNK_LOCK_RASSERT(trunk); 377 378 LIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list) 379 if (ifv->ifv_vid == vid) 380 return (ifv); 381 return (NULL); 382 } 383 384 #if 0 385 /* Debugging code to view the hashtables. */ 386 static void 387 vlan_dumphash(struct ifvlantrunk *trunk) 388 { 389 int i; 390 struct ifvlan *ifv; 391 392 for (i = 0; i < (1 << trunk->hwidth); i++) { 393 printf("%d: ", i); 394 LIST_FOREACH(ifv, &trunk->hash[i], ifv_list) 395 printf("%s ", ifv->ifv_ifp->if_xname); 396 printf("\n"); 397 } 398 } 399 #endif /* 0 */ 400 #else 401 402 static __inline struct ifvlan * 403 vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid) 404 { 405 406 return trunk->vlans[vid]; 407 } 408 409 static __inline int 410 vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) 411 { 412 413 if (trunk->vlans[ifv->ifv_vid] != NULL) 414 return EEXIST; 415 trunk->vlans[ifv->ifv_vid] = ifv; 416 trunk->refcnt++; 417 418 return (0); 419 } 420 421 static __inline int 422 vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv) 423 { 424 425 trunk->vlans[ifv->ifv_vid] = NULL; 426 trunk->refcnt--; 427 428 return (0); 429 } 430 431 static __inline void 432 vlan_freehash(struct ifvlantrunk *trunk) 433 { 434 } 435 436 static __inline void 437 vlan_inithash(struct ifvlantrunk *trunk) 438 { 439 } 440 441 #endif /* !VLAN_ARRAY */ 442 443 static void 444 trunk_destroy(struct ifvlantrunk *trunk) 445 { 446 VLAN_LOCK_ASSERT(); 447 448 TRUNK_LOCK(trunk); 449 vlan_freehash(trunk); 450 trunk->parent->if_vlantrunk = NULL; 451 TRUNK_UNLOCK(trunk); 452 TRUNK_LOCK_DESTROY(trunk); 453 free(trunk, M_VLAN); 454 } 455 456 /* 457 * Program our multicast filter. What we're actually doing is 458 * programming the multicast filter of the parent. This has the 459 * side effect of causing the parent interface to receive multicast 460 * traffic that it doesn't really want, which ends up being discarded 461 * later by the upper protocol layers. Unfortunately, there's no way 462 * to avoid this: there really is only one physical interface. 463 * 464 * XXX: There is a possible race here if more than one thread is 465 * modifying the multicast state of the vlan interface at the same time. 466 */ 467 static int 468 vlan_setmulti(struct ifnet *ifp) 469 { 470 struct ifnet *ifp_p; 471 struct ifmultiaddr *ifma, *rifma = NULL; 472 struct ifvlan *sc; 473 struct vlan_mc_entry *mc; 474 int error; 475 476 /*VLAN_LOCK_ASSERT();*/ 477 478 /* Find the parent. */ 479 sc = ifp->if_softc; 480 ifp_p = PARENT(sc); 481 482 CURVNET_SET_QUIET(ifp_p->if_vnet); 483 484 /* First, remove any existing filter entries. */ 485 while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { 486 error = if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr); 487 if (error) 488 return (error); 489 SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); 490 free(mc, M_VLAN); 491 } 492 493 /* Now program new ones. */ 494 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 495 if (ifma->ifma_addr->sa_family != AF_LINK) 496 continue; 497 mc = malloc(sizeof(struct vlan_mc_entry), M_VLAN, M_NOWAIT); 498 if (mc == NULL) 499 return (ENOMEM); 500 bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len); 501 mc->mc_addr.sdl_index = ifp_p->if_index; 502 SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); 503 error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr, 504 &rifma); 505 if (error) 506 return (error); 507 } 508 509 CURVNET_RESTORE(); 510 return (0); 511 } 512 513 /* 514 * A handler for parent interface link layer address changes. 515 * If the parent interface link layer address is changed we 516 * should also change it on all children vlans. 517 */ 518 static void 519 vlan_iflladdr(void *arg __unused, struct ifnet *ifp) 520 { 521 struct ifvlan *ifv; 522 #ifndef VLAN_ARRAY 523 struct ifvlan *next; 524 #endif 525 int i; 526 527 /* 528 * Check if it's a trunk interface first of all 529 * to avoid needless locking. 530 */ 531 if (ifp->if_vlantrunk == NULL) 532 return; 533 534 VLAN_LOCK(); 535 /* 536 * OK, it's a trunk. Loop over and change all vlan's lladdrs on it. 537 */ 538 #ifdef VLAN_ARRAY 539 for (i = 0; i < VLAN_ARRAY_SIZE; i++) 540 if ((ifv = ifp->if_vlantrunk->vlans[i])) { 541 #else /* VLAN_ARRAY */ 542 for (i = 0; i < (1 << ifp->if_vlantrunk->hwidth); i++) 543 LIST_FOREACH_SAFE(ifv, &ifp->if_vlantrunk->hash[i], ifv_list, next) { 544 #endif /* VLAN_ARRAY */ 545 VLAN_UNLOCK(); 546 if_setlladdr(ifv->ifv_ifp, IF_LLADDR(ifp), 547 ifp->if_addrlen); 548 VLAN_LOCK(); 549 } 550 VLAN_UNLOCK(); 551 552 } 553 554 /* 555 * A handler for network interface departure events. 556 * Track departure of trunks here so that we don't access invalid 557 * pointers or whatever if a trunk is ripped from under us, e.g., 558 * by ejecting its hot-plug card. However, if an ifnet is simply 559 * being renamed, then there's no need to tear down the state. 560 */ 561 static void 562 vlan_ifdetach(void *arg __unused, struct ifnet *ifp) 563 { 564 struct ifvlan *ifv; 565 int i; 566 567 /* 568 * Check if it's a trunk interface first of all 569 * to avoid needless locking. 570 */ 571 if (ifp->if_vlantrunk == NULL) 572 return; 573 574 /* If the ifnet is just being renamed, don't do anything. */ 575 if (ifp->if_flags & IFF_RENAMING) 576 return; 577 578 VLAN_LOCK(); 579 /* 580 * OK, it's a trunk. Loop over and detach all vlan's on it. 581 * Check trunk pointer after each vlan_unconfig() as it will 582 * free it and set to NULL after the last vlan was detached. 583 */ 584 #ifdef VLAN_ARRAY 585 for (i = 0; i < VLAN_ARRAY_SIZE; i++) 586 if ((ifv = ifp->if_vlantrunk->vlans[i])) { 587 vlan_unconfig_locked(ifv->ifv_ifp, 1); 588 if (ifp->if_vlantrunk == NULL) 589 break; 590 } 591 #else /* VLAN_ARRAY */ 592 restart: 593 for (i = 0; i < (1 << ifp->if_vlantrunk->hwidth); i++) 594 if ((ifv = LIST_FIRST(&ifp->if_vlantrunk->hash[i]))) { 595 vlan_unconfig_locked(ifv->ifv_ifp, 1); 596 if (ifp->if_vlantrunk) 597 goto restart; /* trunk->hwidth can change */ 598 else 599 break; 600 } 601 #endif /* VLAN_ARRAY */ 602 /* Trunk should have been destroyed in vlan_unconfig(). */ 603 KASSERT(ifp->if_vlantrunk == NULL, ("%s: purge failed", __func__)); 604 VLAN_UNLOCK(); 605 } 606 607 /* 608 * Return the trunk device for a virtual interface. 609 */ 610 static struct ifnet * 611 vlan_trunkdev(struct ifnet *ifp) 612 { 613 struct ifvlan *ifv; 614 615 if (ifp->if_type != IFT_L2VLAN) 616 return (NULL); 617 ifv = ifp->if_softc; 618 ifp = NULL; 619 VLAN_LOCK(); 620 if (ifv->ifv_trunk) 621 ifp = PARENT(ifv); 622 VLAN_UNLOCK(); 623 return (ifp); 624 } 625 626 /* 627 * Return the 12-bit VLAN VID for this interface, for use by external 628 * components such as Infiniband. 629 * 630 * XXXRW: Note that the function name here is historical; it should be named 631 * vlan_vid(). 632 */ 633 static int 634 vlan_tag(struct ifnet *ifp, uint16_t *vidp) 635 { 636 struct ifvlan *ifv; 637 638 if (ifp->if_type != IFT_L2VLAN) 639 return (EINVAL); 640 ifv = ifp->if_softc; 641 *vidp = ifv->ifv_vid; 642 return (0); 643 } 644 645 /* 646 * Return a driver specific cookie for this interface. Synchronization 647 * with setcookie must be provided by the driver. 648 */ 649 static void * 650 vlan_cookie(struct ifnet *ifp) 651 { 652 struct ifvlan *ifv; 653 654 if (ifp->if_type != IFT_L2VLAN) 655 return (NULL); 656 ifv = ifp->if_softc; 657 return (ifv->ifv_cookie); 658 } 659 660 /* 661 * Store a cookie in our softc that drivers can use to store driver 662 * private per-instance data in. 663 */ 664 static int 665 vlan_setcookie(struct ifnet *ifp, void *cookie) 666 { 667 struct ifvlan *ifv; 668 669 if (ifp->if_type != IFT_L2VLAN) 670 return (EINVAL); 671 ifv = ifp->if_softc; 672 ifv->ifv_cookie = cookie; 673 return (0); 674 } 675 676 /* 677 * Return the vlan device present at the specific VID. 678 */ 679 static struct ifnet * 680 vlan_devat(struct ifnet *ifp, uint16_t vid) 681 { 682 struct ifvlantrunk *trunk; 683 struct ifvlan *ifv; 684 685 trunk = ifp->if_vlantrunk; 686 if (trunk == NULL) 687 return (NULL); 688 ifp = NULL; 689 TRUNK_RLOCK(trunk); 690 ifv = vlan_gethash(trunk, vid); 691 if (ifv) 692 ifp = ifv->ifv_ifp; 693 TRUNK_RUNLOCK(trunk); 694 return (ifp); 695 } 696 697 /* 698 * VLAN support can be loaded as a module. The only place in the 699 * system that's intimately aware of this is ether_input. We hook 700 * into this code through vlan_input_p which is defined there and 701 * set here. Noone else in the system should be aware of this so 702 * we use an explicit reference here. 703 */ 704 extern void (*vlan_input_p)(struct ifnet *, struct mbuf *); 705 706 /* For if_link_state_change() eyes only... */ 707 extern void (*vlan_link_state_p)(struct ifnet *); 708 709 static int 710 vlan_modevent(module_t mod, int type, void *data) 711 { 712 713 switch (type) { 714 case MOD_LOAD: 715 ifdetach_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, 716 vlan_ifdetach, NULL, EVENTHANDLER_PRI_ANY); 717 if (ifdetach_tag == NULL) 718 return (ENOMEM); 719 iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event, 720 vlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY); 721 if (iflladdr_tag == NULL) 722 return (ENOMEM); 723 VLAN_LOCK_INIT(); 724 vlan_input_p = vlan_input; 725 vlan_link_state_p = vlan_link_state; 726 vlan_trunk_cap_p = vlan_trunk_capabilities; 727 vlan_trunkdev_p = vlan_trunkdev; 728 vlan_cookie_p = vlan_cookie; 729 vlan_setcookie_p = vlan_setcookie; 730 vlan_tag_p = vlan_tag; 731 vlan_devat_p = vlan_devat; 732 #ifndef VIMAGE 733 vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match, 734 vlan_clone_create, vlan_clone_destroy); 735 #endif 736 if (bootverbose) 737 printf("vlan: initialized, using " 738 #ifdef VLAN_ARRAY 739 "full-size arrays" 740 #else 741 "hash tables with chaining" 742 #endif 743 744 "\n"); 745 break; 746 case MOD_UNLOAD: 747 #ifndef VIMAGE 748 if_clone_detach(vlan_cloner); 749 #endif 750 EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag); 751 EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag); 752 vlan_input_p = NULL; 753 vlan_link_state_p = NULL; 754 vlan_trunk_cap_p = NULL; 755 vlan_trunkdev_p = NULL; 756 vlan_tag_p = NULL; 757 vlan_cookie_p = NULL; 758 vlan_setcookie_p = NULL; 759 vlan_devat_p = NULL; 760 VLAN_LOCK_DESTROY(); 761 if (bootverbose) 762 printf("vlan: unloaded\n"); 763 break; 764 default: 765 return (EOPNOTSUPP); 766 } 767 return (0); 768 } 769 770 static moduledata_t vlan_mod = { 771 "if_vlan", 772 vlan_modevent, 773 0 774 }; 775 776 DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 777 MODULE_VERSION(if_vlan, 3); 778 779 #ifdef VIMAGE 780 static void 781 vnet_vlan_init(const void *unused __unused) 782 { 783 784 vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match, 785 vlan_clone_create, vlan_clone_destroy); 786 V_vlan_cloner = vlan_cloner; 787 } 788 VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 789 vnet_vlan_init, NULL); 790 791 static void 792 vnet_vlan_uninit(const void *unused __unused) 793 { 794 795 if_clone_detach(V_vlan_cloner); 796 } 797 VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST, 798 vnet_vlan_uninit, NULL); 799 #endif 800 801 static struct ifnet * 802 vlan_clone_match_ethervid(struct if_clone *ifc, const char *name, int *vidp) 803 { 804 const char *cp; 805 struct ifnet *ifp; 806 int vid; 807 808 /* Check for <etherif>.<vlan> style interface names. */ 809 IFNET_RLOCK_NOSLEEP(); 810 TAILQ_FOREACH(ifp, &V_ifnet, if_link) { 811 /* 812 * We can handle non-ethernet hardware types as long as 813 * they handle the tagging and headers themselves. 814 */ 815 if (ifp->if_type != IFT_ETHER && 816 (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) 817 continue; 818 if (strncmp(ifp->if_xname, name, strlen(ifp->if_xname)) != 0) 819 continue; 820 cp = name + strlen(ifp->if_xname); 821 if (*cp++ != '.') 822 continue; 823 if (*cp == '\0') 824 continue; 825 vid = 0; 826 for(; *cp >= '0' && *cp <= '9'; cp++) 827 vid = (vid * 10) + (*cp - '0'); 828 if (*cp != '\0') 829 continue; 830 if (vidp != NULL) 831 *vidp = vid; 832 break; 833 } 834 IFNET_RUNLOCK_NOSLEEP(); 835 836 return (ifp); 837 } 838 839 static int 840 vlan_clone_match(struct if_clone *ifc, const char *name) 841 { 842 const char *cp; 843 844 if (vlan_clone_match_ethervid(ifc, name, NULL) != NULL) 845 return (1); 846 847 if (strncmp(vlanname, name, strlen(vlanname)) != 0) 848 return (0); 849 for (cp = name + 4; *cp != '\0'; cp++) { 850 if (*cp < '0' || *cp > '9') 851 return (0); 852 } 853 854 return (1); 855 } 856 857 static int 858 vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 859 { 860 char *dp; 861 int wildcard; 862 int unit; 863 int error; 864 int vid; 865 int ethertag; 866 struct ifvlan *ifv; 867 struct ifnet *ifp; 868 struct ifnet *p; 869 struct ifaddr *ifa; 870 struct sockaddr_dl *sdl; 871 struct vlanreq vlr; 872 static const u_char eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ 873 874 /* 875 * There are 3 (ugh) ways to specify the cloned device: 876 * o pass a parameter block with the clone request. 877 * o specify parameters in the text of the clone device name 878 * o specify no parameters and get an unattached device that 879 * must be configured separately. 880 * The first technique is preferred; the latter two are 881 * supported for backwards compatibilty. 882 * 883 * XXXRW: Note historic use of the word "tag" here. New ioctls may be 884 * called for. 885 */ 886 if (params) { 887 error = copyin(params, &vlr, sizeof(vlr)); 888 if (error) 889 return error; 890 p = ifunit(vlr.vlr_parent); 891 if (p == NULL) 892 return ENXIO; 893 /* 894 * Don't let the caller set up a VLAN VID with 895 * anything except VLID bits. 896 */ 897 if (vlr.vlr_tag & ~EVL_VLID_MASK) 898 return (EINVAL); 899 error = ifc_name2unit(name, &unit); 900 if (error != 0) 901 return (error); 902 903 ethertag = 1; 904 vid = vlr.vlr_tag; 905 wildcard = (unit < 0); 906 } else if ((p = vlan_clone_match_ethervid(ifc, name, &vid)) != NULL) { 907 ethertag = 1; 908 unit = -1; 909 wildcard = 0; 910 911 /* 912 * Don't let the caller set up a VLAN VID with 913 * anything except VLID bits. 914 */ 915 if (vid & ~EVL_VLID_MASK) 916 return (EINVAL); 917 } else { 918 ethertag = 0; 919 920 error = ifc_name2unit(name, &unit); 921 if (error != 0) 922 return (error); 923 924 wildcard = (unit < 0); 925 } 926 927 error = ifc_alloc_unit(ifc, &unit); 928 if (error != 0) 929 return (error); 930 931 /* In the wildcard case, we need to update the name. */ 932 if (wildcard) { 933 for (dp = name; *dp != '\0'; dp++); 934 if (snprintf(dp, len - (dp-name), "%d", unit) > 935 len - (dp-name) - 1) { 936 panic("%s: interface name too long", __func__); 937 } 938 } 939 940 ifv = malloc(sizeof(struct ifvlan), M_VLAN, M_WAITOK | M_ZERO); 941 ifp = ifv->ifv_ifp = if_alloc(IFT_ETHER); 942 if (ifp == NULL) { 943 ifc_free_unit(ifc, unit); 944 free(ifv, M_VLAN); 945 return (ENOSPC); 946 } 947 SLIST_INIT(&ifv->vlan_mc_listhead); 948 949 ifp->if_softc = ifv; 950 /* 951 * Set the name manually rather than using if_initname because 952 * we don't conform to the default naming convention for interfaces. 953 */ 954 strlcpy(ifp->if_xname, name, IFNAMSIZ); 955 ifp->if_dname = vlanname; 956 ifp->if_dunit = unit; 957 /* NB: flags are not set here */ 958 ifp->if_linkmib = &ifv->ifv_mib; 959 ifp->if_linkmiblen = sizeof(ifv->ifv_mib); 960 /* NB: mtu is not set here */ 961 962 ifp->if_init = vlan_init; 963 ifp->if_transmit = vlan_transmit; 964 ifp->if_qflush = vlan_qflush; 965 ifp->if_ioctl = vlan_ioctl; 966 ifp->if_flags = VLAN_IFFLAGS; 967 ether_ifattach(ifp, eaddr); 968 /* Now undo some of the damage... */ 969 ifp->if_baudrate = 0; 970 ifp->if_type = IFT_L2VLAN; 971 ifp->if_hdrlen = ETHER_VLAN_ENCAP_LEN; 972 ifa = ifp->if_addr; 973 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 974 sdl->sdl_type = IFT_L2VLAN; 975 976 if (ethertag) { 977 error = vlan_config(ifv, p, vid); 978 if (error != 0) { 979 /* 980 * Since we've partially failed, we need to back 981 * out all the way, otherwise userland could get 982 * confused. Thus, we destroy the interface. 983 */ 984 ether_ifdetach(ifp); 985 vlan_unconfig(ifp); 986 if_free(ifp); 987 ifc_free_unit(ifc, unit); 988 free(ifv, M_VLAN); 989 990 return (error); 991 } 992 993 /* Update flags on the parent, if necessary. */ 994 vlan_setflags(ifp, 1); 995 } 996 997 return (0); 998 } 999 1000 static int 1001 vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) 1002 { 1003 struct ifvlan *ifv = ifp->if_softc; 1004 int unit = ifp->if_dunit; 1005 1006 ether_ifdetach(ifp); /* first, remove it from system-wide lists */ 1007 vlan_unconfig(ifp); /* now it can be unconfigured and freed */ 1008 if_free(ifp); 1009 free(ifv, M_VLAN); 1010 ifc_free_unit(ifc, unit); 1011 1012 return (0); 1013 } 1014 1015 /* 1016 * The ifp->if_init entry point for vlan(4) is a no-op. 1017 */ 1018 static void 1019 vlan_init(void *foo __unused) 1020 { 1021 } 1022 1023 /* 1024 * The if_transmit method for vlan(4) interface. 1025 */ 1026 static int 1027 vlan_transmit(struct ifnet *ifp, struct mbuf *m) 1028 { 1029 struct ifvlan *ifv; 1030 struct ifnet *p; 1031 int error, len, mcast; 1032 1033 ifv = ifp->if_softc; 1034 p = PARENT(ifv); 1035 len = m->m_pkthdr.len; 1036 mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; 1037 1038 BPF_MTAP(ifp, m); 1039 1040 /* 1041 * Do not run parent's if_transmit() if the parent is not up, 1042 * or parent's driver will cause a system crash. 1043 */ 1044 if (!UP_AND_RUNNING(p)) { 1045 m_freem(m); 1046 ifp->if_oerrors++; 1047 return (ENETDOWN); 1048 } 1049 1050 /* 1051 * Pad the frame to the minimum size allowed if told to. 1052 * This option is in accord with IEEE Std 802.1Q, 2003 Ed., 1053 * paragraph C.4.4.3.b. It can help to work around buggy 1054 * bridges that violate paragraph C.4.4.3.a from the same 1055 * document, i.e., fail to pad short frames after untagging. 1056 * E.g., a tagged frame 66 bytes long (incl. FCS) is OK, but 1057 * untagging it will produce a 62-byte frame, which is a runt 1058 * and requires padding. There are VLAN-enabled network 1059 * devices that just discard such runts instead or mishandle 1060 * them somehow. 1061 */ 1062 if (soft_pad && p->if_type == IFT_ETHER) { 1063 static char pad[8]; /* just zeros */ 1064 int n; 1065 1066 for (n = ETHERMIN + ETHER_HDR_LEN - m->m_pkthdr.len; 1067 n > 0; n -= sizeof(pad)) 1068 if (!m_append(m, min(n, sizeof(pad)), pad)) 1069 break; 1070 1071 if (n > 0) { 1072 if_printf(ifp, "cannot pad short frame\n"); 1073 ifp->if_oerrors++; 1074 m_freem(m); 1075 return (0); 1076 } 1077 } 1078 1079 /* 1080 * If underlying interface can do VLAN tag insertion itself, 1081 * just pass the packet along. However, we need some way to 1082 * tell the interface where the packet came from so that it 1083 * knows how to find the VLAN tag to use, so we attach a 1084 * packet tag that holds it. 1085 */ 1086 if (p->if_capenable & IFCAP_VLAN_HWTAGGING) { 1087 m->m_pkthdr.ether_vtag = ifv->ifv_vid; 1088 m->m_flags |= M_VLANTAG; 1089 } else { 1090 m = ether_vlanencap(m, ifv->ifv_vid); 1091 if (m == NULL) { 1092 if_printf(ifp, "unable to prepend VLAN header\n"); 1093 ifp->if_oerrors++; 1094 return (0); 1095 } 1096 } 1097 1098 /* 1099 * Send it, precisely as ether_output() would have. 1100 */ 1101 error = (p->if_transmit)(p, m); 1102 if (!error) { 1103 ifp->if_opackets++; 1104 ifp->if_omcasts += mcast; 1105 ifp->if_obytes += len; 1106 } else 1107 ifp->if_oerrors++; 1108 return (error); 1109 } 1110 1111 /* 1112 * The ifp->if_qflush entry point for vlan(4) is a no-op. 1113 */ 1114 static void 1115 vlan_qflush(struct ifnet *ifp __unused) 1116 { 1117 } 1118 1119 static void 1120 vlan_input(struct ifnet *ifp, struct mbuf *m) 1121 { 1122 struct ifvlantrunk *trunk = ifp->if_vlantrunk; 1123 struct ifvlan *ifv; 1124 uint16_t vid; 1125 1126 KASSERT(trunk != NULL, ("%s: no trunk", __func__)); 1127 1128 if (m->m_flags & M_VLANTAG) { 1129 /* 1130 * Packet is tagged, but m contains a normal 1131 * Ethernet frame; the tag is stored out-of-band. 1132 */ 1133 vid = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); 1134 m->m_flags &= ~M_VLANTAG; 1135 } else { 1136 struct ether_vlan_header *evl; 1137 1138 /* 1139 * Packet is tagged in-band as specified by 802.1q. 1140 */ 1141 switch (ifp->if_type) { 1142 case IFT_ETHER: 1143 if (m->m_len < sizeof(*evl) && 1144 (m = m_pullup(m, sizeof(*evl))) == NULL) { 1145 if_printf(ifp, "cannot pullup VLAN header\n"); 1146 return; 1147 } 1148 evl = mtod(m, struct ether_vlan_header *); 1149 vid = EVL_VLANOFTAG(ntohs(evl->evl_tag)); 1150 1151 /* 1152 * Remove the 802.1q header by copying the Ethernet 1153 * addresses over it and adjusting the beginning of 1154 * the data in the mbuf. The encapsulated Ethernet 1155 * type field is already in place. 1156 */ 1157 bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN, 1158 ETHER_HDR_LEN - ETHER_TYPE_LEN); 1159 m_adj(m, ETHER_VLAN_ENCAP_LEN); 1160 break; 1161 1162 default: 1163 #ifdef INVARIANTS 1164 panic("%s: %s has unsupported if_type %u", 1165 __func__, ifp->if_xname, ifp->if_type); 1166 #endif 1167 m_freem(m); 1168 ifp->if_noproto++; 1169 return; 1170 } 1171 } 1172 1173 TRUNK_RLOCK(trunk); 1174 ifv = vlan_gethash(trunk, vid); 1175 if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) { 1176 TRUNK_RUNLOCK(trunk); 1177 m_freem(m); 1178 ifp->if_noproto++; 1179 return; 1180 } 1181 TRUNK_RUNLOCK(trunk); 1182 1183 m->m_pkthdr.rcvif = ifv->ifv_ifp; 1184 ifv->ifv_ifp->if_ipackets++; 1185 1186 /* Pass it back through the parent's input routine. */ 1187 (*ifp->if_input)(ifv->ifv_ifp, m); 1188 } 1189 1190 static int 1191 vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) 1192 { 1193 struct ifvlantrunk *trunk; 1194 struct ifnet *ifp; 1195 int error = 0; 1196 1197 /* VID numbers 0x0 and 0xFFF are reserved */ 1198 if (vid == 0 || vid == 0xFFF) 1199 return (EINVAL); 1200 if (p->if_type != IFT_ETHER && 1201 (p->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) 1202 return (EPROTONOSUPPORT); 1203 if ((p->if_flags & VLAN_IFFLAGS) != VLAN_IFFLAGS) 1204 return (EPROTONOSUPPORT); 1205 if (ifv->ifv_trunk) 1206 return (EBUSY); 1207 1208 if (p->if_vlantrunk == NULL) { 1209 trunk = malloc(sizeof(struct ifvlantrunk), 1210 M_VLAN, M_WAITOK | M_ZERO); 1211 vlan_inithash(trunk); 1212 VLAN_LOCK(); 1213 if (p->if_vlantrunk != NULL) { 1214 /* A race that that is very unlikely to be hit. */ 1215 vlan_freehash(trunk); 1216 free(trunk, M_VLAN); 1217 goto exists; 1218 } 1219 TRUNK_LOCK_INIT(trunk); 1220 TRUNK_LOCK(trunk); 1221 p->if_vlantrunk = trunk; 1222 trunk->parent = p; 1223 } else { 1224 VLAN_LOCK(); 1225 exists: 1226 trunk = p->if_vlantrunk; 1227 TRUNK_LOCK(trunk); 1228 } 1229 1230 ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ 1231 error = vlan_inshash(trunk, ifv); 1232 if (error) 1233 goto done; 1234 ifv->ifv_proto = ETHERTYPE_VLAN; 1235 ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN; 1236 ifv->ifv_mintu = ETHERMIN; 1237 ifv->ifv_pflags = 0; 1238 1239 /* 1240 * If the parent supports the VLAN_MTU capability, 1241 * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames, 1242 * use it. 1243 */ 1244 if (p->if_capenable & IFCAP_VLAN_MTU) { 1245 /* 1246 * No need to fudge the MTU since the parent can 1247 * handle extended frames. 1248 */ 1249 ifv->ifv_mtufudge = 0; 1250 } else { 1251 /* 1252 * Fudge the MTU by the encapsulation size. This 1253 * makes us incompatible with strictly compliant 1254 * 802.1Q implementations, but allows us to use 1255 * the feature with other NetBSD implementations, 1256 * which might still be useful. 1257 */ 1258 ifv->ifv_mtufudge = ifv->ifv_encaplen; 1259 } 1260 1261 ifv->ifv_trunk = trunk; 1262 ifp = ifv->ifv_ifp; 1263 /* 1264 * Initialize fields from our parent. This duplicates some 1265 * work with ether_ifattach() but allows for non-ethernet 1266 * interfaces to also work. 1267 */ 1268 ifp->if_mtu = p->if_mtu - ifv->ifv_mtufudge; 1269 ifp->if_baudrate = p->if_baudrate; 1270 ifp->if_output = p->if_output; 1271 ifp->if_input = p->if_input; 1272 ifp->if_resolvemulti = p->if_resolvemulti; 1273 ifp->if_addrlen = p->if_addrlen; 1274 ifp->if_broadcastaddr = p->if_broadcastaddr; 1275 1276 /* 1277 * Copy only a selected subset of flags from the parent. 1278 * Other flags are none of our business. 1279 */ 1280 #define VLAN_COPY_FLAGS (IFF_SIMPLEX) 1281 ifp->if_flags &= ~VLAN_COPY_FLAGS; 1282 ifp->if_flags |= p->if_flags & VLAN_COPY_FLAGS; 1283 #undef VLAN_COPY_FLAGS 1284 1285 ifp->if_link_state = p->if_link_state; 1286 1287 vlan_capabilities(ifv); 1288 1289 /* 1290 * Set up our interface address to reflect the underlying 1291 * physical interface's. 1292 */ 1293 bcopy(IF_LLADDR(p), IF_LLADDR(ifp), p->if_addrlen); 1294 ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen = 1295 p->if_addrlen; 1296 1297 /* 1298 * Configure multicast addresses that may already be 1299 * joined on the vlan device. 1300 */ 1301 (void)vlan_setmulti(ifp); /* XXX: VLAN lock held */ 1302 1303 /* We are ready for operation now. */ 1304 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1305 done: 1306 TRUNK_UNLOCK(trunk); 1307 if (error == 0) 1308 EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid); 1309 VLAN_UNLOCK(); 1310 1311 return (error); 1312 } 1313 1314 static void 1315 vlan_unconfig(struct ifnet *ifp) 1316 { 1317 1318 VLAN_LOCK(); 1319 vlan_unconfig_locked(ifp, 0); 1320 VLAN_UNLOCK(); 1321 } 1322 1323 static void 1324 vlan_unconfig_locked(struct ifnet *ifp, int departing) 1325 { 1326 struct ifvlantrunk *trunk; 1327 struct vlan_mc_entry *mc; 1328 struct ifvlan *ifv; 1329 struct ifnet *parent; 1330 int error; 1331 1332 VLAN_LOCK_ASSERT(); 1333 1334 ifv = ifp->if_softc; 1335 trunk = ifv->ifv_trunk; 1336 parent = NULL; 1337 1338 if (trunk != NULL) { 1339 1340 TRUNK_LOCK(trunk); 1341 parent = trunk->parent; 1342 1343 /* 1344 * Since the interface is being unconfigured, we need to 1345 * empty the list of multicast groups that we may have joined 1346 * while we were alive from the parent's list. 1347 */ 1348 while ((mc = SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { 1349 /* 1350 * If the parent interface is being detached, 1351 * all its multicast addresses have already 1352 * been removed. Warn about errors if 1353 * if_delmulti() does fail, but don't abort as 1354 * all callers expect vlan destruction to 1355 * succeed. 1356 */ 1357 if (!departing) { 1358 error = if_delmulti(parent, 1359 (struct sockaddr *)&mc->mc_addr); 1360 if (error) 1361 if_printf(ifp, 1362 "Failed to delete multicast address from parent: %d\n", 1363 error); 1364 } 1365 SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); 1366 free(mc, M_VLAN); 1367 } 1368 1369 vlan_setflags(ifp, 0); /* clear special flags on parent */ 1370 vlan_remhash(trunk, ifv); 1371 ifv->ifv_trunk = NULL; 1372 1373 /* 1374 * Check if we were the last. 1375 */ 1376 if (trunk->refcnt == 0) { 1377 trunk->parent->if_vlantrunk = NULL; 1378 /* 1379 * XXXGL: If some ithread has already entered 1380 * vlan_input() and is now blocked on the trunk 1381 * lock, then it should preempt us right after 1382 * unlock and finish its work. Then we will acquire 1383 * lock again in trunk_destroy(). 1384 */ 1385 TRUNK_UNLOCK(trunk); 1386 trunk_destroy(trunk); 1387 } else 1388 TRUNK_UNLOCK(trunk); 1389 } 1390 1391 /* Disconnect from parent. */ 1392 if (ifv->ifv_pflags) 1393 if_printf(ifp, "%s: ifv_pflags unclean\n", __func__); 1394 ifp->if_mtu = ETHERMTU; 1395 ifp->if_link_state = LINK_STATE_UNKNOWN; 1396 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1397 1398 /* 1399 * Only dispatch an event if vlan was 1400 * attached, otherwise there is nothing 1401 * to cleanup anyway. 1402 */ 1403 if (parent != NULL) 1404 EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_vid); 1405 } 1406 1407 /* Handle a reference counted flag that should be set on the parent as well */ 1408 static int 1409 vlan_setflag(struct ifnet *ifp, int flag, int status, 1410 int (*func)(struct ifnet *, int)) 1411 { 1412 struct ifvlan *ifv; 1413 int error; 1414 1415 /* XXX VLAN_LOCK_ASSERT(); */ 1416 1417 ifv = ifp->if_softc; 1418 status = status ? (ifp->if_flags & flag) : 0; 1419 /* Now "status" contains the flag value or 0 */ 1420 1421 /* 1422 * See if recorded parent's status is different from what 1423 * we want it to be. If it is, flip it. We record parent's 1424 * status in ifv_pflags so that we won't clear parent's flag 1425 * we haven't set. In fact, we don't clear or set parent's 1426 * flags directly, but get or release references to them. 1427 * That's why we can be sure that recorded flags still are 1428 * in accord with actual parent's flags. 1429 */ 1430 if (status != (ifv->ifv_pflags & flag)) { 1431 error = (*func)(PARENT(ifv), status); 1432 if (error) 1433 return (error); 1434 ifv->ifv_pflags &= ~flag; 1435 ifv->ifv_pflags |= status; 1436 } 1437 return (0); 1438 } 1439 1440 /* 1441 * Handle IFF_* flags that require certain changes on the parent: 1442 * if "status" is true, update parent's flags respective to our if_flags; 1443 * if "status" is false, forcedly clear the flags set on parent. 1444 */ 1445 static int 1446 vlan_setflags(struct ifnet *ifp, int status) 1447 { 1448 int error, i; 1449 1450 for (i = 0; vlan_pflags[i].flag; i++) { 1451 error = vlan_setflag(ifp, vlan_pflags[i].flag, 1452 status, vlan_pflags[i].func); 1453 if (error) 1454 return (error); 1455 } 1456 return (0); 1457 } 1458 1459 /* Inform all vlans that their parent has changed link state */ 1460 static void 1461 vlan_link_state(struct ifnet *ifp) 1462 { 1463 struct ifvlantrunk *trunk = ifp->if_vlantrunk; 1464 struct ifvlan *ifv; 1465 int i; 1466 1467 TRUNK_LOCK(trunk); 1468 #ifdef VLAN_ARRAY 1469 for (i = 0; i < VLAN_ARRAY_SIZE; i++) 1470 if (trunk->vlans[i] != NULL) { 1471 ifv = trunk->vlans[i]; 1472 #else 1473 for (i = 0; i < (1 << trunk->hwidth); i++) 1474 LIST_FOREACH(ifv, &trunk->hash[i], ifv_list) { 1475 #endif 1476 ifv->ifv_ifp->if_baudrate = trunk->parent->if_baudrate; 1477 if_link_state_change(ifv->ifv_ifp, 1478 trunk->parent->if_link_state); 1479 } 1480 TRUNK_UNLOCK(trunk); 1481 } 1482 1483 static void 1484 vlan_capabilities(struct ifvlan *ifv) 1485 { 1486 struct ifnet *p = PARENT(ifv); 1487 struct ifnet *ifp = ifv->ifv_ifp; 1488 1489 TRUNK_LOCK_ASSERT(TRUNK(ifv)); 1490 1491 /* 1492 * If the parent interface can do checksum offloading 1493 * on VLANs, then propagate its hardware-assisted 1494 * checksumming flags. Also assert that checksum 1495 * offloading requires hardware VLAN tagging. 1496 */ 1497 if (p->if_capabilities & IFCAP_VLAN_HWCSUM) 1498 ifp->if_capabilities = p->if_capabilities & IFCAP_HWCSUM; 1499 1500 if (p->if_capenable & IFCAP_VLAN_HWCSUM && 1501 p->if_capenable & IFCAP_VLAN_HWTAGGING) { 1502 ifp->if_capenable = p->if_capenable & IFCAP_HWCSUM; 1503 ifp->if_hwassist = p->if_hwassist & (CSUM_IP | CSUM_TCP | 1504 CSUM_UDP | CSUM_SCTP | CSUM_FRAGMENT); 1505 } else { 1506 ifp->if_capenable = 0; 1507 ifp->if_hwassist = 0; 1508 } 1509 /* 1510 * If the parent interface can do TSO on VLANs then 1511 * propagate the hardware-assisted flag. TSO on VLANs 1512 * does not necessarily require hardware VLAN tagging. 1513 */ 1514 if (p->if_hw_tsomax > 0) 1515 ifp->if_hw_tsomax = p->if_hw_tsomax; 1516 if (p->if_capabilities & IFCAP_VLAN_HWTSO) 1517 ifp->if_capabilities |= p->if_capabilities & IFCAP_TSO; 1518 if (p->if_capenable & IFCAP_VLAN_HWTSO) { 1519 ifp->if_capenable |= p->if_capenable & IFCAP_TSO; 1520 ifp->if_hwassist |= p->if_hwassist & CSUM_TSO; 1521 } else { 1522 ifp->if_capenable &= ~(p->if_capenable & IFCAP_TSO); 1523 ifp->if_hwassist &= ~(p->if_hwassist & CSUM_TSO); 1524 } 1525 1526 /* 1527 * If the parent interface can offload TCP connections over VLANs then 1528 * propagate its TOE capability to the VLAN interface. 1529 * 1530 * All TOE drivers in the tree today can deal with VLANs. If this 1531 * changes then IFCAP_VLAN_TOE should be promoted to a full capability 1532 * with its own bit. 1533 */ 1534 #define IFCAP_VLAN_TOE IFCAP_TOE 1535 if (p->if_capabilities & IFCAP_VLAN_TOE) 1536 ifp->if_capabilities |= p->if_capabilities & IFCAP_TOE; 1537 if (p->if_capenable & IFCAP_VLAN_TOE) { 1538 TOEDEV(ifp) = TOEDEV(p); 1539 ifp->if_capenable |= p->if_capenable & IFCAP_TOE; 1540 } 1541 } 1542 1543 static void 1544 vlan_trunk_capabilities(struct ifnet *ifp) 1545 { 1546 struct ifvlantrunk *trunk = ifp->if_vlantrunk; 1547 struct ifvlan *ifv; 1548 int i; 1549 1550 TRUNK_LOCK(trunk); 1551 #ifdef VLAN_ARRAY 1552 for (i = 0; i < VLAN_ARRAY_SIZE; i++) 1553 if (trunk->vlans[i] != NULL) { 1554 ifv = trunk->vlans[i]; 1555 #else 1556 for (i = 0; i < (1 << trunk->hwidth); i++) { 1557 LIST_FOREACH(ifv, &trunk->hash[i], ifv_list) 1558 #endif 1559 vlan_capabilities(ifv); 1560 } 1561 TRUNK_UNLOCK(trunk); 1562 } 1563 1564 static int 1565 vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1566 { 1567 struct ifnet *p; 1568 struct ifreq *ifr; 1569 struct ifaddr *ifa; 1570 struct ifvlan *ifv; 1571 struct vlanreq vlr; 1572 int error = 0; 1573 1574 ifr = (struct ifreq *)data; 1575 ifa = (struct ifaddr *) data; 1576 ifv = ifp->if_softc; 1577 1578 switch (cmd) { 1579 case SIOCSIFADDR: 1580 ifp->if_flags |= IFF_UP; 1581 #ifdef INET 1582 if (ifa->ifa_addr->sa_family == AF_INET) 1583 arp_ifinit(ifp, ifa); 1584 #endif 1585 break; 1586 case SIOCGIFADDR: 1587 { 1588 struct sockaddr *sa; 1589 1590 sa = (struct sockaddr *)&ifr->ifr_data; 1591 bcopy(IF_LLADDR(ifp), sa->sa_data, ifp->if_addrlen); 1592 } 1593 break; 1594 case SIOCGIFMEDIA: 1595 VLAN_LOCK(); 1596 if (TRUNK(ifv) != NULL) { 1597 p = PARENT(ifv); 1598 VLAN_UNLOCK(); 1599 error = (*p->if_ioctl)(p, SIOCGIFMEDIA, data); 1600 /* Limit the result to the parent's current config. */ 1601 if (error == 0) { 1602 struct ifmediareq *ifmr; 1603 1604 ifmr = (struct ifmediareq *)data; 1605 if (ifmr->ifm_count >= 1 && ifmr->ifm_ulist) { 1606 ifmr->ifm_count = 1; 1607 error = copyout(&ifmr->ifm_current, 1608 ifmr->ifm_ulist, 1609 sizeof(int)); 1610 } 1611 } 1612 } else { 1613 VLAN_UNLOCK(); 1614 error = EINVAL; 1615 } 1616 break; 1617 1618 case SIOCSIFMEDIA: 1619 error = EINVAL; 1620 break; 1621 1622 case SIOCSIFMTU: 1623 /* 1624 * Set the interface MTU. 1625 */ 1626 VLAN_LOCK(); 1627 if (TRUNK(ifv) != NULL) { 1628 if (ifr->ifr_mtu > 1629 (PARENT(ifv)->if_mtu - ifv->ifv_mtufudge) || 1630 ifr->ifr_mtu < 1631 (ifv->ifv_mintu - ifv->ifv_mtufudge)) 1632 error = EINVAL; 1633 else 1634 ifp->if_mtu = ifr->ifr_mtu; 1635 } else 1636 error = EINVAL; 1637 VLAN_UNLOCK(); 1638 break; 1639 1640 case SIOCSETVLAN: 1641 #ifdef VIMAGE 1642 /* 1643 * XXXRW/XXXBZ: The goal in these checks is to allow a VLAN 1644 * interface to be delegated to a jail without allowing the 1645 * jail to change what underlying interface/VID it is 1646 * associated with. We are not entirely convinced that this 1647 * is the right way to accomplish that policy goal. 1648 */ 1649 if (ifp->if_vnet != ifp->if_home_vnet) { 1650 error = EPERM; 1651 break; 1652 } 1653 #endif 1654 error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); 1655 if (error) 1656 break; 1657 if (vlr.vlr_parent[0] == '\0') { 1658 vlan_unconfig(ifp); 1659 break; 1660 } 1661 p = ifunit(vlr.vlr_parent); 1662 if (p == NULL) { 1663 error = ENOENT; 1664 break; 1665 } 1666 /* 1667 * Don't let the caller set up a VLAN VID with 1668 * anything except VLID bits. 1669 */ 1670 if (vlr.vlr_tag & ~EVL_VLID_MASK) { 1671 error = EINVAL; 1672 break; 1673 } 1674 error = vlan_config(ifv, p, vlr.vlr_tag); 1675 if (error) 1676 break; 1677 1678 /* Update flags on the parent, if necessary. */ 1679 vlan_setflags(ifp, 1); 1680 break; 1681 1682 case SIOCGETVLAN: 1683 #ifdef VIMAGE 1684 if (ifp->if_vnet != ifp->if_home_vnet) { 1685 error = EPERM; 1686 break; 1687 } 1688 #endif 1689 bzero(&vlr, sizeof(vlr)); 1690 VLAN_LOCK(); 1691 if (TRUNK(ifv) != NULL) { 1692 strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname, 1693 sizeof(vlr.vlr_parent)); 1694 vlr.vlr_tag = ifv->ifv_vid; 1695 } 1696 VLAN_UNLOCK(); 1697 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); 1698 break; 1699 1700 case SIOCSIFFLAGS: 1701 /* 1702 * We should propagate selected flags to the parent, 1703 * e.g., promiscuous mode. 1704 */ 1705 if (TRUNK(ifv) != NULL) 1706 error = vlan_setflags(ifp, 1); 1707 break; 1708 1709 case SIOCADDMULTI: 1710 case SIOCDELMULTI: 1711 /* 1712 * If we don't have a parent, just remember the membership for 1713 * when we do. 1714 */ 1715 if (TRUNK(ifv) != NULL) 1716 error = vlan_setmulti(ifp); 1717 break; 1718 1719 default: 1720 error = EINVAL; 1721 break; 1722 } 1723 1724 return (error); 1725 } 1726