コード例 #1
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 *  Sets the local system Id
 *  The LACP module gives the suggested actor parameters according
 *  to mlag protocol state (possible answers are local parameters set in this
 *  function or the remote side parameters)
 *
 *  @param[in] local_sys_id - local system ID
 *
 * @return 0 when successful, otherwise ERROR
 */
int
lacp_manager_system_id_set(unsigned long long local_sys_id)
{
    int err = 0;
    struct peer_lacp_sync_message sync_message;

    MLAG_LOG(MLAG_LOG_NOTICE,
             "LACP system ID set to [%llu] \n", local_sys_id);

    err = lacp_db_local_system_id_set(local_sys_id);
    MLAG_BAIL_ERROR(err);

    if (current_role == MASTER) {
        sync_message.mlag_id = MASTER_PEER_ID;
        sync_message.phase = LACP_SYS_ID_UPDATE;
        sync_message.sys_id = local_sys_id;

        MLAG_LOG(MLAG_LOG_NOTICE,
                 "send LACP sys id update to peer [%u] \n", SLAVE_PEER_ID);

        /* Send sync message with new system id */
        err = lacp_manager_message_send(MLAG_LACP_SYNC_MSG,
                                        &sync_message, sizeof(sync_message),
                                        SLAVE_PEER_ID, MASTER_LOGIC);

        /* Send system id update event to port manager */
        err = send_system_event(MLAG_LACP_SYS_ID_UPDATE_EVENT, NULL, 0);
        MLAG_BAIL_ERROR(err);
    }

bail:
    return err;
}
コード例 #2
0
/**
 *  This function starts mlag l3 interface peer sub-module
 *
 *  @param data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_start(uint8_t *data)
{
    int err = 0;
    int i;
    UNUSED_PARAM(data);

    if (!is_inited) {
    	err = ECANCELED;
    	MLAG_BAIL_ERROR_MSG(err, "l3 interface peer start called before init\n");
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "l3 interface peer manager start\n");

    is_started = 1;
    is_peer_start = 0;
    is_master_sync_done = 0;
    for (i = 0; i < VLAN_N_VID; i++) {
        ipl_vlan_list[i] = 0;
    }

    /* Configure IPL as member of vlan of ipl l3 interface for control messages */
    if ((ipl_vlan_id > 0) &&
    	(ipl_vlan_id < VLAN_N_VID)) {

        err = mlag_topology_ipl_port_get(0, &ipl_ifindex);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to get ipl data from mlag topology database upon start, err=%d\n",
        		err);

        /* For start after disable mlag protocol vlan_id as well as
         * ipl ifindex are not relevant.
         * In that case ipl ifindex 0 will be returned.
         * Ignore it up to peer add event that should configure
         * above mentioned parameters.
         */
        if (ipl_ifindex == 0) {
            goto bail;
        }

        MLAG_LOG(MLAG_LOG_NOTICE, "Add ipl %lu to vlan %d\n",
                 ipl_ifindex, ipl_vlan_id);

        /* Add IPL to vlan */
        err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_ADD,
                                                ipl_ifindex,
                                                &ipl_vlan_id, 1);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to set ipl vlan membership, err=%d, ipl=%lu, vlan_id=%d\n",
        		err, ipl_ifindex, ipl_vlan_id);

        ipl_vlan_list[ipl_vlan_id] = 1;
        mlag_l3_interface_inc_cnt(ADD_IPL_TO_VLAN_EVENTS_SENT);
    }

bail:
    return err;
}
コード例 #3
0
/**
 *  This function adds IPL to vlan of l3 interface
 *  to exchange control messages
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_vlan_interface_add(struct peer_conf_event_data *data)
{
    int err = 0;

    ASSERT(data);

    if (!is_inited) {
    	MLAG_BAIL_ERROR_MSG(err, "Add ipl to vlan interface called before init\n");
    }

    /* vlan_id can be 0 when delete peer event accepted */
    if (!(data->vlan_id < VLAN_N_VID)) {
    	MLAG_BAIL_ERROR_MSG(err, "vlan id %d is not valid\n", data->vlan_id);
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "Add ipl to vlan interface %d\n", data->vlan_id);

    ipl_vlan_id = data->vlan_id;

    if (!is_started) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Add ipl to vlan interface %d ignored because called before start\n",
                 ipl_vlan_id);
        goto bail;
    }

    /* Check if IPL is not a member of the vlan */
    if ((ipl_vlan_id != 0) &&
    	(ipl_vlan_list[ipl_vlan_id] == 0)) {

        /* Add IPL to vlan */
        err = mlag_topology_ipl_port_get(0, &ipl_ifindex);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to get ipl port data from mlag topology: ipl vlan id=%d, ipl ifindex=%lu, err=%d\n",
        		ipl_vlan_id, ipl_ifindex, err);

        if (ipl_ifindex == 0) {
            goto bail;
        }
        err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_ADD,
                                                ipl_ifindex,
                                                &ipl_vlan_id, 1);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to add ipl %lu to vlan interface %d, err %d\n",
        		ipl_ifindex, ipl_vlan_id, err);

        ipl_vlan_list[ipl_vlan_id] = 1;
        mlag_l3_interface_inc_cnt(ADD_IPL_TO_VLAN_EVENTS_SENT);
    }

bail:
    return err;
}
コード例 #4
0
/**
 *  This function handles local sync done event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_local_sync_done(uint8_t *data)
{
    int err = 0;
    UNUSED_PARAM(data);
    struct sync_event_data ev;
    struct mlag_master_election_status master_election_current_status;

    MLAG_LOG(MLAG_LOG_NOTICE,
    		"send MLAG_L3_SYNC_FINISH_EVENT to master logic\n");

    err = mlag_master_election_get_status(&master_election_current_status);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed to get status from master election in handling of local sync done event, err=%d\n",
    		err);

    /* Send MLAG_L3_SYNC_FINISH_EVENT to Master Logic */
    ev.peer_id = master_election_current_status.my_peer_id;
    ev.state = 1;
    err = mlag_dispatcher_message_send(MLAG_L3_SYNC_FINISH_EVENT,
    		&ev, sizeof(ev), MASTER_PEER_ID, PEER_MANAGER);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed in sending MLAG_L3_SYNC_FINISH_EVENT, err=%d\n",
    		err);

