1 /* $NetBSD: if_vlan.c,v 1.92 2016/11/28 00:39:03 joerg 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.92 2016/11/28 00:39:03 joerg 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 == NULL) { 575 error = EINVAL; 576 break; 577 } 578 if ((ifv->ifv_p->if_capenable & ifcr->ifcr_capenable) != 579 ifcr->ifcr_capenable) { 580 error = EINVAL; 581 break; 582 } 583 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 584 error = 0; 585 break; 586 case SIOCINITIFADDR: 587 if (ifv->ifv_p == NULL) { 588 error = EINVAL; 589 break; 590 } 591 592 ifp->if_flags |= IFF_UP; 593 #ifdef INET 594 if (ifa->ifa_addr->sa_family == AF_INET) 595 arp_ifinit(ifp, ifa); 596 #endif 597 break; 598 599 default: 600 error = ether_ioctl(ifp, cmd, data); 601 } 602 603 splx(s); 604 605 return (error); 606 } 607 608 static int 609 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr) 610 { 611 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr); 612 struct vlan_mc_entry *mc; 613 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 614 int error; 615 616 if (sa->sa_len > sizeof(struct sockaddr_storage)) 617 return (EINVAL); 618 619 error = ether_addmulti(sa, &ifv->ifv_ec); 620 if (error != ENETRESET) 621 return (error); 622 623 /* 624 * This is new multicast address. We have to tell parent 625 * about it. Also, remember this multicast address so that 626 * we can delete them on unconfigure. 627 */ 628 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT); 629 if (mc == NULL) { 630 error = ENOMEM; 631 goto alloc_failed; 632 } 633 634 /* 635 * As ether_addmulti() returns ENETRESET, following two 636 * statement shouldn't fail. 637 */ 638 (void)ether_multiaddr(sa, addrlo, addrhi); 639 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, mc->mc_enm); 640 memcpy(&mc->mc_addr, sa, sa->sa_len); 641 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries); 642 643 error = if_mcast_op(ifv->ifv_p, SIOCADDMULTI, sa); 644 if (error != 0) 645 goto ioctl_failed; 646 return (error); 647 648 ioctl_failed: 649 LIST_REMOVE(mc, mc_entries); 650 free(mc, M_DEVBUF); 651 alloc_failed: 652 (void)ether_delmulti(sa, &ifv->ifv_ec); 653 return (error); 654 } 655 656 static int 657 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr) 658 { 659 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr); 660 struct ether_multi *enm; 661 struct vlan_mc_entry *mc; 662 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 663 int error; 664 665 /* 666 * Find a key to lookup vlan_mc_entry. We have to do this 667 * before calling ether_delmulti for obvious reason. 668 */ 669 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0) 670 return (error); 671 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, enm); 672 673 error = ether_delmulti(sa, &ifv->ifv_ec); 674 if (error != ENETRESET) 675 return (error); 676 677 /* We no longer use this multicast address. Tell parent so. */ 678 error = if_mcast_op(ifv->ifv_p, SIOCDELMULTI, sa); 679 if (error == 0) { 680 /* And forget about this address. */ 681 for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; 682 mc = LIST_NEXT(mc, mc_entries)) { 683 if (mc->mc_enm == enm) { 684 LIST_REMOVE(mc, mc_entries); 685 free(mc, M_DEVBUF); 686 break; 687 } 688 } 689 KASSERT(mc != NULL); 690 } else 691 (void)ether_addmulti(sa, &ifv->ifv_ec); 692 return (error); 693 } 694 695 /* 696 * Delete any multicast address we have asked to add from parent 697 * interface. Called when the vlan is being unconfigured. 698 */ 699 static void 700 vlan_ether_purgemulti(struct ifvlan *ifv) 701 { 702 struct ifnet *ifp = ifv->ifv_p; /* Parent. */ 703 struct vlan_mc_entry *mc; 704 705 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { 706 (void)if_mcast_op(ifp, SIOCDELMULTI, 707 (const struct sockaddr *)&mc->mc_addr); 708 LIST_REMOVE(mc, mc_entries); 709 free(mc, M_DEVBUF); 710 } 711 } 712 713 static void 714 vlan_start(struct ifnet *ifp) 715 { 716 struct ifvlan *ifv = ifp->if_softc; 717 struct ifnet *p = ifv->ifv_p; 718 struct ethercom *ec = (void *) ifv->ifv_p; 719 struct mbuf *m; 720 int error; 721 722 #ifndef NET_MPSAFE 723 KASSERT(KERNEL_LOCKED_P()); 724 #endif 725 726 ifp->if_flags |= IFF_OACTIVE; 727 728 for (;;) { 729 IFQ_DEQUEUE(&ifp->if_snd, m); 730 if (m == NULL) 731 break; 732 733 #ifdef ALTQ 734 /* 735 * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE if defined. 736 */ 737 KERNEL_LOCK(1, NULL); 738 /* 739 * If ALTQ is enabled on the parent interface, do 740 * classification; the queueing discipline might 741 * not require classification, but might require 742 * the address family/header pointer in the pktattr. 743 */ 744 if (ALTQ_IS_ENABLED(&p->if_snd)) { 745 switch (p->if_type) { 746 case IFT_ETHER: 747 altq_etherclassify(&p->if_snd, m); 748 break; 749 #ifdef DIAGNOSTIC 750 default: 751 panic("vlan_start: impossible (altq)"); 752 #endif 753 } 754 } 755 KERNEL_UNLOCK_ONE(NULL); 756 #endif /* ALTQ */ 757 758 bpf_mtap(ifp, m); 759 /* 760 * If the parent can insert the tag itself, just mark 761 * the tag in the mbuf header. 762 */ 763 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 764 struct m_tag *mtag; 765 766 mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), 767 M_NOWAIT); 768 if (mtag == NULL) { 769 ifp->if_oerrors++; 770 m_freem(m); 771 continue; 772 } 773 *(u_int *)(mtag + 1) = ifv->ifv_tag; 774 m_tag_prepend(m, mtag); 775 } else { 776 /* 777 * insert the tag ourselves 778 */ 779 M_PREPEND(m, ifv->ifv_encaplen, M_DONTWAIT); 780 if (m == NULL) { 781 printf("%s: unable to prepend encap header", 782 ifv->ifv_p->if_xname); 783 ifp->if_oerrors++; 784 continue; 785 } 786 787 switch (p->if_type) { 788 case IFT_ETHER: 789 { 790 struct ether_vlan_header *evl; 791 792 if (m->m_len < sizeof(struct ether_vlan_header)) 793 m = m_pullup(m, 794 sizeof(struct ether_vlan_header)); 795 if (m == NULL) { 796 printf("%s: unable to pullup encap " 797 "header", ifv->ifv_p->if_xname); 798 ifp->if_oerrors++; 799 continue; 800 } 801 802 /* 803 * Transform the Ethernet header into an 804 * Ethernet header with 802.1Q encapsulation. 805 */ 806 memmove(mtod(m, void *), 807 mtod(m, char *) + ifv->ifv_encaplen, 808 sizeof(struct ether_header)); 809 evl = mtod(m, struct ether_vlan_header *); 810 evl->evl_proto = evl->evl_encap_proto; 811 evl->evl_encap_proto = htons(ETHERTYPE_VLAN); 812 evl->evl_tag = htons(ifv->ifv_tag); 813 814 /* 815 * To cater for VLAN-aware layer 2 ethernet 816 * switches which may need to strip the tag 817 * before forwarding the packet, make sure 818 * the packet+tag is at least 68 bytes long. 819 * This is necessary because our parent will 820 * only pad to 64 bytes (ETHER_MIN_LEN) and 821 * some switches will not pad by themselves 822 * after deleting a tag. 823 */ 824 if (m->m_pkthdr.len < 825 (ETHER_MIN_LEN - ETHER_CRC_LEN + 826 ETHER_VLAN_ENCAP_LEN)) { 827 m_copyback(m, m->m_pkthdr.len, 828 (ETHER_MIN_LEN - ETHER_CRC_LEN + 829 ETHER_VLAN_ENCAP_LEN) - 830 m->m_pkthdr.len, 831 vlan_zero_pad_buff); 832 } 833 break; 834 } 835 836 #ifdef DIAGNOSTIC 837 default: 838 panic("vlan_start: impossible"); 839 #endif 840 } 841 } 842 843 /* 844 * Send it, precisely as the parent's output routine 845 * would have. We are already running at splnet. 846 */ 847 if ((p->if_flags & IFF_RUNNING) != 0) { 848 error = if_transmit_lock(p, m); 849 if (error) { 850 /* mbuf is already freed */ 851 ifp->if_oerrors++; 852 continue; 853 } 854 } 855 856 ifp->if_opackets++; 857 } 858 859 ifp->if_flags &= ~IFF_OACTIVE; 860 } 861 862 /* 863 * Given an Ethernet frame, find a valid vlan interface corresponding to the 864 * given source interface and tag, then run the real packet through the 865 * parent's input routine. 866 */ 867 void 868 vlan_input(struct ifnet *ifp, struct mbuf *m) 869 { 870 struct ifvlan *ifv; 871 u_int tag; 872 struct m_tag *mtag; 873 874 mtag = m_tag_find(m, PACKET_TAG_VLAN, NULL); 875 if (mtag != NULL) { 876 /* m contains a normal ethernet frame, the tag is in mtag */ 877 tag = EVL_VLANOFTAG(*(u_int *)(mtag + 1)); 878 m_tag_delete(m, mtag); 879 } else { 880 switch (ifp->if_type) { 881 case IFT_ETHER: 882 { 883 struct ether_vlan_header *evl; 884 885 if (m->m_len < sizeof(struct ether_vlan_header) && 886 (m = m_pullup(m, 887 sizeof(struct ether_vlan_header))) == NULL) { 888 printf("%s: no memory for VLAN header, " 889 "dropping packet.\n", ifp->if_xname); 890 return; 891 } 892 evl = mtod(m, struct ether_vlan_header *); 893 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN); 894 895 tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); 896 897 /* 898 * Restore the original ethertype. We'll remove 899 * the encapsulation after we've found the vlan 900 * interface corresponding to the tag. 901 */ 902 evl->evl_encap_proto = evl->evl_proto; 903 break; 904 } 905 906 default: 907 tag = (u_int) -1; /* XXX GCC */ 908 #ifdef DIAGNOSTIC 909 panic("vlan_input: impossible"); 910 #endif 911 } 912 } 913 914 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 915 ifv = LIST_NEXT(ifv, ifv_list)) 916 if (ifp == ifv->ifv_p && tag == ifv->ifv_tag) 917 break; 918 919 if (ifv == NULL || 920 (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != 921 (IFF_UP|IFF_RUNNING)) { 922 m_freem(m); 923 ifp->if_noproto++; 924 return; 925 } 926 927 /* 928 * Now, remove the encapsulation header. The original 929 * header has already been fixed up above. 930 */ 931 if (mtag == NULL) { 932 memmove(mtod(m, char *) + ifv->ifv_encaplen, 933 mtod(m, void *), sizeof(struct ether_header)); 934 m_adj(m, ifv->ifv_encaplen); 935 } 936 937 m_set_rcvif(m, &ifv->ifv_if); 938 ifv->ifv_if.if_ipackets++; 939 940 bpf_mtap(&ifv->ifv_if, m); 941 942 m->m_flags &= ~M_PROMISC; 943 if_input(&ifv->ifv_if, m); 944 } 945 946 /* 947 * Module infrastructure 948 */ 949 #include "if_module.h" 950 951 IF_MODULE(MODULE_CLASS_DRIVER, vlan, "") 952