summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/aggr_lacp.h
blob: ef8c7408accb62dd7f1b87da14ab9f0acbdc720d (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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/*
 * 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 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_AGGR_LACP_H
#define	_SYS_AGGR_LACP_H

#include <sys/aggr.h>
#include <sys/ethernet.h>

#ifdef	__cplusplus
extern "C" {
#endif

#ifdef _KERNEL

/*
 * 802.3ad LACP version number
 */
#define	LACP_VERSION	0x01	/* LACP version from 802.3ad */
#define	LACP_SUBTYPE	0x1

/*
 * TLV type (type/length/value carried in the LACPDU structure.
 */
#define	ACTOR_TLV	0x01	/* actor TLV type */
#define	PARTNER_TLV	0x02	/* partner TLV type */
#define	COLLECTOR_TLV	0x03	/* collector TLV type */
#define	TERMINATOR_TLV	0x00	/* end of message */

/*
 * Length fields as per 802.3ad.
 */
#define	LACP_COLLECTOR_INFO_LEN		0x10
#define	LACP_TERMINATOR_INFO_LEN	0x00

/* LACP Receive State Machine states */
typedef	enum {
	LACP_INITIALIZE		= 0,
	LACP_PORT_DISABLED	= 1,
	LACP_EXPIRED		= 2,
	LACP_DISABLED		= 3,
	LACP_DEFAULTED		= 4,
	LACP_CURRENT		= 5
} lacp_receive_state_t;

#define	LACP_RECEIVE_STATE_STRINGS {	\
	"LACP_INITIALIZE",		\
	"LACP_PORT_DISABLED",		\
	"LACP_EXPIRED",			\
	"LACP_DISABLED",		\
	"LACP_DEFAULTED",		\
	"LACP_CURRENT"			\
}

/* LACP Periodic State Machine states */
typedef	enum {
	LACP_NO_PERIODIC		= 0,
	LACP_FAST_PERIODIC		= 1,
	LACP_SLOW_PERIODIC		= 2,
	LACP_PERIODIC_TX		= 3
} lacp_periodic_state_t;

#define	LACP_PERIODIC_STRINGS {		\
	"LACP_NO_PERIODIC",		\
	"LACP_FAST_PERIODIC",		\
	"LACP_SLOW_PERIODIC",		\
	"LACP_PERIODIC_TX"		\
}


/* LACP Mux State Machine states */
typedef	enum {
	LACP_DETACHED			= 0,
	LACP_WAITING			= 1,
	LACP_ATTACHED			= 2,
	LACP_COLLECTING_DISTRIBUTING	= 3
} lacp_mux_state_t;

#define	LACP_MUX_STRINGS {		\
	"LACP_DETACHED",		\
	"LACP_WAITING",			\
	"LACP_ATTACHED",		\
	"LACP_COLLECTING_DISTRIBUTING"	\
}

/* LACP Churn State Machine states */
typedef	enum {
	LACP_NO_ACTOR_CHURN		= 0,
	LACP_ACTOR_CHURN_MONITOR	= 1,
	LACP_ACTOR_CHURN		= 2
} lacp_churn_state_t;

/*
 * 802.3ad timer constants.  (IEEE 802.3ad: section 43.4.4)
 *
 * All timers specified have a implementation tolerance of +- 250 ms.
 */
#define	FAST_PERIODIC_TIME		1	/* using short timeouts (tx) */
#define	SLOW_PERIODIC_TIME		30	/* using long timeouts (tx) */
#define	SHORT_TIMEOUT_TIME		3	/* before invalidate LACPDU */
#define	LONG_TIMEOUT_TIME		90	/* before invalidate LACPDU */
#define	CHURN_DETECTION_TIME		60	/* sync between actor/partner */
#define	AGGREGATE_WAIT_TIME		2  /* Delay wait to aggregate links */

/*
 * 802.3ad Variables associated with the system (section 43.4.5)
 */
typedef struct system_info {
	struct ether_addr system_id;	/* MAC address assigned by admin */
	uint16_t system_priority; 	/* system priority assigned by admin */
} system_info_t;

typedef struct lacp_timer {
	uint32_t	val;
	timeout_id_t	id;
} lacp_timer_t;

/*
 * 802.3ad Variables associated with each aggregation (section 43.4.6)
 *	Note: These are on a per aggregation basis.
 */