bail:
    return err;
}
コード例 #5
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 * Sends notification to reject request
 *
 * @param[in] request - selection request data
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
reject_pending_request(struct lacp_aggregation_message_data *request)
{
    int err = 0;

    MLAG_LOG(MLAG_LOG_DEBUG, "Reject pending request id [%u] port [%lu]\n",
             request->request_id, request->port_id);

    request->is_response = TRUE;
    request->response = LACP_AGGREGATE_DECLINE;

    err = notify_aggregator_selection_response(request);
    MLAG_BAIL_ERROR(err);

    err = lacp_db_pending_request_delete(request->port_id);
    if (err && (err != -ENOENT)) {
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to clear pending request port [%lu] request [%u]",
                            request->port_id, request->request_id);
    }
    else {
        err = 0;
    }

bail:
    return err;
}
コード例 #6
0
/**
 *  This function inits mlag l3 interface peer sub-module
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_init(void)
{
    int err = 0;
    int i;

    if (is_inited) {
    	err = ECANCELED;
    	MLAG_BAIL_ERROR_MSG(err, "l3 interface peer init called twice\n");
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "l3 interface peer init\n");

    is_inited = 1;
    is_started = 0;
    is_peer_start = 0;
    ipl_ifindex = 0;
    ipl_vlan_id = 0;
    is_master_sync_done = 0;
    for (i = 0; i < VLAN_N_VID; i++) {
        ipl_vlan_list[i] = 0;
    }

bail:
    return err;
}
コード例 #7
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 *  Handles peer start notification.Peer start
 *  triggers lacp sync process start. The Master
 *  sends its actor attributes to the remotes.
 *
 * @param[in] mlag_peer_id - peer global index
 *
 * @return 0 if operation completes successfully.
 */
int
lacp_manager_peer_start(int mlag_peer_id)
{
    int err = 0;
    struct peer_lacp_sync_message sync_message;
    struct mlag_master_election_status me_status;

    ASSERT(mlag_peer_id < MLAG_MAX_PEERS);

    if ((started == FALSE) || (lacp_enabled == FALSE)) {
        goto bail;
    }

    err = mlag_master_election_get_status(&me_status);
    MLAG_BAIL_ERROR_MSG(err, "Failed getting ME status\n");

    /* Master will send sync done for itself */
    if (me_status.current_status == SLAVE) {
        /* Slave will send sync start message */
        sync_message.mlag_id = me_status.my_peer_id;
        sync_message.phase = LACP_SYNC_START;

        /* Send message to master */
        MLAG_LOG(MLAG_LOG_DEBUG,
                 "LACP peer [%d] sync send to master \n",
                 sync_message.mlag_id);

        /* Send to master logic sync message */
        err = lacp_manager_message_send(MLAG_LACP_SYNC_MSG,
                                        &sync_message, sizeof(sync_message),
                                        me_status.master_peer_id,
                                        PEER_MANAGER);
        MLAG_BAIL_ERROR_MSG(err, "Failed in sending ports sync message \n");
    }
    else if (mlag_peer_id == me_status.my_peer_id) {
        MLAG_LOG(MLAG_LOG_NOTICE, "Send LACP peer sync\n");
        err = lacp_send_sync_done(mlag_peer_id);
        MLAG_BAIL_ERROR_MSG(err, "Failed in sending lacp sync done\n");
    }

bail:
    return err;
}
コード例 #8
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 *  This function is called to handle IBC message
 *
 * @param[in] data - message body
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
rcv_msg_handler(uint8_t *data)
{
    int err = 0;
    struct recv_payload_data *payload_data = (struct recv_payload_data*) data;
    uint16_t opcode;

    struct peer_lacp_sync_message *lacp_sync;
    struct lacp_aggregation_message_data *select_req;
    struct lacp_aggregator_release_message *rel_msg;

    opcode = *((uint16_t*)(payload_data->payload[0]));

    if ((started == FALSE) || (lacp_enabled == FALSE)) {
        goto bail;
    }

    MLAG_LOG(MLAG_LOG_INFO,
             "lacp manager rcv_msg_handler: opcode=%d\n", opcode);

    lacp_db_counters_inc(LM_CNT_PROTOCOL_RX);

    switch (opcode) {
    case MLAG_LACP_SYNC_MSG:
        lacp_sync =
            (struct peer_lacp_sync_message*) payload_data->payload[0];
        err = handle_lacp_sync_msg(lacp_sync);
        MLAG_BAIL_ERROR_MSG(err, "Failed in handling LACP sync message\n");
        break;
    case MLAG_LACP_SELECTION_EVENT:
        select_req =
            (struct lacp_aggregation_message_data *) payload_data->payload[0];

        err = lacp_manager_aggregator_selection_handle(select_req);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to handle aggregation selection event\n");
        break;
    case MLAG_LACP_RELEASE_EVENT:
        rel_msg =
            (struct lacp_aggregator_release_message *) payload_data->payload[0];

        err = lacp_manager_aggregator_free_handle(rel_msg);
        MLAG_BAIL_ERROR_MSG(err, "Failed to handle aggregation free event\n");
        break;
    default:
        /* Unknown opcode */
        err = -ENOENT;
        MLAG_BAIL_ERROR_MSG(err, "Unknown opcode [%u] in lacp manager\n",
                            opcode);
        break;
    }

bail:
    return err;
}
コード例 #9
0
/**
 *  This function de-inits mlag l3 interface peer sub-module
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_deinit(void)
{
    int err = 0;

    if (!is_inited) {
    	err = ECANCELED;
    	MLAG_BAIL_ERROR_MSG(err, "l3 interface peer deinit called before init\n");
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "l3 interface peer deinit\n");

bail:
    return err;
}
コード例 #10
0
ファイル: notification_layer.c プロジェクト: nirdotan/MLAG
/**
 * Used for dispatching mlag protocol notification
 *
 * @param[in] mlag_notification - mlag notification data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_notify(struct mlag_notification *notification)
{
    int err = 0;

    MLAG_LOG(MLAG_LOG_DEBUG, "mlag_notify [%s]\n",
             mlag_notification_str[notification->notification_type]);

    if (notification->notification_type == MLAG_NOTIFY_AGGREGATOR_RESPONSE) {
        MLAG_LOG(MLAG_LOG_DEBUG, "req [%u] port [%lu]  : response [%u]\n",
                 notification->notification_info.agg_response.request_id,
                 notification->notification_info.agg_response.req_port_id,
                 notification->notification_info.agg_response.response);
        MLAG_LOG(MLAG_LOG_DEBUG, "key [%u] partner [%llu] \n",
                 notification->notification_info.agg_response.req_partner_key,
                 notification->notification_info.agg_response.req_partner_id);
    }
    if (notification->notification_type == MLAG_NOTIFY_AGGREGATOR_RELEASE) {
        MLAG_LOG(MLAG_LOG_DEBUG, "Released port id [%lu] \n",
                 notification->notification_info.agg_release.port_id);
    }

    return err;
}
コード例 #11
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 *  This function is called to handle network order for IBC message
 *
 * @param[in] payload_data - message body
 * @param[in] oper - on send or receive
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
net_order_msg_handler(uint8_t *data, int oper)
{
    int err = 0;
    uint16_t opcode;
    struct peer_lacp_sync_message *lacp_sync;
    struct lacp_aggregator_release_message *rel_msg;
    struct lacp_aggregation_message_data *agg_msg;

    if (oper == MESSAGE_SENDING) {
        opcode = *(uint16_t*)data;
        *(uint16_t*)data = htons(opcode);
    }
    else {
        opcode = ntohs(*(uint16_t*)data);
        *(uint16_t*)data = opcode;
    }

    MLAG_LOG(MLAG_LOG_DEBUG,
             "lacp_manager net_order_msg_handler: opcode=%d\n",
             opcode);

    switch (opcode) {
    case MLAG_LACP_SYNC_MSG:
        lacp_sync = (struct peer_lacp_sync_message *) data;
        net_order_lacp_sync_data(lacp_sync, oper);
        break;
    case MLAG_LACP_SELECTION_EVENT:
        agg_msg = (struct lacp_aggregation_message_data *) data;
        net_order_aggregator_selection_data(agg_msg, oper);
        break;
    case MLAG_LACP_RELEASE_EVENT:
        rel_msg = (struct lacp_aggregator_release_message *) data;
        net_order_aggregator_release_data(rel_msg, oper);
        break;

    default:
        /* Unknown opcode */
        err = -ENOENT;
        MLAG_BAIL_ERROR_MSG(err, "Unknown opcode [%u] in lacp manager\n",
                            opcode);
        break;
    }
