#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
#define LACP_VERSION 0x01
#define LACP_SUBTYPE 0x1
#define ACTOR_TLV 0x01
#define PARTNER_TLV 0x02
#define COLLECTOR_TLV 0x03
#define TERMINATOR_TLV 0x00
#define LACP_COLLECTOR_INFO_LEN 0x10
#define LACP_TERMINATOR_INFO_LEN 0x00
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" \
}
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" \
}
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" \
}
typedef enum {
LACP_NO_ACTOR_CHURN = 0,
LACP_ACTOR_CHURN_MONITOR = 1,
LACP_ACTOR_CHURN = 2
} lacp_churn_state_t;
#define FAST_PERIODIC_TIME 1
#define SLOW_PERIODIC_TIME 30
#define SHORT_TIMEOUT_TIME 3
#define LONG_TIMEOUT_TIME 90
#define CHURN_DETECTION_TIME 60
#define AGGREGATE_WAIT_TIME 2
typedef struct system_info {
struct ether_addr system_id;
uint16_t system_priority;
} system_info_t;
typedef struct lacp_timer {
uint32_t val;
timeout_id_t id;
} lacp_timer_t;
typedef struct Agg {
uint32_t AggregatorIdentifier;
boolean_t IndividualAggr;
uint32_t ActorAdminKey;
uint32_t ActorOperKey;
struct ether_addr PartnerSystem;
uint32_t PartnerSystemPriority;
uint32_t PartnerOperAggrKey;
boolean_t ReceiveState;
boolean_t TransmitState;
uint16_t ActorSystemPriority;
uint16_t CollectorMaxDelay;
aggr_lacp_timer_t PeriodicTimer;
uint64_t TimeOfLastOperChange;
boolean_t ready;
} Agg_t;
typedef enum {
AGGR_UNSELECTED,
AGGR_SELECTED,
AGGR_STANDBY
} lacp_selected_t;
typedef struct state_machine {
uint32_t lacp_on : 1,
begin : 1,
lacp_enabled : 1,
port_enabled : 1,
actor_churn : 1,
partner_churn : 1,
ready_n : 1,
port_moved : 1,
pad_bits : 24;
lacp_selected_t selected;
uint32_t current_while_timer_exp;
lacp_periodic_state_t periodic_state;
lacp_receive_state_t receive_state;
lacp_mux_state_t mux_state;
lacp_churn_state_t churn_state;
} state_machine_t;
#define LACP_PERIODIC_TIMEOUT 0x01
#define LACP_WAIT_WHILE_TIMEOUT 0x02
#define LACP_CURRENT_WHILE_TIMEOUT 0x04
#define LACP_THREAD_EXIT 0x08
typedef struct aggr_lacp_port {
uint16_t ActorPortNumber;
uint16_t ActorPortPriority;
uint32_t ActorPortAggrId;
boolean_t NTT;
uint16_t ActorAdminPortKey;
uint16_t ActorOperPortKey;
aggr_lacp_state_t ActorAdminPortState;
aggr_lacp_state_t ActorOperPortState;
struct ether_addr PartnerAdminSystem;
struct ether_addr PartnerOperSystem;
uint16_t PartnerAdminSysPriority;
uint16_t PartnerOperSysPriority;
uint16_t PartnerAdminKey;
uint16_t PartnerOperKey;
uint16_t PartnerAdminPortNum;
uint16_t PartnerOperPortNum;
uint16_t PartnerAdminPortPriority;
uint16_t PartnerOperPortPriority;
aggr_lacp_state_t PartnerAdminPortState;
aggr_lacp_state_t PartnerOperPortState;
uint16_t PartnerCollectorMaxDelay;
state_machine_t sm;
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;
typedef struct link_info {
uint8_t tlv_type;
uint8_t information_len;
uint16_t system_priority;
struct ether_addr system_id;
uint16_t key;
uint16_t port_priority;
uint16_t port;
aggr_lacp_state_t state;
uint8_t reserved[3];
} link_info_t;
typedef struct lacp {
uint8_t subtype;
uint8_t version;
link_info_t actor_info;
link_info_t partner_info;
uint8_t tlv_collector;
uint8_t collector_len;
uint16_t collector_max_delay;
uint8_t reserved[12];
uint8_t tlv_terminator;
uint8_t terminator_len;
uint8_t lacp_reserved[50];
} lacp_t;
#define MARKER_VERSION 0x1
#define MARKER_SUBTYPE 0x2
#define MARKER_INFO_RESPONSE_LENGTH 16
#define MARKER_INFO_TLV 0x01
#define MARKER_RESPONSE_TLV 0x02
typedef struct marker_pdu {
struct ether_addr dest_addr;
struct ether_addr src_addr;
uint16_t type;
uint8_t subtype;
uint8_t version;
uint8_t tlv_marker;
uint8_t marker_len;
uint16_t requestor_port;
struct ether_addr system_id;
uint8_t transaction_id[4];
uint8_t pad[2];
uint8_t reserved[90];
uint32_t fcs;
} marker_pdu_t;
typedef struct lag_id {
uint16_t system_priority;
struct ether_addr system_id;
uint16_t oper_key;
uint16_t port_priority;
uint16_t port_number;
} lag_id_t;
#endif
#ifdef __cplusplus
}
#endif
#endif