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