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