summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuradha Karuppiah <anuradhak@nvidia.com>2021-12-30 14:56:30 -0800
committerDonald Sharp <sharpd@nvidia.com>2022-06-27 07:56:55 -0400
commita66d6246616e7ba3aebda5d2524164e3fd8f7269 (patch)
tree8765be803cf7b402c99fa70e66aa0cfca61f9db9
parent67f5a232408af238d88f4c85691ff56227f002be (diff)
zebra: setup the zebra interface to dpdk port map table
1. Create mappping table between ifIndex and dpdk-port-id 2. Start the DPDK port Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk.c148
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk.h5
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk_private.h9
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk_vty.c24
4 files changed, 186 insertions, 0 deletions
diff --git a/zebra/dpdk/zebra_dplane_dpdk.c b/zebra/dpdk/zebra_dplane_dpdk.c
index 44c6bac94d..79b8c22b02 100644
--- a/zebra/dpdk/zebra_dplane_dpdk.c
+++ b/zebra/dpdk/zebra_dplane_dpdk.c
@@ -40,6 +40,9 @@ extern struct zebra_privs_t zserv_privs;
static struct zd_dpdk_ctx dpdk_ctx_buf, *dpdk_ctx = &dpdk_ctx_buf;
#define dpdk_stat (&dpdk_ctx->stats)
+static struct zd_dpdk_port *zd_dpdk_port_find_by_index(int ifindex);
+
+DEFINE_MTYPE_STATIC(ZEBRA, DPDK_PORTS, "ZD DPDK port database");
void zd_dpdk_stat_show(struct vty *vty)
{
@@ -161,6 +164,147 @@ static int zd_dpdk_process(struct zebra_dplane_provider *prov)
return 0;
}
+static void zd_dpdk_port_show_entry(struct zd_dpdk_port *dport, struct vty *vty,
+ int detail)
+{
+ struct rte_eth_dev_info *dev_info;
+
+ dev_info = &dport->dev_info;
+ if (detail) {
+ vty_out(vty, "DPDK port: %u\n", dport->port_id);
+ vty_out(vty, " Device: %s\n",
+ dev_info->device ? dev_info->device->name : "-");
+ vty_out(vty, " Driver: %s\n",
+ dev_info->driver_name ? dev_info->driver_name : "-");
+ vty_out(vty, " Interface: %s (%d)\n",
+ ifindex2ifname(dev_info->if_index, VRF_DEFAULT),
+ dev_info->if_index);
+ vty_out(vty, " Switch: %s Domain: %u Port: %u\n",
+ dev_info->switch_info.name,
+ dev_info->switch_info.domain_id,
+ dev_info->switch_info.port_id);
+ vty_out(vty, "\n");
+ } else {
+ vty_out(vty, "%-4u %-16s %-16s %-16d %s,%u,%u\n",
+ dport->port_id,
+ dev_info->device ? dev_info->device->name : "-",
+ ifindex2ifname(dev_info->if_index, VRF_DEFAULT),
+ dev_info->if_index, dev_info->switch_info.name,
+ dev_info->switch_info.domain_id,
+ dev_info->switch_info.port_id);
+ }
+}
+
+
+static struct zd_dpdk_port *zd_dpdk_port_find_by_index(int ifindex)
+{
+ int count;
+ struct zd_dpdk_port *dport;
+ struct rte_eth_dev_info *dev_info;
+
+ for (count = 0; count < RTE_MAX_ETHPORTS; ++count) {
+ dport = &dpdk_ctx->dpdk_ports[count];
+ if (!(dport->flags & ZD_DPDK_PORT_FLAG_INITED))
+ continue;
+ dev_info = &dport->dev_info;
+ if (dev_info->if_index == (uint32_t)ifindex)
+ return dport;
+ }
+
+ return NULL;
+}
+
+
+void zd_dpdk_port_show(struct vty *vty, uint16_t port_id, bool uj, int detail)
+{
+ int count;
+ struct zd_dpdk_port *dport;
+
+ /* XXX - support for json is yet to be added */
+ if (uj)
+ return;
+
+ if (!detail) {
+ vty_out(vty, "%-4s %-16s %-16s %-16s %s\n", "Port", "Device",
+ "IfName", "IfIndex", "sw,domain,port");
+ }
+
+ for (count = 0; count < RTE_MAX_ETHPORTS; ++count) {
+ dport = &dpdk_ctx->dpdk_ports[count];
+ if (dport->flags & ZD_DPDK_PORT_FLAG_INITED)
+ zd_dpdk_port_show_entry(dport, vty, detail);
+ }
+}
+
+
+static void zd_dpdk_port_init(void)
+{
+ struct zd_dpdk_port *dport;
+ uint16_t port_id;
+ struct rte_eth_dev_info *dev_info;
+ int count;
+ int rc;
+ struct rte_flow_error error;
+
+ /* allocate a list of ports */
+ dpdk_ctx->dpdk_ports =
+ XCALLOC(MTYPE_DPDK_PORTS,
+ sizeof(struct zd_dpdk_port) * RTE_MAX_ETHPORTS);
+
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug("dpdk port init");
+ count = 0;
+ RTE_ETH_FOREACH_DEV(port_id)
+ {
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug("dpdk port init %d", port_id);
+ dport = &dpdk_ctx->dpdk_ports[count];
+ count++;
+ dport->port_id = port_id;
+ dport->flags |= ZD_DPDK_PORT_FLAG_PROBED;
+ dev_info = &dport->dev_info;
+ if (rte_eth_dev_info_get(port_id, dev_info) < 0) {
+ zlog_warn("failed to get dev info for %u, %s", port_id,
+ rte_strerror(rte_errno));
+ continue;
+ }
+ dport->flags |= ZD_DPDK_PORT_FLAG_INITED;
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug(
+ "port %u, dev %s, ifI %d, sw_name %s, sw_domain %u, sw_port %u",
+ port_id,
+ dev_info->device ? dev_info->device->name : "-",
+ dev_info->if_index, dev_info->switch_info.name,
+ dev_info->switch_info.domain_id,
+ dev_info->switch_info.port_id);
+ if (rte_flow_isolate(port_id, 1, &error)) {
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug(
+ "Flow isolate on port %u failed %d\n",
+ port_id, error.type);
+ } else {
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug("Flow isolate on port %u\n",
+ port_id);
+ }
+ rc = rte_eth_dev_start(port_id);
+ if (rc) {
+ zlog_warn("DPDK port %d start error: %s", port_id,
+ rte_strerror(-rc));
+ continue;
+ }
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug("DPDK port %d started in promiscuous mode ",
+ port_id);
+ }
+
+ if (!count) {
+ if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
+ zlog_debug("no probed ethernet devices");
+ }
+}
+
+
static int zd_dpdk_init(void)
{
int rc;
@@ -176,9 +320,13 @@ static int zd_dpdk_init(void)
return -1;
}
+ frr_with_privs (&zserv_privs) {
+ zd_dpdk_port_init();
+ }
return 0;
}
+
static int zd_dpdk_start(struct zebra_dplane_provider *prov)
{
if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
diff --git a/zebra/dpdk/zebra_dplane_dpdk.h b/zebra/dpdk/zebra_dplane_dpdk.h
index 469fd8c5bc..32ace04078 100644
--- a/zebra/dpdk/zebra_dplane_dpdk.h
+++ b/zebra/dpdk/zebra_dplane_dpdk.h
@@ -24,6 +24,11 @@
#include <zebra.h>
+
+#define ZD_DPDK_INVALID_PORT 0xffff
+
+extern void zd_dpdk_port_show(struct vty *vty, uint16_t port_id, bool uj,
+ int detail);
extern void zd_dpdk_stat_show(struct vty *vty);
extern void zd_dpdk_vty_init(void);
diff --git a/zebra/dpdk/zebra_dplane_dpdk_private.h b/zebra/dpdk/zebra_dplane_dpdk_private.h
index 8f50296084..0eda45b2e3 100644
--- a/zebra/dpdk/zebra_dplane_dpdk_private.h
+++ b/zebra/dpdk/zebra_dplane_dpdk_private.h
@@ -29,6 +29,14 @@
#include "zebra_dplane_dpdk.h"
+struct zd_dpdk_port {
+ uint16_t port_id; /* dpdk port_id */
+ struct rte_eth_dev_info dev_info; /* PCI info + driver name */
+ uint32_t flags;
+#define ZD_DPDK_PORT_FLAG_PROBED (1 << 0)
+#define ZD_DPDK_PORT_FLAG_INITED (1 << 1)
+};
+
struct zd_dpdk_stat {
_Atomic uint32_t ignored_updates;
@@ -39,6 +47,7 @@ struct zd_dpdk_stat {
struct zd_dpdk_ctx {
/* Stats */
struct zd_dpdk_stat stats;
+ struct zd_dpdk_port *dpdk_ports;
int dpdk_logtype;
};
diff --git a/zebra/dpdk/zebra_dplane_dpdk_vty.c b/zebra/dpdk/zebra_dplane_dpdk_vty.c
index c1fbb20c4c..11df697485 100644
--- a/zebra/dpdk/zebra_dplane_dpdk_vty.c
+++ b/zebra/dpdk/zebra_dplane_dpdk_vty.c
@@ -39,7 +39,31 @@ DEFPY(zd_dpdk_show_counters, zd_dpdk_show_counters_cmd,
return CMD_SUCCESS;
}
+
+DEFPY (zd_dpdk_show_ports,
+ zd_dpdk_show_ports_cmd,
+ "show dplane dpdk port [(1-32)$port_id] [detail$detail] [json$json]",
+ SHOW_STR
+ ZD_STR
+ ZD_DPDK_STR
+ "show port info\n"
+ "DPDK port identifier\n"
+ "Detailed information\n"
+ JSON_STR)
+{
+ bool uj = !!json;
+ bool ud = !!detail;
+
+ if (!port_id)
+ port_id = ZD_DPDK_INVALID_PORT;
+ zd_dpdk_port_show(vty, port_id, uj, ud);
+
+ return CMD_SUCCESS;
+}
+
+
void zd_dpdk_vty_init(void)
{
install_element(VIEW_NODE, &zd_dpdk_show_counters_cmd);
+ install_element(VIEW_NODE, &zd_dpdk_show_ports_cmd);
}