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