From: Anuradha Karuppiah Date: Thu, 30 Dec 2021 22:56:30 +0000 (-0800) Subject: zebra: setup the zebra interface to dpdk port map table X-Git-Tag: base_8.4~295^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=a66d6246616e7ba3aebda5d2524164e3fd8f7269;p=mirror%2Ffrr.git 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 --- 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 + +#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); }