1 /* $OpenBSD: if_bridge.c,v 1.83 2002/01/02 20:06:03 jason Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jason L. Wright 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "bpfilter.h" 35 #include "gif.h" 36 #include "pf.h" 37 38 #include <sys/param.h> 39 #include <sys/proc.h> 40 #include <sys/systm.h> 41 #include <sys/mbuf.h> 42 #include <sys/socket.h> 43 #include <sys/ioctl.h> 44 #include <sys/errno.h> 45 #include <sys/device.h> 46 #include <sys/kernel.h> 47 #include <machine/cpu.h> 48 49 #include <net/if.h> 50 #include <net/if_types.h> 51 #include <net/if_llc.h> 52 #include <net/route.h> 53 #include <net/netisr.h> 54 55 #ifdef INET 56 #include <netinet/in.h> 57 #include <netinet/in_systm.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip.h> 60 #include <netinet/ip_var.h> 61 #include <netinet/if_ether.h> 62 #include <netinet/ip_ipsp.h> 63 64 #include <net/if_enc.h> 65 #endif 66 67 #if NPF > 0 68 #include <net/pfvar.h> 69 #define BRIDGE_IN PF_IN 70 #define BRIDGE_OUT PF_OUT 71 #else 72 #define BRIDGE_IN 0 73 #define BRIDGE_OUT 1 74 #endif 75 76 #if NBPFILTER > 0 77 #include <net/bpf.h> 78 #endif 79 80 #include <net/if_bridge.h> 81 82 #ifndef BRIDGE_RTABLE_SIZE 83 #define BRIDGE_RTABLE_SIZE 1024 84 #endif 85 #define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1) 86 87 /* 88 * Maximum number of addresses to cache 89 */ 90 #ifndef BRIDGE_RTABLE_MAX 91 #define BRIDGE_RTABLE_MAX 100 92 #endif 93 94 /* spanning tree defaults */ 95 #define BSTP_DEFAULT_MAX_AGE (20 * 256) 96 #define BSTP_DEFAULT_HELLO_TIME (2 * 256) 97 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 98 #define BSTP_DEFAULT_HOLD_TIME (1 * 256) 99 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 100 #define BSTP_DEFAULT_PORT_PRIORITY 0x80 101 #define BSTP_DEFAULT_PATH_COST 55 102 103 /* 104 * Timeout (in seconds) for entries learned dynamically 105 */ 106 #ifndef BRIDGE_RTABLE_TIMEOUT 107 #define BRIDGE_RTABLE_TIMEOUT 240 108 #endif 109 110 extern int ifqmaxlen; 111 112 struct bridge_softc *bridgectl; 113 int nbridge; 114 115 void bridgeattach __P((int)); 116 int bridge_ioctl __P((struct ifnet *, u_long, caddr_t)); 117 void bridge_start __P((struct ifnet *)); 118 void bridgeintr_frame __P((struct bridge_softc *, struct mbuf *)); 119 void bridge_broadcast __P((struct bridge_softc *, struct ifnet *, 120 struct ether_header *, struct mbuf *)); 121 void bridge_span __P((struct bridge_softc *, struct ether_header *, 122 struct mbuf *)); 123 void bridge_stop __P((struct bridge_softc *)); 124 void bridge_init __P((struct bridge_softc *)); 125 int bridge_bifconf __P((struct bridge_softc *, struct ifbifconf *)); 126 127 void bridge_timer __P((void *)); 128 int bridge_rtfind __P((struct bridge_softc *, struct ifbaconf *)); 129 void bridge_rtage __P((struct bridge_softc *)); 130 void bridge_rttrim __P((struct bridge_softc *)); 131 void bridge_rtdelete __P((struct bridge_softc *, struct ifnet *)); 132 int bridge_rtdaddr __P((struct bridge_softc *, struct ether_addr *)); 133 int bridge_rtflush __P((struct bridge_softc *, int)); 134 struct ifnet * bridge_rtupdate __P((struct bridge_softc *, 135 struct ether_addr *, struct ifnet *ifp, int, u_int8_t)); 136 struct ifnet * bridge_rtlookup __P((struct bridge_softc *, 137 struct ether_addr *)); 138 u_int32_t bridge_hash __P((struct bridge_softc *, struct ether_addr *)); 139 int bridge_blocknonip __P((struct ether_header *, struct mbuf *)); 140 int bridge_addrule __P((struct bridge_iflist *, 141 struct ifbrlreq *, int out)); 142 int bridge_flushrule __P((struct bridge_iflist *)); 143 int bridge_brlconf __P((struct bridge_softc *, struct ifbrlconf *)); 144 u_int8_t bridge_filterrule __P((struct brl_head *, struct ether_header *)); 145 #if NPF > 0 146 struct mbuf *bridge_filter __P((struct bridge_softc *, int, struct ifnet *, 147 struct ether_header *, struct mbuf *m)); 148 #endif 149 150 #define ETHERADDR_IS_IP_MCAST(a) \ 151 /* struct etheraddr *a; */ \ 152 ((a)->ether_addr_octet[0] == 0x01 && \ 153 (a)->ether_addr_octet[1] == 0x00 && \ 154 (a)->ether_addr_octet[2] == 0x5e) 155 156 157 void 158 bridgeattach(n) 159 int n; 160 { 161 struct bridge_softc *sc; 162 struct ifnet *ifp; 163 int i; 164 165 bridgectl = malloc(n * sizeof(*sc), M_DEVBUF, M_NOWAIT); 166 if (!bridgectl) 167 return; 168 nbridge = n; 169 bzero(bridgectl, n * sizeof(*sc)); 170 for (sc = bridgectl, i = 0; i < nbridge; i++, sc++) { 171 172 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 173 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 174 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 175 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME; 176 sc->sc_bridge_forward_delay= BSTP_DEFAULT_FORWARD_DELAY; 177 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 178 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME; 179 timeout_set(&sc->sc_brtimeout, bridge_timer, sc); 180 LIST_INIT(&sc->sc_iflist); 181 LIST_INIT(&sc->sc_spanlist); 182 ifp = &sc->sc_if; 183 sprintf(ifp->if_xname, "bridge%d", i); 184 ifp->if_softc = sc; 185 ifp->if_mtu = ETHERMTU; 186 ifp->if_ioctl = bridge_ioctl; 187 ifp->if_output = bridge_output; 188 ifp->if_start = bridge_start; 189 ifp->if_type = IFT_BRIDGE; 190 ifp->if_snd.ifq_maxlen = ifqmaxlen; 191 ifp->if_hdrlen = sizeof(struct ether_header); 192 if_attach(ifp); 193 #if NBPFILTER > 0 194 bpfattach(&sc->sc_if.if_bpf, ifp, 195 DLT_EN10MB, sizeof(struct ether_header)); 196 #endif 197 } 198 } 199 200 int 201 bridge_ioctl(ifp, cmd, data) 202 struct ifnet *ifp; 203 u_long cmd; 204 caddr_t data; 205 { 206 struct proc *prc = curproc; /* XXX */ 207 struct ifnet *ifs; 208 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc; 209 struct ifbreq *req = (struct ifbreq *)data; 210 struct ifbaconf *baconf = (struct ifbaconf *)data; 211 struct ifbareq *bareq = (struct ifbareq *)data; 212 struct ifbrparam *bparam = (struct ifbrparam *)data; 213 struct ifbifconf *bifconf = (struct ifbifconf *)data; 214 struct ifbrlreq *brlreq = (struct ifbrlreq *)data; 215 struct ifbrlconf *brlconf = (struct ifbrlconf *)data; 216 struct ifreq ifreq; 217 int error = 0, s; 218 struct bridge_iflist *p; 219 220 s = splnet(); 221 switch (cmd) { 222 case SIOCBRDGADD: 223 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 224 break; 225 226 ifs = ifunit(req->ifbr_ifsname); 227 if (ifs == NULL) { /* no such interface */ 228 error = ENOENT; 229 break; 230 } 231 if (ifs->if_bridge == (caddr_t)sc) { 232 error = EEXIST; 233 break; 234 } 235 if (ifs->if_bridge != NULL) { 236 error = EBUSY; 237 break; 238 } 239 240 /* If it's in the span list, it can't be a member. */ 241 LIST_FOREACH(p, &sc->sc_spanlist, next) { 242 if (p->ifp == ifs) 243 break; 244 } 245 if (p != LIST_END(&sc->sc_spanlist)) { 246 error = EBUSY; 247 break; 248 } 249 250 if (ifs->if_type == IFT_ETHER) { 251 if ((ifs->if_flags & IFF_UP) == 0) { 252 /* 253 * Bring interface up long enough to set 254 * promiscuous flag, then shut it down again. 255 */ 256 strlcpy(ifreq.ifr_name, req->ifbr_ifsname, 257 IFNAMSIZ); 258 ifs->if_flags |= IFF_UP; 259 ifreq.ifr_flags = ifs->if_flags; 260 error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, 261 (caddr_t)&ifreq); 262 if (error != 0) 263 break; 264 265 error = ifpromisc(ifs, 1); 266 if (error != 0) 267 break; 268 269 strlcpy(ifreq.ifr_name, req->ifbr_ifsname, 270 IFNAMSIZ); 271 ifs->if_flags &= ~IFF_UP; 272 ifreq.ifr_flags = ifs->if_flags; 273 error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, 274 (caddr_t)&ifreq); 275 if (error != 0) { 276 ifpromisc(ifs, 0); 277 break; 278 } 279 } else { 280 error = ifpromisc(ifs, 1); 281 if (error != 0) 282 break; 283 } 284 } 285 #if NGIF > 0 286 else if (ifs->if_type == IFT_GIF) { 287 /* Nothing needed */ 288 } 289 #endif /* NGIF */ 290 else { 291 error = EINVAL; 292 break; 293 } 294 295 p = (struct bridge_iflist *) malloc( 296 sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT); 297 if (p == NULL) { 298 if (ifs->if_type == IFT_ETHER) 299 ifpromisc(ifs, 0); 300 error = ENOMEM; 301 break; 302 } 303 bzero(p, sizeof(struct bridge_iflist)); 304 305 p->ifp = ifs; 306 p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 307 p->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; 308 p->bif_path_cost = BSTP_DEFAULT_PATH_COST; 309 SIMPLEQ_INIT(&p->bif_brlin); 310 SIMPLEQ_INIT(&p->bif_brlout); 311 LIST_INSERT_HEAD(&sc->sc_iflist, p, next); 312 ifs->if_bridge = (caddr_t)sc; 313 break; 314 case SIOCBRDGDEL: 315 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 316 break; 317 318 LIST_FOREACH(p, &sc->sc_iflist, next) { 319 if (strncmp(p->ifp->if_xname, req->ifbr_ifsname, 320 sizeof(p->ifp->if_xname)) == 0) { 321 p->ifp->if_bridge = NULL; 322 323 error = ifpromisc(p->ifp, 0); 324 325 LIST_REMOVE(p, next); 326 bridge_rtdelete(sc, p->ifp); 327 bridge_flushrule(p); 328 free(p, M_DEVBUF); 329 break; 330 } 331 } 332 if (p == LIST_END(&sc->sc_iflist)) { 333 error = ENOENT; 334 break; 335 } 336 break; 337 case SIOCBRDGIFS: 338 error = bridge_bifconf(sc, bifconf); 339 break; 340 case SIOCBRDGADDS: 341 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 342 break; 343 ifs = ifunit(req->ifbr_ifsname); 344 if (ifs == NULL) { /* no such interface */ 345 error = ENOENT; 346 break; 347 } 348 if (ifs->if_bridge == (caddr_t)sc) { 349 error = EEXIST; 350 break; 351 } 352 if (ifs->if_bridge != NULL) { 353 error = EBUSY; 354 break; 355 } 356 LIST_FOREACH(p, &sc->sc_spanlist, next) { 357 if (p->ifp == ifs) 358 break; 359 } 360 if (p != LIST_END(&sc->sc_spanlist)) { 361 error = EBUSY; 362 break; 363 } 364 p = (struct bridge_iflist *)malloc( 365 sizeof(struct bridge_iflist), M_DEVBUF, M_NOWAIT); 366 if (p == NULL) { 367 error = ENOMEM; 368 break; 369 } 370 bzero(p, sizeof(struct bridge_iflist)); 371 p->ifp = ifs; 372 SIMPLEQ_INIT(&p->bif_brlin); 373 SIMPLEQ_INIT(&p->bif_brlout); 374 LIST_INSERT_HEAD(&sc->sc_spanlist, p, next); 375 break; 376 case SIOCBRDGDELS: 377 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 378 break; 379 LIST_FOREACH(p, &sc->sc_spanlist, next) { 380 if (strncmp(p->ifp->if_xname, req->ifbr_ifsname, 381 sizeof(p->ifp->if_xname)) == 0) { 382 LIST_REMOVE(p, next); 383 free(p, M_DEVBUF); 384 break; 385 } 386 } 387 if (p == LIST_END(&sc->sc_spanlist)) { 388 error = ENOENT; 389 break; 390 } 391 break; 392 case SIOCBRDGGIFFLGS: 393 ifs = ifunit(req->ifbr_ifsname); 394 if (ifs == NULL) { 395 error = ENOENT; 396 break; 397 } 398 if ((caddr_t)sc != ifs->if_bridge) { 399 error = ESRCH; 400 break; 401 } 402 LIST_FOREACH(p, &sc->sc_iflist, next) { 403 if (p->ifp == ifs) 404 break; 405 } 406 if (p == LIST_END(&sc->sc_iflist)) { 407 error = ESRCH; 408 break; 409 } 410 req->ifbr_ifsflags = p->bif_flags; 411 req->ifbr_state = p->bif_state; 412 req->ifbr_priority = p->bif_priority; 413 req->ifbr_portno = p->ifp->if_index & 0xff; 414 break; 415 case SIOCBRDGSIFFLGS: 416 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 417 break; 418 ifs = ifunit(req->ifbr_ifsname); 419 if (ifs == NULL) { 420 error = ENOENT; 421 break; 422 } 423 if ((caddr_t)sc != ifs->if_bridge) { 424 error = ESRCH; 425 break; 426 } 427 LIST_FOREACH(p, &sc->sc_iflist, next) { 428 if (p->ifp == ifs) 429 break; 430 } 431 if (p == LIST_END(&sc->sc_iflist)) { 432 error = ESRCH; 433 break; 434 } 435 if (req->ifbr_ifsflags & IFBIF_RO_MASK) { 436 error = EINVAL; 437 break; 438 } 439 if ((req->ifbr_ifsflags & IFBIF_STP) && 440 (ifs->if_type != IFT_ETHER)) { 441 error = EINVAL; 442 break; 443 } 444 p->bif_flags = req->ifbr_ifsflags; 445 break; 446 case SIOCBRDGSIFPRIO: 447 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 448 break; 449 ifs = ifunit(req->ifbr_ifsname); 450 if (ifs == NULL) { 451 error = ENOENT; 452 break; 453 } 454 if ((caddr_t)sc != ifs->if_bridge) { 455 error = ESRCH; 456 break; 457 } 458 LIST_FOREACH(p, &sc->sc_iflist, next) { 459 if (p->ifp == ifs) 460 break; 461 } 462 if (p == LIST_END(&sc->sc_iflist)) { 463 error = ESRCH; 464 break; 465 } 466 p->bif_priority = req->ifbr_priority; 467 break; 468 case SIOCBRDGRTS: 469 error = bridge_rtfind(sc, baconf); 470 break; 471 case SIOCBRDGFLUSH: 472 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 473 break; 474 475 error = bridge_rtflush(sc, req->ifbr_ifsflags); 476 break; 477 case SIOCBRDGSADDR: 478 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 479 break; 480 481 ifs = ifunit(bareq->ifba_ifsname); 482 if (ifs == NULL) { /* no such interface */ 483 error = ENOENT; 484 break; 485 } 486 487 if (ifs->if_bridge == NULL || 488 ifs->if_bridge != (caddr_t)sc) { 489 error = ESRCH; 490 break; 491 } 492 493 ifs = bridge_rtupdate(sc, &bareq->ifba_dst, ifs, 1, 494 bareq->ifba_flags); 495 if (ifs == NULL) 496 error = ENOMEM; 497 break; 498 case SIOCBRDGDADDR: 499 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 500 break; 501 error = bridge_rtdaddr(sc, &bareq->ifba_dst); 502 break; 503 case SIOCBRDGGCACHE: 504 bparam->ifbrp_csize = sc->sc_brtmax; 505 break; 506 case SIOCBRDGSCACHE: 507 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 508 break; 509 sc->sc_brtmax = bparam->ifbrp_csize; 510 bridge_rttrim(sc); 511 break; 512 case SIOCBRDGSTO: 513 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 514 break; 515 sc->sc_brttimeout = bparam->ifbrp_ctime; 516 timeout_del(&sc->sc_brtimeout); 517 if (bparam->ifbrp_ctime != 0) 518 timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); 519 break; 520 case SIOCBRDGGTO: 521 bparam->ifbrp_ctime = sc->sc_brttimeout; 522 break; 523 case SIOCSIFFLAGS: 524 if ((ifp->if_flags & IFF_UP) == IFF_UP) 525 bridge_init(sc); 526 527 if ((ifp->if_flags & IFF_UP) == 0) 528 bridge_stop(sc); 529 530 break; 531 case SIOCBRDGARL: 532 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 533 break; 534 ifs = ifunit(brlreq->ifbr_ifsname); 535 if (ifs == NULL) { 536 error = ENOENT; 537 break; 538 } 539 if (ifs->if_bridge == NULL || 540 ifs->if_bridge != (caddr_t)sc) { 541 error = ESRCH; 542 break; 543 } 544 LIST_FOREACH(p, &sc->sc_iflist, next) { 545 if (p->ifp == ifs) 546 break; 547 } 548 if (p == LIST_END(&sc->sc_iflist)) { 549 error = ESRCH; 550 break; 551 } 552 if ((brlreq->ifbr_action != BRL_ACTION_BLOCK && 553 brlreq->ifbr_action != BRL_ACTION_PASS) || 554 (brlreq->ifbr_flags & (BRL_FLAG_IN|BRL_FLAG_OUT)) == 0) { 555 error = EINVAL; 556 break; 557 } 558 if (brlreq->ifbr_flags & BRL_FLAG_IN) { 559 error = bridge_addrule(p, brlreq, 0); 560 if (error) 561 break; 562 } 563 if (brlreq->ifbr_flags & BRL_FLAG_OUT) { 564 error = bridge_addrule(p, brlreq, 1); 565 if (error) 566 break; 567 } 568 break; 569 case SIOCBRDGFRL: 570 if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) 571 break; 572 ifs = ifunit(brlreq->ifbr_ifsname); 573 if (ifs == NULL) { 574 error = ENOENT; 575 break; 576 } 577 if (ifs->if_bridge == NULL || 578 ifs->if_bridge != (caddr_t)sc) { 579 error = ESRCH; 580 break; 581 } 582 LIST_FOREACH(p, &sc->sc_iflist, next) { 583 if (p->ifp == ifs) 584 break; 585 } 586 if (p == LIST_END(&sc->sc_iflist)) { 587 error = ESRCH; 588 break; 589 } 590 error = bridge_flushrule(p); 591 break; 592 case SIOCBRDGGRL: 593 error = bridge_brlconf(sc, brlconf); 594 break; 595 case SIOCBRDGGPRI: 596 case SIOCBRDGGMA: 597 case SIOCBRDGGHT: 598 case SIOCBRDGGFD: 599 break; 600 case SIOCBRDGSPRI: 601 case SIOCBRDGSFD: 602 case SIOCBRDGSMA: 603 case SIOCBRDGSHT: 604 error = suser(prc->p_ucred, &prc->p_acflag); 605 break; 606 default: 607 error = EINVAL; 608 } 609 610 if (!error) 611 error = bstp_ioctl(ifp, cmd, data); 612 613 splx(s); 614 return (error); 615 } 616 617 /* Detach an interface from a bridge. */ 618 void 619 bridge_ifdetach(ifp) 620 struct ifnet *ifp; 621 { 622 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge; 623 struct bridge_iflist *bif; 624 625 LIST_FOREACH(bif, &sc->sc_iflist, next) { 626 if (bif->ifp == ifp) { 627 LIST_REMOVE(bif, next); 628 bridge_rtdelete(sc, ifp); 629 bridge_flushrule(bif); 630 free(bif, M_DEVBUF); 631 ifp->if_bridge = NULL; 632 break; 633 } 634 } 635 } 636 637 int 638 bridge_bifconf(sc, bifc) 639 struct bridge_softc *sc; 640 struct ifbifconf *bifc; 641 { 642 struct bridge_iflist *p; 643 u_int32_t total = 0, i = 0; 644 int error = 0; 645 struct ifbreq breq; 646 647 LIST_FOREACH(p, &sc->sc_iflist, next) { 648 total++; 649 } 650 LIST_FOREACH(p, &sc->sc_spanlist, next) { 651 total++; 652 } 653 if (bifc->ifbic_len == 0) { 654 i = total; 655 goto done; 656 } 657 658 LIST_FOREACH(p, &sc->sc_iflist, next) { 659 if (bifc->ifbic_len < sizeof(breq)) 660 break; 661 strlcpy(breq.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 662 strlcpy(breq.ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ); 663 breq.ifbr_ifsflags = p->bif_flags; 664 breq.ifbr_state = p->bif_state; 665 breq.ifbr_priority = p->bif_priority; 666 breq.ifbr_portno = p->ifp->if_index & 0xff; 667 error = copyout((caddr_t)&breq, 668 (caddr_t)(bifc->ifbic_req + i), sizeof(breq)); 669 if (error) 670 goto done; 671 i++; 672 bifc->ifbic_len -= sizeof(breq); 673 } 674 LIST_FOREACH(p, &sc->sc_spanlist, next) { 675 if (bifc->ifbic_len < sizeof(breq)) 676 break; 677 strlcpy(breq.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 678 strlcpy(breq.ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ); 679 breq.ifbr_ifsflags = p->bif_flags | IFBIF_SPAN; 680 breq.ifbr_state = p->bif_state; 681 breq.ifbr_priority = p->bif_priority; 682 breq.ifbr_portno = p->ifp->if_index & 0xff; 683 error = copyout((caddr_t)&breq, 684 (caddr_t)(bifc->ifbic_req + i), sizeof(breq)); 685 if (error) 686 goto done; 687 i++; 688 bifc->ifbic_len -= sizeof(breq); 689 } 690 691 done: 692 bifc->ifbic_len = i * sizeof(breq); 693 return (error); 694 } 695 696 int 697 bridge_brlconf(sc, bc) 698 struct bridge_softc *sc; 699 struct ifbrlconf *bc; 700 { 701 struct ifnet *ifp; 702 struct bridge_iflist *ifl; 703 struct brl_node *n; 704 struct ifbrlreq req; 705 int error = 0; 706 u_int32_t i = 0, total = 0; 707 708 ifp = ifunit(bc->ifbrl_ifsname); 709 if (ifp == NULL) 710 return (ENOENT); 711 if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc) 712 return (ESRCH); 713 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 714 if (ifl->ifp == ifp) 715 break; 716 } 717 if (ifl == LIST_END(&sc->sc_iflist)) 718 return (ESRCH); 719 720 SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) { 721 total++; 722 } 723 SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) { 724 total++; 725 } 726 727 if (bc->ifbrl_len == 0) { 728 i = total; 729 goto done; 730 } 731 732 SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) { 733 if (bc->ifbrl_len < sizeof(req)) 734 goto done; 735 strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 736 strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ); 737 req.ifbr_action = n->brl_action; 738 req.ifbr_flags = n->brl_flags; 739 req.ifbr_src = n->brl_src; 740 req.ifbr_dst = n->brl_dst; 741 error = copyout((caddr_t)&req, 742 (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req)); 743 if (error) 744 goto done; 745 i++; 746 bc->ifbrl_len -= sizeof(req); 747 } 748 749 SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) { 750 if (bc->ifbrl_len < sizeof(req)) 751 goto done; 752 strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 753 strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ); 754 req.ifbr_action = n->brl_action; 755 req.ifbr_flags = n->brl_flags; 756 req.ifbr_src = n->brl_src; 757 req.ifbr_dst = n->brl_dst; 758 error = copyout((caddr_t)&req, 759 (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req)); 760 if (error) 761 goto done; 762 i++; 763 bc->ifbrl_len -= sizeof(req); 764 } 765 766 done: 767 bc->ifbrl_len = i * sizeof(req); 768 return (error); 769 } 770 771 void 772 bridge_init(sc) 773 struct bridge_softc *sc; 774 { 775 struct ifnet *ifp = &sc->sc_if; 776 int i; 777 778 if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING) 779 return; 780 781 if (sc->sc_rts == NULL) { 782 sc->sc_rts = (struct bridge_rthead *)malloc( 783 BRIDGE_RTABLE_SIZE * (sizeof(struct bridge_rthead)), 784 M_DEVBUF, M_NOWAIT); 785 if (sc->sc_rts == NULL) 786 return; 787 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 788 LIST_INIT(&sc->sc_rts[i]); 789 } 790 sc->sc_hashkey = arc4random(); 791 } 792 ifp->if_flags |= IFF_RUNNING; 793 794 if (sc->sc_brttimeout != 0) 795 timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); 796 } 797 798 /* 799 * Stop the bridge and deallocate the routing table. 800 */ 801 void 802 bridge_stop(sc) 803 struct bridge_softc *sc; 804 { 805 struct ifnet *ifp = &sc->sc_if; 806 807 /* 808 * If we're not running, there's nothing to do. 809 */ 810 if ((ifp->if_flags & IFF_RUNNING) == 0) 811 return; 812 813 timeout_del(&sc->sc_brtimeout); 814 815 bridge_rtflush(sc, IFBF_FLUSHDYN); 816 817 ifp->if_flags &= ~IFF_RUNNING; 818 } 819 820 /* 821 * Send output from the bridge. The mbuf has the ethernet header 822 * already attached. We must enqueue or free the mbuf before exiting. 823 */ 824 int 825 bridge_output(ifp, m, sa, rt) 826 struct ifnet *ifp; 827 struct mbuf *m; 828 struct sockaddr *sa; 829 struct rtentry *rt; 830 { 831 struct ether_header *eh; 832 struct ifnet *dst_if; 833 struct ether_addr *src, *dst; 834 struct bridge_softc *sc; 835 int s, error, len; 836 short mflags; 837 ALTQ_DECL(struct altq_pktattr pktattr;) 838 #ifdef IPSEC 839 struct m_tag *mtag; 840 #endif /* IPSEC */ 841 842 if (m->m_len < sizeof(*eh)) { 843 m = m_pullup(m, sizeof(*eh)); 844 if (m == NULL) 845 return (0); 846 } 847 eh = mtod(m, struct ether_header *); 848 dst = (struct ether_addr *)&eh->ether_dhost[0]; 849 src = (struct ether_addr *)&eh->ether_shost[0]; 850 sc = (struct bridge_softc *)ifp->if_bridge; 851 852 s = splimp(); 853 854 /* 855 * If bridge is down, but original output interface is up, 856 * go ahead and send out that interface. Otherwise the packet 857 * is dropped below. 858 */ 859 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 860 dst_if = ifp; 861 goto sendunicast; 862 } 863 864 /* 865 * If the packet is a broadcast or we don't know a better way to 866 * get there, send to all interfaces. 867 */ 868 dst_if = bridge_rtlookup(sc, dst); 869 if (dst_if == NULL || ETHER_IS_MULTICAST(eh->ether_dhost)) { 870 struct bridge_iflist *p; 871 struct mbuf *mc; 872 int used = 0; 873 874 #ifdef IPSEC 875 /* 876 * Don't send out the packet if IPsec is needed, and 877 * notify IPsec to do its own crypto for now. 878 */ 879 if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, 880 NULL)) != NULL) { 881 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 882 m_freem(m); 883 splx(s); 884 return (0); 885 } 886 #endif /* IPSEC */ 887 888 /* Catch packets that need TCP/UDP/IP hardware checksumming */ 889 if (m->m_pkthdr.csum & M_IPV4_CSUM_OUT || 890 m->m_pkthdr.csum & M_TCPV4_CSUM_OUT || 891 m->m_pkthdr.csum & M_UDPV4_CSUM_OUT) { 892 m_freem(m); 893 splx(s); 894 return (0); 895 } 896 897 bridge_span(sc, NULL, m); 898 899 LIST_FOREACH(p, &sc->sc_iflist, next) { 900 dst_if = p->ifp; 901 if ((dst_if->if_flags & IFF_RUNNING) == 0) 902 continue; 903 #ifdef ALTQ 904 if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) 905 #endif 906 if (IF_QFULL(&dst_if->if_snd)) { 907 IF_DROP(&dst_if->if_snd); 908 sc->sc_if.if_oerrors++; 909 continue; 910 } 911 if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) { 912 used = 1; 913 mc = m; 914 } else { 915 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); 916 if (mc == NULL) { 917 sc->sc_if.if_oerrors++; 918 continue; 919 } 920 } 921 len = mc->m_pkthdr.len; 922 mflags = mc->m_flags; 923 #ifdef ALTQ 924 if (ALTQ_IS_ENABLED(&dst_if->if_snd)) 925 altq_etherclassify(&dst_if->if_snd, mc, &pktattr); 926 #endif 927 IFQ_ENQUEUE(&dst_if->if_snd, mc, &pktattr, error); 928 if (error) { 929 sc->sc_if.if_oerrors++; 930 continue; 931 } 932 sc->sc_if.if_opackets++; 933 sc->sc_if.if_obytes += len; 934 dst_if->if_obytes += len; 935 if (mflags & M_MCAST) 936 dst_if->if_omcasts++; 937 if ((dst_if->if_flags & IFF_OACTIVE) == 0) 938 (*dst_if->if_start)(dst_if); 939 } 940 if (!used) 941 m_freem(m); 942 splx(s); 943 return (0); 944 } 945 946 sendunicast: 947 bridge_span(sc, NULL, m); 948 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 949 m_freem(m); 950 splx(s); 951 return (0); 952 } 953 len = m->m_pkthdr.len; 954 mflags = m->m_flags; 955 #ifdef ALTQ 956 if (ALTQ_IS_ENABLED(&dst_if->if_snd)) 957 altq_etherclassify(&dst_if->if_snd, m, &pktattr); 958 #endif 959 IFQ_ENQUEUE(&dst_if->if_snd, m, &pktattr, error); 960 if (error) { 961 sc->sc_if.if_oerrors++; 962 splx(s); 963 return (0); 964 } 965 sc->sc_if.if_opackets++; 966 sc->sc_if.if_obytes += len; 967 dst_if->if_obytes += len; 968 if (mflags & M_MCAST) 969 dst_if->if_omcasts++; 970 if ((dst_if->if_flags & IFF_OACTIVE) == 0) 971 (*dst_if->if_start)(dst_if); 972 splx(s); 973 return (0); 974 } 975 976 /* 977 * Start output on the bridge. This function should never be called. 978 */ 979 void 980 bridge_start(ifp) 981 struct ifnet *ifp; 982 { 983 } 984 985 /* 986 * Loop through each bridge interface and process their input queues. 987 */ 988 void 989 bridgeintr(void) 990 { 991 struct bridge_softc *sc; 992 struct mbuf *m; 993 int i, s; 994 995 for (i = 0; i < nbridge; i++) { 996 sc = &bridgectl[i]; 997 for (;;) { 998 s = splimp(); 999 IF_DEQUEUE(&sc->sc_if.if_snd, m); 1000 splx(s); 1001 if (m == NULL) 1002 break; 1003 bridgeintr_frame(sc, m); 1004 } 1005 } 1006 } 1007 1008 /* 1009 * Process a single frame. Frame must be freed or queued before returning. 1010 */ 1011 void 1012 bridgeintr_frame(sc, m) 1013 struct bridge_softc *sc; 1014 struct mbuf *m; 1015 { 1016 int s, error, len; 1017 struct ifnet *src_if, *dst_if; 1018 struct bridge_iflist *ifl; 1019 struct ether_addr *dst, *src; 1020 struct ether_header eh; 1021 short mflags; 1022 ALTQ_DECL(struct altq_pktattr pktattr;) 1023 1024 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1025 m_freem(m); 1026 return; 1027 } 1028 1029 src_if = m->m_pkthdr.rcvif; 1030 1031 #if NBPFILTER > 0 1032 if (sc->sc_if.if_bpf) 1033 bpf_mtap(sc->sc_if.if_bpf, m); 1034 #endif 1035 1036 sc->sc_if.if_ipackets++; 1037 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1038 1039 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1040 if (ifl->ifp == src_if) 1041 break; 1042 } 1043 if (ifl == LIST_END(&sc->sc_iflist)) { 1044 m_freem(m); 1045 return; 1046 } 1047 1048 if ((ifl->bif_flags & IFBIF_STP) && 1049 (ifl->bif_state == BSTP_IFSTATE_BLOCKING || 1050 ifl->bif_state == BSTP_IFSTATE_LISTENING || 1051 ifl->bif_state == BSTP_IFSTATE_DISABLED)) { 1052 m_freem(m); 1053 return; 1054 } 1055 1056 if (m->m_pkthdr.len < sizeof(eh)) { 1057 m_freem(m); 1058 return; 1059 } 1060 m_copydata(m, 0, sizeof(struct ether_header), (caddr_t)&eh); 1061 dst = (struct ether_addr *)&eh.ether_dhost[0]; 1062 src = (struct ether_addr *)&eh.ether_shost[0]; 1063 1064 /* 1065 * If interface is learning, and if source address 1066 * is not broadcast or multicast, record it's address. 1067 */ 1068 if ((ifl->bif_flags & IFBIF_LEARNING) && 1069 (eh.ether_shost[0] & 1) == 0 && 1070 !(eh.ether_shost[0] == 0 && eh.ether_shost[1] == 0 && 1071 eh.ether_shost[2] == 0 && eh.ether_shost[3] == 0 && 1072 eh.ether_shost[4] == 0 && eh.ether_shost[5] == 0)) 1073 bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC); 1074 1075 if ((ifl->bif_flags & IFBIF_STP) && 1076 (ifl->bif_state == BSTP_IFSTATE_LEARNING)) { 1077 m_freem(m); 1078 return; 1079 } 1080 1081 /* 1082 * At this point, the port either doesn't participate in stp or 1083 * it's in the forwarding state 1084 */ 1085 1086 /* 1087 * If packet is unicast, destined for someone on "this" 1088 * side of the bridge, drop it. 1089 */ 1090 if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) { 1091 dst_if = bridge_rtlookup(sc, dst); 1092 if (dst_if == src_if) { 1093 m_freem(m); 1094 return; 1095 } 1096 } else 1097 dst_if = NULL; 1098 1099 /* 1100 * Multicast packets get handled a little differently: 1101 * If interface is: 1102 * -link0,-link1 (default) Forward all multicast 1103 * as broadcast. 1104 * -link0,link1 Drop non-IP multicast, forward 1105 * as broadcast IP multicast. 1106 * link0,-link1 Drop IP multicast, forward as 1107 * broadcast non-IP multicast. 1108 * link0,link1 Drop all multicast. 1109 */ 1110 if (m->m_flags & M_MCAST) { 1111 if ((sc->sc_if.if_flags & 1112 (IFF_LINK0 | IFF_LINK1)) == 1113 (IFF_LINK0 | IFF_LINK1)) { 1114 m_freem(m); 1115 return; 1116 } 1117 if (sc->sc_if.if_flags & IFF_LINK0 && 1118 ETHERADDR_IS_IP_MCAST(dst)) { 1119 m_freem(m); 1120 return; 1121 } 1122 if (sc->sc_if.if_flags & IFF_LINK1 && 1123 !ETHERADDR_IS_IP_MCAST(dst)) { 1124 m_freem(m); 1125 return; 1126 } 1127 } 1128 1129 if (ifl->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) { 1130 m_freem(m); 1131 return; 1132 } 1133 1134 if (bridge_filterrule(&ifl->bif_brlin, &eh) == BRL_ACTION_BLOCK) { 1135 m_freem(m); 1136 return; 1137 } 1138 #if NPF > 0 1139 m = bridge_filter(sc, BRIDGE_IN, src_if, &eh, m); 1140 if (m == NULL) 1141 return; 1142 #endif 1143 /* 1144 * If the packet is a multicast or broadcast OR if we don't 1145 * know any better, forward it to all interfaces. 1146 */ 1147 if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) { 1148 sc->sc_if.if_imcasts++; 1149 s = splimp(); 1150 bridge_broadcast(sc, src_if, &eh, m); 1151 splx(s); 1152 return; 1153 } 1154 1155 /* 1156 * At this point, we're dealing with a unicast frame going to a 1157 * different interface 1158 */ 1159 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1160 m_freem(m); 1161 return; 1162 } 1163 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1164 if (ifl->ifp == dst_if) 1165 break; 1166 } 1167 if (ifl == LIST_END(&sc->sc_iflist)) { 1168 m_freem(m); 1169 return; 1170 } 1171 if ((ifl->bif_flags & IFBIF_STP) && 1172 (ifl->bif_state == BSTP_IFSTATE_DISABLED || 1173 ifl->bif_state == BSTP_IFSTATE_BLOCKING)) { 1174 m_freem(m); 1175 return; 1176 } 1177 if (bridge_filterrule(&ifl->bif_brlout, &eh) == BRL_ACTION_BLOCK) { 1178 m_freem(m); 1179 return; 1180 } 1181 #if NPF > 0 1182 m = bridge_filter(sc, BRIDGE_OUT, dst_if, &eh, m); 1183 if (m == NULL) 1184 return; 1185 #endif 1186 1187 #ifdef ALTQ 1188 if (ALTQ_IS_ENABLED(&dst_if->if_snd)) 1189 altq_etherclassify(&dst_if->if_snd, m, &pktattr); 1190 #endif 1191 len = m->m_pkthdr.len; 1192 mflags = m->m_flags; 1193 s = splimp(); 1194 IFQ_ENQUEUE(&dst_if->if_snd, m, &pktattr, error); 1195 if (error) { 1196 sc->sc_if.if_oerrors++; 1197 splx(s); 1198 return; 1199 } 1200 sc->sc_if.if_opackets++; 1201 sc->sc_if.if_obytes += len; 1202 dst_if->if_obytes += len; 1203 if (mflags & M_MCAST) 1204 dst_if->if_omcasts++; 1205 if ((dst_if->if_flags & IFF_OACTIVE) == 0) 1206 (*dst_if->if_start)(dst_if); 1207 splx(s); 1208 } 1209 1210 /* 1211 * Receive input from an interface. Queue the packet for bridging if its 1212 * not for us, and schedule an interrupt. 1213 */ 1214 struct mbuf * 1215 bridge_input(ifp, eh, m) 1216 struct ifnet *ifp; 1217 struct ether_header *eh; 1218 struct mbuf *m; 1219 { 1220 struct bridge_softc *sc; 1221 int s; 1222 struct bridge_iflist *ifl; 1223 struct arpcom *ac; 1224 struct mbuf *mc; 1225 1226 /* 1227 * Make sure this interface is a bridge member. 1228 */ 1229 if (ifp == NULL || ifp->if_bridge == NULL || m == NULL) 1230 return (m); 1231 1232 if ((m->m_flags & M_PKTHDR) == 0) 1233 panic("bridge_input(): no HDR"); 1234 1235 m->m_flags &= ~M_PROTO1; /* Loop prevention */ 1236 1237 sc = (struct bridge_softc *)ifp->if_bridge; 1238 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1239 return (m); 1240 1241 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1242 if (ifl->ifp == ifp) 1243 break; 1244 } 1245 if (ifl == LIST_END(&sc->sc_iflist)) 1246 return (m); 1247 1248 bridge_span(sc, eh, m); 1249 1250 if (m->m_flags & (M_BCAST | M_MCAST)) { 1251 /* Tap off 802.1D packets, they do not get forwarded */ 1252 if (bcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) { 1253 m = bstp_input(sc, ifp, eh, m); 1254 if (m == NULL) 1255 return (NULL); 1256 } 1257 1258 /* 1259 * No need to queue frames for ifs in the blocking, disabled, 1260 * or listening state 1261 */ 1262 if ((ifl->bif_flags & IFBIF_STP) && 1263 ((ifl->bif_state == BSTP_IFSTATE_BLOCKING) || 1264 (ifl->bif_state == BSTP_IFSTATE_LISTENING) || 1265 (ifl->bif_state == BSTP_IFSTATE_DISABLED))) 1266 return (m); 1267 1268 /* 1269 * make a copy of 'm' with 'eh' tacked on to the 1270 * beginning. Return 'm' for local processing 1271 * and enqueue the copy. Schedule netisr. 1272 */ 1273 mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT); 1274 if (mc == NULL) 1275 return (m); 1276 M_PREPEND(mc, sizeof(struct ether_header), M_DONTWAIT); 1277 if (mc == NULL) 1278 return (m); 1279 bcopy(eh, mtod(mc, caddr_t), sizeof(struct ether_header)); 1280 s = splimp(); 1281 if (IF_QFULL(&sc->sc_if.if_snd)) { 1282 m_freem(mc); 1283 splx(s); 1284 return (m); 1285 } 1286 IF_ENQUEUE(&sc->sc_if.if_snd, mc); 1287 splx(s); 1288 schednetisr(NETISR_BRIDGE); 1289 if (ifp->if_type == IFT_GIF) { 1290 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1291 if (ifl->ifp->if_type == IFT_ETHER) 1292 break; 1293 } 1294 if (ifl != LIST_END(&sc->sc_iflist)) { 1295 m->m_flags |= M_PROTO1; 1296 m->m_pkthdr.rcvif = ifl->ifp; 1297 ether_input(ifl->ifp, eh, m); 1298 m = NULL; 1299 } 1300 } 1301 return (m); 1302 } 1303 1304 /* 1305 * No need to queue frames for ifs in the blocking, disabled, or 1306 * listening state 1307 */ 1308 if ((ifl->bif_flags & IFBIF_STP) && 1309 ((ifl->bif_state == BSTP_IFSTATE_BLOCKING) || 1310 (ifl->bif_state == BSTP_IFSTATE_LISTENING) || 1311 (ifl->bif_state == BSTP_IFSTATE_DISABLED))) 1312 return (m); 1313 1314 1315 /* 1316 * Unicast, make sure it's not for us. 1317 */ 1318 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1319 if (ifl->ifp->if_type != IFT_ETHER) 1320 continue; 1321 ac = (struct arpcom *)ifl->ifp; 1322 if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0) { 1323 if (ifl->bif_flags & IFBIF_LEARNING) 1324 bridge_rtupdate(sc, 1325 (struct ether_addr *)&eh->ether_shost, 1326 ifp, 0, IFBAF_DYNAMIC); 1327 m->m_pkthdr.rcvif = ifl->ifp; 1328 if (ifp->if_type == IFT_GIF) { 1329 m->m_flags |= M_PROTO1; 1330 ether_input(ifl->ifp, eh, m); 1331 m = NULL; 1332 } 1333 return (m); 1334 } 1335 if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0) { 1336 m_freem(m); 1337 return (NULL); 1338 } 1339 } 1340 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1341 if (m == NULL) 1342 return (NULL); 1343 bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header)); 1344 s = splimp(); 1345 if (IF_QFULL(&sc->sc_if.if_snd)) { 1346 m_freem(m); 1347 splx(s); 1348 return (NULL); 1349 } 1350 IF_ENQUEUE(&sc->sc_if.if_snd, m); 1351 splx(s); 1352 schednetisr(NETISR_BRIDGE); 1353 return (NULL); 1354 } 1355 1356 /* 1357 * Send a frame to all interfaces that are members of the bridge 1358 * (except the one it came in on). This code assumes that it is 1359 * running at splnet or higher. 1360 */ 1361 void 1362 bridge_broadcast(sc, ifp, eh, m) 1363 struct bridge_softc *sc; 1364 struct ifnet *ifp; 1365 struct ether_header *eh; 1366 struct mbuf *m; 1367 { 1368 struct bridge_iflist *p; 1369 struct mbuf *mc; 1370 struct ifnet *dst_if; 1371 int error, len = m->m_pkthdr.len, used = 0; 1372 short mflags = m->m_flags; 1373 ALTQ_DECL(struct altq_pktattr pktattr;) 1374 1375 LIST_FOREACH(p, &sc->sc_iflist, next) { 1376 /* 1377 * Don't retransmit out of the same interface where 1378 * the packet was received from. 1379 */ 1380 dst_if = p->ifp; 1381 if (dst_if->if_index == ifp->if_index) 1382 continue; 1383 1384 if ((p->bif_flags & IFBIF_STP) && 1385 (p->bif_state == BSTP_IFSTATE_BLOCKING || 1386 p->bif_state == BSTP_IFSTATE_DISABLED)) 1387 continue; 1388 1389 if ((p->bif_flags & IFBIF_DISCOVER) == 0 && 1390 (m->m_flags & (M_BCAST | M_MCAST)) == 0) 1391 continue; 1392 1393 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1394 continue; 1395 1396 #ifdef ALTQ 1397 if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) 1398 #endif 1399 if (IF_QFULL(&dst_if->if_snd)) { 1400 IF_DROP(&dst_if->if_snd); 1401 sc->sc_if.if_oerrors++; 1402 continue; 1403 } 1404 1405 /* Drop non-IP frames if the appropriate flag is set. */ 1406 if (p->bif_flags & IFBIF_BLOCKNONIP && 1407 bridge_blocknonip(eh, m)) 1408 continue; 1409 1410 if (bridge_filterrule(&p->bif_brlout, eh) == BRL_ACTION_BLOCK) 1411 continue; 1412 1413 /* If last one, reuse the passed-in mbuf */ 1414 if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) { 1415 mc = m; 1416 used = 1; 1417 } else { 1418 struct mbuf *m1, *m2, *mx; 1419 1420 m1 = m_copym2(m, 0, sizeof(struct ether_header), 1421 M_DONTWAIT); 1422 if (m1 == NULL) { 1423 sc->sc_if.if_oerrors++; 1424 continue; 1425 } 1426 m2 = m_copym2(m, sizeof(struct ether_header), 1427 M_COPYALL, M_DONTWAIT); 1428 if (m2 == NULL) { 1429 m_freem(m1); 1430 sc->sc_if.if_oerrors++; 1431 continue; 1432 } 1433 1434 for (mx = m1; mx->m_next != NULL; mx = mx->m_next) 1435 /*EMPTY*/; 1436 mx->m_next = m2; 1437 1438 if (m1->m_flags & M_PKTHDR) { 1439 int len = 0; 1440 1441 for (mx = m1; mx != NULL; mx = mx->m_next) 1442 len += mx->m_len; 1443 m1->m_pkthdr.len = len; 1444 } 1445 mc = m1; 1446 } 1447 1448 #if NPF > 0 1449 mc = bridge_filter(sc, BRIDGE_OUT, dst_if, eh, mc); 1450 if (mc == NULL) 1451 continue; 1452 #endif 1453 1454 #ifdef ALTQ 1455 if (ALTQ_IS_ENABLED(&dst_if->if_snd)) 1456 altq_etherclassify(&dst_if->if_snd, mc, &pktattr); 1457 #endif 1458 IFQ_ENQUEUE(&dst_if->if_snd, mc, &pktattr, error); 1459 if (error) { 1460 sc->sc_if.if_oerrors++; 1461 continue; 1462 } 1463 sc->sc_if.if_opackets++; 1464 sc->sc_if.if_obytes += len; 1465 dst_if->if_obytes += len; 1466 if (mflags & M_MCAST) 1467 dst_if->if_omcasts++; 1468 if ((dst_if->if_flags & IFF_OACTIVE) == 0) 1469 (*dst_if->if_start)(dst_if); 1470 } 1471 1472 if (!used) 1473 m_freem(m); 1474 } 1475 1476 void 1477 bridge_span(sc, eh, morig) 1478 struct bridge_softc *sc; 1479 struct ether_header *eh; 1480 struct mbuf *morig; 1481 { 1482 struct bridge_iflist *p; 1483 struct ifnet *ifp; 1484 struct mbuf *mc, *m; 1485 int error; 1486 ALTQ_DECL(struct altq_pktattr pktattr;) 1487 1488 if (LIST_EMPTY(&sc->sc_spanlist)) 1489 return; 1490 1491 m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT); 1492 if (m == NULL) 1493 return; 1494 if (eh != NULL) { 1495 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1496 if (m == NULL) 1497 return; 1498 bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header)); 1499 } 1500 1501 LIST_FOREACH(p, &sc->sc_spanlist, next) { 1502 ifp = p->ifp; 1503 1504 if ((ifp->if_flags & IFF_RUNNING) == 0) 1505 continue; 1506 1507 #ifdef ALTQ 1508 if (ALTQ_IS_ENABLED(&ifp->if_snd) == 0) 1509 #endif 1510 if (IF_QFULL(&ifp->if_snd)) { 1511 IF_DROP(&ifp->if_snd); 1512 sc->sc_if.if_oerrors++; 1513 continue; 1514 } 1515 1516 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1517 if (mc == NULL) { 1518 sc->sc_if.if_oerrors++; 1519 continue; 1520 } 1521 1522 #ifdef ALTQ 1523 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 1524 altq_etherclassify(&ifp->if_snd, mc, &pktattr); 1525 #endif 1526 1527 IFQ_ENQUEUE(&ifp->if_snd, mc, &pktattr, error); 1528 if (error) { 1529 sc->sc_if.if_oerrors++; 1530 continue; 1531 } 1532 sc->sc_if.if_opackets++; 1533 sc->sc_if.if_obytes += m->m_pkthdr.len; 1534 ifp->if_obytes += m->m_pkthdr.len; 1535 if (m->m_flags & M_MCAST) 1536 ifp->if_omcasts++; 1537 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1538 (*ifp->if_start)(ifp); 1539 } 1540 m_freem(m); 1541 } 1542 1543 struct ifnet * 1544 bridge_rtupdate(sc, ea, ifp, setflags, flags) 1545 struct bridge_softc *sc; 1546 struct ether_addr *ea; 1547 struct ifnet *ifp; 1548 int setflags; 1549 u_int8_t flags; 1550 { 1551 struct bridge_rtnode *p, *q; 1552 u_int32_t h; 1553 int dir; 1554 1555 if (sc->sc_rts == NULL) { 1556 if (setflags && flags == IFBAF_STATIC) { 1557 sc->sc_rts = (struct bridge_rthead *)malloc( 1558 BRIDGE_RTABLE_SIZE * 1559 (sizeof(struct bridge_rthead)),M_DEVBUF,M_NOWAIT); 1560 if (sc->sc_rts == NULL) 1561 goto done; 1562 1563 for (h = 0; h < BRIDGE_RTABLE_SIZE; h++) { 1564 LIST_INIT(&sc->sc_rts[h]); 1565 } 1566 sc->sc_hashkey = arc4random(); 1567 } else 1568 goto done; 1569 } 1570 1571 h = bridge_hash(sc, ea); 1572 p = LIST_FIRST(&sc->sc_rts[h]); 1573 if (p == LIST_END(&sc->sc_rts[h])) { 1574 if (sc->sc_brtcnt >= sc->sc_brtmax) 1575 goto done; 1576 p = (struct bridge_rtnode *)malloc( 1577 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1578 if (p == NULL) 1579 goto done; 1580 1581 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1582 p->brt_if = ifp; 1583 p->brt_age = 1; 1584 1585 if (setflags) 1586 p->brt_flags = flags; 1587 else 1588 p->brt_flags = IFBAF_DYNAMIC; 1589 1590 LIST_INSERT_HEAD(&sc->sc_rts[h], p, brt_next); 1591 sc->sc_brtcnt++; 1592 goto want; 1593 } 1594 1595 do { 1596 q = p; 1597 p = LIST_NEXT(p, brt_next); 1598 1599 dir = memcmp(ea, &q->brt_addr, sizeof(q->brt_addr)); 1600 if (dir == 0) { 1601 if (setflags) { 1602 q->brt_if = ifp; 1603 q->brt_flags = flags; 1604 } 1605 1606 if (q->brt_if == ifp) 1607 q->brt_age = 1; 1608 ifp = q->brt_if; 1609 goto want; 1610 } 1611 1612 if (dir > 0) { 1613 if (sc->sc_brtcnt >= sc->sc_brtmax) 1614 goto done; 1615 p = (struct bridge_rtnode *)malloc( 1616 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1617 if (p == NULL) 1618 goto done; 1619 1620 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1621 p->brt_if = ifp; 1622 p->brt_age = 1; 1623 1624 if (setflags) 1625 p->brt_flags = flags; 1626 else 1627 p->brt_flags = IFBAF_DYNAMIC; 1628 1629 LIST_INSERT_BEFORE(q, p, brt_next); 1630 sc->sc_brtcnt++; 1631 goto want; 1632 } 1633 1634 if (p == LIST_END(&sc->sc_rts[h])) { 1635 if (sc->sc_brtcnt >= sc->sc_brtmax) 1636 goto done; 1637 p = (struct bridge_rtnode *)malloc( 1638 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1639 if (p == NULL) 1640 goto done; 1641 1642 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1643 p->brt_if = ifp; 1644 p->brt_age = 1; 1645 1646 if (setflags) 1647 p->brt_flags = flags; 1648 else 1649 p->brt_flags = IFBAF_DYNAMIC; 1650 LIST_INSERT_AFTER(q, p, brt_next); 1651 sc->sc_brtcnt++; 1652 goto want; 1653 } 1654 } while (p != LIST_END(&sc->sc_rts[h])); 1655 1656 done: 1657 ifp = NULL; 1658 want: 1659 return (ifp); 1660 } 1661 1662 struct ifnet * 1663 bridge_rtlookup(sc, ea) 1664 struct bridge_softc *sc; 1665 struct ether_addr *ea; 1666 { 1667 struct bridge_rtnode *p; 1668 u_int32_t h; 1669 int dir; 1670 1671 if (sc->sc_rts == NULL) 1672 goto fail; 1673 1674 h = bridge_hash(sc, ea); 1675 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1676 dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr)); 1677 if (dir == 0) 1678 return (p->brt_if); 1679 if (dir > 0) 1680 goto fail; 1681 } 1682 fail: 1683 return (NULL); 1684 } 1685 1686 /* 1687 * The following hash function is adapted from 'Hash Functions' by Bob Jenkins 1688 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1689 * "You may use this code any way you wish, private, educational, or 1690 * commercial. It's free." 1691 */ 1692 #define mix(a,b,c) \ 1693 do { \ 1694 a -= b; a -= c; a ^= (c >> 13); \ 1695 b -= c; b -= a; b ^= (a << 8); \ 1696 c -= a; c -= b; c ^= (b >> 13); \ 1697 a -= b; a -= c; a ^= (c >> 12); \ 1698 b -= c; b -= a; b ^= (a << 16); \ 1699 c -= a; c -= b; c ^= (b >> 5); \ 1700 a -= b; a -= c; a ^= (c >> 3); \ 1701 b -= c; b -= a; b ^= (a << 10); \ 1702 c -= a; c -= b; c ^= (b >> 15); \ 1703 } while(0) 1704 1705 u_int32_t 1706 bridge_hash(sc, addr) 1707 struct bridge_softc *sc; 1708 struct ether_addr *addr; 1709 { 1710 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_hashkey; 1711 1712 b += addr->ether_addr_octet[5] << 8; 1713 b += addr->ether_addr_octet[4]; 1714 a += addr->ether_addr_octet[3] << 24; 1715 a += addr->ether_addr_octet[2] << 16; 1716 a += addr->ether_addr_octet[1] << 8; 1717 a += addr->ether_addr_octet[0]; 1718 1719 mix(a, b, c); 1720 return (c & BRIDGE_RTABLE_MASK); 1721 } 1722 1723 /* 1724 * Trim the routing table so that we've got a number of routes 1725 * less than or equal to the maximum. 1726 */ 1727 void 1728 bridge_rttrim(sc) 1729 struct bridge_softc *sc; 1730 { 1731 struct bridge_rtnode *n, *p; 1732 int i; 1733 1734 if (sc->sc_rts == NULL) 1735 goto done; 1736 1737 /* 1738 * Make sure we have to trim the address table 1739 */ 1740 if (sc->sc_brtcnt <= sc->sc_brtmax) 1741 goto done; 1742 1743 /* 1744 * Force an aging cycle, this might trim enough addresses. 1745 */ 1746 bridge_rtage(sc); 1747 1748 if (sc->sc_brtcnt <= sc->sc_brtmax) 1749 goto done; 1750 1751 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1752 n = LIST_FIRST(&sc->sc_rts[i]); 1753 while (n != LIST_END(&sc->sc_rts[i])) { 1754 p = LIST_NEXT(n, brt_next); 1755 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1756 LIST_REMOVE(n, brt_next); 1757 sc->sc_brtcnt--; 1758 free(n, M_DEVBUF); 1759 n = p; 1760 if (sc->sc_brtcnt <= sc->sc_brtmax) 1761 goto done; 1762 } 1763 } 1764 } 1765 1766 done: 1767 if (sc->sc_rts != NULL && sc->sc_brtcnt == 0 && 1768 (sc->sc_if.if_flags & IFF_UP) == 0) { 1769 free(sc->sc_rts, M_DEVBUF); 1770 sc->sc_rts = NULL; 1771 } 1772 } 1773 1774 void 1775 bridge_timer(vsc) 1776 void *vsc; 1777 { 1778 struct bridge_softc *sc = vsc; 1779 int s; 1780 1781 s = splsoftnet(); 1782 bridge_rtage(sc); 1783 splx(s); 1784 } 1785 1786 /* 1787 * Perform an aging cycle 1788 */ 1789 void 1790 bridge_rtage(sc) 1791 struct bridge_softc *sc; 1792 { 1793 struct bridge_rtnode *n, *p; 1794 int i; 1795 1796 if (sc->sc_rts == NULL) 1797 return; 1798 1799 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1800 n = LIST_FIRST(&sc->sc_rts[i]); 1801 while (n != LIST_END(&sc->sc_rts[i])) { 1802 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_STATIC) { 1803 n->brt_age = !n->brt_age; 1804 if (n->brt_age) 1805 n->brt_age = 0; 1806 n = LIST_NEXT(n, brt_next); 1807 } else if (n->brt_age) { 1808 n->brt_age = 0; 1809 n = LIST_NEXT(n, brt_next); 1810 } else { 1811 p = LIST_NEXT(n, brt_next); 1812 LIST_REMOVE(n, brt_next); 1813 sc->sc_brtcnt--; 1814 free(n, M_DEVBUF); 1815 n = p; 1816 } 1817 } 1818 } 1819 1820 if (sc->sc_brttimeout != 0) 1821 timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); 1822 } 1823 1824 /* 1825 * Remove all dynamic addresses from the cache 1826 */ 1827 int 1828 bridge_rtflush(sc, full) 1829 struct bridge_softc *sc; 1830 int full; 1831 { 1832 int i; 1833 struct bridge_rtnode *p, *n; 1834 1835 if (sc->sc_rts == NULL) 1836 return (0); 1837 1838 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1839 n = LIST_FIRST(&sc->sc_rts[i]); 1840 while (n != LIST_END(&sc->sc_rts[i])) { 1841 if (full || 1842 (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1843 p = LIST_NEXT(n, brt_next); 1844 LIST_REMOVE(n, brt_next); 1845 sc->sc_brtcnt--; 1846 free(n, M_DEVBUF); 1847 n = p; 1848 } else 1849 n = LIST_NEXT(n, brt_next); 1850 } 1851 } 1852 1853 if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) { 1854 free(sc->sc_rts, M_DEVBUF); 1855 sc->sc_rts = NULL; 1856 } 1857 1858 return (0); 1859 } 1860 1861 /* 1862 * Remove an address from the cache 1863 */ 1864 int 1865 bridge_rtdaddr(sc, ea) 1866 struct bridge_softc *sc; 1867 struct ether_addr *ea; 1868 { 1869 int h; 1870 struct bridge_rtnode *p; 1871 1872 if (sc->sc_rts == NULL) 1873 return (ENOENT); 1874 1875 h = bridge_hash(sc, ea); 1876 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1877 if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) { 1878 LIST_REMOVE(p, brt_next); 1879 sc->sc_brtcnt--; 1880 free(p, M_DEVBUF); 1881 if (sc->sc_brtcnt == 0 && 1882 (sc->sc_if.if_flags & IFF_UP) == 0) { 1883 free(sc->sc_rts, M_DEVBUF); 1884 sc->sc_rts = NULL; 1885 } 1886 return (0); 1887 } 1888 } 1889 1890 return (ENOENT); 1891 } 1892 /* 1893 * Delete routes to a specific interface member. 1894 */ 1895 void 1896 bridge_rtdelete(sc, ifp) 1897 struct bridge_softc *sc; 1898 struct ifnet *ifp; 1899 { 1900 int i; 1901 struct bridge_rtnode *n, *p; 1902 1903 if (sc->sc_rts == NULL) 1904 return; 1905 1906 /* 1907 * Loop through all of the hash buckets and traverse each 1908 * chain looking for routes to this interface. 1909 */ 1910 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1911 n = LIST_FIRST(&sc->sc_rts[i]); 1912 while (n != LIST_END(&sc->sc_rts[i])) { 1913 if (n->brt_if == ifp) { /* found one */ 1914 p = LIST_NEXT(n, brt_next); 1915 LIST_REMOVE(n, brt_next); 1916 sc->sc_brtcnt--; 1917 free(n, M_DEVBUF); 1918 n = p; 1919 } else 1920 n = LIST_NEXT(n, brt_next); 1921 } 1922 } 1923 if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) { 1924 free(sc->sc_rts, M_DEVBUF); 1925 sc->sc_rts = NULL; 1926 } 1927 } 1928 1929 /* 1930 * Gather all of the routes for this interface. 1931 */ 1932 int 1933 bridge_rtfind(sc, baconf) 1934 struct bridge_softc *sc; 1935 struct ifbaconf *baconf; 1936 { 1937 int i, error = 0; 1938 u_int32_t cnt = 0; 1939 struct bridge_rtnode *n; 1940 struct ifbareq bareq; 1941 1942 if (sc->sc_rts == NULL || baconf->ifbac_len == 0) 1943 goto done; 1944 1945 for (i = 0, cnt = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1946 LIST_FOREACH(n, &sc->sc_rts[i], brt_next) { 1947 if (baconf->ifbac_len < sizeof(struct ifbareq)) 1948 goto done; 1949 bcopy(sc->sc_if.if_xname, bareq.ifba_name, 1950 sizeof(bareq.ifba_name)); 1951 bcopy(n->brt_if->if_xname, bareq.ifba_ifsname, 1952 sizeof(bareq.ifba_ifsname)); 1953 bcopy(&n->brt_addr, &bareq.ifba_dst, 1954 sizeof(bareq.ifba_dst)); 1955 bareq.ifba_age = n->brt_age; 1956 bareq.ifba_flags = n->brt_flags; 1957 error = copyout((caddr_t)&bareq, 1958 (caddr_t)(baconf->ifbac_req + cnt), sizeof(bareq)); 1959 if (error) 1960 goto done; 1961 cnt++; 1962 baconf->ifbac_len -= sizeof(struct ifbareq); 1963 } 1964 } 1965 done: 1966 baconf->ifbac_len = cnt * sizeof(struct ifbareq); 1967 return (error); 1968 } 1969 1970 /* 1971 * Block non-ip frames: 1972 * Returns 0 if frame is ip, and 1 if it should be dropped. 1973 */ 1974 int 1975 bridge_blocknonip(eh, m) 1976 struct ether_header *eh; 1977 struct mbuf *m; 1978 { 1979 struct llc llc; 1980 u_int16_t etype; 1981 1982 if (m->m_pkthdr.len < sizeof(struct ether_header)) 1983 return (1); 1984 1985 etype = ntohs(eh->ether_type); 1986 switch (etype) { 1987 case ETHERTYPE_ARP: 1988 case ETHERTYPE_REVARP: 1989 case ETHERTYPE_IP: 1990 case ETHERTYPE_IPV6: 1991 return (0); 1992 } 1993 1994 if (etype > ETHERMTU) 1995 return (1); 1996 1997 if (m->m_pkthdr.len < 1998 (sizeof(struct ether_header) + LLC_SNAPFRAMELEN)) 1999 return (1); 2000 2001 m_copydata(m, sizeof(struct ether_header), LLC_SNAPFRAMELEN, 2002 (caddr_t)&llc); 2003 2004 etype = ntohs(llc.llc_snap.ether_type); 2005 if (llc.llc_dsap == LLC_SNAP_LSAP && 2006 llc.llc_ssap == LLC_SNAP_LSAP && 2007 llc.llc_control == LLC_UI && 2008 llc.llc_snap.org_code[0] == 0 && 2009 llc.llc_snap.org_code[1] == 0 && 2010 llc.llc_snap.org_code[2] == 0 && 2011 (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP || 2012 etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) { 2013 return (0); 2014 } 2015 2016 return (1); 2017 } 2018 2019 u_int8_t 2020 bridge_filterrule(h, eh) 2021 struct brl_head *h; 2022 struct ether_header *eh; 2023 { 2024 struct brl_node *n; 2025 u_int8_t flags; 2026 2027 SIMPLEQ_FOREACH(n, h, brl_next) { 2028 flags = n->brl_flags & (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID); 2029 if (flags == 0) 2030 return (n->brl_action); 2031 if (flags == (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID)) { 2032 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2033 continue; 2034 if (bcmp(eh->ether_dhost, &n->brl_src, ETHER_ADDR_LEN)) 2035 continue; 2036 return (n->brl_action); 2037 } 2038 if (flags == BRL_FLAG_SRCVALID) { 2039 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2040 continue; 2041 return (n->brl_action); 2042 } 2043 if (flags == BRL_FLAG_DSTVALID) { 2044 if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN)) 2045 continue; 2046 return (n->brl_action); 2047 } 2048 } 2049 return (BRL_ACTION_PASS); 2050 } 2051 2052 int 2053 bridge_addrule(bif, req, out) 2054 struct bridge_iflist *bif; 2055 struct ifbrlreq *req; 2056 int out; 2057 { 2058 struct brl_node *n; 2059 2060 n = (struct brl_node *)malloc(sizeof(struct brl_node), M_DEVBUF, M_NOWAIT); 2061 if (n == NULL) 2062 return (ENOMEM); 2063 bcopy(&req->ifbr_src, &n->brl_src, sizeof(struct ether_addr)); 2064 bcopy(&req->ifbr_dst, &n->brl_dst, sizeof(struct ether_addr)); 2065 n->brl_action = req->ifbr_action; 2066 n->brl_flags = req->ifbr_flags; 2067 if (out) { 2068 n->brl_flags &= ~BRL_FLAG_IN; 2069 n->brl_flags |= BRL_FLAG_OUT; 2070 SIMPLEQ_INSERT_TAIL(&bif->bif_brlout, n, brl_next); 2071 } else { 2072 n->brl_flags &= ~BRL_FLAG_OUT; 2073 n->brl_flags |= BRL_FLAG_IN; 2074 SIMPLEQ_INSERT_TAIL(&bif->bif_brlin, n, brl_next); 2075 } 2076 return (0); 2077 } 2078 2079 int 2080 bridge_flushrule(bif) 2081 struct bridge_iflist *bif; 2082 { 2083 struct brl_node *p; 2084 2085 while (!SIMPLEQ_EMPTY(&bif->bif_brlin)) { 2086 p = SIMPLEQ_FIRST(&bif->bif_brlin); 2087 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlin, p, brl_next); 2088 free(p, M_DEVBUF); 2089 } 2090 while (!SIMPLEQ_EMPTY(&bif->bif_brlout)) { 2091 p = SIMPLEQ_FIRST(&bif->bif_brlout); 2092 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlout, p, brl_next); 2093 free(p, M_DEVBUF); 2094 } 2095 return (0); 2096 } 2097 2098 #if NPF > 0 2099 /* 2100 * Filter IP packets by peeking into the ethernet frame. This violates 2101 * the ISO model, but allows us to act as a IP filter at the data link 2102 * layer. As a result, most of this code will look familiar to those 2103 * who've read net/if_ethersubr.c and netinet/ip_input.c 2104 */ 2105 struct mbuf * 2106 bridge_filter(sc, dir, ifp, eh, m) 2107 struct bridge_softc *sc; 2108 int dir; 2109 struct ifnet *ifp; 2110 struct ether_header *eh; 2111 struct mbuf *m; 2112 { 2113 struct llc llc; 2114 int hassnap = 0; 2115 struct ip *ip; 2116 int hlen; 2117 2118 if (eh->ether_type != htons(ETHERTYPE_IP)) { 2119 if (eh->ether_type > ETHERMTU || 2120 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 2121 sizeof(struct ether_header))) 2122 return (m); 2123 2124 m_copydata(m, sizeof(struct ether_header), 2125 LLC_SNAPFRAMELEN, (caddr_t)&llc); 2126 2127 if (llc.llc_dsap != LLC_SNAP_LSAP || 2128 llc.llc_ssap != LLC_SNAP_LSAP || 2129 llc.llc_control != LLC_UI || 2130 llc.llc_snap.org_code[0] || 2131 llc.llc_snap.org_code[1] || 2132 llc.llc_snap.org_code[2] || 2133 llc.llc_snap.ether_type != htons(ETHERTYPE_IP)) 2134 return (m); 2135 hassnap = 1; 2136 } 2137 2138 m_adj(m, sizeof(struct ether_header)); 2139 if (hassnap) 2140 m_adj(m, LLC_SNAPFRAMELEN); 2141 2142 if (m->m_pkthdr.len < sizeof(struct ip)) 2143 goto dropit; 2144 2145 /* Copy minimal header, and drop invalids */ 2146 if (m->m_len < sizeof(struct ip) && 2147 (m = m_pullup(m, sizeof(struct ip))) == NULL) { 2148 ipstat.ips_toosmall++; 2149 return (NULL); 2150 } 2151 ip = mtod(m, struct ip *); 2152 2153 if (ip->ip_v != IPVERSION) { 2154 ipstat.ips_badvers++; 2155 goto dropit; 2156 } 2157 2158 hlen = ip->ip_hl << 2; /* get whole header length */ 2159 if (hlen < sizeof(struct ip)) { 2160 ipstat.ips_badhlen++; 2161 goto dropit; 2162 } 2163 if (hlen > m->m_len) { 2164 if ((m = m_pullup(m, hlen)) == NULL) { 2165 ipstat.ips_badhlen++; 2166 return (NULL); 2167 } 2168 ip = mtod(m, struct ip *); 2169 } 2170 2171 if ((ip->ip_sum = in_cksum(m, hlen)) != 0) { 2172 ipstat.ips_badsum++; 2173 goto dropit; 2174 } 2175 2176 NTOHS(ip->ip_len); 2177 if (ip->ip_len < hlen) 2178 goto dropit; 2179 NTOHS(ip->ip_id); 2180 NTOHS(ip->ip_off); 2181 2182 if (m->m_pkthdr.len < ip->ip_len) 2183 goto dropit; 2184 if (m->m_pkthdr.len > ip->ip_len) { 2185 if (m->m_len == m->m_pkthdr.len) { 2186 m->m_len = ip->ip_len; 2187 m->m_pkthdr.len = ip->ip_len; 2188 } else 2189 m_adj(m, ip->ip_len - m->m_pkthdr.len); 2190 } 2191 2192 /* Finally, we get to filter the packet! */ 2193 m->m_pkthdr.rcvif = ifp; 2194 if (pf_test(dir, ifp, &m) != PF_PASS) 2195 goto dropit; 2196 if (m == NULL) 2197 goto dropit; 2198 2199 /* Rebuild the IP header */ 2200 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL)) 2201 return (NULL); 2202 if (m->m_len < sizeof(struct ip)) 2203 goto dropit; 2204 ip = mtod(m, struct ip *); 2205 HTONS(ip->ip_len); 2206 HTONS(ip->ip_id); 2207 HTONS(ip->ip_off); 2208 ip->ip_sum = 0; 2209 ip->ip_sum = in_cksum(m, hlen); 2210 2211 /* Reattach SNAP header */ 2212 if (hassnap) { 2213 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 2214 if (m == NULL) 2215 goto dropit; 2216 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 2217 } 2218 2219 /* Reattach ethernet header */ 2220 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 2221 if (m == NULL) 2222 goto dropit; 2223 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 2224 2225 return (m); 2226 2227 dropit: 2228 if (m != NULL) 2229 m_freem(m); 2230 return (NULL); 2231 } 2232 #endif /* NPF > 0 */ 2233