bail:
    return err;
}
コード例 #12
0
/**
 *  This function stops mlag l3 interface peer sub-module
 *
 *  @param data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_stop(uint8_t *data)
{
    int err = 0;
    int i;
    UNUSED_PARAM(data);
    int num_vlans_to_del = 0;

    if (!is_started) {
        goto bail;
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "l3 interface peer manager stop\n");

    /* Check on ipl ifindex validity */
	err = mlag_topology_ipl_port_get(0, &ipl_ifindex);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed to get ipl data from mlag topology database upon stop, err=%d\n",
    		err);

    if (ipl_ifindex == 0) {
    	goto bail;
    }
    /* Remove IPL from all vlans */
    for (i = 1; i < VLAN_N_VID; i++) {
        if (ipl_vlan_list[i]) {
            /* Remove IPL from vlan */
            ipl_vlan_list[i] = 0;
            sl_vlan_list[num_vlans_to_del++] = i;
            mlag_l3_interface_inc_cnt(DEL_IPL_FROM_VLAN_EVENTS_SENT);
        }
    }

    if (num_vlans_to_del) {
    	err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_DELETE,
    			ipl_ifindex, sl_vlan_list, num_vlans_to_del);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to delete ipl vlan membership, err=%d, ipl_ifindex=%lu, num_vlans_to_del=%d\n",
        		err, ipl_ifindex, num_vlans_to_del);
    }

bail:
    is_started = 0;
    return err;
}
コード例 #13
0
/**
 *  This function handles master sync done event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_master_sync_done(uint8_t *data)
{
    int err = 0;
    UNUSED_PARAM(data);

    is_master_sync_done = 1;

    MLAG_LOG(MLAG_LOG_NOTICE, "send local vlan oper status trigger\n");

    /* Send query to update local vlans operational states */
    err = sl_api_vlan_oper_status_trigger_get();
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed in local vlan oper status trigger, err=%d\n",
    		err);

bail:
    return err;
}
コード例 #14
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 * This function is sending sync done message to the master, it should not be
 * called on the slave
 *
 * @param[in] mlag_id - This is the mlag ID
 *
 * @return 0 if operation completes successfully.
 */
