if_bridge.c revision 185895
1178354Ssam/*	$NetBSD: if_bridge.c,v 1.31 2005/06/01 19:45:34 jdc Exp $	*/
2186904Ssam
3178354Ssam/*
4178354Ssam * Copyright 2001 Wasabi Systems, Inc.
5178354Ssam * All rights reserved.
6178354Ssam *
7178354Ssam * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8178354Ssam *
9178354Ssam * Redistribution and use in source and binary forms, with or without
10178354Ssam * modification, are permitted provided that the following conditions
11178354Ssam * are met:
12178354Ssam * 1. Redistributions of source code must retain the above copyright
13178354Ssam *    notice, this list of conditions and the following disclaimer.
14178354Ssam * 2. Redistributions in binary form must reproduce the above copyright
15178354Ssam *    notice, this list of conditions and the following disclaimer in the
16178354Ssam *    documentation and/or other materials provided with the distribution.
17178354Ssam * 3. All advertising materials mentioning features or use of this software
18178354Ssam *    must display the following acknowledgement:
19178354Ssam *	This product includes software developed for the NetBSD Project by
20178354Ssam *	Wasabi Systems, Inc.
21178354Ssam * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22178354Ssam *    or promote products derived from this software without specific prior
23178354Ssam *    written permission.
24178354Ssam *
25178354Ssam * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26178354Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27178354Ssam * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28178354Ssam * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29178354Ssam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30189106Sbz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31178354Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32178354Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33178354Ssam * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34178354Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35178354Ssam * POSSIBILITY OF SUCH DAMAGE.
36178354Ssam */
37178354Ssam
38178354Ssam/*
39178354Ssam * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
40178354Ssam * All rights reserved.
41182144Sjulian *
42178354Ssam * Redistribution and use in source and binary forms, with or without
43178354Ssam * modification, are permitted provided that the following conditions
44178354Ssam * are met:
45178354Ssam * 1. Redistributions of source code must retain the above copyright
46178354Ssam *    notice, this list of conditions and the following disclaimer.
47178354Ssam * 2. Redistributions in binary form must reproduce the above copyright
48189106Sbz *    notice, this list of conditions and the following disclaimer in the
49185571Sbz *    documentation and/or other materials provided with the distribution.
50178354Ssam *
51178354Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
52191551Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53191551Ssam * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54191551Ssam * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
55178354Ssam * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56178354Ssam * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
57183355Sthompsa * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58178354Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59191551Ssam * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
60191551Ssam * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61183355Sthompsa * POSSIBILITY OF SUCH DAMAGE.
62191551Ssam *
63191551Ssam * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp
64183355Sthompsa */
65178354Ssam
66178354Ssam/*
67178354Ssam * Network interface bridge support.
68178354Ssam *
69178354Ssam * TODO:
70188182Ssam *
71188182Ssam *	- Currently only supports Ethernet-like interfaces (Ethernet,
72178354Ssam *	  802.11, VLANs on Ethernet, etc.)  Figure out a nice way
73178354Ssam *	  to bridge other types of interfaces (FDDI-FDDI, and maybe
74178354Ssam *	  consider heterogenous bridges).
75178354Ssam */
76178354Ssam
77178354Ssam#include <sys/cdefs.h>
78178354Ssam__FBSDID("$FreeBSD: head/sys/net/if_bridge.c 185895 2008-12-10 23:12:39Z zec $");
79178354Ssam
80178354Ssam#include "opt_inet.h"
81178354Ssam#include "opt_inet6.h"
82178354Ssam#include "opt_carp.h"
83178354Ssam
84178354Ssam#include <sys/param.h>
85178354Ssam#include <sys/mbuf.h>
86178354Ssam#include <sys/malloc.h>
87178354Ssam#include <sys/protosw.h>
88178354Ssam#include <sys/systm.h>
89178354Ssam#include <sys/time.h>
90178354Ssam#include <sys/socket.h> /* for net/if.h */
91188182Ssam#include <sys/sockio.h>
92188182Ssam#include <sys/ctype.h>  /* string functions */
93188182Ssam#include <sys/kernel.h>
94188182Ssam#include <sys/random.h>
95188182Ssam#include <sys/syslog.h>
96188182Ssam#include <sys/sysctl.h>
97188182Ssam#include <vm/uma.h>
98188182Ssam#include <sys/module.h>
99188182Ssam#include <sys/priv.h>
100178354Ssam#include <sys/proc.h>
101178354Ssam#include <sys/lock.h>
102178354Ssam#include <sys/mutex.h>
103178354Ssam#include <sys/rwlock.h>
104178354Ssam#include <sys/vimage.h>
105178354Ssam
106178354Ssam#include <net/bpf.h>
107178354Ssam#include <net/if.h>
108178354Ssam#include <net/if_clone.h>
109178354Ssam#include <net/if_dl.h>
110178354Ssam#include <net/if_types.h>
111178354Ssam#include <net/if_var.h>
112178354Ssam#include <net/pfil.h>
113178354Ssam
114178354Ssam#include <netinet/in.h> /* for struct arpcom */
115178354Ssam#include <netinet/in_systm.h>
116178354Ssam#include <netinet/in_var.h>
117178354Ssam#include <netinet/ip.h>
118178354Ssam#include <netinet/ip_var.h>
119178354Ssam#include <netinet/vinet.h>
120178354Ssam#ifdef INET6
121178354Ssam#include <netinet/ip6.h>
122178354Ssam#include <netinet6/ip6_var.h>
123178354Ssam#include <netinet6/vinet6.h>
124178354Ssam#endif
125178354Ssam#ifdef DEV_CARP
126178354Ssam#include <netinet/ip_carp.h>
127178354Ssam#endif
128178354Ssam#include <machine/in_cksum.h>
129178354Ssam#include <netinet/if_ether.h> /* for struct arpcom */
130178354Ssam#include <net/bridgestp.h>
131178354Ssam#include <net/if_bridgevar.h>
132178354Ssam#include <net/if_llc.h>
133178354Ssam#include <net/if_vlan_var.h>
134178354Ssam
135178354Ssam#include <net/route.h>
136178354Ssam#include <netinet/ip_fw.h>
137178354Ssam#include <netinet/ip_dummynet.h>
138178354Ssam
139178354Ssam/*
140178354Ssam * Size of the route hash table.  Must be a power of two.
141178354Ssam */
142178354Ssam#ifndef BRIDGE_RTHASH_SIZE
143178354Ssam#define	BRIDGE_RTHASH_SIZE		1024
144178354Ssam#endif
145178354Ssam
146178354Ssam#define	BRIDGE_RTHASH_MASK		(BRIDGE_RTHASH_SIZE - 1)
147178354Ssam
148178354Ssam/*
149178354Ssam * Maximum number of addresses to cache.
150178354Ssam */
151183550Szec#ifndef BRIDGE_RTABLE_MAX
152178354Ssam#define	BRIDGE_RTABLE_MAX		100
153178354Ssam#endif
154178354Ssam
155178354Ssam/*
156178354Ssam * Timeout (in seconds) for entries learned dynamically.
157178354Ssam */
158178354Ssam#ifndef BRIDGE_RTABLE_TIMEOUT
159178354Ssam#define	BRIDGE_RTABLE_TIMEOUT		(20 * 60)	/* same as ARP */
160178354Ssam#endif
161178354Ssam
162183550Szec/*
163183550Szec * Number of seconds between walks of the route list.
164183550Szec */
165183550Szec#ifndef BRIDGE_RTABLE_PRUNE_PERIOD
166183550Szec#define	BRIDGE_RTABLE_PRUNE_PERIOD	(5 * 60)
167178354Ssam#endif
168183550Szec
169183550Szec/*
170183550Szec * List of capabilities to possibly mask on the member interface.
171183550Szec */
172183550Szec#define	BRIDGE_IFCAPS_MASK		(IFCAP_TOE|IFCAP_TSO|IFCAP_TXCSUM)
173183550Szec
174183550Szec/*
175183550Szec * Bridge interface list entry.
176183550Szec */
177183550Szecstruct bridge_iflist {
178183550Szec	LIST_ENTRY(bridge_iflist) bif_next;
179183550Szec	struct ifnet		*bif_ifp;	/* member if */
180183550Szec	struct bstp_port	bif_stp;	/* STP state */
181178354Ssam	uint32_t		bif_flags;	/* member if flags */
182178354Ssam	int			bif_savedcaps;	/* saved capabilities */
183178354Ssam	uint32_t		bif_addrmax;	/* max # of addresses */
184178354Ssam	uint32_t		bif_addrcnt;	/* cur. # of addresses */
185178354Ssam	uint32_t		bif_addrexceeded;/* # of address violations */
186191551Ssam};
187191551Ssam
188191551Ssam/*
189191551Ssam * Bridge route node.
190191551Ssam */
191191551Ssamstruct bridge_rtnode {
192191551Ssam	LIST_ENTRY(bridge_rtnode) brt_hash;	/* hash table linkage */
193191551Ssam	LIST_ENTRY(bridge_rtnode) brt_list;	/* list linkage */
194191551Ssam	struct bridge_iflist	*brt_dst;	/* destination if */
195191551Ssam	unsigned long		brt_expire;	/* expiration time */
196178354Ssam	uint8_t			brt_flags;	/* address flags */
197178354Ssam	uint8_t			brt_addr[ETHER_ADDR_LEN];
198178354Ssam	uint16_t		brt_vlan;	/* vlan id */
199178354Ssam};
200178354Ssam#define	brt_ifp			brt_dst->bif_ifp
201191551Ssam
202191551Ssam/*
203178354Ssam * Software state for each bridge.
204178354Ssam */
205178354Ssamstruct bridge_softc {
206178354Ssam	struct ifnet		*sc_ifp;	/* make this an interface */
207178354Ssam	LIST_ENTRY(bridge_softc) sc_list;
208191551Ssam	struct mtx		sc_mtx;
209191551Ssam	struct cv		sc_cv;
210191551Ssam	uint32_t		sc_brtmax;	/* max # of addresses */
211191551Ssam	uint32_t		sc_brtcnt;	/* cur. # of addresses */
212191551Ssam	uint32_t		sc_brttimeout;	/* rt timeout in seconds */
213191551Ssam	struct callout		sc_brcallout;	/* bridge callout */
214191551Ssam	uint32_t		sc_iflist_ref;	/* refcount for sc_iflist */
215178354Ssam	uint32_t		sc_iflist_xcnt;	/* refcount for sc_iflist */
216178354Ssam	LIST_HEAD(, bridge_iflist) sc_iflist;	/* member interface list */
217178354Ssam	LIST_HEAD(, bridge_rtnode) *sc_rthash;	/* our forwarding table */
218178354Ssam	LIST_HEAD(, bridge_rtnode) sc_rtlist;	/* list version of above */
219178354Ssam	uint32_t		sc_rthash_key;	/* key for hash */
220178354Ssam	LIST_HEAD(, bridge_iflist) sc_spanlist;	/* span ports list */
221178354Ssam	struct bstp_state	sc_stp;		/* STP state */
222178354Ssam	uint32_t		sc_brtexceeded;	/* # of cache drops */
223178354Ssam	u_char			sc_defaddr[6];	/* Default MAC address */
224178354Ssam};
225178354Ssam
226178354Ssamstatic struct mtx 	bridge_list_mtx;
227178354Ssameventhandler_tag	bridge_detach_cookie = NULL;
228178354Ssam
229178354Ssamint	bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
230178354Ssam
231178354Ssamuma_zone_t bridge_rtnode_zone;
232178354Ssam
233178354Ssamstatic int	bridge_clone_create(struct if_clone *, int, caddr_t);
234178354Ssamstatic void	bridge_clone_destroy(struct ifnet *);
235178354Ssam
236178354Ssamstatic int	bridge_ioctl(struct ifnet *, u_long, caddr_t);
237178354Ssamstatic void	bridge_mutecaps(struct bridge_softc *);
238178354Ssamstatic void	bridge_set_ifcap(struct bridge_softc *, struct bridge_iflist *,
239178354Ssam		    int);
240178354Ssamstatic void	bridge_ifdetach(void *arg __unused, struct ifnet *);
241178354Ssamstatic void	bridge_init(void *);
242178354Ssamstatic void	bridge_dummynet(struct mbuf *, struct ifnet *);
243178354Ssamstatic void	bridge_stop(struct ifnet *, int);
244178354Ssamstatic void	bridge_start(struct ifnet *);
245178354Ssamstatic struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
246178354Ssamstatic int	bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *,
247178354Ssam		    struct rtentry *);
248188170Ssamstatic void	bridge_enqueue(struct bridge_softc *, struct ifnet *,
249178354Ssam		    struct mbuf *);
250178354Ssamstatic void	bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int);
251178354Ssam
252178354Ssamstatic void	bridge_forward(struct bridge_softc *, struct bridge_iflist *,
253178354Ssam		    struct mbuf *m);
254178354Ssam
255178354Ssamstatic void	bridge_timer(void *);
256178354Ssam
257178354Ssamstatic void	bridge_broadcast(struct bridge_softc *, struct ifnet *,
258178354Ssam		    struct mbuf *, int);
259178354Ssamstatic void	bridge_span(struct bridge_softc *, struct mbuf *);
260178354Ssam
261178354Ssamstatic int	bridge_rtupdate(struct bridge_softc *, const uint8_t *,
262178354Ssam		    uint16_t, struct bridge_iflist *, int, uint8_t);
263178354Ssamstatic struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *,
264178354Ssam		    uint16_t);
265178354Ssamstatic void	bridge_rttrim(struct bridge_softc *);
266182821Ssamstatic void	bridge_rtage(struct bridge_softc *);
267182821Ssamstatic void	bridge_rtflush(struct bridge_softc *, int);
268178354Ssamstatic int	bridge_rtdaddr(struct bridge_softc *, const uint8_t *,
269178354Ssam		    uint16_t);
270178354Ssam
271178354Ssamstatic int	bridge_rtable_init(struct bridge_softc *);
272178354Ssamstatic void	bridge_rtable_fini(struct bridge_softc *);
273178354Ssam
274191551Ssamstatic int	bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
275191551Ssamstatic struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
276178354Ssam		    const uint8_t *, uint16_t);
277178354Ssamstatic int	bridge_rtnode_insert(struct bridge_softc *,
278178354Ssam		    struct bridge_rtnode *);
279178354Ssamstatic void	bridge_rtnode_destroy(struct bridge_softc *,
280178354Ssam		    struct bridge_rtnode *);
281178354Ssamstatic void	bridge_rtable_expire(struct ifnet *, int);
282178354Ssamstatic void	bridge_state_change(struct ifnet *, int);
283191551Ssam
284178354Ssamstatic struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
285191551Ssam		    const char *name);
286191551Ssamstatic struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
287191551Ssam		    struct ifnet *ifp);
288191551Ssamstatic void	bridge_delete_member(struct bridge_softc *,
289191551Ssam		    struct bridge_iflist *, int);
290191551Ssamstatic void	bridge_delete_span(struct bridge_softc *,
291191551Ssam		    struct bridge_iflist *);
292191551Ssam
293191551Ssamstatic int	bridge_ioctl_add(struct bridge_softc *, void *);
294191551Ssamstatic int	bridge_ioctl_del(struct bridge_softc *, void *);
295191551Ssamstatic int	bridge_ioctl_gifflags(struct bridge_softc *, void *);
296191551Ssamstatic int	bridge_ioctl_sifflags(struct bridge_softc *, void *);
297191551Ssamstatic int	bridge_ioctl_scache(struct bridge_softc *, void *);
298191551Ssamstatic int	bridge_ioctl_gcache(struct bridge_softc *, void *);
299191551Ssamstatic int	bridge_ioctl_gifs(struct bridge_softc *, void *);
300191551Ssamstatic int	bridge_ioctl_rts(struct bridge_softc *, void *);
301191551Ssamstatic int	bridge_ioctl_saddr(struct bridge_softc *, void *);
302191551Ssamstatic int	bridge_ioctl_sto(struct bridge_softc *, void *);
303191551Ssamstatic int	bridge_ioctl_gto(struct bridge_softc *, void *);
304191551Ssamstatic int	bridge_ioctl_daddr(struct bridge_softc *, void *);
305191551Ssamstatic int	bridge_ioctl_flush(struct bridge_softc *, void *);
306191551Ssamstatic int	bridge_ioctl_gpri(struct bridge_softc *, void *);
307191551Ssamstatic int	bridge_ioctl_spri(struct bridge_softc *, void *);
308191551Ssamstatic int	bridge_ioctl_ght(struct bridge_softc *, void *);
309191551Ssamstatic int	bridge_ioctl_sht(struct bridge_softc *, void *);
310191551Ssamstatic int	bridge_ioctl_gfd(struct bridge_softc *, void *);
311191551Ssamstatic int	bridge_ioctl_sfd(struct bridge_softc *, void *);
312178354Ssamstatic int	bridge_ioctl_gma(struct bridge_softc *, void *);
313178354Ssamstatic int	bridge_ioctl_sma(struct bridge_softc *, void *);
314178354Ssamstatic int	bridge_ioctl_sifprio(struct bridge_softc *, void *);
315178354Ssamstatic int	bridge_ioctl_sifcost(struct bridge_softc *, void *);
316178354Ssamstatic int	bridge_ioctl_sifmaxaddr(struct bridge_softc *, void *);
317178354Ssamstatic int	bridge_ioctl_addspan(struct bridge_softc *, void *);
318178354Ssamstatic int	bridge_ioctl_delspan(struct bridge_softc *, void *);
319178354Ssamstatic int	bridge_ioctl_gbparam(struct bridge_softc *, void *);
320178354Ssamstatic int	bridge_ioctl_grte(struct bridge_softc *, void *);
321178354Ssamstatic int	bridge_ioctl_gifsstp(struct bridge_softc *, void *);
322178354Ssamstatic int	bridge_ioctl_sproto(struct bridge_softc *, void *);
323178354Ssamstatic int	bridge_ioctl_stxhc(struct bridge_softc *, void *);
324191551Ssamstatic int	bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
325178354Ssam		    int);
326178354Ssamstatic int	bridge_ip_checkbasic(struct mbuf **mp);
327178354Ssam#ifdef INET6
328178354Ssamstatic int	bridge_ip6_checkbasic(struct mbuf **mp);
329178354Ssam#endif /* INET6 */
330178354Ssamstatic int	bridge_fragment(struct ifnet *, struct mbuf *,
331178354Ssam		    struct ether_header *, int, struct llc *);
332178354Ssam
333178354Ssam/* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */
334178354Ssam#define	VLANTAGOF(_m)	\
335178354Ssam    (_m->m_flags & M_VLANTAG) ? EVL_VLANOFTAG(_m->m_pkthdr.ether_vtag) : 1
336178354Ssam
337178354Ssamstatic struct bstp_cb_ops bridge_ops = {
338178354Ssam	.bcb_state = bridge_state_change,
339178354Ssam	.bcb_rtage = bridge_rtable_expire
340178354Ssam};
341178354Ssam
342178354SsamSYSCTL_DECL(_net_link);
343178354SsamSYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW, 0, "Bridge");
344178354Ssam
345178354Ssamstatic int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
346178354Ssamstatic int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
347178354Ssamstatic int pfil_member = 1; /* run pfil hooks on the member interface */
348178354Ssamstatic int pfil_ipfw = 0;   /* layer2 filter with ipfw */
349178354Ssamstatic int pfil_ipfw_arp = 0;   /* layer2 filter with ipfw */
350178354Ssamstatic int pfil_local_phys = 0; /* run pfil hooks on the physical interface for
351178354Ssam                                   locally destined packets */
352178354Ssamstatic int log_stp   = 0;   /* log STP state changes */
353178354Ssamstatic int bridge_inherit_mac = 0;   /* share MAC with first bridge member */
354178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
355178354Ssam    &pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
356178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, ipfw_arp, CTLFLAG_RW,
357178354Ssam    &pfil_ipfw_arp, 0, "Filter ARP packets through IPFW layer2");
358178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
359178354Ssam    &pfil_bridge, 0, "Packet filter on the bridge interface");
360178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
361178354Ssam    &pfil_member, 0, "Packet filter on the member interface");
362178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_local_phys, CTLFLAG_RW,
363178354Ssam    &pfil_local_phys, 0,
364178354Ssam    "Packet filter on the physical interface for locally destined packets");
365178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW,
366178354Ssam    &log_stp, 0, "Log STP state changes");
367178354SsamSYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac, CTLFLAG_RW,
368178354Ssam    &bridge_inherit_mac, 0,
369178354Ssam    "Inherit MAC address from the first bridge member");
370178354Ssam
371178354Ssamstruct bridge_control {
372191551Ssam	int	(*bc_func)(struct bridge_softc *, void *);
373191551Ssam	int	bc_argsize;
374178354Ssam	int	bc_flags;
375178354Ssam};
376178354Ssam
377178354Ssam#define	BC_F_COPYIN		0x01	/* copy arguments in */
378178354Ssam#define	BC_F_COPYOUT		0x02	/* copy arguments out */
379178354Ssam#define	BC_F_SUSER		0x04	/* do super-user check */
380178354Ssam
381178354Ssamconst struct bridge_control bridge_control_table[] = {
382178354Ssam	{ bridge_ioctl_add,		sizeof(struct ifbreq),
383178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
384178354Ssam	{ bridge_ioctl_del,		sizeof(struct ifbreq),
385178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
386178354Ssam
387178354Ssam	{ bridge_ioctl_gifflags,	sizeof(struct ifbreq),
388178354Ssam	  BC_F_COPYIN|BC_F_COPYOUT },
389178354Ssam	{ bridge_ioctl_sifflags,	sizeof(struct ifbreq),
390178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
391178354Ssam
392178354Ssam	{ bridge_ioctl_scache,		sizeof(struct ifbrparam),
393178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
394178354Ssam	{ bridge_ioctl_gcache,		sizeof(struct ifbrparam),
395178354Ssam	  BC_F_COPYOUT },
396178354Ssam
397178354Ssam	{ bridge_ioctl_gifs,		sizeof(struct ifbifconf),
398178354Ssam	  BC_F_COPYIN|BC_F_COPYOUT },
399178354Ssam	{ bridge_ioctl_rts,		sizeof(struct ifbaconf),
400178354Ssam	  BC_F_COPYIN|BC_F_COPYOUT },
401178354Ssam
402178354Ssam	{ bridge_ioctl_saddr,		sizeof(struct ifbareq),
403178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
404178354Ssam
405178354Ssam	{ bridge_ioctl_sto,		sizeof(struct ifbrparam),
406178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
407178354Ssam	{ bridge_ioctl_gto,		sizeof(struct ifbrparam),
408178354Ssam	  BC_F_COPYOUT },
409178354Ssam
410178354Ssam	{ bridge_ioctl_daddr,		sizeof(struct ifbareq),
411178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
412178354Ssam
413178354Ssam	{ bridge_ioctl_flush,		sizeof(struct ifbreq),
414178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
415178354Ssam
416178354Ssam	{ bridge_ioctl_gpri,		sizeof(struct ifbrparam),
417178354Ssam	  BC_F_COPYOUT },
418178354Ssam	{ bridge_ioctl_spri,		sizeof(struct ifbrparam),
419178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
420178354Ssam
421178354Ssam	{ bridge_ioctl_ght,		sizeof(struct ifbrparam),
422178354Ssam	  BC_F_COPYOUT },
423178354Ssam	{ bridge_ioctl_sht,		sizeof(struct ifbrparam),
424178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
425178354Ssam
426178354Ssam	{ bridge_ioctl_gfd,		sizeof(struct ifbrparam),
427178354Ssam	  BC_F_COPYOUT },
428178354Ssam	{ bridge_ioctl_sfd,		sizeof(struct ifbrparam),
429178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
430178354Ssam
431178354Ssam	{ bridge_ioctl_gma,		sizeof(struct ifbrparam),
432178354Ssam	  BC_F_COPYOUT },
433178354Ssam	{ bridge_ioctl_sma,		sizeof(struct ifbrparam),
434178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
435178354Ssam
436178354Ssam	{ bridge_ioctl_sifprio,		sizeof(struct ifbreq),
437178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
438178354Ssam
439178354Ssam	{ bridge_ioctl_sifcost,		sizeof(struct ifbreq),
440178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
441178354Ssam
442178354Ssam	{ bridge_ioctl_addspan,		sizeof(struct ifbreq),
443178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
444178354Ssam	{ bridge_ioctl_delspan,		sizeof(struct ifbreq),
445178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
446178354Ssam
447191551Ssam	{ bridge_ioctl_gbparam,		sizeof(struct ifbropreq),
448178354Ssam	  BC_F_COPYOUT },
449178354Ssam
450178354Ssam	{ bridge_ioctl_grte,		sizeof(struct ifbrparam),
451178354Ssam	  BC_F_COPYOUT },
452178354Ssam
453191551Ssam	{ bridge_ioctl_gifsstp,		sizeof(struct ifbpstpconf),
454191551Ssam	  BC_F_COPYIN|BC_F_COPYOUT },
455191551Ssam
456191551Ssam	{ bridge_ioctl_sproto,		sizeof(struct ifbrparam),
457178354Ssam	  BC_F_COPYIN|BC_F_SUSER },
458191551Ssam
459191551Ssam	{ bridge_ioctl_stxhc,		sizeof(struct ifbrparam),
460191551Ssam	  BC_F_COPYIN|BC_F_SUSER },
461191551Ssam
462191551Ssam	{ bridge_ioctl_sifmaxaddr,	sizeof(struct ifbreq),
463191551Ssam	  BC_F_COPYIN|BC_F_SUSER },
464191551Ssam
465191551Ssam};
466191551Ssamconst int bridge_control_table_size =
467191551Ssam    sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
468191551Ssam
469191551SsamLIST_HEAD(, bridge_softc) bridge_list;
470191551Ssam
471191551SsamIFC_SIMPLE_DECLARE(bridge, 0);
472178354Ssam
473178354Ssamstatic int
474178354Ssambridge_modevent(module_t mod, int type, void *data)
475178354Ssam{
476178354Ssam
477178354Ssam	switch (type) {
478178354Ssam	case MOD_LOAD:
479178354Ssam		mtx_init(&bridge_list_mtx, "if_bridge list", NULL, MTX_DEF);
480178354Ssam		if_clone_attach(&bridge_cloner);
481178354Ssam		bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
482178354Ssam		    sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
483178354Ssam		    UMA_ALIGN_PTR, 0);
484191551Ssam		LIST_INIT(&bridge_list);
485178354Ssam		bridge_input_p = bridge_input;
486178354Ssam		bridge_output_p = bridge_output;
487178354Ssam		bridge_dn_p = bridge_dummynet;
488178354Ssam		bridge_detach_cookie = EVENTHANDLER_REGISTER(
489178354Ssam		    ifnet_departure_event, bridge_ifdetach, NULL,
490178354Ssam		    EVENTHANDLER_PRI_ANY);
491178354Ssam		break;
492178354Ssam	case MOD_UNLOAD:
493178354Ssam		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
494178354Ssam		    bridge_detach_cookie);
495178354Ssam		if_clone_detach(&bridge_cloner);
496178354Ssam		uma_zdestroy(bridge_rtnode_zone);
497178354Ssam		bridge_input_p = NULL;
498178354Ssam		bridge_output_p = NULL;
499178354Ssam		bridge_dn_p = NULL;
500187797Ssam		mtx_destroy(&bridge_list_mtx);
501178354Ssam		break;
502178354Ssam	default:
503178354Ssam		return (EOPNOTSUPP);
504178354Ssam	}
505178354Ssam	return (0);
506178354Ssam}
507178354Ssam
508178354Ssamstatic moduledata_t bridge_mod = {
509178354Ssam	"if_bridge",
510178354Ssam	bridge_modevent,
511178354Ssam	0
512178354Ssam};
513178354Ssam
514178354SsamDECLARE_MODULE(if_bridge, bridge_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
515178354SsamMODULE_DEPEND(if_bridge, bridgestp, 1, 1, 1);
516178354Ssam
517178354Ssam/*
518178354Ssam * handler for net.link.bridge.pfil_ipfw
519178354Ssam */
520178354Ssamstatic int
521178354Ssamsysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS)
522178354Ssam{
523178354Ssam	int enable = pfil_ipfw;
524178354Ssam	int error;
525178354Ssam
526178354Ssam	error = sysctl_handle_int(oidp, &enable, 0, req);
527178354Ssam	enable = (enable) ? 1 : 0;
528178354Ssam
529178354Ssam	if (enable != pfil_ipfw) {
530178354Ssam		pfil_ipfw = enable;
531178354Ssam
532178354Ssam		/*
533178354Ssam		 * Disable pfil so that ipfw doesnt run twice, if the user
534178354Ssam		 * really wants both then they can re-enable pfil_bridge and/or
535178354Ssam		 * pfil_member. Also allow non-ip packets as ipfw can filter by
536178354Ssam		 * layer2 type.
537178354Ssam		 */
538178354Ssam		if (pfil_ipfw) {
539178354Ssam			pfil_onlyip = 0;
540178354Ssam			pfil_bridge = 0;
541186107Ssam			pfil_member = 0;
542178354Ssam		}
543178354Ssam	}
544178354Ssam
545178354Ssam	return (error);
546178354Ssam}
547178354SsamSYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
548178354Ssam	    &pfil_ipfw, 0, &sysctl_pfil_ipfw, "I", "Layer2 filter with IPFW");
549178354Ssam
550178354Ssam/*
551178354Ssam * bridge_clone_create:
552178354Ssam *
553178354Ssam *	Create a new bridge instance.
554178354Ssam */
555178354Ssamstatic int
556178354Ssambridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
557178354Ssam{
558178354Ssam	struct bridge_softc *sc, *sc2;
559178354Ssam	struct ifnet *bifp, *ifp;
560178354Ssam	int retry;
561178354Ssam
562178354Ssam	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
563178354Ssam	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
564178354Ssam	if (ifp == NULL) {
565178354Ssam		free(sc, M_DEVBUF);
566178354Ssam		return (ENOSPC);
567178354Ssam	}
568188182Ssam
569188182Ssam	BRIDGE_LOCK_INIT(sc);
570178354Ssam	sc->sc_brtmax = BRIDGE_RTABLE_MAX;
571188182Ssam	sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
572188182Ssam
573178354Ssam	/* Initialize our routing table. */
574178354Ssam	bridge_rtable_init(sc);
575178354Ssam
576178354Ssam	callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
577178354Ssam
578178354Ssam	LIST_INIT(&sc->sc_iflist);
579178354Ssam	LIST_INIT(&sc->sc_spanlist);
580178354Ssam
581178354Ssam	ifp->if_softc = sc;
582178354Ssam	if_initname(ifp, ifc->ifc_name, unit);
583178354Ssam	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
584178354Ssam	ifp->if_ioctl = bridge_ioctl;
585178354Ssam	ifp->if_start = bridge_start;
586178354Ssam	ifp->if_init = bridge_init;
587178354Ssam	ifp->if_type = IFT_BRIDGE;
588178354Ssam	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
589191551Ssam	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
590191551Ssam	IFQ_SET_READY(&ifp->if_snd);
591178354Ssam
592178354Ssam	/*
593178354Ssam	 * Generate a random ethernet address with a locally administered
594178354Ssam	 * address.
595191551Ssam	 *
596191551Ssam	 * Since we are using random ethernet addresses for the bridge, it is
597191551Ssam	 * possible that we might have address collisions, so make sure that
598191551Ssam	 * this hardware address isn't already in use on another bridge.
599191551Ssam	 */
600191551Ssam	for (retry = 1; retry != 0;) {
601191551Ssam		arc4rand(sc->sc_defaddr, ETHER_ADDR_LEN, 1);
602191551Ssam		sc->sc_defaddr[0] &= ~1;	/* clear multicast bit */
603191551Ssam		sc->sc_defaddr[0] |= 2;		/* set the LAA bit */
604191551Ssam		retry = 0;
605191551Ssam		mtx_lock(&bridge_list_mtx);
606191551Ssam		LIST_FOREACH(sc2, &bridge_list, sc_list) {
607191551Ssam			bifp = sc2->sc_ifp;
608191551Ssam			if (memcmp(sc->sc_defaddr,
609191551Ssam			    IF_LLADDR(bifp), ETHER_ADDR_LEN) == 0)
610191551Ssam				retry = 1;
611191551Ssam		}
612191551Ssam		mtx_unlock(&bridge_list_mtx);
613191551Ssam	}
614191551Ssam
615191551Ssam	bstp_attach(&sc->sc_stp, &bridge_ops);
616191551Ssam	ether_ifattach(ifp, sc->sc_defaddr);
617191551Ssam	/* Now undo some of the damage... */
618191551Ssam	ifp->if_baudrate = 0;
619178354Ssam	ifp->if_type = IFT_BRIDGE;
620178354Ssam
621178354Ssam	mtx_lock(&bridge_list_mtx);
622178354Ssam	LIST_INSERT_HEAD(&bridge_list, sc, sc_list);
623178354Ssam	mtx_unlock(&bridge_list_mtx);
624178354Ssam
625178354Ssam	return (0);
626178354Ssam}
627178354Ssam
628178354Ssam/*
629178354Ssam * bridge_clone_destroy:
630178354Ssam *
631178354Ssam *	Destroy a bridge instance.
632178354Ssam */
633178354Ssamstatic void
634178354Ssambridge_clone_destroy(struct ifnet *ifp)
635178354Ssam{
636178354Ssam	struct bridge_softc *sc = ifp->if_softc;
637188182Ssam	struct bridge_iflist *bif;
638188182Ssam
639188182Ssam	BRIDGE_LOCK(sc);
640188182Ssam
641188182Ssam	bridge_stop(ifp, 1);
642188182Ssam	ifp->if_flags &= ~IFF_UP;
643188182Ssam
644188182Ssam	while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
645188182Ssam		bridge_delete_member(sc, bif, 0);
646188182Ssam
647188182Ssam	while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
648188182Ssam		bridge_delete_span(sc, bif);
649188182Ssam	}
650188182Ssam
651188182Ssam	BRIDGE_UNLOCK(sc);
652188182Ssam
653188182Ssam	callout_drain(&sc->sc_brcallout);
654188182Ssam
655188182Ssam	mtx_lock(&bridge_list_mtx);
656188182Ssam	LIST_REMOVE(sc, sc_list);
657178354Ssam	mtx_unlock(&bridge_list_mtx);
658178354Ssam
659178354Ssam	bstp_detach(&sc->sc_stp);
660178354Ssam	ether_ifdetach(ifp);
661178354Ssam	if_free_type(ifp, IFT_ETHER);
662178354Ssam
663178354Ssam	/* Tear down the routing table. */
664178354Ssam	bridge_rtable_fini(sc);
665188182Ssam
666178354Ssam	BRIDGE_LOCK_DESTROY(sc);
667178354Ssam	free(sc, M_DEVBUF);
668178354Ssam}
669178354Ssam
670178354Ssam/*
671178354Ssam * bridge_ioctl:
672178354Ssam *
673178354Ssam *	Handle a control request from the operator.
674178354Ssam */
675178354Ssamstatic int
676178354Ssambridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
677178354Ssam{
678178354Ssam	struct bridge_softc *sc = ifp->if_softc;
679178354Ssam	struct thread *td = curthread;
680178354Ssam	union {
681178354Ssam		struct ifbreq ifbreq;
682178354Ssam		struct ifbifconf ifbifconf;
683178354Ssam		struct ifbareq ifbareq;
684178354Ssam		struct ifbaconf ifbaconf;
685178354Ssam		struct ifbrparam ifbrparam;
686178354Ssam		struct ifbropreq ifbropreq;
687178354Ssam	} args;
688178354Ssam	struct ifdrv *ifd = (struct ifdrv *) data;
689178354Ssam	const struct bridge_control *bc;
690178354Ssam	int error = 0;
691178354Ssam
692178354Ssam	switch (cmd) {
693178354Ssam
694178354Ssam	case SIOCADDMULTI:
695178354Ssam	case SIOCDELMULTI:
696178354Ssam		break;
697178354Ssam
698178354Ssam	case SIOCGDRVSPEC:
699178354Ssam	case SIOCSDRVSPEC:
700178354Ssam		if (ifd->ifd_cmd >= bridge_control_table_size) {
701178354Ssam			error = EINVAL;
702178354Ssam			break;
703178354Ssam		}
704178354Ssam		bc = &bridge_control_table[ifd->ifd_cmd];
705178354Ssam
706178354Ssam		if (cmd == SIOCGDRVSPEC &&
707178354Ssam		    (bc->bc_flags & BC_F_COPYOUT) == 0) {
708178354Ssam			error = EINVAL;
709178354Ssam			break;
710178354Ssam		}
711178354Ssam		else if (cmd == SIOCSDRVSPEC &&
712178354Ssam		    (bc->bc_flags & BC_F_COPYOUT) != 0) {
713178354Ssam			error = EINVAL;
714178354Ssam			break;
715178354Ssam		}
716178354Ssam
717178354Ssam		if (bc->bc_flags & BC_F_SUSER) {
718178354Ssam			error = priv_check(td, PRIV_NET_BRIDGE);
719178354Ssam			if (error)
720178354Ssam				break;
721178354Ssam		}
722178354Ssam
723178354Ssam		if (ifd->ifd_len != bc->bc_argsize ||
724182822Ssam		    ifd->ifd_len > sizeof(args)) {
725178354Ssam			error = EINVAL;
726178354Ssam			break;
727178354Ssam		}
728178354Ssam
729178354Ssam		bzero(&args, sizeof(args));
730178354Ssam		if (bc->bc_flags & BC_F_COPYIN) {
731182822Ssam			error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
732178354Ssam			if (error)
733178354Ssam				break;
734182822Ssam		}
735178354Ssam
736178354Ssam		BRIDGE_LOCK(sc);
737182822Ssam		error = (*bc->bc_func)(sc, &args);
738178354Ssam		BRIDGE_UNLOCK(sc);
739178354Ssam		if (error)
740182822Ssam			break;
741178354Ssam
742178354Ssam		if (bc->bc_flags & BC_F_COPYOUT)
743182822Ssam			error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
744178354Ssam
745178354Ssam		break;
746178354Ssam
747182822Ssam	case SIOCSIFFLAGS:
748178354Ssam		if (!(ifp->if_flags & IFF_UP) &&
749178354Ssam		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
750188170Ssam			/*
751188170Ssam			 * If interface is marked down and it is running,
752178354Ssam			 * then stop and disable it.
753178354Ssam			 */
754178354Ssam			BRIDGE_LOCK(sc);
755178354Ssam			bridge_stop(ifp, 1);
756178354Ssam			BRIDGE_UNLOCK(sc);
757178354Ssam		} else if ((ifp->if_flags & IFF_UP) &&
758178354Ssam		    !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
759178354Ssam			/*
760178354Ssam			 * If interface is marked up and it is stopped, then
761178354Ssam			 * start it.
762178354Ssam			 */
763178354Ssam			(*ifp->if_init)(sc);
764178354Ssam		}
765188170Ssam		break;
766178354Ssam
767188170Ssam	case SIOCSIFMTU:
768178354Ssam		/* Do not allow the MTU to be changed on the bridge */
769178354Ssam		error = EINVAL;
770178354Ssam		break;
771178354Ssam
772178354Ssam	default:
773178354Ssam		/*
774178354Ssam		 * drop the lock as ether_ioctl() will call bridge_start() and
775178354Ssam		 * cause the lock to be recursed.
776178354Ssam		 */
777178354Ssam		error = ether_ioctl(ifp, cmd, data);
778178354Ssam		break;
779178354Ssam	}
780178354Ssam
781178354Ssam	return (error);
782178354Ssam}
783178354Ssam
784178354Ssam/*
785178354Ssam * bridge_mutecaps:
786178354Ssam *
787178354Ssam *	Clear or restore unwanted capabilities on the member interface
788178354Ssam */
789178354Ssamstatic void
790178354Ssambridge_mutecaps(struct bridge_softc *sc)
791178354Ssam{
792178354Ssam	struct bridge_iflist *bif;
793178354Ssam	int enabled, mask;
794178354Ssam
795178354Ssam	/* Initial bitmask of capabilities to test */
796178354Ssam	mask = BRIDGE_IFCAPS_MASK;
797178354Ssam
798178354Ssam	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
799178354Ssam		/* Every member must support it or its disabled */
800178354Ssam		mask &= bif->bif_savedcaps;
801178354Ssam	}
802178354Ssam
803178354Ssam	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
804178354Ssam		enabled = bif->bif_ifp->if_capenable;
805178354Ssam		/* strip off mask bits and enable them again if allowed */
806178354Ssam		enabled &= ~BRIDGE_IFCAPS_MASK;
807178354Ssam		enabled |= mask;
808178354Ssam		/*
809178354Ssam		 * Receive offload can only be enabled if all members also
810178354Ssam		 * support send offload.
811178354Ssam		 */
812178354Ssam		if ((enabled & IFCAP_TSO) == 0)
813			enabled &= ~IFCAP_LRO;
814
815		bridge_set_ifcap(sc, bif, enabled);
816	}
817
818}
819
820static void
821bridge_set_ifcap(struct bridge_softc *sc, struct bridge_iflist *bif, int set)
822{
823	struct ifnet *ifp = bif->bif_ifp;
824	struct ifreq ifr;
825	int error;
826
827	bzero(&ifr, sizeof(ifr));
828	ifr.ifr_reqcap = set;
829
830	if (ifp->if_capenable != set) {
831		IFF_LOCKGIANT(ifp);
832		error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr);
833		IFF_UNLOCKGIANT(ifp);
834		if (error)
835			if_printf(sc->sc_ifp,
836			    "error setting interface capabilities on %s\n",
837			    ifp->if_xname);
838	}
839}
840
841/*
842 * bridge_lookup_member:
843 *
844 *	Lookup a bridge member interface.
845 */
846static struct bridge_iflist *
847bridge_lookup_member(struct bridge_softc *sc, const char *name)
848{
849	struct bridge_iflist *bif;
850	struct ifnet *ifp;
851
852	BRIDGE_LOCK_ASSERT(sc);
853
854	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
855		ifp = bif->bif_ifp;
856		if (strcmp(ifp->if_xname, name) == 0)
857			return (bif);
858	}
859
860	return (NULL);
861}
862
863/*
864 * bridge_lookup_member_if:
865 *
866 *	Lookup a bridge member interface by ifnet*.
867 */
868static struct bridge_iflist *
869bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
870{
871	struct bridge_iflist *bif;
872
873	BRIDGE_LOCK_ASSERT(sc);
874
875	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
876		if (bif->bif_ifp == member_ifp)
877			return (bif);
878	}
879
880	return (NULL);
881}
882
883/*
884 * bridge_delete_member:
885 *
886 *	Delete the specified member interface.
887 */
888static void
889bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
890    int gone)
891{
892	struct ifnet *ifs = bif->bif_ifp;
893	struct ifnet *fif = NULL;
894
895	BRIDGE_LOCK_ASSERT(sc);
896
897	if (!gone) {
898		switch (ifs->if_type) {
899		case IFT_ETHER:
900		case IFT_L2VLAN:
901			/*
902			 * Take the interface out of promiscuous mode.
903			 */
904			(void) ifpromisc(ifs, 0);
905			break;
906
907		case IFT_GIF:
908			break;
909
910		default:
911#ifdef DIAGNOSTIC
912			panic("bridge_delete_member: impossible");
913#endif
914			break;
915		}
916		/* reneable any interface capabilities */
917		bridge_set_ifcap(sc, bif, bif->bif_savedcaps);
918	}
919
920	if (bif->bif_flags & IFBIF_STP)
921		bstp_disable(&bif->bif_stp);
922
923	ifs->if_bridge = NULL;
924	BRIDGE_XLOCK(sc);
925	LIST_REMOVE(bif, bif_next);
926	BRIDGE_XDROP(sc);
927
928	/*
929	 * If removing the interface that gave the bridge its mac address, set
930	 * the mac address of the bridge to the address of the next member, or
931	 * to its default address if no members are left.
932	 */
933	if (bridge_inherit_mac &&
934	    !memcmp(IF_LLADDR(sc->sc_ifp), IF_LLADDR(ifs), ETHER_ADDR_LEN)) {
935		if (LIST_EMPTY(&sc->sc_iflist))
936			bcopy(sc->sc_defaddr,
937			    IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
938		else {
939			fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp;
940			bcopy(IF_LLADDR(fif),
941			    IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
942		}
943	}
944
945	bridge_mutecaps(sc);	/* recalcuate now this interface is removed */
946	bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
947	KASSERT(bif->bif_addrcnt == 0,
948	    ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt));
949
950	BRIDGE_UNLOCK(sc);
951	bstp_destroy(&bif->bif_stp);	/* prepare to free */
952	BRIDGE_LOCK(sc);
953	free(bif, M_DEVBUF);
954}
955
956/*
957 * bridge_delete_span:
958 *
959 *	Delete the specified span interface.
960 */
961static void
962bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif)
963{
964	BRIDGE_LOCK_ASSERT(sc);
965
966	KASSERT(bif->bif_ifp->if_bridge == NULL,
967	    ("%s: not a span interface", __func__));
968
969	LIST_REMOVE(bif, bif_next);
970	free(bif, M_DEVBUF);
971}
972
973static int
974bridge_ioctl_add(struct bridge_softc *sc, void *arg)
975{
976	struct ifbreq *req = arg;
977	struct bridge_iflist *bif = NULL;
978	struct ifnet *ifs;
979	int error = 0;
980
981	ifs = ifunit(req->ifbr_ifsname);
982	if (ifs == NULL)
983		return (ENOENT);
984	if (ifs->if_ioctl == NULL)	/* must be supported */
985		return (EINVAL);
986
987	/* If it's in the span list, it can't be a member. */
988	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
989		if (ifs == bif->bif_ifp)
990			return (EBUSY);
991
992	/* Allow the first Ethernet member to define the MTU */
993	if (ifs->if_type != IFT_GIF) {
994		if (LIST_EMPTY(&sc->sc_iflist))
995			sc->sc_ifp->if_mtu = ifs->if_mtu;
996		else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
997			if_printf(sc->sc_ifp, "invalid MTU for %s\n",
998			    ifs->if_xname);
999			return (EINVAL);
1000		}
1001	}
1002
1003	if (ifs->if_bridge == sc)
1004		return (EEXIST);
1005
1006	if (ifs->if_bridge != NULL)
1007		return (EBUSY);
1008
1009	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
1010	if (bif == NULL)
1011		return (ENOMEM);
1012
1013	bif->bif_ifp = ifs;
1014	bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
1015	bif->bif_savedcaps = ifs->if_capenable;
1016
1017	switch (ifs->if_type) {
1018	case IFT_ETHER:
1019	case IFT_L2VLAN:
1020		/*
1021		 * Place the interface into promiscuous mode.
1022		 */
1023		error = ifpromisc(ifs, 1);
1024		if (error)
1025			goto out;
1026		break;
1027
1028	case IFT_GIF:
1029		break;
1030
1031	default:
1032		error = EINVAL;
1033		goto out;
1034	}
1035
1036	/*
1037	 * Assign the interface's MAC address to the bridge if it's the first
1038	 * member and the MAC address of the bridge has not been changed from
1039	 * the default randomly generated one.
1040	 */
1041	if (bridge_inherit_mac && LIST_EMPTY(&sc->sc_iflist) &&
1042	    !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr, ETHER_ADDR_LEN))
1043		bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
1044
1045	ifs->if_bridge = sc;
1046	bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp);
1047	/*
1048	 * XXX: XLOCK HERE!?!
1049	 *
1050	 * NOTE: insert_***HEAD*** should be safe for the traversals.
1051	 */
1052	LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
1053
1054	/* Set interface capabilities to the intersection set of all members */
1055	bridge_mutecaps(sc);
1056out:
1057	if (error) {
1058		if (bif != NULL)
1059			free(bif, M_DEVBUF);
1060	}
1061	return (error);
1062}
1063
1064static int
1065bridge_ioctl_del(struct bridge_softc *sc, void *arg)
1066{
1067	struct ifbreq *req = arg;
1068	struct bridge_iflist *bif;
1069
1070	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1071	if (bif == NULL)
1072		return (ENOENT);
1073
1074	bridge_delete_member(sc, bif, 0);
1075
1076	return (0);
1077}
1078
1079static int
1080bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
1081{
1082	struct ifbreq *req = arg;
1083	struct bridge_iflist *bif;
1084	struct bstp_port *bp;
1085
1086	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1087	if (bif == NULL)
1088		return (ENOENT);
1089
1090	bp = &bif->bif_stp;
1091	req->ifbr_ifsflags = bif->bif_flags;
1092	req->ifbr_state = bp->bp_state;
1093	req->ifbr_priority = bp->bp_priority;
1094	req->ifbr_path_cost = bp->bp_path_cost;
1095	req->ifbr_portno = bif->bif_ifp->if_index & 0xfff;
1096	req->ifbr_proto = bp->bp_protover;
1097	req->ifbr_role = bp->bp_role;
1098	req->ifbr_stpflags = bp->bp_flags;
1099	req->ifbr_addrcnt = bif->bif_addrcnt;
1100	req->ifbr_addrmax = bif->bif_addrmax;
1101	req->ifbr_addrexceeded = bif->bif_addrexceeded;
1102
1103	/* Copy STP state options as flags */
1104	if (bp->bp_operedge)
1105		req->ifbr_ifsflags |= IFBIF_BSTP_EDGE;
1106	if (bp->bp_flags & BSTP_PORT_AUTOEDGE)
1107		req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE;
1108	if (bp->bp_ptp_link)
1109		req->ifbr_ifsflags |= IFBIF_BSTP_PTP;
1110	if (bp->bp_flags & BSTP_PORT_AUTOPTP)
1111		req->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP;
1112	if (bp->bp_flags & BSTP_PORT_ADMEDGE)
1113		req->ifbr_ifsflags |= IFBIF_BSTP_ADMEDGE;
1114	if (bp->bp_flags & BSTP_PORT_ADMCOST)
1115		req->ifbr_ifsflags |= IFBIF_BSTP_ADMCOST;
1116	return (0);
1117}
1118
1119static int
1120bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
1121{
1122	struct ifbreq *req = arg;
1123	struct bridge_iflist *bif;
1124	struct bstp_port *bp;
1125	int error;
1126
1127	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1128	if (bif == NULL)
1129		return (ENOENT);
1130	bp = &bif->bif_stp;
1131
1132	if (req->ifbr_ifsflags & IFBIF_SPAN)
1133		/* SPAN is readonly */
1134		return (EINVAL);
1135
1136	if (req->ifbr_ifsflags & IFBIF_STP) {
1137		if ((bif->bif_flags & IFBIF_STP) == 0) {
1138			error = bstp_enable(&bif->bif_stp);
1139			if (error)
1140				return (error);
1141		}
1142	} else {
1143		if ((bif->bif_flags & IFBIF_STP) != 0)
1144			bstp_disable(&bif->bif_stp);
1145	}
1146
1147	/* Pass on STP flags */
1148	bstp_set_edge(bp, req->ifbr_ifsflags & IFBIF_BSTP_EDGE ? 1 : 0);
1149	bstp_set_autoedge(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOEDGE ? 1 : 0);
1150	bstp_set_ptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_PTP ? 1 : 0);
1151	bstp_set_autoptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOPTP ? 1 : 0);
1152
1153	/* Save the bits relating to the bridge */
1154	bif->bif_flags = req->ifbr_ifsflags & IFBIFMASK;
1155
1156	return (0);
1157}
1158
1159static int
1160bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
1161{
1162	struct ifbrparam *param = arg;
1163
1164	sc->sc_brtmax = param->ifbrp_csize;
1165	bridge_rttrim(sc);
1166
1167	return (0);
1168}
1169
1170static int
1171bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
1172{
1173	struct ifbrparam *param = arg;
1174
1175	param->ifbrp_csize = sc->sc_brtmax;
1176
1177	return (0);
1178}
1179
1180static int
1181bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
1182{
1183	struct ifbifconf *bifc = arg;
1184	struct bridge_iflist *bif;
1185	struct ifbreq breq;
1186	char *buf, *outbuf;
1187	int count, buflen, len, error = 0;
1188
1189	count = 0;
1190	LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
1191		count++;
1192	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1193		count++;
1194
1195	buflen = sizeof(breq) * count;
1196	if (bifc->ifbic_len == 0) {
1197		bifc->ifbic_len = buflen;
1198		return (0);
1199	}
1200	BRIDGE_UNLOCK(sc);
1201	outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
1202	BRIDGE_LOCK(sc);
1203
1204	count = 0;
1205	buf = outbuf;
1206	len = min(bifc->ifbic_len, buflen);
1207	bzero(&breq, sizeof(breq));
1208	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1209		if (len < sizeof(breq))
1210			break;
1211
1212		strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
1213		    sizeof(breq.ifbr_ifsname));
1214		/* Fill in the ifbreq structure */
1215		error = bridge_ioctl_gifflags(sc, &breq);
1216		if (error)
1217			break;
1218		memcpy(buf, &breq, sizeof(breq));
1219		count++;
1220		buf += sizeof(breq);
1221		len -= sizeof(breq);
1222	}
1223	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
1224		if (len < sizeof(breq))
1225			break;
1226
1227		strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname,
1228		    sizeof(breq.ifbr_ifsname));
1229		breq.ifbr_ifsflags = bif->bif_flags;
1230		breq.ifbr_portno = bif->bif_ifp->if_index & 0xfff;
1231		memcpy(buf, &breq, sizeof(breq));
1232		count++;
1233		buf += sizeof(breq);
1234		len -= sizeof(breq);
1235	}
1236
1237	BRIDGE_UNLOCK(sc);
1238	bifc->ifbic_len = sizeof(breq) * count;
1239	error = copyout(outbuf, bifc->ifbic_req, bifc->ifbic_len);
1240	BRIDGE_LOCK(sc);
1241	free(outbuf, M_TEMP);
1242	return (error);
1243}
1244
1245static int
1246bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
1247{
1248	struct ifbaconf *bac = arg;
1249	struct bridge_rtnode *brt;
1250	struct ifbareq bareq;
1251	char *buf, *outbuf;
1252	int count, buflen, len, error = 0;
1253
1254	if (bac->ifbac_len == 0)
1255		return (0);
1256
1257	count = 0;
1258	LIST_FOREACH(brt, &sc->sc_rtlist, brt_list)
1259		count++;
1260	buflen = sizeof(bareq) * count;
1261
1262	BRIDGE_UNLOCK(sc);
1263	outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
1264	BRIDGE_LOCK(sc);
1265
1266	count = 0;
1267	buf = outbuf;
1268	len = min(bac->ifbac_len, buflen);
1269	bzero(&bareq, sizeof(bareq));
1270	LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
1271		if (len < sizeof(bareq))
1272			goto out;
1273		strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
1274		    sizeof(bareq.ifba_ifsname));
1275		memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
1276		bareq.ifba_vlan = brt->brt_vlan;
1277		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
1278				time_uptime < brt->brt_expire)
1279			bareq.ifba_expire = brt->brt_expire - time_uptime;
1280		else
1281			bareq.ifba_expire = 0;
1282		bareq.ifba_flags = brt->brt_flags;
1283
1284		memcpy(buf, &bareq, sizeof(bareq));
1285		count++;
1286		buf += sizeof(bareq);
1287		len -= sizeof(bareq);
1288	}
1289out:
1290	BRIDGE_UNLOCK(sc);
1291	bac->ifbac_len = sizeof(bareq) * count;
1292	error = copyout(outbuf, bac->ifbac_req, bac->ifbac_len);
1293	BRIDGE_LOCK(sc);
1294	free(outbuf, M_TEMP);
1295	return (error);
1296}
1297
1298static int
1299bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
1300{
1301	struct ifbareq *req = arg;
1302	struct bridge_iflist *bif;
1303	int error;
1304
1305	bif = bridge_lookup_member(sc, req->ifba_ifsname);
1306	if (bif == NULL)
1307		return (ENOENT);
1308
1309	error = bridge_rtupdate(sc, req->ifba_dst, req->ifba_vlan, bif, 1,
1310	    req->ifba_flags);
1311
1312	return (error);
1313}
1314
1315static int
1316bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
1317{
1318	struct ifbrparam *param = arg;
1319
1320	sc->sc_brttimeout = param->ifbrp_ctime;
1321	return (0);
1322}
1323
1324static int
1325bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
1326{
1327	struct ifbrparam *param = arg;
1328
1329	param->ifbrp_ctime = sc->sc_brttimeout;
1330	return (0);
1331}
1332
1333static int
1334bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
1335{
1336	struct ifbareq *req = arg;
1337
1338	return (bridge_rtdaddr(sc, req->ifba_dst, req->ifba_vlan));
1339}
1340
1341static int
1342bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
1343{
1344	struct ifbreq *req = arg;
1345
1346	bridge_rtflush(sc, req->ifbr_ifsflags);
1347	return (0);
1348}
1349
1350static int
1351bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1352{
1353	struct ifbrparam *param = arg;
1354	struct bstp_state *bs = &sc->sc_stp;
1355
1356	param->ifbrp_prio = bs->bs_bridge_priority;
1357	return (0);
1358}
1359
1360static int
1361bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1362{
1363	struct ifbrparam *param = arg;
1364
1365	return (bstp_set_priority(&sc->sc_stp, param->ifbrp_prio));
1366}
1367
1368static int
1369bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1370{
1371	struct ifbrparam *param = arg;
1372	struct bstp_state *bs = &sc->sc_stp;
1373
1374	param->ifbrp_hellotime = bs->bs_bridge_htime >> 8;
1375	return (0);
1376}
1377
1378static int
1379bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1380{
1381	struct ifbrparam *param = arg;
1382
1383	return (bstp_set_htime(&sc->sc_stp, param->ifbrp_hellotime));
1384}
1385
1386static int
1387bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1388{
1389	struct ifbrparam *param = arg;
1390	struct bstp_state *bs = &sc->sc_stp;
1391
1392	param->ifbrp_fwddelay = bs->bs_bridge_fdelay >> 8;
1393	return (0);
1394}
1395
1396static int
1397bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1398{
1399	struct ifbrparam *param = arg;
1400
1401	return (bstp_set_fdelay(&sc->sc_stp, param->ifbrp_fwddelay));
1402}
1403
1404static int
1405bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1406{
1407	struct ifbrparam *param = arg;
1408	struct bstp_state *bs = &sc->sc_stp;
1409
1410	param->ifbrp_maxage = bs->bs_bridge_max_age >> 8;
1411	return (0);
1412}
1413
1414static int
1415bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1416{
1417	struct ifbrparam *param = arg;
1418
1419	return (bstp_set_maxage(&sc->sc_stp, param->ifbrp_maxage));
1420}
1421
1422static int
1423bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1424{
1425	struct ifbreq *req = arg;
1426	struct bridge_iflist *bif;
1427
1428	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1429	if (bif == NULL)
1430		return (ENOENT);
1431
1432	return (bstp_set_port_priority(&bif->bif_stp, req->ifbr_priority));
1433}
1434
1435static int
1436bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1437{
1438	struct ifbreq *req = arg;
1439	struct bridge_iflist *bif;
1440
1441	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1442	if (bif == NULL)
1443		return (ENOENT);
1444
1445	return (bstp_set_path_cost(&bif->bif_stp, req->ifbr_path_cost));
1446}
1447
1448static int
1449bridge_ioctl_sifmaxaddr(struct bridge_softc *sc, void *arg)
1450{
1451	struct ifbreq *req = arg;
1452	struct bridge_iflist *bif;
1453
1454	bif = bridge_lookup_member(sc, req->ifbr_ifsname);
1455	if (bif == NULL)
1456		return (ENOENT);
1457
1458	bif->bif_addrmax = req->ifbr_addrmax;
1459	return (0);
1460}
1461
1462static int
1463bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
1464{
1465	struct ifbreq *req = arg;
1466	struct bridge_iflist *bif = NULL;
1467	struct ifnet *ifs;
1468
1469	ifs = ifunit(req->ifbr_ifsname);
1470	if (ifs == NULL)
1471		return (ENOENT);
1472
1473	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1474		if (ifs == bif->bif_ifp)
1475			return (EBUSY);
1476
1477	if (ifs->if_bridge != NULL)
1478		return (EBUSY);
1479
1480	switch (ifs->if_type) {
1481		case IFT_ETHER:
1482		case IFT_GIF:
1483		case IFT_L2VLAN:
1484			break;
1485		default:
1486			return (EINVAL);
1487	}
1488
1489	bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
1490	if (bif == NULL)
1491		return (ENOMEM);
1492
1493	bif->bif_ifp = ifs;
1494	bif->bif_flags = IFBIF_SPAN;
1495
1496	LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
1497
1498	return (0);
1499}
1500
1501static int
1502bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
1503{
1504	struct ifbreq *req = arg;
1505	struct bridge_iflist *bif;
1506	struct ifnet *ifs;
1507
1508	ifs = ifunit(req->ifbr_ifsname);
1509	if (ifs == NULL)
1510		return (ENOENT);
1511
1512	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1513		if (ifs == bif->bif_ifp)
1514			break;
1515
1516	if (bif == NULL)
1517		return (ENOENT);
1518
1519	bridge_delete_span(sc, bif);
1520
1521	return (0);
1522}
1523
1524static int
1525bridge_ioctl_gbparam(struct bridge_softc *sc, void *arg)
1526{
1527	struct ifbropreq *req = arg;
1528	struct bstp_state *bs = &sc->sc_stp;
1529	struct bstp_port *root_port;
1530
1531	req->ifbop_maxage = bs->bs_bridge_max_age >> 8;
1532	req->ifbop_hellotime = bs->bs_bridge_htime >> 8;
1533	req->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8;
1534
1535	root_port = bs->bs_root_port;
1536	if (root_port == NULL)
1537		req->ifbop_root_port = 0;
1538	else
1539		req->ifbop_root_port = root_port->bp_ifp->if_index;
1540
1541	req->ifbop_holdcount = bs->bs_txholdcount;
1542	req->ifbop_priority = bs->bs_bridge_priority;
1543	req->ifbop_protocol = bs->bs_protover;
1544	req->ifbop_root_path_cost = bs->bs_root_pv.pv_cost;
1545	req->ifbop_bridgeid = bs->bs_bridge_pv.pv_dbridge_id;
1546	req->ifbop_designated_root = bs->bs_root_pv.pv_root_id;
1547	req->ifbop_designated_bridge = bs->bs_root_pv.pv_dbridge_id;
1548	req->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec;
1549	req->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec;
1550
1551	return (0);
1552}
1553
1554static int
1555bridge_ioctl_grte(struct bridge_softc *sc, void *arg)
1556{
1557	struct ifbrparam *param = arg;
1558
1559	param->ifbrp_cexceeded = sc->sc_brtexceeded;
1560	return (0);
1561}
1562
1563static int
1564bridge_ioctl_gifsstp(struct bridge_softc *sc, void *arg)
1565{
1566	struct ifbpstpconf *bifstp = arg;
1567	struct bridge_iflist *bif;
1568	struct bstp_port *bp;
1569	struct ifbpstpreq bpreq;
1570	char *buf, *outbuf;
1571	int count, buflen, len, error = 0;
1572
1573	count = 0;
1574	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1575		if ((bif->bif_flags & IFBIF_STP) != 0)
1576			count++;
1577	}
1578
1579	buflen = sizeof(bpreq) * count;
1580	if (bifstp->ifbpstp_len == 0) {
1581		bifstp->ifbpstp_len = buflen;
1582		return (0);
1583	}
1584
1585	BRIDGE_UNLOCK(sc);
1586	outbuf = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
1587	BRIDGE_LOCK(sc);
1588
1589	count = 0;
1590	buf = outbuf;
1591	len = min(bifstp->ifbpstp_len, buflen);
1592	bzero(&bpreq, sizeof(bpreq));
1593	LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1594		if (len < sizeof(bpreq))
1595			break;
1596
1597		if ((bif->bif_flags & IFBIF_STP) == 0)
1598			continue;
1599
1600		bp = &bif->bif_stp;
1601		bpreq.ifbp_portno = bif->bif_ifp->if_index & 0xfff;
1602		bpreq.ifbp_fwd_trans = bp->bp_forward_transitions;
1603		bpreq.ifbp_design_cost = bp->bp_desg_pv.pv_cost;
1604		bpreq.ifbp_design_port = bp->bp_desg_pv.pv_port_id;
1605		bpreq.ifbp_design_bridge = bp->bp_desg_pv.pv_dbridge_id;
1606		bpreq.ifbp_design_root = bp->bp_desg_pv.pv_root_id;
1607
1608		memcpy(buf, &bpreq, sizeof(bpreq));
1609		count++;
1610		buf += sizeof(bpreq);
1611		len -= sizeof(bpreq);
1612	}
1613
1614	BRIDGE_UNLOCK(sc);
1615	bifstp->ifbpstp_len = sizeof(bpreq) * count;
1616	error = copyout(outbuf, bifstp->ifbpstp_req, bifstp->ifbpstp_len);
1617	BRIDGE_LOCK(sc);
1618	free(outbuf, M_TEMP);
1619	return (error);
1620}
1621
1622static int
1623bridge_ioctl_sproto(struct bridge_softc *sc, void *arg)
1624{
1625	struct ifbrparam *param = arg;
1626
1627	return (bstp_set_protocol(&sc->sc_stp, param->ifbrp_proto));
1628}
1629
1630static int
1631bridge_ioctl_stxhc(struct bridge_softc *sc, void *arg)
1632{
1633	struct ifbrparam *param = arg;
1634
1635	return (bstp_set_holdcount(&sc->sc_stp, param->ifbrp_txhc));
1636}
1637
1638/*
1639 * bridge_ifdetach:
1640 *
1641 *	Detach an interface from a bridge.  Called when a member
1642 *	interface is detaching.
1643 */
1644static void
1645bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
1646{
1647	struct bridge_softc *sc = ifp->if_bridge;
1648	struct bridge_iflist *bif;
1649
1650	/* Check if the interface is a bridge member */
1651	if (sc != NULL) {
1652		BRIDGE_LOCK(sc);
1653
1654		bif = bridge_lookup_member_if(sc, ifp);
1655		if (bif != NULL)
1656			bridge_delete_member(sc, bif, 1);
1657
1658		BRIDGE_UNLOCK(sc);
1659		return;
1660	}
1661
1662	/* Check if the interface is a span port */
1663	mtx_lock(&bridge_list_mtx);
1664	LIST_FOREACH(sc, &bridge_list, sc_list) {
1665		BRIDGE_LOCK(sc);
1666		LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
1667			if (ifp == bif->bif_ifp) {
1668				bridge_delete_span(sc, bif);
1669				break;
1670			}
1671
1672		BRIDGE_UNLOCK(sc);
1673	}
1674	mtx_unlock(&bridge_list_mtx);
1675}
1676
1677/*
1678 * bridge_init:
1679 *
1680 *	Initialize a bridge interface.
1681 */
1682static void
1683bridge_init(void *xsc)
1684{
1685	struct bridge_softc *sc = (struct bridge_softc *)xsc;
1686	struct ifnet *ifp = sc->sc_ifp;
1687
1688	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1689		return;
1690
1691	BRIDGE_LOCK(sc);
1692	callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1693	    bridge_timer, sc);
1694
1695	ifp->if_drv_flags |= IFF_DRV_RUNNING;
1696	bstp_init(&sc->sc_stp);		/* Initialize Spanning Tree */
1697
1698	BRIDGE_UNLOCK(sc);
1699}
1700
1701/*
1702 * bridge_stop:
1703 *
1704 *	Stop the bridge interface.
1705 */
1706static void
1707bridge_stop(struct ifnet *ifp, int disable)
1708{
1709	struct bridge_softc *sc = ifp->if_softc;
1710
1711	BRIDGE_LOCK_ASSERT(sc);
1712
1713	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1714		return;
1715
1716	callout_stop(&sc->sc_brcallout);
1717	bstp_stop(&sc->sc_stp);
1718
1719	bridge_rtflush(sc, IFBF_FLUSHDYN);
1720
1721	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
1722}
1723
1724/*
1725 * bridge_enqueue:
1726 *
1727 *	Enqueue a packet on a bridge member interface.
1728 *
1729 */
1730static void
1731bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m)
1732{
1733	int len, err = 0;
1734	short mflags;
1735	struct mbuf *m0;
1736
1737	len = m->m_pkthdr.len;
1738	mflags = m->m_flags;
1739
1740	/* We may be sending a fragment so traverse the mbuf */
1741	for (; m; m = m0) {
1742		m0 = m->m_nextpkt;
1743		m->m_nextpkt = NULL;
1744
1745		/*
1746		 * If underlying interface can not do VLAN tag insertion itself
1747		 * then attach a packet tag that holds it.
1748		 */
1749		if ((m->m_flags & M_VLANTAG) &&
1750		    (dst_ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) {
1751			m = ether_vlanencap(m, m->m_pkthdr.ether_vtag);
1752			if (m == NULL) {
1753				if_printf(dst_ifp,
1754				    "unable to prepend VLAN header\n");
1755				dst_ifp->if_oerrors++;
1756				continue;
1757			}
1758			m->m_flags &= ~M_VLANTAG;
1759		}
1760
1761		if (err == 0)
1762			IFQ_ENQUEUE(&dst_ifp->if_snd, m, err);
1763	}
1764
1765	if (err == 0) {
1766
1767		sc->sc_ifp->if_opackets++;
1768		sc->sc_ifp->if_obytes += len;
1769
1770		dst_ifp->if_obytes += len;
1771
1772		if (mflags & M_MCAST) {
1773			sc->sc_ifp->if_omcasts++;
1774			dst_ifp->if_omcasts++;
1775		}
1776	}
1777
1778	if ((dst_ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0)
1779		(*dst_ifp->if_start)(dst_ifp);
1780}
1781
1782/*
1783 * bridge_dummynet:
1784 *
1785 * 	Receive a queued packet from dummynet and pass it on to the output
1786 * 	interface.
1787 *
1788 *	The mbuf has the Ethernet header already attached.
1789 */
1790static void
1791bridge_dummynet(struct mbuf *m, struct ifnet *ifp)
1792{
1793	struct bridge_softc *sc;
1794
1795	sc = ifp->if_bridge;
1796
1797	/*
1798	 * The packet didnt originate from a member interface. This should only
1799	 * ever happen if a member interface is removed while packets are
1800	 * queued for it.
1801	 */
1802	if (sc == NULL) {
1803		m_freem(m);
1804		return;
1805	}
1806
1807	if (PFIL_HOOKED(&inet_pfil_hook)
1808#ifdef INET6
1809	    || PFIL_HOOKED(&inet6_pfil_hook)
1810#endif
1811	    ) {
1812		if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0)
1813			return;
1814		if (m == NULL)
1815			return;
1816	}
1817
1818	bridge_enqueue(sc, ifp, m);
1819}
1820
1821/*
1822 * bridge_output:
1823 *
1824 *	Send output from a bridge member interface.  This
1825 *	performs the bridging function for locally originated
1826 *	packets.
1827 *
1828 *	The mbuf has the Ethernet header already attached.  We must
1829 *	enqueue or free the mbuf before returning.
1830 */
1831static int
1832bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
1833    struct rtentry *rt)
1834{
1835	struct ether_header *eh;
1836	struct ifnet *dst_if;
1837	struct bridge_softc *sc;
1838	uint16_t vlan;
1839
1840	if (m->m_len < ETHER_HDR_LEN) {
1841		m = m_pullup(m, ETHER_HDR_LEN);
1842		if (m == NULL)
1843			return (0);
1844	}
1845
1846	eh = mtod(m, struct ether_header *);
1847	sc = ifp->if_bridge;
1848	vlan = VLANTAGOF(m);
1849
1850	BRIDGE_LOCK(sc);
1851
1852	/*
1853	 * If bridge is down, but the original output interface is up,
1854	 * go ahead and send out that interface.  Otherwise, the packet
1855	 * is dropped below.
1856	 */
1857	if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1858		dst_if = ifp;
1859		goto sendunicast;
1860	}
1861
1862	/*
1863	 * If the packet is a multicast, or we don't know a better way to
1864	 * get there, send to all interfaces.
1865	 */
1866	if (ETHER_IS_MULTICAST(eh->ether_dhost))
1867		dst_if = NULL;
1868	else
1869		dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan);
1870	if (dst_if == NULL) {
1871		struct bridge_iflist *bif;
1872		struct mbuf *mc;
1873		int error = 0, used = 0;
1874
1875		bridge_span(sc, m);
1876
1877		BRIDGE_LOCK2REF(sc, error);
1878		if (error) {
1879			m_freem(m);
1880			return (0);
1881		}
1882
1883		LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1884			dst_if = bif->bif_ifp;
1885
1886			if (dst_if->if_type == IFT_GIF)
1887				continue;
1888			if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
1889				continue;
1890
1891			/*
1892			 * If this is not the original output interface,
1893			 * and the interface is participating in spanning
1894			 * tree, make sure the port is in a state that
1895			 * allows forwarding.
1896			 */
1897			if (dst_if != ifp && (bif->bif_flags & IFBIF_STP) &&
1898			    bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
1899				continue;
1900
1901			if (LIST_NEXT(bif, bif_next) == NULL) {
1902				used = 1;
1903				mc = m;
1904			} else {
1905				mc = m_copypacket(m, M_DONTWAIT);
1906				if (mc == NULL) {
1907					sc->sc_ifp->if_oerrors++;
1908					continue;
1909				}
1910			}
1911
1912			bridge_enqueue(sc, dst_if, mc);
1913		}
1914		if (used == 0)
1915			m_freem(m);
1916		BRIDGE_UNREF(sc);
1917		return (0);
1918	}
1919
1920sendunicast:
1921	/*
1922	 * XXX Spanning tree consideration here?
1923	 */
1924
1925	bridge_span(sc, m);
1926	if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1927		m_freem(m);
1928		BRIDGE_UNLOCK(sc);
1929		return (0);
1930	}
1931
1932	BRIDGE_UNLOCK(sc);
1933	bridge_enqueue(sc, dst_if, m);
1934	return (0);
1935}
1936
1937/*
1938 * bridge_start:
1939 *
1940 *	Start output on a bridge.
1941 *
1942 */
1943static void
1944bridge_start(struct ifnet *ifp)
1945{
1946	struct bridge_softc *sc;
1947	struct mbuf *m;
1948	struct ether_header *eh;
1949	struct ifnet *dst_if;
1950
1951	sc = ifp->if_softc;
1952
1953	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1954	for (;;) {
1955		IFQ_DEQUEUE(&ifp->if_snd, m);
1956		if (m == 0)
1957			break;
1958		ETHER_BPF_MTAP(ifp, m);
1959
1960		eh = mtod(m, struct ether_header *);
1961		dst_if = NULL;
1962
1963		BRIDGE_LOCK(sc);
1964		if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1965			dst_if = bridge_rtlookup(sc, eh->ether_dhost, 1);
1966		}
1967
1968		if (dst_if == NULL)
1969			bridge_broadcast(sc, ifp, m, 0);
1970		else {
1971			BRIDGE_UNLOCK(sc);
1972			bridge_enqueue(sc, dst_if, m);
1973		}
1974	}
1975	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1976}
1977
1978/*
1979 * bridge_forward:
1980 *
1981 *	The forwarding function of the bridge.
1982 *
1983 *	NOTE: Releases the lock on return.
1984 */
1985static void
1986bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif,
1987    struct mbuf *m)
1988{
1989	struct bridge_iflist *dbif;
1990	struct ifnet *src_if, *dst_if, *ifp;
1991	struct ether_header *eh;
1992	uint16_t vlan;
1993	uint8_t *dst;
1994	int error;
1995
1996	src_if = m->m_pkthdr.rcvif;
1997	ifp = sc->sc_ifp;
1998
1999	ifp->if_ipackets++;
2000	ifp->if_ibytes += m->m_pkthdr.len;
2001	vlan = VLANTAGOF(m);
2002
2003	if ((sbif->bif_flags & IFBIF_STP) &&
2004	    sbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
2005		goto drop;
2006
2007	eh = mtod(m, struct ether_header *);
2008	dst = eh->ether_dhost;
2009
2010	/* If the interface is learning, record the address. */
2011	if (sbif->bif_flags & IFBIF_LEARNING) {
2012		error = bridge_rtupdate(sc, eh->ether_shost, vlan,
2013		    sbif, 0, IFBAF_DYNAMIC);
2014		/*
2015		 * If the interface has addresses limits then deny any source
2016		 * that is not in the cache.
2017		 */
2018		if (error && sbif->bif_addrmax)
2019			goto drop;
2020	}
2021
2022	if ((sbif->bif_flags & IFBIF_STP) != 0 &&
2023	    sbif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING)
2024		goto drop;
2025
2026	/*
2027	 * At this point, the port either doesn't participate
2028	 * in spanning tree or it is in the forwarding state.
2029	 */
2030
2031	/*
2032	 * If the packet is unicast, destined for someone on
2033	 * "this" side of the bridge, drop it.
2034	 */
2035	if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
2036		dst_if = bridge_rtlookup(sc, dst, vlan);
2037		if (src_if == dst_if)
2038			goto drop;
2039	} else {
2040		/*
2041		 * Check if its a reserved multicast address, any address
2042		 * listed in 802.1D section 7.12.6 may not be forwarded by the
2043		 * bridge.
2044		 * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F
2045		 */
2046		if (dst[0] == 0x01 && dst[1] == 0x80 &&
2047		    dst[2] == 0xc2 && dst[3] == 0x00 &&
2048		    dst[4] == 0x00 && dst[5] <= 0x0f)
2049			goto drop;
2050
2051		/* ...forward it to all interfaces. */
2052		ifp->if_imcasts++;
2053		dst_if = NULL;
2054	}
2055
2056	/*
2057	 * If we have a destination interface which is a member of our bridge,
2058	 * OR this is a unicast packet, push it through the bpf(4) machinery.
2059	 * For broadcast or multicast packets, don't bother because it will
2060	 * be reinjected into ether_input. We do this before we pass the packets
2061	 * through the pfil(9) framework, as it is possible that pfil(9) will
2062	 * drop the packet, or possibly modify it, making it difficult to debug
2063	 * firewall issues on the bridge.
2064	 */
2065	if (dst_if != NULL || (m->m_flags & (M_BCAST | M_MCAST)) == 0)
2066		ETHER_BPF_MTAP(ifp, m);
2067
2068	/* run the packet filter */
2069	if (PFIL_HOOKED(&inet_pfil_hook)
2070#ifdef INET6
2071	    || PFIL_HOOKED(&inet6_pfil_hook)
2072#endif
2073	    ) {
2074		BRIDGE_UNLOCK(sc);
2075		if (bridge_pfil(&m, ifp, src_if, PFIL_IN) != 0)
2076			return;
2077		if (m == NULL)
2078			return;
2079		BRIDGE_LOCK(sc);
2080	}
2081
2082	if (dst_if == NULL) {
2083		bridge_broadcast(sc, src_if, m, 1);
2084		return;
2085	}
2086
2087	/*
2088	 * At this point, we're dealing with a unicast frame
2089	 * going to a different interface.
2090	 */
2091	if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
2092		goto drop;
2093
2094	dbif = bridge_lookup_member_if(sc, dst_if);
2095	if (dbif == NULL)
2096		/* Not a member of the bridge (anymore?) */
2097		goto drop;
2098
2099	/* Private segments can not talk to each other */
2100	if (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE)
2101		goto drop;
2102
2103	if ((dbif->bif_flags & IFBIF_STP) &&
2104	    dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
2105		goto drop;
2106
2107	BRIDGE_UNLOCK(sc);
2108
2109	if (PFIL_HOOKED(&inet_pfil_hook)
2110#ifdef INET6
2111	    || PFIL_HOOKED(&inet6_pfil_hook)
2112#endif
2113	    ) {
2114		if (bridge_pfil(&m, ifp, dst_if, PFIL_OUT) != 0)
2115			return;
2116		if (m == NULL)
2117			return;
2118	}
2119
2120	bridge_enqueue(sc, dst_if, m);
2121	return;
2122
2123drop:
2124	BRIDGE_UNLOCK(sc);
2125	m_freem(m);
2126}
2127
2128/*
2129 * bridge_input:
2130 *
2131 *	Receive input from a member interface.  Queue the packet for
2132 *	bridging if it is not for us.
2133 */
2134static struct mbuf *
2135bridge_input(struct ifnet *ifp, struct mbuf *m)
2136{
2137	struct bridge_softc *sc = ifp->if_bridge;
2138	struct bridge_iflist *bif, *bif2;
2139	struct ifnet *bifp;
2140	struct ether_header *eh;
2141	struct mbuf *mc, *mc2;
2142	uint16_t vlan;
2143	int error;
2144
2145	if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
2146		return (m);
2147
2148	bifp = sc->sc_ifp;
2149	vlan = VLANTAGOF(m);
2150
2151	/*
2152	 * Implement support for bridge monitoring. If this flag has been
2153	 * set on this interface, discard the packet once we push it through
2154	 * the bpf(4) machinery, but before we do, increment the byte and
2155	 * packet counters associated with this interface.
2156	 */
2157	if ((bifp->if_flags & IFF_MONITOR) != 0) {
2158		m->m_pkthdr.rcvif  = bifp;
2159		ETHER_BPF_MTAP(bifp, m);
2160		bifp->if_ipackets++;
2161		bifp->if_ibytes += m->m_pkthdr.len;
2162		m_freem(m);
2163		return (NULL);
2164	}
2165	BRIDGE_LOCK(sc);
2166	bif = bridge_lookup_member_if(sc, ifp);
2167	if (bif == NULL) {
2168		BRIDGE_UNLOCK(sc);
2169		return (m);
2170	}
2171
2172	eh = mtod(m, struct ether_header *);
2173
2174	bridge_span(sc, m);
2175
2176	if (m->m_flags & (M_BCAST|M_MCAST)) {
2177		/* Tap off 802.1D packets; they do not get forwarded. */
2178		if (memcmp(eh->ether_dhost, bstp_etheraddr,
2179		    ETHER_ADDR_LEN) == 0) {
2180			m = bstp_input(&bif->bif_stp, ifp, m);
2181			if (m == NULL) {
2182				BRIDGE_UNLOCK(sc);
2183				return (NULL);
2184			}
2185		}
2186
2187		if ((bif->bif_flags & IFBIF_STP) &&
2188		    bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
2189			BRIDGE_UNLOCK(sc);
2190			return (m);
2191		}
2192
2193		/*
2194		 * Make a deep copy of the packet and enqueue the copy
2195		 * for bridge processing; return the original packet for
2196		 * local processing.
2197		 */
2198		mc = m_dup(m, M_DONTWAIT);
2199		if (mc == NULL) {
2200			BRIDGE_UNLOCK(sc);
2201			return (m);
2202		}
2203
2204		/* Perform the bridge forwarding function with the copy. */
2205		bridge_forward(sc, bif, mc);
2206
2207		/*
2208		 * Reinject the mbuf as arriving on the bridge so we have a
2209		 * chance at claiming multicast packets. We can not loop back
2210		 * here from ether_input as a bridge is never a member of a
2211		 * bridge.
2212		 */
2213		KASSERT(bifp->if_bridge == NULL,
2214		    ("loop created in bridge_input"));
2215		mc2 = m_dup(m, M_DONTWAIT);
2216		if (mc2 != NULL) {
2217			/* Keep the layer3 header aligned */
2218			int i = min(mc2->m_pkthdr.len, max_protohdr);
2219			mc2 = m_copyup(mc2, i, ETHER_ALIGN);
2220		}
2221		if (mc2 != NULL) {
2222			mc2->m_pkthdr.rcvif = bifp;
2223			(*bifp->if_input)(bifp, mc2);
2224		}
2225
2226		/* Return the original packet for local processing. */
2227		return (m);
2228	}
2229
2230	if ((bif->bif_flags & IFBIF_STP) &&
2231	    bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
2232		BRIDGE_UNLOCK(sc);
2233		return (m);
2234	}
2235
2236#ifdef DEV_CARP
2237#   define OR_CARP_CHECK_WE_ARE_DST(iface) \
2238	|| ((iface)->if_carp \
2239	    && carp_forus((iface)->if_carp, eh->ether_dhost))
2240#   define OR_CARP_CHECK_WE_ARE_SRC(iface) \
2241	|| ((iface)->if_carp \
2242	    && carp_forus((iface)->if_carp, eh->ether_shost))
2243#else
2244#   define OR_CARP_CHECK_WE_ARE_DST(iface)
2245#   define OR_CARP_CHECK_WE_ARE_SRC(iface)
2246#endif
2247
2248#ifdef INET6
2249#   define OR_PFIL_HOOKED_INET6 \
2250	|| PFIL_HOOKED(&inet6_pfil_hook)
2251#else
2252#   define OR_PFIL_HOOKED_INET6
2253#endif
2254
2255#define GRAB_OUR_PACKETS(iface) \
2256	if ((iface)->if_type == IFT_GIF) \
2257		continue; \
2258	/* It is destined for us. */ \
2259	if (memcmp(IF_LLADDR((iface)), eh->ether_dhost,  ETHER_ADDR_LEN) == 0 \
2260	    OR_CARP_CHECK_WE_ARE_DST((iface))				\
2261	    ) {								\
2262		if ((iface)->if_type == IFT_BRIDGE) {			\
2263			ETHER_BPF_MTAP(iface, m);			\
2264			iface->if_ipackets++;				\
2265			/* Filter on the physical interface. */		\
2266			if (pfil_local_phys &&				\
2267			    (PFIL_HOOKED(&inet_pfil_hook)		\
2268			     OR_PFIL_HOOKED_INET6)) {			\
2269				if (bridge_pfil(&m, NULL, ifp,		\
2270				    PFIL_IN) != 0 || m == NULL) {	\
2271					BRIDGE_UNLOCK(sc);		\
2272					return (NULL);			\
2273				}					\
2274			}						\
2275		}							\
2276		if (bif->bif_flags & IFBIF_LEARNING) {			\
2277			error = bridge_rtupdate(sc, eh->ether_shost,	\
2278			    vlan, bif, 0, IFBAF_DYNAMIC);		\
2279			if (error && bif->bif_addrmax) {		\
2280				BRIDGE_UNLOCK(sc);			\
2281				m_freem(m);				\
2282				return (NULL);				\
2283			}						\
2284		}							\
2285		m->m_pkthdr.rcvif = iface;				\
2286		BRIDGE_UNLOCK(sc);					\
2287		return (m);						\
2288	}								\
2289									\
2290	/* We just received a packet that we sent out. */		\
2291	if (memcmp(IF_LLADDR((iface)), eh->ether_shost, ETHER_ADDR_LEN) == 0 \
2292	    OR_CARP_CHECK_WE_ARE_SRC((iface))			\
2293	    ) {								\
2294		BRIDGE_UNLOCK(sc);					\
2295		m_freem(m);						\
2296		return (NULL);						\
2297	}
2298
2299	/*
2300	 * Unicast.  Make sure it's not for the bridge.
2301	 */
2302	do { GRAB_OUR_PACKETS(bifp) } while (0);
2303
2304	/*
2305	 * Give a chance for ifp at first priority. This will help when	the
2306	 * packet comes through the interface like VLAN's with the same MACs
2307	 * on several interfaces from the same bridge. This also will save
2308	 * some CPU cycles in case the destination interface and the input
2309	 * interface (eq ifp) are the same.
2310	 */
2311	do { GRAB_OUR_PACKETS(ifp) } while (0);
2312
2313	/* Now check the all bridge members. */
2314	LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) {
2315		GRAB_OUR_PACKETS(bif2->bif_ifp)
2316	}
2317
2318#undef OR_CARP_CHECK_WE_ARE_DST
2319#undef OR_CARP_CHECK_WE_ARE_SRC
2320#undef OR_PFIL_HOOKED_INET6
2321#undef GRAB_OUR_PACKETS
2322
2323	/* Perform the bridge forwarding function. */
2324	bridge_forward(sc, bif, m);
2325
2326	return (NULL);
2327}
2328
2329/*
2330 * bridge_broadcast:
2331 *
2332 *	Send a frame to all interfaces that are members of
2333 *	the bridge, except for the one on which the packet
2334 *	arrived.
2335 *
2336 *	NOTE: Releases the lock on return.
2337 */
2338static void
2339bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
2340    struct mbuf *m, int runfilt)
2341{
2342	struct bridge_iflist *dbif, *sbif;
2343	struct mbuf *mc;
2344	struct ifnet *dst_if;
2345	int error = 0, used = 0, i;
2346
2347	sbif = bridge_lookup_member_if(sc, src_if);
2348
2349	BRIDGE_LOCK2REF(sc, error);
2350	if (error) {
2351		m_freem(m);
2352		return;
2353	}
2354
2355	/* Filter on the bridge interface before broadcasting */
2356	if (runfilt && (PFIL_HOOKED(&inet_pfil_hook)
2357#ifdef INET6
2358	    || PFIL_HOOKED(&inet6_pfil_hook)
2359#endif
2360	    )) {
2361		if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0)
2362			goto out;
2363		if (m == NULL)
2364			goto out;
2365	}
2366
2367	LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) {
2368		dst_if = dbif->bif_ifp;
2369		if (dst_if == src_if)
2370			continue;
2371
2372		/* Private segments can not talk to each other */
2373		if (sbif && (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE))
2374			continue;
2375
2376		if ((dbif->bif_flags & IFBIF_STP) &&
2377		    dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
2378			continue;
2379
2380		if ((dbif->bif_flags & IFBIF_DISCOVER) == 0 &&
2381		    (m->m_flags & (M_BCAST|M_MCAST)) == 0)
2382			continue;
2383
2384		if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
2385			continue;
2386
2387		if (LIST_NEXT(dbif, bif_next) == NULL) {
2388			mc = m;
2389			used = 1;
2390		} else {
2391			mc = m_dup(m, M_DONTWAIT);
2392			if (mc == NULL) {
2393				sc->sc_ifp->if_oerrors++;
2394				continue;
2395			}
2396		}
2397
2398		/*
2399		 * Filter on the output interface. Pass a NULL bridge interface
2400		 * pointer so we do not redundantly filter on the bridge for
2401		 * each interface we broadcast on.
2402		 */
2403		if (runfilt && (PFIL_HOOKED(&inet_pfil_hook)
2404#ifdef INET6
2405		    || PFIL_HOOKED(&inet6_pfil_hook)
2406#endif
2407		    )) {
2408			if (used == 0) {
2409				/* Keep the layer3 header aligned */
2410				i = min(mc->m_pkthdr.len, max_protohdr);
2411				mc = m_copyup(mc, i, ETHER_ALIGN);
2412				if (mc == NULL) {
2413					sc->sc_ifp->if_oerrors++;
2414					continue;
2415				}
2416			}
2417			if (bridge_pfil(&mc, NULL, dst_if, PFIL_OUT) != 0)
2418				continue;
2419			if (mc == NULL)
2420				continue;
2421		}
2422
2423		bridge_enqueue(sc, dst_if, mc);
2424	}
2425	if (used == 0)
2426		m_freem(m);
2427
2428out:
2429	BRIDGE_UNREF(sc);
2430}
2431
2432/*
2433 * bridge_span:
2434 *
2435 *	Duplicate a packet out one or more interfaces that are in span mode,
2436 *	the original mbuf is unmodified.
2437 */
2438static void
2439bridge_span(struct bridge_softc *sc, struct mbuf *m)
2440{
2441	struct bridge_iflist *bif;
2442	struct ifnet *dst_if;
2443	struct mbuf *mc;
2444
2445	if (LIST_EMPTY(&sc->sc_spanlist))
2446		return;
2447
2448	LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
2449		dst_if = bif->bif_ifp;
2450
2451		if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
2452			continue;
2453
2454		mc = m_copypacket(m, M_DONTWAIT);
2455		if (mc == NULL) {
2456			sc->sc_ifp->if_oerrors++;
2457			continue;
2458		}
2459
2460		bridge_enqueue(sc, dst_if, mc);
2461	}
2462}
2463
2464/*
2465 * bridge_rtupdate:
2466 *
2467 *	Add a bridge routing entry.
2468 */
2469static int
2470bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, uint16_t vlan,
2471    struct bridge_iflist *bif, int setflags, uint8_t flags)
2472{
2473	struct bridge_rtnode *brt;
2474	int error;
2475
2476	BRIDGE_LOCK_ASSERT(sc);
2477
2478	/* Check the source address is valid and not multicast. */
2479	if (ETHER_IS_MULTICAST(dst) ||
2480	    (dst[0] == 0 && dst[1] == 0 && dst[2] == 0 &&
2481	     dst[3] == 0 && dst[4] == 0 && dst[5] == 0) != 0)
2482		return (EINVAL);
2483
2484	/* 802.1p frames map to vlan 1 */
2485	if (vlan == 0)
2486		vlan = 1;
2487
2488	/*
2489	 * A route for this destination might already exist.  If so,
2490	 * update it, otherwise create a new one.
2491	 */
2492	if ((brt = bridge_rtnode_lookup(sc, dst, vlan)) == NULL) {
2493		if (sc->sc_brtcnt >= sc->sc_brtmax) {
2494			sc->sc_brtexceeded++;
2495			return (ENOSPC);
2496		}
2497		/* Check per interface address limits (if enabled) */
2498		if (bif->bif_addrmax && bif->bif_addrcnt >= bif->bif_addrmax) {
2499			bif->bif_addrexceeded++;
2500			return (ENOSPC);
2501		}
2502
2503		/*
2504		 * Allocate a new bridge forwarding node, and
2505		 * initialize the expiration time and Ethernet
2506		 * address.
2507		 */
2508		brt = uma_zalloc(bridge_rtnode_zone, M_NOWAIT | M_ZERO);
2509		if (brt == NULL)
2510			return (ENOMEM);
2511
2512		if (bif->bif_flags & IFBIF_STICKY)
2513			brt->brt_flags = IFBAF_STICKY;
2514		else
2515			brt->brt_flags = IFBAF_DYNAMIC;
2516
2517		memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
2518		brt->brt_vlan = vlan;
2519
2520		if ((error = bridge_rtnode_insert(sc, brt)) != 0) {
2521			uma_zfree(bridge_rtnode_zone, brt);
2522			return (error);
2523		}
2524		brt->brt_dst = bif;
2525		bif->bif_addrcnt++;
2526	}
2527
2528	if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
2529	    brt->brt_dst != bif) {
2530		brt->brt_dst->bif_addrcnt--;
2531		brt->brt_dst = bif;
2532		brt->brt_dst->bif_addrcnt++;
2533	}
2534
2535	if ((flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2536		brt->brt_expire = time_uptime + sc->sc_brttimeout;
2537	if (setflags)
2538		brt->brt_flags = flags;
2539
2540	return (0);
2541}
2542
2543/*
2544 * bridge_rtlookup:
2545 *
2546 *	Lookup the destination interface for an address.
2547 */
2548static struct ifnet *
2549bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan)
2550{
2551	struct bridge_rtnode *brt;
2552
2553	BRIDGE_LOCK_ASSERT(sc);
2554
2555	if ((brt = bridge_rtnode_lookup(sc, addr, vlan)) == NULL)
2556		return (NULL);
2557
2558	return (brt->brt_ifp);
2559}
2560
2561/*
2562 * bridge_rttrim:
2563 *
2564 *	Trim the routine table so that we have a number
2565 *	of routing entries less than or equal to the
2566 *	maximum number.
2567 */
2568static void
2569bridge_rttrim(struct bridge_softc *sc)
2570{
2571	struct bridge_rtnode *brt, *nbrt;
2572
2573	BRIDGE_LOCK_ASSERT(sc);
2574
2575	/* Make sure we actually need to do this. */
2576	if (sc->sc_brtcnt <= sc->sc_brtmax)
2577		return;
2578
2579	/* Force an aging cycle; this might trim enough addresses. */
2580	bridge_rtage(sc);
2581	if (sc->sc_brtcnt <= sc->sc_brtmax)
2582		return;
2583
2584	LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2585		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2586			bridge_rtnode_destroy(sc, brt);
2587			if (sc->sc_brtcnt <= sc->sc_brtmax)
2588				return;
2589		}
2590	}
2591}
2592
2593/*
2594 * bridge_timer:
2595 *
2596 *	Aging timer for the bridge.
2597 */
2598static void
2599bridge_timer(void *arg)
2600{
2601	struct bridge_softc *sc = arg;
2602
2603	BRIDGE_LOCK_ASSERT(sc);
2604
2605	bridge_rtage(sc);
2606
2607	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
2608		callout_reset(&sc->sc_brcallout,
2609		    bridge_rtable_prune_period * hz, bridge_timer, sc);
2610}
2611
2612/*
2613 * bridge_rtage:
2614 *
2615 *	Perform an aging cycle.
2616 */
2617static void
2618bridge_rtage(struct bridge_softc *sc)
2619{
2620	struct bridge_rtnode *brt, *nbrt;
2621
2622	BRIDGE_LOCK_ASSERT(sc);
2623
2624	LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2625		if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2626			if (time_uptime >= brt->brt_expire)
2627				bridge_rtnode_destroy(sc, brt);
2628		}
2629	}
2630}
2631
2632/*
2633 * bridge_rtflush:
2634 *
2635 *	Remove all dynamic addresses from the bridge.
2636 */
2637static void
2638bridge_rtflush(struct bridge_softc *sc, int full)
2639{
2640	struct bridge_rtnode *brt, *nbrt;
2641
2642	BRIDGE_LOCK_ASSERT(sc);
2643
2644	LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2645		if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2646			bridge_rtnode_destroy(sc, brt);
2647	}
2648}
2649
2650/*
2651 * bridge_rtdaddr:
2652 *
2653 *	Remove an address from the table.
2654 */
2655static int
2656bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan)
2657{
2658	struct bridge_rtnode *brt;
2659	int found = 0;
2660
2661	BRIDGE_LOCK_ASSERT(sc);
2662
2663	/*
2664	 * If vlan is zero then we want to delete for all vlans so the lookup
2665	 * may return more than one.
2666	 */
2667	while ((brt = bridge_rtnode_lookup(sc, addr, vlan)) != NULL) {
2668		bridge_rtnode_destroy(sc, brt);
2669		found = 1;
2670	}
2671
2672	return (found ? 0 : ENOENT);
2673}
2674
2675/*
2676 * bridge_rtdelete:
2677 *
2678 *	Delete routes to a speicifc member interface.
2679 */
2680static void
2681bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
2682{
2683	struct bridge_rtnode *brt, *nbrt;
2684
2685	BRIDGE_LOCK_ASSERT(sc);
2686
2687	LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2688		if (brt->brt_ifp == ifp && (full ||
2689			    (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
2690			bridge_rtnode_destroy(sc, brt);
2691	}
2692}
2693
2694/*
2695 * bridge_rtable_init:
2696 *
2697 *	Initialize the route table for this bridge.
2698 */
2699static int
2700bridge_rtable_init(struct bridge_softc *sc)
2701{
2702	int i;
2703
2704	sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
2705	    M_DEVBUF, M_NOWAIT);
2706	if (sc->sc_rthash == NULL)
2707		return (ENOMEM);
2708
2709	for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
2710		LIST_INIT(&sc->sc_rthash[i]);
2711
2712	sc->sc_rthash_key = arc4random();
2713
2714	LIST_INIT(&sc->sc_rtlist);
2715
2716	return (0);
2717}
2718
2719/*
2720 * bridge_rtable_fini:
2721 *
2722 *	Deconstruct the route table for this bridge.
2723 */
2724static void
2725bridge_rtable_fini(struct bridge_softc *sc)
2726{
2727
2728	KASSERT(sc->sc_brtcnt == 0,
2729	    ("%s: %d bridge routes referenced", __func__, sc->sc_brtcnt));
2730	free(sc->sc_rthash, M_DEVBUF);
2731}
2732
2733/*
2734 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2735 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2736 */
2737#define	mix(a, b, c)							\
2738do {									\
2739	a -= b; a -= c; a ^= (c >> 13);					\
2740	b -= c; b -= a; b ^= (a << 8);					\
2741	c -= a; c -= b; c ^= (b >> 13);					\
2742	a -= b; a -= c; a ^= (c >> 12);					\
2743	b -= c; b -= a; b ^= (a << 16);					\
2744	c -= a; c -= b; c ^= (b >> 5);					\
2745	a -= b; a -= c; a ^= (c >> 3);					\
2746	b -= c; b -= a; b ^= (a << 10);					\
2747	c -= a; c -= b; c ^= (b >> 15);					\
2748} while (/*CONSTCOND*/0)
2749
2750static __inline uint32_t
2751bridge_rthash(struct bridge_softc *sc, const uint8_t *addr)
2752{
2753	uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key;
2754
2755	b += addr[5] << 8;
2756	b += addr[4];
2757	a += addr[3] << 24;
2758	a += addr[2] << 16;
2759	a += addr[1] << 8;
2760	a += addr[0];
2761
2762	mix(a, b, c);
2763
2764	return (c & BRIDGE_RTHASH_MASK);
2765}
2766
2767#undef mix
2768
2769static int
2770bridge_rtnode_addr_cmp(const uint8_t *a, const uint8_t *b)
2771{
2772	int i, d;
2773
2774	for (i = 0, d = 0; i < ETHER_ADDR_LEN && d == 0; i++) {
2775		d = ((int)a[i]) - ((int)b[i]);
2776	}
2777
2778	return (d);
2779}
2780
2781/*
2782 * bridge_rtnode_lookup:
2783 *
2784 *	Look up a bridge route node for the specified destination. Compare the
2785 *	vlan id or if zero then just return the first match.
2786 */
2787static struct bridge_rtnode *
2788bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan)
2789{
2790	struct bridge_rtnode *brt;
2791	uint32_t hash;
2792	int dir;
2793
2794	BRIDGE_LOCK_ASSERT(sc);
2795
2796	hash = bridge_rthash(sc, addr);
2797	LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
2798		dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr);
2799		if (dir == 0 && (brt->brt_vlan == vlan || vlan == 0))
2800			return (brt);
2801		if (dir > 0)
2802			return (NULL);
2803	}
2804
2805	return (NULL);
2806}
2807
2808/*
2809 * bridge_rtnode_insert:
2810 *
2811 *	Insert the specified bridge node into the route table.  We
2812 *	assume the entry is not already in the table.
2813 */
2814static int
2815bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
2816{
2817	struct bridge_rtnode *lbrt;
2818	uint32_t hash;
2819	int dir;
2820
2821	BRIDGE_LOCK_ASSERT(sc);
2822
2823	hash = bridge_rthash(sc, brt->brt_addr);
2824
2825	lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
2826	if (lbrt == NULL) {
2827		LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
2828		goto out;
2829	}
2830
2831	do {
2832		dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr);
2833		if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan)
2834			return (EEXIST);
2835		if (dir > 0) {
2836			LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
2837			goto out;
2838		}
2839		if (LIST_NEXT(lbrt, brt_hash) == NULL) {
2840			LIST_INSERT_AFTER(lbrt, brt, brt_hash);
2841			goto out;
2842		}
2843		lbrt = LIST_NEXT(lbrt, brt_hash);
2844	} while (lbrt != NULL);
2845
2846#ifdef DIAGNOSTIC
2847	panic("bridge_rtnode_insert: impossible");
2848#endif
2849
2850out:
2851	LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
2852	sc->sc_brtcnt++;
2853
2854	return (0);
2855}
2856
2857/*
2858 * bridge_rtnode_destroy:
2859 *
2860 *	Destroy a bridge rtnode.
2861 */
2862static void
2863bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
2864{
2865	BRIDGE_LOCK_ASSERT(sc);
2866
2867	LIST_REMOVE(brt, brt_hash);
2868
2869	LIST_REMOVE(brt, brt_list);
2870	sc->sc_brtcnt--;
2871	brt->brt_dst->bif_addrcnt--;
2872	uma_zfree(bridge_rtnode_zone, brt);
2873}
2874
2875/*
2876 * bridge_rtable_expire:
2877 *
2878 *	Set the expiry time for all routes on an interface.
2879 */
2880static void
2881bridge_rtable_expire(struct ifnet *ifp, int age)
2882{
2883	struct bridge_softc *sc = ifp->if_bridge;
2884	struct bridge_rtnode *brt;
2885
2886	BRIDGE_LOCK(sc);
2887
2888	/*
2889	 * If the age is zero then flush, otherwise set all the expiry times to
2890	 * age for the interface
2891	 */
2892	if (age == 0)
2893		bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
2894	else {
2895		LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
2896			/* Cap the expiry time to 'age' */
2897			if (brt->brt_ifp == ifp &&
2898			    brt->brt_expire > time_uptime + age &&
2899			    (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2900				brt->brt_expire = time_uptime + age;
2901		}
2902	}
2903	BRIDGE_UNLOCK(sc);
2904}
2905
2906/*
2907 * bridge_state_change:
2908 *
2909 *	Callback from the bridgestp code when a port changes states.
2910 */
2911static void
2912bridge_state_change(struct ifnet *ifp, int state)
2913{
2914	struct bridge_softc *sc = ifp->if_bridge;
2915	static const char *stpstates[] = {
2916		"disabled",
2917		"listening",
2918		"learning",
2919		"forwarding",
2920		"blocking",
2921		"discarding"
2922	};
2923
2924	if (log_stp)
2925		log(LOG_NOTICE, "%s: state changed to %s on %s\n",
2926		    sc->sc_ifp->if_xname, stpstates[state], ifp->if_xname);
2927}
2928
2929/*
2930 * Send bridge packets through pfil if they are one of the types pfil can deal
2931 * with, or if they are ARP or REVARP.  (pfil will pass ARP and REVARP without
2932 * question.) If *bifp or *ifp are NULL then packet filtering is skipped for
2933 * that interface.
2934 */
2935static int
2936bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
2937{
2938	int snap, error, i, hlen;
2939	struct ether_header *eh1, eh2;
2940	struct ip_fw_args args;
2941	struct ip *ip;
2942	struct llc llc1;
2943	u_int16_t ether_type;
2944
2945	snap = 0;
2946	error = -1;	/* Default error if not error == 0 */
2947
2948#if 0
2949	/* we may return with the IP fields swapped, ensure its not shared */
2950	KASSERT(M_WRITABLE(*mp), ("%s: modifying a shared mbuf", __func__));
2951#endif
2952
2953	if (pfil_bridge == 0 && pfil_member == 0 && pfil_ipfw == 0)
2954		return (0); /* filtering is disabled */
2955
2956	i = min((*mp)->m_pkthdr.len, max_protohdr);
2957	if ((*mp)->m_len < i) {
2958	    *mp = m_pullup(*mp, i);
2959	    if (*mp == NULL) {
2960		printf("%s: m_pullup failed\n", __func__);
2961		return (-1);
2962	    }
2963	}
2964
2965	eh1 = mtod(*mp, struct ether_header *);
2966	ether_type = ntohs(eh1->ether_type);
2967
2968	/*
2969	 * Check for SNAP/LLC.
2970	 */
2971	if (ether_type < ETHERMTU) {
2972		struct llc *llc2 = (struct llc *)(eh1 + 1);
2973
2974		if ((*mp)->m_len >= ETHER_HDR_LEN + 8 &&
2975		    llc2->llc_dsap == LLC_SNAP_LSAP &&
2976		    llc2->llc_ssap == LLC_SNAP_LSAP &&
2977		    llc2->llc_control == LLC_UI) {
2978			ether_type = htons(llc2->llc_un.type_snap.ether_type);
2979			snap = 1;
2980		}
2981	}
2982
2983	/*
2984	 * If we're trying to filter bridge traffic, don't look at anything
2985	 * other than IP and ARP traffic.  If the filter doesn't understand
2986	 * IPv6, don't allow IPv6 through the bridge either.  This is lame
2987	 * since if we really wanted, say, an AppleTalk filter, we are hosed,
2988	 * but of course we don't have an AppleTalk filter to begin with.
2989	 * (Note that since pfil doesn't understand ARP it will pass *ALL*
2990	 * ARP traffic.)
2991	 */
2992	switch (ether_type) {
2993		case ETHERTYPE_ARP:
2994		case ETHERTYPE_REVARP:
2995			if (pfil_ipfw_arp == 0)
2996				return (0); /* Automatically pass */
2997			break;
2998
2999		case ETHERTYPE_IP:
3000#ifdef INET6
3001		case ETHERTYPE_IPV6:
3002#endif /* INET6 */
3003			break;
3004		default:
3005			/*
3006			 * Check to see if the user wants to pass non-ip
3007			 * packets, these will not be checked by pfil(9) and
3008			 * passed unconditionally so the default is to drop.
3009			 */
3010			if (pfil_onlyip)
3011				goto bad;
3012	}
3013
3014	/* Strip off the Ethernet header and keep a copy. */
3015	m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2);
3016	m_adj(*mp, ETHER_HDR_LEN);
3017
3018	/* Strip off snap header, if present */
3019	if (snap) {
3020		m_copydata(*mp, 0, sizeof(struct llc), (caddr_t) &llc1);
3021		m_adj(*mp, sizeof(struct llc));
3022	}
3023
3024	/*
3025	 * Check the IP header for alignment and errors
3026	 */
3027	if (dir == PFIL_IN) {
3028		switch (ether_type) {
3029			case ETHERTYPE_IP:
3030				error = bridge_ip_checkbasic(mp);
3031				break;
3032#ifdef INET6
3033			case ETHERTYPE_IPV6:
3034				error = bridge_ip6_checkbasic(mp);
3035				break;
3036#endif /* INET6 */
3037			default:
3038				error = 0;
3039		}
3040		if (error)
3041			goto bad;
3042	}
3043
3044	if (IPFW_LOADED && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
3045		INIT_VNET_INET(curvnet);
3046
3047		error = -1;
3048		args.rule = ip_dn_claim_rule(*mp);
3049		if (args.rule != NULL && V_fw_one_pass)
3050			goto ipfwpass; /* packet already partially processed */
3051
3052		args.m = *mp;
3053		args.oif = ifp;
3054		args.next_hop = NULL;
3055		args.eh = &eh2;
3056		args.inp = NULL;	/* used by ipfw uid/gid/jail rules */
3057		i = ip_fw_chk_ptr(&args);
3058		*mp = args.m;
3059
3060		if (*mp == NULL)
3061			return (error);
3062
3063		if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) {
3064
3065			/* put the Ethernet header back on */
3066			M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
3067			if (*mp == NULL)
3068				return (error);
3069			bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
3070
3071			/*
3072			 * Pass the pkt to dummynet, which consumes it. The
3073			 * packet will return to us via bridge_dummynet().
3074			 */
3075			args.oif = ifp;
3076			ip_dn_io_ptr(mp, DN_TO_IFB_FWD, &args);
3077			return (error);
3078		}
3079
3080		if (i != IP_FW_PASS) /* drop */
3081			goto bad;
3082	}
3083
3084ipfwpass:
3085	error = 0;
3086
3087	/*
3088	 * Run the packet through pfil
3089	 */
3090	switch (ether_type) {
3091	case ETHERTYPE_IP:
3092		/*
3093		 * before calling the firewall, swap fields the same as
3094		 * IP does. here we assume the header is contiguous
3095		 */
3096		ip = mtod(*mp, struct ip *);
3097
3098		ip->ip_len = ntohs(ip->ip_len);
3099		ip->ip_off = ntohs(ip->ip_off);
3100
3101		/*
3102		 * Run pfil on the member interface and the bridge, both can
3103		 * be skipped by clearing pfil_member or pfil_bridge.
3104		 *
3105		 * Keep the order:
3106		 *   in_if -> bridge_if -> out_if
3107		 */
3108		if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
3109			error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
3110					dir, NULL);
3111
3112		if (*mp == NULL || error != 0) /* filter may consume */
3113			break;
3114
3115		if (pfil_member && ifp != NULL)
3116			error = pfil_run_hooks(&inet_pfil_hook, mp, ifp,
3117					dir, NULL);
3118
3119		if (*mp == NULL || error != 0) /* filter may consume */
3120			break;
3121
3122		if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
3123			error = pfil_run_hooks(&inet_pfil_hook, mp, bifp,
3124					dir, NULL);
3125
3126		if (*mp == NULL || error != 0) /* filter may consume */
3127			break;
3128
3129		/* check if we need to fragment the packet */
3130		if (pfil_member && ifp != NULL && dir == PFIL_OUT) {
3131			i = (*mp)->m_pkthdr.len;
3132			if (i > ifp->if_mtu) {
3133				error = bridge_fragment(ifp, *mp, &eh2, snap,
3134					    &llc1);
3135				return (error);
3136			}
3137		}
3138
3139		/* Recalculate the ip checksum and restore byte ordering */
3140		ip = mtod(*mp, struct ip *);
3141		hlen = ip->ip_hl << 2;
3142		if (hlen < sizeof(struct ip))
3143			goto bad;
3144		if (hlen > (*mp)->m_len) {
3145			if ((*mp = m_pullup(*mp, hlen)) == 0)
3146				goto bad;
3147			ip = mtod(*mp, struct ip *);
3148			if (ip == NULL)
3149				goto bad;
3150		}
3151		ip->ip_len = htons(ip->ip_len);
3152		ip->ip_off = htons(ip->ip_off);
3153		ip->ip_sum = 0;
3154		if (hlen == sizeof(struct ip))
3155			ip->ip_sum = in_cksum_hdr(ip);
3156		else
3157			ip->ip_sum = in_cksum(*mp, hlen);
3158
3159		break;
3160#ifdef INET6
3161	case ETHERTYPE_IPV6:
3162		if (pfil_bridge && dir == PFIL_OUT && bifp != NULL)
3163			error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
3164					dir, NULL);
3165
3166		if (*mp == NULL || error != 0) /* filter may consume */
3167			break;
3168
3169		if (pfil_member && ifp != NULL)
3170			error = pfil_run_hooks(&inet6_pfil_hook, mp, ifp,
3171					dir, NULL);
3172
3173		if (*mp == NULL || error != 0) /* filter may consume */
3174			break;
3175
3176		if (pfil_bridge && dir == PFIL_IN && bifp != NULL)
3177			error = pfil_run_hooks(&inet6_pfil_hook, mp, bifp,
3178					dir, NULL);
3179		break;
3180#endif
3181	default:
3182		error = 0;
3183		break;
3184	}
3185
3186	if (*mp == NULL)
3187		return (error);
3188	if (error != 0)
3189		goto bad;
3190
3191	error = -1;
3192
3193	/*
3194	 * Finally, put everything back the way it was and return
3195	 */
3196	if (snap) {
3197		M_PREPEND(*mp, sizeof(struct llc), M_DONTWAIT);
3198		if (*mp == NULL)
3199			return (error);
3200		bcopy(&llc1, mtod(*mp, caddr_t), sizeof(struct llc));
3201	}
3202
3203	M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT);
3204	if (*mp == NULL)
3205		return (error);
3206	bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN);
3207
3208	return (0);
3209
3210bad:
3211	m_freem(*mp);
3212	*mp = NULL;
3213	return (error);
3214}
3215
3216/*
3217 * Perform basic checks on header size since
3218 * pfil assumes ip_input has already processed
3219 * it for it.  Cut-and-pasted from ip_input.c.
3220 * Given how simple the IPv6 version is,
3221 * does the IPv4 version really need to be
3222 * this complicated?
3223 *
3224 * XXX Should we update ipstat here, or not?
3225 * XXX Right now we update ipstat but not
3226 * XXX csum_counter.
3227 */
3228static int
3229bridge_ip_checkbasic(struct mbuf **mp)
3230{
3231	INIT_VNET_INET(curvnet);
3232	struct mbuf *m = *mp;
3233	struct ip *ip;
3234	int len, hlen;
3235	u_short sum;
3236
3237	if (*mp == NULL)
3238		return (-1);
3239
3240	if (IP_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
3241		if ((m = m_copyup(m, sizeof(struct ip),
3242			(max_linkhdr + 3) & ~3)) == NULL) {
3243			/* XXXJRT new stat, please */
3244			V_ipstat.ips_toosmall++;
3245			goto bad;
3246		}
3247	} else if (__predict_false(m->m_len < sizeof (struct ip))) {
3248		if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
3249			V_ipstat.ips_toosmall++;
3250			goto bad;
3251		}
3252	}
3253	ip = mtod(m, struct ip *);
3254	if (ip == NULL) goto bad;
3255
3256	if (ip->ip_v != IPVERSION) {
3257		V_ipstat.ips_badvers++;
3258		goto bad;
3259	}
3260	hlen = ip->ip_hl << 2;
3261	if (hlen < sizeof(struct ip)) { /* minimum header length */
3262		V_ipstat.ips_badhlen++;
3263		goto bad;
3264	}
3265	if (hlen > m->m_len) {
3266		if ((m = m_pullup(m, hlen)) == 0) {
3267			V_ipstat.ips_badhlen++;
3268			goto bad;
3269		}
3270		ip = mtod(m, struct ip *);
3271		if (ip == NULL) goto bad;
3272	}
3273
3274	if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) {
3275		sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
3276	} else {
3277		if (hlen == sizeof(struct ip)) {
3278			sum = in_cksum_hdr(ip);
3279		} else {
3280			sum = in_cksum(m, hlen);
3281		}
3282	}
3283	if (sum) {
3284		V_ipstat.ips_badsum++;
3285		goto bad;
3286	}
3287
3288	/* Retrieve the packet length. */
3289	len = ntohs(ip->ip_len);
3290
3291	/*
3292	 * Check for additional length bogosity
3293	 */
3294	if (len < hlen) {
3295		V_ipstat.ips_badlen++;
3296		goto bad;
3297	}
3298
3299	/*
3300	 * Check that the amount of data in the buffers
3301	 * is as at least much as the IP header would have us expect.
3302	 * Drop packet if shorter than we expect.
3303	 */
3304	if (m->m_pkthdr.len < len) {
3305		V_ipstat.ips_tooshort++;
3306		goto bad;
3307	}
3308
3309	/* Checks out, proceed */
3310	*mp = m;
3311	return (0);
3312
3313bad:
3314	*mp = m;
3315	return (-1);
3316}
3317
3318#ifdef INET6
3319/*
3320 * Same as above, but for IPv6.
3321 * Cut-and-pasted from ip6_input.c.
3322 * XXX Should we update ip6stat, or not?
3323 */
3324static int
3325bridge_ip6_checkbasic(struct mbuf **mp)
3326{
3327	INIT_VNET_INET6(curvnet);
3328	struct mbuf *m = *mp;
3329	struct ip6_hdr *ip6;
3330
3331	/*
3332	 * If the IPv6 header is not aligned, slurp it up into a new
3333	 * mbuf with space for link headers, in the event we forward
3334	 * it.  Otherwise, if it is aligned, make sure the entire base
3335	 * IPv6 header is in the first mbuf of the chain.
3336	 */
3337	if (IP6_HDR_ALIGNED_P(mtod(m, caddr_t)) == 0) {
3338		struct ifnet *inifp = m->m_pkthdr.rcvif;
3339		if ((m = m_copyup(m, sizeof(struct ip6_hdr),
3340			    (max_linkhdr + 3) & ~3)) == NULL) {
3341			/* XXXJRT new stat, please */
3342			V_ip6stat.ip6s_toosmall++;
3343			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
3344			goto bad;
3345		}
3346	} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
3347		struct ifnet *inifp = m->m_pkthdr.rcvif;
3348		if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
3349			V_ip6stat.ip6s_toosmall++;
3350			in6_ifstat_inc(inifp, ifs6_in_hdrerr);
3351			goto bad;
3352		}
3353	}
3354
3355	ip6 = mtod(m, struct ip6_hdr *);
3356
3357	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
3358		V_ip6stat.ip6s_badvers++;
3359		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
3360		goto bad;
3361	}
3362
3363	/* Checks out, proceed */
3364	*mp = m;
3365	return (0);
3366
3367bad:
3368	*mp = m;
3369	return (-1);
3370}
3371#endif /* INET6 */
3372
3373/*
3374 * bridge_fragment:
3375 *
3376 *	Return a fragmented mbuf chain.
3377 */
3378static int
3379bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
3380    int snap, struct llc *llc)
3381{
3382	INIT_VNET_INET(curvnet);
3383	struct mbuf *m0;
3384	struct ip *ip;
3385	int error = -1;
3386
3387	if (m->m_len < sizeof(struct ip) &&
3388	    (m = m_pullup(m, sizeof(struct ip))) == NULL)
3389		goto out;
3390	ip = mtod(m, struct ip *);
3391
3392	error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist,
3393		    CSUM_DELAY_IP);
3394	if (error)
3395		goto out;
3396
3397	/* walk the chain and re-add the Ethernet header */
3398	for (m0 = m; m0; m0 = m0->m_nextpkt) {
3399		if (error == 0) {
3400			if (snap) {
3401				M_PREPEND(m0, sizeof(struct llc), M_DONTWAIT);
3402				if (m0 == NULL) {
3403					error = ENOBUFS;
3404					continue;
3405				}
3406				bcopy(llc, mtod(m0, caddr_t),
3407				    sizeof(struct llc));
3408			}
3409			M_PREPEND(m0, ETHER_HDR_LEN, M_DONTWAIT);
3410			if (m0 == NULL) {
3411				error = ENOBUFS;
3412				continue;
3413			}
3414			bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN);
3415		} else
3416			m_freem(m);
3417	}
3418
3419	if (error == 0)
3420		V_ipstat.ips_fragmented++;
3421
3422	return (error);
3423
3424out:
3425	if (m != NULL)
3426		m_freem(m);
3427	return (error);
3428}
3429