typedef struct Agg {
	uint32_t	AggregatorIdentifier;	/* not used */
	boolean_t	IndividualAggr;		/* individual aggregator */
	uint32_t	ActorAdminKey;		/* assigned by admin. */
	uint32_t	ActorOperKey;		/* assigned by admin. */
	struct ether_addr PartnerSystem;	/* partner system ID */
	uint32_t	PartnerSystemPriority;	/* partner system priority */
	uint32_t	PartnerOperAggrKey;	/* parter oper aggr. key */
	boolean_t	ReceiveState;		/* Enabled/Disabled */
	boolean_t	TransmitState;		/* Enabled/Disabled */

	uint16_t	ActorSystemPriority;	/* System Priority */
	uint16_t	CollectorMaxDelay;	/* tens of Usecs */
	aggr_lacp_timer_t PeriodicTimer;	/* AGGR_LACP_{LONG,SHORT} */
	uint64_t	TimeOfLastOperChange;	/* Time in state */
	boolean_t	ready;			/* Ready_N for all ports TRUE */
} Agg_t;

/*
 * 802.3ad Variables used for managing the operation of
 * the state machines (section 43.4.8)
 * Note: These are on a per port basis.
 */
typedef	enum {
	AGGR_UNSELECTED,	/* aggregator not selected */
	AGGR_SELECTED,		/* aggregator selected */
	AGGR_STANDBY		/* port in standby */
} lacp_selected_t;

typedef struct state_machine {
	uint32_t	lacp_on : 1,		/* LACP on or off */
			begin : 1,		/* LACP init(or reinit.) */
			lacp_enabled : 1,	/* Full/Half Duplex */
			port_enabled : 1,	/* Link Up/Down */
			actor_churn : 1,	/* failed to converge */
			partner_churn : 1,
			ready_n : 1,		/* waiting */
			port_moved : 1,		/* any port is not waiting */
			pad_bits : 24;
	/* "Ready" is accessed from the aggregator structure */
	lacp_selected_t	selected;	/* SELECTED/UNSELECTED/STANDBY */
	uint32_t	current_while_timer_exp; /* # of times timer expired */
	lacp_periodic_state_t	periodic_state;	/* State of periodic machine */
	lacp_receive_state_t	receive_state;	/* State of receive machine */
	lacp_mux_state_t	mux_state;	/* State of mux machine */
	lacp_churn_state_t	churn_state;	/* State of churn machine */
} state_machine_t;

/*
 * The following three flags are set when specific timer is timed out; used
 * by the LACP timer handler thread.
 */
#define	LACP_PERIODIC_TIMEOUT		0x01
#define	LACP_WAIT_WHILE_TIMEOUT		0x02
#define	LACP_CURRENT_WHILE_TIMEOUT	0x04
/*
 * Set when the port is being deleted; used to inform the LACP timer handler
 * thread to exit.
 */
#define	LACP_THREAD_EXIT		0x08

/*
 * 802.3ad Variables associated with each port (section 43.4.7)
 */
typedef struct aggr_lacp_port {
	uint16_t	ActorPortNumber;	/* actor port number */
	uint16_t	ActorPortPriority;	/* actor port priority */
	uint32_t	ActorPortAggrId;	/* aggregator id */
	boolean_t	NTT;			/* need to transmit */
	uint16_t	ActorAdminPortKey;	/* admin. port key */
	uint16_t	ActorOperPortKey;	/* oper port key */
	aggr_lacp_state_t ActorAdminPortState;	/* actor admin. port state */
	aggr_lacp_state_t ActorOperPortState;	/* actor oper. port state */

	/*
	 * partner information
	 */
	struct ether_addr PartnerAdminSystem;	/* partner admin. system */
	struct ether_addr PartnerOperSystem;	/* partner oper.system */
	uint16_t PartnerAdminSysPriority;	/* partner admin. sys. pri. */
	uint16_t PartnerOperSysPriority;	/* partner oper. sys. pri. */
	uint16_t PartnerAdminKey;		/* partner admin. key */
	uint16_t PartnerOperKey;		/* partner oper. key */
	uint16_t PartnerAdminPortNum;		/* partner admin. port # */
	uint16_t PartnerOperPortNum;		/* partner oper. port # */
	uint16_t PartnerAdminPortPriority;	/* partner admin. port pri. */
	uint16_t PartnerOperPortPriority;	/* partner oper. port pri. */
	aggr_lacp_state_t PartnerAdminPortState; /* partner admin port state */
	aggr_lacp_state_t PartnerOperPortState; /* partner oper port state */
	uint16_t PartnerCollectorMaxDelay;	/* tens of microseconds */

	/*
	 * State machine and Timer information.
	 */
	state_machine_t	sm;		/* state machine variables per port */
	lacp_timer_t	current_while_timer;
	lacp_timer_t	periodic_timer;
	lacp_timer_t	wait_while_timer;
	uint32_t	lacp_timer_bits;
	kthread_t	*lacp_timer_thread;
	kmutex_t	lacp_timer_lock;
	kcondvar_t	lacp_timer_cv;
	hrtime_t	time;
} aggr_lacp_port_t;

