FreeBSD/Linux Kernel Cross Reference
sys/net/if_bridge.c
1 /* $NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc 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@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 __FBSDID("$FreeBSD: releng/6.0/sys/net/if_bridge.c 154808 2006-01-25 10:01:26Z cperciva $");
84
85 #include "opt_inet.h"
86 #include "opt_inet6.h"
87
88 #include <sys/param.h>
89 #include <sys/mbuf.h>
90 #include <sys/malloc.h>
91 #include <sys/protosw.h>
92 #include <sys/systm.h>
93 #include <sys/time.h>
94 #include <sys/socket.h> /* for net/if.h */
95 #include <sys/sockio.h>
96 #include <sys/ctype.h> /* string functions */
97 #include <sys/kernel.h>
98 #include <sys/random.h>
99 #include <sys/sysctl.h>
100 #include <vm/uma.h>
101 #include <sys/module.h>
102 #include <sys/proc.h>
103 #include <sys/lock.h>
104 #include <sys/mutex.h>
105
106 #include <net/bpf.h>
107 #include <net/if.h>
108 #include <net/if_clone.h>
109 #include <net/if_dl.h>
110 #include <net/if_types.h>
111 #include <net/if_var.h>
112 #include <net/pfil.h>
113
114 #include <netinet/in.h> /* for struct arpcom */
115 #include <netinet/in_systm.h>
116 #include <netinet/in_var.h>
117 #include <netinet/ip.h>
118 #include <netinet/ip_var.h>
119 #ifdef INET6
120 #include <netinet/ip6.h>
121 #include <netinet6/ip6_var.h>
122 #endif
123 #include <machine/in_cksum.h>
124 #include <netinet/if_ether.h> /* for struct arpcom */
125 #include <net/if_bridgevar.h>
126 #include <net/if_llc.h>
127
128 #include <net/route.h>
129 #include <netinet/ip_fw.h>
130 #include <netinet/ip_dummynet.h>
131
132 /*
133 * Size of the route hash table. Must be a power of two.
134 */
135 #ifndef BRIDGE_RTHASH_SIZE
136 #define BRIDGE_RTHASH_SIZE 1024
137 #endif
138
139 #define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1)
140
141 /*
142 * Maximum number of addresses to cache.
143 */
144 #ifndef BRIDGE_RTABLE_MAX
145 #define BRIDGE_RTABLE_MAX 100
146 #endif
147
148 /*
149 * Spanning tree defaults.
150 */
151 #define BSTP_DEFAULT_MAX_AGE (20 * 256)
152 #define BSTP_DEFAULT_HELLO_TIME (2 * 256)
153 #define BSTP_DEFAULT_FORWARD_DELAY (15 * 256)
154 #define BSTP_DEFAULT_HOLD_TIME (1 * 256)
155 #define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000
156 #define BSTP_DEFAULT_PORT_PRIORITY 0x80
157 #define BSTP_DEFAULT_PATH_COST 55
158
159 /*
160 * Timeout (in seconds) for entries learned dynamically.
161 */
162 #ifndef BRIDGE_RTABLE_TIMEOUT
163 #define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */
164 #endif
165
166 /*
167 * Number of seconds between walks of the route list.
168 */
169 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD
170 #define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60)
171 #endif
172
173 static struct mtx bridge_list_mtx;
174
175 int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
176
177 uma_zone_t bridge_rtnode_zone;
178
179 int bridge_clone_create(struct if_clone *, int);
180 void bridge_clone_destroy(struct ifnet *);
181
182 int bridge_ioctl(struct ifnet *, u_long, caddr_t);
183 void bridge_ifdetach(struct ifnet *);
184 static void bridge_init(void *);
185 void bridge_dummynet(struct mbuf *, struct ifnet *);
186 void bridge_stop(struct ifnet *, int);
187 void bridge_start(struct ifnet *);
188 struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
189 int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
190 struct rtentry *);
191
192 void bridge_forward(struct bridge_softc *, struct mbuf *m);
193
194 void bridge_timer(void *);
195
196 void bridge_broadcast(struct bridge_softc *, struct ifnet *, struct mbuf *,
197 int);
198
199 int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
200 struct ifnet *, int, uint8_t);
201 struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
202 void bridge_rttrim(struct bridge_softc *);
203 void bridge_rtage(struct bridge_softc *);
204 void bridge_rtflush(struct bridge_softc *, int);
205 int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
206
207 int bridge_rtable_init(struct bridge_softc *);
208 void bridge_rtable_fini(struct bridge_softc *);
209
210 struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
211 const uint8_t *);
212 int bridge_rtnode_insert(struct bridge_softc *, struct bridge_rtnode *);
213 void bridge_rtnode_destroy(struct bridge_softc *, struct bridge_rtnode *);
214
215 struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
216 const char *name);
217 struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
218 struct ifnet *ifp);
219 void bridge_delete_member(struct bridge_softc *, struct bridge_iflist *,
220 int);
221
222 int bridge_ioctl_add(struct bridge_softc *, void *);
223 int bridge_ioctl_del(struct bridge_softc *, void *);
224 int bridge_ioctl_gifflags(struct bridge_softc *, void *);
225 int bridge_ioctl_sifflags(struct bridge_softc *, void *);
226 int bridge_ioctl_scache(struct bridge_softc *, void *);
227 int bridge_ioctl_gcache(struct bridge_softc *, void *);
228 int bridge_ioctl_gifs(struct bridge_softc *, void *);
229 int bridge_ioctl_rts(struct bridge_softc *, void *);
230 int bridge_ioctl_saddr(struct bridge_softc *, void *);
231 int bridge_ioctl_sto(struct bridge_softc *, void *);
232 int bridge_ioctl_gto(struct bridge_softc *, void *);
233 int bridge_ioctl_daddr(struct bridge_softc *, void *);
234 int bridge_ioctl_flush(struct bridge_softc *, void *);
235 int bridge_ioctl_gpri(struct bridge_softc *, void *);
236 int bridge_ioctl_spri(struct bridge_softc *, void *);
237 int bridge_ioctl_ght(struct bridge_softc *, void *);
238 int bridge_ioctl_sht(struct bridge_softc *, void *);
239 int bridge_ioctl_gfd(struct bridge_softc *, void *);
240 int bridge_ioctl_sfd(struct bridge_softc *, void *);
241 int bridge_ioctl_gma(struct bridge_softc *, void *);
242 int bridge_ioctl_sma(struct bridge_softc *, void *);
243 int bridge_ioctl_sifprio(struct bridge_softc *, void *);
244 int bridge_ioctl_sifcost(struct bridge_softc *, void *);
245 static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *, int);
246 static int bridge_ip_checkbasic(struct mbuf **mp);
247 # ifdef INET6
248 static int bridge_ip6_checkbasic(struct mbuf **mp);
249 # endif /* INET6 */
250
251 SYSCTL_DECL(_net_link);
252 SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
253
254 static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
255 static int pfil_member = 1; /* run pfil hooks on the member interface */
256 static int pfil_ipfw = 0; /* layer2 filter with ipfw */
257 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
258 &pfil_bridge, 0, "Packet filter on the bridge interface");
259 SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
260 &pfil_member, 0, "Packet filter on the member interface");
261
262 struct bridge_control {
263 int (*bc_func)(struct bridge_softc *, void *);
264 int bc_argsize;
265 int bc_flags;
266 };
267
268 #define BC_F_COPYIN 0x01 /* copy arguments in */
269 #define BC_F_COPYOUT 0x02 /* copy arguments out */
270 #define BC_F_SUSER 0x04 /* do super-user check */
271
272 const struct bridge_control bridge_control_table[] = {
273 { bridge_ioctl_add, sizeof(struct ifbreq),
274 BC_F_COPYIN|BC_F_SUSER },
275 { bridge_ioctl_del, sizeof(struct ifbreq),
276 BC_F_COPYIN|BC_F_SUSER },
277
278 { bridge_ioctl_gifflags, sizeof(struct ifbreq),
279 BC_F_COPYIN|BC_F_COPYOUT },
280 { bridge_ioctl_sifflags, sizeof(struct ifbreq),
281 BC_F_COPYIN|BC_F_SUSER },
282
283 { bridge_ioctl_scache, sizeof(struct ifbrparam),
284 BC_F_COPYIN|BC_F_SUSER },
285 { bridge_ioctl_gcache, sizeof(struct ifbrparam),
286 BC_F_COPYOUT },
287
288 { bridge_ioctl_gifs, sizeof(struct ifbifconf),
289 BC_F_COPYIN|BC_F_COPYOUT },
290 { bridge_ioctl_rts, sizeof(struct ifbaconf),
291 BC_F_COPYIN|BC_F_COPYOUT },
292
293 { bridge_ioctl_saddr, sizeof(struct ifbareq),
294 BC_F_COPYIN|BC_F_SUSER },
295
296 { bridge_ioctl_sto, sizeof(struct ifbrparam),
297 BC_F_COPYIN|BC_F_SUSER },
298 { bridge_ioctl_gto, sizeof(struct ifbrparam),
299 BC_F_COPYOUT },
300
301 { bridge_ioctl_daddr, sizeof(struct ifbareq),
302 BC_F_COPYIN|BC_F_SUSER },
303
304 { bridge_ioctl_flush, sizeof(struct ifbreq),
305 BC_F_COPYIN|BC_F_SUSER },
306
307 { bridge_ioctl_gpri, sizeof(struct ifbrparam),
308 BC_F_COPYOUT },
309 { bridge_ioctl_spri, sizeof(struct ifbrparam),
310 BC_F_COPYIN|BC_F_SUSER },
311
312 { bridge_ioctl_ght, sizeof(struct ifbrparam),
313 BC_F_COPYOUT },
314 { bridge_ioctl_sht, sizeof(struct ifbrparam),
315 BC_F_COPYIN|BC_F_SUSER },
316
317 { bridge_ioctl_gfd, sizeof(struct ifbrparam),
318 BC_F_COPYOUT },
319 { bridge_ioctl_sfd, sizeof(struct ifbrparam),
320 BC_F_COPYIN|BC_F_SUSER },
321
322 { bridge_ioctl_gma, sizeof(struct ifbrparam),
323 BC_F_COPYOUT },
324 { bridge_ioctl_sma, sizeof(struct ifbrparam),
325 BC_F_COPYIN|BC_F_SUSER },
326
327 { bridge_ioctl_sifprio, sizeof(struct ifbreq),
328 BC_F_COPYIN|BC_F_SUSER },
329
330 { bridge_ioctl_sifcost, sizeof(struct ifbreq),
331 BC_F_COPYIN|BC_F_SUSER },
332 };
333 const int bridge_control_table_size =
334 sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
335
336 static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
337 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
338
339 LIST_HEAD(, bridge_softc) bridge_list;
340
341 IFC_SIMPLE_DECLARE(bridge, 0);
342
343 static int
344 bridge_modevent(module_t mod, int type, void *data)
345 {
346
347 switch (type) {
348 case MOD_LOAD:
349 mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
350 if_clone_attach(&bridge_cloner);
351 bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
352 sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
353 UMA_ALIGN_PTR, 0);
354 LIST_INIT(&bridge_list);
355 bridge_input_p = bridge_input;
356 bridge_output_p = bridge_output;
357 bridge_dn_p = bridge_dummynet;
358 bridge_detach_p = bridge_ifdetach;
359 bstp_linkstate_p = bstp_linkstate;
360 break;
361 case MOD_UNLOAD:
362 if_clone_detach(&bridge_cloner);
363 while (!LIST_EMPTY(&bridge_list))
364 bridge_clone_destroy(LIST_FIRST(&bridge_list)->sc_ifp);
365 uma_zdestroy(bridge_rtnode_zone);
366 bridge_input_p = NULL;
367 bridge_output_p = NULL;
368 bridge_dn_p = NULL;
369 bridge_detach_p = NULL;
370 bstp_linkstate_p = NULL;
371 mtx_destroy(&bridge_list_mtx);
372 break;
373 default:
374 return EOPNOTSUPP;
375 }
376 return 0;
377 }
378
379 static moduledata_t bridge_mod = {
380 "if_bridge",
381 bridge_modevent,
382 0
383 };
384
385 DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
386
387 /*
388 * handler for net.link.bridge.pfil_ipfw
389 */
390 static int
391 sysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS)
392 {
393 int enable = pfil_ipfw;
394 int error;
395
396 error = sysctl_handle_int(oidp, &enable, 0, req);
397 enable = (enable) ? 1 : 0;
398
399 if (enable != pfil_ipfw) {
400 pfil_ipfw = enable;
401
402 /*
403 * Disable pfil so that ipfw doesnt run twice, if the user really wants
404 * both then they can re-enable pfil_bridge and/or pfil_member.
405 */
406 if (pfil_ipfw) {
407 pfil_bridge = 0;
408 pfil_member = 0;
409 }
410 }
411
412 return error;
413 }
414 SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
415 &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW");
416
417 /*
418 * bridge_clone_create:
419 *
420 * Create a new bridge instance.
421 */
422 int
423 bridge_clone_create(struct if_clone *ifc, int unit)
424 {
425 struct bridge_softc *sc;
426 struct ifnet *ifp;
427 u_char eaddr[6];
428
429 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
430 BRIDGE_LOCK_INIT(sc);
431 ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
432 if (ifp == NULL) {
433 free(sc, M_DEVBUF);
434 return (ENOSPC);
435 }
436
437 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
438 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
439 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
440 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
441 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
442 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
443 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
444
445 /* Initialize our routing table. */
446 bridge_rtable_init(sc);
447
448 callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
449 callout_init_mtx(&sc->sc_bstpcallout, &sc->sc_mtx, 0);
450
451 LIST_INIT(&sc->sc_iflist);
452
453 ifp->if_softc = sc;
454 if_initname(ifp, ifc->ifc_name, unit);
455 ifp->if_mtu = ETHERMTU;
456 ifp->if_flags = IFF_MULTICAST;
457 ifp->if_ioctl = bridge_ioctl;
458 ifp->if_output = bridge_output;
459 ifp->if_start = bridge_start;
460 ifp->if_init = bridge_init;
461 ifp->if_type = IFT_BRIDGE;
462 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
463 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
464 IFQ_SET_READY(&ifp->if_snd);
465 ifp->if_hdrlen = ETHER_HDR_LEN;
466
467 /*
468 * Generate a random ethernet address and use the private AC:DE:48
469 * OUI code.
470 */
471 arc4rand(eaddr, ETHER_ADDR_LEN, 1);
472 eaddr[0] = 0xAC;
473 eaddr[1] = 0xDE;
474 eaddr[2] = 0x48;
475
476 ether_ifattach(ifp, eaddr);
477 /* Now undo some of the damage... */
478 ifp->if_baudrate = 0;
479 ifp->if_type = IFT_BRIDGE;
480
481 mtx_lock(&bridge_list_mtx);
482 LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
483 mtx_unlock(&bridge_list_mtx);
484
485 return (0);
486 }
487
488 /*
489 * bridge_clone_destroy:
490 *
491 * Destroy a bridge instance.
492 */
493 void
494 bridge_clone_destroy(struct ifnet *ifp)
495 {
496 struct bridge_softc *sc = ifp->if_softc;
497 struct bridge_iflist *bif;
498
499 BRIDGE_LOCK(sc);
500
501 bridge_stop(ifp, 1);
502 ifp->if_flags &= ~IFF_UP;
503
504 while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
505 bridge_delete_member(sc, bif, 0);
506
507 BRIDGE_UNLOCK(sc);
508
509 callout_drain(&sc->sc_brcallout);
510 callout_drain(&sc->sc_bstpcallout);
511
512 mtx_lock(&bridge_list_mtx);
513 LIST_REMOVE(sc, sc_list);
514 mtx_unlock(&bridge_list_mtx);
515
516 ether_ifdetach(ifp);
517 if_free_type(ifp, IFT_ETHER);
518
519 /* Tear down the routing table. */
520 bridge_rtable_fini(sc);
521
522 BRIDGE_LOCK_DESTROY(sc);
523 free(sc, M_DEVBUF);
524 }
525
526 /*
527 * bridge_ioctl:
528 *
529 * Handle a control request from the operator.
530 */
531 int
532 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
533 {
534 struct bridge_softc *sc = ifp->if_softc;
535 struct thread *td = curthread;
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;
545 int error = 0;
546
547 BRIDGE_LOCK(sc);
548
549 switch (cmd) {
550
551 case SIOCADDMULTI:
552 case SIOCDELMULTI:
553 break;
554
555 case SIOCGDRVSPEC:
556 case SIOCSDRVSPEC:
557 if (ifd->ifd_cmd >= bridge_control_table_size) {
558 error = EINVAL;
559 break;
560 }
561 bc = &bridge_control_table[ifd->ifd_cmd];
562
563 if (cmd == SIOCGDRVSPEC &&
564 (bc->bc_flags & BC_F_COPYOUT) == 0) {
565 error = EINVAL;
566 break;
567 }
568 else if (cmd == SIOCSDRVSPEC &&
569 (bc->bc_flags & BC_F_COPYOUT) != 0) {
570 error = EINVAL;
571 break;
572 }
573
574 if (bc->bc_flags & BC_F_SUSER) {
575 error = suser(td);
576 if (error)
577 break;
578 }
579
580 if (ifd->ifd_len != bc->bc_argsize ||
581 ifd->ifd_len > sizeof(args)) {
582 error = EINVAL;
583 break;
584 }
585
586 bzero(&args, sizeof args);
587 if (bc->bc_flags & BC_F_COPYIN) {
588 error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
589 if (error)
590 break;
591 }
592
593 error = (*bc->bc_func)(sc, &args);
594 if (error)
595 break;
596
597 if (bc->bc_flags & BC_F_COPYOUT)
598 error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
599
600 break;
601
602 case SIOCSIFFLAGS:
603 if (!(ifp->if_flags & IFF_UP) &&
604 (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
605 /*
606 * If interface is marked down and it is running,
607 * then stop and disable it.
608 */
609 bridge_stop(ifp, 1);
610 } else if ((ifp->if_flags & IFF_UP) &&
611 !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
612 /*
613 * If interface is marked up and it is stopped, then
614 * start it.
615 */
616 BRIDGE_UNLOCK(sc);
617 (*ifp->if_init)(sc);
618 }
619 break;
620
621 case SIOCSIFMTU:
622 /* Do not allow the MTU to be changed on the bridge */
623 error = EINVAL;
624 break;
625
626 default:
627 /*
628 * drop the lock as ether_ioctl() will call bridge_start() and
629 * cause the lock to be recursed.
630 */
631 BRIDGE_UNLOCK(sc);
632 error = ether_ioctl(ifp, cmd, data);
633 break;
634 }
635
636 if (BRIDGE_LOCKED(sc))
637 BRIDGE_UNLOCK(sc);
638
639 return (error);
640 }
641
642 /*
643 * bridge_lookup_member:
644 *
645 * Lookup a bridge member interface.
646 */
647 struct bridge_iflist *
648 bridge_lookup_member(struct bridge_softc *sc, const char *name)
649 {
650 struct bridge_iflist *bif;
651 struct ifnet *ifp;
652
653 BRIDGE_LOCK_ASSERT(sc);
654
655 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
656 ifp = bif->bif_ifp;
657 if (strcmp(ifp->if_xname, name) == 0)
658 return (bif);
659 }
660
661 return (NULL);
662 }
663
664 /*
665 * bridge_lookup_member_if:
666 *
667 * Lookup a bridge member interface by ifnet*.
668 */
669 struct bridge_iflist *
670 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
671 {
672 struct bridge_iflist *bif;
673
674 BRIDGE_LOCK_ASSERT(sc);
675
676 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
677 if (bif->bif_ifp == member_ifp)
678 return (bif);
679 }
680
681 return (NULL);
682 }
683
684 /*
685 * bridge_delete_member:
686 *
687 * Delete the specified member interface.
688 */
689 void
690 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
691 int gone)
692 {
693 struct ifnet *ifs = bif->bif_ifp;
694
695 BRIDGE_LOCK_ASSERT(sc);
696
697 if (!gone) {
698 switch (ifs->if_type) {
699 case IFT_ETHER:
700 case IFT_L2VLAN:
701 /*
702 * Take the interface out of promiscuous mode.
703 */
704 (void) ifpromisc(ifs, 0);
705 break;
706
707 default:
708 #ifdef DIAGNOSTIC
709 panic("bridge_delete_member: impossible");
710 #endif
711 break;
712 }
713 }
714
715 ifs->if_bridge = NULL;
716 BRIDGE_XLOCK(sc);
717 LIST_REMOVE(bif, bif_next);
718 BRIDGE_XDROP(sc);
719
720 bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
721
722 free(bif, M_DEVBUF);
723
724 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
725 bstp_initialization(sc);
726 }
727
728 int
729 bridge_ioctl_add(struct bridge_softc *sc, void *arg)
730 {
731 struct ifbreq *req = arg;
732 struct bridge_iflist *bif = NULL;
733 struct ifnet *ifs;
734 int error = 0;
735
736 BRIDGE_LOCK_ASSERT(sc);
737
738 ifs = ifunit(req->ifbr_ifsname);
739 if (ifs == NULL)
740 return (ENOENT);
741
742 /* Allow the first member to define the MTU */
743 if (LIST_EMPTY(&sc->sc_iflist))
744 sc->sc_ifp->if_mtu = ifs->if_mtu;
745 else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
746 if_printf(sc->sc_ifp, "invalid MTU for %s\n", ifs->if_xname);
747 return (EINVAL);
748 }
749
750 if (ifs->if_bridge == sc)
751 return (EEXIST);
752
753 if (ifs->if_bridge != NULL)
754 return (EBUSY);
755
756 bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
757 if (bif == NULL)
758 return (ENOMEM);
759
760 switch (ifs->if_type) {
761 case IFT_ETHER:
762 case IFT_L2VLAN:
763 /*
764 * Place the interface into promiscuous mode.
765 */
766 error = ifpromisc(ifs, 1);
767 if (error)
768 goto out;
769 break;
770
771 default:
772 error = EINVAL;
773 goto out;
774 }
775
776 bif->bif_ifp = ifs;
777 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
778 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
779 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
780
781 ifs->if_bridge = sc;
782 /*
783 * XXX: XLOCK HERE!?!
784 *
785 * NOTE: insert_***HEAD*** should be safe for the traversals.
786 */
787 LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
788
789 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
790 bstp_initialization(sc);
791 else
792 bstp_stop(sc);
793
794 out:
795 if (error) {
796 if (bif != NULL)
797 free(bif, M_DEVBUF);
798 }
799 return (error);
800 }
801
802 int
803 bridge_ioctl_del(struct bridge_softc *sc, void *arg)
804 {
805 struct ifbreq *req = arg;
806 struct bridge_iflist *bif;
807
808 BRIDGE_LOCK_ASSERT(sc);
809
810 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
811 if (bif == NULL)
812 return (ENOENT);
813
814 bridge_delete_member(sc, bif, 0);
815
816 return (0);
817 }
818
819 int
820 bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
821 {
822 struct ifbreq *req = arg;
823 struct bridge_iflist *bif;
824
825 BRIDGE_LOCK_ASSERT(sc);
826
827 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
828 if (bif == NULL)
829 return (ENOENT);
830
831 req->ifbr_ifsflags = bif->bif_flags;
832 req->ifbr_state = bif->bif_state;
833 req->ifbr_priority = bif->bif_priority;
834 req->ifbr_path_cost = bif->bif_path_cost;
835 req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
836
837 return (0);
838 }
839
840 int
841 bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
842 {
843 struct ifbreq *req = arg;
844 struct bridge_iflist *bif;
845
846 BRIDGE_LOCK_ASSERT(sc);
847
848 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
849 if (bif == NULL)
850 return (ENOENT);
851
852 if (req->ifbr_ifsflags & IFBIF_STP) {
853 switch (bif->bif_ifp->if_type) {
854 case IFT_ETHER:
855 /* These can do spanning tree. */
856 break;
857
858 default:
859 /* Nothing else can. */
860 return (EINVAL);
861 }
862 }
863
864 bif->bif_flags = req->ifbr_ifsflags;
865
866 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
867 bstp_initialization(sc);
868
869 return (0);
870 }
871
872 int
873 bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
874 {
875 struct ifbrparam *param = arg;
876
877 BRIDGE_LOCK_ASSERT(sc);
878
879 sc->sc_brtmax = param->ifbrp_csize;
880 bridge_rttrim(sc);
881
882 return (0);
883 }
884
885 int
886 bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
887 {
888 struct ifbrparam *param = arg;
889
890 BRIDGE_LOCK_ASSERT(sc);
891
892 param->ifbrp_csize = sc->sc_brtmax;
893
894 return (0);
895 }
896
897 int
898 bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
899 {
900 struct ifbifconf *bifc = arg;
901 struct bridge_iflist *bif;
902 struct ifbreq breq;
903 int count, len, error = 0;
904
905 BRIDGE_LOCK_ASSERT(sc);
906
907 count = 0;
908 LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
909 count++;
910
911 if (bifc->ifbic_len == 0) {
912 bifc->ifbic_len = sizeof(breq) * count;
913 return (0);
914 }
915
916 count = 0;
917 len = bifc->ifbic_len;
918 bzero(&breq, sizeof breq);
919 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
920 if (len < sizeof(breq))
921 break;
922
923 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
924 sizeof(breq.ifbr_ifsname));
925 breq.ifbr_ifsflags = bif->bif_flags;
926 breq.ifbr_state = bif->bif_state;
927 breq.ifbr_priority = bif->bif_priority;
928 breq.ifbr_path_cost = bif->bif_path_cost;
929 breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
930 error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
931 if (error)
932 break;
933 count++;
934 len -= sizeof(breq);
935 }
936
937 bifc->ifbic_len = sizeof(breq) * count;
938 return (error);
939 }
940
941 int
942 bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
943 {
944 struct ifbaconf *bac = arg;
945 struct bridge_rtnode *brt;
946 struct ifbareq bareq;
947 struct timeval tv;
948 int count = 0, error = 0, len;
949
950 BRIDGE_LOCK_ASSERT(sc);
951
952 if (bac->ifbac_len == 0)
953 return (0);
954
955 getmicrotime(&tv);
956
957 len = bac->ifbac_len;
958 bzero(&bareq, sizeof bareq);
959 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
960 if (len < sizeof(bareq))
961 goto out;
962 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
963 sizeof(bareq.ifba_ifsname));
964 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
965 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
966 tv.tv_sec < brt->brt_expire)
967 bareq.ifba_expire = brt->brt_expire - tv.tv_sec;
968 else
969 bareq.ifba_expire = 0;
970 bareq.ifba_flags = brt->brt_flags;
971
972 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
973 if (error)
974 goto out;
975 count++;
976 len -= sizeof(bareq);
977 }
978 out:
979 bac->ifbac_len = sizeof(bareq) * count;
980 return (error);
981 }
982
983 int
984 bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
985 {
986 struct ifbareq *req = arg;
987 struct bridge_iflist *bif;
988 int error;
989
990 BRIDGE_LOCK_ASSERT(sc);
991
992 bif = bridge_lookup_member(sc, req->ifba_ifsname);
993 if (bif == NULL)
994 return (ENOENT);
995
996 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
997 req->ifba_flags);
998
999 return (error);
1000 }
1001
1002 int
1003 bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
1004 {
1005 struct ifbrparam *param = arg;
1006
1007 BRIDGE_LOCK_ASSERT(sc);
1008
1009 sc->sc_brttimeout = param->ifbrp_ctime;
1010
1011 return (0);
1012 }
1013
1014 int
1015 bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
1016 {
1017 struct ifbrparam *param = arg;
1018
1019 BRIDGE_LOCK_ASSERT(sc);
1020
1021 param->ifbrp_ctime = sc->sc_brttimeout;
1022
1023 return (0);
1024 }
1025
1026 int
1027 bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
1028 {
1029 struct ifbareq *req = arg;
1030
1031 BRIDGE_LOCK_ASSERT(sc);
1032
1033 return (bridge_rtdaddr(sc, req->ifba_dst));
1034 }
1035
1036 int
1037 bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
1038 {
1039 struct ifbreq *req = arg;
1040
1041 BRIDGE_LOCK_ASSERT(sc);
1042
1043 bridge_rtflush(sc, req->ifbr_ifsflags);
1044
1045 return (0);
1046 }
1047
1048 int
1049 bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1050 {
1051 struct ifbrparam *param = arg;
1052
1053 BRIDGE_LOCK_ASSERT(sc);
1054
1055 param->ifbrp_prio = sc->sc_bridge_priority;
1056
1057 return (0);
1058 }
1059
1060 int
1061 bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1062 {
1063 struct ifbrparam *param = arg;
1064
1065 BRIDGE_LOCK_ASSERT(sc);
1066
1067 sc->sc_bridge_priority = param->ifbrp_prio;
1068
1069 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1070 bstp_initialization(sc);
1071
1072 return (0);
1073 }
1074
1075 int
1076 bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1077 {
1078 struct ifbrparam *param = arg;
1079
1080 BRIDGE_LOCK_ASSERT(sc);
1081
1082 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
1083
1084 return (0);
1085 }
1086
1087 int
1088 bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1089 {
1090 struct ifbrparam *param = arg;
1091
1092 BRIDGE_LOCK_ASSERT(sc);
1093
1094 if (param->ifbrp_hellotime == 0)
1095 return (EINVAL);
1096 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
1097
1098 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1099 bstp_initialization(sc);
1100
1101 return (0);
1102 }
1103
1104 int
1105 bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1106 {
1107 struct ifbrparam *param = arg;
1108
1109 BRIDGE_LOCK_ASSERT(sc);
1110
1111 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
1112
1113 return (0);
1114 }
1115
1116 int
1117 bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1118 {
1119 struct ifbrparam *param = arg;
1120
1121 BRIDGE_LOCK_ASSERT(sc);
1122
1123 if (param->ifbrp_fwddelay == 0)
1124 return (EINVAL);
1125 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
1126
1127 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1128 bstp_initialization(sc);
1129
1130 return (0);
1131 }
1132
1133 int
1134 bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1135 {
1136 struct ifbrparam *param = arg;
1137
1138 BRIDGE_LOCK_ASSERT(sc);
1139
1140 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
1141
1142 return (0);
1143 }
1144
1145 int
1146 bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1147 {
1148 struct ifbrparam *param = arg;
1149
1150 BRIDGE_LOCK_ASSERT(sc);
1151
1152 if (param->ifbrp_maxage == 0)
1153 return (EINVAL);
1154 sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
1155
1156 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1157 bstp_initialization(sc);
1158
1159 return (0);
1160 }
1161
1162 int
1163 bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1164 {
1165 struct ifbreq *req = arg;
1166 struct bridge_iflist *bif;
1167
1168 BRIDGE_LOCK_ASSERT(sc);
1169
1170 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1171 if (bif == NULL)
1172 return (ENOENT);
1173
1174 bif->bif_priority = req->ifbr_priority;
1175
1176 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1177 bstp_initialization(sc);
1178
1179 return (0);
1180 }
1181
1182 int
1183 bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1184 {
1185 struct ifbreq *req = arg;
1186 struct bridge_iflist *bif;
1187
1188 BRIDGE_LOCK_ASSERT(sc);
1189
1190 bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1191 if (bif == NULL)
1192 return (ENOENT);
1193
1194 bif->bif_path_cost = req->ifbr_path_cost;
1195
1196 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1197 bstp_initialization(sc);
1198
1199 return (0);
1200 }
1201
1202 /*
1203 * bridge_ifdetach:
1204 *
1205 * Detach an interface from a bridge. Called when a member
1206 * interface is detaching.
1207 */
1208 void
1209 bridge_ifdetach(struct ifnet *ifp)
1210 {
1211 struct bridge_softc *sc = ifp->if_bridge;
1212 struct bridge_iflist *bif;
1213
1214 BRIDGE_LOCK(sc);
1215
1216 bif = bridge_lookup_member_if(sc, ifp);
1217 if (bif == NULL)
1218 return;
1219
1220 bridge_delete_member(sc, bif, 1);
1221
1222 BRIDGE_UNLOCK(sc);
1223 }
1224
1225 /*
1226 * bridge_init:
1227 *
1228 * Initialize a bridge interface.
1229 */
1230 static void
1231 bridge_init(void *xsc)
1232 {
1233 struct bridge_softc *sc = (struct bridge_softc *)xsc;
1234 struct ifnet *ifp = sc->sc_ifp;
1235
1236 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1237 return;
1238
1239 BRIDGE_LOCK(sc);
1240 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1241 bridge_timer, sc);
1242
1243 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1244 bstp_initialization(sc);
1245 BRIDGE_UNLOCK(sc);
1246 return;
1247 }
1248
1249 /*
1250 * bridge_stop:
1251 *
1252 * Stop the bridge interface.
1253 */
1254 void
1255 bridge_stop(struct ifnet *ifp, int disable)
1256 {
1257 struct bridge_softc *sc = ifp->if_softc;
1258
1259 BRIDGE_LOCK_ASSERT(sc);
1260
1261 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1262 return;
1263
1264 callout_stop(&sc->sc_brcallout);
1265 bstp_stop(sc);
1266
1267 bridge_rtflush(sc, IFBF_FLUSHDYN);
1268
1269 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1270 }
1271
1272 /*
1273 * bridge_enqueue:
1274 *
1275 * Enqueue a packet on a bridge member interface.
1276 *
1277 */
1278 __inline void
1279 bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
1280 {
1281 int len, err;
1282 short mflags;
1283
1284 /*
1285 * Clear any in-bound checksum flags for this packet.
1286 */
1287 m->m_pkthdr.csum_flags = 0;
1288
1289 len = m->m_pkthdr.len;
1290 mflags = m->m_flags;
1291
1292 IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
1293 if (err == 0) {
1294
1295 sc->sc_ifp->if_opackets++;
1296 sc->sc_ifp->if_obytes += len;
1297
1298 dst_ifp->if_obytes += len;
1299
1300 if (mflags & M_MCAST) {
1301 sc->sc_ifp->if_omcasts++;
1302 dst_ifp->if_omcasts++;
1303 }
1304 }
1305
1306 if ((dst_ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
1307 (*dst_ifp->if_start)(dst_ifp);
1308 }
1309
1310 /*
1311 * bridge_dummynet:
1312 *
1313 * Receive a queued packet from dummynet and pass it on to the output
1314 * interface.
1315 *
1316 * The mbuf has the Ethernet header already attached.
1317 */
1318 void
1319 bridge_dummynet(struct mbuf *m, struct ifnet *ifp)
1320 {
1321 struct bridge_softc *sc;
1322
1323 sc = ifp->if_bridge;
1324
1325 /*
1326 * The packet didnt originate from a member interface. This should only
1327 * ever happen if a member interface is removed while packets are
1328 * queued for it.
1329 */
1330 if (sc == NULL) {
1331 m_freem(m);
1332 return;
1333 }
1334
1335 if (inet_pfil_hook.ph_busy_count >= 0
1336 #ifdef INET6
1337 || inet6_pfil_hook.ph_busy_count >= 0
1338 #endif
1339 ) {
1340 if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0)
1341 return;
1342 if (m == NULL)
1343 return;
1344 }
1345
1346 bridge_enqueue(sc, ifp, m);
1347 }
1348
1349 /*
1350 * bridge_output:
1351 *
1352 * Send output from a bridge member interface. This
1353 * performs the bridging function for locally originated
1354 * packets.
1355 *
1356 * The mbuf has the Ethernet header already attached. We must
1357 * enqueue or free the mbuf before returning.
1358 */
1359 int
1360 bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
1361 struct rtentry *rt)
1362 {
1363 struct ether_header *eh;
1364 struct ifnet *dst_if;
1365 struct bridge_softc *sc;
1366
1367 if (m->m_len < ETHER_HDR_LEN) {
1368 m = m_pullup(m, ETHER_HDR_LEN);
1369 if (m == NULL)
1370 return (0);
1371 }
1372
1373 eh = mtod(m, struct ether_header *);
1374 sc = ifp->if_bridge;
1375
1376 BRIDGE_LOCK(sc);
1377
1378 /*
1379 * If bridge is down, but the original output interface is up,
1380 * go ahead and send out that interface. Otherwise, the packet
1381 * is dropped below.
1382 */
1383 if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1384 dst_if = ifp;
1385 goto sendunicast;
1386 }
1387
1388 /*
1389 * If the packet is a multicast, or we don't know a better way to
1390 * get there, send to all interfaces.
1391 */
1392 if (ETHER_IS_MULTICAST(eh->ether_dhost))
1393 dst_if = NULL;
1394 else
1395 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1396 if (dst_if == NULL) {
1397 struct bridge_iflist *bif;
1398 struct mbuf *mc;
1399 int error = 0, used = 0;
1400
1401 BRIDGE_LOCK2REF(sc, error);
1402 if (error) {
1403 m_freem(m);
1404 return (0);
1405 }
1406 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1407 dst_if = bif->bif_ifp;
1408 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
1409 continue;
1410
1411 /*
1412 * If this is not the original output interface,
1413 * and the interface is participating in spanning
1414 * tree, make sure the port is in a state that
1415 * allows forwarding.
1416 */
1417 if (dst_if != ifp &&
1418 (bif->bif_flags & IFBIF_STP) != 0) {
1419 switch (bif->bif_state) {
1420 case BSTP_IFSTATE_BLOCKING:
1421 case BSTP_IFSTATE_LISTENING:
1422 case BSTP_IFSTATE_DISABLED:
1423 continue;
1424 }
1425 }
1426
1427 if (LIST_NEXT(bif, bif_next) == NULL) {
1428 used = 1;
1429 mc = m;
1430 } else {
1431 mc = m_copypacket(m, M_DONTWAIT);
1432 if (mc == NULL) {
1433 sc->sc_ifp->if_oerrors++;
1434 continue;
1435 }
1436 }
1437
1438 bridge_enqueue(sc, dst_if, mc);
1439 }
1440 if (used == 0)
1441 m_freem(m);
1442 BRIDGE_UNREF(sc);
1443 return (0);
1444 }
1445
1446 sendunicast:
1447 /*
1448 * XXX Spanning tree consideration here?
1449 */
1450
1451 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1452 m_freem(m);
1453 BRIDGE_UNLOCK(sc);
1454 return (0);
1455 }
1456
1457 BRIDGE_UNLOCK(sc);
1458 bridge_enqueue(sc, dst_if, m);
1459 return (0);
1460 }
1461
1462 /*
1463 * bridge_start:
1464 *
1465 * Start output on a bridge.
1466 *
1467 */
1468 void
1469 bridge_start(struct ifnet *ifp)
1470 {
1471 struct bridge_softc *sc;
1472 struct mbuf *m;
1473 struct ether_header *eh;
1474 struct ifnet *dst_if;
1475
1476 sc = ifp->if_softc;
1477
1478 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1479 for (;;) {
1480 IFQ_DEQUEUE(&ifp->if_snd, m);
1481 if (m == 0)
1482 break;
1483 BPF_MTAP(ifp, m);
1484
1485 eh = mtod(m, struct ether_header *);
1486 dst_if = NULL;
1487
1488 BRIDGE_LOCK(sc);
1489 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1490 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1491 }
1492
1493 if (dst_if == NULL)
1494 bridge_broadcast(sc, ifp, m, 0);
1495 else {
1496 BRIDGE_UNLOCK(sc);
1497 bridge_enqueue(sc, dst_if, m);
1498 }
1499 }
1500 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1501
1502 return;
1503 }
1504
1505 /*
1506 * bridge_forward:
1507 *
1508 * The forwarding function of the bridge.
1509 *
1510 * NOTE: Releases the lock on return.
1511 */
1512 void
1513 bridge_forward(struct bridge_softc *sc, struct mbuf *m)
1514 {
1515 struct bridge_iflist *bif;
1516 struct ifnet *src_if, *dst_if, *ifp;
1517 struct ether_header *eh;
1518
1519 src_if = m->m_pkthdr.rcvif;
1520 BRIDGE_LOCK_ASSERT(sc);
1521 ifp = sc->sc_ifp;
1522
1523 sc->sc_ifp->if_ipackets++;
1524 sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
1525
1526 /*
1527 * Look up the bridge_iflist.
1528 */
1529 bif = bridge_lookup_member_if(sc, src_if);
1530 if (bif == NULL) {
1531 /* Interface is not a bridge member (anymore?) */
1532 BRIDGE_UNLOCK(sc);
1533 m_freem(m);
1534 return;
1535 }
1536
1537 if (bif->bif_flags & IFBIF_STP) {
1538 switch (bif->bif_state) {
1539 case BSTP_IFSTATE_BLOCKING:
1540 case BSTP_IFSTATE_LISTENING:
1541 case BSTP_IFSTATE_DISABLED:
1542 BRIDGE_UNLOCK(sc);
1543 m_freem(m);
1544 return;
1545 }
1546 }
1547
1548 eh = mtod(m, struct ether_header *);
1549
1550 /*
1551 * If the interface is learning, and the source
1552 * address is valid and not multicast, record
1553 * the address.
1554 */
1555 if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1556 ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
1557 (eh->ether_shost[0] == 0 &&
1558 eh->ether_shost[1] == 0 &&
1559 eh->ether_shost[2] == 0 &&
1560 eh->ether_shost[3] == 0 &&
1561 eh->ether_shost[4] == 0 &&
1562 eh->ether_shost[5] == 0) == 0) {
1563 (void) bridge_rtupdate(sc, eh->ether_shost,
1564 src_if, 0, IFBAF_DYNAMIC);
1565 }
1566
1567 if ((bif->bif_flags & IFBIF_STP) != 0 &&
1568 bif->bif_state == BSTP_IFSTATE_LEARNING) {
1569 m_freem(m);
1570 BRIDGE_UNLOCK(sc);
1571 return;
1572 }
1573
1574 /*
1575 * At this point, the port either doesn't participate
1576 * in spanning tree or it is in the forwarding state.
1577 */
1578
1579 /*
1580 * If the packet is unicast, destined for someone on
1581 * "this" side of the bridge, drop it.
1582 */
1583 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1584 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1585 if (src_if == dst_if) {
1586 BRIDGE_UNLOCK(sc);
1587 m_freem(m);
1588 return;
1589 }
1590 } else {
1591 /* ...forward it to all interfaces. */
1592 sc->sc_ifp->if_imcasts++;
1593 dst_if = NULL;
1594 }
1595
1596 /* run the packet filter */
1597 if (inet_pfil_hook.ph_busy_count >= 0
1598 #ifdef INET6
1599 || inet6_pfil_hook.ph_busy_count >= 0
1600 #endif
1601 ) {
1602 BRIDGE_UNLOCK(sc);
1603 if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
1604 return;
1605 if (m == NULL)
1606 return;
1607 BRIDGE_LOCK(sc);
1608 }
1609
1610 if (dst_if == NULL) {
1611 /* tap off packets passing the bridge */
1612 BPF_MTAP(ifp, m);
1613
1614 bridge_broadcast(sc, src_if, m, 1);
1615 return;
1616 }
1617
1618 /*
1619 * At this point, we're dealing with a unicast frame
1620 * going to a different interface.
1621 */
1622 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1623 BRIDGE_UNLOCK(sc);
1624 m_freem(m);
1625 return;
1626 }
1627 bif = bridge_lookup_member_if(sc, dst_if);
1628 if (bif == NULL) {
1629 /* Not a member of the bridge (anymore?) */
1630 BRIDGE_UNLOCK(sc);
1631 m_freem(m);
1632 return;
1633 }
1634
1635 if (bif->bif_flags & IFBIF_STP) {
1636 switch (bif->bif_state) {
1637 case BSTP_IFSTATE_DISABLED:
1638 case BSTP_IFSTATE_BLOCKING:
1639 BRIDGE_UNLOCK(sc);
1640 m_freem(m);
1641 return;
1642 }
1643 }
1644
1645 /* tap off packets passing the bridge */
1646 BPF_MTAP(ifp, m);
1647
1648 BRIDGE_UNLOCK(sc);
1649
1650 if (inet_pfil_hook.ph_busy_count >= 0
1651 #ifdef INET6
1652 || inet6_pfil_hook.ph_busy_count >= 0
1653 #endif
1654 ) {
1655 if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0)
1656 return;
1657 if (m == NULL)
1658 return;
1659 }
1660
1661 bridge_enqueue(sc, dst_if, m);
1662 }
1663
1664 /*
1665 * bridge_input:
1666 *
1667 * Receive input from a member interface. Queue the packet for
1668 * bridging if it is not for us.
1669 */
1670 struct mbuf *
1671 bridge_input(struct ifnet *ifp, struct mbuf *m)
1672 {
1673 struct bridge_softc *sc = ifp->if_bridge;
1674 struct bridge_iflist *bif;
1675 struct ifnet *bifp;
1676 struct ether_header *eh;
1677 struct mbuf *mc, *mc2;
1678
1679 if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1680 return (m);
1681
1682 bifp = sc->sc_ifp;
1683
1684 BRIDGE_LOCK(sc);
1685 bif = bridge_lookup_member_if(sc, ifp);
1686 if (bif == NULL) {
1687 BRIDGE_UNLOCK(sc);
1688 return (m);
1689 }
1690
1691 eh = mtod(m, struct ether_header *);
1692
1693 if (memcmp(eh->ether_dhost, IFP2ENADDR(bifp),
1694 ETHER_ADDR_LEN) == 0) {
1695 /*
1696 * If the packet is for us, set the packets source as the
1697 * bridge, and return the packet back to ether_input for
1698 * local processing.
1699 */
1700
1701 /* XXX Do we tap the packet for the member interface too?
1702 * BPF_MTAP(&m->m_pkthdr.rcvif, m);
1703 */
1704
1705 /* Mark the packet as arriving on the bridge interface */
1706 m->m_pkthdr.rcvif = bifp;
1707 BPF_MTAP(bifp, m);
1708 bifp->if_ipackets++;
1709
1710 BRIDGE_UNLOCK(sc);
1711 return (m);
1712 }
1713
1714 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1715 /* Tap off 802.1D packets; they do not get forwarded. */
1716 if (memcmp(eh->ether_dhost, bstp_etheraddr,
1717 ETHER_ADDR_LEN) == 0) {
1718 m = bstp_input(ifp, m);
1719 if (m == NULL) {
1720 BRIDGE_UNLOCK(sc);
1721 return (NULL);
1722 }
1723 }
1724
1725 if (bif->bif_flags & IFBIF_STP) {
1726 switch (bif->bif_state) {
1727 case BSTP_IFSTATE_BLOCKING:
1728 case BSTP_IFSTATE_LISTENING:
1729 case BSTP_IFSTATE_DISABLED:
1730 BRIDGE_UNLOCK(sc);
1731 return (m);
1732 }
1733 }
1734
1735 if (bcmp(etherbroadcastaddr, eh->ether_dhost,
1736 sizeof(etherbroadcastaddr)) == 0)
1737 m->m_flags |= M_BCAST;
1738 else
1739 m->m_flags |= M_MCAST;
1740
1741 /*
1742 * Make a deep copy of the packet and enqueue the copy
1743 * for bridge processing; return the original packet for
1744 * local processing.
1745 */
1746 mc = m_dup(m, M_DONTWAIT);
1747 if (mc == NULL) {
1748 BRIDGE_UNLOCK(sc);
1749 return (m);
1750 }
1751
1752 /* Perform the bridge forwarding function with the copy. */
1753 bridge_forward(sc, mc);
1754
1755 /*
1756 * Reinject the mbuf as arriving on the bridge so we have a
1757 * chance at claiming multicast packets. We can not loop back
1758 * here from ether_input as a bridge is never a member of a
1759 * bridge.
1760 */
1761 KASSERT(bifp->if_bridge == NULL,
1762 ("loop created in bridge_input"));
1763 mc2 = m_copypacket(m, M_DONTWAIT);
1764 if (mc2 != NULL) {
1765 mc2->m_pkthdr.rcvif = bifp;
1766 (*bifp->if_input)(bifp, mc2);
1767 }
1768
1769 /* Return the original packet for local processing. */
1770 return (m);
1771 }
1772
1773 if (bif->bif_flags & IFBIF_STP) {
1774 switch (bif->bif_state) {
1775 case BSTP_IFSTATE_BLOCKING:
1776 case BSTP_IFSTATE_LISTENING:
1777 case BSTP_IFSTATE_DISABLED:
1778 BRIDGE_UNLOCK(sc);
1779 return (m);
1780 }
1781 }
1782
1783 /*
1784 * Unicast. Make sure it's not for us.
1785 */
1786 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1787 /* It is destined for us. */
1788 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_dhost,
1789 ETHER_ADDR_LEN) == 0) {
1790 if (bif->bif_flags & IFBIF_LEARNING)
1791 (void) bridge_rtupdate(sc,
1792 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1793 m->m_pkthdr.rcvif = bif->bif_ifp;
1794 BRIDGE_UNLOCK(sc);
1795 return (m);
1796 }
1797
1798 /* We just received a packet that we sent out. */
1799 if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_shost,
1800 ETHER_ADDR_LEN) == 0) {
1801 BRIDGE_UNLOCK(sc);
1802 m_freem(m);
1803 return (NULL);
1804 }
1805 }
1806
1807 /* Perform the bridge forwarding function. */
1808 bridge_forward(sc, m);
1809
1810 return (NULL);
1811 }
1812
1813 /*
1814 * bridge_broadcast:
1815 *
1816 * Send a frame to all interfaces that are members of
1817 * the bridge, except for the one on which the packet
1818 * arrived.
1819 *
1820 * NOTE: Releases the lock on return.
1821 */
1822 void
1823 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1824 struct mbuf *m, int runfilt)
1825 {
1826 struct bridge_iflist *bif;
1827 struct mbuf *mc;
1828 struct ifnet *dst_if;
1829 int error = 0, used = 0;
1830
1831 BRIDGE_LOCK_ASSERT(sc);
1832 BRIDGE_LOCK2REF(sc, error);
1833 if (error) {
1834 m_freem(m);
1835 return;
1836 }
1837
1838 /* Filter on the bridge interface before broadcasting */
1839 if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
1840 #ifdef INET6
1841 || inet6_pfil_hook.ph_busy_count >= 0
1842 #endif
1843 )) {
1844 if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0)
1845 return;
1846 if (m == NULL)
1847 return;
1848 }
1849
1850 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1851 dst_if = bif->bif_ifp;
1852 if (dst_if == src_if)
1853 continue;
1854
1855 if (bif->bif_flags & IFBIF_STP) {
1856 switch (bif->bif_state) {
1857 case BSTP_IFSTATE_BLOCKING:
1858 case BSTP_IFSTATE_DISABLED:
1859 continue;
1860 }
1861 }
1862
1863 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
1864 (m->m_flags & (M_BCAST|M_MCAST)) == 0)
1865 continue;
1866
1867 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
1868 continue;
1869
1870 if (LIST_NEXT(bif, bif_next) == NULL) {
1871 mc = m;
1872 used = 1;
1873 } else {
1874 mc = m_copypacket(m, M_DONTWAIT);
1875 if (mc == NULL) {
1876 sc->sc_ifp->if_oerrors++;
1877 continue;
1878 }
1879 }
1880
1881 /*
1882 * Filter on the output interface. Pass a NULL bridge interface
1883 * pointer so we do not redundantly filter on the bridge for
1884 * each interface we broadcast on.
1885 */
1886 if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
1887 #ifdef INET6
1888 || inet6_pfil_hook.ph_busy_count >= 0
1889 #endif
1890 )) {
1891 if (bridge_pfil(&m, NULL, dst_if, PFIL_OUT) != 0)
1892 return;
1893 if (m == NULL)
1894 return;
1895 }
1896
1897 bridge_enqueue(sc, dst_if, mc);
1898 }
1899 if (used == 0)
1900 m_freem(m);
1901
1902 BRIDGE_UNREF(sc);
1903 }
1904
1905 /*
1906 * bridge_rtupdate:
1907 *
1908 * Add a bridge routing entry.
1909 */
1910 int
1911 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
1912 struct ifnet *dst_if, int setflags, uint8_t flags)
1913 {
1914 struct bridge_rtnode *brt;
1915 struct timeval tv;
1916 int error;
1917
1918 BRIDGE_LOCK_ASSERT(sc);
1919
1920 /*
1921 * A route for this destination might already exist. If so,
1922 * update it, otherwise create a new one.
1923 */
1924 getmicrotime(&tv);
1925 if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
1926 if (sc->sc_brtcnt >= sc->sc_brtmax)
1927 return (ENOSPC);
1928
1929 /*
1930 * Allocate a new bridge forwarding node, and
1931 * initialize the expiration time and Ethernet
1932 * address.
1933 */
1934 brt = uma_zalloc(bridge_rtnode_zone, M_NOWAIT | M_ZERO);
1935 if (brt == NULL)
1936 return (ENOMEM);
1937
1938 brt->brt_expire = tv.tv_sec + sc->sc_brttimeout;
1939 brt->brt_flags = IFBAF_DYNAMIC;
1940 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
1941
1942 if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
1943 uma_zfree(bridge_rtnode_zone, brt);
1944 return (error);
1945 }
1946 }
1947
1948 brt->brt_ifp = dst_if;
1949 if (setflags) {
1950 brt->brt_flags = flags;
1951 brt->brt_expire = (flags & IFBAF_STATIC) ? 0 :
1952 tv.tv_sec + sc->sc_brttimeout;
1953 }
1954
1955 return (0);
1956 }
1957
1958 /*
1959 * bridge_rtlookup:
1960 *
1961 * Lookup the destination interface for an address.
1962 */
1963 struct ifnet *
1964 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
1965 {
1966 struct bridge_rtnode *brt;
1967
1968 BRIDGE_LOCK_ASSERT(sc);
1969
1970 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1971 return (NULL);
1972
1973 return (brt->brt_ifp);
1974 }
1975
1976 /*
1977 * bridge_rttrim:
1978 *
1979 * Trim the routine table so that we have a number
1980 * of routing entries less than or equal to the
1981 * maximum number.
1982 */
1983 void
1984 bridge_rttrim(struct bridge_softc *sc)
1985 {
1986 struct bridge_rtnode *brt, *nbrt;
1987
1988 BRIDGE_LOCK_ASSERT(sc);
1989
1990 /* Make sure we actually need to do this. */
1991 if (sc->sc_brtcnt <= sc->sc_brtmax)
1992 return;
1993
1994 /* Force an aging cycle; this might trim enough addresses. */
1995 bridge_rtage(sc);
1996 if (sc->sc_brtcnt <= sc->sc_brtmax)
1997 return;
1998
1999 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2000 nbrt = LIST_NEXT(brt, brt_list);
2001 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2002 bridge_rtnode_destroy(sc, brt);
2003 if (sc->sc_brtcnt <= sc->sc_brtmax)
2004 return;
2005 }
2006 }
2007 }
2008
2009 /*
2010 * bridge_timer:
2011 *
2012 * Aging timer for the bridge.
2013 */
2014 void
2015 bridge_timer(void *arg)
2016 {
2017 struct bridge_softc *sc = arg;
2018
2019 BRIDGE_LOCK_ASSERT(sc);
2020
2021 bridge_rtage(sc);
2022
2023 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
2024 callout_reset(&sc->sc_brcallout,
2025 bridge_rtable_prune_period * hz, bridge_timer, sc);
2026 }
2027
2028 /*
2029 * bridge_rtage:
2030 *
2031 * Perform an aging cycle.
2032 */
2033 void
2034 bridge_rtage(struct bridge_softc *sc)
2035 {
2036 struct bridge_rtnode *brt, *nbrt;
2037 struct timeval tv;
2038
2039 BRIDGE_LOCK_ASSERT(sc);
2040
2041 getmicrotime(&tv);
2042
2043 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2044 nbrt = LIST_NEXT(brt, brt_list);
2045 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2046 if (tv.tv_sec >= brt->brt_expire)
2047 bridge_rtnode_destroy(sc, brt);
2048 }
2049 }
2050 }
2051
2052 /*
2053 * bridge_rtflush:
2054 *
2055 * Remove all dynamic addresses from the bridge.
2056 */
2057 void
2058 bridge_rtflush(struct bridge_softc *sc, int full)
2059 {
2060 struct bridge_rtnode *brt, *nbrt;
2061
2062 BRIDGE_LOCK_ASSERT(sc);
2063
2064 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2065 nbrt = LIST_NEXT(brt, brt_list);
2066 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2067 bridge_rtnode_destroy(sc, brt);
2068 }
2069 }
2070
2071 /*
2072 * bridge_rtdaddr:
2073 *
2074 * Remove an address from the table.
2075 */
2076 int
2077 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
2078 {
2079 struct bridge_rtnode *brt;
2080
2081 BRIDGE_LOCK_ASSERT(sc);
2082
2083 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
2084 return (ENOENT);
2085
2086 bridge_rtnode_destroy(sc, brt);
2087 return (0);
2088 }
2089
2090 /*
2091 * bridge_rtdelete:
2092 *
2093 * Delete routes to a speicifc member interface.
2094 */
2095 void
2096 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
2097 {
2098 struct bridge_rtnode *brt, *nbrt;
2099
2100 BRIDGE_LOCK_ASSERT(sc);
2101
2102 for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2103 nbrt = LIST_NEXT(brt, brt_list);
2104 if (brt->brt_ifp == ifp && (full ||
2105 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
2106 bridge_rtnode_destroy(sc, brt);
2107 }
2108 }
2109
2110 /*
2111 * bridge_rtable_init:
2112 *
2113 * Initialize the route table for this bridge.
2114 */
2115 int
2116 bridge_rtable_init(struct bridge_softc *sc)
2117 {
2118 int i;
2119
2120 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
2121 M_DEVBUF, M_NOWAIT);
2122 if (sc->sc_rthash == NULL)
2123 return (ENOMEM);
2124
2125 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
2126 LIST_INIT(&sc->sc_rthash[i]);
2127
2128 sc->sc_rthash_key = arc4random();
2129
2130 LIST_INIT(&sc->sc_rtlist);
2131
2132 return (0);
2133 }
2134
2135 /*
2136 * bridge_rtable_fini:
2137 *
2138 * Deconstruct the route table for this bridge.
2139 */
2140 void
2141 bridge_rtable_fini(struct bridge_softc *sc)
2142 {
2143
2144 free(sc->sc_rthash, M_DEVBUF);
2145 }
2146
2147 /*
2148 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2149 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2150 */
2151 #define mix(a, b, c) \
2152 do { \
2153 a -= b; a -= c; a ^= (c >> 13); \
2154 b -= c; b -= a; b ^= (a << 8); \
2155 c -= a; c -= b; c ^= (b >> 13); \
2156 a -= b; a -= c; a ^= (c >> 12); \
2157 b -= c; b -= a; b ^= (a << 16); \
2158 c -= a; c -= b; c ^= (b >> 5); \
2159 a -= b; a -= c; a ^= (c >> 3); \
2160 b -= c; b -= a; b ^= (a << 10); \
2161 c -= a; c -= b; c ^= (b >> 15); \
2162 } while (/*CONSTCOND*/0)
2163
2164 static __inline uint32_t
2165 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
2166 {
2167 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
2168
2169 b += addr[5] << 8;
2170 b += addr[4];
2171 a += addr[3] << 24;
2172 a += addr[2] << 16;
2173 a += addr[1] << 8;
2174 a += addr[0];
2175
2176 mix(a, b, c);
2177
2178 return (c & BRIDGE_RTHASH_MASK);
2179 }
2180
2181 #undef mix
2182
2183 /*
2184 * bridge_rtnode_lookup:
2185 *
2186 * Look up a bridge route node for the specified destination.
2187 */
2188 struct bridge_rtnode *
2189 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
2190 {
2191 struct bridge_rtnode *brt;
2192 uint32_t hash;
2193 int dir;
2194
2195 BRIDGE_LOCK_ASSERT(sc);
2196
2197 hash = bridge_rthash(sc, addr);
2198 LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
2199 dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
2200 if (dir == 0)
2201 return (brt);
2202 if (dir > 0)
2203 return (NULL);
2204 }
2205
2206 return (NULL);
2207 }
2208
2209 /*
2210 * bridge_rtnode_insert:
2211 *
2212 * Insert the specified bridge node into the route table. We
2213 * assume the entry is not already in the table.
2214 */
2215 int
2216 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
2217 {
2218 struct bridge_rtnode *lbrt;
2219 uint32_t hash;
2220 int dir;
2221
2222 BRIDGE_LOCK_ASSERT(sc);
2223
2224 hash = bridge_rthash(sc, brt->brt_addr);
2225
2226 lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
2227 if (lbrt == NULL) {
2228 LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
2229 goto out;
2230 }
2231
2232 do {
2233 dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
2234 if (dir == 0)
2235 return (EEXIST);
2236 if (dir > 0) {
2237 LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
2238 goto out;
2239 }
2240 if (LIST_NEXT(lbrt, brt_hash) == NULL) {
2241 LIST_INSERT_AFTER(lbrt, brt, brt_hash);
2242 goto out;
2243 }
2244 lbrt = LIST_NEXT(lbrt, brt_hash);
2245 } while (lbrt != NULL);
2246
2247 #ifdef DIAGNOSTIC
2248 panic("bridge_rtnode_insert: impossible");
2249 #endif
2250
2251 out:
2252 LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
2253 sc->sc_brtcnt++;
2254
2255 return (0);
2256 }
2257
2258 /*
2259 * bridge_rtnode_destroy:
2260 *
2261 * Destroy a bridge rtnode.
2262 */
2263 void
2264 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
2265 {
2266 BRIDGE_LOCK_ASSERT(sc);
2267
2268 LIST_REMOVE(brt, brt_hash);
2269
2270 LIST_REMOVE(brt, brt_list);
2271 sc->sc_brtcnt--;
2272 uma_zfree(bridge_rtnode_zone, brt);
2273 }
2274
2275 /*
2276 * Send bridge packets through pfil if they are one of the types pfil can deal
2277 * with, or if they are ARP or REVARP. (pfil will pass ARP and REVARP without
2278 * question.) If *bifp or *ifp are NULL then packet filtering is skipped for
2279 * that interface.
2280 */
2281 static int bridge_pfil(struct mbuf **mp, struct ifnet *bifp,
2282 struct ifnet *ifp, int dir)
2283 {
2284 int snap, error, i;
2285 struct ether_header *eh1, eh2;
2286 struct ip_fw_args args;
2287 struct ip *ip;
2288 struct llc llc1;
2289 u_int16_t ether_type;
2290
2291 snap = 0;
2292 error = -1; /* Default error if not error == 0 */
2293
2294 i = min((*mp)->m_pkthdr.len, max_protohdr);
2295 if ((*mp)->m_len < i) {
2296 *mp = m_pullup(*mp, i);
2297 if (*mp == NULL) {
2298 printf("%s: m_pullup failed\n", __func__);
2299 return -1;
2300 }
2301 }
2302
2303 eh1 = mtod(*mp, struct ether_header *);
2304 ether_type = ntohs(eh1->ether_type);
2305
2306 /*
2307 * Check for SNAP/LLC.
2308 */
2309 if (ether_type < ETHERMTU) {
2310 struct llc *llc2 = (struct llc *)(eh1 + 1);
2311
2312 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
2313 llc2->llc_dsap == LLC_SNAP_LSAP &&
2314 llc2->llc_ssap == LLC_SNAP_LSAP &&
2315 llc2->llc_control == LLC_UI) {
2316 ether_type = htons(llc2->llc_un.type_snap.ether_type);
2317 snap = 1;
2318 }
2319 }
2320
2321 /*
2322 * If we're trying to filter bridge traffic, don't look at anything
2323 * other than IP and ARP traffic. If the filter doesn't understand
2324 * IPv6, don't allow IPv6 through the bridge either. This is lame
2325 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2326 * but of course we don't have an AppleTalk filter to begin with.
2327 * (Note that since pfil doesn't understand ARP it will pass *ALL*
2328 * ARP traffic.)
2329 */
2330 switch (ether_type) {
2331 case ETHERTYPE_ARP:
2332 case ETHERTYPE_REVARP:
2333 return 0; /* Automatically pass */
2334 case ETHERTYPE_IP:
2335 # ifdef INET6
2336 case ETHERTYPE_IPV6:
2337 # endif /* INET6 */
2338 break;
2339 default:
2340 /*
2341 * ipfw allows layer2 protocol filtering using
2342 * 'mac-type' so we will let the packet past, if
2343 * ipfw is disabled then drop it.
2344 */
2345 if (!IPFW_LOADED || pfil_ipfw == 0)
2346 goto bad;
2347 }
2348
2349 /* Strip off the Ethernet header and keep a copy. */
2350 m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
2351 m_adj(*mp, ETHER_HDR_LEN);
2352
2353 /* Strip off snap header, if present */
2354 if (snap) {
2355 m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
2356 m_adj(*mp, sizeof(struct llc));
2357 }
2358
2359 /*
2360 * Check the IP header for alignment and errors
2361 */
2362 if (dir == PFIL_IN) {
2363 switch (ether_type) {
2364 case ETHERTYPE_IP:
2365 error = bridge_ip_checkbasic(mp);
2366 break;
2367 # ifdef INET6
2368 case ETHERTYPE_IPV6:
2369 error = bridge_ip6_checkbasic(mp);
2370 break;
2371 # endif /* INET6 */
2372 default:
2373 error = 0;
2374 }
2375 if (error)
2376 goto bad;
2377 }
2378
2379 if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
2380 error = -1;
2381 args.rule = ip_dn_claim_rule(*mp);
2382 if (args.rule != NULL && fw_one_pass)
2383 goto ipfwpass; /* packet already partially processed */
2384
2385 args.m = *mp;
2386 args.oif = ifp;
2387 args.next_hop = NULL;
2388 args.eh = &eh2;
2389 i = ip_fw_chk_ptr(&args);
2390 *mp = args.m;
2391
2392 if (*mp == NULL)
2393 return error;
2394
2395 if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) {
2396
2397 /* put the Ethernet header back on */
2398 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2399 if (*mp == NULL)
2400 return error;
2401 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2402
2403 /*
2404 * Pass the pkt to dummynet, which consumes it. The
2405 * packet will return to us via bridge_dummynet().
2406 */
2407 args.oif = ifp;
2408 ip_dn_io_ptr(*mp, DN_TO_IFB_FWD, &args);
2409 return error;
2410 }
2411
2412 if (i != IP_FW_PASS) /* drop */
2413 goto bad;
2414 }
2415
2416 ipfwpass:
2417 error = 0;
2418
2419 /*
2420 * Run the packet through pfil
2421 */
2422 switch (ether_type)
2423 {
2424 case ETHERTYPE_IP :
2425 /*
2426 * before calling the firewall, swap fields the same as
2427 * IP does. here we assume the header is contiguous
2428 */
2429 ip = mtod(*mp, struct ip *);
2430
2431 ip->ip_len = ntohs(ip->ip_len);
2432 ip->ip_off = ntohs(ip->ip_off);
2433
2434 /*
2435 * Run pfil on the member interface and the bridge, both can
2436 * be skipped by clearing pfil_member or pfil_bridge.
2437 *
2438 * Keep the order:
2439 * in_if -> bridge_if -> out_if
2440 */
2441 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
2442 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
2443 dir, NULL);
2444
2445 if (*mp == NULL || error != 0) /* filter may consume */
2446 break;
2447
2448 if (pfil_member && ifp != NULL)
2449 error = pfil_run_hooks(&inet_pfil_hook, mp, ifp,
2450 dir, NULL);
2451
2452 if (*mp == NULL || error != 0) /* filter may consume */
2453 break;
2454
2455 if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
2456 error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
2457 dir, NULL);
2458
2459 /* Restore ip and the fields ntohs()'d. */
2460 if (*mp != NULL && error == 0) {
2461 ip = mtod(*mp, struct ip *);
2462 ip->ip_len = htons(ip->ip_len);
2463 ip->ip_off = htons(ip->ip_off);
2464 }
2465
2466 break;
2467 # ifdef INET6
2468 case ETHERTYPE_IPV6 :
2469 if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
2470 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
2471 dir, NULL);
2472
2473 if (*mp == NULL || error != 0) /* filter may consume */
2474 break;
2475
2476 if (pfil_member && ifp != NULL)
2477 error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp,
2478 dir, NULL);
2479
2480 if (*mp == NULL || error != 0) /* filter may consume */
2481 break;
2482
2483 if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
2484 error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
2485 dir, NULL);
2486 break;
2487 # endif
2488 default :
2489 error = 0;
2490 break;
2491 }
2492
2493 if (*mp == NULL)
2494 return error;
2495 if (error != 0)
2496 goto bad;
2497
2498 error = -1;
2499
2500 /*
2501 * Finally, put everything back the way it was and return
2502 */
2503 if (snap) {
2504 M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2505 if (*mp == NULL)
2506 return error;
2507 bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
2508 }
2509
2510 M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2511 if (*mp == NULL)
2512 return error;
2513 bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2514
2515 return 0;
2516
2517 bad:
2518 m_freem(*mp);
2519 *mp = NULL;
2520 return error;
2521 }
2522
2523 /*
2524 * Perform basic checks on header size since
2525 * pfil assumes ip_input has already processed
2526 * it for it. Cut-and-pasted from ip_input.c.
2527 * Given how simple the IPv6 version is,
2528 * does the IPv4 version really need to be
2529 * this complicated?
2530 *
2531 * XXX Should we update ipstat here, or not?
2532 * XXX Right now we update ipstat but not
2533 * XXX csum_counter.
2534 */
2535 static int
2536 bridge_ip_checkbasic(struct mbuf **mp)
2537 {
2538 struct mbuf *m = *mp;
2539 struct ip *ip;
2540 int len, hlen;
2541 u_short sum;
2542
2543 if (*mp == NULL)
2544 return -1;
2545
2546 if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2547 if ((m = m_copyup(m, sizeof(struct ip),
2548 (max_linkhdr + 3) & ~3)) == NULL) {
2549 /* XXXJRT new stat, please */
2550 ipstat.ips_toosmall++;
2551 goto bad;
2552 }
2553 } else if (__predict_false(m->m_len < sizeof (struct ip))) {
2554 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2555 ipstat.ips_toosmall++;
2556 goto bad;
2557 }
2558 }
2559 ip = mtod(m, struct ip *);
2560 if (ip == NULL) goto bad;
2561
2562 if (ip->ip_v != IPVERSION) {
2563 ipstat.ips_badvers++;
2564 goto bad;
2565 }
2566 hlen = ip->ip_hl << 2;
2567 if (hlen < sizeof(struct ip)) { /* minimum header length */
2568 ipstat.ips_badhlen++;
2569 goto bad;
2570 }
2571 if (hlen > m->m_len) {
2572 if ((m = m_pullup(m, hlen)) == 0) {
2573 ipstat.ips_badhlen++;
2574 goto bad;
2575 }
2576 ip = mtod(m, struct ip *);
2577 if (ip == NULL) goto bad;
2578 }
2579
2580 if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) {
2581 sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
2582 } else {
2583 if (hlen == sizeof(struct ip)) {
2584 sum = in_cksum_hdr(ip);
2585 } else {
2586 sum = in_cksum(m, hlen);
2587 }
2588 }
2589 if (sum) {
2590 ipstat.ips_badsum++;
2591 goto bad;
2592 }
2593
2594 /* Retrieve the packet length. */
2595 len = ntohs(ip->ip_len);
2596
2597 /*
2598 * Check for additional length bogosity
2599 */
2600 if (len < hlen) {
2601 ipstat.ips_badlen++;
2602 goto bad;
2603 }
2604
2605 /*
2606 * Check that the amount of data in the buffers
2607 * is as at least much as the IP header would have us expect.
2608 * Drop packet if shorter than we expect.
2609 */
2610 if (m->m_pkthdr.len < len) {
2611 ipstat.ips_tooshort++;
2612 goto bad;
2613 }
2614
2615 /* Checks out, proceed */
2616 *mp = m;
2617 return 0;
2618
2619 bad:
2620 *mp = m;
2621 return -1;
2622 }
2623
2624 # ifdef INET6
2625 /*
2626 * Same as above, but for IPv6.
2627 * Cut-and-pasted from ip6_input.c.
2628 * XXX Should we update ip6stat, or not?
2629 */
2630 static int
2631 bridge_ip6_checkbasic(struct mbuf **mp)
2632 {
2633 struct mbuf *m = *mp;
2634 struct ip6_hdr *ip6;
2635
2636 /*
2637 * If the IPv6 header is not aligned, slurp it up into a new
2638 * mbuf with space for link headers, in the event we forward
2639 * it. Otherwise, if it is aligned, make sure the entire base
2640 * IPv6 header is in the first mbuf of the chain.
2641 */
2642 if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2643 struct ifnet *inifp = m->m_pkthdr.rcvif;
2644 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2645 (max_linkhdr + 3) & ~3)) == NULL) {
2646 /* XXXJRT new stat, please */
2647 ip6stat.ip6s_toosmall++;
2648 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2649 goto bad;
2650 }
2651 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2652 struct ifnet *inifp = m->m_pkthdr.rcvif;
2653 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2654 ip6stat.ip6s_toosmall++;
2655 in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2656 goto bad;
2657 }
2658 }
2659
2660 ip6 = mtod(m, struct ip6_hdr *);
2661
2662 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2663 ip6stat.ip6s_badvers++;
2664 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2665 goto bad;
2666 }
2667
2668 /* Checks out, proceed */
2669 *mp = m;
2670 return 0;
2671
2672 bad:
2673 *mp = m;
2674 return -1;
2675 }
2676 # endif /* INET6 */
Cache object: 545b4b30948418d65a8ab45c0de1c2ca
|