| 1 | /*	$OpenBSD: trunklacp.h,v 1.14 2018/08/12 23:50:31 ccardenas Exp $	*/ |
| 2 | /*	$NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $	*/ |
| 3 | |
| 4 | /* |
| 5 | * Copyright (c)2005 YAMAMOTO Takashi, |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 27 | * SUCH DAMAGE. |
| 28 | * |
| 29 | * $FreeBSD: src/sys/net/ieee8023ad_lacp.h,v 1.11 2008/03/17 01:26:44 thompsa Exp $ |
| 30 | */ |
| 31 | |
| 32 | #ifndef _NET_TRUNKLACP_H_ |
| 33 | #define _NET_TRUNKLACP_H_ |
| 34 | |
| 35 | /* |
| 36 | * IEEE802.3 slow protocols (on-wire) definitions. |
| 37 | * XXX should be elsewhere. |
| 38 | */ |
| 39 | #define	SLOWPROTOCOLS_SUBTYPE_LACP	1 |
| 40 | #define	SLOWPROTOCOLS_SUBTYPE_MARKER	2 |
| 41 | |
| 42 | /* |
| 43 | * default administrative values |
| 44 | */ |
| 45 | #define	LACP_DEFAULT_MODE		1 /* Active Mode */ |
| 46 | #define	LACP_DEFAULT_TIMEOUT		0 /* Slow Timeout */ |
| 47 | #define	LACP_DEFAULT_SYSTEM_PRIO	0x8000 /* Medium Priority */ |
| 48 | #define	LACP_LOW_SYSTEM_PRIO		0xffff |
| 49 | #define	LACP_HIGH_SYSTEM_PRIO		0x0001 |
| 50 | #define	LACP_DEFAULT_PORT_PRIO		0x8000 /* Medium Priority */ |
| 51 | #define	LACP_LOW_PORT_PRIO		0xffff |
| 52 | #define	LACP_HIGH_PORT_PRIO		0x0001 |
| 53 | #define	LACP_DEFAULT_IFQ_PRIO		6 |
| 54 | |
| 55 | struct slowprothdr { |
| 56 | 	u_int8_t		sph_subtype; |
| 57 | 	u_int8_t		sph_version; |
| 58 | } __packed; |
| 59 | |
| 60 | /* TLV on-wire structure. */ |
| 61 | struct tlvhdr { |
| 62 | 	u_int8_t		tlv_type; |
| 63 | 	u_int8_t		tlv_length; |
| 64 | 	/* u_int8_t tlv_value[]; */ |
| 65 | } __packed; |
| 66 | |
| 67 | /* ... and our implementation. */ |
| 68 | #define	TLV_SET(tlv, type, length) \ |
| 69 | 	do { \ |
| 70 | 		(tlv)->tlv_type = (type); \ |
| 71 | 		(tlv)->tlv_length = sizeof(*tlv) + (length); \ |
| 72 | 	} while (/*CONSTCOND*/0) |
| 73 | |
| 74 | struct tlv_template { |
| 75 | 	u_int8_t			tmpl_type; |
| 76 | 	u_int8_t			tmpl_length; |
| 77 | }; |
| 78 | |
| 79 | struct lacp_systemid { |
| 80 | 	u_int16_t		lsi_prio; |
| 81 | 	u_int8_t		lsi_mac[6]; |
| 82 | } __packed; |
| 83 | |
| 84 | struct lacp_portid { |
| 85 | 	u_int16_t		lpi_prio; |
| 86 | 	u_int16_t		lpi_portno; |
| 87 | } __packed; |
| 88 | |
| 89 | struct lacp_peerinfo { |
| 90 | 	struct lacp_systemid	lip_systemid; |
| 91 | 	u_int16_t		lip_key; |
| 92 | 	struct lacp_portid	lip_portid; |
| 93 | 	u_int8_t		lip_state; |
| 94 | 	u_int8_t		lip_resv[3]; |
| 95 | } __packed; |
| 96 | |
| 97 | struct lacp_collectorinfo { |
| 98 | 	u_int16_t		lci_maxdelay; |
| 99 | 	u_int8_t		lci_resv[12]; |
| 100 | } __packed; |
| 101 | |
| 102 | struct lacpdu { |
| 103 | 	struct ether_header	ldu_eh; |
| 104 | 	struct slowprothdr	ldu_sph; |
| 105 | |
| 106 | 	struct tlvhdr		ldu_tlv_actor; |
| 107 | 	struct lacp_peerinfo	ldu_actor; |
| 108 | 	struct tlvhdr		ldu_tlv_partner; |
| 109 | 	struct lacp_peerinfo	ldu_partner; |
| 110 | 	struct tlvhdr		ldu_tlv_collector; |
| 111 | 	struct lacp_collectorinfo ldu_collector; |
| 112 | 	struct tlvhdr		ldu_tlv_term; |
| 113 | 	u_int8_t		ldu_resv[50]; |
| 114 | } __packed; |
| 115 | |
| 116 | /* |
| 117 | * IEEE802.3ad marker protocol (on-wire) definitions. |
| 118 | */ |
| 119 | struct lacp_markerinfo { |
| 120 | 	u_int16_t		mi_rq_port; |
| 121 | 	u_int8_t		mi_rq_system[ETHER_ADDR_LEN]; |
| 122 | 	u_int32_t		mi_rq_xid; |
| 123 | 	u_int8_t		mi_pad[2]; |
| 124 | } __packed; |
| 125 | |
| 126 | #define	LACP_STATE_BITS		\ |
| 127 | 	"\020"			\ |
| 128 | 	"\001ACTIVITY"		\ |
| 129 | 	"\002TIMEOUT"		\ |
| 130 | 	"\003AGGREGATION"	\ |
| 131 | 	"\004SYNC"		\ |
| 132 | 	"\005COLLECTING"	\ |
| 133 | 	"\006DISTRIBUTING"	\ |
| 134 | 	"\007DEFAULTED"		\ |
| 135 | 	"\010EXPIRED" |
| 136 | |
| 137 | #ifdef _KERNEL |
| 138 | |
| 139 | /* |
| 140 | * IEEE802.3ad LACP implementation details. |
| 141 | */ |
| 142 | #define	LACP_TIMER_CURRENT_WHILE	0 |
| 143 | #define	LACP_TIMER_PERIODIC		1 |
| 144 | #define	LACP_TIMER_WAIT_WHILE		2 |
| 145 | #define	LACP_NTIMER			3 |
| 146 | |
| 147 | #define	LACP_TIMER_ARM(port, timer, val) \ |
| 148 | 	(port)->lp_timer[(timer)] = (val) |
| 149 | #define	LACP_TIMER_DISARM(port, timer) \ |
| 150 | 	(port)->lp_timer[(timer)] = 0 |
| 151 | #define	LACP_TIMER_ISARMED(port, timer) \ |
| 152 | 	((port)->lp_timer[(timer)] > 0) |
| 153 | |
| 154 | /* |
| 155 | * IEEE802.3ad LACP protocol definitions. |
| 156 | */ |
| 157 | #define	LACP_STATE_ACTIVITY	(1<<0) |
| 158 | #define	LACP_STATE_TIMEOUT	(1<<1) |
| 159 | #define	LACP_STATE_AGGREGATION	(1<<2) |
| 160 | #define	LACP_STATE_SYNC		(1<<3) |
| 161 | #define	LACP_STATE_COLLECTING	(1<<4) |
| 162 | #define	LACP_STATE_DISTRIBUTING	(1<<5) |
| 163 | #define	LACP_STATE_DEFAULTED	(1<<6) |
| 164 | #define	LACP_STATE_EXPIRED	(1<<7) |
| 165 | |
| 166 | #define	LACP_PORT_NTT		0x00000001 |
| 167 | #define	LACP_PORT_MARK		0x00000002 |
| 168 | |
| 169 | struct markerdu { |
| 170 | 	struct ether_header	mdu_eh; |
| 171 | 	struct slowprothdr	mdu_sph; |
| 172 | |
| 173 | 	struct tlvhdr		mdu_tlv; |
| 174 | 	struct lacp_markerinfo	mdu_info; |
| 175 | 	struct tlvhdr		mdu_tlv_term; |
| 176 | 	u_int8_t		mdu_resv[90]; |
| 177 | } __packed; |
| 178 | |
| 179 | #define	MARKER_TYPE_INFO	0x01 |
| 180 | #define	MARKER_TYPE_RESPONSE	0x02 |
| 181 | |
| 182 | enum lacp_selected { |
| 183 | 	LACP_UNSELECTED, |
| 184 | 	LACP_STANDBY,	/* not used in this implementation */ |
| 185 | 	LACP_SELECTED, |
| 186 | }; |
| 187 | |
| 188 | enum lacp_mux_state { |
| 189 | 	LACP_MUX_DETACHED, |
| 190 | 	LACP_MUX_WAITING, |
| 191 | 	LACP_MUX_ATTACHED, |
| 192 | 	LACP_MUX_COLLECTING, |
| 193 | 	LACP_MUX_DISTRIBUTING, |
| 194 | }; |
| 195 | |
| 196 | #define	LACP_MAX_PORTS		32 |
| 197 | |
| 198 | struct lacp_portmap { |
| 199 | 	int			pm_count; |
| 200 | 	struct lacp_port	*pm_map[LACP_MAX_PORTS]; |
| 201 | }; |
| 202 | |
| 203 | struct lacp_port { |
| 204 | 	TAILQ_ENTRY(lacp_port)	lp_dist_q; |
| 205 | 	LIST_ENTRY(lacp_port)	lp_next; |
| 206 | 	struct lacp_softc	*lp_lsc; |
| 207 | 	struct trunk_port	*lp_trunk; |
| 208 | 	struct ifnet		*lp_ifp; |
| 209 | 	struct lacp_peerinfo	lp_partner; |
| 210 | 	struct lacp_peerinfo	lp_actor; |
| 211 | 	struct lacp_markerinfo	lp_marker; |
| 212 | #define	lp_state	lp_actor.lip_state |
| 213 | #define	lp_key		lp_actor.lip_key |
| 214 | #define	lp_systemid	lp_actor.lip_systemid |
| 215 | 	struct timeval		lp_last_lacpdu; |
| 216 | 	int			lp_lacpdu_sent; |
| 217 | 	enum lacp_mux_state	lp_mux_state; |
| 218 | 	enum lacp_selected	lp_selected; |
| 219 | 	int			lp_flags; |
| 220 | 	u_int			lp_media; /* XXX redundant */ |
| 221 | 	int			lp_timer[LACP_NTIMER]; |
| 222 | 	struct mbuf_queue	lp_mq; |
| 223 | |
| 224 | 	struct lacp_aggregator	*lp_aggregator; |
| 225 | }; |
| 226 | |
| 227 | struct lacp_aggregator { |
| 228 | 	TAILQ_ENTRY(lacp_aggregator)	la_q; |
| 229 | 	int			la_refcnt; /* num of ports which selected us */ |
| 230 | 	int			la_nports; /* num of distributing ports */ |
| 231 | 	TAILQ_HEAD(, lacp_port)	la_ports; /* distributing ports */ |
| 232 | 	struct lacp_peerinfo	la_partner; |
| 233 | 	struct lacp_peerinfo	la_actor; |
| 234 | 	int			la_pending; /* number of ports in wait_while */ |
| 235 | }; |
| 236 | |
| 237 | struct lacp_admin_def { |
| 238 | 	u_int8_t		lad_mode; /* active or passive */ |
| 239 | 	u_int8_t		lad_timeout; /* fast or slow */ |
| 240 | 	u_int16_t		lad_prio; /* system priority */ |
| 241 | 	u_int16_t		lad_portprio; /* port priority */ |
| 242 | 	u_int8_t		lad_ifqprio; /* ifq priority */ |
| 243 | }; |
| 244 | |
| 245 | struct lacp_softc { |
| 246 | 	struct trunk_softc	*lsc_softc; |
| 247 | 	struct lacp_aggregator	*lsc_active_aggregator; |
| 248 | 	TAILQ_HEAD(, lacp_aggregator) lsc_aggregators; |
| 249 | 	int		lsc_suppress_distributing; |
| 250 | 	struct timeout		lsc_transit_callout; |
| 251 | 	struct timeout		lsc_callout; |
| 252 | 	LIST_HEAD(, lacp_port)	lsc_ports; |
| 253 | 	struct lacp_portmap	lsc_pmap[2]; |
| 254 | 	volatile u_int		lsc_activemap; |
| 255 | 	SIPHASH_KEY		lsc_hashkey; |
| 256 | 	struct task		lsc_input; |
| 257 | 	struct lacp_admin_def	lsc_admin_defaults; |
| 258 | #define lsc_mode		lsc_admin_defaults.lad_mode |
| 259 | #define lsc_timeout		lsc_admin_defaults.lad_timeout |
| 260 | #define lsc_sys_prio	lsc_admin_defaults.lad_prio |
| 261 | #define lsc_port_prio	lsc_admin_defaults.lad_portprio |
| 262 | #define lsc_ifq_prio	lsc_admin_defaults.lad_ifqprio |
| 263 | }; |
| 264 | |
| 265 | #define	LACP_TYPE_ACTORINFO	1 |
| 266 | #define	LACP_TYPE_PARTNERINFO	2 |
| 267 | #define	LACP_TYPE_COLLECTORINFO	3 |
| 268 | |
| 269 | /* timeout values (in sec) */ |
| 270 | #define	LACP_FAST_PERIODIC_TIME		(1) |
| 271 | #define	LACP_SLOW_PERIODIC_TIME		(30) |
| 272 | #define	LACP_SHORT_TIMEOUT_TIME		(3 * LACP_FAST_PERIODIC_TIME) |
| 273 | #define	LACP_LONG_TIMEOUT_TIME		(3 * LACP_SLOW_PERIODIC_TIME) |
| 274 | #define	LACP_CHURN_DETECTION_TIME	(60) |
| 275 | #define	LACP_AGGREGATE_WAIT_TIME	(2) |
| 276 | #define	LACP_TRANSIT_DELAY		3000	/* in msec */ |
| 277 | |
| 278 | #define	LACP_STATE_EQ(s1, s2, mask)	\ |
| 279 | 	((((s1) ^ (s2)) & (mask)) == 0) |
| 280 | |
| 281 | #define	LACP_SYS_PRI(peer)	(peer).lip_systemid.lsi_prio |
| 282 | |
| 283 | #define	LACP_PORT(_lp)	((struct lacp_port *)(_lp)->tp_psc) |
| 284 | #define	LACP_SOFTC(_sc)	((struct lacp_softc *)(_sc)->tr_psc) |
| 285 | |
| 286 | int		lacp_input(struct trunk_port *, struct mbuf *); |
| 287 | struct trunk_port *lacp_select_tx_port(struct trunk_softc *, struct mbuf *); |
| 288 | int		lacp_attach(struct trunk_softc *); |
| 289 | int		lacp_detach(struct trunk_softc *); |
| 290 | void		lacp_init(struct trunk_softc *); |
| 291 | void		lacp_stop(struct trunk_softc *); |
| 292 | int		lacp_port_create(struct trunk_port *); |
| 293 | void		lacp_port_destroy(struct trunk_port *); |
| 294 | void		lacp_linkstate(struct trunk_port *); |
| 295 | void		lacp_req(struct trunk_softc *, caddr_t); |
| 296 | void		lacp_portreq(struct trunk_port *, caddr_t); |
| 297 | u_int		lacp_port_status(struct trunk_port *); |
| 298 | |
| 299 | /* following constants don't include terminating NUL */ |
| 300 | #define	LACP_MACSTR_MAX		(2*6 + 5) |
| 301 | #define	LACP_SYSTEMPRIOSTR_MAX	(4) |
| 302 | #define	LACP_SYSTEMIDSTR_MAX	(LACP_SYSTEMPRIOSTR_MAX + 1 + LACP_MACSTR_MAX) |
| 303 | #define	LACP_PORTPRIOSTR_MAX	(4) |
| 304 | #define	LACP_PORTNOSTR_MAX	(4) |
| 305 | #define	LACP_PORTIDSTR_MAX	(LACP_PORTPRIOSTR_MAX + 1 + LACP_PORTNOSTR_MAX) |
| 306 | #define	LACP_KEYSTR_MAX		(4) |
| 307 | #define	LACP_PARTNERSTR_MAX	\ |
| 308 | 	(1 + LACP_SYSTEMIDSTR_MAX + 1 + LACP_KEYSTR_MAX + 1 \ |
| 309 | 	+ LACP_PORTIDSTR_MAX + 1) |
| 310 | #define	LACP_LAGIDSTR_MAX	\ |
| 311 | 	(1 + LACP_PARTNERSTR_MAX + 1 + LACP_PARTNERSTR_MAX + 1) |
| 312 | #define	LACP_STATESTR_MAX	(255) /* XXX */ |
| 313 | |
| 314 | #endif /* _KERNEL */ |
| 315 | |
| 316 | #endif /* _NET_TRUNKLACP_H_ */ |