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