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