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