1 /* $NetBSD: if_bridge.c,v 1.43 2006/10/13 16:53:36 dogcow 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.43 2006/10/13 16:53:36 dogcow 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 __unused) 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 __unused) 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 #else 1168 do { if (&runfilt) {} } while (/* CONSTCOND */ 0); /* quiet -Wunused */ 1169 #endif /* PFIL_HOOKS */ 1170 1171 #ifdef ALTQ 1172 /* 1173 * If ALTQ is enabled on the member interface, do 1174 * classification; the queueing discipline might 1175 * not require classification, but might require 1176 * the address family/header pointer in the pktattr. 1177 */ 1178 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) { 1179 /* XXX IFT_ETHER */ 1180 altq_etherclassify(&dst_ifp->if_snd, m, &pktattr); 1181 } 1182 #endif /* ALTQ */ 1183 1184 len = m->m_pkthdr.len; 1185 m->m_flags |= M_PROTO1; 1186 mflags = m->m_flags; 1187 IFQ_ENQUEUE(&dst_ifp->if_snd, m, &pktattr, error); 1188 if (error) { 1189 /* mbuf is already freed */ 1190 sc->sc_if.if_oerrors++; 1191 return; 1192 } 1193 1194 sc->sc_if.if_opackets++; 1195 sc->sc_if.if_obytes += len; 1196 1197 dst_ifp->if_obytes += len; 1198 1199 if (mflags & M_MCAST) { 1200 sc->sc_if.if_omcasts++; 1201 dst_ifp->if_omcasts++; 1202 } 1203 1204 if ((dst_ifp->if_flags & IFF_OACTIVE) == 0) 1205 (*dst_ifp->if_start)(dst_ifp); 1206 } 1207 1208 /* 1209 * bridge_output: 1210 * 1211 * Send output from a bridge member interface. This 1212 * performs the bridging function for locally originated 1213 * packets. 1214 * 1215 * The mbuf has the Ethernet header already attached. We must 1216 * enqueue or free the mbuf before returning. 1217 */ 1218 int 1219 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa __unused, 1220 struct rtentry *rt __unused) 1221 { 1222 struct ether_header *eh; 1223 struct ifnet *dst_if; 1224 struct bridge_softc *sc; 1225 int s; 1226 1227 if (m->m_len < ETHER_HDR_LEN) { 1228 m = m_pullup(m, ETHER_HDR_LEN); 1229 if (m == NULL) 1230 return (0); 1231 } 1232 1233 eh = mtod(m, struct ether_header *); 1234 sc = ifp->if_bridge; 1235 1236 s = splnet(); 1237 1238 /* 1239 * If bridge is down, but the original output interface is up, 1240 * go ahead and send out that interface. Otherwise, the packet 1241 * is dropped below. 1242 */ 1243 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1244 dst_if = ifp; 1245 goto sendunicast; 1246 } 1247 1248 /* 1249 * If the packet is a multicast, or we don't know a better way to 1250 * get there, send to all interfaces. 1251 */ 1252 if (ETHER_IS_MULTICAST(eh->ether_dhost)) 1253 dst_if = NULL; 1254 else 1255 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1256 if (dst_if == NULL) { 1257 struct bridge_iflist *bif; 1258 struct mbuf *mc; 1259 int used = 0; 1260 1261 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1262 dst_if = bif->bif_ifp; 1263 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1264 continue; 1265 1266 /* 1267 * If this is not the original output interface, 1268 * and the interface is participating in spanning 1269 * tree, make sure the port is in a state that 1270 * allows forwarding. 1271 */ 1272 if (dst_if != ifp && 1273 (bif->bif_flags & IFBIF_STP) != 0) { 1274 switch (bif->bif_state) { 1275 case BSTP_IFSTATE_BLOCKING: 1276 case BSTP_IFSTATE_LISTENING: 1277 case BSTP_IFSTATE_DISABLED: 1278 continue; 1279 } 1280 } 1281 1282 if (LIST_NEXT(bif, bif_next) == NULL) { 1283 used = 1; 1284 mc = m; 1285 } else { 1286 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); 1287 if (mc == NULL) { 1288 sc->sc_if.if_oerrors++; 1289 continue; 1290 } 1291 } 1292 1293 bridge_enqueue(sc, dst_if, mc, 0); 1294 } 1295 if (used == 0) 1296 m_freem(m); 1297 splx(s); 1298 return (0); 1299 } 1300 1301 sendunicast: 1302 /* 1303 * XXX Spanning tree consideration here? 1304 */ 1305 1306 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1307 m_freem(m); 1308 splx(s); 1309 return (0); 1310 } 1311 1312 bridge_enqueue(sc, dst_if, m, 0); 1313 1314 splx(s); 1315 return (0); 1316 } 1317 1318 /* 1319 * bridge_start: 1320 * 1321 * Start output on a bridge. 1322 * 1323 * NOTE: This routine should never be called in this implementation. 1324 */ 1325 static void 1326 bridge_start(struct ifnet *ifp) 1327 { 1328 1329 printf("%s: bridge_start() called\n", ifp->if_xname); 1330 } 1331 1332 /* 1333 * bridge_forward: 1334 * 1335 * The forwarding function of the bridge. 1336 */ 1337 static void 1338 bridge_forward(struct bridge_softc *sc, struct mbuf *m) 1339 { 1340 struct bridge_iflist *bif; 1341 struct ifnet *src_if, *dst_if; 1342 struct ether_header *eh; 1343 1344 src_if = m->m_pkthdr.rcvif; 1345 1346 sc->sc_if.if_ipackets++; 1347 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1348 1349 /* 1350 * Look up the bridge_iflist. 1351 */ 1352 bif = bridge_lookup_member_if(sc, src_if); 1353 if (bif == NULL) { 1354 /* Interface is not a bridge member (anymore?) */ 1355 m_freem(m); 1356 return; 1357 } 1358 1359 if (bif->bif_flags & IFBIF_STP) { 1360 switch (bif->bif_state) { 1361 case BSTP_IFSTATE_BLOCKING: 1362 case BSTP_IFSTATE_LISTENING: 1363 case BSTP_IFSTATE_DISABLED: 1364 m_freem(m); 1365 return; 1366 } 1367 } 1368 1369 eh = mtod(m, struct ether_header *); 1370 1371 /* 1372 * If the interface is learning, and the source 1373 * address is valid and not multicast, record 1374 * the address. 1375 */ 1376 if ((bif->bif_flags & IFBIF_LEARNING) != 0 && 1377 ETHER_IS_MULTICAST(eh->ether_shost) == 0 && 1378 (eh->ether_shost[0] == 0 && 1379 eh->ether_shost[1] == 0 && 1380 eh->ether_shost[2] == 0 && 1381 eh->ether_shost[3] == 0 && 1382 eh->ether_shost[4] == 0 && 1383 eh->ether_shost[5] == 0) == 0) { 1384 (void) bridge_rtupdate(sc, eh->ether_shost, 1385 src_if, 0, IFBAF_DYNAMIC); 1386 } 1387 1388 if ((bif->bif_flags & IFBIF_STP) != 0 && 1389 bif->bif_state == BSTP_IFSTATE_LEARNING) { 1390 m_freem(m); 1391 return; 1392 } 1393 1394 /* 1395 * At this point, the port either doesn't participate 1396 * in spanning tree or it is in the forwarding state. 1397 */ 1398 1399 /* 1400 * If the packet is unicast, destined for someone on 1401 * "this" side of the bridge, drop it. 1402 */ 1403 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1404 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1405 if (src_if == dst_if) { 1406 m_freem(m); 1407 return; 1408 } 1409 } else { 1410 /* ...forward it to all interfaces. */ 1411 sc->sc_if.if_imcasts++; 1412 dst_if = NULL; 1413 } 1414 1415 #ifdef PFIL_HOOKS 1416 if (pfil_run_hooks(&sc->sc_if.if_pfil, &m, 1417 m->m_pkthdr.rcvif, PFIL_IN) != 0) { 1418 if (m != NULL) 1419 m_freem(m); 1420 return; 1421 } 1422 if (m == NULL) 1423 return; 1424 #endif /* PFIL_HOOKS */ 1425 1426 if (dst_if == NULL) { 1427 bridge_broadcast(sc, src_if, m); 1428 return; 1429 } 1430 1431 /* 1432 * At this point, we're dealing with a unicast frame 1433 * going to a different interface. 1434 */ 1435 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1436 m_freem(m); 1437 return; 1438 } 1439 bif = bridge_lookup_member_if(sc, dst_if); 1440 if (bif == NULL) { 1441 /* Not a member of the bridge (anymore?) */ 1442 m_freem(m); 1443 return; 1444 } 1445 1446 if (bif->bif_flags & IFBIF_STP) { 1447 switch (bif->bif_state) { 1448 case BSTP_IFSTATE_DISABLED: 1449 case BSTP_IFSTATE_BLOCKING: 1450 m_freem(m); 1451 return; 1452 } 1453 } 1454 1455 bridge_enqueue(sc, dst_if, m, 1); 1456 } 1457 1458 /* 1459 * bridge_input: 1460 * 1461 * Receive input from a member interface. Queue the packet for 1462 * bridging if it is not for us. 1463 */ 1464 struct mbuf * 1465 bridge_input(struct ifnet *ifp, struct mbuf *m) 1466 { 1467 struct bridge_softc *sc = ifp->if_bridge; 1468 struct bridge_iflist *bif; 1469 struct ether_header *eh; 1470 struct mbuf *mc; 1471 1472 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1473 return (m); 1474 1475 bif = bridge_lookup_member_if(sc, ifp); 1476 if (bif == NULL) 1477 return (m); 1478 1479 eh = mtod(m, struct ether_header *); 1480 1481 if (m->m_flags & (M_BCAST|M_MCAST)) { 1482 /* Tap off 802.1D packets; they do not get forwarded. */ 1483 if (memcmp(eh->ether_dhost, bstp_etheraddr, 1484 ETHER_ADDR_LEN) == 0) { 1485 m = bstp_input(ifp, m); 1486 if (m == NULL) 1487 return (NULL); 1488 } 1489 1490 if (bif->bif_flags & IFBIF_STP) { 1491 switch (bif->bif_state) { 1492 case BSTP_IFSTATE_BLOCKING: 1493 case BSTP_IFSTATE_LISTENING: 1494 case BSTP_IFSTATE_DISABLED: 1495 return (m); 1496 } 1497 } 1498 1499 /* 1500 * Make a deep copy of the packet and enqueue the copy 1501 * for bridge processing; return the original packet for 1502 * local processing. 1503 */ 1504 mc = m_dup(m, 0, M_COPYALL, M_NOWAIT); 1505 if (mc == NULL) 1506 return (m); 1507 1508 /* Perform the bridge forwarding function with the copy. */ 1509 #if NGIF > 0 1510 if (ifp->if_type == IFT_GIF) { 1511 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1512 if (bif->bif_ifp->if_type == IFT_ETHER) 1513 break; 1514 } 1515 if (bif != NULL) { 1516 m->m_flags |= M_PROTO1; 1517 m->m_pkthdr.rcvif = bif->bif_ifp; 1518 (*bif->bif_ifp->if_input)(bif->bif_ifp, m); 1519 m = NULL; 1520 } 1521 } 1522 #endif 1523 bridge_forward(sc, mc); 1524 1525 /* Return the original packet for local processing. */ 1526 return (m); 1527 } 1528 1529 if (bif->bif_flags & IFBIF_STP) { 1530 switch (bif->bif_state) { 1531 case BSTP_IFSTATE_BLOCKING: 1532 case BSTP_IFSTATE_LISTENING: 1533 case BSTP_IFSTATE_DISABLED: 1534 return (m); 1535 } 1536 } 1537 1538 /* 1539 * Unicast. Make sure it's not for us. 1540 */ 1541 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1542 if(bif->bif_ifp->if_type != IFT_ETHER) 1543 continue; 1544 /* It is destined for us. */ 1545 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost, 1546 ETHER_ADDR_LEN) == 0 1547 #if NCARP > 0 1548 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp, 1549 eh, IFT_ETHER, 0) != NULL) 1550 #endif /* NCARP > 0 */ 1551 ) { 1552 if (bif->bif_flags & IFBIF_LEARNING) 1553 (void) bridge_rtupdate(sc, 1554 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); 1555 m->m_pkthdr.rcvif = bif->bif_ifp; 1556 #if NGIF > 0 1557 if (ifp->if_type == IFT_GIF) { 1558 m->m_flags |= M_PROTO1; 1559 m->m_pkthdr.rcvif = bif->bif_ifp; 1560 (*bif->bif_ifp->if_input)(bif->bif_ifp, m); 1561 m = NULL; 1562 } 1563 #endif 1564 return (m); 1565 } 1566 1567 /* We just received a packet that we sent out. */ 1568 if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_shost, 1569 ETHER_ADDR_LEN) == 0 1570 #if NCARP > 0 1571 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp, 1572 eh, IFT_ETHER, 1) != NULL) 1573 #endif /* NCARP > 0 */ 1574 ) { 1575 m_freem(m); 1576 return (NULL); 1577 } 1578 } 1579 1580 /* Perform the bridge forwarding function. */ 1581 bridge_forward(sc, m); 1582 1583 return (NULL); 1584 } 1585 1586 /* 1587 * bridge_broadcast: 1588 * 1589 * Send a frame to all interfaces that are members of 1590 * the bridge, except for the one on which the packet 1591 * arrived. 1592 */ 1593 static void 1594 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 1595 struct mbuf *m) 1596 { 1597 struct bridge_iflist *bif; 1598 struct mbuf *mc; 1599 struct ifnet *dst_if; 1600 int used = 0; 1601 1602 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1603 dst_if = bif->bif_ifp; 1604 if (dst_if == src_if) 1605 continue; 1606 1607 if (bif->bif_flags & IFBIF_STP) { 1608 switch (bif->bif_state) { 1609 case BSTP_IFSTATE_BLOCKING: 1610 case BSTP_IFSTATE_DISABLED: 1611 continue; 1612 } 1613 } 1614 1615 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && 1616 (m->m_flags & (M_BCAST|M_MCAST)) == 0) 1617 continue; 1618 1619 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1620 continue; 1621 1622 if (LIST_NEXT(bif, bif_next) == NULL) { 1623 mc = m; 1624 used = 1; 1625 } else { 1626 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1627 if (mc == NULL) { 1628 sc->sc_if.if_oerrors++; 1629 continue; 1630 } 1631 } 1632 1633 bridge_enqueue(sc, dst_if, mc, 1); 1634 } 1635 if (used == 0) 1636 m_freem(m); 1637 } 1638 1639 /* 1640 * bridge_rtupdate: 1641 * 1642 * Add a bridge routing entry. 1643 */ 1644 static int 1645 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, 1646 struct ifnet *dst_if, int setflags, uint8_t flags) 1647 { 1648 struct bridge_rtnode *brt; 1649 int error, s; 1650 1651 /* 1652 * A route for this destination might already exist. If so, 1653 * update it, otherwise create a new one. 1654 */ 1655 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) { 1656 if (sc->sc_brtcnt >= sc->sc_brtmax) 1657 return (ENOSPC); 1658 1659 /* 1660 * Allocate a new bridge forwarding node, and 1661 * initialize the expiration time and Ethernet 1662 * address. 1663 */ 1664 s = splnet(); 1665 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT); 1666 splx(s); 1667 if (brt == NULL) 1668 return (ENOMEM); 1669 1670 memset(brt, 0, sizeof(*brt)); 1671 brt->brt_expire = time_uptime + sc->sc_brttimeout; 1672 brt->brt_flags = IFBAF_DYNAMIC; 1673 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 1674 1675 if ((error = bridge_rtnode_insert(sc, brt)) != 0) { 1676 s = splnet(); 1677 pool_put(&bridge_rtnode_pool, brt); 1678 splx(s); 1679 return (error); 1680 } 1681 } 1682 1683 brt->brt_ifp = dst_if; 1684 if (setflags) { 1685 brt->brt_flags = flags; 1686 if (flags & IFBAF_STATIC) 1687 brt->brt_expire = 0; 1688 else 1689 brt->brt_expire = time_uptime + sc->sc_brttimeout; 1690 } 1691 1692 return (0); 1693 } 1694 1695 /* 1696 * bridge_rtlookup: 1697 * 1698 * Lookup the destination interface for an address. 1699 */ 1700 static struct ifnet * 1701 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr) 1702 { 1703 struct bridge_rtnode *brt; 1704 1705 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 1706 return (NULL); 1707 1708 return (brt->brt_ifp); 1709 } 1710 1711 /* 1712 * bridge_rttrim: 1713 * 1714 * Trim the routine table so that we have a number 1715 * of routing entries less than or equal to the 1716 * maximum number. 1717 */ 1718 static void 1719 bridge_rttrim(struct bridge_softc *sc) 1720 { 1721 struct bridge_rtnode *brt, *nbrt; 1722 1723 /* Make sure we actually need to do this. */ 1724 if (sc->sc_brtcnt <= sc->sc_brtmax) 1725 return; 1726 1727 /* Force an aging cycle; this might trim enough addresses. */ 1728 bridge_rtage(sc); 1729 if (sc->sc_brtcnt <= sc->sc_brtmax) 1730 return; 1731 1732 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1733 nbrt = LIST_NEXT(brt, brt_list); 1734 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1735 bridge_rtnode_destroy(sc, brt); 1736 if (sc->sc_brtcnt <= sc->sc_brtmax) 1737 return; 1738 } 1739 } 1740 } 1741 1742 /* 1743 * bridge_timer: 1744 * 1745 * Aging timer for the bridge. 1746 */ 1747 static void 1748 bridge_timer(void *arg) 1749 { 1750 struct bridge_softc *sc = arg; 1751 int s; 1752 1753 s = splnet(); 1754 bridge_rtage(sc); 1755 splx(s); 1756 1757 if (sc->sc_if.if_flags & IFF_RUNNING) 1758 callout_reset(&sc->sc_brcallout, 1759 bridge_rtable_prune_period * hz, bridge_timer, sc); 1760 } 1761 1762 /* 1763 * bridge_rtage: 1764 * 1765 * Perform an aging cycle. 1766 */ 1767 static void 1768 bridge_rtage(struct bridge_softc *sc) 1769 { 1770 struct bridge_rtnode *brt, *nbrt; 1771 1772 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1773 nbrt = LIST_NEXT(brt, brt_list); 1774 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1775 if (time_uptime >= brt->brt_expire) 1776 bridge_rtnode_destroy(sc, brt); 1777 } 1778 } 1779 } 1780 1781 /* 1782 * bridge_rtflush: 1783 * 1784 * Remove all dynamic addresses from the bridge. 1785 */ 1786 static void 1787 bridge_rtflush(struct bridge_softc *sc, int full) 1788 { 1789 struct bridge_rtnode *brt, *nbrt; 1790 1791 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1792 nbrt = LIST_NEXT(brt, brt_list); 1793 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 1794 bridge_rtnode_destroy(sc, brt); 1795 } 1796 } 1797 1798 /* 1799 * bridge_rtdaddr: 1800 * 1801 * Remove an address from the table. 1802 */ 1803 static int 1804 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr) 1805 { 1806 struct bridge_rtnode *brt; 1807 1808 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) 1809 return (ENOENT); 1810 1811 bridge_rtnode_destroy(sc, brt); 1812 return (0); 1813 } 1814 1815 /* 1816 * bridge_rtdelete: 1817 * 1818 * Delete routes to a speicifc member interface. 1819 */ 1820 static void 1821 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp) 1822 { 1823 struct bridge_rtnode *brt, *nbrt; 1824 1825 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { 1826 nbrt = LIST_NEXT(brt, brt_list); 1827 if (brt->brt_ifp == ifp) 1828 bridge_rtnode_destroy(sc, brt); 1829 } 1830 } 1831 1832 /* 1833 * bridge_rtable_init: 1834 * 1835 * Initialize the route table for this bridge. 1836 */ 1837 static int 1838 bridge_rtable_init(struct bridge_softc *sc) 1839 { 1840 int i; 1841 1842 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 1843 M_DEVBUF, M_NOWAIT); 1844 if (sc->sc_rthash == NULL) 1845 return (ENOMEM); 1846 1847 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++) 1848 LIST_INIT(&sc->sc_rthash[i]); 1849 1850 sc->sc_rthash_key = arc4random(); 1851 1852 LIST_INIT(&sc->sc_rtlist); 1853 1854 return (0); 1855 } 1856 1857 /* 1858 * bridge_rtable_fini: 1859 * 1860 * Deconstruct the route table for this bridge. 1861 */ 1862 static void 1863 bridge_rtable_fini(struct bridge_softc *sc) 1864 { 1865 1866 free(sc->sc_rthash, M_DEVBUF); 1867 } 1868 1869 /* 1870 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 1871 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1872 */ 1873 #define mix(a, b, c) \ 1874 do { \ 1875 a -= b; a -= c; a ^= (c >> 13); \ 1876 b -= c; b -= a; b ^= (a << 8); \ 1877 c -= a; c -= b; c ^= (b >> 13); \ 1878 a -= b; a -= c; a ^= (c >> 12); \ 1879 b -= c; b -= a; b ^= (a << 16); \ 1880 c -= a; c -= b; c ^= (b >> 5); \ 1881 a -= b; a -= c; a ^= (c >> 3); \ 1882 b -= c; b -= a; b ^= (a << 10); \ 1883 c -= a; c -= b; c ^= (b >> 15); \ 1884 } while (/*CONSTCOND*/0) 1885 1886 static inline uint32_t 1887 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr) 1888 { 1889 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; 1890 1891 b += addr[5] << 8; 1892 b += addr[4]; 1893 a += addr[3] << 24; 1894 a += addr[2] << 16; 1895 a += addr[1] << 8; 1896 a += addr[0]; 1897 1898 mix(a, b, c); 1899 1900 return (c & BRIDGE_RTHASH_MASK); 1901 } 1902 1903 #undef mix 1904 1905 /* 1906 * bridge_rtnode_lookup: 1907 * 1908 * Look up a bridge route node for the specified destination. 1909 */ 1910 static struct bridge_rtnode * 1911 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr) 1912 { 1913 struct bridge_rtnode *brt; 1914 uint32_t hash; 1915 int dir; 1916 1917 hash = bridge_rthash(sc, addr); 1918 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { 1919 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN); 1920 if (dir == 0) 1921 return (brt); 1922 if (dir > 0) 1923 return (NULL); 1924 } 1925 1926 return (NULL); 1927 } 1928 1929 /* 1930 * bridge_rtnode_insert: 1931 * 1932 * Insert the specified bridge node into the route table. We 1933 * assume the entry is not already in the table. 1934 */ 1935 static int 1936 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) 1937 { 1938 struct bridge_rtnode *lbrt; 1939 uint32_t hash; 1940 int dir; 1941 1942 hash = bridge_rthash(sc, brt->brt_addr); 1943 1944 lbrt = LIST_FIRST(&sc->sc_rthash[hash]); 1945 if (lbrt == NULL) { 1946 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); 1947 goto out; 1948 } 1949 1950 do { 1951 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN); 1952 if (dir == 0) 1953 return (EEXIST); 1954 if (dir > 0) { 1955 LIST_INSERT_BEFORE(lbrt, brt, brt_hash); 1956 goto out; 1957 } 1958 if (LIST_NEXT(lbrt, brt_hash) == NULL) { 1959 LIST_INSERT_AFTER(lbrt, brt, brt_hash); 1960 goto out; 1961 } 1962 lbrt = LIST_NEXT(lbrt, brt_hash); 1963 } while (lbrt != NULL); 1964 1965 #ifdef DIAGNOSTIC 1966 panic("bridge_rtnode_insert: impossible"); 1967 #endif 1968 1969 out: 1970 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); 1971 sc->sc_brtcnt++; 1972 1973 return (0); 1974 } 1975 1976 /* 1977 * bridge_rtnode_destroy: 1978 * 1979 * Destroy a bridge rtnode. 1980 */ 1981 static void 1982 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt) 1983 { 1984 int s = splnet(); 1985 1986 LIST_REMOVE(brt, brt_hash); 1987 1988 LIST_REMOVE(brt, brt_list); 1989 sc->sc_brtcnt--; 1990 pool_put(&bridge_rtnode_pool, brt); 1991 1992 splx(s); 1993 } 1994 1995 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS) 1996 extern struct pfil_head inet_pfil_hook; /* XXX */ 1997 extern struct pfil_head inet6_pfil_hook; /* XXX */ 1998 1999 /* 2000 * Send bridge packets through IPF if they are one of the types IPF can deal 2001 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without 2002 * question.) 2003 */ 2004 static int 2005 bridge_ipf(void *arg __unused, struct mbuf **mp, struct ifnet *ifp, int dir) 2006 { 2007 int snap, error; 2008 struct ether_header *eh1, eh2; 2009 struct llc llc1; 2010 u_int16_t ether_type; 2011 2012 snap = 0; 2013 error = -1; /* Default error if not error == 0 */ 2014 eh1 = mtod(*mp, struct ether_header *); 2015 ether_type = ntohs(eh1->ether_type); 2016 2017 /* 2018 * Check for SNAP/LLC. 2019 */ 2020 if (ether_type < ETHERMTU) { 2021 struct llc *llc2 = (struct llc *)(eh1 + 1); 2022 2023 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && 2024 llc2->llc_dsap == LLC_SNAP_LSAP && 2025 llc2->llc_ssap == LLC_SNAP_LSAP && 2026 llc2->llc_control == LLC_UI) { 2027 ether_type = htons(llc2->llc_un.type_snap.ether_type); 2028 snap = 1; 2029 } 2030 } 2031 2032 /* 2033 * If we're trying to filter bridge traffic, don't look at anything 2034 * other than IP and ARP traffic. If the filter doesn't understand 2035 * IPv6, don't allow IPv6 through the bridge either. This is lame 2036 * since if we really wanted, say, an AppleTalk filter, we are hosed, 2037 * but of course we don't have an AppleTalk filter to begin with. 2038 * (Note that since IPF doesn't understand ARP it will pass *ALL* 2039 * ARP traffic.) 2040 */ 2041 switch (ether_type) { 2042 case ETHERTYPE_ARP: 2043 case ETHERTYPE_REVARP: 2044 return 0; /* Automatically pass */ 2045 case ETHERTYPE_IP: 2046 # ifdef INET6 2047 case ETHERTYPE_IPV6: 2048 # endif /* INET6 */ 2049 break; 2050 default: 2051 goto bad; 2052 } 2053 2054 /* Strip off the Ethernet header and keep a copy. */ 2055 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2); 2056 m_adj(*mp, ETHER_HDR_LEN); 2057 2058 /* Strip off snap header, if present */ 2059 if (snap) { 2060 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1); 2061 m_adj(*mp, sizeof(struct llc)); 2062 } 2063 2064 /* 2065 * Check basic packet sanity and run IPF through pfil. 2066 */ 2067 switch (ether_type) 2068 { 2069 case ETHERTYPE_IP : 2070 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0; 2071 if (error == 0) 2072 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir); 2073 break; 2074 # ifdef INET6 2075 case ETHERTYPE_IPV6 : 2076 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0; 2077 if (error == 0) 2078 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir); 2079 break; 2080 # endif 2081 default : 2082 error = 0; 2083 break; 2084 } 2085 2086 if (*mp == NULL) 2087 return error; 2088 if (error != 0) 2089 goto bad; 2090 2091 error = -1; 2092 2093 /* 2094 * Finally, put everything back the way it was and return 2095 */ 2096 if (snap) { 2097 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT); 2098 if (*mp == NULL) 2099 return error; 2100 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc)); 2101 } 2102 2103 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 2104 if (*mp == NULL) 2105 return error; 2106 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 2107 2108 return 0; 2109 2110 bad: 2111 m_freem(*mp); 2112 *mp = NULL; 2113 return error; 2114 } 2115 2116 /* 2117 * Perform basic checks on header size since 2118 * IPF assumes ip_input has already processed 2119 * it for it. Cut-and-pasted from ip_input.c. 2120 * Given how simple the IPv6 version is, 2121 * does the IPv4 version really need to be 2122 * this complicated? 2123 * 2124 * XXX Should we update ipstat here, or not? 2125 * XXX Right now we update ipstat but not 2126 * XXX csum_counter. 2127 */ 2128 static int 2129 bridge_ip_checkbasic(struct mbuf **mp) 2130 { 2131 struct mbuf *m = *mp; 2132 struct ip *ip; 2133 int len, hlen; 2134 2135 if (*mp == NULL) 2136 return -1; 2137 2138 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2139 if ((m = m_copyup(m, sizeof(struct ip), 2140 (max_linkhdr + 3) & ~3)) == NULL) { 2141 /* XXXJRT new stat, please */ 2142 ipstat.ips_toosmall++; 2143 goto bad; 2144 } 2145 } else if (__predict_false(m->m_len < sizeof (struct ip))) { 2146 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { 2147 ipstat.ips_toosmall++; 2148 goto bad; 2149 } 2150 } 2151 ip = mtod(m, struct ip *); 2152 if (ip == NULL) goto bad; 2153 2154 if (ip->ip_v != IPVERSION) { 2155 ipstat.ips_badvers++; 2156 goto bad; 2157 } 2158 hlen = ip->ip_hl << 2; 2159 if (hlen < sizeof(struct ip)) { /* minimum header length */ 2160 ipstat.ips_badhlen++; 2161 goto bad; 2162 } 2163 if (hlen > m->m_len) { 2164 if ((m = m_pullup(m, hlen)) == 0) { 2165 ipstat.ips_badhlen++; 2166 goto bad; 2167 } 2168 ip = mtod(m, struct ip *); 2169 if (ip == NULL) goto bad; 2170 } 2171 2172 switch (m->m_pkthdr.csum_flags & 2173 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) | 2174 M_CSUM_IPv4_BAD)) { 2175 case M_CSUM_IPv4|M_CSUM_IPv4_BAD: 2176 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */ 2177 goto bad; 2178 2179 case M_CSUM_IPv4: 2180 /* Checksum was okay. */ 2181 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */ 2182 break; 2183 2184 default: 2185 /* Must compute it ourselves. */ 2186 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */ 2187 if (in_cksum(m, hlen) != 0) 2188 goto bad; 2189 break; 2190 } 2191 2192 /* Retrieve the packet length. */ 2193 len = ntohs(ip->ip_len); 2194 2195 /* 2196 * Check for additional length bogosity 2197 */ 2198 if (len < hlen) { 2199 ipstat.ips_badlen++; 2200 goto bad; 2201 } 2202 2203 /* 2204 * Check that the amount of data in the buffers 2205 * is as at least much as the IP header would have us expect. 2206 * Drop packet if shorter than we expect. 2207 */ 2208 if (m->m_pkthdr.len < len) { 2209 ipstat.ips_tooshort++; 2210 goto bad; 2211 } 2212 2213 /* Checks out, proceed */ 2214 *mp = m; 2215 return 0; 2216 2217 bad: 2218 *mp = m; 2219 return -1; 2220 } 2221 2222 # ifdef INET6 2223 /* 2224 * Same as above, but for IPv6. 2225 * Cut-and-pasted from ip6_input.c. 2226 * XXX Should we update ip6stat, or not? 2227 */ 2228 static int 2229 bridge_ip6_checkbasic(struct mbuf **mp) 2230 { 2231 struct mbuf *m = *mp; 2232 struct ip6_hdr *ip6; 2233 2234 /* 2235 * If the IPv6 header is not aligned, slurp it up into a new 2236 * mbuf with space for link headers, in the event we forward 2237 * it. Otherwise, if it is aligned, make sure the entire base 2238 * IPv6 header is in the first mbuf of the chain. 2239 */ 2240 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 2241 struct ifnet *inifp = m->m_pkthdr.rcvif; 2242 if ((m = m_copyup(m, sizeof(struct ip6_hdr), 2243 (max_linkhdr + 3) & ~3)) == NULL) { 2244 /* XXXJRT new stat, please */ 2245 ip6stat.ip6s_toosmall++; 2246 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2247 goto bad; 2248 } 2249 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { 2250 struct ifnet *inifp = m->m_pkthdr.rcvif; 2251 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 2252 ip6stat.ip6s_toosmall++; 2253 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2254 goto bad; 2255 } 2256 } 2257 2258 ip6 = mtod(m, struct ip6_hdr *); 2259 2260 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 2261 ip6stat.ip6s_badvers++; 2262 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 2263 goto bad; 2264 } 2265 2266 /* Checks out, proceed */ 2267 *mp = m; 2268 return 0; 2269 2270 bad: 2271 *mp = m; 2272 return -1; 2273 } 2274 # endif /* INET6 */ 2275 #endif /* BRIDGE_IPF && PFIL_HOOKS */ 2276