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