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