Skip to content

Commit

Permalink
Merge pull request #79 from ipdk-io/LACP_Mode_Support
Browse files Browse the repository at this point in the history
LACP Mode Support for LAG
  • Loading branch information
aashishkuma authored Jan 22, 2024
2 parents 5655335 + 207e1a4 commit 56cbef8
Show file tree
Hide file tree
Showing 9 changed files with 866 additions and 70 deletions.
273 changes: 233 additions & 40 deletions switchapi/es2k/switch_lag.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ switch_status_t switch_api_lag_create(switch_device_t device,
if (!SWITCH_RMAC_HANDLE(api_lag_info->rmac_handle)) {
status = SWITCH_STATUS_INVALID_HANDLE;
krnlmon_log_error(
"LAG create: Invalid rmac handle on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
"LAG create: Invalid rmac handle on device:%d error: %s\n", device,
switch_error_to_string(status));
return status;
}

Expand All @@ -115,18 +114,16 @@ switch_status_t switch_api_lag_create(switch_device_t device,

status = switch_lag_get(device, *lag_h, &lag_info);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"LAG create: Failed to get LAG on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
krnlmon_log_error("LAG create: Failed to get LAG on device:%d error: %s\n",
device, switch_error_to_string(status));
status = switch_lag_handle_delete(device, *lag_h);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);
return status;
}

lag_info->lag_handle = *lag_h;

status = SWITCH_LIST_INIT(&(lag_info->lag_members));
status = SWITCH_LIST_INIT(&lag_info->lag_members);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);

SWITCH_MEMCPY(&lag_info->api_lag_info, api_lag_info,
Expand Down Expand Up @@ -159,19 +156,17 @@ switch_status_t switch_api_lag_delete(switch_device_t device,
status = switch_pd_tx_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete tx_lag_table entry on device %d: "
",error: %s\n",
device, switch_error_to_string(status));
"Failed to delete tx_lag_table entry on device:%d error: %s\n", device,
switch_error_to_string(status));
return status;
}

//--------------------- Rx Path : Del Case ----------------------//
status = switch_pd_rx_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lag_table entry on device %d: "
",error: %s\n",
device, switch_error_to_string(status));
"Failed to delete rx_lag_table entry on device:%d error: %s\n", device,
switch_error_to_string(status));
return status;
}

Expand Down Expand Up @@ -208,8 +203,7 @@ switch_status_t switch_api_lag_member_create(
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"LAG member create: Failed to get LAG member on device %d: "
"error: %s\n",
"LAG member create: Failed to get LAG member on device:%d error: %s\n",
device, switch_error_to_string(status));
status = switch_lag_member_handle_delete(device, *lag_member_h);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);
Expand Down Expand Up @@ -284,6 +278,78 @@ switch_status_t switch_api_lag_update(const switch_device_t device,
status = switch_lag_get(device, lag_h, &lag_info);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);

if (lag_info->api_lag_info.bond_mode == SWITCHAPI_BOND_MODE_ACTIVE_BACKUP) {
if (!SWITCH_LAG_MEMBER_HANDLE(lag_member_h)) {
status = SWITCH_STATUS_INVALID_PARAMETER;
krnlmon_log_error(
"LAG get: Invalid LAG member handle on device %d, "
"LAG member handle 0x%lx: "
"error: %s\n",
device, lag_member_h, switch_error_to_string(status));
return status;
}
status = switch_lag_member_get(device, lag_member_h, &lag_member_info);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);

if (lag_info->active_lag_member != 0) {
// delete rx path
status = switch_pd_rx_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

// insert lag member
status = SWITCH_LIST_INSERT(&lag_info->lag_members,
&lag_member_info->node, lag_member_info);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);

// create rx path
status = switch_pd_rx_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
} else {
// update lag members list with the lag_member_h
status = SWITCH_LIST_INSERT(&lag_info->lag_members,
&lag_member_info->node, lag_member_info);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);
}
}

return status;
}

