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