if_bridge.c revision 153497
1/*	$NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc 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__FBSDID("$FreeBSD: head/sys/net/if_bridge.c 153497 2005-12-17 10:03:48Z thompsa $");
84
85#include "opt_inet.h"
86#include "opt_inet6.h"
87
88#include <sys/param.h>
89#include <sys/mbuf.h>
90#include <sys/malloc.h>
91#include <sys/protosw.h>
92#include <sys/systm.h>
93#include <sys/time.h>
94#include <sys/socket.h> /* for net/if.h */
95#include <sys/sockio.h>
96#include <sys/ctype.h>  /* string functions */
97#include <sys/kernel.h>
98#include <sys/random.h>
99#include <sys/sysctl.h>
100#include <vm/uma.h>
101#include <sys/module.h>
102#include <sys/proc.h>
103#include <sys/lock.h>
104#include <sys/mutex.h>
105
106#include <net/bpf.h>
107#include <net/if.h>
108#include <net/if_clone.h>
109#include <net/if_dl.h>
110#include <net/if_types.h>
111#include <net/if_var.h>
112#include <net/pfil.h>
113
114#include <netinet/in.h> /* for struct arpcom */
115#include <netinet/in_systm.h>
116#include <netinet/in_var.h>
117#include <netinet/ip.h>
118#include <netinet/ip_var.h>
119#ifdef INET6
120#include <netinet/ip6.h>
121#include <netinet6/ip6_var.h>
122#endif
123#include <machine/in_cksum.h>
124#include <netinet/if_ether.h> /* for struct arpcom */
125#include <net/if_bridgevar.h>
126#include <net/if_llc.h>
127
128#include <net/route.h>
129#include <netinet/ip_fw.h>
130#include <netinet/ip_dummynet.h>
131
132/*
133 * Size of the route hash table.  Must be a power of two.
134 */
135#ifndef BRIDGE_RTHASH_SIZE
136#define	BRIDGE_RTHASH_SIZE		1024
137#endif
138
139#define	BRIDGE_RTHASH_MASK		(BRIDGE_RTHASH_SIZE - 1)
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
173static struct mtx 	bridge_list_mtx;
174eventhandler_tag	bridge_detach_cookie = NULL;
175
176int	bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
177
178uma_zone_t bridge_rtnode_zone;
179
180static int	bridge_clone_create(struct if_clone *, int);
181static void	bridge_clone_destroy(struct ifnet *);
182
183static int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
184static void	bridge_ifdetach(void *arg __unused, struct ifnet *);
185static void	bridge_init(void *);
186static void	bridge_dummynet(struct mbuf *, struct ifnet *);
187static void	bridge_stop(struct ifnet *, int);
188static void	bridge_start(struct ifnet *);
189static struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
190static int	bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
191		    struct rtentry *);
192
193static void	bridge_forward(struct bridge_softc *, struct mbuf *m);
194
195static void	bridge_timer(void *);
196
197static void	bridge_broadcast(struct bridge_softc *, struct ifnet *,
198		    struct mbuf *, int);
199static void	bridge_span(struct bridge_softc *, struct mbuf *);
200
201static int	bridge_rtupdate(struct bridge_softc *, const uint8_t *,
202		    struct ifnet *, int, uint8_t);
203static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
204static void	bridge_rttrim(struct bridge_softc *);
205static void	bridge_rtage(struct bridge_softc *);
206static void	bridge_rtflush(struct bridge_softc *, int);
207static int	bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
208
209static int	bridge_rtable_init(struct bridge_softc *);
210static void	bridge_rtable_fini(struct bridge_softc *);
211
212static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
213		    const uint8_t *);
214static int	bridge_rtnode_insert(struct bridge_softc *,
215		    struct bridge_rtnode *);
216static void	bridge_rtnode_destroy(struct bridge_softc *,
217		    struct bridge_rtnode *);
218
219static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
220		    const char *name);
221static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
222		    struct ifnet *ifp);
223static void	bridge_delete_member(struct bridge_softc *,
224		    struct bridge_iflist *, int);
225static void	bridge_delete_span(struct bridge_softc *,
226		    struct bridge_iflist *);
227
228static int	bridge_ioctl_add(struct bridge_softc *, void *);
229static int	bridge_ioctl_del(struct bridge_softc *, void *);
230static int	bridge_ioctl_gifflags(struct bridge_softc *, void *);
231static int	bridge_ioctl_sifflags(struct bridge_softc *, void *);
232static int	bridge_ioctl_scache(struct bridge_softc *, void *);
233static int	bridge_ioctl_gcache(struct bridge_softc *, void *);
234static int	bridge_ioctl_gifs(struct bridge_softc *, void *);
235static int	bridge_ioctl_rts(struct bridge_softc *, void *);
236static int	bridge_ioctl_saddr(struct bridge_softc *, void *);
237static int	bridge_ioctl_sto(struct bridge_softc *, void *);
238static int	bridge_ioctl_gto(struct bridge_softc *, void *);
239static int	bridge_ioctl_daddr(struct bridge_softc *, void *);
240static int	bridge_ioctl_flush(struct bridge_softc *, void *);
241static int	bridge_ioctl_gpri(struct bridge_softc *, void *);
242static int	bridge_ioctl_spri(struct bridge_softc *, void *);
243static int	bridge_ioctl_ght(struct bridge_softc *, void *);
244static int	bridge_ioctl_sht(struct bridge_softc *, void *);
245static int	bridge_ioctl_gfd(struct bridge_softc *, void *);
246static int	bridge_ioctl_sfd(struct bridge_softc *, void *);
247static int	bridge_ioctl_gma(struct bridge_softc *, void *);
248static int	bridge_ioctl_sma(struct bridge_softc *, void *);
249static int	bridge_ioctl_sifprio(struct bridge_softc *, void *);
250static int	bridge_ioctl_sifcost(struct bridge_softc *, void *);
251static int	bridge_ioctl_addspan(struct bridge_softc *, void *);
252static int	bridge_ioctl_delspan(struct bridge_softc *, void *);
253static int	bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
254		    int);
255static int	bridge_ip_checkbasic(struct mbuf **mp);
256# ifdef INET6
257static int	bridge_ip6_checkbasic(struct mbuf **mp);
258# endif /* INET6 */
259
260SYSCTL_DECL(_net_link);
261SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
262
263static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
264static int pfil_member = 1; /* run pfil hooks on the member interface */
265static int pfil_ipfw = 0;   /* layer2 filter with ipfw */
266SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
267    &pfil_bridge, 0, "Packet filter on the bridge interface");
268SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
269    &pfil_member, 0, "Packet filter on the member interface");
270
271struct bridge_control {
272	int	(*bc_func)(struct bridge_softc *, void *);
273	int	bc_argsize;
274	int	bc_flags;
275};
276
277#define	BC_F_COPYIN		0x01	/* copy arguments in */
278#define	BC_F_COPYOUT		0x02	/* copy arguments out */
279#define	BC_F_SUSER		0x04	/* do super-user check */
280
281const struct bridge_control bridge_control_table[] = {
282	{ bridge_ioctl_add,		sizeof(struct ifbreq),
283	  BC_F_COPYIN|BC_F_SUSER },
284	{ bridge_ioctl_del,		sizeof(struct ifbreq),
285	  BC_F_COPYIN|BC_F_SUSER },
286
287	{ bridge_ioctl_gifflags,	sizeof(struct ifbreq),
288	  BC_F_COPYIN|BC_F_COPYOUT },
289	{ bridge_ioctl_sifflags,	sizeof(struct ifbreq),
290	  BC_F_COPYIN|BC_F_SUSER },
291
292	{ bridge_ioctl_scache,		sizeof(struct ifbrparam),
293	  BC_F_COPYIN|BC_F_SUSER },
294	{ bridge_ioctl_gcache,		sizeof(struct ifbrparam),
295	  BC_F_COPYOUT },
296
297	{ bridge_ioctl_gifs,		sizeof(struct ifbifconf),
298	  BC_F_COPYIN|BC_F_COPYOUT },
299	{ bridge_ioctl_rts,		sizeof(struct ifbaconf),
300	  BC_F_COPYIN|BC_F_COPYOUT },
301
302	{ bridge_ioctl_saddr,		sizeof(struct ifbareq),
303	  BC_F_COPYIN|BC_F_SUSER },
304
305	{ bridge_ioctl_sto,		sizeof(struct ifbrparam),
306	  BC_F_COPYIN|BC_F_SUSER },
307	{ bridge_ioctl_gto,		sizeof(struct ifbrparam),
308	  BC_F_COPYOUT },
309
310	{ bridge_ioctl_daddr,		sizeof(struct ifbareq),
311	  BC_F_COPYIN|BC_F_SUSER },
312
313	{ bridge_ioctl_flush,		sizeof(struct ifbreq),
314	  BC_F_COPYIN|BC_F_SUSER },
315
316	{ bridge_ioctl_gpri,		sizeof(struct ifbrparam),
317	  BC_F_COPYOUT },
318	{ bridge_ioctl_spri,		sizeof(struct ifbrparam),
319	  BC_F_COPYIN|BC_F_SUSER },
320
321	{ bridge_ioctl_ght,		sizeof(struct ifbrparam),
322	  BC_F_COPYOUT },
323	{ bridge_ioctl_sht,		sizeof(struct ifbrparam),
324	  BC_F_COPYIN|BC_F_SUSER },
325
326	{ bridge_ioctl_gfd,		sizeof(struct ifbrparam),
327	  BC_F_COPYOUT },
328	{ bridge_ioctl_sfd,		sizeof(struct ifbrparam),
329	  BC_F_COPYIN|BC_F_SUSER },
330
331	{ bridge_ioctl_gma,		sizeof(struct ifbrparam),
332	  BC_F_COPYOUT },
333	{ bridge_ioctl_sma,		sizeof(struct ifbrparam),
334	  BC_F_COPYIN|BC_F_SUSER },
335
336	{ bridge_ioctl_sifprio,		sizeof(struct ifbreq),
337	  BC_F_COPYIN|BC_F_SUSER },
338
339	{ bridge_ioctl_sifcost,		sizeof(struct ifbreq),
340	  BC_F_COPYIN|BC_F_SUSER },
341
342	{ bridge_ioctl_addspan,		sizeof(struct ifbreq),
343	  BC_F_COPYIN|BC_F_SUSER },
344	{ bridge_ioctl_delspan,		sizeof(struct ifbreq),
345	  BC_F_COPYIN|BC_F_SUSER },
346};
347const int bridge_control_table_size =
348    sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
349
350static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
351			{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
352
353LIST_HEAD(, bridge_softc) bridge_list;
354
355IFC_SIMPLE_DECLARE(bridge, 0);
356
357static int
358bridge_modevent(module_t mod, int type, void *data)
359{
360
361	switch (type) {
362	case MOD_LOAD:
363		mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
364		if_clone_attach(&bridge_cloner);
365		bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
366		    sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
367		    UMA_ALIGN_PTR, 0);
368		LIST_INIT(&bridge_list);
369		bridge_input_p = bridge_input;
370		bridge_output_p = bridge_output;
371		bridge_dn_p = bridge_dummynet;
372		bstp_linkstate_p = bstp_linkstate;
373		bridge_detach_cookie = EVENTHANDLER_REGISTER(
374		    ifnet_departure_event, bridge_ifdetach, NULL,
375		    EVENTHANDLER_PRI_ANY);
376		break;
377	case MOD_UNLOAD:
378		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
379		    bridge_detach_cookie);
380		if_clone_detach(&bridge_cloner);
381		uma_zdestroy(bridge_rtnode_zone);
382		bridge_input_p = NULL;
383		bridge_output_p = NULL;
384		bridge_dn_p = NULL;
385		bstp_linkstate_p = NULL;
386		mtx_destroy(&bridge_list_mtx);
387		break;
388	default:
389		return EOPNOTSUPP;
390	}
391	return 0;
392}
393
394static moduledata_t bridge_mod = {
395	"if_bridge",
396	bridge_modevent,
397	0
398};
399
400DECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
401
402/*
403 * handler for net.link.bridge.pfil_ipfw
404 */
405static int
406sysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS)
407{
408	int enable = pfil_ipfw;
409	int error;
410
411	error = sysctl_handle_int(oidp, &enable, 0, req);
412	enable = (enable) ? 1 : 0;
413
414	if (enable != pfil_ipfw) {
415		pfil_ipfw = enable;
416
417		/*
418		 * Disable pfil so that ipfw doesnt run twice, if the user
419		 * really wants both then they can re-enable pfil_bridge and/or
420		 * pfil_member.
421		 */
422		if (pfil_ipfw) {
423			pfil_bridge = 0;
424			pfil_member = 0;
425		}
426	}
427
428	return error;
429}
430SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
431	    &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW");
432
433/*
434 * bridge_clone_create:
435 *
436 *	Create a new bridge instance.
437 */
438static int
439bridge_clone_create(struct if_clone *ifc, int unit)
440{
441	struct bridge_softc *sc;
442	struct ifnet *ifp;
443	u_char eaddr[6];
444
445	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
446	BRIDGE_LOCK_INIT(sc);
447	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
448	if (ifp == NULL) {
449		free(sc, M_DEVBUF);
450		return (ENOSPC);
451	}
452
453	sc->sc_brtmax = BRIDGE_RTABLE_MAX;
454	sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
455	sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
456	sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
457	sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
458	sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
459	sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
460
461	/* Initialize our routing table. */
462	bridge_rtable_init(sc);
463
464	callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
465	callout_init_mtx(&sc->sc_bstpcallout, &sc->sc_mtx, 0);
466
467	LIST_INIT(&sc->sc_iflist);
468	LIST_INIT(&sc->sc_spanlist);
469
470	ifp->if_softc = sc;
471	if_initname(ifp, ifc->ifc_name, unit);
472	ifp->if_mtu = ETHERMTU;
473	ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
474	ifp->if_ioctl = bridge_ioctl;
475	ifp->if_output = bridge_output;
476	ifp->if_start = bridge_start;
477	ifp->if_init = bridge_init;
478	ifp->if_type = IFT_BRIDGE;
479	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
480	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
481	IFQ_SET_READY(&ifp->if_snd);
482	ifp->if_hdrlen = ETHER_HDR_LEN;
483
484	/*
485	 * Generate a random ethernet address and use the private AC:DE:48
486	 * OUI code.
487	 */
488	arc4rand(eaddr, ETHER_ADDR_LEN, 1);
489	eaddr[0] = 0xAC;
490	eaddr[1] = 0xDE;
491	eaddr[2] = 0x48;
492
493	ether_ifattach(ifp, eaddr);
494	/* Now undo some of the damage... */
495	ifp->if_baudrate = 0;
496	ifp->if_type = IFT_BRIDGE;
497
498	mtx_lock(&bridge_list_mtx);
499	LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
500	mtx_unlock(&bridge_list_mtx);
501
502	return (0);
503}
504
505/*
506 * bridge_clone_destroy:
507 *
508 *	Destroy a bridge instance.
509 */
510static void
511bridge_clone_destroy(struct ifnet *ifp)
512{
513	struct bridge_softc *sc = ifp->if_softc;
514	struct bridge_iflist *bif;
515
516	BRIDGE_LOCK(sc);
517
518	bridge_stop(ifp, 1);
519	ifp->if_flags &= ~IFF_UP;
520
521	while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
522		bridge_delete_member(sc, bif, 0);
523
524	while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
525		bridge_delete_span(sc, bif);
526	}
527
528	BRIDGE_UNLOCK(sc);
529
530	callout_drain(&sc->sc_brcallout);
531	callout_drain(&sc->sc_bstpcallout);
532
533	mtx_lock(&bridge_list_mtx);
534	LIST_REMOVE(sc, sc_list);
535	mtx_unlock(&bridge_list_mtx);
536
537	ether_ifdetach(ifp);
538	if_free_type(ifp, IFT_ETHER);
539
540	/* Tear down the routing table. */
541	bridge_rtable_fini(sc);
542
543	BRIDGE_LOCK_DESTROY(sc);
544	free(sc, M_DEVBUF);
545}
546
547/*
548 * bridge_ioctl:
549 *
550 *	Handle a control request from the operator.
551 */
552static int
553bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
554{
555	struct bridge_softc *sc = ifp->if_softc;
556	struct thread *td = curthread;
557	union {
558		struct ifbreq ifbreq;
559		struct ifbifconf ifbifconf;
560		struct ifbareq ifbareq;
561		struct ifbaconf ifbaconf;
562		struct ifbrparam ifbrparam;
563	} args;
564	struct ifdrv *ifd = (struct ifdrv *) data;
565	const struct bridge_control *bc;
566	int error = 0;
567
568	BRIDGE_LOCK(sc);
569
570	switch (cmd) {
571
572	case SIOCADDMULTI:
573	case SIOCDELMULTI:
574		break;
575
576	case SIOCGDRVSPEC:
577	case SIOCSDRVSPEC:
578		if (ifd->ifd_cmd >= bridge_control_table_size) {
579			error = EINVAL;
580			break;
581		}
582		bc = &bridge_control_table[ifd->ifd_cmd];
583
584		if (cmd == SIOCGDRVSPEC &&
585		    (bc->bc_flags & BC_F_COPYOUT) == 0) {
586			error = EINVAL;
587			break;
588		}
589		else if (cmd == SIOCSDRVSPEC &&
590		    (bc->bc_flags & BC_F_COPYOUT) != 0) {
591			error = EINVAL;
592			break;
593		}
594
595		if (bc->bc_flags & BC_F_SUSER) {
596			error = suser(td);
597			if (error)
598				break;
599		}
600
601		if (ifd->ifd_len != bc->bc_argsize ||
602		    ifd->ifd_len > sizeof(args)) {
603			error = EINVAL;
604			break;
605		}
606
607		if (bc->bc_flags & BC_F_COPYIN) {
608			error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
609			if (error)
610				break;
611		}
612
613		error = (*bc->bc_func)(sc, &args);
614		if (error)
615			break;
616
617		if (bc->bc_flags & BC_F_COPYOUT)
618			error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
619
620		break;
621
622	case SIOCSIFFLAGS:
623		if (!(ifp->if_flags & IFF_UP) &&
624		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
625			/*
626			 * If interface is marked down and it is running,
627			 * then stop and disable it.
628			 */
629			bridge_stop(ifp, 1);
630		} else if ((ifp->if_flags & IFF_UP) &&
631		    !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
632			/*
633			 * If interface is marked up and it is stopped, then
634			 * start it.
635			 */
636			BRIDGE_UNLOCK(sc);
637			(*ifp->if_init)(sc);
638		}
639		break;
640
641	case SIOCSIFMTU:
642		/* Do not allow the MTU to be changed on the bridge */
643		error = EINVAL;
644		break;
645
646	default:
647		/*
648		 * drop the lock as ether_ioctl() will call bridge_start() and
649		 * cause the lock to be recursed.
650		 */
651		BRIDGE_UNLOCK(sc);
652		error = ether_ioctl(ifp, cmd, data);
653		break;
654	}
655
656	if (BRIDGE_LOCKED(sc))
657		BRIDGE_UNLOCK(sc);
658
659	return (error);
660}
661
662/*
663 * bridge_lookup_member:
664 *
665 *	Lookup a bridge member interface.
666 */
667static struct bridge_iflist *
668bridge_lookup_member(struct bridge_softc *sc, const char *name)
669{
670	struct bridge_iflist *bif;
671	struct ifnet *ifp;
672
673	BRIDGE_LOCK_ASSERT(sc);
674
675	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
676		ifp = bif->bif_ifp;
677		if (strcmp(ifp->if_xname, name) == 0)
678			return (bif);
679	}
680
681	return (NULL);
682}
683
684/*
685 * bridge_lookup_member_if:
686 *
687 *	Lookup a bridge member interface by ifnet*.
688 */
689static struct bridge_iflist *
690bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
691{
692	struct bridge_iflist *bif;
693
694	BRIDGE_LOCK_ASSERT(sc);
695
696	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
697		if (bif->bif_ifp == member_ifp)
698			return (bif);
699	}
700
701	return (NULL);
702}
703
704/*
705 * bridge_delete_member:
706 *
707 *	Delete the specified member interface.
708 */
709static void
710bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
711    int gone)
712{
713	struct ifnet *ifs = bif->bif_ifp;
714
715	BRIDGE_LOCK_ASSERT(sc);
716
717	if (!gone) {
718	    switch (ifs->if_type) {
719	    case IFT_ETHER:
720	    case IFT_L2VLAN:
721		    /*
722		     * Take the interface out of promiscuous mode.
723		     */
724		    (void) ifpromisc(ifs, 0);
725		    break;
726
727	    default:
728#ifdef DIAGNOSTIC
729		    panic("bridge_delete_member: impossible");
730#endif
731		    break;
732	    }
733	}
734
735	ifs->if_bridge = NULL;
736	BRIDGE_XLOCK(sc);
737	LIST_REMOVE(bif, bif_next);
738	BRIDGE_XDROP(sc);
739
740	bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
741
742	free(bif, M_DEVBUF);
743
744	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
745		bstp_initialization(sc);
746}
747
748/*
749 * bridge_delete_span:
750 *
751 *	Delete the specified span interface.
752 */
753static void
754bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif)
755{
756	BRIDGE_LOCK_ASSERT(sc);
757
758	KASSERT(bif->bif_ifp->if_bridge == NULL,
759	    ("%s: not a span interface", __func__));
760
761	LIST_REMOVE(bif, bif_next);
762	free(bif, M_DEVBUF);
763}
764
765static int
766bridge_ioctl_add(struct bridge_softc *sc, void *arg)
767{
768	struct ifbreq *req = arg;
769	struct bridge_iflist *bif = NULL;
770	struct ifnet *ifs;
771	int error = 0;
772
773	BRIDGE_LOCK_ASSERT(sc);
774
775	ifs = ifunit(req->ifbr_ifsname);
776	if (ifs == NULL)
777		return (ENOENT);
778
779	/* If it's in the span list, it can't be a member. */
780	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
781		if (ifs == bif->bif_ifp)
782			return (EBUSY);
783
784	/* Allow the first member to define the MTU */
785	if (LIST_EMPTY(&sc->sc_iflist))
786		sc->sc_ifp->if_mtu = ifs->if_mtu;
787	else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
788		if_printf(sc->sc_ifp, "invalid MTU for %s\n", ifs->if_xname);
789		return (EINVAL);
790	}
791
792	if (ifs->if_bridge == sc)
793		return (EEXIST);
794
795	if (ifs->if_bridge != NULL)
796		return (EBUSY);
797
798	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
799	if (bif == NULL)
800		return (ENOMEM);
801
802	switch (ifs->if_type) {
803	case IFT_ETHER:
804	case IFT_L2VLAN:
805		/*
806		 * Place the interface into promiscuous mode.
807		 */
808		error = ifpromisc(ifs, 1);
809		if (error)
810			goto out;
811		break;
812
813	default:
814		error = EINVAL;
815		goto out;
816	}
817
818	bif->bif_ifp = ifs;
819	bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
820	bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
821	bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
822
823	ifs->if_bridge = sc;
824	/*
825	 * XXX: XLOCK HERE!?!
826	 *
827	 * NOTE: insert_***HEAD*** should be safe for the traversals.
828	 */
829	LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
830
831	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
832		bstp_initialization(sc);
833	else
834		bstp_stop(sc);
835
836out:
837	if (error) {
838		if (bif != NULL)
839			free(bif, M_DEVBUF);
840	}
841	return (error);
842}
843
844static int
845bridge_ioctl_del(struct bridge_softc *sc, void *arg)
846{
847	struct ifbreq *req = arg;
848	struct bridge_iflist *bif;
849
850	BRIDGE_LOCK_ASSERT(sc);
851
852	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
853	if (bif == NULL)
854		return (ENOENT);
855
856	bridge_delete_member(sc, bif, 0);
857
858	return (0);
859}
860
861static int
862bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
863{
864	struct ifbreq *req = arg;
865	struct bridge_iflist *bif;
866
867	BRIDGE_LOCK_ASSERT(sc);
868
869	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
870	if (bif == NULL)
871		return (ENOENT);
872
873	req->ifbr_ifsflags = bif->bif_flags;
874	req->ifbr_state = bif->bif_state;
875	req->ifbr_priority = bif->bif_priority;
876	req->ifbr_path_cost = bif->bif_path_cost;
877	req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
878
879	return (0);
880}
881
882static int
883bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
884{
885	struct ifbreq *req = arg;
886	struct bridge_iflist *bif;
887
888	BRIDGE_LOCK_ASSERT(sc);
889
890	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
891	if (bif == NULL)
892		return (ENOENT);
893
894	if (req->ifbr_ifsflags & IFBIF_SPAN)
895		/* SPAN is readonly */
896		return (EINVAL);
897
898	if (req->ifbr_ifsflags & IFBIF_STP) {
899		switch (bif->bif_ifp->if_type) {
900		case IFT_ETHER:
901			/* These can do spanning tree. */
902			break;
903
904		default:
905			/* Nothing else can. */
906			return (EINVAL);
907		}
908	}
909
910	bif->bif_flags = req->ifbr_ifsflags;
911
912	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
913		bstp_initialization(sc);
914
915	return (0);
916}
917
918static int
919bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
920{
921	struct ifbrparam *param = arg;
922
923	BRIDGE_LOCK_ASSERT(sc);
924
925	sc->sc_brtmax = param->ifbrp_csize;
926	bridge_rttrim(sc);
927
928	return (0);
929}
930
931static int
932bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
933{
934	struct ifbrparam *param = arg;
935
936	BRIDGE_LOCK_ASSERT(sc);
937
938	param->ifbrp_csize = sc->sc_brtmax;
939
940	return (0);
941}
942
943static int
944bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
945{
946	struct ifbifconf *bifc = arg;
947	struct bridge_iflist *bif;
948	struct ifbreq breq;
949	int count, len, error = 0;
950
951	BRIDGE_LOCK_ASSERT(sc);
952
953	count = 0;
954	LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
955		count++;
956	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
957		count++;
958
959	if (bifc->ifbic_len == 0) {
960		bifc->ifbic_len = sizeof(breq) * count;
961		return (0);
962	}
963
964	count = 0;
965	len = bifc->ifbic_len;
966	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
967		if (len < sizeof(breq))
968			break;
969
970		strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
971		    sizeof(breq.ifbr_ifsname));
972		breq.ifbr_ifsflags = bif->bif_flags;
973		breq.ifbr_state = bif->bif_state;
974		breq.ifbr_priority = bif->bif_priority;
975		breq.ifbr_path_cost = bif->bif_path_cost;
976		breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
977		error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
978		if (error)
979			break;
980		count++;
981		len -= sizeof(breq);
982	}
983	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
984		if (len < sizeof(breq))
985			break;
986
987		strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
988		    sizeof(breq.ifbr_ifsname));
989		breq.ifbr_ifsflags = bif->bif_flags;
990		breq.ifbr_state = bif->bif_state;
991		breq.ifbr_priority = bif->bif_priority;
992		breq.ifbr_path_cost = bif->bif_path_cost;
993		breq.ifbr_portno = bif->bif_ifp->if_index & 0xff;
994		error = copyout(&breq, bifc->ifbic_req + count, sizeof(breq));
995		if (error)
996			break;
997		count++;
998		len -= sizeof(breq);
999	}
1000
1001	bifc->ifbic_len = sizeof(breq) * count;
1002	return (error);
1003}
1004
1005static int
1006bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
1007{
1008	struct ifbaconf *bac = arg;
1009	struct bridge_rtnode *brt;
1010	struct ifbareq bareq;
1011	struct timeval tv;
1012	int count = 0, error = 0, len;
1013
1014	BRIDGE_LOCK_ASSERT(sc);
1015
1016	if (bac->ifbac_len == 0)
1017		return (0);
1018
1019	getmicrotime(&tv);
1020
1021	len = bac->ifbac_len;
1022	LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
1023		if (len < sizeof(bareq))
1024			goto out;
1025		strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
1026		    sizeof(bareq.ifba_ifsname));
1027		memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
1028		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
1029				tv.tv_sec < brt->brt_expire)
1030			bareq.ifba_expire = brt->brt_expire - tv.tv_sec;
1031		else
1032			bareq.ifba_expire = 0;
1033		bareq.ifba_flags = brt->brt_flags;
1034
1035		error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
1036		if (error)
1037			goto out;
1038		count++;
1039		len -= sizeof(bareq);
1040	}
1041out:
1042	bac->ifbac_len = sizeof(bareq) * count;
1043	return (error);
1044}
1045
1046static int
1047bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
1048{
1049	struct ifbareq *req = arg;
1050	struct bridge_iflist *bif;
1051	int error;
1052
1053	BRIDGE_LOCK_ASSERT(sc);
1054
1055	bif = bridge_lookup_member(sc, req->ifba_ifsname);
1056	if (bif == NULL)
1057		return (ENOENT);
1058
1059	error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
1060	    req->ifba_flags);
1061
1062	return (error);
1063}
1064
1065static int
1066bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
1067{
1068	struct ifbrparam *param = arg;
1069
1070	BRIDGE_LOCK_ASSERT(sc);
1071
1072	sc->sc_brttimeout = param->ifbrp_ctime;
1073
1074	return (0);
1075}
1076
1077static int
1078bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
1079{
1080	struct ifbrparam *param = arg;
1081
1082	BRIDGE_LOCK_ASSERT(sc);
1083
1084	param->ifbrp_ctime = sc->sc_brttimeout;
1085
1086	return (0);
1087}
1088
1089static int
1090bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
1091{
1092	struct ifbareq *req = arg;
1093
1094	BRIDGE_LOCK_ASSERT(sc);
1095
1096	return (bridge_rtdaddr(sc, req->ifba_dst));
1097}
1098
1099static int
1100bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
1101{
1102	struct ifbreq *req = arg;
1103
1104	BRIDGE_LOCK_ASSERT(sc);
1105
1106	bridge_rtflush(sc, req->ifbr_ifsflags);
1107
1108	return (0);
1109}
1110
1111static int
1112bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1113{
1114	struct ifbrparam *param = arg;
1115
1116	BRIDGE_LOCK_ASSERT(sc);
1117
1118	param->ifbrp_prio = sc->sc_bridge_priority;
1119
1120	return (0);
1121}
1122
1123static int
1124bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1125{
1126	struct ifbrparam *param = arg;
1127
1128	BRIDGE_LOCK_ASSERT(sc);
1129
1130	sc->sc_bridge_priority = param->ifbrp_prio;
1131
1132	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1133		bstp_initialization(sc);
1134
1135	return (0);
1136}
1137
1138static int
1139bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1140{
1141	struct ifbrparam *param = arg;
1142
1143	BRIDGE_LOCK_ASSERT(sc);
1144
1145	param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
1146
1147	return (0);
1148}
1149
1150static int
1151bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1152{
1153	struct ifbrparam *param = arg;
1154
1155	BRIDGE_LOCK_ASSERT(sc);
1156
1157	if (param->ifbrp_hellotime == 0)
1158		return (EINVAL);
1159	sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
1160
1161	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1162		bstp_initialization(sc);
1163
1164	return (0);
1165}
1166
1167static int
1168bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1169{
1170	struct ifbrparam *param = arg;
1171
1172	BRIDGE_LOCK_ASSERT(sc);
1173
1174	param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
1175
1176	return (0);
1177}
1178
1179static int
1180bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1181{
1182	struct ifbrparam *param = arg;
1183
1184	BRIDGE_LOCK_ASSERT(sc);
1185
1186	if (param->ifbrp_fwddelay == 0)
1187		return (EINVAL);
1188	sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
1189
1190	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1191		bstp_initialization(sc);
1192
1193	return (0);
1194}
1195
1196static int
1197bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1198{
1199	struct ifbrparam *param = arg;
1200
1201	BRIDGE_LOCK_ASSERT(sc);
1202
1203	param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
1204
1205	return (0);
1206}
1207
1208static int
1209bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1210{
1211	struct ifbrparam *param = arg;
1212
1213	BRIDGE_LOCK_ASSERT(sc);
1214
1215	if (param->ifbrp_maxage == 0)
1216		return (EINVAL);
1217	sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
1218
1219	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1220		bstp_initialization(sc);
1221
1222	return (0);
1223}
1224
1225static int
1226bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1227{
1228	struct ifbreq *req = arg;
1229	struct bridge_iflist *bif;
1230
1231	BRIDGE_LOCK_ASSERT(sc);
1232
1233	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1234	if (bif == NULL)
1235		return (ENOENT);
1236
1237	bif->bif_priority = req->ifbr_priority;
1238
1239	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1240		bstp_initialization(sc);
1241
1242	return (0);
1243}
1244
1245static int
1246bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1247{
1248	struct ifbreq *req = arg;
1249	struct bridge_iflist *bif;
1250
1251	BRIDGE_LOCK_ASSERT(sc);
1252
1253	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1254	if (bif == NULL)
1255		return (ENOENT);
1256
1257	bif->bif_path_cost = req->ifbr_path_cost;
1258
1259	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1260		bstp_initialization(sc);
1261
1262	return (0);
1263}
1264
1265static int
1266bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
1267{
1268	struct ifbreq *req = arg;
1269	struct bridge_iflist *bif = NULL;
1270	struct ifnet *ifs;
1271
1272	BRIDGE_LOCK_ASSERT(sc);
1273
1274	ifs = ifunit(req->ifbr_ifsname);
1275	if (ifs == NULL)
1276		return (ENOENT);
1277
1278	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1279		if (ifs == bif->bif_ifp)
1280			return (EBUSY);
1281
1282	if (ifs->if_bridge != NULL)
1283		return (EBUSY);
1284
1285	switch (ifs->if_type) {
1286		case IFT_ETHER:
1287		case IFT_L2VLAN:
1288			break;
1289		default:
1290			return (EINVAL);
1291	}
1292
1293	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
1294	if (bif == NULL)
1295		return (ENOMEM);
1296
1297	bif->bif_ifp = ifs;
1298	bif->bif_flags = IFBIF_SPAN;
1299
1300	LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
1301
1302	return (0);
1303}
1304
1305static int
1306bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
1307{
1308	struct ifbreq *req = arg;
1309	struct bridge_iflist *bif;
1310	struct ifnet *ifs;
1311
1312	BRIDGE_LOCK_ASSERT(sc);
1313
1314	ifs = ifunit(req->ifbr_ifsname);
1315	if (ifs == NULL)
1316		return (ENOENT);
1317
1318	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1319		if (ifs == bif->bif_ifp)
1320			break;
1321
1322	if (bif == NULL)
1323		return (ENOENT);
1324
1325	bridge_delete_span(sc, bif);
1326
1327	return (0);
1328}
1329
1330/*
1331 * bridge_ifdetach:
1332 *
1333 *	Detach an interface from a bridge.  Called when a member
1334 *	interface is detaching.
1335 */
1336static void
1337bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
1338{
1339	struct bridge_softc *sc = ifp->if_bridge;
1340	struct bridge_iflist *bif;
1341
1342	/* Check if the interface is a bridge member */
1343	if (sc != NULL) {
1344		BRIDGE_LOCK(sc);
1345
1346		bif = bridge_lookup_member_if(sc, ifp);
1347		if (bif != NULL)
1348			bridge_delete_member(sc, bif, 1);
1349
1350
1351		BRIDGE_UNLOCK(sc);
1352		return;
1353	}
1354
1355	/* Check if the interface is a span port */
1356	mtx_lock(&bridge_list_mtx);
1357	LIST_FOREACH(sc, &bridge_list, sc_list) {
1358		BRIDGE_LOCK(sc);
1359		LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1360			if (ifp == bif->bif_ifp) {
1361				bridge_delete_span(sc, bif);
1362				break;
1363			}
1364
1365		BRIDGE_UNLOCK(sc);
1366	}
1367	mtx_unlock(&bridge_list_mtx);
1368}
1369
1370/*
1371 * bridge_init:
1372 *
1373 *	Initialize a bridge interface.
1374 */
1375static void
1376bridge_init(void *xsc)
1377{
1378	struct bridge_softc *sc = (struct bridge_softc *)xsc;
1379	struct ifnet *ifp = sc->sc_ifp;
1380
1381	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1382		return;
1383
1384	BRIDGE_LOCK(sc);
1385	callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1386	    bridge_timer, sc);
1387
1388	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1389	bstp_initialization(sc);
1390	BRIDGE_UNLOCK(sc);
1391	return;
1392}
1393
1394/*
1395 * bridge_stop:
1396 *
1397 *	Stop the bridge interface.
1398 */
1399static void
1400bridge_stop(struct ifnet *ifp, int disable)
1401{
1402	struct bridge_softc *sc = ifp->if_softc;
1403
1404	BRIDGE_LOCK_ASSERT(sc);
1405
1406	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1407		return;
1408
1409	callout_stop(&sc->sc_brcallout);
1410	bstp_stop(sc);
1411
1412	bridge_rtflush(sc, IFBF_FLUSHDYN);
1413
1414	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1415}
1416
1417/*
1418 * bridge_enqueue:
1419 *
1420 *	Enqueue a packet on a bridge member interface.
1421 *
1422 */
1423__inline void
1424bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
1425{
1426	int len, err;
1427	short mflags;
1428
1429	/*
1430	 * Clear any in-bound checksum flags for this packet.
1431	 */
1432	m->m_pkthdr.csum_flags = 0;
1433
1434	len = m->m_pkthdr.len;
1435	mflags = m->m_flags;
1436
1437	IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
1438	if (err == 0) {
1439
1440		sc->sc_ifp->if_opackets++;
1441		sc->sc_ifp->if_obytes += len;
1442
1443		dst_ifp->if_obytes += len;
1444
1445		if (mflags & M_MCAST) {
1446			sc->sc_ifp->if_omcasts++;
1447			dst_ifp->if_omcasts++;
1448		}
1449	}
1450
1451	if ((dst_ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
1452		(*dst_ifp->if_start)(dst_ifp);
1453}
1454
1455/*
1456 * bridge_dummynet:
1457 *
1458 * 	Receive a queued packet from dummynet and pass it on to the output
1459 * 	interface.
1460 *
1461 *	The mbuf has the Ethernet header already attached.
1462 */
1463static void
1464bridge_dummynet(struct mbuf *m, struct ifnet *ifp)
1465{
1466	struct bridge_softc *sc;
1467
1468	sc = ifp->if_bridge;
1469
1470	/*
1471	 * The packet didnt originate from a member interface. This should only
1472	 * ever happen if a member interface is removed while packets are
1473	 * queued for it.
1474	 */
1475	if (sc == NULL) {
1476		m_freem(m);
1477		return;
1478	}
1479
1480	if (inet_pfil_hook.ph_busy_count >= 0
1481#ifdef INET6
1482	    || inet6_pfil_hook.ph_busy_count >= 0
1483#endif
1484	    ) {
1485		if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0)
1486			return;
1487		if (m == NULL)
1488			return;
1489	}
1490
1491	bridge_enqueue(sc, ifp, m);
1492}
1493
1494/*
1495 * bridge_output:
1496 *
1497 *	Send output from a bridge member interface.  This
1498 *	performs the bridging function for locally originated
1499 *	packets.
1500 *
1501 *	The mbuf has the Ethernet header already attached.  We must
1502 *	enqueue or free the mbuf before returning.
1503 */
1504static int
1505bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
1506    struct rtentry *rt)
1507{
1508	struct ether_header *eh;
1509	struct ifnet *dst_if;
1510	struct bridge_softc *sc;
1511
1512	if (m->m_len < ETHER_HDR_LEN) {
1513		m = m_pullup(m, ETHER_HDR_LEN);
1514		if (m == NULL)
1515			return (0);
1516	}
1517
1518	eh = mtod(m, struct ether_header *);
1519	sc = ifp->if_bridge;
1520
1521	BRIDGE_LOCK(sc);
1522
1523	/*
1524	 * If bridge is down, but the original output interface is up,
1525	 * go ahead and send out that interface.  Otherwise, the packet
1526	 * is dropped below.
1527	 */
1528	if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1529		dst_if = ifp;
1530		goto sendunicast;
1531	}
1532
1533	/*
1534	 * If the packet is a multicast, or we don't know a better way to
1535	 * get there, send to all interfaces.
1536	 */
1537	if (ETHER_IS_MULTICAST(eh->ether_dhost))
1538		dst_if = NULL;
1539	else
1540		dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1541	if (dst_if == NULL) {
1542		struct bridge_iflist *bif;
1543		struct mbuf *mc;
1544		int error = 0, used = 0;
1545
1546		BRIDGE_LOCK2REF(sc, error);
1547		if (error) {
1548			m_freem(m);
1549			return (0);
1550		}
1551
1552		bridge_span(sc, m);
1553
1554		LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1555			dst_if = bif->bif_ifp;
1556			if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
1557				continue;
1558
1559			/*
1560			 * If this is not the original output interface,
1561			 * and the interface is participating in spanning
1562			 * tree, make sure the port is in a state that
1563			 * allows forwarding.
1564			 */
1565			if (dst_if != ifp &&
1566			    (bif->bif_flags & IFBIF_STP) != 0) {
1567				switch (bif->bif_state) {
1568				case BSTP_IFSTATE_BLOCKING:
1569				case BSTP_IFSTATE_LISTENING:
1570				case BSTP_IFSTATE_DISABLED:
1571					continue;
1572				}
1573			}
1574
1575			if (LIST_NEXT(bif, bif_next) == NULL) {
1576				used = 1;
1577				mc = m;
1578			} else {
1579				mc = m_copypacket(m, M_DONTWAIT);
1580				if (mc == NULL) {
1581					sc->sc_ifp->if_oerrors++;
1582					continue;
1583				}
1584			}
1585
1586			bridge_enqueue(sc, dst_if, mc);
1587		}
1588		if (used == 0)
1589			m_freem(m);
1590		BRIDGE_UNREF(sc);
1591		return (0);
1592	}
1593
1594sendunicast:
1595	/*
1596	 * XXX Spanning tree consideration here?
1597	 */
1598
1599	bridge_span(sc, m);
1600	if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1601		m_freem(m);
1602		BRIDGE_UNLOCK(sc);
1603		return (0);
1604	}
1605
1606	BRIDGE_UNLOCK(sc);
1607	bridge_enqueue(sc, dst_if, m);
1608	return (0);
1609}
1610
1611/*
1612 * bridge_start:
1613 *
1614 *	Start output on a bridge.
1615 *
1616 */
1617static void
1618bridge_start(struct ifnet *ifp)
1619{
1620	struct bridge_softc *sc;
1621	struct mbuf *m;
1622	struct ether_header *eh;
1623	struct ifnet *dst_if;
1624
1625	sc = ifp->if_softc;
1626
1627	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1628	for (;;) {
1629		IFQ_DEQUEUE(&ifp->if_snd, m);
1630		if (m == 0)
1631			break;
1632		BPF_MTAP(ifp, m);
1633
1634		eh = mtod(m, struct ether_header *);
1635		dst_if = NULL;
1636
1637		BRIDGE_LOCK(sc);
1638		if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1639			dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1640		}
1641
1642		if (dst_if == NULL)
1643			bridge_broadcast(sc, ifp, m, 0);
1644		else {
1645			BRIDGE_UNLOCK(sc);
1646			bridge_enqueue(sc, dst_if, m);
1647		}
1648	}
1649	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1650
1651	return;
1652}
1653
1654/*
1655 * bridge_forward:
1656 *
1657 *	The forwarding function of the bridge.
1658 *
1659 *	NOTE: Releases the lock on return.
1660 */
1661static void
1662bridge_forward(struct bridge_softc *sc, struct mbuf *m)
1663{
1664	struct bridge_iflist *bif;
1665	struct ifnet *src_if, *dst_if, *ifp;
1666	struct ether_header *eh;
1667
1668	src_if = m->m_pkthdr.rcvif;
1669	BRIDGE_LOCK_ASSERT(sc);
1670	ifp = sc->sc_ifp;
1671
1672	sc->sc_ifp->if_ipackets++;
1673	sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
1674
1675	/*
1676	 * Look up the bridge_iflist.
1677	 */
1678	bif = bridge_lookup_member_if(sc, src_if);
1679	if (bif == NULL) {
1680		/* Interface is not a bridge member (anymore?) */
1681		BRIDGE_UNLOCK(sc);
1682		m_freem(m);
1683		return;
1684	}
1685
1686	if (bif->bif_flags & IFBIF_STP) {
1687		switch (bif->bif_state) {
1688		case BSTP_IFSTATE_BLOCKING:
1689		case BSTP_IFSTATE_LISTENING:
1690		case BSTP_IFSTATE_DISABLED:
1691			BRIDGE_UNLOCK(sc);
1692			m_freem(m);
1693			return;
1694		}
1695	}
1696
1697	eh = mtod(m, struct ether_header *);
1698
1699	/*
1700	 * If the interface is learning, and the source
1701	 * address is valid and not multicast, record
1702	 * the address.
1703	 */
1704	if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1705	    ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
1706	    (eh->ether_shost[0] == 0 &&
1707	     eh->ether_shost[1] == 0 &&
1708	     eh->ether_shost[2] == 0 &&
1709	     eh->ether_shost[3] == 0 &&
1710	     eh->ether_shost[4] == 0 &&
1711	     eh->ether_shost[5] == 0) == 0) {
1712		(void) bridge_rtupdate(sc, eh->ether_shost,
1713		    src_if, 0, IFBAF_DYNAMIC);
1714	}
1715
1716	if ((bif->bif_flags & IFBIF_STP) != 0 &&
1717	    bif->bif_state == BSTP_IFSTATE_LEARNING) {
1718		m_freem(m);
1719		BRIDGE_UNLOCK(sc);
1720		return;
1721	}
1722
1723	/*
1724	 * At this point, the port either doesn't participate
1725	 * in spanning tree or it is in the forwarding state.
1726	 */
1727
1728	/*
1729	 * If the packet is unicast, destined for someone on
1730	 * "this" side of the bridge, drop it.
1731	 */
1732	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1733		dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1734		if (src_if == dst_if) {
1735			BRIDGE_UNLOCK(sc);
1736			m_freem(m);
1737			return;
1738		}
1739	} else {
1740		/* ...forward it to all interfaces. */
1741		sc->sc_ifp->if_imcasts++;
1742		dst_if = NULL;
1743	}
1744
1745	/* run the packet filter */
1746	if (inet_pfil_hook.ph_busy_count >= 0
1747#ifdef INET6
1748	    || inet6_pfil_hook.ph_busy_count >= 0
1749#endif
1750	    ) {
1751		BRIDGE_UNLOCK(sc);
1752		if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
1753			return;
1754		if (m == NULL)
1755			return;
1756		BRIDGE_LOCK(sc);
1757	}
1758
1759	if (dst_if == NULL) {
1760		/* tap off packets passing the bridge */
1761		BPF_MTAP(ifp, m);
1762
1763		bridge_broadcast(sc, src_if, m, 1);
1764		return;
1765	}
1766
1767	/*
1768	 * At this point, we're dealing with a unicast frame
1769	 * going to a different interface.
1770	 */
1771	if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1772		BRIDGE_UNLOCK(sc);
1773		m_freem(m);
1774		return;
1775	}
1776	bif = bridge_lookup_member_if(sc, dst_if);
1777	if (bif == NULL) {
1778		/* Not a member of the bridge (anymore?) */
1779		BRIDGE_UNLOCK(sc);
1780		m_freem(m);
1781		return;
1782	}
1783
1784	if (bif->bif_flags & IFBIF_STP) {
1785		switch (bif->bif_state) {
1786		case BSTP_IFSTATE_DISABLED:
1787		case BSTP_IFSTATE_BLOCKING:
1788			BRIDGE_UNLOCK(sc);
1789			m_freem(m);
1790			return;
1791		}
1792	}
1793
1794	/* tap off packets passing the bridge */
1795	BPF_MTAP(ifp, m);
1796
1797	BRIDGE_UNLOCK(sc);
1798
1799	if (inet_pfil_hook.ph_busy_count >= 0
1800#ifdef INET6
1801	    || inet6_pfil_hook.ph_busy_count >= 0
1802#endif
1803	    ) {
1804		if (bridge_pfil(&m, sc->sc_ifp, dst_if, PFIL_OUT) != 0)
1805			return;
1806		if (m == NULL)
1807			return;
1808	}
1809
1810	bridge_enqueue(sc, dst_if, m);
1811}
1812
1813/*
1814 * bridge_input:
1815 *
1816 *	Receive input from a member interface.  Queue the packet for
1817 *	bridging if it is not for us.
1818 */
1819static struct mbuf *
1820bridge_input(struct ifnet *ifp, struct mbuf *m)
1821{
1822	struct bridge_softc *sc = ifp->if_bridge;
1823	struct bridge_iflist *bif;
1824	struct ifnet *bifp;
1825	struct ether_header *eh;
1826	struct mbuf *mc, *mc2;
1827
1828	if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1829		return (m);
1830
1831	bifp = sc->sc_ifp;
1832
1833	BRIDGE_LOCK(sc);
1834	bif = bridge_lookup_member_if(sc, ifp);
1835	if (bif == NULL) {
1836		BRIDGE_UNLOCK(sc);
1837		return (m);
1838	}
1839
1840	eh = mtod(m, struct ether_header *);
1841
1842	if (memcmp(eh->ether_dhost, IF_LLADDR(bifp),
1843	    ETHER_ADDR_LEN) == 0) {
1844		/*
1845		 * If the packet is for us, set the packets source as the
1846		 * bridge, and return the packet back to ether_input for
1847		 * local processing.
1848		 */
1849
1850		/* XXX Do we tap the packet for the member interface too?
1851		 * BPF_MTAP(&m->m_pkthdr.rcvif, m);
1852		 */
1853
1854		/* Mark the packet as arriving on the bridge interface */
1855		m->m_pkthdr.rcvif = bifp;
1856		BPF_MTAP(bifp, m);
1857		bifp->if_ipackets++;
1858
1859		BRIDGE_UNLOCK(sc);
1860		return (m);
1861	}
1862
1863	bridge_span(sc, m);
1864
1865	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1866		/* Tap off 802.1D packets; they do not get forwarded. */
1867		if (memcmp(eh->ether_dhost, bstp_etheraddr,
1868		    ETHER_ADDR_LEN) == 0) {
1869			m = bstp_input(ifp, m);
1870			if (m == NULL) {
1871				BRIDGE_UNLOCK(sc);
1872				return (NULL);
1873			}
1874		}
1875
1876		if (bif->bif_flags & IFBIF_STP) {
1877			switch (bif->bif_state) {
1878			case BSTP_IFSTATE_BLOCKING:
1879			case BSTP_IFSTATE_LISTENING:
1880			case BSTP_IFSTATE_DISABLED:
1881				BRIDGE_UNLOCK(sc);
1882				return (m);
1883			}
1884		}
1885
1886		if (bcmp(etherbroadcastaddr, eh->ether_dhost,
1887		    sizeof(etherbroadcastaddr)) == 0)
1888			m->m_flags |= M_BCAST;
1889		else
1890			m->m_flags |= M_MCAST;
1891
1892		/*
1893		 * Make a deep copy of the packet and enqueue the copy
1894		 * for bridge processing; return the original packet for
1895		 * local processing.
1896		 */
1897		mc = m_dup(m, M_DONTWAIT);
1898		if (mc == NULL) {
1899			BRIDGE_UNLOCK(sc);
1900			return (m);
1901		}
1902
1903		/* Perform the bridge forwarding function with the copy. */
1904		bridge_forward(sc, mc);
1905
1906		/*
1907		 * Reinject the mbuf as arriving on the bridge so we have a
1908		 * chance at claiming multicast packets. We can not loop back
1909		 * here from ether_input as a bridge is never a member of a
1910		 * bridge.
1911		 */
1912		KASSERT(bifp->if_bridge == NULL,
1913		    ("loop created in bridge_input"));
1914		mc2 = m_dup(m, M_DONTWAIT);
1915		if (mc2 != NULL) {
1916			/* Keep the layer3 header aligned */
1917			int i = min(mc2->m_pkthdr.len, max_protohdr);
1918			mc2 = m_copyup(mc2, i, ETHER_ALIGN);
1919		}
1920		if (mc2 != NULL) {
1921			mc2->m_pkthdr.rcvif = bifp;
1922			(*bifp->if_input)(bifp, mc2);
1923		}
1924
1925		/* Return the original packet for local processing. */
1926		return (m);
1927	}
1928
1929	if (bif->bif_flags & IFBIF_STP) {
1930		switch (bif->bif_state) {
1931		case BSTP_IFSTATE_BLOCKING:
1932		case BSTP_IFSTATE_LISTENING:
1933		case BSTP_IFSTATE_DISABLED:
1934			BRIDGE_UNLOCK(sc);
1935			return (m);
1936		}
1937	}
1938
1939	/*
1940	 * Unicast.  Make sure it's not for us.
1941	 */
1942	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1943		/* It is destined for us. */
1944		if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_dhost,
1945		    ETHER_ADDR_LEN) == 0) {
1946			if (bif->bif_flags & IFBIF_LEARNING)
1947				(void) bridge_rtupdate(sc,
1948				    eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1949			m->m_pkthdr.rcvif = bif->bif_ifp;
1950			BRIDGE_UNLOCK(sc);
1951			return (m);
1952		}
1953
1954		/* We just received a packet that we sent out. */
1955		if (memcmp(IF_LLADDR(bif->bif_ifp), eh->ether_shost,
1956		    ETHER_ADDR_LEN) == 0) {
1957			BRIDGE_UNLOCK(sc);
1958			m_freem(m);
1959			return (NULL);
1960		}
1961	}
1962
1963	/* Perform the bridge forwarding function. */
1964	bridge_forward(sc, m);
1965
1966	return (NULL);
1967}
1968
1969/*
1970 * bridge_broadcast:
1971 *
1972 *	Send a frame to all interfaces that are members of
1973 *	the bridge, except for the one on which the packet
1974 *	arrived.
1975 *
1976 *	NOTE: Releases the lock on return.
1977 */
1978static void
1979bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1980    struct mbuf *m, int runfilt)
1981{
1982	struct bridge_iflist *bif;
1983	struct mbuf *mc;
1984	struct ifnet *dst_if;
1985	int error = 0, used = 0;
1986
1987	BRIDGE_LOCK_ASSERT(sc);
1988	BRIDGE_LOCK2REF(sc, error);
1989	if (error) {
1990		m_freem(m);
1991		return;
1992	}
1993
1994	/* Filter on the bridge interface before broadcasting */
1995	if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
1996#ifdef INET6
1997	    || inet6_pfil_hook.ph_busy_count >= 0
1998#endif
1999	    )) {
2000		if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0)
2001			goto out;
2002		if (m == NULL)
2003			goto out;
2004	}
2005
2006	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
2007		dst_if = bif->bif_ifp;
2008		if (dst_if == src_if)
2009			continue;
2010
2011		if (bif->bif_flags & IFBIF_STP) {
2012			switch (bif->bif_state) {
2013			case BSTP_IFSTATE_BLOCKING:
2014			case BSTP_IFSTATE_DISABLED:
2015				continue;
2016			}
2017		}
2018
2019		if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
2020		    (m->m_flags & (M_BCAST|M_MCAST)) == 0)
2021			continue;
2022
2023		if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
2024			continue;
2025
2026		if (LIST_NEXT(bif, bif_next) == NULL) {
2027			mc = m;
2028			used = 1;
2029		} else {
2030			mc = m_copypacket(m, M_DONTWAIT);
2031			if (mc == NULL) {
2032				sc->sc_ifp->if_oerrors++;
2033				continue;
2034			}
2035		}
2036
2037		/*
2038		 * Filter on the output interface. Pass a NULL bridge interface
2039		 * pointer so we do not redundantly filter on the bridge for
2040		 * each interface we broadcast on.
2041		 */
2042		if (runfilt && (inet_pfil_hook.ph_busy_count >= 0
2043#ifdef INET6
2044		    || inet6_pfil_hook.ph_busy_count >= 0
2045#endif
2046		    )) {
2047			if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0)
2048				continue;
2049			if (mc == NULL)
2050				continue;
2051		}
2052
2053		bridge_enqueue(sc, dst_if, mc);
2054	}
2055	if (used == 0)
2056		m_freem(m);
2057
2058out:
2059	BRIDGE_UNREF(sc);
2060}
2061
2062/*
2063 * bridge_span:
2064 *
2065 *	Duplicate a packet out one or more interfaces that are in span mode,
2066 *	the original mbuf is unmodified.
2067 */
2068static void
2069bridge_span(struct bridge_softc *sc, struct mbuf *m)
2070{
2071	struct bridge_iflist *bif;
2072	struct ifnet *dst_if;
2073	struct mbuf *mc;
2074
2075	if (LIST_EMPTY(&sc->sc_spanlist))
2076		return;
2077
2078	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
2079		dst_if = bif->bif_ifp;
2080
2081		if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
2082			continue;
2083
2084		mc = m_copypacket(m, M_DONTWAIT);
2085		if (mc == NULL) {
2086			sc->sc_ifp->if_oerrors++;
2087			continue;
2088		}
2089
2090		bridge_enqueue(sc, dst_if, mc);
2091	}
2092}
2093
2094/*
2095 * bridge_rtupdate:
2096 *
2097 *	Add a bridge routing entry.
2098 */
2099static int
2100bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
2101    struct ifnet *dst_if, int setflags, uint8_t flags)
2102{
2103	struct bridge_rtnode *brt;
2104	struct timeval tv;
2105	int error;
2106
2107	BRIDGE_LOCK_ASSERT(sc);
2108
2109	/*
2110	 * A route for this destination might already exist.  If so,
2111	 * update it, otherwise create a new one.
2112	 */
2113	getmicrotime(&tv);
2114	if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
2115		if (sc->sc_brtcnt >= sc->sc_brtmax)
2116			return (ENOSPC);
2117
2118		/*
2119		 * Allocate a new bridge forwarding node, and
2120		 * initialize the expiration time and Ethernet
2121		 * address.
2122		 */
2123		brt = uma_zalloc(bridge_rtnode_zone, M_NOWAIT | M_ZERO);
2124		if (brt == NULL)
2125			return (ENOMEM);
2126
2127		brt->brt_expire = tv.tv_sec + sc->sc_brttimeout;
2128		brt->brt_flags = IFBAF_DYNAMIC;
2129		memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
2130
2131		if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
2132			uma_zfree(bridge_rtnode_zone, brt);
2133			return (error);
2134		}
2135	}
2136
2137	brt->brt_ifp = dst_if;
2138	if (setflags) {
2139		brt->brt_flags = flags;
2140		brt->brt_expire = (flags & IFBAF_STATIC) ? 0 :
2141		    tv.tv_sec + sc->sc_brttimeout;
2142	}
2143
2144	return (0);
2145}
2146
2147/*
2148 * bridge_rtlookup:
2149 *
2150 *	Lookup the destination interface for an address.
2151 */
2152static struct ifnet *
2153bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
2154{
2155	struct bridge_rtnode *brt;
2156
2157	BRIDGE_LOCK_ASSERT(sc);
2158
2159	if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
2160		return (NULL);
2161
2162	return (brt->brt_ifp);
2163}
2164
2165/*
2166 * bridge_rttrim:
2167 *
2168 *	Trim the routine table so that we have a number
2169 *	of routing entries less than or equal to the
2170 *	maximum number.
2171 */
2172static void
2173bridge_rttrim(struct bridge_softc *sc)
2174{
2175	struct bridge_rtnode *brt, *nbrt;
2176
2177	BRIDGE_LOCK_ASSERT(sc);
2178
2179	/* Make sure we actually need to do this. */
2180	if (sc->sc_brtcnt <= sc->sc_brtmax)
2181		return;
2182
2183	/* Force an aging cycle; this might trim enough addresses. */
2184	bridge_rtage(sc);
2185	if (sc->sc_brtcnt <= sc->sc_brtmax)
2186		return;
2187
2188	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2189		nbrt = LIST_NEXT(brt, brt_list);
2190		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2191			bridge_rtnode_destroy(sc, brt);
2192			if (sc->sc_brtcnt <= sc->sc_brtmax)
2193				return;
2194		}
2195	}
2196}
2197
2198/*
2199 * bridge_timer:
2200 *
2201 *	Aging timer for the bridge.
2202 */
2203static void
2204bridge_timer(void *arg)
2205{
2206	struct bridge_softc *sc = arg;
2207
2208	BRIDGE_LOCK_ASSERT(sc);
2209
2210	bridge_rtage(sc);
2211
2212	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
2213		callout_reset(&sc->sc_brcallout,
2214		    bridge_rtable_prune_period * hz, bridge_timer, sc);
2215}
2216
2217/*
2218 * bridge_rtage:
2219 *
2220 *	Perform an aging cycle.
2221 */
2222static void
2223bridge_rtage(struct bridge_softc *sc)
2224{
2225	struct bridge_rtnode *brt, *nbrt;
2226	struct timeval tv;
2227
2228	BRIDGE_LOCK_ASSERT(sc);
2229
2230	getmicrotime(&tv);
2231
2232	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2233		nbrt = LIST_NEXT(brt, brt_list);
2234		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2235			if (tv.tv_sec >= brt->brt_expire)
2236				bridge_rtnode_destroy(sc, brt);
2237		}
2238	}
2239}
2240
2241/*
2242 * bridge_rtflush:
2243 *
2244 *	Remove all dynamic addresses from the bridge.
2245 */
2246static void
2247bridge_rtflush(struct bridge_softc *sc, int full)
2248{
2249	struct bridge_rtnode *brt, *nbrt;
2250
2251	BRIDGE_LOCK_ASSERT(sc);
2252
2253	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2254		nbrt = LIST_NEXT(brt, brt_list);
2255		if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2256			bridge_rtnode_destroy(sc, brt);
2257	}
2258}
2259
2260/*
2261 * bridge_rtdaddr:
2262 *
2263 *	Remove an address from the table.
2264 */
2265static int
2266bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
2267{
2268	struct bridge_rtnode *brt;
2269
2270	BRIDGE_LOCK_ASSERT(sc);
2271
2272	if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL)
2273		return (ENOENT);
2274
2275	bridge_rtnode_destroy(sc, brt);
2276	return (0);
2277}
2278
2279/*
2280 * bridge_rtdelete:
2281 *
2282 *	Delete routes to a speicifc member interface.
2283 */
2284void
2285bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
2286{
2287	struct bridge_rtnode *brt, *nbrt;
2288
2289	BRIDGE_LOCK_ASSERT(sc);
2290
2291	for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) {
2292		nbrt = LIST_NEXT(brt, brt_list);
2293		if (brt->brt_ifp == ifp && (full ||
2294			    (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
2295			bridge_rtnode_destroy(sc, brt);
2296	}
2297}
2298
2299/*
2300 * bridge_rtable_init:
2301 *
2302 *	Initialize the route table for this bridge.
2303 */
2304static int
2305bridge_rtable_init(struct bridge_softc *sc)
2306{
2307	int i;
2308
2309	sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
2310	    M_DEVBUF, M_NOWAIT);
2311	if (sc->sc_rthash == NULL)
2312		return (ENOMEM);
2313
2314	for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
2315		LIST_INIT(&sc->sc_rthash[i]);
2316
2317	sc->sc_rthash_key = arc4random();
2318
2319	LIST_INIT(&sc->sc_rtlist);
2320
2321	return (0);
2322}
2323
2324/*
2325 * bridge_rtable_fini:
2326 *
2327 *	Deconstruct the route table for this bridge.
2328 */
2329static void
2330bridge_rtable_fini(struct bridge_softc *sc)
2331{
2332
2333	free(sc->sc_rthash, M_DEVBUF);
2334}
2335
2336/*
2337 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2338 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2339 */
2340#define	mix(a, b, c)							\
2341do {									\
2342	a -= b; a -= c; a ^= (c >> 13);					\
2343	b -= c; b -= a; b ^= (a << 8);					\
2344	c -= a; c -= b; c ^= (b >> 13);					\
2345	a -= b; a -= c; a ^= (c >> 12);					\
2346	b -= c; b -= a; b ^= (a << 16);					\
2347	c -= a; c -= b; c ^= (b >> 5);					\
2348	a -= b; a -= c; a ^= (c >> 3);					\
2349	b -= c; b -= a; b ^= (a << 10);					\
2350	c -= a; c -= b; c ^= (b >> 15);					\
2351} while (/*CONSTCOND*/0)
2352
2353static __inline uint32_t
2354bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
2355{
2356	uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
2357
2358	b += addr[5] << 8;
2359	b += addr[4];
2360	a += addr[3] << 24;
2361	a += addr[2] << 16;
2362	a += addr[1] << 8;
2363	a += addr[0];
2364
2365	mix(a, b, c);
2366
2367	return (c & BRIDGE_RTHASH_MASK);
2368}
2369
2370#undef mix
2371
2372/*
2373 * bridge_rtnode_lookup:
2374 *
2375 *	Look up a bridge route node for the specified destination.
2376 */
2377static struct bridge_rtnode *
2378bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr)
2379{
2380	struct bridge_rtnode *brt;
2381	uint32_t hash;
2382	int dir;
2383
2384	BRIDGE_LOCK_ASSERT(sc);
2385
2386	hash = bridge_rthash(sc, addr);
2387	LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
2388		dir = memcmp(addr, brt->brt_addr, ETHER_ADDR_LEN);
2389		if (dir == 0)
2390			return (brt);
2391		if (dir > 0)
2392			return (NULL);
2393	}
2394
2395	return (NULL);
2396}
2397
2398/*
2399 * bridge_rtnode_insert:
2400 *
2401 *	Insert the specified bridge node into the route table.  We
2402 *	assume the entry is not already in the table.
2403 */
2404static int
2405bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
2406{
2407	struct bridge_rtnode *lbrt;
2408	uint32_t hash;
2409	int dir;
2410
2411	BRIDGE_LOCK_ASSERT(sc);
2412
2413	hash = bridge_rthash(sc, brt->brt_addr);
2414
2415	lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
2416	if (lbrt == NULL) {
2417		LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
2418		goto out;
2419	}
2420
2421	do {
2422		dir = memcmp(brt->brt_addr, lbrt->brt_addr, ETHER_ADDR_LEN);
2423		if (dir == 0)
2424			return (EEXIST);
2425		if (dir > 0) {
2426			LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
2427			goto out;
2428		}
2429		if (LIST_NEXT(lbrt, brt_hash) == NULL) {
2430			LIST_INSERT_AFTER(lbrt, brt, brt_hash);
2431			goto out;
2432		}
2433		lbrt = LIST_NEXT(lbrt, brt_hash);
2434	} while (lbrt != NULL);
2435
2436#ifdef DIAGNOSTIC
2437	panic("bridge_rtnode_insert: impossible");
2438#endif
2439
2440out:
2441	LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
2442	sc->sc_brtcnt++;
2443
2444	return (0);
2445}
2446
2447/*
2448 * bridge_rtnode_destroy:
2449 *
2450 *	Destroy a bridge rtnode.
2451 */
2452static void
2453bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
2454{
2455	BRIDGE_LOCK_ASSERT(sc);
2456
2457	LIST_REMOVE(brt, brt_hash);
2458
2459	LIST_REMOVE(brt, brt_list);
2460	sc->sc_brtcnt--;
2461	uma_zfree(bridge_rtnode_zone, brt);
2462}
2463
2464/*
2465 * Send bridge packets through pfil if they are one of the types pfil can deal
2466 * with, or if they are ARP or REVARP.  (pfil will pass ARP and REVARP without
2467 * question.) If *bifp or *ifp are NULL then packet filtering is skipped for
2468 * that interface.
2469 */
2470static int
2471bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
2472{
2473	int snap, error, i;
2474	struct ether_header *eh1, eh2;
2475	struct ip_fw_args args;
2476	struct ip *ip;
2477	struct llc llc1;
2478	u_int16_t ether_type;
2479
2480	snap = 0;
2481	error = -1;	/* Default error if not error == 0 */
2482
2483	i = min((*mp)->m_pkthdr.len, max_protohdr);
2484	if ((*mp)->m_len < i) {
2485	    *mp = m_pullup(*mp, i);
2486	    if (*mp == NULL) {
2487		printf("%s: m_pullup failed\n", __func__);
2488		return -1;
2489	    }
2490	}
2491
2492	eh1 = mtod(*mp, struct ether_header *);
2493	ether_type = ntohs(eh1->ether_type);
2494
2495	/*
2496	 * Check for SNAP/LLC.
2497	 */
2498	if (ether_type < ETHERMTU) {
2499		struct llc *llc2 = (struct llc *)(eh1 + 1);
2500
2501		if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
2502		    llc2->llc_dsap == LLC_SNAP_LSAP &&
2503		    llc2->llc_ssap == LLC_SNAP_LSAP &&
2504		    llc2->llc_control == LLC_UI) {
2505			ether_type = htons(llc2->llc_un.type_snap.ether_type);
2506			snap = 1;
2507		}
2508	}
2509
2510	/*
2511	 * If we're trying to filter bridge traffic, don't look at anything
2512	 * other than IP and ARP traffic.  If the filter doesn't understand
2513	 * IPv6, don't allow IPv6 through the bridge either.  This is lame
2514	 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2515	 * but of course we don't have an AppleTalk filter to begin with.
2516	 * (Note that since pfil doesn't understand ARP it will pass *ALL*
2517	 * ARP traffic.)
2518	 */
2519	switch (ether_type) {
2520		case ETHERTYPE_ARP:
2521		case ETHERTYPE_REVARP:
2522			return 0; /* Automatically pass */
2523		case ETHERTYPE_IP:
2524# ifdef INET6
2525		case ETHERTYPE_IPV6:
2526# endif /* INET6 */
2527			break;
2528		default:
2529			/*
2530			 * ipfw allows layer2 protocol filtering using
2531			 * 'mac-type' so we will let the packet past, if
2532			 * ipfw is disabled then drop it.
2533			 */
2534			if (!IPFW_LOADED || pfil_ipfw == 0)
2535				goto bad;
2536	}
2537
2538	/* Strip off the Ethernet header and keep a copy. */
2539	m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
2540	m_adj(*mp, ETHER_HDR_LEN);
2541
2542	/* Strip off snap header, if present */
2543	if (snap) {
2544		m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
2545		m_adj(*mp, sizeof(struct llc));
2546	}
2547
2548	/*
2549	 * Check the IP header for alignment and errors
2550	 */
2551	if (dir == PFIL_IN) {
2552		switch (ether_type) {
2553			case ETHERTYPE_IP:
2554				error = bridge_ip_checkbasic(mp);
2555				break;
2556# ifdef INET6
2557			case ETHERTYPE_IPV6:
2558				error = bridge_ip6_checkbasic(mp);
2559				break;
2560# endif /* INET6 */
2561			default:
2562				error = 0;
2563		}
2564		if (error)
2565			goto bad;
2566	}
2567
2568	if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
2569		error = -1;
2570		args.rule = ip_dn_claim_rule(*mp);
2571		if (args.rule != NULL && fw_one_pass)
2572			goto ipfwpass; /* packet already partially processed */
2573
2574		args.m = *mp;
2575		args.oif = ifp;
2576		args.next_hop = NULL;
2577		args.eh = &eh2;
2578		i = ip_fw_chk_ptr(&args);
2579		*mp = args.m;
2580
2581		if (*mp == NULL)
2582			return error;
2583
2584		if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) {
2585
2586			/* put the Ethernet header back on */
2587			M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2588			if (*mp == NULL)
2589				return error;
2590			bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2591
2592			/*
2593			 * Pass the pkt to dummynet, which consumes it. The
2594			 * packet will return to us via bridge_dummynet().
2595			 */
2596			args.oif = ifp;
2597			ip_dn_io_ptr(*mp, DN_TO_IFB_FWD, &args);
2598			return error;
2599		}
2600
2601		if (i != IP_FW_PASS) /* drop */
2602			goto bad;
2603	}
2604
2605ipfwpass:
2606	error = 0;
2607
2608	/*
2609	 * Run the packet through pfil
2610	 */
2611	switch (ether_type)
2612	{
2613	case ETHERTYPE_IP :
2614		/*
2615		 * before calling the firewall, swap fields the same as
2616		 * IP does. here we assume the header is contiguous
2617		 */
2618		ip = mtod(*mp, struct ip *);
2619
2620		ip->ip_len = ntohs(ip->ip_len);
2621		ip->ip_off = ntohs(ip->ip_off);
2622
2623		/*
2624		 * Run pfil on the member interface and the bridge, both can
2625		 * be skipped by clearing pfil_member or pfil_bridge.
2626		 *
2627		 * Keep the order:
2628		 *   in_if -> bridge_if -> out_if
2629		 */
2630		if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
2631			error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
2632					dir, NULL);
2633
2634		if (*mp == NULL || error != 0) /* filter may consume */
2635			break;
2636
2637		if (pfil_member && ifp != NULL)
2638			error = pfil_run_hooks(&inet_pfil_hook, mp, ifp,
2639					dir, NULL);
2640
2641		if (*mp == NULL || error != 0) /* filter may consume */
2642			break;
2643
2644		if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
2645			error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
2646					dir, NULL);
2647
2648		/* Restore ip and the fields ntohs()'d. */
2649		if (*mp != NULL && error == 0) {
2650			ip = mtod(*mp, struct ip *);
2651			ip->ip_len = htons(ip->ip_len);
2652			ip->ip_off = htons(ip->ip_off);
2653		}
2654
2655		break;
2656# ifdef INET6
2657	case ETHERTYPE_IPV6 :
2658		if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
2659			error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
2660					dir, NULL);
2661
2662		if (*mp == NULL || error != 0) /* filter may consume */
2663			break;
2664
2665		if (pfil_member && ifp != NULL)
2666			error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp,
2667					dir, NULL);
2668
2669		if (*mp == NULL || error != 0) /* filter may consume */
2670			break;
2671
2672		if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
2673			error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
2674					dir, NULL);
2675		break;
2676# endif
2677	default :
2678		error = 0;
2679		break;
2680	}
2681
2682	if (*mp == NULL)
2683		return error;
2684	if (error != 0)
2685		goto bad;
2686
2687	error = -1;
2688
2689	/*
2690	 * Finally, put everything back the way it was and return
2691	 */
2692	if (snap) {
2693		M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
2694		if (*mp == NULL)
2695			return error;
2696		bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
2697	}
2698
2699	M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
2700	if (*mp == NULL)
2701		return error;
2702	bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
2703
2704	return 0;
2705
2706bad:
2707	m_freem(*mp);
2708	*mp = NULL;
2709	return error;
2710}
2711
2712/*
2713 * Perform basic checks on header size since
2714 * pfil assumes ip_input has already processed
2715 * it for it.  Cut-and-pasted from ip_input.c.
2716 * Given how simple the IPv6 version is,
2717 * does the IPv4 version really need to be
2718 * this complicated?
2719 *
2720 * XXX Should we update ipstat here, or not?
2721 * XXX Right now we update ipstat but not
2722 * XXX csum_counter.
2723 */
2724static int
2725bridge_ip_checkbasic(struct mbuf **mp)
2726{
2727	struct mbuf *m = *mp;
2728	struct ip *ip;
2729	int len, hlen;
2730	u_short sum;
2731
2732	if (*mp == NULL)
2733		return -1;
2734
2735	if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2736		if ((m = m_copyup(m, sizeof(struct ip),
2737			(max_linkhdr + 3) & ~3)) == NULL) {
2738			/* XXXJRT new stat, please */
2739			ipstat.ips_toosmall++;
2740			goto bad;
2741		}
2742	} else if (__predict_false(m->m_len < sizeof (struct ip))) {
2743		if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
2744			ipstat.ips_toosmall++;
2745			goto bad;
2746		}
2747	}
2748	ip = mtod(m, struct ip *);
2749	if (ip == NULL) goto bad;
2750
2751	if (ip->ip_v != IPVERSION) {
2752		ipstat.ips_badvers++;
2753		goto bad;
2754	}
2755	hlen = ip->ip_hl << 2;
2756	if (hlen < sizeof(struct ip)) { /* minimum header length */
2757		ipstat.ips_badhlen++;
2758		goto bad;
2759	}
2760	if (hlen > m->m_len) {
2761		if ((m = m_pullup(m, hlen)) == 0) {
2762			ipstat.ips_badhlen++;
2763			goto bad;
2764		}
2765		ip = mtod(m, struct ip *);
2766		if (ip == NULL) goto bad;
2767	}
2768
2769	if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) {
2770		sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
2771	} else {
2772		if (hlen == sizeof(struct ip)) {
2773			sum = in_cksum_hdr(ip);
2774		} else {
2775			sum = in_cksum(m, hlen);
2776		}
2777	}
2778	if (sum) {
2779		ipstat.ips_badsum++;
2780		goto bad;
2781	}
2782
2783	/* Retrieve the packet length. */
2784	len = ntohs(ip->ip_len);
2785
2786	/*
2787	 * Check for additional length bogosity
2788	 */
2789	if (len < hlen) {
2790		ipstat.ips_badlen++;
2791		goto bad;
2792	}
2793
2794	/*
2795	 * Check that the amount of data in the buffers
2796	 * is as at least much as the IP header would have us expect.
2797	 * Drop packet if shorter than we expect.
2798	 */
2799	if (m->m_pkthdr.len < len) {
2800		ipstat.ips_tooshort++;
2801		goto bad;
2802	}
2803
2804	/* Checks out, proceed */
2805	*mp = m;
2806	return 0;
2807
2808bad:
2809	*mp = m;
2810	return -1;
2811}
2812
2813# ifdef INET6
2814/*
2815 * Same as above, but for IPv6.
2816 * Cut-and-pasted from ip6_input.c.
2817 * XXX Should we update ip6stat, or not?
2818 */
2819static int
2820bridge_ip6_checkbasic(struct mbuf **mp)
2821{
2822	struct mbuf *m = *mp;
2823	struct ip6_hdr *ip6;
2824
2825	/*
2826	 * If the IPv6 header is not aligned, slurp it up into a new
2827	 * mbuf with space for link headers, in the event we forward
2828	 * it.  Otherwise, if it is aligned, make sure the entire base
2829	 * IPv6 header is in the first mbuf of the chain.
2830	 */
2831	if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
2832		struct ifnet *inifp = m->m_pkthdr.rcvif;
2833		if ((m = m_copyup(m, sizeof(struct ip6_hdr),
2834			    (max_linkhdr + 3) & ~3)) == NULL) {
2835			/* XXXJRT new stat, please */
2836			ip6stat.ip6s_toosmall++;
2837			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2838			goto bad;
2839		}
2840	} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
2841		struct ifnet *inifp = m->m_pkthdr.rcvif;
2842		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
2843			ip6stat.ip6s_toosmall++;
2844			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
2845			goto bad;
2846		}
2847	}
2848
2849	ip6 = mtod(m, struct ip6_hdr *);
2850
2851	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
2852		ip6stat.ip6s_badvers++;
2853		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
2854		goto bad;
2855	}
2856
2857	/* Checks out, proceed */
2858	*mp = m;
2859	return 0;
2860
2861bad:
2862	*mp = m;
2863	return -1;
2864}
2865# endif /* INET6 */
2866