Пример #1
0
/*
 * 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);
    }
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
/*
 * 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);
}