if_bridge.c revision 1.86 1 /* $NetBSD: if_bridge.c,v 1.86 2014/07/02 09:51:08 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.86 2014/07/02 09:51:08 ozaki-r Exp $");
84
85 #ifdef _KERNEL_OPT
86 #include "opt_bridge_ipf.h"
87 #include "opt_inet.h"
88 #endif /* _KERNEL_OPT */
89
90 #include <sys/param.h>
91 #include <sys/kernel.h>
92 #include <sys/mbuf.h>
93 #include <sys/queue.h>
94 #include <sys/socket.h>
95 #include <sys/socketvar.h> /* for softnet_lock */
96 #include <sys/sockio.h>
97 #include <sys/systm.h>
98 #include <sys/proc.h>
99 #include <sys/pool.h>
100 #include <sys/kauth.h>
101 #include <sys/cpu.h>
102 #include <sys/cprng.h>
103 #include <sys/mutex.h>
104
105 #include <net/bpf.h>
106 #include <net/if.h>
107 #include <net/if_dl.h>
108 #include <net/if_types.h>
109 #include <net/if_llc.h>
110 #include <net/pktqueue.h>
111
112 #include <net/if_ether.h>
113 #include <net/if_bridgevar.h>
114
115 #if defined(BRIDGE_IPF)
116 /* Used for bridge_ip[6]_checkbasic */
117 #include <netinet/in.h>
118 #include <netinet/in_systm.h>
119 #include <netinet/ip.h>
120 #include <netinet/ip_var.h>
121 #include <netinet/ip_private.h> /* XXX */
122
123 #include <netinet/ip6.h>
124 #include <netinet6/in6_var.h>
125 #include <netinet6/ip6_var.h>
126 #include <netinet6/ip6_private.h> /* XXX */
127 #endif /* BRIDGE_IPF */
128
129 /*
130 * Size of the route hash table. Must be a power of two.
131 */
132 #ifndef BRIDGE_RTHASH_SIZE
133 #define BRIDGE_RTHASH_SIZE 1024
134 #endif
135
136 #define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1)
137
138 #include "carp.h"
139 #if NCARP > 0
140 #include <netinet/in.h>
141 #include <netinet/in_var.h>
142 #include <netinet/ip_carp.h>
143 #endif
144
145 /*
146 * Maximum number of addresses to cache.
147 */
148 #ifndef BRIDGE_RTABLE_MAX
149 #define BRIDGE_RTABLE_MAX 100
150 #endif
151
152 /*
153 * Spanning tree defaults.
154 */
155 #define BSTP_DEFAULT_MAX_AGE (20 * 256)
156 #define BSTP_DEFAULT_HELLO_TIME (2 * 256)
157 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256)
158 #define BSTP_DEFAULT_HOLD_TIME (1 * 256)
159 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000
160 #define BSTP_DEFAULT_PORT_PRIORITY 0x80
161 #define BSTP_DEFAULT_PATH_COST 55
162
163 /*
164 * Timeout (in seconds) for entries learned dynamically.
165 */
166 #ifndef BRIDGE_RTABLE_TIMEOUT
167 #define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */
168 #endif
169
170 /*
171 * Number of seconds between walks of the route list.
172 */
173 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD
174 #define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60)
175 #endif
176
177 int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
178
179 static struct pool bridge_rtnode_pool;
180
181 void bridgeattach(int);
182
183 static int bridge_clone_create(struct if_clone *, int);
184 static int bridge_clone_destroy(struct ifnet *);
185
186 static int bridge_ioctl(struct ifnet *, u_long, void *);
187 static int bridge_init(struct ifnet *);
188 static void bridge_stop(struct ifnet *, int);
189 static void bridge_start(struct ifnet *);
190
191 static void bridge_input(struct ifnet *, struct mbuf *);
192 static void bridge_forward(void *);
193
194 static void bridge_timer(void *);
195
196 static void bridge_broadcast(struct bridge_softc *, struct ifnet *,
197 struct mbuf *);
198
199 static int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
200 struct ifnet *, int, uint8_t);
201 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
202 static void bridge_rttrim(struct bridge_softc *);
203 static void bridge_rtage(struct bridge_softc *);
204 static void bridge_rtflush(struct bridge_softc *, int);
205 static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
206 static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp);
207
208 static int bridge_rtable_init(struct bridge_softc *);
209 static void bridge_rtable_fini(struct bridge_softc *);
210
211 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
212 const uint8_t *);
213 static int bridge_rtnode_insert(struct bridge_softc *,
214 struct bridge_rtnode *);
215 static void bridge_rtnode_destroy(struct bridge_softc *,
216 struct bridge_rtnode *);
217
218 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
219 const char *name);
220 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
221 struct ifnet *ifp);
222 static void bridge_delete_member(struct bridge_softc *,
223 struct bridge_iflist *);
224
225 static int bridge_ioctl_add(struct bridge_softc *, void *);
226 static int bridge_ioctl_del(struct bridge_softc *, void *);
227 static int bridge_ioctl_gifflags(struct bridge_softc *, void *);
228 static int bridge_ioctl_sifflags(struct bridge_softc *, void *);
229 static int bridge_ioctl_scache(struct bridge_softc *, void *);
230 static int bridge_ioctl_gcache(struct bridge_softc *, void *);
231 static int bridge_ioctl_gifs(struct bridge_softc *, void *);
232 static int bridge_ioctl_rts(struct bridge_softc *, void *);
233 static int bridge_ioctl_saddr(struct bridge_softc *, void *);
234 static int bridge_ioctl_sto(struct bridge_softc *, void *);
235 static int bridge_ioctl_gto(struct bridge_softc *, void *);
236 static int bridge_ioctl_daddr(struct bridge_softc *, void *);
237 static int bridge_ioctl_flush(struct bridge_softc *, void *);
238 static int bridge_ioctl_gpri(struct bridge_softc *, void *);
239 static int bridge_ioctl_spri(struct bridge_softc *, void *);
240 static int bridge_ioctl_ght(struct bridge_softc *, void *);
241 static int bridge_ioctl_sht(struct bridge_softc *, void *);
242 static int bridge_ioctl_gfd(struct bridge_softc *, void *);
243 static int bridge_ioctl_sfd(struct bridge_softc *, void *);
244 static int bridge_ioctl_gma(struct bridge_softc *, void *);
245 static int bridge_ioctl_sma(struct bridge_softc *, void *);
246 static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
247 static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
248 #if defined(BRIDGE_IPF)
249 static int bridge_ioctl_gfilt(struct bridge_softc *, void *);
250 static int bridge_ioctl_sfilt(struct bridge_softc *, void *);
251 static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
252 static int bridge_ip_checkbasic(struct mbuf **mp);
253 # ifdef INET6
254 static int bridge_ip6_checkbasic(struct mbuf **mp);
255 # endif /* INET6 */
256 #endif /* BRIDGE_IPF */
257
258 static void bridge_sysctl_fwdq_setup(struct sysctllog **clog,
259 struct bridge_softc *sc);
260
261 struct bridge_control {
262 int (*bc_func)(struct bridge_softc *, void *);
263 int bc_argsize;
264 int bc_flags;
265 };
266
267 #define BC_F_COPYIN 0x01 /* copy arguments in */
268 #define BC_F_COPYOUT 0x02 /* copy arguments out */
269 #define BC_F_SUSER 0x04 /* do super-user check */
270
271 static const struct bridge_control bridge_control_table[] = {
272 [BRDGADD] = {bridge_ioctl_add, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
273 [BRDGDEL] = {bridge_ioctl_del, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
274
275 [BRDGGIFFLGS] = {bridge_ioctl_gifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_COPYOUT},
276 [BRDGSIFFLGS] = {bridge_ioctl_sifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
277
278 [BRDGSCACHE] = {bridge_ioctl_scache, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
279 [BRDGGCACHE] = {bridge_ioctl_gcache, sizeof(struct ifbrparam), BC_F_COPYOUT},
280
281 [BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_COPYIN|BC_F_COPYOUT},
282 [BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_COPYIN|BC_F_COPYOUT},
283
284 [BRDGSADDR] = {bridge_ioctl_saddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
285
286 [BRDGSTO] = {bridge_ioctl_sto, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
287 [BRDGGTO] = {bridge_ioctl_gto, sizeof(struct ifbrparam), BC_F_COPYOUT},
288
289 [BRDGDADDR] = {bridge_ioctl_daddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
290
291 [BRDGFLUSH] = {bridge_ioctl_flush, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
292
293 [BRDGGPRI] = {bridge_ioctl_gpri, sizeof(struct ifbrparam), BC_F_COPYOUT},
294 [BRDGSPRI] = {bridge_ioctl_spri, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
295
296 [BRDGGHT] = {bridge_ioctl_ght, sizeof(struct ifbrparam), BC_F_COPYOUT},
297 [BRDGSHT] = {bridge_ioctl_sht, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
298
299 [BRDGGFD] = {bridge_ioctl_gfd, sizeof(struct ifbrparam), BC_F_COPYOUT},
300 [BRDGSFD] = {bridge_ioctl_sfd, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
301
302 [BRDGGMA] = {bridge_ioctl_gma, sizeof(struct ifbrparam), BC_F_COPYOUT},
303 [BRDGSMA] = {bridge_ioctl_sma, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
304
305 [BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
306
307 [BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
308 #if defined(BRIDGE_IPF)
309 [BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT},
310 [BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
311 #endif /* BRIDGE_IPF */
312 };
313 static const int bridge_control_table_size = __arraycount(bridge_control_table);
314
315 static LIST_HEAD(, bridge_softc) bridge_list;
316 static kmutex_t bridge_list_lock;
317
318 static struct if_clone bridge_cloner =
319 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
320
321 /*
322 * bridgeattach:
323 *
324 * Pseudo-device attach routine.
325 */
326 void
327 bridgeattach(int n)
328 {
329
330 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
331 0, 0, 0, "brtpl", NULL, IPL_NET);
332
333 LIST_INIT(&bridge_list);
334 mutex_init(&bridge_list_lock, MUTEX_DEFAULT, IPL_NET);
335 if_clone_attach(&bridge_cloner);
336 }
337
338 /*
339 * bridge_clone_create:
340 *
341 * Create a new bridge instance.
342 */
343 static int
344 bridge_clone_create(struct if_clone *ifc, int unit)
345 {
346 struct bridge_softc *sc;
347 struct ifnet *ifp;
348
349 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
350 ifp = &sc->sc_if;
351
352 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
353 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
354 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
355 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
356 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
357 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
358 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
359 sc->sc_filter_flags = 0;
360
361 /* Initialize our routing table. */
362 bridge_rtable_init(sc);
363
364 callout_init(&sc->sc_brcallout, 0);
365 callout_init(&sc->sc_bstpcallout, 0);
366
367 LIST_INIT(&sc->sc_iflist);
368
369 if_initname(ifp, ifc->ifc_name, unit);
370 ifp->if_softc = sc;
371 ifp->if_mtu = ETHERMTU;
372 ifp->if_ioctl = bridge_ioctl;
373 ifp->if_output = bridge_output;
374 ifp->if_start = bridge_start;
375 ifp->if_stop = bridge_stop;
376 ifp->if_init = bridge_init;
377 ifp->if_type = IFT_BRIDGE;
378 ifp->if_addrlen = 0;
379 ifp->if_dlt = DLT_EN10MB;
380 ifp->if_hdrlen = ETHER_HDR_LEN;
381
382 sc->sc_fwd_pktq = pktq_create(IFQ_MAXLEN, bridge_forward, sc);
383 KASSERT(sc->sc_fwd_pktq != NULL);
384
385 bridge_sysctl_fwdq_setup(&ifp->if_sysctl_log, sc);
386
387 if_attach(ifp);
388
389 if_alloc_sadl(ifp);
390
391 mutex_enter(&bridge_list_lock);
392 LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
393 mutex_exit(&bridge_list_lock);
394
395 return (0);
396 }
397
398 /*
399 * bridge_clone_destroy:
400 *
401 * Destroy a bridge instance.
402 */
403 static int
404 bridge_clone_destroy(struct ifnet *ifp)
405 {
406 struct bridge_softc *sc = ifp->if_softc;
407 struct bridge_iflist *bif;
408 int s;
409
410 /* Must be called during IFF_RUNNING, i.e., before bridge_stop */
411 pktq_barrier(sc->sc_fwd_pktq);
412
413 s = splnet();
414
415 bridge_stop(ifp, 1);
416
417 while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
418 bridge_delete_member(sc, bif);
419
420 mutex_enter(&bridge_list_lock);
421 LIST_REMOVE(sc, sc_list);
422 mutex_exit(&bridge_list_lock);
423
424 splx(s);
425
426 if_detach(ifp);
427
428 /* Should be called after if_detach for safe */
429 pktq_flush(sc->sc_fwd_pktq);
430 pktq_destroy(sc->sc_fwd_pktq);
431
432 /* Tear down the routing table. */
433 bridge_rtable_fini(sc);
434
435 free(sc, M_DEVBUF);
436
437 return (0);
438 }
439
440 static int
441 bridge_sysctl_fwdq_maxlen(SYSCTLFN_ARGS)
442 {
443 struct sysctlnode node = *rnode;
444 const struct bridge_softc *sc = node.sysctl_data;
445 return sysctl_pktq_maxlen(SYSCTLFN_CALL(rnode), sc->sc_fwd_pktq);
446 }
447
448 #define SYSCTL_BRIDGE_PKTQ(cn, c) \
449 static int \
450 bridge_sysctl_fwdq_##cn(SYSCTLFN_ARGS) \
451 { \
452 struct sysctlnode node = *rnode; \
453 const struct bridge_softc *sc = node.sysctl_data; \
454 return sysctl_pktq_count(SYSCTLFN_CALL(rnode), \
455 sc->sc_fwd_pktq, c); \
456 }
457
458 SYSCTL_BRIDGE_PKTQ(items, PKTQ_NITEMS)
459 SYSCTL_BRIDGE_PKTQ(drops, PKTQ_DROPS)
460
461 static void
462 bridge_sysctl_fwdq_setup(struct sysctllog **clog, struct bridge_softc *sc)
463 {
464 const struct sysctlnode *cnode, *rnode;
465 sysctlfn len_func = NULL, maxlen_func = NULL, drops_func = NULL;
466 const char *ifname = sc->sc_if.if_xname;
467
468 len_func = bridge_sysctl_fwdq_items;
469 maxlen_func = bridge_sysctl_fwdq_maxlen;
470 drops_func = bridge_sysctl_fwdq_drops;
471
472 if (sysctl_createv(clog, 0, NULL, &rnode,
473 CTLFLAG_PERMANENT,
474 CTLTYPE_NODE, "interfaces",
475 SYSCTL_DESCR("Per-interface controls"),
476 NULL, 0, NULL, 0,
477 CTL_NET, CTL_CREATE, CTL_EOL) != 0)
478 goto bad;
479
480 if (sysctl_createv(clog, 0, &rnode, &rnode,
481 CTLFLAG_PERMANENT,
482 CTLTYPE_NODE, ifname,
483 SYSCTL_DESCR("Interface controls"),
484 NULL, 0, NULL, 0,
485 CTL_CREATE, CTL_EOL) != 0)
486 goto bad;
487
488 if (sysctl_createv(clog, 0, &rnode, &rnode,
489 CTLFLAG_PERMANENT,
490 CTLTYPE_NODE, "fwdq",
491 SYSCTL_DESCR("Protocol input queue controls"),
492 NULL, 0, NULL, 0,
493 CTL_CREATE, CTL_EOL) != 0)
494 goto bad;
495
496 if (sysctl_createv(clog, 0, &rnode, &cnode,
497 CTLFLAG_PERMANENT,
498 CTLTYPE_INT, "len",
499 SYSCTL_DESCR("Current forwarding queue length"),
500 len_func, 0, (void *)sc, 0,
501 CTL_CREATE, IFQCTL_LEN, CTL_EOL) != 0)
502 goto bad;
503
504 if (sysctl_createv(clog, 0, &rnode, &cnode,
505 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
506 CTLTYPE_INT, "maxlen",
507 SYSCTL_DESCR("Maximum allowed forwarding queue length"),
508 maxlen_func, 0, (void *)sc, 0,
509 CTL_CREATE, IFQCTL_MAXLEN, CTL_EOL) != 0)
510 goto bad;
511
512 if (sysctl_createv(clog, 0, &rnode, &cnode,
513 CTLFLAG_PERMANENT,
514 CTLTYPE_INT, "drops",
515 SYSCTL_DESCR("Packets dropped due to full forwarding queue"),
516 drops_func, 0, (void *)sc, 0,
517 CTL_CREATE, IFQCTL_DROPS, CTL_EOL) != 0)
518 goto bad;
519
520 return;
521 bad:
522 aprint_error("%s: could not attach sysctl nodes\n", ifname);
523 return;
524 }
525
526 /*
527 * bridge_ioctl:
528 *
529 * Handle a control request from the operator.
530 */
531 static int
532 bridge_ioctl(struct ifnet *ifp, u_long cmd, void *data)
533 {
534 struct bridge_softc *sc = ifp->if_softc;
535 struct lwp *l = curlwp; /* XXX */
536 union {
537 struct ifbreq ifbreq;
538 struct ifbifconf ifbifconf;
539 struct ifbareq ifbareq;
540 struct ifbaconf ifbaconf;
541 struct ifbrparam ifbrparam;
542 } args;
543 struct ifdrv *ifd = (struct ifdrv *) data;
544 const struct bridge_control *bc = NULL; /* XXXGCC */
545 int s, error = 0;
546
547 /* Authorize command before calling splnet(). */
548 switch (cmd) {
549 case SIOCGDRVSPEC:
550 case SIOCSDRVSPEC:
551 if (ifd->ifd_cmd >= bridge_control_table_size) {
552 error = EINVAL;
553 return error;
554 }
555
556 bc = &bridge_control_table[ifd->ifd_cmd];
557
558 /* We only care about BC_F_SUSER at this point. */
559 if ((bc->bc_flags & BC_F_SUSER) == 0)
560 break;
561
562 error = kauth_authorize_network(l->l_cred,
563 KAUTH_NETWORK_INTERFACE_BRIDGE,
564 cmd == SIOCGDRVSPEC ?
565 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV :
566 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV,
567 ifd, NULL, NULL);
568 if (error)
569 return (error);
570
571 break;
572 }
573
574 s = splnet();
575
576 switch (cmd) {
577 case SIOCGDRVSPEC:
578 case SIOCSDRVSPEC:
579 KASSERT(bc != NULL);
580 if (cmd == SIOCGDRVSPEC &&
581 (bc->bc_flags & BC_F_COPYOUT) == 0) {
582 error = EINVAL;
583 break;
584 }
585 else if (cmd == SIOCSDRVSPEC &&
586 (bc->bc_flags & BC_F_COPYOUT) != 0) {
587 error = EINVAL;
588 break;
589 }
590
591 /* BC_F_SUSER is checked above, before splnet(). */
592
593 if (ifd->ifd_len != bc->bc_argsize ||
594 ifd->ifd_len > sizeof(args)) {
595 error = EINVAL;
596 break;
597 }
598
599 memset(&args, 0, sizeof(args));
600 if (bc->bc_flags & BC_F_COPYIN) {
601 error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
602 if (error)
603 break;
604 }
605
606 error = (*bc->bc_func)(sc, &args);
607 if (error)
608 break;
609
610 if (bc->bc_flags & BC_F_COPYOUT)
611 error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
612
613 break;
614
615 case SIOCSIFFLAGS:
616 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
617 break;
618 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
619 case IFF_RUNNING:
620 /*
621 * If interface is marked down and it is running,
622 * then stop and disable it.
623 */
624 (*ifp->if_stop)(ifp, 1);
625 break;
626 case IFF_UP:
627 /*
628 * If interface is marked up and it is stopped, then
629 * start it.
630 */
631 error = (*ifp->if_init)(ifp);
632 break;
633 default:
634 break;
635 }
636 break;
637
638 default:
639 error = ifioctl_common(ifp, cmd, data);
640 break;
641 }
642
643 splx(s);
644
645 return (error);
646 }
647
648 /*
649 * bridge_lookup_member:
650 *
651 * Lookup a bridge member interface. Must be called at splnet().
652 */
653 static struct bridge_iflist *
654 bridge_lookup_member(struct bridge_softc *sc, const char *name)
655 {
656 struct bridge_iflist *bif;
657 struct ifnet *ifp;
658
659 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
660 ifp = bif->bif_ifp;
661 if (strcmp(ifp->if_xname, name) == 0)
662 return (bif);
663 }
664
665 return (NULL);
666 }
667
668 /*
669 * bridge_lookup_member_if:
670 *
671 * Lookup a bridge member interface by ifnet*. Must be called at splnet().
672 */
673 static struct bridge_iflist *
674 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
675 {
676 struct bridge_iflist *bif;
677
678 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
679 if (bif->bif_ifp == member_ifp)
680 return (bif);
681 }
682
683 return (NULL);
684 }
685
686 /*
687 * bridge_delete_member:
688 *
689 * Delete the specified member interface.
690 */
691 static void
692 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
693 {
694 struct ifnet *ifs = bif->bif_ifp;
695
696 switch (ifs->if_type) {
697 case IFT_ETHER:
698 /*
699 * Take the interface out of promiscuous mode.
700 */
701 (void) ifpromisc(ifs, 0);
702 break;
703 default:
704 #ifdef DIAGNOSTIC
705 panic("bridge_delete_member: impossible");
706 #endif
707 break;
708 }
709
710 ifs->if_input = ether_input;
711 ifs->if_bridge = NULL;
712 LIST_REMOVE(bif, bif_next);
713
714 bridge_rtdelete(sc, ifs);
715
716 free(bif, M_DEVBUF);
717
718 if (sc->sc_if.if_flags & IFF_RUNNING)
719 bstp_initialization(sc);
720 }
721
722 static int
723 bridge_ioctl_add(struct bridge_softc *sc, void *arg)
724 {
725 struct ifbreq *req = arg;
726 struct bridge_iflist *bif = NULL;
727 struct ifnet *ifs;
728 int error = 0;
729
730 ifs = ifunit(req->ifbr_ifsname);
731 if (ifs == NULL)
732 return (ENOENT);
733
734 if (sc->sc_if.if_mtu != ifs->if_mtu)
735 return (EINVAL);
736
737 if (ifs->if_bridge == sc)
738 return (EEXIST);
739
740 if (ifs->if_bridge != NULL)
741 return (EBUSY);
742
743 if (ifs->if_input != ether_input)
744 return EINVAL;
745
746 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
747 if (bif == NULL)
748 return (ENOMEM);
749
750 switch (ifs->if_type) {
751 case IFT_ETHER:
752 /*
753 * Place the interface into promiscuous mode.
754 */
755 error = ifpromisc(ifs, 1);
756 if (error)
757 goto out;
758 break;
759 default:
760 error = EINVAL;
761 goto out;
762 }
763
764 bif->bif_ifp = ifs;
765 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
766 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
767 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
768
769 ifs->if_bridge = sc;
770 LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
771 ifs->if_input = bridge_input;
772
773 if (sc->sc_if.if_flags & IFF_RUNNING)
774 bstp_initialization(sc);
775 else
776 bstp_stop(sc);
777
778 out:
779 if (error) {
780 if (bif != NULL)
781 free(bif, M_DEVBUF);
782 }
783 return (error);
784 }
785
786 static int
787 bridge_ioctl_del(struct bridge_softc *sc, void *arg)
788 {
789 struct ifbreq *req = arg;
790 struct bridge_iflist *bif;
791
792 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
793 if (bif == NULL)
794 return (ENOENT);
795
796 bridge_delete_member(sc, bif);
797
798 return (0);
799 }
800
801 static int
802 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
803 {
804 struct ifbreq *req = arg;
805 struct bridge_iflist *bif;
806
807 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
808 if (bif == NULL)
809 return (ENOENT);
810
811 req->ifbr_ifsflags = bif->bif_flags;
812 req->ifbr_state = bif->bif_state;
813 req->ifbr_priority = bif->bif_priority;
814 req->ifbr_path_cost = bif->bif_path_cost;
815 req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
816
817 return (0);
818 }
819
820 static int
821 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
822 {
823 struct ifbreq *req = arg;
824 struct bridge_iflist *bif;
825
826 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
827 if (bif == NULL)
828 return (ENOENT);
829
830 if (req->ifbr_ifsflags & IFBIF_STP) {
831 switch (bif->bif_ifp->if_type) {
832 case IFT_ETHER:
833 /* These can do spanning tree. */
834 break;
835
836 default:
837 /* Nothing else can. */
838 return (EINVAL);
839 }
840 }
841
842 bif->bif_flags = req->ifbr_ifsflags;
843
844 if (sc->sc_if.if_flags & IFF_RUNNING)
845 bstp_initialization(sc);
846
847 return (0);
848 }
849
850 static int
851 bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
852 {
853 struct ifbrparam *param = arg;
854
855 sc->sc_brtmax = param->ifbrp_csize;
856 bridge_rttrim(sc);
857
858 return (0);
859 }
860
861 static int
862 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
863 {
864 struct ifbrparam *param = arg;
865
866 param->ifbrp_csize = sc->sc_brtmax;
867
868 return (0);
869 }
870
871 static int
872 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
873 {
874 struct ifbifconf *bifc = arg;
875 struct bridge_iflist *bif;
876 struct ifbreq breq;
877 int count, len, error = 0;
878
879 count = 0;
880 LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
881 count++;
882
883 if (bifc->ifbic_len == 0) {
884 bifc->ifbic_len = sizeof(breq) * count;
885 return (0);
886 }
887
888 count = 0;
889 len = bifc->ifbic_len;
890 memset(&breq, 0, sizeof breq);
891 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
892 if (len < sizeof(breq))
893 break;
894
895 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
896 sizeof(breq.ifbr_ifsname));
897 breq.ifbr_ifsflags = bif->bif_flags;
898 breq.ifbr_state = bif->bif_state;
899 breq.ifbr_priority = bif->bif_priority;
900 breq.ifbr_path_cost = bif->bif_path_cost;
901 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
902 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
903 if (error)
904 break;
905 count++;
906 len -= sizeof(breq);
907 }
908
909 bifc->ifbic_len = sizeof(breq) * count;
910 return (error);
911 }
912
913 static int
914 bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
915 {
916 struct ifbaconf *bac = arg;
917 struct bridge_rtnode *brt;
918 struct ifbareq bareq;
919 int count = 0, error = 0, len;
920
921 if (bac->ifbac_len == 0)
922 return (0);
923
924 len = bac->ifbac_len;
925 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
926 if (len < sizeof(bareq))
927 goto out;
928 memset(&bareq, 0, sizeof(bareq));
929 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
930 sizeof(bareq.ifba_ifsname));
931 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
932 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
933 bareq.ifba_expire = brt->brt_expire - time_uptime;
934 } else
935 bareq.ifba_expire = 0;
936 bareq.ifba_flags = brt->brt_flags;
937
938 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
939 if (error)
940 goto out;
941 count++;
942 len -= sizeof(bareq);
943 }
944 out:
945 bac->ifbac_len = sizeof(bareq) * count;
946 return (error);
947 }
948
949 static int
950 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
951 {
952 struct ifbareq *req = arg;
953 struct bridge_iflist *bif;
954 int error;
955
956 bif = bridge_lookup_member(sc, req->ifba_ifsname);
957 if (bif == NULL)
958 return (ENOENT);
959
960 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
961 req->ifba_flags);
962
963 return (error);
964 }
965
966 static int
967 bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
968 {
969 struct ifbrparam *param = arg;
970
971 sc->sc_brttimeout = param->ifbrp_ctime;
972
973 return (0);
974 }
975
976 static int
977 bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
978 {
979 struct ifbrparam *param = arg;
980
981 param->ifbrp_ctime = sc->sc_brttimeout;
982
983 return (0);
984 }
985
986 static int
987 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
988 {
989 struct ifbareq *req = arg;
990
991 return (bridge_rtdaddr(sc, req->ifba_dst));
992 }
993
994 static int
995 bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
996 {
997 struct ifbreq *req = arg;
998
999 bridge_rtflush(sc, req->ifbr_ifsflags);
1000
1001 return (0);
1002 }
1003
1004 static int
1005 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1006 {
1007 struct ifbrparam *param = arg;
1008
1009 param->ifbrp_prio = sc->sc_bridge_priority;
1010
1011 return (0);
1012 }
1013
1014 static int
1015 bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1016 {
1017 struct ifbrparam *param = arg;
1018
1019 sc->sc_bridge_priority = param->ifbrp_prio;
1020
1021 if (sc->sc_if.if_flags & IFF_RUNNING)
1022 bstp_initialization(sc);
1023
1024 return (0);
1025 }
1026
1027 static int
1028 bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1029 {
1030 struct ifbrparam *param = arg;
1031
1032 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
1033
1034 return (0);
1035 }
1036
1037 static int
1038 bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1039 {
1040 struct ifbrparam *param = arg;
1041
1042 if (param->ifbrp_hellotime == 0)
1043 return (EINVAL);
1044 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
1045
1046 if (sc->sc_if.if_flags & IFF_RUNNING)
1047 bstp_initialization(sc);
1048
1049 return (0);
1050 }
1051
1052 static int
1053 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1054 {
1055 struct ifbrparam *param = arg;
1056
1057 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
1058
1059 return (0);
1060 }
1061
1062 static int
1063 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1064 {
1065 struct ifbrparam *param = arg;
1066
1067 if (param->ifbrp_fwddelay == 0)
1068 return (EINVAL);
1069 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
1070
1071 if (sc->sc_if.if_flags & IFF_RUNNING)
1072 bstp_initialization(sc);
1073
1074 return (0);
1075 }
1076
1077 static int
1078 bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1079 {
1080 struct ifbrparam *param = arg;
1081
1082 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
1083
1084 return (0);
1085 }
1086
1087 static int
1088 bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1089 {
1090 struct ifbrparam *param = arg;
1091
1092 if (param->ifbrp_maxage == 0)
1093 return (EINVAL);
1094 sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
1095
1096 if (sc->sc_if.if_flags & IFF_RUNNING)
1097 bstp_initialization(sc);
1098
1099 return (0);
1100 }
1101
1102 static int
1103 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1104 {
1105 struct ifbreq *req = arg;
1106 struct bridge_iflist *bif;
1107
1108 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1109 if (bif == NULL)
1110 return (ENOENT);
1111
1112 bif->bif_priority = req->ifbr_priority;
1113
1114 if (sc->sc_if.if_flags & IFF_RUNNING)
1115 bstp_initialization(sc);
1116
1117 return (0);
1118 }
1119
1120 #if defined(BRIDGE_IPF)
1121 static int
1122 bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg)
1123 {
1124 struct ifbrparam *param = arg;
1125
1126 param->ifbrp_filter = sc->sc_filter_flags;
1127
1128 return (0);
1129 }
1130
1131 static int
1132 bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg)
1133 {
1134 struct ifbrparam *param = arg;
1135 uint32_t nflags, oflags;
1136
1137 if (param->ifbrp_filter & ~IFBF_FILT_MASK)
1138 return (EINVAL);
1139
1140 nflags = param->ifbrp_filter;
1141 oflags = sc->sc_filter_flags;
1142
1143 if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) {
1144 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
1145 sc->sc_if.if_pfil);
1146 }
1147 if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) {
1148 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
1149 sc->sc_if.if_pfil);
1150 }
1151
1152 sc->sc_filter_flags = nflags;
1153
1154 return (0);
1155 }
1156 #endif /* BRIDGE_IPF */
1157
1158 static int
1159 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1160 {
1161 struct ifbreq *req = arg;
1162 struct bridge_iflist *bif;
1163
1164 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1165 if (bif == NULL)
1166 return (ENOENT);
1167
1168 bif->bif_path_cost = req->ifbr_path_cost;
1169
1170 if (sc->sc_if.if_flags & IFF_RUNNING)
1171 bstp_initialization(sc);
1172
1173 return (0);
1174 }
1175
1176 /*
1177 * bridge_ifdetach:
1178 *
1179 * Detach an interface from a bridge. Called when a member
1180 * interface is detaching.
1181 */
1182 void
1183 bridge_ifdetach(struct ifnet *ifp)
1184 {
1185 struct bridge_softc *sc = ifp->if_bridge;
1186 struct ifbreq breq;
1187
1188 memset(&breq, 0, sizeof(breq));
1189 strlcpy(breq.ifbr_ifsname, ifp->if_xname, sizeof(breq.ifbr_ifsname));
1190
1191 (void) bridge_ioctl_del(sc, &breq);
1192 }
1193
1194 /*
1195 * bridge_init:
1196 *
1197 * Initialize a bridge interface.
1198 */
1199 static int
1200 bridge_init(struct ifnet *ifp)
1201 {
1202 struct bridge_softc *sc = ifp->if_softc;
1203
1204 if (ifp->if_flags & IFF_RUNNING)
1205 return (0);
1206
1207 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1208 bridge_timer, sc);
1209
1210 ifp->if_flags |= IFF_RUNNING;
1211 bstp_initialization(sc);
1212 return (0);
1213 }
1214
1215 /*
1216 * bridge_stop:
1217 *
1218 * Stop the bridge interface.
1219 */
1220 static void
1221 bridge_stop(struct ifnet *ifp, int disable)
1222 {
1223 struct bridge_softc *sc = ifp->if_softc;
1224
1225 if ((ifp->if_flags & IFF_RUNNING) == 0)
1226 return;
1227
1228 callout_stop(&sc->sc_brcallout);
1229 bstp_stop(sc);
1230
1231 bridge_rtflush(sc, IFBF_FLUSHDYN);
1232
1233 ifp->if_flags &= ~IFF_RUNNING;
1234 }
1235
1236 /*
1237 * bridge_enqueue:
1238 *
1239 * Enqueue a packet on a bridge member interface.
1240 *
1241 * NOTE: must be called at splnet().
1242 */
1243 void
1244 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
1245 int runfilt)
1246 {
1247 ALTQ_DECL(struct altq_pktattr pktattr;)
1248 int len, error;
1249 short mflags;
1250
1251 /*
1252 * Clear any in-bound checksum flags for this packet.
1253 */
1254 m->m_pkthdr.csum_flags = 0;
1255
1256 if (runfilt) {
1257 if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
1258 dst_ifp, PFIL_OUT) != 0) {
1259 if (m != NULL)
1260 m_freem(m);
1261 return;
1262 }
1263 if (m == NULL)
1264 return;
1265 }
1266
1267 #ifdef ALTQ
1268 /*
1269 * If ALTQ is enabled on the member interface, do
1270 * classification; the queueing discipline might
1271 * not require classification, but might require
1272 * the address family/header pointer in the pktattr.
1273 */
1274 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) {
1275 /* XXX IFT_ETHER */
1276 altq_etherclassify(&dst_ifp->if_snd, m, &pktattr);
1277 }
1278 #endif /* ALTQ */
1279
1280 len = m->m_pkthdr.len;
1281 m->m_flags |= M_PROTO1;
1282 mflags = m->m_flags;
1283 IFQ_ENQUEUE(&dst_ifp->if_snd, m, &pktattr, error);
1284 if (error) {
1285 /* mbuf is already freed */
1286 sc->sc_if.if_oerrors++;
1287 return;
1288 }
1289
1290 sc->sc_if.if_opackets++;
1291 sc->sc_if.if_obytes += len;
1292
1293 dst_ifp->if_obytes += len;
1294
1295 if (mflags & M_MCAST) {
1296 sc->sc_if.if_omcasts++;
1297 dst_ifp->if_omcasts++;
1298 }
1299
1300 if ((dst_ifp->if_flags & IFF_OACTIVE) == 0)
1301 (*dst_ifp->if_start)(dst_ifp);
1302 }
1303
1304 /*
1305 * bridge_output:
1306 *
1307 * Send output from a bridge member interface. This
1308 * performs the bridging function for locally originated
1309 * packets.
1310 *
1311 * The mbuf has the Ethernet header already attached. We must
1312 * enqueue or free the mbuf before returning.
1313 */
1314 int
1315 bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,
1316 struct rtentry *rt)
1317 {
1318 struct ether_header *eh;
1319 struct ifnet *dst_if;
1320 struct bridge_softc *sc;
1321 int s;
1322
1323 if (m->m_len < ETHER_HDR_LEN) {
1324 m = m_pullup(m, ETHER_HDR_LEN);
1325 if (m == NULL)
1326 return (0);
1327 }
1328
1329 eh = mtod(m, struct ether_header *);
1330 sc = ifp->if_bridge;
1331
1332 s = splnet();
1333
1334 /*
1335 * If bridge is down, but the original output interface is up,
1336 * go ahead and send out that interface. Otherwise, the packet
1337 * is dropped below.
1338 */
1339 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1340 dst_if = ifp;
1341 goto sendunicast;
1342 }
1343
1344 /*
1345 * If the packet is a multicast, or we don't know a better way to
1346 * get there, send to all interfaces.
1347 */
1348 if (ETHER_IS_MULTICAST(eh->ether_dhost))
1349 dst_if = NULL;
1350 else
1351 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1352 if (dst_if == NULL) {
1353 struct bridge_iflist *bif;
1354 struct mbuf *mc;
1355 int used = 0;
1356
1357 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1358 dst_if = bif->bif_ifp;
1359 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1360 continue;
1361
1362 /*
1363 * If this is not the original output interface,
1364 * and the interface is participating in spanning
1365 * tree, make sure the port is in a state that
1366 * allows forwarding.
1367 */
1368 if (dst_if != ifp &&
1369 (bif->bif_flags & IFBIF_STP) != 0) {
1370 switch (bif->bif_state) {
1371 case BSTP_IFSTATE_BLOCKING:
1372 case BSTP_IFSTATE_LISTENING:
1373 case BSTP_IFSTATE_DISABLED:
1374 continue;
1375 }
1376 }
1377
1378 if (LIST_NEXT(bif, bif_next) == NULL) {
1379 used = 1;
1380 mc = m;
1381 } else {
1382 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
1383 if (mc == NULL) {
1384 sc->sc_if.if_oerrors++;
1385 continue;
1386 }
1387 }
1388
1389 bridge_enqueue(sc, dst_if, mc, 0);
1390 }
1391 if (used == 0)
1392 m_freem(m);
1393 splx(s);
1394 return (0);
1395 }
1396
1397 sendunicast:
1398 /*
1399 * XXX Spanning tree consideration here?
1400 */
1401
1402 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1403 m_freem(m);
1404 splx(s);
1405 return (0);
1406 }
1407
1408 bridge_enqueue(sc, dst_if, m, 0);
1409
1410 splx(s);
1411 return (0);
1412 }
1413
1414 /*
1415 * bridge_start:
1416 *
1417 * Start output on a bridge.
1418 *
1419 * NOTE: This routine should never be called in this implementation.
1420 */
1421 static void
1422 bridge_start(struct ifnet *ifp)
1423 {
1424
1425 printf("%s: bridge_start() called\n", ifp->if_xname);
1426 }
1427
1428 /*
1429 * bridge_forward:
1430 *
1431 * The forwarding function of the bridge.
1432 */
1433 static void
1434 bridge_forward(void *v)
1435 {
1436 struct bridge_softc *sc = v;
1437 struct mbuf *m;
1438 struct bridge_iflist *bif;
1439 struct ifnet *src_if, *dst_if;
1440 struct ether_header *eh;
1441 int s;
1442
1443 KERNEL_LOCK(1, NULL);
1444 mutex_enter(softnet_lock);
1445 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1446 mutex_exit(softnet_lock);
1447 KERNEL_UNLOCK_ONE(NULL);
1448 return;
1449 }
1450
1451 s = splnet();
1452 while ((m = pktq_dequeue(sc->sc_fwd_pktq)) != NULL) {
1453 src_if = m->m_pkthdr.rcvif;
1454
1455 sc->sc_if.if_ipackets++;
1456 sc->sc_if.if_ibytes += m->m_pkthdr.len;
1457
1458 /*
1459 * Look up the bridge_iflist.
1460 */
1461 bif = bridge_lookup_member_if(sc, src_if);
1462 if (bif == NULL) {
1463 /* Interface is not a bridge member (anymore?) */
1464 m_freem(m);
1465 continue;
1466 }
1467
1468 if (bif->bif_flags & IFBIF_STP) {
1469 switch (bif->bif_state) {
1470 case BSTP_IFSTATE_BLOCKING:
1471 case BSTP_IFSTATE_LISTENING:
1472 case BSTP_IFSTATE_DISABLED:
1473 m_freem(m);
1474 continue;
1475 }
1476 }
1477
1478 eh = mtod(m, struct ether_header *);
1479
1480 /*
1481 * If the interface is learning, and the source
1482 * address is valid and not multicast, record
1483 * the address.
1484 */
1485 if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1486 ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
1487 (eh->ether_shost[0] == 0 &&
1488 eh->ether_shost[1] == 0 &&
1489 eh->ether_shost[2] == 0 &&
1490 eh->ether_shost[3] == 0 &&
1491 eh->ether_shost[4] == 0 &&
1492 eh->ether_shost[5] == 0) == 0) {
1493 (void) bridge_rtupdate(sc, eh->ether_shost,
1494 src_if, 0, IFBAF_DYNAMIC);
1495 }
1496
1497 if ((bif->bif_flags & IFBIF_STP) != 0 &&
1498 bif->bif_state == BSTP_IFSTATE_LEARNING) {
1499 m_freem(m);
1500 continue;
1501 }
1502
1503 /*
1504 * At this point, the port either doesn't participate
1505 * in spanning tree or it is in the forwarding state.
1506 */
1507
1508 /*
1509 * If the packet is unicast, destined for someone on
1510 * "this" side of the bridge, drop it.
1511 */
1512 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1513 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1514 if (src_if == dst_if) {
1515 m_freem(m);
1516 continue;
1517 }
1518 } else {
1519 /* ...forward it to all interfaces. */
1520 sc->sc_if.if_imcasts++;
1521 dst_if = NULL;
1522 }
1523
1524 if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
1525 m->m_pkthdr.rcvif, PFIL_IN) != 0) {
1526 if (m != NULL)
1527 m_freem(m);
1528 continue;
1529 }
1530 if (m == NULL)
1531 continue;
1532
1533 if (dst_if == NULL) {
1534 bridge_broadcast(sc, src_if, m);
1535 continue;
1536 }
1537
1538 /*
1539 * At this point, we're dealing with a unicast frame
1540 * going to a different interface.
1541 */
1542 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1543 m_freem(m);
1544 continue;
1545 }
1546 bif = bridge_lookup_member_if(sc, dst_if);
1547 if (bif == NULL) {
1548 /* Not a member of the bridge (anymore?) */
1549 m_freem(m);
1550 continue;
1551 }
1552
1553 if (bif->bif_flags & IFBIF_STP) {
1554 switch (bif->bif_state) {
1555 case BSTP_IFSTATE_DISABLED:
1556 case BSTP_IFSTATE_BLOCKING:
1557 m_freem(m);
1558 continue;
1559 }
1560 }
1561
1562 bridge_enqueue(sc, dst_if, m, 1);
1563 }
1564 splx(s);
1565 mutex_exit(softnet_lock);
1566 KERNEL_UNLOCK_ONE(NULL);
1567 }
1568
1569 static bool
1570 bstp_state_before_learning(struct bridge_iflist *bif)
1571 {
1572 if (bif->bif_flags & IFBIF_STP) {
1573 switch (bif->bif_state) {
1574 case BSTP_IFSTATE_BLOCKING:
1575 case BSTP_IFSTATE_LISTENING:
1576 case BSTP_IFSTATE_DISABLED:
1577 return true;
1578 }
1579 }
1580 return false;
1581 }
1582
1583 static bool
1584 bridge_ourether(struct bridge_iflist *bif, struct ether_header *eh, int src)
1585 {
1586 uint8_t *ether = src ? eh->ether_shost : eh->ether_dhost;
1587
1588 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), ether, ETHER_ADDR_LEN) == 0
1589 #if NCARP > 0
1590 || (bif->bif_ifp->if_carp &&
1591 carp_ourether(bif->bif_ifp->if_carp, eh, IFT_ETHER, src) != NULL)
1592 #endif /* NCARP > 0 */
1593 )
1594 return true;
1595
1596 return false;
1597 }
1598
1599 /*
1600 * bridge_input:
1601 *
1602 * Receive input from a member interface. Queue the packet for
1603 * bridging if it is not for us.
1604 * should be called at splnet()
1605 */
1606 static void
1607 bridge_input(struct ifnet *ifp, struct mbuf *m)
1608 {
1609 struct bridge_softc *sc = ifp->if_bridge;
1610 struct bridge_iflist *bif;
1611 struct ether_header *eh;
1612
1613 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1614 ether_input(ifp, m);
1615 return;
1616 }
1617
1618 bif = bridge_lookup_member_if(sc, ifp);
1619 if (bif == NULL) {
1620 ether_input(ifp, m);
1621 return;
1622 }
1623
1624 eh = mtod(m, struct ether_header *);
1625
1626 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1627 if (memcmp(etherbroadcastaddr,
1628 eh->ether_dhost, ETHER_ADDR_LEN) == 0)
1629 m->m_flags |= M_BCAST;
1630 else
1631 m->m_flags |= M_MCAST;
1632 }
1633
1634 /*
1635 * A 'fast' path for packets addressed to interfaces that are
1636 * part of this bridge.
1637 */
1638 if (!(m->m_flags & (M_BCAST|M_MCAST)) &&
1639 !bstp_state_before_learning(bif)) {
1640 struct bridge_iflist *_bif;
1641
1642 LIST_FOREACH(_bif, &sc->sc_iflist, bif_next) {
1643 /* It is destined for us. */
1644 if (bridge_ourether(_bif, eh, 0)) {
1645 if (_bif->bif_flags & IFBIF_LEARNING)
1646 (void) bridge_rtupdate(sc,
1647 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1648 m->m_pkthdr.rcvif = _bif->bif_ifp;
1649 ether_input(_bif->bif_ifp, m);
1650 return;
1651 }
1652
1653 /* We just received a packet that we sent out. */
1654 if (bridge_ourether(_bif, eh, 1)) {
1655 m_freem(m);
1656 return;
1657 }
1658 }
1659 }
1660
1661 /* Tap off 802.1D packets; they do not get forwarded. */
1662 if (bif->bif_flags & IFBIF_STP &&
1663 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
1664 bstp_input(sc, bif, m);
1665 return;
1666 }
1667
1668 /*
1669 * A normal switch would discard the packet here, but that's not what
1670 * we've done historically. This also prevents some obnoxious behaviour.
1671 */
1672 if (bstp_state_before_learning(bif)) {
1673 ether_input(ifp, m);
1674 return;
1675 }
1676
1677 /* Queue the packet for bridge forwarding. */
1678 if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, m, 0)))
1679 m_freem(m);
1680 }
1681
1682 /*
1683 * bridge_broadcast:
1684 *
1685 * Send a frame to all interfaces that are members of
1686 * the bridge, except for the one on which the packet
1687 * arrived.
1688 */
1689 static void
1690 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1691 struct mbuf *m)
1692 {
1693 struct bridge_iflist *bif;
1694 struct mbuf *mc;
1695 struct ifnet *dst_if;
1696 bool used, bmcast;
1697
1698 used = bmcast = m->m_flags & (M_BCAST|M_MCAST);
1699
1700 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1701 dst_if = bif->bif_ifp;
1702 if (dst_if == src_if)
1703 continue;
1704
1705 if (bif->bif_flags & IFBIF_STP) {
1706 switch (bif->bif_state) {
1707 case BSTP_IFSTATE_BLOCKING:
1708 case BSTP_IFSTATE_DISABLED:
1709 continue;
1710 }
1711 }
1712
1713 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast)
1714 continue;
1715
1716 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1717 continue;
1718
1719 if (!used && LIST_NEXT(bif, bif_next) == NULL) {
1720 mc = m;
1721 used = true;
1722 } else {
1723 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1724 if (mc == NULL) {
1725 sc->sc_if.if_oerrors++;
1726 continue;
1727 }
1728 }
1729
1730 bridge_enqueue(sc, dst_if, mc, 1);
1731 }
1732
1733 if (bmcast)
1734 ether_input(src_if, m);
1735 else if (!used)
1736 m_freem(m);
1737 }
1738
1739 /*
1740 * bridge_rtupdate:
1741 *
1742 * Add a bridge routing entry.
1743 */
1744 static int
1745 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
1746 struct ifnet *dst_if, int setflags, uint8_t flags)
1747 {
1748 struct bridge_rtnode *brt;
1749 int error;
1750
1751 /*
1752 * A route for this destination might already exist. If so,
1753 * update it, otherwise create a new one.
1754 */
1755 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
1756 if (sc->sc_brtcnt >= sc->sc_brtmax)
1757 return (ENOSPC);
1758
1759 /*
1760 * Allocate a new bridge forwarding node, and
1761 * initialize the expiration time and Ethernet
1762 * address.
1763 */
1764 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT);
1765 if (brt == NULL)
1766 return (ENOMEM);
1767
1768 memset(brt, 0, sizeof(*brt));
1769 brt->brt_expire = time_uptime + sc->sc_brttimeout;
1770 brt->brt_flags = IFBAF_DYNAMIC;
1771 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
1772
1773 if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
1774 pool_put(&bridge_rtnode_pool, brt);
1775 return (error);
1776 }
1777 }
1778
1779 brt->brt_ifp = dst_if;
1780 if (setflags) {
1781 brt->brt_flags = flags;
1782 if (flags & IFBAF_STATIC)
1783 brt->brt_expire = 0;
1784 else
1785 brt->brt_expire = time_uptime + sc->sc_brttimeout;
1786 }
1787
1788 return (0);
1789 }
1790
1791 /*
1792 * bridge_rtlookup:
1793 *
1794 * Lookup the destination interface for an address.
1795 */
1796 static struct ifnet *
1797 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
1798 {
1799 struct bridge_rtnode *brt;
1800
1801 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1802 return (NULL);
1803
1804 return (brt->brt_ifp);
1805 }
1806
1807 /*
1808 * bridge_rttrim:
1809 *
1810 * Trim the routine table so that we have a number
1811 * of routing entries less than or equal to the
1812 * maximum number.
1813 */
1814 static void
1815 bridge_rttrim(struct bridge_softc *sc)
1816 {
1817 struct bridge_rtnode *brt, *nbrt;
1818
1819 /* Make sure we actually need to do this. */
1820 if (sc->sc_brtcnt <= sc->sc_brtmax)
1821 return;
1822
1823 /* Force an aging cycle; this might trim enough addresses. */
1824 bridge_rtage(sc);
1825 if (sc->sc_brtcnt <= sc->sc_brtmax)
1826 return;
1827
1828 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1829 nbrt = LIST_NEXT(brt, brt_list);
1830 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1831 bridge_rtnode_destroy(sc, brt);
1832 if (sc->sc_brtcnt <= sc->sc_brtmax)
1833 return;
1834 }
1835 }
1836 }
1837
1838 /*
1839 * bridge_timer:
1840 *
1841 * Aging timer for the bridge.
1842 */
1843 static void
1844 bridge_timer(void *arg)
1845 {
1846 struct bridge_softc *sc = arg;
1847 int s;
1848
1849 s = splnet();
1850 bridge_rtage(sc);
1851 splx(s);
1852
1853 if (sc->sc_if.if_flags & IFF_RUNNING)
1854 callout_reset(&sc->sc_brcallout,
1855 bridge_rtable_prune_period * hz, bridge_timer, sc);
1856 }
1857
1858 /*
1859 * bridge_rtage:
1860 *
1861 * Perform an aging cycle.
1862 */
1863 static void
1864 bridge_rtage(struct bridge_softc *sc)
1865 {
1866 struct bridge_rtnode *brt, *nbrt;
1867
1868 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1869 nbrt = LIST_NEXT(brt, brt_list);
1870 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1871 if (time_uptime >= brt->brt_expire)
1872 bridge_rtnode_destroy(sc, brt);
1873 }
1874 }
1875 }
1876
1877 /*
1878 * bridge_rtflush:
1879 *
1880 * Remove all dynamic addresses from the bridge.
1881 */
1882 static void
1883 bridge_rtflush(struct bridge_softc *sc, int full)
1884 {
1885 struct bridge_rtnode *brt, *nbrt;
1886
1887 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1888 nbrt = LIST_NEXT(brt, brt_list);
1889 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
1890 bridge_rtnode_destroy(sc, brt);
1891 }
1892 }
1893
1894 /*
1895 * bridge_rtdaddr:
1896 *
1897 * Remove an address from the table.
1898 */
1899 static int
1900 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
1901 {
1902 struct bridge_rtnode *brt;
1903
1904 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1905 return (ENOENT);
1906
1907 bridge_rtnode_destroy(sc, brt);
1908 return (0);
1909 }
1910
1911 /*
1912 * bridge_rtdelete:
1913 *
1914 * Delete routes to a speicifc member interface.
1915 */
1916 static void
1917 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
1918 {
1919 struct bridge_rtnode *brt, *nbrt;
1920
1921 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1922 nbrt = LIST_NEXT(brt, brt_list);
1923 if (brt->brt_ifp == ifp)
1924 bridge_rtnode_destroy(sc, brt);
1925 }
1926 }
1927
1928 /*
1929 * bridge_rtable_init:
1930 *
1931 * Initialize the route table for this bridge.
1932 */
1933 static int
1934 bridge_rtable_init(struct bridge_softc *sc)
1935 {
1936 int i;
1937
1938 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
1939 M_DEVBUF, M_NOWAIT);
1940 if (sc->sc_rthash == NULL)
1941 return (ENOMEM);
1942
1943 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
1944 LIST_INIT(&sc->sc_rthash[i]);
1945
1946 sc->sc_rthash_key = cprng_fast32();
1947
1948 LIST_INIT(&sc->sc_rtlist);
1949
1950 return (0);
1951 }
1952
1953 /*
1954 * bridge_rtable_fini:
1955 *
1956 * Deconstruct the route table for this bridge.
1957 */
1958 static void
1959 bridge_rtable_fini(struct bridge_softc *sc)
1960 {
1961
1962 free(sc->sc_rthash, M_DEVBUF);
1963 }
1964
1965 /*
1966 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
1967 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
1968 */
1969 #define mix(a, b, c) \
1970 do { \
1971 a -= b; a -= c; a ^= (c >> 13); \
1972 b -= c; b -= a; b ^= (a << 8); \
1973 c -= a; c -= b; c ^= (b >> 13); \
1974 a -= b; a -= c; a ^= (c >> 12); \
1975 b -= c; b -= a; b ^= (a << 16); \
1976 c -= a; c -= b; c ^= (b >> 5); \
1977 a -= b; a -= c; a ^= (c >> 3); \
1978 b -= c; b -= a; b ^= (a << 10); \
1979 c -= a; c -= b; c ^= (b >> 15); \
1980 } while (/*CONSTCOND*/0)
1981
1982 static inline uint32_t
1983 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
1984 {
1985 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
1986
1987 b += addr[5] << 8;
1988 b += addr[4];
1989 a += addr[3] << 24;
1990 a += addr[2] << 16;
1991 a += addr[1] << 8;
1992 a += addr[0];
1993
1994 mix(a, b, c);
1995
1996 return (c & BRIDGE_RTHASH_MASK);
1997 }
1998
1999 #undef mix
2000
2001 /*
2002 * bridge_rtnode_lookup:
2003 *
2004 * Look up a bridge route node for the specified destination.
2005 */
2006 static struct bridge_rtnode *
2007 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
2008 {
2009 struct bridge_rtnode *brt;
2010 uint32_t hash;
2011 int dir;
2012
2013 hash = bridge_rthash(sc, addr);
2014 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
2015 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
2016 if (dir == 0)
2017 return (brt);
2018 if (dir > 0)
2019 return (NULL);
2020 }
2021
2022 return (NULL);
2023 }
2024
2025 /*
2026 * bridge_rtnode_insert:
2027 *
2028 * Insert the specified bridge node into the route table. We
2029 * assume the entry is not already in the table.
2030 */
2031 static int
2032 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
2033 {
2034 struct bridge_rtnode *lbrt;
2035 uint32_t hash;
2036 int dir;
2037
2038 hash = bridge_rthash(sc, brt->brt_addr);
2039
2040 lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
2041 if (lbrt == NULL) {
2042 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
2043 goto out;
2044 }
2045
2046 do {
2047 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
2048 if (dir == 0)
2049 return (EEXIST);
2050 if (dir > 0) {
2051 LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
2052 goto out;
2053 }
2054 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
2055 LIST_INSERT_AFTER(lbrt, brt, brt_hash);
2056 goto out;
2057 }
2058 lbrt = LIST_NEXT(lbrt, brt_hash);
2059 } while (lbrt != NULL);
2060
2061 #ifdef DIAGNOSTIC
2062 panic("bridge_rtnode_insert: impossible");
2063 #endif
2064
2065 out:
2066 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
2067 sc->sc_brtcnt++;
2068
2069 return (0);
2070 }
2071
2072 /*
2073 * bridge_rtnode_destroy:
2074 *
2075 * Destroy a bridge rtnode.
2076 */
2077 static void
2078 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
2079 {
2080 int s = splnet();
2081
2082 LIST_REMOVE(brt, brt_hash);
2083
2084 LIST_REMOVE(brt, brt_list);
2085 sc->sc_brtcnt--;
2086 pool_put(&bridge_rtnode_pool, brt);
2087
2088 splx(s);
2089 }
2090
2091 #if defined(BRIDGE_IPF)
2092 extern pfil_head_t *inet_pfil_hook; /* XXX */
2093 extern pfil_head_t *inet6_pfil_hook; /* XXX */
2094
2095 /*
2096 * Send bridge packets through IPF if they are one of the types IPF can deal
2097 * with, or if they are ARP or REVARP. (IPF will pass ARP and REVARP without
2098 * question.)
2099 */
2100 static int
2101 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
2102 {
2103 int snap, error;
2104 struct ether_header *eh1, eh2;
2105 struct llc llc1;
2106 uint16_t ether_type;
2107
2108 snap = 0;
2109 error = -1; /* Default error if not error == 0 */
2110 eh1 = mtod(*mp, struct ether_header *);
2111 ether_type = ntohs(eh1->ether_type);
2112
2113 /*
2114 * Check for SNAP/LLC.
2115 */
2116 if (ether_type < ETHERMTU) {
2117 struct llc *llc2 = (struct llc *)(eh1 + 1);
2118
2119 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
2120 llc2->llc_dsap == LLC_SNAP_LSAP &&
2121 llc2->llc_ssap == LLC_SNAP_LSAP &&
2122 llc2->llc_control == LLC_UI) {
2123 ether_type = htons(llc2->llc_un.type_snap.ether_type);
2124 snap = 1;
2125 }
2126 }
2127
2128 /*
2129 * If we're trying to filter bridge traffic, don't look at anything
2130 * other than IP and ARP traffic. If the filter doesn't understand
2131 * IPv6, don't allow IPv6 through the bridge either. This is lame
2132 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2133 * but of course we don't have an AppleTalk filter to begin with.
2134 * (Note that since IPF doesn't understand ARP it will pass *ALL*
2135 * ARP traffic.)
2136 */
2137 switch (ether_type) {
2138 case ETHERTYPE_ARP:
2139 case ETHERTYPE_REVARP:
2140 return 0; /* Automatically pass */
2141 case ETHERTYPE_IP:
2142 # ifdef INET6
2143 case ETHERTYPE_IPV6:
2144 # endif /* INET6 */
2145 break;
2146 default:
2147 goto bad;
2148 }
2149
2150 /* Strip off the Ethernet header and keep a copy. */
2151 m_copydata(*mp, 0, ETHER_HDR_LEN, (void *) &eh2);
2152 m_adj(*mp, ETHER_HDR_LEN);
2153
2154 /* Strip off snap header, if present */
2155 if (snap) {
2156 m_copydata(*mp, 0, sizeof(struct llc), (void *) &llc1);
2157 m_adj(*mp, sizeof(struct llc));
2158 }
2159
2160 /*
2161 * Check basic packet sanity and run IPF through pfil.
2162 */
2163 KASSERT(!cpu_intr_p());
2164 switch (ether_type)
2165 {
2166 case ETHERTYPE_IP :
2167 error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0;
2168 if (error == 0)
2169 error = pfil_run_hooks(inet_pfil_hook, mp, ifp, dir);
2170 break;
2171 # ifdef INET6
2172 case ETHERTYPE_IPV6 :
2173 error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0;
2174 if (error == 0)
2175 error = pfil_run_hooks(inet6_pfil_hook, mp, ifp, dir);
2176 break;
2177 # endif
2178 default :
2179 error = 0;
2180 break;
2181 }
2182
2183 if (*mp == NULL)
2184 return error;
2185 if (error != 0)
2186 goto bad;
2187
2188 error = -1;
2189
2190 /*
2191 * Finally, put everything back the way it was and return
2192 */
2193 if (snap) {
2194 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2195 if (*mp == NULL)
2196 return error;
2197 bcopy(&llc1, mtod(*mp, void *), sizeof(struct llc));
2198 }
2199
2200 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2201 if (*mp == NULL)
2202 return error;
2203 bcopy(&eh2, mtod(*mp, void *), ETHER_HDR_LEN);
2204
2205 return 0;
2206
2207 bad:
2208 m_freem(*mp);
2209 *mp = NULL;
2210 return error;
2211 }
2212
2213 /*
2214 * Perform basic checks on header size since
2215 * IPF assumes ip_input has already processed
2216 * it for it. Cut-and-pasted from ip_input.c.
2217 * Given how simple the IPv6 version is,
2218 * does the IPv4 version really need to be
2219 * this complicated?
2220 *
2221 * XXX Should we update ipstat here, or not?
2222 * XXX Right now we update ipstat but not
2223 * XXX csum_counter.
2224 */
2225 static int
2226 bridge_ip_checkbasic(struct mbuf **mp)
2227 {
2228 struct mbuf *m = *mp;
2229 struct ip *ip;
2230 int len, hlen;
2231
2232 if (*mp == NULL)
2233 return -1;
2234
2235 if (IP_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
2236 if ((m = m_copyup(m, sizeof(struct ip),
2237 (max_linkhdr + 3) & ~3)) == NULL) {
2238 /* XXXJRT new stat, please */
2239 ip_statinc(IP_STAT_TOOSMALL);
2240 goto bad;
2241 }
2242 } else if (__predict_false(m->m_len < sizeof (struct ip))) {
2243 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2244 ip_statinc(IP_STAT_TOOSMALL);
2245 goto bad;
2246 }
2247 }
2248 ip = mtod(m, struct ip *);
2249 if (ip == NULL) goto bad;
2250
2251 if (ip->ip_v != IPVERSION) {
2252 ip_statinc(IP_STAT_BADVERS);
2253 goto bad;
2254 }
2255 hlen = ip->ip_hl << 2;
2256 if (hlen < sizeof(struct ip)) { /* minimum header length */
2257 ip_statinc(IP_STAT_BADHLEN);
2258 goto bad;
2259 }
2260 if (hlen > m->m_len) {
2261 if ((m = m_pullup(m, hlen)) == 0) {
2262 ip_statinc(IP_STAT_BADHLEN);
2263 goto bad;
2264 }
2265 ip = mtod(m, struct ip *);
2266 if (ip == NULL) goto bad;
2267 }
2268
2269 switch (m->m_pkthdr.csum_flags &
2270 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
2271 M_CSUM_IPv4_BAD)) {
2272 case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
2273 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */
2274 goto bad;
2275
2276 case M_CSUM_IPv4:
2277 /* Checksum was okay. */
2278 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */
2279 break;
2280
2281 default:
2282 /* Must compute it ourselves. */
2283 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */
2284 if (in_cksum(m, hlen) != 0)
2285 goto bad;
2286 break;
2287 }
2288
2289 /* Retrieve the packet length. */
2290 len = ntohs(ip->ip_len);
2291
2292 /*
2293 * Check for additional length bogosity
2294 */
2295 if (len < hlen) {
2296 ip_statinc(IP_STAT_BADLEN);
2297 goto bad;
2298 }
2299
2300 /*
2301 * Check that the amount of data in the buffers
2302 * is as at least much as the IP header would have us expect.
2303 * Drop packet if shorter than we expect.
2304 */
2305 if (m->m_pkthdr.len < len) {
2306 ip_statinc(IP_STAT_TOOSHORT);
2307 goto bad;
2308 }
2309
2310 /* Checks out, proceed */
2311 *mp = m;
2312 return 0;
2313
2314 bad:
2315 *mp = m;
2316 return -1;
2317 }
2318
2319 # ifdef INET6
2320 /*
2321 * Same as above, but for IPv6.
2322 * Cut-and-pasted from ip6_input.c.
2323 * XXX Should we update ip6stat, or not?
2324 */
2325 static int
2326 bridge_ip6_checkbasic(struct mbuf **mp)
2327 {
2328 struct mbuf *m = *mp;
2329 struct ip6_hdr *ip6;
2330
2331 /*
2332 * If the IPv6 header is not aligned, slurp it up into a new
2333 * mbuf with space for link headers, in the event we forward
2334 * it. Otherwise, if it is aligned, make sure the entire base
2335 * IPv6 header is in the first mbuf of the chain.
2336 */
2337 if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
2338 struct ifnet *inifp = m->m_pkthdr.rcvif;
2339 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2340 (max_linkhdr + 3) & ~3)) == NULL) {
2341 /* XXXJRT new stat, please */
2342 ip6_statinc(IP6_STAT_TOOSMALL);
2343 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2344 goto bad;
2345 }
2346 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2347 struct ifnet *inifp = m->m_pkthdr.rcvif;
2348 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2349 ip6_statinc(IP6_STAT_TOOSMALL);
2350 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2351 goto bad;
2352 }
2353 }
2354
2355 ip6 = mtod(m, struct ip6_hdr *);
2356
2357 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2358 ip6_statinc(IP6_STAT_BADVERS);
2359 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2360 goto bad;
2361 }
2362
2363 /* Checks out, proceed */
2364 *mp = m;
2365 return 0;
2366
2367 bad:
2368 *mp = m;
2369 return -1;
2370 }
2371 # endif /* INET6 */
2372 #endif /* BRIDGE_IPF */
2373