Skip to content

Commit

Permalink
Address review comments and fix issues.
Browse files Browse the repository at this point in the history
- Ignore port add notifications for ports that are not created by
openvswitch or idpf driver
- Populate bridge ID when programming l2_fwd rules

Signed-off-by: Sandeep N <[email protected]>
  • Loading branch information
n-sandeep committed Nov 17, 2023
1 parent d00dda8 commit 351d437
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 20 deletions.
53 changes: 44 additions & 9 deletions switchapi/es2k/switch_pd_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ switch_status_t switch_pd_l2_rx_forward_table_entry(
const tdi_table_hdl* table_hdl = NULL;
const tdi_table_info_hdl* table_info_hdl = NULL;

switch_handle_t rif_handle;
switch_rif_info_t* rif_info = NULL;
switch_port_t port_id;

Expand Down Expand Up @@ -459,6 +458,50 @@ switch_status_t switch_pd_l2_rx_forward_table_entry(
goto dealloc_resources;
}

switch_status_t switch_status =
switch_rif_get(device, api_l2_rx_info->rif_handle, &rif_info);
if (switch_status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error("Unable to get rif info, error: %d", switch_status);
goto dealloc_resources;
}

switch_status =
switch_pd_get_physical_port_id(device, rif_info->api_rif_info.port_id,
(uint8_t*)&api_l2_rx_info->port_id);
if (switch_status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error("Unable to get physical port ID, error: %d",
switch_status);
goto dealloc_resources;
}

status = switch_pd_get_bridge_id(device, (uint8_t)api_l2_rx_info->port_id,
(uint8_t*)&api_l2_rx_info->bridge_id);
if (switch_status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error("Unable to get bridge ID, error: %d", switch_status);
goto dealloc_resources;
}

status = tdi_key_field_id_get(table_info_hdl,
LNW_L2_FWD_RX_TABLE_KEY_BRIDGE_ID, &field_id);
if (status != TDI_SUCCESS) {
krnlmon_log_error("Unable to get field ID for key: %s, error: %d",
LNW_L2_FWD_RX_TABLE_KEY_DST_MAC, status);
goto dealloc_resources;
}

status = tdi_key_field_set_value_ptr(
key_hdl, field_id, (const uint8_t*)&api_l2_rx_info->bridge_id, 1);

status = tdi_key_field_id_get(
table_info_hdl, LNW_L2_FWD_RX_TABLE_KEY_SMAC_LEARNED, &field_id);
if (status != TDI_SUCCESS) {
krnlmon_log_error("Unable to get field ID for key: %s, error: %d",
LNW_L2_FWD_RX_TABLE_KEY_DST_MAC, status);
goto dealloc_resources;
}

status = tdi_key_field_set_value(key_hdl, field_id, 1);

if (entry_add && SWITCH_RIF_HANDLE(api_l2_rx_info->rif_handle)) {
/* Add an entry to target */
krnlmon_log_info(
Expand All @@ -483,14 +526,6 @@ switch_status_t switch_pd_l2_rx_forward_table_entry(
goto dealloc_resources;
}

rif_handle = api_l2_rx_info->rif_handle;
switch_status_t switch_status =
switch_rif_get(device, rif_handle, &rif_info);
if (switch_status != SWITCH_STATUS_SUCCESS) {
krnlmon_log_error("Unable to get rif info, error: %d", switch_status);
goto dealloc_resources;
}

/* While matching l2_fwd_rx_table should receive packet on phy-port
* and send to control port. */
port_id = rif_info->api_rif_info.port_id;
Expand Down
2 changes: 2 additions & 0 deletions switchapi/es2k/switch_pd_p4_name_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ extern "C" {

#define LNW_L2_FWD_RX_TABLE_KEY_BRIDGE_ID "user_meta.pmeta.bridge_id"

#define LNW_L2_FWD_RX_TABLE_KEY_SMAC_LEARNED "user_meta.pmeta.smac_learned"

#define LNW_L2_FWD_RX_TABLE_ACTION_L2_FWD "linux_networking_control.l2_fwd"
#define LNW_ACTION_L2_FWD_PARAM_PORT "port"
#define LNW_L2_FWD_RX_TABLE_ACTION_RX_L2_FWD_LAG \
Expand Down
17 changes: 7 additions & 10 deletions switchapi/es2k/switch_pd_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
#include "switchapi/switch_internal.h"
#include "switchapi/switch_rmac_int.h"

tdi_status_t switch_pd_get_physical_port_id(switch_device_t device,
uint32_t netdev_port_id,
uint8_t* physical_port_id) {
switch_status_t switch_pd_get_physical_port_id(switch_device_t device,
uint32_t netdev_port_id,
uint8_t* physical_port_id) {
tdi_status_t status;

tdi_id_t field_id = 0;
Expand Down Expand Up @@ -187,9 +187,9 @@ tdi_status_t switch_pd_get_physical_port_id(switch_device_t device,
return switch_pd_tdi_status_to_status(status);
}

tdi_status_t switch_pd_get_bridge_id(switch_device_t device,
uint8_t physical_port_id,
uint8_t* bridge_id) {
switch_status_t switch_pd_get_bridge_id(switch_device_t device,
uint8_t physical_port_id,
uint8_t* bridge_id) {
tdi_status_t status;

tdi_id_t field_id = 0;
Expand Down Expand Up @@ -309,7 +309,7 @@ tdi_status_t switch_pd_get_bridge_id(switch_device_t device,
goto dealloc_resources;
}

status = tdi_key_field_set_value(key_hdl, field_id, 1);
status = tdi_key_field_set_value(key_hdl, field_id, 16777214);
if (status != TDI_SUCCESS) {
krnlmon_log_error(
"Unable to set value for key ID: %d for %s"
Expand Down Expand Up @@ -353,9 +353,6 @@ tdi_status_t switch_pd_get_bridge_id(switch_device_t device,
ACTION_L2_FWD_AND_BYPASS_BRIDGE_PARAM_PORT, status);
goto dealloc_resources;
}
// status = tdi_data_field_get_value_ptr(data_hdl, data_field_id,
// sizeof(*physical_port_id),
// physical_port_id);
status = tdi_data_field_get_value(data_hdl, data_field_id, &get_bridge_id);
if (status != TDI_SUCCESS) {
krnlmon_log_error("Failed to get value for the handle: %d", status);
Expand Down
55 changes: 55 additions & 0 deletions switchlink/switchlink_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,22 @@
#include "switchlink_link.h"

#include <fcntl.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/if.h>
#include <linux/if_bridge.h>
#include <linux/sockios.h>
#include <linux/version.h>
#include <netlink/attr.h>
#include <netlink/msg.h>
#include <netlink/netlink.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include "switchlink.h"
#include "switchlink_handle.h"
#include "switchlink_int.h"
#include "switchlink_utils.h"

#if defined(ES2K_TARGET)
// ES2K creates netdevs from idpf driver/SR-IOVs.
Expand Down Expand Up @@ -88,6 +93,48 @@ static switchlink_link_type_t get_link_type(const char* info_kind) {
return link_type;
}

/*
* Routine Description:
* Check if the interface driver is valid for our use case
*
* Arguments:
* [in] ifname - Interface name
*
* Return Values:
* boolean
*/
bool validate_driver_name(char* ifname) {
struct ethtool_drvinfo drv = {0};
char drvname[32] = {0};
struct ifreq ifr = {0};
int fd, r = 0;

fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
return false;
}

drv.cmd = ETHTOOL_GDRVINFO;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
ifr.ifr_data = (void*)&drv;

r = ioctl(fd, SIOCETHTOOL, &ifr);
if (r) {
goto end;
}

strncpy(drvname, drv.driver, sizeof(drvname));

if (!memcmp(drvname, "openvswitch", strlen(drvname)) ||
!memcmp(drvname, "idpf", strlen(drvname))) {
close(fd);
return true;
}
end:
close(fd);
return false;
}

/*
* Routine Description:
* Processes a nested INFO_DATA attribute.
Expand Down Expand Up @@ -349,6 +396,14 @@ void switchlink_process_link_msg(const struct nlmsghdr* nlmsg, int msgtype) {
break;
}

if (!validate_driver_name(attrs.ifname)) {
krnlmon_log_info(
"Ignoring interface: %s which is not created"
" by openvswitch or idpf driver",
intf_info.ifname);
break;
}

snprintf(intf_info.ifname, sizeof(intf_info.ifname), "%s",
attrs.ifname);
intf_info.ifindex = ifmsg->ifi_index;
Expand Down
2 changes: 1 addition & 1 deletion switchlink/switchlink_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ void switchlink_process_route_msg(const struct nlmsghdr* nlmsg, int msgtype) {
intf_h = ifinfo.intf_h;
}
} else if (status != SWITCHLINK_DB_STATUS_SUCCESS) {
krnlmon_log_error(
krnlmon_log_debug(
"route: Failed to get switchlink DB interface info, "
"error: %d \n",
status);
Expand Down

0 comments on commit 351d437

Please sign in to comment.