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