1 /* $NetBSD: if_vlan.c,v 1.83 2015/11/19 16:23:54 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.83 2015/11/19 16:23:54 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 99 #include <net/bpf.h> 100 #include <net/if.h> 101 #include <net/if_dl.h> 102 #include <net/if_types.h> 103 #include <net/if_ether.h> 104 #include <net/if_vlanvar.h> 105 106 #ifdef INET 107 #include <netinet/in.h> 108 #include <netinet/if_inarp.h> 109 #endif 110 #ifdef INET6 111 #include <netinet6/in6_ifattach.h> 112 #endif 113 114 #include "ioconf.h" 115 116 struct vlan_mc_entry { 117 LIST_ENTRY(vlan_mc_entry) mc_entries; 118 /* 119 * A key to identify this entry. The mc_addr below can't be 120 * used since multiple sockaddr may mapped into the same 121 * ether_multi (e.g., AF_UNSPEC). 122 */ 123 union { 124 struct ether_multi *mcu_enm; 125 } mc_u; 126 struct sockaddr_storage mc_addr; 127 }; 128 129 #define mc_enm mc_u.mcu_enm 130 131 struct ifvlan { 132 union { 133 struct ethercom ifvu_ec; 134 } ifv_u; 135 struct ifnet *ifv_p; /* parent interface of this vlan */ 136 struct ifv_linkmib { 137 const struct vlan_multisw *ifvm_msw; 138 int ifvm_encaplen; /* encapsulation length */ 139 int ifvm_mtufudge; /* MTU fudged by this much */ 140 int ifvm_mintu; /* min transmission unit */ 141 uint16_t ifvm_proto; /* encapsulation ethertype */ 142 uint16_t ifvm_tag; /* tag to apply on packets */ 143 } ifv_mib; 144 LIST_HEAD(__vlan_mchead, vlan_mc_entry) ifv_mc_listhead; 145 LIST_ENTRY(ifvlan) ifv_list; 146 int ifv_flags; 147 }; 148 149 #define IFVF_PROMISC 0x01 /* promiscuous mode enabled */ 150 151 #define ifv_ec ifv_u.ifvu_ec 152 153 #define ifv_if ifv_ec.ec_if 154 155 #define ifv_msw ifv_mib.ifvm_msw 156 #define ifv_encaplen ifv_mib.ifvm_encaplen 157 #define ifv_mtufudge ifv_mib.ifvm_mtufudge 158 #define ifv_mintu ifv_mib.ifvm_mintu 159 #define ifv_tag ifv_mib.ifvm_tag 160 161 struct vlan_multisw { 162 int (*vmsw_addmulti)(struct ifvlan *, struct ifreq *); 163 int (*vmsw_delmulti)(struct ifvlan *, struct ifreq *); 164 void (*vmsw_purgemulti)(struct ifvlan *); 165 }; 166 167 static int vlan_ether_addmulti(struct ifvlan *, struct ifreq *); 168 static int vlan_ether_delmulti(struct ifvlan *, struct ifreq *); 169 static void vlan_ether_purgemulti(struct ifvlan *); 170 171 const struct vlan_multisw vlan_ether_multisw = { 172 vlan_ether_addmulti, 173 vlan_ether_delmulti, 174 vlan_ether_purgemulti, 175 }; 176 177 static int vlan_clone_create(struct if_clone *, int); 178 static int vlan_clone_destroy(struct ifnet *); 179 static int vlan_config(struct ifvlan *, struct ifnet *); 180 static int vlan_ioctl(struct ifnet *, u_long, void *); 181 static void vlan_start(struct ifnet *); 182 static void vlan_unconfig(struct ifnet *); 183 184 /* XXX This should be a hash table with the tag as the basis of the key. */ 185 static LIST_HEAD(, ifvlan) ifv_list; 186 187 static kmutex_t ifv_mtx __cacheline_aligned; 188 189 struct if_clone vlan_cloner = 190 IF_CLONE_INITIALIZER("vlan", vlan_clone_create, vlan_clone_destroy); 191 192 /* Used to pad ethernet frames with < ETHER_MIN_LEN bytes */ 193 static char vlan_zero_pad_buff[ETHER_MIN_LEN]; 194 195 void 196 vlanattach(int n) 197 { 198 199 LIST_INIT(&ifv_list); 200 mutex_init(&ifv_mtx, MUTEX_DEFAULT, IPL_NONE); 201 if_clone_attach(&vlan_cloner); 202 } 203 204 static void 205 vlan_reset_linkname(struct ifnet *ifp) 206 { 207 208 /* 209 * We start out with a "802.1Q VLAN" type and zero-length 210 * addresses. When we attach to a parent interface, we 211 * inherit its type, address length, address, and data link 212 * type. 213 */ 214 215 ifp->if_type = IFT_L2VLAN; 216 ifp->if_addrlen = 0; 217 ifp->if_dlt = DLT_NULL; 218 if_alloc_sadl(ifp); 219 } 220 221 static int 222 vlan_clone_create(struct if_clone *ifc, int unit) 223 { 224 struct ifvlan *ifv; 225 struct ifnet *ifp; 226 int s; 227 228 ifv = malloc(sizeof(struct ifvlan), M_DEVBUF, M_WAITOK|M_ZERO); 229 ifp = &ifv->ifv_if; 230 LIST_INIT(&ifv->ifv_mc_listhead); 231 232 s = splnet(); 233 LIST_INSERT_HEAD(&ifv_list, ifv, ifv_list); 234 splx(s); 235 236 if_initname(ifp, ifc->ifc_name, unit); 237 ifp->if_softc = ifv; 238 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 239 ifp->if_start = vlan_start; 240 ifp->if_ioctl = vlan_ioctl; 241 IFQ_SET_READY(&ifp->if_snd); 242 243 if_attach(ifp); 244 vlan_reset_linkname(ifp); 245 246 return (0); 247 } 248 249 static int 250 vlan_clone_destroy(struct ifnet *ifp) 251 { 252 struct ifvlan *ifv = ifp->if_softc; 253 int s; 254 255 s = splnet(); 256 LIST_REMOVE(ifv, ifv_list); 257 vlan_unconfig(ifp); 258 if_detach(ifp); 259 splx(s); 260 261 free(ifv, M_DEVBUF); 262 263 return (0); 264 } 265 266 /* 267 * Configure a VLAN interface. Must be called at splnet(). 268 */ 269 static int 270 vlan_config(struct ifvlan *ifv, struct ifnet *p) 271 { 272 struct ifnet *ifp = &ifv->ifv_if; 273 int error; 274 275 if (ifv->ifv_p != NULL) 276 return (EBUSY); 277 278 switch (p->if_type) { 279 case IFT_ETHER: 280 { 281 struct ethercom *ec = (void *) p; 282 283 ifv->ifv_msw = &vlan_ether_multisw; 284 ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN; 285 ifv->ifv_mintu = ETHERMIN; 286 287 if (ec->ec_nvlans == 0) { 288 if ((error = ether_enable_vlan_mtu(p)) >= 0) { 289 if (error) 290 return error; 291 ifv->ifv_mtufudge = 0; 292 } else { 293 /* 294 * Fudge the MTU by the encapsulation size. This 295 * makes us incompatible with strictly compliant 296 * 802.1Q implementations, but allows us to use 297 * the feature with other NetBSD 298 * implementations, which might still be useful. 299 */ 300 ifv->ifv_mtufudge = ifv->ifv_encaplen; 301 } 302 ec->ec_nvlans++; 303 } 304 305 /* 306 * If the parent interface can do hardware-assisted 307 * VLAN encapsulation, then propagate its hardware- 308 * assisted checksumming flags and tcp segmentation 309 * offload. 310 */ 311 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 312 ec->ec_capenable |= ETHERCAP_VLAN_HWTAGGING; 313 ifp->if_capabilities = p->if_capabilities & 314 (IFCAP_TSOv4 | IFCAP_TSOv6 | 315 IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_IPv4_Rx| 316 IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_TCPv4_Rx| 317 IFCAP_CSUM_UDPv4_Tx|IFCAP_CSUM_UDPv4_Rx| 318 IFCAP_CSUM_TCPv6_Tx|IFCAP_CSUM_TCPv6_Rx| 319 IFCAP_CSUM_UDPv6_Tx|IFCAP_CSUM_UDPv6_Rx); 320 } 321 /* 322 * We inherit the parent's Ethernet address. 323 */ 324 ether_ifattach(ifp, CLLADDR(p->if_sadl)); 325 ifp->if_hdrlen = sizeof(struct ether_vlan_header); /* XXX? */ 326 break; 327 } 328 329 default: 330 return (EPROTONOSUPPORT); 331 } 332 333 ifv->ifv_p = p; 334 ifv->ifv_if.if_mtu = p->if_mtu - ifv->ifv_mtufudge; 335 ifv->ifv_if.if_flags = p->if_flags & 336 (IFF_UP | IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); 337 338 /* 339 * Inherit the if_type from the parent. This allows us 340 * to participate in bridges of that type. 341 */ 342 ifv->ifv_if.if_type = p->if_type; 343 344 return (0); 345 } 346 347 /* 348 * Unconfigure a VLAN interface. Must be called at splnet(). 349 */ 350 static void 351 vlan_unconfig(struct ifnet *ifp) 352 { 353 struct ifvlan *ifv = ifp->if_softc; 354 struct ifnet *p; 355 356 mutex_enter(&ifv_mtx); 357 p = ifv->ifv_p; 358 359 if (p == NULL) { 360 mutex_exit(&ifv_mtx); 361 return; 362 } 363 364 /* 365 * Since the interface is being unconfigured, we need to empty the 366 * list of multicast groups that we may have joined while we were 367 * alive and remove them from the parent's list also. 368 */ 369 (*ifv->ifv_msw->vmsw_purgemulti)(ifv); 370 371 /* Disconnect from parent. */ 372 switch (p->if_type) { 373 case IFT_ETHER: 374 { 375 struct ethercom *ec = (void *)p; 376 if (--ec->ec_nvlans == 0) 377 (void)ether_disable_vlan_mtu(p); 378 379 ether_ifdetach(ifp); 380 /* Restore vlan_ioctl overwritten by ether_ifdetach */ 381 ifp->if_ioctl = vlan_ioctl; 382 vlan_reset_linkname(ifp); 383 break; 384 } 385 386 #ifdef DIAGNOSTIC 387 default: 388 panic("vlan_unconfig: impossible"); 389 #endif 390 } 391 392 ifv->ifv_p = NULL; 393 ifv->ifv_if.if_mtu = 0; 394 ifv->ifv_flags = 0; 395 396 #ifdef INET6 397 /* To delete v6 link local addresses */ 398 in6_ifdetach(ifp); 399 #endif 400 if ((ifp->if_flags & IFF_PROMISC) != 0) 401 ifpromisc(ifp, 0); 402 if_down(ifp); 403 ifp->if_flags &= ~(IFF_UP|IFF_RUNNING); 404 ifp->if_capabilities = 0; 405 406 mutex_exit(&ifv_mtx); 407 } 408 409 /* 410 * Called when a parent interface is detaching; destroy any VLAN 411 * configuration for the parent interface. 412 */ 413 void 414 vlan_ifdetach(struct ifnet *p) 415 { 416 struct ifvlan *ifv; 417 int s; 418 419 s = splnet(); 420 421 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 422 ifv = LIST_NEXT(ifv, ifv_list)) { 423 if (ifv->ifv_p == p) 424 vlan_unconfig(&ifv->ifv_if); 425 } 426 427 splx(s); 428 } 429 430 static int 431 vlan_set_promisc(struct ifnet *ifp) 432 { 433 struct ifvlan *ifv = ifp->if_softc; 434 int error = 0; 435 436 if ((ifp->if_flags & IFF_PROMISC) != 0) { 437 if ((ifv->ifv_flags & IFVF_PROMISC) == 0) { 438 error = ifpromisc(ifv->ifv_p, 1); 439 if (error == 0) 440 ifv->ifv_flags |= IFVF_PROMISC; 441 } 442 } else { 443 if ((ifv->ifv_flags & IFVF_PROMISC) != 0) { 444 error = ifpromisc(ifv->ifv_p, 0); 445 if (error == 0) 446 ifv->ifv_flags &= ~IFVF_PROMISC; 447 } 448 } 449 450 return (error); 451 } 452 453 static int 454 vlan_ioctl(struct ifnet *ifp, u_long cmd, void *data) 455 { 456 struct lwp *l = curlwp; /* XXX */ 457 struct ifvlan *ifv = ifp->if_softc; 458 struct ifaddr *ifa = (struct ifaddr *) data; 459 struct ifreq *ifr = (struct ifreq *) data; 460 struct ifnet *pr; 461 struct ifcapreq *ifcr; 462 struct vlanreq vlr; 463 int s, error = 0; 464 465 s = splnet(); 466 467 switch (cmd) { 468 case SIOCSIFMTU: 469 if (ifv->ifv_p == NULL) 470 error = EINVAL; 471 else if ( 472 ifr->ifr_mtu > (ifv->ifv_p->if_mtu - ifv->ifv_mtufudge) || 473 ifr->ifr_mtu < (ifv->ifv_mintu - ifv->ifv_mtufudge)) 474 error = EINVAL; 475 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 476 error = 0; 477 break; 478 479 case SIOCSETVLAN: 480 if ((error = kauth_authorize_network(l->l_cred, 481 KAUTH_NETWORK_INTERFACE, 482 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 483 NULL)) != 0) 484 break; 485 if ((error = copyin(ifr->ifr_data, &vlr, sizeof(vlr))) != 0) 486 break; 487 if (vlr.vlr_parent[0] == '\0') { 488 if (ifv->ifv_p != NULL && 489 (ifp->if_flags & IFF_PROMISC) != 0) 490 error = ifpromisc(ifv->ifv_p, 0); 491 vlan_unconfig(ifp); 492 break; 493 } 494 if (vlr.vlr_tag != EVL_VLANOFTAG(vlr.vlr_tag)) { 495 error = EINVAL; /* check for valid tag */ 496 break; 497 } 498 if ((pr = ifunit(vlr.vlr_parent)) == 0) { 499 error = ENOENT; 500 break; 501 } 502 if ((error = vlan_config(ifv, pr)) != 0) 503 break; 504 ifv->ifv_tag = vlr.vlr_tag; 505 ifp->if_flags |= IFF_RUNNING; 506 507 /* Update promiscuous mode, if necessary. */ 508 vlan_set_promisc(ifp); 509 break; 510 511 case SIOCGETVLAN: 512 memset(&vlr, 0, sizeof(vlr)); 513 if (ifv->ifv_p != NULL) { 514 snprintf(vlr.vlr_parent, sizeof(vlr.vlr_parent), "%s", 515 ifv->ifv_p->if_xname); 516 vlr.vlr_tag = ifv->ifv_tag; 517 } 518 error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); 519 break; 520 521 case SIOCSIFFLAGS: 522 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 523 break; 524 /* 525 * For promiscuous mode, we enable promiscuous mode on 526 * the parent if we need promiscuous on the VLAN interface. 527 */ 528 if (ifv->ifv_p != NULL) 529 error = vlan_set_promisc(ifp); 530 break; 531 532 case SIOCADDMULTI: 533 error = (ifv->ifv_p != NULL) ? 534 (*ifv->ifv_msw->vmsw_addmulti)(ifv, ifr) : EINVAL; 535 break; 536 537 case SIOCDELMULTI: 538 error = (ifv->ifv_p != NULL) ? 539 (*ifv->ifv_msw->vmsw_delmulti)(ifv, ifr) : EINVAL; 540 break; 541 542 case SIOCSIFCAP: 543 ifcr = data; 544 /* make sure caps are enabled on parent */ 545 if ((ifv->ifv_p->if_capenable & ifcr->ifcr_capenable) != 546 ifcr->ifcr_capenable) { 547 error = EINVAL; 548 break; 549 } 550 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 551 error = 0; 552 break; 553 case SIOCINITIFADDR: 554 if (ifv->ifv_p == NULL) { 555 error = EINVAL; 556 break; 557 } 558 559 ifp->if_flags |= IFF_UP; 560 #ifdef INET 561 if (ifa->ifa_addr->sa_family == AF_INET) 562 arp_ifinit(ifp, ifa); 563 #endif 564 break; 565 566 default: 567 error = ether_ioctl(ifp, cmd, data); 568 } 569 570 splx(s); 571 572 return (error); 573 } 574 575 static int 576 vlan_ether_addmulti(struct ifvlan *ifv, struct ifreq *ifr) 577 { 578 const struct sockaddr *sa = ifreq_getaddr(SIOCADDMULTI, ifr); 579 struct vlan_mc_entry *mc; 580 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 581 int error; 582 583 if (sa->sa_len > sizeof(struct sockaddr_storage)) 584 return (EINVAL); 585 586 error = ether_addmulti(sa, &ifv->ifv_ec); 587 if (error != ENETRESET) 588 return (error); 589 590 /* 591 * This is new multicast address. We have to tell parent 592 * about it. Also, remember this multicast address so that 593 * we can delete them on unconfigure. 594 */ 595 mc = malloc(sizeof(struct vlan_mc_entry), M_DEVBUF, M_NOWAIT); 596 if (mc == NULL) { 597 error = ENOMEM; 598 goto alloc_failed; 599 } 600 601 /* 602 * As ether_addmulti() returns ENETRESET, following two 603 * statement shouldn't fail. 604 */ 605 (void)ether_multiaddr(sa, addrlo, addrhi); 606 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, mc->mc_enm); 607 memcpy(&mc->mc_addr, sa, sa->sa_len); 608 LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries); 609 610 error = if_mcast_op(ifv->ifv_p, SIOCADDMULTI, sa); 611 if (error != 0) 612 goto ioctl_failed; 613 return (error); 614 615 ioctl_failed: 616 LIST_REMOVE(mc, mc_entries); 617 free(mc, M_DEVBUF); 618 alloc_failed: 619 (void)ether_delmulti(sa, &ifv->ifv_ec); 620 return (error); 621 } 622 623 static int 624 vlan_ether_delmulti(struct ifvlan *ifv, struct ifreq *ifr) 625 { 626 const struct sockaddr *sa = ifreq_getaddr(SIOCDELMULTI, ifr); 627 struct ether_multi *enm; 628 struct vlan_mc_entry *mc; 629 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 630 int error; 631 632 /* 633 * Find a key to lookup vlan_mc_entry. We have to do this 634 * before calling ether_delmulti for obvious reason. 635 */ 636 if ((error = ether_multiaddr(sa, addrlo, addrhi)) != 0) 637 return (error); 638 ETHER_LOOKUP_MULTI(addrlo, addrhi, &ifv->ifv_ec, enm); 639 640 error = ether_delmulti(sa, &ifv->ifv_ec); 641 if (error != ENETRESET) 642 return (error); 643 644 /* We no longer use this multicast address. Tell parent so. */ 645 error = if_mcast_op(ifv->ifv_p, SIOCDELMULTI, sa); 646 if (error == 0) { 647 /* And forget about this address. */ 648 for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; 649 mc = LIST_NEXT(mc, mc_entries)) { 650 if (mc->mc_enm == enm) { 651 LIST_REMOVE(mc, mc_entries); 652 free(mc, M_DEVBUF); 653 break; 654 } 655 } 656 KASSERT(mc != NULL); 657 } else 658 (void)ether_addmulti(sa, &ifv->ifv_ec); 659 return (error); 660 } 661 662 /* 663 * Delete any multicast address we have asked to add from parent 664 * interface. Called when the vlan is being unconfigured. 665 */ 666 static void 667 vlan_ether_purgemulti(struct ifvlan *ifv) 668 { 669 struct ifnet *ifp = ifv->ifv_p; /* Parent. */ 670 struct vlan_mc_entry *mc; 671 672 while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { 673 (void)if_mcast_op(ifp, SIOCDELMULTI, 674 (const struct sockaddr *)&mc->mc_addr); 675 LIST_REMOVE(mc, mc_entries); 676 free(mc, M_DEVBUF); 677 } 678 } 679 680 static void 681 vlan_start(struct ifnet *ifp) 682 { 683 struct ifvlan *ifv = ifp->if_softc; 684 struct ifnet *p = ifv->ifv_p; 685 struct ethercom *ec = (void *) ifv->ifv_p; 686 struct mbuf *m; 687 int error; 688 ALTQ_DECL(struct altq_pktattr pktattr;) 689 690 #ifndef NET_MPSAFE 691 KASSERT(KERNEL_LOCKED_P()); 692 #endif 693 694 ifp->if_flags |= IFF_OACTIVE; 695 696 for (;;) { 697 IFQ_DEQUEUE(&ifp->if_snd, m); 698 if (m == NULL) 699 break; 700 701 #ifdef ALTQ 702 /* 703 * If ALTQ is enabled on the parent interface, do 704 * classification; the queueing discipline might 705 * not require classification, but might require 706 * the address family/header pointer in the pktattr. 707 */ 708 if (ALTQ_IS_ENABLED(&p->if_snd)) { 709 switch (p->if_type) { 710 case IFT_ETHER: 711 altq_etherclassify(&p->if_snd, m, &pktattr); 712 break; 713 #ifdef DIAGNOSTIC 714 default: 715 panic("vlan_start: impossible (altq)"); 716 #endif 717 } 718 } 719 #endif /* ALTQ */ 720 721 bpf_mtap(ifp, m); 722 /* 723 * If the parent can insert the tag itself, just mark 724 * the tag in the mbuf header. 725 */ 726 if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) { 727 struct m_tag *mtag; 728 729 mtag = m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), 730 M_NOWAIT); 731 if (mtag == NULL) { 732 ifp->if_oerrors++; 733 m_freem(m); 734 continue; 735 } 736 *(u_int *)(mtag + 1) = ifv->ifv_tag; 737 m_tag_prepend(m, mtag); 738 } else { 739 /* 740 * insert the tag ourselves 741 */ 742 M_PREPEND(m, ifv->ifv_encaplen, M_DONTWAIT); 743 if (m == NULL) { 744 printf("%s: unable to prepend encap header", 745 ifv->ifv_p->if_xname); 746 ifp->if_oerrors++; 747 continue; 748 } 749 750 switch (p->if_type) { 751 case IFT_ETHER: 752 { 753 struct ether_vlan_header *evl; 754 755 if (m->m_len < sizeof(struct ether_vlan_header)) 756 m = m_pullup(m, 757 sizeof(struct ether_vlan_header)); 758 if (m == NULL) { 759 printf("%s: unable to pullup encap " 760 "header", ifv->ifv_p->if_xname); 761 ifp->if_oerrors++; 762 continue; 763 } 764 765 /* 766 * Transform the Ethernet header into an 767 * Ethernet header with 802.1Q encapsulation. 768 */ 769 memmove(mtod(m, void *), 770 mtod(m, char *) + ifv->ifv_encaplen, 771 sizeof(struct ether_header)); 772 evl = mtod(m, struct ether_vlan_header *); 773 evl->evl_proto = evl->evl_encap_proto; 774 evl->evl_encap_proto = htons(ETHERTYPE_VLAN); 775 evl->evl_tag = htons(ifv->ifv_tag); 776 777 /* 778 * To cater for VLAN-aware layer 2 ethernet 779 * switches which may need to strip the tag 780 * before forwarding the packet, make sure 781 * the packet+tag is at least 68 bytes long. 782 * This is necessary because our parent will 783 * only pad to 64 bytes (ETHER_MIN_LEN) and 784 * some switches will not pad by themselves 785 * after deleting a tag. 786 */ 787 if (m->m_pkthdr.len < 788 (ETHER_MIN_LEN - ETHER_CRC_LEN + 789 ETHER_VLAN_ENCAP_LEN)) { 790 m_copyback(m, m->m_pkthdr.len, 791 (ETHER_MIN_LEN - ETHER_CRC_LEN + 792 ETHER_VLAN_ENCAP_LEN) - 793 m->m_pkthdr.len, 794 vlan_zero_pad_buff); 795 } 796 break; 797 } 798 799 #ifdef DIAGNOSTIC 800 default: 801 panic("vlan_start: impossible"); 802 #endif 803 } 804 } 805 806 /* 807 * Send it, precisely as the parent's output routine 808 * would have. We are already running at splnet. 809 */ 810 IFQ_ENQUEUE(&p->if_snd, m, &pktattr, error); 811 if (error) { 812 /* mbuf is already freed */ 813 ifp->if_oerrors++; 814 continue; 815 } 816 817 ifp->if_opackets++; 818 819 p->if_obytes += m->m_pkthdr.len; 820 if (m->m_flags & M_MCAST) 821 p->if_omcasts++; 822 if ((p->if_flags & (IFF_RUNNING|IFF_OACTIVE)) == IFF_RUNNING) 823 (*p->if_start)(p); 824 } 825 826 ifp->if_flags &= ~IFF_OACTIVE; 827 } 828 829 /* 830 * Given an Ethernet frame, find a valid vlan interface corresponding to the 831 * given source interface and tag, then run the real packet through the 832 * parent's input routine. 833 */ 834 void 835 vlan_input(struct ifnet *ifp, struct mbuf *m) 836 { 837 struct ifvlan *ifv; 838 u_int tag; 839 struct m_tag *mtag; 840 841 mtag = m_tag_find(m, PACKET_TAG_VLAN, NULL); 842 if (mtag != NULL) { 843 /* m contains a normal ethernet frame, the tag is in mtag */ 844 tag = EVL_VLANOFTAG(*(u_int *)(mtag + 1)); 845 m_tag_delete(m, mtag); 846 } else { 847 switch (ifp->if_type) { 848 case IFT_ETHER: 849 { 850 struct ether_vlan_header *evl; 851 852 if (m->m_len < sizeof(struct ether_vlan_header) && 853 (m = m_pullup(m, 854 sizeof(struct ether_vlan_header))) == NULL) { 855 printf("%s: no memory for VLAN header, " 856 "dropping packet.\n", ifp->if_xname); 857 return; 858 } 859 evl = mtod(m, struct ether_vlan_header *); 860 KASSERT(ntohs(evl->evl_encap_proto) == ETHERTYPE_VLAN); 861 862 tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); 863 864 /* 865 * Restore the original ethertype. We'll remove 866 * the encapsulation after we've found the vlan 867 * interface corresponding to the tag. 868 */ 869 evl->evl_encap_proto = evl->evl_proto; 870 break; 871 } 872 873 default: 874 tag = (u_int) -1; /* XXX GCC */ 875 #ifdef DIAGNOSTIC 876 panic("vlan_input: impossible"); 877 #endif 878 } 879 } 880 881 for (ifv = LIST_FIRST(&ifv_list); ifv != NULL; 882 ifv = LIST_NEXT(ifv, ifv_list)) 883 if (ifp == ifv->ifv_p && tag == ifv->ifv_tag) 884 break; 885 886 if (ifv == NULL || 887 (ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != 888 (IFF_UP|IFF_RUNNING)) { 889 m_freem(m); 890 ifp->if_noproto++; 891 return; 892 } 893 894 /* 895 * Now, remove the encapsulation header. The original 896 * header has already been fixed up above. 897 */ 898 if (mtag == NULL) { 899 memmove(mtod(m, char *) + ifv->ifv_encaplen, 900 mtod(m, void *), sizeof(struct ether_header)); 901 m_adj(m, ifv->ifv_encaplen); 902 } 903 904 m->m_pkthdr.rcvif = &ifv->ifv_if; 905 ifv->ifv_if.if_ipackets++; 906 907 bpf_mtap(&ifv->ifv_if, m); 908 909 m->m_flags &= ~M_PROMISC; 910 ifv->ifv_if.if_input(&ifv->ifv_if, m); 911 } 912