]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: setup the zebra interface to dpdk port map table
authorAnuradha Karuppiah <anuradhak@nvidia.com>
Thu, 30 Dec 2021 22:56:30 +0000 (14:56 -0800)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 27 Jun 2022 11:56:55 +0000 (07:56 -0400)
1. Create mappping table between ifIndex and dpdk-port-id
2. Start the DPDK port

Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
zebra/dpdk/zebra_dplane_dpdk.c
zebra/dpdk/zebra_dplane_dpdk.h
zebra/dpdk/zebra_dplane_dpdk_private.h
zebra/dpdk/zebra_dplane_dpdk_vty.c

index 44c6bac94d8e7b381815ed94f4b2445447995fea..79b8c22b0219c48d4a1d4dc514636b856190f756 100644 (file)
@@ -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)
index 469fd8c5bcaa618874741bbe2c5895d604e55331..32ace040784ff1b62c16852c056e93ae1bec5391 100644 (file)
 
 #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);
 
index 8f502960849c71c936ca7f608d04fdbbd7d46fb7..0eda45b2e314996d395057f7a8e4c5faf262ae73 100644 (file)
 #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;
 };
 
index c1fbb20c4c74cad7a67450faafa262aefacfb472..11df697485ad5e3b652675059479375449d92bba 100644 (file)
@@ -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);
 }