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