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