1 /* $OpenBSD: if_bridge.c,v 1.172 2008/09/10 14:01:23 blambert 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Effort sponsored in part by the Defense Advanced Research Projects 29 * Agency (DARPA) and Air Force Research Laboratory, Air Force 30 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 31 * 32 */ 33 34 #include "bpfilter.h" 35 #include "gif.h" 36 #include "pf.h" 37 #include "carp.h" 38 39 #include <sys/param.h> 40 #include <sys/proc.h> 41 #include <sys/systm.h> 42 #include <sys/mbuf.h> 43 #include <sys/socket.h> 44 #include <sys/ioctl.h> 45 #include <sys/errno.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 /* for arc4random() */ 56 #include <dev/rndvar.h> 57 58 #ifdef INET 59 #include <netinet/in.h> 60 #include <netinet/in_systm.h> 61 #include <netinet/in_var.h> 62 #include <netinet/ip.h> 63 #include <netinet/ip_var.h> 64 #include <netinet/if_ether.h> 65 #include <netinet/ip_icmp.h> 66 #endif 67 68 #ifdef IPSEC 69 #include <netinet/ip_ipsp.h> 70 71 #include <net/if_enc.h> 72 #endif 73 74 #ifdef INET6 75 #include <netinet/ip6.h> 76 #include <netinet6/ip6_var.h> 77 #endif 78 79 #if NPF > 0 80 #include <net/pfvar.h> 81 #define BRIDGE_IN PF_IN 82 #define BRIDGE_OUT PF_OUT 83 #else 84 #define BRIDGE_IN 0 85 #define BRIDGE_OUT 1 86 #endif 87 88 #if NBPFILTER > 0 89 #include <net/bpf.h> 90 #endif 91 92 #include <net/if_vlan_var.h> 93 94 #if NCARP > 0 95 #include <netinet/ip_carp.h> 96 #endif 97 98 #include <net/if_bridge.h> 99 100 /* 101 * Maximum number of addresses to cache 102 */ 103 #ifndef BRIDGE_RTABLE_MAX 104 #define BRIDGE_RTABLE_MAX 100 105 #endif 106 107 /* 108 * Timeout (in seconds) for entries learned dynamically 109 */ 110 #ifndef BRIDGE_RTABLE_TIMEOUT 111 #define BRIDGE_RTABLE_TIMEOUT 240 112 #endif 113 114 void bridgeattach(int); 115 int bridge_ioctl(struct ifnet *, u_long, caddr_t); 116 void bridge_start(struct ifnet *); 117 void bridgeintr_frame(struct bridge_softc *, struct mbuf *); 118 void bridge_broadcast(struct bridge_softc *, struct ifnet *, 119 struct ether_header *, struct mbuf *); 120 void bridge_span(struct bridge_softc *, struct ether_header *, 121 struct mbuf *); 122 void bridge_stop(struct bridge_softc *); 123 void bridge_init(struct bridge_softc *); 124 int bridge_bifconf(struct bridge_softc *, struct ifbifconf *); 125 126 void bridge_timer(void *); 127 int bridge_rtfind(struct bridge_softc *, struct ifbaconf *); 128 void bridge_rtage(struct bridge_softc *); 129 void bridge_rttrim(struct bridge_softc *); 130 int bridge_rtdaddr(struct bridge_softc *, struct ether_addr *); 131 int bridge_rtflush(struct bridge_softc *, int); 132 struct ifnet * bridge_rtupdate(struct bridge_softc *, 133 struct ether_addr *, struct ifnet *ifp, int, u_int8_t); 134 struct ifnet * bridge_rtlookup(struct bridge_softc *, 135 struct ether_addr *); 136 u_int32_t bridge_hash(struct bridge_softc *, struct ether_addr *); 137 int bridge_blocknonip(struct ether_header *, struct mbuf *); 138 int bridge_addrule(struct bridge_iflist *, 139 struct ifbrlreq *, int out); 140 int bridge_flushrule(struct bridge_iflist *); 141 int bridge_brlconf(struct bridge_softc *, struct ifbrlconf *); 142 u_int8_t bridge_filterrule(struct brl_head *, struct ether_header *, 143 struct mbuf *); 144 #if NPF > 0 145 struct mbuf *bridge_filter(struct bridge_softc *, int, struct ifnet *, 146 struct ether_header *, struct mbuf *m); 147 #endif 148 int bridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *); 149 void bridge_fragment(struct bridge_softc *, struct ifnet *, 150 struct ether_header *, struct mbuf *); 151 #ifdef INET 152 void bridge_send_icmp_err(struct bridge_softc *, struct ifnet *, 153 struct ether_header *, struct mbuf *, int, struct llc *, int, int, int); 154 #endif 155 #ifdef IPSEC 156 int bridge_ipsec(struct bridge_softc *, struct ifnet *, 157 struct ether_header *, int, struct llc *, 158 int, int, int, struct mbuf *); 159 #define ICMP_DEFLEN MHLEN 160 #endif 161 int bridge_clone_create(struct if_clone *, int); 162 int bridge_clone_destroy(struct ifnet *ifp); 163 int bridge_delete(struct bridge_softc *, struct bridge_iflist *); 164 165 #define ETHERADDR_IS_IP_MCAST(a) \ 166 /* struct etheraddr *a; */ \ 167 ((a)->ether_addr_octet[0] == 0x01 && \ 168 (a)->ether_addr_octet[1] == 0x00 && \ 169 (a)->ether_addr_octet[2] == 0x5e) 170 171 LIST_HEAD(, bridge_softc) bridge_list; 172 173 struct if_clone bridge_cloner = 174 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); 175 176 /* ARGSUSED */ 177 void 178 bridgeattach(int n) 179 { 180 LIST_INIT(&bridge_list); 181 if_clone_attach(&bridge_cloner); 182 bstp_attach(n); 183 } 184 185 int 186 bridge_clone_create(struct if_clone *ifc, int unit) 187 { 188 struct bridge_softc *sc; 189 struct ifnet *ifp; 190 int i, s; 191 192 sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT|M_ZERO); 193 if (!sc) 194 return (ENOMEM); 195 196 sc->sc_stp = bstp_create(&sc->sc_if); 197 if (!sc->sc_stp) { 198 free(sc, M_DEVBUF); 199 return (ENOMEM); 200 } 201 202 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 203 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 204 timeout_set(&sc->sc_brtimeout, bridge_timer, sc); 205 LIST_INIT(&sc->sc_iflist); 206 LIST_INIT(&sc->sc_spanlist); 207 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) 208 LIST_INIT(&sc->sc_rts[i]); 209 sc->sc_hashkey = arc4random(); 210 ifp = &sc->sc_if; 211 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, 212 unit); 213 ifp->if_softc = sc; 214 ifp->if_mtu = ETHERMTU; 215 ifp->if_ioctl = bridge_ioctl; 216 ifp->if_output = bridge_output; 217 ifp->if_start = bridge_start; 218 ifp->if_type = IFT_BRIDGE; 219 ifp->if_hdrlen = ETHER_HDR_LEN; 220 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 221 IFQ_SET_READY(&ifp->if_snd); 222 223 if_attach(ifp); 224 if_alloc_sadl(ifp); 225 226 #if NBPFILTER > 0 227 bpfattach(&sc->sc_if.if_bpf, ifp, 228 DLT_EN10MB, ETHER_HDR_LEN); 229 #endif 230 231 s = splnet(); 232 LIST_INSERT_HEAD(&bridge_list, sc, sc_list); 233 splx(s); 234 235 return (0); 236 } 237 238 int 239 bridge_clone_destroy(struct ifnet *ifp) 240 { 241 struct bridge_softc *sc = ifp->if_softc; 242 struct bridge_iflist *bif; 243 int s; 244 245 bridge_stop(sc); 246 bridge_rtflush(sc, IFBF_FLUSHALL); 247 while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) 248 bridge_delete(sc, bif); 249 while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) { 250 LIST_REMOVE(bif, next); 251 free(bif, M_DEVBUF); 252 } 253 254 s = splnet(); 255 LIST_REMOVE(sc, sc_list); 256 splx(s); 257 258 bstp_destroy(sc->sc_stp); 259 if_detach(ifp); 260 261 free(sc, M_DEVBUF); 262 return (0); 263 } 264 265 int 266 bridge_delete(struct bridge_softc *sc, struct bridge_iflist *p) 267 { 268 int error; 269 270 if (p->bif_flags & IFBIF_STP) 271 bstp_delete(p->bif_stp); 272 273 p->ifp->if_bridge = NULL; 274 error = ifpromisc(p->ifp, 0); 275 276 LIST_REMOVE(p, next); 277 bridge_rtdelete(sc, p->ifp, 0); 278 bridge_flushrule(p); 279 free(p, M_DEVBUF); 280 281 return (error); 282 } 283 284 int 285 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 286 { 287 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc; 288 struct ifbreq *req = (struct ifbreq *)data; 289 struct ifbareq *bareq = (struct ifbareq *)data; 290 struct ifbrparam *bparam = (struct ifbrparam *)data; 291 struct ifbrlreq *brlreq = (struct ifbrlreq *)data; 292 struct ifbropreq *brop = (struct ifbropreq *)data; 293 struct ifnet *ifs; 294 struct bridge_iflist *p; 295 struct bstp_port *bp; 296 struct bstp_state *bs = sc->sc_stp; 297 int error = 0, s; 298 299 s = splnet(); 300 switch (cmd) { 301 case SIOCBRDGADD: 302 if ((error = suser(curproc, 0)) != 0) 303 break; 304 305 ifs = ifunit(req->ifbr_ifsname); 306 if (ifs == NULL) { /* no such interface */ 307 error = ENOENT; 308 break; 309 } 310 if (ifs->if_bridge == (caddr_t)sc) { 311 error = EEXIST; 312 break; 313 } 314 if (ifs->if_bridge != NULL) { 315 error = EBUSY; 316 break; 317 } 318 319 /* If it's in the span list, it can't be a member. */ 320 LIST_FOREACH(p, &sc->sc_spanlist, next) 321 if (p->ifp == ifs) 322 break; 323 324 if (p != LIST_END(&sc->sc_spanlist)) { 325 error = EBUSY; 326 break; 327 } 328 329 if (ifs->if_type == IFT_ETHER) { 330 if ((ifs->if_flags & IFF_UP) == 0) { 331 struct ifreq ifreq; 332 333 /* 334 * Bring interface up long enough to set 335 * promiscuous flag, then shut it down again. 336 */ 337 strlcpy(ifreq.ifr_name, req->ifbr_ifsname, 338 IFNAMSIZ); 339 ifs->if_flags |= IFF_UP; 340 ifreq.ifr_flags = ifs->if_flags; 341 error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, 342 (caddr_t)&ifreq); 343 if (error != 0) 344 break; 345 346 error = ifpromisc(ifs, 1); 347 if (error != 0) 348 break; 349 350 strlcpy(ifreq.ifr_name, req->ifbr_ifsname, 351 IFNAMSIZ); 352 ifs->if_flags &= ~IFF_UP; 353 ifreq.ifr_flags = ifs->if_flags; 354 error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, 355 (caddr_t)&ifreq); 356 if (error != 0) { 357 ifpromisc(ifs, 0); 358 break; 359 } 360 } else { 361 error = ifpromisc(ifs, 1); 362 if (error != 0) 363 break; 364 } 365 } 366 #if NGIF > 0 367 else if (ifs->if_type == IFT_GIF) { 368 /* Nothing needed */ 369 } 370 #endif /* NGIF */ 371 else { 372 error = EINVAL; 373 break; 374 } 375 376 p = malloc(sizeof(*p), M_DEVBUF, M_NOWAIT|M_ZERO); 377 if (p == NULL) { 378 if (ifs->if_type == IFT_ETHER) 379 ifpromisc(ifs, 0); 380 error = ENOMEM; 381 break; 382 } 383 384 p->ifp = ifs; 385 p->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 386 SIMPLEQ_INIT(&p->bif_brlin); 387 SIMPLEQ_INIT(&p->bif_brlout); 388 ifs->if_bridge = (caddr_t)sc; 389 LIST_INSERT_HEAD(&sc->sc_iflist, p, next); 390 break; 391 case SIOCBRDGDEL: 392 if ((error = suser(curproc, 0)) != 0) 393 break; 394 395 LIST_FOREACH(p, &sc->sc_iflist, next) { 396 if (strncmp(p->ifp->if_xname, req->ifbr_ifsname, 397 sizeof(p->ifp->if_xname)) == 0) { 398 error = bridge_delete(sc, p); 399 p = NULL; 400 break; 401 } 402 } 403 if (p != NULL && p == LIST_END(&sc->sc_iflist)) { 404 error = ENOENT; 405 break; 406 } 407 break; 408 case SIOCBRDGIFS: 409 error = bridge_bifconf(sc, (struct ifbifconf *)data); 410 break; 411 case SIOCBRDGADDS: 412 if ((error = suser(curproc, 0)) != 0) 413 break; 414 ifs = ifunit(req->ifbr_ifsname); 415 if (ifs == NULL) { /* no such interface */ 416 error = ENOENT; 417 break; 418 } 419 if (ifs->if_bridge == (caddr_t)sc) { 420 error = EEXIST; 421 break; 422 } 423 if (ifs->if_bridge != NULL) { 424 error = EBUSY; 425 break; 426 } 427 LIST_FOREACH(p, &sc->sc_spanlist, next) { 428 if (p->ifp == ifs) 429 break; 430 } 431 if (p != LIST_END(&sc->sc_spanlist)) { 432 error = EBUSY; 433 break; 434 } 435 p = malloc(sizeof(*p), M_DEVBUF, M_NOWAIT|M_ZERO); 436 if (p == NULL) { 437 error = ENOMEM; 438 break; 439 } 440 p->ifp = ifs; 441 p->bif_flags = IFBIF_SPAN; 442 SIMPLEQ_INIT(&p->bif_brlin); 443 SIMPLEQ_INIT(&p->bif_brlout); 444 LIST_INSERT_HEAD(&sc->sc_spanlist, p, next); 445 break; 446 case SIOCBRDGDELS: 447 if ((error = suser(curproc, 0)) != 0) 448 break; 449 LIST_FOREACH(p, &sc->sc_spanlist, next) { 450 if (strncmp(p->ifp->if_xname, req->ifbr_ifsname, 451 sizeof(p->ifp->if_xname)) == 0) { 452 LIST_REMOVE(p, next); 453 free(p, M_DEVBUF); 454 break; 455 } 456 } 457 if (p == LIST_END(&sc->sc_spanlist)) { 458 error = ENOENT; 459 break; 460 } 461 break; 462 case SIOCBRDGGIFFLGS: 463 ifs = ifunit(req->ifbr_ifsname); 464 if (ifs == NULL) { 465 error = ENOENT; 466 break; 467 } 468 if ((caddr_t)sc != ifs->if_bridge) { 469 error = ESRCH; 470 break; 471 } 472 LIST_FOREACH(p, &sc->sc_iflist, next) { 473 if (p->ifp == ifs) 474 break; 475 } 476 if (p == LIST_END(&sc->sc_iflist)) { 477 error = ESRCH; 478 break; 479 } 480 req->ifbr_ifsflags = p->bif_flags; 481 req->ifbr_portno = p->ifp->if_index & 0xfff; 482 if (p->bif_flags & IFBIF_STP) { 483 bp = p->bif_stp; 484 req->ifbr_state = bstp_getstate(bs, bp); 485 req->ifbr_priority = bp->bp_priority; 486 req->ifbr_path_cost = bp->bp_path_cost; 487 req->ifbr_proto = bp->bp_protover; 488 req->ifbr_role = bp->bp_role; 489 req->ifbr_stpflags = bp->bp_flags; 490 req->ifbr_fwd_trans = bp->bp_forward_transitions; 491 req->ifbr_desg_bridge = bp->bp_desg_pv.pv_dbridge_id; 492 req->ifbr_desg_port = bp->bp_desg_pv.pv_dport_id; 493 req->ifbr_root_bridge = bp->bp_desg_pv.pv_root_id; 494 req->ifbr_root_cost = bp->bp_desg_pv.pv_cost; 495 req->ifbr_root_port = bp->bp_desg_pv.pv_port_id; 496 497 /* Copy STP state options as flags */ 498 if (bp->bp_operedge) 499 req->ifbr_ifsflags |= IFBIF_BSTP_EDGE; 500 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) 501 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; 502 if (bp->bp_ptp_link) 503 req->ifbr_ifsflags |= IFBIF_BSTP_PTP; 504 if (bp->bp_flags & BSTP_PORT_AUTOPTP) 505 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; 506 } 507 break; 508 case SIOCBRDGSIFFLGS: 509 if ((error = suser(curproc, 0)) != 0) 510 break; 511 ifs = ifunit(req->ifbr_ifsname); 512 if (ifs == NULL) { 513 error = ENOENT; 514 break; 515 } 516 if ((caddr_t)sc != ifs->if_bridge) { 517 error = ESRCH; 518 break; 519 } 520 LIST_FOREACH(p, &sc->sc_iflist, next) { 521 if (p->ifp == ifs) 522 break; 523 } 524 if (p == LIST_END(&sc->sc_iflist)) { 525 error = ESRCH; 526 break; 527 } 528 if (req->ifbr_ifsflags & IFBIF_RO_MASK) { 529 error = EINVAL; 530 break; 531 } 532 if (req->ifbr_ifsflags & IFBIF_STP) { 533 if ((p->bif_flags & IFBIF_STP) == 0) { 534 /* Enable STP */ 535 if ((p->bif_stp = bstp_add(sc->sc_stp, 536 p->ifp)) == NULL) { 537 error = ENOMEM; 538 break; 539 } 540 } else { 541 /* Update STP flags */ 542 bstp_ifsflags(p->bif_stp, req->ifbr_ifsflags); 543 } 544 } else if (p->bif_flags & IFBIF_STP) { 545 bstp_delete(p->bif_stp); 546 p->bif_stp = NULL; 547 } 548 p->bif_flags = req->ifbr_ifsflags; 549 break; 550 case SIOCBRDGRTS: 551 error = bridge_rtfind(sc, (struct ifbaconf *)data); 552 break; 553 case SIOCBRDGFLUSH: 554 if ((error = suser(curproc, 0)) != 0) 555 break; 556 557 error = bridge_rtflush(sc, req->ifbr_ifsflags); 558 break; 559 case SIOCBRDGSADDR: 560 if ((error = suser(curproc, 0)) != 0) 561 break; 562 563 ifs = ifunit(bareq->ifba_ifsname); 564 if (ifs == NULL) { /* no such interface */ 565 error = ENOENT; 566 break; 567 } 568 569 if (ifs->if_bridge == NULL || 570 ifs->if_bridge != (caddr_t)sc) { 571 error = ESRCH; 572 break; 573 } 574 575 ifs = bridge_rtupdate(sc, &bareq->ifba_dst, ifs, 1, 576 bareq->ifba_flags); 577 if (ifs == NULL) 578 error = ENOMEM; 579 break; 580 case SIOCBRDGDADDR: 581 if ((error = suser(curproc, 0)) != 0) 582 break; 583 error = bridge_rtdaddr(sc, &bareq->ifba_dst); 584 break; 585 case SIOCBRDGGCACHE: 586 bparam->ifbrp_csize = sc->sc_brtmax; 587 break; 588 case SIOCBRDGSCACHE: 589 if ((error = suser(curproc, 0)) != 0) 590 break; 591 sc->sc_brtmax = bparam->ifbrp_csize; 592 bridge_rttrim(sc); 593 break; 594 case SIOCBRDGSTO: 595 if ((error = suser(curproc, 0)) != 0) 596 break; 597 if (bparam->ifbrp_ctime < 0 || 598 bparam->ifbrp_ctime > INT_MAX / hz) { 599 error = EINVAL; 600 break; 601 } 602 sc->sc_brttimeout = bparam->ifbrp_ctime; 603 if (bparam->ifbrp_ctime != 0) 604 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout); 605 else 606 timeout_del(&sc->sc_brtimeout); 607 break; 608 case SIOCBRDGGTO: 609 bparam->ifbrp_ctime = sc->sc_brttimeout; 610 break; 611 case SIOCSIFFLAGS: 612 if ((ifp->if_flags & IFF_UP) == IFF_UP) 613 bridge_init(sc); 614 615 if ((ifp->if_flags & IFF_UP) == 0) 616 bridge_stop(sc); 617 618 break; 619 case SIOCBRDGARL: 620 if ((error = suser(curproc, 0)) != 0) 621 break; 622 ifs = ifunit(brlreq->ifbr_ifsname); 623 if (ifs == NULL) { 624 error = ENOENT; 625 break; 626 } 627 if (ifs->if_bridge == NULL || 628 ifs->if_bridge != (caddr_t)sc) { 629 error = ESRCH; 630 break; 631 } 632 LIST_FOREACH(p, &sc->sc_iflist, next) { 633 if (p->ifp == ifs) 634 break; 635 } 636 if (p == LIST_END(&sc->sc_iflist)) { 637 error = ESRCH; 638 break; 639 } 640 if ((brlreq->ifbr_action != BRL_ACTION_BLOCK && 641 brlreq->ifbr_action != BRL_ACTION_PASS) || 642 (brlreq->ifbr_flags & (BRL_FLAG_IN|BRL_FLAG_OUT)) == 0) { 643 error = EINVAL; 644 break; 645 } 646 if (brlreq->ifbr_flags & BRL_FLAG_IN) { 647 error = bridge_addrule(p, brlreq, 0); 648 if (error) 649 break; 650 } 651 if (brlreq->ifbr_flags & BRL_FLAG_OUT) { 652 error = bridge_addrule(p, brlreq, 1); 653 if (error) 654 break; 655 } 656 break; 657 case SIOCBRDGFRL: 658 if ((error = suser(curproc, 0)) != 0) 659 break; 660 ifs = ifunit(brlreq->ifbr_ifsname); 661 if (ifs == NULL) { 662 error = ENOENT; 663 break; 664 } 665 if (ifs->if_bridge == NULL || 666 ifs->if_bridge != (caddr_t)sc) { 667 error = ESRCH; 668 break; 669 } 670 LIST_FOREACH(p, &sc->sc_iflist, next) { 671 if (p->ifp == ifs) 672 break; 673 } 674 if (p == LIST_END(&sc->sc_iflist)) { 675 error = ESRCH; 676 break; 677 } 678 error = bridge_flushrule(p); 679 break; 680 case SIOCBRDGGRL: 681 error = bridge_brlconf(sc, (struct ifbrlconf *)data); 682 break; 683 case SIOCBRDGGPARAM: 684 if ((bp = bs->bs_root_port) == NULL) 685 brop->ifbop_root_port = 0; 686 else 687 brop->ifbop_root_port = bp->bp_ifp->if_index; 688 brop->ifbop_maxage = bs->bs_bridge_max_age >> 8; 689 brop->ifbop_hellotime = bs->bs_bridge_htime >> 8; 690 brop->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8; 691 brop->ifbop_holdcount = bs->bs_txholdcount; 692 brop->ifbop_priority = bs->bs_bridge_priority; 693 brop->ifbop_protocol = bs->bs_protover; 694 brop->ifbop_root_bridge = bs->bs_root_pv.pv_root_id; 695 brop->ifbop_root_path_cost = bs->bs_root_pv.pv_cost; 696 brop->ifbop_root_port = bs->bs_root_pv.pv_port_id; 697 brop->ifbop_desg_bridge = bs->bs_root_pv.pv_dbridge_id; 698 brop->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec; 699 brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec; 700 break; 701 case SIOCBRDGGPRI: 702 case SIOCBRDGGMA: 703 case SIOCBRDGGHT: 704 case SIOCBRDGGFD: 705 break; 706 case SIOCBRDGSPRI: 707 case SIOCBRDGSFD: 708 case SIOCBRDGSMA: 709 case SIOCBRDGSHT: 710 case SIOCBRDGSTXHC: 711 case SIOCBRDGSPROTO: 712 case SIOCBRDGSIFPRIO: 713 case SIOCBRDGSIFCOST: 714 error = suser(curproc, 0); 715 break; 716 default: 717 error = ENOTTY; 718 break; 719 } 720 721 if (!error) 722 error = bstp_ioctl(ifp, cmd, data); 723 724 splx(s); 725 return (error); 726 } 727 728 /* Detach an interface from a bridge. */ 729 void 730 bridge_ifdetach(struct ifnet *ifp) 731 { 732 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge; 733 struct bridge_iflist *bif; 734 735 LIST_FOREACH(bif, &sc->sc_iflist, next) 736 if (bif->ifp == ifp) { 737 LIST_REMOVE(bif, next); 738 bridge_rtdelete(sc, ifp, 0); 739 bridge_flushrule(bif); 740 free(bif, M_DEVBUF); 741 ifp->if_bridge = NULL; 742 break; 743 } 744 } 745 746 void 747 bridge_update(struct ifnet *ifp, struct ether_addr *ea, int delete) 748 { 749 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge; 750 struct bridge_iflist *bif; 751 u_int8_t *addr; 752 753 addr = (u_int8_t *)ea; 754 755 LIST_FOREACH(bif, &sc->sc_iflist, next) 756 if (bif->ifp == ifp) { 757 /* 758 * Update the bridge interface if it is in 759 * the learning state. 760 */ 761 if ((bif->bif_flags & IFBIF_LEARNING) && 762 (ETHER_IS_MULTICAST(addr) == 0) && 763 !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && 764 addr[3] == 0 && addr[4] == 0 && addr[5] == 0)) { 765 /* Care must be taken with spanning tree */ 766 if ((bif->bif_flags & IFBIF_STP) && 767 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) 768 return; 769 770 /* Delete the address from the bridge */ 771 bridge_rtdaddr(sc, ea); 772 773 if (!delete) { 774 /* Update the bridge table */ 775 bridge_rtupdate(sc, ea, ifp, 0, 776 IFBAF_DYNAMIC); 777 } 778 } 779 return; 780 } 781 } 782 783 int 784 bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc) 785 { 786 struct bridge_iflist *p; 787 struct bstp_port *bp; 788 struct bstp_state *bs = sc->sc_stp; 789 u_int32_t total = 0, i = 0; 790 int error = 0; 791 struct ifbreq *breq = NULL; 792 793 LIST_FOREACH(p, &sc->sc_iflist, next) 794 total++; 795 796 LIST_FOREACH(p, &sc->sc_spanlist, next) 797 total++; 798 799 if (bifc->ifbic_len == 0) { 800 i = total; 801 goto done; 802 } 803 804 if ((breq = (struct ifbreq *) 805 malloc(sizeof(*breq), M_DEVBUF, M_NOWAIT)) == NULL) 806 goto done; 807 808 LIST_FOREACH(p, &sc->sc_iflist, next) { 809 bzero(breq, sizeof(*breq)); 810 if (bifc->ifbic_len < sizeof(*breq)) 811 break; 812 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 813 strlcpy(breq->ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ); 814 breq->ifbr_ifsflags = p->bif_flags; 815 breq->ifbr_portno = p->ifp->if_index & 0xfff; 816 if (p->bif_flags & IFBIF_STP) { 817 bp = p->bif_stp; 818 breq->ifbr_state = bstp_getstate(sc->sc_stp, bp); 819 breq->ifbr_priority = bp->bp_priority; 820 breq->ifbr_path_cost = bp->bp_path_cost; 821 breq->ifbr_proto = bp->bp_protover; 822 breq->ifbr_role = bp->bp_role; 823 breq->ifbr_stpflags = bp->bp_flags; 824 breq->ifbr_fwd_trans = bp->bp_forward_transitions; 825 breq->ifbr_root_bridge = bs->bs_root_pv.pv_root_id; 826 breq->ifbr_root_cost = bs->bs_root_pv.pv_cost; 827 breq->ifbr_root_port = bs->bs_root_pv.pv_port_id; 828 breq->ifbr_desg_bridge = bs->bs_root_pv.pv_dbridge_id; 829 breq->ifbr_desg_port = bs->bs_root_pv.pv_dport_id; 830 831 /* Copy STP state options as flags */ 832 if (bp->bp_operedge) 833 breq->ifbr_ifsflags |= IFBIF_BSTP_EDGE; 834 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) 835 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; 836 if (bp->bp_ptp_link) 837 breq->ifbr_ifsflags |= IFBIF_BSTP_PTP; 838 if (bp->bp_flags & BSTP_PORT_AUTOPTP) 839 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; 840 } 841 error = copyout((caddr_t)breq, 842 (caddr_t)(bifc->ifbic_req + i), sizeof(*breq)); 843 if (error) 844 goto done; 845 i++; 846 bifc->ifbic_len -= sizeof(*breq); 847 } 848 LIST_FOREACH(p, &sc->sc_spanlist, next) { 849 bzero(breq, sizeof(*breq)); 850 if (bifc->ifbic_len < sizeof(*breq)) 851 break; 852 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 853 strlcpy(breq->ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ); 854 breq->ifbr_ifsflags = p->bif_flags | IFBIF_SPAN; 855 breq->ifbr_portno = p->ifp->if_index & 0xfff; 856 error = copyout((caddr_t)breq, 857 (caddr_t)(bifc->ifbic_req + i), sizeof(*breq)); 858 if (error) 859 goto done; 860 i++; 861 bifc->ifbic_len -= sizeof(*breq); 862 } 863 864 done: 865 if (breq != NULL) 866 free(breq, M_DEVBUF); 867 bifc->ifbic_len = i * sizeof(*breq); 868 return (error); 869 } 870 871 int 872 bridge_brlconf(struct bridge_softc *sc, struct ifbrlconf *bc) 873 { 874 struct ifnet *ifp; 875 struct bridge_iflist *ifl; 876 struct brl_node *n; 877 struct ifbrlreq req; 878 int error = 0; 879 u_int32_t i = 0, total = 0; 880 881 ifp = ifunit(bc->ifbrl_ifsname); 882 if (ifp == NULL) 883 return (ENOENT); 884 if (ifp->if_bridge == NULL || ifp->if_bridge != (caddr_t)sc) 885 return (ESRCH); 886 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 887 if (ifl->ifp == ifp) 888 break; 889 } 890 if (ifl == LIST_END(&sc->sc_iflist)) 891 return (ESRCH); 892 893 SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) { 894 total++; 895 } 896 SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) { 897 total++; 898 } 899 900 if (bc->ifbrl_len == 0) { 901 i = total; 902 goto done; 903 } 904 905 SIMPLEQ_FOREACH(n, &ifl->bif_brlin, brl_next) { 906 bzero(&req, sizeof req); 907 if (bc->ifbrl_len < sizeof(req)) 908 goto done; 909 strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 910 strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ); 911 req.ifbr_action = n->brl_action; 912 req.ifbr_flags = n->brl_flags; 913 req.ifbr_src = n->brl_src; 914 req.ifbr_dst = n->brl_dst; 915 #if NPF > 0 916 req.ifbr_tagname[0] = '\0'; 917 if (n->brl_tag) 918 pf_tag2tagname(n->brl_tag, req.ifbr_tagname); 919 #endif 920 error = copyout((caddr_t)&req, 921 (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req)); 922 if (error) 923 goto done; 924 i++; 925 bc->ifbrl_len -= sizeof(req); 926 } 927 928 SIMPLEQ_FOREACH(n, &ifl->bif_brlout, brl_next) { 929 bzero(&req, sizeof req); 930 if (bc->ifbrl_len < sizeof(req)) 931 goto done; 932 strlcpy(req.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 933 strlcpy(req.ifbr_ifsname, ifl->ifp->if_xname, IFNAMSIZ); 934 req.ifbr_action = n->brl_action; 935 req.ifbr_flags = n->brl_flags; 936 req.ifbr_src = n->brl_src; 937 req.ifbr_dst = n->brl_dst; 938 #if NPF > 0 939 req.ifbr_tagname[0] = '\0'; 940 if (n->brl_tag) 941 pf_tag2tagname(n->brl_tag, req.ifbr_tagname); 942 #endif 943 error = copyout((caddr_t)&req, 944 (caddr_t)(bc->ifbrl_buf + (i * sizeof(req))), sizeof(req)); 945 if (error) 946 goto done; 947 i++; 948 bc->ifbrl_len -= sizeof(req); 949 } 950 951 done: 952 bc->ifbrl_len = i * sizeof(req); 953 return (error); 954 } 955 956 void 957 bridge_init(struct bridge_softc *sc) 958 { 959 struct ifnet *ifp = &sc->sc_if; 960 961 if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING) 962 return; 963 964 ifp->if_flags |= IFF_RUNNING; 965 bstp_initialization(sc->sc_stp); 966 967 if (sc->sc_brttimeout != 0) 968 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout); 969 } 970 971 /* 972 * Stop the bridge and deallocate the routing table. 973 */ 974 void 975 bridge_stop(struct bridge_softc *sc) 976 { 977 struct ifnet *ifp = &sc->sc_if; 978 979 /* 980 * If we're not running, there's nothing to do. 981 */ 982 if ((ifp->if_flags & IFF_RUNNING) == 0) 983 return; 984 985 timeout_del(&sc->sc_brtimeout); 986 987 bridge_rtflush(sc, IFBF_FLUSHDYN); 988 989 ifp->if_flags &= ~IFF_RUNNING; 990 } 991 992 /* 993 * Send output from the bridge. The mbuf has the ethernet header 994 * already attached. We must enqueue or free the mbuf before exiting. 995 */ 996 int 997 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, 998 struct rtentry *rt) 999 { 1000 struct ether_header *eh; 1001 struct ifnet *dst_if; 1002 struct ether_addr *dst; 1003 struct bridge_softc *sc; 1004 int s, error, len; 1005 #ifdef IPSEC 1006 struct m_tag *mtag; 1007 #endif /* IPSEC */ 1008 1009 /* ifp must be a member interface of the bridge. */ 1010 sc = (struct bridge_softc *)ifp->if_bridge; 1011 if (sc == NULL) { 1012 m_freem(m); 1013 return (EINVAL); 1014 } 1015 1016 if (m->m_len < sizeof(*eh)) { 1017 m = m_pullup(m, sizeof(*eh)); 1018 if (m == NULL) 1019 return (ENOBUFS); 1020 } 1021 eh = mtod(m, struct ether_header *); 1022 dst = (struct ether_addr *)&eh->ether_dhost[0]; 1023 1024 s = splnet(); 1025 1026 /* 1027 * If bridge is down, but original output interface is up, 1028 * go ahead and send out that interface. Otherwise the packet 1029 * is dropped below. 1030 */ 1031 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1032 dst_if = ifp; 1033 goto sendunicast; 1034 } 1035 1036 /* 1037 * If the packet is a broadcast or we don't know a better way to 1038 * get there, send to all interfaces. 1039 */ 1040 dst_if = bridge_rtlookup(sc, dst); 1041 if (dst_if == NULL || ETHER_IS_MULTICAST(eh->ether_dhost)) { 1042 struct bridge_iflist *p; 1043 struct mbuf *mc; 1044 int used = 0; 1045 1046 #ifdef IPSEC 1047 /* 1048 * Don't send out the packet if IPsec is needed, and 1049 * notify IPsec to do its own crypto for now. 1050 */ 1051 if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, 1052 NULL)) != NULL) { 1053 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 1054 m_freem(m); 1055 splx(s); 1056 return (0); 1057 } 1058 #endif /* IPSEC */ 1059 1060 /* Catch packets that need TCP/UDP/IP hardware checksumming */ 1061 if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT || 1062 m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT || 1063 m->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 1064 m_freem(m); 1065 splx(s); 1066 return (0); 1067 } 1068 1069 bridge_span(sc, NULL, m); 1070 1071 LIST_FOREACH(p, &sc->sc_iflist, next) { 1072 dst_if = p->ifp; 1073 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1074 continue; 1075 1076 /* 1077 * If this is not the original output interface, 1078 * and the interface is participating in spanning 1079 * tree, make sure the port is in a state that 1080 * allows forwarding. 1081 */ 1082 if (dst_if != ifp && 1083 (p->bif_flags & IFBIF_STP) && 1084 (p->bif_state == BSTP_IFSTATE_DISCARDING)) 1085 continue; 1086 1087 if ((p->bif_flags & IFBIF_DISCOVER) == 0 && 1088 (m->m_flags & (M_BCAST | M_MCAST)) == 0) 1089 continue; 1090 1091 #ifdef ALTQ 1092 if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) 1093 #endif 1094 if (IF_QFULL(&dst_if->if_snd)) { 1095 IF_DROP(&dst_if->if_snd); 1096 sc->sc_if.if_oerrors++; 1097 continue; 1098 } 1099 if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) { 1100 used = 1; 1101 mc = m; 1102 } else { 1103 struct mbuf *m1, *m2, *mx; 1104 1105 m1 = m_copym2(m, 0, ETHER_HDR_LEN, 1106 M_DONTWAIT); 1107 if (m1 == NULL) { 1108 sc->sc_if.if_oerrors++; 1109 continue; 1110 } 1111 m2 = m_copym2(m, ETHER_HDR_LEN, 1112 M_COPYALL, M_DONTWAIT); 1113 if (m2 == NULL) { 1114 m_freem(m1); 1115 sc->sc_if.if_oerrors++; 1116 continue; 1117 } 1118 1119 for (mx = m1; mx->m_next != NULL; mx = mx->m_next) 1120 /*EMPTY*/; 1121 mx->m_next = m2; 1122 1123 if (m1->m_flags & M_PKTHDR) { 1124 len = 0; 1125 for (mx = m1; mx != NULL; mx = mx->m_next) 1126 len += mx->m_len; 1127 m1->m_pkthdr.len = len; 1128 } 1129 mc = m1; 1130 } 1131 1132 error = bridge_ifenqueue(sc, dst_if, mc); 1133 if (error) 1134 continue; 1135 } 1136 if (!used) 1137 m_freem(m); 1138 splx(s); 1139 return (0); 1140 } 1141 1142 sendunicast: 1143 bridge_span(sc, NULL, m); 1144 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1145 m_freem(m); 1146 splx(s); 1147 return (ENETDOWN); 1148 } 1149 bridge_ifenqueue(sc, dst_if, m); 1150 splx(s); 1151 return (0); 1152 } 1153 1154 /* 1155 * Start output on the bridge. This function should never be called. 1156 */ 1157 void 1158 bridge_start(struct ifnet *ifp) 1159 { 1160 } 1161 1162 /* 1163 * Loop through each bridge interface and process their input queues. 1164 */ 1165 void 1166 bridgeintr(void) 1167 { 1168 struct bridge_softc *sc; 1169 struct mbuf *m; 1170 int s; 1171 1172 LIST_FOREACH(sc, &bridge_list, sc_list) { 1173 for (;;) { 1174 s = splnet(); 1175 IF_DEQUEUE(&sc->sc_if.if_snd, m); 1176 splx(s); 1177 if (m == NULL) 1178 break; 1179 bridgeintr_frame(sc, m); 1180 } 1181 } 1182 } 1183 1184 /* 1185 * Process a single frame. Frame must be freed or queued before returning. 1186 */ 1187 void 1188 bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m) 1189 { 1190 int s, len; 1191 struct ifnet *src_if, *dst_if; 1192 struct bridge_iflist *ifl; 1193 struct ether_addr *dst, *src; 1194 struct ether_header eh; 1195 1196 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1197 m_freem(m); 1198 return; 1199 } 1200 1201 src_if = m->m_pkthdr.rcvif; 1202 1203 #if NBPFILTER > 0 1204 if (sc->sc_if.if_bpf) 1205 bpf_mtap(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN); 1206 #endif 1207 1208 sc->sc_if.if_ipackets++; 1209 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1210 1211 LIST_FOREACH(ifl, &sc->sc_iflist, next) 1212 if (ifl->ifp == src_if) 1213 break; 1214 1215 if (ifl == LIST_END(&sc->sc_iflist)) { 1216 m_freem(m); 1217 return; 1218 } 1219 1220 if ((ifl->bif_flags & IFBIF_STP) && 1221 (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) { 1222 m_freem(m); 1223 return; 1224 } 1225 1226 if (m->m_pkthdr.len < sizeof(eh)) { 1227 m_freem(m); 1228 return; 1229 } 1230 m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&eh); 1231 dst = (struct ether_addr *)&eh.ether_dhost[0]; 1232 src = (struct ether_addr *)&eh.ether_shost[0]; 1233 1234 /* 1235 * If interface is learning, and if source address 1236 * is not broadcast or multicast, record its address. 1237 */ 1238 if ((ifl->bif_flags & IFBIF_LEARNING) && 1239 (eh.ether_shost[0] & 1) == 0 && 1240 !(eh.ether_shost[0] == 0 && eh.ether_shost[1] == 0 && 1241 eh.ether_shost[2] == 0 && eh.ether_shost[3] == 0 && 1242 eh.ether_shost[4] == 0 && eh.ether_shost[5] == 0)) 1243 bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC); 1244 1245 if ((ifl->bif_flags & IFBIF_STP) && 1246 (ifl->bif_state == BSTP_IFSTATE_LEARNING)) { 1247 m_freem(m); 1248 return; 1249 } 1250 1251 /* 1252 * At this point, the port either doesn't participate in stp or 1253 * it's in the forwarding state 1254 */ 1255 1256 /* 1257 * If packet is unicast, destined for someone on "this" 1258 * side of the bridge, drop it. 1259 */ 1260 if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) { 1261 dst_if = bridge_rtlookup(sc, dst); 1262 if (dst_if == src_if) { 1263 m_freem(m); 1264 return; 1265 } 1266 } else 1267 dst_if = NULL; 1268 1269 /* 1270 * Multicast packets get handled a little differently: 1271 * If interface is: 1272 * -link0,-link1 (default) Forward all multicast 1273 * as broadcast. 1274 * -link0,link1 Drop non-IP multicast, forward 1275 * as broadcast IP multicast. 1276 * link0,-link1 Drop IP multicast, forward as 1277 * broadcast non-IP multicast. 1278 * link0,link1 Drop all multicast. 1279 */ 1280 if (m->m_flags & M_MCAST) { 1281 if ((sc->sc_if.if_flags & 1282 (IFF_LINK0 | IFF_LINK1)) == 1283 (IFF_LINK0 | IFF_LINK1)) { 1284 m_freem(m); 1285 return; 1286 } 1287 if (sc->sc_if.if_flags & IFF_LINK0 && 1288 ETHERADDR_IS_IP_MCAST(dst)) { 1289 m_freem(m); 1290 return; 1291 } 1292 if (sc->sc_if.if_flags & IFF_LINK1 && 1293 !ETHERADDR_IS_IP_MCAST(dst)) { 1294 m_freem(m); 1295 return; 1296 } 1297 } 1298 1299 if (ifl->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) { 1300 m_freem(m); 1301 return; 1302 } 1303 1304 if (bridge_filterrule(&ifl->bif_brlin, &eh, m) == BRL_ACTION_BLOCK) { 1305 m_freem(m); 1306 return; 1307 } 1308 #if NPF > 0 1309 m = bridge_filter(sc, BRIDGE_IN, src_if, &eh, m); 1310 if (m == NULL) 1311 return; 1312 #endif 1313 /* 1314 * If the packet is a multicast or broadcast OR if we don't 1315 * know any better, forward it to all interfaces. 1316 */ 1317 if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) { 1318 sc->sc_if.if_imcasts++; 1319 s = splnet(); 1320 bridge_broadcast(sc, src_if, &eh, m); 1321 splx(s); 1322 return; 1323 } 1324 1325 /* 1326 * At this point, we're dealing with a unicast frame going to a 1327 * different interface 1328 */ 1329 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1330 m_freem(m); 1331 return; 1332 } 1333 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1334 if (ifl->ifp == dst_if) 1335 break; 1336 } 1337 if (ifl == LIST_END(&sc->sc_iflist)) { 1338 m_freem(m); 1339 return; 1340 } 1341 if ((ifl->bif_flags & IFBIF_STP) && 1342 (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) { 1343 m_freem(m); 1344 return; 1345 } 1346 if (bridge_filterrule(&ifl->bif_brlout, &eh, m) == BRL_ACTION_BLOCK) { 1347 m_freem(m); 1348 return; 1349 } 1350 #if NPF > 0 1351 m = bridge_filter(sc, BRIDGE_OUT, dst_if, &eh, m); 1352 if (m == NULL) 1353 return; 1354 #endif 1355 1356 len = m->m_pkthdr.len; 1357 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu) 1358 bridge_fragment(sc, dst_if, &eh, m); 1359 else { 1360 s = splnet(); 1361 bridge_ifenqueue(sc, dst_if, m); 1362 splx(s); 1363 } 1364 } 1365 1366 /* 1367 * Receive input from an interface. Queue the packet for bridging if its 1368 * not for us, and schedule an interrupt. 1369 */ 1370 struct mbuf * 1371 bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m) 1372 { 1373 struct bridge_softc *sc; 1374 int s; 1375 struct bridge_iflist *ifl, *srcifl; 1376 struct arpcom *ac; 1377 struct mbuf *mc; 1378 1379 /* 1380 * Make sure this interface is a bridge member. 1381 */ 1382 if (ifp == NULL || ifp->if_bridge == NULL || m == NULL) 1383 return (m); 1384 1385 if ((m->m_flags & M_PKTHDR) == 0) 1386 panic("bridge_input(): no HDR"); 1387 1388 m->m_flags &= ~M_PROTO1; /* Loop prevention */ 1389 1390 sc = (struct bridge_softc *)ifp->if_bridge; 1391 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1392 return (m); 1393 1394 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1395 if (ifl->ifp == ifp) 1396 break; 1397 } 1398 if (ifl == LIST_END(&sc->sc_iflist)) 1399 return (m); 1400 1401 bridge_span(sc, eh, m); 1402 1403 if (m->m_flags & (M_BCAST | M_MCAST)) { 1404 /* Tap off 802.1D packets, they do not get forwarded */ 1405 if (bcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) { 1406 m = bstp_input(sc->sc_stp, ifl->bif_stp, eh, m); 1407 if (m == NULL) 1408 return (NULL); 1409 } 1410 1411 /* 1412 * No need to queue frames for ifs in the discarding state 1413 */ 1414 if ((ifl->bif_flags & IFBIF_STP) && 1415 (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) 1416 return (m); 1417 1418 /* 1419 * make a copy of 'm' with 'eh' tacked on to the 1420 * beginning. Return 'm' for local processing 1421 * and enqueue the copy. Schedule netisr. 1422 */ 1423 mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT); 1424 if (mc == NULL) 1425 return (m); 1426 M_PREPEND(mc, ETHER_HDR_LEN, M_DONTWAIT); 1427 if (mc == NULL) 1428 return (m); 1429 bcopy(eh, mtod(mc, caddr_t), ETHER_HDR_LEN); 1430 s = splnet(); 1431 if (IF_QFULL(&sc->sc_if.if_snd)) { 1432 m_freem(mc); 1433 splx(s); 1434 return (m); 1435 } 1436 IF_ENQUEUE(&sc->sc_if.if_snd, mc); 1437 splx(s); 1438 schednetisr(NETISR_BRIDGE); 1439 if (ifp->if_type == IFT_GIF) { 1440 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1441 if (ifl->ifp->if_type == IFT_ETHER) 1442 break; 1443 } 1444 if (ifl != LIST_END(&sc->sc_iflist)) { 1445 m->m_flags |= M_PROTO1; 1446 m->m_pkthdr.rcvif = ifl->ifp; 1447 ether_input(ifl->ifp, eh, m); 1448 m = NULL; 1449 } 1450 } 1451 return (m); 1452 } 1453 1454 /* 1455 * No need to queue frames for ifs in the discarding state 1456 */ 1457 if ((ifl->bif_flags & IFBIF_STP) && 1458 (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) 1459 return (m); 1460 1461 /* 1462 * Unicast, make sure it's not for us. 1463 */ 1464 srcifl = ifl; 1465 LIST_FOREACH(ifl, &sc->sc_iflist, next) { 1466 if (ifl->ifp->if_type != IFT_ETHER) 1467 continue; 1468 ac = (struct arpcom *)ifl->ifp; 1469 if (bcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) == 0 1470 #if NCARP > 0 1471 || (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp, 1472 eh, 0) != NULL) 1473 #endif 1474 ) { 1475 if (srcifl->bif_flags & IFBIF_LEARNING) 1476 bridge_rtupdate(sc, 1477 (struct ether_addr *)&eh->ether_shost, 1478 ifp, 0, IFBAF_DYNAMIC); 1479 if (bridge_filterrule(&srcifl->bif_brlin, eh, m) == 1480 BRL_ACTION_BLOCK) { 1481 m_freem(m); 1482 return (NULL); 1483 } 1484 m->m_pkthdr.rcvif = ifl->ifp; 1485 if (ifp->if_type == IFT_GIF) { 1486 m->m_flags |= M_PROTO1; 1487 ether_input(ifl->ifp, eh, m); 1488 m = NULL; 1489 } 1490 return (m); 1491 } 1492 if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0 1493 #if NCARP > 0 1494 || (ifl->ifp->if_carp && carp_ourether(ifl->ifp->if_carp, 1495 eh, 1) != NULL) 1496 #endif 1497 ) { 1498 m_freem(m); 1499 return (NULL); 1500 } 1501 } 1502 M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); 1503 if (m == NULL) 1504 return (NULL); 1505 bcopy(eh, mtod(m, caddr_t), ETHER_HDR_LEN); 1506 s = splnet(); 1507 if (IF_QFULL(&sc->sc_if.if_snd)) { 1508 m_freem(m); 1509 splx(s); 1510 return (NULL); 1511 } 1512 IF_ENQUEUE(&sc->sc_if.if_snd, m); 1513 splx(s); 1514 schednetisr(NETISR_BRIDGE); 1515 return (NULL); 1516 } 1517 1518 /* 1519 * Send a frame to all interfaces that are members of the bridge 1520 * (except the one it came in on). This code assumes that it is 1521 * running at splnet or higher. 1522 */ 1523 void 1524 bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp, 1525 struct ether_header *eh, struct mbuf *m) 1526 { 1527 struct bridge_iflist *p; 1528 struct mbuf *mc; 1529 struct ifnet *dst_if; 1530 int len = m->m_pkthdr.len, used = 0; 1531 1532 splassert(IPL_NET); 1533 1534 LIST_FOREACH(p, &sc->sc_iflist, next) { 1535 /* 1536 * Don't retransmit out of the same interface where 1537 * the packet was received from. 1538 */ 1539 dst_if = p->ifp; 1540 if (dst_if->if_index == ifp->if_index) 1541 continue; 1542 1543 if ((p->bif_flags & IFBIF_STP) && 1544 (p->bif_state == BSTP_IFSTATE_DISCARDING)) 1545 continue; 1546 1547 if ((p->bif_flags & IFBIF_DISCOVER) == 0 && 1548 (m->m_flags & (M_BCAST | M_MCAST)) == 0) 1549 continue; 1550 1551 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1552 continue; 1553 1554 #ifdef ALTQ 1555 if (ALTQ_IS_ENABLED(&dst_if->if_snd) == 0) 1556 #endif 1557 if (IF_QFULL(&dst_if->if_snd)) { 1558 IF_DROP(&dst_if->if_snd); 1559 sc->sc_if.if_oerrors++; 1560 continue; 1561 } 1562 1563 /* Drop non-IP frames if the appropriate flag is set. */ 1564 if (p->bif_flags & IFBIF_BLOCKNONIP && 1565 bridge_blocknonip(eh, m)) 1566 continue; 1567 1568 if (bridge_filterrule(&p->bif_brlout, eh, m) == BRL_ACTION_BLOCK) 1569 continue; 1570 1571 /* If last one, reuse the passed-in mbuf */ 1572 if (LIST_NEXT(p, next) == LIST_END(&sc->sc_iflist)) { 1573 mc = m; 1574 used = 1; 1575 } else { 1576 struct mbuf *m1, *m2, *mx; 1577 1578 m1 = m_copym2(m, 0, ETHER_HDR_LEN, 1579 M_DONTWAIT); 1580 if (m1 == NULL) { 1581 sc->sc_if.if_oerrors++; 1582 continue; 1583 } 1584 m2 = m_copym2(m, ETHER_HDR_LEN, 1585 M_COPYALL, M_DONTWAIT); 1586 if (m2 == NULL) { 1587 m_freem(m1); 1588 sc->sc_if.if_oerrors++; 1589 continue; 1590 } 1591 1592 for (mx = m1; mx->m_next != NULL; mx = mx->m_next) 1593 /*EMPTY*/; 1594 mx->m_next = m2; 1595 1596 if (m1->m_flags & M_PKTHDR) { 1597 int len = 0; 1598 1599 for (mx = m1; mx != NULL; mx = mx->m_next) 1600 len += mx->m_len; 1601 m1->m_pkthdr.len = len; 1602 } 1603 mc = m1; 1604 } 1605 1606 #if NPF > 0 1607 mc = bridge_filter(sc, BRIDGE_OUT, dst_if, eh, mc); 1608 if (mc == NULL) 1609 continue; 1610 #endif 1611 1612 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu) 1613 bridge_fragment(sc, dst_if, eh, mc); 1614 else { 1615 bridge_ifenqueue(sc, dst_if, mc); 1616 } 1617 } 1618 1619 if (!used) 1620 m_freem(m); 1621 } 1622 1623 void 1624 bridge_span(struct bridge_softc *sc, struct ether_header *eh, 1625 struct mbuf *morig) 1626 { 1627 struct bridge_iflist *p; 1628 struct ifnet *ifp; 1629 struct mbuf *mc, *m; 1630 int error; 1631 1632 if (LIST_EMPTY(&sc->sc_spanlist)) 1633 return; 1634 1635 m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT); 1636 if (m == NULL) 1637 return; 1638 if (eh != NULL) { 1639 M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); 1640 if (m == NULL) 1641 return; 1642 bcopy(eh, mtod(m, caddr_t), ETHER_HDR_LEN); 1643 } 1644 1645 LIST_FOREACH(p, &sc->sc_spanlist, next) { 1646 ifp = p->ifp; 1647 1648 if ((ifp->if_flags & IFF_RUNNING) == 0) 1649 continue; 1650 1651 #ifdef ALTQ 1652 if (ALTQ_IS_ENABLED(&ifp->if_snd) == 0) 1653 #endif 1654 if (IF_QFULL(&ifp->if_snd)) { 1655 IF_DROP(&ifp->if_snd); 1656 sc->sc_if.if_oerrors++; 1657 continue; 1658 } 1659 1660 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1661 if (mc == NULL) { 1662 sc->sc_if.if_oerrors++; 1663 continue; 1664 } 1665 1666 error = bridge_ifenqueue(sc, ifp, mc); 1667 if (error) 1668 continue; 1669 } 1670 m_freem(m); 1671 } 1672 1673 struct ifnet * 1674 bridge_rtupdate(struct bridge_softc *sc, struct ether_addr *ea, 1675 struct ifnet *ifp, int setflags, u_int8_t flags) 1676 { 1677 struct bridge_rtnode *p, *q; 1678 u_int32_t h; 1679 int dir; 1680 1681 h = bridge_hash(sc, ea); 1682 p = LIST_FIRST(&sc->sc_rts[h]); 1683 if (p == LIST_END(&sc->sc_rts[h])) { 1684 if (sc->sc_brtcnt >= sc->sc_brtmax) 1685 goto done; 1686 p = malloc(sizeof(*p), M_DEVBUF, M_NOWAIT); 1687 if (p == NULL) 1688 goto done; 1689 1690 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1691 p->brt_if = ifp; 1692 p->brt_age = 1; 1693 1694 if (setflags) 1695 p->brt_flags = flags; 1696 else 1697 p->brt_flags = IFBAF_DYNAMIC; 1698 1699 LIST_INSERT_HEAD(&sc->sc_rts[h], p, brt_next); 1700 sc->sc_brtcnt++; 1701 goto want; 1702 } 1703 1704 do { 1705 q = p; 1706 p = LIST_NEXT(p, brt_next); 1707 1708 dir = memcmp(ea, &q->brt_addr, sizeof(q->brt_addr)); 1709 if (dir == 0) { 1710 if (setflags) { 1711 q->brt_if = ifp; 1712 q->brt_flags = flags; 1713 } else if (!(q->brt_flags & IFBAF_STATIC)) 1714 q->brt_if = ifp; 1715 1716 if (q->brt_if == ifp) 1717 q->brt_age = 1; 1718 ifp = q->brt_if; 1719 goto want; 1720 } 1721 1722 if (dir > 0) { 1723 if (sc->sc_brtcnt >= sc->sc_brtmax) 1724 goto done; 1725 p = malloc(sizeof(*p), M_DEVBUF, M_NOWAIT); 1726 if (p == NULL) 1727 goto done; 1728 1729 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1730 p->brt_if = ifp; 1731 p->brt_age = 1; 1732 1733 if (setflags) 1734 p->brt_flags = flags; 1735 else 1736 p->brt_flags = IFBAF_DYNAMIC; 1737 1738 LIST_INSERT_BEFORE(q, p, brt_next); 1739 sc->sc_brtcnt++; 1740 goto want; 1741 } 1742 1743 if (p == LIST_END(&sc->sc_rts[h])) { 1744 if (sc->sc_brtcnt >= sc->sc_brtmax) 1745 goto done; 1746 p = malloc(sizeof(*p), M_DEVBUF, M_NOWAIT); 1747 if (p == NULL) 1748 goto done; 1749 1750 bcopy(ea, &p->brt_addr, sizeof(p->brt_addr)); 1751 p->brt_if = ifp; 1752 p->brt_age = 1; 1753 1754 if (setflags) 1755 p->brt_flags = flags; 1756 else 1757 p->brt_flags = IFBAF_DYNAMIC; 1758 LIST_INSERT_AFTER(q, p, brt_next); 1759 sc->sc_brtcnt++; 1760 goto want; 1761 } 1762 } while (p != LIST_END(&sc->sc_rts[h])); 1763 1764 done: 1765 ifp = NULL; 1766 want: 1767 return (ifp); 1768 } 1769 1770 struct ifnet * 1771 bridge_rtlookup(struct bridge_softc *sc, struct ether_addr *ea) 1772 { 1773 struct bridge_rtnode *p; 1774 u_int32_t h; 1775 int dir; 1776 1777 h = bridge_hash(sc, ea); 1778 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1779 dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr)); 1780 if (dir == 0) 1781 return (p->brt_if); 1782 if (dir > 0) 1783 goto fail; 1784 } 1785 fail: 1786 return (NULL); 1787 } 1788 1789 /* 1790 * The following hash function is adapted from 'Hash Functions' by Bob Jenkins 1791 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 1792 * "You may use this code any way you wish, private, educational, or 1793 * commercial. It's free." 1794 */ 1795 #define mix(a,b,c) \ 1796 do { \ 1797 a -= b; a -= c; a ^= (c >> 13); \ 1798 b -= c; b -= a; b ^= (a << 8); \ 1799 c -= a; c -= b; c ^= (b >> 13); \ 1800 a -= b; a -= c; a ^= (c >> 12); \ 1801 b -= c; b -= a; b ^= (a << 16); \ 1802 c -= a; c -= b; c ^= (b >> 5); \ 1803 a -= b; a -= c; a ^= (c >> 3); \ 1804 b -= c; b -= a; b ^= (a << 10); \ 1805 c -= a; c -= b; c ^= (b >> 15); \ 1806 } while (0) 1807 1808 u_int32_t 1809 bridge_hash(struct bridge_softc *sc, struct ether_addr *addr) 1810 { 1811 u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_hashkey; 1812 1813 b += addr->ether_addr_octet[5] << 8; 1814 b += addr->ether_addr_octet[4]; 1815 a += addr->ether_addr_octet[3] << 24; 1816 a += addr->ether_addr_octet[2] << 16; 1817 a += addr->ether_addr_octet[1] << 8; 1818 a += addr->ether_addr_octet[0]; 1819 1820 mix(a, b, c); 1821 return (c & BRIDGE_RTABLE_MASK); 1822 } 1823 1824 /* 1825 * Trim the routing table so that we've got a number of routes 1826 * less than or equal to the maximum. 1827 */ 1828 void 1829 bridge_rttrim(struct bridge_softc *sc) 1830 { 1831 struct bridge_rtnode *n, *p; 1832 int i; 1833 1834 /* 1835 * Make sure we have to trim the address table 1836 */ 1837 if (sc->sc_brtcnt <= sc->sc_brtmax) 1838 return; 1839 1840 /* 1841 * Force an aging cycle, this might trim enough addresses. 1842 */ 1843 bridge_rtage(sc); 1844 1845 if (sc->sc_brtcnt <= sc->sc_brtmax) 1846 return; 1847 1848 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1849 n = LIST_FIRST(&sc->sc_rts[i]); 1850 while (n != LIST_END(&sc->sc_rts[i])) { 1851 p = LIST_NEXT(n, brt_next); 1852 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1853 LIST_REMOVE(n, brt_next); 1854 sc->sc_brtcnt--; 1855 free(n, M_DEVBUF); 1856 n = p; 1857 if (sc->sc_brtcnt <= sc->sc_brtmax) 1858 return; 1859 } 1860 } 1861 } 1862 } 1863 1864 void 1865 bridge_timer(void *vsc) 1866 { 1867 struct bridge_softc *sc = vsc; 1868 int s; 1869 1870 s = splsoftnet(); 1871 bridge_rtage(sc); 1872 splx(s); 1873 } 1874 1875 /* 1876 * Perform an aging cycle 1877 */ 1878 void 1879 bridge_rtage(struct bridge_softc *sc) 1880 { 1881 struct bridge_rtnode *n, *p; 1882 int i; 1883 1884 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1885 n = LIST_FIRST(&sc->sc_rts[i]); 1886 while (n != LIST_END(&sc->sc_rts[i])) { 1887 if ((n->brt_flags & IFBAF_TYPEMASK) == IFBAF_STATIC) { 1888 n->brt_age = !n->brt_age; 1889 if (n->brt_age) 1890 n->brt_age = 0; 1891 n = LIST_NEXT(n, brt_next); 1892 } else if (n->brt_age) { 1893 n->brt_age = 0; 1894 n = LIST_NEXT(n, brt_next); 1895 } else { 1896 p = LIST_NEXT(n, brt_next); 1897 LIST_REMOVE(n, brt_next); 1898 sc->sc_brtcnt--; 1899 free(n, M_DEVBUF); 1900 n = p; 1901 } 1902 } 1903 } 1904 1905 if (sc->sc_brttimeout != 0) 1906 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout); 1907 } 1908 1909 void 1910 bridge_rtagenode(struct ifnet *ifp, int age) 1911 { 1912 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_bridge; 1913 struct bridge_rtnode *n; 1914 int i; 1915 1916 if (sc == NULL) 1917 return; 1918 1919 /* 1920 * If the age is zero then flush, otherwise set all the expiry times to 1921 * age for the interface 1922 */ 1923 if (age == 0) 1924 bridge_rtdelete(sc, ifp, 1); 1925 else { 1926 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1927 n = LIST_FIRST(&sc->sc_rts[i]); 1928 while (n != LIST_END(&sc->sc_rts[i])) { 1929 /* Cap the expiry time to 'age' */ 1930 if (n->brt_if == ifp && 1931 n->brt_age > time_uptime + age && 1932 (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 1933 n->brt_age = time_uptime + age; 1934 } 1935 } 1936 } 1937 } 1938 1939 1940 1941 /* 1942 * Remove all dynamic addresses from the cache 1943 */ 1944 int 1945 bridge_rtflush(struct bridge_softc *sc, int full) 1946 { 1947 int i; 1948 struct bridge_rtnode *p, *n; 1949 1950 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 1951 n = LIST_FIRST(&sc->sc_rts[i]); 1952 while (n != LIST_END(&sc->sc_rts[i])) { 1953 if (full || 1954 (n->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1955 p = LIST_NEXT(n, brt_next); 1956 LIST_REMOVE(n, brt_next); 1957 sc->sc_brtcnt--; 1958 free(n, M_DEVBUF); 1959 n = p; 1960 } else 1961 n = LIST_NEXT(n, brt_next); 1962 } 1963 } 1964 1965 return (0); 1966 } 1967 1968 /* 1969 * Remove an address from the cache 1970 */ 1971 int 1972 bridge_rtdaddr(struct bridge_softc *sc, struct ether_addr *ea) 1973 { 1974 int h; 1975 struct bridge_rtnode *p; 1976 1977 h = bridge_hash(sc, ea); 1978 LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { 1979 if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) { 1980 LIST_REMOVE(p, brt_next); 1981 sc->sc_brtcnt--; 1982 free(p, M_DEVBUF); 1983 return (0); 1984 } 1985 } 1986 1987 return (ENOENT); 1988 } 1989 /* 1990 * Delete routes to a specific interface member. 1991 */ 1992 void 1993 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int dynonly) 1994 { 1995 int i; 1996 struct bridge_rtnode *n, *p; 1997 1998 /* 1999 * Loop through all of the hash buckets and traverse each 2000 * chain looking for routes to this interface. 2001 */ 2002 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { 2003 n = LIST_FIRST(&sc->sc_rts[i]); 2004 while (n != LIST_END(&sc->sc_rts[i])) { 2005 if (n->brt_if != ifp) { 2006 /* Not ours */ 2007 n = LIST_NEXT(n, brt_next); 2008 continue; 2009 } 2010 if (dynonly && 2011 (n->brt_flags & IFBAF_TYPEMASK) != IFBAF_DYNAMIC) { 2012 /* only deleting dynamics */ 2013 n = LIST_NEXT(n, brt_next); 2014 continue; 2015 } 2016 p = LIST_NEXT(n, brt_next); 2017 LIST_REMOVE(n, brt_next); 2018 sc->sc_brtcnt--; 2019 free(n, M_DEVBUF); 2020 n = p; 2021 } 2022 } 2023 } 2024 2025 /* 2026 * Gather all of the routes for this interface. 2027 */ 2028 int 2029 bridge_rtfind(struct bridge_softc *sc, struct ifbaconf *baconf) 2030 { 2031 int i, error = 0, onlycnt = 0; 2032 u_int32_t cnt = 0; 2033 struct bridge_rtnode *n; 2034 struct ifbareq bareq; 2035 2036 if (baconf->ifbac_len == 0) 2037 onlycnt = 1; 2038 2039 for (i = 0, cnt = 0; i < BRIDGE_RTABLE_SIZE; i++) { 2040 LIST_FOREACH(n, &sc->sc_rts[i], brt_next) { 2041 if (!onlycnt) { 2042 if (baconf->ifbac_len < sizeof(struct ifbareq)) 2043 goto done; 2044 bcopy(sc->sc_if.if_xname, bareq.ifba_name, 2045 sizeof(bareq.ifba_name)); 2046 bcopy(n->brt_if->if_xname, bareq.ifba_ifsname, 2047 sizeof(bareq.ifba_ifsname)); 2048 bcopy(&n->brt_addr, &bareq.ifba_dst, 2049 sizeof(bareq.ifba_dst)); 2050 bareq.ifba_age = n->brt_age; 2051 bareq.ifba_flags = n->brt_flags; 2052 error = copyout((caddr_t)&bareq, 2053 (caddr_t)(baconf->ifbac_req + cnt), sizeof(bareq)); 2054 if (error) 2055 goto done; 2056 baconf->ifbac_len -= sizeof(struct ifbareq); 2057 } 2058 cnt++; 2059 } 2060 } 2061 done: 2062 baconf->ifbac_len = cnt * sizeof(struct ifbareq); 2063 return (error); 2064 } 2065 2066 /* 2067 * Block non-ip frames: 2068 * Returns 0 if frame is ip, and 1 if it should be dropped. 2069 */ 2070 int 2071 bridge_blocknonip(struct ether_header *eh, struct mbuf *m) 2072 { 2073 struct llc llc; 2074 u_int16_t etype; 2075 2076 if (m->m_pkthdr.len < ETHER_HDR_LEN) 2077 return (1); 2078 2079 etype = ntohs(eh->ether_type); 2080 switch (etype) { 2081 case ETHERTYPE_ARP: 2082 case ETHERTYPE_REVARP: 2083 case ETHERTYPE_IP: 2084 case ETHERTYPE_IPV6: 2085 return (0); 2086 } 2087 2088 if (etype > ETHERMTU) 2089 return (1); 2090 2091 if (m->m_pkthdr.len < 2092 (ETHER_HDR_LEN + LLC_SNAPFRAMELEN)) 2093 return (1); 2094 2095 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, 2096 (caddr_t)&llc); 2097 2098 etype = ntohs(llc.llc_snap.ether_type); 2099 if (llc.llc_dsap == LLC_SNAP_LSAP && 2100 llc.llc_ssap == LLC_SNAP_LSAP && 2101 llc.llc_control == LLC_UI && 2102 llc.llc_snap.org_code[0] == 0 && 2103 llc.llc_snap.org_code[1] == 0 && 2104 llc.llc_snap.org_code[2] == 0 && 2105 (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP || 2106 etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) { 2107 return (0); 2108 } 2109 2110 return (1); 2111 } 2112 2113 u_int8_t 2114 bridge_filterrule(struct brl_head *h, struct ether_header *eh, struct mbuf *m) 2115 { 2116 struct brl_node *n; 2117 u_int8_t flags; 2118 2119 SIMPLEQ_FOREACH(n, h, brl_next) { 2120 flags = n->brl_flags & (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID); 2121 if (flags == 0) 2122 goto return_action; 2123 if (flags == (BRL_FLAG_SRCVALID|BRL_FLAG_DSTVALID)) { 2124 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2125 continue; 2126 if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN)) 2127 continue; 2128 goto return_action; 2129 } 2130 if (flags == BRL_FLAG_SRCVALID) { 2131 if (bcmp(eh->ether_shost, &n->brl_src, ETHER_ADDR_LEN)) 2132 continue; 2133 goto return_action; 2134 } 2135 if (flags == BRL_FLAG_DSTVALID) { 2136 if (bcmp(eh->ether_dhost, &n->brl_dst, ETHER_ADDR_LEN)) 2137 continue; 2138 goto return_action; 2139 } 2140 } 2141 return (BRL_ACTION_PASS); 2142 2143 return_action: 2144 #if NPF > 0 2145 pf_tag_packet(m, n->brl_tag, -1); 2146 #endif 2147 return (n->brl_action); 2148 } 2149 2150 int 2151 bridge_addrule(struct bridge_iflist *bif, struct ifbrlreq *req, int out) 2152 { 2153 struct brl_node *n; 2154 2155 n = malloc(sizeof(*n), M_DEVBUF, M_NOWAIT); 2156 if (n == NULL) 2157 return (ENOMEM); 2158 bcopy(&req->ifbr_src, &n->brl_src, sizeof(struct ether_addr)); 2159 bcopy(&req->ifbr_dst, &n->brl_dst, sizeof(struct ether_addr)); 2160 n->brl_action = req->ifbr_action; 2161 n->brl_flags = req->ifbr_flags; 2162 #if NPF > 0 2163 if (req->ifbr_tagname[0]) 2164 n->brl_tag = pf_tagname2tag(req->ifbr_tagname); 2165 else 2166 n->brl_tag = 0; 2167 #endif 2168 if (out) { 2169 n->brl_flags &= ~BRL_FLAG_IN; 2170 n->brl_flags |= BRL_FLAG_OUT; 2171 SIMPLEQ_INSERT_TAIL(&bif->bif_brlout, n, brl_next); 2172 } else { 2173 n->brl_flags &= ~BRL_FLAG_OUT; 2174 n->brl_flags |= BRL_FLAG_IN; 2175 SIMPLEQ_INSERT_TAIL(&bif->bif_brlin, n, brl_next); 2176 } 2177 return (0); 2178 } 2179 2180 int 2181 bridge_flushrule(struct bridge_iflist *bif) 2182 { 2183 struct brl_node *p; 2184 2185 while (!SIMPLEQ_EMPTY(&bif->bif_brlin)) { 2186 p = SIMPLEQ_FIRST(&bif->bif_brlin); 2187 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlin, brl_next); 2188 #if NPF > 0 2189 pf_tag_unref(p->brl_tag); 2190 #endif 2191 free(p, M_DEVBUF); 2192 } 2193 while (!SIMPLEQ_EMPTY(&bif->bif_brlout)) { 2194 p = SIMPLEQ_FIRST(&bif->bif_brlout); 2195 SIMPLEQ_REMOVE_HEAD(&bif->bif_brlout, brl_next); 2196 #if NPF > 0 2197 pf_tag_unref(p->brl_tag); 2198 #endif 2199 free(p, M_DEVBUF); 2200 } 2201 return (0); 2202 } 2203 2204 #ifdef IPSEC 2205 int 2206 bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp, 2207 struct ether_header *eh, int hassnap, struct llc *llc, 2208 int dir, int af, int hlen, struct mbuf *m) 2209 { 2210 union sockaddr_union dst; 2211 struct timeval tv; 2212 struct tdb *tdb; 2213 u_int32_t spi; 2214 u_int16_t cpi; 2215 int error, off, s; 2216 u_int8_t proto = 0; 2217 #ifdef INET 2218 struct ip *ip; 2219 #endif /* INET */ 2220 #ifdef INET6 2221 struct ip6_hdr *ip6; 2222 #endif /* INET6 */ 2223 2224 if (dir == BRIDGE_IN) { 2225 switch (af) { 2226 #ifdef INET 2227 case AF_INET: 2228 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t)) 2229 break; 2230 2231 ip = mtod(m, struct ip *); 2232 proto = ip->ip_p; 2233 off = offsetof(struct ip, ip_p); 2234 2235 if (proto != IPPROTO_ESP && proto != IPPROTO_AH && 2236 proto != IPPROTO_IPCOMP) 2237 goto skiplookup; 2238 2239 bzero(&dst, sizeof(union sockaddr_union)); 2240 dst.sa.sa_family = AF_INET; 2241 dst.sin.sin_len = sizeof(struct sockaddr_in); 2242 m_copydata(m, offsetof(struct ip, ip_dst), 2243 sizeof(struct in_addr), 2244 (caddr_t)&dst.sin.sin_addr); 2245 2246 if (ip->ip_p == IPPROTO_ESP) 2247 m_copydata(m, hlen, sizeof(u_int32_t), 2248 (caddr_t)&spi); 2249 else if (ip->ip_p == IPPROTO_AH) 2250 m_copydata(m, hlen + sizeof(u_int32_t), 2251 sizeof(u_int32_t), (caddr_t)&spi); 2252 else if (ip->ip_p == IPPROTO_IPCOMP) { 2253 m_copydata(m, hlen + sizeof(u_int16_t), 2254 sizeof(u_int16_t), (caddr_t)&cpi); 2255 spi = ntohl(htons(cpi)); 2256 } 2257 break; 2258 #endif /* INET */ 2259 #ifdef INET6 2260 case AF_INET6: 2261 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t)) 2262 break; 2263 2264 ip6 = mtod(m, struct ip6_hdr *); 2265 2266 /* XXX We should chase down the header chain */ 2267 proto = ip6->ip6_nxt; 2268 off = offsetof(struct ip6_hdr, ip6_nxt); 2269 2270 if (proto != IPPROTO_ESP && proto != IPPROTO_AH && 2271 proto != IPPROTO_IPCOMP) 2272 goto skiplookup; 2273 2274 bzero(&dst, sizeof(union sockaddr_union)); 2275 dst.sa.sa_family = AF_INET6; 2276 dst.sin6.sin6_len = sizeof(struct sockaddr_in6); 2277 m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt), 2278 sizeof(struct in6_addr), 2279 (caddr_t)&dst.sin6.sin6_addr); 2280 2281 if (proto == IPPROTO_ESP) 2282 m_copydata(m, hlen, sizeof(u_int32_t), 2283 (caddr_t)&spi); 2284 else if (proto == IPPROTO_AH) 2285 m_copydata(m, hlen + sizeof(u_int32_t), 2286 sizeof(u_int32_t), (caddr_t)&spi); 2287 else if (proto == IPPROTO_IPCOMP) { 2288 m_copydata(m, hlen + sizeof(u_int16_t), 2289 sizeof(u_int16_t), (caddr_t)&cpi); 2290 spi = ntohl(htons(cpi)); 2291 } 2292 break; 2293 #endif /* INET6 */ 2294 default: 2295 return (0); 2296 } 2297 2298 if (proto == 0) 2299 goto skiplookup; 2300 2301 s = spltdb(); 2302 2303 tdb = gettdb(spi, &dst, proto); 2304 if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 && 2305 tdb->tdb_xform != NULL) { 2306 if (tdb->tdb_first_use == 0) { 2307 tdb->tdb_first_use = time_second; 2308 2309 tv.tv_usec = 0; 2310 2311 /* Check for wrap-around. */ 2312 if (tdb->tdb_exp_first_use + tdb->tdb_first_use 2313 < tdb->tdb_first_use) 2314 tv.tv_sec = ((unsigned long)-1) / 2; 2315 else 2316 tv.tv_sec = tdb->tdb_exp_first_use + 2317 tdb->tdb_first_use; 2318 2319 if (tdb->tdb_flags & TDBF_FIRSTUSE) 2320 timeout_add(&tdb->tdb_first_tmo, 2321 hzto(&tv)); 2322 2323 /* Check for wrap-around. */ 2324 if (tdb->tdb_first_use + 2325 tdb->tdb_soft_first_use 2326 < tdb->tdb_first_use) 2327 tv.tv_sec = ((unsigned long)-1) / 2; 2328 else 2329 tv.tv_sec = tdb->tdb_first_use + 2330 tdb->tdb_soft_first_use; 2331 2332 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) 2333 timeout_add(&tdb->tdb_sfirst_tmo, 2334 hzto(&tv)); 2335 } 2336 2337 (*(tdb->tdb_xform->xf_input))(m, tdb, hlen, off); 2338 splx(s); 2339 return (1); 2340 } else { 2341 splx(s); 2342 skiplookup: 2343 /* XXX do an input policy lookup */ 2344 return (0); 2345 } 2346 } else { /* Outgoing from the bridge. */ 2347 tdb = ipsp_spd_lookup(m, af, hlen, &error, 2348 IPSP_DIRECTION_OUT, NULL, NULL); 2349 if (tdb != NULL) { 2350 /* 2351 * We don't need to do loop detection, the 2352 * bridge will do that for us. 2353 */ 2354 #if NPF > 0 2355 switch (af) { 2356 #ifdef INET 2357 case AF_INET: 2358 if (pf_test(dir, &encif[0].sc_if, 2359 &m, NULL) != PF_PASS) { 2360 m_freem(m); 2361 return (1); 2362 } 2363 break; 2364 #endif /* INET */ 2365 #ifdef INET6 2366 case AF_INET6: 2367 if (pf_test6(dir, &encif[0].sc_if, 2368 &m, NULL) != PF_PASS) { 2369 m_freem(m); 2370 return (1); 2371 } 2372 break; 2373 #endif /* INET6 */ 2374 } 2375 if (m == NULL) 2376 return (1); 2377 #endif /* NPF */ 2378 2379 ip = mtod(m, struct ip *); 2380 if ((af == AF_INET) && 2381 ip_mtudisc && (ip->ip_off & htons(IP_DF)) && 2382 tdb->tdb_mtu && ntohs(ip->ip_len) > tdb->tdb_mtu && 2383 tdb->tdb_mtutimeout > time_second) 2384 bridge_send_icmp_err(sc, ifp, eh, m, 2385 hassnap, llc, tdb->tdb_mtu, 2386 ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG); 2387 else 2388 error = ipsp_process_packet(m, tdb, af, 0); 2389 return (1); 2390 } else 2391 return (0); 2392 } 2393 2394 return (0); 2395 } 2396 #endif /* IPSEC */ 2397 2398 #if NPF > 0 2399 /* 2400 * Filter IP packets by peeking into the ethernet frame. This violates 2401 * the ISO model, but allows us to act as a IP filter at the data link 2402 * layer. As a result, most of this code will look familiar to those 2403 * who've read net/if_ethersubr.c and netinet/ip_input.c 2404 */ 2405 struct mbuf * 2406 bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp, 2407 struct ether_header *eh, struct mbuf *m) 2408 { 2409 struct llc llc; 2410 int hassnap = 0; 2411 struct ip *ip; 2412 int hlen; 2413 u_int16_t etype; 2414 2415 etype = ntohs(eh->ether_type); 2416 2417 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) { 2418 if (etype > ETHERMTU || 2419 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 2420 ETHER_HDR_LEN)) 2421 return (m); 2422 2423 m_copydata(m, ETHER_HDR_LEN, 2424 LLC_SNAPFRAMELEN, (caddr_t)&llc); 2425 2426 if (llc.llc_dsap != LLC_SNAP_LSAP || 2427 llc.llc_ssap != LLC_SNAP_LSAP || 2428 llc.llc_control != LLC_UI || 2429 llc.llc_snap.org_code[0] || 2430 llc.llc_snap.org_code[1] || 2431 llc.llc_snap.org_code[2]) 2432 return (m); 2433 2434 etype = ntohs(llc.llc_snap.ether_type); 2435 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) 2436 return (m); 2437 hassnap = 1; 2438 } 2439 2440 m_adj(m, ETHER_HDR_LEN); 2441 if (hassnap) 2442 m_adj(m, LLC_SNAPFRAMELEN); 2443 2444 switch (etype) { 2445 2446 case ETHERTYPE_IP: 2447 if (m->m_pkthdr.len < sizeof(struct ip)) 2448 goto dropit; 2449 2450 /* Copy minimal header, and drop invalids */ 2451 if (m->m_len < sizeof(struct ip) && 2452 (m = m_pullup(m, sizeof(struct ip))) == NULL) { 2453 ipstat.ips_toosmall++; 2454 return (NULL); 2455 } 2456 ip = mtod(m, struct ip *); 2457 2458 if (ip->ip_v != IPVERSION) { 2459 ipstat.ips_badvers++; 2460 goto dropit; 2461 } 2462 2463 hlen = ip->ip_hl << 2; /* get whole header length */ 2464 if (hlen < sizeof(struct ip)) { 2465 ipstat.ips_badhlen++; 2466 goto dropit; 2467 } 2468 2469 if (hlen > m->m_len) { 2470 if ((m = m_pullup(m, hlen)) == NULL) { 2471 ipstat.ips_badhlen++; 2472 return (NULL); 2473 } 2474 ip = mtod(m, struct ip *); 2475 } 2476 2477 if ((ip->ip_sum = in_cksum(m, hlen)) != 0) { 2478 ipstat.ips_badsum++; 2479 goto dropit; 2480 } 2481 2482 if (ntohs(ip->ip_len) < hlen) 2483 goto dropit; 2484 2485 if (m->m_pkthdr.len < ntohs(ip->ip_len)) 2486 goto dropit; 2487 if (m->m_pkthdr.len > ntohs(ip->ip_len)) { 2488 if (m->m_len == m->m_pkthdr.len) { 2489 m->m_len = ntohs(ip->ip_len); 2490 m->m_pkthdr.len = ntohs(ip->ip_len); 2491 } else 2492 m_adj(m, ntohs(ip->ip_len) - m->m_pkthdr.len); 2493 } 2494 2495 #ifdef IPSEC 2496 if ((sc->sc_if.if_flags & IFF_LINK2) == IFF_LINK2 && 2497 bridge_ipsec(sc, ifp, eh, hassnap, &llc, 2498 dir, AF_INET, hlen, m)) 2499 return (NULL); 2500 #endif /* IPSEC */ 2501 2502 /* Finally, we get to filter the packet! */ 2503 m->m_pkthdr.rcvif = ifp; 2504 if (pf_test(dir, ifp, &m, eh) != PF_PASS) 2505 goto dropit; 2506 if (m == NULL) 2507 goto dropit; 2508 2509 /* Rebuild the IP header */ 2510 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL)) 2511 return (NULL); 2512 if (m->m_len < sizeof(struct ip)) 2513 goto dropit; 2514 ip = mtod(m, struct ip *); 2515 ip->ip_sum = 0; 2516 ip->ip_sum = in_cksum(m, hlen); 2517 2518 break; 2519 2520 #ifdef INET6 2521 case ETHERTYPE_IPV6: { 2522 struct ip6_hdr *ip6; 2523 2524 if (m->m_len < sizeof(struct ip6_hdr)) { 2525 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) 2526 == NULL) { 2527 ip6stat.ip6s_toosmall++; 2528 return (NULL); 2529 } 2530 } 2531 2532 ip6 = mtod(m, struct ip6_hdr *); 2533 2534 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 2535 ip6stat.ip6s_badvers++; 2536 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 2537 goto dropit; 2538 } 2539 2540 #ifdef IPSEC 2541 hlen = sizeof(struct ip6_hdr); 2542 2543 if ((sc->sc_if.if_flags & IFF_LINK2) == IFF_LINK2 && 2544 bridge_ipsec(sc, ifp, eh, hassnap, &llc, 2545 dir, AF_INET6, hlen, m)) 2546 return (NULL); 2547 #endif /* IPSEC */ 2548 2549 if (pf_test6(dir, ifp, &m, eh) != PF_PASS) 2550 goto dropit; 2551 if (m == NULL) 2552 return (NULL); 2553 2554 break; 2555 } 2556 #endif /* INET6 */ 2557 2558 default: 2559 goto dropit; 2560 break; 2561 } 2562 2563 /* Reattach SNAP header */ 2564 if (hassnap) { 2565 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 2566 if (m == NULL) 2567 goto dropit; 2568 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 2569 } 2570 2571 /* Reattach ethernet header */ 2572 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 2573 if (m == NULL) 2574 goto dropit; 2575 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 2576 2577 return (m); 2578 2579 dropit: 2580 if (m != NULL) 2581 m_freem(m); 2582 return (NULL); 2583 } 2584 #endif /* NPF > 0 */ 2585 2586 void 2587 bridge_fragment(struct bridge_softc *sc, struct ifnet *ifp, 2588 struct ether_header *eh, struct mbuf *m) 2589 { 2590 struct llc llc; 2591 struct mbuf *m0; 2592 int s, error = 0; 2593 int hassnap = 0; 2594 #ifdef INET 2595 u_int16_t etype; 2596 struct ip *ip; 2597 #endif 2598 2599 #ifndef INET 2600 goto dropit; 2601 #else 2602 etype = ntohs(eh->ether_type); 2603 if (etype == ETHERTYPE_VLAN && 2604 (ifp->if_capabilities & IFCAP_VLAN_MTU) && 2605 ((m->m_pkthdr.len - sizeof(struct ether_vlan_header)) <= 2606 ifp->if_mtu)) { 2607 s = splnet(); 2608 bridge_ifenqueue(sc, ifp, m); 2609 splx(s); 2610 return; 2611 } 2612 if (etype != ETHERTYPE_IP) { 2613 if (etype > ETHERMTU || 2614 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 2615 ETHER_HDR_LEN)) 2616 goto dropit; 2617 2618 m_copydata(m, ETHER_HDR_LEN, 2619 LLC_SNAPFRAMELEN, (caddr_t)&llc); 2620 2621 if (llc.llc_dsap != LLC_SNAP_LSAP || 2622 llc.llc_ssap != LLC_SNAP_LSAP || 2623 llc.llc_control != LLC_UI || 2624 llc.llc_snap.org_code[0] || 2625 llc.llc_snap.org_code[1] || 2626 llc.llc_snap.org_code[2] || 2627 llc.llc_snap.ether_type != htons(ETHERTYPE_IP)) 2628 goto dropit; 2629 2630 hassnap = 1; 2631 } 2632 2633 m_adj(m, ETHER_HDR_LEN); 2634 if (hassnap) 2635 m_adj(m, LLC_SNAPFRAMELEN); 2636 2637 if (m->m_len < sizeof(struct ip) && 2638 (m = m_pullup(m, sizeof(struct ip))) == NULL) 2639 goto dropit; 2640 ip = mtod(m, struct ip *); 2641 2642 /* Respect IP_DF, return a ICMP_UNREACH_NEEDFRAG. */ 2643 if (ip->ip_off & htons(IP_DF)) { 2644 bridge_send_icmp_err(sc, ifp, eh, m, hassnap, &llc, 2645 ifp->if_mtu, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG); 2646 return; 2647 } 2648 2649 error = ip_fragment(m, ifp, ifp->if_mtu); 2650 if (error) { 2651 m = NULL; 2652 goto dropit; 2653 } 2654 2655 for (; m; m = m0) { 2656 m0 = m->m_nextpkt; 2657 m->m_nextpkt = NULL; 2658 if (error == 0) { 2659 if (hassnap) { 2660 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 2661 if (m == NULL) { 2662 error = ENOBUFS; 2663 continue; 2664 } 2665 bcopy(&llc, mtod(m, caddr_t), 2666 LLC_SNAPFRAMELEN); 2667 } 2668 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 2669 if (m == NULL) { 2670 error = ENOBUFS; 2671 continue; 2672 } 2673 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 2674 s = splnet(); 2675 error = bridge_ifenqueue(sc, ifp, m); 2676 if (error) { 2677 splx(s); 2678 continue; 2679 } 2680 splx(s); 2681 } else 2682 m_freem(m); 2683 } 2684 2685 if (error == 0) 2686 ipstat.ips_fragmented++; 2687 2688 return; 2689 #endif /* INET */ 2690 dropit: 2691 if (m != NULL) 2692 m_freem(m); 2693 } 2694 2695 int 2696 bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m) 2697 { 2698 int error, len; 2699 short mflags; 2700 2701 #if NGIF > 0 2702 /* Packet needs etherip encapsulation. */ 2703 if (ifp->if_type == IFT_GIF) 2704 m->m_flags |= M_PROTO1; 2705 #endif 2706 len = m->m_pkthdr.len; 2707 mflags = m->m_flags; 2708 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error); 2709 if (error) { 2710 sc->sc_if.if_oerrors++; 2711 return (error); 2712 } 2713 sc->sc_if.if_opackets++; 2714 sc->sc_if.if_obytes += len; 2715 ifp->if_obytes += len; 2716 if (mflags & M_MCAST) 2717 ifp->if_omcasts++; 2718 if_start(ifp); 2719 2720 return (0); 2721 } 2722 2723 #ifdef INET 2724 void 2725 bridge_send_icmp_err(struct bridge_softc *sc, struct ifnet *ifp, 2726 struct ether_header *eh, struct mbuf *n, int hassnap, struct llc *llc, 2727 int mtu, int type, int code) 2728 { 2729 struct ip *ip; 2730 struct icmp *icp; 2731 struct in_addr t; 2732 struct mbuf *m, *n2; 2733 int hlen; 2734 u_int8_t ether_tmp[ETHER_ADDR_LEN]; 2735 2736 n2 = m_copym(n, 0, M_COPYALL, M_DONTWAIT); 2737 if (!n2) { 2738 m_freem(n); 2739 return; 2740 } 2741 m = icmp_do_error(n, type, code, 0, mtu); 2742 if (m == NULL) { 2743 m_freem(n2); 2744 return; 2745 } 2746 2747 n = n2; 2748 2749 ip = mtod(m, struct ip *); 2750 hlen = ip->ip_hl << 2; 2751 t = ip->ip_dst; 2752 ip->ip_dst = ip->ip_src; 2753 ip->ip_src = t; 2754 2755 m->m_data += hlen; 2756 m->m_len -= hlen; 2757 icp = mtod(m, struct icmp *); 2758 icp->icmp_cksum = 0; 2759 icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen); 2760 m->m_data -= hlen; 2761 m->m_len += hlen; 2762 2763 ip->ip_v = IPVERSION; 2764 ip->ip_off &= htons(IP_DF); 2765 ip->ip_id = htons(ip_randomid()); 2766 ip->ip_ttl = MAXTTL; 2767 ip->ip_sum = 0; 2768 ip->ip_sum = in_cksum(m, hlen); 2769 2770 /* Swap ethernet addresses */ 2771 bcopy(&eh->ether_dhost, ðer_tmp, sizeof(ether_tmp)); 2772 bcopy(&eh->ether_shost, &eh->ether_dhost, sizeof(ether_tmp)); 2773 bcopy(ðer_tmp, &eh->ether_shost, sizeof(ether_tmp)); 2774 2775 /* Reattach SNAP header */ 2776 if (hassnap) { 2777 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 2778 if (m == NULL) 2779 goto dropit; 2780 bcopy(llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 2781 } 2782 2783 /* Reattach ethernet header */ 2784 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 2785 if (m == NULL) 2786 goto dropit; 2787 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 2788 2789 bridge_output(ifp, m, NULL, NULL); 2790 m_freem(n); 2791 return; 2792 2793 dropit: 2794 m_freem(n); 2795 } 2796 #endif 2797