1 /* $NetBSD: if_bridge.c,v 1.123 2016/05/16 01:23:51 ozaki-r Exp $ */ 2 3 /* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by Jason L. Wright 53 * 4. The name of the author may not be used to endorse or promote products 54 * derived from this software without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 59 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 * 68 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp 69 */ 70 71 /* 72 * Network interface bridge support. 73 * 74 * TODO: 75 * 76 * - Currently only supports Ethernet-like interfaces (Ethernet, 77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way 78 * to bridge other types of interfaces (FDDI-FDDI, and maybe 79 * consider heterogenous bridges). 80 */ 81 82 #include <sys/cdefs.h> 83 __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.123 2016/05/16 01:23:51 ozaki-r Exp $"); 84 85 #ifdef _KERNEL_OPT 86 #include "opt_bridge_ipf.h" 87 #include "opt_inet.h" 88 #include "opt_net_mpsafe.h" 89 #endif /* _KERNEL_OPT */ 90 91 #include <sys/param.h> 92 #include <sys/kernel.h> 93 #include <sys/mbuf.h> 94 #include <sys/queue.h> 95 #include <sys/socket.h> 96 #include <sys/socketvar.h> /* for softnet_lock */ 97 #include <sys/sockio.h> 98 #include <sys/systm.h> 99 #include <sys/proc.h> 100 #include <sys/pool.h> 101 #include <sys/kauth.h> 102 #include <sys/cpu.h> 103 #include <sys/cprng.h> 104 #include <sys/mutex.h> 105 #include <sys/kmem.h> 106 107 #include <net/bpf.h> 108 #include <net/if.h> 109 #include <net/if_dl.h> 110 #include <net/if_types.h> 111 #include <net/if_llc.h> 112 113 #include <net/if_ether.h> 114 #include <net/if_bridgevar.h> 115 116 #if defined(BRIDGE_IPF) 117 /* Used for bridge_ip[6]_checkbasic */ 118 #include <netinet/in.h> 119 #include <netinet/in_systm.h> 120 #include <netinet/ip.h> 121 #include <netinet/ip_var.h> 122 #include <netinet/ip_private.h> /* XXX */ 123 124 #include <netinet/ip6.h> 125 #include <netinet6/in6_var.h> 126 #include <netinet6/ip6_var.h> 127 #include <netinet6/ip6_private.h> /* XXX */ 128 #endif /* BRIDGE_IPF */ 129 130 /* 131 * Size of the route hash table. Must be a power of two. 132 */ 133 #ifndef BRIDGE_RTHASH_SIZE 134 #define BRIDGE_RTHASH_SIZE 1024 135 #endif 136 137 #define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1) 138 139 #include "carp.h" 140 #if NCARP > 0 141 #include <netinet/in.h> 142 #include <netinet/in_var.h> 143 #include <netinet/ip_carp.h> 144 #endif 145 146 #include "ioconf.h" 147 148 __CTASSERT(sizeof(struct ifbifconf) == sizeof(struct ifbaconf)); 149 __CTASSERT(offsetof(struct ifbifconf, ifbic_len) == offsetof(struct ifbaconf, ifbac_len)); 150 __CTASSERT(offsetof(struct ifbifconf, ifbic_buf) == offsetof(struct ifbaconf, ifbac_buf)); 151 152 /* 153 * Maximum number of addresses to cache. 154 */ 155 #ifndef BRIDGE_RTABLE_MAX 156 #define BRIDGE_RTABLE_MAX 100 157 #endif 158 159 /* 160 * Spanning tree defaults. 161 */ 162 #define BSTP_DEFAULT_MAX_AGE (20 * 256) 163 #define BSTP_DEFAULT_HELLO_TIME (2 * 256) 164 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 165 #define BSTP_DEFAULT_HOLD_TIME (1 * 256) 166 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 167 #define BSTP_DEFAULT_PORT_PRIORITY 0x80 168 #define BSTP_DEFAULT_PATH_COST 55 169 170 /* 171 * Timeout (in seconds) for entries learned dynamically. 172 */ 173 #ifndef BRIDGE_RTABLE_TIMEOUT 174 #define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */ 175 #endif 176 177 /* 178 * Number of seconds between walks of the route list. 179 */ 180 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD 181 #define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60) 182 #endif 183 184 #define BRIDGE_RT_LOCK(_sc) if ((_sc)->sc_rtlist_lock) \ 185 mutex_enter((_sc)->sc_rtlist_lock) 186 #define BRIDGE_RT_UNLOCK(_sc) if ((_sc)->sc_rtlist_lock) \ 187 mutex_exit((_sc)->sc_rtlist_lock) 188 #define BRIDGE_RT_LOCKED(_sc) (!(_sc)->sc_rtlist_lock || \ 189 mutex_owned((_sc)->sc_rtlist_lock)) 190 191 #define BRIDGE_RT_PSZ_PERFORM(_sc) \ 192 if ((_sc)->sc_rtlist_psz != NULL) \ 193 pserialize_perform((_sc)->sc_rtlist_psz); 194 195 #define BRIDGE_RT_RENTER(__s) do { __s = pserialize_read_enter(); } while (0) 196 #define BRIDGE_RT_REXIT(__s) do { pserialize_read_exit(__s); } while (0) 197 198 199 #ifdef NET_MPSAFE 200 #define DECLARE_LOCK_VARIABLE 201 #define ACQUIRE_GLOBAL_LOCKS() do { } while (0) 202 #define RELEASE_GLOBAL_LOCKS() do { } while (0) 203 #else 204 #define DECLARE_LOCK_VARIABLE int __s 205 #define ACQUIRE_GLOBAL_LOCKS() do { \ 206 KERNEL_LOCK(1, NULL); \ 207 mutex_enter(softnet_lock); \ 208 __s = splnet(); \ 209 } while (0) 210 #define RELEASE_GLOBAL_LOCKS() do { \ 211 splx(__s); \ 212 mutex_exit(softnet_lock); \ 213 KERNEL_UNLOCK_ONE(NULL); \ 214 } while (0) 215 #endif 216 217 struct psref_class *bridge_psref_class __read_mostly; 218 219 int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; 220 221 static struct pool bridge_rtnode_pool; 222 223 static int bridge_clone_create(struct if_clone *, int); 224 static int bridge_clone_destroy(struct ifnet *); 225 226 static int bridge_ioctl(struct ifnet *, u_long, void *); 227 static int bridge_init(struct ifnet *); 228 static void bridge_stop(struct ifnet *, int); 229 static void bridge_start(struct ifnet *); 230 231 static void bridge_input(struct ifnet *, struct mbuf *); 232 static void bridge_forward(struct bridge_softc *, struct mbuf *); 233 234 static void bridge_timer(void *); 235 236 static void bridge_broadcast(struct bridge_softc *, struct ifnet *, 237 struct mbuf *); 238 239 static int bridge_rtupdate(struct bridge_softc *, const uint8_t *, 240 struct ifnet *, int, uint8_t); 241 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *); 242 static void bridge_rttrim(struct bridge_softc *); 243 static void bridge_rtage(struct bridge_softc *); 244 static void bridge_rtage_work(struct work *, void *); 245 static void bridge_rtflush(struct bridge_softc *, int); 246 static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *); 247 static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp); 248 249 static void bridge_rtable_init(struct bridge_softc *); 250 static void bridge_rtable_fini(struct bridge_softc *); 251 252 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *, 253 const uint8_t *); 254 static int bridge_rtnode_insert(struct bridge_softc *, 255 struct bridge_rtnode *); 256 static void bridge_rtnode_remove(struct bridge_softc *, 257 struct bridge_rtnode *); 258 static void bridge_rtnode_destroy(struct bridge_rtnode *); 259 260 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *, 261 const char *name, 262 struct psref *); 263 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *, 264 struct ifnet *ifp, 265 struct psref *); 266 static void bridge_release_member(struct bridge_softc *, struct bridge_iflist *, 267 struct psref *); 268 static void bridge_delete_member(struct bridge_softc *, 269 struct bridge_iflist *); 270 static void bridge_acquire_member(struct bridge_softc *sc, 271 struct bridge_iflist *, 272 struct psref *); 273 274 static int bridge_ioctl_add(struct bridge_softc *, void *); 275 static int bridge_ioctl_del(struct bridge_softc *, void *); 276 static int bridge_ioctl_gifflags(struct bridge_softc *, void *); 277 static int bridge_ioctl_sifflags(struct bridge_softc *, void *); 278 static int bridge_ioctl_scache(struct bridge_softc *, void *); 279 static int bridge_ioctl_gcache(struct bridge_softc *, void *); 280 static int bridge_ioctl_gifs(struct bridge_softc *, void *); 281 static int bridge_ioctl_rts(struct bridge_softc *, void *); 282 static int bridge_ioctl_saddr(struct bridge_softc *, void *); 283 static int bridge_ioctl_sto(struct bridge_softc *, void *); 284 static int bridge_ioctl_gto(struct bridge_softc *, void *); 285 static int bridge_ioctl_daddr(struct bridge_softc *, void *); 286 static int bridge_ioctl_flush(struct bridge_softc *, void *); 287 static int bridge_ioctl_gpri(struct bridge_softc *, void *); 288 static int bridge_ioctl_spri(struct bridge_softc *, void *); 289 static int bridge_ioctl_ght(struct bridge_softc *, void *); 290 static int bridge_ioctl_sht(struct bridge_softc *, void *); 291 static int bridge_ioctl_gfd(struct bridge_softc *, void *); 292 static int bridge_ioctl_sfd(struct bridge_softc *, void *); 293 static int bridge_ioctl_gma(struct bridge_softc *, void *); 294 static int bridge_ioctl_sma(struct bridge_softc *, void *); 295 static int bridge_ioctl_sifprio(struct bridge_softc *, void *); 296 static int bridge_ioctl_sifcost(struct bridge_softc *, void *); 297 #if defined(BRIDGE_IPF) 298 static int bridge_ioctl_gfilt(struct bridge_softc *, void *); 299 static int bridge_ioctl_sfilt(struct bridge_softc *, void *); 300 static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int); 301 static int bridge_ip_checkbasic(struct mbuf **mp); 302 # ifdef INET6 303 static int bridge_ip6_checkbasic(struct mbuf **mp); 304 # endif /* INET6 */ 305 #endif /* BRIDGE_IPF */ 306 307 struct bridge_control { 308 int (*bc_func)(struct bridge_softc *, void *); 309 int bc_argsize; 310 int bc_flags; 311 }; 312 313 #define BC_F_COPYIN 0x01 /* copy arguments in */ 314 #define BC_F_COPYOUT 0x02 /* copy arguments out */ 315 #define BC_F_SUSER 0x04 /* do super-user check */ 316 #define BC_F_XLATEIN 0x08 /* xlate arguments in */ 317 #define BC_F_XLATEOUT 0x10 /* xlate arguments out */ 318 319 static const struct bridge_control bridge_control_table[] = { 320 [BRDGADD] = {bridge_ioctl_add, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 321 [BRDGDEL] = {bridge_ioctl_del, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 322 323 [BRDGGIFFLGS] = {bridge_ioctl_gifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_COPYOUT}, 324 [BRDGSIFFLGS] = {bridge_ioctl_sifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 325 326 [BRDGSCACHE] = {bridge_ioctl_scache, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 327 [BRDGGCACHE] = {bridge_ioctl_gcache, sizeof(struct ifbrparam), BC_F_COPYOUT}, 328 329 [OBRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_COPYIN|BC_F_COPYOUT}, 330 [OBRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_COPYIN|BC_F_COPYOUT}, 331 332 [BRDGSADDR] = {bridge_ioctl_saddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER}, 333 334 [BRDGSTO] = {bridge_ioctl_sto, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 335 [BRDGGTO] = {bridge_ioctl_gto, sizeof(struct ifbrparam), BC_F_COPYOUT}, 336 337 [BRDGDADDR] = {bridge_ioctl_daddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER}, 338 339 [BRDGFLUSH] = {bridge_ioctl_flush, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 340 341 [BRDGGPRI] = {bridge_ioctl_gpri, sizeof(struct ifbrparam), BC_F_COPYOUT}, 342 [BRDGSPRI] = {bridge_ioctl_spri, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 343 344 [BRDGGHT] = {bridge_ioctl_ght, sizeof(struct ifbrparam), BC_F_COPYOUT}, 345 [BRDGSHT] = {bridge_ioctl_sht, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 346 347 [BRDGGFD] = {bridge_ioctl_gfd, sizeof(struct ifbrparam), BC_F_COPYOUT}, 348 [BRDGSFD] = {bridge_ioctl_sfd, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 349 350 [BRDGGMA] = {bridge_ioctl_gma, sizeof(struct ifbrparam), BC_F_COPYOUT}, 351 [BRDGSMA] = {bridge_ioctl_sma, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 352 353 [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 354 355 [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 356 #if defined(BRIDGE_IPF) 357 [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT}, 358 [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 359 #endif /* BRIDGE_IPF */ 360 [BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT}, 361 [BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT}, 362 }; 363 364 static const int bridge_control_table_size = __arraycount(bridge_control_table); 365 366 static struct if_clone bridge_cloner = 367 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); 368 369 /* 370 * bridgeattach: 371 * 372 * Pseudo-device attach routine. 373 */ 374 void 375 bridgeattach(int n) 376 { 377 378 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode), 379 0, 0, 0, "brtpl", NULL, IPL_NET); 380 381 bridge_psref_class = psref_class_create("bridge", IPL_SOFTNET); 382 383 if_clone_attach(&bridge_cloner); 384 } 385 386 /* 387 * bridge_clone_create: 388 * 389 * Create a new bridge instance. 390 */ 391 static int 392 bridge_clone_create(struct if_clone *ifc, int unit) 393 { 394 struct bridge_softc *sc; 395 struct ifnet *ifp; 396 int error; 397 398 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 399 ifp = &sc->sc_if; 400 401 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 402 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 403 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 404 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME; 405 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY; 406 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 407 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME; 408 sc->sc_filter_flags = 0; 409 410 /* Initialize our routing table. */ 411 bridge_rtable_init(sc); 412 413 error = workqueue_create(&sc->sc_rtage_wq, "bridge_rtage", 414 bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE); 415 if (error) 416 panic("%s: workqueue_create %d\n", __func__, error); 417 418 callout_init(&sc->sc_brcallout, 0); 419 callout_init(&sc->sc_bstpcallout, 0); 420 421 mutex_init(&sc->sc_iflist_psref.bip_lock, MUTEX_DEFAULT, IPL_NONE); 422 PSLIST_INIT(&sc->sc_iflist_psref.bip_iflist); 423 sc->sc_iflist_psref.bip_psz = pserialize_create(); 424 425 if_initname(ifp, ifc->ifc_name, unit); 426 ifp->if_softc = sc; 427 ifp->if_mtu = ETHERMTU; 428 ifp->if_ioctl = bridge_ioctl; 429 ifp->if_output = bridge_output; 430 ifp->if_start = bridge_start; 431 ifp->if_stop = bridge_stop; 432 ifp->if_init = bridge_init; 433 ifp->if_type = IFT_BRIDGE; 434 ifp->if_addrlen = 0; 435 ifp->if_dlt = DLT_EN10MB; 436 ifp->if_hdrlen = ETHER_HDR_LEN; 437 438 if_initialize(ifp); 439 if_register(ifp); 440 441 if_alloc_sadl(ifp); 442 443 return (0); 444 } 445 446 /* 447 * bridge_clone_destroy: 448 * 449 * Destroy a bridge instance. 450 */ 451 static int 452 bridge_clone_destroy(struct ifnet *ifp) 453 { 454 struct bridge_softc *sc = ifp->if_softc; 455 struct bridge_iflist *bif; 456 int s; 457 458 s = splnet(); 459 460 bridge_stop(ifp, 1); 461 462 BRIDGE_LOCK(sc); 463 for (;;) { 464 bif = PSLIST_WRITER_FIRST(&sc->sc_iflist_psref.bip_iflist, struct bridge_iflist, 465 bif_next); 466 if (bif == NULL) 467 break; 468 bridge_delete_member(sc, bif); 469 } 470 PSLIST_DESTROY(&sc->sc_iflist_psref.bip_iflist); 471 BRIDGE_UNLOCK(sc); 472 473 splx(s); 474 475 if_detach(ifp); 476 477 /* Tear down the routing table. */ 478 bridge_rtable_fini(sc); 479 480 pserialize_destroy(sc->sc_iflist_psref.bip_psz); 481 mutex_destroy(&sc->sc_iflist_psref.bip_lock); 482 483 workqueue_destroy(sc->sc_rtage_wq); 484 485 kmem_free(sc, sizeof(*sc)); 486 487 return (0); 488 } 489 490 /* 491 * bridge_ioctl: 492 * 493 * Handle a control request from the operator. 494 */ 495 static int 496 bridge_ioctl(struct ifnet *ifp, u_long cmd, void *data) 497 { 498 struct bridge_softc *sc = ifp->if_softc; 499 struct lwp *l = curlwp; /* XXX */ 500 union { 501 struct ifbreq ifbreq; 502 struct ifbifconf ifbifconf; 503 struct ifbareq ifbareq; 504 struct ifbaconf ifbaconf; 505 struct ifbrparam ifbrparam; 506 } args; 507 struct ifdrv *ifd = (struct ifdrv *) data; 508 const struct bridge_control *bc = NULL; /* XXXGCC */ 509 int s, error = 0; 510 511 /* Authorize command before calling splnet(). */ 512 switch (cmd) { 513 case SIOCGDRVSPEC: 514 case SIOCSDRVSPEC: 515 if (ifd->ifd_cmd >= bridge_control_table_size 516 || (bc = &bridge_control_table[ifd->ifd_cmd]) == NULL) { 517 error = EINVAL; 518 return error; 519 } 520 521 /* We only care about BC_F_SUSER at this point. */ 522 if ((bc->bc_flags & BC_F_SUSER) == 0) 523 break; 524 525 error = kauth_authorize_network(l->l_cred, 526 KAUTH_NETWORK_INTERFACE_BRIDGE, 527 cmd == SIOCGDRVSPEC ? 528 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV : 529 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV, 530 ifd, NULL, NULL); 531 if (error) 532 return (error); 533 534 break; 535 } 536 537 s = splnet(); 538 539 switch (cmd) { 540 case SIOCGDRVSPEC: 541 case SIOCSDRVSPEC: 542 KASSERT(bc != NULL); 543 if (cmd == SIOCGDRVSPEC && 544 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) == 0) { 545 error = EINVAL; 546 break; 547 } 548 else if (cmd == SIOCSDRVSPEC && 549 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) != 0) { 550 error = EINVAL; 551 break; 552 } 553 554 /* BC_F_SUSER is checked above, before splnet(). */ 555 556 if ((bc->bc_flags & (BC_F_XLATEIN|BC_F_XLATEOUT)) == 0 557 && (ifd->ifd_len != bc->bc_argsize 558 || ifd->ifd_len > sizeof(args))) { 559 error = EINVAL; 560 break; 561 } 562 563 memset(&args, 0, sizeof(args)); 564 if (bc->bc_flags & BC_F_COPYIN) { 565 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); 566 if (error) 567 break; 568 } else if (bc->bc_flags & BC_F_XLATEIN) { 569 args.ifbifconf.ifbic_len = ifd->ifd_len; 570 args.ifbifconf.ifbic_buf = ifd->ifd_data; 571 } 572 573 error = (*bc->bc_func)(sc, &args); 574 if (error) 575 break; 576 577 if (bc->bc_flags & BC_F_COPYOUT) { 578 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); 579 } else if (bc->bc_flags & BC_F_XLATEOUT) { 580 ifd->ifd_len = args.ifbifconf.ifbic_len; 581 ifd->ifd_data = args.ifbifconf.ifbic_buf; 582 } 583 break; 584 585 case SIOCSIFFLAGS: 586 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 587 break; 588 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 589 case IFF_RUNNING: 590 /* 591 * If interface is marked down and it is running, 592 * then stop and disable it. 593 */ 594 (*ifp->if_stop)(ifp, 1); 595 break; 596 case IFF_UP: 597 /* 598 * If interface is marked up and it is stopped, then 599 * start it. 600 */ 601 error = (*ifp->if_init)(ifp); 602 break; 603 default: 604 break; 605 } 606 break; 607 608 case SIOCSIFMTU: 609 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 610 error = 0; 611 break; 612 613 default: 614 error = ifioctl_common(ifp, cmd, data); 615 break; 616 } 617 618 splx(s); 619 620 return (error); 621 } 622 623 /* 624 * bridge_lookup_member: 625 * 626 * Lookup a bridge member interface. 627 */ 628 static struct bridge_iflist * 629 bridge_lookup_member(struct bridge_softc *sc, const char *name, struct psref *psref) 630 { 631 struct bridge_iflist *bif; 632 struct ifnet *ifp; 633 int s; 634 635 BRIDGE_PSZ_RENTER(s); 636 637 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 638 ifp = bif->bif_ifp; 639 if (strcmp(ifp->if_xname, name) == 0) 640 break; 641 } 642 if (bif != NULL) 643 bridge_acquire_member(sc, bif, psref); 644 645 BRIDGE_PSZ_REXIT(s); 646 647 return bif; 648 } 649 650 /* 651 * bridge_lookup_member_if: 652 * 653 * Lookup a bridge member interface by ifnet*. 654 */ 655 static struct bridge_iflist * 656 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp, 657 struct psref *psref) 658 { 659 struct bridge_iflist *bif; 660 int s; 661 662 BRIDGE_PSZ_RENTER(s); 663 664 bif = member_ifp->if_bridgeif; 665 if (bif != NULL) { 666 psref_acquire(psref, &bif->bif_psref, 667 bridge_psref_class); 668 } 669 670 BRIDGE_PSZ_REXIT(s); 671 672 return bif; 673 } 674 675 static void 676 bridge_acquire_member(struct bridge_softc *sc, struct bridge_iflist *bif, 677 struct psref *psref) 678 { 679 680 psref_acquire(psref, &bif->bif_psref, bridge_psref_class); 681 } 682 683 /* 684 * bridge_release_member: 685 * 686 * Release the specified member interface. 687 */ 688 static void 689 bridge_release_member(struct bridge_softc *sc, struct bridge_iflist *bif, 690 struct psref *psref) 691 { 692 693 psref_release(psref, &bif->bif_psref, bridge_psref_class); 694 } 695 696 /* 697 * bridge_delete_member: 698 * 699 * Delete the specified member interface. 700 */ 701 static void 702 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif) 703 { 704 struct ifnet *ifs = bif->bif_ifp; 705 706 KASSERT(BRIDGE_LOCKED(sc)); 707 708 ifs->_if_input = ether_input; 709 ifs->if_bridge = NULL; 710 ifs->if_bridgeif = NULL; 711 712 PSLIST_WRITER_REMOVE(bif, bif_next); 713 BRIDGE_PSZ_PERFORM(sc); 714 BRIDGE_UNLOCK(sc); 715 716 psref_target_destroy(&bif->bif_psref, bridge_psref_class); 717 718 PSLIST_ENTRY_DESTROY(bif, bif_next); 719 kmem_free(bif, sizeof(*bif)); 720 721 BRIDGE_LOCK(sc); 722 } 723 724 static int 725 bridge_ioctl_add(struct bridge_softc *sc, void *arg) 726 { 727 struct ifbreq *req = arg; 728 struct bridge_iflist *bif = NULL; 729 struct ifnet *ifs; 730 int error = 0; 731 struct psref psref; 732 733 ifs = if_get(req->ifbr_ifsname, &psref); 734 if (ifs == NULL) 735 return (ENOENT); 736 737 if (sc->sc_if.if_mtu != ifs->if_mtu) { 738 error = EINVAL; 739 goto out; 740 } 741 742 if (ifs->if_bridge == sc) { 743 error = EEXIST; 744 goto out; 745 } 746 747 if (ifs->if_bridge != NULL) { 748 error = EBUSY; 749 goto out; 750 } 751 752 if (ifs->_if_input != ether_input) { 753 error = EINVAL; 754 goto out; 755 } 756 757 /* FIXME: doesn't work with non-IFF_SIMPLEX interfaces */ 758 if ((ifs->if_flags & IFF_SIMPLEX) == 0) { 759 error = EINVAL; 760 goto out; 761 } 762 763 bif = kmem_alloc(sizeof(*bif), KM_SLEEP); 764 765 switch (ifs->if_type) { 766 case IFT_ETHER: 767 if ((error = ether_enable_vlan_mtu(ifs)) > 0) 768 goto out; 769 /* 770 * Place the interface into promiscuous mode. 771 */ 772 error = ifpromisc(ifs, 1); 773 if (error) 774 goto out; 775 break; 776 default: 777 error = EINVAL; 778 goto out; 779 } 780 781 bif->bif_ifp = ifs; 782 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 783 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; 784 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST; 785 PSLIST_ENTRY_INIT(bif, bif_next); 786 psref_target_init(&bif->bif_psref, bridge_psref_class); 787 788 BRIDGE_LOCK(sc); 789 790 ifs->if_bridge = sc; 791 ifs->if_bridgeif = bif; 792 PSLIST_WRITER_INSERT_HEAD(&sc->sc_iflist_psref.bip_iflist, bif, bif_next); 793 ifs->_if_input = bridge_input; 794 795 BRIDGE_UNLOCK(sc); 796 797 if (sc->sc_if.if_flags & IFF_RUNNING) 798 bstp_initialization(sc); 799 else 800 bstp_stop(sc); 801 802 out: 803 if_put(ifs, &psref); 804 if (error) { 805 if (bif != NULL) 806 kmem_free(bif, sizeof(*bif)); 807 } 808 return (error); 809 } 810 811 static int 812 bridge_ioctl_del(struct bridge_softc *sc, void *arg) 813 { 814 struct ifbreq *req = arg; 815 const char *name = req->ifbr_ifsname; 816 struct bridge_iflist *bif; 817 struct ifnet *ifs; 818 819 BRIDGE_LOCK(sc); 820 821 /* 822 * Don't use bridge_lookup_member. We want to get a member 823 * with bif_refs == 0. 824 */ 825 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) { 826 ifs = bif->bif_ifp; 827 if (strcmp(ifs->if_xname, name) == 0) 828 break; 829 } 830 831 if (bif == NULL) { 832 BRIDGE_UNLOCK(sc); 833 return ENOENT; 834 } 835 836 bridge_delete_member(sc, bif); 837 838 BRIDGE_UNLOCK(sc); 839 840 switch (ifs->if_type) { 841 case IFT_ETHER: 842 /* 843 * Take the interface out of promiscuous mode. 844 * Don't call it with holding a spin lock. 845 */ 846 (void) ifpromisc(ifs, 0); 847 (void) ether_disable_vlan_mtu(ifs); 848 break; 849 default: 850 #ifdef DIAGNOSTIC 851 panic("bridge_delete_member: impossible"); 852 #endif 853 break; 854 } 855 856 bridge_rtdelete(sc, ifs); 857 858 if (sc->sc_if.if_flags & IFF_RUNNING) 859 bstp_initialization(sc); 860 861 return 0; 862 } 863 864 static int 865 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) 866 { 867 struct ifbreq *req = arg; 868 struct bridge_iflist *bif; 869 struct psref psref; 870 871 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 872 if (bif == NULL) 873 return (ENOENT); 874 875 req->ifbr_ifsflags = bif->bif_flags; 876 req->ifbr_state = bif->bif_state; 877 req->ifbr_priority = bif->bif_priority; 878 req->ifbr_path_cost = bif->bif_path_cost; 879 req->ifbr_portno = bif->bif_ifp->if_index & 0xff; 880 881 bridge_release_member(sc, bif, &psref); 882 883 return (0); 884 } 885 886 static int 887 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) 888 { 889 struct ifbreq *req = arg; 890 struct bridge_iflist *bif; 891 struct psref psref; 892 893 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 894 if (bif == NULL) 895 return (ENOENT); 896 897 if (req->ifbr_ifsflags & IFBIF_STP) { 898 switch (bif->bif_ifp->if_type) { 899 case IFT_ETHER: 900 /* These can do spanning tree. */ 901 break; 902 903 default: 904 /* Nothing else can. */ 905 bridge_release_member(sc, bif, &psref); 906 return (EINVAL); 907 } 908 } 909 910 bif->bif_flags = req->ifbr_ifsflags; 911 912 bridge_release_member(sc, bif, &psref); 913 914 if (sc->sc_if.if_flags & IFF_RUNNING) 915 bstp_initialization(sc); 916 917 return (0); 918 } 919 920 static int 921 bridge_ioctl_scache(struct bridge_softc *sc, void *arg) 922 { 923 struct ifbrparam *param = arg; 924 925 sc->sc_brtmax = param->ifbrp_csize; 926 bridge_rttrim(sc); 927 928 return (0); 929 } 930 931 static int 932 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg) 933 { 934 struct ifbrparam *param = arg; 935 936 param->ifbrp_csize = sc->sc_brtmax; 937 938 return (0); 939 } 940 941 static int 942 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) 943 { 944 struct ifbifconf *bifc = arg; 945 struct bridge_iflist *bif; 946 struct ifbreq *breqs; 947 int i, count, error = 0; 948 949 retry: 950 BRIDGE_LOCK(sc); 951 count = 0; 952 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) 953 count++; 954 BRIDGE_UNLOCK(sc); 955 956 if (count == 0) { 957 bifc->ifbic_len = 0; 958 return 0; 959 } 960 961 if (bifc->ifbic_len == 0 || bifc->ifbic_len < (sizeof(*breqs) * count)) { 962 /* Tell that a larger buffer is needed */ 963 bifc->ifbic_len = sizeof(*breqs) * count; 964 return 0; 965 } 966 967 breqs = kmem_alloc(sizeof(*breqs) * count, KM_SLEEP); 968 969 BRIDGE_LOCK(sc); 970 971 i = 0; 972 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) 973 i++; 974 if (i > count) { 975 /* 976 * The number of members has been increased. 977 * We need more memory! 978 */ 979 BRIDGE_UNLOCK(sc); 980 kmem_free(breqs, sizeof(*breqs) * count); 981 goto retry; 982 } 983 984 i = 0; 985 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) { 986 struct ifbreq *breq = &breqs[i++]; 987 memset(breq, 0, sizeof(*breq)); 988 989 strlcpy(breq->ifbr_ifsname, bif->bif_ifp->if_xname, 990 sizeof(breq->ifbr_ifsname)); 991 breq->ifbr_ifsflags = bif->bif_flags; 992 breq->ifbr_state = bif->bif_state; 993 breq->ifbr_priority = bif->bif_priority; 994 breq->ifbr_path_cost = bif->bif_path_cost; 995 breq->ifbr_portno = bif->bif_ifp->if_index & 0xff; 996 } 997 998 /* Don't call copyout with holding the mutex */ 999 BRIDGE_UNLOCK(sc); 1000 1001 for (i = 0; i < count; i++) { 1002 error = copyout(&breqs[i], bifc->ifbic_req + i, sizeof(*breqs)); 1003 if (error) 1004 break; 1005 } 1006 bifc->ifbic_len = sizeof(*breqs) * i; 1007 1008 kmem_free(breqs, sizeof(*breqs) * count); 1009 1010 return error; 1011 } 1012 1013 static int 1014 bridge_ioctl_rts(struct bridge_softc *sc, void *arg) 1015 { 1016 struct ifbaconf *bac = arg; 1017 struct bridge_rtnode *brt; 1018 struct ifbareq bareq; 1019 int count = 0, error = 0, len; 1020 1021 if (bac->ifbac_len == 0) 1022 return (0); 1023 1024 BRIDGE_RT_LOCK(sc); 1025 1026 len = bac->ifbac_len; 1027 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 1028 if (len < sizeof(bareq)) 1029 goto out; 1030 memset(&bareq, 0, sizeof(bareq)); 1031 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, 1032 sizeof(bareq.ifba_ifsname)); 1033 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); 1034 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1035 bareq.ifba_expire = brt->brt_expire - time_uptime; 1036 } else 1037 bareq.ifba_expire = 0; 1038 bareq.ifba_flags = brt->brt_flags; 1039 1040 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq)); 1041 if (error) 1042 goto out; 1043 count++; 1044 len -= sizeof(bareq); 1045 } 1046 out: 1047 BRIDGE_RT_UNLOCK(sc); 1048 1049 bac->ifbac_len = sizeof(bareq) * count; 1050 return (error); 1051 } 1052 1053 static int 1054 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) 1055 { 1056 struct ifbareq *req = arg; 1057 struct bridge_iflist *bif; 1058 int error; 1059 struct psref psref; 1060 1061 bif = bridge_lookup_member(sc, req->ifba_ifsname, &psref); 1062 if (bif == NULL) 1063 return (ENOENT); 1064 1065 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1, 1066 req->ifba_flags); 1067 1068 bridge_release_member(sc, bif, &psref); 1069 1070 return (error); 1071 } 1072 1073 static int 1074 bridge_ioctl_sto(struct bridge_softc *sc, void *arg) 1075 { 1076 struct ifbrparam *param = arg; 1077 1078 sc->sc_brttimeout = param->ifbrp_ctime; 1079 1080 return (0); 1081 } 1082 1083 static int 1084 bridge_ioctl_gto(struct bridge_softc *sc, void *arg) 1085 { 1086 struct ifbrparam *param = arg; 1087 1088 param->ifbrp_ctime = sc->sc_brttimeout; 1089 1090 return (0); 1091 } 1092 1093 static int 1094 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg) 1095 { 1096 struct ifbareq *req = arg; 1097 1098 return (bridge_rtdaddr(sc, req->ifba_dst)); 1099 } 1100 1101 static int 1102 bridge_ioctl_flush(struct bridge_softc *sc, void *arg) 1103 { 1104 struct ifbreq *req = arg; 1105 1106 bridge_rtflush(sc, req->ifbr_ifsflags); 1107 1108 return (0); 1109 } 1110 1111 static int 1112 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg) 1113 { 1114 struct ifbrparam *param = arg; 1115 1116 param->ifbrp_prio = sc->sc_bridge_priority; 1117 1118 return (0); 1119 } 1120 1121 static int 1122 bridge_ioctl_spri(struct bridge_softc *sc, void *arg) 1123 { 1124 struct ifbrparam *param = arg; 1125 1126 sc->sc_bridge_priority = param->ifbrp_prio; 1127 1128 if (sc->sc_if.if_flags & IFF_RUNNING) 1129 bstp_initialization(sc); 1130 1131 return (0); 1132 } 1133 1134 static int 1135 bridge_ioctl_ght(struct bridge_softc *sc, void *arg) 1136 { 1137 struct ifbrparam *param = arg; 1138 1139 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8; 1140 1141 return (0); 1142 } 1143 1144 static int 1145 bridge_ioctl_sht(struct bridge_softc *sc, void *arg) 1146 { 1147 struct ifbrparam *param = arg; 1148 1149 if (param->ifbrp_hellotime == 0) 1150 return (EINVAL); 1151 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8; 1152 1153 if (sc->sc_if.if_flags & IFF_RUNNING) 1154 bstp_initialization(sc); 1155 1156 return (0); 1157 } 1158 1159 static int 1160 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg) 1161 { 1162 struct ifbrparam *param = arg; 1163 1164 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8; 1165 1166 return (0); 1167 } 1168 1169 static int 1170 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg) 1171 { 1172 struct ifbrparam *param = arg; 1173 1174 if (param->ifbrp_fwddelay == 0) 1175 return (EINVAL); 1176 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8; 1177 1178 if (sc->sc_if.if_flags & IFF_RUNNING) 1179 bstp_initialization(sc); 1180 1181 return (0); 1182 } 1183 1184 static int 1185 bridge_ioctl_gma(struct bridge_softc *sc, void *arg) 1186 { 1187 struct ifbrparam *param = arg; 1188 1189 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8; 1190 1191 return (0); 1192 } 1193 1194 static int 1195 bridge_ioctl_sma(struct bridge_softc *sc, void *arg) 1196 { 1197 struct ifbrparam *param = arg; 1198 1199 if (param->ifbrp_maxage == 0) 1200 return (EINVAL); 1201 sc->sc_bridge_max_age = param->ifbrp_maxage << 8; 1202 1203 if (sc->sc_if.if_flags & IFF_RUNNING) 1204 bstp_initialization(sc); 1205 1206 return (0); 1207 } 1208 1209 static int 1210 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) 1211 { 1212 struct ifbreq *req = arg; 1213 struct bridge_iflist *bif; 1214 struct psref psref; 1215 1216 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 1217 if (bif == NULL) 1218 return (ENOENT); 1219 1220 bif->bif_priority = req->ifbr_priority; 1221 1222 if (sc->sc_if.if_flags & IFF_RUNNING) 1223 bstp_initialization(sc); 1224 1225 bridge_release_member(sc, bif, &psref); 1226 1227 return (0); 1228 } 1229 1230 #if defined(BRIDGE_IPF) 1231 static int 1232 bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg) 1233 { 1234 struct ifbrparam *param = arg; 1235 1236 param->ifbrp_filter = sc->sc_filter_flags; 1237 1238 return (0); 1239 } 1240 1241 static int 1242 bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg) 1243 { 1244 struct ifbrparam *param = arg; 1245 uint32_t nflags, oflags; 1246 1247 if (param->ifbrp_filter & ~IFBF_FILT_MASK) 1248 return (EINVAL); 1249 1250 nflags = param->ifbrp_filter; 1251 oflags = sc->sc_filter_flags; 1252 1253 if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) { 1254 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1255 sc->sc_if.if_pfil); 1256 } 1257 if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) { 1258 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1259 sc->sc_if.if_pfil); 1260 } 1261 1262 sc->sc_filter_flags = nflags; 1263 1264 return (0); 1265 } 1266 #endif /* BRIDGE_IPF */ 1267 1268 static int 1269 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) 1270 { 1271 struct ifbreq *req = arg; 1272 struct bridge_iflist *bif; 1273 struct psref psref; 1274 1275 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 1276 if (bif == NULL) 1277 return (ENOENT); 1278 1279 bif->bif_path_cost = req->ifbr_path_cost; 1280 1281 if (sc->sc_if.if_flags & IFF_RUNNING) 1282 bstp_initialization(sc); 1283 1284 bridge_release_member(sc, bif, &psref); 1285 1286 return (0); 1287 } 1288 1289 /* 1290 * bridge_ifdetach: 1291 * 1292 * Detach an interface from a bridge. Called when a member 1293 * interface is detaching. 1294 */ 1295 void 1296 bridge_ifdetach(struct ifnet *ifp) 1297 { 1298 struct bridge_softc *sc = ifp->if_bridge; 1299 struct ifbreq breq; 1300 1301 /* ioctl_lock should prevent this from happening */ 1302 KASSERT(sc != NULL); 1303 1304 memset(&breq, 0, sizeof(breq)); 1305 strlcpy(breq.ifbr_ifsname, ifp->if_xname, sizeof(breq.ifbr_ifsname)); 1306 1307 (void) bridge_ioctl_del(sc, &breq); 1308 } 1309 1310 /* 1311 * bridge_init: 1312 * 1313 * Initialize a bridge interface. 1314 */ 1315 static int 1316 bridge_init(struct ifnet *ifp) 1317 { 1318 struct bridge_softc *sc = ifp->if_softc; 1319 1320 if (ifp->if_flags & IFF_RUNNING) 1321 return (0); 1322 1323 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, 1324 bridge_timer, sc); 1325 1326 ifp->if_flags |= IFF_RUNNING; 1327 bstp_initialization(sc); 1328 return (0); 1329 } 1330 1331 /* 1332 * bridge_stop: 1333 * 1334 * Stop the bridge interface. 1335 */ 1336 static void 1337 bridge_stop(struct ifnet *ifp, int disable) 1338 { 1339 struct bridge_softc *sc = ifp->if_softc; 1340 1341 if ((ifp->if_flags & IFF_RUNNING) == 0) 1342 return; 1343 1344 callout_stop(&sc->sc_brcallout); 1345 bstp_stop(sc); 1346 1347 bridge_rtflush(sc, IFBF_FLUSHDYN); 1348 1349 ifp->if_flags &= ~IFF_RUNNING; 1350 } 1351 1352 /* 1353 * bridge_enqueue: 1354 * 1355 * Enqueue a packet on a bridge member interface. 1356 */ 1357 void 1358 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, 1359 int runfilt) 1360 { 1361 int len, error; 1362 short mflags; 1363 1364 /* 1365 * Clear any in-bound checksum flags for this packet. 1366 */ 1367 m->m_pkthdr.csum_flags = 0; 1368 1369 if (runfilt) { 1370 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, 1371 dst_ifp, PFIL_OUT) != 0) { 1372 if (m != NULL) 1373 m_freem(m); 1374 return; 1375 } 1376 if (m == NULL) 1377 return; 1378 } 1379 1380 #ifdef ALTQ 1381 /* 1382 * If ALTQ is enabled on the member interface, do 1383 * classification; the queueing discipline might 1384 * not require classification, but might require 1385 * the address family/header pointer in the pktattr. 1386 */ 1387 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) { 1388 /* XXX IFT_ETHER */ 1389 altq_etherclassify(&dst_ifp->if_snd, m); 1390 } 1391 #endif /* ALTQ */ 1392 1393 len = m->m_pkthdr.len; 1394 mflags = m->m_flags; 1395 1396 error = (*dst_ifp->if_transmit)(dst_ifp, m); 1397 if (error) { 1398 /* mbuf is already freed */ 1399 sc->sc_if.if_oerrors++; 1400 return; 1401 } 1402 1403 sc->sc_if.if_opackets++; 1404 sc->sc_if.if_obytes += len; 1405 if (mflags & M_MCAST) 1406 sc->sc_if.if_omcasts++; 1407 } 1408 1409 /* 1410 * bridge_output: 1411 * 1412 * Send output from a bridge member interface. This 1413 * performs the bridging function for locally originated 1414 * packets. 1415 * 1416 * The mbuf has the Ethernet header already attached. We must 1417 * enqueue or free the mbuf before returning. 1418 */ 1419 int 1420 bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa, 1421 const struct rtentry *rt) 1422 { 1423 struct ether_header *eh; 1424 struct ifnet *dst_if; 1425 struct bridge_softc *sc; 1426 int s; 1427 1428 if (m->m_len < ETHER_HDR_LEN) { 1429 m = m_pullup(m, ETHER_HDR_LEN); 1430 if (m == NULL) 1431 return (0); 1432 } 1433 1434 eh = mtod(m, struct ether_header *); 1435 sc = ifp->if_bridge; 1436 1437 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1438 if (memcmp(etherbroadcastaddr, 1439 eh->ether_dhost, ETHER_ADDR_LEN) == 0) 1440 m->m_flags |= M_BCAST; 1441 else 1442 m->m_flags |= M_MCAST; 1443 } 1444 1445 /* 1446 * If bridge is down, but the original output interface is up, 1447 * go ahead and send out that interface. Otherwise, the packet 1448 * is dropped below. 1449 */ 1450 if (__predict_false(sc == NULL) || 1451 (sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1452 dst_if = ifp; 1453 goto sendunicast; 1454 } 1455 1456 /* 1457 * If the packet is a multicast, or we don't know a better way to 1458 * get there, send to all interfaces. 1459 */ 1460 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0) 1461 dst_if = NULL; 1462 else 1463 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1464 if (dst_if == NULL) { 1465 /* XXX Should call bridge_broadcast, but there are locking 1466 * issues which need resolving first. */ 1467 struct bridge_iflist *bif; 1468 struct mbuf *mc; 1469 bool used = false; 1470 1471 BRIDGE_PSZ_RENTER(s); 1472 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 1473 struct psref psref; 1474 1475 bridge_acquire_member(sc, bif, &psref); 1476 BRIDGE_PSZ_REXIT(s); 1477 1478 dst_if = bif->bif_ifp; 1479 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1480 goto next; 1481 1482 /* 1483 * If this is not the original output interface, 1484 * and the interface is participating in spanning 1485 * tree, make sure the port is in a state that 1486 * allows forwarding. 1487 */ 1488 if (dst_if != ifp && 1489 (bif->bif_flags & IFBIF_STP) != 0) { 1490 switch (bif->bif_state) { 1491 case BSTP_IFSTATE_BLOCKING: 1492 case BSTP_IFSTATE_LISTENING: 1493 case BSTP_IFSTATE_DISABLED: 1494 goto next; 1495 } 1496 } 1497 1498 if (PSLIST_READER_NEXT(bif, struct bridge_iflist, 1499 bif_next) == NULL && 1500 ((m->m_flags & (M_MCAST | M_BCAST)) == 0 || 1501 dst_if == ifp)) 1502 { 1503 used = true; 1504 mc = m; 1505 } else { 1506 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); 1507 if (mc == NULL) { 1508 sc->sc_if.if_oerrors++; 1509 goto next; 1510 } 1511 } 1512 1513 #ifndef NET_MPSAFE 1514 s = splnet(); 1515 #endif 1516 bridge_enqueue(sc, dst_if, mc, 0); 1517 #ifndef NET_MPSAFE 1518 splx(s); 1519 #endif 1520 1521 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0 && 1522 dst_if != ifp) 1523 { 1524 if (PSLIST_READER_NEXT(bif, 1525 struct bridge_iflist, bif_next) == NULL) 1526 { 1527 used = true; 1528 mc = m; 1529 } else { 1530 mc = m_copym(m, 0, M_COPYALL, 1531 M_DONTWAIT); 1532 if (mc == NULL) { 1533 sc->sc_if.if_oerrors++; 1534 goto next; 1535 } 1536 } 1537 1538 mc->m_pkthdr.rcvif = dst_if; 1539 mc->m_flags &= ~M_PROMISC; 1540 1541 #ifndef NET_MPSAFE 1542 s = splnet(); 1543 #endif 1544 ether_input(dst_if, mc); 1545 #ifndef NET_MPSAFE 1546 splx(s); 1547 #endif 1548 } 1549 1550 next: 1551 BRIDGE_PSZ_RENTER(s); 1552 bridge_release_member(sc, bif, &psref); 1553 1554 /* Guarantee we don't re-enter the loop as we already 1555 * decided we're at the end. */ 1556 if (used) 1557 break; 1558 } 1559 BRIDGE_PSZ_REXIT(s); 1560 1561 if (!used) 1562 m_freem(m); 1563 return (0); 1564 } 1565 1566 sendunicast: 1567 /* 1568 * XXX Spanning tree consideration here? 1569 */ 1570 1571 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1572 m_freem(m); 1573 return (0); 1574 } 1575 1576 #ifndef NET_MPSAFE 1577 s = splnet(); 1578 #endif 1579 bridge_enqueue(sc, dst_if, m, 0); 1580 #ifndef NET_MPSAFE 1581 splx(s); 1582 #endif 1583 1584 return (0); 1585 } 1586 1587 /* 1588 * bridge_start: 1589 * 1590 * Start output on a bridge. 1591 * 1592 * NOTE: This routine should never be called in this implementation. 1593 */ 1594 static void 1595 bridge_start(struct ifnet *ifp) 1596 { 1597 1598 printf("%s: bridge_start() called\n", ifp->if_xname); 1599 } 1600 1601 /* 1602 * bridge_forward: 1603 * 1604 * The forwarding function of the bridge. 1605 */ 1606 static void 1607 bridge_forward(struct bridge_softc *sc, struct mbuf *m) 1608 { 1609 struct bridge_iflist *bif; 1610 struct ifnet *src_if, *dst_if; 1611 struct ether_header *eh; 1612 struct psref psref; 1613 DECLARE_LOCK_VARIABLE; 1614 1615 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1616 return; 1617 1618 src_if = m->m_pkthdr.rcvif; 1619 1620 sc->sc_if.if_ipackets++; 1621 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1622 1623 /* 1624 * Look up the bridge_iflist. 1625 */ 1626 bif = bridge_lookup_member_if(sc, src_if, &psref); 1627 if (bif == NULL) { 1628 /* Interface is not a bridge member (anymore?) */ 1629 m_freem(m); 1630 goto out; 1631 } 1632 1633 if (bif->bif_flags & IFBIF_STP) { 1634 switch (bif->bif_state) { 1635 case BSTP_IFSTATE_BLOCKING: 1636 case BSTP_IFSTATE_LISTENING: 1637 case BSTP_IFSTATE_DISABLED: 1638 m_freem(m); 1639 bridge_release_member(sc, bif, &psref); 1640 goto out; 1641 } 1642 } 1643 1644 eh = mtod(m, struct ether_header *); 1645 1646 /* 1647 * If the interface is learning, and the source 1648 * address is valid and not multicast, record 1649 * the address. 1650 */ 1651 if ((bif->bif_flags & IFBIF_LEARNING) != 0 && 1652 ETHER_IS_MULTICAST(eh->ether_shost) == 0 && 1653 (eh->ether_shost[0] == 0 && 1654 eh->ether_shost[1] == 0 && 1655 eh->ether_shost[2] == 0 && 1656 eh->ether_shost[3] == 0 && 1657 eh->ether_shost[4] == 0 && 1658 eh->ether_shost[5] == 0) == 0) { 1659 (void) bridge_rtupdate(sc, eh->ether_shost, 1660 src_if, 0, IFBAF_DYNAMIC); 1661 } 1662 1663 if ((bif->bif_flags & IFBIF_STP) != 0 && 1664 bif->bif_state == BSTP_IFSTATE_LEARNING) { 1665 m_freem(m); 1666 bridge_release_member(sc, bif, &psref); 1667 goto out; 1668 } 1669 1670 bridge_release_member(sc, bif, &psref); 1671 1672 /* 1673 * At this point, the port either doesn't participate 1674 * in spanning tree or it is in the forwarding state. 1675 */ 1676 1677 /* 1678 * If the packet is unicast, destined for someone on 1679 * "this" side of the bridge, drop it. 1680 */ 1681 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1682 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1683 if (src_if == dst_if) { 1684 m_freem(m); 1685 goto out; 1686 } 1687 } else { 1688 /* ...forward it to all interfaces. */ 1689 sc->sc_if.if_imcasts++; 1690 dst_if = NULL; 1691 } 1692 1693 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, 1694 m->m_pkthdr.rcvif, PFIL_IN) != 0) { 1695 if (m != NULL) 1696 m_freem(m); 1697 goto out; 1698 } 1699 if (m == NULL) 1700 goto out; 1701 1702 if (dst_if == NULL) { 1703 bridge_broadcast(sc, src_if, m); 1704 goto out; 1705 } 1706 1707 /* 1708 * At this point, we're dealing with a unicast frame 1709 * going to a different interface. 1710 */ 1711 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1712 m_freem(m); 1713 goto out; 1714 } 1715 1716 bif = bridge_lookup_member_if(sc, dst_if, &psref); 1717 if (bif == NULL) { 1718 /* Not a member of the bridge (anymore?) */ 1719 m_freem(m); 1720 goto out; 1721 } 1722 1723 if (bif->bif_flags & IFBIF_STP) { 1724 switch (bif->bif_state) { 1725 case BSTP_IFSTATE_DISABLED: 1726 case BSTP_IFSTATE_BLOCKING: 1727 m_freem(m); 1728 bridge_release_member(sc, bif, &psref); 1729 goto out; 1730 } 1731 } 1732 1733 bridge_release_member(sc, bif, &psref); 1734 1735 ACQUIRE_GLOBAL_LOCKS(); 1736 bridge_enqueue(sc, dst_if, m, 1); 1737 RELEASE_GLOBAL_LOCKS(); 1738 out: 1739 /* XXX gcc */ 1740 return; 1741 } 1742 1743 static bool 1744 bstp_state_before_learning(struct bridge_iflist *bif) 1745 { 1746 if (bif->bif_flags & IFBIF_STP) { 1747 switch (bif->bif_state) { 1748 case BSTP_IFSTATE_BLOCKING: 1749 case BSTP_IFSTATE_LISTENING: 1750 case BSTP_IFSTATE_DISABLED: 1751 return true; 1752 } 1753 } 1754 return false; 1755 } 1756 1757 static bool 1758 bridge_ourether(struct bridge_iflist *bif, struct ether_header *eh, int src) 1759 { 1760 uint8_t *ether = src ? eh->ether_shost : eh->ether_dhost; 1761 1762 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), ether, ETHER_ADDR_LEN) == 0 1763 #if NCARP > 0 1764 || (bif->bif_ifp->if_carp && 1765 carp_ourether(bif->bif_ifp->if_carp, eh, IFT_ETHER, src) != NULL) 1766 #endif /* NCARP > 0 */ 1767 ) 1768 return true; 1769 1770 return false; 1771 } 1772 1773 /* 1774 * bridge_input: 1775 * 1776 * Receive input from a member interface. Queue the packet for 1777 * bridging if it is not for us. 1778 */ 1779 static void 1780 bridge_input(struct ifnet *ifp, struct mbuf *m) 1781 { 1782 struct bridge_softc *sc = ifp->if_bridge; 1783 struct bridge_iflist *bif; 1784 struct ether_header *eh; 1785 struct psref psref; 1786 DECLARE_LOCK_VARIABLE; 1787 1788 KASSERT(!cpu_intr_p()); 1789 1790 if (__predict_false(sc == NULL) || 1791 (sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1792 ACQUIRE_GLOBAL_LOCKS(); 1793 ether_input(ifp, m); 1794 RELEASE_GLOBAL_LOCKS(); 1795 return; 1796 } 1797 1798 bif = bridge_lookup_member_if(sc, ifp, &psref); 1799 if (bif == NULL) { 1800 ACQUIRE_GLOBAL_LOCKS(); 1801 ether_input(ifp, m); 1802 RELEASE_GLOBAL_LOCKS(); 1803 return; 1804 } 1805 1806 eh = mtod(m, struct ether_header *); 1807 1808 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1809 if (memcmp(etherbroadcastaddr, 1810 eh->ether_dhost, ETHER_ADDR_LEN) == 0) 1811 m->m_flags |= M_BCAST; 1812 else 1813 m->m_flags |= M_MCAST; 1814 } 1815 1816 /* 1817 * A 'fast' path for packets addressed to interfaces that are 1818 * part of this bridge. 1819 */ 1820 if (!(m->m_flags & (M_BCAST|M_MCAST)) && 1821 !bstp_state_before_learning(bif)) { 1822 struct bridge_iflist *_bif; 1823 struct ifnet *_ifp = NULL; 1824 int s; 1825 struct psref _psref; 1826 1827 BRIDGE_PSZ_RENTER(s); 1828 BRIDGE_IFLIST_READER_FOREACH(_bif, sc) { 1829 /* It is destined for us. */ 1830 if (bridge_ourether(_bif, eh, 0)) { 1831 bridge_acquire_member(sc, _bif, &_psref); 1832 BRIDGE_PSZ_REXIT(s); 1833 if (_bif->bif_flags & IFBIF_LEARNING) 1834 (void) bridge_rtupdate(sc, 1835 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); 1836 _ifp = m->m_pkthdr.rcvif = _bif->bif_ifp; 1837 bridge_release_member(sc, _bif, &_psref); 1838 goto out; 1839 } 1840 1841 /* We just received a packet that we sent out. */ 1842 if (bridge_ourether(_bif, eh, 1)) 1843 break; 1844 } 1845 BRIDGE_PSZ_REXIT(s); 1846 out: 1847 1848 if (_bif != NULL) { 1849 bridge_release_member(sc, bif, &psref); 1850 if (_ifp != NULL) { 1851 m->m_flags &= ~M_PROMISC; 1852 ACQUIRE_GLOBAL_LOCKS(); 1853 ether_input(_ifp, m); 1854 RELEASE_GLOBAL_LOCKS(); 1855 } else 1856 m_freem(m); 1857 return; 1858 } 1859 } 1860 1861 /* Tap off 802.1D packets; they do not get forwarded. */ 1862 if (bif->bif_flags & IFBIF_STP && 1863 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) { 1864 bstp_input(sc, bif, m); 1865 bridge_release_member(sc, bif, &psref); 1866 return; 1867 } 1868 1869 /* 1870 * A normal switch would discard the packet here, but that's not what 1871 * we've done historically. This also prevents some obnoxious behaviour. 1872 */ 1873 if (bstp_state_before_learning(bif)) { 1874 bridge_release_member(sc, bif, &psref); 1875 ACQUIRE_GLOBAL_LOCKS(); 1876 ether_input(ifp, m); 1877 RELEASE_GLOBAL_LOCKS(); 1878 return; 1879 } 1880 1881 bridge_release_member(sc, bif, &psref); 1882 1883 bridge_forward(sc, m); 1884 } 1885 1886 /* 1887 * bridge_broadcast: 1888 * 1889 * Send a frame to all interfaces that are members of 1890 * the bridge, except for the one on which the packet 1891 * arrived. 1892 */ 1893 static void 1894 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 1895 struct mbuf *m) 1896 { 1897 struct bridge_iflist *bif; 1898 struct mbuf *mc; 1899 struct ifnet *dst_if; 1900 bool bmcast; 1901 int s; 1902 DECLARE_LOCK_VARIABLE; 1903 1904 bmcast = m->m_flags & (M_BCAST|M_MCAST); 1905 1906 BRIDGE_PSZ_RENTER(s); 1907 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 1908 struct psref psref; 1909 1910 bridge_acquire_member(sc, bif, &psref); 1911 BRIDGE_PSZ_REXIT(s); 1912 1913 dst_if = bif->bif_ifp; 1914 1915 if (bif->bif_flags & IFBIF_STP) { 1916 switch (bif->bif_state) { 1917 case BSTP_IFSTATE_BLOCKING: 1918 case BSTP_IFSTATE_DISABLED: 1919 goto next; 1920 } 1921 } 1922 1923 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast) 1924 goto next; 1925 1926 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1927 goto next; 1928 1929 if (dst_if != src_if) { 1930 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1931 if (mc == NULL) { 1932 sc->sc_if.if_oerrors++; 1933 goto next; 1934 } 1935 ACQUIRE_GLOBAL_LOCKS(); 1936 bridge_enqueue(sc, dst_if, mc, 1); 1937 RELEASE_GLOBAL_LOCKS(); 1938 } 1939 1940 if (bmcast) { 1941 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1942 if (mc == NULL) { 1943 sc->sc_if.if_oerrors++; 1944 goto next; 1945 } 1946 1947 mc->m_pkthdr.rcvif = dst_if; 1948 mc->m_flags &= ~M_PROMISC; 1949 1950 ACQUIRE_GLOBAL_LOCKS(); 1951 ether_input(dst_if, mc); 1952 RELEASE_GLOBAL_LOCKS(); 1953 } 1954 next: 1955 BRIDGE_PSZ_RENTER(s); 1956 bridge_release_member(sc, bif, &psref); 1957 } 1958 BRIDGE_PSZ_REXIT(s); 1959 1960 m_freem(m); 1961 } 1962 1963 static int 1964 bridge_rtalloc(struct bridge_softc *sc, const uint8_t *dst, 1965 struct bridge_rtnode **brtp) 1966 { 1967 struct bridge_rtnode *brt; 1968 int error; 1969 1970 if (sc->sc_brtcnt >= sc->sc_brtmax) 1971 return ENOSPC; 1972 1973 /* 1974 * Allocate a new bridge forwarding node, and 1975 * initialize the expiration time and Ethernet 1976 * address. 1977 */ 1978 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT); 1979 if (brt == NULL) 1980 return ENOMEM; 1981 1982 memset(brt, 0, sizeof(*brt)); 1983 brt->brt_expire = time_uptime + sc->sc_brttimeout; 1984 brt->brt_flags = IFBAF_DYNAMIC; 1985 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 1986 1987 BRIDGE_RT_LOCK(sc); 1988 error = bridge_rtnode_insert(sc, brt); 1989 BRIDGE_RT_UNLOCK(sc); 1990 1991 if (error != 0) { 1992 pool_put(&bridge_rtnode_pool, brt); 1993 return error; 1994 } 1995 1996 *brtp = brt; 1997 return 0; 1998 } 1999 2000 /* 2001 * bridge_rtupdate: 2002 * 2003 * Add a bridge routing entry. 2004 */ 2005 static int 2006 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, 2007 struct ifnet *dst_if, int setflags, uint8_t flags) 2008 { 2009 struct bridge_rtnode *brt; 2010 int s; 2011 2012 again: 2013 /* 2014 * A route for this destination might already exist. If so, 2015 * update it, otherwise create a new one. 2016 */ 2017 BRIDGE_RT_RENTER(s); 2018 brt = bridge_rtnode_lookup(sc, dst); 2019 2020 if (brt != NULL) { 2021 brt->brt_ifp = dst_if; 2022 if (setflags) { 2023 brt->brt_flags = flags; 2024 if (flags & IFBAF_STATIC) 2025 brt->brt_expire = 0; 2026 else 2027 brt->brt_expire = time_uptime + sc->sc_brttimeout; 2028 } else { 2029 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 2030 brt->brt_expire = time_uptime + sc->sc_brttimeout; 2031 } 2032 } 2033 BRIDGE_RT_REXIT(s); 2034 2035 if (brt == NULL) { 2036 int r; 2037 2038 r = bridge_rtalloc(sc, dst, &brt); 2039 if (r != 0) 2040 return r; 2041 goto again; 2042 } 2043 2044 return 0; 2045 } 2046 2047 /* 2048 * bridge_rtlookup: 2049 * 2050 * Lookup the destination interface for an address. 2051 */ 2052 static struct ifnet * 2053 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr) 2054 { 2055 struct bridge_rtnode *brt; 2056 struct ifnet *ifs = NULL; 2057 int s; 2058 2059 BRIDGE_RT_RENTER(s); 2060 brt = bridge_rtnode_lookup(sc, addr); 2061 if (brt != NULL) 2062 ifs = brt->brt_ifp; 2063 BRIDGE_RT_REXIT(s); 2064 2065 return ifs; 2066 } 2067 2068 typedef bool (*bridge_iterate_cb_t) 2069 (struct bridge_softc *, struct bridge_rtnode *, bool *, void *); 2070 2071 /* 2072 * bridge_rtlist_iterate_remove: 2073 * 2074 * It iterates on sc->sc_rtlist and removes rtnodes of it which func 2075 * callback judges to remove. Removals of rtnodes are done in a manner 2076 * of pserialize. To this end, all kmem_* operations are placed out of 2077 * mutexes. 2078 */ 2079 static void 2080 bridge_rtlist_iterate_remove(struct bridge_softc *sc, bridge_iterate_cb_t func, void *arg) 2081 { 2082 struct bridge_rtnode *brt, *nbrt; 2083 struct bridge_rtnode **brt_list; 2084 int i, count; 2085 2086 retry: 2087 count = sc->sc_brtcnt; 2088 if (count == 0) 2089 return; 2090 brt_list = kmem_alloc(sizeof(*brt_list) * count, KM_SLEEP); 2091 2092 BRIDGE_RT_LOCK(sc); 2093 if (__predict_false(sc->sc_brtcnt > count)) { 2094 /* The rtnodes increased, we need more memory */ 2095 BRIDGE_RT_UNLOCK(sc); 2096 kmem_free(brt_list, sizeof(*brt_list) * count); 2097 goto retry; 2098 } 2099 2100 i = 0; 2101 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 2102 bool need_break = false; 2103 if (func(sc, brt, &need_break, arg)) { 2104 bridge_rtnode_remove(sc, brt); 2105 brt_list[i++] = brt; 2106 } 2107 if (need_break) 2108 break; 2109 } 2110 2111 if (i > 0) 2112 BRIDGE_RT_PSZ_PERFORM(sc); 2113 BRIDGE_RT_UNLOCK(sc); 2114 2115 while (--i >= 0) 2116 bridge_rtnode_destroy(brt_list[i]); 2117 2118 kmem_free(brt_list, sizeof(*brt_list) * count); 2119 } 2120 2121 static bool 2122 bridge_rttrim0_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2123 bool *need_break, void *arg) 2124 { 2125 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 2126 /* Take into account of the subsequent removal */ 2127 if ((sc->sc_brtcnt - 1) <= sc->sc_brtmax) 2128 *need_break = true; 2129 return true; 2130 } else 2131 return false; 2132 } 2133 2134 static void 2135 bridge_rttrim0(struct bridge_softc *sc) 2136 { 2137 bridge_rtlist_iterate_remove(sc, bridge_rttrim0_cb, NULL); 2138 } 2139 2140 /* 2141 * bridge_rttrim: 2142 * 2143 * Trim the routine table so that we have a number 2144 * of routing entries less than or equal to the 2145 * maximum number. 2146 */ 2147 static void 2148 bridge_rttrim(struct bridge_softc *sc) 2149 { 2150 2151 /* Make sure we actually need to do this. */ 2152 if (sc->sc_brtcnt <= sc->sc_brtmax) 2153 return; 2154 2155 /* Force an aging cycle; this might trim enough addresses. */ 2156 bridge_rtage(sc); 2157 if (sc->sc_brtcnt <= sc->sc_brtmax) 2158 return; 2159 2160 bridge_rttrim0(sc); 2161 2162 return; 2163 } 2164 2165 /* 2166 * bridge_timer: 2167 * 2168 * Aging timer for the bridge. 2169 */ 2170 static void 2171 bridge_timer(void *arg) 2172 { 2173 struct bridge_softc *sc = arg; 2174 2175 workqueue_enqueue(sc->sc_rtage_wq, &sc->sc_rtage_wk, NULL); 2176 } 2177 2178 static void 2179 bridge_rtage_work(struct work *wk, void *arg) 2180 { 2181 struct bridge_softc *sc = arg; 2182 2183 KASSERT(wk == &sc->sc_rtage_wk); 2184 2185 bridge_rtage(sc); 2186 2187 if (sc->sc_if.if_flags & IFF_RUNNING) 2188 callout_reset(&sc->sc_brcallout, 2189 bridge_rtable_prune_period * hz, bridge_timer, sc); 2190 } 2191 2192 static bool 2193 bridge_rtage_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2194 bool *need_break, void *arg) 2195 { 2196 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && 2197 time_uptime >= brt->brt_expire) 2198 return true; 2199 else 2200 return false; 2201 } 2202 2203 /* 2204 * bridge_rtage: 2205 * 2206 * Perform an aging cycle. 2207 */ 2208 static void 2209 bridge_rtage(struct bridge_softc *sc) 2210 { 2211 bridge_rtlist_iterate_remove(sc, bridge_rtage_cb, NULL); 2212 } 2213 2214 2215 static bool 2216 bridge_rtflush_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2217 bool *need_break, void *arg) 2218 { 2219 int full = *(int*)arg; 2220 2221 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 2222 return true; 2223 else 2224 return false; 2225 } 2226 2227 /* 2228 * bridge_rtflush: 2229 * 2230 * Remove all dynamic addresses from the bridge. 2231 */ 2232 static void 2233 bridge_rtflush(struct bridge_softc *sc, int full) 2234 { 2235 bridge_rtlist_iterate_remove(sc, bridge_rtflush_cb, &full); 2236 } 2237 2238 /* 2239 * bridge_rtdaddr: 2240 * 2241 * Remove an address from the table. 2242 */ 2243 static int 2244 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr) 2245 { 2246 struct bridge_rtnode *brt; 2247 2248 BRIDGE_RT_LOCK(sc); 2249 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) { 2250 BRIDGE_RT_UNLOCK(sc); 2251 return ENOENT; 2252 } 2253 bridge_rtnode_remove(sc, brt); 2254 BRIDGE_RT_PSZ_PERFORM(sc); 2255 BRIDGE_RT_UNLOCK(sc); 2256 2257 bridge_rtnode_destroy(brt); 2258 2259 return 0; 2260 } 2261 2262 /* 2263 * bridge_rtdelete: 2264 * 2265 * Delete routes to a speicifc member interface. 2266 */ 2267 static void 2268 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp) 2269 { 2270 struct bridge_rtnode *brt; 2271 2272 BRIDGE_RT_LOCK(sc); 2273 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 2274 if (brt->brt_ifp == ifp) 2275 break; 2276 } 2277 if (brt == NULL) { 2278 BRIDGE_RT_UNLOCK(sc); 2279 return; 2280 } 2281 bridge_rtnode_remove(sc, brt); 2282 BRIDGE_RT_PSZ_PERFORM(sc); 2283 BRIDGE_RT_UNLOCK(sc); 2284 2285 bridge_rtnode_destroy(brt); 2286 } 2287 2288 /* 2289 * bridge_rtable_init: 2290 * 2291 * Initialize the route table for this bridge. 2292 */ 2293 static void 2294 bridge_rtable_init(struct bridge_softc *sc) 2295 { 2296 int i; 2297 2298 sc->sc_rthash = kmem_alloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 2299 KM_SLEEP); 2300 2301 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++) 2302 LIST_INIT(&sc->sc_rthash[i]); 2303 2304 sc->sc_rthash_key = cprng_fast32(); 2305 2306 LIST_INIT(&sc->sc_rtlist); 2307 2308 sc->sc_rtlist_psz = pserialize_create(); 2309 sc->sc_rtlist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 2310 } 2311 2312 /* 2313 * bridge_rtable_fini: 2314 * 2315 * Deconstruct the route table for this bridge. 2316 */ 2317 static void 2318 bridge_rtable_fini(struct bridge_softc *sc) 2319 { 2320 2321 kmem_free(sc->sc_rthash, sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE); 2322 if (sc->sc_rtlist_lock) 2323 mutex_obj_free(sc->sc_rtlist_lock); 2324 if (sc->sc_rtlist_psz) 2325 pserialize_destroy(sc->sc_rtlist_psz); 2326 } 2327 2328 /* 2329 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 2330 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 2331 */ 2332 #define mix(a, b, c) \ 2333 do { \ 2334 a -= b; a -= c; a ^= (c >> 13); \ 2335 b -= c; b -= a; b ^= (a << 8); \ 2336 c -= a; c -= b; c ^= (b >> 13); \ 2337 a -= b; a -= c; a ^= (c >> 12); \ 2338 b -= c; b -= a; b ^= (a << 16); \ 2339 c -= a; c -= b; c ^= (b >> 5); \ 2340 a -= b; a -= c; a ^= (c >> 3); \ 2341 b -= c; b -= a; b ^= (a << 10); \ 2342 c -= a; c -= b; c ^= (b >> 15); \ 2343 } while (/*CONSTCOND*/0) 2344 2345 static inline uint32_t 2346 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr) 2347 { 2348 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; 2349 2350 b += addr[5] << 8; 2351 b += addr[4]; 2352 a += addr[3] << 24; 2353 a += addr[2] << 16; 2354 a += addr[1] << 8; 2355 a += addr[0]; 2356 2357 mix(a, b, c); 2358 2359 return (c & BRIDGE_RTHASH_MASK); 2360 } 2361 2362 #undef mix 2363 2364 /* 2365 * bridge_rtnode_lookup: 2366 * 2367 * Look up a bridge route node for the specified destination. 2368 */ 2369 static struct bridge_rtnode * 2370 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr) 2371 { 2372 struct bridge_rtnode *brt; 2373 uint32_t hash; 2374 int dir; 2375 2376 hash = bridge_rthash(sc, addr); 2377 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { 2378 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN); 2379 if (dir == 0) 2380 return (brt); 2381 if (dir > 0) 2382 return (NULL); 2383 } 2384 2385 return (NULL); 2386 } 2387 2388 /* 2389 * bridge_rtnode_insert: 2390 * 2391 * Insert the specified bridge node into the route table. We 2392 * assume the entry is not already in the table. 2393 */ 2394 static int 2395 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) 2396 { 2397 struct bridge_rtnode *lbrt; 2398 uint32_t hash; 2399 int dir; 2400 2401 KASSERT(BRIDGE_RT_LOCKED(sc)); 2402 2403 hash = bridge_rthash(sc, brt->brt_addr); 2404 2405 lbrt = LIST_FIRST(&sc->sc_rthash[hash]); 2406 if (lbrt == NULL) { 2407 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); 2408 goto out; 2409 } 2410 2411 do { 2412 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN); 2413 if (dir == 0) 2414 return (EEXIST); 2415 if (dir > 0) { 2416 LIST_INSERT_BEFORE(lbrt, brt, brt_hash); 2417 goto out; 2418 } 2419 if (LIST_NEXT(lbrt, brt_hash) == NULL) { 2420 LIST_INSERT_AFTER(lbrt, brt, brt_hash); 2421 goto out; 2422 } 2423 lbrt = LIST_NEXT(lbrt, brt_hash); 2424 } while (lbrt != NULL); 2425 2426 #ifdef DIAGNOSTIC 2427 panic("bridge_rtnode_insert: impossible"); 2428 #endif 2429 2430 out: 2431 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); 2432 sc->sc_brtcnt++; 2433 2434 return (0); 2435 } 2436 2437 /* 2438 * bridge_rtnode_remove: 2439 * 2440 * Remove a bridge rtnode from the rthash and the rtlist of a bridge. 2441 */ 2442 static void 2443 bridge_rtnode_remove(struct bridge_softc *sc, struct bridge_rtnode *brt) 2444 { 2445 2446 KASSERT(BRIDGE_RT_LOCKED(sc)); 2447 2448 LIST_REMOVE(brt, brt_hash); 2449 LIST_REMOVE(brt, brt_list); 2450 sc->sc_brtcnt--; 2451 } 2452 2453 /* 2454 * bridge_rtnode_destroy: 2455 * 2456 * Destroy a bridge rtnode. 2457 */ 2458 static void 2459 bridge_rtnode_destroy(struct bridge_rtnode *brt) 2460 { 2461 2462 pool_put(&bridge_rtnode_pool, brt); 2463 } 2464 2465 #if defined(BRIDGE_IPF) 2466 extern pfil_head_t *inet_pfil_hook; /* XXX */ 2467 extern pfil_head_t *inet6_pfil_hook; /* XXX */ 2468 2469 /* 2470 * Send bridge packets through IPF if they are one of the types IPF can deal 2471 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without 2472 * question.) 2473 */ 2474 static int 2475 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) 2476 { 2477 int snap, error; 2478 struct ether_header *eh1, eh2; 2479 struct llc llc1; 2480 uint16_t ether_type; 2481 2482 snap = 0; 2483 error = -1; /* Default error if not error == 0 */ 2484 eh1 = mtod(*mp, struct ether_header *); 2485 ether_type = ntohs(eh1->ether_type); 2486 2487 /* 2488 * Check for SNAP/LLC. 2489 */ 2490 if (ether_type < ETHERMTU) { 2491 struct llc *llc2 = (struct llc *)(eh1 + 1); 2492 2493 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && 2494 llc2->llc_dsap == LLC_SNAP_LSAP && 2495 llc2->llc_ssap == LLC_SNAP_LSAP && 2496 llc2->llc_control == LLC_UI) { 2497 ether_type = htons(llc2->llc_un.type_snap.ether_type); 2498 snap = 1; 2499 } 2500 } 2501 2502 /* 2503 * If we're trying to filter bridge traffic, don't look at anything 2504 * other than IP and ARP traffic. If the filter doesn't understand 2505 * IPv6, don't allow IPv6 through the bridge either. This is lame 2506 * since if we really wanted, say, an AppleTalk filter, we are hosed, 2507 * but of course we don't have an AppleTalk filter to begin with. 2508 * (Note that since IPF doesn't understand ARP it will pass *ALL* 2509 * ARP traffic.) 2510 */ 2511 switch (ether_type) { 2512 case ETHERTYPE_ARP: 2513 case ETHERTYPE_REVARP: 2514 return 0; /* Automatically pass */ 2515 case ETHERTYPE_IP: 2516 # ifdef INET6 2517 case ETHERTYPE_IPV6: 2518 # endif /* INET6 */ 2519 break; 2520 default: 2521 goto bad; 2522 } 2523 2524 /* Strip off the Ethernet header and keep a copy. */ 2525 m_copydata(*mp, 0, ETHER_HDR_LEN, (void *) &eh2); 2526 m_adj(*mp, ETHER_HDR_LEN); 2527 2528 /* Strip off snap header, if present */ 2529 if (snap) { 2530 m_copydata(*mp, 0, sizeof(struct llc), (void *) &llc1); 2531 m_adj(*mp, sizeof(struct llc)); 2532 } 2533 2534 /* 2535 * Check basic packet sanity and run IPF through pfil. 2536 */ 2537 KASSERT(!cpu_intr_p()); 2538 switch (ether_type) 2539 { 2540 case ETHERTYPE_IP : 2541 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0; 2542 if (error == 0) 2543 error = pfil_run_hooks(inet_pfil_hook, mp, ifp, dir); 2544 break; 2545 # ifdef INET6 2546 case ETHERTYPE_IPV6 : 2547 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0; 2548 if (error == 0) 2549 error = pfil_run_hooks(inet6_pfil_hook, mp, ifp, dir); 2550 break; 2551 # endif 2552 default : 2553 error = 0; 2554 break; 2555 } 2556 2557 if (*mp == NULL) 2558 return error; 2559 if (error != 0) 2560 goto bad; 2561 2562 error = -1; 2563 2564 /* 2565 * Finally, put everything back the way it was and return 2566 */ 2567 if (snap) { 2568 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT); 2569 if (*mp == NULL) 2570 return error; 2571 bcopy(&llc1, mtod(*mp, void *), sizeof(struct llc)); 2572 } 2573 2574 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 2575 if (*mp == NULL) 2576 return error; 2577 bcopy(&eh2, mtod(*mp, void *), ETHER_HDR_LEN); 2578 2579 return 0; 2580 2581 bad: 2582 m_freem(*mp); 2583 *mp = NULL; 2584 return error; 2585 } 2586 2587 /* 2588 * Perform basic checks on header size since 2589 * IPF assumes ip_input has already processed 2590 * it for it. Cut-and-pasted from ip_input.c. 2591 * Given how simple the IPv6 version is, 2592 * does the IPv4 version really need to be 2593 * this complicated? 2594 * 2595 * XXX Should we update ipstat here, or not? 2596 * XXX Right now we update ipstat but not 2597 * XXX csum_counter. 2598 */ 2599 static int 2600 bridge_ip_checkbasic(struct mbuf **mp) 2601 { 2602 struct mbuf *m = *mp; 2603 struct ip *ip; 2604 int len, hlen; 2605 2606 if (*mp == NULL) 2607 return -1; 2608 2609 if (IP_HDR_ALIGNED_P(mtod(m, void *)) == 0) { 2610 if ((m = m_copyup(m, sizeof(struct ip), 2611 (max_linkhdr + 3) & ~3)) == NULL) { 2612 /* XXXJRT new stat, please */ 2613 ip_statinc(IP_STAT_TOOSMALL); 2614 goto bad; 2615 } 2616 } else if (__predict_false(m->m_len < sizeof (struct ip))) { 2617 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { 2618 ip_statinc(IP_STAT_TOOSMALL); 2619 goto bad; 2620 } 2621 } 2622 ip = mtod(m, struct ip *); 2623 if (ip == NULL) goto bad; 2624 2625 if (ip->ip_v != IPVERSION) { 2626 ip_statinc(IP_STAT_BADVERS); 2627 goto bad; 2628 } 2629 hlen = ip->ip_hl << 2; 2630 if (hlen < sizeof(struct ip)) { /* minimum header length */ 2631 ip_statinc(IP_STAT_BADHLEN); 2632 goto bad; 2633 } 2634 if (hlen > m->m_len) { 2635 if ((m = m_pullup(m, hlen)) == 0) { 2636 ip_statinc(IP_STAT_BADHLEN); 2637 goto bad; 2638 } 2639 ip = mtod(m, struct ip *); 2640 if (ip == NULL) goto bad; 2641 } 2642 2643 switch (m->m_pkthdr.csum_flags & 2644 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) | 2645 M_CSUM_IPv4_BAD)) { 2646 case M_CSUM_IPv4|M_CSUM_IPv4_BAD: 2647 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */ 2648 goto bad; 2649 2650 case M_CSUM_IPv4: 2651 /* Checksum was okay. */ 2652 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */ 2653 break; 2654 2655 default: 2656 /* Must compute it ourselves. */ 2657 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */ 2658 if (in_cksum(m, hlen) != 0) 2659 goto bad; 2660 break; 2661 } 2662 2663 /* Retrieve the packet length. */ 2664 len = ntohs(ip->ip_len); 2665 2666 /* 2667 * Check for additional length bogosity 2668 */ 2669 if (len < hlen) { 2670 ip_statinc(IP_STAT_BADLEN); 2671 goto bad; 2672 } 2673 2674 /* 2675 * Check that the amount of data in the buffers 2676 * is as at least much as the IP header would have us expect. 2677 * Drop packet if shorter than we expect. 2678 */ 2679 if (m->m_pkthdr.len < len) { 2680 ip_statinc(IP_STAT_TOOSHORT); 2681 goto bad; 2682 } 2683 2684 /* Checks out, proceed */ 2685 *mp = m; 2686 return 0; 2687 2688 bad: 2689 *mp = m; 2690 return -1; 2691 } 2692 2693 # ifdef INET6 2694 /* 2695 * Same as above, but for IPv6. 2696 * Cut-and-pasted from ip6_input.c. 2697 * XXX Should we update ip6stat, or not? 2698 */ 2699 static int 2700 bridge_ip6_checkbasic(struct mbuf **mp) 2701 { 2702 struct mbuf *m = *mp; 2703 struct ip6_hdr *ip6; 2704 2705 /* 2706 * If the IPv6 header is not aligned, slurp it up into a new 2707 * mbuf with space for link headers, in the event we forward 2708 * it. Otherwise, if it is aligned, make sure the entire base 2709 * IPv6 header is in the first mbuf of the chain. 2710 */ 2711 if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { 2712 struct ifnet *inifp = m->m_pkthdr.rcvif; 2713 if ((m = m_copyup(m, sizeof(struct ip6_hdr), 2714 (max_linkhdr + 3) & ~3)) == NULL) { 2715 /* XXXJRT new stat, please */ 2716 ip6_statinc(IP6_STAT_TOOSMALL); 2717 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2718 goto bad; 2719 } 2720 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { 2721 struct ifnet *inifp = m->m_pkthdr.rcvif; 2722 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 2723 ip6_statinc(IP6_STAT_TOOSMALL); 2724 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 2725 goto bad; 2726 } 2727 } 2728 2729 ip6 = mtod(m, struct ip6_hdr *); 2730 2731 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 2732 ip6_statinc(IP6_STAT_BADVERS); 2733 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 2734 goto bad; 2735 } 2736 2737 /* Checks out, proceed */ 2738 *mp = m; 2739 return 0; 2740 2741 bad: 2742 *mp = m; 2743 return -1; 2744 } 2745 # endif /* INET6 */ 2746 #endif /* BRIDGE_IPF */ 2747