|  | @@ -1,406 +0,0 @@
 | 
		
	
		
			
			| 1 |  | -/* Copyright 2004 Linux Networx */
 | 
		
	
		
			
			| 2 |  | -#ifdef PROTO_LACP
 | 
		
	
		
			
			| 3 |  | -#if 0
 | 
		
	
		
			
			| 4 |  | -#include "nic.h"
 | 
		
	
		
			
			| 5 |  | -#include "timer.h"
 | 
		
	
		
			
			| 6 |  | -#endif
 | 
		
	
		
			
			| 7 |  | -
 | 
		
	
		
			
			| 8 |  | -#define LACP_DEBUG 0
 | 
		
	
		
			
			| 9 |  | -
 | 
		
	
		
			
			| 10 |  | -/* Structure definitions originally taken from the linux bond_3ad driver */
 | 
		
	
		
			
			| 11 |  | -
 | 
		
	
		
			
			| 12 |  | -#define SLOW_DST_MAC "\x01\x80\xc2\x00\x00\x02"
 | 
		
	
		
			
			| 13 |  | -static const char slow_dest[] = SLOW_DST_MAC;
 | 
		
	
		
			
			| 14 |  | -
 | 
		
	
		
			
			| 15 |  | -
 | 
		
	
		
			
			| 16 |  | -#define SLOW_SUBTYPE_LACP 1
 | 
		
	
		
			
			| 17 |  | -#define SLOW_SUBTYPE_MARKER 2
 | 
		
	
		
			
			| 18 |  | -
 | 
		
	
		
			
			| 19 |  | -struct slow_header {
 | 
		
	
		
			
			| 20 |  | -	uint8_t subtype;
 | 
		
	
		
			
			| 21 |  | -};
 | 
		
	
		
			
			| 22 |  | -
 | 
		
	
		
			
			| 23 |  | -struct lacp_info {
 | 
		
	
		
			
			| 24 |  | -	uint16_t system_priority;
 | 
		
	
		
			
			| 25 |  | -	uint8_t  system[ETH_ALEN];
 | 
		
	
		
			
			| 26 |  | -	uint16_t key;
 | 
		
	
		
			
			| 27 |  | -	uint16_t port_priority;
 | 
		
	
		
			
			| 28 |  | -	uint16_t port;
 | 
		
	
		
			
			| 29 |  | -	uint8_t  state;
 | 
		
	
		
			
			| 30 |  | -	uint8_t  reserved[3];
 | 
		
	
		
			
			| 31 |  | -} PACKED;
 | 
		
	
		
			
			| 32 |  | -
 | 
		
	
		
			
			| 33 |  | -#define LACP_CMP_LEN (2 + 6 + 2 + 2 + 2)
 | 
		
	
		
			
			| 34 |  | -#define LACP_CP_LEN  (2 + 6 + 2 + 2 + 2 + 1)
 | 
		
	
		
			
			| 35 |  | -
 | 
		
	
		
			
			| 36 |  | -/* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */
 | 
		
	
		
			
			| 37 |  | -struct slow_lacp {
 | 
		
	
		
			
			| 38 |  | -	uint8_t  subtype;		       /* = LACP(= 0x01) */
 | 
		
	
		
			
			| 39 |  | -	uint8_t  version_number;
 | 
		
	
		
			
			| 40 |  | -	uint8_t  tlv_type_actor_info;	       /* = actor information(type/length/value) */
 | 
		
	
		
			
			| 41 |  | -#define LACP_TLV_TERMINATOR 0
 | 
		
	
		
			
			| 42 |  | -#define LACP_TLV_ACTOR      1
 | 
		
	
		
			
			| 43 |  | -#define LACP_TLV_PARTNER    2
 | 
		
	
		
			
			| 44 |  | -#define LACP_TLV_COLLECTOR  3
 | 
		
	
		
			
			| 45 |  | -	uint8_t  actor_information_length;     /* = 20 */
 | 
		
	
		
			
			| 46 |  | -	struct lacp_info actor;
 | 
		
	
		
			
			| 47 |  | -	uint8_t  tlv_type_partner_info;        /* = partner information */
 | 
		
	
		
			
			| 48 |  | -	uint8_t  partner_information_length;   /* = 20 */
 | 
		
	
		
			
			| 49 |  | -	struct lacp_info partner;
 | 
		
	
		
			
			| 50 |  | -	uint8_t  tlv_type_collector_info;      /* = collector information */
 | 
		
	
		
			
			| 51 |  | -	uint8_t  collector_information_length; /* = 16 */
 | 
		
	
		
			
			| 52 |  | -	uint16_t collector_max_delay;
 | 
		
	
		
			
			| 53 |  | -	uint8_t  reserved_12[12];
 | 
		
	
		
			
			| 54 |  | -	uint8_t  tlv_type_terminator;	       /* = terminator */
 | 
		
	
		
			
			| 55 |  | -	uint8_t  terminator_length;	       /* = 0 */ 
 | 
		
	
		
			
			| 56 |  | -	uint8_t  reserved_50[50];	       /* = 0 */
 | 
		
	
		
			
			| 57 |  | -} PACKED;
 | 
		
	
		
			
			| 58 |  | -
 | 
		
	
		
			
			| 59 |  | -/* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */
 | 
		
	
		
			
			| 60 |  | -struct slow_marker {
 | 
		
	
		
			
			| 61 |  | -	uint8_t  subtype;                      /* = 0x02  (marker PDU) */
 | 
		
	
		
			
			| 62 |  | -	uint8_t  version_number;	       /* = 0x01 */
 | 
		
	
		
			
			| 63 |  | -	uint8_t  tlv_type;
 | 
		
	
		
			
			| 64 |  | -#define MARKER_TLV_TERMINATOR 0                /* marker terminator */
 | 
		
	
		
			
			| 65 |  | -#define MARKER_TLV_INFO       1	               /* marker information */
 | 
		
	
		
			
			| 66 |  | -#define MARKER_TLV_RESPONSE   2	               /* marker response information */
 | 
		
	
		
			
			| 67 |  | -	uint8_t  marker_length;                /* = 0x16 */
 | 
		
	
		
			
			| 68 |  | -	uint16_t requester_port;	       /* The number assigned to the port by the requester */
 | 
		
	
		
			
			| 69 |  | -	uint8_t  requester_system[ETH_ALEN];   /* The requester's system id */
 | 
		
	
		
			
			| 70 |  | -	uint32_t requester_transaction_id;     /* The transaction id allocated by the requester, */
 | 
		
	
		
			
			| 71 |  | -	uint16_t pad;		               /* = 0 */
 | 
		
	
		
			
			| 72 |  | -	uint8_t  tlv_type_terminator;	       /* = 0x00 */
 | 
		
	
		
			
			| 73 |  | -	uint8_t  terminator_length;	       /* = 0x00 */
 | 
		
	
		
			
			| 74 |  | -	uint8_t  reserved_90[90];	       /* = 0 */
 | 
		
	
		
			
			| 75 |  | -} PACKED;
 | 
		
	
		
			
			| 76 |  | -
 | 
		
	
		
			
			| 77 |  | -union slow_union {
 | 
		
	
		
			
			| 78 |  | -	struct slow_header header;
 | 
		
	
		
			
			| 79 |  | -	struct slow_lacp lacp;
 | 
		
	
		
			
			| 80 |  | -	struct slow_marker marker;
 | 
		
	
		
			
			| 81 |  | -};
 | 
		
	
		
			
			| 82 |  | -
 | 
		
	
		
			
			| 83 |  | -#define FAST_PERIODIC_TIME   (1*TICKS_PER_SEC)
 | 
		
	
		
			
			| 84 |  | -#define SLOW_PERIODIC_TIME   (30*TICKS_PER_SEC)
 | 
		
	
		
			
			| 85 |  | -#define SHORT_TIMEOUT_TIME   (3*FAST_PERIODIC_TIME)
 | 
		
	
		
			
			| 86 |  | -#define LONG_TIMEOUT_TIME    (3*SLOW_PERIODIC_TIME)
 | 
		
	
		
			
			| 87 |  | -#define CHURN_DETECTION_TIME (60*TICKS_PER_SEC)
 | 
		
	
		
			
			| 88 |  | -#define AGGREGATE_WAIT_TIME  (2*TICKS_PER_SEC)
 | 
		
	
		
			
			| 89 |  | -
 | 
		
	
		
			
			| 90 |  | -#define LACP_ACTIVITY        (1 << 0)
 | 
		
	
		
			
			| 91 |  | -#define LACP_TIMEOUT         (1 << 1)
 | 
		
	
		
			
			| 92 |  | -#define LACP_AGGREGATION     (1 << 2)
 | 
		
	
		
			
			| 93 |  | -#define LACP_SYNCHRONIZATION (1 << 3)
 | 
		
	
		
			
			| 94 |  | -#define LACP_COLLECTING      (1 << 4)
 | 
		
	
		
			
			| 95 |  | -#define LACP_DISTRIBUTING    (1 << 5)
 | 
		
	
		
			
			| 96 |  | -#define LACP_DEFAULTED       (1 << 6)
 | 
		
	
		
			
			| 97 |  | -#define LACP_EXPIRED         (1 << 7)
 | 
		
	
		
			
			| 98 |  | -
 | 
		
	
		
			
			| 99 |  | -#define UNSELECTED 0
 | 
		
	
		
			
			| 100 |  | -#define STANDBY    1
 | 
		
	
		
			
			| 101 |  | -#define SELECTED   2
 | 
		
	
		
			
			| 102 |  | -
 | 
		
	
		
			
			| 103 |  | -
 | 
		
	
		
			
			| 104 |  | -struct lacp_state {
 | 
		
	
		
			
			| 105 |  | -	struct slow_lacp pkt;
 | 
		
	
		
			
			| 106 |  | -	unsigned long current_while_timer; /* Time when the LACP information expires */
 | 
		
	
		
			
			| 107 |  | -	unsigned long periodic_timer; /* Time when I need to send my partner an update */
 | 
		
	
		
			
			| 108 |  | -};
 | 
		
	
		
			
			| 109 |  | -
 | 
		
	
		
			
			| 110 |  | -static struct lacp_state lacp;
 | 
		
	
		
			
			| 111 |  | -
 | 
		
	
		
			
			| 112 |  | -
 | 
		
	
		
			
			| 113 |  | -#if LACP_DEBUG > 0
 | 
		
	
		
			
			| 114 |  | -static void print_lacp_state(uint8_t state)
 | 
		
	
		
			
			| 115 |  | -{
 | 
		
	
		
			
			| 116 |  | -	printf("%hhx", state);
 | 
		
	
		
			
			| 117 |  | -	if (state & LACP_ACTIVITY) {
 | 
		
	
		
			
			| 118 |  | -		printf(" Activity");
 | 
		
	
		
			
			| 119 |  | -	}
 | 
		
	
		
			
			| 120 |  | -	if (state & LACP_TIMEOUT) {
 | 
		
	
		
			
			| 121 |  | -		printf(" Timeout");
 | 
		
	
		
			
			| 122 |  | -	}
 | 
		
	
		
			
			| 123 |  | -	if (state & LACP_AGGREGATION) {
 | 
		
	
		
			
			| 124 |  | -		printf(" Aggregation");
 | 
		
	
		
			
			| 125 |  | -	}
 | 
		
	
		
			
			| 126 |  | -	if (state & LACP_SYNCHRONIZATION) {
 | 
		
	
		
			
			| 127 |  | -		printf(" Syncronization");
 | 
		
	
		
			
			| 128 |  | -	}
 | 
		
	
		
			
			| 129 |  | -	if (state & LACP_COLLECTING) {
 | 
		
	
		
			
			| 130 |  | -		printf(" Collecting");
 | 
		
	
		
			
			| 131 |  | -	}
 | 
		
	
		
			
			| 132 |  | -	if (state & LACP_DISTRIBUTING) {
 | 
		
	
		
			
			| 133 |  | -		printf(" Distributing");
 | 
		
	
		
			
			| 134 |  | -	}
 | 
		
	
		
			
			| 135 |  | -	if (state & LACP_DEFAULTED) {
 | 
		
	
		
			
			| 136 |  | -		printf(" Defaulted");
 | 
		
	
		
			
			| 137 |  | -	}
 | 
		
	
		
			
			| 138 |  | -	if (state & LACP_EXPIRED) {
 | 
		
	
		
			
			| 139 |  | -		printf(" Expired");
 | 
		
	
		
			
			| 140 |  | -	}
 | 
		
	
		
			
			| 141 |  | -	printf("\n");
 | 
		
	
		
			
			| 142 |  | -}
 | 
		
	
		
			
			| 143 |  | -
 | 
		
	
		
			
			| 144 |  | -static inline void print_lacpdu(struct slow_lacp *pkt)
 | 
		
	
		
			
			| 145 |  | -{
 | 
		
	
		
			
			| 146 |  | -	printf("subtype version:  %hhx %hhx\n", 
 | 
		
	
		
			
			| 147 |  | -		pkt->subtype, pkt->version_number);
 | 
		
	
		
			
			| 148 |  | -	printf("actor_tlv %hhx", pkt->tlv_type_actor_info);
 | 
		
	
		
			
			| 149 |  | -	printf(" len: %hhx (\n", pkt->actor_information_length);
 | 
		
	
		
			
			| 150 |  | -	printf(" sys_pri: %hx", ntohs(pkt->actor.system_priority));
 | 
		
	
		
			
			| 151 |  | -	printf(" mac: %!", pkt->actor.system);
 | 
		
	
		
			
			| 152 |  | -	printf(" key: %hx", ntohs(pkt->actor.key));
 | 
		
	
		
			
			| 153 |  | -	printf(" port_pri: %hx", ntohs(pkt->actor.port_priority));
 | 
		
	
		
			
			| 154 |  | -	printf(" port: %hx\n", ntohs(pkt->actor.port));
 | 
		
	
		
			
			| 155 |  | -	printf(" state: ");
 | 
		
	
		
			
			| 156 |  | -	print_lacp_state(pkt->actor.state);
 | 
		
	
		
			
			| 157 |  | -#if LACP_DEBUG > 1
 | 
		
	
		
			
			| 158 |  | -	printf(" reserved:     %hhx %hhx %hhx\n",
 | 
		
	
		
			
			| 159 |  | -		pkt->actor.reserved[0], pkt->actor.reserved[1], pkt->actor.reserved[2]);
 | 
		
	
		
			
			| 160 |  | -#endif
 | 
		
	
		
			
			| 161 |  | -	printf(")\n");
 | 
		
	
		
			
			| 162 |  | -	printf("partner_tlv: %hhx", pkt->tlv_type_partner_info);
 | 
		
	
		
			
			| 163 |  | -	printf(" len: %hhx (\n", pkt->partner_information_length);
 | 
		
	
		
			
			| 164 |  | -	printf(" sys_pri: %hx", ntohs(pkt->partner.system_priority));
 | 
		
	
		
			
			| 165 |  | -	printf(" mac: %!", pkt->partner.system);
 | 
		
	
		
			
			| 166 |  | -	printf(" key: %hx", ntohs(pkt->partner.key));
 | 
		
	
		
			
			| 167 |  | -	printf(" port_pri: %hx", ntohs(pkt->partner.port_priority));
 | 
		
	
		
			
			| 168 |  | -	printf(" port: %hx\n", ntohs(pkt->partner.port));
 | 
		
	
		
			
			| 169 |  | -	printf(" state: ");
 | 
		
	
		
			
			| 170 |  | -	print_lacp_state(pkt->partner.state);
 | 
		
	
		
			
			| 171 |  | -#if LACP_DEBUG > 1
 | 
		
	
		
			
			| 172 |  | -	printf(" reserved:     %hhx %hhx %hhx\n",
 | 
		
	
		
			
			| 173 |  | -		pkt->partner.reserved[0], pkt->partner.reserved[1], pkt->partner.reserved[2]);
 | 
		
	
		
			
			| 174 |  | -#endif
 | 
		
	
		
			
			| 175 |  | -	printf(")\n");
 | 
		
	
		
			
			| 176 |  | -	printf("collector_tlv: %hhx ", pkt->tlv_type_collector_info);
 | 
		
	
		
			
			| 177 |  | -	printf(" len: %hhx (", pkt->collector_information_length);
 | 
		
	
		
			
			| 178 |  | -	printf(" max_delay: %hx", ntohs(pkt->collector_max_delay));
 | 
		
	
		
			
			| 179 |  | -#if LACP_DEBUG > 1
 | 
		
	
		
			
			| 180 |  | -	printf("reserved_12:      %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n",
 | 
		
	
		
			
			| 181 |  | -		pkt->reserved_12[0], pkt->reserved_12[1], pkt->reserved_12[2], 
 | 
		
	
		
			
			| 182 |  | -		pkt->reserved_12[3], pkt->reserved_12[4], pkt->reserved_12[5], 
 | 
		
	
		
			
			| 183 |  | -		pkt->reserved_12[6], pkt->reserved_12[7], pkt->reserved_12[8], 
 | 
		
	
		
			
			| 184 |  | -		pkt->reserved_12[9], pkt->reserved_12[10], pkt->reserved_12[11]);
 | 
		
	
		
			
			| 185 |  | -#endif
 | 
		
	
		
			
			| 186 |  | -	printf(" )\n");
 | 
		
	
		
			
			| 187 |  | -	printf("terminator_tlv: %hhx", pkt->tlv_type_terminator);
 | 
		
	
		
			
			| 188 |  | -	printf(" len: %hhx ()\n", pkt->terminator_length);
 | 
		
	
		
			
			| 189 |  | -}
 | 
		
	
		
			
			| 190 |  | -
 | 
		
	
		
			
			| 191 |  | -static inline unsigned long lacp_timer_val(unsigned long now, unsigned long when)
 | 
		
	
		
			
			| 192 |  | -{
 | 
		
	
		
			
			| 193 |  | -	return when?(when - now)/TICKS_PER_SEC : 0;
 | 
		
	
		
			
			| 194 |  | -}
 | 
		
	
		
			
			| 195 |  | -static void print_lacp(const char *which, struct slow_lacp *pkt, unsigned long now)
 | 
		
	
		
			
			| 196 |  | -{
 | 
		
	
		
			
			| 197 |  | -	printf("%s\n", which);
 | 
		
	
		
			
			| 198 |  | -	print_lacpdu(pkt);
 | 
		
	
		
			
			| 199 |  | -	printf("timers: c %ds p %ds\n",
 | 
		
	
		
			
			| 200 |  | -		lacp_timer_val(now, lacp.current_while_timer),
 | 
		
	
		
			
			| 201 |  | -		lacp_timer_val(now, lacp.periodic_timer)
 | 
		
	
		
			
			| 202 |  | -		);
 | 
		
	
		
			
			| 203 |  | -	printf("\n");
 | 
		
	
		
			
			| 204 |  | -}
 | 
		
	
		
			
			| 205 |  | -#else /* LACP_DEBUG */
 | 
		
	
		
			
			| 206 |  | -#define print_lacp(which, pkt, now) do {} while(0)
 | 
		
	
		
			
			| 207 |  | -#endif /* LACP_DEBUG */
 | 
		
	
		
			
			| 208 |  | -
 | 
		
	
		
			
			| 209 |  | -static void lacp_init_state(const uint8_t *mac)
 | 
		
	
		
			
			| 210 |  | -{
 | 
		
	
		
			
			| 211 |  | -	memset(&lacp, 0, sizeof(lacp));
 | 
		
	
		
			
			| 212 |  | -
 | 
		
	
		
			
			| 213 |  | -	/* Initialize the packet constants */
 | 
		
	
		
			
			| 214 |  | -	lacp.pkt.subtype               = 1;
 | 
		
	
		
			
			| 215 |  | -	lacp.pkt.version_number        = 1;
 | 
		
	
		
			
			| 216 |  | -
 | 
		
	
		
			
			| 217 |  | -
 | 
		
	
		
			
			| 218 |  | -	/* The default state of my interface */
 | 
		
	
		
			
			| 219 |  | -	lacp.pkt.tlv_type_actor_info      = LACP_TLV_ACTOR;
 | 
		
	
		
			
			| 220 |  | -	lacp.pkt.actor_information_length = 0x14;
 | 
		
	
		
			
			| 221 |  | -	lacp.pkt.actor.system_priority    = htons(1);
 | 
		
	
		
			
			| 222 |  | -	memcpy(lacp.pkt.actor.system, mac, ETH_ALEN);
 | 
		
	
		
			
			| 223 |  | -	lacp.pkt.actor.key                = htons(1);
 | 
		
	
		
			
			| 224 |  | -	lacp.pkt.actor.port               = htons(1);
 | 
		
	
		
			
			| 225 |  | -	lacp.pkt.actor.port_priority      = htons(1);
 | 
		
	
		
			
			| 226 |  | -	lacp.pkt.actor.state = 
 | 
		
	
		
			
			| 227 |  | -		LACP_SYNCHRONIZATION |
 | 
		
	
		
			
			| 228 |  | -		LACP_COLLECTING      |
 | 
		
	
		
			
			| 229 |  | -		LACP_DISTRIBUTING    |
 | 
		
	
		
			
			| 230 |  | -		LACP_DEFAULTED;
 | 
		
	
		
			
			| 231 |  | -
 | 
		
	
		
			
			| 232 |  | -	/* Set my partner defaults */
 | 
		
	
		
			
			| 233 |  | -	lacp.pkt.tlv_type_partner_info      = LACP_TLV_PARTNER;
 | 
		
	
		
			
			| 234 |  | -	lacp.pkt.partner_information_length = 0x14;
 | 
		
	
		
			
			| 235 |  | -	lacp.pkt.partner.system_priority    = htons(1);
 | 
		
	
		
			
			| 236 |  | -	/* memset(lacp.pkt.parnter_system, 0, ETH_ALEN); */
 | 
		
	
		
			
			| 237 |  | -	lacp.pkt.partner.key                = htons(1);
 | 
		
	
		
			
			| 238 |  | -	lacp.pkt.partner.port               = htons(1);
 | 
		
	
		
			
			| 239 |  | -	lacp.pkt.partner.port_priority      = htons(1);
 | 
		
	
		
			
			| 240 |  | -	lacp.pkt.partner.state =
 | 
		
	
		
			
			| 241 |  | -		LACP_ACTIVITY        |
 | 
		
	
		
			
			| 242 |  | -		LACP_SYNCHRONIZATION |
 | 
		
	
		
			
			| 243 |  | -		LACP_COLLECTING      |
 | 
		
	
		
			
			| 244 |  | -		LACP_DISTRIBUTING    |
 | 
		
	
		
			
			| 245 |  | -		LACP_DEFAULTED;
 | 
		
	
		
			
			| 246 |  | -
 | 
		
	
		
			
			| 247 |  | -	lacp.pkt.tlv_type_collector_info      = LACP_TLV_COLLECTOR;
 | 
		
	
		
			
			| 248 |  | -	lacp.pkt.collector_information_length = 0x10;
 | 
		
	
		
			
			| 249 |  | -	lacp.pkt.collector_max_delay          = htons(0x8000); /* ???? */
 | 
		
	
		
			
			| 250 |  | -
 | 
		
	
		
			
			| 251 |  | -	lacp.pkt.tlv_type_terminator          = LACP_TLV_TERMINATOR;
 | 
		
	
		
			
			| 252 |  | -	lacp.pkt.terminator_length            = 0;
 | 
		
	
		
			
			| 253 |  | -}
 | 
		
	
		
			
			| 254 |  | -
 | 
		
	
		
			
			| 255 |  | -#define LACP_NTT_MASK (LACP_ACTIVITY | LACP_TIMEOUT | \
 | 
		
	
		
			
			| 256 |  | -	LACP_SYNCHRONIZATION | LACP_AGGREGATION)
 | 
		
	
		
			
			| 257 |  | -
 | 
		
	
		
			
			| 258 |  | -static inline int lacp_update_ntt(struct slow_lacp *pkt)
 | 
		
	
		
			
			| 259 |  | -{
 | 
		
	
		
			
			| 260 |  | -	int ntt = 0;
 | 
		
	
		
			
			| 261 |  | -	if ((memcmp(&pkt->partner, &lacp.pkt.actor, LACP_CMP_LEN) != 0) ||
 | 
		
	
		
			
			| 262 |  | -		((pkt->partner.state & LACP_NTT_MASK) != 
 | 
		
	
		
			
			| 263 |  | -			(lacp.pkt.actor.state & LACP_NTT_MASK)))
 | 
		
	
		
			
			| 264 |  | -	{
 | 
		
	
		
			
			| 265 |  | -		ntt = 1;
 | 
		
	
		
			
			| 266 |  | -	}
 | 
		
	
		
			
			| 267 |  | -	return ntt;
 | 
		
	
		
			
			| 268 |  | -}
 | 
		
	
		
			
			| 269 |  | -
 | 
		
	
		
			
			| 270 |  | -static inline void lacp_record_pdu(struct slow_lacp *pkt)
 | 
		
	
		
			
			| 271 |  | -{
 | 
		
	
		
			
			| 272 |  | -	memcpy(&lacp.pkt.partner, &pkt->actor, LACP_CP_LEN);
 | 
		
	
		
			
			| 273 |  | -
 | 
		
	
		
			
			| 274 |  | -	lacp.pkt.actor.state &= ~LACP_DEFAULTED;
 | 
		
	
		
			
			| 275 |  | -	lacp.pkt.partner.state &= ~LACP_SYNCHRONIZATION;
 | 
		
	
		
			
			| 276 |  | -	if ((memcmp(&pkt->partner, &lacp.pkt.actor, LACP_CMP_LEN) == 0) &&
 | 
		
	
		
			
			| 277 |  | -		((pkt->partner.state & LACP_AGGREGATION) ==
 | 
		
	
		
			
			| 278 |  | -			(lacp.pkt.actor.state & LACP_AGGREGATION)))
 | 
		
	
		
			
			| 279 |  | -	{
 | 
		
	
		
			
			| 280 |  | -		lacp.pkt.partner.state  |= LACP_SYNCHRONIZATION;
 | 
		
	
		
			
			| 281 |  | -	}
 | 
		
	
		
			
			| 282 |  | -	if (!(pkt->actor.state & LACP_AGGREGATION)) {
 | 
		
	
		
			
			| 283 |  | -		lacp.pkt.partner.state |= LACP_SYNCHRONIZATION;
 | 
		
	
		
			
			| 284 |  | -	}
 | 
		
	
		
			
			| 285 |  | -
 | 
		
	
		
			
			| 286 |  | -	/* ACTIVITY? */
 | 
		
	
		
			
			| 287 |  | -}
 | 
		
	
		
			
			| 288 |  | -
 | 
		
	
		
			
			| 289 |  | -static inline int lacp_timer_expired(unsigned long now, unsigned long when)
 | 
		
	
		
			
			| 290 |  | -{
 | 
		
	
		
			
			| 291 |  | -	return when && (now > when);
 | 
		
	
		
			
			| 292 |  | -}
 | 
		
	
		
			
			| 293 |  | -
 | 
		
	
		
			
			| 294 |  | -static inline void lacp_start_periodic_timer(unsigned long now)
 | 
		
	
		
			
			| 295 |  | -{
 | 
		
	
		
			
			| 296 |  | -	if ((lacp.pkt.partner.state & LACP_ACTIVITY) ||
 | 
		
	
		
			
			| 297 |  | -		(lacp.pkt.actor.state & LACP_ACTIVITY)) {
 | 
		
	
		
			
			| 298 |  | -		lacp.periodic_timer = now +
 | 
		
	
		
			
			| 299 |  | -			(((lacp.pkt.partner.state & LACP_TIMEOUT)?
 | 
		
	
		
			
			| 300 |  | -				FAST_PERIODIC_TIME : SLOW_PERIODIC_TIME));
 | 
		
	
		
			
			| 301 |  | -	}
 | 
		
	
		
			
			| 302 |  | -}
 | 
		
	
		
			
			| 303 |  | -
 | 
		
	
		
			
			| 304 |  | -static inline void lacp_start_current_while_timer(unsigned long now)
 | 
		
	
		
			
			| 305 |  | -{
 | 
		
	
		
			
			| 306 |  | -	lacp.current_while_timer = now +
 | 
		
	
		
			
			| 307 |  | -		((lacp.pkt.actor.state & LACP_TIMEOUT) ?
 | 
		
	
		
			
			| 308 |  | -		SHORT_TIMEOUT_TIME : LONG_TIMEOUT_TIME);
 | 
		
	
		
			
			| 309 |  | -
 | 
		
	
		
			
			| 310 |  | -	lacp.pkt.actor.state &= ~LACP_EXPIRED;
 | 
		
	
		
			
			| 311 |  | -}
 | 
		
	
		
			
			| 312 |  | -
 | 
		
	
		
			
			| 313 |  | -static void send_lacp_reports(unsigned long now, int ntt)
 | 
		
	
		
			
			| 314 |  | -{
 | 
		
	
		
			
			| 315 |  | -	if (memcmp(nic.node_addr, lacp.pkt.actor.system, ETH_ALEN) != 0) {
 | 
		
	
		
			
			| 316 |  | -		lacp_init_state(nic.node_addr);
 | 
		
	
		
			
			| 317 |  | -	}
 | 
		
	
		
			
			| 318 |  | -	/* If the remote information has expired I need to take action */
 | 
		
	
		
			
			| 319 |  | -	if (lacp_timer_expired(now, lacp.current_while_timer)) {
 | 
		
	
		
			
			| 320 |  | -		if (!(lacp.pkt.actor.state & LACP_EXPIRED)) {
 | 
		
	
		
			
			| 321 |  | -			lacp.pkt.partner.state &= ~LACP_SYNCHRONIZATION;
 | 
		
	
		
			
			| 322 |  | -			lacp.pkt.partner.state |= LACP_TIMEOUT;
 | 
		
	
		
			
			| 323 |  | -			lacp.pkt.actor.state |= LACP_EXPIRED;
 | 
		
	
		
			
			| 324 |  | -			lacp.current_while_timer = now + SHORT_TIMEOUT_TIME;
 | 
		
	
		
			
			| 325 |  | -			ntt = 1;
 | 
		
	
		
			
			| 326 |  | -		}
 | 
		
	
		
			
			| 327 |  | -		else {
 | 
		
	
		
			
			| 328 |  | -			lacp_init_state(nic.node_addr);
 | 
		
	
		
			
			| 329 |  | -		}
 | 
		
	
		
			
			| 330 |  | -	}
 | 
		
	
		
			
			| 331 |  | -	/* If the periodic timer has expired I need to transmit */
 | 
		
	
		
			
			| 332 |  | -	if (lacp_timer_expired(now, lacp.periodic_timer)) {
 | 
		
	
		
			
			| 333 |  | -		ntt = 1;
 | 
		
	
		
			
			| 334 |  | -		/* Reset by lacp_start_periodic_timer */
 | 
		
	
		
			
			| 335 |  | -	}
 | 
		
	
		
			
			| 336 |  | -	if (ntt) {
 | 
		
	
		
			
			| 337 |  | -		eth_transmit(slow_dest, ETH_P_SLOW, sizeof(lacp.pkt), &lacp.pkt);
 | 
		
	
		
			
			| 338 |  | -
 | 
		
	
		
			
			| 339 |  | -		/* Restart the periodic timer */
 | 
		
	
		
			
			| 340 |  | -		lacp_start_periodic_timer(now);
 | 
		
	
		
			
			| 341 |  | -
 | 
		
	
		
			
			| 342 |  | -		print_lacp("Trasmitted", &lacp.pkt, now);
 | 
		
	
		
			
			| 343 |  | -	}
 | 
		
	
		
			
			| 344 |  | -}
 | 
		
	
		
			
			| 345 |  | -
 | 
		
	
		
			
			| 346 |  | -static inline void send_eth_slow_reports(unsigned long now)
 | 
		
	
		
			
			| 347 |  | -{
 | 
		
	
		
			
			| 348 |  | -	send_lacp_reports(now, 0);
 | 
		
	
		
			
			| 349 |  | -}
 | 
		
	
		
			
			| 350 |  | -
 | 
		
	
		
			
			| 351 |  | -static inline void process_eth_slow(unsigned short ptype, unsigned long now)
 | 
		
	
		
			
			| 352 |  | -{
 | 
		
	
		
			
			| 353 |  | -	union slow_union *pkt;
 | 
		
	
		
			
			| 354 |  | -	if ((ptype != ETH_P_SLOW) || 
 | 
		
	
		
			
			| 355 |  | -		(nic.packetlen < (ETH_HLEN + sizeof(pkt->header)))) {
 | 
		
	
		
			
			| 356 |  | -		return;
 | 
		
	
		
			
			| 357 |  | -	}
 | 
		
	
		
			
			| 358 |  | -	pkt = (union slow_union *)&nic.packet[ETH_HLEN];
 | 
		
	
		
			
			| 359 |  | -	if ((pkt->header.subtype == SLOW_SUBTYPE_LACP) &&
 | 
		
	
		
			
			| 360 |  | -		(nic.packetlen >= ETH_HLEN + sizeof(pkt->lacp))) {
 | 
		
	
		
			
			| 361 |  | -		int ntt;
 | 
		
	
		
			
			| 362 |  | -		if (memcmp(nic.node_addr, lacp.pkt.actor.system, ETH_ALEN) != 0) {
 | 
		
	
		
			
			| 363 |  | -			lacp_init_state(nic.node_addr);
 | 
		
	
		
			
			| 364 |  | -		}
 | 
		
	
		
			
			| 365 |  | -		/* As long as nic.packet is 2 byte aligned all is good */
 | 
		
	
		
			
			| 366 |  | -		print_lacp("Received", &pkt->lacp, now);
 | 
		
	
		
			
			| 367 |  | -		/* I don't actually implement the MUX or SELECT
 | 
		
	
		
			
			| 368 |  | -		 * machines.  
 | 
		
	
		
			
			| 369 |  | -		 *
 | 
		
	
		
			
			| 370 |  | -		 * What logically happens when the client and I
 | 
		
	
		
			
			| 371 |  | -		 * disagree about an aggregator is the current
 | 
		
	
		
			
			| 372 |  | -		 * aggregtator is unselected.  The MUX machine places
 | 
		
	
		
			
			| 373 |  | -		 * me in DETACHED.  The SELECT machine runs and
 | 
		
	
		
			
			| 374 |  | -		 * reslects the same aggregator.  If I go through
 | 
		
	
		
			
			| 375 |  | -		 * these steps fast enough an outside observer can not
 | 
		
	
		
			
			| 376 |  | -		 * notice this.  
 | 
		
	
		
			
			| 377 |  | -		 *
 | 
		
	
		
			
			| 378 |  | -		 * Since the process will not generate any noticeable
 | 
		
	
		
			
			| 379 |  | -		 * effect it does not need an implmenetation.  This
 | 
		
	
		
			
			| 380 |  | -		 * keeps the code simple and the code and binary
 | 
		
	
		
			
			| 381 |  | -		 * size down.
 | 
		
	
		
			
			| 382 |  | -		 */
 | 
		
	
		
			
			| 383 |  | -		/* lacp_update_selected(&pkt->lacp); */
 | 
		
	
		
			
			| 384 |  | -		ntt = lacp_update_ntt(&pkt->lacp);
 | 
		
	
		
			
			| 385 |  | -		lacp_record_pdu(&pkt->lacp);
 | 
		
	
		
			
			| 386 |  | -		lacp_start_current_while_timer(now);
 | 
		
	
		
			
			| 387 |  | -		send_lacp_reports(now, ntt);
 | 
		
	
		
			
			| 388 |  | -	}
 | 
		
	
		
			
			| 389 |  | -	/* If we receive a marker information packet return it */
 | 
		
	
		
			
			| 390 |  | -	else if ((pkt->header.subtype == SLOW_SUBTYPE_MARKER) &&
 | 
		
	
		
			
			| 391 |  | -		(nic.packetlen >= ETH_HLEN + sizeof(pkt->marker)) &&
 | 
		
	
		
			
			| 392 |  | -		(pkt->marker.tlv_type == MARKER_TLV_INFO) &&
 | 
		
	
		
			
			| 393 |  | -		(pkt->marker.marker_length == 0x16)) 
 | 
		
	
		
			
			| 394 |  | -	{
 | 
		
	
		
			
			| 395 |  | -		pkt->marker.tlv_type = MARKER_TLV_RESPONSE;
 | 
		
	
		
			
			| 396 |  | -		eth_transmit(slow_dest, ETH_P_SLOW, 
 | 
		
	
		
			
			| 397 |  | -			sizeof(pkt->marker), &pkt->marker);
 | 
		
	
		
			
			| 398 |  | -	}
 | 
		
	
		
			
			| 399 |  | -
 | 
		
	
		
			
			| 400 |  | - }
 | 
		
	
		
			
			| 401 |  | -#else
 | 
		
	
		
			
			| 402 |  | -
 | 
		
	
		
			
			| 403 |  | -#define send_eth_slow_reports(now)    do {} while(0)
 | 
		
	
		
			
			| 404 |  | -#define process_eth_slow(ptype, now)  do {} while(0)
 | 
		
	
		
			
			| 405 |  | -
 | 
		
	
		
			
			| 406 |  | -#endif 
 |