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