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