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