summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/net/bridge_impl.h
blob: bf2e47e91b623fc5af71bf0e9f29bf54f398f63f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _BRIDGE_IMPL_H
#define	_BRIDGE_IMPL_H

/*
 * These are the internal data structures used by the layer-two (Ethernet)
 * bridging module.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/list.h>
#include <sys/sysmacros.h>
#include <sys/avl.h>
#include <sys/queue.h>
#include <sys/kstat.h>
#include <sys/ksynch.h>
#include <sys/ethernet.h>
#include <sys/dld.h>
#include <sys/mac.h>
#include <sys/mac_client.h>
#include <sys/vlan.h>
#include <net/bridge.h>

#define	BRIDGE_DEV_NAME	"bridge"

#define	KSINST_NAMES	"recv", "sent", "drops", \
	"forward_direct", "forward_unknown", "forward_mbcast",	\
	"learn_source", "learn_moved", "learn_expire", "learn_size"
typedef struct bridge_ksinst_s {
	kstat_named_t	bki_recv;	/* packets received */
	kstat_named_t	bki_sent;	/* packets sent through */
	kstat_named_t	bki_drops;	/* packets dropped (untowardly) */
	kstat_named_t	bki_forwards;	/* packets forwarded */
	kstat_named_t	bki_unknown;	/* packets forwarded (unknown dest) */
	kstat_named_t	bki_mbcast;	/* packets forwarded (multi/bcast) */
	kstat_named_t	bki_source;	/* source addresses learned */
	kstat_named_t	bki_moved;	/* source addresses moved */
	kstat_named_t	bki_expire;	/* source addresses expired */
	kstat_named_t	bki_count;	/* source addresses known */
} bridge_ksinst_t;

#define	KSLINK_NAMES	"recv", "xmit", "drops"
typedef struct bridge_kslink_s {
	kstat_named_t	bkl_recv;	/* packets received */
	kstat_named_t	bkl_xmit;	/* packets transmitted */
	kstat_named_t	bkl_drops;	/* packets dropped */
} bridge_kslink_t;

/*
 * There's one instance structure and one observability mac node for each
 * bridge.  Each open non-DLPI stream gets a 'stream' structure; these are used
 * for bridge instance allocation and control.  Each link on the bridge has a
 * link structure.  Finally, the bridge has a table of learned forwarding
 * entries, each with a list of outputs, which are either links or TRILL
 * nicknames.
 *
 * The mac structure lives as long as the dls and mac layers are busy.  It can
 * outlive the bridge instance and be picked up again (by name) if the instance
 * is restarted.
 */

struct bridge_mac_s;
struct bridge_stream_s;

typedef struct bridge_inst_s {
	list_node_t	bi_node;
	dev_t		bi_dev;
	uint_t		bi_flags;
	uint_t		bi_refs;
	uint32_t	bi_tablemax;
	uint_t		bi_tshift;
	krwlock_t	bi_rwlock;
	list_t		bi_links;
	kcondvar_t	bi_linkwait;
	avl_tree_t	bi_fwd;
	kstat_t		*bi_ksp;
	struct bridge_stream_s *bi_control;
	struct bridge_mac_s *bi_mac;
	void		*bi_trilldata;
	char		bi_name[MAXLINKNAMELEN];
	bridge_ksinst_t	bi_kstats;
} bridge_inst_t;

#define	BIF_SHUTDOWN	0x0001		/* control stream has closed */

/*
 * The bridge MAC structure has the same lifetime as an observability node.
 * It's created when a bridge instance is allocated, but is not freed when the
 * instance is removed because there's no way for a MAC client to guarantee
 * that all users have disappeared.
 */
typedef struct bridge_mac_s {
	list_node_t	bm_node;
	mac_handle_t	bm_mh;
	bridge_inst_t	*bm_inst;
	uint_t		bm_flags;	/* BMF_* below */
	uint_t		bm_maxsdu;
	link_state_t	bm_linkstate;
	char		bm_name[MAXLINKNAMELEN];
} bridge_mac_t;

#define	BMF_DLS		0x0001		/* dls monitor node created */
#define	BMF_STARTED	0x0002		/* snoop-like client is present */

/*
 * Bridge streams are used only for instance allocation and control.
 */
typedef struct bridge_stream_s {
	bridge_inst_t	*bs_inst;
	queue_t		*bs_wq;		/* write-side queue for stream */
	minor_t		bs_minor;
	uint_t		bs_taskq_cnt;	/* taskq references */
} bridge_stream_t;

/*
 * These macros are used to set and test link membership in particular VLANs.
 * This membership is used to determine how to forward packets between
 * interfaces.
 */

#define	BRIDGE_VLAN_ARR_SIZE	\
	(P2ROUNDUP(VLAN_ID_MAX, NBBY) / NBBY)

#define	BRIDGE_VLAN_ISSET(l, v)	((l)->bl_vlans[(v) / NBBY] & \
	(1 << ((v) % NBBY)))

#define	BRIDGE_VLAN_SET(l, v)	((l)->bl_vlans[(v) / NBBY] |= \
	(1 << ((v) % NBBY)))

#define	BRIDGE_VLAN_CLR(l, v)	((l)->bl_vlans[(v) / NBBY] &= \
	~(1 << ((v) % NBBY)))

