1 /* $OpenBSD: if_vlan.c,v 1.209 2021/08/30 14:44:39 jasper 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 NET_ASSERT_LOCKED(); 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 /* commit */ 941 sc->sc_ifidx0 = ifp0->if_index; 942 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 943 if_setlladdr(ifp, LLADDR(ifp0->if_sadl)); 944 945 put: 946 if_put(ifp0); 947 return (error); 948 } 949 950 int 951 vlan_del_parent(struct vlan_softc *sc) 952 { 953 struct ifnet *ifp = &sc->sc_if; 954 955 if (ISSET(ifp->if_flags, IFF_RUNNING)) 956 return (EBUSY); 957 958 /* commit */ 959 sc->sc_ifidx0 = 0; 960 if (!ISSET(sc->sc_flags, IFVF_LLADDR)) 961 if_setlladdr(ifp, etheranyaddr); 962 963 return (0); 964 } 965 966 int 967 vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr) 968 { 969 struct vlanreq vlr; 970 struct ifreq req; 971 struct if_parent parent; 972 973 int error; 974 975 error = suser(curproc); 976 if (error != 0) 977 return (error); 978 979 error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); 980 if (error != 0) 981 return (error); 982 983 if (vlr.vlr_parent[0] == '\0') 984 return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr)); 985 986 memset(&req, 0, sizeof(req)); 987 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 988 req.ifr_vnetid = vlr.vlr_tag; 989 990 error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req); 991 if (error != 0) 992 return (error); 993 994 memset(&parent, 0, sizeof(parent)); 995 memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name)); 996 memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent)); 997 error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent); 998 if (error != 0) 999 return (error); 1000 1001 memset(&req, 0, sizeof(req)); 1002 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 1003 SET(ifp->if_flags, IFF_UP); 1004 return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req)); 1005 } 1006 1007 int 1008 vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr) 1009 { 1010 struct vlan_softc *sc = ifp->if_softc; 1011 struct vlanreq vlr; 1012 struct ifnet *p; 1013 1014 memset(&vlr, 0, sizeof(vlr)); 1015 p = if_get(sc->sc_ifidx0); 1016 if (p != NULL) 1017 memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent)); 1018 if_put(p); 1019 1020 vlr.vlr_tag = sc->sc_tag; 1021 1022 return (copyout(&vlr, ifr->ifr_data, sizeof(vlr))); 1023 } 1024 1025 /* 1026 * do a quick check of up and running vlans for existing configurations. 1027 * 1028 * NOTE: this does allow the same config on down vlans, but vlan_up() 1029 * will catch them. 1030 */ 1031 int 1032 vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag) 1033 { 1034 int error = 0; 1035 1036 error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR); 1037 if (error != 0) 1038 return (error); 1039 1040 error = vlan_inuse_locked(type, ifidx, tag); 1041 1042 rw_exit(&vlan_tagh_lk); 1043 1044 return (error); 1045 } 1046 1047 int 1048 vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag) 1049 { 1050 struct vlan_list *tagh, *list; 1051 struct vlan_softc *sc; 1052 1053 tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 1054 list = &tagh[TAG_HASH(tag)]; 1055 1056 SMR_SLIST_FOREACH_LOCKED(sc, list, sc_list) { 1057 if (sc->sc_tag == tag && 1058 sc->sc_type == type && /* wat */ 1059 sc->sc_ifidx0 == ifidx) 1060 return (EADDRINUSE); 1061 } 1062 1063 return (0); 1064 } 1065 1066 int 1067 vlan_multi_add(struct vlan_softc *sc, struct ifreq *ifr) 1068 { 1069 struct ifnet *ifp0; 1070 struct vlan_mc_entry *mc; 1071 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1072 int error; 1073 1074 error = ether_addmulti(ifr, &sc->sc_ac); 1075 if (error != ENETRESET) 1076 return (error); 1077 1078 /* 1079 * This is new multicast address. We have to tell parent 1080 * about it. Also, remember this multicast address so that 1081 * we can delete them on unconfigure. 1082 */ 1083 if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) { 1084 error = ENOMEM; 1085 goto alloc_failed; 1086 } 1087 1088 /* 1089 * As ether_addmulti() returns ENETRESET, following two 1090 * statement shouldn't fail. 1091 */ 1092 (void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 1093 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, mc->mc_enm); 1094 memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); 1095 LIST_INSERT_HEAD(&sc->sc_mc_listhead, mc, mc_entries); 1096 1097 ifp0 = if_get(sc->sc_ifidx0); 1098 error = (ifp0 == NULL) ? 0 : 1099 (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr); 1100 if_put(ifp0); 1101 1102 if (error != 0) 1103 goto ioctl_failed; 1104 1105 return (error); 1106 1107 ioctl_failed: 1108 LIST_REMOVE(mc, mc_entries); 1109 free(mc, M_DEVBUF, sizeof(*mc)); 1110 alloc_failed: 1111 (void)ether_delmulti(ifr, &sc->sc_ac); 1112 1113 return (error); 1114 } 1115 1116 int 1117 vlan_multi_del(struct vlan_softc *sc, struct ifreq *ifr) 1118 { 1119 struct ifnet *ifp0; 1120 struct ether_multi *enm; 1121 struct vlan_mc_entry *mc; 1122 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1123 int error; 1124 1125 /* 1126 * Find a key to lookup vlan_mc_entry. We have to do this 1127 * before calling ether_delmulti for obvious reason. 1128 */ 1129 if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0) 1130 return (error); 1131 ETHER_LOOKUP_MULTI(addrlo, addrhi, &sc->sc_ac, enm); 1132 if (enm == NULL) 1133 return (EINVAL); 1134 1135 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1136 if (mc->mc_enm == enm) 1137 break; 1138 } 1139 1140 /* We won't delete entries we didn't add */ 1141 if (mc == NULL) 1142 return (EINVAL); 1143 1144 error = ether_delmulti(ifr, &sc->sc_ac); 1145 if (error != ENETRESET) 1146 return (error); 1147 1148 if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING)) 1149 goto forget; 1150 1151 ifp0 = if_get(sc->sc_ifidx0); 1152 error = (ifp0 == NULL) ? 0 : 1153 (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr); 1154 if_put(ifp0); 1155 1156 if (error != 0) { 1157 (void)ether_addmulti(ifr, &sc->sc_ac); 1158 return (error); 1159 } 1160 1161 forget: 1162 /* forget about this address */ 1163 LIST_REMOVE(mc, mc_entries); 1164 free(mc, M_DEVBUF, sizeof(*mc)); 1165 1166 return (0); 1167 } 1168 1169 int 1170 vlan_media_get(struct vlan_softc *sc, struct ifreq *ifr) 1171 { 1172 struct ifnet *ifp0; 1173 int error; 1174 1175 ifp0 = if_get(sc->sc_ifidx0); 1176 error = (ifp0 == NULL) ? ENOTTY : 1177 (*ifp0->if_ioctl)(ifp0, SIOCGIFMEDIA, (caddr_t)ifr); 1178 if_put(ifp0); 1179 1180 return (error); 1181 } 1182 1183 void 1184 vlan_multi_apply(struct vlan_softc *sc, struct ifnet *ifp0, u_long cmd) 1185 { 1186 struct vlan_mc_entry *mc; 1187 union { 1188 struct ifreq ifreq; 1189 struct { 1190 char ifr_name[IFNAMSIZ]; 1191 struct sockaddr_storage ifr_ss; 1192 } ifreq_storage; 1193 } ifreq; 1194 struct ifreq *ifr = &ifreq.ifreq; 1195 1196 memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ); 1197 LIST_FOREACH(mc, &sc->sc_mc_listhead, mc_entries) { 1198 memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); 1199 1200 (void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr); 1201 } 1202 } 1203 1204 void 1205 vlan_multi_free(struct vlan_softc *sc) 1206 { 1207 struct vlan_mc_entry *mc; 1208 1209 while ((mc = LIST_FIRST(&sc->sc_mc_listhead)) != NULL) { 1210 LIST_REMOVE(mc, mc_entries); 1211 free(mc, M_DEVBUF, sizeof(*mc)); 1212 } 1213 } 1214