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