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