#define	BRIDGE_AF_ISSET(l, v)	((l)->bl_afs[(v) / NBBY] & \
	(1 << ((v) % NBBY)))

/*
 * This structure represents a link attached to a bridge.  VLAN membership
 * information is kept here; when forwarding, we must look at the membership of
 * the input link and the output to determine when to update the packet
 * contents and when to discard.
 */
typedef struct bridge_link_s {
	list_node_t	bl_node;
	uint_t		bl_refs;
	datalink_id_t	bl_linkid;	/* allocated link ID for bridge */
	bridge_state_t	bl_state;	/* blocking/learning/forwarding */
	uint_t		bl_pvid;	/* VLAN ID for untagged traffic */
	uint_t		bl_flags;	/* BLF_* below */
	uint_t		bl_learns;	/* learning limit */
	mac_handle_t	bl_mh;
	mac_client_handle_t	bl_mch;
	uint32_t	bl_margin;
	uint_t		bl_maxsdu;
	mac_unicast_handle_t	bl_mah;
	mac_notify_handle_t	bl_mnh;
	mac_promisc_handle_t	bl_mphp;
	bridge_inst_t	*bl_inst;	/* backpointer to bridge instance */
	kstat_t		*bl_ksp;
	void		*bl_trilldata;
	mblk_t		*bl_lfailmp;	/* preallocated */
	link_state_t	bl_linkstate;
	uint_t		bl_trillthreads;
	kcondvar_t	bl_trillwait;
	kmutex_t	bl_trilllock;
	uint8_t		bl_local_mac[ETHERADDRL];
	uint8_t		bl_vlans[BRIDGE_VLAN_ARR_SIZE];
	uint8_t		bl_afs[BRIDGE_VLAN_ARR_SIZE];
	bridge_kslink_t	bl_kstats;
} bridge_link_t;

#define	BLF_DELETED		0x0001	/* waiting for last reference to go */
#define	BLF_CLIENT_OPEN		0x0002	/* MAC client opened */
#define	BLF_MARGIN_ADDED	0x0004	/* MAC margin added */
#define	BLF_SET_BRIDGE		0x0008	/* MAC in bridging mode */
#define	BLF_PROM_ADDED		0x0010	/* MAC promiscuous added */
#define	BLF_FREED		0x0020	/* free has begun; debug assertion */
#define	BLF_TRILLACTIVE		0x0040	/* in active forwarding use */
#define	BLF_SDUFAIL		0x0080	/* has mismatched SDU */
#define	BLF_LINK_ADDED		0x0100	/* link added in bridge instance */

/*
 * This represents a learned forwarding entry.  These are generally created and
 * refreshed on demand as we learn about nodes through source MAC addresses we
 * see.  They're destroyed when they age away.  For forwarding, we look up the
 * destination address in an AVL tree, and the entry found tells us where the
 * that source must live.
 */
typedef struct bridge_fwd_s {
	avl_node_t	bf_node;
	uchar_t		bf_dest[ETHERADDRL];
	uint16_t	bf_trill_nick;	/* destination nickname */
	clock_t		bf_lastheard;	/* time we last heard from this node */
	uint_t		bf_flags;	/* BFF_* below */
	uint_t		bf_refs;
	uint16_t	bf_vlanid;	/* VLAN ID for IVL */
	uint16_t	bf_vcnt;	/* number of duplicates */
	uint_t		bf_nlinks;	/* number of links in bf_links */
	uint_t		bf_maxlinks;	/* allocated size of link array */
	bridge_link_t	**bf_links;
} bridge_fwd_t;

#define	BFF_INTREE	0x0001
#define	BFF_LOCALADDR	0x0002		/* address is known to mac layer */
#define	BFF_VLANLOCAL	0x0004		/* set if duplicate for IVL */

/* TRILL linkage */
typedef void (*trill_recv_pkt_t)(void *, bridge_link_t *, mac_resource_handle_t,
    mblk_t *, mac_header_info_t *);
typedef void (*trill_encap_pkt_t)(void *, bridge_link_t *, mac_header_info_t *,
    mblk_t *, uint16_t);
typedef void (*trill_br_dstr_t)(void *, bridge_inst_t *);
typedef void (*trill_ln_dstr_t)(void *, bridge_link_t *);

extern void bridge_trill_register_cb(trill_recv_pkt_t, trill_encap_pkt_t,
    trill_br_dstr_t, trill_ln_dstr_t);
extern bridge_inst_t *bridge_trill_brref(const char *, void *);
extern void bridge_trill_brunref(bridge_inst_t *);
extern bridge_link_t *bridge_trill_lnref(bridge_inst_t *, datalink_id_t,
    void *);
extern void bridge_trill_lnunref(bridge_link_t *);
extern void bridge_trill_decaps(bridge_link_t *, mblk_t *, uint16_t);
extern mblk_t *bridge_trill_output(bridge_link_t *, mblk_t *);
extern void bridge_trill_setvlans(bridge_link_t *, const uint8_t *);
extern void bridge_trill_flush(bridge_link_t *, uint16_t, boolean_t);

/* Ethernet multicast address; constant stored in bridge module */
extern const uint8_t all_isis_rbridges[];
extern const uint8_t bridge_group_address[];

#ifdef __cplusplus
}
#endif

#endif /* _BRIDGE_IMPL_H */