1 /* $OpenBSD: if_vlan.c,v 1.218 2023/12/23 10:52:54 bluhm 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 77 struct 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 86 struct 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 105 SMR_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) 114 struct vlan_list *vlan_tagh, *svlan_tagh; 115 struct rwlock vlan_tagh_lk = RWLOCK_INITIALIZER("vlantag"); 116 117 void vlanattach(int count); 118 int vlan_clone_create(struct if_clone *, int); 119 int vlan_clone_destroy(struct ifnet *); 120 121 int vlan_enqueue(struct ifnet *, struct mbuf *); 122 void vlan_start(struct ifqueue *ifq); 123 int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); 124 125 int vlan_up(struct vlan_softc *); 126 int vlan_down(struct vlan_softc *); 127 128 void vlan_ifdetach(void *); 129 void vlan_link_hook(void *); 130 void vlan_link_state(struct vlan_softc *, u_char, uint64_t); 131 132 int vlan_set_vnetid(struct vlan_softc *, uint16_t); 133 int vlan_set_parent(struct vlan_softc *, const char *); 134 int vlan_del_parent(struct vlan_softc *); 135 int vlan_inuse(uint16_t, unsigned int, uint16_t); 136 int vlan_inuse_locked(uint16_t, unsigned int, uint16_t); 137 138 int vlan_multi_add(struct vlan_softc *, struct ifreq *); 139 int vlan_multi_del(struct vlan_softc *, struct ifreq *); 140 void vlan_multi_apply(struct vlan_softc *, struct ifnet *, u_long); 141 void vlan_multi_free(struct vlan_softc *); 142 143 int vlan_media_get(struct vlan_softc *, struct ifreq *); 144 145 int vlan_iff(struct vlan_softc *); 146 int vlan_setlladdr(struct vlan_softc *, struct ifreq *); 147 148 int vlan_set_compat(struct ifnet *, struct ifreq *); 149 int vlan_get_compat(struct ifnet *, struct ifreq *); 150 151 struct if_clone vlan_cloner = 152 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); 153 struct if_clone svlan_cloner = 154 IF_CLONE_INITIALIZER("svlan", vlan_clone_create, vlan_clone_destroy); 155 156 void 157 vlanattach(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 182 int 183 vlan_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 226 int 227 vlan_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 248 void 249 vlan_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 289 int 290 vlan_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 316 void 317 vlan_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 333 leave: 334 if_put(ifp0); 335 } 336 337 struct mbuf * 338 vlan_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 354 struct mbuf * 355 vlan_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 376 struct mbuf * 377 vlan_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); 475 leave: 476 refcnt_rele_wake(&sc->sc_refcnt); 477 return (NULL); 478 } 479 480 int 481 vlan_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 VLAN and 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 /* 536 * Chips that can do hardware-assisted VLAN encapsulation, can 537 * calculate the correct checksum for VLAN tagged packets. 538 */ 539 ifp->if_capabilities = ifp0->if_capabilities & 540 (IFCAP_CSUM_MASK | IFCAP_TSOv4 | IFCAP_TSOv6); 541 } 542 543 /* commit the sc */ 544 error = rw_enter(&vlan_tagh_lk, RW_WRITE | RW_INTR); 545 if (error != 0) 546 goto unpromisc; 547 548 error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, sc->sc_tag); 549 if (error != 0) 550 goto leave; 551 552 SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); 553 rw_exit(&vlan_tagh_lk); 554 555 /* Register callback for physical link state changes */ 556 if_linkstatehook_add(ifp0, &sc->sc_ltask); 557 558 /* Register callback if parent wants to unregister */ 559 if_detachhook_add(ifp0, &sc->sc_dtask); 560 561 /* configure the parent to handle packets for this vlan */ 562 vlan_multi_apply(sc, ifp0, SIOCADDMULTI); 563 564 /* we're running now */ 565 SET(ifp->if_flags, IFF_RUNNING); 566 vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate); 567 568 if_put(ifp0); 569 570 return (ENETRESET); 571 572 leave: 573 rw_exit(&vlan_tagh_lk); 574 unpromisc: 575 if (ISSET(sc->sc_flags, IFVF_PROMISC)) 576 (void)ifpromisc(ifp0, 0); /* XXX */ 577 scrub: 578 ifp->if_capabilities = 0; 579 CLR(ifp->if_flags, IFF_SIMPLEX); 580 ifp->if_hardmtu = 0xffff; 581 put: 582 if_put(ifp0); 583 584 return (error); 585 } 586 587 int 588 vlan_down(struct vlan_softc *sc) 589 { 590 struct vlan_list *tagh, *list; 591 struct ifnet *ifp = &sc->sc_if; 592 struct ifnet *ifp0; 593 594 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 595 list = &tagh[TAG_HASH(sc->sc_tag)]; 596 597 KASSERT(ISSET(ifp->if_flags, IFF_RUNNING)); 598 599 vlan_link_state(sc, LINK_STATE_DOWN, 0); 600 CLR(ifp->if_flags, IFF_RUNNING); 601 602 ifq_barrier(&ifp->if_snd); 603 604 ifp0 = if_get(sc->sc_ifidx0); 605 if (ifp0 != NULL) { 606 if (ISSET(sc->sc_flags, IFVF_PROMISC)) 607 ifpromisc(ifp0, 0); 608 vlan_multi_apply(sc, ifp0, SIOCDELMULTI); 609 if_detachhook_del(ifp0, &sc->sc_dtask); 610 if_linkstatehook_del(ifp0, &sc->sc_ltask); 611 } 612 if_put(ifp0); 613 614 rw_enter_write(&vlan_tagh_lk); 615 SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list); 616 rw_exit_write(&vlan_tagh_lk); 617 618 ifp->if_capabilities = 0; 619 CLR(ifp->if_flags, IFF_SIMPLEX); 620 ifp->if_hardmtu = 0xffff; 621 622 return (0); 623 } 624 625 void 626 vlan_ifdetach(void *v) 627 { 628 struct vlan_softc *sc = v; 629 struct ifnet *ifp = &sc->sc_if; 630 631 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 632 vlan_down(sc); 633 CLR(ifp->if_flags, IFF_UP); 634 } 635 636 sc->sc_ifidx0 = 0; 637 } 638 639 void 640 vlan_link_hook(void *v) 641 { 642 struct vlan_softc *sc = v; 643 struct ifnet *ifp0; 644 645 u_char link = LINK_STATE_DOWN; 646 uint64_t baud = 0; 647 648 ifp0 = if_get(sc->sc_ifidx0); 649 if (ifp0 != NULL) { 650 link = ifp0->if_link_state; 651 baud = ifp0->if_baudrate; 652 } 653 if_put(ifp0); 654 655 vlan_link_state(sc, link, baud); 656 } 657 658 void 659 vlan_link_state(struct vlan_softc *sc, u_char link, uint64_t baud) 660 { 661 if (sc->sc_if.if_link_state == link) 662 return; 663 664 sc->sc_if.if_link_state = link; 665 sc->sc_if.if_baudrate = baud; 666 667 if_link_state_change(&sc->sc_if); 668 } 669 670 int 671 vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 672 { 673 struct vlan_softc *sc = ifp->if_softc; 674 struct ifreq *ifr = (struct ifreq *)data; 675 struct if_parent *parent = (struct if_parent *)data; 676 struct ifnet *ifp0; 677 uint16_t tag; 678 int error = 0; 679 680 if (sc->sc_dead) 681 return (ENXIO); 682 683 switch (cmd) { 684 case SIOCSIFADDR: 685 ifp->if_flags |= IFF_UP; 686 /* FALLTHROUGH */ 687 688 case SIOCSIFFLAGS: 689 if (ISSET(ifp->if_flags, IFF_UP)) { 690 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 691 error = vlan_up(sc); 692 else 693 error = ENETRESET; 694 } else { 695 if (ISSET(ifp->if_flags, IFF_RUNNING)) 696 error = vlan_down(sc); 697 } 698 break; 699 700 case SIOCSVNETID: 701 if (ifr->ifr_vnetid < EVL_VLID_MIN || 702 ifr->ifr_vnetid > EVL_VLID_MAX) { 703 error = EINVAL; 704 break; 705 } 706 707 tag = ifr->ifr_vnetid; 708 if (tag == sc->sc_tag) 709 break; 710 711 error = vlan_set_vnetid(sc, tag); 712 break; 713 714 case SIOCGVNETID: 715 if (sc->sc_tag == EVL_VLID_NULL) 716 error = EADDRNOTAVAIL; 717 else 718 ifr->ifr_vnetid = (int64_t)sc->sc_tag; 719 break; 720 721 case SIOCDVNETID: 722 error = vlan_set_vnetid(sc, 0); 723 break; 724 725 case SIOCSIFPARENT: 726 error = vlan_set_parent(sc, parent->ifp_parent); 727 break; 728 729 case SIOCGIFPARENT: 730 ifp0 = if_get(sc->sc_ifidx0); 731 if (ifp0 == NULL) 732 error = EADDRNOTAVAIL; 733 else { 734 memcpy(parent->ifp_parent, ifp0->if_xname, 735 sizeof(parent->ifp_parent)); 736 } 737 if_put(ifp0); 738 break; 739 740 case SIOCDIFPARENT: 741 error = vlan_del_parent(sc); 742 break; 743 744 case SIOCADDMULTI: 745 error = vlan_multi_add(sc, ifr); 746 break; 747 748 case SIOCDELMULTI: 749 error = vlan_multi_del(sc, ifr); 750 break; 751 752 case SIOCGIFMEDIA: 753 error = vlan_media_get(sc, ifr); 754 break; 755 756 case SIOCSIFMEDIA: 757 error = ENOTTY; 758 break; 759 760 case SIOCSIFLLADDR: 761 error = vlan_setlladdr(sc, ifr); 762 break; 763 764 case SIOCSETVLAN: 765 error = vlan_set_compat(ifp, ifr); 766 break; 767 case SIOCGETVLAN: 768 error = vlan_get_compat(ifp, ifr); 769 break; 770 771 case SIOCSTXHPRIO: 772 error = if_txhprio_l2_check(ifr->ifr_hdrprio); 773 if (error != 0) 774 break; 775 776 sc->sc_txprio = ifr->ifr_hdrprio; 777 break; 778 case SIOCGTXHPRIO: 779 ifr->ifr_hdrprio = sc->sc_txprio; 780 break; 781 782 case SIOCSRXHPRIO: 783 error = if_rxhprio_l2_check(ifr->ifr_hdrprio); 784 if (error != 0) 785 break; 786 787 sc->sc_rxprio = ifr->ifr_hdrprio; 788 break; 789 case SIOCGRXHPRIO: 790 ifr->ifr_hdrprio = sc->sc_rxprio; 791 break; 792 793 default: 794 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 795 break; 796 } 797 798 if (error == ENETRESET) 799 error = vlan_iff(sc); 800 801 return error; 802 } 803 804 int 805 vlan_iff(struct vlan_softc *sc) 806 { 807 struct ifnet *ifp0; 808 int promisc = 0; 809 int error = 0; 810 811 if (ISSET(sc->sc_if.if_flags, IFF_PROMISC) || 812 ISSET(sc->sc_flags, IFVF_LLADDR)) 813 promisc = IFVF_PROMISC; 814 815 if (ISSET(sc->sc_flags, IFVF_PROMISC) == promisc) 816 return (0); 817 818 if (ISSET(sc->sc_if.if_flags, IFF_RUNNING)) { 819 ifp0 = if_get(sc->sc_ifidx0); 820 if (ifp0 != NULL) 821 error = ifpromisc(ifp0, promisc); 822 if_put(ifp0); 823 } 824 825 if (error == 0) { 826 CLR(sc->sc_flags, IFVF_PROMISC); 827 SET(sc->sc_flags, promisc); 828 } 829 830 return (error); 831 } 832 833 int 834 vlan_setlladdr(struct vlan_softc *sc, struct ifreq *ifr) 835 { 836 struct ifnet *ifp = &sc->sc_if; 837 struct ifnet *ifp0; 838 uint8_t lladdr[ETHER_ADDR_LEN]; 839 int flag; 840 841 memcpy(lladdr, ifr->ifr_addr.sa_data, sizeof(lladdr)); 842 843 /* setting the mac addr to 00:00:00:00:00:00 means reset lladdr */ 844 if (memcmp(lladdr, etheranyaddr, sizeof(lladdr)) == 0) { 845 ifp0 = if_get(sc->sc_ifidx0); 846 if (ifp0 != NULL) 847 memcpy(lladdr, LLADDR(ifp0->if_sadl), sizeof(lladdr)); 848 if_put(ifp0); 849 850 flag = 0; 851 } else 852 flag = IFVF_LLADDR; 853 854 if (memcmp(lladdr, LLADDR(ifp->if_sadl), sizeof(lladdr)) == 0 && 855 ISSET(sc->sc_flags, IFVF_LLADDR) == flag) { 856 /* nop */ 857 return (0); 858 } 859 860 /* commit */ 861 if_setlladdr(ifp, lladdr); 862 CLR(sc->sc_flags, IFVF_LLADDR); 863 SET(sc->sc_flags, flag); 864 865 return (ENETRESET); 866 } 867 868 int 869 vlan_set_vnetid(struct vlan_softc *sc, uint16_t tag) 870 { 871 struct ifnet *ifp = &sc->sc_if; 872 struct vlan_list *tagh, *list; 873 u_char link = ifp->if_link_state; 874 uint64_t baud = ifp->if_baudrate; 875 int error; 876 877 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 878 879 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 880 vlan_link_state(sc, LINK_STATE_DOWN, 0); 881 882 error = rw_enter(&vlan_tagh_lk, RW_WRITE); 883 if (error != 0) 884 return (error); 885 886 error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, tag); 887 if (error != 0) 888 goto unlock; 889 890 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 891 list = &tagh[TAG_HASH(sc->sc_tag)]; 892 SMR_SLIST_REMOVE_LOCKED(list, sc, vlan_softc, sc_list); 893 894 sc->sc_tag = tag; 895 896 list = &tagh[TAG_HASH(sc->sc_tag)]; 897 SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); 898 } else 899 sc->sc_tag = tag; 900 901 unlock: 902 rw_exit(&vlan_tagh_lk); 903 904 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 905 vlan_link_state(sc, link, baud); 906 907 return (error); 908 } 909 910 int 911 vlan_set_parent(struct vlan_softc *sc, const char *parent) 912 { 913 struct ifnet *ifp = &sc->sc_if; 914 struct ifnet *ifp0; 915 int error = 0; 916 917 ifp0 = if_unit(parent); 918 if (ifp0 == NULL) 919 return (EINVAL); 920 921 if (ifp0->if_type != IFT_ETHER) { 922 error = EPROTONOSUPPORT; 923 goto put; 924 } 925 926 if (sc->sc_ifidx0 == ifp0->if_index) { 927 /* nop */ 928 goto put; 929 } 930 931 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 932 error = EBUSY; 933 goto put; 934 } 935 936 error = vlan_inuse(sc->sc_type, ifp0->if_index, sc->sc_tag); 937 if (error != 0) 938 goto put; 939 940 if (ether_brport_isset(ifp)) 941 ifsetlro(ifp0, 0); 942 943 /* commit */ 944 sc->sc_ifidx0 = ifp0->if_index; 945 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 946 if_setlladdr(ifp, LLADDR(ifp0->if_sadl)); 947 948 put: 949 if_put(ifp0); 950 return (error); 951 } 952 953 int 954 vlan_del_parent(struct vlan_softc *sc) 955 { 956 struct ifnet *ifp = &sc->sc_if; 957 958 if (ISSET(ifp->if_flags, IFF_RUNNING)) 959 return (EBUSY); 960 961 /* commit */ 962 sc->sc_ifidx0 = 0; 963 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 964 if_setlladdr(ifp, etheranyaddr); 965 966 return (0); 967 } 968 969 int 970 vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr) 971 { 972 struct vlanreq vlr; 973 struct ifreq req; 974 struct if_parent parent; 975 976 int error; 977 978 error = suser(curproc); 979 if (error != 0) 980 return (error); 981 982 error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); 983 if (error != 0) 984 return (error); 985 986 if (vlr.vlr_parent[0] == '\0') 987 return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr)); 988 989 memset(&req, 0, sizeof(req)); 990 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 991 req.ifr_vnetid = vlr.vlr_tag; 992 993 error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req); 994 if (error != 0) 995 return (error); 996 997 memset(&parent, 0, sizeof(parent)); 998 memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name)); 999 memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent)); 1000 error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent); 1001 if (error != 0) 1002 return (error); 1003 1004 memset(&req, 0, sizeof(req)); 1005 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 1006 SET(ifp->if_flags, IFF_UP); 1007 return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req)); 1008 } 1009 1010 int 1011 vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr) 1012 { 1013 struct vlan_softc *sc = ifp->if_softc; 1014 struct vlanreq vlr; 1015 struct ifnet *p; 1016 1017 memset(&vlr, 0, sizeof(vlr)); 1018 p = if_get(sc->sc_ifidx0); 1019 if (p != NULL) 1020 memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent)); 1021 if_put(p); 1022 1023 vlr.vlr_tag = sc->sc_tag; 1024 1025 return (copyout(&vlr, ifr->ifr_data, sizeof(vlr))); 1026 } 1027 1028 /* 1029 * do a quick check of up and running vlans for existing configurations. 1030 * 1031 * NOTE: this does allow the same config on down vlans, but vlan_up() 1032 * will catch them. 1033 */ 1034 int 1035 vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag) 1036 { 1037 int error = 0; 1038 1039 error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR); 1040 if (error != 0) 1041 return (error); 1042 1043 error = vlan_inuse_locked(type, ifidx, tag); 1044 1045 rw_exit(&vlan_tagh_lk); 1046 1047 return (error); 1048 } 1049 1050 int 1051 vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag) 1052 { 1053 struct vlan_list *tagh, *list; 1054 struct vlan_softc *sc; 1055 1056 tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 1057 list = &tagh[TAG_HASH(tag)]; 1058 1059 SMR_SLIST_FOREACH_LOCKED(sc, list, sc_list) { 1060 if (sc->sc_tag == tag && 1061 sc->sc_type == type && /* wat */ 1062 sc->sc_ifidx0 == ifidx) 1063 return (EADDRINUSE); 1064 } 1065 1066 return (0); 1067 } 1068 1069 int 1070 vlan_multi_add(struct vlan_softc *sc, struct ifreq *ifr) 1071 { 1072 struct ifnet *ifp0; 1073 struct vlan_mc_entry *mc; 1074 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1075 int error; 1076 1077 error = ether_addmulti(ifr, &sc->sc_ac); 1078 if (error != ENETRESET) 1079 return (error); 1080 1081 /* 1082 * This is new multicast address. We have to tell parent 1083 * about it. Also, remember this multicast address so that 1084 * we can delete them on unconfigure. 1085 */ 1086 if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) { 1087 error = ENOMEM; 1088 goto alloc_failed; 1089 } 1090 1091 /* 1092 * As ether_addmulti() returns ENETRESET, following two 1093 * statement shouldn't fail. 1094 */ 1095 (void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 1096 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, mc->mc_enm); 1097 memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); 1098 LIST_INSERT_HEAD(&sc->sc_mc_listhead, mc, mc_entries); 1099 1100 ifp0 = if_get(sc->sc_ifidx0); 1101 error = (ifp0 == NULL) ? 0 : 1102 (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr); 1103 if_put(ifp0); 1104 1105 if (error != 0) 1106 goto ioctl_failed; 1107 1108 return (error); 1109 1110 ioctl_failed: 1111 LIST_REMOVE(mc, mc_entries); 1112 free(mc, M_DEVBUF, sizeof(*mc)); 1113 alloc_failed: 1114 (void)ether_delmulti(ifr, &sc->sc_ac); 1115 1116 return (error); 1117 } 1118 1119 int 1120 vlan_multi_del(struct vlan_softc *sc, struct ifreq *ifr) 1121 { 1122 struct ifnet *ifp0; 1123 struct ether_multi *enm; 1124 struct vlan_mc_entry *mc; 1125 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1126 int error; 1127 1128 /* 1129 * Find a key to lookup vlan_mc_entry. We have to do this 1130 * before calling ether_delmulti for obvious reason. 1131 */ 1132 if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0) 1133 return (error); 1134 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, enm); 1135 if (enm == NULL) 1136 return (EINVAL); 1137 1138 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1139 if (mc->mc_enm == enm) 1140 break; 1141 } 1142 1143 /* We won't delete entries we didn't add */ 1144 if (mc == NULL) 1145 return (EINVAL); 1146 1147 error = ether_delmulti(ifr, &sc->sc_ac); 1148 if (error != ENETRESET) 1149 return (error); 1150 1151 if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING)) 1152 goto forget; 1153 1154 ifp0 = if_get(sc->sc_ifidx0); 1155 error = (ifp0 == NULL) ? 0 : 1156 (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr); 1157 if_put(ifp0); 1158 1159 if (error != 0) { 1160 (void)ether_addmulti(ifr, &sc->sc_ac); 1161 return (error); 1162 } 1163 1164 forget: 1165 /* forget about this address */ 1166 LIST_REMOVE(mc, mc_entries); 1167 free(mc, M_DEVBUF, sizeof(*mc)); 1168 1169 return (0); 1170 } 1171 1172 int 1173 vlan_media_get(struct vlan_softc *sc, struct ifreq *ifr) 1174 { 1175 struct ifnet *ifp0; 1176 int error; 1177 1178 ifp0 = if_get(sc->sc_ifidx0); 1179 error = (ifp0 == NULL) ? ENOTTY : 1180 (*ifp0->if_ioctl)(ifp0, SIOCGIFMEDIA, (caddr_t)ifr); 1181 if_put(ifp0); 1182 1183 return (error); 1184 } 1185 1186 void 1187 vlan_multi_apply(struct vlan_softc *sc, struct ifnet *ifp0, u_long cmd) 1188 { 1189 struct vlan_mc_entry *mc; 1190 union { 1191 struct ifreq ifreq; 1192 struct { 1193 char ifr_name[IFNAMSIZ]; 1194 struct sockaddr_storage ifr_ss; 1195 } ifreq_storage; 1196 } ifreq; 1197 struct ifreq *ifr = &ifreq.ifreq; 1198 1199 memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ); 1200 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1201 memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); 1202 1203 (void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr); 1204 } 1205 } 1206 1207 void 1208 vlan_multi_free(struct vlan_softc *sc) 1209 { 1210 struct vlan_mc_entry *mc; 1211 1212 while ((mc = LIST_FIRST(&sc->sc_mc_listhead)) != NULL) { 1213 LIST_REMOVE(mc, mc_entries); 1214 free(mc, M_DEVBUF, sizeof(*mc)); 1215 } 1216 } 1217