static int
lacp_send_sync_done(int mlag_id)
{
    int err = 0;
    struct sync_event_data data;

    data.peer_id = mlag_id;
    data.opcode = 0;
    data.sync_type = LACP_PEER_SYNC;
    data.state = 1; /* finish */

    err = send_system_event(MLAG_PEER_SYNC_DONE, &data, sizeof(data));
    MLAG_BAIL_ERROR(err);

    MLAG_LOG(MLAG_LOG_NOTICE, "Successfully sent SYNC_DONE for LACP\n");

bail:
    return err;
}
コード例 #15
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 * Returns actor attributes. The actor attributes are
 * system ID, system priority to be used in the LACP PDU
 * and a chassis ID which is an index of this node within the MLAG
 * cluster, with a value in the range of 0..15
 *
 * @param[out] actor_sys_id - actor sys ID (for LACP PDU)
 * @param[out] chassis_id - MLAG cluster chassis ID, range 0..15
 *
 * @return 0 when successful, otherwise ERROR
 */
int
lacp_manager_actor_parameters_get(unsigned long long *actor_sys_id,
                                  unsigned int *chassis_id)
{
    int err = 0;
    struct mlag_master_election_status me_status;

    ASSERT(actor_sys_id != NULL);
    ASSERT(chassis_id != NULL);

    if ((started == FALSE) || (lacp_enabled == FALSE)) {
        *chassis_id = 0;
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Actor parameters requested although LACP module inactive\n");
        err = lacp_db_local_system_id_get(actor_sys_id);
        MLAG_BAIL_ERROR_MSG(err, "Failed to retrieve local LACP attributes\n");
        goto bail;
    }

    err = mlag_master_election_get_status(&me_status);
    MLAG_BAIL_ERROR_MSG(err, "Failed getting ME status\n");

    /* If slave we return master's parameters, otherwise we
     * return the local parameters
     */
    if ((me_status.current_status == SLAVE) &&
        (use_local_lacp_logic == FALSE)) {
        err = lacp_db_master_system_id_get(actor_sys_id);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to retrieve master LACP attributes\n");
        /* Chassis ID is set by master election module */
        *chassis_id = me_status.my_peer_id;
    }
    else {
        *chassis_id = 0;
        err = lacp_db_local_system_id_get(actor_sys_id);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to retrieve master LACP attributes\n");
    }

bail:
    return err;
}
コード例 #16
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 *  This function implements LACP selection
 *
 * @param[in] mlag_id - mlag id of requestor
 * @param[in] port_id - port ID
 * @param[in] partner_id - request partner ID
 * @param[out] response - selected or not
 * @param[out] current_partner_id - currently selected partner id
 * @param[out] current_partner_key - currently selected partner key
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
lacp_aggregator_select_logic(int mlag_id,
                             unsigned long port_id,
                             unsigned long long partner_id,
                             unsigned int partner_key,
                             enum aggregate_select_response *response,
                             unsigned long long *current_partner_id,
                             unsigned int *current_partner_key)
{
    int err = 0;
    int i;
    struct mlag_lacp_data *lacp_data = NULL;
    *response = LACP_AGGREGATE_DECLINE;

    MLAG_LOG(MLAG_LOG_INFO,
             "Aggregator select logic for port [%lu] partner [%llu] key [%u]\n",
             port_id, partner_id, partner_key);

    err = lacp_db_entry_get(port_id, &lacp_data);
    if (err == -ENOENT) {
        /* create entry for first entry */
        err = lacp_db_entry_allocate(port_id, &lacp_data);
        MLAG_BAIL_ERROR_MSG(err, "Failed to create lacp entry port [%lu]\n",
                            port_id);
        lacp_data->partner_id = partner_id;
        lacp_data->partner_key = partner_key;
        for (i = 0; i < MLAG_MAX_PEERS; i++) {
            lacp_data->peer_state[i] = FALSE;
        }
    }
    if ((lacp_data->partner_id == partner_id) &&
        (lacp_data->partner_key == partner_key)) {
        /* Update users and ACCEPT request */
        lacp_data->peer_state[mlag_id] = TRUE;
        *response = LACP_AGGREGATE_ACCEPT;
    }
    *current_partner_key = lacp_data->partner_key;
    *current_partner_id = lacp_data->partner_id;

bail:
    return err;
}
コード例 #17
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 *  This function handles peer state change notification.
 *
 * @param[in] state_change - state  change data
 *
 * @return 0 if operation completes successfully.
 */
int
lacp_manager_peer_state_change(struct peer_state_change_data *state_change)
{
    int err = 0;
    int i;
    struct lacp_peer_down_ports_data peer_down_data;

    MLAG_LOG(MLAG_LOG_NOTICE, "LACP manager peer state change [%d]\n",
             state_change->state);

    if ((started == FALSE) || (lacp_enabled == FALSE)) {
        goto bail;
    }

    if ((current_role == SLAVE) && (state_change->state != HEALTH_PEER_UP)) {
        /* reject all pending requests */
        err = lacp_db_pending_foreach(clear_pending_request, NULL);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to reject pending requests on peer down\n");
        /* switch to local LACP logic */
        set_lacp_logic_origin(TRUE);
    }
    if ((current_role == MASTER) && (state_change->state != HEALTH_PEER_UP)) {
        peer_down_data.mlag_id = state_change->mlag_id;
        peer_down_data.port_num = 0;
        /* peer down, clear all active system IDs taken by this peer */
        err = lacp_db_port_foreach(clear_peer, &peer_down_data);
        MLAG_BAIL_ERROR_MSG(err, "Failed to clear peer usage on peer down\n");

        /* clear DB from unused entries */
        for (i = 0; i < peer_down_data.port_num; i++) {
            err = lacp_db_entry_delete(peer_down_data.ports_to_delete[i]);
            MLAG_BAIL_ERROR_MSG(err,
                                "Failed to remove port [%lu] entry on peer down\n",
                                peer_down_data.ports_to_delete[i]);
        }
    }

bail:
    return err;
}
コード例 #18
0
/**
 *  This function removes IPL from vlan of l3 interface
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_vlan_interface_del()
{
    int err = 0;

    if (!is_inited) {
    	MLAG_BAIL_ERROR_MSG(err, "Delete ipl from vlan interface called before init\n");
    }

    MLAG_LOG(MLAG_LOG_NOTICE, "Delete ipl from vlan interface: ipl_vlan_id=%d\n",
    		 ipl_vlan_id);

    /* Check if IPL is not a member of the vlan */
    if ((ipl_vlan_id != 0) &&
    	(ipl_vlan_list[ipl_vlan_id] == 1)) {
        ipl_vlan_list[ipl_vlan_id] = 0;
    }

