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