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