1 /* $NetBSD: if_vlan.c,v 1.95 2017/01/23 06:47:54 ozaki-r 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.95 2017/01/23 06:47:54 ozaki-r 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 ec->ec_nvlans--; 320 return error; 321 } 322 ifv->ifv_mtufudge = 0; 323 } else { 324 /* 325 * Fudge the MTU by the encapsulation size. This 326 * makes us incompatible with strictly compliant 327 * 802.1Q implementations, but allows us to use 328 * the feature with other NetBSD 329 * implementations, which might still be useful. 330 */ 331 ifv->ifv_mtufudge = ifv->ifv_encaplen; 332 } 333 } 334 335 /* 336 * If the parent interface can do hardware-assisted 337 * VLAN encapsulation, then propagate its hardware- 338 * assisted checksumming flags and tcp segmentation 339 * offload. 340 */ 341 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 342 ec->ec_capenable |= ETHERCAP_VLAN_HWTAGGING; 343 ifp->if_capabilities = p->if_capabilities & 344 (IFCAP_TSOv4 | IFCAP_TSOv6 | 345 IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_IPv4_Rx| 346 IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_TCPv4_Rx| 347 IFCAP_CSUM_UDPv4_Tx|IFCAP_CSUM_UDPv4_Rx| 348 IFCAP_CSUM_TCPv6_Tx|IFCAP_CSUM_TCPv6_Rx| 349 IFCAP_CSUM_UDPv6_Tx|IFCAP_CSUM_UDPv6_Rx); 350 } 351 /* 352 * We inherit the parent's Ethernet address. 353 */ 354 ether_ifattach(ifp, CLLADDR(p->if_sadl)); 355 ifp->if_hdrlen = sizeof(struct ether_vlan_header); /* XXX? */ 356 break; 357 } 358 359 default: 360 return (EPROTONOSUPPORT); 361 } 362 363 ifv->ifv_p = p; 364 ifv->ifv_if.if_mtu = p->if_mtu - ifv->ifv_mtufudge; 365 ifv->ifv_if.if_flags = p->if_flags & 366 (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); 367 368 /* 369 * Inherit the if_type from the parent. This allows us 370 * to participate in bridges of that type. 371 */ 372 ifv->ifv_if.if_type = p->if_type; 373 374 return (0); 375 } 376 377 /* 378 * Unconfigure a VLAN interface. Must be called at splnet(). 379 */ 380 static void 381 vlan_unconfig(struct ifnet *ifp) 382 { 383 struct ifvlan *ifv = ifp->if_softc; 384 struct ifnet *p; 385 386 mutex_enter(&ifv_mtx); 387 p = ifv->ifv_p; 388 389 if (p == NULL) { 390 mutex_exit(&ifv_mtx); 391 return; 392 } 393 394 /* 395 * Since the interface is being unconfigured, we need to empty the 396 * list of multicast groups that we may have joined while we were 397 * alive and remove them from the parent's list also. 398 */ 399 (*ifv->ifv_msw->vmsw_purgemulti)(ifv); 400 401 /* Disconnect from parent. */ 402 switch (p->if_type) { 403 case IFT_ETHER: 404 { 405 struct ethercom *ec = (void *)p; 406 if (--ec->ec_nvlans == 0) 407 (void)ether_disable_vlan_mtu(p); 408 409 ether_ifdetach(ifp); 410 /* Restore vlan_ioctl overwritten by ether_ifdetach */ 411 ifp->if_ioctl = vlan_ioctl; 412 vlan_reset_linkname(ifp); 413 break; 414 } 415 416 #ifdef DIAGNOSTIC 417 default: 418 panic("vlan_unconfig: impossible"); 419 #endif 420 } 421 422 ifv->ifv_p = NULL; 423 ifv->ifv_if.if_mtu = 0; 424 ifv->ifv_flags = 0; 425 426 #ifdef INET6 427 /* To delete v6 link local addresses */ 428 in6_ifdetach(ifp); 429 #endif 430 if ((ifp->if_flags & IFF_PROMISC) != 0) 431 ifpromisc(ifp, 0); 432 if_down(ifp); 433 ifp->if_flags &= ~(IFF_UP|IFF_RUNNING); 434 ifp->if_capabilities = 0; 435 436 mutex_exit(&ifv_mtx); 437 } 438 439 /* 440 * Called when a parent interface is detaching; destroy any VLAN 441 * configuration for the parent interface. 442 */ 443 void 444 vlan_ifdetach(struct ifnet *p) 445 { 446 struct ifvlan *ifv; 447 int s; 448 449 s = splnet(); 450 451 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 452 ifv = LIST_NEXT(ifv, ifv_list)) { 453 if (ifv->ifv_p == p) 454 vlan_unconfig(&ifv->ifv_if); 455 } 456 457 splx(s); 458 } 459 460 static int 461 vlan_set_promisc(struct ifnet *ifp) 462 { 463 struct ifvlan *ifv = ifp->if_softc; 464 int error = 0; 465 466 if ((ifp->if_flags & IFF_PROMISC) != 0) { 467 if ((ifv->ifv_flags & IFVF_PROMISC) == 0) { 468 error = ifpromisc(ifv->ifv_p, 1); 469 if (error == 0) 470 ifv->ifv_flags |= IFVF_PROMISC; 471 } 472 } else { 473 if ((ifv->ifv_flags & IFVF_PROMISC) != 0) { 474 error = ifpromisc(ifv->ifv_p, 0); 475 if (error == 0) 476 ifv->ifv_flags &= ~IFVF_PROMISC; 477 } 478 } 479 480 return (error); 481 } 482 483 static int 484 vlan_ioctl(struct ifnet *ifp, u_long cmd, void *data) 485 { 486 struct lwp *l = curlwp; /* XXX */ 487 struct ifvlan *ifv = ifp->if_softc; 488 struct ifaddr *ifa = (struct ifaddr *) data; 489 struct ifreq *ifr = (struct ifreq *) data; 490 struct ifnet *pr; 491 struct ifcapreq *ifcr; 492 struct vlanreq vlr; 493 int s, error = 0; 494 495 s = splnet(); 496 497 switch (cmd) { 498 case SIOCSIFMTU: 499 if (ifv->ifv_p == NULL) 500 error = EINVAL; 501 else if ( 502 ifr->ifr_mtu > (ifv->ifv_p->if_mtu - ifv->ifv_mtufudge) || 503 ifr->ifr_mtu < (ifv->ifv_mintu - ifv->ifv_mtufudge)) 504 error = EINVAL; 505 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 506 error = 0; 507 break; 508 509 case SIOCSETVLAN: 510 if ((error = kauth_authorize_network(l->l_cred, 511 KAUTH_NETWORK_INTERFACE, 512 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 513 NULL)) != 0) 514 break; 515 if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0) 516 break; 517 if (vlr.vlr_parent[0] == '\0') { 518 if (ifv->ifv_p != NULL && 519 (ifp->if_flags & IFF_PROMISC) != 0) 520 error = ifpromisc(ifv->ifv_p, 0); 521 vlan_unconfig(ifp); 522 break; 523 } 524 if (vlr.vlr_tag != EVL_VLANOFTAG(vlr.vlr_tag)) { 525 error = EINVAL; /* check for valid tag */ 526 break; 527 } 528 if ((pr = ifunit(vlr.vlr_parent)) == 0) { 529 error = ENOENT; 530 break; 531 } 532 if ((error = vlan_config(ifv, pr)) != 0) 533 break; 534 ifv->ifv_tag = vlr.vlr_tag; 535 ifp->if_flags |= IFF_RUNNING; 536 537 /* Update promiscuous mode, if necessary. */ 538 vlan_set_promisc(ifp); 539 break; 540 541 case SIOCGETVLAN: 542 memset(&vlr, 0, sizeof(vlr)); 543 if (ifv->ifv_p != NULL) { 544 snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), "%s", 545 ifv->ifv_p->if_xname); 546 vlr.vlr_tag = ifv->ifv_tag; 547 } 548 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); 549 break; 550 551 case SIOCSIFFLAGS: 552 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 553 break; 554 /* 555 * For promiscuous mode, we enable promiscuous mode on 556 * the parent if we need promiscuous on the VLAN interface. 557 */ 558 if (ifv->ifv_p != NULL) 559 error = vlan_set_promisc(ifp); 560 break; 561 562 case SIOCADDMULTI: 563 error = (ifv->ifv_p != NULL) ? 564 (*ifv->ifv_msw->vmsw_addmulti)(ifv, ifr) : EINVAL; 565 break; 566 567 case SIOCDELMULTI: 568 error = (ifv->ifv_p != NULL) ? 569 (*ifv->ifv_msw->vmsw_delmulti)(ifv, ifr) : EINVAL; 570 break; 571 572 case SIOCSIFCAP: 573 ifcr = data; 574 /* make sure caps are enabled on parent */ 575 if (ifv->ifv_p == NULL) { 576 error = EINVAL; 577 break; 578 } 579 if ((ifv->ifv_p->if_capenable & ifcr->ifcr_capenable) != 580 ifcr->ifcr_capenable) { 581 error = EINVAL; 582 break; 583 } 584 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 585 error = 0; 586 break; 587 case SIOCINITIFADDR: 588 if (ifv->ifv_p == NULL) { 589 error = EINVAL; 590 break; 591 } 592 593 ifp->if_flags |= IFF_UP; 594 #ifdef INET 595 if (ifa->ifa_addr->sa_family == AF_INET) 596 arp_ifinit(ifp, ifa); 597 #endif 598 break; 599 600 default: 601 error = ether_ioctl(ifp, cmd, data); 602 } 603 604 splx(s); 605 606 return (error); 607 } 608 609 static int 610 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr) 611 { 612 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr); 613 struct vlan_mc_entry *mc; 614 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 615 int error; 616 617 if (sa->sa_len > sizeof(struct sockaddr_storage)) 618 return (EINVAL); 619 620 error = ether_addmulti(sa, &ifv->ifv_ec); 621 if (error != ENETRESET) 622 return (error); 623 624 /* 625 * This is new multicast address. We have to tell parent 626 * about it. Also, remember this multicast address so that 627 * we can delete them on unconfigure. 628 */ 629 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT); 630 if (mc == NULL) { 631 error = ENOMEM; 632 goto alloc_failed; 633 } 634 635 /* 636 * As ether_addmulti() returns ENETRESET, following two 637 * statement shouldn't fail. 638 */ 639 (void)ether_multiaddr(sa, addrlo, addrhi); 640 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, mc->mc_enm); 641 memcpy(&mc->mc_addr, sa, sa->sa_len); 642 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries); 643 644 error = if_mcast_op(ifv->ifv_p, SIOCADDMULTI, sa); 645 if (error != 0) 646 goto ioctl_failed; 647 return (error); 648 649 ioctl_failed: 650 LIST_REMOVE(mc, mc_entries); 651 free(mc, M_DEVBUF); 652 alloc_failed: 653 (void)ether_delmulti(sa, &ifv->ifv_ec); 654 return (error); 655 } 656 657 static int 658 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr) 659 { 660 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr); 661 struct ether_multi *enm; 662 struct vlan_mc_entry *mc; 663 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 664 int error; 665 666 /* 667 * Find a key to lookup vlan_mc_entry. We have to do this 668 * before calling ether_delmulti for obvious reason. 669 */ 670 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0) 671 return (error); 672 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, enm); 673 674 error = ether_delmulti(sa, &ifv->ifv_ec); 675 if (error != ENETRESET) 676 return (error); 677 678 /* We no longer use this multicast address. Tell parent so. */ 679 error = if_mcast_op(ifv->ifv_p, SIOCDELMULTI, sa); 680 if (error == 0) { 681 /* And forget about this address. */ 682 for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; 683 mc = LIST_NEXT(mc, mc_entries)) { 684 if (mc->mc_enm == enm) { 685 LIST_REMOVE(mc, mc_entries); 686 free(mc, M_DEVBUF); 687 break; 688 } 689 } 690 KASSERT(mc != NULL); 691 } else 692 (void)ether_addmulti(sa, &ifv->ifv_ec); 693 return (error); 694 } 695 696 /* 697 * Delete any multicast address we have asked to add from parent 698 * interface. Called when the vlan is being unconfigured. 699 */ 700 static void 701 vlan_ether_purgemulti(struct ifvlan *ifv) 702 { 703 struct ifnet *ifp = ifv->ifv_p; /* Parent. */ 704 struct vlan_mc_entry *mc; 705 706 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { 707 (void)if_mcast_op(ifp, SIOCDELMULTI, 708 (const struct sockaddr *)&mc->mc_addr); 709 LIST_REMOVE(mc, mc_entries); 710 free(mc, M_DEVBUF); 711 } 712 } 713 714 static void 715 vlan_start(struct ifnet *ifp) 716 { 717 struct ifvlan *ifv = ifp->if_softc; 718 struct ifnet *p = ifv->ifv_p; 719 struct ethercom *ec = (void *) ifv->ifv_p; 720 struct mbuf *m; 721 int error; 722 723 #ifndef NET_MPSAFE 724 KASSERT(KERNEL_LOCKED_P()); 725 #endif 726 727 ifp->if_flags |= IFF_OACTIVE; 728 729 for (;;) { 730 IFQ_DEQUEUE(&ifp->if_snd, m); 731 if (m == NULL) 732 break; 733 734 #ifdef ALTQ 735 /* 736 * KERNEL_LOCK is required for ALTQ even if NET_MPSAFE is defined. 737 */ 738 KERNEL_LOCK(1, NULL); 739 /* 740 * If ALTQ is enabled on the parent interface, do 741 * classification; the queueing discipline might 742 * not require classification, but might require 743 * the address family/header pointer in the pktattr. 744 */ 745 if (ALTQ_IS_ENABLED(&p->if_snd)) { 746 switch (p->if_type) { 747 case IFT_ETHER: 748 altq_etherclassify(&p->if_snd, m); 749 break; 750 #ifdef DIAGNOSTIC 751 default: 752 panic("vlan_start: impossible (altq)"); 753 #endif 754 } 755 } 756 KERNEL_UNLOCK_ONE(NULL); 757 #endif /* ALTQ */ 758 759 bpf_mtap(ifp, m); 760 /* 761 * If the parent can insert the tag itself, just mark 762 * the tag in the mbuf header. 763 */ 764 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 765 struct m_tag *mtag; 766 767 mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), 768 M_NOWAIT); 769 if (mtag == NULL) { 770 ifp->if_oerrors++; 771 m_freem(m); 772 continue; 773 } 774 *(u_int *)(mtag + 1) = ifv->ifv_tag; 775 m_tag_prepend(m, mtag); 776 } else { 777 /* 778 * insert the tag ourselves 779 */ 780 M_PREPEND(m, ifv->ifv_encaplen, M_DONTWAIT); 781 if (m == NULL) { 782 printf("%s: unable to prepend encap header", 783 ifv->ifv_p->if_xname); 784 ifp->if_oerrors++; 785 continue; 786 } 787 788 switch (p->if_type) { 789 case IFT_ETHER: 790 { 791 struct ether_vlan_header *evl; 792 793 if (m->m_len < sizeof(struct ether_vlan_header)) 794 m = m_pullup(m, 795 sizeof(struct ether_vlan_header)); 796 if (m == NULL) { 797 printf("%s: unable to pullup encap " 798 "header", ifv->ifv_p->if_xname); 799 ifp->if_oerrors++; 800 continue; 801 } 802 803 /* 804 * Transform the Ethernet header into an 805 * Ethernet header with 802.1Q encapsulation. 806 */ 807 memmove(mtod(m, void *), 808 mtod(m, char *) + ifv->ifv_encaplen, 809 sizeof(struct ether_header)); 810 evl = mtod(m, struct ether_vlan_header *); 811 evl->evl_proto = evl->evl_encap_proto; 812 evl->evl_encap_proto = htons(ETHERTYPE_VLAN); 813 evl->evl_tag = htons(ifv->ifv_tag); 814 815 /* 816 * To cater for VLAN-aware layer 2 ethernet 817 * switches which may need to strip the tag 818 * before forwarding the packet, make sure 819 * the packet+tag is at least 68 bytes long. 820 * This is necessary because our parent will 821 * only pad to 64 bytes (ETHER_MIN_LEN) and 822 * some switches will not pad by themselves 823 * after deleting a tag. 824 */ 825 if (m->m_pkthdr.len < 826 (ETHER_MIN_LEN - ETHER_CRC_LEN + 827 ETHER_VLAN_ENCAP_LEN)) { 828 m_copyback(m, m->m_pkthdr.len, 829 (ETHER_MIN_LEN - ETHER_CRC_LEN + 830 ETHER_VLAN_ENCAP_LEN) - 831 m->m_pkthdr.len, 832 vlan_zero_pad_buff); 833 } 834 break; 835 } 836 837 #ifdef DIAGNOSTIC 838 default: 839 panic("vlan_start: impossible"); 840 #endif 841 } 842 } 843 844 /* 845 * Send it, precisely as the parent's output routine 846 * would have. We are already running at splnet. 847 */ 848 if ((p->if_flags & IFF_RUNNING) != 0) { 849 error = if_transmit_lock(p, m); 850 if (error) { 851 /* mbuf is already freed */ 852 ifp->if_oerrors++; 853 continue; 854 } 855 } 856 857 ifp->if_opackets++; 858 } 859 860 ifp->if_flags &= ~IFF_OACTIVE; 861 } 862 863 /* 864 * Given an Ethernet frame, find a valid vlan interface corresponding to the 865 * given source interface and tag, then run the real packet through the 866 * parent's input routine. 867 */ 868 void 869 vlan_input(struct ifnet *ifp, struct mbuf *m) 870 { 871 struct ifvlan *ifv; 872 u_int tag; 873 struct m_tag *mtag; 874 875 mtag = m_tag_find(m, PACKET_TAG_VLAN, NULL); 876 if (mtag != NULL) { 877 /* m contains a normal ethernet frame, the tag is in mtag */ 878 tag = EVL_VLANOFTAG(*(u_int *)(mtag + 1)); 879 m_tag_delete(m, mtag); 880 } else { 881 switch (ifp->if_type) { 882 case IFT_ETHER: 883 { 884 struct ether_vlan_header *evl; 885 886 if (m->m_len < sizeof(struct ether_vlan_header) && 887 (m = m_pullup(m, 888 sizeof(struct ether_vlan_header))) == NULL) { 889 printf("%s: no memory for VLAN header, " 890 "dropping packet.\n", ifp->if_xname); 891 return; 892 } 893 evl = mtod(m, struct ether_vlan_header *); 894 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN); 895 896 tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); 897 898 /* 899 * Restore the original ethertype. We'll remove 900 * the encapsulation after we've found the vlan 901 * interface corresponding to the tag. 902 */ 903 evl->evl_encap_proto = evl->evl_proto; 904 break; 905 } 906 907 default: 908 tag = (u_int) -1; /* XXX GCC */ 909 #ifdef DIAGNOSTIC 910 panic("vlan_input: impossible"); 911 #endif 912 } 913 } 914 915 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 916 ifv = LIST_NEXT(ifv, ifv_list)) 917 if (ifp == ifv->ifv_p && tag == ifv->ifv_tag) 918 break; 919 920 if (ifv == NULL || 921 (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != 922 (IFF_UP|IFF_RUNNING)) { 923 m_freem(m); 924 ifp->if_noproto++; 925 return; 926 } 927 928 /* 929 * Now, remove the encapsulation header. The original 930 * header has already been fixed up above. 931 */ 932 if (mtag == NULL) { 933 memmove(mtod(m, char *) + ifv->ifv_encaplen, 934 mtod(m, void *), sizeof(struct ether_header)); 935 m_adj(m, ifv->ifv_encaplen); 936 } 937 938 m_set_rcvif(m, &ifv->ifv_if); 939 ifv->ifv_if.if_ipackets++; 940 941 m->m_flags &= ~M_PROMISC; 942 if_input(&ifv->ifv_if, m); 943 } 944 945 /* 946 * Module infrastructure 947 */ 948 #include "if_module.h" 949 950 IF_MODULE(MODULE_CLASS_DRIVER, vlan, "") 951