1 /* $OpenBSD: if_vlan.c,v 1.165 2016/05/18 03:46:03 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 "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 tag = ifr->ifr_vnetid; 652 if (tag == ifv->ifv_tag) 653 break; 654 655 if (tag < EVL_VLID_MIN || tag > EVL_VLID_MAX) { 656 error = EINVAL; 657 break; 658 } 659 660 error = vlan_set_vnetid(ifv, tag); 661 break; 662 663 case SIOCGVNETID: 664 if (ifv->ifv_tag == EVL_VLID_NULL) 665 error = EADDRNOTAVAIL; 666 else 667 ifr->ifr_vnetid = (uint32_t)ifv->ifv_tag; 668 break; 669 670 case SIOCDVNETID: 671 error = vlan_set_vnetid(ifv, 0); 672 break; 673 674 case SIOCSIFPARENT: 675 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 676 error = EBUSY; 677 break; 678 } 679 680 ifp0 = ifunit(parent->ifp_parent); 681 if (ifp0 == NULL) { 682 error = EINVAL; 683 break; 684 } 685 686 if (ifv->ifv_ifp0 == ifp0->if_index) { 687 /* nop */ 688 break; 689 } 690 691 if (ifp0->if_type != IFT_ETHER) { 692 error = EPROTONOSUPPORT; 693 break; 694 } 695 696 error = vlan_inuse(ifv->ifv_type, ifp0->if_index, ifv->ifv_tag); 697 if (error != 0) 698 break; 699 700 ifv->ifv_ifp0 = ifp0->if_index; 701 break; 702 703 case SIOCGIFPARENT: 704 ifp0 = if_get(ifv->ifv_ifp0); 705 if (ifp0 == NULL) 706 error = EADDRNOTAVAIL; 707 else { 708 memcpy(parent->ifp_parent, ifp0->if_xname, 709 sizeof(parent->ifp_parent)); 710 } 711 if_put(ifp0); 712 break; 713 714 case SIOCDIFPARENT: 715 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 716 error = EBUSY; 717 break; 718 } 719 720 ifv->ifv_ifp0 = 0; 721 break; 722 723 case SIOCADDMULTI: 724 error = vlan_multi_add(ifv, ifr); 725 break; 726 case SIOCDELMULTI: 727 error = vlan_multi_del(ifv, ifr); 728 break; 729 730 case SIOCSIFLLADDR: 731 error = vlan_setlladdr(ifv, ifr); 732 break; 733 734 case SIOCSETVLAN: 735 error = vlan_set_compat(ifp, ifr); 736 break; 737 case SIOCGETVLAN: 738 error = vlan_get_compat(ifp, ifr); 739 break; 740 741 default: 742 error = ether_ioctl(ifp, &ifv->ifv_ac, cmd, data); 743 break; 744 } 745 746 if (error == ENETRESET) { 747 vlan_iff(ifv); 748 error = 0; 749 } 750 751 return error; 752 } 753 754 int 755 vlan_iff(struct ifvlan *ifv) 756 { 757 struct ifnet *ifp0; 758 int promisc = 0; 759 int error = 0; 760 761 if (ISSET(ifv->ifv_if.if_flags, IFF_PROMISC) || 762 ISSET(ifv->ifv_flags, IFVF_LLADDR)) 763 promisc = IFVF_PROMISC; 764 765 if (ISSET(ifv->ifv_flags, IFVF_PROMISC) == promisc) 766 return (0); 767 768 if (ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) { 769 ifp0 = if_get(ifv->ifv_ifp0); 770 if (ifp0 != NULL) 771 error = ifpromisc(ifp0, promisc); 772 if_put(ifp0); 773 } 774 775 if (error == 0) { 776 CLR(ifv->ifv_flags, IFVF_PROMISC); 777 SET(ifv->ifv_flags, promisc); 778 } 779 780 return (error); 781 } 782 783 int 784 vlan_setlladdr(struct ifvlan *ifv, struct ifreq *ifr) 785 { 786 struct ifnet *ifp = &ifv->ifv_if;; 787 struct ifnet *ifp0; 788 int flag = IFVF_LLADDR; 789 790 /* setting the mac addr to 00:00:00:00:00:00 means reset lladdr */ 791 if (memcmp(ifr->ifr_addr.sa_data, etheranyaddr, ETHER_ADDR_LEN) == 0) 792 flag = 0; 793 794 if (ISSET(ifv->ifv_flags, IFVF_LLADDR) == flag) 795 return (0); 796 797 /* if we're up and the mac is reset, inherit the parents mac */ 798 if (ISSET(ifp->if_flags, IFF_RUNNING) && flag == 0) { 799 ifp0 = if_get(ifv->ifv_ifp0); 800 if (ifp0 != NULL) 801 if_setlladdr(ifp, LLADDR(ifp0->if_sadl)); 802 if_put(ifp0); 803 } 804 805 CLR(ifv->ifv_flags, IFVF_LLADDR); 806 SET(ifv->ifv_flags, flag); 807 808 return (ENETRESET); 809 } 810 811 int 812 vlan_set_vnetid(struct ifvlan *ifv, uint16_t tag) 813 { 814 struct ifnet *ifp = &ifv->ifv_if; 815 SRPL_HEAD(, ifvlan) *tagh, *list; 816 u_char link = ifp->if_link_state; 817 uint64_t baud = ifp->if_baudrate; 818 int error; 819 820 tagh = ifv->ifv_type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 821 822 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 823 vlan_link_state(ifv, LINK_STATE_DOWN, 0); 824 825 error = rw_enter(&vlan_tagh_lk, RW_WRITE); 826 if (error != 0) 827 return (error); 828 829 error = vlan_inuse_locked(ifv->ifv_type, ifv->ifv_ifp0, tag); 830 if (error != 0) 831 goto unlock; 832 833 if (ISSET(ifp->if_flags, IFF_RUNNING)) { 834 list = &tagh[TAG_HASH(ifv->ifv_tag)]; 835 SRPL_REMOVE_LOCKED(&vlan_tagh_rc, list, ifv, ifvlan, ifv_list); 836 837 ifv->ifv_tag = tag; 838 839 list = &tagh[TAG_HASH(ifv->ifv_tag)]; 840 SRPL_INSERT_HEAD_LOCKED(&vlan_tagh_rc, list, ifv, ifv_list); 841 } else 842 ifv->ifv_tag = tag; 843 844 unlock: 845 rw_exit(&vlan_tagh_lk); 846 847 if (ISSET(ifp->if_flags, IFF_RUNNING) && LINK_STATE_IS_UP(link)) 848 vlan_link_state(ifv, link, baud); 849 850 return (error); 851 } 852 853 int 854 vlan_set_compat(struct ifnet *ifp, struct ifreq *ifr) 855 { 856 struct vlanreq vlr; 857 struct ifreq req; 858 struct if_parent parent; 859 860 int error; 861 862 error = suser(curproc, 0); 863 if (error != 0) 864 return (error); 865 866 error = copyin(ifr->ifr_data, &vlr, sizeof(vlr)); 867 if (error != 0) 868 return (error); 869 870 if (vlr.vlr_parent[0] == '\0') 871 return (vlan_ioctl(ifp, SIOCDIFPARENT, (caddr_t)ifr)); 872 873 memset(&req, 0, sizeof(req)); 874 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 875 req.ifr_vnetid = vlr.vlr_tag; 876 877 error = vlan_ioctl(ifp, SIOCSVNETID, (caddr_t)&req); 878 if (error != 0) 879 return (error); 880 881 memset(&parent, 0, sizeof(parent)); 882 memcpy(parent.ifp_name, ifp->if_xname, sizeof(parent.ifp_name)); 883 memcpy(parent.ifp_parent, vlr.vlr_parent, sizeof(parent.ifp_parent)); 884 error = vlan_ioctl(ifp, SIOCSIFPARENT, (caddr_t)&parent); 885 if (error != 0) 886 return (error); 887 888 memset(&req, 0, sizeof(req)); 889 memcpy(req.ifr_name, ifp->if_xname, sizeof(req.ifr_name)); 890 SET(ifp->if_flags, IFF_UP); 891 return (vlan_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&req)); 892 } 893 894 int 895 vlan_get_compat(struct ifnet *ifp, struct ifreq *ifr) 896 { 897 struct ifvlan *ifv = ifp->if_softc; 898 struct vlanreq vlr; 899 struct ifnet *p; 900 901 memset(&vlr, 0, sizeof(vlr)); 902 p = if_get(ifv->ifv_ifp0); 903 if (p != NULL) 904 memcpy(vlr.vlr_parent, p->if_xname, sizeof(vlr.vlr_parent)); 905 if_put(p); 906 907 vlr.vlr_tag = ifv->ifv_tag; 908 909 return (copyout(&vlr, ifr->ifr_data, sizeof(vlr))); 910 } 911 912 /* 913 * do a quick check of up and running vlans for existing configurations. 914 * 915 * NOTE: this does allow the same config on down vlans, but vlan_up() 916 * will catch them. 917 */ 918 int 919 vlan_inuse(uint16_t type, unsigned int ifidx, uint16_t tag) 920 { 921 int error = 0; 922 923 error = rw_enter(&vlan_tagh_lk, RW_READ | RW_INTR); 924 if (error != 0) 925 return (error); 926 927 error = vlan_inuse_locked(type, ifidx, tag); 928 929 rw_exit(&vlan_tagh_lk); 930 931 return (error); 932 } 933 934 int 935 vlan_inuse_locked(uint16_t type, unsigned int ifidx, uint16_t tag) 936 { 937 SRPL_HEAD(, ifvlan) *tagh, *list; 938 struct ifvlan *ifv; 939 940 tagh = type == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; 941 list = &tagh[TAG_HASH(tag)]; 942 943 SRPL_FOREACH_LOCKED(ifv, list, ifv_list) { 944 if (ifv->ifv_tag == tag && 945 ifv->ifv_type == type && /* wat */ 946 ifv->ifv_ifp0 == ifidx) 947 return (EADDRINUSE); 948 } 949 950 return (0); 951 } 952 953 int 954 vlan_multi_add(struct ifvlan *ifv, struct ifreq *ifr) 955 { 956 struct ifnet *ifp0; 957 struct vlan_mc_entry *mc; 958 u_int8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 959 int error; 960 961 error = ether_addmulti(ifr, &ifv->ifv_ac); 962 if (error != ENETRESET) 963 return (error); 964 965 /* 966 * This is new multicast address. We have to tell parent 967 * about it. Also, remember this multicast address so that 968 * we can delete them on unconfigure. 969 */ 970 if ((mc = malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT)) == NULL) { 971 error = ENOMEM; 972 goto alloc_failed; 973 } 974 975 /* 976 * As ether_addmulti() returns ENETRESET, following two 977 * statement shouldn't fail. 978 */ 979 (void)ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 980 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ac, mc->mc_enm); 981 memcpy(&mc->mc_addr, &ifr->ifr_addr, ifr->ifr_addr.sa_len); 982 LIST_INSERT_HEAD(&ifv->vlan_mc_listhead, mc, mc_entries); 983 984 ifp0 = if_get(ifv->ifv_ifp0); 985 error = (ifp0 == NULL) ? 0 : 986 (*ifp0->if_ioctl)(ifp0, SIOCADDMULTI, (caddr_t)ifr); 987 if_put(ifp0); 988 989 if (error != 0) 990 goto ioctl_failed; 991 992 return (error); 993 994 ioctl_failed: 995 LIST_REMOVE(mc, mc_entries); 996 free(mc, M_DEVBUF, sizeof(*mc)); 997 alloc_failed: 998 (void)ether_delmulti(ifr, &ifv->ifv_ac); 999 1000 return (error); 1001 } 1002 1003 int 1004 vlan_multi_del(struct ifvlan *ifv, struct ifreq *ifr) 1005 { 1006 struct ifnet *ifp0; 1007 struct ether_multi *enm; 1008 struct vlan_mc_entry *mc; 1009 u_int8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1010 int error; 1011 1012 /* 1013 * Find a key to lookup vlan_mc_entry. We have to do this 1014 * before calling ether_delmulti for obvious reason. 1015 */ 1016 if ((error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi)) != 0) 1017 return (error); 1018 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ac, enm); 1019 if (enm == NULL) 1020 return (EINVAL); 1021 1022 LIST_FOREACH(mc, &ifv->vlan_mc_listhead, mc_entries) { 1023 if (mc->mc_enm == enm) 1024 break; 1025 } 1026 1027 /* We won't delete entries we didn't add */ 1028 if (mc == NULL) 1029 return (EINVAL); 1030 1031 error = ether_delmulti(ifr, &ifv->ifv_ac); 1032 if (error != ENETRESET) 1033 return (error); 1034 1035 if (!ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) 1036 goto forget; 1037 1038 ifp0 = if_get(ifv->ifv_ifp0); 1039 error = (ifp0 == NULL) ? 0 : 1040 (*ifp0->if_ioctl)(ifp0, SIOCDELMULTI, (caddr_t)ifr); 1041 if_put(ifp0); 1042 1043 if (error != 0) { 1044 (void)ether_addmulti(ifr, &ifv->ifv_ac); 1045 return (error); 1046 } 1047 1048 forget: 1049 /* forget about this address */ 1050 LIST_REMOVE(mc, mc_entries); 1051 free(mc, M_DEVBUF, sizeof(*mc)); 1052 1053 return (0); 1054 } 1055 1056 void 1057 vlan_multi_apply(struct ifvlan *ifv, struct ifnet *ifp0, u_long cmd) 1058 { 1059 struct vlan_mc_entry *mc; 1060 union { 1061 struct ifreq ifreq; 1062 struct { 1063 char ifr_name[IFNAMSIZ]; 1064 struct sockaddr_storage ifr_ss; 1065 } ifreq_storage; 1066 } ifreq; 1067 struct ifreq *ifr = &ifreq.ifreq; 1068 1069 memcpy(ifr->ifr_name, ifp0->if_xname, IFNAMSIZ); 1070 LIST_FOREACH(mc, &ifv->vlan_mc_listhead, mc_entries) { 1071 memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); 1072 1073 (void)(*ifp0->if_ioctl)(ifp0, cmd, (caddr_t)ifr); 1074 } 1075 } 1076 1077 void 1078 vlan_multi_free(struct ifvlan *ifv) 1079 { 1080 struct vlan_mc_entry *mc; 1081 1082 while ((mc = LIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { 1083 LIST_REMOVE(mc, mc_entries); 1084 free(mc, M_DEVBUF, sizeof(*mc)); 1085 } 1086 } 1087