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