ieee8023ad_lacp.h revision 177289
1210678Srpaulo/* $NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $ */ 2210678Srpaulo 3210678Srpaulo/*- 4210678Srpaulo * Copyright (c)2005 YAMAMOTO Takashi, 5210678Srpaulo * All rights reserved. 6210678Srpaulo * 7210678Srpaulo * Redistribution and use in source and binary forms, with or without 8210678Srpaulo * modification, are permitted provided that the following conditions 9210678Srpaulo * are met: 10210678Srpaulo * 1. Redistributions of source code must retain the above copyright 11210678Srpaulo * notice, this list of conditions and the following disclaimer. 12210678Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 13210678Srpaulo * notice, this list of conditions and the following disclaimer in the 14210678Srpaulo * documentation and/or other materials provided with the distribution. 15210678Srpaulo * 16210678Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17210678Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18210678Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19210678Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20210678Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21210678Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22210678Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23210678Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24210678Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25210678Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26210678Srpaulo * SUCH DAMAGE. 27210678Srpaulo * 28210678Srpaulo * $FreeBSD: head/sys/net/ieee8023ad_lacp.h 177289 2008-03-17 01:26:44Z thompsa $ 29210678Srpaulo */ 30210678Srpaulo 31210678Srpaulo/* 32210678Srpaulo * IEEE802.3ad LACP 33210678Srpaulo * 34210678Srpaulo * implementation details. 35210678Srpaulo */ 36210678Srpaulo 37210678Srpaulo#define LACP_TIMER_CURRENT_WHILE 0 38210678Srpaulo#define LACP_TIMER_PERIODIC 1 39210678Srpaulo#define LACP_TIMER_WAIT_WHILE 2 40210678Srpaulo#define LACP_NTIMER 3 41210678Srpaulo 42210678Srpaulo#define LACP_TIMER_ARM(port, timer, val) \ 43210678Srpaulo (port)->lp_timer[(timer)] = (val) 44210678Srpaulo#define LACP_TIMER_DISARM(port, timer) \ 45210678Srpaulo (port)->lp_timer[(timer)] = 0 46210678Srpaulo#define LACP_TIMER_ISARMED(port, timer) \ 47210769Suqs ((port)->lp_timer[(timer)] > 0) 48210678Srpaulo 49210678Srpaulo/* 50210678Srpaulo * IEEE802.3ad LACP 51269720Smarkj * 52210678Srpaulo * protocol definitions. 53210678Srpaulo */ 54210678Srpaulo 55210678Srpaulo#define LACP_STATE_ACTIVITY (1<<0) 56210678Srpaulo#define LACP_STATE_TIMEOUT (1<<1) 57210678Srpaulo#define LACP_STATE_AGGREGATION (1<<2) 58210678Srpaulo#define LACP_STATE_SYNC (1<<3) 59210678Srpaulo#define LACP_STATE_COLLECTING (1<<4) 60210678Srpaulo#define LACP_STATE_DISTRIBUTING (1<<5) 61210678Srpaulo#define LACP_STATE_DEFAULTED (1<<6) 62210678Srpaulo#define LACP_STATE_EXPIRED (1<<7) 63210678Srpaulo 64210678Srpaulo#define LACP_PORT_NTT 0x00000001 65210678Srpaulo#define LACP_PORT_MARK 0x00000002 66210678Srpaulo 67210678Srpaulo#define LACP_STATE_BITS \ 68210678Srpaulo "\020" \ 69210678Srpaulo "\001ACTIVITY" \ 70210678Srpaulo "\002TIMEOUT" \ 71210678Srpaulo "\003AGGREGATION" \ 72210678Srpaulo "\004SYNC" \ 73210678Srpaulo "\005COLLECTING" \ 74210678Srpaulo "\006DISTRIBUTING" \ 75210678Srpaulo "\007DEFAULTED" \ 76210678Srpaulo "\010EXPIRED" 77210678Srpaulo 78210678Srpaulo/* 79210678Srpaulo * IEEE802.3 slow protocols 80210678Srpaulo * 81210678Srpaulo * protocol (on-wire) definitions. 82210678Srpaulo * 83210678Srpaulo * XXX should be elsewhere. 84210678Srpaulo */ 85210678Srpaulo 86210678Srpaulo#define SLOWPROTOCOLS_SUBTYPE_LACP 1 87210769Suqs#define SLOWPROTOCOLS_SUBTYPE_MARKER 2 88210769Suqs 89210678Srpaulostruct slowprothdr { 90210678Srpaulo uint8_t sph_subtype; 91210678Srpaulo uint8_t sph_version; 92210678Srpaulo} __packed; 93210678Srpaulo 94210678Srpaulo/* 95210678Srpaulo * TLV on-wire structure. 96210678Srpaulo */ 97210678Srpaulo 98210678Srpaulostruct tlvhdr { 99210678Srpaulo uint8_t tlv_type; 100210678Srpaulo uint8_t tlv_length; 101210678Srpaulo /* uint8_t tlv_value[]; */ 102210678Srpaulo} __packed; 103210678Srpaulo 104210769Suqs/* 105210678Srpaulo * ... and our implementation. 106210678Srpaulo */ 107210678Srpaulo 108210678Srpaulo#define TLV_SET(tlv, type, length) \ 109210678Srpaulo do { \ 110210678Srpaulo (tlv)->tlv_type = (type); \ 111210678Srpaulo (tlv)->tlv_length = sizeof(*tlv) + (length); \ 112210678Srpaulo } while (/*CONSTCOND*/0) 113210678Srpaulo 114210678Srpaulostruct tlv_template { 115210678Srpaulo uint8_t tmpl_type; 116210678Srpaulo uint8_t tmpl_length; 117210678Srpaulo}; 118210678Srpaulo 119210678Srpaulostruct lacp_systemid { 120210678Srpaulo uint16_t lsi_prio; 121210678Srpaulo uint8_t lsi_mac[6]; 122210678Srpaulo} __packed; 123210678Srpaulo 124210678Srpaulostruct lacp_portid { 125210678Srpaulo uint16_t lpi_prio; 126210678Srpaulo uint16_t lpi_portno; 127210678Srpaulo} __packed; 128210678Srpaulo 129210678Srpaulostruct lacp_peerinfo { 130210678Srpaulo struct lacp_systemid lip_systemid; 131210678Srpaulo uint16_t lip_key; 132210678Srpaulo struct lacp_portid lip_portid; 133210678Srpaulo uint8_t lip_state; 134210823Sjoel uint8_t lip_resv[3]; 135210678Srpaulo} __packed; 136210678Srpaulo 137210678Srpaulostruct lacp_collectorinfo { 138210678Srpaulo uint16_t lci_maxdelay; 139210678Srpaulo uint8_t lci_resv[12]; 140210678Srpaulo} __packed; 141210678Srpaulo 142210678Srpaulostruct lacpdu { 143210678Srpaulo struct ether_header ldu_eh; 144210678Srpaulo struct slowprothdr ldu_sph; 145269720Smarkj 146210678Srpaulo struct tlvhdr ldu_tlv_actor; 147210823Sjoel struct lacp_peerinfo ldu_actor; 148269720Smarkj struct tlvhdr ldu_tlv_partner; 149210678Srpaulo struct lacp_peerinfo ldu_partner; 150210678Srpaulo struct tlvhdr ldu_tlv_collector; 151210823Sjoel struct lacp_collectorinfo ldu_collector; 152210678Srpaulo struct tlvhdr ldu_tlv_term; 153210678Srpaulo uint8_t ldu_resv[50]; 154210678Srpaulo} __packed; 155210678Srpaulo 156210678Srpaulo/* 157210678Srpaulo * IEEE802.3ad marker protocol 158210678Srpaulo * 159210678Srpaulo * protocol (on-wire) definitions. 160210678Srpaulo */ 161210678Srpaulostruct lacp_markerinfo { 162210678Srpaulo uint16_t mi_rq_port; 163210678Srpaulo uint8_t mi_rq_system[ETHER_ADDR_LEN]; 164210678Srpaulo uint32_t mi_rq_xid; 165210678Srpaulo uint8_t mi_pad[2]; 166210678Srpaulo} __packed; 167210678Srpaulo 168210678Srpaulostruct markerdu { 169210678Srpaulo struct ether_header mdu_eh; 170210678Srpaulo struct slowprothdr mdu_sph; 171210678Srpaulo 172210678Srpaulo struct tlvhdr mdu_tlv; 173210678Srpaulo struct lacp_markerinfo mdu_info; 174210769Suqs struct tlvhdr mdu_tlv_term; 175210678Srpaulo uint8_t mdu_resv[90]; 176210769Suqs} __packed; 177210678Srpaulo 178210678Srpaulo#define MARKER_TYPE_INFO 0x01 179210678Srpaulo#define MARKER_TYPE_RESPONSE 0x02 180210678Srpaulo 181210678Srpauloenum lacp_selected { 182210769Suqs LACP_UNSELECTED, 183210678Srpaulo LACP_STANDBY, /* not used in this implementation */ 184210769Suqs LACP_SELECTED, 185210769Suqs}; 186210769Suqs 187210769Suqsenum lacp_mux_state { 188210769Suqs LACP_MUX_DETACHED, 189210769Suqs LACP_MUX_WAITING, 190210769Suqs LACP_MUX_ATTACHED, 191210769Suqs LACP_MUX_COLLECTING, 192 LACP_MUX_DISTRIBUTING, 193}; 194 195#define LACP_MAX_PORTS 32 196 197struct lacp_portmap { 198 int pm_count; 199 struct lacp_port *pm_map[LACP_MAX_PORTS]; 200}; 201 202struct lacp_port { 203 TAILQ_ENTRY(lacp_port) lp_dist_q; 204 LIST_ENTRY(lacp_port) lp_next; 205 struct lacp_softc *lp_lsc; 206 struct lagg_port *lp_lagg; 207 struct ifnet *lp_ifp; 208 struct lacp_peerinfo lp_partner; 209 struct lacp_peerinfo lp_actor; 210 struct lacp_markerinfo lp_marker; 211#define lp_state lp_actor.lip_state 212#define lp_key lp_actor.lip_key 213#define lp_systemid lp_actor.lip_systemid 214 struct timeval lp_last_lacpdu; 215 int lp_lacpdu_sent; 216 enum lacp_mux_state lp_mux_state; 217 enum lacp_selected lp_selected; 218 int lp_flags; 219 u_int lp_media; /* XXX redundant */ 220 int lp_timer[LACP_NTIMER]; 221 struct ifmultiaddr *lp_ifma; 222 223 struct lacp_aggregator *lp_aggregator; 224}; 225 226struct lacp_aggregator { 227 TAILQ_ENTRY(lacp_aggregator) la_q; 228 int la_refcnt; /* num of ports which selected us */ 229 int la_nports; /* num of distributing ports */ 230 TAILQ_HEAD(, lacp_port) la_ports; /* distributing ports */ 231 struct lacp_peerinfo la_partner; 232 struct lacp_peerinfo la_actor; 233 int la_pending; /* number of ports in wait_while */ 234}; 235 236struct lacp_softc { 237 struct lagg_softc *lsc_softc; 238 struct mtx lsc_mtx; 239 struct lacp_aggregator *lsc_active_aggregator; 240 TAILQ_HEAD(, lacp_aggregator) lsc_aggregators; 241 boolean_t lsc_suppress_distributing; 242 struct callout lsc_transit_callout; 243 struct callout lsc_callout; 244 LIST_HEAD(, lacp_port) lsc_ports; 245 struct lacp_portmap lsc_pmap[2]; 246 volatile u_int lsc_activemap; 247 u_int32_t lsc_hashkey; 248}; 249 250#define LACP_TYPE_ACTORINFO 1 251#define LACP_TYPE_PARTNERINFO 2 252#define LACP_TYPE_COLLECTORINFO 3 253 254/* timeout values (in sec) */ 255#define LACP_FAST_PERIODIC_TIME (1) 256#define LACP_SLOW_PERIODIC_TIME (30) 257#define LACP_SHORT_TIMEOUT_TIME (3 * LACP_FAST_PERIODIC_TIME) 258#define LACP_LONG_TIMEOUT_TIME (3 * LACP_SLOW_PERIODIC_TIME) 259#define LACP_CHURN_DETECTION_TIME (60) 260#define LACP_AGGREGATE_WAIT_TIME (2) 261#define LACP_TRANSIT_DELAY 3000 /* in msec */ 262 263#define LACP_STATE_EQ(s1, s2, mask) \ 264 ((((s1) ^ (s2)) & (mask)) == 0) 265 266#define LACP_SYS_PRI(peer) (peer).lip_systemid.lsi_prio 267 268#define LACP_PORT(_lp) ((struct lacp_port *)(_lp)->lp_psc) 269#define LACP_SOFTC(_sc) ((struct lacp_softc *)(_sc)->sc_psc) 270 271#define LACP_LOCK_INIT(_lsc) mtx_init(&(_lsc)->lsc_mtx, \ 272 "lacp mtx", NULL, MTX_DEF) 273#define LACP_LOCK_DESTROY(_lsc) mtx_destroy(&(_lsc)->lsc_mtx) 274#define LACP_LOCK(_lsc) mtx_lock(&(_lsc)->lsc_mtx) 275#define LACP_UNLOCK(_lsc) mtx_unlock(&(_lsc)->lsc_mtx) 276#define LACP_LOCK_ASSERT(_lsc) mtx_assert(&(_lsc)->lsc_mtx, MA_OWNED) 277 278struct mbuf *lacp_input(struct lagg_port *, struct mbuf *); 279struct lagg_port *lacp_select_tx_port(struct lagg_softc *, struct mbuf *); 280int lacp_attach(struct lagg_softc *); 281int lacp_detach(struct lagg_softc *); 282void lacp_init(struct lagg_softc *); 283void lacp_stop(struct lagg_softc *); 284int lacp_port_create(struct lagg_port *); 285void lacp_port_destroy(struct lagg_port *); 286void lacp_linkstate(struct lagg_port *); 287void lacp_req(struct lagg_softc *, caddr_t); 288void lacp_portreq(struct lagg_port *, caddr_t); 289 290static __inline int 291lacp_isactive(struct lagg_port *lgp) 292{ 293 struct lacp_port *lp = LACP_PORT(lgp); 294 struct lacp_softc *lsc = lp->lp_lsc; 295 struct lacp_aggregator *la = lp->lp_aggregator; 296 297 /* This port is joined to the active aggregator */ 298 if (la != NULL && la == lsc->lsc_active_aggregator) 299 return (1); 300 301 return (0); 302} 303 304static __inline int 305lacp_iscollecting(struct lagg_port *lgp) 306{ 307 struct lacp_port *lp = LACP_PORT(lgp); 308 309 return ((lp->lp_state & LACP_STATE_COLLECTING) != 0); 310} 311 312static __inline int 313lacp_isdistributing(struct lagg_port *lgp) 314{ 315 struct lacp_port *lp = LACP_PORT(lgp); 316 317 return ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0); 318} 319 320/* following constants don't include terminating NUL */ 321#define LACP_MACSTR_MAX (2*6 + 5) 322#define LACP_SYSTEMPRIOSTR_MAX (4) 323#define LACP_SYSTEMIDSTR_MAX (LACP_SYSTEMPRIOSTR_MAX + 1 + LACP_MACSTR_MAX) 324#define LACP_PORTPRIOSTR_MAX (4) 325#define LACP_PORTNOSTR_MAX (4) 326#define LACP_PORTIDSTR_MAX (LACP_PORTPRIOSTR_MAX + 1 + LACP_PORTNOSTR_MAX) 327#define LACP_KEYSTR_MAX (4) 328#define LACP_PARTNERSTR_MAX \ 329 (1 + LACP_SYSTEMIDSTR_MAX + 1 + LACP_KEYSTR_MAX + 1 \ 330 + LACP_PORTIDSTR_MAX + 1) 331#define LACP_LAGIDSTR_MAX \ 332 (1 + LACP_PARTNERSTR_MAX + 1 + LACP_PARTNERSTR_MAX + 1) 333#define LACP_STATESTR_MAX (255) /* XXX */ 334