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