1*4eaa4710SRishi Srivatsavai /*
2*4eaa4710SRishi Srivatsavai  * CDDL HEADER START
3*4eaa4710SRishi Srivatsavai  *
4*4eaa4710SRishi Srivatsavai  * The contents of this file are subject to the terms of the
5*4eaa4710SRishi Srivatsavai  * Common Development and Distribution License (the "License").
6*4eaa4710SRishi Srivatsavai  * You may not use this file except in compliance with the License.
7*4eaa4710SRishi Srivatsavai  *
8*4eaa4710SRishi Srivatsavai  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4eaa4710SRishi Srivatsavai  * or http://www.opensolaris.org/os/licensing.
10*4eaa4710SRishi Srivatsavai  * See the License for the specific language governing permissions
11*4eaa4710SRishi Srivatsavai  * and limitations under the License.
12*4eaa4710SRishi Srivatsavai  *
13*4eaa4710SRishi Srivatsavai  * When distributing Covered Code, include this CDDL HEADER in each
14*4eaa4710SRishi Srivatsavai  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4eaa4710SRishi Srivatsavai  * If applicable, add the following below this CDDL HEADER, with the
16*4eaa4710SRishi Srivatsavai  * fields enclosed by brackets "[]" replaced with your own identifying
17*4eaa4710SRishi Srivatsavai  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4eaa4710SRishi Srivatsavai  *
19*4eaa4710SRishi Srivatsavai  * CDDL HEADER END
20*4eaa4710SRishi Srivatsavai  */
21*4eaa4710SRishi Srivatsavai 
22*4eaa4710SRishi Srivatsavai /*
23*4eaa4710SRishi Srivatsavai  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*4eaa4710SRishi Srivatsavai  * Use is subject to license terms.
25*4eaa4710SRishi Srivatsavai  */
26*4eaa4710SRishi Srivatsavai 
27*4eaa4710SRishi Srivatsavai #ifndef _BRIDGE_IMPL_H
28*4eaa4710SRishi Srivatsavai #define	_BRIDGE_IMPL_H
29*4eaa4710SRishi Srivatsavai 
30*4eaa4710SRishi Srivatsavai /*
31*4eaa4710SRishi Srivatsavai  * These are the internal data structures used by the layer-two (Ethernet)
32*4eaa4710SRishi Srivatsavai  * bridging module.
33*4eaa4710SRishi Srivatsavai  */
34*4eaa4710SRishi Srivatsavai 
35*4eaa4710SRishi Srivatsavai #ifdef __cplusplus
36*4eaa4710SRishi Srivatsavai extern "C" {
37*4eaa4710SRishi Srivatsavai #endif
38*4eaa4710SRishi Srivatsavai 
39*4eaa4710SRishi Srivatsavai #include <sys/list.h>
40*4eaa4710SRishi Srivatsavai #include <sys/sysmacros.h>
41*4eaa4710SRishi Srivatsavai #include <sys/avl.h>
42*4eaa4710SRishi Srivatsavai #include <sys/queue.h>
43*4eaa4710SRishi Srivatsavai #include <sys/kstat.h>
44*4eaa4710SRishi Srivatsavai #include <sys/ksynch.h>
45*4eaa4710SRishi Srivatsavai #include <sys/ethernet.h>
46*4eaa4710SRishi Srivatsavai #include <sys/dld.h>
47*4eaa4710SRishi Srivatsavai #include <sys/mac.h>
48*4eaa4710SRishi Srivatsavai #include <sys/mac_client.h>
49*4eaa4710SRishi Srivatsavai #include <sys/vlan.h>
50*4eaa4710SRishi Srivatsavai #include <net/bridge.h>
51*4eaa4710SRishi Srivatsavai 
52*4eaa4710SRishi Srivatsavai #define	KSINST_NAMES	"recv", "sent", "drops", \
53*4eaa4710SRishi Srivatsavai 	"forward_direct", "forward_unknown", "forward_mbcast",	\
54*4eaa4710SRishi Srivatsavai 	"learn_source", "learn_moved", "learn_expire", "learn_size"
55*4eaa4710SRishi Srivatsavai typedef struct bridge_ksinst_s {
56*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_recv;	/* packets received */
57*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_sent;	/* packets sent through */
58*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_drops;	/* packets dropped (untowardly) */
59*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_forwards;	/* packets forwarded */
60*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_unknown;	/* packets forwarded (unknown dest) */
61*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_mbcast;	/* packets forwarded (multi/bcast) */
62*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_source;	/* source addresses learned */
63*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_moved;	/* source addresses moved */
64*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_expire;	/* source addresses expired */
65*4eaa4710SRishi Srivatsavai 	kstat_named_t	bki_count;	/* source addresses known */
66*4eaa4710SRishi Srivatsavai } bridge_ksinst_t;
67*4eaa4710SRishi Srivatsavai 
68*4eaa4710SRishi Srivatsavai #define	KSLINK_NAMES	"recv", "xmit", "drops"
69*4eaa4710SRishi Srivatsavai typedef struct bridge_kslink_s {
70*4eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_recv;	/* packets received */
71*4eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_xmit;	/* packets transmitted */
72*4eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_drops;	/* packets dropped */
73*4eaa4710SRishi Srivatsavai } bridge_kslink_t;
74*4eaa4710SRishi Srivatsavai 
75*4eaa4710SRishi Srivatsavai /*
76*4eaa4710SRishi Srivatsavai  * There's one instance structure and one observability mac node for each
77*4eaa4710SRishi Srivatsavai  * bridge.  Each open non-DLPI stream gets a 'stream' structure; these are used
78*4eaa4710SRishi Srivatsavai  * for bridge instance allocation and control.  Each link on the bridge has a
79*4eaa4710SRishi Srivatsavai  * link structure.  Finally, the bridge has a table of learned forwarding
80*4eaa4710SRishi Srivatsavai  * entries, each with a list of outputs, which are either links or TRILL
81*4eaa4710SRishi Srivatsavai  * nicknames.
82*4eaa4710SRishi Srivatsavai  *
83*4eaa4710SRishi Srivatsavai  * The mac structure lives as long as the dls and mac layers are busy.  It can
84*4eaa4710SRishi Srivatsavai  * outlive the bridge instance and be picked up again (by name) if the instance
85*4eaa4710SRishi Srivatsavai  * is restarted.
86*4eaa4710SRishi Srivatsavai  */
87*4eaa4710SRishi Srivatsavai 
88*4eaa4710SRishi Srivatsavai struct bridge_mac_s;
89*4eaa4710SRishi Srivatsavai struct bridge_stream_s;
90*4eaa4710SRishi Srivatsavai 
91*4eaa4710SRishi Srivatsavai typedef struct bridge_inst_s {
92*4eaa4710SRishi Srivatsavai 	list_node_t	bi_node;
93*4eaa4710SRishi Srivatsavai 	dev_t		bi_dev;
94*4eaa4710SRishi Srivatsavai 	uint_t		bi_flags;
95*4eaa4710SRishi Srivatsavai 	uint_t		bi_refs;
96*4eaa4710SRishi Srivatsavai 	uint32_t	bi_tablemax;
97*4eaa4710SRishi Srivatsavai 	uint_t		bi_tshift;
98*4eaa4710SRishi Srivatsavai 	krwlock_t	bi_rwlock;
99*4eaa4710SRishi Srivatsavai 	list_t		bi_links;
100*4eaa4710SRishi Srivatsavai 	kcondvar_t	bi_linkwait;
101*4eaa4710SRishi Srivatsavai 	avl_tree_t	bi_fwd;
102*4eaa4710SRishi Srivatsavai 	kstat_t		*bi_ksp;
103*4eaa4710SRishi Srivatsavai 	struct bridge_stream_s *bi_control;
104*4eaa4710SRishi Srivatsavai 	struct bridge_mac_s *bi_mac;
105*4eaa4710SRishi Srivatsavai 	void		*bi_trilldata;
106*4eaa4710SRishi Srivatsavai 	char		bi_name[MAXLINKNAMELEN];
107*4eaa4710SRishi Srivatsavai 	bridge_ksinst_t	bi_kstats;
108*4eaa4710SRishi Srivatsavai } bridge_inst_t;
109*4eaa4710SRishi Srivatsavai 
110*4eaa4710SRishi Srivatsavai #define	BIF_SHUTDOWN	0x0001		/* control stream has closed */
111*4eaa4710SRishi Srivatsavai 
112*4eaa4710SRishi Srivatsavai /*
113*4eaa4710SRishi Srivatsavai  * The bridge MAC structure has the same lifetime as an observability node.
114*4eaa4710SRishi Srivatsavai  * It's created when a bridge instance is allocated, but is not freed when the
115*4eaa4710SRishi Srivatsavai  * instance is removed because there's no way for a MAC client to guarantee
116*4eaa4710SRishi Srivatsavai  * that all users have disappeared.
117*4eaa4710SRishi Srivatsavai  */
118*4eaa4710SRishi Srivatsavai typedef struct bridge_mac_s {
119*4eaa4710SRishi Srivatsavai 	list_node_t	bm_node;
120*4eaa4710SRishi Srivatsavai 	mac_handle_t	bm_mh;
121*4eaa4710SRishi Srivatsavai 	bridge_inst_t	*bm_inst;
122*4eaa4710SRishi Srivatsavai 	uint_t		bm_flags;	/* BMF_* below */
123*4eaa4710SRishi Srivatsavai 	uint_t		bm_maxsdu;
124*4eaa4710SRishi Srivatsavai 	link_state_t	bm_linkstate;
125*4eaa4710SRishi Srivatsavai 	char		bm_name[MAXLINKNAMELEN];
126*4eaa4710SRishi Srivatsavai } bridge_mac_t;
127*4eaa4710SRishi Srivatsavai 
128*4eaa4710SRishi Srivatsavai #define	BMF_DLS		0x0001		/* dls monitor node created */
129*4eaa4710SRishi Srivatsavai #define	BMF_STARTED	0x0002		/* snoop-like client is present */
130*4eaa4710SRishi Srivatsavai 
131*4eaa4710SRishi Srivatsavai /*
132*4eaa4710SRishi Srivatsavai  * Bridge streams are used only for instance allocation and control.
133*4eaa4710SRishi Srivatsavai  */
134*4eaa4710SRishi Srivatsavai typedef struct bridge_stream_s {
135*4eaa4710SRishi Srivatsavai 	bridge_inst_t	*bs_inst;
136*4eaa4710SRishi Srivatsavai 	queue_t		*bs_wq;		/* write-side queue for stream */
137*4eaa4710SRishi Srivatsavai 	minor_t		bs_minor;
138*4eaa4710SRishi Srivatsavai 	uint_t		bs_taskq_cnt;	/* taskq references */
139*4eaa4710SRishi Srivatsavai } bridge_stream_t;
140*4eaa4710SRishi Srivatsavai 
141*4eaa4710SRishi Srivatsavai /*
142*4eaa4710SRishi Srivatsavai  * These macros are used to set and test link membership in particular VLANs.
143*4eaa4710SRishi Srivatsavai  * This membership is used to determine how to forward packets between
144*4eaa4710SRishi Srivatsavai  * interfaces.
145*4eaa4710SRishi Srivatsavai  */
146*4eaa4710SRishi Srivatsavai 
147*4eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_ARR_SIZE	\
148*4eaa4710SRishi Srivatsavai 	(P2ROUNDUP(VLAN_ID_MAX, NBBY) / NBBY)
149*4eaa4710SRishi Srivatsavai 
150*4eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_ISSET(l, v)	((l)->bl_vlans[(v) / NBBY] & \
151*4eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
152*4eaa4710SRishi Srivatsavai 
153*4eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_SET(l, v)	((l)->bl_vlans[(v) / NBBY] |= \
154*4eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
155*4eaa4710SRishi Srivatsavai 
156*4eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_CLR(l, v)	((l)->bl_vlans[(v) / NBBY] &= \
157*4eaa4710SRishi Srivatsavai 	~(1 << ((v) % NBBY)))
158*4eaa4710SRishi Srivatsavai 
159*4eaa4710SRishi Srivatsavai #define	BRIDGE_AF_ISSET(l, v)	((l)->bl_afs[(v) / NBBY] & \
160*4eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
161*4eaa4710SRishi Srivatsavai 
162*4eaa4710SRishi Srivatsavai /*
163*4eaa4710SRishi Srivatsavai  * This structure represents a link attached to a bridge.  VLAN membership
164*4eaa4710SRishi Srivatsavai  * information is kept here; when forwarding, we must look at the membership of
165*4eaa4710SRishi Srivatsavai  * the input link and the output to determine when to update the packet
166*4eaa4710SRishi Srivatsavai  * contents and when to discard.
167*4eaa4710SRishi Srivatsavai  */
168*4eaa4710SRishi Srivatsavai typedef struct bridge_link_s {
169*4eaa4710SRishi Srivatsavai 	list_node_t	bl_node;
170*4eaa4710SRishi Srivatsavai 	uint_t		bl_refs;
171*4eaa4710SRishi Srivatsavai 	datalink_id_t	bl_linkid;	/* allocated link ID for bridge */
172*4eaa4710SRishi Srivatsavai 	bridge_state_t	bl_state;	/* blocking/learning/forwarding */
173*4eaa4710SRishi Srivatsavai 	uint_t		bl_pvid;	/* VLAN ID for untagged traffic */
174*4eaa4710SRishi Srivatsavai 	uint_t		bl_flags;	/* BLF_* below */
175*4eaa4710SRishi Srivatsavai 	uint_t		bl_learns;	/* learning limit */
176*4eaa4710SRishi Srivatsavai 	mac_handle_t	bl_mh;
177*4eaa4710SRishi Srivatsavai 	mac_client_handle_t	bl_mch;
178*4eaa4710SRishi Srivatsavai 	uint32_t	bl_margin;
179*4eaa4710SRishi Srivatsavai 	uint_t		bl_maxsdu;
180*4eaa4710SRishi Srivatsavai 	mac_unicast_handle_t	bl_mah;
181*4eaa4710SRishi Srivatsavai 	mac_notify_handle_t	bl_mnh;
182*4eaa4710SRishi Srivatsavai 	mac_promisc_handle_t	bl_mphp;
183*4eaa4710SRishi Srivatsavai 	bridge_inst_t	*bl_inst;	/* backpointer to bridge instance */
184*4eaa4710SRishi Srivatsavai 	kstat_t		*bl_ksp;
185*4eaa4710SRishi Srivatsavai 	void		*bl_trilldata;
186*4eaa4710SRishi Srivatsavai 	mblk_t		*bl_lfailmp;	/* preallocated */
187*4eaa4710SRishi Srivatsavai 	link_state_t	bl_linkstate;
188*4eaa4710SRishi Srivatsavai 	uint_t		bl_trillthreads;
189*4eaa4710SRishi Srivatsavai 	kcondvar_t	bl_trillwait;
190*4eaa4710SRishi Srivatsavai 	kmutex_t	bl_trilllock;
191*4eaa4710SRishi Srivatsavai 	uint8_t		bl_local_mac[ETHERADDRL];
192*4eaa4710SRishi Srivatsavai 	uint8_t		bl_vlans[BRIDGE_VLAN_ARR_SIZE];
193*4eaa4710SRishi Srivatsavai 	uint8_t		bl_afs[BRIDGE_VLAN_ARR_SIZE];
194*4eaa4710SRishi Srivatsavai 	bridge_kslink_t	bl_kstats;
195*4eaa4710SRishi Srivatsavai } bridge_link_t;
196*4eaa4710SRishi Srivatsavai 
197*4eaa4710SRishi Srivatsavai #define	BLF_DELETED		0x0001	/* waiting for last reference to go */
198*4eaa4710SRishi Srivatsavai #define	BLF_CLIENT_OPEN		0x0002	/* MAC client opened */
199*4eaa4710SRishi Srivatsavai #define	BLF_MARGIN_ADDED	0x0004	/* MAC margin added */
200*4eaa4710SRishi Srivatsavai #define	BLF_SET_BRIDGE		0x0008	/* MAC in bridging mode */
201*4eaa4710SRishi Srivatsavai #define	BLF_PROM_ADDED		0x0010	/* MAC promiscuous added */
202*4eaa4710SRishi Srivatsavai #define	BLF_FREED		0x0020	/* free has begun; debug assertion */
203*4eaa4710SRishi Srivatsavai #define	BLF_TRILLACTIVE		0x0040	/* in active forwarding use */
204*4eaa4710SRishi Srivatsavai #define	BLF_SDUFAIL		0x0080	/* has mismatched SDU */
205*4eaa4710SRishi Srivatsavai 
206*4eaa4710SRishi Srivatsavai /*
207*4eaa4710SRishi Srivatsavai  * This represents a learned forwarding entry.  These are generally created and
208*4eaa4710SRishi Srivatsavai  * refreshed on demand as we learn about nodes through source MAC addresses we
209*4eaa4710SRishi Srivatsavai  * see.  They're destroyed when they age away.  For forwarding, we look up the
210*4eaa4710SRishi Srivatsavai  * destination address in an AVL tree, and the entry found tells us where the
211*4eaa4710SRishi Srivatsavai  * that source must live.
212*4eaa4710SRishi Srivatsavai  */
213*4eaa4710SRishi Srivatsavai typedef struct bridge_fwd_s {
214*4eaa4710SRishi Srivatsavai 	avl_node_t	bf_node;
215*4eaa4710SRishi Srivatsavai 	uchar_t		bf_dest[ETHERADDRL];
216*4eaa4710SRishi Srivatsavai 	uint16_t	bf_trill_nick;	/* destination nickname */
217*4eaa4710SRishi Srivatsavai 	clock_t		bf_lastheard;	/* time we last heard from this node */
218*4eaa4710SRishi Srivatsavai 	uint_t		bf_flags;	/* BFF_* below */
219*4eaa4710SRishi Srivatsavai 	uint_t		bf_refs;
220*4eaa4710SRishi Srivatsavai 	uint16_t	bf_vlanid;	/* VLAN ID for IVL */
221*4eaa4710SRishi Srivatsavai 	uint16_t	bf_vcnt;	/* number of duplicates */
222*4eaa4710SRishi Srivatsavai 	uint_t		bf_nlinks;	/* number of links in bf_links */
223*4eaa4710SRishi Srivatsavai 	uint_t		bf_maxlinks;	/* allocated size of link array */
224*4eaa4710SRishi Srivatsavai 	bridge_link_t	**bf_links;
225*4eaa4710SRishi Srivatsavai } bridge_fwd_t;
226*4eaa4710SRishi Srivatsavai 
227*4eaa4710SRishi Srivatsavai #define	BFF_INTREE	0x0001
228*4eaa4710SRishi Srivatsavai #define	BFF_LOCALADDR	0x0002		/* address is known to mac layer */
229*4eaa4710SRishi Srivatsavai #define	BFF_VLANLOCAL	0x0004		/* set if duplicate for IVL */
230*4eaa4710SRishi Srivatsavai 
231*4eaa4710SRishi Srivatsavai /* TRILL linkage */
232*4eaa4710SRishi Srivatsavai typedef void (*trill_recv_pkt_t)(void *, bridge_link_t *, mac_resource_handle_t,
233*4eaa4710SRishi Srivatsavai     mblk_t *, mac_header_info_t *);
234*4eaa4710SRishi Srivatsavai typedef void (*trill_encap_pkt_t)(void *, bridge_link_t *, mac_header_info_t *,
235*4eaa4710SRishi Srivatsavai     mblk_t *, uint16_t);
236*4eaa4710SRishi Srivatsavai typedef void (*trill_br_dstr_t)(void *, bridge_inst_t *);
237*4eaa4710SRishi Srivatsavai typedef void (*trill_ln_dstr_t)(void *, bridge_link_t *);
238*4eaa4710SRishi Srivatsavai 
239*4eaa4710SRishi Srivatsavai extern void bridge_trill_register_cb(trill_recv_pkt_t, trill_encap_pkt_t,
240*4eaa4710SRishi Srivatsavai     trill_br_dstr_t, trill_ln_dstr_t);
241*4eaa4710SRishi Srivatsavai extern bridge_inst_t *bridge_trill_brref(const char *, void *);
242*4eaa4710SRishi Srivatsavai extern void bridge_trill_brunref(bridge_inst_t *);
243*4eaa4710SRishi Srivatsavai extern bridge_link_t *bridge_trill_lnref(bridge_inst_t *, datalink_id_t,
244*4eaa4710SRishi Srivatsavai     void *);
245*4eaa4710SRishi Srivatsavai extern void bridge_trill_lnunref(bridge_link_t *);
246*4eaa4710SRishi Srivatsavai extern void bridge_trill_decaps(bridge_link_t *, mblk_t *, uint16_t);
247*4eaa4710SRishi Srivatsavai extern mblk_t *bridge_trill_output(bridge_link_t *, mblk_t *);
248*4eaa4710SRishi Srivatsavai extern void bridge_trill_setvlans(bridge_link_t *, const uint8_t *);
249*4eaa4710SRishi Srivatsavai extern void bridge_trill_flush(bridge_link_t *, uint16_t, boolean_t);
250*4eaa4710SRishi Srivatsavai 
251*4eaa4710SRishi Srivatsavai /* Ethernet multicast address; constant stored in bridge module */
252*4eaa4710SRishi Srivatsavai extern const uint8_t all_isis_rbridges[];
253*4eaa4710SRishi Srivatsavai extern const uint8_t bridge_group_address[];
254*4eaa4710SRishi Srivatsavai 
255*4eaa4710SRishi Srivatsavai #ifdef __cplusplus
256*4eaa4710SRishi Srivatsavai }
257*4eaa4710SRishi Srivatsavai #endif
258*4eaa4710SRishi Srivatsavai 
259*4eaa4710SRishi Srivatsavai #endif /* _BRIDGE_IMPL_H */
260