if_bridge.c revision 1.145 1 /* $NetBSD: if_bridge.c,v 1.145 2017/12/11 03:29:20 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.145 2017/12/11 03:29:20 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) if ((_sc)->sc_rtlist_lock) \
185 mutex_enter((_sc)->sc_rtlist_lock)
186 #define BRIDGE_RT_UNLOCK(_sc) if ((_sc)->sc_rtlist_lock) \
187 mutex_exit((_sc)->sc_rtlist_lock)
188 #define BRIDGE_RT_LOCKED(_sc) (!(_sc)->sc_rtlist_lock || \
189 mutex_owned((_sc)->sc_rtlist_lock))
190
191 #define BRIDGE_RT_PSZ_PERFORM(_sc) \
192 if ((_sc)->sc_rtlist_psz != NULL) \
193 pserialize_perform((_sc)->sc_rtlist_psz);
194
195 #define BRIDGE_RT_RENTER(__s) do { __s = pserialize_read_enter(); } while (0)
196 #define BRIDGE_RT_REXIT(__s) do { pserialize_read_exit(__s); } while (0)
197
198
199 #ifdef NET_MPSAFE
200 #define DECLARE_LOCK_VARIABLE
201 #define ACQUIRE_GLOBAL_LOCKS() do { } while (0)
202 #define RELEASE_GLOBAL_LOCKS() do { } while (0)
203 #else
204 #define DECLARE_LOCK_VARIABLE int __s
205 #define ACQUIRE_GLOBAL_LOCKS() do { \
206 KERNEL_LOCK(1, NULL); \
207 mutex_enter(softnet_lock); \
208 __s = splsoftnet(); \
209 } while (0)
210 #define RELEASE_GLOBAL_LOCKS() do { \
211 splx(__s); \
212 mutex_exit(softnet_lock); \
213 KERNEL_UNLOCK_ONE(NULL); \
214 } while (0)
215 #endif
216
217 struct psref_class *bridge_psref_class __read_mostly;
218
219 int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
220
221 static struct pool bridge_rtnode_pool;
222
223 static int bridge_clone_create(struct if_clone *, int);
224 static int bridge_clone_destroy(struct ifnet *);
225
226 static int bridge_ioctl(struct ifnet *, u_long, void *);
227 static int bridge_init(struct ifnet *);
228 static void bridge_stop(struct ifnet *, int);
229 static void bridge_start(struct ifnet *);
230
231 static void bridge_input(struct ifnet *, struct mbuf *);
232 static void bridge_forward(struct bridge_softc *, struct mbuf *);
233
234 static void bridge_timer(void *);
235
236 static void bridge_broadcast(struct bridge_softc *, struct ifnet *,
237 struct mbuf *);
238
239 static int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
240 struct ifnet *, int, uint8_t);
241 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
242 static void bridge_rttrim(struct bridge_softc *);
243 static void bridge_rtage(struct bridge_softc *);
244 static void bridge_rtage_work(struct work *, void *);
245 static void bridge_rtflush(struct bridge_softc *, int);
246 static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
247 static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp);
248
249 static void bridge_rtable_init(struct bridge_softc *);
250 static void bridge_rtable_fini(struct bridge_softc *);
251
252 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
253 const uint8_t *);
254 static int bridge_rtnode_insert(struct bridge_softc *,
255 struct bridge_rtnode *);
256 static void bridge_rtnode_remove(struct bridge_softc *,
257 struct bridge_rtnode *);
258 static void bridge_rtnode_destroy(struct bridge_rtnode *);
259
260 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
261 const char *name,
262 struct psref *);
263 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
264 struct ifnet *ifp,
265 struct psref *);
266 static void bridge_release_member(struct bridge_softc *, struct bridge_iflist *,
267 struct psref *);
268 static void bridge_delete_member(struct bridge_softc *,
269 struct bridge_iflist *);
270 static void bridge_acquire_member(struct bridge_softc *sc,
271 struct bridge_iflist *,
272 struct psref *);
273
274 static int bridge_ioctl_add(struct bridge_softc *, void *);
275 static int bridge_ioctl_del(struct bridge_softc *, void *);
276 static int bridge_ioctl_gifflags(struct bridge_softc *, void *);
277 static int bridge_ioctl_sifflags(struct bridge_softc *, void *);
278 static int bridge_ioctl_scache(struct bridge_softc *, void *);
279 static int bridge_ioctl_gcache(struct bridge_softc *, void *);
280 static int bridge_ioctl_gifs(struct bridge_softc *, void *);
281 static int bridge_ioctl_rts(struct bridge_softc *, void *);
282 static int bridge_ioctl_saddr(struct bridge_softc *, void *);
283 static int bridge_ioctl_sto(struct bridge_softc *, void *);
284 static int bridge_ioctl_gto(struct bridge_softc *, void *);
285 static int bridge_ioctl_daddr(struct bridge_softc *, void *);
286 static int bridge_ioctl_flush(struct bridge_softc *, void *);
287 static int bridge_ioctl_gpri(struct bridge_softc *, void *);
288 static int bridge_ioctl_spri(struct bridge_softc *, void *);
289 static int bridge_ioctl_ght(struct bridge_softc *, void *);
290 static int bridge_ioctl_sht(struct bridge_softc *, void *);
291 static int bridge_ioctl_gfd(struct bridge_softc *, void *);
292 static int bridge_ioctl_sfd(struct bridge_softc *, void *);
293 static int bridge_ioctl_gma(struct bridge_softc *, void *);
294 static int bridge_ioctl_sma(struct bridge_softc *, void *);
295 static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
296 static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
297 #if defined(BRIDGE_IPF)
298 static int bridge_ioctl_gfilt(struct bridge_softc *, void *);
299 static int bridge_ioctl_sfilt(struct bridge_softc *, void *);
300 static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
301 static int bridge_ip_checkbasic(struct mbuf **mp);
302 # ifdef INET6
303 static int bridge_ip6_checkbasic(struct mbuf **mp);
304 # endif /* INET6 */
305 #endif /* BRIDGE_IPF */
306
307 struct bridge_control {
308 int (*bc_func)(struct bridge_softc *, void *);
309 int bc_argsize;
310 int bc_flags;
311 };
312
313 #define BC_F_COPYIN 0x01 /* copy arguments in */
314 #define BC_F_COPYOUT 0x02 /* copy arguments out */
315 #define BC_F_SUSER 0x04 /* do super-user check */
316 #define BC_F_XLATEIN 0x08 /* xlate arguments in */
317 #define BC_F_XLATEOUT 0x10 /* xlate arguments out */
318
319 static const struct bridge_control bridge_control_table[] = {
320 [BRDGADD] = {bridge_ioctl_add, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
321 [BRDGDEL] = {bridge_ioctl_del, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
322
323 [BRDGGIFFLGS] = {bridge_ioctl_gifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_COPYOUT},
324 [BRDGSIFFLGS] = {bridge_ioctl_sifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
325
326 [BRDGSCACHE] = {bridge_ioctl_scache, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
327 [BRDGGCACHE] = {bridge_ioctl_gcache, sizeof(struct ifbrparam), BC_F_COPYOUT},
328
329 [OBRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_COPYIN|BC_F_COPYOUT},
330 [OBRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_COPYIN|BC_F_COPYOUT},
331
332 [BRDGSADDR] = {bridge_ioctl_saddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
333
334 [BRDGSTO] = {bridge_ioctl_sto, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
335 [BRDGGTO] = {bridge_ioctl_gto, sizeof(struct ifbrparam), BC_F_COPYOUT},
336
337 [BRDGDADDR] = {bridge_ioctl_daddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
338
339 [BRDGFLUSH] = {bridge_ioctl_flush, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
340
341 [BRDGGPRI] = {bridge_ioctl_gpri, sizeof(struct ifbrparam), BC_F_COPYOUT},
342 [BRDGSPRI] = {bridge_ioctl_spri, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
343
344 [BRDGGHT] = {bridge_ioctl_ght, sizeof(struct ifbrparam), BC_F_COPYOUT},
345 [BRDGSHT] = {bridge_ioctl_sht, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
346
347 [BRDGGFD] = {bridge_ioctl_gfd, sizeof(struct ifbrparam), BC_F_COPYOUT},
348 [BRDGSFD] = {bridge_ioctl_sfd, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
349
350 [BRDGGMA] = {bridge_ioctl_gma, sizeof(struct ifbrparam), BC_F_COPYOUT},
351 [BRDGSMA] = {bridge_ioctl_sma, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
352
353 [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
354
355 [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
356 #if defined(BRIDGE_IPF)
357 [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT},
358 [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
359 #endif /* BRIDGE_IPF */
360 [BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT},
361 [BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT},
362 };
363
364 static const int bridge_control_table_size = __arraycount(bridge_control_table);
365
366 static struct if_clone bridge_cloner =
367 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
368
369 /*
370 * bridgeattach:
371 *
372 * Pseudo-device attach routine.
373 */
374 void
375 bridgeattach(int n)
376 {
377
378 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
379 0, 0, 0, "brtpl", NULL, IPL_NET);
380
381 bridge_psref_class = psref_class_create("bridge", IPL_SOFTNET);
382
383 if_clone_attach(&bridge_cloner);
384 }
385
386 /*
387 * bridge_clone_create:
388 *
389 * Create a new bridge instance.
390 */
391 static int
392 bridge_clone_create(struct if_clone *ifc, int unit)
393 {
394 struct bridge_softc *sc;
395 struct ifnet *ifp;
396 int error;
397
398 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
399 ifp = &sc->sc_if;
400
401 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
402 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
403 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
404 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
405 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
406 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
407 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
408 sc->sc_filter_flags = 0;
409
410 /* Initialize our routing table. */
411 bridge_rtable_init(sc);
412
413 error = workqueue_create(&sc->sc_rtage_wq, "bridge_rtage",
414 bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE);
415 if (error)
416 panic("%s: workqueue_create %d\n", __func__, error);
417
418 callout_init(&sc->sc_brcallout, CALLOUT_MPSAFE);
419 callout_init(&sc->sc_bstpcallout, CALLOUT_MPSAFE);
420
421 mutex_init(&sc->sc_iflist_psref.bip_lock, MUTEX_DEFAULT, IPL_NONE);
422 PSLIST_INIT(&sc->sc_iflist_psref.bip_iflist);
423 sc->sc_iflist_psref.bip_psz = pserialize_create();
424
425 if_initname(ifp, ifc->ifc_name, unit);
426 ifp->if_softc = sc;
427 ifp->if_extflags = IFEF_MPSAFE | IFEF_NO_LINK_STATE_CHANGE;
428 ifp->if_mtu = ETHERMTU;
429 ifp->if_ioctl = bridge_ioctl;
430 ifp->if_output = bridge_output;
431 ifp->if_start = bridge_start;
432 ifp->if_stop = bridge_stop;
433 ifp->if_init = bridge_init;
434 ifp->if_type = IFT_BRIDGE;
435 ifp->if_addrlen = 0;
436 ifp->if_dlt = DLT_EN10MB;
437 ifp->if_hdrlen = ETHER_HDR_LEN;
438
439 error = if_initialize(ifp);
440 if (error != 0) {
441 pserialize_destroy(sc->sc_iflist_psref.bip_psz);
442 mutex_destroy(&sc->sc_iflist_psref.bip_lock);
443 callout_destroy(&sc->sc_brcallout);
444 callout_destroy(&sc->sc_bstpcallout);
445 workqueue_destroy(sc->sc_rtage_wq);
446 bridge_rtable_fini(sc);
447 kmem_free(sc, sizeof(*sc));
448
449 return error;
450 }
451 if_register(ifp);
452
453 if_alloc_sadl(ifp);
454
455 return 0;
456 }
457
458 /*
459 * bridge_clone_destroy:
460 *
461 * Destroy a bridge instance.
462 */
463 static int
464 bridge_clone_destroy(struct ifnet *ifp)
465 {
466 struct bridge_softc *sc = ifp->if_softc;
467 struct bridge_iflist *bif;
468
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_stop(&sc->sc_brcallout);
1359 bstp_stop(sc);
1360 bridge_rtflush(sc, IFBF_FLUSHDYN);
1361 }
1362
1363 /*
1364 * bridge_enqueue:
1365 *
1366 * Enqueue a packet on a bridge member interface.
1367 */
1368 void
1369 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
1370 int runfilt)
1371 {
1372 int len, error;
1373 short mflags;
1374
1375 /*
1376 * Clear any in-bound checksum flags for this packet.
1377 */
1378 m->m_pkthdr.csum_flags = 0;
1379
1380 if (runfilt) {
1381 if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
1382 dst_ifp, PFIL_OUT) != 0) {
1383 if (m != NULL)
1384 m_freem(m);
1385 return;
1386 }
1387 if (m == NULL)
1388 return;
1389 }
1390
1391 #ifdef ALTQ
1392 KERNEL_LOCK(1, NULL);
1393 /*
1394 * If ALTQ is enabled on the member interface, do
1395 * classification; the queueing discipline might
1396 * not require classification, but might require
1397 * the address family/header pointer in the pktattr.
1398 */
1399 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) {
1400 /* XXX IFT_ETHER */
1401 altq_etherclassify(&dst_ifp->if_snd, m);
1402 }
1403 KERNEL_UNLOCK_ONE(NULL);
1404 #endif /* ALTQ */
1405
1406 len = m->m_pkthdr.len;
1407 mflags = m->m_flags;
1408
1409 error = if_transmit_lock(dst_ifp, m);
1410 if (error) {
1411 /* mbuf is already freed */
1412 sc->sc_if.if_oerrors++;
1413 return;
1414 }
1415
1416 sc->sc_if.if_opackets++;
1417 sc->sc_if.if_obytes += len;
1418 if (mflags & M_MCAST)
1419 sc->sc_if.if_omcasts++;
1420 }
1421
1422 /*
1423 * bridge_output:
1424 *
1425 * Send output from a bridge member interface. This
1426 * performs the bridging function for locally originated
1427 * packets.
1428 *
1429 * The mbuf has the Ethernet header already attached. We must
1430 * enqueue or free the mbuf before returning.
1431 */
1432 int
1433 bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,
1434 const struct rtentry *rt)
1435 {
1436 struct ether_header *eh;
1437 struct ifnet *dst_if;
1438 struct bridge_softc *sc;
1439 int s;
1440
1441 /*
1442 * bridge_output() is called from ether_output(), furthermore
1443 * ifp argument doesn't point to bridge(4). So, don't assert
1444 * IFEF_MPSAFE here.
1445 */
1446
1447 if (m->m_len < ETHER_HDR_LEN) {
1448 m = m_pullup(m, ETHER_HDR_LEN);
1449 if (m == NULL)
1450 return 0;
1451 }
1452
1453 eh = mtod(m, struct ether_header *);
1454 sc = ifp->if_bridge;
1455
1456 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1457 if (memcmp(etherbroadcastaddr,
1458 eh->ether_dhost, ETHER_ADDR_LEN) == 0)
1459 m->m_flags |= M_BCAST;
1460 else
1461 m->m_flags |= M_MCAST;
1462 }
1463
1464 /*
1465 * If bridge is down, but the original output interface is up,
1466 * go ahead and send out that interface. Otherwise, the packet
1467 * is dropped below.
1468 */
1469 if (__predict_false(sc == NULL) ||
1470 (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1471 dst_if = ifp;
1472 goto sendunicast;
1473 }
1474
1475 /*
1476 * If the packet is a multicast, or we don't know a better way to
1477 * get there, send to all interfaces.
1478 */
1479 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0)
1480 dst_if = NULL;
1481 else
1482 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1483 if (dst_if == NULL) {
1484 /* XXX Should call bridge_broadcast, but there are locking
1485 * issues which need resolving first. */
1486 struct bridge_iflist *bif;
1487 struct mbuf *mc;
1488 bool used = false;
1489
1490 BRIDGE_PSZ_RENTER(s);
1491 BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
1492 struct psref psref;
1493
1494 bridge_acquire_member(sc, bif, &psref);
1495 BRIDGE_PSZ_REXIT(s);
1496
1497 dst_if = bif->bif_ifp;
1498 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1499 goto next;
1500
1501 /*
1502 * If this is not the original output interface,
1503 * and the interface is participating in spanning
1504 * tree, make sure the port is in a state that
1505 * allows forwarding.
1506 */
1507 if (dst_if != ifp &&
1508 (bif->bif_flags & IFBIF_STP) != 0) {
1509 switch (bif->bif_state) {
1510 case BSTP_IFSTATE_BLOCKING:
1511 case BSTP_IFSTATE_LISTENING:
1512 case BSTP_IFSTATE_DISABLED:
1513 goto next;
1514 }
1515 }
1516
1517 if (PSLIST_READER_NEXT(bif, struct bridge_iflist,
1518 bif_next) == NULL &&
1519 ((m->m_flags & (M_MCAST | M_BCAST)) == 0 ||
1520 dst_if == ifp))
1521 {
1522 used = true;
1523 mc = m;
1524 } else {
1525 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
1526 if (mc == NULL) {
1527 sc->sc_if.if_oerrors++;
1528 goto next;
1529 }
1530 }
1531
1532 bridge_enqueue(sc, dst_if, mc, 0);
1533
1534 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0 &&
1535 dst_if != ifp)
1536 {
1537 if (PSLIST_READER_NEXT(bif,
1538 struct bridge_iflist, bif_next) == NULL)
1539 {
1540 used = true;
1541 mc = m;
1542 } else {
1543 mc = m_copym(m, 0, M_COPYALL,
1544 M_DONTWAIT);
1545 if (mc == NULL) {
1546 sc->sc_if.if_oerrors++;
1547 goto next;
1548 }
1549 }
1550
1551 m_set_rcvif(mc, dst_if);
1552 mc->m_flags &= ~M_PROMISC;
1553
1554 #ifndef NET_MPSAFE
1555 s = splsoftnet();
1556 #endif
1557 ether_input(dst_if, mc);
1558 #ifndef NET_MPSAFE
1559 splx(s);
1560 #endif
1561 }
1562
1563 next:
1564 BRIDGE_PSZ_RENTER(s);
1565 bridge_release_member(sc, bif, &psref);
1566
1567 /* Guarantee we don't re-enter the loop as we already
1568 * decided we're at the end. */
1569 if (used)
1570 break;
1571 }
1572 BRIDGE_PSZ_REXIT(s);
1573
1574 if (!used)
1575 m_freem(m);
1576 return 0;
1577 }
1578
1579 sendunicast:
1580 /*
1581 * XXX Spanning tree consideration here?
1582 */
1583
1584 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1585 m_freem(m);
1586 return 0;
1587 }
1588
1589 bridge_enqueue(sc, dst_if, m, 0);
1590
1591 return 0;
1592 }
1593
1594 /*
1595 * bridge_start:
1596 *
1597 * Start output on a bridge.
1598 *
1599 * NOTE: This routine should never be called in this implementation.
1600 */
1601 static void
1602 bridge_start(struct ifnet *ifp)
1603 {
1604
1605 printf("%s: bridge_start() called\n", ifp->if_xname);
1606 }
1607
1608 /*
1609 * bridge_forward:
1610 *
1611 * The forwarding function of the bridge.
1612 */
1613 static void
1614 bridge_forward(struct bridge_softc *sc, struct mbuf *m)
1615 {
1616 struct bridge_iflist *bif;
1617 struct ifnet *src_if, *dst_if;
1618 struct ether_header *eh;
1619 struct psref psref;
1620 struct psref psref_src;
1621 DECLARE_LOCK_VARIABLE;
1622
1623 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
1624 return;
1625
1626 src_if = m_get_rcvif_psref(m, &psref_src);
1627 if (src_if == NULL) {
1628 /* Interface is being destroyed? */
1629 m_freem(m);
1630 goto out;
1631 }
1632
1633 sc->sc_if.if_ipackets++;
1634 sc->sc_if.if_ibytes += m->m_pkthdr.len;
1635
1636 /*
1637 * Look up the bridge_iflist.
1638 */
1639 bif = bridge_lookup_member_if(sc, src_if, &psref);
1640 if (bif == NULL) {
1641 /* Interface is not a bridge member (anymore?) */
1642 m_freem(m);
1643 goto out;
1644 }
1645
1646 if (bif->bif_flags & IFBIF_STP) {
1647 switch (bif->bif_state) {
1648 case BSTP_IFSTATE_BLOCKING:
1649 case BSTP_IFSTATE_LISTENING:
1650 case BSTP_IFSTATE_DISABLED:
1651 m_freem(m);
1652 bridge_release_member(sc, bif, &psref);
1653 goto out;
1654 }
1655 }
1656
1657 eh = mtod(m, struct ether_header *);
1658
1659 /*
1660 * If the interface is learning, and the source
1661 * address is valid and not multicast, record
1662 * the address.
1663 */
1664 if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1665 ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
1666 (eh->ether_shost[0] == 0 &&
1667 eh->ether_shost[1] == 0 &&
1668 eh->ether_shost[2] == 0 &&
1669 eh->ether_shost[3] == 0 &&
1670 eh->ether_shost[4] == 0 &&
1671 eh->ether_shost[5] == 0) == 0) {
1672 (void) bridge_rtupdate(sc, eh->ether_shost,
1673 src_if, 0, IFBAF_DYNAMIC);
1674 }
1675
1676 if ((bif->bif_flags & IFBIF_STP) != 0 &&
1677 bif->bif_state == BSTP_IFSTATE_LEARNING) {
1678 m_freem(m);
1679 bridge_release_member(sc, bif, &psref);
1680 goto out;
1681 }
1682
1683 bridge_release_member(sc, bif, &psref);
1684
1685 /*
1686 * At this point, the port either doesn't participate
1687 * in spanning tree or it is in the forwarding state.
1688 */
1689
1690 /*
1691 * If the packet is unicast, destined for someone on
1692 * "this" side of the bridge, drop it.
1693 */
1694 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1695 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1696 if (src_if == dst_if) {
1697 m_freem(m);
1698 goto out;
1699 }
1700 } else {
1701 /* ...forward it to all interfaces. */
1702 sc->sc_if.if_imcasts++;
1703 dst_if = NULL;
1704 }
1705
1706 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, src_if, PFIL_IN) != 0) {
1707 if (m != NULL)
1708 m_freem(m);
1709 goto out;
1710 }
1711 if (m == NULL)
1712 goto out;
1713
1714 if (dst_if == NULL) {
1715 bridge_broadcast(sc, src_if, m);
1716 goto out;
1717 }
1718
1719 m_put_rcvif_psref(src_if, &psref_src);
1720 src_if = NULL;
1721
1722 /*
1723 * At this point, we're dealing with a unicast frame
1724 * going to a different interface.
1725 */
1726 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1727 m_freem(m);
1728 goto out;
1729 }
1730
1731 bif = bridge_lookup_member_if(sc, dst_if, &psref);
1732 if (bif == NULL) {
1733 /* Not a member of the bridge (anymore?) */
1734 m_freem(m);
1735 goto out;
1736 }
1737
1738 if (bif->bif_flags & IFBIF_STP) {
1739 switch (bif->bif_state) {
1740 case BSTP_IFSTATE_DISABLED:
1741 case BSTP_IFSTATE_BLOCKING:
1742 m_freem(m);
1743 bridge_release_member(sc, bif, &psref);
1744 goto out;
1745 }
1746 }
1747
1748 bridge_release_member(sc, bif, &psref);
1749
1750 ACQUIRE_GLOBAL_LOCKS();
1751 bridge_enqueue(sc, dst_if, m, 1);
1752 RELEASE_GLOBAL_LOCKS();
1753 out:
1754 if (src_if != NULL)
1755 m_put_rcvif_psref(src_if, &psref_src);
1756 return;
1757 }
1758
1759 static bool
1760 bstp_state_before_learning(struct bridge_iflist *bif)
1761 {
1762 if (bif->bif_flags & IFBIF_STP) {
1763 switch (bif->bif_state) {
1764 case BSTP_IFSTATE_BLOCKING:
1765 case BSTP_IFSTATE_LISTENING:
1766 case BSTP_IFSTATE_DISABLED:
1767 return true;
1768 }
1769 }
1770 return false;
1771 }
1772
1773 static bool
1774 bridge_ourether(struct bridge_iflist *bif, struct ether_header *eh, int src)
1775 {
1776 uint8_t *ether = src ? eh->ether_shost : eh->ether_dhost;
1777
1778 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), ether, ETHER_ADDR_LEN) == 0
1779 #if NCARP > 0
1780 || (bif->bif_ifp->if_carp &&
1781 carp_ourether(bif->bif_ifp->if_carp, eh, IFT_ETHER, src) != NULL)
1782 #endif /* NCARP > 0 */
1783 )
1784 return true;
1785
1786 return false;
1787 }
1788
1789 /*
1790 * bridge_input:
1791 *
1792 * Receive input from a member interface. Queue the packet for
1793 * bridging if it is not for us.
1794 */
1795 static void
1796 bridge_input(struct ifnet *ifp, struct mbuf *m)
1797 {
1798 struct bridge_softc *sc = ifp->if_bridge;
1799 struct bridge_iflist *bif;
1800 struct ether_header *eh;
1801 struct psref psref;
1802 int bound;
1803 DECLARE_LOCK_VARIABLE;
1804
1805 KASSERT(!cpu_intr_p());
1806
1807 if (__predict_false(sc == NULL) ||
1808 (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1809 ACQUIRE_GLOBAL_LOCKS();
1810 ether_input(ifp, m);
1811 RELEASE_GLOBAL_LOCKS();
1812 return;
1813 }
1814
1815 bound = curlwp_bind();
1816 bif = bridge_lookup_member_if(sc, ifp, &psref);
1817 if (bif == NULL) {
1818 curlwp_bindx(bound);
1819 ACQUIRE_GLOBAL_LOCKS();
1820 ether_input(ifp, m);
1821 RELEASE_GLOBAL_LOCKS();
1822 return;
1823 }
1824
1825 eh = mtod(m, struct ether_header *);
1826
1827 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1828 if (memcmp(etherbroadcastaddr,
1829 eh->ether_dhost, ETHER_ADDR_LEN) == 0)
1830 m->m_flags |= M_BCAST;
1831 else
1832 m->m_flags |= M_MCAST;
1833 }
1834
1835 /*
1836 * A 'fast' path for packets addressed to interfaces that are
1837 * part of this bridge.
1838 */
1839 if (!(m->m_flags & (M_BCAST|M_MCAST)) &&
1840 !bstp_state_before_learning(bif)) {
1841 struct bridge_iflist *_bif;
1842 struct ifnet *_ifp = NULL;
1843 int s;
1844 struct psref _psref;
1845
1846 BRIDGE_PSZ_RENTER(s);
1847 BRIDGE_IFLIST_READER_FOREACH(_bif, sc) {
1848 /* It is destined for us. */
1849 if (bridge_ourether(_bif, eh, 0)) {
1850 bridge_acquire_member(sc, _bif, &_psref);
1851 BRIDGE_PSZ_REXIT(s);
1852 if (_bif->bif_flags & IFBIF_LEARNING)
1853 (void) bridge_rtupdate(sc,
1854 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1855 m_set_rcvif(m, _bif->bif_ifp);
1856 _ifp = _bif->bif_ifp;
1857 bridge_release_member(sc, _bif, &_psref);
1858 goto out;
1859 }
1860
1861 /* We just received a packet that we sent out. */
1862 if (bridge_ourether(_bif, eh, 1))
1863 break;
1864 }
1865 BRIDGE_PSZ_REXIT(s);
1866 out:
1867
1868 if (_bif != NULL) {
1869 bridge_release_member(sc, bif, &psref);
1870 curlwp_bindx(bound);
1871 if (_ifp != NULL) {
1872 m->m_flags &= ~M_PROMISC;
1873 ACQUIRE_GLOBAL_LOCKS();
1874 ether_input(_ifp, m);
1875 RELEASE_GLOBAL_LOCKS();
1876 } else
1877 m_freem(m);
1878 return;
1879 }
1880 }
1881
1882 /* Tap off 802.1D packets; they do not get forwarded. */
1883 if (bif->bif_flags & IFBIF_STP &&
1884 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
1885 bstp_input(sc, bif, m);
1886 bridge_release_member(sc, bif, &psref);
1887 curlwp_bindx(bound);
1888 return;
1889 }
1890
1891 /*
1892 * A normal switch would discard the packet here, but that's not what
1893 * we've done historically. This also prevents some obnoxious behaviour.
1894 */
1895 if (bstp_state_before_learning(bif)) {
1896 bridge_release_member(sc, bif, &psref);
1897 curlwp_bindx(bound);
1898 ACQUIRE_GLOBAL_LOCKS();
1899 ether_input(ifp, m);
1900 RELEASE_GLOBAL_LOCKS();
1901 return;
1902 }
1903
1904 bridge_release_member(sc, bif, &psref);
1905
1906 bridge_forward(sc, m);
1907
1908 curlwp_bindx(bound);
1909 }
1910
1911 /*
1912 * bridge_broadcast:
1913 *
1914 * Send a frame to all interfaces that are members of
1915 * the bridge, except for the one on which the packet
1916 * arrived.
1917 */
1918 static void
1919 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1920 struct mbuf *m)
1921 {
1922 struct bridge_iflist *bif;
1923 struct mbuf *mc;
1924 struct ifnet *dst_if;
1925 bool bmcast;
1926 int s;
1927 DECLARE_LOCK_VARIABLE;
1928
1929 bmcast = m->m_flags & (M_BCAST|M_MCAST);
1930
1931 BRIDGE_PSZ_RENTER(s);
1932 BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
1933 struct psref psref;
1934
1935 bridge_acquire_member(sc, bif, &psref);
1936 BRIDGE_PSZ_REXIT(s);
1937
1938 dst_if = bif->bif_ifp;
1939
1940 if (bif->bif_flags & IFBIF_STP) {
1941 switch (bif->bif_state) {
1942 case BSTP_IFSTATE_BLOCKING:
1943 case BSTP_IFSTATE_DISABLED:
1944 goto next;
1945 }
1946 }
1947
1948 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast)
1949 goto next;
1950
1951 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1952 goto next;
1953
1954 if (dst_if != src_if) {
1955 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1956 if (mc == NULL) {
1957 sc->sc_if.if_oerrors++;
1958 goto next;
1959 }
1960 ACQUIRE_GLOBAL_LOCKS();
1961 bridge_enqueue(sc, dst_if, mc, 1);
1962 RELEASE_GLOBAL_LOCKS();
1963 }
1964
1965 if (bmcast) {
1966 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1967 if (mc == NULL) {
1968 sc->sc_if.if_oerrors++;
1969 goto next;
1970 }
1971
1972 m_set_rcvif(mc, dst_if);
1973 mc->m_flags &= ~M_PROMISC;
1974
1975 ACQUIRE_GLOBAL_LOCKS();
1976 ether_input(dst_if, mc);
1977 RELEASE_GLOBAL_LOCKS();
1978 }
1979 next:
1980 BRIDGE_PSZ_RENTER(s);
1981 bridge_release_member(sc, bif, &psref);
1982 }
1983 BRIDGE_PSZ_REXIT(s);
1984
1985 m_freem(m);
1986 }
1987
1988 static int
1989 bridge_rtalloc(struct bridge_softc *sc, const uint8_t *dst,
1990 struct bridge_rtnode **brtp)
1991 {
1992 struct bridge_rtnode *brt;
1993 int error;
1994
1995 if (sc->sc_brtcnt >= sc->sc_brtmax)
1996 return ENOSPC;
1997
1998 /*
1999 * Allocate a new bridge forwarding node, and
2000 * initialize the expiration time and Ethernet
2001 * address.
2002 */
2003 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT);
2004 if (brt == NULL)
2005 return ENOMEM;
2006
2007 memset(brt, 0, sizeof(*brt));
2008 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2009 brt->brt_flags = IFBAF_DYNAMIC;
2010 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
2011
2012 BRIDGE_RT_LOCK(sc);
2013 error = bridge_rtnode_insert(sc, brt);
2014 BRIDGE_RT_UNLOCK(sc);
2015
2016 if (error != 0) {
2017 pool_put(&bridge_rtnode_pool, brt);
2018 return error;
2019 }
2020
2021 *brtp = brt;
2022 return 0;
2023 }
2024
2025 /*
2026 * bridge_rtupdate:
2027 *
2028 * Add a bridge routing entry.
2029 */
2030 static int
2031 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
2032 struct ifnet *dst_if, int setflags, uint8_t flags)
2033 {
2034 struct bridge_rtnode *brt;
2035 int s;
2036
2037 again:
2038 /*
2039 * A route for this destination might already exist. If so,
2040 * update it, otherwise create a new one.
2041 */
2042 BRIDGE_RT_RENTER(s);
2043 brt = bridge_rtnode_lookup(sc, dst);
2044
2045 if (brt != NULL) {
2046 brt->brt_ifp = dst_if;
2047 if (setflags) {
2048 brt->brt_flags = flags;
2049 if (flags & IFBAF_STATIC)
2050 brt->brt_expire = 0;
2051 else
2052 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2053 } else {
2054 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2055 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2056 }
2057 }
2058 BRIDGE_RT_REXIT(s);
2059
2060 if (brt == NULL) {
2061 int r;
2062
2063 r = bridge_rtalloc(sc, dst, &brt);
2064 if (r != 0)
2065 return r;
2066 goto again;
2067 }
2068
2069 return 0;
2070 }
2071
2072 /*
2073 * bridge_rtlookup:
2074 *
2075 * Lookup the destination interface for an address.
2076 */
2077 static struct ifnet *
2078 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
2079 {
2080 struct bridge_rtnode *brt;
2081 struct ifnet *ifs = NULL;
2082 int s;
2083
2084 BRIDGE_RT_RENTER(s);
2085 brt = bridge_rtnode_lookup(sc, addr);
2086 if (brt != NULL)
2087 ifs = brt->brt_ifp;
2088 BRIDGE_RT_REXIT(s);
2089
2090 return ifs;
2091 }
2092
2093 typedef bool (*bridge_iterate_cb_t)
2094 (struct bridge_softc *, struct bridge_rtnode *, bool *, void *);
2095
2096 /*
2097 * bridge_rtlist_iterate_remove:
2098 *
2099 * It iterates on sc->sc_rtlist and removes rtnodes of it which func
2100 * callback judges to remove. Removals of rtnodes are done in a manner
2101 * of pserialize. To this end, all kmem_* operations are placed out of
2102 * mutexes.
2103 */
2104 static void
2105 bridge_rtlist_iterate_remove(struct bridge_softc *sc, bridge_iterate_cb_t func, void *arg)
2106 {
2107 struct bridge_rtnode *brt, *nbrt;
2108 struct bridge_rtnode **brt_list;
2109 int i, count;
2110
2111 retry:
2112 count = sc->sc_brtcnt;
2113 if (count == 0)
2114 return;
2115 brt_list = kmem_alloc(sizeof(*brt_list) * count, KM_SLEEP);
2116
2117 BRIDGE_RT_LOCK(sc);
2118 if (__predict_false(sc->sc_brtcnt > count)) {
2119 /* The rtnodes increased, we need more memory */
2120 BRIDGE_RT_UNLOCK(sc);
2121 kmem_free(brt_list, sizeof(*brt_list) * count);
2122 goto retry;
2123 }
2124
2125 i = 0;
2126 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2127 bool need_break = false;
2128 if (func(sc, brt, &need_break, arg)) {
2129 bridge_rtnode_remove(sc, brt);
2130 brt_list[i++] = brt;
2131 }
2132 if (need_break)
2133 break;
2134 }
2135
2136 if (i > 0)
2137 BRIDGE_RT_PSZ_PERFORM(sc);
2138 BRIDGE_RT_UNLOCK(sc);
2139
2140 while (--i >= 0)
2141 bridge_rtnode_destroy(brt_list[i]);
2142
2143 kmem_free(brt_list, sizeof(*brt_list) * count);
2144 }
2145
2146 static bool
2147 bridge_rttrim0_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2148 bool *need_break, void *arg)
2149 {
2150 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2151 /* Take into account of the subsequent removal */
2152 if ((sc->sc_brtcnt - 1) <= sc->sc_brtmax)
2153 *need_break = true;
2154 return true;
2155 } else
2156 return false;
2157 }
2158
2159 static void
2160 bridge_rttrim0(struct bridge_softc *sc)
2161 {
2162 bridge_rtlist_iterate_remove(sc, bridge_rttrim0_cb, NULL);
2163 }
2164
2165 /*
2166 * bridge_rttrim:
2167 *
2168 * Trim the routine table so that we have a number
2169 * of routing entries less than or equal to the
2170 * maximum number.
2171 */
2172 static void
2173 bridge_rttrim(struct bridge_softc *sc)
2174 {
2175
2176 /* Make sure we actually need to do this. */
2177 if (sc->sc_brtcnt <= sc->sc_brtmax)
2178 return;
2179
2180 /* Force an aging cycle; this might trim enough addresses. */
2181 bridge_rtage(sc);
2182 if (sc->sc_brtcnt <= sc->sc_brtmax)
2183 return;
2184
2185 bridge_rttrim0(sc);
2186
2187 return;
2188 }
2189
2190 /*
2191 * bridge_timer:
2192 *
2193 * Aging timer for the bridge.
2194 */
2195 static void
2196 bridge_timer(void *arg)
2197 {
2198 struct bridge_softc *sc = arg;
2199
2200 workqueue_enqueue(sc->sc_rtage_wq, &sc->sc_rtage_wk, NULL);
2201 }
2202
2203 static void
2204 bridge_rtage_work(struct work *wk, void *arg)
2205 {
2206 struct bridge_softc *sc = arg;
2207
2208 KASSERT(wk == &sc->sc_rtage_wk);
2209
2210 bridge_rtage(sc);
2211
2212 if (sc->sc_if.if_flags & IFF_RUNNING)
2213 callout_reset(&sc->sc_brcallout,
2214 bridge_rtable_prune_period * hz, bridge_timer, sc);
2215 }
2216
2217 static bool
2218 bridge_rtage_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2219 bool *need_break, void *arg)
2220 {
2221 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
2222 time_uptime >= brt->brt_expire)
2223 return true;
2224 else
2225 return false;
2226 }
2227
2228 /*
2229 * bridge_rtage:
2230 *
2231 * Perform an aging cycle.
2232 */
2233 static void
2234 bridge_rtage(struct bridge_softc *sc)
2235 {
2236 bridge_rtlist_iterate_remove(sc, bridge_rtage_cb, NULL);
2237 }
2238
2239
2240 static bool
2241 bridge_rtflush_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2242 bool *need_break, void *arg)
2243 {
2244 int full = *(int*)arg;
2245
2246 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2247 return true;
2248 else
2249 return false;
2250 }
2251
2252 /*
2253 * bridge_rtflush:
2254 *
2255 * Remove all dynamic addresses from the bridge.
2256 */
2257 static void
2258 bridge_rtflush(struct bridge_softc *sc, int full)
2259 {
2260 bridge_rtlist_iterate_remove(sc, bridge_rtflush_cb, &full);
2261 }
2262
2263 /*
2264 * bridge_rtdaddr:
2265 *
2266 * Remove an address from the table.
2267 */
2268 static int
2269 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
2270 {
2271 struct bridge_rtnode *brt;
2272
2273 BRIDGE_RT_LOCK(sc);
2274 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) {
2275 BRIDGE_RT_UNLOCK(sc);
2276 return ENOENT;
2277 }
2278 bridge_rtnode_remove(sc, brt);
2279 BRIDGE_RT_PSZ_PERFORM(sc);
2280 BRIDGE_RT_UNLOCK(sc);
2281
2282 bridge_rtnode_destroy(brt);
2283
2284 return 0;
2285 }
2286
2287 /*
2288 * bridge_rtdelete:
2289 *
2290 * Delete routes to a speicifc member interface.
2291 */
2292 static void
2293 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
2294 {
2295 struct bridge_rtnode *brt;
2296
2297 BRIDGE_RT_LOCK(sc);
2298 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
2299 if (brt->brt_ifp == ifp)
2300 break;
2301 }
2302 if (brt == NULL) {
2303 BRIDGE_RT_UNLOCK(sc);
2304 return;
2305 }
2306 bridge_rtnode_remove(sc, brt);
2307 BRIDGE_RT_PSZ_PERFORM(sc);
2308 BRIDGE_RT_UNLOCK(sc);
2309
2310 bridge_rtnode_destroy(brt);
2311 }
2312
2313 /*
2314 * bridge_rtable_init:
2315 *
2316 * Initialize the route table for this bridge.
2317 */
2318 static void
2319 bridge_rtable_init(struct bridge_softc *sc)
2320 {
2321 int i;
2322
2323 sc->sc_rthash = kmem_alloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
2324 KM_SLEEP);
2325
2326 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
2327 LIST_INIT(&sc->sc_rthash[i]);
2328
2329 sc->sc_rthash_key = cprng_fast32();
2330
2331 LIST_INIT(&sc->sc_rtlist);
2332
2333 sc->sc_rtlist_psz = pserialize_create();
2334 sc->sc_rtlist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
2335 }
2336
2337 /*
2338 * bridge_rtable_fini:
2339 *
2340 * Deconstruct the route table for this bridge.
2341 */
2342 static void
2343 bridge_rtable_fini(struct bridge_softc *sc)
2344 {
2345
2346 kmem_free(sc->sc_rthash, sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE);
2347 if (sc->sc_rtlist_lock)
2348 mutex_obj_free(sc->sc_rtlist_lock);
2349 if (sc->sc_rtlist_psz)
2350 pserialize_destroy(sc->sc_rtlist_psz);
2351 }
2352
2353 /*
2354 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2355 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2356 */
2357 #define mix(a, b, c) \
2358 do { \
2359 a -= b; a -= c; a ^= (c >> 13); \
2360 b -= c; b -= a; b ^= (a << 8); \
2361 c -= a; c -= b; c ^= (b >> 13); \
2362 a -= b; a -= c; a ^= (c >> 12); \
2363 b -= c; b -= a; b ^= (a << 16); \
2364 c -= a; c -= b; c ^= (b >> 5); \
2365 a -= b; a -= c; a ^= (c >> 3); \
2366 b -= c; b -= a; b ^= (a << 10); \
2367 c -= a; c -= b; c ^= (b >> 15); \
2368 } while (/*CONSTCOND*/0)
2369
2370 static inline uint32_t
2371 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
2372 {
2373 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
2374
2375 b += addr[5] << 8;
2376 b += addr[4];
2377 a += addr[3] << 24;
2378 a += addr[2] << 16;
2379 a += addr[1] << 8;
2380 a += addr[0];
2381
2382 mix(a, b, c);
2383
2384 return (c & BRIDGE_RTHASH_MASK);
2385 }
2386
2387 #undef mix
2388
2389 /*
2390 * bridge_rtnode_lookup:
2391 *
2392 * Look up a bridge route node for the specified destination.
2393 */
2394 static struct bridge_rtnode *
2395 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
2396 {
2397 struct bridge_rtnode *brt;
2398 uint32_t hash;
2399 int dir;
2400
2401 hash = bridge_rthash(sc, addr);
2402 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
2403 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
2404 if (dir == 0)
2405 return brt;
2406 if (dir > 0)
2407 return NULL;
2408 }
2409
2410 return NULL;
2411 }
2412
2413 /*
2414 * bridge_rtnode_insert:
2415 *
2416 * Insert the specified bridge node into the route table. We
2417 * assume the entry is not already in the table.
2418 */
2419 static int
2420 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
2421 {
2422 struct bridge_rtnode *lbrt;
2423 uint32_t hash;
2424 int dir;
2425
2426 KASSERT(BRIDGE_RT_LOCKED(sc));
2427
2428 hash = bridge_rthash(sc, brt->brt_addr);
2429
2430 lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
2431 if (lbrt == NULL) {
2432 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
2433 goto out;
2434 }
2435
2436 do {
2437 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
2438 if (dir == 0)
2439 return EEXIST;
2440 if (dir > 0) {
2441 LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
2442 goto out;
2443 }
2444 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
2445 LIST_INSERT_AFTER(lbrt, brt, brt_hash);
2446 goto out;
2447 }
2448 lbrt = LIST_NEXT(lbrt, brt_hash);
2449 } while (lbrt != NULL);
2450
2451 #ifdef DIAGNOSTIC
2452 panic("bridge_rtnode_insert: impossible");
2453 #endif
2454
2455 out:
2456 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
2457 sc->sc_brtcnt++;
2458
2459 return 0;
2460 }
2461
2462 /*
2463 * bridge_rtnode_remove:
2464 *
2465 * Remove a bridge rtnode from the rthash and the rtlist of a bridge.
2466 */
2467 static void
2468 bridge_rtnode_remove(struct bridge_softc *sc, struct bridge_rtnode *brt)
2469 {
2470
2471 KASSERT(BRIDGE_RT_LOCKED(sc));
2472
2473 LIST_REMOVE(brt, brt_hash);
2474 LIST_REMOVE(brt, brt_list);
2475 sc->sc_brtcnt--;
2476 }
2477
2478 /*
2479 * bridge_rtnode_destroy:
2480 *
2481 * Destroy a bridge rtnode.
2482 */
2483 static void
2484 bridge_rtnode_destroy(struct bridge_rtnode *brt)
2485 {
2486
2487 pool_put(&bridge_rtnode_pool, brt);
2488 }
2489
2490 #if defined(BRIDGE_IPF)
2491 extern pfil_head_t *inet_pfil_hook; /* XXX */
2492 extern pfil_head_t *inet6_pfil_hook; /* XXX */
2493
2494 /*
2495 * Send bridge packets through IPF if they are one of the types IPF can deal
2496 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without
2497 * question.)
2498 */
2499 static int
2500 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
2501 {
2502 int snap, error;
2503 struct ether_header *eh1, eh2;
2504 struct llc llc1;
2505 uint16_t ether_type;
2506
2507 snap = 0;
2508 error = -1; /* Default error if not error == 0 */
2509 eh1 = mtod(*mp, struct ether_header *);
2510 ether_type = ntohs(eh1->ether_type);
2511
2512 /*
2513 * Check for SNAP/LLC.
2514 */
2515 if (ether_type < ETHERMTU) {
2516 struct llc *llc2 = (struct llc *)(eh1 + 1);
2517
2518 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
2519 llc2->llc_dsap == LLC_SNAP_LSAP &&
2520 llc2->llc_ssap == LLC_SNAP_LSAP &&
2521 llc2->llc_control == LLC_UI) {
2522 ether_type = htons(llc2->llc_un.type_snap.ether_type);
2523 snap = 1;
2524 }
2525 }
2526
2527 /*
2528 * If we're trying to filter bridge traffic, don't look at anything
2529 * other than IP and ARP traffic. If the filter doesn't understand
2530 * IPv6, don't allow IPv6 through the bridge either. This is lame
2531 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2532 * but of course we don't have an AppleTalk filter to begin with.
2533 * (Note that since IPF doesn't understand ARP it will pass *ALL*
2534 * ARP traffic.)
2535 */
2536 switch (ether_type) {
2537 case ETHERTYPE_ARP:
2538 case ETHERTYPE_REVARP:
2539 return 0; /* Automatically pass */
2540 case ETHERTYPE_IP:
2541 # ifdef INET6
2542 case ETHERTYPE_IPV6:
2543 # endif /* INET6 */
2544 break;
2545 default:
2546 goto bad;
2547 }
2548
2549 /* Strip off the Ethernet header and keep a copy. */
2550 m_copydata(*mp, 0, ETHER_HDR_LEN, (void *) &eh2);
2551 m_adj(*mp, ETHER_HDR_LEN);
2552
2553 /* Strip off snap header, if present */
2554 if (snap) {
2555 m_copydata(*mp, 0, sizeof(struct llc), (void *) &llc1);
2556 m_adj(*mp, sizeof(struct llc));
2557 }
2558
2559 /*
2560 * Check basic packet sanity and run IPF through pfil.
2561 */
2562 KASSERT(!cpu_intr_p());
2563 switch (ether_type)
2564 {
2565 case ETHERTYPE_IP :
2566 error = bridge_ip_checkbasic(mp);
2567 if (error == 0)
2568 error = pfil_run_hooks(inet_pfil_hook, mp, ifp, dir);
2569 break;
2570 # ifdef INET6
2571 case ETHERTYPE_IPV6 :
2572 error = bridge_ip6_checkbasic(mp);
2573 if (error == 0)
2574 error = pfil_run_hooks(inet6_pfil_hook, mp, ifp, dir);
2575 break;
2576 # endif
2577 default :
2578 error = 0;
2579 break;
2580 }
2581
2582 if (*mp == NULL)
2583 return error;
2584 if (error != 0)
2585 goto bad;
2586
2587 error = -1;
2588
2589 /*
2590 * Finally, put everything back the way it was and return
2591 */
2592 if (snap) {
2593 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2594 if (*mp == NULL)
2595 return error;
2596 bcopy(&llc1, mtod(*mp, void *), sizeof(struct llc));
2597 }
2598
2599 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2600 if (*mp == NULL)
2601 return error;
2602 bcopy(&eh2, mtod(*mp, void *), ETHER_HDR_LEN);
2603
2604 return 0;
2605
2606 bad:
2607 m_freem(*mp);
2608 *mp = NULL;
2609 return error;
2610 }
2611
2612 /*
2613 * Perform basic checks on header size since
2614 * IPF assumes ip_input has already processed
2615 * it for it. Cut-and-pasted from ip_input.c.
2616 * Given how simple the IPv6 version is,
2617 * does the IPv4 version really need to be
2618 * this complicated?
2619 *
2620 * XXX Should we update ipstat here, or not?
2621 * XXX Right now we update ipstat but not
2622 * XXX csum_counter.
2623 */
2624 static int
2625 bridge_ip_checkbasic(struct mbuf **mp)
2626 {
2627 struct mbuf *m = *mp;
2628 struct ip *ip;
2629 int len, hlen;
2630
2631 if (*mp == NULL)
2632 return -1;
2633
2634 if (IP_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
2635 if ((m = m_copyup(m, sizeof(struct ip),
2636 (max_linkhdr + 3) & ~3)) == NULL) {
2637 /* XXXJRT new stat, please */
2638 ip_statinc(IP_STAT_TOOSMALL);
2639 goto bad;
2640 }
2641 } else if (__predict_false(m->m_len < sizeof (struct ip))) {
2642 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2643 ip_statinc(IP_STAT_TOOSMALL);
2644 goto bad;
2645 }
2646 }
2647 ip = mtod(m, struct ip *);
2648 if (ip == NULL) goto bad;
2649
2650 if (ip->ip_v != IPVERSION) {
2651 ip_statinc(IP_STAT_BADVERS);
2652 goto bad;
2653 }
2654 hlen = ip->ip_hl << 2;
2655 if (hlen < sizeof(struct ip)) { /* minimum header length */
2656 ip_statinc(IP_STAT_BADHLEN);
2657 goto bad;
2658 }
2659 if (hlen > m->m_len) {
2660 if ((m = m_pullup(m, hlen)) == 0) {
2661 ip_statinc(IP_STAT_BADHLEN);
2662 goto bad;
2663 }
2664 ip = mtod(m, struct ip *);
2665 if (ip == NULL) goto bad;
2666 }
2667
2668 switch (m->m_pkthdr.csum_flags &
2669 ((m_get_rcvif_NOMPSAFE(m)->if_csum_flags_rx & M_CSUM_IPv4) |
2670 M_CSUM_IPv4_BAD)) {
2671 case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
2672 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */
2673 goto bad;
2674
2675 case M_CSUM_IPv4:
2676 /* Checksum was okay. */
2677 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */
2678 break;
2679
2680 default:
2681 /* Must compute it ourselves. */
2682 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */
2683 if (in_cksum(m, hlen) != 0)
2684 goto bad;
2685 break;
2686 }
2687
2688 /* Retrieve the packet length. */
2689 len = ntohs(ip->ip_len);
2690
2691 /*
2692 * Check for additional length bogosity
2693 */
2694 if (len < hlen) {
2695 ip_statinc(IP_STAT_BADLEN);
2696 goto bad;
2697 }
2698
2699 /*
2700 * Check that the amount of data in the buffers
2701 * is as at least much as the IP header would have us expect.
2702 * Drop packet if shorter than we expect.
2703 */
2704 if (m->m_pkthdr.len < len) {
2705 ip_statinc(IP_STAT_TOOSHORT);
2706 goto bad;
2707 }
2708
2709 /* Checks out, proceed */
2710 *mp = m;
2711 return 0;
2712
2713 bad:
2714 *mp = m;
2715 return -1;
2716 }
2717
2718 # ifdef INET6
2719 /*
2720 * Same as above, but for IPv6.
2721 * Cut-and-pasted from ip6_input.c.
2722 * XXX Should we update ip6stat, or not?
2723 */
2724 static int
2725 bridge_ip6_checkbasic(struct mbuf **mp)
2726 {
2727 struct mbuf *m = *mp;
2728 struct ip6_hdr *ip6;
2729
2730 /*
2731 * If the IPv6 header is not aligned, slurp it up into a new
2732 * mbuf with space for link headers, in the event we forward
2733 * it. Otherwise, if it is aligned, make sure the entire base
2734 * IPv6 header is in the first mbuf of the chain.
2735 */
2736 if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
2737 struct ifnet *inifp = m_get_rcvif_NOMPSAFE(m);
2738 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2739 (max_linkhdr + 3) & ~3)) == NULL) {
2740 /* XXXJRT new stat, please */
2741 ip6_statinc(IP6_STAT_TOOSMALL);
2742 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2743 goto bad;
2744 }
2745 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2746 struct ifnet *inifp = m_get_rcvif_NOMPSAFE(m);
2747 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2748 ip6_statinc(IP6_STAT_TOOSMALL);
2749 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2750 goto bad;
2751 }
2752 }
2753
2754 ip6 = mtod(m, struct ip6_hdr *);
2755
2756 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2757 ip6_statinc(IP6_STAT_BADVERS);
2758 in6_ifstat_inc(m_get_rcvif_NOMPSAFE(m), ifs6_in_hdrerr);
2759 goto bad;
2760 }
2761
2762 /* Checks out, proceed */
2763 *mp = m;
2764 return 0;
2765
2766 bad:
2767 *mp = m;
2768 return -1;
2769 }
2770 # endif /* INET6 */
2771 #endif /* BRIDGE_IPF */
2772