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