if_bridge.c revision 148372
1/* $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $ */ 2 3/* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by Jason L. Wright 53 * 4. The name of the author may not be used to endorse or promote products 54 * derived from this software without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 59 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 * 68 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp 69 */ 70 71/* 72 * Network interface bridge support. 73 * 74 * TODO: 75 * 76 * - Currently only supports Ethernet-like interfaces (Ethernet, 77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way 78 * to bridge other types of interfaces (FDDI-FDDI, and maybe 79 * consider heterogenous bridges). 80 */ 81 82#include <sys/cdefs.h> 83__FBSDID("$FreeBSD: head/sys/net/if_bridge.c 148372 2005-07-25 02:22:37Z thompsa $"); 84 85#include "opt_inet.h" 86#include "opt_inet6.h" 87 88#include <sys/param.h> 89#include <sys/mbuf.h> 90#include <sys/malloc.h> 91#include <sys/protosw.h> 92#include <sys/systm.h> 93#include <sys/time.h> 94#include <sys/socket.h> /* for net/if.h */ 95#include <sys/sockio.h> 96#include <sys/ctype.h> /* string functions */ 97#include <sys/kernel.h> 98#include <sys/random.h> 99#include <sys/sysctl.h> 100#include <vm/uma.h> 101#include <sys/module.h> 102#include <sys/proc.h> 103#include <sys/lock.h> 104#include <sys/mutex.h> 105#include <sys/condvar.h> 106 107#include <net/bpf.h> 108#include <net/if.h> 109#include <net/if_clone.h> 110#include <net/if_dl.h> 111#include <net/if_types.h> 112#include <net/if_var.h> 113#include <net/pfil.h> 114 115#include <netinet/in.h> /* for struct arpcom */ 116#include <netinet/in_systm.h> 117#include <netinet/in_var.h> 118#include <netinet/ip.h> 119#include <netinet/ip_var.h> 120#ifdef INET6 121#include <netinet/ip6.h> 122#include <netinet6/ip6_var.h> 123#endif 124#include <machine/in_cksum.h> 125#include <netinet/if_ether.h> /* for struct arpcom */ 126#include <net/if_bridgevar.h> 127#include <net/if_llc.h> 128 129#include <net/route.h> 130#include <netinet/ip_fw.h> 131#include <netinet/ip_dummynet.h> 132 133/* 134 * Size of the route hash table. Must be a power of two. 135 */ 136#ifndef BRIDGE_RTHASH_SIZE 137#define BRIDGE_RTHASH_SIZE 1024 138#endif 139 140#define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1) 141 142/* 143 * Maximum number of addresses to cache. 144 */ 145#ifndef BRIDGE_RTABLE_MAX 146#define BRIDGE_RTABLE_MAX 100 147#endif 148 149/* 150 * Spanning tree defaults. 151 */ 152#define BSTP_DEFAULT_MAX_AGE (20 * 256) 153#define BSTP_DEFAULT_HELLO_TIME (2 * 256) 154#define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 155#define BSTP_DEFAULT_HOLD_TIME (1 * 256) 156#define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 157#define BSTP_DEFAULT_PORT_PRIORITY 0x80 158#define BSTP_DEFAULT_PATH_COST 55 159 160/* 161 * Timeout (in seconds) for entries learned dynamically. 162 */ 163#ifndef BRIDGE_RTABLE_TIMEOUT 164#define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */ 165#endif 166 167/* 168 * Number of seconds between walks of the route list. 169 */ 170#ifndef BRIDGE_RTABLE_PRUNE_PERIOD 171#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60) 172#endif 173 174static struct mtx bridge_list_mtx; 175 176extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *); 177extern int (*bridge_output_p)(struct ifnet *, struct mbuf *, 178 struct sockaddr *, struct rtentry *); 179extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *); 180 181int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; 182 183uma_zone_t bridge_rtnode_zone; 184 185int bridge_clone_create(struct if_clone *, int); 186void bridge_clone_destroy(struct ifnet *); 187 188int bridge_ioctl(struct ifnet *, u_long, caddr_t); 189static void bridge_init(void *); 190void bridge_stop(struct ifnet *, int); 191void bridge_start(struct ifnet *); 192 193void bridge_forward(struct bridge_softc *, struct mbuf *m); 194 195void bridge_timer(void *); 196 197void bridge_broadcast(struct bridge_softc *, struct ifnet *, struct mbuf *); 198 199int bridge_rtupdate(struct bridge_softc *, const uint8_t *, 200 struct ifnet *, int, uint8_t); 201struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *); 202void bridge_rttrim(struct bridge_softc *); 203void bridge_rtage(struct bridge_softc *); 204void bridge_rtflush(struct bridge_softc *, int); 205int bridge_rtdaddr(struct bridge_softc *, const uint8_t *); 206 207int bridge_rtable_init(struct bridge_softc *); 208void bridge_rtable_fini(struct bridge_softc *); 209 210struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *, 211 const uint8_t *); 212int bridge_rtnode_insert(struct bridge_softc *, struct bridge_rtnode *); 213void bridge_rtnode_destroy(struct bridge_softc *, struct bridge_rtnode *); 214 215struct bridge_iflist *bridge_lookup_member(struct bridge_softc *, 216 const char *name); 217struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *, 218 struct ifnet *ifp); 219void bridge_delete_member(struct bridge_softc *, struct bridge_iflist *); 220 221int bridge_ioctl_add(struct bridge_softc *, void *); 222int bridge_ioctl_del(struct bridge_softc *, void *); 223int bridge_ioctl_gifflags(struct bridge_softc *, void *); 224int bridge_ioctl_sifflags(struct bridge_softc *, void *); 225int bridge_ioctl_scache(struct bridge_softc *, void *); 226int bridge_ioctl_gcache(struct bridge_softc *, void *); 227int bridge_ioctl_gifs(struct bridge_softc *, void *); 228int bridge_ioctl_rts(struct bridge_softc *, void *); 229int bridge_ioctl_saddr(struct bridge_softc *, void *); 230int bridge_ioctl_sto(struct bridge_softc *, void *); 231int bridge_ioctl_gto(struct bridge_softc *, void *); 232int bridge_ioctl_daddr(struct bridge_softc *, void *); 233int bridge_ioctl_flush(struct bridge_softc *, void *); 234int bridge_ioctl_gpri(struct bridge_softc *, void *); 235int bridge_ioctl_spri(struct bridge_softc *, void *); 236int bridge_ioctl_ght(struct bridge_softc *, void *); 237int bridge_ioctl_sht(struct bridge_softc *, void *); 238int bridge_ioctl_gfd(struct bridge_softc *, void *); 239int bridge_ioctl_sfd(struct bridge_softc *, void *); 240int bridge_ioctl_gma(struct bridge_softc *, void *); 241int bridge_ioctl_sma(struct bridge_softc *, void *); 242int bridge_ioctl_sifprio(struct bridge_softc *, void *); 243int bridge_ioctl_sifcost(struct bridge_softc *, void *); 244static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *, int); 245static int bridge_ip_checkbasic(struct mbuf **mp); 246# ifdef INET6 247static int bridge_ip6_checkbasic(struct mbuf **mp); 248# endif /* INET6 */ 249 250SYSCTL_DECL(_net_link); 251SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge"); 252 253static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */ 254static int pfil_member = 1; /* run pfil hooks on the member interface */ 255static int pfil_ipfw = 0; /* layer2 filter with ipfw */ 256SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW, 257 &pfil_bridge, 0, "Packet filter on the bridge interface"); 258SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW, 259 &pfil_member, 0, "Packet filter on the member interface"); 260 261struct bridge_control { 262 int (*bc_func)(struct bridge_softc *, void *); 263 int bc_argsize; 264 int bc_flags; 265}; 266 267#define BC_F_COPYIN 0x01 /* copy arguments in */ 268#define BC_F_COPYOUT 0x02 /* copy arguments out */ 269#define BC_F_SUSER 0x04 /* do super-user check */ 270 271const struct bridge_control bridge_control_table[] = { 272 { bridge_ioctl_add, sizeof(struct ifbreq), 273 BC_F_COPYIN|BC_F_SUSER }, 274 { bridge_ioctl_del, sizeof(struct ifbreq), 275 BC_F_COPYIN|BC_F_SUSER }, 276 277 { bridge_ioctl_gifflags, sizeof(struct ifbreq), 278 BC_F_COPYIN|BC_F_COPYOUT }, 279 { bridge_ioctl_sifflags, sizeof(struct ifbreq), 280 BC_F_COPYIN|BC_F_SUSER }, 281 282 { bridge_ioctl_scache, sizeof(struct ifbrparam), 283 BC_F_COPYIN|BC_F_SUSER }, 284 { bridge_ioctl_gcache, sizeof(struct ifbrparam), 285 BC_F_COPYOUT }, 286 287 { bridge_ioctl_gifs, sizeof(struct ifbifconf), 288 BC_F_COPYIN|BC_F_COPYOUT }, 289 { bridge_ioctl_rts, sizeof(struct ifbaconf), 290 BC_F_COPYIN|BC_F_COPYOUT }, 291 292 { bridge_ioctl_saddr, sizeof(struct ifbareq), 293 BC_F_COPYIN|BC_F_SUSER }, 294 295 { bridge_ioctl_sto, sizeof(struct ifbrparam), 296 BC_F_COPYIN|BC_F_SUSER }, 297 { bridge_ioctl_gto, sizeof(struct ifbrparam), 298 BC_F_COPYOUT }, 299 300 { bridge_ioctl_daddr, sizeof(struct ifbareq), 301 BC_F_COPYIN|BC_F_SUSER }, 302 303 { bridge_ioctl_flush, sizeof(struct ifbreq), 304 BC_F_COPYIN|BC_F_SUSER }, 305 306 { bridge_ioctl_gpri, sizeof(struct ifbrparam), 307 BC_F_COPYOUT }, 308 { bridge_ioctl_spri, sizeof(struct ifbrparam), 309 BC_F_COPYIN|BC_F_SUSER }, 310 311 { bridge_ioctl_ght, sizeof(struct ifbrparam), 312 BC_F_COPYOUT }, 313 { bridge_ioctl_sht, sizeof(struct ifbrparam), 314 BC_F_COPYIN|BC_F_SUSER }, 315 316 { bridge_ioctl_gfd, sizeof(struct ifbrparam), 317 BC_F_COPYOUT }, 318 { bridge_ioctl_sfd, sizeof(struct ifbrparam), 319 BC_F_COPYIN|BC_F_SUSER }, 320 321 { bridge_ioctl_gma, sizeof(struct ifbrparam), 322 BC_F_COPYOUT }, 323 { bridge_ioctl_sma, sizeof(struct ifbrparam), 324 BC_F_COPYIN|BC_F_SUSER }, 325 326 { bridge_ioctl_sifprio, sizeof(struct ifbreq), 327 BC_F_COPYIN|BC_F_SUSER }, 328 329 { bridge_ioctl_sifcost, sizeof(struct ifbreq), 330 BC_F_COPYIN|BC_F_SUSER }, 331}; 332const int bridge_control_table_size = 333 sizeof(bridge_control_table) / sizeof(bridge_control_table[0]); 334 335LIST_HEAD(, bridge_softc) bridge_list; 336 337IFC_SIMPLE_DECLARE(bridge, 0); 338 339static int 340bridge_modevent(module_t mod, int type, void *data) 341{ 342 343 switch (type) { 344 case MOD_LOAD: 345 mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF); 346 if_clone_attach(&bridge_cloner); 347 bridge_rtnode_zone = uma_zcreate("bridge_rtnode", 348 sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL, 349 UMA_ALIGN_PTR, 0); 350 LIST_INIT(&bridge_list); 351 bridge_input_p = bridge_input; 352 bridge_output_p = bridge_output; 353 bridge_dn_p = bridge_dummynet; 354 bstp_linkstate_p = bstp_linkstate; 355 break; 356 case MOD_UNLOAD: 357 if_clone_detach(&bridge_cloner); 358 while (!LIST_EMPTY(&bridge_list)) 359 bridge_clone_destroy(LIST_FIRST(&bridge_list)->sc_ifp); 360 uma_zdestroy(bridge_rtnode_zone); 361 bridge_input_p = NULL; 362 bridge_output_p = NULL; 363 bridge_dn_p = NULL; 364 bstp_linkstate_p = NULL; 365 mtx_destroy(&bridge_list_mtx); 366 break; 367 default: 368 return EOPNOTSUPP; 369 } 370 return 0; 371} 372 373static moduledata_t bridge_mod = { 374 "if_bridge", 375 bridge_modevent, 376 0 377}; 378 379DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 380 381/* 382 * handler for net.link.bridge.pfil_ipfw 383 */ 384static int 385sysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS) 386{ 387 int enable = pfil_ipfw; 388 int error; 389 390 error = sysctl_handle_int(oidp, &enable, 0, req); 391 enable = (enable) ? 1 : 0; 392 393 if (enable != pfil_ipfw) { 394 pfil_ipfw = enable; 395 396 /* 397 * Disable pfil so that ipfw doesnt run twice, if the user really wants 398 * both then they can re-enable pfil_bridge and/or pfil_member. 399 */ 400 if (pfil_ipfw) { 401 pfil_bridge = 0; 402 pfil_member = 0; 403 } 404 } 405 406 return error; 407} 408SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW, 409 &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW"); 410 411/* 412 * bridge_clone_create: 413 * 414 * Create a new bridge instance. 415 */ 416int 417bridge_clone_create(struct if_clone *ifc, int unit) 418{ 419 struct bridge_softc *sc; 420 struct ifnet *ifp; 421 u_char eaddr[6]; 422 423 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); 424 BRIDGE_LOCK_INIT(sc); 425 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); 426 if (ifp == NULL) { 427 free(sc, M_DEVBUF); 428 return (ENOSPC); 429 } 430 431 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 432 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 433 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 434 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME; 435 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY; 436 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 437 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME; 438 439 /* Initialize our routing table. */ 440 bridge_rtable_init(sc); 441 442 callout_init(&sc->sc_brcallout, 0); 443 callout_init(&sc->sc_bstpcallout, 0); 444 445 LIST_INIT(&sc->sc_iflist); 446 447 ifp->if_softc = sc; 448 if_initname(ifp, ifc->ifc_name, unit); 449 ifp->if_mtu = ETHERMTU; 450 ifp->if_ioctl = bridge_ioctl; 451 ifp->if_output = bridge_output; 452 ifp->if_start = bridge_start; 453 ifp->if_init = bridge_init; 454 ifp->if_type = IFT_BRIDGE; 455 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 456 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 457 IFQ_SET_READY(&ifp->if_snd); 458 ifp->if_hdrlen = ETHER_HDR_LEN; 459 460 /* 461 * Generate a random ethernet address and use the private AC:DE:48 462 * OUI code. 463 */ 464 arc4rand(eaddr, ETHER_ADDR_LEN, 1); 465 eaddr[0] = 0xAC; 466 eaddr[1] = 0xDE; 467 eaddr[2] = 0x48; 468 469 ether_ifattach(ifp, eaddr); 470 /* Now undo some of the damage... */ 471 ifp->if_baudrate = 0; 472 ifp->if_type = IFT_BRIDGE; 473 474 mtx_lock(&bridge_list_mtx); 475 LIST_INSERT_HEAD(&bridge_list, sc, sc_list); 476 mtx_unlock(&bridge_list_mtx); 477 478 return (0); 479} 480 481/* 482 * bridge_clone_destroy: 483 * 484 * Destroy a bridge instance. 485 */ 486void 487bridge_clone_destroy(struct ifnet *ifp) 488{ 489 struct bridge_softc *sc = ifp->if_softc; 490 struct bridge_iflist *bif; 491 492 BRIDGE_LOCK(sc); 493 494 bridge_stop(ifp, 1); 495 496 while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) 497 bridge_delete_member(sc, bif); 498 499 BRIDGE_UNLOCK(sc); 500 501 mtx_lock(&bridge_list_mtx); 502 LIST_REMOVE(sc, sc_list); 503 mtx_unlock(&bridge_list_mtx); 504 505 ether_ifdetach(ifp); 506 if_free_type(ifp, IFT_ETHER); 507 508 /* Tear down the routing table. */ 509 bridge_rtable_fini(sc); 510 511 BRIDGE_LOCK_DESTROY(sc); 512 free(sc, M_DEVBUF); 513} 514 515/* 516 * bridge_ioctl: 517 * 518 * Handle a control request from the operator. 519 */ 520int 521bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 522{ 523 struct bridge_softc *sc = ifp->if_softc; 524 struct thread *td = curthread; 525 union { 526 struct ifbreq ifbreq; 527 struct ifbifconf ifbifconf; 528 struct ifbareq ifbareq; 529 struct ifbaconf ifbaconf; 530 struct ifbrparam ifbrparam; 531 } args; 532 struct ifdrv *ifd = (struct ifdrv *) data; 533 const struct bridge_control *bc; 534 int error = 0; 535 536 BRIDGE_LOCK(sc); 537 538 switch (cmd) { 539 540 case SIOCGDRVSPEC: 541 case SIOCSDRVSPEC: 542 if (ifd->ifd_cmd >= bridge_control_table_size) { 543 error = EINVAL; 544 break; 545 } 546 bc = &bridge_control_table[ifd->ifd_cmd]; 547 548 if (cmd == SIOCGDRVSPEC && 549 (bc->bc_flags & BC_F_COPYOUT) == 0) { 550 error = EINVAL; 551 break; 552 } 553 else if (cmd == SIOCSDRVSPEC && 554 (bc->bc_flags & BC_F_COPYOUT) != 0) { 555 error = EINVAL; 556 break; 557 } 558 559 if (bc->bc_flags & BC_F_SUSER) { 560 error = suser(td); 561 if (error) 562 break; 563 } 564 565 if (ifd->ifd_len != bc->bc_argsize || 566 ifd->ifd_len > sizeof(args)) { 567 error = EINVAL; 568 break; 569 } 570 571 if (bc->bc_flags & BC_F_COPYIN) { 572 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); 573 if (error) 574 break; 575 } 576 577 error = (*bc->bc_func)(sc, &args); 578 if (error) 579 break; 580 581 if (bc->bc_flags & BC_F_COPYOUT) 582 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); 583 584 break; 585 586 case SIOCSIFFLAGS: 587 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) { 588 /* 589 * If interface is marked down and it is running, 590 * then stop and disable it. 591 */ 592 bridge_stop(ifp, 1); 593 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) { 594 /* 595 * If interface is marked up and it is stopped, then 596 * start it. 597 */ 598 (*ifp->if_init)(sc); 599 } 600 break; 601 602 case SIOCSIFMTU: 603 /* Do not allow the MTU to be changed on the bridge */ 604 error = EINVAL; 605 break; 606 607 default: 608 /* 609 * drop the lock as ether_ioctl() will call bridge_start() and 610 * cause the lock to be recursed. 611 */ 612 BRIDGE_UNLOCK(sc); 613 error = ether_ioctl(ifp, cmd, data); 614 break; 615 } 616 617 if (BRIDGE_LOCKED(sc)) 618 BRIDGE_UNLOCK(sc); 619 620 return (error); 621} 622 623/* 624 * bridge_lookup_member: 625 * 626 * Lookup a bridge member interface. 627 */ 628struct bridge_iflist * 629bridge_lookup_member(struct bridge_softc *sc, const char *name) 630{ 631 struct bridge_iflist *bif; 632 struct ifnet *ifp; 633 634 BRIDGE_LOCK_ASSERT(sc); 635 636 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 637 ifp = bif->bif_ifp; 638 if (strcmp(ifp->if_xname, name) == 0) 639 return (bif); 640 } 641 642 return (NULL); 643} 644 645/* 646 * bridge_lookup_member_if: 647 * 648 * Lookup a bridge member interface by ifnet*. 649 */ 650struct bridge_iflist * 651bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp) 652{ 653 struct bridge_iflist *bif; 654 655 BRIDGE_LOCK_ASSERT(sc); 656 657 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 658 if (bif->bif_ifp == member_ifp) 659 return (bif); 660 } 661 662 return (NULL); 663} 664 665/* 666 * bridge_delete_member: 667 * 668 * Delete the specified member interface. 669 */ 670void 671bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif) 672{ 673 struct ifnet *ifs = bif->bif_ifp; 674 675 BRIDGE_LOCK_ASSERT(sc); 676 677 switch (ifs->if_type) { 678 case IFT_ETHER: 679 case IFT_L2VLAN: 680 /* 681 * Take the interface out of promiscuous mode. 682 */ 683 (void) ifpromisc(ifs, 0); 684 break; 685 686 default: 687#ifdef DIAGNOSTIC 688 panic("bridge_delete_member: impossible"); 689#endif 690 break; 691 } 692 693 ifs->if_bridge = NULL; 694 BRIDGE_XLOCK(sc); 695 LIST_REMOVE(bif, bif_next); 696 BRIDGE_XDROP(sc); 697 698 bridge_rtdelete(sc, ifs, IFBF_FLUSHALL); 699 700 free(bif, M_DEVBUF); 701 702 if (sc->sc_ifp->if_flags & IFF_RUNNING) 703 bstp_initialization(sc); 704} 705 706int 707bridge_ioctl_add(struct bridge_softc *sc, void *arg) 708{ 709 struct ifbreq *req = arg; 710 struct bridge_iflist *bif = NULL; 711 struct ifnet *ifs; 712 int error = 0; 713 714 BRIDGE_LOCK_ASSERT(sc); 715 716 ifs = ifunit(req->ifbr_ifsname); 717 if (ifs == NULL) 718 return (ENOENT); 719 720 /* Allow the first member to define the MTU */ 721 if (LIST_EMPTY(&sc->sc_iflist)) 722 sc->sc_ifp->if_mtu = ifs->if_mtu; 723 else if (sc->sc_ifp->if_mtu != ifs->if_mtu) { 724 if_printf(sc->sc_ifp, "invalid MTU for %s\n", ifs->if_xname); 725 return (EINVAL); 726 } 727 728 if (ifs->if_bridge == sc) 729 return (EEXIST); 730 731 if (ifs->if_bridge != NULL) 732 return (EBUSY); 733 734 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT); 735 if (bif == NULL) 736 return (ENOMEM); 737 738 switch (ifs->if_type) { 739 case IFT_ETHER: 740 case IFT_L2VLAN: 741 /* 742 * Place the interface into promiscuous mode. 743 */ 744 error = ifpromisc(ifs, 1); 745 if (error) 746 goto out; 747 break; 748 749 default: 750 error = EINVAL; 751 goto out; 752 } 753 754 bif->bif_ifp = ifs; 755 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 756 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; 757 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST; 758 759 ifs->if_bridge = sc; 760 /* 761 * XXX: XLOCK HERE!?! 762 * 763 * NOTE: insert_***HEAD*** should be safe for the traversals. 764 */ 765 LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next); 766 767 if (sc->sc_ifp->if_flags & IFF_RUNNING) 768 bstp_initialization(sc); 769 else 770 bstp_stop(sc); 771 772 out: 773 if (error) { 774 if (bif != NULL) 775 free(bif, M_DEVBUF); 776 } 777 return (error); 778} 779 780int 781bridge_ioctl_del(struct bridge_softc *sc, void *arg) 782{ 783 struct ifbreq *req = arg; 784 struct bridge_iflist *bif; 785 786 BRIDGE_LOCK_ASSERT(sc); 787 788 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 789 if (bif == NULL) 790 return (ENOENT); 791 792 bridge_delete_member(sc, bif); 793 794 return (0); 795} 796 797int 798bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) 799{ 800 struct ifbreq *req = arg; 801 struct bridge_iflist *bif; 802 803 BRIDGE_LOCK_ASSERT(sc); 804 805 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 806 if (bif == NULL) 807 return (ENOENT); 808 809 req->ifbr_ifsflags = bif->bif_flags; 810 req->ifbr_state = bif->bif_state; 811 req->ifbr_priority = bif->bif_priority; 812 req->ifbr_path_cost = bif->bif_path_cost; 813 req->ifbr_portno = bif->bif_ifp->if_index & 0xff; 814 815 return (0); 816} 817 818int 819bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) 820{ 821 struct ifbreq *req = arg; 822 struct bridge_iflist *bif; 823 824 BRIDGE_LOCK_ASSERT(sc); 825 826 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 827 if (bif == NULL) 828 return (ENOENT); 829 830 if (req->ifbr_ifsflags & IFBIF_STP) { 831 switch (bif->bif_ifp->if_type) { 832 case IFT_ETHER: 833 /* These can do spanning tree. */ 834 break; 835 836 default: 837 /* Nothing else can. */ 838 return (EINVAL); 839 } 840 } 841 842 bif->bif_flags = req->ifbr_ifsflags; 843 844 if (sc->sc_ifp->if_flags & IFF_RUNNING) 845 bstp_initialization(sc); 846 847 return (0); 848} 849 850int 851bridge_ioctl_scache(struct bridge_softc *sc, void *arg) 852{ 853 struct ifbrparam *param = arg; 854 855 BRIDGE_LOCK_ASSERT(sc); 856 857 sc->sc_brtmax = param->ifbrp_csize; 858 bridge_rttrim(sc); 859 860 return (0); 861} 862 863int 864bridge_ioctl_gcache(struct bridge_softc *sc, void *arg) 865{ 866 struct ifbrparam *param = arg; 867 868 BRIDGE_LOCK_ASSERT(sc); 869 870 param->ifbrp_csize = sc->sc_brtmax; 871 872 return (0); 873} 874 875int 876bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) 877{ 878 struct ifbifconf *bifc = arg; 879 struct bridge_iflist *bif; 880 struct ifbreq breq; 881 int count, len, error = 0; 882 883 BRIDGE_LOCK_ASSERT(sc); 884 885 count = 0; 886 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) 887 count++; 888 889 if (bifc->ifbic_len == 0) { 890 bifc->ifbic_len = sizeof(breq) * count; 891 return (0); 892 } 893 894 count = 0; 895 len = bifc->ifbic_len; 896 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 897 if (len < sizeof(breq)) 898 break; 899 900 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname, 901 sizeof(breq.ifbr_ifsname)); 902 breq.ifbr_ifsflags = bif->bif_flags; 903 breq.ifbr_state = bif->bif_state; 904 breq.ifbr_priority = bif->bif_priority; 905 breq.ifbr_path_cost = bif->bif_path_cost; 906 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff; 907 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq)); 908 if (error) 909 break; 910 count++; 911 len -= sizeof(breq); 912 } 913 914 bifc->ifbic_len = sizeof(breq) * count; 915 return (error); 916} 917 918int 919bridge_ioctl_rts(struct bridge_softc *sc, void *arg) 920{ 921 struct ifbaconf *bac = arg; 922 struct bridge_rtnode *brt; 923 struct ifbareq bareq; 924 struct timeval tv; 925 int count = 0, error = 0, len; 926 927 BRIDGE_LOCK_ASSERT(sc); 928 929 if (bac->ifbac_len == 0) 930 return (0); 931 932 getmicrotime(&tv); 933 934 len = bac->ifbac_len; 935 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 936 if (len < sizeof(bareq)) 937 goto out; 938 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, 939 sizeof(bareq.ifba_ifsname)); 940 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); 941 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && 942 tv.tv_sec < brt->brt_expire) 943 bareq.ifba_expire = brt->brt_expire - tv.tv_sec; 944 else 945 bareq.ifba_expire = 0; 946 bareq.ifba_flags = brt->brt_flags; 947 948 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq)); 949 if (error) 950 goto out; 951 count++; 952 len -= sizeof(bareq); 953 } 954 out: 955 bac->ifbac_len = sizeof(bareq) * count; 956 return (error); 957} 958 959int 960bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) 961{ 962 struct ifbareq *req = arg; 963 struct bridge_iflist *bif; 964 int error; 965 966 BRIDGE_LOCK_ASSERT(sc); 967 968 bif = bridge_lookup_member(sc, req->ifba_ifsname); 969 if (bif == NULL) 970 return (ENOENT); 971 972 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1, 973 req->ifba_flags); 974 975 return (error); 976} 977 978int 979bridge_ioctl_sto(struct bridge_softc *sc, void *arg) 980{ 981 struct ifbrparam *param = arg; 982 983 BRIDGE_LOCK_ASSERT(sc); 984 985 sc->sc_brttimeout = param->ifbrp_ctime; 986 987 return (0); 988} 989 990int 991bridge_ioctl_gto(struct bridge_softc *sc, void *arg) 992{ 993 struct ifbrparam *param = arg; 994 995 BRIDGE_LOCK_ASSERT(sc); 996 997 param->ifbrp_ctime = sc->sc_brttimeout; 998 999 return (0); 1000} 1001 1002int 1003bridge_ioctl_daddr(struct bridge_softc *sc, void *arg) 1004{ 1005 struct ifbareq *req = arg; 1006 1007 BRIDGE_LOCK_ASSERT(sc); 1008 1009 return (bridge_rtdaddr(sc, req->ifba_dst)); 1010} 1011 1012int 1013bridge_ioctl_flush(struct bridge_softc *sc, void *arg) 1014{ 1015 struct ifbreq *req = arg; 1016 1017 BRIDGE_LOCK_ASSERT(sc); 1018 1019 bridge_rtflush(sc, req->ifbr_ifsflags); 1020 1021 return (0); 1022} 1023 1024int 1025bridge_ioctl_gpri(struct bridge_softc *sc, void *arg) 1026{ 1027 struct ifbrparam *param = arg; 1028 1029 BRIDGE_LOCK_ASSERT(sc); 1030 1031 param->ifbrp_prio = sc->sc_bridge_priority; 1032 1033 return (0); 1034} 1035 1036int 1037bridge_ioctl_spri(struct bridge_softc *sc, void *arg) 1038{ 1039 struct ifbrparam *param = arg; 1040 1041 BRIDGE_LOCK_ASSERT(sc); 1042 1043 sc->sc_bridge_priority = param->ifbrp_prio; 1044 1045 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1046 bstp_initialization(sc); 1047 1048 return (0); 1049} 1050 1051int 1052bridge_ioctl_ght(struct bridge_softc *sc, void *arg) 1053{ 1054 struct ifbrparam *param = arg; 1055 1056 BRIDGE_LOCK_ASSERT(sc); 1057 1058 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8; 1059 1060 return (0); 1061} 1062 1063int 1064bridge_ioctl_sht(struct bridge_softc *sc, void *arg) 1065{ 1066 struct ifbrparam *param = arg; 1067 1068 BRIDGE_LOCK_ASSERT(sc); 1069 1070 if (param->ifbrp_hellotime == 0) 1071 return (EINVAL); 1072 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8; 1073 1074 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1075 bstp_initialization(sc); 1076 1077 return (0); 1078} 1079 1080int 1081bridge_ioctl_gfd(struct bridge_softc *sc, void *arg) 1082{ 1083 struct ifbrparam *param = arg; 1084 1085 BRIDGE_LOCK_ASSERT(sc); 1086 1087 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8; 1088 1089 return (0); 1090} 1091 1092int 1093bridge_ioctl_sfd(struct bridge_softc *sc, void *arg) 1094{ 1095 struct ifbrparam *param = arg; 1096 1097 BRIDGE_LOCK_ASSERT(sc); 1098 1099 if (param->ifbrp_fwddelay == 0) 1100 return (EINVAL); 1101 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8; 1102 1103 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1104 bstp_initialization(sc); 1105 1106 return (0); 1107} 1108 1109int 1110bridge_ioctl_gma(struct bridge_softc *sc, void *arg) 1111{ 1112 struct ifbrparam *param = arg; 1113 1114 BRIDGE_LOCK_ASSERT(sc); 1115 1116 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8; 1117 1118 return (0); 1119} 1120 1121int 1122bridge_ioctl_sma(struct bridge_softc *sc, void *arg) 1123{ 1124 struct ifbrparam *param = arg; 1125 1126 BRIDGE_LOCK_ASSERT(sc); 1127 1128 if (param->ifbrp_maxage == 0) 1129 return (EINVAL); 1130 sc->sc_bridge_max_age = param->ifbrp_maxage << 8; 1131 1132 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1133 bstp_initialization(sc); 1134 1135 return (0); 1136} 1137 1138int 1139bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) 1140{ 1141 struct ifbreq *req = arg; 1142 struct bridge_iflist *bif; 1143 1144 BRIDGE_LOCK_ASSERT(sc); 1145 1146 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 1147 if (bif == NULL) 1148 return (ENOENT); 1149 1150 bif->bif_priority = req->ifbr_priority; 1151 1152 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1153 bstp_initialization(sc); 1154 1155 return (0); 1156} 1157 1158int 1159bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) 1160{ 1161 struct ifbreq *req = arg; 1162 struct bridge_iflist *bif; 1163 1164 BRIDGE_LOCK_ASSERT(sc); 1165 1166 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 1167 if (bif == NULL) 1168 return (ENOENT); 1169 1170 bif->bif_path_cost = req->ifbr_path_cost; 1171 1172 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1173 bstp_initialization(sc); 1174 1175 return (0); 1176} 1177 1178/* 1179 * bridge_ifdetach: 1180 * 1181 * Detach an interface from a bridge. Called when a member 1182 * interface is detaching. 1183 */ 1184void 1185bridge_ifdetach(struct ifnet *ifp) 1186{ 1187 struct bridge_softc *sc = ifp->if_bridge; 1188 struct ifbreq breq; 1189 1190 BRIDGE_LOCK_ASSERT(sc); 1191 1192 memset(&breq, 0, sizeof(breq)); 1193 snprintf(breq.ifbr_ifsname, sizeof(breq.ifbr_ifsname), ifp->if_xname); 1194 1195 (void) bridge_ioctl_del(sc, &breq); 1196} 1197 1198/* 1199 * bridge_init: 1200 * 1201 * Initialize a bridge interface. 1202 */ 1203static void 1204bridge_init(void *xsc) 1205{ 1206 struct bridge_softc *sc = (struct bridge_softc *)xsc; 1207 struct ifnet *ifp = sc->sc_ifp; 1208 1209 if (ifp->if_flags & IFF_RUNNING) 1210 return; 1211 1212 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, 1213 bridge_timer, sc); 1214 1215 ifp->if_flags |= IFF_RUNNING; 1216 bstp_initialization(sc); 1217 return; 1218} 1219 1220/* 1221 * bridge_stop: 1222 * 1223 * Stop the bridge interface. 1224 */ 1225void 1226bridge_stop(struct ifnet *ifp, int disable) 1227{ 1228 struct bridge_softc *sc = ifp->if_softc; 1229 1230 if ((ifp->if_flags & IFF_RUNNING) == 0) 1231 return; 1232 1233 callout_stop(&sc->sc_brcallout); 1234 bstp_stop(sc); 1235 1236 bridge_rtflush(sc, IFBF_FLUSHDYN); 1237 1238 ifp->if_flags &= ~IFF_RUNNING; 1239} 1240 1241/* 1242 * bridge_enqueue: 1243 * 1244 * Enqueue a packet on a bridge member interface. 1245 * 1246 */ 1247__inline void 1248bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m) 1249{ 1250 int len, err; 1251 short mflags; 1252 1253 /* 1254 * Clear any in-bound checksum flags for this packet. 1255 */ 1256 m->m_pkthdr.csum_flags = 0; 1257 1258 len = m->m_pkthdr.len; 1259 mflags = m->m_flags; 1260 1261#ifdef INVARIANTS 1262 if (len > dst_ifp->if_mtu) 1263 if_printf(sc->sc_ifp, 1264 "MTU mismatch, frame length %d exceeds %ld on %s\n", len, 1265 dst_ifp->if_mtu, dst_ifp->if_xname); 1266#endif 1267 1268 IFQ_ENQUEUE(&dst_ifp->if_snd, m, err); 1269 if (err == 0) { 1270 1271 sc->sc_ifp->if_opackets++; 1272 sc->sc_ifp->if_obytes += len; 1273 1274 dst_ifp->if_obytes += len; 1275 1276 if (mflags & M_MCAST) { 1277 sc->sc_ifp->if_omcasts++; 1278 dst_ifp->if_omcasts++; 1279 } 1280 } 1281 1282 if ((dst_ifp->if_flags & IFF_OACTIVE) == 0) 1283 (*dst_ifp->if_start)(dst_ifp); 1284} 1285 1286/* 1287 * bridge_dummynet: 1288 * 1289 * Receive a queued packet from dummynet and pass it on to the output 1290 * interface. 1291 * 1292 * The mbuf has the Ethernet header already attached. 1293 */ 1294void 1295bridge_dummynet(struct mbuf *m, struct ifnet *ifp) 1296{ 1297 struct bridge_softc *sc; 1298 1299 sc = ifp->if_bridge; 1300 1301 /* 1302 * The packet didnt originate from a member interface. This should only 1303 * ever happen if a member interface is removed while packets are 1304 * queued for it. 1305 */ 1306 if (sc == NULL) { 1307 m_freem(m); 1308 return; 1309 } 1310 1311 if (inet_pfil_hook.ph_busy_count >= 0 1312#ifdef INET6 1313 || inet6_pfil_hook.ph_busy_count >= 0 1314#endif 1315 ) { 1316 if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0) 1317 return; 1318 if (m == NULL) 1319 return; 1320 } 1321 1322 bridge_enqueue(sc, ifp, m); 1323} 1324 1325/* 1326 * bridge_output: 1327 * 1328 * Send output from a bridge member interface. This 1329 * performs the bridging function for locally originated 1330 * packets. 1331 * 1332 * The mbuf has the Ethernet header already attached. We must 1333 * enqueue or free the mbuf before returning. 1334 */ 1335int 1336bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, 1337 struct rtentry *rt) 1338{ 1339 struct ether_header *eh; 1340 struct ifnet *dst_if; 1341 struct bridge_softc *sc; 1342 1343 if (m->m_len < ETHER_HDR_LEN) { 1344 m = m_pullup(m, ETHER_HDR_LEN); 1345 if (m == NULL) 1346 return (0); 1347 } 1348 1349 eh = mtod(m, struct ether_header *); 1350 sc = ifp->if_bridge; 1351 1352 BRIDGE_LOCK(sc); 1353 1354 /* 1355 * If bridge is down, but the original output interface is up, 1356 * go ahead and send out that interface. Otherwise, the packet 1357 * is dropped below. 1358 */ 1359 if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) { 1360 dst_if = ifp; 1361 goto sendunicast; 1362 } 1363 1364 /* 1365 * If the packet is a multicast, or we don't know a better way to 1366 * get there, send to all interfaces. 1367 */ 1368 if (ETHER_IS_MULTICAST(eh->ether_dhost)) 1369 dst_if = NULL; 1370 else 1371 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1372 if (dst_if == NULL) { 1373 struct bridge_iflist *bif; 1374 struct mbuf *mc; 1375 int error = 0, used = 0; 1376 1377 BRIDGE_LOCK2REF(sc, error); 1378 if (error) { 1379 m_freem(m); 1380 return (0); 1381 } 1382 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1383 dst_if = bif->bif_ifp; 1384 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1385 continue; 1386 1387 /* 1388 * If this is not the original output interface, 1389 * and the interface is participating in spanning 1390 * tree, make sure the port is in a state that 1391 * allows forwarding. 1392 */ 1393 if (dst_if != ifp && 1394 (bif->bif_flags & IFBIF_STP) != 0) { 1395 switch (bif->bif_state) { 1396 case BSTP_IFSTATE_BLOCKING: 1397 case BSTP_IFSTATE_LISTENING: 1398 case BSTP_IFSTATE_DISABLED: 1399 continue; 1400 } 1401 } 1402 1403 if (LIST_NEXT(bif, bif_next) == NULL) { 1404 used = 1; 1405 mc = m; 1406 } else { 1407 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1408 if (mc == NULL) { 1409 sc->sc_ifp->if_oerrors++; 1410 continue; 1411 } 1412 } 1413 1414 bridge_enqueue(sc, dst_if, mc); 1415 } 1416 if (used == 0) 1417 m_freem(m); 1418 BRIDGE_UNREF(sc); 1419 return (0); 1420 } 1421 1422 sendunicast: 1423 /* 1424 * XXX Spanning tree consideration here? 1425 */ 1426 1427 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1428 m_freem(m); 1429 BRIDGE_UNLOCK(sc); 1430 return (0); 1431 } 1432 1433 BRIDGE_UNLOCK(sc); 1434 bridge_enqueue(sc, dst_if, m); 1435 return (0); 1436} 1437 1438/* 1439 * bridge_start: 1440 * 1441 * Start output on a bridge. 1442 * 1443 */ 1444void 1445bridge_start(struct ifnet *ifp) 1446{ 1447 struct bridge_softc *sc; 1448 struct mbuf *m; 1449 struct ether_header *eh; 1450 struct ifnet *dst_if; 1451 1452 sc = ifp->if_softc; 1453 1454 ifp->if_flags |= IFF_OACTIVE; 1455 for (;;) { 1456 IFQ_DEQUEUE(&ifp->if_snd, m); 1457 if (m == 0) 1458 break; 1459 BPF_MTAP(ifp, m); 1460 1461 eh = mtod(m, struct ether_header *); 1462 dst_if = NULL; 1463 1464 BRIDGE_LOCK(sc); 1465 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1466 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1467 } 1468 1469 if (dst_if == NULL) 1470 bridge_broadcast(sc, ifp, m); 1471 else { 1472 BRIDGE_UNLOCK(sc); 1473 1474 if (inet_pfil_hook.ph_busy_count >= 0 1475#ifdef INET6 1476 || inet6_pfil_hook.ph_busy_count >= 0 1477#endif 1478 ) { 1479 if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0) 1480 return; 1481 if (m == NULL) 1482 return; 1483 } 1484 1485 bridge_enqueue(sc, dst_if, m); 1486 } 1487 } 1488 ifp->if_flags &= ~IFF_OACTIVE; 1489 1490 return; 1491} 1492 1493/* 1494 * bridge_forward: 1495 * 1496 * The forwarding function of the bridge. 1497 * 1498 * NOTE: Releases the lock on return. 1499 */ 1500void 1501bridge_forward(struct bridge_softc *sc, struct mbuf *m) 1502{ 1503 struct bridge_iflist *bif; 1504 struct ifnet *src_if, *dst_if, *ifp; 1505 struct ether_header *eh; 1506 1507 src_if = m->m_pkthdr.rcvif; 1508 BRIDGE_LOCK_ASSERT(sc); 1509 ifp = sc->sc_ifp; 1510 1511 sc->sc_ifp->if_ipackets++; 1512 sc->sc_ifp->if_ibytes += m->m_pkthdr.len; 1513 1514 /* 1515 * Look up the bridge_iflist. 1516 */ 1517 bif = bridge_lookup_member_if(sc, src_if); 1518 if (bif == NULL) { 1519 /* Interface is not a bridge member (anymore?) */ 1520 BRIDGE_UNLOCK(sc); 1521 m_freem(m); 1522 return; 1523 } 1524 1525 if (bif->bif_flags & IFBIF_STP) { 1526 switch (bif->bif_state) { 1527 case BSTP_IFSTATE_BLOCKING: 1528 case BSTP_IFSTATE_LISTENING: 1529 case BSTP_IFSTATE_DISABLED: 1530 BRIDGE_UNLOCK(sc); 1531 m_freem(m); 1532 return; 1533 } 1534 } 1535 1536 eh = mtod(m, struct ether_header *); 1537 1538 /* 1539 * If the interface is learning, and the source 1540 * address is valid and not multicast, record 1541 * the address. 1542 */ 1543 if ((bif->bif_flags & IFBIF_LEARNING) != 0 && 1544 ETHER_IS_MULTICAST(eh->ether_shost) == 0 && 1545 (eh->ether_shost[0] == 0 && 1546 eh->ether_shost[1] == 0 && 1547 eh->ether_shost[2] == 0 && 1548 eh->ether_shost[3] == 0 && 1549 eh->ether_shost[4] == 0 && 1550 eh->ether_shost[5] == 0) == 0) { 1551 (void) bridge_rtupdate(sc, eh->ether_shost, 1552 src_if, 0, IFBAF_DYNAMIC); 1553 } 1554 1555 if ((bif->bif_flags & IFBIF_STP) != 0 && 1556 bif->bif_state == BSTP_IFSTATE_LEARNING) { 1557 m_freem(m); 1558 BRIDGE_UNLOCK(sc); 1559 return; 1560 } 1561 1562 /* 1563 * At this point, the port either doesn't participate 1564 * in spanning tree or it is in the forwarding state. 1565 */ 1566 1567 /* 1568 * If the packet is unicast, destined for someone on 1569 * "this" side of the bridge, drop it. 1570 */ 1571 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1572 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1573 if (src_if == dst_if) { 1574 BRIDGE_UNLOCK(sc); 1575 m_freem(m); 1576 return; 1577 } 1578 } else { 1579 /* ...forward it to all interfaces. */ 1580 sc->sc_ifp->if_imcasts++; 1581 dst_if = NULL; 1582 } 1583 1584 /* run the packet filter */ 1585 if (inet_pfil_hook.ph_busy_count >= 0 1586#ifdef INET6 1587 || inet6_pfil_hook.ph_busy_count >= 0 1588#endif 1589 ) { 1590 BRIDGE_UNLOCK(sc); 1591 if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0) 1592 return; 1593 if (m == NULL) 1594 return; 1595 BRIDGE_LOCK(sc); 1596 } 1597 1598 if (dst_if == NULL) { 1599 /* tap off packets passing the bridge */ 1600 BPF_MTAP(ifp, m); 1601 1602 bridge_broadcast(sc, src_if, m); 1603 return; 1604 } 1605 1606 /* 1607 * At this point, we're dealing with a unicast frame 1608 * going to a different interface. 1609 */ 1610 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1611 BRIDGE_UNLOCK(sc); 1612 m_freem(m); 1613 return; 1614 } 1615 bif = bridge_lookup_member_if(sc, dst_if); 1616 if (bif == NULL) { 1617 /* Not a member of the bridge (anymore?) */ 1618 BRIDGE_UNLOCK(sc); 1619 m_freem(m); 1620 return; 1621 } 1622 1623 if (bif->bif_flags & IFBIF_STP) { 1624 switch (bif->bif_state) { 1625 case BSTP_IFSTATE_DISABLED: 1626 case BSTP_IFSTATE_BLOCKING: 1627 BRIDGE_UNLOCK(sc); 1628 m_freem(m); 1629 return; 1630 } 1631 } 1632 1633 /* tap off packets passing the bridge */ 1634 BPF_MTAP(ifp, m); 1635 1636 BRIDGE_UNLOCK(sc); 1637 1638 if (inet_pfil_hook.ph_busy_count >= 0 1639#ifdef INET6 1640 || inet6_pfil_hook.ph_busy_count >= 0 1641#endif 1642 ) { 1643 if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0) 1644 return; 1645 if (m == NULL) 1646 return; 1647 } 1648 1649 bridge_enqueue(sc, dst_if, m); 1650} 1651 1652/* 1653 * bridge_input: 1654 * 1655 * Receive input from a member interface. Queue the packet for 1656 * bridging if it is not for us. 1657 */ 1658struct mbuf * 1659bridge_input(struct ifnet *ifp, struct mbuf *m) 1660{ 1661 struct bridge_softc *sc = ifp->if_bridge; 1662 struct bridge_iflist *bif; 1663 struct ether_header *eh; 1664 struct mbuf *mc; 1665 1666 if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) 1667 return (m); 1668 1669 BRIDGE_LOCK(sc); 1670 bif = bridge_lookup_member_if(sc, ifp); 1671 if (bif == NULL) { 1672 BRIDGE_UNLOCK(sc); 1673 return (m); 1674 } 1675 1676 eh = mtod(m, struct ether_header *); 1677 1678 if (memcmp(eh->ether_dhost, IFP2ENADDR(sc->sc_ifp), 1679 ETHER_ADDR_LEN) == 0) { 1680 /* 1681 * If the packet is for us, set the packets source as the 1682 * bridge, and return the packet back to ether_input for 1683 * local processing. 1684 */ 1685 1686 /* XXX Do we tap the packet for the member interface too? 1687 * BPF_MTAP(&m->m_pkthdr.rcvif, m); 1688 */ 1689 1690 /* Mark the packet as arriving on the bridge interface */ 1691 m->m_pkthdr.rcvif = sc->sc_ifp; 1692 BPF_MTAP(sc->sc_ifp, m); 1693 sc->sc_ifp->if_ipackets++; 1694 1695 BRIDGE_UNLOCK(sc); 1696 return (m); 1697 } 1698 1699 if (m->m_flags & (M_BCAST|M_MCAST)) { 1700 /* Tap off 802.1D packets; they do not get forwarded. */ 1701 if (memcmp(eh->ether_dhost, bstp_etheraddr, 1702 ETHER_ADDR_LEN) == 0) { 1703 m = bstp_input(ifp, m); 1704 if (m == NULL) { 1705 BRIDGE_UNLOCK(sc); 1706 return (NULL); 1707 } 1708 } 1709 1710 if (bif->bif_flags & IFBIF_STP) { 1711 switch (bif->bif_state) { 1712 case BSTP_IFSTATE_BLOCKING: 1713 case BSTP_IFSTATE_LISTENING: 1714 case BSTP_IFSTATE_DISABLED: 1715 BRIDGE_UNLOCK(sc); 1716 return (m); 1717 } 1718 } 1719 1720 /* 1721 * Make a deep copy of the packet and enqueue the copy 1722 * for bridge processing; return the original packet for 1723 * local processing. 1724 */ 1725 mc = m_dup(m, M_DONTWAIT); 1726 if (mc == NULL) { 1727 BRIDGE_UNLOCK(sc); 1728 return (m); 1729 } 1730 1731 /* Perform the bridge forwarding function with the copy. */ 1732 bridge_forward(sc, mc); 1733 1734 /* Return the original packet for local processing. */ 1735 return (m); 1736 } 1737 1738 if (bif->bif_flags & IFBIF_STP) { 1739 switch (bif->bif_state) { 1740 case BSTP_IFSTATE_BLOCKING: 1741 case BSTP_IFSTATE_LISTENING: 1742 case BSTP_IFSTATE_DISABLED: 1743 BRIDGE_UNLOCK(sc); 1744 return (m); 1745 } 1746 } 1747 1748 /* 1749 * Unicast. Make sure it's not for us. 1750 */ 1751 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1752 /* It is destined for us. */ 1753 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_dhost, 1754 ETHER_ADDR_LEN) == 0) { 1755 if (bif->bif_flags & IFBIF_LEARNING) 1756 (void) bridge_rtupdate(sc, 1757 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); 1758 m->m_pkthdr.rcvif = bif->bif_ifp; 1759 BRIDGE_UNLOCK(sc); 1760 return (m); 1761 } 1762 1763 /* We just received a packet that we sent out. */ 1764 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_shost, 1765 ETHER_ADDR_LEN) == 0) { 1766 BRIDGE_UNLOCK(sc); 1767 m_freem(m); 1768 return (NULL); 1769 } 1770 } 1771 1772 /* Perform the bridge forwarding function. */ 1773 bridge_forward(sc, m); 1774 1775 return (NULL); 1776} 1777 1778/* 1779 * bridge_broadcast: 1780 * 1781 * Send a frame to all interfaces that are members of 1782 * the bridge, except for the one on which the packet 1783 * arrived. 1784 * 1785 * NOTE: Releases the lock on return. 1786 */ 1787void 1788bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 1789 struct mbuf *m) 1790{ 1791 struct bridge_iflist *bif; 1792 struct mbuf *mc; 1793 struct ifnet *dst_if; 1794 int error = 0, used = 0; 1795 1796 BRIDGE_LOCK_ASSERT(sc); 1797 BRIDGE_LOCK2REF(sc, error); 1798 if (error) { 1799 m_freem(m); 1800 return; 1801 } 1802 1803 /* Filter on the bridge interface before broadcasting */ 1804 if (inet_pfil_hook.ph_busy_count >= 0 1805#ifdef INET6 1806 || inet6_pfil_hook.ph_busy_count >= 0 1807#endif 1808 ) { 1809 if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0) 1810 return; 1811 if (m == NULL) 1812 return; 1813 } 1814 1815 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1816 dst_if = bif->bif_ifp; 1817 if (dst_if == src_if) 1818 continue; 1819 1820 if (bif->bif_flags & IFBIF_STP) { 1821 switch (bif->bif_state) { 1822 case BSTP_IFSTATE_BLOCKING: 1823 case BSTP_IFSTATE_DISABLED: 1824 continue; 1825 } 1826 } 1827 1828 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && 1829 (m->m_flags & (M_BCAST|M_MCAST)) == 0) 1830 continue; 1831 1832 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1833 continue; 1834 1835 if (LIST_NEXT(bif, bif_next) == NULL) { 1836 mc = m; 1837 used = 1; 1838 } else { 1839 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1840 if (mc == NULL) { 1841 sc->sc_ifp->if_oerrors++; 1842 continue; 1843 } 1844 } 1845 1846 /* 1847 * Filter on the output interface. Pass a NULL bridge interface 1848 * pointer so we do not redundantly filter on the bridge for 1849 * each interface we broadcast on. 1850 */ 1851 if (inet_pfil_hook.ph_busy_count >= 0 1852#ifdef INET6 1853 || inet6_pfil_hook.ph_busy_count >= 0 1854#endif 1855 ) { 1856 if (bridge_pfil(&m, NULL, dst_if, PFIL_OUT) != 0) 1857 return; 1858 if (m == NULL) 1859 return; 1860 } 1861 1862 bridge_enqueue(sc, dst_if, mc); 1863 } 1864 if (used == 0) 1865 m_freem(m); 1866 1867 BRIDGE_UNREF(sc); 1868} 1869 1870/* 1871 * bridge_rtupdate: 1872 * 1873 * Add a bridge routing entry. 1874 */ 1875int 1876bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, 1877 struct ifnet *dst_if, int setflags, uint8_t flags) 1878{ 1879 struct bridge_rtnode *brt; 1880 struct timeval tv; 1881 int error; 1882 1883 BRIDGE_LOCK_ASSERT(sc); 1884 1885 /* 1886 * A route for this destination might already exist. If so, 1887 * update it, otherwise create a new one. 1888 */ 1889 getmicrotime(&tv); 1890 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) { 1891 if (sc->sc_brtcnt >= sc->sc_brtmax) 1892 return (ENOSPC); 1893 1894 /* 1895 * Allocate a new bridge forwarding node, and 1896 * initialize the expiration time and Ethernet 1897 * address. 1898 */ 1899 brt = uma_zalloc(bridge_rtnode_zone, M_NOWAIT | M_ZERO); 1900 if (brt == NULL) 1901 return (ENOMEM); 1902 1903 brt->brt_expire = tv.tv_sec + sc->sc_brttimeout; 1904 brt->brt_flags = IFBAF_DYNAMIC; 1905 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 1906 1907 if ((error = bridge_rtnode_insert(sc, brt)) != 0) { 1908 uma_zfree(bridge_rtnode_zone, brt); 1909 return (error); 1910 } 1911 } 1912 1913 brt->brt_ifp = dst_if; 1914 if (setflags) { 1915 brt->brt_flags = flags; 1916 brt->brt_expire = (flags & IFBAF_STATIC) ? 0 : 1917 tv.tv_sec + sc->sc_brttimeout; 1918 } 1919 1920 return (0); 1921} 1922 1923/* 1924 * bridge_rtlookup: 1925 * 1926 * Lookup the destination interface for an address. 1927 */ 1928struct ifnet * 1929bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr) 1930{ 1931 struct bridge_rtnode *brt; 1932 1933 BRIDGE_LOCK_ASSERT(sc); 1934 1935 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 1936 return (NULL); 1937 1938 return (brt->brt_ifp); 1939} 1940 1941/* 1942 * bridge_rttrim: 1943 * 1944 * Trim the routine table so that we have a number 1945 * of routing entries less than or equal to the 1946 * maximum number. 1947 */ 1948void 1949bridge_rttrim(struct bridge_softc *sc) 1950{ 1951 struct bridge_rtnode *brt, *nbrt; 1952 1953 BRIDGE_LOCK_ASSERT(sc); 1954 1955 /* Make sure we actually need to do this. */ 1956 if (sc->sc_brtcnt <= sc->sc_brtmax) 1957 return; 1958 1959 /* Force an aging cycle; this might trim enough addresses. */ 1960 bridge_rtage(sc); 1961 if (sc->sc_brtcnt <= sc->sc_brtmax) 1962 return; 1963 1964 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1965 nbrt = LIST_NEXT(brt, brt_list); 1966 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1967 bridge_rtnode_destroy(sc, brt); 1968 if (sc->sc_brtcnt <= sc->sc_brtmax) 1969 return; 1970 } 1971 } 1972} 1973 1974/* 1975 * bridge_timer: 1976 * 1977 * Aging timer for the bridge. 1978 */ 1979void 1980bridge_timer(void *arg) 1981{ 1982 struct bridge_softc *sc = arg; 1983 1984 BRIDGE_LOCK(sc); 1985 bridge_rtage(sc); 1986 BRIDGE_UNLOCK(sc); 1987 1988 if (sc->sc_ifp->if_flags & IFF_RUNNING) 1989 callout_reset(&sc->sc_brcallout, 1990 bridge_rtable_prune_period * hz, bridge_timer, sc); 1991} 1992 1993/* 1994 * bridge_rtage: 1995 * 1996 * Perform an aging cycle. 1997 */ 1998void 1999bridge_rtage(struct bridge_softc *sc) 2000{ 2001 struct bridge_rtnode *brt, *nbrt; 2002 struct timeval tv; 2003 2004 BRIDGE_LOCK_ASSERT(sc); 2005 2006 getmicrotime(&tv); 2007 2008 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 2009 nbrt = LIST_NEXT(brt, brt_list); 2010 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 2011 if (tv.tv_sec >= brt->brt_expire) 2012 bridge_rtnode_destroy(sc, brt); 2013 } 2014 } 2015} 2016 2017/* 2018 * bridge_rtflush: 2019 * 2020 * Remove all dynamic addresses from the bridge. 2021 */ 2022void 2023bridge_rtflush(struct bridge_softc *sc, int full) 2024{ 2025 struct bridge_rtnode *brt, *nbrt; 2026 2027 BRIDGE_LOCK_ASSERT(sc); 2028 2029 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 2030 nbrt = LIST_NEXT(brt, brt_list); 2031 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 2032 bridge_rtnode_destroy(sc, brt); 2033 } 2034} 2035 2036/* 2037 * bridge_rtdaddr: 2038 * 2039 * Remove an address from the table. 2040 */ 2041int 2042bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr) 2043{ 2044 struct bridge_rtnode *brt; 2045 2046 BRIDGE_LOCK_ASSERT(sc); 2047 2048 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 2049 return (ENOENT); 2050 2051 bridge_rtnode_destroy(sc, brt); 2052 return (0); 2053} 2054 2055/* 2056 * bridge_rtdelete: 2057 * 2058 * Delete routes to a speicifc member interface. 2059 */ 2060void 2061bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full) 2062{ 2063 struct bridge_rtnode *brt, *nbrt; 2064 2065 BRIDGE_LOCK_ASSERT(sc); 2066 2067 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 2068 nbrt = LIST_NEXT(brt, brt_list); 2069 if (brt->brt_ifp == ifp && (full || 2070 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)) 2071 bridge_rtnode_destroy(sc, brt); 2072 } 2073} 2074 2075/* 2076 * bridge_rtable_init: 2077 * 2078 * Initialize the route table for this bridge. 2079 */ 2080int 2081bridge_rtable_init(struct bridge_softc *sc) 2082{ 2083 int i; 2084 2085 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 2086 M_DEVBUF, M_NOWAIT); 2087 if (sc->sc_rthash == NULL) 2088 return (ENOMEM); 2089 2090 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++) 2091 LIST_INIT(&sc->sc_rthash[i]); 2092 2093 sc->sc_rthash_key = arc4random(); 2094 2095 LIST_INIT(&sc->sc_rtlist); 2096 2097 return (0); 2098} 2099 2100/* 2101 * bridge_rtable_fini: 2102 * 2103 * Deconstruct the route table for this bridge. 2104 */ 2105void 2106bridge_rtable_fini(struct bridge_softc *sc) 2107{ 2108 2109 free(sc->sc_rthash, M_DEVBUF); 2110} 2111 2112/* 2113 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 2114 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 2115 */ 2116#define mix(a, b, c) \ 2117do { \ 2118 a -= b; a -= c; a ^= (c >> 13); \ 2119 b -= c; b -= a; b ^= (a << 8); \ 2120 c -= a; c -= b; c ^= (b >> 13); \ 2121 a -= b; a -= c; a ^= (c >> 12); \ 2122 b -= c; b -= a; b ^= (a << 16); \ 2123 c -= a; c -= b; c ^= (b >> 5); \ 2124 a -= b; a -= c; a ^= (c >> 3); \ 2125 b -= c; b -= a; b ^= (a << 10); \ 2126 c -= a; c -= b; c ^= (b >> 15); \ 2127} while (/*CONSTCOND*/0) 2128 2129static __inline uint32_t 2130bridge_rthash(struct bridge_softc *sc, const uint8_t *addr) 2131{ 2132 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; 2133 2134 b += addr[5] << 8; 2135 b += addr[4]; 2136 a += addr[3] << 24; 2137 a += addr[2] << 16; 2138 a += addr[1] << 8; 2139 a += addr[0]; 2140 2141 mix(a, b, c); 2142 2143 return (c & BRIDGE_RTHASH_MASK); 2144} 2145 2146#undef mix 2147 2148/* 2149 * bridge_rtnode_lookup: 2150 * 2151 * Look up a bridge route node for the specified destination. 2152 */ 2153struct bridge_rtnode * 2154bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr) 2155{ 2156 struct bridge_rtnode *brt; 2157 uint32_t hash; 2158 int dir; 2159 2160 BRIDGE_LOCK_ASSERT(sc); 2161 2162 hash = bridge_rthash(sc, addr); 2163 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { 2164 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN); 2165 if (dir == 0) 2166 return (brt); 2167 if (dir > 0) 2168 return (NULL); 2169 } 2170 2171 return (NULL); 2172} 2173 2174/* 2175 * bridge_rtnode_insert: 2176 * 2177 * Insert the specified bridge node into the route table. We 2178 * assume the entry is not already in the table. 2179 */ 2180int 2181bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) 2182{ 2183 struct bridge_rtnode *lbrt; 2184 uint32_t hash; 2185 int dir; 2186 2187 BRIDGE_LOCK_ASSERT(sc); 2188 2189 hash = bridge_rthash(sc, brt->brt_addr); 2190 2191 lbrt = LIST_FIRST(&sc->sc_rthash[hash]); 2192 if (lbrt == NULL) { 2193 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); 2194 goto out; 2195 } 2196 2197 do { 2198 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN); 2199 if (dir == 0) 2200 return (EEXIST); 2201 if (dir > 0) { 2202 LIST_INSERT_BEFORE(lbrt, brt, brt_hash); 2203 goto out; 2204 } 2205 if (LIST_NEXT(lbrt, brt_hash) == NULL) { 2206 LIST_INSERT_AFTER(lbrt, brt, brt_hash); 2207 goto out; 2208 } 2209 lbrt = LIST_NEXT(lbrt, brt_hash); 2210 } while (lbrt != NULL); 2211 2212#ifdef DIAGNOSTIC 2213 panic("bridge_rtnode_insert: impossible"); 2214#endif 2215 2216 out: 2217 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); 2218 sc->sc_brtcnt++; 2219 2220 return (0); 2221} 2222 2223/* 2224 * bridge_rtnode_destroy: 2225 * 2226 * Destroy a bridge rtnode. 2227 */ 2228void 2229bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt) 2230{ 2231 BRIDGE_LOCK_ASSERT(sc); 2232 2233 LIST_REMOVE(brt, brt_hash); 2234 2235 LIST_REMOVE(brt, brt_list); 2236 sc->sc_brtcnt--; 2237 uma_zfree(bridge_rtnode_zone, brt); 2238} 2239 2240/* 2241 * Send bridge packets through pfil if they are one of the types pfil can deal 2242 * with, or if they are ARP or REVARP. (pfil will pass ARP and REVARP without 2243 * question.) If *bifp or *ifp are NULL then packet filtering is skipped for 2244 * that interface. 2245 */ 2246static int bridge_pfil(struct mbuf **mp, struct ifnet *bifp, 2247 struct ifnet *ifp, int dir) 2248{ 2249 int snap, error, i; 2250 struct ether_header *eh1, eh2; 2251 struct ip_fw_args args; 2252 struct ip *ip; 2253 struct llc llc1; 2254 u_int16_t ether_type; 2255 2256 snap = 0; 2257 error = -1; /* Default error if not error == 0 */ 2258 2259 i = min((*mp)->m_pkthdr.len, max_protohdr); 2260 if ((*mp)->m_len < i) { 2261 *mp = m_pullup(*mp, i); 2262 if (*mp == NULL) { 2263 printf("%s: m_pullup failed\n", __func__); 2264 return -1; 2265 } 2266 } 2267 2268 eh1 = mtod(*mp, struct ether_header *); 2269 ether_type = ntohs(eh1->ether_type); 2270 2271 /* 2272 * Check for SNAP/LLC. 2273 */ 2274 if (ether_type < ETHERMTU) { 2275 struct llc *llc2 = (struct llc *)(eh1 + 1); 2276 2277 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && 2278 llc2->llc_dsap == LLC_SNAP_LSAP && 2279 llc2->llc_ssap == LLC_SNAP_LSAP && 2280 llc2->llc_control == LLC_UI) { 2281 ether_type = htons(llc2->llc_un.type_snap.ether_type); 2282 snap = 1; 2283 } 2284 } 2285 2286 /* 2287 * If we're trying to filter bridge traffic, don't look at anything 2288 * other than IP and ARP traffic. If the filter doesn't understand 2289 * IPv6, don't allow IPv6 through the bridge either. This is lame 2290 * since if we really wanted, say, an AppleTalk filter, we are hosed, 2291 * but of course we don't have an AppleTalk filter to begin with. 2292 * (Note that since pfil doesn't understand ARP it will pass *ALL* 2293 * ARP traffic.) 2294 */ 2295 switch (ether_type) { 2296 case ETHERTYPE_ARP: 2297 case ETHERTYPE_REVARP: 2298 return 0; /* Automatically pass */ 2299 case ETHERTYPE_IP: 2300# ifdef INET6 2301 case ETHERTYPE_IPV6: 2302# endif /* INET6 */ 2303 break; 2304 default: 2305 /* 2306 * ipfw allows layer2 protocol filtering using 2307 * 'mac-type' so we will let the packet past, if 2308 * ipfw is disabled then drop it. 2309 */ 2310 if (!IPFW_LOADED || pfil_ipfw == 0) 2311 goto bad; 2312 } 2313 2314 /* Strip off the Ethernet header and keep a copy. */ 2315 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2); 2316 m_adj(*mp, ETHER_HDR_LEN); 2317 2318 /* Strip off snap header, if present */ 2319 if (snap) { 2320 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1); 2321 m_adj(*mp, sizeof(struct llc)); 2322 } 2323 2324 /* 2325 * Check the IP header for alignment and errors 2326 */ 2327 if (dir == PFIL_IN) { 2328 switch (ether_type) { 2329 case ETHERTYPE_IP: 2330 error = bridge_ip_checkbasic(mp); 2331 break; 2332# ifdef INET6 2333 case ETHERTYPE_IPV6: 2334 error = bridge_ip6_checkbasic(mp); 2335 break; 2336# endif /* INET6 */ 2337 default: 2338 error = 0; 2339 } 2340 if (error) 2341 goto bad; 2342 } 2343 2344 if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) { 2345 error = -1; 2346 args.rule = ip_dn_claim_rule(*mp); 2347 if (args.rule != NULL && fw_one_pass) 2348 goto ipfwpass; /* packet already partially processed */ 2349 2350 args.m = *mp; 2351 args.oif = ifp; 2352 args.next_hop = NULL; 2353 args.eh = &eh2; 2354 i = ip_fw_chk_ptr(&args); 2355 *mp = args.m; 2356 2357 if (*mp == NULL) 2358 return error; 2359 2360 if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) { 2361 2362 /* put the Ethernet header back on */ 2363 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 2364 if (*mp == NULL) 2365 return error; 2366 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 2367 2368 /* 2369 * Pass the pkt to dummynet, which consumes it. The 2370 * packet will return to us via bridge_dummynet(). 2371 */ 2372 args.oif = ifp; 2373 ip_dn_io_ptr(*mp, DN_TO_IFB_FWD, &args); 2374 return error; 2375 } 2376 2377 if (i != IP_FW_PASS) /* drop */ 2378 goto bad; 2379 } 2380 2381ipfwpass: 2382 error = 0; 2383 2384 /* 2385 * Run the packet through pfil 2386 */ 2387 switch (ether_type) 2388 { 2389 case ETHERTYPE_IP : 2390 /* 2391 * before calling the firewall, swap fields the same as 2392 * IP does. here we assume the header is contiguous 2393 */ 2394 ip = mtod(*mp, struct ip *); 2395 2396 ip->ip_len = ntohs(ip->ip_len); 2397 ip->ip_off = ntohs(ip->ip_off); 2398 2399 /* 2400 * Run pfil on the member interface and the bridge, both can 2401 * be skipped by clearing pfil_member or pfil_bridge. 2402 * 2403 * Keep the order: 2404 * in_if -> bridge_if -> out_if 2405 */ 2406 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) 2407 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, 2408 dir, NULL); 2409 2410 if (*mp == NULL || error != 0) /* filter may consume */ 2411 break; 2412 2413 if (pfil_member && ifp != NULL) 2414 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, 2415 dir, NULL); 2416 2417 if (*mp == NULL || error != 0) /* filter may consume */ 2418 break; 2419 2420 if (pfil_bridge && dir == PFIL_IN && bifp != NULL) 2421 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, 2422 dir, NULL); 2423 2424 /* Restore ip and the fields ntohs()'d. */ 2425 if (*mp != NULL && error == 0) { 2426 ip = mtod(*mp, struct ip *); 2427 ip->ip_len = htons(ip->ip_len); 2428 ip->ip_off = htons(ip->ip_off); 2429 } 2430 2431 break; 2432# ifdef INET6 2433 case ETHERTYPE_IPV6 : 2434 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) 2435 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, 2436 dir, NULL); 2437 2438 if (*mp == NULL || error != 0) /* filter may consume */ 2439 break; 2440 2441 if (pfil_member && ifp != NULL) 2442 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, 2443 dir, NULL); 2444 2445 if (*mp == NULL || error != 0) /* filter may consume */ 2446 break; 2447 2448 if (pfil_bridge && dir == PFIL_IN && bifp != NULL) 2449 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, 2450 dir, NULL); 2451 break; 2452# endif 2453 default : 2454 error = 0; 2455 break; 2456 } 2457 2458 if (*mp == NULL) 2459 return error; 2460 if (error != 0) 2461 goto bad; 2462 2463 error = -1; 2464 2465 /* 2466 * Finally, put everything back the way it was and return 2467 */ 2468 if (snap) { 2469 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT); 2470 if (*mp == NULL) 2471 return error; 2472 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc)); 2473 } 2474 2475 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 2476 if (*mp == NULL) 2477 return error; 2478 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 2479 2480 return 0; 2481 2482 bad: 2483 m_freem(*mp); 2484 *mp = NULL; 2485 return error; 2486} 2487 2488/* 2489 * Perform basic checks on header size since 2490 * pfil assumes ip_input has already processed 2491 * it for it. Cut-and-pasted from ip_input.c. 2492 * Given how simple the IPv6 version is, 2493 * does the IPv4 version really need to be 2494 * this complicated? 2495 * 2496 * XXX Should we update ipstat here, or not? 2497 * XXX Right now we update ipstat but not 2498 * XXX csum_counter. 2499 */ 2500static int 2501bridge_ip_checkbasic(struct mbuf **mp) 2502{ 2503 struct mbuf *m = *mp; 2504 struct ip *ip; 2505 int len, hlen; 2506 u_short sum; 2507 2508 if (*mp == NULL) 2509 return -1; 2510 2511 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2512 if ((m = m_copyup(m, sizeof(struct ip), 2513 (max_linkhdr + 3) & ~3)) == NULL) { 2514 /* XXXJRT new stat, please */ 2515 ipstat.ips_toosmall++; 2516 goto bad; 2517 } 2518 } else if (__predict_false(m->m_len < sizeof (struct ip))) { 2519 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { 2520 ipstat.ips_toosmall++; 2521 goto bad; 2522 } 2523 } 2524 ip = mtod(m, struct ip *); 2525 if (ip == NULL) goto bad; 2526 2527 if (ip->ip_v != IPVERSION) { 2528 ipstat.ips_badvers++; 2529 goto bad; 2530 } 2531 hlen = ip->ip_hl << 2; 2532 if (hlen < sizeof(struct ip)) { /* minimum header length */ 2533 ipstat.ips_badhlen++; 2534 goto bad; 2535 } 2536 if (hlen > m->m_len) { 2537 if ((m = m_pullup(m, hlen)) == 0) { 2538 ipstat.ips_badhlen++; 2539 goto bad; 2540 } 2541 ip = mtod(m, struct ip *); 2542 if (ip == NULL) goto bad; 2543 } 2544 2545 if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { 2546 sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); 2547 } else { 2548 if (hlen == sizeof(struct ip)) { 2549 sum = in_cksum_hdr(ip); 2550 } else { 2551 sum = in_cksum(m, hlen); 2552 } 2553 } 2554 if (sum) { 2555 ipstat.ips_badsum++; 2556 goto bad; 2557 } 2558 2559 /* Retrieve the packet length. */ 2560 len = ntohs(ip->ip_len); 2561 2562 /* 2563 * Check for additional length bogosity 2564 */ 2565 if (len < hlen) { 2566 ipstat.ips_badlen++; 2567 goto bad; 2568 } 2569 2570 /* 2571 * Check that the amount of data in the buffers 2572 * is as at least much as the IP header would have us expect. 2573 * Drop packet if shorter than we expect. 2574 */ 2575 if (m->m_pkthdr.len < len) { 2576 ipstat.ips_tooshort++; 2577 goto bad; 2578 } 2579 2580 /* Checks out, proceed */ 2581 *mp = m; 2582 return 0; 2583 2584 bad: 2585 *mp = m; 2586 return -1; 2587} 2588 2589# ifdef INET6 2590/* 2591 * Same as above, but for IPv6. 2592 * Cut-and-pasted from ip6_input.c. 2593 * XXX Should we update ip6stat, or not? 2594 */ 2595static int 2596bridge_ip6_checkbasic(struct mbuf **mp) 2597{ 2598 struct mbuf *m = *mp; 2599 struct ip6_hdr *ip6; 2600 2601 /* 2602 * If the IPv6 header is not aligned, slurp it up into a new 2603 * mbuf with space for link headers, in the event we forward 2604 * it. Otherwise, if it is aligned, make sure the entire base 2605 * IPv6 header is in the first mbuf of the chain. 2606 */ 2607 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2608 struct ifnet *inifp = m->m_pkthdr.rcvif; 2609 if ((m = m_copyup(m, sizeof(struct ip6_hdr), 2610 (max_linkhdr + 3) & ~3)) == NULL) { 2611 /* XXXJRT new stat, please */ 2612 ip6stat.ip6s_toosmall++; 2613 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2614 goto bad; 2615 } 2616 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { 2617 struct ifnet *inifp = m->m_pkthdr.rcvif; 2618 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 2619 ip6stat.ip6s_toosmall++; 2620 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2621 goto bad; 2622 } 2623 } 2624 2625 ip6 = mtod(m, struct ip6_hdr *); 2626 2627 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 2628 ip6stat.ip6s_badvers++; 2629 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 2630 goto bad; 2631 } 2632 2633 /* Checks out, proceed */ 2634 *mp = m; 2635 return 0; 2636 2637 bad: 2638 *mp = m; 2639 return -1; 2640} 2641# endif /* INET6 */ 2642