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