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