typedef struct lacp_stats_s {
	uint64_t	LACPDUsRx;
	uint64_t	MarkerPDUsRx;
	uint64_t	MarkerResponsePDUsRx;
	uint64_t	UnknownRx;
	uint64_t	IllegalRx;
	uint64_t	LACPDUsTx;
	uint64_t	MarkerPDUsTx;
	uint64_t	MarkerResponsePDUsTx;
} lacp_stats_t;

/*
 * 802.3ad protocol information
 */
/*
 * Actor/Partner information
 */
typedef struct link_info {
	uint8_t			tlv_type;	/* type/length/value */
	uint8_t			information_len; /* information length */
	uint16_t		system_priority; /* system priority */
	struct ether_addr	system_id;	/* encoded as MAC address */
	uint16_t		key;		/* operational key */
	uint16_t		port_priority;	/* port priority */
	uint16_t		port;		/* port */
	aggr_lacp_state_t	state;		/* state info */
	uint8_t			reserved[3];	/* reserved */
} link_info_t;

/*
 * Link Aggregation Control Protocol (LACPDU) structure
 */
typedef struct lacp {
	uint8_t			subtype;	/* = LACP */
	uint8_t			version;	/* LACP version */
	link_info_t		actor_info;	/* actor information */
	link_info_t		partner_info;	/* partner information */
	uint8_t			tlv_collector;	/* collector tlv */
	uint8_t			collector_len;	/* collector len */
	uint16_t		collector_max_delay; /* tens of miscrosecond */
	uint8_t			reserved[12];	/* reserved */
	uint8_t			tlv_terminator;	/* terminator tlv */
	uint8_t			terminator_len;	/* terminator len */
	uint8_t			lacp_reserved[50];	/* reserved */
} lacp_t;

/*
 * Marker protocol
 */

#define	MARKER_VERSION	0x1		/* 802.3ad Marker version number */
#define	MARKER_SUBTYPE	0x2
#define	MARKER_INFO_RESPONSE_LENGTH	16

/*
 * marker TLV_type
 */
#define	MARKER_INFO_TLV		0x01	/* marker information */
#define	MARKER_RESPONSE_TLV	0x02	/* marker response information */

typedef struct marker_pdu {
	struct ether_addr	dest_addr;	/* Slow protocol multicast */
	struct ether_addr	src_addr;	/* Source address */
	uint16_t		type;		/* Slow protocol type */
	uint8_t			subtype;	/* = Marker 0x2 */
	uint8_t			version;	/* Marker version 0x01 */
	uint8_t			tlv_marker;	/* marker tlv */
	uint8_t			marker_len;	/* marker len */
	uint16_t		requestor_port; /* requestor port */
	struct ether_addr	system_id;	/* requestor system */
	uint8_t			transaction_id[4];	/* transaction id */
	uint8_t			pad[2];		/* zeros to align */
	uint8_t			reserved[90];	/* reserved */
	uint32_t		fcs;		/* generated by MAC */
} marker_pdu_t;

/*
 * 802.3ad Link Aggregation Group Identifier (IEEE 802.3ad 43.3.6)
 * port identifire = port priority and port number.
 */
typedef struct lag_id {
	uint16_t		system_priority;	/* system priority */
	struct ether_addr	system_id;		/* system identifier */
	uint16_t		oper_key;		/* operational key */
	uint16_t		port_priority;		/* port priority */
	uint16_t		port_number;		/* 0: aggregatable */
} lag_id_t;

#endif /* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_AGGR_LACP_H */