xref: /netbsd-src/sys/net/if_bridge.c (revision eb961d0e02b7a46a9acfa877b02df48df6637278)
1 /*	$NetBSD: if_bridge.c,v 1.36 2006/01/17 13:23:02 christos 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.36 2006/01/17 13:23:02 christos Exp $");
84 
85 #include "opt_bridge_ipf.h"
86 #include "opt_inet.h"
87 #include "opt_pfil_hooks.h"
88 #include "bpfilter.h"
89 #include "gif.h"
90 
91 #include <sys/param.h>
92 #include <sys/kernel.h>
93 #include <sys/mbuf.h>
94 #include <sys/queue.h>
95 #include <sys/socket.h>
96 #include <sys/sockio.h>
97 #include <sys/systm.h>
98 #include <sys/proc.h>
99 #include <sys/pool.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 /*
134  * Maximum number of addresses to cache.
135  */
136 #ifndef BRIDGE_RTABLE_MAX
137 #define	BRIDGE_RTABLE_MAX		100
138 #endif
139 
140 /*
141  * Spanning tree defaults.
142  */
143 #define	BSTP_DEFAULT_MAX_AGE		(20 * 256)
144 #define	BSTP_DEFAULT_HELLO_TIME		(2 * 256)
145 #define	BSTP_DEFAULT_FORWARD_DELAY	(15 * 256)
146 #define	BSTP_DEFAULT_HOLD_TIME		(1 * 256)
147 #define	BSTP_DEFAULT_BRIDGE_PRIORITY	0x8000
148 #define	BSTP_DEFAULT_PORT_PRIORITY	0x80
149 #define	BSTP_DEFAULT_PATH_COST		55
150 
151 /*
152  * Timeout (in seconds) for entries learned dynamically.
153  */
154 #ifndef BRIDGE_RTABLE_TIMEOUT
155 #define	BRIDGE_RTABLE_TIMEOUT		(20 * 60)	/* same as ARP */
156 #endif
157 
158 /*
159  * Number of seconds between walks of the route list.
160  */
161 #ifndef BRIDGE_RTABLE_PRUNE_PERIOD
162 #define	BRIDGE_RTABLE_PRUNE_PERIOD	(5 * 60)
163 #endif
164 
165 int	bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
166 
167 static struct pool bridge_rtnode_pool;
168 
169 void	bridgeattach(int);
170 
171 static int	bridge_clone_create(struct if_clone *, int);
172 static int	bridge_clone_destroy(struct ifnet *);
173 
174 static int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
175 static int	bridge_init(struct ifnet *);
176 static void	bridge_stop(struct ifnet *, int);
177 static void	bridge_start(struct ifnet *);
178 
179 static void	bridge_forward(struct bridge_softc *, struct mbuf *m);
180 
181 static void	bridge_timer(void *);
182 
183 static void	bridge_broadcast(struct bridge_softc *, struct ifnet *,
184 				 struct mbuf *);
185 
186 static int	bridge_rtupdate(struct bridge_softc *, const uint8_t *,
187 				struct ifnet *, int, uint8_t);
188 static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
189 static void	bridge_rttrim(struct bridge_softc *);
190 static void	bridge_rtage(struct bridge_softc *);
191 static void	bridge_rtflush(struct bridge_softc *, int);
192 static int	bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
193 static void	bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp);
194 
195 static int	bridge_rtable_init(struct bridge_softc *);
196 static void	bridge_rtable_fini(struct bridge_softc *);
197 
198 static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
199 						  const uint8_t *);
200 static int	bridge_rtnode_insert(struct bridge_softc *,
201 				     struct bridge_rtnode *);
202 static void	bridge_rtnode_destroy(struct bridge_softc *,
203 				      struct bridge_rtnode *);
204 
205 static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
206 						  const char *name);
207 static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
208 						     struct ifnet *ifp);
209 static void	bridge_delete_member(struct bridge_softc *,
210 				     struct bridge_iflist *);
211 
212 static int	bridge_ioctl_add(struct bridge_softc *, void *);
213 static int	bridge_ioctl_del(struct bridge_softc *, void *);
214 static int	bridge_ioctl_gifflags(struct bridge_softc *, void *);
215 static int	bridge_ioctl_sifflags(struct bridge_softc *, void *);
216 static int	bridge_ioctl_scache(struct bridge_softc *, void *);
217 static int	bridge_ioctl_gcache(struct bridge_softc *, void *);
218 static int	bridge_ioctl_gifs(struct bridge_softc *, void *);
219 static int	bridge_ioctl_rts(struct bridge_softc *, void *);
220 static int	bridge_ioctl_saddr(struct bridge_softc *, void *);
221 static int	bridge_ioctl_sto(struct bridge_softc *, void *);
222 static int	bridge_ioctl_gto(struct bridge_softc *, void *);
223 static int	bridge_ioctl_daddr(struct bridge_softc *, void *);
224 static int	bridge_ioctl_flush(struct bridge_softc *, void *);
225 static int	bridge_ioctl_gpri(struct bridge_softc *, void *);
226 static int	bridge_ioctl_spri(struct bridge_softc *, void *);
227 static int	bridge_ioctl_ght(struct bridge_softc *, void *);
228 static int	bridge_ioctl_sht(struct bridge_softc *, void *);
229 static int	bridge_ioctl_gfd(struct bridge_softc *, void *);
230 static int	bridge_ioctl_sfd(struct bridge_softc *, void *);
231 static int	bridge_ioctl_gma(struct bridge_softc *, void *);
232 static int	bridge_ioctl_sma(struct bridge_softc *, void *);
233 static int	bridge_ioctl_sifprio(struct bridge_softc *, void *);
234 static int	bridge_ioctl_sifcost(struct bridge_softc *, void *);
235 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
236 static int	bridge_ioctl_gfilt(struct bridge_softc *, void *);
237 static int	bridge_ioctl_sfilt(struct bridge_softc *, void *);
238 static int	bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
239 static int	bridge_ip_checkbasic(struct mbuf **mp);
240 # ifdef INET6
241 static int	bridge_ip6_checkbasic(struct mbuf **mp);
242 # endif /* INET6 */
243 #endif /* BRIDGE_IPF && PFIL_HOOKS */
244 
245 struct bridge_control {
246 	int	(*bc_func)(struct bridge_softc *, void *);
247 	int	bc_argsize;
248 	int	bc_flags;
249 };
250 
251 #define	BC_F_COPYIN		0x01	/* copy arguments in */
252 #define	BC_F_COPYOUT		0x02	/* copy arguments out */
253 #define	BC_F_SUSER		0x04	/* do super-user check */
254 
255 static const struct bridge_control bridge_control_table[] = {
256 	{ bridge_ioctl_add,		sizeof(struct ifbreq),
257 	  BC_F_COPYIN|BC_F_SUSER },
258 	{ bridge_ioctl_del,		sizeof(struct ifbreq),
259 	  BC_F_COPYIN|BC_F_SUSER },
260 
261 	{ bridge_ioctl_gifflags,	sizeof(struct ifbreq),
262 	  BC_F_COPYIN|BC_F_COPYOUT },
263 	{ bridge_ioctl_sifflags,	sizeof(struct ifbreq),
264 	  BC_F_COPYIN|BC_F_SUSER },
265 
266 	{ bridge_ioctl_scache,		sizeof(struct ifbrparam),
267 	  BC_F_COPYIN|BC_F_SUSER },
268 	{ bridge_ioctl_gcache,		sizeof(struct ifbrparam),
269 	  BC_F_COPYOUT },
270 
271 	{ bridge_ioctl_gifs,		sizeof(struct ifbifconf),
272 	  BC_F_COPYIN|BC_F_COPYOUT },
273 	{ bridge_ioctl_rts,		sizeof(struct ifbaconf),
274 	  BC_F_COPYIN|BC_F_COPYOUT },
275 
276 	{ bridge_ioctl_saddr,		sizeof(struct ifbareq),
277 	  BC_F_COPYIN|BC_F_SUSER },
278 
279 	{ bridge_ioctl_sto,		sizeof(struct ifbrparam),
280 	  BC_F_COPYIN|BC_F_SUSER },
281 	{ bridge_ioctl_gto,		sizeof(struct ifbrparam),
282 	  BC_F_COPYOUT },
283 
284 	{ bridge_ioctl_daddr,		sizeof(struct ifbareq),
285 	  BC_F_COPYIN|BC_F_SUSER },
286 
287 	{ bridge_ioctl_flush,		sizeof(struct ifbreq),
288 	  BC_F_COPYIN|BC_F_SUSER },
289 
290 	{ bridge_ioctl_gpri,		sizeof(struct ifbrparam),
291 	  BC_F_COPYOUT },
292 	{ bridge_ioctl_spri,		sizeof(struct ifbrparam),
293 	  BC_F_COPYIN|BC_F_SUSER },
294 
295 	{ bridge_ioctl_ght,		sizeof(struct ifbrparam),
296 	  BC_F_COPYOUT },
297 	{ bridge_ioctl_sht,		sizeof(struct ifbrparam),
298 	  BC_F_COPYIN|BC_F_SUSER },
299 
300 	{ bridge_ioctl_gfd,		sizeof(struct ifbrparam),
301 	  BC_F_COPYOUT },
302 	{ bridge_ioctl_sfd,		sizeof(struct ifbrparam),
303 	  BC_F_COPYIN|BC_F_SUSER },
304 
305 	{ bridge_ioctl_gma,		sizeof(struct ifbrparam),
306 	  BC_F_COPYOUT },
307 	{ bridge_ioctl_sma,		sizeof(struct ifbrparam),
308 	  BC_F_COPYIN|BC_F_SUSER },
309 
310 	{ bridge_ioctl_sifprio,		sizeof(struct ifbreq),
311 	  BC_F_COPYIN|BC_F_SUSER },
312 
313 	{ bridge_ioctl_sifcost,		sizeof(struct ifbreq),
314 	  BC_F_COPYIN|BC_F_SUSER },
315 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
316 	{ bridge_ioctl_gfilt,		sizeof(struct ifbrparam),
317 	  BC_F_COPYOUT },
318 	{ bridge_ioctl_sfilt,		sizeof(struct ifbrparam),
319 	  BC_F_COPYIN|BC_F_SUSER },
320 #endif /* BRIDGE_IPF && PFIL_HOOKS */
321 };
322 static const int bridge_control_table_size =
323     sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
324 
325 static LIST_HEAD(, bridge_softc) bridge_list;
326 
327 static struct if_clone bridge_cloner =
328     IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
329 
330 /*
331  * bridgeattach:
332  *
333  *	Pseudo-device attach routine.
334  */
335 void
336 bridgeattach(int n)
337 {
338 
339 	pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
340 	    0, 0, 0, "brtpl", NULL);
341 
342 	LIST_INIT(&bridge_list);
343 	if_clone_attach(&bridge_cloner);
344 }
345 
346 /*
347  * bridge_clone_create:
348  *
349  *	Create a new bridge instance.
350  */
351 static int
352 bridge_clone_create(struct if_clone *ifc, int unit)
353 {
354 	struct bridge_softc *sc;
355 	struct ifnet *ifp;
356 	int s;
357 
358 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK);
359 	memset(sc, 0, sizeof(*sc));
360 	ifp = &sc->sc_if;
361 
362 	sc->sc_brtmax = BRIDGE_RTABLE_MAX;
363 	sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
364 	sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
365 	sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
366 	sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
367 	sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
368 	sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
369 	sc->sc_filter_flags = 0;
370 
371 	/* Initialize our routing table. */
372 	bridge_rtable_init(sc);
373 
374 	callout_init(&sc->sc_brcallout);
375 	callout_init(&sc->sc_bstpcallout);
376 
377 	LIST_INIT(&sc->sc_iflist);
378 
379 	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", ifc->ifc_name,
380 	    unit);
381 	ifp->if_softc = sc;
382 	ifp->if_mtu = ETHERMTU;
383 	ifp->if_ioctl = bridge_ioctl;
384 	ifp->if_output = bridge_output;
385 	ifp->if_start = bridge_start;
386 	ifp->if_stop = bridge_stop;
387 	ifp->if_init = bridge_init;
388 	ifp->if_type = IFT_BRIDGE;
389 	ifp->if_addrlen = 0;
390 	ifp->if_dlt = DLT_EN10MB;
391 	ifp->if_hdrlen = ETHER_HDR_LEN;
392 
393 	if_attach(ifp);
394 
395 	if_alloc_sadl(ifp);
396 
397 	s = splnet();
398 	LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
399 	splx(s);
400 
401 	return (0);
402 }
403 
404 /*
405  * bridge_clone_destroy:
406  *
407  *	Destroy a bridge instance.
408  */
409 static int
410 bridge_clone_destroy(struct ifnet *ifp)
411 {
412 	struct bridge_softc *sc = ifp->if_softc;
413 	struct bridge_iflist *bif;
414 	int s;
415 
416 	s = splnet();
417 
418 	bridge_stop(ifp, 1);
419 
420 	while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
421 		bridge_delete_member(sc, bif);
422 
423 	LIST_REMOVE(sc, sc_list);
424 
425 	splx(s);
426 
427 	if_detach(ifp);
428 
429 	/* Tear down the routing table. */
430 	bridge_rtable_fini(sc);
431 
432 	free(sc, M_DEVBUF);
433 
434 	return (0);
435 }
436 
437 /*
438  * bridge_ioctl:
439  *
440  *	Handle a control request from the operator.
441  */
442 static int
443 bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
444 {
445 	struct bridge_softc *sc = ifp->if_softc;
446 	struct proc *p = curproc;	/* XXX */
447 	union {
448 		struct ifbreq ifbreq;
449 		struct ifbifconf ifbifconf;
450 		struct ifbareq ifbareq;
451 		struct ifbaconf ifbaconf;
452 		struct ifbrparam ifbrparam;
453 	} args;
454 	struct ifdrv *ifd = (struct ifdrv *) data;
455 	const struct bridge_control *bc;
456 	int s, error = 0;
457 
458 	s = splnet();
459 
460 	switch (cmd) {
461 	case SIOCGDRVSPEC:
462 	case SIOCSDRVSPEC:
463 		if (ifd->ifd_cmd >= bridge_control_table_size) {
464 			error = EINVAL;
465 			break;
466 		}
467 		bc = &bridge_control_table[ifd->ifd_cmd];
468 
469 		if (cmd == SIOCGDRVSPEC &&
470 		    (bc->bc_flags & BC_F_COPYOUT) == 0) {
471 			error = EINVAL;
472 			break;
473 		}
474 		else if (cmd == SIOCSDRVSPEC &&
475 		    (bc->bc_flags & BC_F_COPYOUT) != 0) {
476 			error = EINVAL;
477 			break;
478 		}
479 
480 		if (bc->bc_flags & BC_F_SUSER) {
481 			error = suser(p->p_ucred, &p->p_acflag);
482 			if (error)
483 				break;
484 		}
485 
486 		if (ifd->ifd_len != bc->bc_argsize ||
487 		    ifd->ifd_len > sizeof(args)) {
488 			error = EINVAL;
489 			break;
490 		}
491 
492 		memset(&args, 0, sizeof(args));
493 		if (bc->bc_flags & BC_F_COPYIN) {
494 			error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
495 			if (error)
496 				break;
497 		}
498 
499 		error = (*bc->bc_func)(sc, &args);
500 		if (error)
501 			break;
502 
503 		if (bc->bc_flags & BC_F_COPYOUT)
504 			error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
505 
506 		break;
507 
508 	case SIOCSIFFLAGS:
509 		if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) {
510 			/*
511 			 * If interface is marked down and it is running,
512 			 * then stop and disable it.
513 			 */
514 			(*ifp->if_stop)(ifp, 1);
515 		} else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) {
516 			/*
517 			 * If interface is marked up and it is stopped, then
518 			 * start it.
519 			 */
520 			error = (*ifp->if_init)(ifp);
521 		}
522 		break;
523 
524 	default:
525 		error = ENOTTY;
526 		break;
527 	}
528 
529 	splx(s);
530 
531 	return (error);
532 }
533 
534 /*
535  * bridge_lookup_member:
536  *
537  *	Lookup a bridge member interface.  Must be called at splnet().
538  */
539 static struct bridge_iflist *
540 bridge_lookup_member(struct bridge_softc *sc, const char *name)
541 {
542 	struct bridge_iflist *bif;
543 	struct ifnet *ifp;
544 
545 	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
546 		ifp = bif->bif_ifp;
547 		if (strcmp(ifp->if_xname, name) == 0)
548 			return (bif);
549 	}
550 
551 	return (NULL);
552 }
553 
554 /*
555  * bridge_lookup_member_if:
556  *
557  *	Lookup a bridge member interface by ifnet*.  Must be called at splnet().
558  */
559 static struct bridge_iflist *
560 bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
561 {
562 	struct bridge_iflist *bif;
563 
564 	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
565 		if (bif->bif_ifp == member_ifp)
566 			return (bif);
567 	}
568 
569 	return (NULL);
570 }
571 
572 /*
573  * bridge_delete_member:
574  *
575  *	Delete the specified member interface.
576  */
577 static void
578 bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
579 {
580 	struct ifnet *ifs = bif->bif_ifp;
581 
582 	switch (ifs->if_type) {
583 	case IFT_ETHER:
584 		/*
585 		 * Take the interface out of promiscuous mode.
586 		 */
587 		(void) ifpromisc(ifs, 0);
588 		break;
589 #if NGIF > 0
590 	case IFT_GIF:
591 		break;
592 #endif
593 	default:
594 #ifdef DIAGNOSTIC
595 		panic("bridge_delete_member: impossible");
596 #endif
597 		break;
598 	}
599 
600 	ifs->if_bridge = NULL;
601 	LIST_REMOVE(bif, bif_next);
602 
603 	bridge_rtdelete(sc, ifs);
604 
605 	free(bif, M_DEVBUF);
606 
607 	if (sc->sc_if.if_flags & IFF_RUNNING)
608 		bstp_initialization(sc);
609 }
610 
611 static int
612 bridge_ioctl_add(struct bridge_softc *sc, void *arg)
613 {
614 	struct ifbreq *req = arg;
615 	struct bridge_iflist *bif = NULL;
616 	struct ifnet *ifs;
617 	int error = 0;
618 
619 	ifs = ifunit(req->ifbr_ifsname);
620 	if (ifs == NULL)
621 		return (ENOENT);
622 
623 	if (sc->sc_if.if_mtu != ifs->if_mtu)
624 		return (EINVAL);
625 
626 	if (ifs->if_bridge == sc)
627 		return (EEXIST);
628 
629 	if (ifs->if_bridge != NULL)
630 		return (EBUSY);
631 
632 	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
633 	if (bif == NULL)
634 		return (ENOMEM);
635 
636 	switch (ifs->if_type) {
637 	case IFT_ETHER:
638 		/*
639 		 * Place the interface into promiscuous mode.
640 		 */
641 		error = ifpromisc(ifs, 1);
642 		if (error)
643 			goto out;
644 		break;
645 #if NGIF > 0
646 	case IFT_GIF:
647 		break;
648 #endif
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 - mono_time.tv_sec;
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 #if NGIF > 0
1499 		if (ifp->if_type == IFT_GIF) {
1500 			LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1501 				if (bif->bif_ifp->if_type == IFT_ETHER)
1502 				break;
1503 			}
1504 			if (bif != NULL) {
1505 				m->m_flags |= M_PROTO1;
1506 				m->m_pkthdr.rcvif = bif->bif_ifp;
1507 				(*bif->bif_ifp->if_input)(bif->bif_ifp, m);
1508 				m = NULL;
1509 			}
1510 		}
1511 #endif
1512 		bridge_forward(sc, mc);
1513 
1514 		/* Return the original packet for local processing. */
1515 		return (m);
1516 	}
1517 
1518 	if (bif->bif_flags & IFBIF_STP) {
1519 		switch (bif->bif_state) {
1520 		case BSTP_IFSTATE_BLOCKING:
1521 		case BSTP_IFSTATE_LISTENING:
1522 		case BSTP_IFSTATE_DISABLED:
1523 			return (m);
1524 		}
1525 	}
1526 
1527 	/*
1528 	 * Unicast.  Make sure it's not for us.
1529 	 */
1530 	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1531 		if(bif->bif_ifp->if_type != IFT_ETHER)
1532 			continue;
1533 		/* It is destined for us. */
1534 		if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost,
1535 		    ETHER_ADDR_LEN) == 0) {
1536 			if (bif->bif_flags & IFBIF_LEARNING)
1537 				(void) bridge_rtupdate(sc,
1538 				    eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1539 			m->m_pkthdr.rcvif = bif->bif_ifp;
1540 #if NGIF > 0
1541 			if (ifp->if_type == IFT_GIF) {
1542 				m->m_flags |= M_PROTO1;
1543 				m->m_pkthdr.rcvif = bif->bif_ifp;
1544 				(*bif->bif_ifp->if_input)(bif->bif_ifp, m);
1545 				m = NULL;
1546 			}
1547 #endif
1548 			return (m);
1549 		}
1550 
1551 		/* We just received a packet that we sent out. */
1552 		if (memcmp(LLADDR(bif->bif_ifp->if_sadl), eh->ether_shost,
1553 		    ETHER_ADDR_LEN) == 0) {
1554 			m_freem(m);
1555 			return (NULL);
1556 		}
1557 	}
1558 
1559 	/* Perform the bridge forwarding function. */
1560 	bridge_forward(sc, m);
1561 
1562 	return (NULL);
1563 }
1564 
1565 /*
1566  * bridge_broadcast:
1567  *
1568  *	Send a frame to all interfaces that are members of
1569  *	the bridge, except for the one on which the packet
1570  *	arrived.
1571  */
1572 static void
1573 bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1574     struct mbuf *m)
1575 {
1576 	struct bridge_iflist *bif;
1577 	struct mbuf *mc;
1578 	struct ifnet *dst_if;
1579 	int used = 0;
1580 
1581 	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1582 		dst_if = bif->bif_ifp;
1583 		if (dst_if == src_if)
1584 			continue;
1585 
1586 		if (bif->bif_flags & IFBIF_STP) {
1587 			switch (bif->bif_state) {
1588 			case BSTP_IFSTATE_BLOCKING:
1589 			case BSTP_IFSTATE_DISABLED:
1590 				continue;
1591 			}
1592 		}
1593 
1594 		if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
1595 		    (m->m_flags & (M_BCAST|M_MCAST)) == 0)
1596 			continue;
1597 
1598 		if ((dst_if->if_flags & IFF_RUNNING) == 0)
1599 			continue;
1600 
1601 		if (LIST_NEXT(bif, bif_next) == NULL) {
1602 			mc = m;
1603 			used = 1;
1604 		} else {
1605 			mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1606 			if (mc == NULL) {
1607 				sc->sc_if.if_oerrors++;
1608 				continue;
1609 			}
1610 		}
1611 
1612 		bridge_enqueue(sc, dst_if, mc, 1);
1613 	}
1614 	if (used == 0)
1615 		m_freem(m);
1616 }
1617 
1618 /*
1619  * bridge_rtupdate:
1620  *
1621  *	Add a bridge routing entry.
1622  */
1623 static int
1624 bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
1625     struct ifnet *dst_if, int setflags, uint8_t flags)
1626 {
1627 	struct bridge_rtnode *brt;
1628 	int error;
1629 
1630 	/*
1631 	 * A route for this destination might already exist.  If so,
1632 	 * update it, otherwise create a new one.
1633 	 */
1634 	if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
1635 		if (sc->sc_brtcnt >= sc->sc_brtmax)
1636 			return (ENOSPC);
1637 
1638 		/*
1639 		 * Allocate a new bridge forwarding node, and
1640 		 * initialize the expiration time and Ethernet
1641 		 * address.
1642 		 */
1643 		brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT);
1644 		if (brt == NULL)
1645 			return (ENOMEM);
1646 
1647 		memset(brt, 0, sizeof(*brt));
1648 		brt->brt_expire = mono_time.tv_sec + sc->sc_brttimeout;
1649 		brt->brt_flags = IFBAF_DYNAMIC;
1650 		memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
1651 
1652 		if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
1653 			pool_put(&bridge_rtnode_pool, brt);
1654 			return (error);
1655 		}
1656 	}
1657 
1658 	brt->brt_ifp = dst_if;
1659 	if (setflags) {
1660 		brt->brt_flags = flags;
1661 		brt->brt_expire = (flags & IFBAF_STATIC) ? 0 :
1662 		    mono_time.tv_sec + sc->sc_brttimeout;
1663 	}
1664 
1665 	return (0);
1666 }
1667 
1668 /*
1669  * bridge_rtlookup:
1670  *
1671  *	Lookup the destination interface for an address.
1672  */
1673 static struct ifnet *
1674 bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
1675 {
1676 	struct bridge_rtnode *brt;
1677 
1678 	if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1679 		return (NULL);
1680 
1681 	return (brt->brt_ifp);
1682 }
1683 
1684 /*
1685  * bridge_rttrim:
1686  *
1687  *	Trim the routine table so that we have a number
1688  *	of routing entries less than or equal to the
1689  *	maximum number.
1690  */
1691 static void
1692 bridge_rttrim(struct bridge_softc *sc)
1693 {
1694 	struct bridge_rtnode *brt, *nbrt;
1695 
1696 	/* Make sure we actually need to do this. */
1697 	if (sc->sc_brtcnt <= sc->sc_brtmax)
1698 		return;
1699 
1700 	/* Force an aging cycle; this might trim enough addresses. */
1701 	bridge_rtage(sc);
1702 	if (sc->sc_brtcnt <= sc->sc_brtmax)
1703 		return;
1704 
1705 	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1706 		nbrt = LIST_NEXT(brt, brt_list);
1707 		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1708 			bridge_rtnode_destroy(sc, brt);
1709 			if (sc->sc_brtcnt <= sc->sc_brtmax)
1710 				return;
1711 		}
1712 	}
1713 }
1714 
1715 /*
1716  * bridge_timer:
1717  *
1718  *	Aging timer for the bridge.
1719  */
1720 static void
1721 bridge_timer(void *arg)
1722 {
1723 	struct bridge_softc *sc = arg;
1724 	int s;
1725 
1726 	s = splnet();
1727 	bridge_rtage(sc);
1728 	splx(s);
1729 
1730 	if (sc->sc_if.if_flags & IFF_RUNNING)
1731 		callout_reset(&sc->sc_brcallout,
1732 		    bridge_rtable_prune_period * hz, bridge_timer, sc);
1733 }
1734 
1735 /*
1736  * bridge_rtage:
1737  *
1738  *	Perform an aging cycle.
1739  */
1740 static void
1741 bridge_rtage(struct bridge_softc *sc)
1742 {
1743 	struct bridge_rtnode *brt, *nbrt;
1744 
1745 	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1746 		nbrt = LIST_NEXT(brt, brt_list);
1747 		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1748 			if (mono_time.tv_sec >= brt->brt_expire)
1749 				bridge_rtnode_destroy(sc, brt);
1750 		}
1751 	}
1752 }
1753 
1754 /*
1755  * bridge_rtflush:
1756  *
1757  *	Remove all dynamic addresses from the bridge.
1758  */
1759 static void
1760 bridge_rtflush(struct bridge_softc *sc, int full)
1761 {
1762 	struct bridge_rtnode *brt, *nbrt;
1763 
1764 	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1765 		nbrt = LIST_NEXT(brt, brt_list);
1766 		if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
1767 			bridge_rtnode_destroy(sc, brt);
1768 	}
1769 }
1770 
1771 /*
1772  * bridge_rtdaddr:
1773  *
1774  *	Remove an address from the table.
1775  */
1776 static int
1777 bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
1778 {
1779 	struct bridge_rtnode *brt;
1780 
1781 	if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
1782 		return (ENOENT);
1783 
1784 	bridge_rtnode_destroy(sc, brt);
1785 	return (0);
1786 }
1787 
1788 /*
1789  * bridge_rtdelete:
1790  *
1791  *	Delete routes to a speicifc member interface.
1792  */
1793 static void
1794 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
1795 {
1796 	struct bridge_rtnode *brt, *nbrt;
1797 
1798 	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
1799 		nbrt = LIST_NEXT(brt, brt_list);
1800 		if (brt->brt_ifp == ifp)
1801 			bridge_rtnode_destroy(sc, brt);
1802 	}
1803 }
1804 
1805 /*
1806  * bridge_rtable_init:
1807  *
1808  *	Initialize the route table for this bridge.
1809  */
1810 static int
1811 bridge_rtable_init(struct bridge_softc *sc)
1812 {
1813 	int i;
1814 
1815 	sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
1816 	    M_DEVBUF, M_NOWAIT);
1817 	if (sc->sc_rthash == NULL)
1818 		return (ENOMEM);
1819 
1820 	for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
1821 		LIST_INIT(&sc->sc_rthash[i]);
1822 
1823 	sc->sc_rthash_key = arc4random();
1824 
1825 	LIST_INIT(&sc->sc_rtlist);
1826 
1827 	return (0);
1828 }
1829 
1830 /*
1831  * bridge_rtable_fini:
1832  *
1833  *	Deconstruct the route table for this bridge.
1834  */
1835 static void
1836 bridge_rtable_fini(struct bridge_softc *sc)
1837 {
1838 
1839 	free(sc->sc_rthash, M_DEVBUF);
1840 }
1841 
1842 /*
1843  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
1844  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
1845  */
1846 #define	mix(a, b, c)							\
1847 do {									\
1848 	a -= b; a -= c; a ^= (c >> 13);					\
1849 	b -= c; b -= a; b ^= (a << 8);					\
1850 	c -= a; c -= b; c ^= (b >> 13);					\
1851 	a -= b; a -= c; a ^= (c >> 12);					\
1852 	b -= c; b -= a; b ^= (a << 16);					\
1853 	c -= a; c -= b; c ^= (b >> 5);					\
1854 	a -= b; a -= c; a ^= (c >> 3);					\
1855 	b -= c; b -= a; b ^= (a << 10);					\
1856 	c -= a; c -= b; c ^= (b >> 15);					\
1857 } while (/*CONSTCOND*/0)
1858 
1859 static inline uint32_t
1860 bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
1861 {
1862 	uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
1863 
1864 	b += addr[5] << 8;
1865 	b += addr[4];
1866 	a += addr[3] << 24;
1867 	a += addr[2] << 16;
1868 	a += addr[1] << 8;
1869 	a += addr[0];
1870 
1871 	mix(a, b, c);
1872 
1873 	return (c & BRIDGE_RTHASH_MASK);
1874 }
1875 
1876 #undef mix
1877 
1878 /*
1879  * bridge_rtnode_lookup:
1880  *
1881  *	Look up a bridge route node for the specified destination.
1882  */
1883 static struct bridge_rtnode *
1884 bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
1885 {
1886 	struct bridge_rtnode *brt;
1887 	uint32_t hash;
1888 	int dir;
1889 
1890 	hash = bridge_rthash(sc, addr);
1891 	LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
1892 		dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
1893 		if (dir == 0)
1894 			return (brt);
1895 		if (dir > 0)
1896 			return (NULL);
1897 	}
1898 
1899 	return (NULL);
1900 }
1901 
1902 /*
1903  * bridge_rtnode_insert:
1904  *
1905  *	Insert the specified bridge node into the route table.  We
1906  *	assume the entry is not already in the table.
1907  */
1908 static int
1909 bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
1910 {
1911 	struct bridge_rtnode *lbrt;
1912 	uint32_t hash;
1913 	int dir;
1914 
1915 	hash = bridge_rthash(sc, brt->brt_addr);
1916 
1917 	lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
1918 	if (lbrt == NULL) {
1919 		LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
1920 		goto out;
1921 	}
1922 
1923 	do {
1924 		dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
1925 		if (dir == 0)
1926 			return (EEXIST);
1927 		if (dir > 0) {
1928 			LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
1929 			goto out;
1930 		}
1931 		if (LIST_NEXT(lbrt, brt_hash) == NULL) {
1932 			LIST_INSERT_AFTER(lbrt, brt, brt_hash);
1933 			goto out;
1934 		}
1935 		lbrt = LIST_NEXT(lbrt, brt_hash);
1936 	} while (lbrt != NULL);
1937 
1938 #ifdef DIAGNOSTIC
1939 	panic("bridge_rtnode_insert: impossible");
1940 #endif
1941 
1942  out:
1943 	LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
1944 	sc->sc_brtcnt++;
1945 
1946 	return (0);
1947 }
1948 
1949 /*
1950  * bridge_rtnode_destroy:
1951  *
1952  *	Destroy a bridge rtnode.
1953  */
1954 static void
1955 bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
1956 {
1957 
1958 	LIST_REMOVE(brt, brt_hash);
1959 
1960 	LIST_REMOVE(brt, brt_list);
1961 	sc->sc_brtcnt--;
1962 	pool_put(&bridge_rtnode_pool, brt);
1963 }
1964 
1965 #if defined(BRIDGE_IPF) && defined(PFIL_HOOKS)
1966 extern struct pfil_head inet_pfil_hook;                 /* XXX */
1967 extern struct pfil_head inet6_pfil_hook;                /* XXX */
1968 
1969 /*
1970  * Send bridge packets through IPF if they are one of the types IPF can deal
1971  * with, or if they are ARP or REVARP.  (IPF will pass ARP and REVARP without
1972  * question.)
1973  */
1974 static int
1975 bridge_ipf(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
1976 {
1977 	int snap, error;
1978 	struct ether_header *eh1, eh2;
1979 	struct llc llc1;
1980 	u_int16_t ether_type;
1981 
1982 	snap = 0;
1983 	error = -1;	/* Default error if not error == 0 */
1984 	eh1 = mtod(*mp, struct ether_header *);
1985 	ether_type = ntohs(eh1->ether_type);
1986 
1987 	/*
1988 	 * Check for SNAP/LLC.
1989 	 */
1990         if (ether_type < ETHERMTU) {
1991                 struct llc *llc2 = (struct llc *)(eh1 + 1);
1992 
1993                 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
1994                     llc2->llc_dsap == LLC_SNAP_LSAP &&
1995                     llc2->llc_ssap == LLC_SNAP_LSAP &&
1996                     llc2->llc_control == LLC_UI) {
1997                 	ether_type = htons(llc2->llc_un.type_snap.ether_type);
1998 			snap = 1;
1999                 }
2000         }
2001 
2002 	/*
2003 	 * If we're trying to filter bridge traffic, don't look at anything
2004 	 * other than IP and ARP traffic.  If the filter doesn't understand
2005 	 * IPv6, don't allow IPv6 through the bridge either.  This is lame
2006 	 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2007 	 * but of course we don't have an AppleTalk filter to begin with.
2008 	 * (Note that since IPF doesn't understand ARP it will pass *ALL*
2009 	 * ARP traffic.)
2010 	 */
2011 	switch (ether_type) {
2012 		case ETHERTYPE_ARP:
2013 		case ETHERTYPE_REVARP:
2014 			return 0; /* Automatically pass */
2015 		case ETHERTYPE_IP:
2016 # ifdef INET6
2017 		case ETHERTYPE_IPV6:
2018 # endif /* INET6 */
2019 			break;
2020 		default:
2021 			goto bad;
2022 	}
2023 
2024 	/* Strip off the Ethernet header and keep a copy. */
2025 	m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
2026 	m_adj(*mp, ETHER_HDR_LEN);
2027 
2028 	/* Strip off snap header, if present */
2029 	if (snap) {
2030 		m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
2031 		m_adj(*mp, sizeof(struct llc));
2032 	}
2033 
2034 	/*
2035 	 * Check basic packet sanity and run IPF through pfil.
2036 	 */
2037 	switch (ether_type)
2038 	{
2039 	case ETHERTYPE_IP :
2040 		error = (dir == PFIL_IN) ? bridge_ip_checkbasic(mp) : 0;
2041 		if (error == 0)
2042 			error = pfil_run_hooks(&inet_pfil_hook, mp, ifp, dir);
2043 		break;
2044 # ifdef INET6
2045 	case ETHERTYPE_IPV6 :
2046 		error = (dir == PFIL_IN) ? bridge_ip6_checkbasic(mp) : 0;
2047 		if (error == 0)
2048 			error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp, dir);
2049 		break;
2050 # endif
2051 	default :
2052 		error = 0;
2053 		break;
2054 	}
2055 
2056 	if (*mp == NULL)
2057 		return error;
2058 	if (error != 0)
2059 		goto bad;
2060 
2061 	error = -1;
2062 
2063 	/*
2064 	 * Finally, put everything back the way it was and return
2065 	 */
2066 	if (snap) {
2067 		M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2068 		if (*mp == NULL)
2069 			return error;
2070 		bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
2071 	}
2072 
2073 	M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2074 	if (*mp == NULL)
2075 		return error;
2076 	bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2077 
2078 	return 0;
2079 
2080     bad:
2081 	m_freem(*mp);
2082 	*mp = NULL;
2083 	return error;
2084 }
2085 
2086 /*
2087  * Perform basic checks on header size since
2088  * IPF assumes ip_input has already processed
2089  * it for it.  Cut-and-pasted from ip_input.c.
2090  * Given how simple the IPv6 version is,
2091  * does the IPv4 version really need to be
2092  * this complicated?
2093  *
2094  * XXX Should we update ipstat here, or not?
2095  * XXX Right now we update ipstat but not
2096  * XXX csum_counter.
2097  */
2098 static int
2099 bridge_ip_checkbasic(struct mbuf **mp)
2100 {
2101 	struct mbuf *m = *mp;
2102 	struct ip *ip;
2103 	int len, hlen;
2104 
2105 	if (*mp == NULL)
2106 		return -1;
2107 
2108 	if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2109 		if ((m = m_copyup(m, sizeof(struct ip),
2110 			(max_linkhdr + 3) & ~3)) == NULL) {
2111 			/* XXXJRT new stat, please */
2112 			ipstat.ips_toosmall++;
2113 			goto bad;
2114 		}
2115 	} else if (__predict_false(m->m_len < sizeof (struct ip))) {
2116 		if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2117 			ipstat.ips_toosmall++;
2118 			goto bad;
2119 		}
2120 	}
2121 	ip = mtod(m, struct ip *);
2122 	if (ip == NULL) goto bad;
2123 
2124 	if (ip->ip_v != IPVERSION) {
2125 		ipstat.ips_badvers++;
2126 		goto bad;
2127 	}
2128 	hlen = ip->ip_hl << 2;
2129 	if (hlen < sizeof(struct ip)) { /* minimum header length */
2130 		ipstat.ips_badhlen++;
2131 		goto bad;
2132 	}
2133 	if (hlen > m->m_len) {
2134 		if ((m = m_pullup(m, hlen)) == 0) {
2135 			ipstat.ips_badhlen++;
2136 			goto bad;
2137 		}
2138 		ip = mtod(m, struct ip *);
2139 		if (ip == NULL) goto bad;
2140 	}
2141 
2142         switch (m->m_pkthdr.csum_flags &
2143                 ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_IPv4) |
2144                  M_CSUM_IPv4_BAD)) {
2145         case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
2146                 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad); */
2147                 goto bad;
2148 
2149         case M_CSUM_IPv4:
2150                 /* Checksum was okay. */
2151                 /* INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok); */
2152                 break;
2153 
2154         default:
2155                 /* Must compute it ourselves. */
2156                 /* INET_CSUM_COUNTER_INCR(&ip_swcsum); */
2157                 if (in_cksum(m, hlen) != 0)
2158                         goto bad;
2159                 break;
2160         }
2161 
2162         /* Retrieve the packet length. */
2163         len = ntohs(ip->ip_len);
2164 
2165         /*
2166          * Check for additional length bogosity
2167          */
2168         if (len < hlen) {
2169                 ipstat.ips_badlen++;
2170                 goto bad;
2171         }
2172 
2173         /*
2174          * Check that the amount of data in the buffers
2175          * is as at least much as the IP header would have us expect.
2176          * Drop packet if shorter than we expect.
2177          */
2178         if (m->m_pkthdr.len < len) {
2179                 ipstat.ips_tooshort++;
2180                 goto bad;
2181         }
2182 
2183 	/* Checks out, proceed */
2184 	*mp = m;
2185 	return 0;
2186 
2187     bad:
2188 	*mp = m;
2189 	return -1;
2190 }
2191 
2192 # ifdef INET6
2193 /*
2194  * Same as above, but for IPv6.
2195  * Cut-and-pasted from ip6_input.c.
2196  * XXX Should we update ip6stat, or not?
2197  */
2198 static int
2199 bridge_ip6_checkbasic(struct mbuf **mp)
2200 {
2201 	struct mbuf *m = *mp;
2202 	struct ip6_hdr *ip6;
2203 
2204         /*
2205          * If the IPv6 header is not aligned, slurp it up into a new
2206          * mbuf with space for link headers, in the event we forward
2207          * it.  Otherwise, if it is aligned, make sure the entire base
2208          * IPv6 header is in the first mbuf of the chain.
2209          */
2210         if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2211                 struct ifnet *inifp = m->m_pkthdr.rcvif;
2212                 if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2213                                   (max_linkhdr + 3) & ~3)) == NULL) {
2214                         /* XXXJRT new stat, please */
2215                         ip6stat.ip6s_toosmall++;
2216                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2217                         goto bad;
2218                 }
2219         } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2220                 struct ifnet *inifp = m->m_pkthdr.rcvif;
2221                 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2222                         ip6stat.ip6s_toosmall++;
2223                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2224                         goto bad;
2225                 }
2226         }
2227 
2228         ip6 = mtod(m, struct ip6_hdr *);
2229 
2230         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2231                 ip6stat.ip6s_badvers++;
2232                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2233                 goto bad;
2234         }
2235 
2236 	/* Checks out, proceed */
2237 	*mp = m;
2238 	return 0;
2239 
2240     bad:
2241 	*mp = m;
2242 	return -1;
2243 }
2244 # endif /* INET6 */
2245 #endif /* BRIDGE_IPF && PFIL_HOOKS */
2246