bail:
    return err;
}
コード例 #19
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 * Sends notification to reject request
 *
 * @param[in] msg - selection request data
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
notify_aggregator_selection_response(struct lacp_aggregation_message_data *msg)
{
    int err = 0;
    struct lacp_aggregation_message_data *db_req = NULL;
    struct mlag_notification notify;

    /* check if there is a pending request in DB */
    err = lacp_db_pending_request_get(msg->port_id, &db_req);
    if ((err == -ENOENT) || (db_req == NULL) ||
        (db_req->request_id != msg->request_id)) {
        /* no pending request - ignore */
        err = 0;
        MLAG_LOG(MLAG_LOG_DEBUG, "Ignore response port ID [%lu] req ID [%u]\n",
                 msg->port_id, msg->request_id);
        goto bail;
    }
    MLAG_BAIL_ERROR(err);

    /* fill notification msg */
    notify.notification_type = MLAG_NOTIFY_AGGREGATOR_RESPONSE;
    notify.notification_info.agg_response.request_id = msg->request_id;
    notify.notification_info.agg_response.req_partner_id = msg->partner_id;
    notify.notification_info.agg_response.req_partner_key = msg->partner_key;
    notify.notification_info.agg_response.req_port_id = msg->port_id;
    notify.notification_info.agg_response.response = msg->response;

    err = mlag_notify(&notify);
    MLAG_BAIL_ERROR_MSG(err,
                        "Failed to notify response for port [%lu] req [%u]",
                        msg->port_id, msg->request_id);

    err = lacp_db_pending_request_delete(msg->port_id);
    MLAG_BAIL_ERROR_MSG(err,
                        "Failed to clear pending request port [%lu] request [%u]",
                        msg->port_id, msg->request_id);

bail:
    return err;
}
コード例 #20
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 * Handles a aggregator release
 * This may involve a remote peer,
 *
 * @param[in] request_id - index given by caller that will appear in reply
 * @param[in] port_id - Interface index of port. Must represent MLAG port.
 *
 * @return 0 when successful, otherwise ERROR
 */
int
lacp_manager_aggregator_selection_release(unsigned int request_id,
                                          unsigned long port_id)
{
    int err = 0;
    struct lacp_aggregation_message_data *previous_req = NULL;
    struct lacp_aggregation_message_data selection_req;

    if (lacp_enabled == FALSE) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Request for selection release while LACP disabled\n");
        goto bail;
    }

    /* Expect there is an outstanding request -> reject it */
    err = lacp_db_pending_request_get(port_id, &previous_req);
    if (err && (err != -ENOENT)) {
        MLAG_BAIL_ERROR_MSG(err, "Failed in pending request lookup\n");
    }
    else if (err == 0) {
        /* Found a pending request - drop it */
        err = lacp_db_pending_request_delete(port_id);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed to delete pending request for port [%lu]",
                            port_id);
    }

    /* prepare selection request */
    selection_req.is_response = FALSE;
    selection_req.request_id = request_id;
    selection_req.port_id = port_id;

    /* send selection request to master logic */
    err = send_release_message(&selection_req);
    MLAG_BAIL_ERROR(err);

bail:
    return err;
}
コード例 #21
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 *  Handle incoming LACP sync data
 *
 * @param[in] lacp_sync - message body
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
update_lacp_master_attributes(struct peer_lacp_sync_message *lacp_sync)
{
    int err = 0;

    MLAG_LOG(MLAG_LOG_NOTICE,
             "got lacp sync id is [%llu]\n", lacp_sync->sys_id);

    if (current_role == SLAVE) {

    	err = lacp_db_master_system_id_set(lacp_sync->sys_id);
    	MLAG_BAIL_ERROR(err);

    	if (lacp_sync->phase == LACP_SYS_ID_UPDATE) {
    		/* Send system id update event to port manager */
    		err = send_system_event(MLAG_LACP_SYS_ID_UPDATE_EVENT, NULL, 0);
    		MLAG_BAIL_ERROR(err);
    	}
    }

bail:
    return err;
}
コード例 #22
0
/**
 *  This function handles peer start event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_peer_start(struct peer_state_change_data *data)
{
    int err = 0;
    struct sync_event_data ev;

    MLAG_LOG(MLAG_LOG_NOTICE,
             "Sending MLAG_L3_SYNC_START_EVENT to master logic\n");

    is_peer_start = 1;

    /* Send MLAG_SYNC_START_EVENT event to Master Logic */
    ev.peer_id = data->mlag_id;
    ev.state = 0;
    err = mlag_dispatcher_message_send(MLAG_L3_SYNC_START_EVENT, &ev,
                                       sizeof(ev), MASTER_PEER_ID,
                                       PEER_MANAGER);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed in sending MLAG_L3_SYNC_START_EVENT, err=%d\n",
    		err);

