1/* $OpenBSD: if_vlan.c,v 1.219 2024/06/09 16:25:28 jan Exp $ */ 2 3/* 4 * Copyright 1998 Massachusetts Institute of Technology 5 * 6 * Permission to use, copy, modify, and distribute this software and 7 * its documentation for any purpose and without fee is hereby 8 * granted, provided that both the above copyright notice and this 9 * permission notice appear in all copies, that both the above 10 * copyright notice and this permission notice appear in all 11 * supporting documentation, and that the name of M.I.T. not be used 12 * in advertising or publicity pertaining to distribution of the 13 * software without specific, written prior permission. M.I.T. makes 14 * no representations about the suitability of this software for any 15 * purpose. It is provided "as is" without express or implied 16 * warranty. 17 * 18 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 19 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 22 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $FreeBSD: src/sys/net/if_vlan.c,v 1.16 2000/03/26 15:21:40 charnier Exp $ 32 */ 33 34/* 35 * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs. 36 * This is sort of sneaky in the implementation, since 37 * we need to pretend to be enough of an Ethernet implementation 38 * to make arp work. The way we do this is by telling everyone 39 * that we are an Ethernet, and then catch the packets that 40 * ether_output() left on our output queue when it calls 41 * if_start(), rewrite them for use by the real outgoing interface, 42 * and ask it to send them. 43 * 44 * Some devices support 802.1Q tag insertion in firmware. The 45 * vlan interface behavior changes when the IFCAP_VLAN_HWTAGGING 46 * capability is set on the parent. In this case, vlan_start() 47 * will not modify the ethernet header. 48 */ 49 50#include <sys/param.h> 51#include <sys/kernel.h> 52#include <sys/malloc.h> 53#include <sys/mbuf.h> 54#include <sys/queue.h> 55#include <sys/socket.h> 56#include <sys/sockio.h> 57#include <sys/systm.h> 58#include <sys/rwlock.h> 59#include <sys/percpu.h> 60#include <sys/refcnt.h> 61#include <sys/smr.h> 62 63#include <net/if.h> 64#include <net/if_dl.h> 65#include <net/if_types.h> 66 67#include <netinet/in.h> 68#include <netinet/if_ether.h> 69 70#include <net/if_vlan_var.h> 71 72#include "bpfilter.h" 73#if NBPFILTER > 0 74#include <net/bpf.h> 75#endif 76 77struct vlan_mc_entry { 78 LIST_ENTRY(vlan_mc_entry) mc_entries; 79 union { 80 struct ether_multi *mcu_enm; 81 } mc_u; 82#define mc_enm mc_u.mcu_enm 83 struct sockaddr_storage mc_addr; 84}; 85 86struct vlan_softc { 87 struct arpcom sc_ac; 88#define sc_if sc_ac.ac_if 89 unsigned int sc_dead; 90 unsigned int sc_ifidx0; /* parent interface */ 91 int sc_txprio; 92 int sc_rxprio; 93 uint16_t sc_proto; /* encapsulation ethertype */ 94 uint16_t sc_tag; 95 uint16_t sc_type; /* non-standard ethertype or 0x8100 */ 96 LIST_HEAD(__vlan_mchead, vlan_mc_entry) 97 sc_mc_listhead; 98 SMR_SLIST_ENTRY(vlan_softc) sc_list; 99 int sc_flags; 100 struct refcnt sc_refcnt; 101 struct task sc_ltask; 102 struct task sc_dtask; 103}; 104 105SMR_SLIST_HEAD(vlan_list, vlan_softc); 106 107#define IFVF_PROMISC 0x01 /* the parent should be made promisc */ 108#define IFVF_LLADDR 0x02 /* don't inherit the parents mac */ 109 110#define TAG_HASH_BITS 5 111#define TAG_HASH_SIZE (1 << TAG_HASH_BITS) 112#define TAG_HASH_MASK (TAG_HASH_SIZE - 1) 113#define TAG_HASH(tag) (tag & TAG_HASH_MASK) 114struct vlan_list *vlan_tagh, *svlan_tagh; 115struct rwlock vlan_tagh_lk = RWLOCK_INITIALIZER("vlantag"); 116 117void vlanattach(int count); 118int vlan_clone_create(struct if_clone *, int); 119int vlan_clone_destroy(struct ifnet *); 120 121int vlan_enqueue(struct ifnet *, struct mbuf *); 122void vlan_start(struct ifqueue *ifq); 123int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); 124 125int vlan_up(struct vlan_softc *); 126int vlan_down(struct vlan_softc *); 127 128void vlan_ifdetach(void *); 129void vlan_link_hook(void *); 130void vlan_link_state(struct vlan_softc *, u_char, uint64_t); 131 132int vlan_set_vnetid(struct vlan_softc *, uint16_t); 133int vlan_set_parent(struct vlan_softc *, const char *); 134int vlan_del_parent(struct vlan_softc *); 135int vlan_inuse(uint16_t, unsigned int, uint16_t); 136int vlan_inuse_locked(uint16_t, unsigned int, uint16_t); 137 138int vlan_multi_add(struct vlan_softc *, struct ifreq *); 139int vlan_multi_del(struct vlan_softc *, struct ifreq *); 140void vlan_multi_apply(struct vlan_softc *, struct ifnet *, u_long); 141void vlan_multi_free(struct vlan_softc *); 142 143int vlan_media_get(struct vlan_softc *, struct ifreq *); 144 145int vlan_iff(struct vlan_softc *); 146int vlan_setlladdr(struct vlan_softc *, struct ifreq *); 147 148int vlan_set_compat(struct ifnet *, struct ifreq *); 149int vlan_get_compat(struct ifnet *, struct ifreq *); 150 151struct if_clone vlan_cloner = 152 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); 153struct if_clone svlan_cloner = 154 IF_CLONE_INITIALIZER("svlan", vlan_clone_create, vlan_clone_destroy); 155 156void 157vlanattach(int count) 158{ 159 unsigned int i; 160 161 /* Normal VLAN */ 162 vlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*vlan_tagh), 163 M_DEVBUF, M_NOWAIT); 164 if (vlan_tagh == NULL) 165 panic("vlanattach: hashinit"); 166 167 /* Service-VLAN for QinQ/802.1ad provider bridges */ 168 svlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*svlan_tagh), 169 M_DEVBUF, M_NOWAIT); 170 if (svlan_tagh == NULL) 171 panic("vlanattach: hashinit"); 172 173 for (i = 0; i < TAG_HASH_SIZE; i++) { 174 SMR_SLIST_INIT(&vlan_tagh[i]); 175 SMR_SLIST_INIT(&svlan_tagh[i]); 176 } 177 178 if_clone_attach(&vlan_cloner); 179 if_clone_attach(&svlan_cloner); 180} 181 182int 183vlan_clone_create(struct if_clone *ifc, int unit) 184{ 185 struct vlan_softc *sc; 186 struct ifnet *ifp; 187 188 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); 189 sc->sc_dead = 0; 190 LIST_INIT(&sc->sc_mc_listhead); 191 task_set(&sc->sc_ltask, vlan_link_hook, sc); 192 task_set(&sc->sc_dtask, vlan_ifdetach, sc); 193 ifp = &sc->sc_if; 194 ifp->if_softc = sc; 195 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, 196 unit); 197 /* NB: flags are not set here */ 198 /* NB: mtu is not set here */ 199 200 /* Special handling for the IEEE 802.1ad QinQ variant */ 201 if (strcmp("svlan", ifc->ifc_name) == 0) 202 sc->sc_type = ETHERTYPE_QINQ; 203 else 204 sc->sc_type = ETHERTYPE_VLAN; 205 206 refcnt_init(&sc->sc_refcnt); 207 sc->sc_txprio = IF_HDRPRIO_PACKET; 208 sc->sc_rxprio = IF_HDRPRIO_OUTER; 209 210 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST; 211 ifp->if_xflags = IFXF_CLONED|IFXF_MPSAFE; 212 ifp->if_qstart = vlan_start; 213 ifp->if_enqueue = vlan_enqueue; 214 ifp->if_ioctl = vlan_ioctl; 215 ifp->if_hardmtu = 0xffff; 216 ifp->if_link_state = LINK_STATE_DOWN; 217 218 if_counters_alloc(ifp); 219 if_attach(ifp); 220 ether_ifattach(ifp); 221 ifp->if_hdrlen = EVL_ENCAPLEN; 222 223 return (0); 224} 225 226int 227vlan_clone_destroy(struct ifnet *ifp) 228{ 229 struct vlan_softc *sc = ifp->if_softc; 230 231 NET_LOCK(); 232 sc->sc_dead = 1; 233 234 if (ISSET(ifp->if_flags, IFF_RUNNING)) 235 vlan_down(sc); 236 NET_UNLOCK(); 237 238 ether_ifdetach(ifp); 239 if_detach(ifp); 240 smr_barrier(); 241 refcnt_finalize(&sc->sc_refcnt, "vlanrefs"); 242 vlan_multi_free(sc); 243 free(sc, M_DEVBUF, sizeof(*sc)); 244 245 return (0); 246} 247 248void 249vlan_transmit(struct vlan_softc *sc, struct ifnet *ifp0, struct mbuf *m) 250{ 251 struct ifnet *ifp = &sc->sc_if; 252 int txprio = sc->sc_txprio; 253 uint8_t prio; 254 255#if NBPFILTER > 0 256 if (ifp->if_bpf) 257 bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); 258#endif /* NBPFILTER > 0 */ 259 260 prio = (txprio == IF_HDRPRIO_PACKET) ? 261 m->m_pkthdr.pf.prio : txprio; 262 263 /* IEEE 802.1p has prio 0 and 1 swapped */ 264 if (prio <= 1) 265 prio = !prio; 266 267 /* 268 * If the underlying interface cannot do VLAN tag insertion 269 * itself, create an encapsulation header. 270 */ 271 if ((ifp0->if_capabilities & IFCAP_VLAN_HWTAGGING) && 272 (sc->sc_type == ETHERTYPE_VLAN)) { 273 m->m_pkthdr.ether_vtag = sc->sc_tag | 274 (prio << EVL_PRIO_BITS); 275 m->m_flags |= M_VLANTAG; 276 } else { 277 m = vlan_inject(m, sc->sc_type, sc->sc_tag | 278 (prio << EVL_PRIO_BITS)); 279 if (m == NULL) { 280 counters_inc(ifp->if_counters, ifc_oerrors); 281 return; 282 } 283 } 284 285 if (if_enqueue(ifp0, m)) 286 counters_inc(ifp->if_counters, ifc_oerrors); 287} 288 289int 290vlan_enqueue(struct ifnet *ifp, struct mbuf *m) 291{ 292 struct ifnet *ifp0; 293 struct vlan_softc *sc; 294 int error = 0; 295 296 if (!ifq_is_priq(&ifp->if_snd)) 297 return (if_enqueue_ifq(ifp, m)); 298 299 sc = ifp->if_softc; 300 ifp0 = if_get(sc->sc_ifidx0); 301 302 if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) { 303 m_freem(m); 304 error = ENETDOWN; 305 } else { 306 counters_pkt(ifp->if_counters, 307 ifc_opackets, ifc_obytes, m->m_pkthdr.len); 308 vlan_transmit(sc, ifp0, m); 309 } 310 311 if_put(ifp0); 312 313 return (error); 314} 315 316void 317vlan_start(struct ifqueue *ifq) 318{ 319 struct ifnet *ifp = ifq->ifq_if; 320 struct vlan_softc *sc = ifp->if_softc; 321 struct ifnet *ifp0; 322 struct mbuf *m; 323 324 ifp0 = if_get(sc->sc_ifidx0); 325 if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) { 326 ifq_purge(ifq); 327 goto leave; 328 } 329 330 while ((m = ifq_dequeue(ifq)) != NULL) 331 vlan_transmit(sc, ifp0, m); 332 333leave: 334 if_put(ifp0); 335} 336 337struct mbuf * 338vlan_strip(struct mbuf *m) 339{ 340 if (ISSET(m->m_flags, M_VLANTAG)) { 341 CLR(m->m_flags, M_VLANTAG); 342 } else { 343 struct ether_vlan_header *evl; 344 345 evl = mtod(m, struct ether_vlan_header *); 346 memmove((caddr_t)evl + EVL_ENCAPLEN, evl, 347 offsetof(struct ether_vlan_header, evl_encap_proto)); 348 m_adj(m, EVL_ENCAPLEN); 349 } 350 351 return (m); 352} 353 354struct mbuf * 355vlan_inject(struct mbuf *m, uint16_t type, uint16_t tag) 356{ 357 struct ether_vlan_header evh; 358 359 m_copydata(m, 0, ETHER_HDR_LEN, &evh); 360 evh.evl_proto = evh.evl_encap_proto; 361 evh.evl_encap_proto = htons(type); 362 evh.evl_tag = htons(tag); 363 m_adj(m, ETHER_HDR_LEN); 364 M_PREPEND(m, sizeof(evh) + ETHER_ALIGN, M_DONTWAIT); 365 if (m == NULL) 366 return (NULL); 367 368 m_adj(m, ETHER_ALIGN); 369 370 m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT); 371 CLR(m->m_flags, M_VLANTAG); 372 373 return (m); 374} 375 376struct mbuf * 377vlan_input(struct ifnet *ifp0, struct mbuf *m, unsigned int *sdelim) 378{ 379 struct vlan_softc *sc; 380 struct ifnet *ifp; 381 struct ether_vlan_header *evl; 382 struct vlan_list *tagh, *list; 383 uint16_t vtag, tag; 384 uint16_t etype; 385 int rxprio; 386 387 if (m->m_flags & M_VLANTAG) { 388 vtag = m->m_pkthdr.ether_vtag; 389 etype = ETHERTYPE_VLAN; 390 tagh = vlan_tagh; 391 } else { 392 if (m->m_len < sizeof(*evl)) { 393 m = m_pullup(m, sizeof(*evl)); 394 if (m == NULL) 395 return (NULL); 396 } 397 398 evl = mtod(m, struct ether_vlan_header *); 399 vtag = bemtoh16(&evl->evl_tag); 400 etype = bemtoh16(&evl->evl_encap_proto); 401 switch (etype) { 402 case ETHERTYPE_VLAN: 403 tagh = vlan_tagh; 404 break; 405 case ETHERTYPE_QINQ: 406 tagh = svlan_tagh; 407 break; 408 default: 409 panic("%s: unexpected etype 0x%04x", __func__, etype); 410 /* NOTREACHED */ 411 } 412 } 413 414 tag = EVL_VLANOFTAG(vtag); 415 list = &tagh[TAG_HASH(tag)]; 416 smr_read_enter(); 417 SMR_SLIST_FOREACH(sc, list, sc_list) { 418 if (ifp0->if_index == sc->sc_ifidx0 && tag == sc->sc_tag && 419 etype == sc->sc_type) { 420 refcnt_take(&sc->sc_refcnt); 421 break; 422 } 423 } 424 smr_read_leave(); 425 426 if (sc == NULL) { 427 /* VLAN 0 Priority Tagging */ 428 if (tag == 0 && etype == ETHERTYPE_VLAN) { 429 struct ether_header *eh; 430 431 /* XXX we should actually use the prio value? */ 432 m = vlan_strip(m); 433 434 eh = mtod(m, struct ether_header *); 435 if (eh->ether_type == htons(ETHERTYPE_VLAN) || 436 eh->ether_type == htons(ETHERTYPE_QINQ)) { 437 m_freem(m); 438 return (NULL); 439 } 440 } else 441 *sdelim = 1; 442 443 return (m); /* decline */ 444 } 445 446 ifp = &sc->sc_if; 447 if (!ISSET(ifp->if_flags, IFF_RUNNING)) { 448 m_freem(m); 449 goto leave; 450 } 451 452 /* 453 * Having found a valid vlan interface corresponding to 454 * the given source interface and vlan tag, remove the 455 * encapsulation. 456 */ 457 m = vlan_strip(m); 458 459 rxprio = sc->sc_rxprio; 460 switch (rxprio) { 461 case IF_HDRPRIO_PACKET: 462 break; 463 case IF_HDRPRIO_OUTER: 464 m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); 465 /* IEEE 802.1p has prio 0 and 1 swapped */ 466 if (m->m_pkthdr.pf.prio <= 1) 467 m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; 468 break; 469 default: 470 m->m_pkthdr.pf.prio = rxprio; 471 break; 472 } 473 474 if_vinput(ifp, m); 475leave: 476 refcnt_rele_wake(&sc->sc_refcnt); 477 return (NULL); 478} 479 480int 481vlan_up(struct vlan_softc *sc) 482{ 483 struct vlan_list *tagh, *list; 484 struct ifnet *ifp = &sc->sc_if; 485 struct ifnet *ifp0; 486 int error = 0; 487 unsigned int hardmtu; 488 489 KASSERT(!ISSET(ifp->if_flags, IFF_RUNNING)); 490 491 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 492 list = &tagh[TAG_HASH(sc->sc_tag)]; 493 494 ifp0 = if_get(sc->sc_ifidx0); 495 if (ifp0 == NULL) 496 return (ENXIO); 497 498 /* check vlan will work on top of the parent */ 499 if (ifp0->if_type != IFT_ETHER) { 500 error = EPROTONOSUPPORT; 501 goto put; 502 } 503 504 hardmtu = ifp0->if_hardmtu; 505 if (!ISSET(ifp0->if_capabilities, IFCAP_VLAN_MTU)) 506 hardmtu -= EVL_ENCAPLEN; 507 508 if (ifp->if_mtu > hardmtu) { 509 error = ENOBUFS; 510 goto put; 511 } 512 513 /* parent is fine, let's prepare the sc to handle packets */ 514 ifp->if_hardmtu = hardmtu; 515 SET(ifp->if_flags, ifp0->if_flags & IFF_SIMPLEX); 516 517 if (ISSET(sc->sc_flags, IFVF_PROMISC)) { 518 error = ifpromisc(ifp0, 1); 519 if (error != 0) 520 goto scrub; 521 } 522 523 /* 524 * Note: In cases like vio(4) and em(4) where the offsets of the 525 * csum can be freely defined, we could actually do csum offload 526 * for QINQ packets. 527 */ 528 if (sc->sc_type != ETHERTYPE_VLAN) { 529 /* 530 * Hardware offload only works with the default VLAN 531 * ethernet type (0x8100). 532 */ 533 ifp->if_capabilities = 0; 534 } else if (ISSET(ifp0->if_capabilities, IFCAP_VLAN_HWTAGGING) || 535 ISSET(ifp0->if_capabilities, IFCAP_VLAN_HWOFFLOAD)) { 536 /* 537 * Chips that can do hardware-assisted VLAN encapsulation, can 538 * calculate the correct checksum for VLAN tagged packets. 539 * 540 * Hardware which does checksum offloading, but not VLAN tag 541 * injection, have to set IFCAP_VLAN_HWOFFLOAD. 542 */ 543 ifp->if_capabilities = ifp0->if_capabilities & 544 (IFCAP_CSUM_MASK | IFCAP_TSOv4 | IFCAP_TSOv6); 545 } 546 547 /* commit the sc */ 548 error = rw_enter(&vlan_tagh_lk, RW_WRITE | RW_INTR); 549 if (error != 0) 550 goto unpromisc; 551 552 error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, sc->sc_tag); 553 if (error != 0) 554 goto leave; 555 556 SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); 557 rw_exit(&vlan_tagh_lk); 558 559 /* Register callback for physical link state changes */ 560 if_linkstatehook_add(ifp0, &sc->sc_ltask); 561 562 /* Register callback if parent wants to unregister */ 563 if_detachhook_add(ifp0, &sc->sc_dtask); 564 565 /* configure the parent to handle packets for this vlan */ 566 vlan_multi_apply(sc, ifp0, SIOCADDMULTI); 567 568 /* we're running now */ 569 SET(ifp->if_flags, IFF_RUNNING); 570 vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate); 571 572 if_put(ifp0); 573 574 return (ENETRESET); 575 576leave: 577 rw_exit(&vlan_tagh_lk); 578unpromisc: 579 if (ISSET(sc->sc_flags, IFVF_PROMISC)) 580 (void)ifpromisc(ifp0, 0); /* XXX */ 581scrub: 582 ifp->if_capabilities = 0; 583 CLR(ifp->if_flags, IFF_SIMPLEX); 584 ifp->if_hardmtu = 0xffff; 585put: 586 if_put(ifp0); 587 588 return (error); 589} 590 591int 592vlan_down(struct vlan_softc *sc) 593{ 594 struct vlan_list *tagh, *list; 595 struct ifnet *ifp = &sc->sc_if; 596 struct ifnet *ifp0; 597 598 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 599 list = &tagh[TAG_HASH(sc->sc_tag)]; 600 601 KASSERT(ISSET(ifp->if_flags, IFF_RUNNING)); 602 603 vlan_link_state(sc, LINK_STATE_DOWN, 0); 604 CLR(ifp->if_flags, IFF_RUNNING); 605 606 ifq_barrier(&ifp->if_snd); 607 608 ifp0 = if_get(sc->sc_ifidx0); 609 if (ifp0 != NULL) { 610 if (ISSET(sc->sc_flags, IFVF_PROMISC)) 611 ifpromisc(ifp0, 0); 612 vlan_multi_apply(sc, ifp0, SIOCDELMULTI); 613 if_detachhook_del(ifp0, &sc->sc_dtask); 614 if_linkstatehook_del(ifp0, &sc->sc_ltask); 615 } 616 if_put(ifp0); 617 618 rw_enter_write(&vlan_tagh_lk); 619 SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list); 620 rw_exit_write(&vlan_tagh_lk); 621 622 ifp->if_capabilities = 0; 623 CLR(ifp->if_flags, IFF_SIMPLEX); 624 ifp->if_hardmtu = 0xffff; 625 626 return (0); 627} 628 629void 630vlan_ifdetach(void *v) 631{ 632 struct vlan_softc *sc = v; 633 struct ifnet *ifp = &sc->sc_if; 634 635 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 636 vlan_down(sc); 637 CLR(ifp->if_flags, IFF_UP); 638 } 639 640 sc->sc_ifidx0 = 0; 641} 642 643void 644vlan_link_hook(void *v) 645{ 646 struct vlan_softc *sc = v; 647 struct ifnet *ifp0; 648 649 u_char link = LINK_STATE_DOWN; 650 uint64_t baud = 0; 651 652 ifp0 = if_get(sc->sc_ifidx0); 653 if (ifp0 != NULL) { 654 link = ifp0->if_link_state; 655 baud = ifp0->if_baudrate; 656 } 657 if_put(ifp0); 658 659 vlan_link_state(sc, link, baud); 660} 661 662void 663vlan_link_state(struct vlan_softc *sc, u_char link, uint64_t baud) 664{ 665 if (sc->sc_if.if_link_state == link) 666 return; 667 668 sc->sc_if.if_link_state = link; 669 sc->sc_if.if_baudrate = baud; 670 671 if_link_state_change(&sc->sc_if); 672} 673 674int 675vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 676{ 677 struct vlan_softc *sc = ifp->if_softc; 678 struct ifreq *ifr = (struct ifreq *)data; 679 struct if_parent *parent = (struct if_parent *)data; 680 struct ifnet *ifp0; 681 uint16_t tag; 682 int error = 0; 683 684 if (sc->sc_dead) 685 return (ENXIO); 686 687 switch (cmd) { 688 case SIOCSIFADDR: 689 ifp->if_flags |= IFF_UP; 690 /* FALLTHROUGH */ 691 692 case SIOCSIFFLAGS: 693 if (ISSET(ifp->if_flags, IFF_UP)) { 694 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 695 error = vlan_up(sc); 696 else 697 error = ENETRESET; 698 } else { 699 if (ISSET(ifp->if_flags, IFF_RUNNING)) 700 error = vlan_down(sc); 701 } 702 break; 703 704 case SIOCSVNETID: 705 if (ifr->ifr_vnetid < EVL_VLID_MIN || 706 ifr->ifr_vnetid > EVL_VLID_MAX) { 707 error = EINVAL; 708 break; 709 } 710 711 tag = ifr->ifr_vnetid; 712 if (tag == sc->sc_tag) 713 break; 714 715 error = vlan_set_vnetid(sc, tag); 716 break; 717 718 case SIOCGVNETID: 719 if (sc->sc_tag == EVL_VLID_NULL) 720 error = EADDRNOTAVAIL; 721 else 722 ifr->ifr_vnetid = (int64_t)sc->sc_tag; 723 break; 724 725 case SIOCDVNETID: 726 error = vlan_set_vnetid(sc, 0); 727 break; 728 729 case SIOCSIFPARENT: 730 error = vlan_set_parent(sc, parent->ifp_parent); 731 break; 732 733 case SIOCGIFPARENT: 734 ifp0 = if_get(sc->sc_ifidx0); 735 if (ifp0 == NULL) 736 error = EADDRNOTAVAIL; 737 else { 738 memcpy(parent->ifp_parent, ifp0->if_xname, 739 sizeof(parent->ifp_parent)); 740 } 741 if_put(ifp0); 742 break; 743 744 case SIOCDIFPARENT: 745 error = vlan_del_parent(sc); 746 break; 747 748 case SIOCADDMULTI: 749 error = vlan_multi_add(sc, ifr); 750 break; 751 752 case SIOCDELMULTI: 753 error = vlan_multi_del(sc, ifr); 754 break; 755 756 case SIOCGIFMEDIA: 757 error = vlan_media_get(sc, ifr); 758 break; 759 760 case SIOCSIFMEDIA: 761 error = ENOTTY; 762 break; 763 764 case SIOCSIFLLADDR: 765 error = vlan_setlladdr(sc, ifr); 766 break; 767 768 case SIOCSETVLAN: 769 error = vlan_set_compat(ifp, ifr); 770 break; 771 case SIOCGETVLAN: 772 error = vlan_get_compat(ifp, ifr); 773 break; 774 775 case SIOCSTXHPRIO: 776 error = if_txhprio_l2_check(ifr->ifr_hdrprio); 777 if (error != 0) 778 break; 779 780 sc->sc_txprio = ifr->ifr_hdrprio; 781 break; 782 case SIOCGTXHPRIO: 783 ifr->ifr_hdrprio = sc->sc_txprio; 784 break; 785 786 case SIOCSRXHPRIO: 787 error = if_rxhprio_l2_check(ifr->ifr_hdrprio); 788 if (error != 0) 789 break; 790 791 sc->sc_rxprio = ifr->ifr_hdrprio; 792 break; 793 case SIOCGRXHPRIO: 794 ifr->ifr_hdrprio = sc->sc_rxprio; 795 break; 796 797 default: 798 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 799 break; 800 } 801 802 if (error == ENETRESET) 803 error = vlan_iff(sc); 804 805 return error; 806} 807 808int 809vlan_iff(struct vlan_softc *sc) 810{ 811 struct ifnet *ifp0; 812 int promisc = 0; 813 int error = 0; 814 815 if (ISSET(sc->sc_if.if_flags, IFF_PROMISC) || 816 ISSET(sc->sc_flags, IFVF_LLADDR)) 817 promisc = IFVF_PROMISC; 818 819 if (ISSET(sc->sc_flags, IFVF_PROMISC) == promisc) 820 return (0); 821 822 if (ISSET(sc->sc_if.if_flags, IFF_RUNNING)) { 823 ifp0 = if_get(sc->sc_ifidx0); 824 if (ifp0 != NULL) 825 error = ifpromisc(ifp0, promisc); 826 if_put(ifp0); 827 } 828 829 if (error == 0) { 830 CLR(sc->sc_flags, IFVF_PROMISC); 831 SET(sc->sc_flags, promisc); 832 } 833 834 return (error); 835} 836 837int 838vlan_setlladdr(struct vlan_softc *sc, struct ifreq *ifr) 839{ 840 struct ifnet *ifp = &sc->sc_if; 841 struct ifnet *ifp0; 842 uint8_t lladdr[ETHER_ADDR_LEN]; 843 int flag; 844 845 memcpy(lladdr, ifr->ifr_addr.sa_data, sizeof(lladdr)); 846 847 /* setting the mac addr to 00:00:00:00:00:00 means reset lladdr */ 848 if (memcmp(lladdr, etheranyaddr, sizeof(lladdr)) == 0) { 849 ifp0 = if_get(sc->sc_ifidx0); 850 if (ifp0 != NULL) 851 memcpy(lladdr, LLADDR(ifp0->if_sadl), sizeof(lladdr)); 852 if_put(ifp0); 853 854 flag = 0; 855 } else 856 flag = IFVF_LLADDR; 857 858 if (memcmp(lladdr, LLADDR(ifp->if_sadl), sizeof(lladdr)) == 0 && 859 ISSET(sc->sc_flags, IFVF_LLADDR) == flag) { 860 /* nop */ 861 return (0); 862 } 863 864 /* commit */ 865 if_setlladdr(ifp, lladdr); 866 CLR(sc->sc_flags, IFVF_LLADDR); 867 SET(sc->sc_flags, flag); 868 869 return (ENETRESET); 870} 871 872int 873vlan_set_vnetid(struct vlan_softc *sc, uint16_t tag) 874{ 875 struct ifnet *ifp = &sc->sc_if; 876 struct vlan_list *tagh, *list; 877 u_char link = ifp->if_link_state; 878 uint64_t baud = ifp->if_baudrate; 879 int error; 880 881 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 882 883 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 884 vlan_link_state(sc, LINK_STATE_DOWN, 0); 885 886 error = rw_enter(&vlan_tagh_lk, RW_WRITE); 887 if (error != 0) 888 return (error); 889 890 error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, tag); 891 if (error != 0) 892 goto unlock; 893 894 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 895 list = &tagh[TAG_HASH(sc->sc_tag)]; 896 SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list); 897 898 sc->sc_tag = tag; 899 900 list = &tagh[TAG_HASH(sc->sc_tag)]; 901 SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); 902 } else 903 sc->sc_tag = tag; 904 905unlock: 906 rw_exit(&vlan_tagh_lk); 907 908 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 909 vlan_link_state(sc, link, baud); 910 911 return (error); 912} 913 914int 915vlan_set_parent(struct vlan_softc *sc, const char *parent) 916{ 917 struct ifnet *ifp = &sc->sc_if; 918 struct ifnet *ifp0; 919 int error = 0; 920 921 ifp0 = if_unit(parent); 922 if (ifp0 == NULL) 923 return (EINVAL); 924 925 if (ifp0->if_type != IFT_ETHER) { 926 error = EPROTONOSUPPORT; 927 goto put; 928 } 929 930 if (sc->sc_ifidx0 == ifp0->if_index) { 931 /* nop */ 932 goto put; 933 } 934 935 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 936 error = EBUSY; 937 goto put; 938 } 939 940 error = vlan_inuse(sc->sc_type, ifp0->if_index, sc->sc_tag); 941 if (error != 0) 942 goto put; 943 944 if (ether_brport_isset(ifp)) 945 ifsetlro(ifp0, 0); 946 947 /* commit */ 948 sc->sc_ifidx0 = ifp0->if_index; 949 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 950 if_setlladdr(ifp, LLADDR(ifp0->if_sadl)); 951 952put: 953 if_put(ifp0); 954 return (error); 955} 956 957int 958vlan_del_parent(struct vlan_softc *sc) 959{ 960 struct ifnet *ifp = &sc->sc_if; 961 962 if (ISSET(ifp->if_flags, IFF_RUNNING)) 963 return (EBUSY); 964 965 /* commit */ 966 sc->sc_ifidx0 = 0; 967 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 968 if_setlladdr(ifp, etheranyaddr); 969 970 return (0); 971} 972 973int 974vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr) 975{ 976 struct vlanreq vlr; 977 struct ifreq req; 978 struct if_parent parent; 979 980 int error; 981 982 error = suser(curproc); 983 if (error != 0) 984 return (error); 985 986 error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); 987 if (error != 0) 988 return (error); 989 990 if (vlr.vlr_parent[0] == '\0') 991 return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr)); 992 993 memset(&req, 0, sizeof(req)); 994 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 995 req.ifr_vnetid = vlr.vlr_tag; 996 997 error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req); 998 if (error != 0) 999 return (error); 1000 1001 memset(&parent, 0, sizeof(parent)); 1002 memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name)); 1003 memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent)); 1004 error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent); 1005 if (error != 0) 1006 return (error); 1007 1008 memset(&req, 0, sizeof(req)); 1009 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 1010 SET(ifp->if_flags, IFF_UP); 1011 return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req)); 1012} 1013 1014int 1015vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr) 1016{ 1017 struct vlan_softc *sc = ifp->if_softc; 1018 struct vlanreq vlr; 1019 struct ifnet *p; 1020 1021 memset(&vlr, 0, sizeof(vlr)); 1022 p = if_get(sc->sc_ifidx0); 1023 if (p != NULL) 1024 memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent)); 1025 if_put(p); 1026 1027 vlr.vlr_tag = sc->sc_tag; 1028 1029 return (copyout(&vlr, ifr->ifr_data, sizeof(vlr))); 1030} 1031 1032/* 1033 * do a quick check of up and running vlans for existing configurations. 1034 * 1035 * NOTE: this does allow the same config on down vlans, but vlan_up() 1036 * will catch them. 1037 */ 1038int 1039vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag) 1040{ 1041 int error = 0; 1042 1043 error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR); 1044 if (error != 0) 1045 return (error); 1046 1047 error = vlan_inuse_locked(type, ifidx, tag); 1048 1049 rw_exit(&vlan_tagh_lk); 1050 1051 return (error); 1052} 1053 1054int 1055vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag) 1056{ 1057 struct vlan_list *tagh, *list; 1058 struct vlan_softc *sc; 1059 1060 tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 1061 list = &tagh[TAG_HASH(tag)]; 1062 1063 SMR_SLIST_FOREACH_LOCKED(sc, list, sc_list) { 1064 if (sc->sc_tag == tag && 1065 sc->sc_type == type && /* wat */ 1066 sc->sc_ifidx0 == ifidx) 1067 return (EADDRINUSE); 1068 } 1069 1070 return (0); 1071} 1072 1073int 1074vlan_multi_add(struct vlan_softc *sc, struct ifreq *ifr) 1075{ 1076 struct ifnet *ifp0; 1077 struct vlan_mc_entry *mc; 1078 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1079 int error; 1080 1081 error = ether_addmulti(ifr, &sc->sc_ac); 1082 if (error != ENETRESET) 1083 return (error); 1084 1085 /* 1086 * This is new multicast address. We have to tell parent 1087 * about it. Also, remember this multicast address so that 1088 * we can delete them on unconfigure. 1089 */ 1090 if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) { 1091 error = ENOMEM; 1092 goto alloc_failed; 1093 } 1094 1095 /* 1096 * As ether_addmulti() returns ENETRESET, following two 1097 * statement shouldn't fail. 1098 */ 1099 (void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 1100 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, mc->mc_enm); 1101 memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); 1102 LIST_INSERT_HEAD(&sc->sc_mc_listhead, mc, mc_entries); 1103 1104 ifp0 = if_get(sc->sc_ifidx0); 1105 error = (ifp0 == NULL) ? 0 : 1106 (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr); 1107 if_put(ifp0); 1108 1109 if (error != 0) 1110 goto ioctl_failed; 1111 1112 return (error); 1113 1114 ioctl_failed: 1115 LIST_REMOVE(mc, mc_entries); 1116 free(mc, M_DEVBUF, sizeof(*mc)); 1117 alloc_failed: 1118 (void)ether_delmulti(ifr, &sc->sc_ac); 1119 1120 return (error); 1121} 1122 1123int 1124vlan_multi_del(struct vlan_softc *sc, struct ifreq *ifr) 1125{ 1126 struct ifnet *ifp0; 1127 struct ether_multi *enm; 1128 struct vlan_mc_entry *mc; 1129 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1130 int error; 1131 1132 /* 1133 * Find a key to lookup vlan_mc_entry. We have to do this 1134 * before calling ether_delmulti for obvious reason. 1135 */ 1136 if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0) 1137 return (error); 1138 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, enm); 1139 if (enm == NULL) 1140 return (EINVAL); 1141 1142 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1143 if (mc->mc_enm == enm) 1144 break; 1145 } 1146 1147 /* We won't delete entries we didn't add */ 1148 if (mc == NULL) 1149 return (EINVAL); 1150 1151 error = ether_delmulti(ifr, &sc->sc_ac); 1152 if (error != ENETRESET) 1153 return (error); 1154 1155 if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING)) 1156 goto forget; 1157 1158 ifp0 = if_get(sc->sc_ifidx0); 1159 error = (ifp0 == NULL) ? 0 : 1160 (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr); 1161 if_put(ifp0); 1162 1163 if (error != 0) { 1164 (void)ether_addmulti(ifr, &sc->sc_ac); 1165 return (error); 1166 } 1167 1168forget: 1169 /* forget about this address */ 1170 LIST_REMOVE(mc, mc_entries); 1171 free(mc, M_DEVBUF, sizeof(*mc)); 1172 1173 return (0); 1174} 1175 1176int 1177vlan_media_get(struct vlan_softc *sc, struct ifreq *ifr) 1178{ 1179 struct ifnet *ifp0; 1180 int error; 1181 1182 ifp0 = if_get(sc->sc_ifidx0); 1183 error = (ifp0 == NULL) ? ENOTTY : 1184 (*ifp0->if_ioctl)(ifp0, SIOCGIFMEDIA, (caddr_t)ifr); 1185 if_put(ifp0); 1186 1187 return (error); 1188} 1189 1190void 1191vlan_multi_apply(struct vlan_softc *sc, struct ifnet *ifp0, u_long cmd) 1192{ 1193 struct vlan_mc_entry *mc; 1194 union { 1195 struct ifreq ifreq; 1196 struct { 1197 char ifr_name[IFNAMSIZ]; 1198 struct sockaddr_storage ifr_ss; 1199 } ifreq_storage; 1200 } ifreq; 1201 struct ifreq *ifr = &ifreq.ifreq; 1202 1203 memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ); 1204 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1205 memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); 1206 1207 (void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr); 1208 } 1209} 1210 1211void 1212vlan_multi_free(struct vlan_softc *sc) 1213{ 1214 struct vlan_mc_entry *mc; 1215 1216 while ((mc = LIST_FIRST(&sc->sc_mc_listhead)) != NULL) { 1217 LIST_REMOVE(mc, mc_entries); 1218 free(mc, M_DEVBUF, sizeof(*mc)); 1219 } 1220} 1221