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