Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LACP Mode Support for LAG #79

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You update oper_state before you've validated lag_h or tried to fetch lag_info.

Will the lag member be in a valid state if any of the following calls does a return on error?


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;
aashishkuma marked this conversation as resolved.
Show resolved Hide resolved
}
status = switch_lag_get(device, lag_h, &lag_info);
CHECK_RET(status != SWITCH_STATUS_SUCCESS, status);
aashishkuma marked this conversation as resolved.
Show resolved Hide resolved

// 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;
aashishkuma marked this conversation as resolved.
Show resolved Hide resolved
}

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;
aashishkuma marked this conversation as resolved.
Show resolved Hide resolved
}

// 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) {
aashishkuma marked this conversation as resolved.
Show resolved Hide resolved
// 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