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