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