1 /* $NetBSD: if_bridge.c,v 1.41 2006/10/05 17:35:19 tls Exp $ */ 2 3 /* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by Jason L. Wright 53 * 4. The name of the author may not be used to endorse or promote products 54 * derived from this software without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 59 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 * 68 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp 69 */ 70 71 /* 72 * Network interface bridge support. 73 * 74 * TODO: 75 * 76 * - Currently only supports Ethernet-like interfaces (Ethernet, 77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way 78 * to bridge other types of interfaces (FDDI-FDDI, and maybe 79 * consider heterogenous bridges). 80 */ 81 82 #include <sys/cdefs.h> 83 __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.41 2006/10/05 17:35:19 tls Exp $"); 84 85 #include "opt_bridge_ipf.h" 86 #include "opt_inet.h" 87 #include "opt_pfil_hooks.h" 88 #include "bpfilter.h" 89 #include "gif.h" 90 91 #include <sys/param.h> 92 #include <sys/kernel.h> 93 #include <sys/mbuf.h> 94 #include <sys/queue.h> 95 #include <sys/socket.h> 96 #include <sys/sockio.h> 97 #include <sys/systm.h> 98 #include <sys/proc.h> 99 #include <sys/pool.h> 100 #include <sys/kauth.h> 101 102 #if NBPFILTER > 0 103 #include <net/bpf.h> 104 #endif 105 #include <net/if.h> 106 #include <net/if_dl.h> 107 #include <net/if_types.h> 108 #include <net/if_llc.h> 109 110 #include <net/if_ether.h> 111 #include <net/if_bridgevar.h> 112 113 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 114 /* Used for bridge_ip[6]_checkbasic */ 115 #include <netinet/in.h> 116 #include <netinet/in_systm.h> 117 #include <netinet/ip.h> 118 #include <netinet/ip_var.h> 119 120 #include <netinet/ip6.h> 121 #include <netinet6/in6_var.h> 122 #include <netinet6/ip6_var.h> 123 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 124 125 /* 126 * Size of the route hash table. Must be a power of two. 127 */ 128 #ifndef BRIDGE_RTHASH_SIZE 129 #define BRIDGE_RTHASH_SIZE 1024 130 #endif 131 132 #define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1) 133 134 #include "carp.h" 135 #if NCARP > 0 136 #include <netinet/in.h> 137 #include <netinet/in_var.h> 138 #include <netinet/ip_carp.h> 139 #endif 140 141 /* 142 * Maximum number of addresses to cache. 143 */ 144 #ifndef BRIDGE_RTABLE_MAX 145 #define BRIDGE_RTABLE_MAX 100 146 #endif 147 148 /* 149 * Spanning tree defaults. 150 */ 151 #define BSTP_DEFAULT_MAX_AGE (20 * 256) 152 #define BSTP_DEFAULT_HELLO_TIME (2 * 256) 153 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 154 #define BSTP_DEFAULT_HOLD_TIME (1 * 256) 155 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 156 #define BSTP_DEFAULT_PORT_PRIORITY 0x80 157 #define BSTP_DEFAULT_PATH_COST 55 158 159 /* 160 * Timeout (in seconds) for entries learned dynamically. 161 */ 162 #ifndef BRIDGE_RTABLE_TIMEOUT 163 #define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */ 164 #endif 165 166 /* 167 * Number of seconds between walks of the route list. 168 */ 169 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD 170 #define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60) 171 #endif 172 173 int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; 174 175 static struct pool bridge_rtnode_pool; 176 177 void bridgeattach(int); 178 179 static int bridge_clone_create(struct if_clone *, int); 180 static int bridge_clone_destroy(struct ifnet *); 181 182 static int bridge_ioctl(struct ifnet *, u_long, caddr_t); 183 static int bridge_init(struct ifnet *); 184 static void bridge_stop(struct ifnet *, int); 185 static void bridge_start(struct ifnet *); 186 187 static void bridge_forward(struct bridge_softc *, struct mbuf *m); 188 189 static void bridge_timer(void *); 190 191 static void bridge_broadcast(struct bridge_softc *, struct ifnet *, 192 struct mbuf *); 193 194 static int bridge_rtupdate(struct bridge_softc *, const uint8_t *, 195 struct ifnet *, int, uint8_t); 196 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *); 197 static void bridge_rttrim(struct bridge_softc *); 198 static void bridge_rtage(struct bridge_softc *); 199 static void bridge_rtflush(struct bridge_softc *, int); 200 static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *); 201 static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp); 202 203 static int bridge_rtable_init(struct bridge_softc *); 204 static void bridge_rtable_fini(struct bridge_softc *); 205 206 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *, 207 const uint8_t *); 208 static int bridge_rtnode_insert(struct bridge_softc *, 209 struct bridge_rtnode *); 210 static void bridge_rtnode_destroy(struct bridge_softc *, 211 struct bridge_rtnode *); 212 213 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *, 214 const char *name); 215 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *, 216 struct ifnet *ifp); 217 static void bridge_delete_member(struct bridge_softc *, 218 struct bridge_iflist *); 219 220 static int bridge_ioctl_add(struct bridge_softc *, void *); 221 static int bridge_ioctl_del(struct bridge_softc *, void *); 222 static int bridge_ioctl_gifflags(struct bridge_softc *, void *); 223 static int bridge_ioctl_sifflags(struct bridge_softc *, void *); 224 static int bridge_ioctl_scache(struct bridge_softc *, void *); 225 static int bridge_ioctl_gcache(struct bridge_softc *, void *); 226 static int bridge_ioctl_gifs(struct bridge_softc *, void *); 227 static int bridge_ioctl_rts(struct bridge_softc *, void *); 228 static int bridge_ioctl_saddr(struct bridge_softc *, void *); 229 static int bridge_ioctl_sto(struct bridge_softc *, void *); 230 static int bridge_ioctl_gto(struct bridge_softc *, void *); 231 static int bridge_ioctl_daddr(struct bridge_softc *, void *); 232 static int bridge_ioctl_flush(struct bridge_softc *, void *); 233 static int bridge_ioctl_gpri(struct bridge_softc *, void *); 234 static int bridge_ioctl_spri(struct bridge_softc *, void *); 235 static int bridge_ioctl_ght(struct bridge_softc *, void *); 236 static int bridge_ioctl_sht(struct bridge_softc *, void *); 237 static int bridge_ioctl_gfd(struct bridge_softc *, void *); 238 static int bridge_ioctl_sfd(struct bridge_softc *, void *); 239 static int bridge_ioctl_gma(struct bridge_softc *, void *); 240 static int bridge_ioctl_sma(struct bridge_softc *, void *); 241 static int bridge_ioctl_sifprio(struct bridge_softc *, void *); 242 static int bridge_ioctl_sifcost(struct bridge_softc *, void *); 243 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 244 static int bridge_ioctl_gfilt(struct bridge_softc *, void *); 245 static int bridge_ioctl_sfilt(struct bridge_softc *, void *); 246 static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int); 247 static int bridge_ip_checkbasic(struct mbuf **mp); 248 # ifdef INET6 249 static int bridge_ip6_checkbasic(struct mbuf **mp); 250 # endif /* INET6 */ 251 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 252 253 struct bridge_control { 254 int (*bc_func)(struct bridge_softc *, void *); 255 int bc_argsize; 256 int bc_flags; 257 }; 258 259 #define BC_F_COPYIN 0x01 /* copy arguments in */ 260 #define BC_F_COPYOUT 0x02 /* copy arguments out */ 261 #define BC_F_SUSER 0x04 /* do super-user check */ 262 263 static const struct bridge_control bridge_control_table[] = { 264 { bridge_ioctl_add, sizeof(struct ifbreq), 265 BC_F_COPYIN|BC_F_SUSER }, 266 { bridge_ioctl_del, sizeof(struct ifbreq), 267 BC_F_COPYIN|BC_F_SUSER }, 268 269 { bridge_ioctl_gifflags, sizeof(struct ifbreq), 270 BC_F_COPYIN|BC_F_COPYOUT }, 271 { bridge_ioctl_sifflags, sizeof(struct ifbreq), 272 BC_F_COPYIN|BC_F_SUSER }, 273 274 { bridge_ioctl_scache, sizeof(struct ifbrparam), 275 BC_F_COPYIN|BC_F_SUSER }, 276 { bridge_ioctl_gcache, sizeof(struct ifbrparam), 277 BC_F_COPYOUT }, 278 279 { bridge_ioctl_gifs, sizeof(struct ifbifconf), 280 BC_F_COPYIN|BC_F_COPYOUT }, 281 { bridge_ioctl_rts, sizeof(struct ifbaconf), 282 BC_F_COPYIN|BC_F_COPYOUT }, 283 284 { bridge_ioctl_saddr, sizeof(struct ifbareq), 285 BC_F_COPYIN|BC_F_SUSER }, 286 287 { bridge_ioctl_sto, sizeof(struct ifbrparam), 288 BC_F_COPYIN|BC_F_SUSER }, 289 { bridge_ioctl_gto, sizeof(struct ifbrparam), 290 BC_F_COPYOUT }, 291 292 { bridge_ioctl_daddr, sizeof(struct ifbareq), 293 BC_F_COPYIN|BC_F_SUSER }, 294 295 { bridge_ioctl_flush, sizeof(struct ifbreq), 296 BC_F_COPYIN|BC_F_SUSER }, 297 298 { bridge_ioctl_gpri, sizeof(struct ifbrparam), 299 BC_F_COPYOUT }, 300 { bridge_ioctl_spri, sizeof(struct ifbrparam), 301 BC_F_COPYIN|BC_F_SUSER }, 302 303 { bridge_ioctl_ght, sizeof(struct ifbrparam), 304 BC_F_COPYOUT }, 305 { bridge_ioctl_sht, sizeof(struct ifbrparam), 306 BC_F_COPYIN|BC_F_SUSER }, 307 308 { bridge_ioctl_gfd, sizeof(struct ifbrparam), 309 BC_F_COPYOUT }, 310 { bridge_ioctl_sfd, sizeof(struct ifbrparam), 311 BC_F_COPYIN|BC_F_SUSER }, 312 313 { bridge_ioctl_gma, sizeof(struct ifbrparam), 314 BC_F_COPYOUT }, 315 { bridge_ioctl_sma, sizeof(struct ifbrparam), 316 BC_F_COPYIN|BC_F_SUSER }, 317 318 { bridge_ioctl_sifprio, sizeof(struct ifbreq), 319 BC_F_COPYIN|BC_F_SUSER }, 320 321 { bridge_ioctl_sifcost, sizeof(struct ifbreq), 322 BC_F_COPYIN|BC_F_SUSER }, 323 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 324 { bridge_ioctl_gfilt, sizeof(struct ifbrparam), 325 BC_F_COPYOUT }, 326 { bridge_ioctl_sfilt, sizeof(struct ifbrparam), 327 BC_F_COPYIN|BC_F_SUSER }, 328 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 329 }; 330 static const int bridge_control_table_size = 331 sizeof(bridge_control_table) / sizeof(bridge_control_table[0]); 332 333 static LIST_HEAD(, bridge_softc) bridge_list; 334 335 static struct if_clone bridge_cloner = 336 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); 337 338 /* 339 * bridgeattach: 340 * 341 * Pseudo-device attach routine. 342 */ 343 void 344 bridgeattach(int n) 345 { 346 347 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode), 348 0, 0, 0, "brtpl", NULL); 349 350 LIST_INIT(&bridge_list); 351 if_clone_attach(&bridge_cloner); 352 } 353 354 /* 355 * bridge_clone_create: 356 * 357 * Create a new bridge instance. 358 */ 359 static int 360 bridge_clone_create(struct if_clone *ifc, int unit) 361 { 362 struct bridge_softc *sc; 363 struct ifnet *ifp; 364 int s; 365 366 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK); 367 memset(sc, 0, sizeof(*sc)); 368 ifp = &sc->sc_if; 369 370 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 371 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 372 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 373 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME; 374 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY; 375 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 376 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME; 377 sc->sc_filter_flags = 0; 378 379 /* Initialize our routing table. */ 380 bridge_rtable_init(sc); 381 382 callout_init(&sc->sc_brcallout); 383 callout_init(&sc->sc_bstpcallout); 384 385 LIST_INIT(&sc->sc_iflist); 386 387 snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", ifc->ifc_name, 388 unit); 389 ifp->if_softc = sc; 390 ifp->if_mtu = ETHERMTU; 391 ifp->if_ioctl = bridge_ioctl; 392 ifp->if_output = bridge_output; 393 ifp->if_start = bridge_start; 394 ifp->if_stop = bridge_stop; 395 ifp->if_init = bridge_init; 396 ifp->if_type = IFT_BRIDGE; 397 ifp->if_addrlen = 0; 398 ifp->if_dlt = DLT_EN10MB; 399 ifp->if_hdrlen = ETHER_HDR_LEN; 400 401 if_attach(ifp); 402 403 if_alloc_sadl(ifp); 404 405 s = splnet(); 406 LIST_INSERT_HEAD(&bridge_list, sc, sc_list); 407 splx(s); 408 409 return (0); 410 } 411 412 /* 413 * bridge_clone_destroy: 414 * 415 * Destroy a bridge instance. 416 */ 417 static int 418 bridge_clone_destroy(struct ifnet *ifp) 419 { 420 struct bridge_softc *sc = ifp->if_softc; 421 struct bridge_iflist *bif; 422 int s; 423 424 s = splnet(); 425 426 bridge_stop(ifp, 1); 427 428 while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) 429 bridge_delete_member(sc, bif); 430 431 LIST_REMOVE(sc, sc_list); 432 433 splx(s); 434 435 if_detach(ifp); 436 437 /* Tear down the routing table. */ 438 bridge_rtable_fini(sc); 439 440 free(sc, M_DEVBUF); 441 442 return (0); 443 } 444 445 /* 446 * bridge_ioctl: 447 * 448 * Handle a control request from the operator. 449 */ 450 static int 451 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 452 { 453 struct bridge_softc *sc = ifp->if_softc; 454 struct lwp *l = curlwp; /* XXX */ 455 union { 456 struct ifbreq ifbreq; 457 struct ifbifconf ifbifconf; 458 struct ifbareq ifbareq; 459 struct ifbaconf ifbaconf; 460 struct ifbrparam ifbrparam; 461 } args; 462 struct ifdrv *ifd = (struct ifdrv *) data; 463 const struct bridge_control *bc; 464 int s, error = 0; 465 466 s = splnet(); 467 468 switch (cmd) { 469 case SIOCGDRVSPEC: 470 case SIOCSDRVSPEC: 471 if (ifd->ifd_cmd >= bridge_control_table_size) { 472 error = EINVAL; 473 break; 474 } 475 bc = &bridge_control_table[ifd->ifd_cmd]; 476 477 if (cmd == SIOCGDRVSPEC && 478 (bc->bc_flags & BC_F_COPYOUT) == 0) { 479 error = EINVAL; 480 break; 481 } 482 else if (cmd == SIOCSDRVSPEC && 483 (bc->bc_flags & BC_F_COPYOUT) != 0) { 484 error = EINVAL; 485 break; 486 } 487 488 if (bc->bc_flags & BC_F_SUSER) { 489 error = kauth_authorize_generic(l->l_cred, 490 KAUTH_GENERIC_ISSUSER, &l->l_acflag); 491 if (error) 492 break; 493 } 494 495 if (ifd->ifd_len != bc->bc_argsize || 496 ifd->ifd_len > sizeof(args)) { 497 error = EINVAL; 498 break; 499 } 500 501 memset(&args, 0, sizeof(args)); 502 if (bc->bc_flags & BC_F_COPYIN) { 503 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); 504 if (error) 505 break; 506 } 507 508 error = (*bc->bc_func)(sc, &args); 509 if (error) 510 break; 511 512 if (bc->bc_flags & BC_F_COPYOUT) 513 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); 514 515 break; 516 517 case SIOCSIFFLAGS: 518 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) { 519 /* 520 * If interface is marked down and it is running, 521 * then stop and disable it. 522 */ 523 (*ifp->if_stop)(ifp, 1); 524 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) { 525 /* 526 * If interface is marked up and it is stopped, then 527 * start it. 528 */ 529 error = (*ifp->if_init)(ifp); 530 } 531 break; 532 533 default: 534 error = ENOTTY; 535 break; 536 } 537 538 splx(s); 539 540 return (error); 541 } 542 543 /* 544 * bridge_lookup_member: 545 * 546 * Lookup a bridge member interface. Must be called at splnet(). 547 */ 548 static struct bridge_iflist * 549 bridge_lookup_member(struct bridge_softc *sc, const char *name) 550 { 551 struct bridge_iflist *bif; 552 struct ifnet *ifp; 553 554 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 555 ifp = bif->bif_ifp; 556 if (strcmp(ifp->if_xname, name) == 0) 557 return (bif); 558 } 559 560 return (NULL); 561 } 562 563 /* 564 * bridge_lookup_member_if: 565 * 566 * Lookup a bridge member interface by ifnet*. Must be called at splnet(). 567 */ 568 static struct bridge_iflist * 569 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp) 570 { 571 struct bridge_iflist *bif; 572 573 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 574 if (bif->bif_ifp == member_ifp) 575 return (bif); 576 } 577 578 return (NULL); 579 } 580 581 /* 582 * bridge_delete_member: 583 * 584 * Delete the specified member interface. 585 */ 586 static void 587 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif) 588 { 589 struct ifnet *ifs = bif->bif_ifp; 590 591 switch (ifs->if_type) { 592 case IFT_ETHER: 593 /* 594 * Take the interface out of promiscuous mode. 595 */ 596 (void) ifpromisc(ifs, 0); 597 break; 598 #if NGIF > 0 599 case IFT_GIF: 600 break; 601 #endif 602 default: 603 #ifdef DIAGNOSTIC 604 panic("bridge_delete_member: impossible"); 605 #endif 606 break; 607 } 608 609 ifs->if_bridge = NULL; 610 LIST_REMOVE(bif, bif_next); 611 612 bridge_rtdelete(sc, ifs); 613 614 free(bif, M_DEVBUF); 615 616 if (sc->sc_if.if_flags & IFF_RUNNING) 617 bstp_initialization(sc); 618 } 619 620 static int 621 bridge_ioctl_add(struct bridge_softc *sc, void *arg) 622 { 623 struct ifbreq *req = arg; 624 struct bridge_iflist *bif = NULL; 625 struct ifnet *ifs; 626 int error = 0; 627 628 ifs = ifunit(req->ifbr_ifsname); 629 if (ifs == NULL) 630 return (ENOENT); 631 632 if (sc->sc_if.if_mtu != ifs->if_mtu) 633 return (EINVAL); 634 635 if (ifs->if_bridge == sc) 636 return (EEXIST); 637 638 if (ifs->if_bridge != NULL) 639 return (EBUSY); 640 641 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT); 642 if (bif == NULL) 643 return (ENOMEM); 644 645 switch (ifs->if_type) { 646 case IFT_ETHER: 647 /* 648 * Place the interface into promiscuous mode. 649 */ 650 error = ifpromisc(ifs, 1); 651 if (error) 652 goto out; 653 break; 654 #if NGIF > 0 655 case IFT_GIF: 656 break; 657 #endif 658 default: 659 error = EINVAL; 660 goto out; 661 } 662 663 bif->bif_ifp = ifs; 664 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 665 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; 666 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST; 667 668 ifs->if_bridge = sc; 669 LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next); 670 671 if (sc->sc_if.if_flags & IFF_RUNNING) 672 bstp_initialization(sc); 673 else 674 bstp_stop(sc); 675 676 out: 677 if (error) { 678 if (bif != NULL) 679 free(bif, M_DEVBUF); 680 } 681 return (error); 682 } 683 684 static int 685 bridge_ioctl_del(struct bridge_softc *sc, void *arg) 686 { 687 struct ifbreq *req = arg; 688 struct bridge_iflist *bif; 689 690 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 691 if (bif == NULL) 692 return (ENOENT); 693 694 bridge_delete_member(sc, bif); 695 696 return (0); 697 } 698 699 static int 700 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) 701 { 702 struct ifbreq *req = arg; 703 struct bridge_iflist *bif; 704 705 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 706 if (bif == NULL) 707 return (ENOENT); 708 709 req->ifbr_ifsflags = bif->bif_flags; 710 req->ifbr_state = bif->bif_state; 711 req->ifbr_priority = bif->bif_priority; 712 req->ifbr_path_cost = bif->bif_path_cost; 713 req->ifbr_portno = bif->bif_ifp->if_index & 0xff; 714 715 return (0); 716 } 717 718 static int 719 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) 720 { 721 struct ifbreq *req = arg; 722 struct bridge_iflist *bif; 723 724 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 725 if (bif == NULL) 726 return (ENOENT); 727 728 if (req->ifbr_ifsflags & IFBIF_STP) { 729 switch (bif->bif_ifp->if_type) { 730 case IFT_ETHER: 731 /* These can do spanning tree. */ 732 break; 733 734 default: 735 /* Nothing else can. */ 736 return (EINVAL); 737 } 738 } 739 740 bif->bif_flags = req->ifbr_ifsflags; 741 742 if (sc->sc_if.if_flags & IFF_RUNNING) 743 bstp_initialization(sc); 744 745 return (0); 746 } 747 748 static int 749 bridge_ioctl_scache(struct bridge_softc *sc, void *arg) 750 { 751 struct ifbrparam *param = arg; 752 753 sc->sc_brtmax = param->ifbrp_csize; 754 bridge_rttrim(sc); 755 756 return (0); 757 } 758 759 static int 760 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg) 761 { 762 struct ifbrparam *param = arg; 763 764 param->ifbrp_csize = sc->sc_brtmax; 765 766 return (0); 767 } 768 769 static int 770 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) 771 { 772 struct ifbifconf *bifc = arg; 773 struct bridge_iflist *bif; 774 struct ifbreq breq; 775 int count, len, error = 0; 776 777 count = 0; 778 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) 779 count++; 780 781 if (bifc->ifbic_len == 0) { 782 bifc->ifbic_len = sizeof(breq) * count; 783 return (0); 784 } 785 786 count = 0; 787 len = bifc->ifbic_len; 788 memset(&breq, 0, sizeof breq); 789 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 790 if (len < sizeof(breq)) 791 break; 792 793 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname, 794 sizeof(breq.ifbr_ifsname)); 795 breq.ifbr_ifsflags = bif->bif_flags; 796 breq.ifbr_state = bif->bif_state; 797 breq.ifbr_priority = bif->bif_priority; 798 breq.ifbr_path_cost = bif->bif_path_cost; 799 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff; 800 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq)); 801 if (error) 802 break; 803 count++; 804 len -= sizeof(breq); 805 } 806 807 bifc->ifbic_len = sizeof(breq) * count; 808 return (error); 809 } 810 811 static int 812 bridge_ioctl_rts(struct bridge_softc *sc, void *arg) 813 { 814 struct ifbaconf *bac = arg; 815 struct bridge_rtnode *brt; 816 struct ifbareq bareq; 817 int count = 0, error = 0, len; 818 819 if (bac->ifbac_len == 0) 820 return (0); 821 822 len = bac->ifbac_len; 823 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 824 if (len < sizeof(bareq)) 825 goto out; 826 memset(&bareq, 0, sizeof(bareq)); 827 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, 828 sizeof(bareq.ifba_ifsname)); 829 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); 830 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 831 bareq.ifba_expire = brt->brt_expire - time_uptime; 832 } else 833 bareq.ifba_expire = 0; 834 bareq.ifba_flags = brt->brt_flags; 835 836 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq)); 837 if (error) 838 goto out; 839 count++; 840 len -= sizeof(bareq); 841 } 842 out: 843 bac->ifbac_len = sizeof(bareq) * count; 844 return (error); 845 } 846 847 static int 848 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) 849 { 850 struct ifbareq *req = arg; 851 struct bridge_iflist *bif; 852 int error; 853 854 bif = bridge_lookup_member(sc, req->ifba_ifsname); 855 if (bif == NULL) 856 return (ENOENT); 857 858 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1, 859 req->ifba_flags); 860 861 return (error); 862 } 863 864 static int 865 bridge_ioctl_sto(struct bridge_softc *sc, void *arg) 866 { 867 struct ifbrparam *param = arg; 868 869 sc->sc_brttimeout = param->ifbrp_ctime; 870 871 return (0); 872 } 873 874 static int 875 bridge_ioctl_gto(struct bridge_softc *sc, void *arg) 876 { 877 struct ifbrparam *param = arg; 878 879 param->ifbrp_ctime = sc->sc_brttimeout; 880 881 return (0); 882 } 883 884 static int 885 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg) 886 { 887 struct ifbareq *req = arg; 888 889 return (bridge_rtdaddr(sc, req->ifba_dst)); 890 } 891 892 static int 893 bridge_ioctl_flush(struct bridge_softc *sc, void *arg) 894 { 895 struct ifbreq *req = arg; 896 897 bridge_rtflush(sc, req->ifbr_ifsflags); 898 899 return (0); 900 } 901 902 static int 903 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg) 904 { 905 struct ifbrparam *param = arg; 906 907 param->ifbrp_prio = sc->sc_bridge_priority; 908 909 return (0); 910 } 911 912 static int 913 bridge_ioctl_spri(struct bridge_softc *sc, void *arg) 914 { 915 struct ifbrparam *param = arg; 916 917 sc->sc_bridge_priority = param->ifbrp_prio; 918 919 if (sc->sc_if.if_flags & IFF_RUNNING) 920 bstp_initialization(sc); 921 922 return (0); 923 } 924 925 static int 926 bridge_ioctl_ght(struct bridge_softc *sc, void *arg) 927 { 928 struct ifbrparam *param = arg; 929 930 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8; 931 932 return (0); 933 } 934 935 static int 936 bridge_ioctl_sht(struct bridge_softc *sc, void *arg) 937 { 938 struct ifbrparam *param = arg; 939 940 if (param->ifbrp_hellotime == 0) 941 return (EINVAL); 942 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8; 943 944 if (sc->sc_if.if_flags & IFF_RUNNING) 945 bstp_initialization(sc); 946 947 return (0); 948 } 949 950 static int 951 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg) 952 { 953 struct ifbrparam *param = arg; 954 955 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8; 956 957 return (0); 958 } 959 960 static int 961 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg) 962 { 963 struct ifbrparam *param = arg; 964 965 if (param->ifbrp_fwddelay == 0) 966 return (EINVAL); 967 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8; 968 969 if (sc->sc_if.if_flags & IFF_RUNNING) 970 bstp_initialization(sc); 971 972 return (0); 973 } 974 975 static int 976 bridge_ioctl_gma(struct bridge_softc *sc, void *arg) 977 { 978 struct ifbrparam *param = arg; 979 980 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8; 981 982 return (0); 983 } 984 985 static int 986 bridge_ioctl_sma(struct bridge_softc *sc, void *arg) 987 { 988 struct ifbrparam *param = arg; 989 990 if (param->ifbrp_maxage == 0) 991 return (EINVAL); 992 sc->sc_bridge_max_age = param->ifbrp_maxage << 8; 993 994 if (sc->sc_if.if_flags & IFF_RUNNING) 995 bstp_initialization(sc); 996 997 return (0); 998 } 999 1000 static int 1001 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) 1002 { 1003 struct ifbreq *req = arg; 1004 struct bridge_iflist *bif; 1005 1006 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 1007 if (bif == NULL) 1008 return (ENOENT); 1009 1010 bif->bif_priority = req->ifbr_priority; 1011 1012 if (sc->sc_if.if_flags & IFF_RUNNING) 1013 bstp_initialization(sc); 1014 1015 return (0); 1016 } 1017 1018 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 1019 static int 1020 bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg) 1021 { 1022 struct ifbrparam *param = arg; 1023 1024 param->ifbrp_filter = sc->sc_filter_flags; 1025 1026 return (0); 1027 } 1028 1029 static int 1030 bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg) 1031 { 1032 struct ifbrparam *param = arg; 1033 uint32_t nflags, oflags; 1034 1035 if (param->ifbrp_filter & ~IFBF_FILT_MASK) 1036 return (EINVAL); 1037 1038 nflags = param->ifbrp_filter; 1039 oflags = sc->sc_filter_flags; 1040 1041 if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) { 1042 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1043 &sc->sc_if.if_pfil); 1044 } 1045 if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) { 1046 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1047 &sc->sc_if.if_pfil); 1048 } 1049 1050 sc->sc_filter_flags = nflags; 1051 1052 return (0); 1053 } 1054 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 1055 1056 static int 1057 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) 1058 { 1059 struct ifbreq *req = arg; 1060 struct bridge_iflist *bif; 1061 1062 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 1063 if (bif == NULL) 1064 return (ENOENT); 1065 1066 bif->bif_path_cost = req->ifbr_path_cost; 1067 1068 if (sc->sc_if.if_flags & IFF_RUNNING) 1069 bstp_initialization(sc); 1070 1071 return (0); 1072 } 1073 1074 /* 1075 * bridge_ifdetach: 1076 * 1077 * Detach an interface from a bridge. Called when a member 1078 * interface is detaching. 1079 */ 1080 void 1081 bridge_ifdetach(struct ifnet *ifp) 1082 { 1083 struct bridge_softc *sc = ifp->if_bridge; 1084 struct ifbreq breq; 1085 1086 memset(&breq, 0, sizeof(breq)); 1087 snprintf(breq.ifbr_ifsname, sizeof(breq.ifbr_ifsname), ifp->if_xname); 1088 1089 (void) bridge_ioctl_del(sc, &breq); 1090 } 1091 1092 /* 1093 * bridge_init: 1094 * 1095 * Initialize a bridge interface. 1096 */ 1097 static int 1098 bridge_init(struct ifnet *ifp) 1099 { 1100 struct bridge_softc *sc = ifp->if_softc; 1101 1102 if (ifp->if_flags & IFF_RUNNING) 1103 return (0); 1104 1105 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, 1106 bridge_timer, sc); 1107 1108 ifp->if_flags |= IFF_RUNNING; 1109 bstp_initialization(sc); 1110 return (0); 1111 } 1112 1113 /* 1114 * bridge_stop: 1115 * 1116 * Stop the bridge interface. 1117 */ 1118 static void 1119 bridge_stop(struct ifnet *ifp, int disable) 1120 { 1121 struct bridge_softc *sc = ifp->if_softc; 1122 1123 if ((ifp->if_flags & IFF_RUNNING) == 0) 1124 return; 1125 1126 callout_stop(&sc->sc_brcallout); 1127 bstp_stop(sc); 1128 1129 IF_PURGE(&ifp->if_snd); 1130 1131 bridge_rtflush(sc, IFBF_FLUSHDYN); 1132 1133 ifp->if_flags &= ~IFF_RUNNING; 1134 } 1135 1136 /* 1137 * bridge_enqueue: 1138 * 1139 * Enqueue a packet on a bridge member interface. 1140 * 1141 * NOTE: must be called at splnet(). 1142 */ 1143 void 1144 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, 1145 int runfilt) 1146 { 1147 ALTQ_DECL(struct altq_pktattr pktattr;) 1148 int len, error; 1149 short mflags; 1150 1151 /* 1152 * Clear any in-bound checksum flags for this packet. 1153 */ 1154 m->m_pkthdr.csum_flags = 0; 1155 1156 #ifdef PFIL_HOOKS 1157 if (runfilt) { 1158 if (pfil_run_hooks(&sc->sc_if.if_pfil, &m, 1159 dst_ifp, PFIL_OUT) != 0) { 1160 if (m != NULL) 1161 m_freem(m); 1162 return; 1163 } 1164 if (m == NULL) 1165 return; 1166 } 1167 #endif /* PFIL_HOOKS */ 1168 1169 #ifdef ALTQ 1170 /* 1171 * If ALTQ is enabled on the member interface, do 1172 * classification; the queueing discipline might 1173 * not require classification, but might require 1174 * the address family/header pointer in the pktattr. 1175 */ 1176 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) { 1177 /* XXX IFT_ETHER */ 1178 altq_etherclassify(&dst_ifp->if_snd, m, &pktattr); 1179 } 1180 #endif /* ALTQ */ 1181 1182 len = m->m_pkthdr.len; 1183 m->m_flags |= M_PROTO1; 1184 mflags = m->m_flags; 1185 IFQ_ENQUEUE(&dst_ifp->if_snd, m, &pktattr, error); 1186 if (error) { 1187 /* mbuf is already freed */ 1188 sc->sc_if.if_oerrors++; 1189 return; 1190 } 1191 1192 sc->sc_if.if_opackets++; 1193 sc->sc_if.if_obytes += len; 1194 1195 dst_ifp->if_obytes += len; 1196 1197 if (mflags & M_MCAST) { 1198 sc->sc_if.if_omcasts++; 1199 dst_ifp->if_omcasts++; 1200 } 1201 1202 if ((dst_ifp->if_flags & IFF_OACTIVE) == 0) 1203 (*dst_ifp->if_start)(dst_ifp); 1204 } 1205 1206 /* 1207 * bridge_output: 1208 * 1209 * Send output from a bridge member interface. This 1210 * performs the bridging function for locally originated 1211 * packets. 1212 * 1213 * The mbuf has the Ethernet header already attached. We must 1214 * enqueue or free the mbuf before returning. 1215 */ 1216 int 1217 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, 1218 struct rtentry *rt) 1219 { 1220 struct ether_header *eh; 1221 struct ifnet *dst_if; 1222 struct bridge_softc *sc; 1223 int s; 1224 1225 if (m->m_len < ETHER_HDR_LEN) { 1226 m = m_pullup(m, ETHER_HDR_LEN); 1227 if (m == NULL) 1228 return (0); 1229 } 1230 1231 eh = mtod(m, struct ether_header *); 1232 sc = ifp->if_bridge; 1233 1234 s = splnet(); 1235 1236 /* 1237 * If bridge is down, but the original output interface is up, 1238 * go ahead and send out that interface. Otherwise, the packet 1239 * is dropped below. 1240 */ 1241 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1242 dst_if = ifp; 1243 goto sendunicast; 1244 } 1245 1246 /* 1247 * If the packet is a multicast, or we don't know a better way to 1248 * get there, send to all interfaces. 1249 */ 1250 if (ETHER_IS_MULTICAST(eh->ether_dhost)) 1251 dst_if = NULL; 1252 else 1253 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1254 if (dst_if == NULL) { 1255 struct bridge_iflist *bif; 1256 struct mbuf *mc; 1257 int used = 0; 1258 1259 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1260 dst_if = bif->bif_ifp; 1261 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1262 continue; 1263 1264 /* 1265 * If this is not the original output interface, 1266 * and the interface is participating in spanning 1267 * tree, make sure the port is in a state that 1268 * allows forwarding. 1269 */ 1270 if (dst_if != ifp && 1271 (bif->bif_flags & IFBIF_STP) != 0) { 1272 switch (bif->bif_state) { 1273 case BSTP_IFSTATE_BLOCKING: 1274 case BSTP_IFSTATE_LISTENING: 1275 case BSTP_IFSTATE_DISABLED: 1276 continue; 1277 } 1278 } 1279 1280 if (LIST_NEXT(bif, bif_next) == NULL) { 1281 used = 1; 1282 mc = m; 1283 } else { 1284 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); 1285 if (mc == NULL) { 1286 sc->sc_if.if_oerrors++; 1287 continue; 1288 } 1289 } 1290 1291 bridge_enqueue(sc, dst_if, mc, 0); 1292 } 1293 if (used == 0) 1294 m_freem(m); 1295 splx(s); 1296 return (0); 1297 } 1298 1299 sendunicast: 1300 /* 1301 * XXX Spanning tree consideration here? 1302 */ 1303 1304 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1305 m_freem(m); 1306 splx(s); 1307 return (0); 1308 } 1309 1310 bridge_enqueue(sc, dst_if, m, 0); 1311 1312 splx(s); 1313 return (0); 1314 } 1315 1316 /* 1317 * bridge_start: 1318 * 1319 * Start output on a bridge. 1320 * 1321 * NOTE: This routine should never be called in this implementation. 1322 */ 1323 static void 1324 bridge_start(struct ifnet *ifp) 1325 { 1326 1327 printf("%s: bridge_start() called\n", ifp->if_xname); 1328 } 1329 1330 /* 1331 * bridge_forward: 1332 * 1333 * The forwarding function of the bridge. 1334 */ 1335 static void 1336 bridge_forward(struct bridge_softc *sc, struct mbuf *m) 1337 { 1338 struct bridge_iflist *bif; 1339 struct ifnet *src_if, *dst_if; 1340 struct ether_header *eh; 1341 1342 src_if = m->m_pkthdr.rcvif; 1343 1344 sc->sc_if.if_ipackets++; 1345 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1346 1347 /* 1348 * Look up the bridge_iflist. 1349 */ 1350 bif = bridge_lookup_member_if(sc, src_if); 1351 if (bif == NULL) { 1352 /* Interface is not a bridge member (anymore?) */ 1353 m_freem(m); 1354 return; 1355 } 1356 1357 if (bif->bif_flags & IFBIF_STP) { 1358 switch (bif->bif_state) { 1359 case BSTP_IFSTATE_BLOCKING: 1360 case BSTP_IFSTATE_LISTENING: 1361 case BSTP_IFSTATE_DISABLED: 1362 m_freem(m); 1363 return; 1364 } 1365 } 1366 1367 eh = mtod(m, struct ether_header *); 1368 1369 /* 1370 * If the interface is learning, and the source 1371 * address is valid and not multicast, record 1372 * the address. 1373 */ 1374 if ((bif->bif_flags & IFBIF_LEARNING) != 0 && 1375 ETHER_IS_MULTICAST(eh->ether_shost) == 0 && 1376 (eh->ether_shost[0] == 0 && 1377 eh->ether_shost[1] == 0 && 1378 eh->ether_shost[2] == 0 && 1379 eh->ether_shost[3] == 0 && 1380 eh->ether_shost[4] == 0 && 1381 eh->ether_shost[5] == 0) == 0) { 1382 (void) bridge_rtupdate(sc, eh->ether_shost, 1383 src_if, 0, IFBAF_DYNAMIC); 1384 } 1385 1386 if ((bif->bif_flags & IFBIF_STP) != 0 && 1387 bif->bif_state == BSTP_IFSTATE_LEARNING) { 1388 m_freem(m); 1389 return; 1390 } 1391 1392 /* 1393 * At this point, the port either doesn't participate 1394 * in spanning tree or it is in the forwarding state. 1395 */ 1396 1397 /* 1398 * If the packet is unicast, destined for someone on 1399 * "this" side of the bridge, drop it. 1400 */ 1401 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1402 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1403 if (src_if == dst_if) { 1404 m_freem(m); 1405 return; 1406 } 1407 } else { 1408 /* ...forward it to all interfaces. */ 1409 sc->sc_if.if_imcasts++; 1410 dst_if = NULL; 1411 } 1412 1413 #ifdef PFIL_HOOKS 1414 if (pfil_run_hooks(&sc->sc_if.if_pfil, &m, 1415 m->m_pkthdr.rcvif, PFIL_IN) != 0) { 1416 if (m != NULL) 1417 m_freem(m); 1418 return; 1419 } 1420 if (m == NULL) 1421 return; 1422 #endif /* PFIL_HOOKS */ 1423 1424 if (dst_if == NULL) { 1425 bridge_broadcast(sc, src_if, m); 1426 return; 1427 } 1428 1429 /* 1430 * At this point, we're dealing with a unicast frame 1431 * going to a different interface. 1432 */ 1433 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1434 m_freem(m); 1435 return; 1436 } 1437 bif = bridge_lookup_member_if(sc, dst_if); 1438 if (bif == NULL) { 1439 /* Not a member of the bridge (anymore?) */ 1440 m_freem(m); 1441 return; 1442 } 1443 1444 if (bif->bif_flags & IFBIF_STP) { 1445 switch (bif->bif_state) { 1446 case BSTP_IFSTATE_DISABLED: 1447 case BSTP_IFSTATE_BLOCKING: 1448 m_freem(m); 1449 return; 1450 } 1451 } 1452 1453 bridge_enqueue(sc, dst_if, m, 1); 1454 } 1455 1456 /* 1457 * bridge_input: 1458 * 1459 * Receive input from a member interface. Queue the packet for 1460 * bridging if it is not for us. 1461 */ 1462 struct mbuf * 1463 bridge_input(struct ifnet *ifp, struct mbuf *m) 1464 { 1465 struct bridge_softc *sc = ifp->if_bridge; 1466 struct bridge_iflist *bif; 1467 struct ether_header *eh; 1468 struct mbuf *mc; 1469 1470 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1471 return (m); 1472 1473 bif = bridge_lookup_member_if(sc, ifp); 1474 if (bif == NULL) 1475 return (m); 1476 1477 eh = mtod(m, struct ether_header *); 1478 1479 if (m->m_flags & (M_BCAST|M_MCAST)) { 1480 /* Tap off 802.1D packets; they do not get forwarded. */ 1481 if (memcmp(eh->ether_dhost, bstp_etheraddr, 1482 ETHER_ADDR_LEN) == 0) { 1483 m = bstp_input(ifp, m); 1484 if (m == NULL) 1485 return (NULL); 1486 } 1487 1488 if (bif->bif_flags & IFBIF_STP) { 1489 switch (bif->bif_state) { 1490 case BSTP_IFSTATE_BLOCKING: 1491 case BSTP_IFSTATE_LISTENING: 1492 case BSTP_IFSTATE_DISABLED: 1493 return (m); 1494 } 1495 } 1496 1497 /* 1498 * Make a deep copy of the packet and enqueue the copy 1499 * for bridge processing; return the original packet for 1500 * local processing. 1501 */ 1502 mc = m_dup(m, 0, M_COPYALL, M_NOWAIT); 1503 if (mc == NULL) 1504 return (m); 1505 1506 /* Perform the bridge forwarding function with the copy. */ 1507 #if NGIF > 0 1508 if (ifp->if_type == IFT_GIF) { 1509 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1510 if (bif->bif_ifp->if_type == IFT_ETHER) 1511 break; 1512 } 1513 if (bif != NULL) { 1514 m->m_flags |= M_PROTO1; 1515 m->m_pkthdr.rcvif = bif->bif_ifp; 1516 (*bif->bif_ifp->if_input)(bif->bif_ifp, m); 1517 m = NULL; 1518 } 1519 } 1520 #endif 1521 bridge_forward(sc, mc); 1522 1523 /* Return the original packet for local processing. */ 1524 return (m); 1525 } 1526 1527 if (bif->bif_flags & IFBIF_STP) { 1528 switch (bif->bif_state) { 1529 case BSTP_IFSTATE_BLOCKING: 1530 case BSTP_IFSTATE_LISTENING: 1531 case BSTP_IFSTATE_DISABLED: 1532 return (m); 1533 } 1534 } 1535 1536 /* 1537 * Unicast. Make sure it's not for us. 1538 */ 1539 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1540 if(bif->bif_ifp->if_type != IFT_ETHER) 1541 continue; 1542 /* It is destined for us. */ 1543 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost, 1544 ETHER_ADDR_LEN) == 0 1545 #if NCARP > 0 1546 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp, 1547 eh, IFT_ETHER, 0) != NULL) 1548 #endif /* NCARP > 0 */ 1549 ) { 1550 if (bif->bif_flags & IFBIF_LEARNING) 1551 (void) bridge_rtupdate(sc, 1552 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); 1553 m->m_pkthdr.rcvif = bif->bif_ifp; 1554 #if NGIF > 0 1555 if (ifp->if_type == IFT_GIF) { 1556 m->m_flags |= M_PROTO1; 1557 m->m_pkthdr.rcvif = bif->bif_ifp; 1558 (*bif->bif_ifp->if_input)(bif->bif_ifp, m); 1559 m = NULL; 1560 } 1561 #endif 1562 return (m); 1563 } 1564 1565 /* We just received a packet that we sent out. */ 1566 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_shost, 1567 ETHER_ADDR_LEN) == 0 1568 #if NCARP > 0 1569 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp, 1570 eh, IFT_ETHER, 1) != NULL) 1571 #endif /* NCARP > 0 */ 1572 ) { 1573 m_freem(m); 1574 return (NULL); 1575 } 1576 } 1577 1578 /* Perform the bridge forwarding function. */ 1579 bridge_forward(sc, m); 1580 1581 return (NULL); 1582 } 1583 1584 /* 1585 * bridge_broadcast: 1586 * 1587 * Send a frame to all interfaces that are members of 1588 * the bridge, except for the one on which the packet 1589 * arrived. 1590 */ 1591 static void 1592 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 1593 struct mbuf *m) 1594 { 1595 struct bridge_iflist *bif; 1596 struct mbuf *mc; 1597 struct ifnet *dst_if; 1598 int used = 0; 1599 1600 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1601 dst_if = bif->bif_ifp; 1602 if (dst_if == src_if) 1603 continue; 1604 1605 if (bif->bif_flags & IFBIF_STP) { 1606 switch (bif->bif_state) { 1607 case BSTP_IFSTATE_BLOCKING: 1608 case BSTP_IFSTATE_DISABLED: 1609 continue; 1610 } 1611 } 1612 1613 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && 1614 (m->m_flags & (M_BCAST|M_MCAST)) == 0) 1615 continue; 1616 1617 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1618 continue; 1619 1620 if (LIST_NEXT(bif, bif_next) == NULL) { 1621 mc = m; 1622 used = 1; 1623 } else { 1624 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1625 if (mc == NULL) { 1626 sc->sc_if.if_oerrors++; 1627 continue; 1628 } 1629 } 1630 1631 bridge_enqueue(sc, dst_if, mc, 1); 1632 } 1633 if (used == 0) 1634 m_freem(m); 1635 } 1636 1637 /* 1638 * bridge_rtupdate: 1639 * 1640 * Add a bridge routing entry. 1641 */ 1642 static int 1643 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, 1644 struct ifnet *dst_if, int setflags, uint8_t flags) 1645 { 1646 struct bridge_rtnode *brt; 1647 int error, s; 1648 1649 /* 1650 * A route for this destination might already exist. If so, 1651 * update it, otherwise create a new one. 1652 */ 1653 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) { 1654 if (sc->sc_brtcnt >= sc->sc_brtmax) 1655 return (ENOSPC); 1656 1657 /* 1658 * Allocate a new bridge forwarding node, and 1659 * initialize the expiration time and Ethernet 1660 * address. 1661 */ 1662 s = splnet(); 1663 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT); 1664 splx(s); 1665 if (brt == NULL) 1666 return (ENOMEM); 1667 1668 memset(brt, 0, sizeof(*brt)); 1669 brt->brt_expire = time_uptime + sc->sc_brttimeout; 1670 brt->brt_flags = IFBAF_DYNAMIC; 1671 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 1672 1673 if ((error = bridge_rtnode_insert(sc, brt)) != 0) { 1674 s = splnet(); 1675 pool_put(&bridge_rtnode_pool, brt); 1676 splx(s); 1677 return (error); 1678 } 1679 } 1680 1681 brt->brt_ifp = dst_if; 1682 if (setflags) { 1683 brt->brt_flags = flags; 1684 if (flags & IFBAF_STATIC) 1685 brt->brt_expire = 0; 1686 else 1687 brt->brt_expire = time_uptime + sc->sc_brttimeout; 1688 } 1689 1690 return (0); 1691 } 1692 1693 /* 1694 * bridge_rtlookup: 1695 * 1696 * Lookup the destination interface for an address. 1697 */ 1698 static struct ifnet * 1699 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr) 1700 { 1701 struct bridge_rtnode *brt; 1702 1703 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 1704 return (NULL); 1705 1706 return (brt->brt_ifp); 1707 } 1708 1709 /* 1710 * bridge_rttrim: 1711 * 1712 * Trim the routine table so that we have a number 1713 * of routing entries less than or equal to the 1714 * maximum number. 1715 */ 1716 static void 1717 bridge_rttrim(struct bridge_softc *sc) 1718 { 1719 struct bridge_rtnode *brt, *nbrt; 1720 1721 /* Make sure we actually need to do this. */ 1722 if (sc->sc_brtcnt <= sc->sc_brtmax) 1723 return; 1724 1725 /* Force an aging cycle; this might trim enough addresses. */ 1726 bridge_rtage(sc); 1727 if (sc->sc_brtcnt <= sc->sc_brtmax) 1728 return; 1729 1730 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1731 nbrt = LIST_NEXT(brt, brt_list); 1732 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1733 bridge_rtnode_destroy(sc, brt); 1734 if (sc->sc_brtcnt <= sc->sc_brtmax) 1735 return; 1736 } 1737 } 1738 } 1739 1740 /* 1741 * bridge_timer: 1742 * 1743 * Aging timer for the bridge. 1744 */ 1745 static void 1746 bridge_timer(void *arg) 1747 { 1748 struct bridge_softc *sc = arg; 1749 int s; 1750 1751 s = splnet(); 1752 bridge_rtage(sc); 1753 splx(s); 1754 1755 if (sc->sc_if.if_flags & IFF_RUNNING) 1756 callout_reset(&sc->sc_brcallout, 1757 bridge_rtable_prune_period * hz, bridge_timer, sc); 1758 } 1759 1760 /* 1761 * bridge_rtage: 1762 * 1763 * Perform an aging cycle. 1764 */ 1765 static void 1766 bridge_rtage(struct bridge_softc *sc) 1767 { 1768 struct bridge_rtnode *brt, *nbrt; 1769 1770 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1771 nbrt = LIST_NEXT(brt, brt_list); 1772 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1773 if (time_uptime >= brt->brt_expire) 1774 bridge_rtnode_destroy(sc, brt); 1775 } 1776 } 1777 } 1778 1779 /* 1780 * bridge_rtflush: 1781 * 1782 * Remove all dynamic addresses from the bridge. 1783 */ 1784 static void 1785 bridge_rtflush(struct bridge_softc *sc, int full) 1786 { 1787 struct bridge_rtnode *brt, *nbrt; 1788 1789 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1790 nbrt = LIST_NEXT(brt, brt_list); 1791 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 1792 bridge_rtnode_destroy(sc, brt); 1793 } 1794 } 1795 1796 /* 1797 * bridge_rtdaddr: 1798 * 1799 * Remove an address from the table. 1800 */ 1801 static int 1802 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr) 1803 { 1804 struct bridge_rtnode *brt; 1805 1806 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 1807 return (ENOENT); 1808 1809 bridge_rtnode_destroy(sc, brt); 1810 return (0); 1811 } 1812 1813 /* 1814 * bridge_rtdelete: 1815 * 1816 * Delete routes to a speicifc member interface. 1817 */ 1818 static void 1819 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp) 1820 { 1821 struct bridge_rtnode *brt, *nbrt; 1822 1823 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1824 nbrt = LIST_NEXT(brt, brt_list); 1825 if (brt->brt_ifp == ifp) 1826 bridge_rtnode_destroy(sc, brt); 1827 } 1828 } 1829 1830 /* 1831 * bridge_rtable_init: 1832 * 1833 * Initialize the route table for this bridge. 1834 */ 1835 static int 1836 bridge_rtable_init(struct bridge_softc *sc) 1837 { 1838 int i; 1839 1840 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 1841 M_DEVBUF, M_NOWAIT); 1842 if (sc->sc_rthash == NULL) 1843 return (ENOMEM); 1844 1845 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++) 1846 LIST_INIT(&sc->sc_rthash[i]); 1847 1848 sc->sc_rthash_key = arc4random(); 1849 1850 LIST_INIT(&sc->sc_rtlist); 1851 1852 return (0); 1853 } 1854 1855 /* 1856 * bridge_rtable_fini: 1857 * 1858 * Deconstruct the route table for this bridge. 1859 */ 1860 static void 1861 bridge_rtable_fini(struct bridge_softc *sc) 1862 { 1863 1864 free(sc->sc_rthash, M_DEVBUF); 1865 } 1866 1867 /* 1868 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 1869 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1870 */ 1871 #define mix(a, b, c) \ 1872 do { \ 1873 a -= b; a -= c; a ^= (c >> 13); \ 1874 b -= c; b -= a; b ^= (a << 8); \ 1875 c -= a; c -= b; c ^= (b >> 13); \ 1876 a -= b; a -= c; a ^= (c >> 12); \ 1877 b -= c; b -= a; b ^= (a << 16); \ 1878 c -= a; c -= b; c ^= (b >> 5); \ 1879 a -= b; a -= c; a ^= (c >> 3); \ 1880 b -= c; b -= a; b ^= (a << 10); \ 1881 c -= a; c -= b; c ^= (b >> 15); \ 1882 } while (/*CONSTCOND*/0) 1883 1884 static inline uint32_t 1885 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr) 1886 { 1887 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; 1888 1889 b += addr[5] << 8; 1890 b += addr[4]; 1891 a += addr[3] << 24; 1892 a += addr[2] << 16; 1893 a += addr[1] << 8; 1894 a += addr[0]; 1895 1896 mix(a, b, c); 1897 1898 return (c & BRIDGE_RTHASH_MASK); 1899 } 1900 1901 #undef mix 1902 1903 /* 1904 * bridge_rtnode_lookup: 1905 * 1906 * Look up a bridge route node for the specified destination. 1907 */ 1908 static struct bridge_rtnode * 1909 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr) 1910 { 1911 struct bridge_rtnode *brt; 1912 uint32_t hash; 1913 int dir; 1914 1915 hash = bridge_rthash(sc, addr); 1916 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { 1917 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN); 1918 if (dir == 0) 1919 return (brt); 1920 if (dir > 0) 1921 return (NULL); 1922 } 1923 1924 return (NULL); 1925 } 1926 1927 /* 1928 * bridge_rtnode_insert: 1929 * 1930 * Insert the specified bridge node into the route table. We 1931 * assume the entry is not already in the table. 1932 */ 1933 static int 1934 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) 1935 { 1936 struct bridge_rtnode *lbrt; 1937 uint32_t hash; 1938 int dir; 1939 1940 hash = bridge_rthash(sc, brt->brt_addr); 1941 1942 lbrt = LIST_FIRST(&sc->sc_rthash[hash]); 1943 if (lbrt == NULL) { 1944 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); 1945 goto out; 1946 } 1947 1948 do { 1949 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN); 1950 if (dir == 0) 1951 return (EEXIST); 1952 if (dir > 0) { 1953 LIST_INSERT_BEFORE(lbrt, brt, brt_hash); 1954 goto out; 1955 } 1956 if (LIST_NEXT(lbrt, brt_hash) == NULL) { 1957 LIST_INSERT_AFTER(lbrt, brt, brt_hash); 1958 goto out; 1959 } 1960 lbrt = LIST_NEXT(lbrt, brt_hash); 1961 } while (lbrt != NULL); 1962 1963 #ifdef DIAGNOSTIC 1964 panic("bridge_rtnode_insert: impossible"); 1965 #endif 1966 1967 out: 1968 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); 1969 sc->sc_brtcnt++; 1970 1971 return (0); 1972 } 1973 1974 /* 1975 * bridge_rtnode_destroy: 1976 * 1977 * Destroy a bridge rtnode. 1978 */ 1979 static void 1980 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt) 1981 { 1982 int s = splnet(); 1983 1984 LIST_REMOVE(brt, brt_hash); 1985 1986 LIST_REMOVE(brt, brt_list); 1987 sc->sc_brtcnt--; 1988 pool_put(&bridge_rtnode_pool, brt); 1989 1990 splx(s); 1991 } 1992 1993 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 1994 extern struct pfil_head inet_pfil_hook; /* XXX */ 1995 extern struct pfil_head inet6_pfil_hook; /* XXX */ 1996 1997 /* 1998 * Send bridge packets through IPF if they are one of the types IPF can deal 1999 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without 2000 * question.) 2001 */ 2002 static int 2003 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) 2004 { 2005 int snap, error; 2006 struct ether_header *eh1, eh2; 2007 struct llc llc1; 2008 u_int16_t ether_type; 2009 2010 snap = 0; 2011 error = -1; /* Default error if not error == 0 */ 2012 eh1 = mtod(*mp, struct ether_header *); 2013 ether_type = ntohs(eh1->ether_type); 2014 2015 /* 2016 * Check for SNAP/LLC. 2017 */ 2018 if (ether_type < ETHERMTU) { 2019 struct llc *llc2 = (struct llc *)(eh1 + 1); 2020 2021 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && 2022 llc2->llc_dsap == LLC_SNAP_LSAP && 2023 llc2->llc_ssap == LLC_SNAP_LSAP && 2024 llc2->llc_control == LLC_UI) { 2025 ether_type = htons(llc2->llc_un.type_snap.ether_type); 2026 snap = 1; 2027 } 2028 } 2029 2030 /* 2031 * If we're trying to filter bridge traffic, don't look at anything 2032 * other than IP and ARP traffic. If the filter doesn't understand 2033 * IPv6, don't allow IPv6 through the bridge either. This is lame 2034 * since if we really wanted, say, an AppleTalk filter, we are hosed, 2035 * but of course we don't have an AppleTalk filter to begin with. 2036 * (Note that since IPF doesn't understand ARP it will pass *ALL* 2037 * ARP traffic.) 2038 */ 2039 switch (ether_type) { 2040 case ETHERTYPE_ARP: 2041 case ETHERTYPE_REVARP: 2042 return 0; /* Automatically pass */ 2043 case ETHERTYPE_IP: 2044 # ifdef INET6 2045 case ETHERTYPE_IPV6: 2046 # endif /* INET6 */ 2047 break; 2048 default: 2049 goto bad; 2050 } 2051 2052 /* Strip off the Ethernet header and keep a copy. */ 2053 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2); 2054 m_adj(*mp, ETHER_HDR_LEN); 2055 2056 /* Strip off snap header, if present */ 2057 if (snap) { 2058 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1); 2059 m_adj(*mp, sizeof(struct llc)); 2060 } 2061 2062 /* 2063 * Check basic packet sanity and run IPF through pfil. 2064 */ 2065 switch (ether_type) 2066 { 2067 case ETHERTYPE_IP : 2068 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0; 2069 if (error == 0) 2070 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir); 2071 break; 2072 # ifdef INET6 2073 case ETHERTYPE_IPV6 : 2074 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0; 2075 if (error == 0) 2076 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir); 2077 break; 2078 # endif 2079 default : 2080 error = 0; 2081 break; 2082 } 2083 2084 if (*mp == NULL) 2085 return error; 2086 if (error != 0) 2087 goto bad; 2088 2089 error = -1; 2090 2091 /* 2092 * Finally, put everything back the way it was and return 2093 */ 2094 if (snap) { 2095 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT); 2096 if (*mp == NULL) 2097 return error; 2098 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc)); 2099 } 2100 2101 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 2102 if (*mp == NULL) 2103 return error; 2104 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 2105 2106 return 0; 2107 2108 bad: 2109 m_freem(*mp); 2110 *mp = NULL; 2111 return error; 2112 } 2113 2114 /* 2115 * Perform basic checks on header size since 2116 * IPF assumes ip_input has already processed 2117 * it for it. Cut-and-pasted from ip_input.c. 2118 * Given how simple the IPv6 version is, 2119 * does the IPv4 version really need to be 2120 * this complicated? 2121 * 2122 * XXX Should we update ipstat here, or not? 2123 * XXX Right now we update ipstat but not 2124 * XXX csum_counter. 2125 */ 2126 static int 2127 bridge_ip_checkbasic(struct mbuf **mp) 2128 { 2129 struct mbuf *m = *mp; 2130 struct ip *ip; 2131 int len, hlen; 2132 2133 if (*mp == NULL) 2134 return -1; 2135 2136 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2137 if ((m = m_copyup(m, sizeof(struct ip), 2138 (max_linkhdr + 3) & ~3)) == NULL) { 2139 /* XXXJRT new stat, please */ 2140 ipstat.ips_toosmall++; 2141 goto bad; 2142 } 2143 } else if (__predict_false(m->m_len < sizeof (struct ip))) { 2144 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { 2145 ipstat.ips_toosmall++; 2146 goto bad; 2147 } 2148 } 2149 ip = mtod(m, struct ip *); 2150 if (ip == NULL) goto bad; 2151 2152 if (ip->ip_v != IPVERSION) { 2153 ipstat.ips_badvers++; 2154 goto bad; 2155 } 2156 hlen = ip->ip_hl << 2; 2157 if (hlen < sizeof(struct ip)) { /* minimum header length */ 2158 ipstat.ips_badhlen++; 2159 goto bad; 2160 } 2161 if (hlen > m->m_len) { 2162 if ((m = m_pullup(m, hlen)) == 0) { 2163 ipstat.ips_badhlen++; 2164 goto bad; 2165 } 2166 ip = mtod(m, struct ip *); 2167 if (ip == NULL) goto bad; 2168 } 2169 2170 switch (m->m_pkthdr.csum_flags & 2171 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) | 2172 M_CSUM_IPv4_BAD)) { 2173 case M_CSUM_IPv4|M_CSUM_IPv4_BAD: 2174 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */ 2175 goto bad; 2176 2177 case M_CSUM_IPv4: 2178 /* Checksum was okay. */ 2179 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */ 2180 break; 2181 2182 default: 2183 /* Must compute it ourselves. */ 2184 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */ 2185 if (in_cksum(m, hlen) != 0) 2186 goto bad; 2187 break; 2188 } 2189 2190 /* Retrieve the packet length. */ 2191 len = ntohs(ip->ip_len); 2192 2193 /* 2194 * Check for additional length bogosity 2195 */ 2196 if (len < hlen) { 2197 ipstat.ips_badlen++; 2198 goto bad; 2199 } 2200 2201 /* 2202 * Check that the amount of data in the buffers 2203 * is as at least much as the IP header would have us expect. 2204 * Drop packet if shorter than we expect. 2205 */ 2206 if (m->m_pkthdr.len < len) { 2207 ipstat.ips_tooshort++; 2208 goto bad; 2209 } 2210 2211 /* Checks out, proceed */ 2212 *mp = m; 2213 return 0; 2214 2215 bad: 2216 *mp = m; 2217 return -1; 2218 } 2219 2220 # ifdef INET6 2221 /* 2222 * Same as above, but for IPv6. 2223 * Cut-and-pasted from ip6_input.c. 2224 * XXX Should we update ip6stat, or not? 2225 */ 2226 static int 2227 bridge_ip6_checkbasic(struct mbuf **mp) 2228 { 2229 struct mbuf *m = *mp; 2230 struct ip6_hdr *ip6; 2231 2232 /* 2233 * If the IPv6 header is not aligned, slurp it up into a new 2234 * mbuf with space for link headers, in the event we forward 2235 * it. Otherwise, if it is aligned, make sure the entire base 2236 * IPv6 header is in the first mbuf of the chain. 2237 */ 2238 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2239 struct ifnet *inifp = m->m_pkthdr.rcvif; 2240 if ((m = m_copyup(m, sizeof(struct ip6_hdr), 2241 (max_linkhdr + 3) & ~3)) == NULL) { 2242 /* XXXJRT new stat, please */ 2243 ip6stat.ip6s_toosmall++; 2244 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2245 goto bad; 2246 } 2247 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { 2248 struct ifnet *inifp = m->m_pkthdr.rcvif; 2249 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 2250 ip6stat.ip6s_toosmall++; 2251 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2252 goto bad; 2253 } 2254 } 2255 2256 ip6 = mtod(m, struct ip6_hdr *); 2257 2258 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 2259 ip6stat.ip6s_badvers++; 2260 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 2261 goto bad; 2262 } 2263 2264 /* Checks out, proceed */ 2265 *mp = m; 2266 return 0; 2267 2268 bad: 2269 *mp = m; 2270 return -1; 2271 } 2272 # endif /* INET6 */ 2273 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 2274