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