1 /* $OpenBSD: if_vlan.c,v 1.204 2020/07/22 01:30:54 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 #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_enqueue(struct ifnet *, struct mbuf *); 123 void vlan_start(struct ifqueue *ifq); 124 int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); 125 126 int vlan_up(struct vlan_softc *); 127 int vlan_down(struct vlan_softc *); 128 129 void vlan_ifdetach(void *); 130 void vlan_link_hook(void *); 131 void vlan_link_state(struct vlan_softc *, u_char, uint64_t); 132 133 int vlan_set_vnetid(struct vlan_softc *, uint16_t); 134 int vlan_set_parent(struct vlan_softc *, const char *); 135 int vlan_del_parent(struct vlan_softc *); 136 int vlan_inuse(uint16_t, unsigned int, uint16_t); 137 int vlan_inuse_locked(uint16_t, unsigned int, uint16_t); 138 139 int vlan_multi_add(struct vlan_softc *, struct ifreq *); 140 int vlan_multi_del(struct vlan_softc *, struct ifreq *); 141 void vlan_multi_apply(struct vlan_softc *, struct ifnet *, u_long); 142 void vlan_multi_free(struct vlan_softc *); 143 144 int vlan_media_get(struct vlan_softc *, struct ifreq *); 145 146 int vlan_iff(struct vlan_softc *); 147 int vlan_setlladdr(struct vlan_softc *, struct ifreq *); 148 149 int vlan_set_compat(struct ifnet *, struct ifreq *); 150 int vlan_get_compat(struct ifnet *, struct ifreq *); 151 152 struct if_clone vlan_cloner = 153 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); 154 struct if_clone svlan_cloner = 155 IF_CLONE_INITIALIZER("svlan", vlan_clone_create, vlan_clone_destroy); 156 157 void 158 vlanattach(int count) 159 { 160 unsigned int i; 161 162 /* Normal VLAN */ 163 vlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*vlan_tagh), 164 M_DEVBUF, M_NOWAIT); 165 if (vlan_tagh == NULL) 166 panic("vlanattach: hashinit"); 167 168 /* Service-VLAN for QinQ/802.1ad provider bridges */ 169 svlan_tagh = mallocarray(TAG_HASH_SIZE, sizeof(*svlan_tagh), 170 M_DEVBUF, M_NOWAIT); 171 if (svlan_tagh == NULL) 172 panic("vlanattach: hashinit"); 173 174 for (i = 0; i < TAG_HASH_SIZE; i++) { 175 SMR_SLIST_INIT(&vlan_tagh[i]); 176 SMR_SLIST_INIT(&svlan_tagh[i]); 177 } 178 179 if_clone_attach(&vlan_cloner); 180 if_clone_attach(&svlan_cloner); 181 } 182 183 int 184 vlan_clone_create(struct if_clone *ifc, int unit) 185 { 186 struct vlan_softc *sc; 187 struct ifnet *ifp; 188 189 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); 190 sc->sc_dead = 0; 191 LIST_INIT(&sc->sc_mc_listhead); 192 task_set(&sc->sc_ltask, vlan_link_hook, sc); 193 task_set(&sc->sc_dtask, vlan_ifdetach, sc); 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 int 228 vlan_clone_destroy(struct ifnet *ifp) 229 { 230 struct vlan_softc *sc = ifp->if_softc; 231 232 NET_LOCK(); 233 sc->sc_dead = 1; 234 235 if (ISSET(ifp->if_flags, IFF_RUNNING)) 236 vlan_down(sc); 237 NET_UNLOCK(); 238 239 ether_ifdetach(ifp); 240 if_detach(ifp); 241 smr_barrier(); 242 refcnt_finalize(&sc->sc_refcnt, "vlanrefs"); 243 vlan_multi_free(sc); 244 free(sc, M_DEVBUF, sizeof(*sc)); 245 246 return (0); 247 } 248 249 void 250 vlan_transmit(struct vlan_softc *sc, struct ifnet *ifp0, struct mbuf *m) 251 { 252 struct ifnet *ifp = &sc->sc_if; 253 int txprio = sc->sc_txprio; 254 uint8_t prio; 255 256 #if NBPFILTER > 0 257 if (ifp->if_bpf) 258 bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT); 259 #endif /* NBPFILTER > 0 */ 260 261 prio = (txprio == IF_HDRPRIO_PACKET) ? 262 m->m_pkthdr.pf.prio : txprio; 263 264 /* IEEE 802.1p has prio 0 and 1 swapped */ 265 if (prio <= 1) 266 prio = !prio; 267 268 /* 269 * If the underlying interface cannot do VLAN tag insertion 270 * itself, create an encapsulation header. 271 */ 272 if ((ifp0->if_capabilities & IFCAP_VLAN_HWTAGGING) && 273 (sc->sc_type == ETHERTYPE_VLAN)) { 274 m->m_pkthdr.ether_vtag = sc->sc_tag + 275 (prio << EVL_PRIO_BITS); 276 m->m_flags |= M_VLANTAG; 277 } else { 278 m = vlan_inject(m, sc->sc_type, sc->sc_tag | 279 (prio << EVL_PRIO_BITS)); 280 if (m == NULL) { 281 counters_inc(ifp->if_counters, ifc_oerrors); 282 return; 283 } 284 } 285 286 if (if_enqueue(ifp0, m)) 287 counters_inc(ifp->if_counters, ifc_oerrors); 288 } 289 290 int 291 vlan_enqueue(struct ifnet *ifp, struct mbuf *m) 292 { 293 struct ifnet *ifp0; 294 struct vlan_softc *sc; 295 int error = 0; 296 297 if (!ifq_is_priq(&ifp->if_snd)) 298 return (if_enqueue_ifq(ifp, m)); 299 300 sc = ifp->if_softc; 301 ifp0 = if_get(sc->sc_ifidx0); 302 303 if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) { 304 m_freem(m); 305 error = ENETDOWN; 306 } else { 307 counters_pkt(ifp->if_counters, 308 ifc_opackets, ifc_obytes, m->m_pkthdr.len); 309 vlan_transmit(sc, ifp0, m); 310 } 311 312 if_put(ifp0); 313 314 return (error); 315 } 316 317 void 318 vlan_start(struct ifqueue *ifq) 319 { 320 struct ifnet *ifp = ifq->ifq_if; 321 struct vlan_softc *sc = ifp->if_softc; 322 struct ifnet *ifp0; 323 struct mbuf *m; 324 325 ifp0 = if_get(sc->sc_ifidx0); 326 if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) { 327 ifq_purge(ifq); 328 goto leave; 329 } 330 331 while ((m = ifq_dequeue(ifq)) != NULL) 332 vlan_transmit(sc, ifp0, m); 333 334 leave: 335 if_put(ifp0); 336 } 337 338 struct mbuf * 339 vlan_inject(struct mbuf *m, uint16_t type, uint16_t tag) 340 { 341 struct ether_vlan_header evh; 342 343 m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&evh); 344 evh.evl_proto = evh.evl_encap_proto; 345 evh.evl_encap_proto = htons(type); 346 evh.evl_tag = htons(tag); 347 m_adj(m, ETHER_HDR_LEN); 348 M_PREPEND(m, sizeof(evh) + ETHER_ALIGN, M_DONTWAIT); 349 if (m == NULL) 350 return (NULL); 351 352 m_adj(m, ETHER_ALIGN); 353 354 m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT); 355 CLR(m->m_flags, M_VLANTAG); 356 357 return (m); 358 } 359 360 struct mbuf * 361 vlan_input(struct ifnet *ifp0, struct mbuf *m) 362 { 363 struct vlan_softc *sc; 364 struct ifnet *ifp; 365 struct ether_vlan_header *evl; 366 struct vlan_list *tagh, *list; 367 uint16_t vtag, tag; 368 uint16_t etype; 369 int rxprio; 370 371 if (m->m_flags & M_VLANTAG) { 372 vtag = m->m_pkthdr.ether_vtag; 373 etype = ETHERTYPE_VLAN; 374 tagh = vlan_tagh; 375 } else { 376 if (m->m_len < sizeof(*evl)) { 377 m = m_pullup(m, sizeof(*evl)); 378 if (m == NULL) 379 return (NULL); 380 } 381 382 evl = mtod(m, struct ether_vlan_header *); 383 vtag = bemtoh16(&evl->evl_tag); 384 etype = bemtoh16(&evl->evl_encap_proto); 385 switch (etype) { 386 case ETHERTYPE_VLAN: 387 tagh = vlan_tagh; 388 break; 389 case ETHERTYPE_QINQ: 390 tagh = svlan_tagh; 391 break; 392 default: 393 panic("%s: unexpected etype 0x%04x", __func__, etype); 394 /* NOTREACHED */ 395 } 396 } 397 398 tag = EVL_VLANOFTAG(vtag); 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) 411 return (m); /* decline, let bridge have a go */ 412 413 ifp = &sc->sc_if; 414 if (!ISSET(ifp->if_flags, IFF_RUNNING)) { 415 m_freem(m); 416 goto leave; 417 } 418 419 /* 420 * Having found a valid vlan interface corresponding to 421 * the given source interface and vlan tag, remove the 422 * encapsulation. 423 */ 424 if (ISSET(m->m_flags, M_VLANTAG)) { 425 CLR(m->m_flags, M_VLANTAG); 426 } else { 427 memmove((caddr_t)evl + EVL_ENCAPLEN, evl, 428 offsetof(struct ether_vlan_header, evl_encap_proto)); 429 m_adj(m, EVL_ENCAPLEN); 430 } 431 432 rxprio = sc->sc_rxprio; 433 switch (rxprio) { 434 case IF_HDRPRIO_PACKET: 435 break; 436 case IF_HDRPRIO_OUTER: 437 m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); 438 /* IEEE 802.1p has prio 0 and 1 swapped */ 439 if (m->m_pkthdr.pf.prio <= 1) 440 m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; 441 break; 442 default: 443 m->m_pkthdr.pf.prio = rxprio; 444 break; 445 } 446 447 if_vinput(ifp, m); 448 leave: 449 refcnt_rele_wake(&sc->sc_refcnt); 450 return (NULL); 451 } 452 453 int 454 vlan_up(struct vlan_softc *sc) 455 { 456 struct vlan_list *tagh, *list; 457 struct ifnet *ifp = &sc->sc_if; 458 struct ifnet *ifp0; 459 int error = 0; 460 unsigned int hardmtu; 461 462 KASSERT(!ISSET(ifp->if_flags, IFF_RUNNING)); 463 464 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 465 list = &tagh[TAG_HASH(sc->sc_tag)]; 466 467 ifp0 = if_get(sc->sc_ifidx0); 468 if (ifp0 == NULL) 469 return (ENXIO); 470 471 /* check vlan will work on top of the parent */ 472 if (ifp0->if_type != IFT_ETHER) { 473 error = EPROTONOSUPPORT; 474 goto put; 475 } 476 477 hardmtu = ifp0->if_hardmtu; 478 if (!ISSET(ifp0->if_capabilities, IFCAP_VLAN_MTU)) 479 hardmtu -= EVL_ENCAPLEN; 480 481 if (ifp->if_mtu > hardmtu) { 482 error = ENOBUFS; 483 goto put; 484 } 485 486 /* parent is fine, let's prepare the sc to handle packets */ 487 ifp->if_hardmtu = hardmtu; 488 SET(ifp->if_flags, ifp0->if_flags & IFF_SIMPLEX); 489 490 if (ISSET(sc->sc_flags, IFVF_PROMISC)) { 491 error = ifpromisc(ifp0, 1); 492 if (error != 0) 493 goto scrub; 494 } 495 496 /* 497 * Note: In cases like vio(4) and em(4) where the offsets of the 498 * csum can be freely defined, we could actually do csum offload 499 * for VLAN and QINQ packets. 500 */ 501 if (sc->sc_type != ETHERTYPE_VLAN) { 502 /* 503 * Hardware offload only works with the default VLAN 504 * ethernet type (0x8100). 505 */ 506 ifp->if_capabilities = 0; 507 } else if (ISSET(ifp0->if_capabilities, IFCAP_VLAN_HWTAGGING)) { 508 /* 509 * Chips that can do hardware-assisted VLAN encapsulation, can 510 * calculate the correct checksum for VLAN tagged packets. 511 */ 512 ifp->if_capabilities = ifp0->if_capabilities & IFCAP_CSUM_MASK; 513 } 514 515 /* commit the sc */ 516 error = rw_enter(&vlan_tagh_lk, RW_WRITE | RW_INTR); 517 if (error != 0) 518 goto unpromisc; 519 520 error = vlan_inuse_locked(sc->sc_type, sc->sc_ifidx0, sc->sc_tag); 521 if (error != 0) 522 goto leave; 523 524 SMR_SLIST_INSERT_HEAD_LOCKED(list, sc, sc_list); 525 rw_exit(&vlan_tagh_lk); 526 527 /* Register callback for physical link state changes */ 528 if_linkstatehook_add(ifp0, &sc->sc_ltask); 529 530 /* Register callback if parent wants to unregister */ 531 if_detachhook_add(ifp0, &sc->sc_dtask); 532 533 /* configure the parent to handle packets for this vlan */ 534 vlan_multi_apply(sc, ifp0, SIOCADDMULTI); 535 536 /* we're running now */ 537 SET(ifp->if_flags, IFF_RUNNING); 538 vlan_link_state(sc, ifp0->if_link_state, ifp0->if_baudrate); 539 540 if_put(ifp0); 541 542 return (ENETRESET); 543 544 leave: 545 rw_exit(&vlan_tagh_lk); 546 unpromisc: 547 if (ISSET(sc->sc_flags, IFVF_PROMISC)) 548 (void)ifpromisc(ifp0, 0); /* XXX */ 549 scrub: 550 ifp->if_capabilities = 0; 551 CLR(ifp->if_flags, IFF_SIMPLEX); 552 ifp->if_hardmtu = 0xffff; 553 put: 554 if_put(ifp0); 555 556 return (error); 557 } 558 559 int 560 vlan_down(struct vlan_softc *sc) 561 { 562 struct vlan_list *tagh, *list; 563 struct ifnet *ifp = &sc->sc_if; 564 struct ifnet *ifp0; 565 566 tagh = sc->sc_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 567 list = &tagh[TAG_HASH(sc->sc_tag)]; 568 569 KASSERT(ISSET(ifp->if_flags, IFF_RUNNING)); 570 571 vlan_link_state(sc, LINK_STATE_DOWN, 0); 572 CLR(ifp->if_flags, IFF_RUNNING); 573 574 ifq_barrier(&ifp->if_snd); 575 576 ifp0 = if_get(sc->sc_ifidx0); 577 if (ifp0 != 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