bail:
    return err;
}
コード例 #23
0
/**
 *  This function dumps sub-module's internal attributes
 *
 * @param[in] dump_cb - callback for dumping, if NULL, log will be used
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_print(void (*dump_cb)(const char *, ...))
{
    int i, cnt, total_cnt, tmp;

    if (dump_cb == NULL) {
       	MLAG_LOG(MLAG_LOG_NOTICE, "L3 interface local peer dump:\n");
    	MLAG_LOG(MLAG_LOG_NOTICE, "is_initialized=%d, is_started=%d, "
    	        "is_peer_start=%d, is_master_sync_done=%d\n",
    			 is_inited, is_started, is_peer_start, is_master_sync_done);
    }
    else {
    	dump_cb("L3 interface local peer dump:\n");
    	dump_cb("is_initialized=%d, is_started=%d, is_peer_start=%d, "
    	        "is_master_sync_done=%d\n",
   			    is_inited, is_started, is_peer_start, is_master_sync_done);
    }

    if (dump_cb == NULL) {
        MLAG_LOG(MLAG_LOG_NOTICE, "ipl_ifindex=%lu, ipl_vlan_id=%d\n",
                 ipl_ifindex, ipl_vlan_id);
    }
    else {
        dump_cb("ipl_ifindex=%lu, ipl_vlan_id=%d\n",
                ipl_ifindex, ipl_vlan_id);
    }

    if (!is_inited) {
        goto bail;
    }

    /* Print IPL vlan list */
    if (dump_cb == NULL) {
        MLAG_LOG(MLAG_LOG_NOTICE, "ipl vlan list:\n");
    }
    else {
        dump_cb("ipl vlan list:\n");
    }

    for (i = 1, total_cnt = 0; i < VLAN_N_VID; i++) {
        if (ipl_vlan_list[i]) {
        	total_cnt++;
        }
    }
    for (i = 1, cnt = 0, tmp = 0; i < VLAN_N_VID; i++) {
        if (ipl_vlan_list[i]) {
        	if ((++cnt > 100) &&
                (cnt < (total_cnt-100))) {
        		continue;
        	}
       		tmp++;
       		if (dump_cb == NULL) {
       			MLAG_LOG(MLAG_LOG_NOTICE, "%d  ", i);
       		}
       		else {
       			dump_cb("%d  ", i);
       		}
        	if (tmp >= 10) {
        		if (dump_cb == NULL) {
        			MLAG_LOG(MLAG_LOG_NOTICE, "\n");
        		}
        		else {
        			dump_cb("\n");
        		}
        		tmp = 0;
        	}
        }
    }
    if (dump_cb == NULL) {
    	MLAG_LOG(MLAG_LOG_NOTICE, "\ntotal vlans in ipl_vlan_list: %d\n", total_cnt);
    	MLAG_LOG(MLAG_LOG_NOTICE, "\n");
    }
    else {
    	dump_cb("\ntotal vlans in ipl_vlan_list: %d\n", total_cnt);
    	dump_cb("\n");
    }

bail:
    return 0;
}
コード例 #24
0
/**
 *  This function handles vlan global state change event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_vlan_global_state_change(
    struct vlan_state_change_event_data *data)
{
    int err = 0;
    int i;
    unsigned short vlan_id;
    int num_vlans_to_add = 0;
    int num_vlans_to_del = 0;

    ASSERT(data);

    if (!is_started) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Vlan global state change event accepted before start of module\n");
        goto bail;
    }

    if (!is_peer_start) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Vlan global state change event accepted before peer start event\n");
    }

    MLAG_LOG(MLAG_LOG_INFO, "Vlan global state change event: number vlans %d\n",
             data->vlans_arr_cnt);

    mlag_l3_interface_inc_cnt(VLAN_GLOBAL_STATE_EVENTS_RCVD);

    for (i=0; i < data->vlans_arr_cnt; i++) {
    	vlan_id = data->vlan_data[i].vlan_id;
    	if (data->vlan_data[i].vlan_state == VLAN_GLOBAL_DOWN) {
    		/* Check if IPL is a member of the vlan */
    		if (ipl_vlan_list[vlan_id] == 1) {
    			/* Remove IPL from vlan */
    			/* Do not remove vlan of mlag control messages interface from ipl */
    			if (vlan_id != ipl_vlan_id) {
    				ipl_vlan_list[vlan_id] = 0;
    				sl_vlan_list[num_vlans_to_del++] = vlan_id;
    				mlag_l3_interface_inc_cnt(DEL_IPL_FROM_VLAN_EVENTS_SENT);
    			}
    			else {
    				MLAG_LOG(MLAG_LOG_NOTICE,
    						"ignored ipl vlan %d, state=%s\n",
    						vlan_id, l3_interface_vlan_global_state_str[data->vlan_data[i].vlan_state]);
    			}
    		}
    	}
    }
    if (num_vlans_to_del) {
    	err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_DELETE,
    			ipl_ifindex, sl_vlan_list, num_vlans_to_del);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to delete ipl vlan membership, err=%d\n",
        		err);
    }

    for (i=0; i < data->vlans_arr_cnt; i++) {
    	vlan_id = data->vlan_data[i].vlan_id;
    	if (data->vlan_data[i].vlan_state == VLAN_GLOBAL_UP) {
    		/* Check if IPL is not a member of the vlan */
    		if (ipl_vlan_list[vlan_id] == 0) {
    			/* Add IPL to vlan */
    			ipl_vlan_list[vlan_id] = 1;
    			sl_vlan_list[num_vlans_to_add++] = vlan_id;
    			mlag_l3_interface_inc_cnt(ADD_IPL_TO_VLAN_EVENTS_SENT);
    		}
    	}
    }
    if (num_vlans_to_add) {
    	err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_ADD,
    			ipl_ifindex, sl_vlan_list, num_vlans_to_add);
        MLAG_BAIL_ERROR_MSG(err,
        		"Failed to add ipl vlan membership, err=%d\n",
        		err);
    }

