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