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