bail:
    return err;
}
コード例 #25
0
/**
 *  This function handles vlan local state change event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_vlan_local_state_change(
    struct vlan_state_change_event_data *data)
{
    int err = 0;
    int ev_len = 0;
    struct mlag_master_election_status master_election_current_status;
    int i;

    ASSERT(data);

    if (!is_started) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Vlan local state change event accepted before start of module\n");
        goto bail;
    }

    if (!is_master_sync_done) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Vlan local state change event accepted before master sync done\n");
        goto bail;
    }

    MLAG_LOG(MLAG_LOG_INFO, "Vlan local state change event: number vlans %d\n",
    		 data->vlans_arr_cnt);

    if ((!data->vlans_arr_cnt) ||
        (data->vlans_arr_cnt >= VLAN_N_VID)) {
    	err = -EINVAL;
    	MLAG_BAIL_ERROR_MSG(EINVAL,	"Invalid vlans array_counter %d",
    			data->vlans_arr_cnt);
    }

    for (i=0; i < data->vlans_arr_cnt; i++) {
    	if (!(((data->vlan_data[i].vlan_id > 0) &&
    		   (data->vlan_data[i].vlan_id < VLAN_N_VID)) &&
    		  ((data->vlan_data[i].vlan_state == VLAN_DOWN) ||
    		   (data->vlan_data[i].vlan_state == VLAN_UP)))) {
        	MLAG_BAIL_ERROR_MSG(EINVAL,	"Invalid vlan parameters: vlan id=%d, vlan state=%s",
        			data->vlan_data[i].vlan_id,
        			(data->vlan_data[i].vlan_state == VLAN_UP) ? "up" : "down");
    	}
    }

    mlag_l3_interface_inc_cnt(VLAN_LOCAL_STATE_EVENTS_RCVD);

    /* Send MLAG_L3_INTERFACE_VLAN_LOCAL_STATE_CHANGE_FROM_PEER_EVENT
     * to Master Logic */
    err = mlag_master_election_get_status(&master_election_current_status);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed to get status from master election in handling of vlan local state change event, err=%d\n",
    		err);

    ev_len = sizeof(struct vlan_state_change_base_event_data) +
    		 sizeof(data->vlan_data[0]) * data->vlans_arr_cnt;

    data->peer_id = master_election_current_status.my_peer_id;

    err = mlag_dispatcher_message_send(
        MLAG_L3_INTERFACE_VLAN_LOCAL_STATE_CHANGE_FROM_PEER_EVENT,
        data, ev_len, MASTER_PEER_ID, PEER_MANAGER);
    MLAG_BAIL_ERROR_MSG(err,
    		"Failed in sending MLAG_L3_INTERFACE_VLAN_LOCAL_STATE_CHANGE_FROM_PEER_EVENT, err=%d\n",
    		err);

bail:
    return err;
}
コード例 #26
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/**
 * Handles a selection query .
 * This query may involve a remote peer,
 * When a delete command is used, only port_id parameter is relevant.
 * Force option is given in order to allow
 * releasing currently used key and migrating to the given partner.
 *
 * @param[in] request_id - index given by caller that will appear in reply
 * @param[in] port_id - Interface index of port. Must represent MLAG port.
 * @param[in] partner_id - partner system ID (taken from LACP PDU)
 * @param[in] partner_key - partner operational Key (taken from LACP PDU)
 * @param[in] force - force positive notification (will release key in use)
 *
 * @return 0 when successful, otherwise ERROR
 */
int
lacp_manager_aggregator_selection_request(unsigned int request_id,
                                          unsigned long port_id,
                                          unsigned long long partner_id,
                                          unsigned int partner_key,
                                          unsigned char force)
{
    int err = 0;
    int fail_err = 0;
    struct lacp_aggregation_message_data *previous_req = NULL;
    struct lacp_aggregation_message_data selection_req;
    int reject_req_on_err = FALSE;

    if (lacp_enabled == FALSE) {
        MLAG_LOG(MLAG_LOG_NOTICE,
                 "Request for selection release while LACP disabled\n");
        goto bail;
    }

    /* prepare selection request */
    selection_req.is_response = FALSE;
    selection_req.request_id = request_id;
    selection_req.port_id = port_id;
    selection_req.partner_id = partner_id;
    selection_req.partner_key = partner_key;
    selection_req.force = force;
    reject_req_on_err = TRUE;

    /* If there is an outstanding request -> reject it */
    err = lacp_db_pending_request_get(port_id, &previous_req);
    if (err && (err != -ENOENT)) {
        MLAG_BAIL_ERROR_MSG(err, "Failed in pending request lookup\n");
    }
    else if (err == 0) {
        previous_req->partner_id = partner_id;
        previous_req->partner_key = partner_key;
        err = reject_pending_request(previous_req);
        MLAG_BAIL_ERROR(err);
    }

    /* insert request to pending queue */
    err = update_pending_selection_queue(&selection_req);
    MLAG_BAIL_ERROR_MSG(err,
                        "Failed to update pending selection req. queue\n");

    /* check that the port is mlag port, if not avoid DB update*/
    if (port_db_entry_exist(port_id) == FALSE) {
        err = -ENOENT;
        MLAG_BAIL_ERROR_MSG(err, "Can not find Port [%lu] in port DB\n",
                            port_id);
    }

    /* send selection request to master logic */
    err = send_selection_message(&selection_req);
    MLAG_BAIL_ERROR_MSG(err,
                        "Failed to send selection req [%u] port [%lu]\n",
                        selection_req.request_id, selection_req.port_id);

bail:
    if (err && (reject_req_on_err == TRUE)) {
        fail_err = reject_pending_request(&selection_req);
        if (fail_err) {
            MLAG_LOG(MLAG_LOG_ERROR,
                     "Failed in pending req [%u] port [%lu] reject\n",
                     selection_req.request_id, selection_req.port_id);
        }
    }
    return err;
}
コード例 #27
0
/**
 *  This function handles ipl port set event
 *
 * @param[in] data - event data
 *
 * @return 0 when successful, otherwise ERROR
 */
