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