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