1b47888ceSAndrew Thompson /* $NetBSD: ieee8023ad_impl.h,v 1.2 2005/12/10 23:21:39 elad Exp $ */ 2b47888ceSAndrew Thompson 3b47888ceSAndrew Thompson /*- 4b47888ceSAndrew Thompson * Copyright (c)2005 YAMAMOTO Takashi, 5b47888ceSAndrew Thompson * All rights reserved. 6b47888ceSAndrew Thompson * 7b47888ceSAndrew Thompson * Redistribution and use in source and binary forms, with or without 8b47888ceSAndrew Thompson * modification, are permitted provided that the following conditions 9b47888ceSAndrew Thompson * are met: 10b47888ceSAndrew Thompson * 1. Redistributions of source code must retain the above copyright 11b47888ceSAndrew Thompson * notice, this list of conditions and the following disclaimer. 12b47888ceSAndrew Thompson * 2. Redistributions in binary form must reproduce the above copyright 13b47888ceSAndrew Thompson * notice, this list of conditions and the following disclaimer in the 14b47888ceSAndrew Thompson * documentation and/or other materials provided with the distribution. 15b47888ceSAndrew Thompson * 16b47888ceSAndrew Thompson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17b47888ceSAndrew Thompson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18b47888ceSAndrew Thompson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19b47888ceSAndrew Thompson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20b47888ceSAndrew Thompson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b47888ceSAndrew Thompson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22b47888ceSAndrew Thompson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23b47888ceSAndrew Thompson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24b47888ceSAndrew Thompson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25b47888ceSAndrew Thompson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26b47888ceSAndrew Thompson * SUCH DAMAGE. 27b47888ceSAndrew Thompson * 28b47888ceSAndrew Thompson * $FreeBSD$ 29b47888ceSAndrew Thompson */ 30b47888ceSAndrew Thompson 31b47888ceSAndrew Thompson /* 32b47888ceSAndrew Thompson * IEEE802.3ad LACP 33b47888ceSAndrew Thompson * 34b47888ceSAndrew Thompson * implementation details. 35b47888ceSAndrew Thompson */ 36b47888ceSAndrew Thompson 37b47888ceSAndrew Thompson #define LACP_TIMER_CURRENT_WHILE 0 38b47888ceSAndrew Thompson #define LACP_TIMER_PERIODIC 1 39b47888ceSAndrew Thompson #define LACP_TIMER_WAIT_WHILE 2 40b47888ceSAndrew Thompson #define LACP_NTIMER 3 41b47888ceSAndrew Thompson 42b47888ceSAndrew Thompson #define LACP_TIMER_ARM(port, timer, val) \ 43b47888ceSAndrew Thompson (port)->lp_timer[(timer)] = (val) 44b47888ceSAndrew Thompson #define LACP_TIMER_DISARM(port, timer) \ 45b47888ceSAndrew Thompson (port)->lp_timer[(timer)] = 0 46b47888ceSAndrew Thompson #define LACP_TIMER_ISARMED(port, timer) \ 47b47888ceSAndrew Thompson ((port)->lp_timer[(timer)] > 0) 48b47888ceSAndrew Thompson 49b47888ceSAndrew Thompson /* 50b47888ceSAndrew Thompson * IEEE802.3ad LACP 51b47888ceSAndrew Thompson * 52b47888ceSAndrew Thompson * protocol definitions. 53b47888ceSAndrew Thompson */ 54b47888ceSAndrew Thompson 55b47888ceSAndrew Thompson #define LACP_STATE_ACTIVITY (1<<0) 56b47888ceSAndrew Thompson #define LACP_STATE_TIMEOUT (1<<1) 57b47888ceSAndrew Thompson #define LACP_STATE_AGGREGATION (1<<2) 58b47888ceSAndrew Thompson #define LACP_STATE_SYNC (1<<3) 59b47888ceSAndrew Thompson #define LACP_STATE_COLLECTING (1<<4) 60b47888ceSAndrew Thompson #define LACP_STATE_DISTRIBUTING (1<<5) 61b47888ceSAndrew Thompson #define LACP_STATE_DEFAULTED (1<<6) 62b47888ceSAndrew Thompson #define LACP_STATE_EXPIRED (1<<7) 63b47888ceSAndrew Thompson 64b47888ceSAndrew Thompson #define LACP_PORT_NTT 0x00000001 65998971a7SAndrew Thompson #define LACP_PORT_MARK 0x00000002 66b47888ceSAndrew Thompson 67b47888ceSAndrew Thompson #define LACP_STATE_BITS \ 68b47888ceSAndrew Thompson "\020" \ 69b47888ceSAndrew Thompson "\001ACTIVITY" \ 70b47888ceSAndrew Thompson "\002TIMEOUT" \ 71b47888ceSAndrew Thompson "\003AGGREGATION" \ 72b47888ceSAndrew Thompson "\004SYNC" \ 73b47888ceSAndrew Thompson "\005COLLECTING" \ 74b47888ceSAndrew Thompson "\006DISTRIBUTING" \ 75b47888ceSAndrew Thompson "\007DEFAULTED" \ 76b47888ceSAndrew Thompson "\010EXPIRED" 77b47888ceSAndrew Thompson 78b47888ceSAndrew Thompson /* 79b47888ceSAndrew Thompson * IEEE802.3 slow protocols 80b47888ceSAndrew Thompson * 81b47888ceSAndrew Thompson * protocol (on-wire) definitions. 82b47888ceSAndrew Thompson * 83b47888ceSAndrew Thompson * XXX should be elsewhere. 84b47888ceSAndrew Thompson */ 85b47888ceSAndrew Thompson 86b47888ceSAndrew Thompson #define SLOWPROTOCOLS_SUBTYPE_LACP 1 87b47888ceSAndrew Thompson #define SLOWPROTOCOLS_SUBTYPE_MARKER 2 88b47888ceSAndrew Thompson 89b47888ceSAndrew Thompson struct slowprothdr { 90b47888ceSAndrew Thompson uint8_t sph_subtype; 91b47888ceSAndrew Thompson uint8_t sph_version; 92b47888ceSAndrew Thompson } __packed; 93b47888ceSAndrew Thompson 94b47888ceSAndrew Thompson /* 95b47888ceSAndrew Thompson * TLV on-wire structure. 96b47888ceSAndrew Thompson */ 97b47888ceSAndrew Thompson 98b47888ceSAndrew Thompson struct tlvhdr { 99b47888ceSAndrew Thompson uint8_t tlv_type; 100b47888ceSAndrew Thompson uint8_t tlv_length; 101b47888ceSAndrew Thompson /* uint8_t tlv_value[]; */ 102b47888ceSAndrew Thompson } __packed; 103b47888ceSAndrew Thompson 104b47888ceSAndrew Thompson /* 105b47888ceSAndrew Thompson * ... and our implementation. 106b47888ceSAndrew Thompson */ 107b47888ceSAndrew Thompson 108b47888ceSAndrew Thompson #define TLV_SET(tlv, type, length) \ 109b47888ceSAndrew Thompson do { \ 110b47888ceSAndrew Thompson (tlv)->tlv_type = (type); \ 111b47888ceSAndrew Thompson (tlv)->tlv_length = sizeof(*tlv) + (length); \ 112b47888ceSAndrew Thompson } while (/*CONSTCOND*/0) 113b47888ceSAndrew Thompson 114b47888ceSAndrew Thompson struct tlv_template { 115b47888ceSAndrew Thompson uint8_t tmpl_type; 116b47888ceSAndrew Thompson uint8_t tmpl_length; 117b47888ceSAndrew Thompson }; 118b47888ceSAndrew Thompson 119b47888ceSAndrew Thompson struct lacp_systemid { 120b47888ceSAndrew Thompson uint16_t lsi_prio; 121b47888ceSAndrew Thompson uint8_t lsi_mac[6]; 122b47888ceSAndrew Thompson } __packed; 123b47888ceSAndrew Thompson 124b47888ceSAndrew Thompson struct lacp_portid { 125b47888ceSAndrew Thompson uint16_t lpi_prio; 126b47888ceSAndrew Thompson uint16_t lpi_portno; 127b47888ceSAndrew Thompson } __packed; 128b47888ceSAndrew Thompson 129b47888ceSAndrew Thompson struct lacp_peerinfo { 130b47888ceSAndrew Thompson struct lacp_systemid lip_systemid; 131b47888ceSAndrew Thompson uint16_t lip_key; 132b47888ceSAndrew Thompson struct lacp_portid lip_portid; 133b47888ceSAndrew Thompson uint8_t lip_state; 134b47888ceSAndrew Thompson uint8_t lip_resv[3]; 135b47888ceSAndrew Thompson } __packed; 136b47888ceSAndrew Thompson 137b47888ceSAndrew Thompson struct lacp_collectorinfo { 138b47888ceSAndrew Thompson uint16_t lci_maxdelay; 139b47888ceSAndrew Thompson uint8_t lci_resv[12]; 140b47888ceSAndrew Thompson } __packed; 141b47888ceSAndrew Thompson 142b47888ceSAndrew Thompson struct lacpdu { 143b47888ceSAndrew Thompson struct ether_header ldu_eh; 144b47888ceSAndrew Thompson struct slowprothdr ldu_sph; 145b47888ceSAndrew Thompson 146b47888ceSAndrew Thompson struct tlvhdr ldu_tlv_actor; 147b47888ceSAndrew Thompson struct lacp_peerinfo ldu_actor; 148b47888ceSAndrew Thompson struct tlvhdr ldu_tlv_partner; 149b47888ceSAndrew Thompson struct lacp_peerinfo ldu_partner; 150b47888ceSAndrew Thompson struct tlvhdr ldu_tlv_collector; 151b47888ceSAndrew Thompson struct lacp_collectorinfo ldu_collector; 152b47888ceSAndrew Thompson struct tlvhdr ldu_tlv_term; 153b47888ceSAndrew Thompson uint8_t ldu_resv[50]; 154b47888ceSAndrew Thompson } __packed; 155b47888ceSAndrew Thompson 156998971a7SAndrew Thompson /* 157998971a7SAndrew Thompson * IEEE802.3ad marker protocol 158998971a7SAndrew Thompson * 159998971a7SAndrew Thompson * protocol (on-wire) definitions. 160998971a7SAndrew Thompson */ 161998971a7SAndrew Thompson struct lacp_markerinfo { 162998971a7SAndrew Thompson uint16_t mi_rq_port; 163998971a7SAndrew Thompson uint8_t mi_rq_system[ETHER_ADDR_LEN]; 164998971a7SAndrew Thompson uint32_t mi_rq_xid; 165998971a7SAndrew Thompson uint8_t mi_pad[2]; 166998971a7SAndrew Thompson } __packed; 167998971a7SAndrew Thompson 168998971a7SAndrew Thompson struct markerdu { 169998971a7SAndrew Thompson struct ether_header mdu_eh; 170998971a7SAndrew Thompson struct slowprothdr mdu_sph; 171998971a7SAndrew Thompson 172998971a7SAndrew Thompson struct tlvhdr mdu_tlv; 173998971a7SAndrew Thompson struct lacp_markerinfo mdu_info; 174998971a7SAndrew Thompson struct tlvhdr mdu_tlv_term; 175998971a7SAndrew Thompson uint8_t mdu_resv[90]; 176998971a7SAndrew Thompson } __packed; 177998971a7SAndrew Thompson 178998971a7SAndrew Thompson #define MARKER_TYPE_INFO 0x01 179998971a7SAndrew Thompson #define MARKER_TYPE_RESPONSE 0x02 180b47888ceSAndrew Thompson 181b47888ceSAndrew Thompson enum lacp_selected { 182b47888ceSAndrew Thompson LACP_UNSELECTED, 183b47888ceSAndrew Thompson LACP_STANDBY, /* not used in this implementation */ 184b47888ceSAndrew Thompson LACP_SELECTED, 185b47888ceSAndrew Thompson }; 186b47888ceSAndrew Thompson 187b47888ceSAndrew Thompson enum lacp_mux_state { 188b47888ceSAndrew Thompson LACP_MUX_DETACHED, 189b47888ceSAndrew Thompson LACP_MUX_WAITING, 190b47888ceSAndrew Thompson LACP_MUX_ATTACHED, 191b47888ceSAndrew Thompson LACP_MUX_COLLECTING, 192b47888ceSAndrew Thompson LACP_MUX_DISTRIBUTING, 193b47888ceSAndrew Thompson }; 194b47888ceSAndrew Thompson 1953de18008SAndrew Thompson #define LACP_MAX_PORTS 32 1963de18008SAndrew Thompson 1973de18008SAndrew Thompson struct lacp_portmap { 1983de18008SAndrew Thompson int pm_count; 1993de18008SAndrew Thompson struct lacp_port *pm_map[LACP_MAX_PORTS]; 2003de18008SAndrew Thompson }; 2013de18008SAndrew Thompson 202b47888ceSAndrew Thompson struct lacp_port { 203b47888ceSAndrew Thompson TAILQ_ENTRY(lacp_port) lp_dist_q; 204b47888ceSAndrew Thompson LIST_ENTRY(lacp_port) lp_next; 205b47888ceSAndrew Thompson struct lacp_softc *lp_lsc; 20618242d3bSAndrew Thompson struct lagg_port *lp_lagg; 207b47888ceSAndrew Thompson struct ifnet *lp_ifp; 208b47888ceSAndrew Thompson struct lacp_peerinfo lp_partner; 209b47888ceSAndrew Thompson struct lacp_peerinfo lp_actor; 210998971a7SAndrew Thompson struct lacp_markerinfo lp_marker; 211b47888ceSAndrew Thompson #define lp_state lp_actor.lip_state 212b47888ceSAndrew Thompson #define lp_key lp_actor.lip_key 213998971a7SAndrew Thompson #define lp_systemid lp_actor.lip_systemid 214b47888ceSAndrew Thompson struct timeval lp_last_lacpdu; 215b47888ceSAndrew Thompson int lp_lacpdu_sent; 216b47888ceSAndrew Thompson enum lacp_mux_state lp_mux_state; 217b47888ceSAndrew Thompson enum lacp_selected lp_selected; 218b47888ceSAndrew Thompson int lp_flags; 219b47888ceSAndrew Thompson u_int lp_media; /* XXX redundant */ 220b47888ceSAndrew Thompson int lp_timer[LACP_NTIMER]; 221d74fd345SAndrew Thompson struct ifmultiaddr *lp_ifma; 222b47888ceSAndrew Thompson 223b47888ceSAndrew Thompson struct lacp_aggregator *lp_aggregator; 224b47888ceSAndrew Thompson }; 225b47888ceSAndrew Thompson 226b47888ceSAndrew Thompson struct lacp_aggregator { 227b47888ceSAndrew Thompson TAILQ_ENTRY(lacp_aggregator) la_q; 228b47888ceSAndrew Thompson int la_refcnt; /* num of ports which selected us */ 229b47888ceSAndrew Thompson int la_nports; /* num of distributing ports */ 230b47888ceSAndrew Thompson TAILQ_HEAD(, lacp_port) la_ports; /* distributing ports */ 231b47888ceSAndrew Thompson struct lacp_peerinfo la_partner; 232b47888ceSAndrew Thompson struct lacp_peerinfo la_actor; 233ec32b37eSAndrew Thompson int la_pending; /* number of ports in wait_while */ 234b47888ceSAndrew Thompson }; 235b47888ceSAndrew Thompson 236b47888ceSAndrew Thompson struct lacp_softc { 237ec32b37eSAndrew Thompson struct lagg_softc *lsc_softc; 2383de18008SAndrew Thompson struct mtx lsc_mtx; 239b47888ceSAndrew Thompson struct lacp_aggregator *lsc_active_aggregator; 240b47888ceSAndrew Thompson TAILQ_HEAD(, lacp_aggregator) lsc_aggregators; 241b47888ceSAndrew Thompson boolean_t lsc_suppress_distributing; 242b47888ceSAndrew Thompson struct callout lsc_transit_callout; 243b47888ceSAndrew Thompson struct callout lsc_callout; 244b47888ceSAndrew Thompson LIST_HEAD(, lacp_port) lsc_ports; 2453de18008SAndrew Thompson struct lacp_portmap lsc_pmap[2]; 2463de18008SAndrew Thompson volatile u_int lsc_activemap; 247b47888ceSAndrew Thompson u_int32_t lsc_hashkey; 248*49de4f22SAdrian Chadd struct { 249*49de4f22SAdrian Chadd u_int32_t lsc_rx_test; 250*49de4f22SAdrian Chadd u_int32_t lsc_tx_test; 251*49de4f22SAdrian Chadd } lsc_debug; 252*49de4f22SAdrian Chadd u_int32_t lsc_strict_mode; 253b47888ceSAndrew Thompson }; 254b47888ceSAndrew Thompson 255b47888ceSAndrew Thompson #define LACP_TYPE_ACTORINFO 1 256b47888ceSAndrew Thompson #define LACP_TYPE_PARTNERINFO 2 257b47888ceSAndrew Thompson #define LACP_TYPE_COLLECTORINFO 3 258b47888ceSAndrew Thompson 259b47888ceSAndrew Thompson /* timeout values (in sec) */ 260b47888ceSAndrew Thompson #define LACP_FAST_PERIODIC_TIME (1) 261b47888ceSAndrew Thompson #define LACP_SLOW_PERIODIC_TIME (30) 262b47888ceSAndrew Thompson #define LACP_SHORT_TIMEOUT_TIME (3 * LACP_FAST_PERIODIC_TIME) 263b47888ceSAndrew Thompson #define LACP_LONG_TIMEOUT_TIME (3 * LACP_SLOW_PERIODIC_TIME) 264b47888ceSAndrew Thompson #define LACP_CHURN_DETECTION_TIME (60) 265b47888ceSAndrew Thompson #define LACP_AGGREGATE_WAIT_TIME (2) 266998971a7SAndrew Thompson #define LACP_TRANSIT_DELAY 3000 /* in msec */ 267b47888ceSAndrew Thompson 268b47888ceSAndrew Thompson #define LACP_STATE_EQ(s1, s2, mask) \ 269b47888ceSAndrew Thompson ((((s1) ^ (s2)) & (mask)) == 0) 270b47888ceSAndrew Thompson 271fe45e65fSAndrew Thompson #define LACP_SYS_PRI(peer) (peer).lip_systemid.lsi_prio 272fe45e65fSAndrew Thompson 27318242d3bSAndrew Thompson #define LACP_PORT(_lp) ((struct lacp_port *)(_lp)->lp_psc) 27418242d3bSAndrew Thompson #define LACP_SOFTC(_sc) ((struct lacp_softc *)(_sc)->sc_psc) 275b47888ceSAndrew Thompson 2763de18008SAndrew Thompson #define LACP_LOCK_INIT(_lsc) mtx_init(&(_lsc)->lsc_mtx, \ 27769f04a82SAndrew Thompson "lacp mtx", NULL, MTX_DEF) 27869f04a82SAndrew Thompson #define LACP_LOCK_DESTROY(_lsc) mtx_destroy(&(_lsc)->lsc_mtx) 2793de18008SAndrew Thompson #define LACP_LOCK(_lsc) mtx_lock(&(_lsc)->lsc_mtx) 2803de18008SAndrew Thompson #define LACP_UNLOCK(_lsc) mtx_unlock(&(_lsc)->lsc_mtx) 2813de18008SAndrew Thompson #define LACP_LOCK_ASSERT(_lsc) mtx_assert(&(_lsc)->lsc_mtx, MA_OWNED) 2823de18008SAndrew Thompson 283af0084c9SAndrew Thompson struct mbuf *lacp_input(struct lagg_port *, struct mbuf *); 28418242d3bSAndrew Thompson struct lagg_port *lacp_select_tx_port(struct lagg_softc *, struct mbuf *); 28518242d3bSAndrew Thompson int lacp_attach(struct lagg_softc *); 28618242d3bSAndrew Thompson int lacp_detach(struct lagg_softc *); 28718242d3bSAndrew Thompson void lacp_init(struct lagg_softc *); 28818242d3bSAndrew Thompson void lacp_stop(struct lagg_softc *); 28918242d3bSAndrew Thompson int lacp_port_create(struct lagg_port *); 29018242d3bSAndrew Thompson void lacp_port_destroy(struct lagg_port *); 29118242d3bSAndrew Thompson void lacp_linkstate(struct lagg_port *); 292b3d37ca5SAndrew Thompson void lacp_req(struct lagg_softc *, caddr_t); 293b3d37ca5SAndrew Thompson void lacp_portreq(struct lagg_port *, caddr_t); 294b47888ceSAndrew Thompson 2953de18008SAndrew Thompson static __inline int 2963de18008SAndrew Thompson lacp_isactive(struct lagg_port *lgp) 2973de18008SAndrew Thompson { 2983de18008SAndrew Thompson struct lacp_port *lp = LACP_PORT(lgp); 2993de18008SAndrew Thompson struct lacp_softc *lsc = lp->lp_lsc; 3003de18008SAndrew Thompson struct lacp_aggregator *la = lp->lp_aggregator; 3013de18008SAndrew Thompson 3023de18008SAndrew Thompson /* This port is joined to the active aggregator */ 3033de18008SAndrew Thompson if (la != NULL && la == lsc->lsc_active_aggregator) 3043de18008SAndrew Thompson return (1); 3053de18008SAndrew Thompson 3063de18008SAndrew Thompson return (0); 3073de18008SAndrew Thompson } 3083de18008SAndrew Thompson 3093de18008SAndrew Thompson static __inline int 3103de18008SAndrew Thompson lacp_iscollecting(struct lagg_port *lgp) 3113de18008SAndrew Thompson { 3123de18008SAndrew Thompson struct lacp_port *lp = LACP_PORT(lgp); 3133de18008SAndrew Thompson 3143de18008SAndrew Thompson return ((lp->lp_state & LACP_STATE_COLLECTING) != 0); 3153de18008SAndrew Thompson } 3163de18008SAndrew Thompson 3173de18008SAndrew Thompson static __inline int 3183de18008SAndrew Thompson lacp_isdistributing(struct lagg_port *lgp) 3193de18008SAndrew Thompson { 3203de18008SAndrew Thompson struct lacp_port *lp = LACP_PORT(lgp); 3213de18008SAndrew Thompson 3223de18008SAndrew Thompson return ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0); 3233de18008SAndrew Thompson } 3243de18008SAndrew Thompson 325b47888ceSAndrew Thompson /* following constants don't include terminating NUL */ 326b47888ceSAndrew Thompson #define LACP_MACSTR_MAX (2*6 + 5) 327b47888ceSAndrew Thompson #define LACP_SYSTEMPRIOSTR_MAX (4) 328b47888ceSAndrew Thompson #define LACP_SYSTEMIDSTR_MAX (LACP_SYSTEMPRIOSTR_MAX + 1 + LACP_MACSTR_MAX) 329b47888ceSAndrew Thompson #define LACP_PORTPRIOSTR_MAX (4) 330b47888ceSAndrew Thompson #define LACP_PORTNOSTR_MAX (4) 331b47888ceSAndrew Thompson #define LACP_PORTIDSTR_MAX (LACP_PORTPRIOSTR_MAX + 1 + LACP_PORTNOSTR_MAX) 332b47888ceSAndrew Thompson #define LACP_KEYSTR_MAX (4) 333b47888ceSAndrew Thompson #define LACP_PARTNERSTR_MAX \ 334b47888ceSAndrew Thompson (1 + LACP_SYSTEMIDSTR_MAX + 1 + LACP_KEYSTR_MAX + 1 \ 335b47888ceSAndrew Thompson + LACP_PORTIDSTR_MAX + 1) 336b47888ceSAndrew Thompson #define LACP_LAGIDSTR_MAX \ 337b47888ceSAndrew Thompson (1 + LACP_PARTNERSTR_MAX + 1 + LACP_PARTNERSTR_MAX + 1) 338b47888ceSAndrew Thompson #define LACP_STATESTR_MAX (255) /* XXX */ 339