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