1/* 2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* 30 * lacp.h 31 * - definitions for the Link Aggregation Control Protocol (LACP) and 32 * the Link Aggregation Marker Protocol 33 */ 34 35/* 36 * Modification History 37 * 38 * May 14, 2004 Dieter Siegmund (dieter@apple.com) 39 * - created 40 */ 41 42#ifndef _NET_LACP_H_ 43#define _NET_LACP_H_ 44 45#include <sys/types.h> 46#include <string.h> 47 48/** 49 ** Link Aggregation Control Protocol (LACP) definitions 50 **/ 51#define LACPDU_VERSION_1 1 52 53#define LACPDU_TLV_TYPE_TERMINATOR 0x00 54#define LACPDU_TLV_TYPE_ACTOR 0x01 55#define LACPDU_TLV_TYPE_PARTNER 0x02 56#define LACPDU_TLV_TYPE_COLLECTOR 0x03 57 58#define LACPDU_ACTOR_TLV_LENGTH 20 59#define LACPDU_PARTNER_TLV_LENGTH 20 60#define LACPDU_COLLECTOR_TLV_LENGTH 16 61 62typedef u_char lacp_actor_partner_state; 63typedef u_int16_t lacp_key; 64typedef u_int16_t lacp_system_priority, lacp_port_priority, lacp_port; 65typedef u_int16_t lacp_collector_max_delay; 66typedef struct { 67 u_char system_id[6]; 68} lacp_system, *lacp_system_ref; 69 70/* 71 * LACP Actor/Partner TLV 72 */ 73typedef struct lacp_actor_partner_tlv_s { 74 u_char lap_tlv_type; /* 0x01 or 0x02 */ 75 u_char lap_length; /* 20 */ 76 u_char lap_system_priority[2]; 77 u_char lap_system[6]; 78 u_char lap_key[2]; 79 u_char lap_port_priority[2]; 80 u_char lap_port[2]; 81 u_char lap_state; 82 u_char lap_reserved[3]; 83} lacp_actor_partner_tlv, *lacp_actor_partner_tlv_ref; 84 85/* 86 * LACP Collector TLV 87 */ 88typedef struct lacp_collector_tlv_s { 89 u_char lac_tlv_type; /* 0x03 */ 90 u_char lac_length; /* 16 */ 91 u_char lac_max_delay[2]; 92 u_char lac_reserved[12]; 93} lacp_collector_tlv, *lacp_collector_tlv_ref; 94 95 96/* 97 * LACP Actor/Partner State bits 98 */ 99#define LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY 0x01 100#define LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT 0x02 101#define LACP_ACTOR_PARTNER_STATE_AGGREGATION 0x04 102#define LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION 0x08 103#define LACP_ACTOR_PARTNER_STATE_COLLECTING 0x10 104#define LACP_ACTOR_PARTNER_STATE_DISTRIBUTING 0x20 105#define LACP_ACTOR_PARTNER_STATE_DEFAULTED 0x40 106#define LACP_ACTOR_PARTNER_STATE_EXPIRED 0x80 107 108static __inline__ lacp_actor_partner_state 109lacp_actor_partner_state_set_active_lacp(lacp_actor_partner_state state) 110{ 111 return (state | LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY); 112} 113 114static __inline__ lacp_actor_partner_state 115lacp_actor_partner_state_set_passive_lacp(lacp_actor_partner_state state) 116{ 117 return (state &= ~LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY); 118} 119 120static __inline__ int 121lacp_actor_partner_state_active_lacp(lacp_actor_partner_state state) 122{ 123 return ((state & LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY) != 0); 124} 125 126static __inline__ lacp_actor_partner_state 127lacp_actor_partner_state_set_short_timeout(lacp_actor_partner_state state) 128{ 129 return (state | LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT); 130} 131 132static __inline__ lacp_actor_partner_state 133lacp_actor_partner_state_set_long_timeout(lacp_actor_partner_state state) 134{ 135 return (state &= ~LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT); 136} 137 138static __inline__ int 139lacp_actor_partner_state_short_timeout(lacp_actor_partner_state state) 140{ 141 return ((state & LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT) != 0); 142} 143 144static __inline__ lacp_actor_partner_state 145lacp_actor_partner_state_set_aggregatable(lacp_actor_partner_state state) 146{ 147 return (state | LACP_ACTOR_PARTNER_STATE_AGGREGATION); 148} 149 150static __inline__ lacp_actor_partner_state 151lacp_actor_partner_state_set_individual(lacp_actor_partner_state state) 152{ 153 return (state &= ~LACP_ACTOR_PARTNER_STATE_AGGREGATION); 154} 155 156static __inline__ lacp_actor_partner_state 157lacp_actor_partner_state_aggregatable(lacp_actor_partner_state state) 158{ 159 return ((state & LACP_ACTOR_PARTNER_STATE_AGGREGATION) != 0); 160} 161 162static __inline__ lacp_actor_partner_state 163lacp_actor_partner_state_set_in_sync(lacp_actor_partner_state state) 164{ 165 return (state | LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION); 166} 167 168static __inline__ lacp_actor_partner_state 169lacp_actor_partner_state_set_out_of_sync(lacp_actor_partner_state state) 170{ 171 return (state &= ~LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION); 172} 173 174static __inline__ int 175lacp_actor_partner_state_in_sync(lacp_actor_partner_state state) 176{ 177 return ((state & LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION) != 0); 178} 179 180static __inline__ lacp_actor_partner_state 181lacp_actor_partner_state_set_collecting(lacp_actor_partner_state state) 182{ 183 return (state | LACP_ACTOR_PARTNER_STATE_COLLECTING); 184} 185 186static __inline__ lacp_actor_partner_state 187lacp_actor_partner_state_set_not_collecting(lacp_actor_partner_state state) 188{ 189 return (state &= ~LACP_ACTOR_PARTNER_STATE_COLLECTING); 190} 191 192static __inline__ lacp_actor_partner_state 193lacp_actor_partner_state_collecting(lacp_actor_partner_state state) 194{ 195 return ((state & LACP_ACTOR_PARTNER_STATE_COLLECTING) != 0); 196} 197 198static __inline__ lacp_actor_partner_state 199lacp_actor_partner_state_set_distributing(lacp_actor_partner_state state) 200{ 201 return (state | LACP_ACTOR_PARTNER_STATE_DISTRIBUTING); 202} 203 204static __inline__ lacp_actor_partner_state 205lacp_actor_partner_state_set_not_distributing(lacp_actor_partner_state state) 206{ 207 return (state &= ~LACP_ACTOR_PARTNER_STATE_DISTRIBUTING); 208} 209 210static __inline__ lacp_actor_partner_state 211lacp_actor_partner_state_distributing(lacp_actor_partner_state state) 212{ 213 return ((state & LACP_ACTOR_PARTNER_STATE_DISTRIBUTING) != 0); 214} 215 216static __inline__ lacp_actor_partner_state 217lacp_actor_partner_state_set_defaulted(lacp_actor_partner_state state) 218{ 219 return (state | LACP_ACTOR_PARTNER_STATE_DEFAULTED); 220} 221 222static __inline__ lacp_actor_partner_state 223lacp_actor_partner_state_set_not_defaulted(lacp_actor_partner_state state) 224{ 225 return (state &= ~LACP_ACTOR_PARTNER_STATE_DEFAULTED); 226} 227 228static __inline__ lacp_actor_partner_state 229lacp_actor_partner_state_defaulted(lacp_actor_partner_state state) 230{ 231 return ((state & LACP_ACTOR_PARTNER_STATE_DEFAULTED) != 0); 232} 233 234static __inline__ lacp_actor_partner_state 235lacp_actor_partner_state_set_expired(lacp_actor_partner_state state) 236{ 237 return (state | LACP_ACTOR_PARTNER_STATE_EXPIRED); 238} 239 240static __inline__ lacp_actor_partner_state 241lacp_actor_partner_state_set_not_expired(lacp_actor_partner_state state) 242{ 243 return (state &= ~LACP_ACTOR_PARTNER_STATE_EXPIRED); 244} 245 246static __inline__ lacp_actor_partner_state 247lacp_actor_partner_state_expired(lacp_actor_partner_state state) 248{ 249 return ((state & LACP_ACTOR_PARTNER_STATE_EXPIRED) != 0); 250} 251 252/* 253 * Function: lacp_uint16_set 254 * Purpose: 255 * Set a field in a structure that's at least 16 bits to the given 256 * value, putting it into network byte order 257 */ 258static __inline__ void 259lacp_uint16_set(uint8_t * field, uint16_t value) 260{ 261 uint16_t tmp_value = htons(value); 262 memcpy((void *)field, (void *)&tmp_value, sizeof(uint16_t)); 263 return; 264} 265 266/* 267 * Function: lacp_uint16_get 268 * Purpose: 269 * Get a field in a structure that's at least 16 bits, converting 270 * to host byte order. 271 */ 272static __inline__ uint16_t 273lacp_uint16_get(const uint8_t * field) 274{ 275 uint16_t tmp_field; 276 memcpy((void *)&tmp_field, (void *)field, sizeof(uint16_t)); 277 return (ntohs(tmp_field)); 278} 279 280/* 281 * Function: lacp_uint32_set 282 * Purpose: 283 * Set a field in a structure that's at least 32 bits to the given 284 * value, putting it into network byte order 285 */ 286static __inline__ void 287lacp_uint32_set(uint8_t * field, uint32_t value) 288{ 289 uint32_t tmp_value = htonl(value); 290 memcpy((void *)field, (void *)&tmp_value, sizeof(uint32_t)); 291 return; 292} 293 294/* 295 * Function: lacp_uint32_get 296 * Purpose: 297 * Get a field in a structure that's at least 32 bits, converting 298 * to host byte order. 299 */ 300static __inline__ uint32_t 301lacp_uint32_get(const uint8_t * field) 302{ 303 uint32_t tmp_field; 304 memcpy((void *)&tmp_field, (void *)field, sizeof(uint32_t)); 305 return (ntohl(tmp_field)); 306} 307 308/* 309 * LACP Actor/Partner TLV access functions 310 */ 311static __inline__ void 312lacp_actor_partner_tlv_set_system_priority(lacp_actor_partner_tlv_ref tlv, 313 lacp_system_priority system_priority) 314{ 315 lacp_uint16_set(tlv->lap_system_priority, system_priority); 316 return; 317} 318 319static __inline__ lacp_system_priority 320lacp_actor_partner_tlv_get_system_priority(const lacp_actor_partner_tlv_ref tlv) 321{ 322 return (lacp_system_priority)lacp_uint16_get(tlv->lap_system_priority); 323} 324 325static __inline__ void 326lacp_actor_partner_tlv_set_key(lacp_actor_partner_tlv_ref tlv, lacp_key key) 327{ 328 lacp_uint16_set(tlv->lap_key, key); 329 return; 330} 331 332static __inline__ lacp_key 333lacp_actor_partner_tlv_get_key(const lacp_actor_partner_tlv_ref tlv) 334{ 335 return (lacp_key)lacp_uint16_get(tlv->lap_key); 336} 337 338static __inline__ void 339lacp_actor_partner_tlv_set_port_priority(lacp_actor_partner_tlv_ref tlv, 340 lacp_port_priority port_priority) 341{ 342 lacp_uint16_set(tlv->lap_port_priority, port_priority); 343 return; 344} 345 346static __inline__ lacp_port_priority 347lacp_actor_partner_tlv_get_port_priority(const lacp_actor_partner_tlv_ref tlv) 348{ 349 return (lacp_port_priority)lacp_uint16_get(tlv->lap_port_priority); 350} 351 352static __inline__ void 353lacp_actor_partner_tlv_set_port(lacp_actor_partner_tlv_ref tlv, lacp_port port) 354{ 355 lacp_uint16_set(tlv->lap_port, port); 356 return; 357} 358 359static __inline__ lacp_port 360lacp_actor_partner_tlv_get_port(const lacp_actor_partner_tlv_ref tlv) 361{ 362 return (lacp_port)lacp_uint16_get(tlv->lap_port); 363} 364 365/* 366 * LACP Collector TLV access functions 367 */ 368static __inline__ void 369lacp_collector_tlv_set_max_delay(lacp_collector_tlv_ref tlv, 370 lacp_collector_max_delay delay) 371{ 372 lacp_uint16_set(tlv->lac_max_delay, delay); 373 return; 374} 375 376static __inline__ lacp_collector_max_delay 377lacp_collector_tlv_get_max_delay(const lacp_collector_tlv_ref tlv) 378{ 379 return (lacp_collector_max_delay)lacp_uint16_get(tlv->lac_max_delay); 380} 381 382typedef struct lacpdu_s { 383 u_char la_subtype; 384 u_char la_version; 385 u_char la_actor_tlv[LACPDU_ACTOR_TLV_LENGTH]; 386 u_char la_partner_tlv[LACPDU_PARTNER_TLV_LENGTH]; 387 u_char la_collector_tlv[LACPDU_COLLECTOR_TLV_LENGTH]; 388 u_char la_terminator_type; 389 u_char la_terminator_length; 390 u_char la_reserved[50]; 391} lacpdu, *lacpdu_ref; 392 393/* timer values in seconds */ 394#define LACP_FAST_PERIODIC_TIME 1 395#define LACP_SLOW_PERIODIC_TIME 30 396#define LACP_SHORT_TIMEOUT_TIME 3 397#define LACP_LONG_TIMEOUT_TIME 90 398#define LACP_CHURN_DETECTION_TIME 60 399#define LACP_AGGREGATE_WAIT_TIME 2 400 401/* packet rate per second */ 402#define LACP_PACKET_RATE 3 403 404/** 405 ** Link Aggregation Marker Protocol definitions 406 **/ 407#define LA_MARKER_PDU_VERSION_1 1 408#define LA_MARKER_TLV_TYPE_TERMINATOR 0x00 409#define LA_MARKER_TLV_TYPE_MARKER 0x01 410#define LA_MARKER_TLV_TYPE_MARKER_RESPONSE 0x02 411 412#define LA_MARKER_TLV_LENGTH 16 413#define LA_MARKER_RESPONSE_TLV_LENGTH 16 414 415typedef u_int32_t la_marker_transaction_id; 416 417typedef struct la_marker_pdu_s { 418 u_char lm_subtype; /* 0x02 */ 419 u_char lm_version; /* 0x01 */ 420 u_char lm_marker_tlv_type; /* 0x01 or 0x02 */ 421 u_char lm_marker_tlv_length; /* 16 */ 422 u_char lm_requestor_port[2]; 423 u_char lm_requestor_system[6]; 424 u_char lm_requestor_transaction_id[4]; 425 u_char lm_pad[2]; 426 u_char lm_terminator_type; /* 0x00 */ 427 u_char lm_terminator_length; /* 0 */ 428 u_char lm_reserved[90]; 429} la_marker_pdu, *la_marker_pdu_ref, 430 la_marker_response_pdu, * la_marker_response_pdu_ref; 431 432static __inline__ void 433la_marker_pdu_set_requestor_port(la_marker_pdu_ref lmpdu, lacp_port port) 434{ 435 lacp_uint16_set(lmpdu->lm_requestor_port, port); 436 return; 437} 438 439static __inline__ lacp_port 440la_marker_pdu_get_requestor_port(la_marker_pdu_ref lmpdu) 441{ 442 return (lacp_port)lacp_uint16_get(lmpdu->lm_requestor_port); 443} 444 445static __inline__ void 446la_marker_pdu_set_requestor_transaction_id(la_marker_pdu_ref lmpdu, 447 la_marker_transaction_id xid) 448{ 449 lacp_uint32_set(lmpdu->lm_requestor_transaction_id, xid); 450 return; 451} 452 453static __inline__ la_marker_transaction_id 454la_marker_pdu_get_requestor_transaction_id(la_marker_pdu_ref lmpdu) 455{ 456 return (la_marker_transaction_id)lacp_uint32_get(lmpdu->lm_requestor_transaction_id); 457} 458 459static __inline__ void 460la_marker_pdu_set_requestor_system(la_marker_pdu_ref lmpdu, lacp_system sys) 461{ 462 *((lacp_system_ref)lmpdu->lm_requestor_system) = sys; 463 return; 464} 465 466static __inline__ lacp_system 467la_marker_pdu_get_requestor_system(la_marker_pdu_ref lmpdu) 468{ 469 return (*(lacp_system_ref)(lmpdu->lm_requestor_system)); 470} 471 472#endif /* _NET_LACP_H_ */ 473