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