1 /* $OpenBSD: if_bridge.c,v 1.82 2002/01/01 22:39:45 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 sc->sc_if.if_oerrors++; 1430 continue; 1431 } 1432 1433 for (mx = m1; mx->m_next != NULL; mx = mx->m_next) 1434 ; 1435 mx->m_next = m2; 1436 1437 if (m1->m_flags & M_PKTHDR) { 1438 int len = 0; 1439 1440 for (mx = m1; mx != NULL; mx = mx->m_next) 1441 len += mx->m_len; 1442 m1->m_pkthdr.len = len; 1443 } 1444 mc = m1; 1445 } 1446 1447 #if NPF > 0 1448 mc = bridge_filter(sc, BRIDGE_OUT, dst_if, eh, mc); 1449 if (mc == NULL) 1450 continue; 1451 #endif 1452 1453 #ifdef ALTQ 1454 if (ALTQ_IS_ENABLED(&dst_if->if_snd)) 1455 altq_etherclassify(&dst_if->if_snd, mc, &pktattr); 1456 #endif 1457 IFQ_ENQUEUE(&dst_if->if_snd, mc, &pktattr, error); 1458 if (error) { 1459 sc->sc_if.if_oerrors++; 1460 continue; 1461 } 1462 sc->sc_if.if_opackets++; 1463 sc->sc_if.if_obytes += len; 1464 dst_if->if_obytes += len; 1465 if (mflags & M_MCAST) 1466 dst_if->if_omcasts++; 1467 if ((dst_if->if_flags & IFF_OACTIVE) == 0) 1468 (*dst_if->if_start)(dst_if); 1469 } 1470 1471 if (!used) 1472 m_freem(m); 1473 } 1474 1475 void 1476 bridge_span(sc, eh, morig) 1477 struct bridge_softc *sc; 1478 struct ether_header *eh; 1479 struct mbuf *morig; 1480 { 1481 struct bridge_iflist *p; 1482 struct ifnet *ifp; 1483 struct mbuf *mc, *m; 1484 int error; 1485 ALTQ_DECL(struct altq_pktattr pktattr;) 1486 1487 if (LIST_EMPTY(&sc->sc_spanlist)) 1488 return; 1489 1490 m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT); 1491 if (m == NULL) 1492 return; 1493 if (eh != NULL) { 1494 M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT); 1495 if (m == NULL) 1496 return; 1497 bcopy(eh, mtod(m, caddr_t), sizeof(struct ether_header)); 1498 } 1499 1500 LIST_FOREACH(p, &sc->sc_spanlist, next) { 1501 ifp = p->ifp; 1502 1503 if ((ifp->if_flags & IFF_RUNNING) == 0) 1504 continue; 1505 1506 #ifdef ALTQ 1507 if (ALTQ_IS_ENABLED(&ifp->if_snd) == 0) 1508 #endif 1509 if (IF_QFULL(&ifp->if_snd)) { 1510 IF_DROP(&ifp->if_snd); 1511 sc->sc_if.if_oerrors++; 1512 continue; 1513 } 1514 1515 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1516 if (mc == NULL) { 1517 sc->sc_if.if_oerrors++; 1518 continue; 1519 } 1520 1521 #ifdef ALTQ 1522 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 1523 altq_etherclassify(&ifp->if_snd, mc, &pktattr); 1524 #endif 1525 1526 IFQ_ENQUEUE(&ifp->if_snd, mc, &pktattr, error); 1527 if (error) { 1528 sc->sc_if.if_oerrors++; 1529 continue; 1530 } 1531 sc->sc_if.if_opackets++; 1532 sc->sc_if.if_obytes += m->m_pkthdr.len; 1533 ifp->if_obytes += m->m_pkthdr.len; 1534 if (m->m_flags & M_MCAST) 1535 ifp->if_omcasts++; 1536 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1537 (*ifp->if_start)(ifp); 1538 } 1539 m_freem(m); 1540 } 1541 1542 struct ifnet * 1543 bridge_rtupdate(sc, ea, ifp, setflags, flags) 1544 struct bridge_softc *sc; 1545 struct ether_addr *ea; 1546 struct ifnet *ifp; 1547 int setflags; 1548 u_int8_t flags; 1549 { 1550 struct bridge_rtnode *p, *q; 1551 u_int32_t h; 1552 int dir; 1553 1554 if (sc->sc_rts == NULL) { 1555 if (setflags && flags == IFBAF_STATIC) { 1556 sc->sc_rts = (struct bridge_rthead *)malloc( 1557 BRIDGE_RTABLE_SIZE * 1558 (sizeof(struct bridge_rthead)),M_DEVBUF,M_NOWAIT); 1559 if (sc->sc_rts == NULL) 1560 goto done; 1561 1562 for (h = 0; h < BRIDGE_RTABLE_SIZE; h++) { 1563 LIST_INIT(&sc->sc_rts[h]); 1564 } 1565 sc->sc_hashkey = arc4random(); 1566 } else 1567 goto done; 1568 } 1569 1570 h = bridge_hash(sc, ea); 1571 p = LIST_FIRST(&sc->sc_rts[h]); 1572 if (p == LIST_END(&sc->sc_rts[h])) { 1573 if (sc->sc_brtcnt >= sc->sc_brtmax) 1574 goto done; 1575 p = (struct bridge_rtnode *)malloc( 1576 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1577 if (p == NULL) 1578 goto done; 1579 1580 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1581 p->brt_if = ifp; 1582 p->brt_age = 1; 1583 1584 if (setflags) 1585 p->brt_flags = flags; 1586 else 1587 p->brt_flags = IFBAF_DYNAMIC; 1588 1589 LIST_INSERT_HEAD(&sc->sc_rts[h], p, brt_next); 1590 sc->sc_brtcnt++; 1591 goto want; 1592 } 1593 1594 do { 1595 q = p; 1596 p = LIST_NEXT(p, brt_next); 1597 1598 dir = memcmp(ea, &q->brt_addr, sizeof(q->brt_addr)); 1599 if (dir == 0) { 1600 if (setflags) { 1601 q->brt_if = ifp; 1602 q->brt_flags = flags; 1603 } 1604 1605 if (q->brt_if == ifp) 1606 q->brt_age = 1; 1607 ifp = q->brt_if; 1608 goto want; 1609 } 1610 1611 if (dir > 0) { 1612 if (sc->sc_brtcnt >= sc->sc_brtmax) 1613 goto done; 1614 p = (struct bridge_rtnode *)malloc( 1615 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1616 if (p == NULL) 1617 goto done; 1618 1619 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1620 p->brt_if = ifp; 1621 p->brt_age = 1; 1622 1623 if (setflags) 1624 p->brt_flags = flags; 1625 else 1626 p->brt_flags = IFBAF_DYNAMIC; 1627 1628 LIST_INSERT_BEFORE(q, p, brt_next); 1629 sc->sc_brtcnt++; 1630 goto want; 1631 } 1632 1633 if (p == LIST_END(&sc->sc_rts[h])) { 1634 if (sc->sc_brtcnt >= sc->sc_brtmax) 1635 goto done; 1636 p = (struct bridge_rtnode *)malloc( 1637 sizeof(struct bridge_rtnode), M_DEVBUF, M_NOWAIT); 1638 if (p == NULL) 1639 goto done; 1640 1641 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1642 p->brt_if = ifp; 1643 p->brt_age = 1; 1644 1645 if (setflags) 1646 p->brt_flags = flags; 1647 else 1648 p->brt_flags = IFBAF_DYNAMIC; 1649 LIST_INSERT_AFTER(q, p, brt_next); 1650 sc->sc_brtcnt++; 1651 goto want; 1652 } 1653 } while (p != LIST_END(&sc->sc_rts[h])); 1654 1655 done: 1656 ifp = NULL; 1657 want: 1658 return (ifp); 1659 } 1660 1661 struct ifnet * 1662 bridge_rtlookup(sc, ea) 1663 struct bridge_softc *sc; 1664 struct ether_addr *ea; 1665 { 1666 struct bridge_rtnode *p; 1667 u_int32_t h; 1668 int dir; 1669 1670 if (sc->sc_rts == NULL) 1671 goto fail; 1672 1673 h = bridge_hash(sc, ea); 1674 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1675 dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr)); 1676 if (dir == 0) 1677 return (p->brt_if); 1678 if (dir > 0) 1679 goto fail; 1680 } 1681 fail: 1682 return (NULL); 1683 } 1684 1685 /* 1686 * The following hash function is adapted from 'Hash Functions' by Bob Jenkins 1687 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1688 * "You may use this code any way you wish, private, educational, or 1689 * commercial. It's free." 1690 */ 1691 #define mix(a,b,c) \ 1692 do { \ 1693 a -= b; a -= c; a ^= (c >> 13); \ 1694 b -= c; b -= a; b ^= (a << 8); \ 1695 c -= a; c -= b; c ^= (b >> 13); \ 1696 a -= b; a -= c; a ^= (c >> 12); \ 1697 b -= c; b -= a; b ^= (a << 16); \ 1698 c -= a; c -= b; c ^= (b >> 5); \ 1699 a -= b; a -= c; a ^= (c >> 3); \ 1700 b -= c; b -= a; b ^= (a << 10); \ 1701 c -= a; c -= b; c ^= (b >> 15); \ 1702 } while(0) 1703 1704 u_int32_t 1705 bridge_hash(sc, addr) 1706 struct bridge_softc *sc; 1707 struct ether_addr *addr; 1708 { 1709 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_hashkey; 1710 1711 b += addr->ether_addr_octet[5] << 8; 1712 b += addr->ether_addr_octet[4]; 1713 a += addr->ether_addr_octet[3] << 24; 1714 a += addr->ether_addr_octet[2] << 16; 1715 a += addr->ether_addr_octet[1] << 8; 1716 a += addr->ether_addr_octet[0]; 1717 1718 mix(a, b, c); 1719 return (c & BRIDGE_RTABLE_MASK); 1720 } 1721 1722 /* 1723 * Trim the routing table so that we've got a number of routes 1724 * less than or equal to the maximum. 1725 */ 1726 void 1727 bridge_rttrim(sc) 1728 struct bridge_softc *sc; 1729 { 1730 struct bridge_rtnode *n, *p; 1731 int i; 1732 1733 if (sc->sc_rts == NULL) 1734 goto done; 1735 1736 /* 1737 * Make sure we have to trim the address table 1738 */ 1739 if (sc->sc_brtcnt <= sc->sc_brtmax) 1740 goto done; 1741 1742 /* 1743 * Force an aging cycle, this might trim enough addresses. 1744 */ 1745 bridge_rtage(sc); 1746 1747 if (sc->sc_brtcnt <= sc->sc_brtmax) 1748 goto done; 1749 1750 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1751 n = LIST_FIRST(&sc->sc_rts[i]); 1752 while (n != LIST_END(&sc->sc_rts[i])) { 1753 p = LIST_NEXT(n, brt_next); 1754 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1755 LIST_REMOVE(n, brt_next); 1756 sc->sc_brtcnt--; 1757 free(n, M_DEVBUF); 1758 n = p; 1759 if (sc->sc_brtcnt <= sc->sc_brtmax) 1760 goto done; 1761 } 1762 } 1763 } 1764 1765 done: 1766 if (sc->sc_rts != NULL && sc->sc_brtcnt == 0 && 1767 (sc->sc_if.if_flags & IFF_UP) == 0) { 1768 free(sc->sc_rts, M_DEVBUF); 1769 sc->sc_rts = NULL; 1770 } 1771 } 1772 1773 void 1774 bridge_timer(vsc) 1775 void *vsc; 1776 { 1777 struct bridge_softc *sc = vsc; 1778 int s; 1779 1780 s = splsoftnet(); 1781 bridge_rtage(sc); 1782 splx(s); 1783 } 1784 1785 /* 1786 * Perform an aging cycle 1787 */ 1788 void 1789 bridge_rtage(sc) 1790 struct bridge_softc *sc; 1791 { 1792 struct bridge_rtnode *n, *p; 1793 int i; 1794 1795 if (sc->sc_rts == NULL) 1796 return; 1797 1798 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1799 n = LIST_FIRST(&sc->sc_rts[i]); 1800 while (n != LIST_END(&sc->sc_rts[i])) { 1801 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_STATIC) { 1802 n->brt_age = !n->brt_age; 1803 if (n->brt_age) 1804 n->brt_age = 0; 1805 n = LIST_NEXT(n, brt_next); 1806 } else if (n->brt_age) { 1807 n->brt_age = 0; 1808 n = LIST_NEXT(n, brt_next); 1809 } else { 1810 p = LIST_NEXT(n, brt_next); 1811 LIST_REMOVE(n, brt_next); 1812 sc->sc_brtcnt--; 1813 free(n, M_DEVBUF); 1814 n = p; 1815 } 1816 } 1817 } 1818 1819 if (sc->sc_brttimeout != 0) 1820 timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); 1821 } 1822 1823 /* 1824 * Remove all dynamic addresses from the cache 1825 */ 1826 int 1827 bridge_rtflush(sc, full) 1828 struct bridge_softc *sc; 1829 int full; 1830 { 1831 int i; 1832 struct bridge_rtnode *p, *n; 1833 1834 if (sc->sc_rts == NULL) 1835 return (0); 1836 1837 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1838 n = LIST_FIRST(&sc->sc_rts[i]); 1839 while (n != LIST_END(&sc->sc_rts[i])) { 1840 if (full || 1841 (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1842 p = LIST_NEXT(n, brt_next); 1843 LIST_REMOVE(n, brt_next); 1844 sc->sc_brtcnt--; 1845 free(n, M_DEVBUF); 1846 n = p; 1847 } else 1848 n = LIST_NEXT(n, brt_next); 1849 } 1850 } 1851 1852 if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) { 1853 free(sc->sc_rts, M_DEVBUF); 1854 sc->sc_rts = NULL; 1855 } 1856 1857 return (0); 1858 } 1859 1860 /* 1861 * Remove an address from the cache 1862 */ 1863 int 1864 bridge_rtdaddr(sc, ea) 1865 struct bridge_softc *sc; 1866 struct ether_addr *ea; 1867 { 1868 int h; 1869 struct bridge_rtnode *p; 1870 1871 if (sc->sc_rts == NULL) 1872 return (ENOENT); 1873 1874 h = bridge_hash(sc, ea); 1875 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1876 if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) { 1877 LIST_REMOVE(p, brt_next); 1878 sc->sc_brtcnt--; 1879 free(p, M_DEVBUF); 1880 if (sc->sc_brtcnt == 0 && 1881 (sc->sc_if.if_flags & IFF_UP) == 0) { 1882 free(sc->sc_rts, M_DEVBUF); 1883 sc->sc_rts = NULL; 1884 } 1885 return (0); 1886 } 1887 } 1888 1889 return (ENOENT); 1890 } 1891 /* 1892 * Delete routes to a specific interface member. 1893 */ 1894 void 1895 bridge_rtdelete(sc, ifp) 1896 struct bridge_softc *sc; 1897 struct ifnet *ifp; 1898 { 1899 int i; 1900 struct bridge_rtnode *n, *p; 1901 1902 if (sc->sc_rts == NULL) 1903 return; 1904 1905 /* 1906 * Loop through all of the hash buckets and traverse each 1907 * chain looking for routes to this interface. 1908 */ 1909 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1910 n = LIST_FIRST(&sc->sc_rts[i]); 1911 while (n != LIST_END(&sc->sc_rts[i])) { 1912 if (n->brt_if == ifp) { /* found one */ 1913 p = LIST_NEXT(n, brt_next); 1914 LIST_REMOVE(n, brt_next); 1915 sc->sc_brtcnt--; 1916 free(n, M_DEVBUF); 1917 n = p; 1918 } else 1919 n = LIST_NEXT(n, brt_next); 1920 } 1921 } 1922 if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) { 1923 free(sc->sc_rts, M_DEVBUF); 1924 sc->sc_rts = NULL; 1925 } 1926 } 1927 1928 /* 1929 * Gather all of the routes for this interface. 1930 */ 1931 int 1932 bridge_rtfind(sc, baconf) 1933 struct bridge_softc *sc; 1934 struct ifbaconf *baconf; 1935 { 1936 int i, error = 0; 1937 u_int32_t cnt = 0; 1938 struct bridge_rtnode *n; 1939 struct ifbareq bareq; 1940 1941 if (sc->sc_rts == NULL || baconf->ifbac_len == 0) 1942 goto done; 1943 1944 for (i = 0, cnt = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1945 LIST_FOREACH(n, &sc->sc_rts[i], brt_next) { 1946 if (baconf->ifbac_len < sizeof(struct ifbareq)) 1947 goto done; 1948 bcopy(sc->sc_if.if_xname, bareq.ifba_name, 1949 sizeof(bareq.ifba_name)); 1950 bcopy(n->brt_if->if_xname, bareq.ifba_ifsname, 1951 sizeof(bareq.ifba_ifsname)); 1952 bcopy(&n->brt_addr, &bareq.ifba_dst, 1953 sizeof(bareq.ifba_dst)); 1954 bareq.ifba_age = n->brt_age; 1955 bareq.ifba_flags = n->brt_flags; 1956 error = copyout((caddr_t)&bareq, 1957 (caddr_t)(baconf->ifbac_req + cnt), sizeof(bareq)); 1958 if (error) 1959 goto done; 1960 cnt++; 1961 baconf->ifbac_len -= sizeof(struct ifbareq); 1962 } 1963 } 1964 done: 1965 baconf->ifbac_len = cnt * sizeof(struct ifbareq); 1966 return (error); 1967 } 1968 1969 /* 1970 * Block non-ip frames: 1971 * Returns 0 if frame is ip, and 1 if it should be dropped. 1972 */ 1973 int 1974 bridge_blocknonip(eh, m) 1975 struct ether_header *eh; 1976 struct mbuf *m; 1977 { 1978 struct llc llc; 1979 u_int16_t etype; 1980 1981 if (m->m_pkthdr.len < sizeof(struct ether_header)) 1982 return (1); 1983 1984 etype = ntohs(eh->ether_type); 1985 switch (etype) { 1986 case ETHERTYPE_ARP: 1987 case ETHERTYPE_REVARP: 1988 case ETHERTYPE_IP: 1989 case ETHERTYPE_IPV6: 1990 return (0); 1991 } 1992 1993 if (etype > ETHERMTU) 1994 return (1); 1995 1996 if (m->m_pkthdr.len < 1997 (sizeof(struct ether_header) + LLC_SNAPFRAMELEN)) 1998 return (1); 1999 2000 m_copydata(m, sizeof(struct ether_header), LLC_SNAPFRAMELEN, 2001 (caddr_t)&llc); 2002 2003 etype = ntohs(llc.llc_snap.ether_type); 2004 if (llc.llc_dsap == LLC_SNAP_LSAP && 2005 llc.llc_ssap == LLC_SNAP_LSAP && 2006 llc.llc_control == LLC_UI && 2007 llc.llc_snap.org_code[0] == 0 && 2008 llc.llc_snap.org_code[1] == 0 && 2009 llc.llc_snap.org_code[2] == 0 && 2010 (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP || 2011 etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) { 2012 return (0); 2013 } 2014 2015 return (1); 2016 } 2017 2018 u_int8_t 2019 bridge_filterrule(h, eh) 2020 struct brl_head *h; 2021 struct ether_header *eh; 2022 { 2023 struct brl_node *n; 2024 u_int8_t flags; 2025 2026 SIMPLEQ_FOREACH(n, h, brl_next) { 2027 flags = n->brl_flags & (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID); 2028 if (flags == 0) 2029 return (n->brl_action); 2030 if (flags == (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID)) { 2031 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2032 continue; 2033 if (bcmp(eh->ether_dhost, &n->brl_src, ETHER_ADDR_LEN)) 2034 continue; 2035 return (n->brl_action); 2036 } 2037 if (flags == BRL_FLAG_SRCVALID) { 2038 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2039 continue; 2040 return (n->brl_action); 2041 } 2042 if (flags == BRL_FLAG_DSTVALID) { 2043 if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN)) 2044 continue; 2045 return (n->brl_action); 2046 } 2047 } 2048 return (BRL_ACTION_PASS); 2049 } 2050 2051 int 2052 bridge_addrule(bif, req, out) 2053 struct bridge_iflist *bif; 2054 struct ifbrlreq *req; 2055 int out; 2056 { 2057 struct brl_node *n; 2058 2059 n = (struct brl_node *)malloc(sizeof(struct brl_node), M_DEVBUF, M_NOWAIT); 2060 if (n == NULL) 2061 return (ENOMEM); 2062 bcopy(&req->ifbr_src, &n->brl_src, sizeof(struct ether_addr)); 2063 bcopy(&req->ifbr_dst, &n->brl_dst, sizeof(struct ether_addr)); 2064 n->brl_action = req->ifbr_action; 2065 n->brl_flags = req->ifbr_flags; 2066 if (out) { 2067 n->brl_flags &= ~BRL_FLAG_IN; 2068 n->brl_flags |= BRL_FLAG_OUT; 2069 SIMPLEQ_INSERT_TAIL(&bif->bif_brlout, n, brl_next); 2070 } else { 2071 n->brl_flags &= ~BRL_FLAG_OUT; 2072 n->brl_flags |= BRL_FLAG_IN; 2073 SIMPLEQ_INSERT_TAIL(&bif->bif_brlin, n, brl_next); 2074 } 2075 return (0); 2076 } 2077 2078 int 2079 bridge_flushrule(bif) 2080 struct bridge_iflist *bif; 2081 { 2082 struct brl_node *p; 2083 2084 while (!SIMPLEQ_EMPTY(&bif->bif_brlin)) { 2085 p = SIMPLEQ_FIRST(&bif->bif_brlin); 2086 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlin, p, brl_next); 2087 free(p, M_DEVBUF); 2088 } 2089 while (!SIMPLEQ_EMPTY(&bif->bif_brlout)) { 2090 p = SIMPLEQ_FIRST(&bif->bif_brlout); 2091 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlout, p, brl_next); 2092 free(p, M_DEVBUF); 2093 } 2094 return (0); 2095 } 2096 2097 #if NPF > 0 2098 /* 2099 * Filter IP packets by peeking into the ethernet frame. This violates 2100 * the ISO model, but allows us to act as a IP filter at the data link 2101 * layer. As a result, most of this code will look familiar to those 2102 * who've read net/if_ethersubr.c and netinet/ip_input.c 2103 */ 2104 struct mbuf * 2105 bridge_filter(sc, dir, ifp, eh, m) 2106 struct bridge_softc *sc; 2107 int dir; 2108 struct ifnet *ifp; 2109 struct ether_header *eh; 2110 struct mbuf *m; 2111 { 2112 struct llc llc; 2113 int hassnap = 0; 2114 struct ip *ip; 2115 int hlen; 2116 2117 if (eh->ether_type != htons(ETHERTYPE_IP)) { 2118 if (eh->ether_type > ETHERMTU || 2119 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 2120 sizeof(struct ether_header))) 2121 return (m); 2122 2123 m_copydata(m, sizeof(struct ether_header), 2124 LLC_SNAPFRAMELEN, (caddr_t)&llc); 2125 2126 if (llc.llc_dsap != LLC_SNAP_LSAP || 2127 llc.llc_ssap != LLC_SNAP_LSAP || 2128 llc.llc_control != LLC_UI || 2129 llc.llc_snap.org_code[0] || 2130 llc.llc_snap.org_code[1] || 2131 llc.llc_snap.org_code[2] || 2132 llc.llc_snap.ether_type != htons(ETHERTYPE_IP)) 2133 return (m); 2134 hassnap = 1; 2135 } 2136 2137 m_adj(m, sizeof(struct ether_header)); 2138 if (hassnap) 2139 m_adj(m, LLC_SNAPFRAMELEN); 2140 2141 if (m->m_pkthdr.len < sizeof(struct ip)) 2142 goto dropit; 2143 2144 /* Copy minimal header, and drop invalids */ 2145 if (m->m_len < sizeof(struct ip) && 2146 (m = m_pullup(m, sizeof(struct ip))) == NULL) { 2147 ipstat.ips_toosmall++; 2148 return (NULL); 2149 } 2150 ip = mtod(m, struct ip *); 2151 2152 if (ip->ip_v != IPVERSION) { 2153 ipstat.ips_badvers++; 2154 goto dropit; 2155 } 2156 2157 hlen = ip->ip_hl << 2; /* get whole header length */ 2158 if (hlen < sizeof(struct ip)) { 2159 ipstat.ips_badhlen++; 2160 goto dropit; 2161 } 2162 if (hlen > m->m_len) { 2163 if ((m = m_pullup(m, hlen)) == NULL) { 2164 ipstat.ips_badhlen++; 2165 return (NULL); 2166 } 2167 ip = mtod(m, struct ip *); 2168 } 2169 2170 if ((ip->ip_sum = in_cksum(m, hlen)) != 0) { 2171 ipstat.ips_badsum++; 2172 goto dropit; 2173 } 2174 2175 NTOHS(ip->ip_len); 2176 if (ip->ip_len < hlen) 2177 goto dropit; 2178 NTOHS(ip->ip_id); 2179 NTOHS(ip->ip_off); 2180 2181 if (m->m_pkthdr.len < ip->ip_len) 2182 goto dropit; 2183 if (m->m_pkthdr.len > ip->ip_len) { 2184 if (m->m_len == m->m_pkthdr.len) { 2185 m->m_len = ip->ip_len; 2186 m->m_pkthdr.len = ip->ip_len; 2187 } else 2188 m_adj(m, ip->ip_len - m->m_pkthdr.len); 2189 } 2190 2191 /* Finally, we get to filter the packet! */ 2192 m->m_pkthdr.rcvif = ifp; 2193 if (pf_test(dir, ifp, &m) != PF_PASS) 2194 goto dropit; 2195 if (m == NULL) 2196 goto dropit; 2197 2198 /* Rebuild the IP header */ 2199 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL)) 2200 return (NULL); 2201 if (m->m_len < sizeof(struct ip)) 2202 goto dropit; 2203 ip = mtod(m, struct ip *); 2204 HTONS(ip->ip_len); 2205 HTONS(ip->ip_id); 2206 HTONS(ip->ip_off); 2207 ip->ip_sum = 0; 2208 ip->ip_sum = in_cksum(m, hlen); 2209 2210 /* Reattach SNAP header */ 2211 if (hassnap) { 2212 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 2213 if (m == NULL) 2214 goto dropit; 2215 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 2216 } 2217 2218 /* Reattach ethernet header */ 2219 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 2220 if (m == NULL) 2221 goto dropit; 2222 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 2223 2224 return (m); 2225 2226 dropit: 2227 if (m != NULL) 2228 m_freem(m); 2229 return (NULL); 2230 } 2231 #endif /* NPF > 0 */ 2232