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