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