1/* 2 * Copyright (c) 2004-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $ */ 30/* 31 * Copyright 2001 Wasabi Systems, Inc. 32 * All rights reserved. 33 * 34 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed for the NetBSD Project by 47 * Wasabi Systems, Inc. 48 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 49 * or promote products derived from this software without specific prior 50 * written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65/* 66 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 67 * All rights reserved. 68 * 69 * Redistribution and use in source and binary forms, with or without 70 * modification, are permitted provided that the following conditions 71 * are met: 72 * 1. Redistributions of source code must retain the above copyright 73 * notice, this list of conditions and the following disclaimer. 74 * 2. Redistributions in binary form must reproduce the above copyright 75 * notice, this list of conditions and the following disclaimer in the 76 * documentation and/or other materials provided with the distribution. 77 * 78 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 79 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 80 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 81 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 82 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 83 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 84 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 86 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 87 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 88 * POSSIBILITY OF SUCH DAMAGE. 89 * 90 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp 91 */ 92 93/* 94 * Network interface bridge support. 95 * 96 * TODO: 97 * 98 * - Currently only supports Ethernet-like interfaces (Ethernet, 99 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way 100 * to bridge other types of interfaces (FDDI-FDDI, and maybe 101 * consider heterogenous bridges). 102 * 103 * - GIF isn't handled due to the lack of IPPROTO_ETHERIP support. 104 */ 105 106#include <sys/cdefs.h> 107 108#define BRIDGE_DEBUG 1 109 110#include <sys/param.h> 111#include <sys/mbuf.h> 112#include <sys/malloc.h> 113#include <sys/protosw.h> 114#include <sys/systm.h> 115#include <sys/time.h> 116#include <sys/socket.h> /* for net/if.h */ 117#include <sys/sockio.h> 118#include <sys/kernel.h> 119#include <sys/random.h> 120#include <sys/syslog.h> 121#include <sys/sysctl.h> 122#include <sys/proc.h> 123#include <sys/lock.h> 124#include <sys/mcache.h> 125 126#include <sys/kauth.h> 127 128#include <kern/thread_call.h> 129 130#include <libkern/libkern.h> 131 132#include <kern/zalloc.h> 133 134#if NBPFILTER > 0 135#include <net/bpf.h> 136#endif 137#include <net/if.h> 138#include <net/if_dl.h> 139#include <net/if_types.h> 140#include <net/if_var.h> 141#include <net/if_media.h> 142 143#include <netinet/in.h> /* for struct arpcom */ 144#include <netinet/in_systm.h> 145#include <netinet/in_var.h> 146#include <netinet/ip.h> 147#include <netinet/ip_var.h> 148#if INET6 149#include <netinet/ip6.h> 150#include <netinet6/ip6_var.h> 151#endif 152#ifdef DEV_CARP 153#include <netinet/ip_carp.h> 154#endif 155#include <netinet/if_ether.h> /* for struct arpcom */ 156#include <net/bridgestp.h> 157#include <net/if_bridgevar.h> 158#include <net/if_llc.h> 159#if NVLAN > 0 160#include <net/if_vlan_var.h> 161#endif /* NVLAN > 0 */ 162 163#include <net/if_ether.h> 164#include <net/dlil.h> 165#include <net/kpi_interfacefilter.h> 166 167#include <net/route.h> 168#ifdef PFIL_HOOKS 169#include <netinet/ip_fw2.h> 170#include <netinet/ip_dummynet.h> 171#endif /* PFIL_HOOKS */ 172#include <dev/random/randomdev.h> 173 174#if BRIDGE_DEBUG 175#define BR_DBGF_LIFECYCLE 0x0001 176#define BR_DBGF_INPUT 0x0002 177#define BR_DBGF_OUTPPUT 0x0004 178#define BR_DBGF_RT_TABLE 0x0008 179#define BR_DBGF_DELAYED_CALL 0x0010 180#define BR_DBGF_IOCTL 0x0020 181#define BR_DBGF_MBUF 0x0040 182#define BR_DBGF_MCAST 0x0080 183#endif /* BRIDGE_DEBUG */ 184 185#define _BRIDGE_LOCK(_sc) lck_mtx_lock(&(_sc)->sc_mtx) 186#define _BRIDGE_UNLOCK(_sc) lck_mtx_unlock(&(_sc)->sc_mtx) 187#define BRIDGE_LOCK_ASSERT_HELD(_sc) \ 188 lck_mtx_assert(&(_sc)->sc_mtx, LCK_MTX_ASSERT_OWNED) 189#define BRIDGE_LOCK_ASSERT_NOTHELD(_sc) \ 190 lck_mtx_assert(&(_sc)->sc_mtx, LCK_MTX_ASSERT_NOTOWNED) 191 192#if BRIDGE_DEBUG 193 194#define BR_LCKDBG_MAX 4 195 196#define BRIDGE_LOCK(_sc) bridge_lock(_sc) 197#define BRIDGE_UNLOCK(_sc) bridge_unlock(_sc) 198#define BRIDGE_LOCK2REF(_sc, _err) _err = bridge_lock2ref(_sc) 199#define BRIDGE_UNREF(_sc) bridge_unref(_sc) 200#define BRIDGE_XLOCK(_sc) bridge_xlock(_sc) 201#define BRIDGE_XDROP(_sc) bridge_xdrop(_sc) 202 203#else /* !BRIDGE_DEBUG */ 204 205#define BRIDGE_LOCK(_sc) _BRIDGE_LOCK(_sc) 206#define BRIDGE_UNLOCK(_sc) _BRIDGE_UNLOCK(_sc) 207#define BRIDGE_LOCK2REF(_sc, _err) do { \ 208 BRIDGE_LOCK_ASSERT_HELD(_sc); \ 209 if ((_sc)->sc_iflist_xcnt > 0) \ 210 (_err) = EBUSY; \ 211 else \ 212 (_sc)->sc_iflist_ref++; \ 213 _BRIDGE_UNLOCK(_sc); \ 214} while (0) 215#define BRIDGE_UNREF(_sc) do { \ 216 _BRIDGE_LOCK(_sc); \ 217 (_sc)->sc_iflist_ref--; \ 218 if (((_sc)->sc_iflist_xcnt > 0) && ((_sc)->sc_iflist_ref == 0)) { \ 219 _BRIDGE_UNLOCK(_sc); \ 220 wakeup(&(_sc)->sc_cv); \ 221 } else \ 222 _BRIDGE_UNLOCK(_sc); \ 223} while (0) 224#define BRIDGE_XLOCK(_sc) do { \ 225 BRIDGE_LOCK_ASSERT_HELD(_sc); \ 226 (_sc)->sc_iflist_xcnt++; \ 227 while ((_sc)->sc_iflist_ref > 0) \ 228 msleep(&(_sc)->sc_cv, &(_sc)->sc_mtx, PZERO, \ 229 "BRIDGE_XLOCK", NULL); \ 230} while (0) 231#define BRIDGE_XDROP(_sc) do { \ 232 BRIDGE_LOCK_ASSERT_HELD(_sc); \ 233 (_sc)->sc_iflist_xcnt--; \ 234} while (0) 235 236#endif /* BRIDGE_DEBUG */ 237 238#if NBPFILTER > 0 239#define BRIDGE_BPF_MTAP_INPUT(sc, m) \ 240 if (sc->sc_bpf_input) \ 241 bridge_bpf_input(sc->sc_ifp, m) 242#else /* NBPFILTER */ 243#define BRIDGE_BPF_MTAP_INPUT(ifp, m) 244#endif /* NBPFILTER */ 245 246/* 247 * Initial size of the route hash table. Must be a power of two. 248 */ 249#ifndef BRIDGE_RTHASH_SIZE 250#define BRIDGE_RTHASH_SIZE 16 251#endif 252 253/* 254 * Maximum size of the routing hash table 255 */ 256#define BRIDGE_RTHASH_SIZE_MAX 2048 257 258#define BRIDGE_RTHASH_MASK(sc) ((sc)->sc_rthash_size - 1) 259 260/* 261 * Maximum number of addresses to cache. 262 */ 263#ifndef BRIDGE_RTABLE_MAX 264#define BRIDGE_RTABLE_MAX 100 265#endif 266 267 268/* 269 * Timeout (in seconds) for entries learned dynamically. 270 */ 271#ifndef BRIDGE_RTABLE_TIMEOUT 272#define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */ 273#endif 274 275/* 276 * Number of seconds between walks of the route list. 277 */ 278#ifndef BRIDGE_RTABLE_PRUNE_PERIOD 279#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60) 280#endif 281 282/* 283 * List of capabilities to possibly mask on the member interface. 284 */ 285#define BRIDGE_IFCAPS_MASK (IFCAP_TOE|IFCAP_TSO|IFCAP_TXCSUM) 286/* 287 * List of capabilities to disable on the member interface. 288 */ 289#define BRIDGE_IFCAPS_STRIP IFCAP_LRO 290 291/* 292 * Bridge interface list entry. 293 */ 294struct bridge_iflist { 295 TAILQ_ENTRY(bridge_iflist) bif_next; 296 struct ifnet *bif_ifp; /* member if */ 297 struct bstp_port bif_stp; /* STP state */ 298 uint32_t bif_ifflags; /* member if flags */ 299 int bif_savedcaps; /* saved capabilities */ 300 uint32_t bif_addrmax; /* max # of addresses */ 301 uint32_t bif_addrcnt; /* cur. # of addresses */ 302 uint32_t bif_addrexceeded; /* # of address violations */ 303 304 interface_filter_t bif_iff_ref; 305 struct bridge_softc *bif_sc; 306 uint32_t bif_flags; 307}; 308 309#define BIFF_PROMISC 0x01 /* promiscuous mode set */ 310#define BIFF_PROTO_ATTACHED 0x02 /* protocol attached */ 311#define BIFF_FILTER_ATTACHED 0x04 /* interface filter attached */ 312#define BIFF_MEDIA_ACTIVE 0x08 /* interface media active */ 313 314/* 315 * Bridge route node. 316 */ 317struct bridge_rtnode { 318 LIST_ENTRY(bridge_rtnode) brt_hash; /* hash table linkage */ 319 LIST_ENTRY(bridge_rtnode) brt_list; /* list linkage */ 320 struct bridge_iflist *brt_dst; /* destination if */ 321 unsigned long brt_expire; /* expiration time */ 322 uint8_t brt_flags; /* address flags */ 323 uint8_t brt_addr[ETHER_ADDR_LEN]; 324 uint16_t brt_vlan; /* vlan id */ 325 326}; 327#define brt_ifp brt_dst->bif_ifp 328 329/* 330 * Bridge delayed function call context 331 */ 332typedef void (*bridge_delayed_func_t)(struct bridge_softc *); 333 334struct bridge_delayed_call { 335 struct bridge_softc *bdc_sc; 336 bridge_delayed_func_t bdc_func; /* Function to call */ 337 struct timespec bdc_ts; /* Time to call */ 338 u_int32_t bdc_flags; 339}; 340 341#define BDCF_OUTSTANDING 0x01 /* Delayed call has been scheduled */ 342#define BDCF_CANCELLING 0x02 /* May be waiting for call completion */ 343 344/* 345 * Software state for each bridge. 346 */ 347 348LIST_HEAD(_bridge_rtnode_list, bridge_rtnode); 349 350struct bridge_softc { 351 struct ifnet *sc_ifp; /* make this an interface */ 352 LIST_ENTRY(bridge_softc) sc_list; 353 decl_lck_mtx_data(, sc_mtx); 354 void *sc_cv; 355 uint32_t sc_brtmax; /* max # of addresses */ 356 uint32_t sc_brtcnt; /* cur. # of addresses */ 357 uint32_t sc_brttimeout; /* rt timeout in seconds */ 358 uint32_t sc_iflist_ref; /* refcount for sc_iflist */ 359 uint32_t sc_iflist_xcnt; /* refcount for sc_iflist */ 360 TAILQ_HEAD(, bridge_iflist) sc_iflist; /* member interface list */ 361 struct _bridge_rtnode_list *sc_rthash; /* our forwarding table */ 362 struct _bridge_rtnode_list sc_rtlist; /* list version of above */ 363 uint32_t sc_rthash_key; /* key for hash */ 364 uint32_t sc_rthash_size; /* size of the hash table */ 365 TAILQ_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ 366 struct bstp_state sc_stp; /* STP state */ 367 uint32_t sc_brtexceeded; /* # of cache drops */ 368 uint32_t sc_filter_flags; /* ipf and flags */ 369 struct ifnet *sc_ifaddr; /* member mac copied from */ 370 u_char sc_defaddr[6]; /* Default MAC address */ 371 372 char sc_if_xname[IFNAMSIZ]; 373 bpf_packet_func sc_bpf_input; 374 bpf_packet_func sc_bpf_output; 375 u_int32_t sc_flags; 376 struct bridge_delayed_call sc_aging_timer; 377 struct bridge_delayed_call sc_resize_call; 378 379#if BRIDGE_DEBUG 380 /* 381 * Locking and unlocking calling history 382 */ 383 void *lock_lr[BR_LCKDBG_MAX]; 384 int next_lock_lr; 385 void *unlock_lr[BR_LCKDBG_MAX]; 386 int next_unlock_lr; 387#endif /* BRIDGE_DEBUG */ 388}; 389 390#define SCF_DETACHING 0x01 391#define SCF_RESIZING 0x02 392#define SCF_MEDIA_ACTIVE 0x04 393 394decl_lck_mtx_data(static, bridge_list_mtx); 395 396static int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; 397 398static zone_t bridge_rtnode_pool = NULL; 399 400static int bridge_clone_create(struct if_clone *, uint32_t, void *); 401static int bridge_clone_destroy(struct ifnet *); 402 403static errno_t bridge_ioctl(struct ifnet *, u_long, void *); 404#if HAS_IF_CAP 405static void bridge_mutecaps(struct bridge_softc *); 406static void bridge_set_ifcap(struct bridge_softc *, struct bridge_iflist *, 407 int); 408#endif 409static errno_t bridge_set_tso(struct bridge_softc *); 410__private_extern__ void bridge_ifdetach(struct bridge_iflist *, struct ifnet *); 411static int bridge_init(struct ifnet *); 412#if HAS_BRIDGE_DUMMYNET 413static void bridge_dummynet(struct mbuf *, struct ifnet *); 414#endif 415static void bridge_ifstop(struct ifnet *, int); 416static int bridge_output(struct ifnet *, struct mbuf *); 417static void bridge_finalize_cksum(struct ifnet *, struct mbuf *); 418static void bridge_start(struct ifnet *); 419__private_extern__ errno_t bridge_input(struct ifnet *, struct mbuf *, void *); 420#if BRIDGE_MEMBER_OUT_FILTER 421static errno_t bridge_iff_output(void *, ifnet_t, protocol_family_t, 422 mbuf_t *); 423static int bridge_member_output(struct ifnet *, struct mbuf *, 424 struct sockaddr *, struct rtentry *); 425#endif 426static int bridge_enqueue(struct bridge_softc *, struct ifnet *, 427 struct mbuf *); 428static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int); 429 430static void bridge_forward(struct bridge_softc *, struct bridge_iflist *, 431 struct mbuf *); 432 433static void bridge_aging_timer(struct bridge_softc *sc); 434 435static void bridge_broadcast(struct bridge_softc *, struct ifnet *, 436 struct mbuf *, int); 437static void bridge_span(struct bridge_softc *, struct mbuf *); 438 439static int bridge_rtupdate(struct bridge_softc *, const uint8_t *, 440 uint16_t, struct bridge_iflist *, int, uint8_t); 441static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *, 442 uint16_t); 443static void bridge_rttrim(struct bridge_softc *); 444static void bridge_rtage(struct bridge_softc *); 445static void bridge_rtflush(struct bridge_softc *, int); 446static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *, 447 uint16_t); 448 449static int bridge_rtable_init(struct bridge_softc *); 450static void bridge_rtable_fini(struct bridge_softc *); 451 452static void bridge_rthash_resize(struct bridge_softc *); 453 454static int bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *); 455static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *, 456 const uint8_t *, uint16_t); 457static int bridge_rtnode_hash(struct bridge_softc *, 458 struct bridge_rtnode *); 459static int bridge_rtnode_insert(struct bridge_softc *, 460 struct bridge_rtnode *); 461static void bridge_rtnode_destroy(struct bridge_softc *, 462 struct bridge_rtnode *); 463#if BRIDGESTP 464static void bridge_rtable_expire(struct ifnet *, int); 465static void bridge_state_change(struct ifnet *, int); 466#endif /* BRIDGESTP */ 467 468static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *, 469 const char *name); 470static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *, 471 struct ifnet *ifp); 472static void bridge_delete_member(struct bridge_softc *, 473 struct bridge_iflist *, int); 474static void bridge_delete_span(struct bridge_softc *, 475 struct bridge_iflist *); 476 477static int bridge_ioctl_add(struct bridge_softc *, void *); 478static int bridge_ioctl_del(struct bridge_softc *, void *); 479static int bridge_ioctl_gifflags(struct bridge_softc *, void *); 480static int bridge_ioctl_sifflags(struct bridge_softc *, void *); 481static int bridge_ioctl_scache(struct bridge_softc *, void *); 482static int bridge_ioctl_gcache(struct bridge_softc *, void *); 483static int bridge_ioctl_gifs32(struct bridge_softc *, void *); 484static int bridge_ioctl_gifs64(struct bridge_softc *, void *); 485static int bridge_ioctl_rts32(struct bridge_softc *, void *); 486static int bridge_ioctl_rts64(struct bridge_softc *, void *); 487static int bridge_ioctl_saddr32(struct bridge_softc *, void *); 488static int bridge_ioctl_saddr64(struct bridge_softc *, void *); 489static int bridge_ioctl_sto(struct bridge_softc *, void *); 490static int bridge_ioctl_gto(struct bridge_softc *, void *); 491static int bridge_ioctl_daddr32(struct bridge_softc *, void *); 492static int bridge_ioctl_daddr64(struct bridge_softc *, void *); 493static int bridge_ioctl_flush(struct bridge_softc *, void *); 494static int bridge_ioctl_gpri(struct bridge_softc *, void *); 495static int bridge_ioctl_spri(struct bridge_softc *, void *); 496static int bridge_ioctl_ght(struct bridge_softc *, void *); 497static int bridge_ioctl_sht(struct bridge_softc *, void *); 498static int bridge_ioctl_gfd(struct bridge_softc *, void *); 499static int bridge_ioctl_sfd(struct bridge_softc *, void *); 500static int bridge_ioctl_gma(struct bridge_softc *, void *); 501static int bridge_ioctl_sma(struct bridge_softc *, void *); 502static int bridge_ioctl_sifprio(struct bridge_softc *, void *); 503static int bridge_ioctl_sifcost(struct bridge_softc *, void *); 504static int bridge_ioctl_sifmaxaddr(struct bridge_softc *, void *); 505static int bridge_ioctl_addspan(struct bridge_softc *, void *); 506static int bridge_ioctl_delspan(struct bridge_softc *, void *); 507static int bridge_ioctl_gbparam32(struct bridge_softc *, void *); 508static int bridge_ioctl_gbparam64(struct bridge_softc *, void *); 509static int bridge_ioctl_grte(struct bridge_softc *, void *); 510static int bridge_ioctl_gifsstp32(struct bridge_softc *, void *); 511static int bridge_ioctl_gifsstp64(struct bridge_softc *, void *); 512static int bridge_ioctl_sproto(struct bridge_softc *, void *); 513static int bridge_ioctl_stxhc(struct bridge_softc *, void *); 514static int bridge_ioctl_purge(struct bridge_softc *sc, void *); 515static int bridge_ioctl_gfilt(struct bridge_softc *, void *); 516static int bridge_ioctl_sfilt(struct bridge_softc *, void *); 517#ifdef PFIL_HOOKS 518static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *, 519 int); 520static int bridge_ip_checkbasic(struct mbuf **); 521#ifdef INET6 522static int bridge_ip6_checkbasic(struct mbuf **); 523#endif /* INET6 */ 524static int bridge_fragment(struct ifnet *, struct mbuf *, 525 struct ether_header *, int, struct llc *); 526#endif /* PFIL_HOOKS */ 527 528static errno_t bridge_set_bpf_tap(ifnet_t, bpf_tap_mode, bpf_packet_func); 529__private_extern__ errno_t bridge_bpf_input(ifnet_t, struct mbuf *); 530__private_extern__ errno_t bridge_bpf_output(ifnet_t, struct mbuf *); 531 532static void bridge_detach(ifnet_t); 533static void bridge_link_event(struct ifnet *, u_int32_t); 534static void bridge_iflinkevent(struct ifnet *); 535static u_int32_t bridge_updatelinkstatus(struct bridge_softc *); 536static int interface_media_active(struct ifnet *); 537static void bridge_schedule_delayed_call(struct bridge_delayed_call *); 538static void bridge_cancel_delayed_call(struct bridge_delayed_call *); 539 540#define m_copypacket(m, how) m_copym(m, 0, M_COPYALL, how) 541 542/* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */ 543#define VLANTAGOF(_m) 0 544 545u_int8_t bstp_etheraddr[ETHER_ADDR_LEN] = 546 { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; 547 548#if BRIDGESTP 549static struct bstp_cb_ops bridge_ops = { 550 .bcb_state = bridge_state_change, 551 .bcb_rtage = bridge_rtable_expire 552}; 553#endif /* BRIDGESTP */ 554 555SYSCTL_DECL(_net_link); 556SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW|CTLFLAG_LOCKED, 0, 557 "Bridge"); 558 559static int bridge_inherit_mac = 0; /* share MAC with first bridge member */ 560SYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac, 561 CTLFLAG_RW|CTLFLAG_LOCKED, 562 &bridge_inherit_mac, 0, 563 "Inherit MAC address from the first bridge member"); 564 565SYSCTL_INT(_net_link_bridge, OID_AUTO, rtable_prune_period, 566 CTLFLAG_RW|CTLFLAG_LOCKED, 567 &bridge_rtable_prune_period, 0, 568 "Interval between pruning of routing table"); 569 570static unsigned int bridge_rtable_hash_size_max = BRIDGE_RTHASH_SIZE_MAX; 571SYSCTL_UINT(_net_link_bridge, OID_AUTO, rtable_hash_size_max, 572 CTLFLAG_RW|CTLFLAG_LOCKED, 573 &bridge_rtable_hash_size_max, 0, 574 "Maximum size of the routing hash table"); 575 576#if BRIDGE_DEBUG_DELAYED_CALLBACK 577static int bridge_delayed_callback_delay = 0; 578SYSCTL_INT(_net_link_bridge, OID_AUTO, delayed_callback_delay, 579 CTLFLAG_RW|CTLFLAG_LOCKED, 580 &bridge_delayed_callback_delay, 0, 581 "Delay before calling delayed function"); 582#endif 583 584#if defined(PFIL_HOOKS) 585static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */ 586static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */ 587static int pfil_member = 1; /* run pfil hooks on the member interface */ 588static int pfil_ipfw = 0; /* layer2 filter with ipfw */ 589static int pfil_ipfw_arp = 0; /* layer2 filter with ipfw */ 590static int pfil_local_phys = 0; /* run pfil hooks on the physical interface */ 591 /* for locally destined packets */ 592SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW|CTLFLAG_LOCKED, 593 &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled"); 594SYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW|CTLFLAG_LOCKED, 595 &pfil_ipfw_arp, 0, "Filter ARP packets through IPFW layer2"); 596SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW|CTLFLAG_LOCKED, 597 &pfil_bridge, 0, "Packet filter on the bridge interface"); 598SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW|CTLFLAG_LOCKED, 599 &pfil_member, 0, "Packet filter on the member interface"); 600SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_local_phys, 601 CTLFLAG_RW|CTLFLAG_LOCKED, &pfil_local_phys, 0, 602 "Packet filter on the physical interface for locally destined packets"); 603#endif /* PFIL_HOOKS */ 604 605#if BRIDGESTP 606static int log_stp = 0; /* log STP state changes */ 607SYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW, 608 &log_stp, 0, "Log STP state changes"); 609#endif /* BRIDGESTP */ 610 611struct bridge_control { 612 int (*bc_func)(struct bridge_softc *, void *); 613 unsigned int bc_argsize; 614 unsigned int bc_flags; 615}; 616 617#define BC_F_COPYIN 0x01 /* copy arguments in */ 618#define BC_F_COPYOUT 0x02 /* copy arguments out */ 619#define BC_F_SUSER 0x04 /* do super-user check */ 620 621static const struct bridge_control bridge_control_table32[] = { 622 { bridge_ioctl_add, sizeof (struct ifbreq), 623 BC_F_COPYIN|BC_F_SUSER }, 624 { bridge_ioctl_del, sizeof (struct ifbreq), 625 BC_F_COPYIN|BC_F_SUSER }, 626 627 { bridge_ioctl_gifflags, sizeof (struct ifbreq), 628 BC_F_COPYIN|BC_F_COPYOUT }, 629 { bridge_ioctl_sifflags, sizeof (struct ifbreq), 630 BC_F_COPYIN|BC_F_SUSER }, 631 632 { bridge_ioctl_scache, sizeof (struct ifbrparam), 633 BC_F_COPYIN|BC_F_SUSER }, 634 { bridge_ioctl_gcache, sizeof (struct ifbrparam), 635 BC_F_COPYOUT }, 636 637 { bridge_ioctl_gifs32, sizeof (struct ifbifconf32), 638 BC_F_COPYIN|BC_F_COPYOUT }, 639 { bridge_ioctl_rts32, sizeof (struct ifbaconf32), 640 BC_F_COPYIN|BC_F_COPYOUT }, 641 642 { bridge_ioctl_saddr32, sizeof (struct ifbareq32), 643 BC_F_COPYIN|BC_F_SUSER }, 644 645 { bridge_ioctl_sto, sizeof (struct ifbrparam), 646 BC_F_COPYIN|BC_F_SUSER }, 647 { bridge_ioctl_gto, sizeof (struct ifbrparam), 648 BC_F_COPYOUT }, 649 650 { bridge_ioctl_daddr32, sizeof (struct ifbareq32), 651 BC_F_COPYIN|BC_F_SUSER }, 652 653 { bridge_ioctl_flush, sizeof (struct ifbreq), 654 BC_F_COPYIN|BC_F_SUSER }, 655 656 { bridge_ioctl_gpri, sizeof (struct ifbrparam), 657 BC_F_COPYOUT }, 658 { bridge_ioctl_spri, sizeof (struct ifbrparam), 659 BC_F_COPYIN|BC_F_SUSER }, 660 661 { bridge_ioctl_ght, sizeof (struct ifbrparam), 662 BC_F_COPYOUT }, 663 { bridge_ioctl_sht, sizeof (struct ifbrparam), 664 BC_F_COPYIN|BC_F_SUSER }, 665 666 { bridge_ioctl_gfd, sizeof (struct ifbrparam), 667 BC_F_COPYOUT }, 668 { bridge_ioctl_sfd, sizeof (struct ifbrparam), 669 BC_F_COPYIN|BC_F_SUSER }, 670 671 { bridge_ioctl_gma, sizeof (struct ifbrparam), 672 BC_F_COPYOUT }, 673 { bridge_ioctl_sma, sizeof (struct ifbrparam), 674 BC_F_COPYIN|BC_F_SUSER }, 675 676 { bridge_ioctl_sifprio, sizeof (struct ifbreq), 677 BC_F_COPYIN|BC_F_SUSER }, 678 679 { bridge_ioctl_sifcost, sizeof (struct ifbreq), 680 BC_F_COPYIN|BC_F_SUSER }, 681 682 { bridge_ioctl_gfilt, sizeof (struct ifbrparam), 683 BC_F_COPYOUT }, 684 { bridge_ioctl_sfilt, sizeof (struct ifbrparam), 685 BC_F_COPYIN|BC_F_SUSER }, 686 687 { bridge_ioctl_purge, sizeof (struct ifbreq), 688 BC_F_COPYIN|BC_F_SUSER }, 689 690 { bridge_ioctl_addspan, sizeof (struct ifbreq), 691 BC_F_COPYIN|BC_F_SUSER }, 692 { bridge_ioctl_delspan, sizeof (struct ifbreq), 693 BC_F_COPYIN|BC_F_SUSER }, 694 695 { bridge_ioctl_gbparam32, sizeof (struct ifbropreq32), 696 BC_F_COPYOUT }, 697 698 { bridge_ioctl_grte, sizeof (struct ifbrparam), 699 BC_F_COPYOUT }, 700 701 { bridge_ioctl_gifsstp32, sizeof (struct ifbpstpconf32), 702 BC_F_COPYIN|BC_F_COPYOUT }, 703 704 { bridge_ioctl_sproto, sizeof (struct ifbrparam), 705 BC_F_COPYIN|BC_F_SUSER }, 706 707 { bridge_ioctl_stxhc, sizeof (struct ifbrparam), 708 BC_F_COPYIN|BC_F_SUSER }, 709 710 { bridge_ioctl_sifmaxaddr, sizeof (struct ifbreq), 711 BC_F_COPYIN|BC_F_SUSER }, 712}; 713 714static const struct bridge_control bridge_control_table64[] = { 715 { bridge_ioctl_add, sizeof (struct ifbreq), 716 BC_F_COPYIN|BC_F_SUSER }, 717 { bridge_ioctl_del, sizeof (struct ifbreq), 718 BC_F_COPYIN|BC_F_SUSER }, 719 720 { bridge_ioctl_gifflags, sizeof (struct ifbreq), 721 BC_F_COPYIN|BC_F_COPYOUT }, 722 { bridge_ioctl_sifflags, sizeof (struct ifbreq), 723 BC_F_COPYIN|BC_F_SUSER }, 724 725 { bridge_ioctl_scache, sizeof (struct ifbrparam), 726 BC_F_COPYIN|BC_F_SUSER }, 727 { bridge_ioctl_gcache, sizeof (struct ifbrparam), 728 BC_F_COPYOUT }, 729 730 { bridge_ioctl_gifs64, sizeof (struct ifbifconf64), 731 BC_F_COPYIN|BC_F_COPYOUT }, 732 { bridge_ioctl_rts64, sizeof (struct ifbaconf64), 733 BC_F_COPYIN|BC_F_COPYOUT }, 734 735 { bridge_ioctl_saddr64, sizeof (struct ifbareq64), 736 BC_F_COPYIN|BC_F_SUSER }, 737 738 { bridge_ioctl_sto, sizeof (struct ifbrparam), 739 BC_F_COPYIN|BC_F_SUSER }, 740 { bridge_ioctl_gto, sizeof (struct ifbrparam), 741 BC_F_COPYOUT }, 742 743 { bridge_ioctl_daddr64, sizeof (struct ifbareq64), 744 BC_F_COPYIN|BC_F_SUSER }, 745 746 { bridge_ioctl_flush, sizeof (struct ifbreq), 747 BC_F_COPYIN|BC_F_SUSER }, 748 749 { bridge_ioctl_gpri, sizeof (struct ifbrparam), 750 BC_F_COPYOUT }, 751 { bridge_ioctl_spri, sizeof (struct ifbrparam), 752 BC_F_COPYIN|BC_F_SUSER }, 753 754 { bridge_ioctl_ght, sizeof (struct ifbrparam), 755 BC_F_COPYOUT }, 756 { bridge_ioctl_sht, sizeof (struct ifbrparam), 757 BC_F_COPYIN|BC_F_SUSER }, 758 759 { bridge_ioctl_gfd, sizeof (struct ifbrparam), 760 BC_F_COPYOUT }, 761 { bridge_ioctl_sfd, sizeof (struct ifbrparam), 762 BC_F_COPYIN|BC_F_SUSER }, 763 764 { bridge_ioctl_gma, sizeof (struct ifbrparam), 765 BC_F_COPYOUT }, 766 { bridge_ioctl_sma, sizeof (struct ifbrparam), 767 BC_F_COPYIN|BC_F_SUSER }, 768 769 { bridge_ioctl_sifprio, sizeof (struct ifbreq), 770 BC_F_COPYIN|BC_F_SUSER }, 771 772 { bridge_ioctl_sifcost, sizeof (struct ifbreq), 773 BC_F_COPYIN|BC_F_SUSER }, 774 775 { bridge_ioctl_gfilt, sizeof (struct ifbrparam), 776 BC_F_COPYOUT }, 777 { bridge_ioctl_sfilt, sizeof (struct ifbrparam), 778 BC_F_COPYIN|BC_F_SUSER }, 779 780 { bridge_ioctl_purge, sizeof (struct ifbreq), 781 BC_F_COPYIN|BC_F_SUSER }, 782 783 { bridge_ioctl_addspan, sizeof (struct ifbreq), 784 BC_F_COPYIN|BC_F_SUSER }, 785 { bridge_ioctl_delspan, sizeof (struct ifbreq), 786 BC_F_COPYIN|BC_F_SUSER }, 787 788 { bridge_ioctl_gbparam64, sizeof (struct ifbropreq64), 789 BC_F_COPYOUT }, 790 791 { bridge_ioctl_grte, sizeof (struct ifbrparam), 792 BC_F_COPYOUT }, 793 794 { bridge_ioctl_gifsstp64, sizeof (struct ifbpstpconf64), 795 BC_F_COPYIN|BC_F_COPYOUT }, 796 797 { bridge_ioctl_sproto, sizeof (struct ifbrparam), 798 BC_F_COPYIN|BC_F_SUSER }, 799 800 { bridge_ioctl_stxhc, sizeof (struct ifbrparam), 801 BC_F_COPYIN|BC_F_SUSER }, 802 803 { bridge_ioctl_sifmaxaddr, sizeof (struct ifbreq), 804 BC_F_COPYIN|BC_F_SUSER }, 805}; 806 807static const unsigned int bridge_control_table_size = 808 sizeof (bridge_control_table32) / sizeof (bridge_control_table32[0]); 809 810static LIST_HEAD(, bridge_softc) bridge_list = 811 LIST_HEAD_INITIALIZER(bridge_list); 812 813static lck_grp_t *bridge_lock_grp = NULL; 814static lck_attr_t *bridge_lock_attr = NULL; 815 816static if_clone_t bridge_cloner = NULL; 817 818static int if_bridge_txstart = 0; 819SYSCTL_INT(_net_link_bridge, OID_AUTO, txstart, CTLFLAG_RW | CTLFLAG_LOCKED, 820 &if_bridge_txstart, 0, "Bridge interface uses TXSTART model"); 821 822#if BRIDGE_DEBUG 823static int if_bridge_debug = 0; 824SYSCTL_INT(_net_link_bridge, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_LOCKED, 825 &if_bridge_debug, 0, "Bridge debug"); 826 827static void printf_ether_header(struct ether_header *); 828static void printf_mbuf_data(mbuf_t, size_t, size_t); 829static void printf_mbuf_pkthdr(mbuf_t, const char *, const char *); 830static void printf_mbuf(mbuf_t, const char *, const char *); 831static void link_print(struct sockaddr_dl *); 832 833static void bridge_lock(struct bridge_softc *); 834static void bridge_unlock(struct bridge_softc *); 835static int bridge_lock2ref(struct bridge_softc *); 836static void bridge_unref(struct bridge_softc *); 837static void bridge_xlock(struct bridge_softc *); 838static void bridge_xdrop(struct bridge_softc *); 839 840static void 841bridge_lock(struct bridge_softc *sc) 842{ 843 void *lr_saved = __builtin_return_address(0); 844 845 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 846 847 _BRIDGE_LOCK(sc); 848 849 sc->lock_lr[sc->next_lock_lr] = lr_saved; 850 sc->next_lock_lr = (sc->next_lock_lr+1) % SO_LCKDBG_MAX; 851} 852 853static void 854bridge_unlock(struct bridge_softc *sc) 855{ 856 void *lr_saved = __builtin_return_address(0); 857 858 BRIDGE_LOCK_ASSERT_HELD(sc); 859 860 sc->unlock_lr[sc->next_unlock_lr] = lr_saved; 861 sc->next_unlock_lr = (sc->next_unlock_lr+1) % SO_LCKDBG_MAX; 862 863 _BRIDGE_UNLOCK(sc); 864} 865 866static int 867bridge_lock2ref(struct bridge_softc *sc) 868{ 869 int error = 0; 870 void *lr_saved = __builtin_return_address(0); 871 872 BRIDGE_LOCK_ASSERT_HELD(sc); 873 874 if (sc->sc_iflist_xcnt > 0) 875 error = EBUSY; 876 else 877 sc->sc_iflist_ref++; 878 879 sc->unlock_lr[sc->next_unlock_lr] = lr_saved; 880 sc->next_unlock_lr = (sc->next_unlock_lr+1) % SO_LCKDBG_MAX; 881 882 _BRIDGE_UNLOCK(sc); 883 884 return (error); 885} 886 887static void 888bridge_unref(struct bridge_softc *sc) 889{ 890 void *lr_saved = __builtin_return_address(0); 891 892 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 893 894 _BRIDGE_LOCK(sc); 895 sc->lock_lr[sc->next_lock_lr] = lr_saved; 896 sc->next_lock_lr = (sc->next_lock_lr+1) % SO_LCKDBG_MAX; 897 898 sc->sc_iflist_ref--; 899 900 sc->unlock_lr[sc->next_unlock_lr] = lr_saved; 901 sc->next_unlock_lr = (sc->next_unlock_lr+1) % SO_LCKDBG_MAX; 902 if ((sc->sc_iflist_xcnt > 0) && (sc->sc_iflist_ref == 0)) { 903 _BRIDGE_UNLOCK(sc); 904 wakeup(&sc->sc_cv); 905 } else 906 _BRIDGE_UNLOCK(sc); 907} 908 909static void 910bridge_xlock(struct bridge_softc *sc) 911{ 912 void *lr_saved = __builtin_return_address(0); 913 914 BRIDGE_LOCK_ASSERT_HELD(sc); 915 916 sc->sc_iflist_xcnt++; 917 while (sc->sc_iflist_ref > 0) { 918 sc->unlock_lr[sc->next_unlock_lr] = lr_saved; 919 sc->next_unlock_lr = (sc->next_unlock_lr+1) % SO_LCKDBG_MAX; 920 921 msleep(&sc->sc_cv, &sc->sc_mtx, PZERO, "BRIDGE_XLOCK", NULL); 922 923 sc->lock_lr[sc->next_lock_lr] = lr_saved; 924 sc->next_lock_lr = (sc->next_lock_lr+1) % SO_LCKDBG_MAX; 925 } 926} 927 928static void 929bridge_xdrop(struct bridge_softc *sc) 930{ 931 BRIDGE_LOCK_ASSERT_HELD(sc); 932 933 sc->sc_iflist_xcnt--; 934} 935 936void 937printf_mbuf_pkthdr(mbuf_t m, const char *prefix, const char *suffix) 938{ 939 if (m) 940 printf("%spktlen: %u rcvif: 0x%llx header: 0x%llx " 941 "nextpkt: 0x%llx%s", 942 prefix ? prefix : "", (unsigned int)mbuf_pkthdr_len(m), 943 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_pkthdr_rcvif(m)), 944 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_pkthdr_header(m)), 945 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_nextpkt(m)), 946 suffix ? suffix : ""); 947 else 948 printf("%s<NULL>%s\n", prefix, suffix); 949} 950 951void 952printf_mbuf(mbuf_t m, const char *prefix, const char *suffix) 953{ 954 if (m) { 955 printf("%s0x%llx type: %u flags: 0x%x len: %u data: 0x%llx " 956 "maxlen: %u datastart: 0x%llx next: 0x%llx%s", 957 prefix ? prefix : "", (uint64_t)VM_KERNEL_ADDRPERM(m), 958 mbuf_type(m), mbuf_flags(m), (unsigned int)mbuf_len(m), 959 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_data(m)), 960 (unsigned int)mbuf_maxlen(m), 961 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_datastart(m)), 962 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_next(m)), 963 !suffix || (mbuf_flags(m) & MBUF_PKTHDR) ? "" : suffix); 964 if ((mbuf_flags(m) & MBUF_PKTHDR)) 965 printf_mbuf_pkthdr(m, " ", suffix); 966 } else 967 printf("%s<NULL>%s\n", prefix, suffix); 968} 969 970void 971printf_mbuf_data(mbuf_t m, size_t offset, size_t len) 972{ 973 mbuf_t n; 974 size_t i, j; 975 size_t pktlen, mlen, maxlen; 976 unsigned char *ptr; 977 978 pktlen = mbuf_pkthdr_len(m); 979 980 if (offset > pktlen) 981 return; 982 983 maxlen = (pktlen - offset > len) ? len : pktlen; 984 n = m; 985 mlen = mbuf_len(n); 986 ptr = mbuf_data(n); 987 for (i = 0, j = 0; i < maxlen; i++, j++) { 988 if (j >= mlen) { 989 n = mbuf_next(n); 990 if (n == 0) 991 break; 992 ptr = mbuf_data(n); 993 mlen = mbuf_len(n); 994 j = 0; 995 } 996 if (i >= offset) { 997 printf("%02x%s", ptr[j], i % 2 ? " " : ""); 998 } 999 } 1000} 1001 1002static void 1003printf_ether_header(struct ether_header *eh) 1004{ 1005 printf("%02x:%02x:%02x:%02x:%02x:%02x > " 1006 "%02x:%02x:%02x:%02x:%02x:%02x 0x%04x ", 1007 eh->ether_shost[0], eh->ether_shost[1], eh->ether_shost[2], 1008 eh->ether_shost[3], eh->ether_shost[4], eh->ether_shost[5], 1009 eh->ether_dhost[0], eh->ether_dhost[1], eh->ether_dhost[2], 1010 eh->ether_dhost[3], eh->ether_dhost[4], eh->ether_dhost[5], 1011 ntohs(eh->ether_type)); 1012} 1013 1014static void 1015link_print(struct sockaddr_dl *dl_p) 1016{ 1017 int i; 1018 1019#if 1 1020 printf("sdl len %d index %d family %d type 0x%x nlen %d alen %d" 1021 " slen %d addr ", dl_p->sdl_len, dl_p->sdl_index, 1022 dl_p->sdl_family, dl_p->sdl_type, dl_p->sdl_nlen, 1023 dl_p->sdl_alen, dl_p->sdl_slen); 1024#endif 1025 for (i = 0; i < dl_p->sdl_alen; i++) 1026 printf("%s%x", i ? ":" : "", (CONST_LLADDR(dl_p))[i]); 1027 printf("\n"); 1028} 1029 1030#endif /* BRIDGE_DEBUG */ 1031 1032/* 1033 * bridgeattach: 1034 * 1035 * Pseudo-device attach routine. 1036 */ 1037__private_extern__ int 1038bridgeattach(int n) 1039{ 1040#pragma unused(n) 1041 int error; 1042 lck_grp_attr_t *lck_grp_attr = NULL; 1043 struct ifnet_clone_params ifnet_clone_params; 1044 1045 bridge_rtnode_pool = zinit(sizeof (struct bridge_rtnode), 1046 1024 * sizeof (struct bridge_rtnode), 0, "bridge_rtnode"); 1047 zone_change(bridge_rtnode_pool, Z_CALLERACCT, FALSE); 1048 1049 lck_grp_attr = lck_grp_attr_alloc_init(); 1050 1051 bridge_lock_grp = lck_grp_alloc_init("if_bridge", lck_grp_attr); 1052 1053 bridge_lock_attr = lck_attr_alloc_init(); 1054 1055#if BRIDGE_DEBUG 1056 lck_attr_setdebug(bridge_lock_attr); 1057#endif 1058 1059 lck_mtx_init(&bridge_list_mtx, bridge_lock_grp, bridge_lock_attr); 1060 1061 /* can free the attributes once we've allocated the group lock */ 1062 lck_grp_attr_free(lck_grp_attr); 1063 1064 LIST_INIT(&bridge_list); 1065 1066#if BRIDGESTP 1067 bstp_sys_init(); 1068#endif /* BRIDGESTP */ 1069 1070 ifnet_clone_params.ifc_name = "bridge"; 1071 ifnet_clone_params.ifc_create = bridge_clone_create; 1072 ifnet_clone_params.ifc_destroy = bridge_clone_destroy; 1073 1074 error = ifnet_clone_attach(&ifnet_clone_params, &bridge_cloner); 1075 if (error != 0) 1076 printf("%s: ifnet_clone_attach failed %d\n", __func__, error); 1077 1078 return (error); 1079} 1080 1081#if defined(PFIL_HOOKS) 1082/* 1083 * handler for net.link.bridge.pfil_ipfw 1084 */ 1085static int 1086sysctl_pfil_ipfw SYSCTL_HANDLER_ARGS 1087{ 1088#pragma unused(arg1, arg2) 1089 int enable = pfil_ipfw; 1090 int error; 1091 1092 error = sysctl_handle_int(oidp, &enable, 0, req); 1093 enable = (enable) ? 1 : 0; 1094 1095 if (enable != pfil_ipfw) { 1096 pfil_ipfw = enable; 1097 1098 /* 1099 * Disable pfil so that ipfw doesnt run twice, if the user 1100 * really wants both then they can re-enable pfil_bridge and/or 1101 * pfil_member. Also allow non-ip packets as ipfw can filter by 1102 * layer2 type. 1103 */ 1104 if (pfil_ipfw) { 1105 pfil_onlyip = 0; 1106 pfil_bridge = 0; 1107 pfil_member = 0; 1108 } 1109 } 1110 1111 return (error); 1112} 1113 1114SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW, 1115 &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW"); 1116#endif /* PFIL_HOOKS */ 1117 1118/* 1119 * bridge_clone_create: 1120 * 1121 * Create a new bridge instance. 1122 */ 1123static int 1124bridge_clone_create(struct if_clone *ifc, uint32_t unit, void *params) 1125{ 1126#pragma unused(params) 1127 struct ifnet *ifp = NULL; 1128 struct bridge_softc *sc, *sc2; 1129 struct ifnet_init_eparams init_params; 1130 errno_t error = 0; 1131 uint32_t sdl_buffer[offsetof(struct sockaddr_dl, sdl_data) + 1132 IFNAMSIZ + ETHER_ADDR_LEN]; 1133 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sdl_buffer; 1134 uint8_t eth_hostid[ETHER_ADDR_LEN]; 1135 int fb, retry, has_hostid; 1136 1137 sc = _MALLOC(sizeof (*sc), M_DEVBUF, M_WAITOK | M_ZERO); 1138 1139 lck_mtx_init(&sc->sc_mtx, bridge_lock_grp, bridge_lock_attr); 1140 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 1141 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 1142 sc->sc_filter_flags = IFBF_FILT_DEFAULT; 1143#ifndef BRIDGE_IPF 1144 /* 1145 * For backwards compatibility with previous behaviour... 1146 * Switch off filtering on the bridge itself if BRIDGE_IPF is 1147 * not defined. 1148 */ 1149 sc->sc_filter_flags &= ~IFBF_FILT_USEIPF; 1150#endif 1151 1152 /* Initialize our routing table. */ 1153 error = bridge_rtable_init(sc); 1154 if (error != 0) { 1155 printf("%s: bridge_rtable_init failed %d\n", __func__, error); 1156 goto done; 1157 } 1158 1159 TAILQ_INIT(&sc->sc_iflist); 1160 TAILQ_INIT(&sc->sc_spanlist); 1161 1162 /* use the interface name as the unique id for ifp recycle */ 1163 snprintf(sc->sc_if_xname, sizeof (sc->sc_if_xname), "%s%d", 1164 ifc->ifc_name, unit); 1165 bzero(&init_params, sizeof (init_params)); 1166 init_params.ver = IFNET_INIT_CURRENT_VERSION; 1167 init_params.len = sizeof (init_params); 1168 if (if_bridge_txstart) { 1169 init_params.start = bridge_start; 1170 } else { 1171 init_params.flags = IFNET_INIT_LEGACY; 1172 init_params.output = bridge_output; 1173 } 1174 init_params.uniqueid = sc->sc_if_xname; 1175 init_params.uniqueid_len = strlen(sc->sc_if_xname); 1176 init_params.sndq_maxlen = IFQ_MAXLEN; 1177 init_params.name = ifc->ifc_name; 1178 init_params.unit = unit; 1179 init_params.family = IFNET_FAMILY_ETHERNET; 1180 init_params.type = IFT_BRIDGE; 1181 init_params.demux = ether_demux; 1182 init_params.add_proto = ether_add_proto; 1183 init_params.del_proto = ether_del_proto; 1184 init_params.check_multi = ether_check_multi; 1185 init_params.framer_extended = ether_frameout_extended; 1186 init_params.softc = sc; 1187 init_params.ioctl = bridge_ioctl; 1188 init_params.set_bpf_tap = bridge_set_bpf_tap; 1189 init_params.detach = bridge_detach; 1190 init_params.broadcast_addr = etherbroadcastaddr; 1191 init_params.broadcast_len = ETHER_ADDR_LEN; 1192 error = ifnet_allocate_extended(&init_params, &ifp); 1193 if (error != 0) { 1194 printf("%s: ifnet_allocate failed %d\n", __func__, error); 1195 goto done; 1196 } 1197 sc->sc_ifp = ifp; 1198 1199 error = ifnet_set_mtu(ifp, ETHERMTU); 1200 if (error != 0) { 1201 printf("%s: ifnet_set_mtu failed %d\n", __func__, error); 1202 goto done; 1203 } 1204 error = ifnet_set_addrlen(ifp, ETHER_ADDR_LEN); 1205 if (error != 0) { 1206 printf("%s: ifnet_set_addrlen failed %d\n", __func__, error); 1207 goto done; 1208 } 1209 error = ifnet_set_hdrlen(ifp, ETHER_HDR_LEN); 1210 if (error != 0) { 1211 printf("%s: ifnet_set_hdrlen failed %d\n", __func__, error); 1212 goto done; 1213 } 1214 error = ifnet_set_flags(ifp, 1215 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST, 1216 0xffff); 1217 if (error != 0) { 1218 printf("%s: ifnet_set_flags failed %d\n", __func__, error); 1219 goto done; 1220 } 1221 1222 /* 1223 * Generate an ethernet address with a locally administered address. 1224 * 1225 * Since we are using random ethernet addresses for the bridge, it is 1226 * possible that we might have address collisions, so make sure that 1227 * this hardware address isn't already in use on another bridge. 1228 * The first try uses the "hostid" and falls back to read_random(); 1229 * for "hostid", we use the MAC address of the first-encountered 1230 * Ethernet-type interface that is currently configured. 1231 */ 1232 fb = 0; 1233 has_hostid = (uuid_get_ethernet(ð_hostid[0]) == 0); 1234 for (retry = 1; retry != 0; ) { 1235 if (fb || has_hostid == 0) { 1236 read_random(&sc->sc_defaddr, ETHER_ADDR_LEN); 1237 sc->sc_defaddr[0] &= ~1; /* clear multicast bit */ 1238 sc->sc_defaddr[0] |= 2; /* set the LAA bit */ 1239 } else { 1240 bcopy(ð_hostid[0], &sc->sc_defaddr, 1241 ETHER_ADDR_LEN); 1242 sc->sc_defaddr[0] &= ~1; /* clear multicast bit */ 1243 sc->sc_defaddr[0] |= 2; /* set the LAA bit */ 1244 sc->sc_defaddr[3] = /* stir it up a bit */ 1245 ((sc->sc_defaddr[3] & 0x0f) << 4) | 1246 ((sc->sc_defaddr[3] & 0xf0) >> 4); 1247 /* 1248 * Mix in the LSB as it's actually pretty significant, 1249 * see rdar://14076061 1250 */ 1251 sc->sc_defaddr[4] = 1252 (((sc->sc_defaddr[4] & 0x0f) << 4) | 1253 ((sc->sc_defaddr[4] & 0xf0) >> 4)) ^ 1254 sc->sc_defaddr[5]; 1255 sc->sc_defaddr[5] = ifp->if_unit & 0xff; 1256 } 1257 1258 fb = 1; 1259 retry = 0; 1260 lck_mtx_lock(&bridge_list_mtx); 1261 LIST_FOREACH(sc2, &bridge_list, sc_list) { 1262 if (memcmp(sc->sc_defaddr, 1263 IF_LLADDR(sc2->sc_ifp), ETHER_ADDR_LEN) == 0) 1264 retry = 1; 1265 } 1266 lck_mtx_unlock(&bridge_list_mtx); 1267 } 1268 1269 memset(sdl, 0, sizeof (sdl_buffer)); 1270 sdl->sdl_family = AF_LINK; 1271 sdl->sdl_nlen = strlen(sc->sc_if_xname); 1272 sdl->sdl_alen = ETHER_ADDR_LEN; 1273 sdl->sdl_len = offsetof(struct sockaddr_dl, sdl_data); 1274 memcpy(sdl->sdl_data, sc->sc_if_xname, sdl->sdl_nlen); 1275 memcpy(LLADDR(sdl), sc->sc_defaddr, ETHER_ADDR_LEN); 1276 1277 sc->sc_flags &= ~SCF_MEDIA_ACTIVE; 1278 1279#if BRIDGE_DEBUG 1280 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1281 link_print(sdl); 1282#endif 1283 1284 error = ifnet_attach(ifp, NULL); 1285 if (error != 0) { 1286 printf("%s: ifnet_attach failed %d\n", __func__, error); 1287 goto done; 1288 } 1289 1290 error = ifnet_set_lladdr_and_type(ifp, sc->sc_defaddr, ETHER_ADDR_LEN, 1291 IFT_ETHER); 1292 if (error != 0) { 1293 printf("%s: ifnet_set_lladdr_and_type failed %d\n", __func__, 1294 error); 1295 goto done; 1296 } 1297 1298 ifnet_set_offload(ifp, 1299 IFNET_CSUM_IP | IFNET_CSUM_TCP | IFNET_CSUM_UDP | 1300 IFNET_CSUM_TCPIPV6 | IFNET_CSUM_UDPIPV6 | IFNET_MULTIPAGES); 1301 1302 error = bridge_set_tso(sc); 1303 if (error != 0) { 1304 printf("%s: bridge_set_tso failed %d\n", __func__, error); 1305 goto done; 1306 } 1307 1308#if BRIDGESTP 1309 bstp_attach(&sc->sc_stp, &bridge_ops); 1310#endif /* BRIDGESTP */ 1311 1312 lck_mtx_lock(&bridge_list_mtx); 1313 LIST_INSERT_HEAD(&bridge_list, sc, sc_list); 1314 lck_mtx_unlock(&bridge_list_mtx); 1315 1316 /* attach as ethernet */ 1317 error = bpf_attach(ifp, DLT_EN10MB, sizeof (struct ether_header), 1318 NULL, NULL); 1319 1320done: 1321 if (error != 0) { 1322 printf("%s failed error %d\n", __func__, error); 1323 /* Cleanup TBD */ 1324 } 1325 1326 return (error); 1327} 1328 1329/* 1330 * bridge_clone_destroy: 1331 * 1332 * Destroy a bridge instance. 1333 */ 1334static int 1335bridge_clone_destroy(struct ifnet *ifp) 1336{ 1337 struct bridge_softc *sc = ifp->if_softc; 1338 struct bridge_iflist *bif; 1339 errno_t error; 1340 1341 BRIDGE_LOCK(sc); 1342 if ((sc->sc_flags & SCF_DETACHING)) { 1343 BRIDGE_UNLOCK(sc); 1344 return (0); 1345 } 1346 sc->sc_flags |= SCF_DETACHING; 1347 1348 bridge_ifstop(ifp, 1); 1349 1350 bridge_cancel_delayed_call(&sc->sc_resize_call); 1351 1352 error = ifnet_set_flags(ifp, 0, IFF_UP); 1353 if (error != 0) { 1354 printf("%s: ifnet_set_flags failed %d\n", __func__, error); 1355 } 1356 1357 while ((bif = TAILQ_FIRST(&sc->sc_iflist)) != NULL) 1358 bridge_delete_member(sc, bif, 0); 1359 1360 while ((bif = TAILQ_FIRST(&sc->sc_spanlist)) != NULL) { 1361 bridge_delete_span(sc, bif); 1362 } 1363 1364 BRIDGE_UNLOCK(sc); 1365 1366 error = ifnet_detach(ifp); 1367 if (error != 0) { 1368 panic("bridge_clone_destroy: ifnet_detach(%p) failed %d\n", 1369 ifp, error); 1370 if ((sc = (struct bridge_softc *)ifnet_softc(ifp)) != NULL) { 1371 BRIDGE_LOCK(sc); 1372 sc->sc_flags &= ~SCF_DETACHING; 1373 BRIDGE_UNLOCK(sc); 1374 } 1375 return (0); 1376 } 1377 1378 return (0); 1379} 1380 1381#define DRVSPEC do { \ 1382 if (ifd->ifd_cmd >= bridge_control_table_size) { \ 1383 error = EINVAL; \ 1384 break; \ 1385 } \ 1386 bc = &bridge_control_table[ifd->ifd_cmd]; \ 1387 \ 1388 if (cmd == SIOCGDRVSPEC && \ 1389 (bc->bc_flags & BC_F_COPYOUT) == 0) { \ 1390 error = EINVAL; \ 1391 break; \ 1392 } else if (cmd == SIOCSDRVSPEC && \ 1393 (bc->bc_flags & BC_F_COPYOUT) != 0) { \ 1394 error = EINVAL; \ 1395 break; \ 1396 } \ 1397 \ 1398 if (bc->bc_flags & BC_F_SUSER) { \ 1399 error = kauth_authorize_generic(kauth_cred_get(), \ 1400 KAUTH_GENERIC_ISSUSER); \ 1401 if (error) \ 1402 break; \ 1403 } \ 1404 \ 1405 if (ifd->ifd_len != bc->bc_argsize || \ 1406 ifd->ifd_len > sizeof (args)) { \ 1407 error = EINVAL; \ 1408 break; \ 1409 } \ 1410 \ 1411 bzero(&args, sizeof (args)); \ 1412 if (bc->bc_flags & BC_F_COPYIN) { \ 1413 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); \ 1414 if (error) \ 1415 break; \ 1416 } \ 1417 \ 1418 BRIDGE_LOCK(sc); \ 1419 error = (*bc->bc_func)(sc, &args); \ 1420 BRIDGE_UNLOCK(sc); \ 1421 if (error) \ 1422 break; \ 1423 \ 1424 if (bc->bc_flags & BC_F_COPYOUT) \ 1425 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); \ 1426} while (0) 1427 1428/* 1429 * bridge_ioctl: 1430 * 1431 * Handle a control request from the operator. 1432 */ 1433static errno_t 1434bridge_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1435{ 1436 struct bridge_softc *sc = ifp->if_softc; 1437 struct ifreq *ifr = (struct ifreq *)data; 1438 struct bridge_iflist *bif; 1439 int error = 0; 1440 1441 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 1442 1443#if BRIDGE_DEBUG 1444 if (if_bridge_debug & BR_DBGF_IOCTL) 1445 printf("%s: ifp %s cmd 0x%08lx (%c%c [%lu] %c %lu)\n", 1446 __func__, ifp->if_xname, cmd, (cmd & IOC_IN) ? 'I' : ' ', 1447 (cmd & IOC_OUT) ? 'O' : ' ', IOCPARM_LEN(cmd), 1448 (char)IOCGROUP(cmd), cmd & 0xff); 1449#endif /* BRIDGE_DEBUG */ 1450 1451 switch (cmd) { 1452 1453 case SIOCSIFADDR: 1454 case SIOCAIFADDR: 1455 ifnet_set_flags(ifp, IFF_UP, IFF_UP); 1456 break; 1457 1458 case SIOCGIFMEDIA32: 1459 case SIOCGIFMEDIA64: { 1460 struct ifmediareq *ifmr = (struct ifmediareq *)data; 1461 user_addr_t user_addr; 1462 1463 user_addr = (cmd == SIOCGIFMEDIA64) ? 1464 ((struct ifmediareq64 *)ifmr)->ifmu_ulist : 1465 CAST_USER_ADDR_T(((struct ifmediareq32 *)ifmr)->ifmu_ulist); 1466 1467 ifmr->ifm_status = IFM_AVALID; 1468 ifmr->ifm_mask = 0; 1469 ifmr->ifm_count = 1; 1470 1471 BRIDGE_LOCK(sc); 1472 if (!(sc->sc_flags & SCF_DETACHING) && 1473 (sc->sc_flags & SCF_MEDIA_ACTIVE)) { 1474 ifmr->ifm_status |= IFM_ACTIVE; 1475 ifmr->ifm_active = ifmr->ifm_current = 1476 IFM_ETHER | IFM_AUTO; 1477 } else { 1478 ifmr->ifm_active = ifmr->ifm_current = IFM_NONE; 1479 } 1480 BRIDGE_UNLOCK(sc); 1481 1482 if (user_addr != USER_ADDR_NULL) { 1483 error = copyout(&ifmr->ifm_current, user_addr, 1484 sizeof (int)); 1485 } 1486 break; 1487 } 1488 1489 case SIOCADDMULTI: 1490 case SIOCDELMULTI: 1491 break; 1492 1493 case SIOCSDRVSPEC32: 1494 case SIOCGDRVSPEC32: { 1495 union { 1496 struct ifbreq ifbreq; 1497 struct ifbifconf32 ifbifconf; 1498 struct ifbareq32 ifbareq; 1499 struct ifbaconf32 ifbaconf; 1500 struct ifbrparam ifbrparam; 1501 struct ifbropreq32 ifbropreq; 1502 } args; 1503 struct ifdrv32 *ifd = (struct ifdrv32 *)data; 1504 const struct bridge_control *bridge_control_table = 1505 bridge_control_table32, *bc; 1506 1507 DRVSPEC; 1508 1509 break; 1510 } 1511 case SIOCSDRVSPEC64: 1512 case SIOCGDRVSPEC64: { 1513 union { 1514 struct ifbreq ifbreq; 1515 struct ifbifconf64 ifbifconf; 1516 struct ifbareq64 ifbareq; 1517 struct ifbaconf64 ifbaconf; 1518 struct ifbrparam ifbrparam; 1519 struct ifbropreq64 ifbropreq; 1520 } args; 1521 struct ifdrv64 *ifd = (struct ifdrv64 *)data; 1522 const struct bridge_control *bridge_control_table = 1523 bridge_control_table64, *bc; 1524 1525 DRVSPEC; 1526 1527 break; 1528 } 1529 1530 case SIOCSIFFLAGS: 1531 if (!(ifp->if_flags & IFF_UP) && 1532 (ifp->if_flags & IFF_RUNNING)) { 1533 /* 1534 * If interface is marked down and it is running, 1535 * then stop and disable it. 1536 */ 1537 BRIDGE_LOCK(sc); 1538 bridge_ifstop(ifp, 1); 1539 BRIDGE_UNLOCK(sc); 1540 } else if ((ifp->if_flags & IFF_UP) && 1541 !(ifp->if_flags & IFF_RUNNING)) { 1542 /* 1543 * If interface is marked up and it is stopped, then 1544 * start it. 1545 */ 1546 BRIDGE_LOCK(sc); 1547 error = bridge_init(ifp); 1548 BRIDGE_UNLOCK(sc); 1549 } 1550 break; 1551 1552 case SIOCSIFLLADDR: 1553 error = ifnet_set_lladdr(ifp, ifr->ifr_addr.sa_data, 1554 ifr->ifr_addr.sa_len); 1555 if (error != 0) 1556 printf("%s: SIOCSIFLLADDR error %d\n", ifp->if_xname, 1557 error); 1558 break; 1559 1560 case SIOCSIFMTU: 1561 if (ifr->ifr_mtu < 576) { 1562 error = EINVAL; 1563 break; 1564 } 1565 BRIDGE_LOCK(sc); 1566 if (TAILQ_EMPTY(&sc->sc_iflist)) { 1567 sc->sc_ifp->if_mtu = ifr->ifr_mtu; 1568 BRIDGE_UNLOCK(sc); 1569 break; 1570 } 1571 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1572 if (bif->bif_ifp->if_mtu != (unsigned)ifr->ifr_mtu) { 1573 printf("%s: invalid MTU: %u(%s) != %d\n", 1574 sc->sc_ifp->if_xname, 1575 bif->bif_ifp->if_mtu, 1576 bif->bif_ifp->if_xname, ifr->ifr_mtu); 1577 error = EINVAL; 1578 break; 1579 } 1580 } 1581 if (!error) 1582 sc->sc_ifp->if_mtu = ifr->ifr_mtu; 1583 BRIDGE_UNLOCK(sc); 1584 break; 1585 1586 default: 1587 error = ether_ioctl(ifp, cmd, data); 1588#if BRIDGE_DEBUG 1589 if (error != 0 && error != EOPNOTSUPP) 1590 printf("%s: ifp %s cmd 0x%08lx " 1591 "(%c%c [%lu] %c %lu) failed error: %d\n", 1592 __func__, ifp->if_xname, cmd, 1593 (cmd & IOC_IN) ? 'I' : ' ', 1594 (cmd & IOC_OUT) ? 'O' : ' ', 1595 IOCPARM_LEN(cmd), (char)IOCGROUP(cmd), 1596 cmd & 0xff, error); 1597#endif /* BRIDGE_DEBUG */ 1598 break; 1599 } 1600 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 1601 1602 return (error); 1603} 1604 1605#if HAS_IF_CAP 1606/* 1607 * bridge_mutecaps: 1608 * 1609 * Clear or restore unwanted capabilities on the member interface 1610 */ 1611static void 1612bridge_mutecaps(struct bridge_softc *sc) 1613{ 1614 struct bridge_iflist *bif; 1615 int enabled, mask; 1616 1617 /* Initial bitmask of capabilities to test */ 1618 mask = BRIDGE_IFCAPS_MASK; 1619 1620 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1621 /* Every member must support it or its disabled */ 1622 mask &= bif->bif_savedcaps; 1623 } 1624 1625 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1626 enabled = bif->bif_ifp->if_capenable; 1627 enabled &= ~BRIDGE_IFCAPS_STRIP; 1628 /* strip off mask bits and enable them again if allowed */ 1629 enabled &= ~BRIDGE_IFCAPS_MASK; 1630 enabled |= mask; 1631 1632 bridge_set_ifcap(sc, bif, enabled); 1633 } 1634 1635} 1636 1637static void 1638bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set) 1639{ 1640 struct ifnet *ifp = bif->bif_ifp; 1641 struct ifreq ifr; 1642 int error; 1643 1644 bzero(&ifr, sizeof (ifr)); 1645 ifr.ifr_reqcap = set; 1646 1647 if (ifp->if_capenable != set) { 1648 IFF_LOCKGIANT(ifp); 1649 error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); 1650 IFF_UNLOCKGIANT(ifp); 1651 if (error) 1652 printf("%s: %s error setting interface capabilities " 1653 "on %s\n", __func__, sc->sc_ifp->if_xname, 1654 ifp->if_xname); 1655 } 1656} 1657#endif /* HAS_IF_CAP */ 1658 1659static errno_t 1660bridge_set_tso(struct bridge_softc *sc) 1661{ 1662 struct bridge_iflist *bif; 1663 u_int32_t tso_v4_mtu; 1664 u_int32_t tso_v6_mtu; 1665 ifnet_offload_t offload; 1666 errno_t error = 0; 1667 1668 /* By default, support TSO */ 1669 offload = sc->sc_ifp->if_hwassist | IFNET_TSO_IPV4 | IFNET_TSO_IPV6; 1670 tso_v4_mtu = IP_MAXPACKET; 1671 tso_v6_mtu = IP_MAXPACKET; 1672 1673 /* Use the lowest common denominator of the members */ 1674 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1675 ifnet_t ifp = bif->bif_ifp; 1676 1677 if (ifp == NULL) 1678 continue; 1679 1680 if (offload & IFNET_TSO_IPV4) { 1681 if (ifp->if_hwassist & IFNET_TSO_IPV4) { 1682 if (tso_v4_mtu > ifp->if_tso_v4_mtu) 1683 tso_v4_mtu = ifp->if_tso_v4_mtu; 1684 } else { 1685 offload &= ~IFNET_TSO_IPV4; 1686 tso_v4_mtu = 0; 1687 } 1688 } 1689 if (offload & IFNET_TSO_IPV6) { 1690 if (ifp->if_hwassist & IFNET_TSO_IPV6) { 1691 if (tso_v6_mtu > ifp->if_tso_v6_mtu) 1692 tso_v6_mtu = ifp->if_tso_v6_mtu; 1693 } else { 1694 offload &= ~IFNET_TSO_IPV6; 1695 tso_v6_mtu = 0; 1696 } 1697 } 1698 } 1699 1700 if (offload != sc->sc_ifp->if_hwassist) { 1701 error = ifnet_set_offload(sc->sc_ifp, offload); 1702 if (error != 0) { 1703#if BRIDGE_DEBUG 1704 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1705 printf("%s: ifnet_set_offload(%s, 0x%x) " 1706 "failed %d\n", __func__, 1707 sc->sc_ifp->if_xname, offload, error); 1708#endif /* BRIDGE_DEBUG */ 1709 goto done; 1710 } 1711 /* 1712 * For ifnet_set_tso_mtu() sake, the TSO MTU must be at least 1713 * as large as the interface MTU 1714 */ 1715 if (sc->sc_ifp->if_hwassist & IFNET_TSO_IPV4) { 1716 if (tso_v4_mtu < sc->sc_ifp->if_mtu) 1717 tso_v4_mtu = sc->sc_ifp->if_mtu; 1718 error = ifnet_set_tso_mtu(sc->sc_ifp, AF_INET, 1719 tso_v4_mtu); 1720 if (error != 0) { 1721#if BRIDGE_DEBUG 1722 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1723 printf("%s: ifnet_set_tso_mtu(%s, " 1724 "AF_INET, %u) failed %d\n", 1725 __func__, sc->sc_ifp->if_xname, 1726 tso_v4_mtu, error); 1727#endif /* BRIDGE_DEBUG */ 1728 goto done; 1729 } 1730 } 1731 if (sc->sc_ifp->if_hwassist & IFNET_TSO_IPV6) { 1732 if (tso_v6_mtu < sc->sc_ifp->if_mtu) 1733 tso_v6_mtu = sc->sc_ifp->if_mtu; 1734 error = ifnet_set_tso_mtu(sc->sc_ifp, AF_INET6, 1735 tso_v6_mtu); 1736 if (error != 0) { 1737#if BRIDGE_DEBUG 1738 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1739 printf("%s: ifnet_set_tso_mtu(%s, " 1740 "AF_INET6, %u) failed %d\n", 1741 __func__, sc->sc_ifp->if_xname, 1742 tso_v6_mtu, error); 1743#endif /* BRIDGE_DEBUG */ 1744 goto done; 1745 } 1746 } 1747 } 1748done: 1749 return (error); 1750} 1751 1752/* 1753 * bridge_lookup_member: 1754 * 1755 * Lookup a bridge member interface. 1756 */ 1757static struct bridge_iflist * 1758bridge_lookup_member(struct bridge_softc *sc, const char *name) 1759{ 1760 struct bridge_iflist *bif; 1761 struct ifnet *ifp; 1762 1763 BRIDGE_LOCK_ASSERT_HELD(sc); 1764 1765 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1766 ifp = bif->bif_ifp; 1767 if (strcmp(ifp->if_xname, name) == 0) 1768 return (bif); 1769 } 1770 1771 return (NULL); 1772} 1773 1774/* 1775 * bridge_lookup_member_if: 1776 * 1777 * Lookup a bridge member interface by ifnet*. 1778 */ 1779static struct bridge_iflist * 1780bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp) 1781{ 1782 struct bridge_iflist *bif; 1783 1784 BRIDGE_LOCK_ASSERT_HELD(sc); 1785 1786 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 1787 if (bif->bif_ifp == member_ifp) 1788 return (bif); 1789 } 1790 1791 return (NULL); 1792} 1793 1794static errno_t 1795bridge_iff_input(void *cookie, ifnet_t ifp, protocol_family_t protocol, 1796 mbuf_t *data, char **frame_ptr) 1797{ 1798#pragma unused(protocol) 1799 errno_t error = 0; 1800 struct bridge_iflist *bif = (struct bridge_iflist *)cookie; 1801 struct bridge_softc *sc = bif->bif_sc; 1802 int included = 0; 1803 size_t frmlen = 0; 1804 mbuf_t m = *data; 1805 1806 if ((m->m_flags & M_PROTO1)) 1807 goto out; 1808 1809 if (*frame_ptr >= (char *)mbuf_datastart(m) && 1810 *frame_ptr <= (char *)mbuf_data(m)) { 1811 included = 1; 1812 frmlen = (char *)mbuf_data(m) - *frame_ptr; 1813 } 1814#if BRIDGE_DEBUG 1815 if (if_bridge_debug & BR_DBGF_INPUT) { 1816 printf("%s: %s from %s m 0x%llx data 0x%llx frame 0x%llx %s " 1817 "frmlen %lu\n", __func__, sc->sc_ifp->if_xname, 1818 ifp->if_xname, (uint64_t)VM_KERNEL_ADDRPERM(m), 1819 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_data(m)), 1820 (uint64_t)VM_KERNEL_ADDRPERM(*frame_ptr), 1821 included ? "inside" : "outside", frmlen); 1822 1823 if (if_bridge_debug & BR_DBGF_MBUF) { 1824 printf_mbuf(m, "bridge_iff_input[", "\n"); 1825 printf_ether_header((struct ether_header *) 1826 (void *)*frame_ptr); 1827 printf_mbuf_data(m, 0, 20); 1828 printf("\n"); 1829 } 1830 } 1831#endif /* BRIDGE_DEBUG */ 1832 1833 /* Move data pointer to start of frame to the link layer header */ 1834 if (included) { 1835 (void) mbuf_setdata(m, (char *)mbuf_data(m) - frmlen, 1836 mbuf_len(m) + frmlen); 1837 (void) mbuf_pkthdr_adjustlen(m, frmlen); 1838 } else { 1839 printf("%s: frame_ptr outside mbuf\n", __func__); 1840 goto out; 1841 } 1842 1843 error = bridge_input(ifp, m, *frame_ptr); 1844 1845 /* Adjust packet back to original */ 1846 if (error == 0) { 1847 (void) mbuf_setdata(m, (char *)mbuf_data(m) + frmlen, 1848 mbuf_len(m) - frmlen); 1849 (void) mbuf_pkthdr_adjustlen(m, -frmlen); 1850 } 1851#if BRIDGE_DEBUG 1852 if ((if_bridge_debug & BR_DBGF_INPUT) && 1853 (if_bridge_debug & BR_DBGF_MBUF)) { 1854 printf("\n"); 1855 printf_mbuf(m, "bridge_iff_input]", "\n"); 1856 } 1857#endif /* BRIDGE_DEBUG */ 1858 1859out: 1860 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 1861 1862 return (error); 1863} 1864 1865#if BRIDGE_MEMBER_OUT_FILTER 1866static errno_t 1867bridge_iff_output(void *cookie, ifnet_t ifp, protocol_family_t protocol, 1868 mbuf_t *data) 1869{ 1870#pragma unused(protocol) 1871 errno_t error = 0; 1872 struct bridge_iflist *bif = (struct bridge_iflist *)cookie; 1873 struct bridge_softc *sc = bif->bif_sc; 1874 mbuf_t m = *data; 1875 1876 if ((m->m_flags & M_PROTO1)) 1877 goto out; 1878 1879#if BRIDGE_DEBUG 1880 if (if_bridge_debug & BR_DBGF_OUTPPUT) { 1881 printf("%s: %s from %s m 0x%llx data 0x%llx\n", __func__, 1882 sc->sc_ifp->if_xname, ifp->if_xname, 1883 (uint64_t)VM_KERNEL_ADDRPERM(m), 1884 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_data(m))); 1885 } 1886#endif /* BRIDGE_DEBUG */ 1887 1888 error = bridge_member_output(sc, ifp, m); 1889 if (error != 0) { 1890 printf("%s: bridge_member_output failed error %d\n", __func__, 1891 error); 1892 } 1893 1894out: 1895 BRIDGE_LOCK_ASSERT_NOTHELD(sc); 1896 1897 return (error); 1898} 1899#endif /* BRIDGE_MEMBER_OUT_FILTER */ 1900 1901static void 1902bridge_iff_event(void *cookie, ifnet_t ifp, protocol_family_t protocol, 1903 const struct kev_msg *event_msg) 1904{ 1905#pragma unused(protocol) 1906 struct bridge_iflist *bif = (struct bridge_iflist *)cookie; 1907 struct bridge_softc *sc = bif->bif_sc; 1908 1909 if (event_msg->vendor_code == KEV_VENDOR_APPLE && 1910 event_msg->kev_class == KEV_NETWORK_CLASS && 1911 event_msg->kev_subclass == KEV_DL_SUBCLASS) { 1912#if BRIDGE_DEBUG 1913 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1914 printf("%s: %s event_code %u - %s\n", __func__, 1915 ifp->if_xname, event_msg->event_code, 1916 dlil_kev_dl_code_str(event_msg->event_code)); 1917#endif /* BRIDGE_DEBUG */ 1918 1919 switch (event_msg->event_code) { 1920 case KEV_DL_IF_DETACHING: 1921 case KEV_DL_IF_DETACHED: { 1922 bridge_ifdetach(bif, ifp); 1923 break; 1924 } 1925 case KEV_DL_LINK_OFF: 1926 case KEV_DL_LINK_ON: { 1927 bridge_iflinkevent(ifp); 1928#if BRIDGESTP 1929 bstp_linkstate(ifp, event_msg->event_code); 1930#endif /* BRIDGESTP */ 1931 break; 1932 } 1933 case KEV_DL_SIFFLAGS: { 1934 if ((bif->bif_flags & BIFF_PROMISC) == 0 && 1935 (ifp->if_flags & IFF_UP)) { 1936 errno_t error; 1937 1938 error = ifnet_set_promiscuous(ifp, 1); 1939 if (error != 0) { 1940 printf("%s: " 1941 "ifnet_set_promiscuous (%s)" 1942 " failed %d\n", 1943 __func__, ifp->if_xname, 1944 error); 1945 } else { 1946 bif->bif_flags |= BIFF_PROMISC; 1947 } 1948 } 1949 break; 1950 } 1951 case KEV_DL_IFCAP_CHANGED: { 1952 BRIDGE_LOCK(sc); 1953 bridge_set_tso(sc); 1954 BRIDGE_UNLOCK(sc); 1955 break; 1956 } 1957 default: 1958 break; 1959 } 1960 } 1961} 1962 1963/* 1964 * bridge_iff_detached: 1965 * 1966 * Detach an interface from a bridge. Called when a member 1967 * interface is detaching. 1968 */ 1969static void 1970bridge_iff_detached(void *cookie, ifnet_t ifp) 1971{ 1972 struct bridge_iflist *bif = (struct bridge_iflist *)cookie; 1973 1974#if BRIDGE_DEBUG 1975 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 1976 printf("%s: %s\n", __func__, ifp->if_xname); 1977#endif /* BRIDGE_DEBUG */ 1978 1979 bridge_ifdetach(bif, ifp); 1980 1981 _FREE(bif, M_DEVBUF); 1982} 1983 1984static errno_t 1985bridge_proto_input(ifnet_t ifp, protocol_family_t protocol, mbuf_t packet, 1986 char *header) 1987{ 1988#pragma unused(protocol, packet, header) 1989#if BRIDGE_DEBUG 1990 printf("%s: unexpected packet from %s\n", __func__, 1991 ifp->if_xname); 1992#endif /* BRIDGE_DEBUG */ 1993 return (0); 1994} 1995 1996static int 1997bridge_attach_protocol(struct ifnet *ifp) 1998{ 1999 int error; 2000 struct ifnet_attach_proto_param reg; 2001 2002#if BRIDGE_DEBUG 2003 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 2004 printf("%s: %s\n", __func__, ifp->if_xname); 2005#endif /* BRIDGE_DEBUG */ 2006 2007 bzero(®, sizeof (reg)); 2008 reg.input = bridge_proto_input; 2009 2010 error = ifnet_attach_protocol(ifp, PF_BRIDGE, ®); 2011 if (error) 2012 printf("%s: ifnet_attach_protocol(%s) failed, %d\n", 2013 __func__, ifp->if_xname, error); 2014 2015 return (error); 2016} 2017 2018static int 2019bridge_detach_protocol(struct ifnet *ifp) 2020{ 2021 int error; 2022 2023#if BRIDGE_DEBUG 2024 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 2025 printf("%s: %s\n", __func__, ifp->if_xname); 2026#endif /* BRIDGE_DEBUG */ 2027 error = ifnet_detach_protocol(ifp, PF_BRIDGE); 2028 if (error) 2029 printf("%s: ifnet_detach_protocol(%s) failed, %d\n", 2030 __func__, ifp->if_xname, error); 2031 2032 return (error); 2033} 2034 2035/* 2036 * bridge_delete_member: 2037 * 2038 * Delete the specified member interface. 2039 */ 2040static void 2041bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif, 2042 int gone) 2043{ 2044 struct ifnet *ifs = bif->bif_ifp, *bifp = sc->sc_ifp; 2045 int lladdr_changed = 0, error, filt_attached; 2046 uint8_t eaddr[ETHER_ADDR_LEN]; 2047 u_int32_t event_code = 0; 2048 2049 BRIDGE_LOCK_ASSERT_HELD(sc); 2050 VERIFY(ifs != NULL); 2051 2052 if (!gone) { 2053 switch (ifs->if_type) { 2054 case IFT_ETHER: 2055 case IFT_L2VLAN: 2056 /* 2057 * Take the interface out of promiscuous mode. 2058 */ 2059 if (bif->bif_flags & BIFF_PROMISC) 2060 (void) ifnet_set_promiscuous(ifs, 0); 2061 break; 2062 2063 case IFT_GIF: 2064 /* currently not supported */ 2065 /* FALLTHRU */ 2066 default: 2067 VERIFY(0); 2068 /* NOTREACHED */ 2069 } 2070 2071#if HAS_IF_CAP 2072 /* reneable any interface capabilities */ 2073 bridge_set_ifcap(sc, bif, bif->bif_savedcaps); 2074#endif 2075 } 2076 2077 if (bif->bif_flags & BIFF_PROTO_ATTACHED) { 2078 /* Respect lock ordering with DLIL lock */ 2079 BRIDGE_UNLOCK(sc); 2080 (void) bridge_detach_protocol(ifs); 2081 BRIDGE_LOCK(sc); 2082 } 2083#if BRIDGESTP 2084 if (bif->bif_ifflags & IFBIF_STP) 2085 bstp_disable(&bif->bif_stp); 2086#endif /* BRIDGESTP */ 2087 2088 BRIDGE_XLOCK(sc); 2089 TAILQ_REMOVE(&sc->sc_iflist, bif, bif_next); 2090 BRIDGE_XDROP(sc); 2091 2092 /* 2093 * If removing the interface that gave the bridge its mac address, set 2094 * the mac address of the bridge to the address of the next member, or 2095 * to its default address if no members are left. 2096 */ 2097 if (bridge_inherit_mac && sc->sc_ifaddr == ifs) { 2098 ifnet_release(sc->sc_ifaddr); 2099 if (TAILQ_EMPTY(&sc->sc_iflist)) { 2100 bcopy(sc->sc_defaddr, eaddr, ETHER_ADDR_LEN); 2101 sc->sc_ifaddr = NULL; 2102 } else { 2103 struct ifnet *fif = 2104 TAILQ_FIRST(&sc->sc_iflist)->bif_ifp; 2105 bcopy(IF_LLADDR(fif), eaddr, ETHER_ADDR_LEN); 2106 sc->sc_ifaddr = fif; 2107 ifnet_reference(fif); /* for sc_ifaddr */ 2108 } 2109 lladdr_changed = 1; 2110 } 2111 2112#if HAS_IF_CAP 2113 bridge_mutecaps(sc); /* recalculate now this interface is removed */ 2114#endif /* HAS_IF_CAP */ 2115 2116 error = bridge_set_tso(sc); 2117 if (error != 0) { 2118 printf("%s: bridge_set_tso failed %d\n", __func__, error); 2119 } 2120 2121 bridge_rtdelete(sc, ifs, IFBF_FLUSHALL); 2122 KASSERT(bif->bif_addrcnt == 0, 2123 ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt)); 2124 2125 filt_attached = bif->bif_flags & BIFF_FILTER_ATTACHED; 2126 2127 /* 2128 * Update link status of the bridge based on its remaining members 2129 */ 2130 event_code = bridge_updatelinkstatus(sc); 2131 2132 BRIDGE_UNLOCK(sc); 2133 2134 if (lladdr_changed && 2135 (error = ifnet_set_lladdr(bifp, eaddr, ETHER_ADDR_LEN)) != 0) 2136 printf("%s: ifnet_set_lladdr failed %d\n", __func__, error); 2137 2138 if (event_code != 0) 2139 bridge_link_event(bifp, event_code); 2140 2141#if BRIDGESTP 2142 bstp_destroy(&bif->bif_stp); /* prepare to free */ 2143#endif /* BRIDGESTP */ 2144 2145 if (filt_attached) 2146 iflt_detach(bif->bif_iff_ref); 2147 else 2148 _FREE(bif, M_DEVBUF); 2149 2150 ifs->if_bridge = NULL; 2151 ifnet_release(ifs); 2152 2153 BRIDGE_LOCK(sc); 2154} 2155 2156/* 2157 * bridge_delete_span: 2158 * 2159 * Delete the specified span interface. 2160 */ 2161static void 2162bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif) 2163{ 2164 BRIDGE_LOCK_ASSERT_HELD(sc); 2165 2166 KASSERT(bif->bif_ifp->if_bridge == NULL, 2167 ("%s: not a span interface", __func__)); 2168 2169 ifnet_release(bif->bif_ifp); 2170 2171 TAILQ_REMOVE(&sc->sc_spanlist, bif, bif_next); 2172 _FREE(bif, M_DEVBUF); 2173} 2174 2175static int 2176bridge_ioctl_add(struct bridge_softc *sc, void *arg) 2177{ 2178 struct ifbreq *req = arg; 2179 struct bridge_iflist *bif = NULL; 2180 struct ifnet *ifs, *bifp = sc->sc_ifp; 2181 int error = 0, lladdr_changed = 0; 2182 uint8_t eaddr[ETHER_ADDR_LEN]; 2183 struct iff_filter iff; 2184 u_int32_t event_code = 0; 2185 2186 ifs = ifunit(req->ifbr_ifsname); 2187 if (ifs == NULL) 2188 return (ENOENT); 2189 if (ifs->if_ioctl == NULL) /* must be supported */ 2190 return (EINVAL); 2191 2192 /* If it's in the span list, it can't be a member. */ 2193 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) 2194 if (ifs == bif->bif_ifp) 2195 return (EBUSY); 2196 2197 if (ifs->if_bridge == sc) 2198 return (EEXIST); 2199 2200 if (ifs->if_bridge != NULL) 2201 return (EBUSY); 2202 2203 switch (ifs->if_type) { 2204 case IFT_ETHER: 2205 case IFT_L2VLAN: 2206 /* permitted interface types */ 2207 break; 2208 case IFT_GIF: 2209 /* currently not supported */ 2210 /* FALLTHRU */ 2211 default: 2212 return (EINVAL); 2213 } 2214 2215 bif = _MALLOC(sizeof (*bif), M_DEVBUF, M_NOWAIT | M_ZERO); 2216 if (bif == NULL) 2217 return (ENOMEM); 2218 2219 bif->bif_ifp = ifs; 2220 ifnet_reference(ifs); 2221 bif->bif_ifflags = IFBIF_LEARNING | IFBIF_DISCOVER; 2222#if HAS_IF_CAP 2223 bif->bif_savedcaps = ifs->if_capenable; 2224#endif /* HAS_IF_CAP */ 2225 bif->bif_sc = sc; 2226 2227 /* Allow the first Ethernet member to define the MTU */ 2228 if (TAILQ_EMPTY(&sc->sc_iflist)) 2229 sc->sc_ifp->if_mtu = ifs->if_mtu; 2230 else if (sc->sc_ifp->if_mtu != ifs->if_mtu) { 2231 printf("%s: %s: invalid MTU for %s", __func__, 2232 sc->sc_ifp->if_xname, 2233 ifs->if_xname); 2234 return (EINVAL); 2235 } 2236 2237 /* 2238 * Assign the interface's MAC address to the bridge if it's the first 2239 * member and the MAC address of the bridge has not been changed from 2240 * the default (randomly) generated one. 2241 */ 2242 if (bridge_inherit_mac && TAILQ_EMPTY(&sc->sc_iflist) && 2243 !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN)) { 2244 bcopy(IF_LLADDR(ifs), eaddr, ETHER_ADDR_LEN); 2245 sc->sc_ifaddr = ifs; 2246 ifnet_reference(ifs); /* for sc_ifaddr */ 2247 lladdr_changed = 1; 2248 } 2249 2250 ifs->if_bridge = sc; 2251#if BRIDGESTP 2252 bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp); 2253#endif /* BRIDGESTP */ 2254 2255 /* 2256 * XXX: XLOCK HERE!?! 2257 */ 2258 TAILQ_INSERT_TAIL(&sc->sc_iflist, bif, bif_next); 2259 2260#if HAS_IF_CAP 2261 /* Set interface capabilities to the intersection set of all members */ 2262 bridge_mutecaps(sc); 2263#endif /* HAS_IF_CAP */ 2264 2265 bridge_set_tso(sc); 2266 2267 2268 /* 2269 * Place the interface into promiscuous mode. 2270 */ 2271 switch (ifs->if_type) { 2272 case IFT_ETHER: 2273 case IFT_L2VLAN: 2274 error = ifnet_set_promiscuous(ifs, 1); 2275 if (error) { 2276 /* Ignore error when device is not up */ 2277 if (error != ENETDOWN) 2278 goto out; 2279 error = 0; 2280 } else { 2281 bif->bif_flags |= BIFF_PROMISC; 2282 } 2283 break; 2284 2285 default: 2286 break; 2287 } 2288 2289 /* 2290 * The new member may change the link status of the bridge interface 2291 */ 2292 if (interface_media_active(ifs)) 2293 bif->bif_flags |= BIFF_MEDIA_ACTIVE; 2294 else 2295 bif->bif_flags &= ~BIFF_MEDIA_ACTIVE; 2296 2297 event_code = bridge_updatelinkstatus(sc); 2298 2299 /* 2300 * Respect lock ordering with DLIL lock for the following operations 2301 */ 2302 BRIDGE_UNLOCK(sc); 2303 2304 /* 2305 * install an interface filter 2306 */ 2307 memset(&iff, 0, sizeof (struct iff_filter)); 2308 iff.iff_cookie = bif; 2309 iff.iff_name = "com.apple.kernel.bsd.net.if_bridge"; 2310 iff.iff_input = bridge_iff_input; 2311#if BRIDGE_MEMBER_OUT_FILTER 2312 iff.iff_output = bridge_iff_output; 2313#endif /* BRIDGE_MEMBER_OUT_FILTER */ 2314 iff.iff_event = bridge_iff_event; 2315 iff.iff_detached = bridge_iff_detached; 2316 error = dlil_attach_filter(ifs, &iff, &bif->bif_iff_ref, DLIL_IFF_TSO); 2317 if (error != 0) { 2318 printf("%s: iflt_attach failed %d\n", __func__, error); 2319 BRIDGE_LOCK(sc); 2320 goto out; 2321 } 2322 bif->bif_flags |= BIFF_FILTER_ATTACHED; 2323 2324 /* 2325 * install an dummy "bridge" protocol 2326 */ 2327 if ((error = bridge_attach_protocol(ifs)) != 0) { 2328 if (error != 0) { 2329 printf("%s: bridge_attach_protocol failed %d\n", 2330 __func__, error); 2331 BRIDGE_LOCK(sc); 2332 goto out; 2333 } 2334 } 2335 bif->bif_flags |= BIFF_PROTO_ATTACHED; 2336 2337 if (lladdr_changed && 2338 (error = ifnet_set_lladdr(bifp, eaddr, ETHER_ADDR_LEN)) != 0) 2339 printf("%s: ifnet_set_lladdr failed %d\n", __func__, error); 2340 2341 if (event_code != 0) 2342 bridge_link_event(bifp, event_code); 2343 2344 BRIDGE_LOCK(sc); 2345 2346out: 2347 if (error && bif != NULL) 2348 bridge_delete_member(sc, bif, 1); 2349 2350 return (error); 2351} 2352 2353static int 2354bridge_ioctl_del(struct bridge_softc *sc, void *arg) 2355{ 2356 struct ifbreq *req = arg; 2357 struct bridge_iflist *bif; 2358 2359 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2360 if (bif == NULL) 2361 return (ENOENT); 2362 2363 bridge_delete_member(sc, bif, 0); 2364 2365 return (0); 2366} 2367 2368static int 2369bridge_ioctl_purge(struct bridge_softc *sc, void *arg) 2370{ 2371#pragma unused(sc, arg) 2372 return (0); 2373} 2374 2375static int 2376bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) 2377{ 2378 struct ifbreq *req = arg; 2379 struct bridge_iflist *bif; 2380 struct bstp_port *bp; 2381 2382 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2383 if (bif == NULL) 2384 return (ENOENT); 2385 2386 bp = &bif->bif_stp; 2387 req->ifbr_ifsflags = bif->bif_ifflags; 2388 req->ifbr_state = bp->bp_state; 2389 req->ifbr_priority = bp->bp_priority; 2390 req->ifbr_path_cost = bp->bp_path_cost; 2391 req->ifbr_portno = bif->bif_ifp->if_index & 0xfff; 2392 req->ifbr_proto = bp->bp_protover; 2393 req->ifbr_role = bp->bp_role; 2394 req->ifbr_stpflags = bp->bp_flags; 2395 req->ifbr_addrcnt = bif->bif_addrcnt; 2396 req->ifbr_addrmax = bif->bif_addrmax; 2397 req->ifbr_addrexceeded = bif->bif_addrexceeded; 2398 2399 /* Copy STP state options as flags */ 2400 if (bp->bp_operedge) 2401 req->ifbr_ifsflags |= IFBIF_BSTP_EDGE; 2402 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) 2403 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; 2404 if (bp->bp_ptp_link) 2405 req->ifbr_ifsflags |= IFBIF_BSTP_PTP; 2406 if (bp->bp_flags & BSTP_PORT_AUTOPTP) 2407 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; 2408 if (bp->bp_flags & BSTP_PORT_ADMEDGE) 2409 req->ifbr_ifsflags |= IFBIF_BSTP_ADMEDGE; 2410 if (bp->bp_flags & BSTP_PORT_ADMCOST) 2411 req->ifbr_ifsflags |= IFBIF_BSTP_ADMCOST; 2412 return (0); 2413} 2414 2415static int 2416bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) 2417{ 2418 struct ifbreq *req = arg; 2419 struct bridge_iflist *bif; 2420#if BRIDGESTP 2421 struct bstp_port *bp; 2422 int error; 2423#endif /* BRIDGESTP */ 2424 2425 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2426 if (bif == NULL) 2427 return (ENOENT); 2428 2429 if (req->ifbr_ifsflags & IFBIF_SPAN) 2430 /* SPAN is readonly */ 2431 return (EINVAL); 2432 2433 2434#if BRIDGESTP 2435 if (req->ifbr_ifsflags & IFBIF_STP) { 2436 if ((bif->bif_ifflags & IFBIF_STP) == 0) { 2437 error = bstp_enable(&bif->bif_stp); 2438 if (error) 2439 return (error); 2440 } 2441 } else { 2442 if ((bif->bif_ifflags & IFBIF_STP) != 0) 2443 bstp_disable(&bif->bif_stp); 2444 } 2445 2446 /* Pass on STP flags */ 2447 bp = &bif->bif_stp; 2448 bstp_set_edge(bp, req->ifbr_ifsflags & IFBIF_BSTP_EDGE ? 1 : 0); 2449 bstp_set_autoedge(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOEDGE ? 1 : 0); 2450 bstp_set_ptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_PTP ? 1 : 0); 2451 bstp_set_autoptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOPTP ? 1 : 0); 2452#else /* !BRIDGESTP */ 2453 if (req->ifbr_ifsflags & IFBIF_STP) 2454 return (EOPNOTSUPP); 2455#endif /* !BRIDGESTP */ 2456 2457 /* Save the bits relating to the bridge */ 2458 bif->bif_ifflags = req->ifbr_ifsflags & IFBIFMASK; 2459 2460 2461 return (0); 2462} 2463 2464static int 2465bridge_ioctl_scache(struct bridge_softc *sc, void *arg) 2466{ 2467 struct ifbrparam *param = arg; 2468 2469 sc->sc_brtmax = param->ifbrp_csize; 2470 bridge_rttrim(sc); 2471 2472 return (0); 2473} 2474 2475static int 2476bridge_ioctl_gcache(struct bridge_softc *sc, void *arg) 2477{ 2478 struct ifbrparam *param = arg; 2479 2480 param->ifbrp_csize = sc->sc_brtmax; 2481 2482 return (0); 2483} 2484 2485#define BRIDGE_IOCTL_GIFS do { \ 2486 struct bridge_iflist *bif; \ 2487 struct ifbreq breq; \ 2488 char *buf, *outbuf; \ 2489 unsigned int count, buflen, len; \ 2490 \ 2491 count = 0; \ 2492 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) \ 2493 count++; \ 2494 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) \ 2495 count++; \ 2496 \ 2497 buflen = sizeof (breq) * count; \ 2498 if (bifc->ifbic_len == 0) { \ 2499 bifc->ifbic_len = buflen; \ 2500 return (0); \ 2501 } \ 2502 BRIDGE_UNLOCK(sc); \ 2503 outbuf = _MALLOC(buflen, M_TEMP, M_WAITOK | M_ZERO); \ 2504 BRIDGE_LOCK(sc); \ 2505 \ 2506 count = 0; \ 2507 buf = outbuf; \ 2508 len = min(bifc->ifbic_len, buflen); \ 2509 bzero(&breq, sizeof (breq)); \ 2510 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { \ 2511 if (len < sizeof (breq)) \ 2512 break; \ 2513 \ 2514 snprintf(breq.ifbr_ifsname, sizeof (breq.ifbr_ifsname), \ 2515 "%s", bif->bif_ifp->if_xname); \ 2516 /* Fill in the ifbreq structure */ \ 2517 error = bridge_ioctl_gifflags(sc, &breq); \ 2518 if (error) \ 2519 break; \ 2520 memcpy(buf, &breq, sizeof (breq)); \ 2521 count++; \ 2522 buf += sizeof (breq); \ 2523 len -= sizeof (breq); \ 2524 } \ 2525 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) { \ 2526 if (len < sizeof (breq)) \ 2527 break; \ 2528 \ 2529 snprintf(breq.ifbr_ifsname, sizeof (breq.ifbr_ifsname), \ 2530 "%s", bif->bif_ifp->if_xname); \ 2531 breq.ifbr_ifsflags = bif->bif_ifflags; \ 2532 breq.ifbr_portno = bif->bif_ifp->if_index & 0xfff; \ 2533 memcpy(buf, &breq, sizeof (breq)); \ 2534 count++; \ 2535 buf += sizeof (breq); \ 2536 len -= sizeof (breq); \ 2537 } \ 2538 \ 2539 BRIDGE_UNLOCK(sc); \ 2540 bifc->ifbic_len = sizeof (breq) * count; \ 2541 error = copyout(outbuf, bifc->ifbic_req, bifc->ifbic_len); \ 2542 BRIDGE_LOCK(sc); \ 2543 _FREE(outbuf, M_TEMP); \ 2544} while (0) 2545 2546static int 2547bridge_ioctl_gifs64(struct bridge_softc *sc, void *arg) 2548{ 2549 struct ifbifconf64 *bifc = arg; 2550 int error = 0; 2551 2552 BRIDGE_IOCTL_GIFS; 2553 2554 return (error); 2555} 2556 2557static int 2558bridge_ioctl_gifs32(struct bridge_softc *sc, void *arg) 2559{ 2560 struct ifbifconf32 *bifc = arg; 2561 int error = 0; 2562 2563 BRIDGE_IOCTL_GIFS; 2564 2565 return (error); 2566} 2567 2568#define BRIDGE_IOCTL_RTS do { \ 2569 struct bridge_rtnode *brt; \ 2570 char *buf, *outbuf; \ 2571 unsigned int count, buflen, len; \ 2572 unsigned long now; \ 2573 \ 2574 if (bac->ifbac_len == 0) \ 2575 return (0); \ 2576 \ 2577 count = 0; \ 2578 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) \ 2579 count++; \ 2580 buflen = sizeof (bareq) * count; \ 2581 \ 2582 BRIDGE_UNLOCK(sc); \ 2583 outbuf = _MALLOC(buflen, M_TEMP, M_WAITOK | M_ZERO); \ 2584 BRIDGE_LOCK(sc); \ 2585 \ 2586 count = 0; \ 2587 buf = outbuf; \ 2588 len = min(bac->ifbac_len, buflen); \ 2589 bzero(&bareq, sizeof (bareq)); \ 2590 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { \ 2591 if (len < sizeof (bareq)) \ 2592 goto out; \ 2593 snprintf(bareq.ifba_ifsname, sizeof (bareq.ifba_ifsname), \ 2594 "%s", brt->brt_ifp->if_xname); \ 2595 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof (brt->brt_addr)); \ 2596 bareq.ifba_vlan = brt->brt_vlan; \ 2597 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { \ 2598 now = (unsigned long) net_uptime(); \ 2599 if (now < brt->brt_expire) \ 2600 bareq.ifba_expire = \ 2601 brt->brt_expire - now; \ 2602 } else \ 2603 bareq.ifba_expire = 0; \ 2604 bareq.ifba_flags = brt->brt_flags; \ 2605 \ 2606 memcpy(buf, &bareq, sizeof (bareq)); \ 2607 count++; \ 2608 buf += sizeof (bareq); \ 2609 len -= sizeof (bareq); \ 2610 } \ 2611out: \ 2612 BRIDGE_UNLOCK(sc); \ 2613 bac->ifbac_len = sizeof (bareq) * count; \ 2614 error = copyout(outbuf, bac->ifbac_req, bac->ifbac_len); \ 2615 BRIDGE_LOCK(sc); \ 2616 _FREE(outbuf, M_TEMP); \ 2617 return (error); \ 2618} while (0) 2619 2620static int 2621bridge_ioctl_rts64(struct bridge_softc *sc, void *arg) 2622{ 2623 struct ifbaconf64 *bac = arg; 2624 struct ifbareq64 bareq; 2625 int error = 0; 2626 2627 BRIDGE_IOCTL_RTS; 2628 2629 return (error); 2630} 2631 2632static int 2633bridge_ioctl_rts32(struct bridge_softc *sc, void *arg) 2634{ 2635 struct ifbaconf32 *bac = arg; 2636 struct ifbareq32 bareq; 2637 int error = 0; 2638 2639 BRIDGE_IOCTL_RTS; 2640 2641 return (error); 2642} 2643 2644static int 2645bridge_ioctl_saddr32(struct bridge_softc *sc, void *arg) 2646{ 2647 struct ifbareq32 *req = arg; 2648 struct bridge_iflist *bif; 2649 int error; 2650 2651 bif = bridge_lookup_member(sc, req->ifba_ifsname); 2652 if (bif == NULL) 2653 return (ENOENT); 2654 2655 error = bridge_rtupdate(sc, req->ifba_dst, req->ifba_vlan, bif, 1, 2656 req->ifba_flags); 2657 2658 return (error); 2659} 2660 2661static int 2662bridge_ioctl_saddr64(struct bridge_softc *sc, void *arg) 2663{ 2664 struct ifbareq64 *req = arg; 2665 struct bridge_iflist *bif; 2666 int error; 2667 2668 bif = bridge_lookup_member(sc, req->ifba_ifsname); 2669 if (bif == NULL) 2670 return (ENOENT); 2671 2672 error = bridge_rtupdate(sc, req->ifba_dst, req->ifba_vlan, bif, 1, 2673 req->ifba_flags); 2674 2675 return (error); 2676} 2677 2678static int 2679bridge_ioctl_sto(struct bridge_softc *sc, void *arg) 2680{ 2681 struct ifbrparam *param = arg; 2682 2683 sc->sc_brttimeout = param->ifbrp_ctime; 2684 return (0); 2685} 2686 2687static int 2688bridge_ioctl_gto(struct bridge_softc *sc, void *arg) 2689{ 2690 struct ifbrparam *param = arg; 2691 2692 param->ifbrp_ctime = sc->sc_brttimeout; 2693 return (0); 2694} 2695 2696static int 2697bridge_ioctl_daddr32(struct bridge_softc *sc, void *arg) 2698{ 2699 struct ifbareq32 *req = arg; 2700 2701 return (bridge_rtdaddr(sc, req->ifba_dst, req->ifba_vlan)); 2702} 2703 2704static int 2705bridge_ioctl_daddr64(struct bridge_softc *sc, void *arg) 2706{ 2707 struct ifbareq64 *req = arg; 2708 2709 return (bridge_rtdaddr(sc, req->ifba_dst, req->ifba_vlan)); 2710} 2711 2712static int 2713bridge_ioctl_flush(struct bridge_softc *sc, void *arg) 2714{ 2715 struct ifbreq *req = arg; 2716 2717 bridge_rtflush(sc, req->ifbr_ifsflags); 2718 return (0); 2719} 2720 2721static int 2722bridge_ioctl_gpri(struct bridge_softc *sc, void *arg) 2723{ 2724 struct ifbrparam *param = arg; 2725 struct bstp_state *bs = &sc->sc_stp; 2726 2727 param->ifbrp_prio = bs->bs_bridge_priority; 2728 return (0); 2729} 2730 2731static int 2732bridge_ioctl_spri(struct bridge_softc *sc, void *arg) 2733{ 2734#if BRIDGESTP 2735 struct ifbrparam *param = arg; 2736 2737 return (bstp_set_priority(&sc->sc_stp, param->ifbrp_prio)); 2738#else /* !BRIDGESTP */ 2739#pragma unused(sc, arg) 2740 return (EOPNOTSUPP); 2741#endif /* !BRIDGESTP */ 2742} 2743 2744static int 2745bridge_ioctl_ght(struct bridge_softc *sc, void *arg) 2746{ 2747 struct ifbrparam *param = arg; 2748 struct bstp_state *bs = &sc->sc_stp; 2749 2750 param->ifbrp_hellotime = bs->bs_bridge_htime >> 8; 2751 return (0); 2752} 2753 2754static int 2755bridge_ioctl_sht(struct bridge_softc *sc, void *arg) 2756{ 2757#if BRIDGESTP 2758 struct ifbrparam *param = arg; 2759 2760 return (bstp_set_htime(&sc->sc_stp, param->ifbrp_hellotime)); 2761#else /* !BRIDGESTP */ 2762#pragma unused(sc, arg) 2763 return (EOPNOTSUPP); 2764#endif /* !BRIDGESTP */ 2765} 2766 2767static int 2768bridge_ioctl_gfd(struct bridge_softc *sc, void *arg) 2769{ 2770 struct ifbrparam *param = arg; 2771 struct bstp_state *bs = &sc->sc_stp; 2772 2773 param->ifbrp_fwddelay = bs->bs_bridge_fdelay >> 8; 2774 return (0); 2775} 2776 2777static int 2778bridge_ioctl_sfd(struct bridge_softc *sc, void *arg) 2779{ 2780#if BRIDGESTP 2781 struct ifbrparam *param = arg; 2782 2783 return (bstp_set_fdelay(&sc->sc_stp, param->ifbrp_fwddelay)); 2784#else /* !BRIDGESTP */ 2785#pragma unused(sc, arg) 2786 return (EOPNOTSUPP); 2787#endif /* !BRIDGESTP */ 2788} 2789 2790static int 2791bridge_ioctl_gma(struct bridge_softc *sc, void *arg) 2792{ 2793 struct ifbrparam *param = arg; 2794 struct bstp_state *bs = &sc->sc_stp; 2795 2796 param->ifbrp_maxage = bs->bs_bridge_max_age >> 8; 2797 return (0); 2798} 2799 2800static int 2801bridge_ioctl_sma(struct bridge_softc *sc, void *arg) 2802{ 2803#if BRIDGESTP 2804 struct ifbrparam *param = arg; 2805 2806 return (bstp_set_maxage(&sc->sc_stp, param->ifbrp_maxage)); 2807#else /* !BRIDGESTP */ 2808#pragma unused(sc, arg) 2809 return (EOPNOTSUPP); 2810#endif /* !BRIDGESTP */ 2811} 2812 2813static int 2814bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) 2815{ 2816#if BRIDGESTP 2817 struct ifbreq *req = arg; 2818 struct bridge_iflist *bif; 2819 2820 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2821 if (bif == NULL) 2822 return (ENOENT); 2823 2824 return (bstp_set_port_priority(&bif->bif_stp, req->ifbr_priority)); 2825#else /* !BRIDGESTP */ 2826#pragma unused(sc, arg) 2827 return (EOPNOTSUPP); 2828#endif /* !BRIDGESTP */ 2829} 2830 2831static int 2832bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) 2833{ 2834#if BRIDGESTP 2835 struct ifbreq *req = arg; 2836 struct bridge_iflist *bif; 2837 2838 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2839 if (bif == NULL) 2840 return (ENOENT); 2841 2842 return (bstp_set_path_cost(&bif->bif_stp, req->ifbr_path_cost)); 2843#else /* !BRIDGESTP */ 2844#pragma unused(sc, arg) 2845 return (EOPNOTSUPP); 2846#endif /* !BRIDGESTP */ 2847} 2848 2849static int 2850bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg) 2851{ 2852 struct ifbrparam *param = arg; 2853 2854 param->ifbrp_filter = sc->sc_filter_flags; 2855 2856 return (0); 2857} 2858 2859static int 2860bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg) 2861{ 2862 struct ifbrparam *param = arg; 2863 2864 if (param->ifbrp_filter & ~IFBF_FILT_MASK) 2865 return (EINVAL); 2866 2867#ifndef BRIDGE_IPF 2868 if (param->ifbrp_filter & IFBF_FILT_USEIPF) 2869 return (EINVAL); 2870#endif 2871 2872 sc->sc_filter_flags = param->ifbrp_filter; 2873 2874 return (0); 2875} 2876 2877static int 2878bridge_ioctl_sifmaxaddr(struct bridge_softc *sc, void *arg) 2879{ 2880 struct ifbreq *req = arg; 2881 struct bridge_iflist *bif; 2882 2883 bif = bridge_lookup_member(sc, req->ifbr_ifsname); 2884 if (bif == NULL) 2885 return (ENOENT); 2886 2887 bif->bif_addrmax = req->ifbr_addrmax; 2888 return (0); 2889} 2890 2891static int 2892bridge_ioctl_addspan(struct bridge_softc *sc, void *arg) 2893{ 2894 struct ifbreq *req = arg; 2895 struct bridge_iflist *bif = NULL; 2896 struct ifnet *ifs; 2897 2898 ifs = ifunit(req->ifbr_ifsname); 2899 if (ifs == NULL) 2900 return (ENOENT); 2901 2902 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) 2903 if (ifs == bif->bif_ifp) 2904 return (EBUSY); 2905 2906 if (ifs->if_bridge != NULL) 2907 return (EBUSY); 2908 2909 switch (ifs->if_type) { 2910 case IFT_ETHER: 2911 case IFT_L2VLAN: 2912 break; 2913 case IFT_GIF: 2914 /* currently not supported */ 2915 /* FALLTHRU */ 2916 default: 2917 return (EINVAL); 2918 } 2919 2920 bif = _MALLOC(sizeof (*bif), M_DEVBUF, M_NOWAIT | M_ZERO); 2921 if (bif == NULL) 2922 return (ENOMEM); 2923 2924 bif->bif_ifp = ifs; 2925 bif->bif_ifflags = IFBIF_SPAN; 2926 2927 ifnet_reference(bif->bif_ifp); 2928 2929 TAILQ_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next); 2930 2931 return (0); 2932} 2933 2934static int 2935bridge_ioctl_delspan(struct bridge_softc *sc, void *arg) 2936{ 2937 struct ifbreq *req = arg; 2938 struct bridge_iflist *bif; 2939 struct ifnet *ifs; 2940 2941 ifs = ifunit(req->ifbr_ifsname); 2942 if (ifs == NULL) 2943 return (ENOENT); 2944 2945 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) 2946 if (ifs == bif->bif_ifp) 2947 break; 2948 2949 if (bif == NULL) 2950 return (ENOENT); 2951 2952 bridge_delete_span(sc, bif); 2953 2954 return (0); 2955} 2956 2957#define BRIDGE_IOCTL_GBPARAM do { \ 2958 struct bstp_state *bs = &sc->sc_stp; \ 2959 struct bstp_port *root_port; \ 2960 \ 2961 req->ifbop_maxage = bs->bs_bridge_max_age >> 8; \ 2962 req->ifbop_hellotime = bs->bs_bridge_htime >> 8; \ 2963 req->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8; \ 2964 \ 2965 root_port = bs->bs_root_port; \ 2966 if (root_port == NULL) \ 2967 req->ifbop_root_port = 0; \ 2968 else \ 2969 req->ifbop_root_port = root_port->bp_ifp->if_index; \ 2970 \ 2971 req->ifbop_holdcount = bs->bs_txholdcount; \ 2972 req->ifbop_priority = bs->bs_bridge_priority; \ 2973 req->ifbop_protocol = bs->bs_protover; \ 2974 req->ifbop_root_path_cost = bs->bs_root_pv.pv_cost; \ 2975 req->ifbop_bridgeid = bs->bs_bridge_pv.pv_dbridge_id; \ 2976 req->ifbop_designated_root = bs->bs_root_pv.pv_root_id; \ 2977 req->ifbop_designated_bridge = bs->bs_root_pv.pv_dbridge_id; \ 2978 req->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec; \ 2979 req->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec; \ 2980} while (0) 2981 2982static int 2983bridge_ioctl_gbparam32(struct bridge_softc *sc, void *arg) 2984{ 2985 struct ifbropreq32 *req = arg; 2986 2987 BRIDGE_IOCTL_GBPARAM; 2988 2989 return (0); 2990} 2991 2992static int 2993bridge_ioctl_gbparam64(struct bridge_softc *sc, void *arg) 2994{ 2995 struct ifbropreq64 *req = arg; 2996 2997 BRIDGE_IOCTL_GBPARAM; 2998 2999 return (0); 3000} 3001 3002static int 3003bridge_ioctl_grte(struct bridge_softc *sc, void *arg) 3004{ 3005 struct ifbrparam *param = arg; 3006 3007 param->ifbrp_cexceeded = sc->sc_brtexceeded; 3008 return (0); 3009} 3010 3011#define BRIDGE_IOCTL_GIFSSTP do { \ 3012 struct bridge_iflist *bif; \ 3013 struct bstp_port *bp; \ 3014 struct ifbpstpreq bpreq; \ 3015 char *buf, *outbuf; \ 3016 unsigned int count, buflen, len; \ 3017 \ 3018 count = 0; \ 3019 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { \ 3020 if ((bif->bif_ifflags & IFBIF_STP) != 0) \ 3021 count++; \ 3022 } \ 3023 \ 3024 buflen = sizeof (bpreq) * count; \ 3025 if (bifstp->ifbpstp_len == 0) { \ 3026 bifstp->ifbpstp_len = buflen; \ 3027 return (0); \ 3028 } \ 3029 \ 3030 BRIDGE_UNLOCK(sc); \ 3031 outbuf = _MALLOC(buflen, M_TEMP, M_WAITOK | M_ZERO); \ 3032 BRIDGE_LOCK(sc); \ 3033 \ 3034 count = 0; \ 3035 buf = outbuf; \ 3036 len = min(bifstp->ifbpstp_len, buflen); \ 3037 bzero(&bpreq, sizeof (bpreq)); \ 3038 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { \ 3039 if (len < sizeof (bpreq)) \ 3040 break; \ 3041 \ 3042 if ((bif->bif_ifflags & IFBIF_STP) == 0) \ 3043 continue; \ 3044 \ 3045 bp = &bif->bif_stp; \ 3046 bpreq.ifbp_portno = bif->bif_ifp->if_index & 0xfff; \ 3047 bpreq.ifbp_fwd_trans = bp->bp_forward_transitions; \ 3048 bpreq.ifbp_design_cost = bp->bp_desg_pv.pv_cost; \ 3049 bpreq.ifbp_design_port = bp->bp_desg_pv.pv_port_id; \ 3050 bpreq.ifbp_design_bridge = bp->bp_desg_pv.pv_dbridge_id; \ 3051 bpreq.ifbp_design_root = bp->bp_desg_pv.pv_root_id; \ 3052 \ 3053 memcpy(buf, &bpreq, sizeof (bpreq)); \ 3054 count++; \ 3055 buf += sizeof (bpreq); \ 3056 len -= sizeof (bpreq); \ 3057 } \ 3058 \ 3059 BRIDGE_UNLOCK(sc); \ 3060 bifstp->ifbpstp_len = sizeof (bpreq) * count; \ 3061 error = copyout(outbuf, bifstp->ifbpstp_req, bifstp->ifbpstp_len); \ 3062 BRIDGE_LOCK(sc); \ 3063 _FREE(outbuf, M_TEMP); \ 3064 return (error); \ 3065} while (0) 3066 3067static int 3068bridge_ioctl_gifsstp32(struct bridge_softc *sc, void *arg) 3069{ 3070 struct ifbpstpconf32 *bifstp = arg; 3071 int error = 0; 3072 3073 BRIDGE_IOCTL_GIFSSTP; 3074 3075 return (error); 3076} 3077 3078static int 3079bridge_ioctl_gifsstp64(struct bridge_softc *sc, void *arg) 3080{ 3081 struct ifbpstpconf64 *bifstp = arg; 3082 int error = 0; 3083 3084 BRIDGE_IOCTL_GIFSSTP; 3085 3086 return (error); 3087} 3088 3089static int 3090bridge_ioctl_sproto(struct bridge_softc *sc, void *arg) 3091{ 3092#if BRIDGESTP 3093 struct ifbrparam *param = arg; 3094 3095 return (bstp_set_protocol(&sc->sc_stp, param->ifbrp_proto)); 3096#else /* !BRIDGESTP */ 3097#pragma unused(sc, arg) 3098 return (EOPNOTSUPP); 3099#endif /* !BRIDGESTP */ 3100} 3101 3102static int 3103bridge_ioctl_stxhc(struct bridge_softc *sc, void *arg) 3104{ 3105#if BRIDGESTP 3106 struct ifbrparam *param = arg; 3107 3108 return (bstp_set_holdcount(&sc->sc_stp, param->ifbrp_txhc)); 3109#else /* !BRIDGESTP */ 3110#pragma unused(sc, arg) 3111 return (EOPNOTSUPP); 3112#endif /* !BRIDGESTP */ 3113} 3114 3115/* 3116 * bridge_ifdetach: 3117 * 3118 * Detach an interface from a bridge. Called when a member 3119 * interface is detaching. 3120 */ 3121__private_extern__ void 3122bridge_ifdetach(struct bridge_iflist *bif, struct ifnet *ifp) 3123{ 3124 struct bridge_softc *sc = ifp->if_bridge; 3125 3126#if BRIDGE_DEBUG 3127 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 3128 printf("%s: %s\n", __func__, ifp->if_xname); 3129#endif /* BRIDGE_DEBUG */ 3130 3131 /* Check if the interface is a bridge member */ 3132 if (sc != NULL) { 3133 BRIDGE_LOCK(sc); 3134 bif = bridge_lookup_member_if(sc, ifp); 3135 if (bif != NULL) 3136 bridge_delete_member(sc, bif, 1); 3137 BRIDGE_UNLOCK(sc); 3138 return; 3139 } 3140 3141 /* Check if the interface is a span port */ 3142 lck_mtx_lock(&bridge_list_mtx); 3143 LIST_FOREACH(sc, &bridge_list, sc_list) { 3144 BRIDGE_LOCK(sc); 3145 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) 3146 if (ifp == bif->bif_ifp) { 3147 bridge_delete_span(sc, bif); 3148 break; 3149 } 3150 BRIDGE_UNLOCK(sc); 3151 } 3152 lck_mtx_unlock(&bridge_list_mtx); 3153} 3154 3155/* 3156 * interface_media_active: 3157 * 3158 * Tells if an interface media is active. 3159 */ 3160static int 3161interface_media_active(struct ifnet *ifp) 3162{ 3163 struct ifmediareq ifmr; 3164 int status = 0; 3165 3166 bzero(&ifmr, sizeof(ifmr)); 3167 if (ifnet_ioctl(ifp, 0, SIOCGIFMEDIA, &ifmr) == 0) { 3168 if ((ifmr.ifm_status & IFM_AVALID) && ifmr.ifm_count > 0) 3169 status = ifmr.ifm_status & IFM_ACTIVE ? 1 : 0; 3170 } 3171 3172 return (status); 3173} 3174 3175/* 3176 * bridge_updatelinkstatus: 3177 * 3178 * Update the media active status of the bridge based on the 3179 * media active status of its member. 3180 * If changed, return the corresponding onf/off link event. 3181 */ 3182static u_int32_t 3183bridge_updatelinkstatus(struct bridge_softc *sc) 3184{ 3185 struct bridge_iflist *bif; 3186 int active_member = 0; 3187 u_int32_t event_code = 0; 3188 3189 BRIDGE_LOCK_ASSERT_HELD(sc); 3190 3191 /* 3192 * Find out if we have an active interface 3193 */ 3194 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 3195 if (bif->bif_flags & BIFF_MEDIA_ACTIVE) { 3196 active_member = 1; 3197 break; 3198 } 3199 } 3200 3201 if (active_member && !(sc->sc_flags & SCF_MEDIA_ACTIVE)) { 3202 sc->sc_flags |= SCF_MEDIA_ACTIVE; 3203 event_code = KEV_DL_LINK_ON; 3204 } else if (!active_member && (sc->sc_flags & SCF_MEDIA_ACTIVE)) { 3205 sc->sc_flags &= ~SCF_MEDIA_ACTIVE; 3206 event_code = KEV_DL_LINK_OFF; 3207 } 3208 3209 return (event_code); 3210} 3211 3212/* 3213 * bridge_iflinkevent: 3214 */ 3215static void 3216bridge_iflinkevent(struct ifnet *ifp) 3217{ 3218 struct bridge_softc *sc = ifp->if_bridge; 3219 struct bridge_iflist *bif; 3220 u_int32_t event_code = 0; 3221 3222#if BRIDGE_DEBUG 3223 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 3224 printf("%s: %s\n", __func__, ifp->if_xname); 3225#endif /* BRIDGE_DEBUG */ 3226 3227 /* Check if the interface is a bridge member */ 3228 if (sc == NULL) 3229 return; 3230 3231 BRIDGE_LOCK(sc); 3232 bif = bridge_lookup_member_if(sc, ifp); 3233 if (bif != NULL) { 3234 if (interface_media_active(ifp)) 3235 bif->bif_flags |= BIFF_MEDIA_ACTIVE; 3236 else 3237 bif->bif_flags &= ~BIFF_MEDIA_ACTIVE; 3238 3239 event_code = bridge_updatelinkstatus(sc); 3240 } 3241 BRIDGE_UNLOCK(sc); 3242 3243 if (event_code != 0) 3244 bridge_link_event(sc->sc_ifp, event_code); 3245} 3246 3247/* 3248 * bridge_delayed_callback: 3249 * 3250 * Makes a delayed call 3251 */ 3252static void 3253bridge_delayed_callback(void *param) 3254{ 3255 struct bridge_delayed_call *call = (struct bridge_delayed_call *)param; 3256 struct bridge_softc *sc = call->bdc_sc; 3257 3258#if BRIDGE_DEBUG_DELAYED_CALLBACK 3259 if (bridge_delayed_callback_delay > 0) { 3260 struct timespec ts; 3261 3262 ts.tv_sec = bridge_delayed_callback_delay; 3263 ts.tv_nsec = 0; 3264 3265 printf("%s: sleeping for %d seconds\n", 3266 __func__, bridge_delayed_callback_delay); 3267 3268 msleep(&bridge_delayed_callback_delay, NULL, PZERO, 3269 __func__, &ts); 3270 3271 printf("%s: awoken\n", __func__); 3272 } 3273#endif /* BRIDGE_DEBUG_DELAYED_CALLBACK */ 3274 3275 BRIDGE_LOCK(sc); 3276 3277#if BRIDGE_DEBUG 3278 if (if_bridge_debug & BR_DBGF_DELAYED_CALL) 3279 printf("%s: %s call 0x%llx flags 0x%x\n", __func__, 3280 sc->sc_if_xname, (uint64_t)VM_KERNEL_ADDRPERM(call), 3281 call->bdc_flags); 3282#endif /* BRIDGE_DEBUG */ 3283 3284 if (call->bdc_flags & BDCF_CANCELLING) { 3285 wakeup(call); 3286 } else { 3287 if ((sc->sc_flags & SCF_DETACHING) == 0) 3288 (*call->bdc_func)(sc); 3289 } 3290 call->bdc_flags &= ~BDCF_OUTSTANDING; 3291 BRIDGE_UNLOCK(sc); 3292} 3293 3294/* 3295 * bridge_schedule_delayed_call: 3296 * 3297 * Schedule a function to be called on a separate thread 3298 * The actual call may be scheduled to run at a given time or ASAP. 3299 */ 3300static void 3301bridge_schedule_delayed_call(struct bridge_delayed_call *call) 3302{ 3303 uint64_t deadline = 0; 3304 struct bridge_softc *sc = call->bdc_sc; 3305 3306 BRIDGE_LOCK_ASSERT_HELD(sc); 3307 3308 if ((sc->sc_flags & SCF_DETACHING) || 3309 (call->bdc_flags & (BDCF_OUTSTANDING | BDCF_CANCELLING))) 3310 return; 3311 3312 if (call->bdc_ts.tv_sec || call->bdc_ts.tv_nsec) { 3313 nanoseconds_to_absolutetime( 3314 (uint64_t)call->bdc_ts.tv_sec * NSEC_PER_SEC + 3315 call->bdc_ts.tv_nsec, &deadline); 3316 clock_absolutetime_interval_to_deadline(deadline, &deadline); 3317 } 3318 3319 call->bdc_flags = BDCF_OUTSTANDING; 3320 3321#if BRIDGE_DEBUG 3322 if (if_bridge_debug & BR_DBGF_DELAYED_CALL) 3323 printf("%s: %s call 0x%llx flags 0x%x\n", __func__, 3324 sc->sc_if_xname, (uint64_t)VM_KERNEL_ADDRPERM(call), 3325 call->bdc_flags); 3326#endif /* BRIDGE_DEBUG */ 3327 3328 thread_call_func_delayed((thread_call_func_t)bridge_delayed_callback, 3329 call, deadline); 3330} 3331 3332/* 3333 * bridge_cancel_delayed_call: 3334 * 3335 * Cancel a queued or running delayed call. 3336 * If call is running, does not return until the call is done to 3337 * prevent race condition with the brigde interface getting destroyed 3338 */ 3339static void 3340bridge_cancel_delayed_call(struct bridge_delayed_call *call) 3341{ 3342 boolean_t result; 3343 struct bridge_softc *sc = call->bdc_sc; 3344 3345 /* 3346 * The call was never scheduled 3347 */ 3348 if (sc == NULL) 3349 return; 3350 3351 BRIDGE_LOCK_ASSERT_HELD(sc); 3352 3353 call->bdc_flags |= BDCF_CANCELLING; 3354 3355 while (call->bdc_flags & BDCF_OUTSTANDING) { 3356#if BRIDGE_DEBUG 3357 if (if_bridge_debug & BR_DBGF_DELAYED_CALL) 3358 printf("%s: %s call 0x%llx flags 0x%x\n", __func__, 3359 sc->sc_if_xname, (uint64_t)VM_KERNEL_ADDRPERM(call), 3360 call->bdc_flags); 3361#endif /* BRIDGE_DEBUG */ 3362 result = thread_call_func_cancel( 3363 (thread_call_func_t)bridge_delayed_callback, call, FALSE); 3364 3365 if (result) { 3366 /* 3367 * We managed to dequeue the delayed call 3368 */ 3369 call->bdc_flags &= ~BDCF_OUTSTANDING; 3370 } else { 3371 /* 3372 * Wait for delayed call do be done running 3373 */ 3374 msleep(call, &sc->sc_mtx, PZERO, __func__, NULL); 3375 } 3376 } 3377 call->bdc_flags &= ~BDCF_CANCELLING; 3378} 3379 3380/* 3381 * bridge_init: 3382 * 3383 * Initialize a bridge interface. 3384 */ 3385static int 3386bridge_init(struct ifnet *ifp) 3387{ 3388 struct bridge_softc *sc = (struct bridge_softc *)ifp->if_softc; 3389 errno_t error; 3390 3391 BRIDGE_LOCK_ASSERT_HELD(sc); 3392 3393 if ((ifnet_flags(ifp) & IFF_RUNNING)) 3394 return (0); 3395 3396 error = ifnet_set_flags(ifp, IFF_RUNNING, IFF_RUNNING); 3397 3398 /* 3399 * Calling bridge_aging_timer() is OK as there are no entries to 3400 * age so we're just going to arm the timer 3401 */ 3402 bridge_aging_timer(sc); 3403 3404#if BRIDGESTP 3405 if (error == 0) 3406 bstp_init(&sc->sc_stp); /* Initialize Spanning Tree */ 3407#endif /* BRIDGESTP */ 3408 3409 return (error); 3410} 3411 3412/* 3413 * bridge_ifstop: 3414 * 3415 * Stop the bridge interface. 3416 */ 3417static void 3418bridge_ifstop(struct ifnet *ifp, int disable) 3419{ 3420#pragma unused(disable) 3421 struct bridge_softc *sc = ifp->if_softc; 3422 3423 BRIDGE_LOCK_ASSERT_HELD(sc); 3424 3425 if ((ifnet_flags(ifp) & IFF_RUNNING) == 0) 3426 return; 3427 3428 bridge_cancel_delayed_call(&sc->sc_aging_timer); 3429 3430#if BRIDGESTP 3431 bstp_stop(&sc->sc_stp); 3432#endif /* BRIDGESTP */ 3433 3434 bridge_rtflush(sc, IFBF_FLUSHDYN); 3435 3436 (void) ifnet_set_flags(ifp, 0, IFF_RUNNING); 3437} 3438 3439/* 3440 * bridge_enqueue: 3441 * 3442 * Enqueue a packet on a bridge member interface. 3443 * 3444 */ 3445static int 3446bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m) 3447{ 3448 int len, error = 0; 3449 short mflags; 3450 struct mbuf *m0; 3451 3452 VERIFY(dst_ifp != NULL); 3453 3454 /* 3455 * We may be sending a fragment so traverse the mbuf 3456 * 3457 * NOTE: bridge_fragment() is called only when PFIL_HOOKS is enabled. 3458 */ 3459 for (; m; m = m0) { 3460 errno_t _error; 3461 struct flowadv adv = { FADV_SUCCESS }; 3462 3463 m0 = m->m_nextpkt; 3464 m->m_nextpkt = NULL; 3465 3466 len = m->m_pkthdr.len; 3467 mflags = m->m_flags; 3468 m->m_flags |= M_PROTO1; /* set to avoid loops */ 3469 3470 bridge_finalize_cksum(dst_ifp, m); 3471 3472#if HAS_IF_CAP 3473 /* 3474 * If underlying interface can not do VLAN tag insertion itself 3475 * then attach a packet tag that holds it. 3476 */ 3477 if ((m->m_flags & M_VLANTAG) && 3478 (dst_ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) { 3479 m = ether_vlanencap(m, m->m_pkthdr.ether_vtag); 3480 if (m == NULL) { 3481 printf("%s: %s: unable to prepend VLAN " 3482 "header\n", __func__, dst_ifp->if_xname); 3483 (void) ifnet_stat_increment_out(dst_ifp, 3484 0, 0, 1); 3485 continue; 3486 } 3487 m->m_flags &= ~M_VLANTAG; 3488 } 3489#endif /* HAS_IF_CAP */ 3490 3491 _error = dlil_output(dst_ifp, 0, m, NULL, NULL, 1, &adv); 3492 3493 /* Preserve existing error value */ 3494 if (error == 0) { 3495 if (_error != 0) 3496 error = _error; 3497 else if (adv.code == FADV_FLOW_CONTROLLED) 3498 error = EQFULL; 3499 else if (adv.code == FADV_SUSPENDED) 3500 error = EQSUSPENDED; 3501 } 3502 3503 if (_error == 0) { 3504 (void) ifnet_stat_increment_out(sc->sc_ifp, 1, len, 0); 3505 } else { 3506 (void) ifnet_stat_increment_out(sc->sc_ifp, 0, 0, 1); 3507 } 3508 } 3509 3510 return (error); 3511} 3512 3513#if HAS_BRIDGE_DUMMYNET 3514/* 3515 * bridge_dummynet: 3516 * 3517 * Receive a queued packet from dummynet and pass it on to the output 3518 * interface. 3519 * 3520 * The mbuf has the Ethernet header already attached. 3521 */ 3522static void 3523bridge_dummynet(struct mbuf *m, struct ifnet *ifp) 3524{ 3525 struct bridge_softc *sc; 3526 3527 sc = ifp->if_bridge; 3528 3529 /* 3530 * The packet didnt originate from a member interface. This should only 3531 * ever happen if a member interface is removed while packets are 3532 * queued for it. 3533 */ 3534 if (sc == NULL) { 3535 m_freem(m); 3536 return; 3537 } 3538 3539 if (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6) { 3540 if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0) 3541 return; 3542 if (m == NULL) 3543 return; 3544 } 3545 3546 (void) bridge_enqueue(sc, ifp, m); 3547} 3548#endif /* HAS_BRIDGE_DUMMYNET */ 3549 3550#if BRIDGE_MEMBER_OUT_FILTER 3551/* 3552 * bridge_member_output: 3553 * 3554 * Send output from a bridge member interface. This 3555 * performs the bridging function for locally originated 3556 * packets. 3557 * 3558 * The mbuf has the Ethernet header already attached. We must 3559 * enqueue or free the mbuf before returning. 3560 */ 3561static int 3562bridge_member_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, 3563 struct rtentry *rt) 3564{ 3565#pragma unused(sa, rt) 3566 struct ether_header *eh; 3567 struct ifnet *dst_if; 3568 struct bridge_softc *sc; 3569 uint16_t vlan; 3570 3571#if BRIDGE_DEBUG 3572 if (if_bridge_debug & BR_DBGF_OUTPPUT) 3573 printf("%s: ifp %s\n", __func__, ifp->if_xname); 3574#endif /* BRIDGE_DEBUG */ 3575 3576 if (m->m_len < ETHER_HDR_LEN) { 3577 m = m_pullup(m, ETHER_HDR_LEN); 3578 if (m == NULL) 3579 return (0); 3580 } 3581 3582 eh = mtod(m, struct ether_header *); 3583 sc = ifp->if_bridge; 3584 vlan = VLANTAGOF(m); 3585 3586 BRIDGE_LOCK(sc); 3587 3588 /* 3589 * APPLE MODIFICATION 3590 * If the packet is an 802.1X ethertype, then only send on the 3591 * original output interface. 3592 */ 3593 if (eh->ether_type == htons(ETHERTYPE_PAE)) { 3594 dst_if = ifp; 3595 goto sendunicast; 3596 } 3597 3598 /* 3599 * If bridge is down, but the original output interface is up, 3600 * go ahead and send out that interface. Otherwise, the packet 3601 * is dropped below. 3602 */ 3603 if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) { 3604 dst_if = ifp; 3605 goto sendunicast; 3606 } 3607 3608 /* 3609 * If the packet is a multicast, or we don't know a better way to 3610 * get there, send to all interfaces. 3611 */ 3612 if (ETHER_IS_MULTICAST(eh->ether_dhost)) 3613 dst_if = NULL; 3614 else 3615 dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan); 3616 if (dst_if == NULL) { 3617 struct bridge_iflist *bif; 3618 struct mbuf *mc; 3619 int error = 0, used = 0; 3620 3621 bridge_span(sc, m); 3622 3623 BRIDGE_LOCK2REF(sc, error); 3624 if (error) { 3625 m_freem(m); 3626 return (0); 3627 } 3628 3629 TAILQ_FOREACH(bif, &sc->sc_iflist, bif_next) { 3630 dst_if = bif->bif_ifp; 3631 3632 if (dst_if->if_type == IFT_GIF) 3633 continue; 3634 if ((dst_if->if_flags & IFF_RUNNING) == 0) 3635 continue; 3636 3637 /* 3638 * If this is not the original output interface, 3639 * and the interface is participating in spanning 3640 * tree, make sure the port is in a state that 3641 * allows forwarding. 3642 */ 3643 if (dst_if != ifp && (bif->bif_ifflags & IFBIF_STP) && 3644 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) 3645 continue; 3646 3647 if (LIST_NEXT(bif, bif_next) == NULL) { 3648 used = 1; 3649 mc = m; 3650 } else { 3651 mc = m_copypacket(m, M_DONTWAIT); 3652 if (mc == NULL) { 3653 (void) ifnet_stat_increment_out( 3654 sc->sc_ifp, 0, 0, 1); 3655 continue; 3656 } 3657 } 3658 3659 (void) bridge_enqueue(sc, dst_if, mc); 3660 } 3661 if (used == 0) 3662 m_freem(m); 3663 BRIDGE_UNREF(sc); 3664 return (0); 3665 } 3666 3667sendunicast: 3668 /* 3669 * XXX Spanning tree consideration here? 3670 */ 3671 3672 bridge_span(sc, m); 3673 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 3674 m_freem(m); 3675 BRIDGE_UNLOCK(sc); 3676 return (0); 3677 } 3678 3679 BRIDGE_UNLOCK(sc); 3680 (void) bridge_enqueue(sc, dst_if, m); 3681 return (0); 3682} 3683#endif /* BRIDGE_MEMBER_OUT_FILTER */ 3684 3685/* 3686 * Output callback. 3687 * 3688 * This routine is called externally from above only when if_bridge_txstart 3689 * is disabled; otherwise it is called internally by bridge_start(). 3690 */ 3691static int 3692bridge_output(struct ifnet *ifp, struct mbuf *m) 3693{ 3694 struct bridge_softc *sc = ifnet_softc(ifp); 3695 struct ether_header *eh; 3696 struct ifnet *dst_if; 3697 int error = 0; 3698 3699 eh = mtod(m, struct ether_header *); 3700 dst_if = NULL; 3701 3702 BRIDGE_LOCK(sc); 3703 if (!(m->m_flags & (M_BCAST|M_MCAST))) 3704 dst_if = bridge_rtlookup(sc, eh->ether_dhost, 0); 3705 3706 (void) ifnet_stat_increment_out(ifp, 1, m->m_pkthdr.len, 0); 3707 3708#if NBPFILTER > 0 3709 if (sc->sc_bpf_output) 3710 bridge_bpf_output(ifp, m); 3711#endif 3712 3713 if (dst_if == NULL) { 3714 /* callee will unlock */ 3715 bridge_broadcast(sc, ifp, m, 0); 3716 } else { 3717 BRIDGE_UNLOCK(sc); 3718 error = bridge_enqueue(sc, dst_if, m); 3719 } 3720 3721 return (error); 3722} 3723 3724static void 3725bridge_finalize_cksum(struct ifnet *ifp, struct mbuf *m) 3726{ 3727 struct ether_header *eh = mtod(m, struct ether_header *); 3728 uint32_t sw_csum, hwcap; 3729 3730 if (ifp != NULL) 3731 hwcap = (ifp->if_hwassist | CSUM_DATA_VALID); 3732 else 3733 hwcap = 0; 3734 3735 /* do in software what the hardware cannot */ 3736 sw_csum = m->m_pkthdr.csum_flags & ~IF_HWASSIST_CSUM_FLAGS(hwcap); 3737 sw_csum &= IF_HWASSIST_CSUM_MASK; 3738 3739 switch (ntohs(eh->ether_type)) { 3740 case ETHERTYPE_IP: 3741 if ((hwcap & CSUM_PARTIAL) && !(sw_csum & CSUM_DELAY_DATA) && 3742 (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)) { 3743 if (m->m_pkthdr.csum_flags & CSUM_TCP) { 3744 uint16_t start = 3745 sizeof (*eh) + sizeof (struct ip); 3746 uint16_t ulpoff = 3747 m->m_pkthdr.csum_data & 0xffff; 3748 m->m_pkthdr.csum_flags |= 3749 (CSUM_DATA_VALID | CSUM_PARTIAL); 3750 m->m_pkthdr.csum_tx_stuff = (ulpoff + start); 3751 m->m_pkthdr.csum_tx_start = start; 3752 } else { 3753 sw_csum |= (CSUM_DELAY_DATA & 3754 m->m_pkthdr.csum_flags); 3755 } 3756 } 3757 (void) in_finalize_cksum(m, sizeof (*eh), sw_csum); 3758 break; 3759 3760#if INET6 3761 case ETHERTYPE_IPV6: 3762 if ((hwcap & CSUM_PARTIAL) && 3763 !(sw_csum & CSUM_DELAY_IPV6_DATA) && 3764 (m->m_pkthdr.csum_flags & CSUM_DELAY_IPV6_DATA)) { 3765 if (m->m_pkthdr.csum_flags & CSUM_TCPIPV6) { 3766 uint16_t start = 3767 sizeof (*eh) + sizeof (struct ip6_hdr); 3768 uint16_t ulpoff = 3769 m->m_pkthdr.csum_data & 0xffff; 3770 m->m_pkthdr.csum_flags |= 3771 (CSUM_DATA_VALID | CSUM_PARTIAL); 3772 m->m_pkthdr.csum_tx_stuff = (ulpoff + start); 3773 m->m_pkthdr.csum_tx_start = start; 3774 } else { 3775 sw_csum |= (CSUM_DELAY_IPV6_DATA & 3776 m->m_pkthdr.csum_flags); 3777 } 3778 } 3779 (void) in6_finalize_cksum(m, sizeof (*eh), -1, -1, sw_csum); 3780 break; 3781#endif /* INET6 */ 3782 } 3783} 3784 3785/* 3786 * bridge_start: 3787 * 3788 * Start output on a bridge. 3789 * 3790 * This routine is invoked by the start worker thread; because we never call 3791 * it directly, there is no need do deploy any serialization mechanism other 3792 * than what's already used by the worker thread, i.e. this is already single 3793 * threaded. 3794 * 3795 * This routine is called only when if_bridge_txstart is enabled. 3796 */ 3797static void 3798bridge_start(struct ifnet *ifp) 3799{ 3800 struct mbuf *m; 3801 3802 for (;;) { 3803 if (ifnet_dequeue(ifp, &m) != 0) 3804 break; 3805 3806 (void) bridge_output(ifp, m); 3807 } 3808} 3809 3810/* 3811 * bridge_forward: 3812 * 3813 * The forwarding function of the bridge. 3814 * 3815 * NOTE: Releases the lock on return. 3816 */ 3817static void 3818bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif, 3819 struct mbuf *m) 3820{ 3821 struct bridge_iflist *dbif; 3822 struct ifnet *src_if, *dst_if, *ifp; 3823 struct ether_header *eh; 3824 uint16_t vlan; 3825 uint8_t *dst; 3826 int error; 3827 3828 BRIDGE_LOCK_ASSERT_HELD(sc); 3829 3830#if BRIDGE_DEBUG 3831 if (if_bridge_debug & BR_DBGF_OUTPPUT) 3832 printf("%s: %s m 0x%llx\n", __func__, sc->sc_ifp->if_xname, 3833 (uint64_t)VM_KERNEL_ADDRPERM(m)); 3834#endif /* BRIDGE_DEBUG */ 3835 3836 src_if = m->m_pkthdr.rcvif; 3837 ifp = sc->sc_ifp; 3838 3839 (void) ifnet_stat_increment_in(ifp, 1, m->m_pkthdr.len, 0); 3840 vlan = VLANTAGOF(m); 3841 3842 3843 if ((sbif->bif_ifflags & IFBIF_STP) && 3844 sbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) 3845 goto drop; 3846 3847 eh = mtod(m, struct ether_header *); 3848 dst = eh->ether_dhost; 3849 3850 /* If the interface is learning, record the address. */ 3851 if (sbif->bif_ifflags & IFBIF_LEARNING) { 3852 error = bridge_rtupdate(sc, eh->ether_shost, vlan, 3853 sbif, 0, IFBAF_DYNAMIC); 3854 /* 3855 * If the interface has addresses limits then deny any source 3856 * that is not in the cache. 3857 */ 3858 if (error && sbif->bif_addrmax) 3859 goto drop; 3860 } 3861 3862 if ((sbif->bif_ifflags & IFBIF_STP) != 0 && 3863 sbif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING) 3864 goto drop; 3865 3866 /* 3867 * At this point, the port either doesn't participate 3868 * in spanning tree or it is in the forwarding state. 3869 */ 3870 3871 /* 3872 * If the packet is unicast, destined for someone on 3873 * "this" side of the bridge, drop it. 3874 */ 3875 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 3876 dst_if = bridge_rtlookup(sc, dst, vlan); 3877 if (src_if == dst_if) 3878 goto drop; 3879 } else { 3880 /* 3881 * Check if its a reserved multicast address, any address 3882 * listed in 802.1D section 7.12.6 may not be forwarded by the 3883 * bridge. 3884 * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F 3885 */ 3886 if (dst[0] == 0x01 && dst[1] == 0x80 && 3887 dst[2] == 0xc2 && dst[3] == 0x00 && 3888 dst[4] == 0x00 && dst[5] <= 0x0f) 3889 goto drop; 3890 3891 3892 /* ...forward it to all interfaces. */ 3893 atomic_add_64(&ifp->if_imcasts, 1); 3894 dst_if = NULL; 3895 } 3896 3897 /* 3898 * If we have a destination interface which is a member of our bridge, 3899 * OR this is a unicast packet, push it through the bpf(4) machinery. 3900 * For broadcast or multicast packets, don't bother because it will 3901 * be reinjected into ether_input. We do this before we pass the packets 3902 * through the pfil(9) framework, as it is possible that pfil(9) will 3903 * drop the packet, or possibly modify it, making it difficult to debug 3904 * firewall issues on the bridge. 3905 */ 3906#if NBPFILTER > 0 3907 if (eh->ether_type == htons(ETHERTYPE_RSN_PREAUTH) || 3908 dst_if != NULL || (m->m_flags & (M_BCAST | M_MCAST)) == 0) { 3909 m->m_pkthdr.rcvif = ifp; 3910 if (sc->sc_bpf_input) 3911 bridge_bpf_input(ifp, m); 3912 } 3913#endif /* NBPFILTER */ 3914 3915#if defined(PFIL_HOOKS) 3916 /* run the packet filter */ 3917 if (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6) { 3918 BRIDGE_UNLOCK(sc); 3919 if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0) 3920 return; 3921 if (m == NULL) 3922 return; 3923 BRIDGE_LOCK(sc); 3924 } 3925#endif /* PFIL_HOOKS */ 3926 3927 if (dst_if == NULL) { 3928 bridge_broadcast(sc, src_if, m, 1); 3929 return; 3930 } 3931 3932 /* 3933 * At this point, we're dealing with a unicast frame 3934 * going to a different interface. 3935 */ 3936 if ((dst_if->if_flags & IFF_RUNNING) == 0) 3937 goto drop; 3938 3939 dbif = bridge_lookup_member_if(sc, dst_if); 3940 if (dbif == NULL) 3941 /* Not a member of the bridge (anymore?) */ 3942 goto drop; 3943 3944 /* Private segments can not talk to each other */ 3945 if (sbif->bif_ifflags & dbif->bif_ifflags & IFBIF_PRIVATE) 3946 goto drop; 3947 3948 if ((dbif->bif_ifflags & IFBIF_STP) && 3949 dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) 3950 goto drop; 3951 3952#if HAS_DHCPRA_MASK 3953 /* APPLE MODIFICATION <rdar:6985737> */ 3954 if ((dst_if->if_extflags & IFEXTF_DHCPRA_MASK) != 0) { 3955 m = ip_xdhcpra_output(dst_if, m); 3956 if (!m) { 3957 ++sc->sc_sc.sc_ifp.if_xdhcpra; 3958 return; 3959 } 3960 } 3961#endif /* HAS_DHCPRA_MASK */ 3962 3963 BRIDGE_UNLOCK(sc); 3964 3965#if defined(PFIL_HOOKS) 3966 if (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6) { 3967 if (bridge_pfil(&m, ifp, dst_if, PFIL_OUT) != 0) 3968 return; 3969 if (m == NULL) 3970 return; 3971 } 3972#endif /* PFIL_HOOKS */ 3973 3974 (void) bridge_enqueue(sc, dst_if, m); 3975 return; 3976 3977drop: 3978 BRIDGE_UNLOCK(sc); 3979 m_freem(m); 3980} 3981 3982#if BRIDGE_DEBUG 3983 3984char *ether_ntop(char *, size_t, const u_char *); 3985 3986__private_extern__ char * 3987ether_ntop(char *buf, size_t len, const u_char *ap) 3988{ 3989 snprintf(buf, len, "%02x:%02x:%02x:%02x:%02x:%02x", 3990 ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]); 3991 3992 return (buf); 3993} 3994 3995#endif /* BRIDGE_DEBUG */ 3996 3997/* 3998 * bridge_input: 3999 * 4000 * Filter input from a member interface. Queue the packet for 4001 * bridging if it is not for us. 4002 */ 4003__private_extern__ errno_t 4004bridge_input(struct ifnet *ifp, struct mbuf *m, void *frame_header) 4005{ 4006 struct bridge_softc *sc = ifp->if_bridge; 4007 struct bridge_iflist *bif, *bif2; 4008 struct ifnet *bifp; 4009 struct ether_header *eh; 4010 struct mbuf *mc, *mc2; 4011 uint16_t vlan; 4012 int error; 4013 4014#if BRIDGE_DEBUG 4015 if (if_bridge_debug & BR_DBGF_INPUT) 4016 printf("%s: %s from %s m 0x%llx data 0x%llx\n", __func__, 4017 sc->sc_ifp->if_xname, ifp->if_xname, 4018 (uint64_t)VM_KERNEL_ADDRPERM(m), 4019 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_data(m))); 4020#endif /* BRIDGE_DEBUG */ 4021 4022 if ((sc->sc_ifp->if_flags & IFF_RUNNING) == 0) { 4023#if BRIDGE_DEBUG 4024 if (if_bridge_debug & BR_DBGF_INPUT) 4025 printf("%s: %s not running passing along\n", 4026 __func__, sc->sc_ifp->if_xname); 4027#endif /* BRIDGE_DEBUG */ 4028 return (0); 4029 } 4030 4031 bifp = sc->sc_ifp; 4032 vlan = VLANTAGOF(m); 4033 4034#ifdef IFF_MONITOR 4035 /* 4036 * Implement support for bridge monitoring. If this flag has been 4037 * set on this interface, discard the packet once we push it through 4038 * the bpf(4) machinery, but before we do, increment the byte and 4039 * packet counters associated with this interface. 4040 */ 4041 if ((bifp->if_flags & IFF_MONITOR) != 0) { 4042 m->m_pkthdr.rcvif = bifp; 4043 BRIDGE_BPF_MTAP_INPUT(sc, m); 4044 (void) ifnet_stat_increment_in(bifp, 1, m->m_pkthdr.len, 0); 4045 m_freem(m); 4046 return (EJUSTRETURN); 4047 } 4048#endif /* IFF_MONITOR */ 4049 4050 /* 4051 * Need to clear the promiscous flags otherwise it will be 4052 * dropped by DLIL after processing filters 4053 */ 4054 if ((mbuf_flags(m) & MBUF_PROMISC)) 4055 mbuf_setflags_mask(m, 0, MBUF_PROMISC); 4056 4057 BRIDGE_LOCK(sc); 4058 bif = bridge_lookup_member_if(sc, ifp); 4059 if (bif == NULL) { 4060 BRIDGE_UNLOCK(sc); 4061#if BRIDGE_DEBUG 4062 if (if_bridge_debug & BR_DBGF_INPUT) 4063 printf("%s: %s bridge_lookup_member_if failed\n", 4064 __func__, sc->sc_ifp->if_xname); 4065#endif /* BRIDGE_DEBUG */ 4066 return (0); 4067 } 4068 4069 eh = mtod(m, struct ether_header *); 4070 4071 bridge_span(sc, m); 4072 4073 if (m->m_flags & (M_BCAST|M_MCAST)) { 4074 4075#if BRIDGE_DEBUG 4076 if (if_bridge_debug & BR_DBGF_MCAST) 4077 if ((m->m_flags & M_MCAST)) 4078 printf("%s: multicast: " 4079 "%02x:%02x:%02x:%02x:%02x:%02x\n", 4080 __func__, 4081 eh->ether_dhost[0], eh->ether_dhost[1], 4082 eh->ether_dhost[2], eh->ether_dhost[3], 4083 eh->ether_dhost[4], eh->ether_dhost[5]); 4084#endif /* BRIDGE_DEBUG */ 4085 4086 /* Tap off 802.1D packets; they do not get forwarded. */ 4087 if (memcmp(eh->ether_dhost, bstp_etheraddr, 4088 ETHER_ADDR_LEN) == 0) { 4089#if BRIDGESTP 4090 m = bstp_input(&bif->bif_stp, ifp, m); 4091#else /* !BRIDGESTP */ 4092 m_freem(m); 4093 m = NULL; 4094#endif /* !BRIDGESTP */ 4095 if (m == NULL) { 4096 BRIDGE_UNLOCK(sc); 4097 return (EJUSTRETURN); 4098 } 4099 } 4100 4101 if ((bif->bif_ifflags & IFBIF_STP) && 4102 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) { 4103 BRIDGE_UNLOCK(sc); 4104 return (0); 4105 } 4106 4107 /* 4108 * Make a deep copy of the packet and enqueue the copy 4109 * for bridge processing; return the original packet for 4110 * local processing. 4111 */ 4112 mc = m_dup(m, M_DONTWAIT); 4113 if (mc == NULL) { 4114 BRIDGE_UNLOCK(sc); 4115 return (0); 4116 } 4117 4118 /* 4119 * Perform the bridge forwarding function with the copy. 4120 * 4121 * Note that bridge_forward calls BRIDGE_UNLOCK 4122 */ 4123 bridge_forward(sc, bif, mc); 4124 4125 /* 4126 * Reinject the mbuf as arriving on the bridge so we have a 4127 * chance at claiming multicast packets. We can not loop back 4128 * here from ether_input as a bridge is never a member of a 4129 * bridge. 4130 */ 4131 VERIFY(bifp->if_bridge == NULL); 4132 mc2 = m_dup(m, M_DONTWAIT); 4133 if (mc2 != NULL) { 4134 /* Keep the layer3 header aligned */ 4135 int i = min(mc2->m_pkthdr.len, max_protohdr); 4136 mc2 = m_copyup(mc2, i, ETHER_ALIGN); 4137 } 4138 if (mc2 != NULL) { 4139 /* mark packet as arriving on the bridge */ 4140 mc2->m_pkthdr.rcvif = bifp; 4141 mc2->m_pkthdr.pkt_hdr = mbuf_data(mc2); 4142 4143#if NBPFILTER > 0 4144 if (sc->sc_bpf_input) 4145 bridge_bpf_input(bifp, mc2); 4146#endif /* NBPFILTER */ 4147 (void) mbuf_setdata(mc2, 4148 (char *)mbuf_data(mc2) + ETHER_HDR_LEN, 4149 mbuf_len(mc2) - ETHER_HDR_LEN); 4150 (void) mbuf_pkthdr_adjustlen(mc2, - ETHER_HDR_LEN); 4151 4152 (void) ifnet_stat_increment_in(bifp, 1, 4153 mbuf_pkthdr_len(mc2), 0); 4154 4155#if BRIDGE_DEBUG 4156 if (if_bridge_debug & BR_DBGF_MCAST) 4157 printf("%s: %s mcast for us\n", __func__, 4158 sc->sc_ifp->if_xname); 4159#endif /* BRIDGE_DEBUG */ 4160 4161 dlil_input_packet_list(bifp, mc2); 4162 } 4163 4164 /* Return the original packet for local processing. */ 4165 return (0); 4166 } 4167 4168 if ((bif->bif_ifflags & IFBIF_STP) && 4169 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) { 4170 BRIDGE_UNLOCK(sc); 4171 return (0); 4172 } 4173 4174#ifdef DEV_CARP 4175#define CARP_CHECK_WE_ARE_DST(iface) \ 4176 ((iface)->if_carp &&\ 4177 carp_forus((iface)->if_carp, eh->ether_dhost)) 4178#define CARP_CHECK_WE_ARE_SRC(iface) \ 4179 ((iface)->if_carp &&\ 4180 carp_forus((iface)->if_carp, eh->ether_shost)) 4181#else 4182#define CARP_CHECK_WE_ARE_DST(iface) 0 4183#define CARP_CHECK_WE_ARE_SRC(iface) 0 4184#endif 4185 4186#ifdef INET6 4187#define PFIL_HOOKED_INET6 PFIL_HOOKED(&inet6_pfil_hook) 4188#else 4189#define PFIL_HOOKED_INET6 0 4190#endif 4191 4192#if defined(PFIL_HOOKS) 4193#define PFIL_PHYS(sc, ifp, m) do { \ 4194 if (pfil_local_phys && \ 4195 (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6)) { \ 4196 if (bridge_pfil(&m, NULL, ifp, \ 4197 PFIL_IN) != 0 || m == NULL) { \ 4198 BRIDGE_UNLOCK(sc); \ 4199 return (NULL); \ 4200 } \ 4201 } \ 4202} while (0) 4203#else /* PFIL_HOOKS */ 4204#define PFIL_PHYS(sc, ifp, m) 4205#endif /* PFIL_HOOKS */ 4206 4207#define GRAB_OUR_PACKETS(iface) \ 4208 if ((iface)->if_type == IFT_GIF) \ 4209 continue; \ 4210 /* It is destined for us. */ \ 4211 if (memcmp(IF_LLADDR((iface)), eh->ether_dhost, \ 4212 ETHER_ADDR_LEN) == 0 || CARP_CHECK_WE_ARE_DST((iface))) { \ 4213 if ((iface)->if_type == IFT_BRIDGE) { \ 4214 BRIDGE_BPF_MTAP_INPUT(sc, m); \ 4215 /* Filter on the physical interface. */ \ 4216 PFIL_PHYS(sc, iface, m); \ 4217 } \ 4218 if (bif->bif_ifflags & IFBIF_LEARNING) { \ 4219 error = bridge_rtupdate(sc, eh->ether_shost, \ 4220 vlan, bif, 0, IFBAF_DYNAMIC); \ 4221 if (error && bif->bif_addrmax) { \ 4222 BRIDGE_UNLOCK(sc); \ 4223 return (EJUSTRETURN); \ 4224 } \ 4225 } \ 4226 m->m_pkthdr.rcvif = iface; \ 4227 BRIDGE_UNLOCK(sc); \ 4228 return (0); \ 4229 } \ 4230 \ 4231 /* We just received a packet that we sent out. */ \ 4232 if (memcmp(IF_LLADDR((iface)), eh->ether_shost, \ 4233 ETHER_ADDR_LEN) == 0 || CARP_CHECK_WE_ARE_SRC((iface))) { \ 4234 BRIDGE_UNLOCK(sc); \ 4235 return (EJUSTRETURN); \ 4236 } 4237 4238 /* 4239 * Unicast. 4240 */ 4241 /* 4242 * If the packet is for us, set the packets source as the 4243 * bridge, and return the packet back to ether_input for 4244 * local processing. 4245 */ 4246 if (memcmp(eh->ether_dhost, IF_LLADDR(bifp), 4247 ETHER_ADDR_LEN) == 0 || CARP_CHECK_WE_ARE_DST(bifp)) { 4248 4249 /* Mark the packet as arriving on the bridge interface */ 4250 (void) mbuf_pkthdr_setrcvif(m, bifp); 4251 mbuf_pkthdr_setheader(m, frame_header); 4252 4253 /* 4254 * If the interface is learning, and the source 4255 * address is valid and not multicast, record 4256 * the address. 4257 */ 4258 if (bif->bif_ifflags & IFBIF_LEARNING) 4259 (void) bridge_rtupdate(sc, eh->ether_shost, 4260 vlan, bif, 0, IFBAF_DYNAMIC); 4261 4262 BRIDGE_BPF_MTAP_INPUT(sc, m); 4263 4264 (void) mbuf_setdata(m, (char *)mbuf_data(m) + ETHER_HDR_LEN, 4265 mbuf_len(m) - ETHER_HDR_LEN); 4266 (void) mbuf_pkthdr_adjustlen(m, - ETHER_HDR_LEN); 4267 4268 (void) ifnet_stat_increment_in(bifp, 1, mbuf_pkthdr_len(m), 0); 4269 4270 BRIDGE_UNLOCK(sc); 4271 4272#if BRIDGE_DEBUG 4273 if (if_bridge_debug & BR_DBGF_INPUT) 4274 printf("%s: %s packet for bridge\n", __func__, 4275 sc->sc_ifp->if_xname); 4276#endif /* BRIDGE_DEBUG */ 4277 4278 dlil_input_packet_list(bifp, m); 4279 4280 return (EJUSTRETURN); 4281 } 4282 4283 /* 4284 * if the destination of the packet is for the MAC address of 4285 * the member interface itself, then we don't need to forward 4286 * it -- just pass it back. Note that it'll likely just be 4287 * dropped by the stack, but if something else is bound to 4288 * the interface directly (for example, the wireless stats 4289 * protocol -- although that actually uses BPF right now), 4290 * then it will consume the packet 4291 * 4292 * ALSO, note that we do this check AFTER checking for the 4293 * bridge's own MAC address, because the bridge may be 4294 * using the SAME MAC address as one of its interfaces 4295 */ 4296 if (memcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) { 4297 4298#ifdef VERY_VERY_VERY_DIAGNOSTIC 4299 printf("%s: not forwarding packet bound for member " 4300 "interface\n", __func__); 4301#endif 4302 BRIDGE_UNLOCK(sc); 4303 return (0); 4304 } 4305 4306 /* Now check the all bridge members. */ 4307 TAILQ_FOREACH(bif2, &sc->sc_iflist, bif_next) { 4308 GRAB_OUR_PACKETS(bif2->bif_ifp) 4309 } 4310 4311#undef CARP_CHECK_WE_ARE_DST 4312#undef CARP_CHECK_WE_ARE_SRC 4313#undef GRAB_OUR_PACKETS 4314 4315 /* 4316 * Perform the bridge forwarding function. 4317 * 4318 * Note that bridge_forward calls BRIDGE_UNLOCK 4319 */ 4320 bridge_forward(sc, bif, m); 4321 4322 return (EJUSTRETURN); 4323} 4324 4325/* 4326 * bridge_broadcast: 4327 * 4328 * Send a frame to all interfaces that are members of 4329 * the bridge, except for the one on which the packet 4330 * arrived. 4331 * 4332 * NOTE: Releases the lock on return. 4333 */ 4334static void 4335bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 4336 struct mbuf *m, int runfilt) 4337{ 4338#ifndef PFIL_HOOKS 4339#pragma unused(runfilt) 4340#endif 4341 struct bridge_iflist *dbif, *sbif; 4342 struct mbuf *mc; 4343 struct ifnet *dst_if; 4344 int error = 0, used = 0; 4345 4346 sbif = bridge_lookup_member_if(sc, src_if); 4347 4348 BRIDGE_LOCK2REF(sc, error); 4349 if (error) { 4350 m_freem(m); 4351 return; 4352 } 4353 4354#ifdef PFIL_HOOKS 4355 /* Filter on the bridge interface before broadcasting */ 4356 if (runfilt && (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6)) { 4357 if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0) 4358 goto out; 4359 if (m == NULL) 4360 goto out; 4361 } 4362#endif /* PFIL_HOOKS */ 4363 4364 TAILQ_FOREACH(dbif, &sc->sc_iflist, bif_next) { 4365 dst_if = dbif->bif_ifp; 4366 if (dst_if == src_if) 4367 continue; 4368 4369 /* Private segments can not talk to each other */ 4370 if (sbif && 4371 (sbif->bif_ifflags & dbif->bif_ifflags & IFBIF_PRIVATE)) 4372 continue; 4373 4374 if ((dbif->bif_ifflags & IFBIF_STP) && 4375 dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) 4376 continue; 4377 4378 if ((dbif->bif_ifflags & IFBIF_DISCOVER) == 0 && 4379 (m->m_flags & (M_BCAST|M_MCAST)) == 0) 4380 continue; 4381 4382 if ((dst_if->if_flags & IFF_RUNNING) == 0) 4383 continue; 4384 4385 if (TAILQ_NEXT(dbif, bif_next) == NULL) { 4386 mc = m; 4387 used = 1; 4388 } else { 4389 mc = m_dup(m, M_DONTWAIT); 4390 if (mc == NULL) { 4391 (void) ifnet_stat_increment_out(sc->sc_ifp, 4392 0, 0, 1); 4393 continue; 4394 } 4395 } 4396 4397#ifdef PFIL_HOOKS 4398 /* 4399 * Filter on the output interface. Pass a NULL bridge interface 4400 * pointer so we do not redundantly filter on the bridge for 4401 * each interface we broadcast on. 4402 */ 4403 if (runfilt && 4404 (PFIL_HOOKED(&inet_pfil_hook) || PFIL_HOOKED_INET6)) { 4405 if (used == 0) { 4406 /* Keep the layer3 header aligned */ 4407 int i = min(mc->m_pkthdr.len, max_protohdr); 4408 mc = m_copyup(mc, i, ETHER_ALIGN); 4409 if (mc == NULL) { 4410 (void) ifnet_stat_increment_out( 4411 sc->sc_ifp, 0, 0, 1); 4412 continue; 4413 } 4414 } 4415 if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0) 4416 continue; 4417 if (mc == NULL) 4418 continue; 4419 } 4420#endif /* PFIL_HOOKS */ 4421 4422 (void) bridge_enqueue(sc, dst_if, mc); 4423 } 4424 if (used == 0) 4425 m_freem(m); 4426 4427#ifdef PFIL_HOOKS 4428out: 4429#endif /* PFIL_HOOKS */ 4430 4431 BRIDGE_UNREF(sc); 4432} 4433 4434/* 4435 * bridge_span: 4436 * 4437 * Duplicate a packet out one or more interfaces that are in span mode, 4438 * the original mbuf is unmodified. 4439 */ 4440static void 4441bridge_span(struct bridge_softc *sc, struct mbuf *m) 4442{ 4443 struct bridge_iflist *bif; 4444 struct ifnet *dst_if; 4445 struct mbuf *mc; 4446 4447 if (TAILQ_EMPTY(&sc->sc_spanlist)) 4448 return; 4449 4450 TAILQ_FOREACH(bif, &sc->sc_spanlist, bif_next) { 4451 dst_if = bif->bif_ifp; 4452 4453 if ((dst_if->if_flags & IFF_RUNNING) == 0) 4454 continue; 4455 4456 mc = m_copypacket(m, M_DONTWAIT); 4457 if (mc == NULL) { 4458 (void) ifnet_stat_increment_out(sc->sc_ifp, 0, 0, 1); 4459 continue; 4460 } 4461 4462 (void) bridge_enqueue(sc, dst_if, mc); 4463 } 4464} 4465 4466 4467/* 4468 * bridge_rtupdate: 4469 * 4470 * Add a bridge routing entry. 4471 */ 4472static int 4473bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, uint16_t vlan, 4474 struct bridge_iflist *bif, int setflags, uint8_t flags) 4475{ 4476 struct bridge_rtnode *brt; 4477 int error; 4478 4479 BRIDGE_LOCK_ASSERT_HELD(sc); 4480 4481 /* Check the source address is valid and not multicast. */ 4482 if (ETHER_IS_MULTICAST(dst) || 4483 (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 && 4484 dst[3] == 0 && dst[4] == 0 && dst[5] == 0) != 0) 4485 return (EINVAL); 4486 4487 4488 /* 802.1p frames map to vlan 1 */ 4489 if (vlan == 0) 4490 vlan = 1; 4491 4492 /* 4493 * A route for this destination might already exist. If so, 4494 * update it, otherwise create a new one. 4495 */ 4496 if ((brt = bridge_rtnode_lookup(sc, dst, vlan)) == NULL) { 4497 if (sc->sc_brtcnt >= sc->sc_brtmax) { 4498 sc->sc_brtexceeded++; 4499 return (ENOSPC); 4500 } 4501 /* Check per interface address limits (if enabled) */ 4502 if (bif->bif_addrmax && bif->bif_addrcnt >= bif->bif_addrmax) { 4503 bif->bif_addrexceeded++; 4504 return (ENOSPC); 4505 } 4506 4507 /* 4508 * Allocate a new bridge forwarding node, and 4509 * initialize the expiration time and Ethernet 4510 * address. 4511 */ 4512 brt = zalloc_noblock(bridge_rtnode_pool); 4513 if (brt == NULL) 4514 return (ENOMEM); 4515 bzero(brt, sizeof(struct bridge_rtnode)); 4516 4517 if (bif->bif_ifflags & IFBIF_STICKY) 4518 brt->brt_flags = IFBAF_STICKY; 4519 else 4520 brt->brt_flags = IFBAF_DYNAMIC; 4521 4522 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 4523 brt->brt_vlan = vlan; 4524 4525 4526 if ((error = bridge_rtnode_insert(sc, brt)) != 0) { 4527 zfree(bridge_rtnode_pool, brt); 4528 return (error); 4529 } 4530 brt->brt_dst = bif; 4531 bif->bif_addrcnt++; 4532#if BRIDGE_DEBUG 4533 if (if_bridge_debug & BR_DBGF_RT_TABLE) 4534 printf("%s: added %02x:%02x:%02x:%02x:%02x:%02x " 4535 "on %s count %u hashsize %u\n", __func__, 4536 dst[0], dst[1], dst[2], dst[3], dst[4], dst[5], 4537 sc->sc_ifp->if_xname, sc->sc_brtcnt, 4538 sc->sc_rthash_size); 4539#endif 4540 } 4541 4542 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && 4543 brt->brt_dst != bif) { 4544 brt->brt_dst->bif_addrcnt--; 4545 brt->brt_dst = bif; 4546 brt->brt_dst->bif_addrcnt++; 4547 } 4548 4549 if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 4550 unsigned long now; 4551 4552 now = (unsigned long) net_uptime(); 4553 brt->brt_expire = now + sc->sc_brttimeout; 4554 } 4555 if (setflags) 4556 brt->brt_flags = flags; 4557 4558 4559 return (0); 4560} 4561 4562/* 4563 * bridge_rtlookup: 4564 * 4565 * Lookup the destination interface for an address. 4566 */ 4567static struct ifnet * 4568bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan) 4569{ 4570 struct bridge_rtnode *brt; 4571 4572 BRIDGE_LOCK_ASSERT_HELD(sc); 4573 4574 if ((brt = bridge_rtnode_lookup(sc, addr, vlan)) == NULL) 4575 return (NULL); 4576 4577 return (brt->brt_ifp); 4578} 4579 4580/* 4581 * bridge_rttrim: 4582 * 4583 * Trim the routine table so that we have a number 4584 * of routing entries less than or equal to the 4585 * maximum number. 4586 */ 4587static void 4588bridge_rttrim(struct bridge_softc *sc) 4589{ 4590 struct bridge_rtnode *brt, *nbrt; 4591 4592 BRIDGE_LOCK_ASSERT_HELD(sc); 4593 4594 /* Make sure we actually need to do this. */ 4595 if (sc->sc_brtcnt <= sc->sc_brtmax) 4596 return; 4597 4598 /* Force an aging cycle; this might trim enough addresses. */ 4599 bridge_rtage(sc); 4600 if (sc->sc_brtcnt <= sc->sc_brtmax) 4601 return; 4602 4603 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 4604 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 4605 bridge_rtnode_destroy(sc, brt); 4606 if (sc->sc_brtcnt <= sc->sc_brtmax) 4607 return; 4608 } 4609 } 4610} 4611 4612/* 4613 * bridge_aging_timer: 4614 * 4615 * Aging periodic timer for the bridge routing table. 4616 */ 4617static void 4618bridge_aging_timer(struct bridge_softc *sc) 4619{ 4620 BRIDGE_LOCK_ASSERT_HELD(sc); 4621 4622 bridge_rtage(sc); 4623 4624 if ((sc->sc_ifp->if_flags & IFF_RUNNING) && 4625 (sc->sc_flags & SCF_DETACHING) == 0) { 4626 sc->sc_aging_timer.bdc_sc = sc; 4627 sc->sc_aging_timer.bdc_func = bridge_aging_timer; 4628 sc->sc_aging_timer.bdc_ts.tv_sec = bridge_rtable_prune_period; 4629 bridge_schedule_delayed_call(&sc->sc_aging_timer); 4630 } 4631} 4632 4633/* 4634 * bridge_rtage: 4635 * 4636 * Perform an aging cycle. 4637 */ 4638static void 4639bridge_rtage(struct bridge_softc *sc) 4640{ 4641 struct bridge_rtnode *brt, *nbrt; 4642 unsigned long now; 4643 4644 BRIDGE_LOCK_ASSERT_HELD(sc); 4645 4646 now = (unsigned long) net_uptime(); 4647 4648 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 4649 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 4650 if (now >= brt->brt_expire) 4651 bridge_rtnode_destroy(sc, brt); 4652 } 4653 } 4654} 4655 4656/* 4657 * bridge_rtflush: 4658 * 4659 * Remove all dynamic addresses from the bridge. 4660 */ 4661static void 4662bridge_rtflush(struct bridge_softc *sc, int full) 4663{ 4664 struct bridge_rtnode *brt, *nbrt; 4665 4666 BRIDGE_LOCK_ASSERT_HELD(sc); 4667 4668 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 4669 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 4670 bridge_rtnode_destroy(sc, brt); 4671 } 4672} 4673 4674/* 4675 * bridge_rtdaddr: 4676 * 4677 * Remove an address from the table. 4678 */ 4679static int 4680bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan) 4681{ 4682 struct bridge_rtnode *brt; 4683 int found = 0; 4684 4685 BRIDGE_LOCK_ASSERT_HELD(sc); 4686 4687 /* 4688 * If vlan is zero then we want to delete for all vlans so the lookup 4689 * may return more than one. 4690 */ 4691 while ((brt = bridge_rtnode_lookup(sc, addr, vlan)) != NULL) { 4692 bridge_rtnode_destroy(sc, brt); 4693 found = 1; 4694 } 4695 4696 return (found ? 0 : ENOENT); 4697} 4698 4699/* 4700 * bridge_rtdelete: 4701 * 4702 * Delete routes to a speicifc member interface. 4703 */ 4704static void 4705bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full) 4706{ 4707 struct bridge_rtnode *brt, *nbrt; 4708 4709 BRIDGE_LOCK_ASSERT_HELD(sc); 4710 4711 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 4712 if (brt->brt_ifp == ifp && (full || 4713 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)) 4714 bridge_rtnode_destroy(sc, brt); 4715 } 4716} 4717 4718/* 4719 * bridge_rtable_init: 4720 * 4721 * Initialize the route table for this bridge. 4722 */ 4723static int 4724bridge_rtable_init(struct bridge_softc *sc) 4725{ 4726 u_int32_t i; 4727 4728 sc->sc_rthash = _MALLOC(sizeof (*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 4729 M_DEVBUF, M_WAITOK | M_ZERO); 4730 if (sc->sc_rthash == NULL) { 4731 printf("%s: no memory\n", __func__); 4732 return (ENOMEM); 4733 } 4734 sc->sc_rthash_size = BRIDGE_RTHASH_SIZE; 4735 4736 for (i = 0; i < sc->sc_rthash_size; i++) 4737 LIST_INIT(&sc->sc_rthash[i]); 4738 4739 sc->sc_rthash_key = RandomULong(); 4740 4741 LIST_INIT(&sc->sc_rtlist); 4742 4743 return (0); 4744} 4745 4746/* 4747 * bridge_rthash_delayed_resize: 4748 * 4749 * Resize the routing table hash on a delayed thread call. 4750 */ 4751static void 4752bridge_rthash_delayed_resize(struct bridge_softc *sc) 4753{ 4754 u_int32_t new_rthash_size; 4755 struct _bridge_rtnode_list *new_rthash = NULL; 4756 struct _bridge_rtnode_list *old_rthash = NULL; 4757 u_int32_t i; 4758 struct bridge_rtnode *brt; 4759 int error = 0; 4760 4761 BRIDGE_LOCK_ASSERT_HELD(sc); 4762 4763 /* 4764 * Four entries per hash bucket is our ideal load factor 4765 */ 4766 if (sc->sc_brtcnt < sc->sc_rthash_size * 4) 4767 goto out; 4768 4769 /* 4770 * Doubling the number of hash buckets may be too simplistic 4771 * especially when facing a spike of new entries 4772 */ 4773 new_rthash_size = sc->sc_rthash_size * 2; 4774 4775 sc->sc_flags |= SCF_RESIZING; 4776 BRIDGE_UNLOCK(sc); 4777 4778 new_rthash = _MALLOC(sizeof (*sc->sc_rthash) * new_rthash_size, 4779 M_DEVBUF, M_WAITOK | M_ZERO); 4780 4781 BRIDGE_LOCK(sc); 4782 sc->sc_flags &= ~SCF_RESIZING; 4783 4784 if (new_rthash == NULL) { 4785 error = ENOMEM; 4786 goto out; 4787 } 4788 if ((sc->sc_flags & SCF_DETACHING)) { 4789 error = ENODEV; 4790 goto out; 4791 } 4792 /* 4793 * Fail safe from here on 4794 */ 4795 old_rthash = sc->sc_rthash; 4796 sc->sc_rthash = new_rthash; 4797 sc->sc_rthash_size = new_rthash_size; 4798 4799 /* 4800 * Get a new key to force entries to be shuffled around to reduce 4801 * the likelihood they will land in the same buckets 4802 */ 4803 sc->sc_rthash_key = RandomULong(); 4804 4805 for (i = 0; i < sc->sc_rthash_size; i++) 4806 LIST_INIT(&sc->sc_rthash[i]); 4807 4808 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 4809 LIST_REMOVE(brt, brt_hash); 4810 (void) bridge_rtnode_hash(sc, brt); 4811 } 4812out: 4813 if (error == 0) { 4814#if BRIDGE_DEBUG 4815 if (if_bridge_debug & BR_DBGF_RT_TABLE) 4816 printf("%s: %s new size %u\n", __func__, 4817 sc->sc_ifp->if_xname, sc->sc_rthash_size); 4818#endif /* BRIDGE_DEBUG */ 4819 if (old_rthash) 4820 _FREE(old_rthash, M_DEVBUF); 4821 } else { 4822#if BRIDGE_DEBUG 4823 printf("%s: %s failed %d\n", __func__, 4824 sc->sc_ifp->if_xname, error); 4825#endif /* BRIDGE_DEBUG */ 4826 if (new_rthash != NULL) 4827 _FREE(new_rthash, M_DEVBUF); 4828 } 4829} 4830 4831/* 4832 * Resize the number of hash buckets based on the load factor 4833 * Currently only grow 4834 * Failing to resize the hash table is not fatal 4835 */ 4836static void 4837bridge_rthash_resize(struct bridge_softc *sc) 4838{ 4839 BRIDGE_LOCK_ASSERT_HELD(sc); 4840 4841 if ((sc->sc_flags & SCF_DETACHING) || (sc->sc_flags & SCF_RESIZING)) 4842 return; 4843 4844 /* 4845 * Four entries per hash bucket is our ideal load factor 4846 */ 4847 if (sc->sc_brtcnt < sc->sc_rthash_size * 4) 4848 return; 4849 /* 4850 * Hard limit on the size of the routing hash table 4851 */ 4852 if (sc->sc_rthash_size >= bridge_rtable_hash_size_max) 4853 return; 4854 4855 sc->sc_resize_call.bdc_sc = sc; 4856 sc->sc_resize_call.bdc_func = bridge_rthash_delayed_resize; 4857 bridge_schedule_delayed_call(&sc->sc_resize_call); 4858} 4859 4860/* 4861 * bridge_rtable_fini: 4862 * 4863 * Deconstruct the route table for this bridge. 4864 */ 4865static void 4866bridge_rtable_fini(struct bridge_softc *sc) 4867{ 4868 KASSERT(sc->sc_brtcnt == 0, 4869 ("%s: %d bridge routes referenced", __func__, sc->sc_brtcnt)); 4870 if (sc->sc_rthash) { 4871 _FREE(sc->sc_rthash, M_DEVBUF); 4872 sc->sc_rthash = NULL; 4873 } 4874} 4875 4876/* 4877 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 4878 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 4879 */ 4880#define mix(a, b, c) \ 4881do { \ 4882 a -= b; a -= c; a ^= (c >> 13); \ 4883 b -= c; b -= a; b ^= (a << 8); \ 4884 c -= a; c -= b; c ^= (b >> 13); \ 4885 a -= b; a -= c; a ^= (c >> 12); \ 4886 b -= c; b -= a; b ^= (a << 16); \ 4887 c -= a; c -= b; c ^= (b >> 5); \ 4888 a -= b; a -= c; a ^= (c >> 3); \ 4889 b -= c; b -= a; b ^= (a << 10); \ 4890 c -= a; c -= b; c ^= (b >> 15); \ 4891} while (/*CONSTCOND*/0) 4892 4893static __inline uint32_t 4894bridge_rthash(struct bridge_softc *sc, const uint8_t *addr) 4895{ 4896 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; 4897 4898 b += addr[5] << 8; 4899 b += addr[4]; 4900 a += addr[3] << 24; 4901 a += addr[2] << 16; 4902 a += addr[1] << 8; 4903 a += addr[0]; 4904 4905 mix(a, b, c); 4906 4907 return (c & BRIDGE_RTHASH_MASK(sc)); 4908} 4909 4910#undef mix 4911 4912static int 4913bridge_rtnode_addr_cmp(const uint8_t *a, const uint8_t *b) 4914{ 4915 int i, d; 4916 4917 for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++) { 4918 d = ((int)a[i]) - ((int)b[i]); 4919 } 4920 4921 return (d); 4922} 4923 4924/* 4925 * bridge_rtnode_lookup: 4926 * 4927 * Look up a bridge route node for the specified destination. Compare the 4928 * vlan id or if zero then just return the first match. 4929 */ 4930static struct bridge_rtnode * 4931bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr, 4932 uint16_t vlan) 4933{ 4934 struct bridge_rtnode *brt; 4935 uint32_t hash; 4936 int dir; 4937 4938 BRIDGE_LOCK_ASSERT_HELD(sc); 4939 4940 hash = bridge_rthash(sc, addr); 4941 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { 4942 dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr); 4943 if (dir == 0 && (brt->brt_vlan == vlan || vlan == 0)) 4944 return (brt); 4945 if (dir > 0) 4946 return (NULL); 4947 } 4948 4949 return (NULL); 4950} 4951 4952/* 4953 * bridge_rtnode_hash: 4954 * 4955 * Insert the specified bridge node into the route hash table. 4956 * This is used when adding a new node or to rehash when resizing 4957 * the hash table 4958 */ 4959static int 4960bridge_rtnode_hash(struct bridge_softc *sc, struct bridge_rtnode *brt) 4961{ 4962 struct bridge_rtnode *lbrt; 4963 uint32_t hash; 4964 int dir; 4965 4966 BRIDGE_LOCK_ASSERT_HELD(sc); 4967 4968 hash = bridge_rthash(sc, brt->brt_addr); 4969 4970 lbrt = LIST_FIRST(&sc->sc_rthash[hash]); 4971 if (lbrt == NULL) { 4972 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); 4973 goto out; 4974 } 4975 4976 do { 4977 dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr); 4978 if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan) { 4979#if BRIDGE_DEBUG 4980 if (if_bridge_debug & BR_DBGF_RT_TABLE) 4981 printf("%s: %s EEXIST " 4982 "%02x:%02x:%02x:%02x:%02x:%02x\n", 4983 __func__, sc->sc_ifp->if_xname, 4984 brt->brt_addr[0], brt->brt_addr[1], 4985 brt->brt_addr[2], brt->brt_addr[3], 4986 brt->brt_addr[4], brt->brt_addr[5]); 4987#endif 4988 return (EEXIST); 4989 } 4990 if (dir > 0) { 4991 LIST_INSERT_BEFORE(lbrt, brt, brt_hash); 4992 goto out; 4993 } 4994 if (LIST_NEXT(lbrt, brt_hash) == NULL) { 4995 LIST_INSERT_AFTER(lbrt, brt, brt_hash); 4996 goto out; 4997 } 4998 lbrt = LIST_NEXT(lbrt, brt_hash); 4999 } while (lbrt != NULL); 5000 5001#if BRIDGE_DEBUG 5002 if (if_bridge_debug & BR_DBGF_RT_TABLE) 5003 printf("%s: %s impossible %02x:%02x:%02x:%02x:%02x:%02x\n", 5004 __func__, sc->sc_ifp->if_xname, 5005 brt->brt_addr[0], brt->brt_addr[1], brt->brt_addr[2], 5006 brt->brt_addr[3], brt->brt_addr[4], brt->brt_addr[5]); 5007#endif 5008 5009out: 5010 return (0); 5011} 5012 5013/* 5014 * bridge_rtnode_insert: 5015 * 5016 * Insert the specified bridge node into the route table. We 5017 * assume the entry is not already in the table. 5018 */ 5019static int 5020bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt) 5021{ 5022 int error; 5023 5024 error = bridge_rtnode_hash(sc, brt); 5025 if (error != 0) 5026 return (error); 5027 5028 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); 5029 sc->sc_brtcnt++; 5030 5031 bridge_rthash_resize(sc); 5032 5033 return (0); 5034} 5035 5036/* 5037 * bridge_rtnode_destroy: 5038 * 5039 * Destroy a bridge rtnode. 5040 */ 5041static void 5042bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt) 5043{ 5044 BRIDGE_LOCK_ASSERT_HELD(sc); 5045 5046 LIST_REMOVE(brt, brt_hash); 5047 5048 LIST_REMOVE(brt, brt_list); 5049 sc->sc_brtcnt--; 5050 brt->brt_dst->bif_addrcnt--; 5051 zfree(bridge_rtnode_pool, brt); 5052} 5053 5054#if BRIDGESTP 5055/* 5056 * bridge_rtable_expire: 5057 * 5058 * Set the expiry time for all routes on an interface. 5059 */ 5060static void 5061bridge_rtable_expire(struct ifnet *ifp, int age) 5062{ 5063 struct bridge_softc *sc = ifp->if_bridge; 5064 struct bridge_rtnode *brt; 5065 5066 BRIDGE_LOCK(sc); 5067 5068 /* 5069 * If the age is zero then flush, otherwise set all the expiry times to 5070 * age for the interface 5071 */ 5072 if (age == 0) { 5073 bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN); 5074 } else { 5075 unsigned long now; 5076 5077 now = (unsigned long) net_uptime(); 5078 5079 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 5080 /* Cap the expiry time to 'age' */ 5081 if (brt->brt_ifp == ifp && 5082 brt->brt_expire > now + age && 5083 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 5084 brt->brt_expire = now + age; 5085 } 5086 } 5087 BRIDGE_UNLOCK(sc); 5088} 5089 5090/* 5091 * bridge_state_change: 5092 * 5093 * Callback from the bridgestp code when a port changes states. 5094 */ 5095static void 5096bridge_state_change(struct ifnet *ifp, int state) 5097{ 5098 struct bridge_softc *sc = ifp->if_bridge; 5099 static const char *stpstates[] = { 5100 "disabled", 5101 "listening", 5102 "learning", 5103 "forwarding", 5104 "blocking", 5105 "discarding" 5106 }; 5107 5108 if (log_stp) 5109 log(LOG_NOTICE, "%s: state changed to %s on %s\n", 5110 sc->sc_ifp->if_xname, 5111 stpstates[state], ifp->if_xname); 5112} 5113#endif /* BRIDGESTP */ 5114 5115#ifdef PFIL_HOOKS 5116/* 5117 * Send bridge packets through pfil if they are one of the types pfil can deal 5118 * with, or if they are ARP or REVARP. (pfil will pass ARP and REVARP without 5119 * question.) If *bifp or *ifp are NULL then packet filtering is skipped for 5120 * that interface. 5121 */ 5122static int 5123bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) 5124{ 5125 int snap, error, i, hlen; 5126 struct ether_header *eh1, eh2; 5127 struct ip_fw_args args; 5128 struct ip *ip; 5129 struct llc llc1; 5130 u_int16_t ether_type; 5131 5132 snap = 0; 5133 error = -1; /* Default error if not error == 0 */ 5134 5135#if 0 5136 /* we may return with the IP fields swapped, ensure its not shared */ 5137 KASSERT(M_WRITABLE(*mp), ("%s: modifying a shared mbuf", __func__)); 5138#endif 5139 5140 if (pfil_bridge == 0 && pfil_member == 0 && pfil_ipfw == 0) 5141 return (0); /* filtering is disabled */ 5142 5143 i = min((*mp)->m_pkthdr.len, max_protohdr); 5144 if ((*mp)->m_len < i) { 5145 *mp = m_pullup(*mp, i); 5146 if (*mp == NULL) { 5147 printf("%s: m_pullup failed\n", __func__); 5148 return (-1); 5149 } 5150 } 5151 5152 eh1 = mtod(*mp, struct ether_header *); 5153 ether_type = ntohs(eh1->ether_type); 5154 5155 /* 5156 * Check for SNAP/LLC. 5157 */ 5158 if (ether_type < ETHERMTU) { 5159 struct llc *llc2 = (struct llc *)(eh1 + 1); 5160 5161 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && 5162 llc2->llc_dsap == LLC_SNAP_LSAP && 5163 llc2->llc_ssap == LLC_SNAP_LSAP && 5164 llc2->llc_control == LLC_UI) { 5165 ether_type = htons(llc2->llc_un.type_snap.ether_type); 5166 snap = 1; 5167 } 5168 } 5169 5170 /* 5171 * If we're trying to filter bridge traffic, don't look at anything 5172 * other than IP and ARP traffic. If the filter doesn't understand 5173 * IPv6, don't allow IPv6 through the bridge either. This is lame 5174 * since if we really wanted, say, an AppleTalk filter, we are hosed, 5175 * but of course we don't have an AppleTalk filter to begin with. 5176 * (Note that since pfil doesn't understand ARP it will pass *ALL* 5177 * ARP traffic.) 5178 */ 5179 switch (ether_type) { 5180 case ETHERTYPE_ARP: 5181 case ETHERTYPE_REVARP: 5182 if (pfil_ipfw_arp == 0) 5183 return (0); /* Automatically pass */ 5184 break; 5185 5186 case ETHERTYPE_IP: 5187#if INET6 5188 case ETHERTYPE_IPV6: 5189#endif /* INET6 */ 5190 break; 5191 default: 5192 /* 5193 * Check to see if the user wants to pass non-ip 5194 * packets, these will not be checked by pfil(9) and 5195 * passed unconditionally so the default is to drop. 5196 */ 5197 if (pfil_onlyip) 5198 goto bad; 5199 } 5200 5201 /* Strip off the Ethernet header and keep a copy. */ 5202 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t)&eh2); 5203 m_adj(*mp, ETHER_HDR_LEN); 5204 5205 /* Strip off snap header, if present */ 5206 if (snap) { 5207 m_copydata(*mp, 0, sizeof (struct llc), (caddr_t)&llc1); 5208 m_adj(*mp, sizeof (struct llc)); 5209 } 5210 5211 /* 5212 * Check the IP header for alignment and errors 5213 */ 5214 if (dir == PFIL_IN) { 5215 switch (ether_type) { 5216 case ETHERTYPE_IP: 5217 error = bridge_ip_checkbasic(mp); 5218 break; 5219#if INET6 5220 case ETHERTYPE_IPV6: 5221 error = bridge_ip6_checkbasic(mp); 5222 break; 5223#endif /* INET6 */ 5224 default: 5225 error = 0; 5226 } 5227 if (error) 5228 goto bad; 5229 } 5230 5231 if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) { 5232 error = -1; 5233 args.rule = ip_dn_claim_rule(*mp); 5234 if (args.rule != NULL && fw_one_pass) 5235 goto ipfwpass; /* packet already partially processed */ 5236 5237 args.m = *mp; 5238 args.oif = ifp; 5239 args.next_hop = NULL; 5240 args.eh = &eh2; 5241 args.inp = NULL; /* used by ipfw uid/gid/jail rules */ 5242 i = ip_fw_chk_ptr(&args); 5243 *mp = args.m; 5244 5245 if (*mp == NULL) 5246 return (error); 5247 5248 if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) { 5249 5250 /* put the Ethernet header back on */ 5251 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 5252 if (*mp == NULL) 5253 return (error); 5254 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 5255 5256 /* 5257 * Pass the pkt to dummynet, which consumes it. The 5258 * packet will return to us via bridge_dummynet(). 5259 */ 5260 args.oif = ifp; 5261 ip_dn_io_ptr(mp, DN_TO_IFB_FWD, &args, DN_CLIENT_IPFW); 5262 return (error); 5263 } 5264 5265 if (i != IP_FW_PASS) /* drop */ 5266 goto bad; 5267 } 5268 5269ipfwpass: 5270 error = 0; 5271 5272 /* 5273 * Run the packet through pfil 5274 */ 5275 switch (ether_type) { 5276 case ETHERTYPE_IP: 5277 /* 5278 * before calling the firewall, swap fields the same as 5279 * IP does. here we assume the header is contiguous 5280 */ 5281 ip = mtod(*mp, struct ip *); 5282 5283 ip->ip_len = ntohs(ip->ip_len); 5284 ip->ip_off = ntohs(ip->ip_off); 5285 5286 /* 5287 * Run pfil on the member interface and the bridge, both can 5288 * be skipped by clearing pfil_member or pfil_bridge. 5289 * 5290 * Keep the order: 5291 * in_if -> bridge_if -> out_if 5292 */ 5293 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) 5294 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, 5295 dir, NULL); 5296 5297 if (*mp == NULL || error != 0) /* filter may consume */ 5298 break; 5299 5300 if (pfil_member && ifp != NULL) 5301 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, 5302 dir, NULL); 5303 5304 if (*mp == NULL || error != 0) /* filter may consume */ 5305 break; 5306 5307 if (pfil_bridge && dir == PFIL_IN && bifp != NULL) 5308 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp, 5309 dir, NULL); 5310 5311 if (*mp == NULL || error != 0) /* filter may consume */ 5312 break; 5313 5314 /* check if we need to fragment the packet */ 5315 if (pfil_member && ifp != NULL && dir == PFIL_OUT) { 5316 i = (*mp)->m_pkthdr.len; 5317 if (i > ifp->if_mtu) { 5318 error = bridge_fragment(ifp, *mp, &eh2, snap, 5319 &llc1); 5320 return (error); 5321 } 5322 } 5323 5324 /* Recalculate the ip checksum and restore byte ordering */ 5325 ip = mtod(*mp, struct ip *); 5326 hlen = ip->ip_hl << 2; 5327 if (hlen < sizeof (struct ip)) 5328 goto bad; 5329 if (hlen > (*mp)->m_len) { 5330 if ((*mp = m_pullup(*mp, hlen)) == 0) 5331 goto bad; 5332 ip = mtod(*mp, struct ip *); 5333 if (ip == NULL) 5334 goto bad; 5335 } 5336 ip->ip_len = htons(ip->ip_len); 5337 ip->ip_off = htons(ip->ip_off); 5338 ip->ip_sum = 0; 5339 if (hlen == sizeof (struct ip)) 5340 ip->ip_sum = in_cksum_hdr(ip); 5341 else 5342 ip->ip_sum = in_cksum(*mp, hlen); 5343 5344 break; 5345#if INET6 5346 case ETHERTYPE_IPV6: 5347 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL) 5348 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, 5349 dir, NULL); 5350 5351 if (*mp == NULL || error != 0) /* filter may consume */ 5352 break; 5353 5354 if (pfil_member && ifp != NULL) 5355 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, 5356 dir, NULL); 5357 5358 if (*mp == NULL || error != 0) /* filter may consume */ 5359 break; 5360 5361 if (pfil_bridge && dir == PFIL_IN && bifp != NULL) 5362 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp, 5363 dir, NULL); 5364 break; 5365#endif 5366 default: 5367 error = 0; 5368 break; 5369 } 5370 5371 if (*mp == NULL) 5372 return (error); 5373 if (error != 0) 5374 goto bad; 5375 5376 error = -1; 5377 5378 /* 5379 * Finally, put everything back the way it was and return 5380 */ 5381 if (snap) { 5382 M_PREPEND(*mp, sizeof (struct llc), M_DONTWAIT); 5383 if (*mp == NULL) 5384 return (error); 5385 bcopy(&llc1, mtod(*mp, caddr_t), sizeof (struct llc)); 5386 } 5387 5388 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); 5389 if (*mp == NULL) 5390 return (error); 5391 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); 5392 5393 return (0); 5394 5395bad: 5396 m_freem(*mp); 5397 *mp = NULL; 5398 return (error); 5399} 5400 5401/* 5402 * Perform basic checks on header size since 5403 * pfil assumes ip_input has already processed 5404 * it for it. Cut-and-pasted from ip_input.c. 5405 * Given how simple the IPv6 version is, 5406 * does the IPv4 version really need to be 5407 * this complicated? 5408 * 5409 * XXX Should we update ipstat here, or not? 5410 * XXX Right now we update ipstat but not 5411 * XXX csum_counter. 5412 */ 5413static int 5414bridge_ip_checkbasic(struct mbuf **mp) 5415{ 5416 struct mbuf *m = *mp; 5417 struct ip *ip; 5418 int len, hlen; 5419 u_short sum; 5420 5421 if (*mp == NULL) 5422 return (-1); 5423 5424 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 5425 /* max_linkhdr is already rounded up to nearest 4-byte */ 5426 if ((m = m_copyup(m, sizeof (struct ip), 5427 max_linkhdr)) == NULL) { 5428 /* XXXJRT new stat, please */ 5429 ipstat.ips_toosmall++; 5430 goto bad; 5431 } 5432 } else if (__predict_false(m->m_len < sizeof (struct ip))) { 5433 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) { 5434 ipstat.ips_toosmall++; 5435 goto bad; 5436 } 5437 } 5438 ip = mtod(m, struct ip *); 5439 if (ip == NULL) goto bad; 5440 5441 if (ip->ip_v != IPVERSION) { 5442 ipstat.ips_badvers++; 5443 goto bad; 5444 } 5445 hlen = ip->ip_hl << 2; 5446 if (hlen < sizeof (struct ip)) { /* minimum header length */ 5447 ipstat.ips_badhlen++; 5448 goto bad; 5449 } 5450 if (hlen > m->m_len) { 5451 if ((m = m_pullup(m, hlen)) == 0) { 5452 ipstat.ips_badhlen++; 5453 goto bad; 5454 } 5455 ip = mtod(m, struct ip *); 5456 if (ip == NULL) goto bad; 5457 } 5458 5459 if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { 5460 sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); 5461 } else { 5462 if (hlen == sizeof (struct ip)) { 5463 sum = in_cksum_hdr(ip); 5464 } else { 5465 sum = in_cksum(m, hlen); 5466 } 5467 } 5468 if (sum) { 5469 ipstat.ips_badsum++; 5470 goto bad; 5471 } 5472 5473 /* Retrieve the packet length. */ 5474 len = ntohs(ip->ip_len); 5475 5476 /* 5477 * Check for additional length bogosity 5478 */ 5479 if (len < hlen) { 5480 ipstat.ips_badlen++; 5481 goto bad; 5482 } 5483 5484 /* 5485 * Check that the amount of data in the buffers 5486 * is as at least much as the IP header would have us expect. 5487 * Drop packet if shorter than we expect. 5488 */ 5489 if (m->m_pkthdr.len < len) { 5490 ipstat.ips_tooshort++; 5491 goto bad; 5492 } 5493 5494 /* Checks out, proceed */ 5495 *mp = m; 5496 return (0); 5497 5498bad: 5499 *mp = m; 5500 return (-1); 5501} 5502 5503#if INET6 5504/* 5505 * Same as above, but for IPv6. 5506 * Cut-and-pasted from ip6_input.c. 5507 * XXX Should we update ip6stat, or not? 5508 */ 5509static int 5510bridge_ip6_checkbasic(struct mbuf **mp) 5511{ 5512 struct mbuf *m = *mp; 5513 struct ip6_hdr *ip6; 5514 5515 /* 5516 * If the IPv6 header is not aligned, slurp it up into a new 5517 * mbuf with space for link headers, in the event we forward 5518 * it. Otherwise, if it is aligned, make sure the entire base 5519 * IPv6 header is in the first mbuf of the chain. 5520 */ 5521 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) { 5522 struct ifnet *inifp = m->m_pkthdr.rcvif; 5523 /* max_linkhdr is already rounded up to nearest 4-byte */ 5524 if ((m = m_copyup(m, sizeof (struct ip6_hdr), 5525 max_linkhdr)) == NULL) { 5526 /* XXXJRT new stat, please */ 5527 ip6stat.ip6s_toosmall++; 5528 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 5529 goto bad; 5530 } 5531 } else if (__predict_false(m->m_len < sizeof (struct ip6_hdr))) { 5532 struct ifnet *inifp = m->m_pkthdr.rcvif; 5533 if ((m = m_pullup(m, sizeof (struct ip6_hdr))) == NULL) { 5534 ip6stat.ip6s_toosmall++; 5535 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 5536 goto bad; 5537 } 5538 } 5539 5540 ip6 = mtod(m, struct ip6_hdr *); 5541 5542 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 5543 ip6stat.ip6s_badvers++; 5544 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 5545 goto bad; 5546 } 5547 5548 /* Checks out, proceed */ 5549 *mp = m; 5550 return (0); 5551 5552bad: 5553 *mp = m; 5554 return (-1); 5555} 5556#endif /* INET6 */ 5557 5558/* 5559 * bridge_fragment: 5560 * 5561 * Return a fragmented mbuf chain. 5562 */ 5563static int 5564bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh, 5565 int snap, struct llc *llc) 5566{ 5567 struct mbuf *m0; 5568 struct ip *ip; 5569 int error = -1; 5570 5571 if (m->m_len < sizeof (struct ip) && 5572 (m = m_pullup(m, sizeof (struct ip))) == NULL) 5573 goto out; 5574 ip = mtod(m, struct ip *); 5575 5576 error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist, 5577 CSUM_DELAY_IP); 5578 if (error) 5579 goto out; 5580 5581 /* walk the chain and re-add the Ethernet header */ 5582 for (m0 = m; m0; m0 = m0->m_nextpkt) { 5583 if (error == 0) { 5584 if (snap) { 5585 M_PREPEND(m0, sizeof (struct llc), M_DONTWAIT); 5586 if (m0 == NULL) { 5587 error = ENOBUFS; 5588 continue; 5589 } 5590 bcopy(llc, mtod(m0, caddr_t), 5591 sizeof (struct llc)); 5592 } 5593 M_PREPEND(m0, ETHER_HDR_LEN, M_DONTWAIT); 5594 if (m0 == NULL) { 5595 error = ENOBUFS; 5596 continue; 5597 } 5598 bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN); 5599 } else { 5600 m_freem(m); 5601 } 5602 } 5603 5604 if (error == 0) 5605 ipstat.ips_fragmented++; 5606 5607 return (error); 5608 5609out: 5610 if (m != NULL) 5611 m_freem(m); 5612 return (error); 5613} 5614#endif /* PFIL_HOOKS */ 5615 5616/* 5617 * bridge_set_bpf_tap: 5618 * 5619 * Sets ups the BPF callbacks. 5620 */ 5621static errno_t 5622bridge_set_bpf_tap(ifnet_t ifp, bpf_tap_mode mode, bpf_packet_func bpf_callback) 5623{ 5624 struct bridge_softc *sc = (struct bridge_softc *)ifnet_softc(ifp); 5625 5626 /* TBD locking */ 5627 if (sc == NULL || (sc->sc_flags & SCF_DETACHING)) { 5628 return (ENODEV); 5629 } 5630 5631 switch (mode) { 5632 case BPF_TAP_DISABLE: 5633 sc->sc_bpf_input = sc->sc_bpf_output = NULL; 5634 break; 5635 5636 case BPF_TAP_INPUT: 5637 sc->sc_bpf_input = bpf_callback; 5638 break; 5639 5640 case BPF_TAP_OUTPUT: 5641 sc->sc_bpf_output = bpf_callback; 5642 break; 5643 5644 case BPF_TAP_INPUT_OUTPUT: 5645 sc->sc_bpf_input = sc->sc_bpf_output = bpf_callback; 5646 break; 5647 5648 default: 5649 break; 5650 } 5651 5652 return (0); 5653} 5654 5655/* 5656 * bridge_detach: 5657 * 5658 * Callback when interface has been detached. 5659 */ 5660static void 5661bridge_detach(ifnet_t ifp) 5662{ 5663 struct bridge_softc *sc = (struct bridge_softc *)ifnet_softc(ifp); 5664 5665#if BRIDGESTP 5666 bstp_detach(&sc->sc_stp); 5667#endif /* BRIDGESTP */ 5668 5669 /* Tear down the routing table. */ 5670 bridge_rtable_fini(sc); 5671 5672 lck_mtx_lock(&bridge_list_mtx); 5673 LIST_REMOVE(sc, sc_list); 5674 lck_mtx_unlock(&bridge_list_mtx); 5675 5676 ifnet_release(ifp); 5677 5678 lck_mtx_destroy(&sc->sc_mtx, bridge_lock_grp); 5679 5680 _FREE(sc, M_DEVBUF); 5681} 5682 5683/* 5684 * bridge_bpf_input: 5685 * 5686 * Invoke the input BPF callback if enabled 5687 */ 5688__private_extern__ errno_t 5689bridge_bpf_input(ifnet_t ifp, struct mbuf *m) 5690{ 5691 struct bridge_softc *sc = (struct bridge_softc *)ifnet_softc(ifp); 5692 5693 if (sc->sc_bpf_input) { 5694 if (mbuf_pkthdr_rcvif(m) != ifp) { 5695 printf("%s: rcvif: 0x%llx != ifp 0x%llx\n", __func__, 5696 (uint64_t)VM_KERNEL_ADDRPERM(mbuf_pkthdr_rcvif(m)), 5697 (uint64_t)VM_KERNEL_ADDRPERM(ifp)); 5698 } 5699 (*sc->sc_bpf_input)(ifp, m); 5700 } 5701 return (0); 5702} 5703 5704/* 5705 * bridge_bpf_output: 5706 * 5707 * Invoke the output BPF callback if enabled 5708 */ 5709__private_extern__ errno_t 5710bridge_bpf_output(ifnet_t ifp, struct mbuf *m) 5711{ 5712 struct bridge_softc *sc = (struct bridge_softc *)ifnet_softc(ifp); 5713 5714 if (sc->sc_bpf_output) { 5715 (*sc->sc_bpf_output)(ifp, m); 5716 } 5717 return (0); 5718} 5719 5720/* 5721 * bridge_link_event: 5722 * 5723 * Report a data link event on an interface 5724 */ 5725static void 5726bridge_link_event(struct ifnet *ifp, u_int32_t event_code) 5727{ 5728 struct { 5729 struct kern_event_msg header; 5730 u_int32_t unit; 5731 char if_name[IFNAMSIZ]; 5732 } event; 5733 5734#if BRIDGE_DEBUG 5735 if (if_bridge_debug & BR_DBGF_LIFECYCLE) 5736 printf("%s: %s event_code %u - %s\n", __func__, ifp->if_xname, 5737 event_code, dlil_kev_dl_code_str(event_code)); 5738#endif /* BRIDGE_DEBUG */ 5739 5740 bzero(&event, sizeof (event)); 5741 event.header.total_size = sizeof (event); 5742 event.header.vendor_code = KEV_VENDOR_APPLE; 5743 event.header.kev_class = KEV_NETWORK_CLASS; 5744 event.header.kev_subclass = KEV_DL_SUBCLASS; 5745 event.header.event_code = event_code; 5746 event.header.event_data[0] = ifnet_family(ifp); 5747 event.unit = (u_int32_t)ifnet_unit(ifp); 5748 strncpy(event.if_name, ifnet_name(ifp), IFNAMSIZ); 5749 ifnet_event(ifp, &event.header); 5750} 5751