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