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