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