]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/if_bridge.c
xnu-2422.115.4.tar.gz
[apple/xnu.git] / bsd / net / if_bridge.c
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 */
294 struct 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 */
317 struct 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 */
332 typedef void (*bridge_delayed_func_t)(struct bridge_softc *);
333
334 struct 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
348 LIST_HEAD(_bridge_rtnode_list, bridge_rtnode);
349
350 struct 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
394 decl_lck_mtx_data(static, bridge_list_mtx);
395
396 static int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
397
398 static zone_t bridge_rtnode_pool = NULL;
399
400 static int bridge_clone_create(struct if_clone *, uint32_t, void *);
401 static int bridge_clone_destroy(struct ifnet *);
402
403 static errno_t bridge_ioctl(struct ifnet *, u_long, void *);
404 #if HAS_IF_CAP
405 static void bridge_mutecaps(struct bridge_softc *);
406 static void bridge_set_ifcap(struct bridge_softc *, struct bridge_iflist *,
407 int);
408 #endif
409 static errno_t bridge_set_tso(struct bridge_softc *);
410 __private_extern__ void bridge_ifdetach(struct bridge_iflist *, struct ifnet *);
411 static int bridge_init(struct ifnet *);
412 #if HAS_BRIDGE_DUMMYNET
413 static void bridge_dummynet(struct mbuf *, struct ifnet *);
414 #endif
415 static void bridge_ifstop(struct ifnet *, int);
416 static int bridge_output(struct ifnet *, struct mbuf *);
417 static void bridge_finalize_cksum(struct ifnet *, struct mbuf *);
418 static void bridge_start(struct ifnet *);
419 __private_extern__ errno_t bridge_input(struct ifnet *, struct mbuf *, void *);
420 #if BRIDGE_MEMBER_OUT_FILTER
421 static errno_t bridge_iff_output(void *, ifnet_t, protocol_family_t,
422 mbuf_t *);
423 static int bridge_member_output(struct ifnet *, struct mbuf *,
424 struct sockaddr *, struct rtentry *);
425 #endif
426 static int bridge_enqueue(struct bridge_softc *, struct ifnet *,
427 struct mbuf *);
428 static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int);
429
430 static void bridge_forward(struct bridge_softc *, struct bridge_iflist *,
431 struct mbuf *);
432
433 static void bridge_aging_timer(struct bridge_softc *sc);
434
435 static void bridge_broadcast(struct bridge_softc *, struct ifnet *,
436 struct mbuf *, int);
437 static void bridge_span(struct bridge_softc *, struct mbuf *);
438
439 static int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
440 uint16_t, struct bridge_iflist *, int, uint8_t);
441 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *,
442 uint16_t);
443 static void bridge_rttrim(struct bridge_softc *);
444 static void bridge_rtage(struct bridge_softc *);
445 static void bridge_rtflush(struct bridge_softc *, int);
446 static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *,
447 uint16_t);
448
449 static int bridge_rtable_init(struct bridge_softc *);
450 static void bridge_rtable_fini(struct bridge_softc *);
451
452 static void bridge_rthash_resize(struct bridge_softc *);
453
454 static int bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
455 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
456 const uint8_t *, uint16_t);
457 static int bridge_rtnode_hash(struct bridge_softc *,
458 struct bridge_rtnode *);
459 static int bridge_rtnode_insert(struct bridge_softc *,
460 struct bridge_rtnode *);
461 static void bridge_rtnode_destroy(struct bridge_softc *,
462 struct bridge_rtnode *);
463 #if BRIDGESTP
464 static void bridge_rtable_expire(struct ifnet *, int);
465 static void bridge_state_change(struct ifnet *, int);
466 #endif /* BRIDGESTP */
467
468 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
469 const char *name);
470 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
471 struct ifnet *ifp);
472 static void bridge_delete_member(struct bridge_softc *,
473 struct bridge_iflist *, int);
474 static void bridge_delete_span(struct bridge_softc *,
475 struct bridge_iflist *);
476
477 static int bridge_ioctl_add(struct bridge_softc *, void *);
478 static int bridge_ioctl_del(struct bridge_softc *, void *);
479 static int bridge_ioctl_gifflags(struct bridge_softc *, void *);
480 static int bridge_ioctl_sifflags(struct bridge_softc *, void *);
481 static int bridge_ioctl_scache(struct bridge_softc *, void *);
482 static int bridge_ioctl_gcache(struct bridge_softc *, void *);
483 static int bridge_ioctl_gifs32(struct bridge_softc *, void *);
484 static int bridge_ioctl_gifs64(struct bridge_softc *, void *);
485 static int bridge_ioctl_rts32(struct bridge_softc *, void *);
486 static int bridge_ioctl_rts64(struct bridge_softc *, void *);
487 static int bridge_ioctl_saddr32(struct bridge_softc *, void *);
488 static int bridge_ioctl_saddr64(struct bridge_softc *, void *);
489 static int bridge_ioctl_sto(struct bridge_softc *, void *);
490 static int bridge_ioctl_gto(struct bridge_softc *, void *);
491 static int bridge_ioctl_daddr32(struct bridge_softc *, void *);
492 static int bridge_ioctl_daddr64(struct bridge_softc *, void *);
493 static int bridge_ioctl_flush(struct bridge_softc *, void *);
494 static int bridge_ioctl_gpri(struct bridge_softc *, void *);
495 static int bridge_ioctl_spri(struct bridge_softc *, void *);
496 static int bridge_ioctl_ght(struct bridge_softc *, void *);
497 static int bridge_ioctl_sht(struct bridge_softc *, void *);
498 static int bridge_ioctl_gfd(struct bridge_softc *, void *);
499 static int bridge_ioctl_sfd(struct bridge_softc *, void *);
500 static int bridge_ioctl_gma(struct bridge_softc *, void *);
501 static int bridge_ioctl_sma(struct bridge_softc *, void *);
502 static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
503 static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
504 static int bridge_ioctl_sifmaxaddr(struct bridge_softc *, void *);
505 static int bridge_ioctl_addspan(struct bridge_softc *, void *);
506 static int bridge_ioctl_delspan(struct bridge_softc *, void *);
507 static int bridge_ioctl_gbparam32(struct bridge_softc *, void *);
508 static int bridge_ioctl_gbparam64(struct bridge_softc *, void *);
509 static int bridge_ioctl_grte(struct bridge_softc *, void *);
510 static int bridge_ioctl_gifsstp32(struct bridge_softc *, void *);
511 static int bridge_ioctl_gifsstp64(struct bridge_softc *, void *);
512 static int bridge_ioctl_sproto(struct bridge_softc *, void *);
513 static int bridge_ioctl_stxhc(struct bridge_softc *, void *);
514 static int bridge_ioctl_purge(struct bridge_softc *sc, void *);
515 static int bridge_ioctl_gfilt(struct bridge_softc *, void *);
516 static int bridge_ioctl_sfilt(struct bridge_softc *, void *);
517 #ifdef PFIL_HOOKS
518 static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
519 int);
520 static int bridge_ip_checkbasic(struct mbuf **);
521 #ifdef INET6
522 static int bridge_ip6_checkbasic(struct mbuf **);
523 #endif /* INET6 */
524 static int bridge_fragment(struct ifnet *, struct mbuf *,
525 struct ether_header *, int, struct llc *);
526 #endif /* PFIL_HOOKS */
527
528 static 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
532 static void bridge_detach(ifnet_t);
533 static void bridge_link_event(struct ifnet *, u_int32_t);
534 static void bridge_iflinkevent(struct ifnet *);
535 static u_int32_t bridge_updatelinkstatus(struct bridge_softc *);
536 static int interface_media_active(struct ifnet *);
537 static void bridge_schedule_delayed_call(struct bridge_delayed_call *);
538 static 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
545 u_int8_t bstp_etheraddr[ETHER_ADDR_LEN] =
546 { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
547
548 #if BRIDGESTP
549 static struct bstp_cb_ops bridge_ops = {
550 .bcb_state = bridge_state_change,
551 .bcb_rtage = bridge_rtable_expire
552 };
553 #endif /* BRIDGESTP */
554
555 SYSCTL_DECL(_net_link);
556 SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
557 "Bridge");
558
559 static int bridge_inherit_mac = 0; /* share MAC with first bridge member */
560 SYSCTL_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
565 SYSCTL_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
570 static unsigned int bridge_rtable_hash_size_max = BRIDGE_RTHASH_SIZE_MAX;
571 SYSCTL_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
577 static int bridge_delayed_callback_delay = 0;
578 SYSCTL_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)
585 static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
586 static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
587 static int pfil_member = 1; /* run pfil hooks on the member interface */
588 static int pfil_ipfw = 0; /* layer2 filter with ipfw */
589 static int pfil_ipfw_arp = 0; /* layer2 filter with ipfw */
590 static int pfil_local_phys = 0; /* run pfil hooks on the physical interface */
591 /* for locally destined packets */
592 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW|CTLFLAG_LOCKED,
593 &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
594 SYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW|CTLFLAG_LOCKED,
595 &pfil_ipfw_arp, 0, "Filter ARP packets through IPFW layer2");
596 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW|CTLFLAG_LOCKED,
597 &pfil_bridge, 0, "Packet filter on the bridge interface");
598 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW|CTLFLAG_LOCKED,
599 &pfil_member, 0, "Packet filter on the member interface");
600 SYSCTL_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
606 static int log_stp = 0; /* log STP state changes */
607 SYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW,
608 &log_stp, 0, "Log STP state changes");
609 #endif /* BRIDGESTP */
610
611 struct 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
621 static 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
714 static 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
807 static const unsigned int bridge_control_table_size =
808 sizeof (bridge_control_table32) / sizeof (bridge_control_table32[0]);
809
810 static LIST_HEAD(, bridge_softc) bridge_list =
811 LIST_HEAD_INITIALIZER(bridge_list);
812
813 static lck_grp_t *bridge_lock_grp = NULL;
814 static lck_attr_t *bridge_lock_attr = NULL;
815
816 static if_clone_t bridge_cloner = NULL;
817
818 static int if_bridge_txstart = 0;
819 SYSCTL_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
823 static int if_bridge_debug = 0;
824 SYSCTL_INT(_net_link_bridge, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_LOCKED,
825 &if_bridge_debug, 0, "Bridge debug");
826
827 static void printf_ether_header(struct ether_header *);
828 static void printf_mbuf_data(mbuf_t, size_t, size_t);
829 static void printf_mbuf_pkthdr(mbuf_t, const char *, const char *);
830 static void printf_mbuf(mbuf_t, const char *, const char *);
831 static void link_print(struct sockaddr_dl *);
832
833 static void bridge_lock(struct bridge_softc *);
834 static void bridge_unlock(struct bridge_softc *);
835 static int bridge_lock2ref(struct bridge_softc *);
836 static void bridge_unref(struct bridge_softc *);
837 static void bridge_xlock(struct bridge_softc *);
838 static void bridge_xdrop(struct bridge_softc *);
839
840 static void
841 bridge_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
853 static void
854 bridge_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
866 static int
867 bridge_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
887 static void
888 bridge_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
909 static void
910 bridge_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
928 static void
929 bridge_xdrop(struct bridge_softc *sc)
930 {
931 BRIDGE_LOCK_ASSERT_HELD(sc);
932
933 sc->sc_iflist_xcnt--;
934 }
935
936 void
937 printf_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
951 void
952 printf_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
970 void
971 printf_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
1002 static void
1003 printf_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
1014 static void
1015 link_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
1038 bridgeattach(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 */
1085 static int
1086 sysctl_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
1114 SYSCTL_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 */
1123 static int
1124 bridge_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(&eth_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(&eth_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
1320 done:
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 */
1334 static int
1335 bridge_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 */
1433 static errno_t
1434 bridge_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 */
1611 static void
1612 bridge_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
1637 static void
1638 bridge_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
1659 static errno_t
1660 bridge_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 }
1748 done:
1749 return (error);
1750 }
1751
1752 /*
1753 * bridge_lookup_member:
1754 *
1755 * Lookup a bridge member interface.
1756 */
1757 static struct bridge_iflist *
1758 bridge_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 */
1779 static struct bridge_iflist *
1780 bridge_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
1794 static errno_t
1795 bridge_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
1859 out:
1860 BRIDGE_LOCK_ASSERT_NOTHELD(sc);
1861
1862 return (error);
1863 }
1864
1865 #if BRIDGE_MEMBER_OUT_FILTER
1866 static errno_t
1867 bridge_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
1894 out:
1895 BRIDGE_LOCK_ASSERT_NOTHELD(sc);
1896
1897 return (error);
1898 }
1899 #endif /* BRIDGE_MEMBER_OUT_FILTER */
1900
1901 static void
1902 bridge_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 */
1969 static void
1970 bridge_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
1984 static errno_t
1985 bridge_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
1996 static int
1997 bridge_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(&reg, sizeof (reg));
2008 reg.input = bridge_proto_input;
2009
2010 error = ifnet_attach_protocol(ifp, PF_BRIDGE, &reg);
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
2018 static int
2019 bridge_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 */
2040 static void
2041 bridge_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 */
2161 static void
2162 bridge_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
2175 static int
2176 bridge_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
2346 out:
2347 if (error && bif != NULL)
2348 bridge_delete_member(sc, bif, 1);
2349
2350 return (error);
2351 }
2352
2353 static int
2354 bridge_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
2368 static int
2369 bridge_ioctl_purge(struct bridge_softc *sc, void *arg)
2370 {
2371 #pragma unused(sc, arg)
2372 return (0);
2373 }
2374
2375 static int
2376 bridge_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
2415 static int
2416 bridge_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
2464 static int
2465 bridge_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
2475 static int
2476 bridge_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
2546 static int
2547 bridge_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
2557 static int
2558 bridge_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 } \
2611 out: \
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
2620 static int
2621 bridge_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
2632 static int
2633 bridge_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
2644 static int
2645 bridge_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
2661 static int
2662 bridge_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
2678 static int
2679 bridge_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
2687 static int
2688 bridge_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
2696 static int
2697 bridge_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
2704 static int
2705 bridge_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
2712 static int
2713 bridge_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
2721 static int
2722 bridge_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
2731 static int
2732 bridge_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
2744 static int
2745 bridge_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
2754 static int
2755 bridge_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
2767 static int
2768 bridge_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
2777 static int
2778 bridge_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
2790 static int
2791 bridge_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
2800 static int
2801 bridge_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
2813 static int
2814 bridge_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
2831 static int
2832 bridge_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
2849 static int
2850 bridge_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
2859 static int
2860 bridge_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
2877 static int
2878 bridge_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
2891 static int
2892 bridge_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
2934 static int
2935 bridge_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
2982 static int
2983 bridge_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
2992 static int
2993 bridge_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
3002 static int
3003 bridge_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
3067 static int
3068 bridge_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
3078 static int
3079 bridge_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
3089 static int
3090 bridge_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
3102 static int
3103 bridge_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
3122 bridge_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 */
3160 static int
3161 interface_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 */
3182 static u_int32_t
3183 bridge_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 */
3215 static void
3216 bridge_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 */
3252 static void
3253 bridge_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 */
3300 static void
3301 bridge_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 */
3339 static void
3340 bridge_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 */
3385 static int
3386 bridge_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 */
3417 static void
3418 bridge_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 */
3445 static int
3446 bridge_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 */
3522 static void
3523 bridge_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 */
3561 static int
3562 bridge_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
3667 sendunicast:
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 */
3691 static int
3692 bridge_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
3724 static void
3725 bridge_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 */
3797 static void
3798 bridge_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 */
3817 static void
3818 bridge_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
3977 drop:
3978 BRIDGE_UNLOCK(sc);
3979 m_freem(m);
3980 }
3981
3982 #if BRIDGE_DEBUG
3983
3984 char *ether_ntop(char *, size_t, const u_char *);
3985
3986 __private_extern__ char *
3987 ether_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
4004 bridge_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 */
4334 static void
4335 bridge_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
4428 out:
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 */
4440 static void
4441 bridge_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 */
4472 static int
4473 bridge_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 */
4567 static struct ifnet *
4568 bridge_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 */
4587 static void
4588 bridge_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 */
4617 static void
4618 bridge_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 */
4638 static void
4639 bridge_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 */
4661 static void
4662 bridge_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 */
4679 static int
4680 bridge_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 */
4704 static void
4705 bridge_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 */
4723 static int
4724 bridge_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 */
4751 static void
4752 bridge_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 }
4812 out:
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 */
4836 static void
4837 bridge_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 */
4865 static void
4866 bridge_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) \
4881 do { \
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
4893 static __inline uint32_t
4894 bridge_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
4912 static int
4913 bridge_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 */
4930 static struct bridge_rtnode *
4931 bridge_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 */
4959 static int
4960 bridge_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
5009 out:
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 */
5019 static int
5020 bridge_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 */
5041 static void
5042 bridge_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 */
5060 static void
5061 bridge_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 */
5095 static void
5096 bridge_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 */
5122 static int
5123 bridge_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
5269 ipfwpass:
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
5395 bad:
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 */
5413 static int
5414 bridge_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
5498 bad:
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 */
5509 static int
5510 bridge_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
5552 bad:
5553 *mp = m;
5554 return (-1);
5555 }
5556 #endif /* INET6 */
5557
5558 /*
5559 * bridge_fragment:
5560 *
5561 * Return a fragmented mbuf chain.
5562 */
5563 static int
5564 bridge_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
5609 out:
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 */
5621 static errno_t
5622 bridge_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 */
5660 static void
5661 bridge_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
5689 bridge_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
5710 bridge_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 */
5725 static void
5726 bridge_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 }