/**
* Routine Description:
* @details On change of oper_state of a LAG member,
* update the number of active ports of a LAG and
* re-populate the Tx and Rx LAG table entries with
* active port.
*
* Arguments:
* @param[in] device - device
* @param[in] lag_member_h - LAG member handle
* @param[in] oper_state - oper state of LAG member
*
* Return Values:
* @return SWITCH_STATUS_SUCCESS on success
* Failure status code on error
*/
switch_status_t switch_api_lag_member_update(const switch_device_t device,
const switch_handle_t lag_member_h,
bool oper_state) {
switch_lag_info_t* lag_info = NULL;
switch_lag_member_info_t* lag_member_info = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;

if (!SWITCH_LAG_MEMBER_HANDLE(lag_member_h)) {
status = SWITCH_STATUS_INVALID_PARAMETER;
krnlmon_log_error(
Expand All @@ -296,36 +362,163 @@ switch_status_t switch_api_lag_update(const switch_device_t device,
status = switch_lag_member_get(device, lag_member_h, &lag_member_info);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);

if (lag_info->active_lag_member != 0) {
// delete rx path
status = switch_pd_rx_lag_table_entry(device, lag_info, false);
lag_member_info->api_lag_member_info.oper_state = oper_state;

switch_handle_t lag_h = lag_member_info->api_lag_member_info.lag_h;

if (!SWITCH_LAG_HANDLE(lag_h)) {
status = SWITCH_STATUS_INVALID_PARAMETER;
krnlmon_log_error(
"LAG get: Invalid LAG handle on device %d, "
"LAG handle 0x%lx: "
"error: %s\n",
device, lag_h, switch_error_to_string(status));
return status;
}
status = switch_lag_get(device, lag_h, &lag_info);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);

// update the active num ports of LAG
if (oper_state)
lag_info->num_active_ports++;
else
lag_info->num_active_ports--;

if (lag_info->num_active_ports == 0 &&
(SWITCH_LIST_COUNT(&lag_info->lag_members) != 0)) {
// delete the existing tx and rx entries
status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lag_table entry on device %d: "
",error: %s\n",
"Failed to delete tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

// insert lag member
status = SWITCH_LIST_INSERT(&(lag_info->lag_members),
&(lag_member_info->node), lag_member_info);
// delete the lag_member from the LAG
status = SWITCH_LIST_DELETE(&lag_info->lag_members, &lag_member_info->node);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);

// create rx path
status = switch_pd_rx_lag_table_entry(device, lag_info, true);
} else if (lag_info->num_active_ports == 1) {
/* oper_state false means num_active_ports is decremented from 2 to 1
and oper_state true means it is incremented from 0 to 1 */
if (oper_state) {
// populate the tx and rx entries with single active member
status = SWITCH_LIST_INSERT(&lag_info->lag_members,
&lag_member_info->node, lag_member_info);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);
status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
} else {
// delete the existing entries and populate the tx and rx entries with
// other active member
status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status =
SWITCH_LIST_DELETE(&lag_info->lag_members, &lag_member_info->node);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);

status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
}
} else if (lag_info->num_active_ports == 2) {
// delete the existing entries and re-distribute
// table entries between both active ports
status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lag_table entry on device %d: "
",error: %s\n",
"Failed to delete tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
} else {
// update lag members list with the lag_member_h
status = SWITCH_LIST_INSERT(&(lag_info->lag_members),
&(lag_member_info->node), lag_member_info);

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, false);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = SWITCH_LIST_INSERT(&lag_info->lag_members, &lag_member_info->node,
lag_member_info);
SWITCH_ASSERT(status == SWITCH_STATUS_SUCCESS);

status = switch_pd_tx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create tx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}

status = switch_pd_rx_lacp_lag_table_entry(device, lag_info, true);
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lacp_lag_table entry on device %d: "
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
}

return status;
Expand Down Expand Up @@ -409,7 +602,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create tx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -419,7 +612,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -430,7 +623,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete tx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -439,7 +632,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -451,7 +644,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create tx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -460,7 +653,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to create rx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -470,7 +663,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete tx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand All @@ -479,7 +672,7 @@ switch_status_t switch_api_program_lag_hw(const switch_device_t device,
if (status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error(
"Failed to delete rx_lag_table entry on device %d: "
",error: %s\n",
"error: %s\n",
device, switch_error_to_string(status));
return status;
}
Expand Down
Loading

0 comments on commit 56cbef8

Please sign in to comment.