int
mlag_l3_interface_peer_ipl_port_set(struct ipl_port_set_event_data *data)
{
    int err = 0;

    ASSERT(data);

    if (!is_inited) {
    	err = ECANCELED;
    	MLAG_BAIL_ERROR_MSG(err, "ipl port set called before init\n");
    }

    mlag_l3_interface_inc_cnt(L3_INTERFACE_IPL_PORT_SET_EVENTS_RCVD);

    if (data->ifindex == 0) {
    	/* Remove ipl port from ipl vlan due to disconnect of IPL from port-channel */
        /* Check if IPL is a member of the vlan */
        if ((ipl_vlan_id != 0) &&
        	(ipl_vlan_list[ipl_vlan_id] == 1)) {

            MLAG_LOG(MLAG_LOG_NOTICE,
                     "mlag internal delete vlan %d from ipl vlan list\n",
                     ipl_vlan_id);
            ipl_vlan_list[ipl_vlan_id] = 0;
        }
    }
    else {

    	if (!is_started) {
            MLAG_LOG(MLAG_LOG_NOTICE,
                     "ipl port set event ignored because it called before start: ipl=%d, ipl_vlan=%d\n",
                     data->ifindex, ipl_vlan_id);
            goto bail;
        }
    	/* Connect port-channel to ipl */
    	/* If ipl vlan is not configured on ipl yet configure it here */
        if ((ipl_vlan_id != 0) &&
          	(ipl_vlan_list[ipl_vlan_id] == 0)) {

            MLAG_LOG(MLAG_LOG_NOTICE, "Add ipl=%d to ipl vlan=%d\n",
                     data->ifindex, ipl_vlan_id);

            /* Add IPL to vlan */
            err = sl_api_ipl_vlan_membership_action(OES_ACCESS_CMD_ADD,
            										data->ifindex,
                                                    &ipl_vlan_id, 1);
            MLAG_BAIL_ERROR_MSG(err,
            		"Failed to add ipl vlan membership: ipl=%d, ipl_vlan=%d, err=%d\n",
            		data->ifindex, ipl_vlan_id, err);
            ipl_vlan_list[ipl_vlan_id] = 1;
            mlag_l3_interface_inc_cnt(ADD_IPL_TO_VLAN_EVENTS_SENT);
        }
        else {
            MLAG_LOG(MLAG_LOG_NOTICE,
                     "Vlan is not configured on ipl vlan interface: ipl=%d, ipl_vlan=%d\n",
                     data->ifindex, ipl_vlan_id);
        }
    }

bail:
    ipl_ifindex = data->ifindex;
    return err;
}
コード例 #28
0
ファイル: lacp_manager.c プロジェクト: nirdotan/MLAG
/*
 *  Handle incoming LACP sync message
 *
 * @param[in] lacp_sync - message body
 *
 * @return 0 when successful, otherwise ERROR
 */
static int
handle_lacp_sync_msg(struct peer_lacp_sync_message *lacp_sync)
{
    int err = 0;
    struct mlag_master_election_status me_status;
    struct peer_lacp_sync_message sync_message;

    ASSERT(lacp_sync != NULL);

    err = mlag_master_election_get_status(&me_status);
    MLAG_BAIL_ERROR_MSG(err, "Failed getting ME status\n");

    switch (lacp_sync->phase) {
    case LACP_SYNC_START:
        /* send sync data if master */
        sync_message.mlag_id = me_status.my_peer_id;
        sync_message.phase = LACP_SYNC_DATA;
        err = lacp_db_local_system_id_get(&sync_message.sys_id);
        MLAG_BAIL_ERROR_MSG(err, "Failed getting local actor attributes\n");

        /* Send message to master */
        MLAG_LOG(MLAG_LOG_DEBUG,
                 "send LACP data to peer [%u] \n", lacp_sync->mlag_id);

        /* Send sync message with data */
        err = lacp_manager_message_send(MLAG_LACP_SYNC_MSG,
                                        &sync_message, sizeof(sync_message),
                                        lacp_sync->mlag_id, MASTER_LOGIC);
        break;
    case LACP_SYNC_DATA:
        /* slave handles sync data */
        err = update_lacp_master_attributes(lacp_sync);
        MLAG_BAIL_ERROR_MSG(err, "Failed updating master LACP attributes\n");
        /* send sync done message */
        sync_message.mlag_id = me_status.my_peer_id;
        sync_message.phase = LACP_SYNC_DONE;
        set_lacp_logic_origin(FALSE);

        /* Send message to master */
        MLAG_LOG(MLAG_LOG_DEBUG,
                 "send LACP data to peer [%u] \n", lacp_sync->mlag_id);

        /* Send to master logic sync message */
        err = lacp_manager_message_send(MLAG_LACP_SYNC_MSG,
                                        &sync_message, sizeof(sync_message),
                                        lacp_sync->mlag_id, PEER_MANAGER);

        break;
    case LACP_SYNC_DONE:
        /* sync done received in master */
        err = lacp_send_sync_done(lacp_sync->mlag_id);
        MLAG_BAIL_ERROR(err);
        break;
    case LACP_SYS_ID_UPDATE:
        /* slave handles lacp system id update from master */
        err = update_lacp_master_attributes(lacp_sync);
        MLAG_BAIL_ERROR_MSG(err,
                            "Failed updating master LACP attributes upon LACP_SYS_ID_UPDATE\n");
        break;
    default:
        err = -ENOENT;
        MLAG_BAIL_ERROR_MSG(err, "Invalid LACP sync message\n");
        break;
    }

bail:
    return err;
}