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