1 /* $NetBSD: if_vlan.c,v 1.91 2016/08/07 17:38:34 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran, and by Jason R. Thorpe of Zembu Labs, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright 1998 Massachusetts Institute of Technology 34 * 35 * Permission to use, copy, modify, and distribute this software and 36 * its documentation for any purpose and without fee is hereby 37 * granted, provided that both the above copyright notice and this 38 * permission notice appear in all copies, that both the above 39 * copyright notice and this permission notice appear in all 40 * supporting documentation, and that the name of M.I.T. not be used 41 * in advertising or publicity pertaining to distribution of the 42 * software without specific, written prior permission. M.I.T. makes 43 * no representations about the suitability of this software for any 44 * purpose. It is provided "as is" without express or implied 45 * warranty. 46 * 47 * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 48 * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 49 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 50 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 51 * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 54 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 55 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 56 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * from FreeBSD: if_vlan.c,v 1.16 2000/03/26 15:21:40 charnier Exp 61 * via OpenBSD: if_vlan.c,v 1.4 2000/05/15 19:15:00 chris Exp 62 */ 63 64 /* 65 * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs. Might be 66 * extended some day to also handle IEEE 802.1P priority tagging. This is 67 * sort of sneaky in the implementation, since we need to pretend to be 68 * enough of an Ethernet implementation to make ARP work. The way we do 69 * this is by telling everyone that we are an Ethernet interface, and then 70 * catch the packets that ether_output() left on our output queue when it 71 * calls if_start(), rewrite them for use by the real outgoing interface, 72 * and ask it to send them. 73 * 74 * TODO: 75 * 76 * - Need some way to notify vlan interfaces when the parent 77 * interface changes MTU. 78 */ 79 80 #include <sys/cdefs.h> 81 __KERNEL_RCSID(0, "$NetBSD: if_vlan.c,v 1.91 2016/08/07 17:38:34 christos Exp $"); 82 83 #ifdef _KERNEL_OPT 84 #include "opt_inet.h" 85 #include "opt_net_mpsafe.h" 86 #endif 87 88 #include <sys/param.h> 89 #include <sys/kernel.h> 90 #include <sys/mbuf.h> 91 #include <sys/queue.h> 92 #include <sys/socket.h> 93 #include <sys/sockio.h> 94 #include <sys/systm.h> 95 #include <sys/proc.h> 96 #include <sys/kauth.h> 97 #include <sys/mutex.h> 98 #include <sys/device.h> 99 #include <sys/module.h> 100 101 #include <net/bpf.h> 102 #include <net/if.h> 103 #include <net/if_dl.h> 104 #include <net/if_types.h> 105 #include <net/if_ether.h> 106 #include <net/if_vlanvar.h> 107 108 #ifdef INET 109 #include <netinet/in.h> 110 #include <netinet/if_inarp.h> 111 #endif 112 #ifdef INET6 113 #include <netinet6/in6_ifattach.h> 114 #endif 115 116 #include "ioconf.h" 117 118 struct vlan_mc_entry { 119 LIST_ENTRY(vlan_mc_entry) mc_entries; 120 /* 121 * A key to identify this entry. The mc_addr below can't be 122 * used since multiple sockaddr may mapped into the same 123 * ether_multi (e.g., AF_UNSPEC). 124 */ 125 union { 126 struct ether_multi *mcu_enm; 127 } mc_u; 128 struct sockaddr_storage mc_addr; 129 }; 130 131 #define mc_enm mc_u.mcu_enm 132 133 struct ifvlan { 134 union { 135 struct ethercom ifvu_ec; 136 } ifv_u; 137 struct ifnet *ifv_p; /* parent interface of this vlan */ 138 struct ifv_linkmib { 139 const struct vlan_multisw *ifvm_msw; 140 int ifvm_encaplen; /* encapsulation length */ 141 int ifvm_mtufudge; /* MTU fudged by this much */ 142 int ifvm_mintu; /* min transmission unit */ 143 uint16_t ifvm_proto; /* encapsulation ethertype */ 144 uint16_t ifvm_tag; /* tag to apply on packets */ 145 } ifv_mib; 146 LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead; 147 LIST_ENTRY(ifvlan) ifv_list; 148 int ifv_flags; 149 }; 150 151 #define IFVF_PROMISC 0x01 /* promiscuous mode enabled */ 152 153 #define ifv_ec ifv_u.ifvu_ec 154 155 #define ifv_if ifv_ec.ec_if 156 157 #define ifv_msw ifv_mib.ifvm_msw 158 #define ifv_encaplen ifv_mib.ifvm_encaplen 159 #define ifv_mtufudge ifv_mib.ifvm_mtufudge 160 #define ifv_mintu ifv_mib.ifvm_mintu 161 #define ifv_tag ifv_mib.ifvm_tag 162 163 struct vlan_multisw { 164 int (*vmsw_addmulti)(struct ifvlan *, struct ifreq *); 165 int (*vmsw_delmulti)(struct ifvlan *, struct ifreq *); 166 void (*vmsw_purgemulti)(struct ifvlan *); 167 }; 168 169 static int vlan_ether_addmulti(struct ifvlan *, struct ifreq *); 170 static int vlan_ether_delmulti(struct ifvlan *, struct ifreq *); 171 static void vlan_ether_purgemulti(struct ifvlan *); 172 173 const struct vlan_multisw vlan_ether_multisw = { 174 vlan_ether_addmulti, 175 vlan_ether_delmulti, 176 vlan_ether_purgemulti, 177 }; 178 179 static int vlan_clone_create(struct if_clone *, int); 180 static int vlan_clone_destroy(struct ifnet *); 181 static int vlan_config(struct ifvlan *, struct ifnet *); 182 static int vlan_ioctl(struct ifnet *, u_long, void *); 183 static void vlan_start(struct ifnet *); 184 static void vlan_unconfig(struct ifnet *); 185 186 /* XXX This should be a hash table with the tag as the basis of the key. */ 187 static LIST_HEAD(, ifvlan) ifv_list; 188 189 static kmutex_t ifv_mtx __cacheline_aligned; 190 191 struct if_clone vlan_cloner = 192 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); 193 194 /* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */ 195 static char vlan_zero_pad_buff[ETHER_MIN_LEN]; 196 197 void 198 vlanattach(int n) 199 { 200 201 /* 202 * Nothing to do here, initialization is handled by the 203 * module initialization code in vlaninit() below). 204 */ 205 } 206 207 static void 208 vlaninit(void) 209 { 210 211 LIST_INIT(&ifv_list); 212 mutex_init(&ifv_mtx, MUTEX_DEFAULT, IPL_NONE); 213 if_clone_attach(&vlan_cloner); 214 } 215 216 static int 217 vlandetach(void) 218 { 219 int error = 0; 220 221 if (!LIST_EMPTY(&ifv_list)) 222 error = EBUSY; 223 224 if (error == 0) { 225 if_clone_detach(&vlan_cloner); 226 mutex_destroy(&ifv_mtx); 227 } 228 229 return error; 230 } 231 232 static void 233 vlan_reset_linkname(struct ifnet *ifp) 234 { 235 236 /* 237 * We start out with a "802.1Q VLAN" type and zero-length 238 * addresses. When we attach to a parent interface, we 239 * inherit its type, address length, address, and data link 240 * type. 241 */ 242 243 ifp->if_type = IFT_L2VLAN; 244 ifp->if_addrlen = 0; 245 ifp->if_dlt = DLT_NULL; 246 if_alloc_sadl(ifp); 247 } 248 249 static int 250 vlan_clone_create(struct if_clone *ifc, int unit) 251 { 252 struct ifvlan *ifv; 253 struct ifnet *ifp; 254 int s; 255 256 ifv = malloc(sizeof(struct ifvlan), M_DEVBUF, M_WAITOK|M_ZERO); 257 ifp = &ifv->ifv_if; 258 LIST_INIT(&ifv->ifv_mc_listhead); 259 260 s = splnet(); 261 LIST_INSERT_HEAD(&ifv_list, ifv, ifv_list); 262 splx(s); 263 264 if_initname(ifp, ifc->ifc_name, unit); 265 ifp->if_softc = ifv; 266 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 267 ifp->if_start = vlan_start; 268 ifp->if_ioctl = vlan_ioctl; 269 IFQ_SET_READY(&ifp->if_snd); 270 271 if_initialize(ifp); 272 vlan_reset_linkname(ifp); 273 if_register(ifp); 274 275 return (0); 276 } 277 278 static int 279 vlan_clone_destroy(struct ifnet *ifp) 280 { 281 struct ifvlan *ifv = ifp->if_softc; 282 int s; 283 284 s = splnet(); 285 LIST_REMOVE(ifv, ifv_list); 286 vlan_unconfig(ifp); 287 if_detach(ifp); 288 splx(s); 289 290 free(ifv, M_DEVBUF); 291 292 return (0); 293 } 294 295 /* 296 * Configure a VLAN interface. Must be called at splnet(). 297 */ 298 static int 299 vlan_config(struct ifvlan *ifv, struct ifnet *p) 300 { 301 struct ifnet *ifp = &ifv->ifv_if; 302 int error; 303 304 if (ifv->ifv_p != NULL) 305 return (EBUSY); 306 307 switch (p->if_type) { 308 case IFT_ETHER: 309 { 310 struct ethercom *ec = (void *) p; 311 312 ifv->ifv_msw = &vlan_ether_multisw; 313 ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN; 314 ifv->ifv_mintu = ETHERMIN; 315 316 if (ec->ec_nvlans == 0) { 317 if ((error = ether_enable_vlan_mtu(p)) >= 0) { 318 if (error) 319 return error; 320 ifv->ifv_mtufudge = 0; 321 } else { 322 /* 323 * Fudge the MTU by the encapsulation size. This 324 * makes us incompatible with strictly compliant 325 * 802.1Q implementations, but allows us to use 326 * the feature with other NetBSD 327 * implementations, which might still be useful. 328 */ 329 ifv->ifv_mtufudge = ifv->ifv_encaplen; 330 } 331 } 332 ec->ec_nvlans++; 333 334 /* 335 * If the parent interface can do hardware-assisted 336 * VLAN encapsulation, then propagate its hardware- 337 * assisted checksumming flags and tcp segmentation 338 * offload. 339 */ 340 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 341 ec->ec_capenable |= ETHERCAP_VLAN_HWTAGGING; 342 ifp->if_capabilities = p->if_capabilities & 343 (IFCAP_TSOv4 | IFCAP_TSOv6 | 344 IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_IPv4_Rx| 345 IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_TCPv4_Rx| 346 IFCAP_CSUM_UDPv4_Tx|IFCAP_CSUM_UDPv4_Rx| 347 IFCAP_CSUM_TCPv6_Tx|IFCAP_CSUM_TCPv6_Rx| 348 IFCAP_CSUM_UDPv6_Tx|IFCAP_CSUM_UDPv6_Rx); 349 } 350 /* 351 * We inherit the parent's Ethernet address. 352 */ 353 ether_ifattach(ifp, CLLADDR(p->if_sadl)); 354 ifp->if_hdrlen = sizeof(struct ether_vlan_header); /* XXX? */ 355 break; 356 } 357 358 default: 359 return (EPROTONOSUPPORT); 360 } 361 362 ifv->ifv_p = p; 363 ifv->ifv_if.if_mtu = p->if_mtu - ifv->ifv_mtufudge; 364 ifv->ifv_if.if_flags = p->if_flags & 365 (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); 366 367 /* 368 * Inherit the if_type from the parent. This allows us 369 * to participate in bridges of that type. 370 */ 371 ifv->ifv_if.if_type = p->if_type; 372 373 return (0); 374 } 375 376 /* 377 * Unconfigure a VLAN interface. Must be called at splnet(). 378 */ 379 static void 380 vlan_unconfig(struct ifnet *ifp) 381 { 382 struct ifvlan *ifv = ifp->if_softc; 383 struct ifnet *p; 384 385 mutex_enter(&ifv_mtx); 386 p = ifv->ifv_p; 387 388 if (p == NULL) { 389 mutex_exit(&ifv_mtx); 390 return; 391 } 392 393 /* 394 * Since the interface is being unconfigured, we need to empty the 395 * list of multicast groups that we may have joined while we were 396 * alive and remove them from the parent's list also. 397 */ 398 (*ifv->ifv_msw->vmsw_purgemulti)(ifv); 399 400 /* Disconnect from parent. */ 401 switch (p->if_type) { 402 case IFT_ETHER: 403 { 404 struct ethercom *ec = (void *)p; 405 if (--ec->ec_nvlans == 0) 406 (void)ether_disable_vlan_mtu(p); 407 408 ether_ifdetach(ifp); 409 /* Restore vlan_ioctl overwritten by ether_ifdetach */ 410 ifp->if_ioctl = vlan_ioctl; 411 vlan_reset_linkname(ifp); 412 break; 413 } 414 415 #ifdef DIAGNOSTIC 416 default: 417 panic("vlan_unconfig: impossible"); 418 #endif 419 } 420 421 ifv->ifv_p = NULL; 422 ifv->ifv_if.if_mtu = 0; 423 ifv->ifv_flags = 0; 424 425 #ifdef INET6 426 /* To delete v6 link local addresses */ 427 in6_ifdetach(ifp); 428 #endif 429 if ((ifp->if_flags & IFF_PROMISC) != 0) 430 ifpromisc(ifp, 0); 431 if_down(ifp); 432 ifp->if_flags &= ~(IFF_UP|IFF_RUNNING); 433 ifp->if_capabilities = 0; 434 435 mutex_exit(&ifv_mtx); 436 } 437 438 /* 439 * Called when a parent interface is detaching; destroy any VLAN 440 * configuration for the parent interface. 441 */ 442 void 443 vlan_ifdetach(struct ifnet *p) 444 { 445 struct ifvlan *ifv; 446 int s; 447 448 s = splnet(); 449 450 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 451 ifv = LIST_NEXT(ifv, ifv_list)) { 452 if (ifv->ifv_p == p) 453 vlan_unconfig(&ifv->ifv_if); 454 } 455 456 splx(s); 457 } 458 459 static int 460 vlan_set_promisc(struct ifnet *ifp) 461 { 462 struct ifvlan *ifv = ifp->if_softc; 463 int error = 0; 464 465 if ((ifp->if_flags & IFF_PROMISC) != 0) { 466 if ((ifv->ifv_flags & IFVF_PROMISC) == 0) { 467 error = ifpromisc(ifv->ifv_p, 1); 468 if (error == 0) 469 ifv->ifv_flags |= IFVF_PROMISC; 470 } 471 } else { 472 if ((ifv->ifv_flags & IFVF_PROMISC) != 0) { 473 error = ifpromisc(ifv->ifv_p, 0); 474 if (error == 0) 475 ifv->ifv_flags &= ~IFVF_PROMISC; 476 } 477 } 478 479 return (error); 480 } 481 482 static int 483 vlan_ioctl(struct ifnet *ifp, u_long cmd, void *data) 484 { 485 struct lwp *l = curlwp; /* XXX */ 486 struct ifvlan *ifv = ifp->if_softc; 487 struct ifaddr *ifa = (struct ifaddr *) data; 488 struct ifreq *ifr = (struct ifreq *) data; 489 struct ifnet *pr; 490 struct ifcapreq *ifcr; 491 struct vlanreq vlr; 492 int s, error = 0; 493 494 s = splnet(); 495 496 switch (cmd) { 497 case SIOCSIFMTU: 498 if (ifv->ifv_p == NULL) 499 error = EINVAL; 500 else if ( 501 ifr->ifr_mtu > (ifv->ifv_p->if_mtu - ifv->ifv_mtufudge) || 502 ifr->ifr_mtu < (ifv->ifv_mintu - ifv->ifv_mtufudge)) 503 error = EINVAL; 504 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 505 error = 0; 506 break; 507 508 case SIOCSETVLAN: 509 if ((error = kauth_authorize_network(l->l_cred, 510 KAUTH_NETWORK_INTERFACE, 511 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 512 NULL)) != 0) 513 break; 514 if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0) 515 break; 516 if (vlr.vlr_parent[0] == '\0') { 517 if (ifv->ifv_p != NULL && 518 (ifp->if_flags & IFF_PROMISC) != 0) 519 error = ifpromisc(ifv->ifv_p, 0); 520 vlan_unconfig(ifp); 521 break; 522 } 523 if (vlr.vlr_tag != EVL_VLANOFTAG(vlr.vlr_tag)) { 524 error = EINVAL; /* check for valid tag */ 525 break; 526 } 527 if ((pr = ifunit(vlr.vlr_parent)) == 0) { 528 error = ENOENT; 529 break; 530 } 531 if ((error = vlan_config(ifv, pr)) != 0) 532 break; 533 ifv->ifv_tag = vlr.vlr_tag; 534 ifp->if_flags |= IFF_RUNNING; 535 536 /* Update promiscuous mode, if necessary. */ 537 vlan_set_promisc(ifp); 538 break; 539 540 case SIOCGETVLAN: 541 memset(&vlr, 0, sizeof(vlr)); 542 if (ifv->ifv_p != NULL) { 543 snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), "%s", 544 ifv->ifv_p->if_xname); 545 vlr.vlr_tag = ifv->ifv_tag; 546 } 547 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); 548 break; 549 550 case SIOCSIFFLAGS: 551 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 552 break; 553 /* 554 * For promiscuous mode, we enable promiscuous mode on 555 * the parent if we need promiscuous on the VLAN interface. 556 */ 557 if (ifv->ifv_p != NULL) 558 error = vlan_set_promisc(ifp); 559 break; 560 561 case SIOCADDMULTI: 562 error = (ifv->ifv_p != NULL) ? 563 (*ifv->ifv_msw->vmsw_addmulti)(ifv, ifr) : EINVAL; 564 break; 565 566 case SIOCDELMULTI: 567 error = (ifv->ifv_p != NULL) ? 568 (*ifv->ifv_msw->vmsw_delmulti)(ifv, ifr) : EINVAL; 569 break; 570 571 case SIOCSIFCAP: 572 ifcr = data; 573 /* make sure caps are enabled on parent */ 574 if ((ifv->ifv_p->if_capenable & ifcr->ifcr_capenable) != 575 ifcr->ifcr_capenable) { 576 error = EINVAL; 577 break; 578 } 579 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 580 error = 0; 581 break; 582 case SIOCINITIFADDR: 583 if (ifv->ifv_p == NULL) { 584 error = EINVAL; 585 break; 586 } 587 588 ifp->if_flags |= IFF_UP; 589 #ifdef INET 590 if (ifa->ifa_addr->sa_family == AF_INET) 591 arp_ifinit(ifp, ifa); 592 #endif 593 break; 594 595 default: 596 error = ether_ioctl(ifp, cmd, data); 597 } 598 599 splx(s); 600 601 return (error); 602 } 603 604 static int 605 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr) 606 { 607 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr); 608 struct vlan_mc_entry *mc; 609 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 610 int error; 611 612 if (sa->sa_len > sizeof(struct sockaddr_storage)) 613 return (EINVAL); 614 615 error = ether_addmulti(sa, &ifv->ifv_ec); 616 if (error != ENETRESET) 617 return (error); 618 619 /* 620 * This is new multicast address. We have to tell parent 621 * about it. Also, remember this multicast address so that 622 * we can delete them on unconfigure. 623 */ 624 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT); 625 if (mc == NULL) { 626 error = ENOMEM; 627 goto alloc_failed; 628 } 629 630 /* 631 * As ether_addmulti() returns ENETRESET, following two 632 * statement shouldn't fail. 633 */ 634 (void)ether_multiaddr(sa, addrlo, addrhi); 635 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, mc->mc_enm); 636 memcpy(&mc->mc_addr, sa, sa->sa_len); 637 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries); 638 639 error = if_mcast_op(ifv->ifv_p, SIOCADDMULTI, sa); 640 if (error != 0) 641 goto ioctl_failed; 642 return (error); 643 644 ioctl_failed: 645 LIST_REMOVE(mc, mc_entries); 646 free(mc, M_DEVBUF); 647 alloc_failed: 648 (void)ether_delmulti(sa, &ifv->ifv_ec); 649 return (error); 650 } 651 652 static int 653 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr) 654 { 655 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr); 656 struct ether_multi *enm; 657 struct vlan_mc_entry *mc; 658 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 659 int error; 660 661 /* 662 * Find a key to lookup vlan_mc_entry. We have to do this 663 * before calling ether_delmulti for obvious reason. 664 */ 665 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0) 666 return (error); 667 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, enm); 668 669 error = ether_delmulti(sa, &ifv->ifv_ec); 670 if (error != ENETRESET) 671 return (error); 672 673 /* We no longer use this multicast address. Tell parent so. */ 674 error = if_mcast_op(ifv->ifv_p, SIOCDELMULTI, sa); 675 if (error == 0) { 676 /* And forget about this address. */ 677 for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; 678 mc = LIST_NEXT(mc, mc_entries)) { 679 if (mc->mc_enm == enm) { 680 LIST_REMOVE(mc, mc_entries); 681 free(mc, M_DEVBUF); 682 break; 683 } 684 } 685 KASSERT(mc != NULL); 686 } else 687 (void)ether_addmulti(sa, &ifv->ifv_ec); 688 return (error); 689 } 690 691 /* 692 * Delete any multicast address we have asked to add from parent 693 * interface. Called when the vlan is being unconfigured. 694 */ 695 static void 696 vlan_ether_purgemulti(struct ifvlan *ifv) 697 { 698 struct ifnet *ifp = ifv->ifv_p; /* Parent. */ 699 struct vlan_mc_entry *mc; 700 701 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { 702 (void)if_mcast_op(ifp, SIOCDELMULTI, 703 (const struct sockaddr *)&mc->mc_addr); 704 LIST_REMOVE(mc, mc_entries); 705 free(mc, M_DEVBUF); 706 } 707 } 708 709 static void 710 vlan_start(struct ifnet *ifp) 711 { 712 struct ifvlan *ifv = ifp->if_softc; 713 struct ifnet *p = ifv->ifv_p; 714 struct ethercom *ec = (void *) ifv->ifv_p; 715 struct mbuf *m; 716 int error; 717 718 #ifndef NET_MPSAFE 719 KASSERT(KERNEL_LOCKED_P()); 720 #endif 721 722 ifp->if_flags |= IFF_OACTIVE; 723 724 for (;;) { 725 IFQ_DEQUEUE(&ifp->if_snd, m); 726 if (m == NULL) 727 break; 728 729 #ifdef ALTQ 730 /* 731 * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE if defined. 732 */ 733 KERNEL_LOCK(1, NULL); 734 /* 735 * If ALTQ is enabled on the parent interface, do 736 * classification; the queueing discipline might 737 * not require classification, but might require 738 * the address family/header pointer in the pktattr. 739 */ 740 if (ALTQ_IS_ENABLED(&p->if_snd)) { 741 switch (p->if_type) { 742 case IFT_ETHER: 743 altq_etherclassify(&p->if_snd, m); 744 break; 745 #ifdef DIAGNOSTIC 746 default: 747 panic("vlan_start: impossible (altq)"); 748 #endif 749 } 750 } 751 KERNEL_UNLOCK_ONE(NULL); 752 #endif /* ALTQ */ 753 754 bpf_mtap(ifp, m); 755 /* 756 * If the parent can insert the tag itself, just mark 757 * the tag in the mbuf header. 758 */ 759 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 760 struct m_tag *mtag; 761 762 mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), 763 M_NOWAIT); 764 if (mtag == NULL) { 765 ifp->if_oerrors++; 766 m_freem(m); 767 continue; 768 } 769 *(u_int *)(mtag + 1) = ifv->ifv_tag; 770 m_tag_prepend(m, mtag); 771 } else { 772 /* 773 * insert the tag ourselves 774 */ 775 M_PREPEND(m, ifv->ifv_encaplen, M_DONTWAIT); 776 if (m == NULL) { 777 printf("%s: unable to prepend encap header", 778 ifv->ifv_p->if_xname); 779 ifp->if_oerrors++; 780 continue; 781 } 782 783 switch (p->if_type) { 784 case IFT_ETHER: 785 { 786 struct ether_vlan_header *evl; 787 788 if (m->m_len < sizeof(struct ether_vlan_header)) 789 m = m_pullup(m, 790 sizeof(struct ether_vlan_header)); 791 if (m == NULL) { 792 printf("%s: unable to pullup encap " 793 "header", ifv->ifv_p->if_xname); 794 ifp->if_oerrors++; 795 continue; 796 } 797 798 /* 799 * Transform the Ethernet header into an 800 * Ethernet header with 802.1Q encapsulation. 801 */ 802 memmove(mtod(m, void *), 803 mtod(m, char *) + ifv->ifv_encaplen, 804 sizeof(struct ether_header)); 805 evl = mtod(m, struct ether_vlan_header *); 806 evl->evl_proto = evl->evl_encap_proto; 807 evl->evl_encap_proto = htons(ETHERTYPE_VLAN); 808 evl->evl_tag = htons(ifv->ifv_tag); 809 810 /* 811 * To cater for VLAN-aware layer 2 ethernet 812 * switches which may need to strip the tag 813 * before forwarding the packet, make sure 814 * the packet+tag is at least 68 bytes long. 815 * This is necessary because our parent will 816 * only pad to 64 bytes (ETHER_MIN_LEN) and 817 * some switches will not pad by themselves 818 * after deleting a tag. 819 */ 820 if (m->m_pkthdr.len < 821 (ETHER_MIN_LEN - ETHER_CRC_LEN + 822 ETHER_VLAN_ENCAP_LEN)) { 823 m_copyback(m, m->m_pkthdr.len, 824 (ETHER_MIN_LEN - ETHER_CRC_LEN + 825 ETHER_VLAN_ENCAP_LEN) - 826 m->m_pkthdr.len, 827 vlan_zero_pad_buff); 828 } 829 break; 830 } 831 832 #ifdef DIAGNOSTIC 833 default: 834 panic("vlan_start: impossible"); 835 #endif 836 } 837 } 838 839 /* 840 * Send it, precisely as the parent's output routine 841 * would have. We are already running at splnet. 842 */ 843 if ((p->if_flags & IFF_RUNNING) != 0) { 844 error = if_transmit_lock(p, m); 845 if (error) { 846 /* mbuf is already freed */ 847 ifp->if_oerrors++; 848 continue; 849 } 850 } 851 852 ifp->if_opackets++; 853 } 854 855 ifp->if_flags &= ~IFF_OACTIVE; 856 } 857 858 /* 859 * Given an Ethernet frame, find a valid vlan interface corresponding to the 860 * given source interface and tag, then run the real packet through the 861 * parent's input routine. 862 */ 863 void 864 vlan_input(struct ifnet *ifp, struct mbuf *m) 865 { 866 struct ifvlan *ifv; 867 u_int tag; 868 struct m_tag *mtag; 869 870 mtag = m_tag_find(m, PACKET_TAG_VLAN, NULL); 871 if (mtag != NULL) { 872 /* m contains a normal ethernet frame, the tag is in mtag */ 873 tag = EVL_VLANOFTAG(*(u_int *)(mtag + 1)); 874 m_tag_delete(m, mtag); 875 } else { 876 switch (ifp->if_type) { 877 case IFT_ETHER: 878 { 879 struct ether_vlan_header *evl; 880 881 if (m->m_len < sizeof(struct ether_vlan_header) && 882 (m = m_pullup(m, 883 sizeof(struct ether_vlan_header))) == NULL) { 884 printf("%s: no memory for VLAN header, " 885 "dropping packet.\n", ifp->if_xname); 886 return; 887 } 888 evl = mtod(m, struct ether_vlan_header *); 889 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN); 890 891 tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); 892 893 /* 894 * Restore the original ethertype. We'll remove 895 * the encapsulation after we've found the vlan 896 * interface corresponding to the tag. 897 */ 898 evl->evl_encap_proto = evl->evl_proto; 899 break; 900 } 901 902 default: 903 tag = (u_int) -1; /* XXX GCC */ 904 #ifdef DIAGNOSTIC 905 panic("vlan_input: impossible"); 906 #endif 907 } 908 } 909 910 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 911 ifv = LIST_NEXT(ifv, ifv_list)) 912 if (ifp == ifv->ifv_p && tag == ifv->ifv_tag) 913 break; 914 915 if (ifv == NULL || 916 (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != 917 (IFF_UP|IFF_RUNNING)) { 918 m_freem(m); 919 ifp->if_noproto++; 920 return; 921 } 922 923 /* 924 * Now, remove the encapsulation header. The original 925 * header has already been fixed up above. 926 */ 927 if (mtag == NULL) { 928 memmove(mtod(m, char *) + ifv->ifv_encaplen, 929 mtod(m, void *), sizeof(struct ether_header)); 930 m_adj(m, ifv->ifv_encaplen); 931 } 932 933 m_set_rcvif(m, &ifv->ifv_if); 934 ifv->ifv_if.if_ipackets++; 935 936 bpf_mtap(&ifv->ifv_if, m); 937 938 m->m_flags &= ~M_PROMISC; 939 if_input(&ifv->ifv_if, m); 940 } 941 942 /* 943 * Module infrastructure 944 */ 945 #include "if_module.h" 946 947 IF_MODULE(MODULE_CLASS_DRIVER, vlan, "") 948