/* * lacpa_periodic_expiration_timer_cb * * Periodic Timer Expiration callback */ static void lacpa_periodic_expiration_timer_cb (void *cookie) { if (!cookie) return; lacpa_port_t *port = (lacpa_port_t *)cookie; if (!port) return; AIM_LOG_TRACE("Periodic timer callback for port: %d", port->actor.port_no); if (port->lacp_state != LACPA_MACHINE_AGENT_STOPPED) { port->debug_info.ntt_reason = LACPA_TRANSMIT_PERIODIC_TIMER_EXPIRED; lacpa_transmit(port); } else { lacpa_stop_periodic_timer(port); } }
/* * lacpa_process_pdu * * Do the following with the incoming PDU: * 1. Compare Actor Info in the PDU with our Partner Info * 2. Compare Partner Info in the PDU with our Actor Info * 3. Decide if we need to Tx a new LACPDU * 4. Decide Protocol Converged/Unconverged */ static void lacpa_process_pdu (lacpa_port_t *port, lacpa_pdu_t *pdu) { bool ntt = FALSE; if (!port || !pdu) return; lacpa_update_partner(port, pdu); lacpa_update_ntt(port, pdu, &ntt); lacpa_update_convergence(port, &ntt); /* * Identify if there is a need to inform the controller */ if (port->is_converged) lacpa_update_controller(port); /* * Identify if there is a need to transmit a new LACPDU */ if (ntt) lacpa_transmit(port); }
/* * lacpa_machine * * LACP Agent State Machine * * Rx/Tx and Processing of LACPDU's. */ extern void lacpa_machine (lacpa_port_t *port, lacpa_pdu_t *pdu) { lacpa_error_t prev_error; if (!port || !port->system) return; lacpa_machine_t prev_state = port->lacp_state; switch (port->lacp_event) { case LACPA_EVENT_DISABLED: port->lacp_state = LACPA_MACHINE_AGENT_STOPPED; port->lacp_enabled = FALSE; lacpa_periodic_machine(port, FALSE); lacpa_churn_detection_machine(port, FALSE); lacpa_current_while_timer(port, FALSE); port->system->lacp_active_port_count--; break; case LACPA_EVENT_ENABLED: port->lacp_state = LACPA_MACHINE_AGENT_CURRENT; port->lacp_enabled = TRUE; /* * Set Actor's LACP_ACTIVITY, LACP_TIMEOUT and AGGREGATION * to default values */ LACPA_SET_STATE_LACP_ACTIVITY(port->actor.state); LACPA_CLR_STATE_LACP_TIMEOUT(port->actor.state); LACPA_SET_STATE_AGGREGATION(port->actor.state); port->ntt_reason = LACPA_TRANSMIT_AGENT_ENABLED; lacpa_transmit(port); lacpa_periodic_machine(port, TRUE); lacpa_churn_detection_machine(port, TRUE); lacpa_current_while_timer(port, TRUE); port->system->lacp_active_port_count++; break; case LACPA_EVENT_PDU_RECEIVED: port->lacp_state = LACPA_MACHINE_AGENT_CURRENT; LACPA_CLR_STATE_LACP_TIMEOUT(port->actor.state); prev_error = port->error; /* * Process the received Partner LACPDU */ lacpa_process_pdu(port, pdu); /* * Restart the churn detection timer if: * 1. Converged * 2. Unconverged; but because of a different reason */ if (port->is_converged || (prev_error != port->error)) { AIM_LOG_TRACE("Restarting Churn Detection timer for port: %d, " "is_converged: %d, prev_error: %{lacpa_error}, " "new_error: %{lacpa_error}", port->actor.port_no, port->is_converged, prev_error, port->error); lacpa_churn_detection_machine(port, TRUE); } else if (prev_state == LACPA_MACHINE_AGENT_DEFAULTED) { AIM_LOG_TRACE("Prev State was AGENT_DEFAULTED due to same error: " "%{lacpa_error}, Staying in Defaulted State for port:" " %d", port->error, port->actor.port_no); port->lacp_state = LACPA_MACHINE_AGENT_DEFAULTED; } lacpa_current_while_timer(port, TRUE); break; case LACPA_EVENT_CURRENT_TIMER_EXPIRED: port->lacp_state = LACPA_MACHINE_AGENT_EXPIRED; /* * Set the Actor/Partner LACP Timeout to Short so that we can do * FAST Transmits of LACPDU's */ LACPA_SET_STATE_LACP_TIMEOUT(port->actor.state); if (!LACPA_IS_STATE_LACP_TIMEOUT(port->partner.state)) { LACPA_SET_STATE_LACP_TIMEOUT(port->partner.state); lacpa_periodic_machine(port, TRUE); } lacpa_transmit(port); lacpa_current_while_timer(port, TRUE); break; case LACPA_EVENT_EXPIRY_TIMER_EXPIRED: case LACPA_EVENT_CHURN_DETECTION_EXPIRED: case LACPA_EVENT_PROTOCOL_UNCONVERGED: port->lacp_state = LACPA_MACHINE_AGENT_DEFAULTED; lacpa_defaulted(port); break; default: break; } AIM_LOG_TRACE("State change for Port: %d, Event: %{lacpa_event}, Prev: " "%{lacpa_machine}, New: %{lacpa_machine}", port->actor.port_no, port->lacp_event, prev_state, port->lacp_state); }