1 /* $OpenBSD: if_bridge.c,v 1.319 2019/01/29 17:47:35 mpi 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 #include "mpw.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/mbuf.h> 44 #include <sys/socket.h> 45 #include <sys/ioctl.h> 46 #include <sys/kernel.h> 47 48 #include <net/if.h> 49 #include <net/if_types.h> 50 #include <net/if_llc.h> 51 #include <net/netisr.h> 52 53 #include <netinet/in.h> 54 #include <netinet/ip.h> 55 #include <netinet/ip_var.h> 56 #include <netinet/if_ether.h> 57 #include <netinet/ip_icmp.h> 58 59 #ifdef IPSEC 60 #include <netinet/ip_ipsp.h> 61 #include <net/if_enc.h> 62 #endif 63 64 #ifdef INET6 65 #include <netinet6/in6_var.h> 66 #include <netinet/ip6.h> 67 #include <netinet6/ip6_var.h> 68 #endif 69 70 #if NPF > 0 71 #include <net/pfvar.h> 72 #define BRIDGE_IN PF_IN 73 #define BRIDGE_OUT PF_OUT 74 #else 75 #define BRIDGE_IN 0 76 #define BRIDGE_OUT 1 77 #endif 78 79 #if NBPFILTER > 0 80 #include <net/bpf.h> 81 #endif 82 83 #if NCARP > 0 84 #include <netinet/ip_carp.h> 85 #endif 86 87 #if NVLAN > 0 88 #include <net/if_vlan_var.h> 89 #endif 90 91 #include <net/if_bridge.h> 92 93 /* 94 * Maximum number of addresses to cache 95 */ 96 #ifndef BRIDGE_RTABLE_MAX 97 #define BRIDGE_RTABLE_MAX 100 98 #endif 99 100 /* 101 * Timeout (in seconds) for entries learned dynamically 102 */ 103 #ifndef BRIDGE_RTABLE_TIMEOUT 104 #define BRIDGE_RTABLE_TIMEOUT 240 105 #endif 106 107 void bridgeattach(int); 108 int bridge_ioctl(struct ifnet *, u_long, caddr_t); 109 void bridge_ifdetach(void *); 110 void bridge_spandetach(void *); 111 int bridge_ifremove(struct bridge_iflist *); 112 void bridge_spanremove(struct bridge_iflist *); 113 int bridge_input(struct ifnet *, struct mbuf *, void *); 114 void bridge_process(struct ifnet *, struct mbuf *); 115 void bridgeintr_frame(struct bridge_softc *, struct ifnet *, struct mbuf *); 116 void bridge_broadcast(struct bridge_softc *, struct ifnet *, 117 struct ether_header *, struct mbuf *); 118 int bridge_localbroadcast(struct ifnet *, struct ether_header *, 119 struct mbuf *); 120 void bridge_span(struct bridge_softc *, struct mbuf *); 121 void bridge_stop(struct bridge_softc *); 122 void bridge_init(struct bridge_softc *); 123 int bridge_bifconf(struct bridge_softc *, struct ifbifconf *); 124 int bridge_blocknonip(struct ether_header *, struct mbuf *); 125 void bridge_ifinput(struct ifnet *, struct mbuf *); 126 int bridge_dummy_output(struct ifnet *, struct mbuf *, struct sockaddr *, 127 struct rtentry *); 128 void bridge_send_icmp_err(struct ifnet *, struct ether_header *, 129 struct mbuf *, int, struct llc *, int, int, int); 130 int bridge_ifenqueue(struct ifnet *, struct ifnet *, struct mbuf *); 131 struct mbuf *bridge_ip(struct ifnet *, int, struct ifnet *, 132 struct ether_header *, struct mbuf *); 133 #ifdef IPSEC 134 int bridge_ipsec(struct ifnet *, struct ether_header *, int, struct llc *, 135 int, int, int, struct mbuf *); 136 #endif 137 int bridge_clone_create(struct if_clone *, int); 138 int bridge_clone_destroy(struct ifnet *); 139 int bridge_delete(struct bridge_softc *, struct bridge_iflist *); 140 141 #define ETHERADDR_IS_IP_MCAST(a) \ 142 /* struct etheraddr *a; */ \ 143 ((a)->ether_addr_octet[0] == 0x01 && \ 144 (a)->ether_addr_octet[1] == 0x00 && \ 145 (a)->ether_addr_octet[2] == 0x5e) 146 147 struct niqueue bridgeintrq = NIQUEUE_INITIALIZER(1024, NETISR_BRIDGE); 148 149 struct if_clone bridge_cloner = 150 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); 151 152 void 153 bridgeattach(int n) 154 { 155 if_clone_attach(&bridge_cloner); 156 } 157 158 int 159 bridge_clone_create(struct if_clone *ifc, int unit) 160 { 161 struct bridge_softc *sc; 162 struct ifnet *ifp; 163 int i; 164 165 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); 166 sc->sc_stp = bstp_create(&sc->sc_if); 167 if (!sc->sc_stp) { 168 free(sc, M_DEVBUF, sizeof *sc); 169 return (ENOMEM); 170 } 171 172 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 173 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 174 timeout_set(&sc->sc_brtimeout, bridge_rtage, sc); 175 SLIST_INIT(&sc->sc_iflist); 176 SLIST_INIT(&sc->sc_spanlist); 177 for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) 178 LIST_INIT(&sc->sc_rts[i]); 179 arc4random_buf(&sc->sc_hashkey, sizeof(sc->sc_hashkey)); 180 ifp = &sc->sc_if; 181 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, 182 unit); 183 ifp->if_softc = sc; 184 ifp->if_mtu = ETHERMTU; 185 ifp->if_ioctl = bridge_ioctl; 186 ifp->if_output = bridge_dummy_output; 187 ifp->if_xflags = IFXF_CLONED; 188 ifp->if_start = NULL; 189 ifp->if_type = IFT_BRIDGE; 190 ifp->if_hdrlen = ETHER_HDR_LEN; 191 192 if_attach(ifp); 193 if_alloc_sadl(ifp); 194 195 #if NBPFILTER > 0 196 bpfattach(&sc->sc_if.if_bpf, ifp, 197 DLT_EN10MB, ETHER_HDR_LEN); 198 #endif 199 200 if_ih_insert(ifp, ether_input, NULL); 201 202 return (0); 203 } 204 205 int 206 bridge_dummy_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 207 struct rtentry *rt) 208 { 209 m_freem(m); 210 return (EAFNOSUPPORT); 211 } 212 213 int 214 bridge_clone_destroy(struct ifnet *ifp) 215 { 216 struct bridge_softc *sc = ifp->if_softc; 217 struct bridge_iflist *bif; 218 219 bridge_stop(sc); 220 bridge_rtflush(sc, IFBF_FLUSHALL); 221 while ((bif = SLIST_FIRST(&sc->sc_iflist)) != NULL) 222 bridge_ifremove(bif); 223 while ((bif = SLIST_FIRST(&sc->sc_spanlist)) != NULL) 224 bridge_spanremove(bif); 225 226 bstp_destroy(sc->sc_stp); 227 228 /* Undo pseudo-driver changes. */ 229 if_deactivate(ifp); 230 231 if_ih_remove(ifp, ether_input, NULL); 232 233 KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); 234 235 if_detach(ifp); 236 237 free(sc, M_DEVBUF, sizeof *sc); 238 return (0); 239 } 240 241 int 242 bridge_delete(struct bridge_softc *sc, struct bridge_iflist *bif) 243 { 244 int error; 245 246 if (bif->bif_flags & IFBIF_STP) 247 bstp_delete(bif->bif_stp); 248 249 bif->ifp->if_bridgeport = NULL; 250 error = ifpromisc(bif->ifp, 0); 251 hook_disestablish(bif->ifp->if_detachhooks, bif->bif_dhcookie); 252 253 if_ih_remove(bif->ifp, bridge_input, NULL); 254 bridge_rtdelete(sc, bif->ifp, 0); 255 bridge_flushrule(bif); 256 free(bif, M_DEVBUF, sizeof *bif); 257 258 return (error); 259 } 260 261 int 262 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 263 { 264 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc; 265 struct ifbreq *req = (struct ifbreq *)data; 266 struct ifbropreq *brop = (struct ifbropreq *)data; 267 struct ifnet *ifs; 268 struct bridge_iflist *bif; 269 struct bstp_port *bp; 270 struct bstp_state *bs = sc->sc_stp; 271 int error = 0; 272 273 switch (cmd) { 274 case SIOCBRDGADD: 275 /* bridge(4) does not distinguish between routing/forwarding ports */ 276 case SIOCBRDGADDL: 277 if ((error = suser(curproc)) != 0) 278 break; 279 280 ifs = ifunit(req->ifbr_ifsname); 281 282 /* try to create the interface if it does't exist */ 283 if (ifs == NULL && if_clone_create(req->ifbr_ifsname, 0) == 0) 284 ifs = ifunit(req->ifbr_ifsname); 285 286 if (ifs == NULL) { /* no such interface */ 287 error = ENOENT; 288 break; 289 } 290 291 if (ifs->if_bridgeport != NULL) { 292 bif = (struct bridge_iflist *)ifs->if_bridgeport; 293 if (bif->bridge_sc == sc) 294 error = EEXIST; 295 else 296 error = EBUSY; 297 break; 298 } 299 300 /* If it's in the span list, it can't be a member. */ 301 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { 302 if (bif->ifp == ifs) 303 break; 304 } 305 if (bif != NULL) { 306 error = EBUSY; 307 break; 308 } 309 310 if (ifs->if_type == IFT_ETHER) { 311 error = ifpromisc(ifs, 1); 312 if (error != 0) 313 break; 314 } 315 #if NMPW > 0 316 else if (ifs->if_type == IFT_MPLSTUNNEL) { 317 /* Nothing needed */ 318 } 319 #endif /* NMPW */ 320 else { 321 error = EINVAL; 322 break; 323 } 324 325 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO); 326 if (bif == NULL) { 327 if (ifs->if_type == IFT_ETHER) 328 ifpromisc(ifs, 0); 329 error = ENOMEM; 330 break; 331 } 332 333 bif->bridge_sc = sc; 334 bif->ifp = ifs; 335 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 336 SIMPLEQ_INIT(&bif->bif_brlin); 337 SIMPLEQ_INIT(&bif->bif_brlout); 338 ifs->if_bridgeport = (caddr_t)bif; 339 bif->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, 340 bridge_ifdetach, bif); 341 if_ih_insert(bif->ifp, bridge_input, NULL); 342 SLIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next); 343 break; 344 case SIOCBRDGDEL: 345 if ((error = suser(curproc)) != 0) 346 break; 347 ifs = ifunit(req->ifbr_ifsname); 348 if (ifs == NULL) { 349 error = ENOENT; 350 break; 351 } 352 bif = (struct bridge_iflist *)ifs->if_bridgeport; 353 if (bif == NULL || bif->bridge_sc != sc) { 354 error = ESRCH; 355 break; 356 } 357 error = bridge_ifremove(bif); 358 break; 359 case SIOCBRDGIFS: 360 error = bridge_bifconf(sc, (struct ifbifconf *)data); 361 break; 362 case SIOCBRDGADDS: 363 if ((error = suser(curproc)) != 0) 364 break; 365 ifs = ifunit(req->ifbr_ifsname); 366 if (ifs == NULL) { /* no such interface */ 367 error = ENOENT; 368 break; 369 } 370 if (ifs->if_type != IFT_ETHER && 371 ifs->if_type != IFT_MPLSTUNNEL) { 372 error = EINVAL; 373 break; 374 } 375 if (ifs->if_bridgeport != NULL) { 376 error = EBUSY; 377 break; 378 } 379 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { 380 if (bif->ifp == ifs) 381 break; 382 } 383 if (bif != NULL) { 384 error = EEXIST; 385 break; 386 } 387 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO); 388 if (bif == NULL) { 389 error = ENOMEM; 390 break; 391 } 392 bif->ifp = ifs; 393 bif->bif_flags = IFBIF_SPAN; 394 bif->bridge_sc = sc; 395 bif->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, 396 bridge_spandetach, bif); 397 SIMPLEQ_INIT(&bif->bif_brlin); 398 SIMPLEQ_INIT(&bif->bif_brlout); 399 SLIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next); 400 break; 401 case SIOCBRDGDELS: 402 if ((error = suser(curproc)) != 0) 403 break; 404 ifs = ifunit(req->ifbr_ifsname); 405 if (ifs == NULL) { 406 error = ENOENT; 407 break; 408 } 409 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { 410 if (bif->ifp == ifs) 411 break; 412 } 413 if (bif == NULL) { 414 error = ESRCH; 415 break; 416 } 417 bridge_spanremove(bif); 418 break; 419 case SIOCBRDGGIFFLGS: 420 ifs = ifunit(req->ifbr_ifsname); 421 if (ifs == NULL) { 422 error = ENOENT; 423 break; 424 } 425 bif = (struct bridge_iflist *)ifs->if_bridgeport; 426 if (bif == NULL || bif->bridge_sc != sc) { 427 error = ESRCH; 428 break; 429 } 430 req->ifbr_ifsflags = bif->bif_flags; 431 req->ifbr_portno = bif->ifp->if_index & 0xfff; 432 req->ifbr_protected = bif->bif_protected; 433 if (bif->bif_flags & IFBIF_STP) { 434 bp = bif->bif_stp; 435 req->ifbr_state = bstp_getstate(bs, bp); 436 req->ifbr_priority = bp->bp_priority; 437 req->ifbr_path_cost = bp->bp_path_cost; 438 req->ifbr_proto = bp->bp_protover; 439 req->ifbr_role = bp->bp_role; 440 req->ifbr_stpflags = bp->bp_flags; 441 req->ifbr_fwd_trans = bp->bp_forward_transitions; 442 req->ifbr_desg_bridge = bp->bp_desg_pv.pv_dbridge_id; 443 req->ifbr_desg_port = bp->bp_desg_pv.pv_dport_id; 444 req->ifbr_root_bridge = bp->bp_desg_pv.pv_root_id; 445 req->ifbr_root_cost = bp->bp_desg_pv.pv_cost; 446 req->ifbr_root_port = bp->bp_desg_pv.pv_port_id; 447 448 /* Copy STP state options as flags */ 449 if (bp->bp_operedge) 450 req->ifbr_ifsflags |= IFBIF_BSTP_EDGE; 451 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) 452 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; 453 if (bp->bp_ptp_link) 454 req->ifbr_ifsflags |= IFBIF_BSTP_PTP; 455 if (bp->bp_flags & BSTP_PORT_AUTOPTP) 456 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; 457 } 458 break; 459 case SIOCBRDGSIFFLGS: 460 if ((error = suser(curproc)) != 0) 461 break; 462 ifs = ifunit(req->ifbr_ifsname); 463 if (ifs == NULL) { 464 error = ENOENT; 465 break; 466 } 467 bif = (struct bridge_iflist *)ifs->if_bridgeport; 468 if (bif == NULL || bif->bridge_sc != sc) { 469 error = ESRCH; 470 break; 471 } 472 if (req->ifbr_ifsflags & IFBIF_RO_MASK) { 473 error = EINVAL; 474 break; 475 } 476 if (req->ifbr_ifsflags & IFBIF_STP) { 477 if ((bif->bif_flags & IFBIF_STP) == 0) { 478 /* Enable STP */ 479 if ((bif->bif_stp = bstp_add(sc->sc_stp, 480 bif->ifp)) == NULL) { 481 error = ENOMEM; 482 break; 483 } 484 } else { 485 /* Update STP flags */ 486 bstp_ifsflags(bif->bif_stp, req->ifbr_ifsflags); 487 } 488 } else if (bif->bif_flags & IFBIF_STP) { 489 bstp_delete(bif->bif_stp); 490 bif->bif_stp = NULL; 491 } 492 bif->bif_flags = req->ifbr_ifsflags; 493 break; 494 case SIOCSIFFLAGS: 495 if ((ifp->if_flags & IFF_UP) == IFF_UP) 496 bridge_init(sc); 497 498 if ((ifp->if_flags & IFF_UP) == 0) 499 bridge_stop(sc); 500 501 break; 502 case SIOCBRDGGPARAM: 503 if ((bp = bs->bs_root_port) == NULL) 504 brop->ifbop_root_port = 0; 505 else 506 brop->ifbop_root_port = bp->bp_ifp->if_index; 507 brop->ifbop_maxage = bs->bs_bridge_max_age >> 8; 508 brop->ifbop_hellotime = bs->bs_bridge_htime >> 8; 509 brop->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8; 510 brop->ifbop_holdcount = bs->bs_txholdcount; 511 brop->ifbop_priority = bs->bs_bridge_priority; 512 brop->ifbop_protocol = bs->bs_protover; 513 brop->ifbop_root_bridge = bs->bs_root_pv.pv_root_id; 514 brop->ifbop_root_path_cost = bs->bs_root_pv.pv_cost; 515 brop->ifbop_root_port = bs->bs_root_pv.pv_port_id; 516 brop->ifbop_desg_bridge = bs->bs_root_pv.pv_dbridge_id; 517 brop->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec; 518 brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec; 519 break; 520 case SIOCBRDGSIFPROT: 521 ifs = ifunit(req->ifbr_ifsname); 522 if (ifs == NULL) { 523 error = ENOENT; 524 break; 525 } 526 bif = (struct bridge_iflist *)ifs->if_bridgeport; 527 if (bif == NULL || bif->bridge_sc != sc) { 528 error = ESRCH; 529 break; 530 } 531 bif->bif_protected = req->ifbr_protected; 532 break; 533 case SIOCBRDGRTS: 534 case SIOCBRDGGCACHE: 535 case SIOCBRDGGPRI: 536 case SIOCBRDGGMA: 537 case SIOCBRDGGHT: 538 case SIOCBRDGGFD: 539 case SIOCBRDGGTO: 540 case SIOCBRDGGRL: 541 break; 542 case SIOCBRDGFLUSH: 543 case SIOCBRDGSADDR: 544 case SIOCBRDGDADDR: 545 case SIOCBRDGSCACHE: 546 case SIOCBRDGSTO: 547 case SIOCBRDGARL: 548 case SIOCBRDGFRL: 549 case SIOCBRDGSPRI: 550 case SIOCBRDGSFD: 551 case SIOCBRDGSMA: 552 case SIOCBRDGSHT: 553 case SIOCBRDGSTXHC: 554 case SIOCBRDGSPROTO: 555 case SIOCBRDGSIFPRIO: 556 case SIOCBRDGSIFCOST: 557 error = suser(curproc); 558 break; 559 default: 560 error = ENOTTY; 561 break; 562 } 563 564 if (!error) 565 error = bridgectl_ioctl(ifp, cmd, data); 566 567 if (!error) 568 error = bstp_ioctl(ifp, cmd, data); 569 570 return (error); 571 } 572 573 /* Detach an interface from a bridge. */ 574 int 575 bridge_ifremove(struct bridge_iflist *bif) 576 { 577 struct bridge_softc *sc = bif->bridge_sc; 578 579 SLIST_REMOVE(&sc->sc_iflist, bif, bridge_iflist, bif_next); 580 return (bridge_delete(sc, bif)); 581 } 582 583 void 584 bridge_spanremove(struct bridge_iflist *bif) 585 { 586 struct bridge_softc *sc = bif->bridge_sc; 587 588 SLIST_REMOVE(&sc->sc_spanlist, bif, bridge_iflist, bif_next); 589 hook_disestablish(bif->ifp->if_detachhooks, bif->bif_dhcookie); 590 free(bif, M_DEVBUF, sizeof(*bif)); 591 } 592 593 void 594 bridge_ifdetach(void *xbif) 595 { 596 struct bridge_iflist *bif = xbif; 597 598 bridge_ifremove(bif); 599 } 600 601 void 602 bridge_spandetach(void *xbif) 603 { 604 struct bridge_iflist *bif = xbif; 605 606 bridge_spanremove(bif); 607 } 608 609 int 610 bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc) 611 { 612 struct bridge_iflist *bif; 613 struct bstp_port *bp; 614 struct bstp_state *bs = sc->sc_stp; 615 u_int32_t total = 0, i = 0; 616 int error = 0; 617 struct ifbreq *breq, *breqs = NULL; 618 619 SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) 620 total++; 621 622 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) 623 total++; 624 625 if (bifc->ifbic_len == 0) { 626 i = total; 627 goto done; 628 } 629 630 breqs = mallocarray(total, sizeof(*breqs), M_TEMP, M_NOWAIT|M_ZERO); 631 if (breqs == NULL) 632 goto done; 633 634 SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 635 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs)) 636 break; 637 breq = &breqs[i]; 638 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 639 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ); 640 breq->ifbr_ifsflags = bif->bif_flags; 641 breq->ifbr_portno = bif->ifp->if_index & 0xfff; 642 breq->ifbr_protected = bif->bif_protected; 643 if (bif->bif_flags & IFBIF_STP) { 644 bp = bif->bif_stp; 645 breq->ifbr_state = bstp_getstate(sc->sc_stp, bp); 646 breq->ifbr_priority = bp->bp_priority; 647 breq->ifbr_path_cost = bp->bp_path_cost; 648 breq->ifbr_proto = bp->bp_protover; 649 breq->ifbr_role = bp->bp_role; 650 breq->ifbr_stpflags = bp->bp_flags; 651 breq->ifbr_fwd_trans = bp->bp_forward_transitions; 652 breq->ifbr_root_bridge = bs->bs_root_pv.pv_root_id; 653 breq->ifbr_root_cost = bs->bs_root_pv.pv_cost; 654 breq->ifbr_root_port = bs->bs_root_pv.pv_port_id; 655 breq->ifbr_desg_bridge = bs->bs_root_pv.pv_dbridge_id; 656 breq->ifbr_desg_port = bs->bs_root_pv.pv_dport_id; 657 658 /* Copy STP state options as flags */ 659 if (bp->bp_operedge) 660 breq->ifbr_ifsflags |= IFBIF_BSTP_EDGE; 661 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) 662 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; 663 if (bp->bp_ptp_link) 664 breq->ifbr_ifsflags |= IFBIF_BSTP_PTP; 665 if (bp->bp_flags & BSTP_PORT_AUTOPTP) 666 breq->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; 667 } 668 i++; 669 } 670 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { 671 if (bifc->ifbic_len < (i + 1) * sizeof(*breqs)) 672 break; 673 breq = &breqs[i]; 674 strlcpy(breq->ifbr_name, sc->sc_if.if_xname, IFNAMSIZ); 675 strlcpy(breq->ifbr_ifsname, bif->ifp->if_xname, IFNAMSIZ); 676 breq->ifbr_ifsflags = bif->bif_flags | IFBIF_SPAN; 677 breq->ifbr_portno = bif->ifp->if_index & 0xfff; 678 i++; 679 } 680 681 error = copyout(breqs, bifc->ifbic_req, i * sizeof(*breqs)); 682 done: 683 free(breqs, M_TEMP, total * sizeof(*breq)); 684 bifc->ifbic_len = i * sizeof(*breq); 685 return (error); 686 } 687 688 void 689 bridge_init(struct bridge_softc *sc) 690 { 691 struct ifnet *ifp = &sc->sc_if; 692 693 if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING) 694 return; 695 696 ifp->if_flags |= IFF_RUNNING; 697 bstp_initialization(sc->sc_stp); 698 699 if (sc->sc_brttimeout != 0) 700 timeout_add_sec(&sc->sc_brtimeout, sc->sc_brttimeout); 701 } 702 703 /* 704 * Stop the bridge and deallocate the routing table. 705 */ 706 void 707 bridge_stop(struct bridge_softc *sc) 708 { 709 struct ifnet *ifp = &sc->sc_if; 710 711 /* 712 * If we're not running, there's nothing to do. 713 */ 714 if ((ifp->if_flags & IFF_RUNNING) == 0) 715 return; 716 717 timeout_del(&sc->sc_brtimeout); 718 719 bridge_rtflush(sc, IFBF_FLUSHDYN); 720 721 ifp->if_flags &= ~IFF_RUNNING; 722 } 723 724 /* 725 * Send output from the bridge. The mbuf has the ethernet header 726 * already attached. We must enqueue or free the mbuf before exiting. 727 */ 728 int 729 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, 730 struct rtentry *rt) 731 { 732 struct bridge_iflist *bif; 733 struct ether_header *eh; 734 struct ifnet *dst_if = NULL; 735 struct bridge_softc *sc; 736 #if NBPFILTER > 0 737 caddr_t if_bpf; 738 #endif 739 int error; 740 741 KERNEL_ASSERT_LOCKED(); 742 743 if (m->m_len < sizeof(*eh)) { 744 m = m_pullup(m, sizeof(*eh)); 745 if (m == NULL) 746 return (ENOBUFS); 747 } 748 749 /* ifp must be a member interface of the bridge. */ 750 bif = (struct bridge_iflist *)ifp->if_bridgeport; 751 if (bif == NULL) { 752 m_freem(m); 753 return (EINVAL); 754 } 755 756 /* 757 * If bridge is down, but original output interface is up, 758 * go ahead and send out that interface. Otherwise the packet 759 * is dropped below. 760 */ 761 sc = bif->bridge_sc; 762 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) { 763 dst_if = ifp; 764 goto sendunicast; 765 } 766 767 #if NBPFILTER > 0 768 if_bpf = sc->sc_if.if_bpf; 769 if (if_bpf) 770 bpf_mtap(if_bpf, m, BPF_DIRECTION_OUT); 771 #endif 772 ifp->if_opackets++; 773 ifp->if_obytes += m->m_pkthdr.len; 774 775 bridge_span(sc, m); 776 777 eh = mtod(m, struct ether_header *); 778 if (!ETHER_IS_MULTICAST(eh->ether_dhost)) { 779 struct bridge_rtnode *dst_p; 780 struct bridge_tunneltag *brtag; 781 struct ether_addr *dst; 782 783 dst = (struct ether_addr *)&eh->ether_dhost[0]; 784 if ((dst_p = bridge_rtlookup(sc, dst)) != NULL) { 785 dst_if = dst_p->brt_if; 786 if ((dst_p->brt_family != AF_UNSPEC) && 787 ((brtag = bridge_tunneltag(m)) != NULL)) 788 bridge_copytag(&dst_p->brt_tunnel, brtag); 789 } 790 } 791 792 /* 793 * If the packet is a broadcast or we don't know a better way to 794 * get there, send to all interfaces. 795 */ 796 if (dst_if == NULL) { 797 struct bridge_iflist *bif, *bif0; 798 struct mbuf *mc; 799 int used = 0; 800 801 SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 802 dst_if = bif->ifp; 803 if ((dst_if->if_flags & IFF_RUNNING) == 0) 804 continue; 805 806 /* 807 * If this is not the original output interface, 808 * and the interface is participating in spanning 809 * tree, make sure the port is in a state that 810 * allows forwarding. 811 */ 812 if (dst_if != ifp && 813 (bif->bif_flags & IFBIF_STP) && 814 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) 815 continue; 816 #if NMPW > 0 817 /* 818 * Split horizon: avoid broadcasting messages from 819 * wire to another wire. 820 */ 821 if (ifp->if_type == IFT_MPLSTUNNEL && 822 dst_if->if_type == IFT_MPLSTUNNEL) 823 continue; 824 #endif /* NMPW */ 825 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && 826 (m->m_flags & (M_BCAST | M_MCAST)) == 0) 827 continue; 828 829 if (SLIST_NEXT(bif, bif_next) == NULL) { 830 used = 1; 831 mc = m; 832 } else { 833 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT); 834 if (mc == NULL) { 835 sc->sc_if.if_oerrors++; 836 continue; 837 } 838 } 839 840 bif0 = (struct bridge_iflist *)dst_if->if_bridgeport; 841 KASSERT(bif0 != NULL); 842 if (bridge_filterrule(&bif0->bif_brlout, eh, mc) == 843 BRL_ACTION_BLOCK) 844 continue; 845 846 error = bridge_ifenqueue(&sc->sc_if, dst_if, mc); 847 if (error) 848 continue; 849 } 850 if (!used) 851 m_freem(m); 852 return (0); 853 } 854 855 sendunicast: 856 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 857 m_freem(m); 858 return (ENETDOWN); 859 } 860 bridge_ifenqueue(&sc->sc_if, dst_if, m); 861 return (0); 862 } 863 864 /* 865 * Loop through each bridge interface and process their input queues. 866 */ 867 void 868 bridgeintr(void) 869 { 870 struct mbuf_list ml; 871 struct mbuf *m; 872 struct ifnet *ifp; 873 874 niq_delist(&bridgeintrq, &ml); 875 if (ml_empty(&ml)) 876 return; 877 878 KERNEL_LOCK(); 879 while ((m = ml_dequeue(&ml)) != NULL) { 880 881 ifp = if_get(m->m_pkthdr.ph_ifidx); 882 if (ifp == NULL) { 883 m_freem(m); 884 continue; 885 } 886 887 bridge_process(ifp, m); 888 889 if_put(ifp); 890 } 891 KERNEL_UNLOCK(); 892 } 893 894 /* 895 * Process a single frame. Frame must be freed or queued before returning. 896 */ 897 void 898 bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m) 899 { 900 struct ifnet *dst_if = NULL; 901 struct bridge_iflist *bif; 902 struct ether_addr *dst, *src; 903 struct ether_header eh; 904 u_int32_t protected; 905 int len; 906 907 908 sc->sc_if.if_ipackets++; 909 sc->sc_if.if_ibytes += m->m_pkthdr.len; 910 911 bif = (struct bridge_iflist *)src_if->if_bridgeport; 912 KASSERT(bif != NULL); 913 914 if (m->m_pkthdr.len < sizeof(eh)) { 915 m_freem(m); 916 return; 917 } 918 m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&eh); 919 dst = (struct ether_addr *)&eh.ether_dhost[0]; 920 src = (struct ether_addr *)&eh.ether_shost[0]; 921 922 /* 923 * If interface is learning, and if source address 924 * is not broadcast or multicast, record its address. 925 */ 926 if ((bif->bif_flags & IFBIF_LEARNING) && 927 (eh.ether_shost[0] & 1) == 0 && 928 !(eh.ether_shost[0] == 0 && eh.ether_shost[1] == 0 && 929 eh.ether_shost[2] == 0 && eh.ether_shost[3] == 0 && 930 eh.ether_shost[4] == 0 && eh.ether_shost[5] == 0)) 931 bridge_rtupdate(sc, src, src_if, 0, IFBAF_DYNAMIC, m); 932 933 if ((bif->bif_flags & IFBIF_STP) && 934 (bif->bif_state == BSTP_IFSTATE_LEARNING)) { 935 m_freem(m); 936 return; 937 } 938 939 /* 940 * At this point, the port either doesn't participate in stp or 941 * it's in the forwarding state 942 */ 943 944 /* 945 * If packet is unicast, destined for someone on "this" 946 * side of the bridge, drop it. 947 */ 948 if (!ETHER_IS_MULTICAST(eh.ether_dhost)) { 949 struct bridge_rtnode *dst_p; 950 951 if ((dst_p = bridge_rtlookup(sc, dst)) != NULL) 952 dst_if = dst_p->brt_if; 953 if (dst_if == src_if) { 954 m_freem(m); 955 return; 956 } 957 } else { 958 if (memcmp(etherbroadcastaddr, eh.ether_dhost, 959 sizeof(etherbroadcastaddr)) == 0) 960 m->m_flags |= M_BCAST; 961 else 962 m->m_flags |= M_MCAST; 963 } 964 965 /* 966 * Multicast packets get handled a little differently: 967 * If interface is: 968 * -link0,-link1 (default) Forward all multicast 969 * as broadcast. 970 * -link0,link1 Drop non-IP multicast, forward 971 * as broadcast IP multicast. 972 * link0,-link1 Drop IP multicast, forward as 973 * broadcast non-IP multicast. 974 * link0,link1 Drop all multicast. 975 */ 976 if (m->m_flags & M_MCAST) { 977 if ((sc->sc_if.if_flags & 978 (IFF_LINK0 | IFF_LINK1)) == 979 (IFF_LINK0 | IFF_LINK1)) { 980 m_freem(m); 981 return; 982 } 983 if (sc->sc_if.if_flags & IFF_LINK0 && 984 ETHERADDR_IS_IP_MCAST(dst)) { 985 m_freem(m); 986 return; 987 } 988 if (sc->sc_if.if_flags & IFF_LINK1 && 989 !ETHERADDR_IS_IP_MCAST(dst)) { 990 m_freem(m); 991 return; 992 } 993 } 994 995 if (bif->bif_flags & IFBIF_BLOCKNONIP && bridge_blocknonip(&eh, m)) { 996 m_freem(m); 997 return; 998 } 999 1000 if (bridge_filterrule(&bif->bif_brlin, &eh, m) == BRL_ACTION_BLOCK) { 1001 m_freem(m); 1002 return; 1003 } 1004 m = bridge_ip(&sc->sc_if, BRIDGE_IN, src_if, &eh, m); 1005 if (m == NULL) 1006 return; 1007 /* 1008 * If the packet is a multicast or broadcast OR if we don't 1009 * know any better, forward it to all interfaces. 1010 */ 1011 if ((m->m_flags & (M_BCAST | M_MCAST)) || dst_if == NULL) { 1012 sc->sc_if.if_imcasts++; 1013 bridge_broadcast(sc, src_if, &eh, m); 1014 return; 1015 } 1016 protected = bif->bif_protected; 1017 1018 /* 1019 * At this point, we're dealing with a unicast frame going to a 1020 * different interface 1021 */ 1022 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1023 m_freem(m); 1024 return; 1025 } 1026 bif = (struct bridge_iflist *)dst_if->if_bridgeport; 1027 if ((bif->bif_flags & IFBIF_STP) && 1028 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) { 1029 m_freem(m); 1030 return; 1031 } 1032 /* 1033 * Do not transmit if both ports are part of the same protected 1034 * domain. 1035 */ 1036 if (protected != 0 && (protected & bif->bif_protected)) { 1037 m_freem(m); 1038 return; 1039 } 1040 if (bridge_filterrule(&bif->bif_brlout, &eh, m) == BRL_ACTION_BLOCK) { 1041 m_freem(m); 1042 return; 1043 } 1044 m = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, &eh, m); 1045 if (m == NULL) 1046 return; 1047 1048 len = m->m_pkthdr.len; 1049 #if NVLAN > 0 1050 if ((m->m_flags & M_VLANTAG) && 1051 (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0) 1052 len += ETHER_VLAN_ENCAP_LEN; 1053 #endif 1054 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu) 1055 bridge_fragment(&sc->sc_if, dst_if, &eh, m); 1056 else { 1057 bridge_ifenqueue(&sc->sc_if, dst_if, m); 1058 } 1059 } 1060 1061 /* 1062 * Return 1 if `ena' belongs to `bif', 0 otherwise. 1063 */ 1064 int 1065 bridge_ourether(struct ifnet *ifp, uint8_t *ena) 1066 { 1067 struct arpcom *ac = (struct arpcom *)ifp; 1068 1069 if (memcmp(ac->ac_enaddr, ena, ETHER_ADDR_LEN) == 0) 1070 return (1); 1071 1072 #if NCARP > 0 1073 if (carp_ourether(ifp, ena)) 1074 return (1); 1075 #endif 1076 1077 return (0); 1078 } 1079 1080 /* 1081 * Receive input from an interface. Queue the packet for bridging if its 1082 * not for us, and schedule an interrupt. 1083 */ 1084 int 1085 bridge_input(struct ifnet *ifp, struct mbuf *m, void *cookie) 1086 { 1087 KASSERT(m->m_flags & M_PKTHDR); 1088 1089 if (m->m_flags & M_PROTO1) { 1090 m->m_flags &= ~M_PROTO1; 1091 return (0); 1092 } 1093 1094 niq_enqueue(&bridgeintrq, m); 1095 1096 return (1); 1097 } 1098 1099 void 1100 bridge_process(struct ifnet *ifp, struct mbuf *m) 1101 { 1102 struct bridge_softc *sc; 1103 struct bridge_iflist *bif, *bif0; 1104 struct ether_header *eh; 1105 struct mbuf *mc; 1106 #if NBPFILTER > 0 1107 caddr_t if_bpf; 1108 #endif 1109 1110 KERNEL_ASSERT_LOCKED(); 1111 1112 bif = (struct bridge_iflist *)ifp->if_bridgeport; 1113 if (bif == NULL) 1114 goto reenqueue; 1115 1116 sc = bif->bridge_sc; 1117 if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 1118 goto reenqueue; 1119 1120 #if NVLAN > 0 1121 /* 1122 * If the underlying interface removed the VLAN header itself, 1123 * add it back. 1124 */ 1125 if (ISSET(m->m_flags, M_VLANTAG)) { 1126 m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag); 1127 if (m == NULL) 1128 return; 1129 } 1130 #endif 1131 1132 #if NBPFILTER > 0 1133 if_bpf = sc->sc_if.if_bpf; 1134 if (if_bpf) 1135 bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN); 1136 #endif 1137 1138 bridge_span(sc, m); 1139 1140 eh = mtod(m, struct ether_header *); 1141 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1142 /* 1143 * Reserved destination MAC addresses (01:80:C2:00:00:0x) 1144 * should not be forwarded to bridge members according to 1145 * section 7.12.6 of the 802.1D-2004 specification. The 1146 * STP destination address (as stored in bstp_etheraddr) 1147 * is the first of these. 1148 */ 1149 if (memcmp(eh->ether_dhost, bstp_etheraddr, 1150 ETHER_ADDR_LEN - 1) == 0) { 1151 if (eh->ether_dhost[ETHER_ADDR_LEN - 1] == 0) { 1152 /* STP traffic */ 1153 if ((m = bstp_input(sc->sc_stp, bif->bif_stp, 1154 eh, m)) == NULL) 1155 return; 1156 } else if (eh->ether_dhost[ETHER_ADDR_LEN - 1] <= 0xf) { 1157 m_freem(m); 1158 return; 1159 } 1160 } 1161 1162 /* 1163 * No need to process frames for ifs in the discarding state 1164 */ 1165 if ((bif->bif_flags & IFBIF_STP) && 1166 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) 1167 goto reenqueue; 1168 1169 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT); 1170 if (mc == NULL) 1171 goto reenqueue; 1172 1173 bridge_ifinput(ifp, mc); 1174 1175 bridgeintr_frame(sc, ifp, m); 1176 return; 1177 } 1178 1179 /* 1180 * No need to queue frames for ifs in the discarding state 1181 */ 1182 if ((bif->bif_flags & IFBIF_STP) && 1183 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) 1184 goto reenqueue; 1185 1186 /* 1187 * Unicast, make sure it's not for us. 1188 */ 1189 bif0 = bif; 1190 SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1191 if (bif->ifp->if_type != IFT_ETHER) 1192 continue; 1193 if (bridge_ourether(bif->ifp, eh->ether_dhost)) { 1194 if (bif0->bif_flags & IFBIF_LEARNING) 1195 bridge_rtupdate(sc, 1196 (struct ether_addr *)&eh->ether_shost, 1197 ifp, 0, IFBAF_DYNAMIC, m); 1198 if (bridge_filterrule(&bif0->bif_brlin, eh, m) == 1199 BRL_ACTION_BLOCK) { 1200 m_freem(m); 1201 return; 1202 } 1203 1204 /* Count for the bridge */ 1205 sc->sc_if.if_ipackets++; 1206 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1207 1208 bridge_ifinput(bif->ifp, m); 1209 return; 1210 } 1211 if (bridge_ourether(bif->ifp, eh->ether_shost)) { 1212 m_freem(m); 1213 return; 1214 } 1215 } 1216 1217 bridgeintr_frame(sc, ifp, m); 1218 return; 1219 1220 reenqueue: 1221 bridge_ifinput(ifp, m); 1222 } 1223 1224 /* 1225 * Send a frame to all interfaces that are members of the bridge 1226 * (except the one it came in on). 1227 */ 1228 void 1229 bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp, 1230 struct ether_header *eh, struct mbuf *m) 1231 { 1232 struct bridge_iflist *bif; 1233 struct mbuf *mc; 1234 struct ifnet *dst_if; 1235 int len, used = 0; 1236 u_int32_t protected; 1237 1238 bif = (struct bridge_iflist *)ifp->if_bridgeport; 1239 protected = bif->bif_protected; 1240 1241 SLIST_FOREACH(bif, &sc->sc_iflist, bif_next) { 1242 dst_if = bif->ifp; 1243 1244 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1245 continue; 1246 1247 if ((bif->bif_flags & IFBIF_STP) && 1248 (bif->bif_state == BSTP_IFSTATE_DISCARDING)) 1249 continue; 1250 1251 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && 1252 (m->m_flags & (M_BCAST | M_MCAST)) == 0) 1253 continue; 1254 1255 /* Drop non-IP frames if the appropriate flag is set. */ 1256 if (bif->bif_flags & IFBIF_BLOCKNONIP && 1257 bridge_blocknonip(eh, m)) 1258 continue; 1259 1260 /* 1261 * Do not transmit if both ports are part of the same 1262 * protected domain. 1263 */ 1264 if (protected != 0 && (protected & bif->bif_protected)) 1265 continue; 1266 1267 if (bridge_filterrule(&bif->bif_brlout, eh, m) == BRL_ACTION_BLOCK) 1268 continue; 1269 1270 /* 1271 * Don't retransmit out of the same interface where 1272 * the packet was received from. 1273 */ 1274 if (dst_if->if_index == ifp->if_index) 1275 continue; 1276 1277 if (bridge_localbroadcast(dst_if, eh, m)) 1278 sc->sc_if.if_oerrors++; 1279 1280 #if NMPW > 0 1281 /* 1282 * Split horizon: avoid broadcasting messages from wire to 1283 * another wire. 1284 */ 1285 if (ifp->if_type == IFT_MPLSTUNNEL && 1286 dst_if->if_type == IFT_MPLSTUNNEL) 1287 continue; 1288 #endif /* NMPW */ 1289 1290 /* If last one, reuse the passed-in mbuf */ 1291 if (SLIST_NEXT(bif, bif_next) == NULL) { 1292 mc = m; 1293 used = 1; 1294 } else { 1295 mc = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT); 1296 if (mc == NULL) { 1297 sc->sc_if.if_oerrors++; 1298 continue; 1299 } 1300 } 1301 1302 mc = bridge_ip(&sc->sc_if, BRIDGE_OUT, dst_if, eh, mc); 1303 if (mc == NULL) 1304 continue; 1305 1306 len = mc->m_pkthdr.len; 1307 #if NVLAN > 0 1308 if ((mc->m_flags & M_VLANTAG) && 1309 (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0) 1310 len += ETHER_VLAN_ENCAP_LEN; 1311 #endif 1312 if ((len - ETHER_HDR_LEN) > dst_if->if_mtu) 1313 bridge_fragment(&sc->sc_if, dst_if, eh, mc); 1314 else { 1315 bridge_ifenqueue(&sc->sc_if, dst_if, mc); 1316 } 1317 } 1318 1319 if (!used) 1320 m_freem(m); 1321 } 1322 1323 int 1324 bridge_localbroadcast(struct ifnet *ifp, struct ether_header *eh, 1325 struct mbuf *m) 1326 { 1327 struct mbuf *m1; 1328 u_int16_t etype; 1329 1330 /* 1331 * quick optimisation, don't send packets up the stack if no 1332 * corresponding address has been specified. 1333 */ 1334 etype = ntohs(eh->ether_type); 1335 if (!(m->m_flags & M_VLANTAG) && etype == ETHERTYPE_IP) { 1336 struct ifaddr *ifa; 1337 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1338 if (ifa->ifa_addr->sa_family == AF_INET) 1339 break; 1340 } 1341 if (ifa == NULL) 1342 return (0); 1343 } 1344 1345 m1 = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT); 1346 if (m1 == NULL) 1347 return (1); 1348 1349 #if NPF > 0 1350 pf_pkt_addr_changed(m1); 1351 #endif /* NPF */ 1352 1353 bridge_ifinput(ifp, m1); 1354 1355 return (0); 1356 } 1357 1358 void 1359 bridge_span(struct bridge_softc *sc, struct mbuf *m) 1360 { 1361 struct bridge_iflist *bif; 1362 struct ifnet *ifp; 1363 struct mbuf *mc; 1364 int error; 1365 1366 SLIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { 1367 ifp = bif->ifp; 1368 1369 if ((ifp->if_flags & IFF_RUNNING) == 0) 1370 continue; 1371 1372 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1373 if (mc == NULL) { 1374 sc->sc_if.if_oerrors++; 1375 continue; 1376 } 1377 1378 error = bridge_ifenqueue(&sc->sc_if, ifp, mc); 1379 if (error) 1380 continue; 1381 } 1382 } 1383 1384 /* 1385 * Block non-ip frames: 1386 * Returns 0 if frame is ip, and 1 if it should be dropped. 1387 */ 1388 int 1389 bridge_blocknonip(struct ether_header *eh, struct mbuf *m) 1390 { 1391 struct llc llc; 1392 u_int16_t etype; 1393 1394 if (m->m_pkthdr.len < ETHER_HDR_LEN) 1395 return (1); 1396 1397 #if NVLAN > 0 1398 if (m->m_flags & M_VLANTAG) 1399 return (1); 1400 #endif 1401 1402 etype = ntohs(eh->ether_type); 1403 switch (etype) { 1404 case ETHERTYPE_ARP: 1405 case ETHERTYPE_REVARP: 1406 case ETHERTYPE_IP: 1407 case ETHERTYPE_IPV6: 1408 return (0); 1409 } 1410 1411 if (etype > ETHERMTU) 1412 return (1); 1413 1414 if (m->m_pkthdr.len < 1415 (ETHER_HDR_LEN + LLC_SNAPFRAMELEN)) 1416 return (1); 1417 1418 m_copydata(m, ETHER_HDR_LEN, LLC_SNAPFRAMELEN, 1419 (caddr_t)&llc); 1420 1421 etype = ntohs(llc.llc_snap.ether_type); 1422 if (llc.llc_dsap == LLC_SNAP_LSAP && 1423 llc.llc_ssap == LLC_SNAP_LSAP && 1424 llc.llc_control == LLC_UI && 1425 llc.llc_snap.org_code[0] == 0 && 1426 llc.llc_snap.org_code[1] == 0 && 1427 llc.llc_snap.org_code[2] == 0 && 1428 (etype == ETHERTYPE_ARP || etype == ETHERTYPE_REVARP || 1429 etype == ETHERTYPE_IP || etype == ETHERTYPE_IPV6)) { 1430 return (0); 1431 } 1432 1433 return (1); 1434 } 1435 1436 #ifdef IPSEC 1437 int 1438 bridge_ipsec(struct ifnet *ifp, struct ether_header *eh, int hassnap, 1439 struct llc *llc, int dir, int af, int hlen, struct mbuf *m) 1440 { 1441 union sockaddr_union dst; 1442 struct tdb *tdb; 1443 u_int32_t spi; 1444 u_int16_t cpi; 1445 int error, off; 1446 u_int8_t proto = 0; 1447 struct ip *ip; 1448 #ifdef INET6 1449 struct ip6_hdr *ip6; 1450 #endif /* INET6 */ 1451 #if NPF > 0 1452 struct ifnet *encif; 1453 #endif 1454 1455 if (dir == BRIDGE_IN) { 1456 switch (af) { 1457 case AF_INET: 1458 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t)) 1459 goto skiplookup; 1460 1461 ip = mtod(m, struct ip *); 1462 proto = ip->ip_p; 1463 off = offsetof(struct ip, ip_p); 1464 1465 if (proto != IPPROTO_ESP && proto != IPPROTO_AH && 1466 proto != IPPROTO_IPCOMP) 1467 goto skiplookup; 1468 1469 bzero(&dst, sizeof(union sockaddr_union)); 1470 dst.sa.sa_family = AF_INET; 1471 dst.sin.sin_len = sizeof(struct sockaddr_in); 1472 m_copydata(m, offsetof(struct ip, ip_dst), 1473 sizeof(struct in_addr), 1474 (caddr_t)&dst.sin.sin_addr); 1475 1476 break; 1477 #ifdef INET6 1478 case AF_INET6: 1479 if (m->m_pkthdr.len - hlen < 2 * sizeof(u_int32_t)) 1480 goto skiplookup; 1481 1482 ip6 = mtod(m, struct ip6_hdr *); 1483 1484 /* XXX We should chase down the header chain */ 1485 proto = ip6->ip6_nxt; 1486 off = offsetof(struct ip6_hdr, ip6_nxt); 1487 1488 if (proto != IPPROTO_ESP && proto != IPPROTO_AH && 1489 proto != IPPROTO_IPCOMP) 1490 goto skiplookup; 1491 1492 bzero(&dst, sizeof(union sockaddr_union)); 1493 dst.sa.sa_family = AF_INET6; 1494 dst.sin6.sin6_len = sizeof(struct sockaddr_in6); 1495 m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt), 1496 sizeof(struct in6_addr), 1497 (caddr_t)&dst.sin6.sin6_addr); 1498 1499 break; 1500 #endif /* INET6 */ 1501 default: 1502 return (0); 1503 } 1504 1505 switch (proto) { 1506 case IPPROTO_ESP: 1507 m_copydata(m, hlen, sizeof(u_int32_t), (caddr_t)&spi); 1508 break; 1509 case IPPROTO_AH: 1510 m_copydata(m, hlen + sizeof(u_int32_t), 1511 sizeof(u_int32_t), (caddr_t)&spi); 1512 break; 1513 case IPPROTO_IPCOMP: 1514 m_copydata(m, hlen + sizeof(u_int16_t), 1515 sizeof(u_int16_t), (caddr_t)&cpi); 1516 spi = ntohl(htons(cpi)); 1517 break; 1518 } 1519 1520 NET_ASSERT_LOCKED(); 1521 1522 tdb = gettdb(ifp->if_rdomain, spi, &dst, proto); 1523 if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 && 1524 tdb->tdb_xform != NULL) { 1525 if (tdb->tdb_first_use == 0) { 1526 tdb->tdb_first_use = time_second; 1527 if (tdb->tdb_flags & TDBF_FIRSTUSE) 1528 timeout_add_sec(&tdb->tdb_first_tmo, 1529 tdb->tdb_exp_first_use); 1530 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE) 1531 timeout_add_sec(&tdb->tdb_sfirst_tmo, 1532 tdb->tdb_soft_first_use); 1533 } 1534 1535 (*(tdb->tdb_xform->xf_input))(m, tdb, hlen, off); 1536 return (1); 1537 } else { 1538 skiplookup: 1539 /* XXX do an input policy lookup */ 1540 return (0); 1541 } 1542 } else { /* Outgoing from the bridge. */ 1543 tdb = ipsp_spd_lookup(m, af, hlen, &error, 1544 IPSP_DIRECTION_OUT, NULL, NULL, 0); 1545 if (tdb != NULL) { 1546 /* 1547 * We don't need to do loop detection, the 1548 * bridge will do that for us. 1549 */ 1550 #if NPF > 0 1551 if ((encif = enc_getif(tdb->tdb_rdomain, 1552 tdb->tdb_tap)) == NULL || 1553 pf_test(af, dir, encif, &m) != PF_PASS) { 1554 m_freem(m); 1555 return (1); 1556 } 1557 if (m == NULL) 1558 return (1); 1559 else if (af == AF_INET) 1560 in_proto_cksum_out(m, encif); 1561 #ifdef INET6 1562 else if (af == AF_INET6) 1563 in6_proto_cksum_out(m, encif); 1564 #endif /* INET6 */ 1565 #endif /* NPF */ 1566 1567 ip = mtod(m, struct ip *); 1568 if ((af == AF_INET) && 1569 ip_mtudisc && (ip->ip_off & htons(IP_DF)) && 1570 tdb->tdb_mtu && ntohs(ip->ip_len) > tdb->tdb_mtu && 1571 tdb->tdb_mtutimeout > time_second) 1572 bridge_send_icmp_err(ifp, eh, m, 1573 hassnap, llc, tdb->tdb_mtu, 1574 ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG); 1575 else 1576 error = ipsp_process_packet(m, tdb, af, 0); 1577 return (1); 1578 } else 1579 return (0); 1580 } 1581 1582 return (0); 1583 } 1584 #endif /* IPSEC */ 1585 1586 /* 1587 * Filter IP packets by peeking into the ethernet frame. This violates 1588 * the ISO model, but allows us to act as a IP filter at the data link 1589 * layer. As a result, most of this code will look familiar to those 1590 * who've read net/if_ethersubr.c and netinet/ip_input.c 1591 */ 1592 struct mbuf * 1593 bridge_ip(struct ifnet *brifp, int dir, struct ifnet *ifp, 1594 struct ether_header *eh, struct mbuf *m) 1595 { 1596 struct llc llc; 1597 int hassnap = 0; 1598 struct ip *ip; 1599 int hlen; 1600 u_int16_t etype; 1601 1602 #if NVLAN > 0 1603 if (m->m_flags & M_VLANTAG) 1604 return (m); 1605 #endif 1606 1607 etype = ntohs(eh->ether_type); 1608 1609 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) { 1610 if (etype > ETHERMTU || 1611 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 1612 ETHER_HDR_LEN)) 1613 return (m); 1614 1615 m_copydata(m, ETHER_HDR_LEN, 1616 LLC_SNAPFRAMELEN, (caddr_t)&llc); 1617 1618 if (llc.llc_dsap != LLC_SNAP_LSAP || 1619 llc.llc_ssap != LLC_SNAP_LSAP || 1620 llc.llc_control != LLC_UI || 1621 llc.llc_snap.org_code[0] || 1622 llc.llc_snap.org_code[1] || 1623 llc.llc_snap.org_code[2]) 1624 return (m); 1625 1626 etype = ntohs(llc.llc_snap.ether_type); 1627 if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) 1628 return (m); 1629 hassnap = 1; 1630 } 1631 1632 m_adj(m, ETHER_HDR_LEN); 1633 if (hassnap) 1634 m_adj(m, LLC_SNAPFRAMELEN); 1635 1636 switch (etype) { 1637 1638 case ETHERTYPE_IP: 1639 if (m->m_pkthdr.len < sizeof(struct ip)) 1640 goto dropit; 1641 1642 /* Copy minimal header, and drop invalids */ 1643 if (m->m_len < sizeof(struct ip) && 1644 (m = m_pullup(m, sizeof(struct ip))) == NULL) { 1645 ipstat_inc(ips_toosmall); 1646 return (NULL); 1647 } 1648 ip = mtod(m, struct ip *); 1649 1650 if (ip->ip_v != IPVERSION) { 1651 ipstat_inc(ips_badvers); 1652 goto dropit; 1653 } 1654 1655 hlen = ip->ip_hl << 2; /* get whole header length */ 1656 if (hlen < sizeof(struct ip)) { 1657 ipstat_inc(ips_badhlen); 1658 goto dropit; 1659 } 1660 1661 if (hlen > m->m_len) { 1662 if ((m = m_pullup(m, hlen)) == NULL) { 1663 ipstat_inc(ips_badhlen); 1664 return (NULL); 1665 } 1666 ip = mtod(m, struct ip *); 1667 } 1668 1669 if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) { 1670 if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) { 1671 ipstat_inc(ips_badsum); 1672 goto dropit; 1673 } 1674 1675 ipstat_inc(ips_inswcsum); 1676 if (in_cksum(m, hlen) != 0) { 1677 ipstat_inc(ips_badsum); 1678 goto dropit; 1679 } 1680 } 1681 1682 if (ntohs(ip->ip_len) < hlen) 1683 goto dropit; 1684 1685 if (m->m_pkthdr.len < ntohs(ip->ip_len)) 1686 goto dropit; 1687 if (m->m_pkthdr.len > ntohs(ip->ip_len)) { 1688 if (m->m_len == m->m_pkthdr.len) { 1689 m->m_len = ntohs(ip->ip_len); 1690 m->m_pkthdr.len = ntohs(ip->ip_len); 1691 } else 1692 m_adj(m, ntohs(ip->ip_len) - m->m_pkthdr.len); 1693 } 1694 1695 #ifdef IPSEC 1696 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 && 1697 bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET, hlen, m)) 1698 return (NULL); 1699 #endif /* IPSEC */ 1700 #if NPF > 0 1701 /* Finally, we get to filter the packet! */ 1702 if (pf_test(AF_INET, dir, ifp, &m) != PF_PASS) 1703 goto dropit; 1704 if (m == NULL) 1705 goto dropit; 1706 #endif /* NPF > 0 */ 1707 1708 /* Rebuild the IP header */ 1709 if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL)) 1710 return (NULL); 1711 if (m->m_len < sizeof(struct ip)) 1712 goto dropit; 1713 in_proto_cksum_out(m, ifp); 1714 ip = mtod(m, struct ip *); 1715 ip->ip_sum = 0; 1716 if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4)) 1717 m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 1718 else { 1719 ipstat_inc(ips_outswcsum); 1720 ip->ip_sum = in_cksum(m, hlen); 1721 } 1722 1723 break; 1724 1725 #ifdef INET6 1726 case ETHERTYPE_IPV6: { 1727 struct ip6_hdr *ip6; 1728 1729 if (m->m_len < sizeof(struct ip6_hdr)) { 1730 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) 1731 == NULL) { 1732 ip6stat_inc(ip6s_toosmall); 1733 return (NULL); 1734 } 1735 } 1736 1737 ip6 = mtod(m, struct ip6_hdr *); 1738 1739 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 1740 ip6stat_inc(ip6s_badvers); 1741 goto dropit; 1742 } 1743 1744 #ifdef IPSEC 1745 hlen = sizeof(struct ip6_hdr); 1746 1747 if ((brifp->if_flags & IFF_LINK2) == IFF_LINK2 && 1748 bridge_ipsec(ifp, eh, hassnap, &llc, dir, AF_INET6, hlen, 1749 m)) 1750 return (NULL); 1751 #endif /* IPSEC */ 1752 1753 #if NPF > 0 1754 if (pf_test(AF_INET6, dir, ifp, &m) != PF_PASS) 1755 goto dropit; 1756 if (m == NULL) 1757 return (NULL); 1758 #endif /* NPF > 0 */ 1759 in6_proto_cksum_out(m, ifp); 1760 1761 break; 1762 } 1763 #endif /* INET6 */ 1764 1765 default: 1766 goto dropit; 1767 break; 1768 } 1769 1770 /* Reattach SNAP header */ 1771 if (hassnap) { 1772 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 1773 if (m == NULL) 1774 goto dropit; 1775 bcopy(&llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 1776 } 1777 1778 /* Reattach ethernet header */ 1779 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 1780 if (m == NULL) 1781 goto dropit; 1782 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 1783 1784 return (m); 1785 1786 dropit: 1787 m_freem(m); 1788 return (NULL); 1789 } 1790 1791 void 1792 bridge_fragment(struct ifnet *brifp, struct ifnet *ifp, struct ether_header *eh, 1793 struct mbuf *m) 1794 { 1795 struct llc llc; 1796 struct mbuf *m0; 1797 int error = 0; 1798 int hassnap = 0; 1799 u_int16_t etype; 1800 struct ip *ip; 1801 1802 etype = ntohs(eh->ether_type); 1803 #if NVLAN > 0 1804 if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN || 1805 etype == ETHERTYPE_QINQ) { 1806 int len = m->m_pkthdr.len; 1807 1808 if (m->m_flags & M_VLANTAG) 1809 len += ETHER_VLAN_ENCAP_LEN; 1810 if ((ifp->if_capabilities & IFCAP_VLAN_MTU) && 1811 (len - sizeof(struct ether_vlan_header) <= ifp->if_mtu)) { 1812 bridge_ifenqueue(brifp, ifp, m); 1813 return; 1814 } 1815 goto dropit; 1816 } 1817 #endif 1818 if (etype != ETHERTYPE_IP) { 1819 if (etype > ETHERMTU || 1820 m->m_pkthdr.len < (LLC_SNAPFRAMELEN + 1821 ETHER_HDR_LEN)) 1822 goto dropit; 1823 1824 m_copydata(m, ETHER_HDR_LEN, 1825 LLC_SNAPFRAMELEN, (caddr_t)&llc); 1826 1827 if (llc.llc_dsap != LLC_SNAP_LSAP || 1828 llc.llc_ssap != LLC_SNAP_LSAP || 1829 llc.llc_control != LLC_UI || 1830 llc.llc_snap.org_code[0] || 1831 llc.llc_snap.org_code[1] || 1832 llc.llc_snap.org_code[2] || 1833 llc.llc_snap.ether_type != htons(ETHERTYPE_IP)) 1834 goto dropit; 1835 1836 hassnap = 1; 1837 } 1838 1839 m_adj(m, ETHER_HDR_LEN); 1840 if (hassnap) 1841 m_adj(m, LLC_SNAPFRAMELEN); 1842 1843 if (m->m_len < sizeof(struct ip) && 1844 (m = m_pullup(m, sizeof(struct ip))) == NULL) 1845 goto dropit; 1846 ip = mtod(m, struct ip *); 1847 1848 /* Respect IP_DF, return a ICMP_UNREACH_NEEDFRAG. */ 1849 if (ip->ip_off & htons(IP_DF)) { 1850 bridge_send_icmp_err(ifp, eh, m, hassnap, &llc, 1851 ifp->if_mtu, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG); 1852 return; 1853 } 1854 1855 error = ip_fragment(m, ifp, ifp->if_mtu); 1856 if (error) { 1857 m = NULL; 1858 goto dropit; 1859 } 1860 1861 for (; m; m = m0) { 1862 m0 = m->m_nextpkt; 1863 m->m_nextpkt = NULL; 1864 if (error == 0) { 1865 if (hassnap) { 1866 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 1867 if (m == NULL) { 1868 error = ENOBUFS; 1869 continue; 1870 } 1871 bcopy(&llc, mtod(m, caddr_t), 1872 LLC_SNAPFRAMELEN); 1873 } 1874 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 1875 if (m == NULL) { 1876 error = ENOBUFS; 1877 continue; 1878 } 1879 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 1880 error = bridge_ifenqueue(brifp, ifp, m); 1881 if (error) { 1882 continue; 1883 } 1884 } else 1885 m_freem(m); 1886 } 1887 1888 if (error == 0) 1889 ipstat_inc(ips_fragmented); 1890 1891 return; 1892 dropit: 1893 m_freem(m); 1894 } 1895 1896 int 1897 bridge_ifenqueue(struct ifnet *brifp, struct ifnet *ifp, struct mbuf *m) 1898 { 1899 int error, len; 1900 1901 /* Loop prevention. */ 1902 m->m_flags |= M_PROTO1; 1903 1904 len = m->m_pkthdr.len; 1905 1906 error = if_enqueue(ifp, m); 1907 if (error) { 1908 brifp->if_oerrors++; 1909 return (error); 1910 } 1911 1912 brifp->if_opackets++; 1913 brifp->if_obytes += len; 1914 1915 return (0); 1916 } 1917 1918 void 1919 bridge_ifinput(struct ifnet *ifp, struct mbuf *m) 1920 { 1921 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 1922 1923 m->m_flags |= M_PROTO1; 1924 1925 ml_enqueue(&ml, m); 1926 if_input(ifp, &ml); 1927 } 1928 1929 void 1930 bridge_send_icmp_err(struct ifnet *ifp, 1931 struct ether_header *eh, struct mbuf *n, int hassnap, struct llc *llc, 1932 int mtu, int type, int code) 1933 { 1934 struct ip *ip; 1935 struct icmp *icp; 1936 struct in_addr t; 1937 struct mbuf *m, *n2; 1938 int hlen; 1939 u_int8_t ether_tmp[ETHER_ADDR_LEN]; 1940 1941 n2 = m_copym(n, 0, M_COPYALL, M_DONTWAIT); 1942 if (!n2) { 1943 m_freem(n); 1944 return; 1945 } 1946 m = icmp_do_error(n, type, code, 0, mtu); 1947 if (m == NULL) { 1948 m_freem(n2); 1949 return; 1950 } 1951 1952 n = n2; 1953 1954 ip = mtod(m, struct ip *); 1955 hlen = ip->ip_hl << 2; 1956 t = ip->ip_dst; 1957 ip->ip_dst = ip->ip_src; 1958 ip->ip_src = t; 1959 1960 m->m_data += hlen; 1961 m->m_len -= hlen; 1962 icp = mtod(m, struct icmp *); 1963 icp->icmp_cksum = 0; 1964 icp->icmp_cksum = in_cksum(m, ntohs(ip->ip_len) - hlen); 1965 m->m_data -= hlen; 1966 m->m_len += hlen; 1967 1968 ip->ip_v = IPVERSION; 1969 ip->ip_off &= htons(IP_DF); 1970 ip->ip_id = htons(ip_randomid()); 1971 ip->ip_ttl = MAXTTL; 1972 ip->ip_sum = 0; 1973 ip->ip_sum = in_cksum(m, hlen); 1974 1975 /* Swap ethernet addresses */ 1976 bcopy(&eh->ether_dhost, ðer_tmp, sizeof(ether_tmp)); 1977 bcopy(&eh->ether_shost, &eh->ether_dhost, sizeof(ether_tmp)); 1978 bcopy(ðer_tmp, &eh->ether_shost, sizeof(ether_tmp)); 1979 1980 /* Reattach SNAP header */ 1981 if (hassnap) { 1982 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT); 1983 if (m == NULL) 1984 goto dropit; 1985 bcopy(llc, mtod(m, caddr_t), LLC_SNAPFRAMELEN); 1986 } 1987 1988 /* Reattach ethernet header */ 1989 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 1990 if (m == NULL) 1991 goto dropit; 1992 bcopy(eh, mtod(m, caddr_t), sizeof(*eh)); 1993 1994 bridge_output(ifp, m, NULL, NULL); 1995 m_freem(n); 1996 return; 1997 1998 dropit: 1999 m_freem(n); 2000 } 2001 2002 struct bridge_tunneltag * 2003 bridge_tunnel(struct mbuf *m) 2004 { 2005 struct m_tag *mtag; 2006 2007 if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL) 2008 return (NULL); 2009 2010 return ((struct bridge_tunneltag *)(mtag + 1)); 2011 } 2012 2013 struct bridge_tunneltag * 2014 bridge_tunneltag(struct mbuf *m) 2015 { 2016 struct m_tag *mtag; 2017 2018 if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) == NULL) { 2019 mtag = m_tag_get(PACKET_TAG_TUNNEL, 2020 sizeof(struct bridge_tunneltag), M_NOWAIT); 2021 if (mtag == NULL) 2022 return (NULL); 2023 bzero(mtag + 1, sizeof(struct bridge_tunneltag)); 2024 m_tag_prepend(m, mtag); 2025 } 2026 2027 return ((struct bridge_tunneltag *)(mtag + 1)); 2028 } 2029 2030 void 2031 bridge_tunneluntag(struct mbuf *m) 2032 { 2033 struct m_tag *mtag; 2034 if ((mtag = m_tag_find(m, PACKET_TAG_TUNNEL, NULL)) != NULL) 2035 m_tag_delete(m, mtag); 2036 } 2037 2038 void 2039 bridge_copyaddr(struct sockaddr *src, struct sockaddr *dst) 2040 { 2041 if (src != NULL && src->sa_family != AF_UNSPEC) 2042 memcpy(dst, src, src->sa_len); 2043 else { 2044 dst->sa_family = AF_UNSPEC; 2045 dst->sa_len = 0; 2046 } 2047 } 2048 2049 void 2050 bridge_copytag(struct bridge_tunneltag *src, struct bridge_tunneltag *dst) 2051 { 2052 if (src == NULL) { 2053 memset(dst, 0, sizeof(*dst)); 2054 } else { 2055 bridge_copyaddr(&src->brtag_peer.sa, &dst->brtag_peer.sa); 2056 bridge_copyaddr(&src->brtag_local.sa, &dst->brtag_local.sa); 2057 dst->brtag_id = src->brtag_id; 2058 } 2059 } 2060