From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from bcmv-tmail01.ecl.ntt.co.jp (bcmv-tmail01.ecl.ntt.co.jp [124.146.185.148]) by dpdk.org (Postfix) with ESMTP id 5581D1B0FF for ; Tue, 15 Jan 2019 04:30:16 +0100 (CET) Received: from bcmv-ns01.ecl.ntt.co.jp (bcmv-ns01.ecl.ntt.co.jp [129.60.83.123]) by bcmv-tmail01.ecl.ntt.co.jp (8.14.4/8.14.4) with ESMTP id x0F3UEg8017628; Tue, 15 Jan 2019 12:30:14 +0900 Received: from bcmv-ns01.ecl.ntt.co.jp (localhost [127.0.0.1]) by bcmv-ns01.ecl.ntt.co.jp (Postfix) with ESMTP id C00F6D6; Tue, 15 Jan 2019 12:30:14 +0900 (JST) Received: from localhost.localdomain (lobster.nslab.ecl.ntt.co.jp [129.60.13.95]) by bcmv-ns01.ecl.ntt.co.jp (Postfix) with ESMTP id AB0161A1; Tue, 15 Jan 2019 12:30:14 +0900 (JST) From: ogawa.yasufumi@lab.ntt.co.jp To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp Date: Tue, 15 Jan 2019 12:28:00 +0900 Message-Id: <1547522881-10105-6-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547522881-10105-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> References: <1547522881-10105-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> X-TM-AS-MML: disable Subject: [spp] [PATCH 5/6] shared: refactor libs of SPP secondary X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2019 03:30:18 -0000 From: Yasufumi Ogawa This update is to redefine common functions of SPP secondary process. Move functions for adding port and other util functions are moved to `shared/secondary/`. Signed-off-by: Yasufumi Ogawa --- src/nfv/nfv.h | 13 - src/nfv/nfv_utils.h | 118 ++++++ src/shared/secondary.c | 359 ------------------ src/shared/secondary.h | 102 ----- .../secondary/add_port.h} | 198 +++------- src/shared/secondary/utils.c | 119 ++++++ src/shared/secondary/utils.h | 39 ++ 7 files changed, 328 insertions(+), 620 deletions(-) delete mode 100644 src/nfv/nfv.h create mode 100644 src/nfv/nfv_utils.h delete mode 100644 src/shared/secondary.c delete mode 100644 src/shared/secondary.h rename src/{nfv/command_utils.h => shared/secondary/add_port.h} (61%) create mode 100644 src/shared/secondary/utils.c create mode 100644 src/shared/secondary/utils.h diff --git a/src/nfv/nfv.h b/src/nfv/nfv.h deleted file mode 100644 index d9e5adf..0000000 --- a/src/nfv/nfv.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation - */ - -#ifndef _NFV_H_ -#define _NFV_H_ - -#include "common.h" -#include "params.h" -#include "command_utils.h" -#include "commands.h" - -#endif // _NFV_H_ diff --git a/src/nfv/nfv_utils.h b/src/nfv/nfv_utils.h new file mode 100644 index 0000000..aca5f13 --- /dev/null +++ b/src/nfv/nfv_utils.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2015-2016 Intel Corporation + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _NFV_NFV_UTILS_H_ +#define _NFV_NFV_UTILS_H_ + +#define RTE_LOGTYPE_SPP_NFV RTE_LOGTYPE_USER1 + +static void +forward_array_remove(int port_id) +{ + unsigned int i; + + /* Update ports_fwd_array */ + forward_array_init_one(port_id); + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (ports_fwd_array[i].in_port_id == PORT_RESET) + continue; + + if (ports_fwd_array[i].out_port_id == port_id) { + ports_fwd_array[i].out_port_id = PORT_RESET; + break; + } + } +} + +/* Return 0 if invalid */ +static int +is_valid_port(uint16_t port_id) +{ + if (port_id > RTE_MAX_ETHPORTS) + return 0; + + return port_map[port_id].id != PORT_RESET; +} + +/* + * Return actual port ID which is assigned by system internally, or PORT_RESET + * if port is not found. + */ +static uint16_t +find_port_id(int id, enum port_type type) +{ + uint16_t port_id = PORT_RESET; + uint16_t i; + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (port_map[i].port_type != type) + continue; + + if (port_map[i].id == id) { + port_id = i; + break; + } + } + + return port_id; +} + +/* Return -1 as an error if given patch is invalid */ +static int +add_patch(uint16_t in_port, uint16_t out_port) +{ + if (!is_valid_port(in_port) || !is_valid_port(out_port)) + return -1; + + /* Populate in port data */ + ports_fwd_array[in_port].in_port_id = in_port; + ports_fwd_array[in_port].rx_func = &rte_eth_rx_burst; + ports_fwd_array[in_port].tx_func = &rte_eth_tx_burst; + ports_fwd_array[in_port].out_port_id = out_port; + + /* Populate out port data */ + ports_fwd_array[out_port].in_port_id = out_port; + ports_fwd_array[out_port].rx_func = &rte_eth_rx_burst; + ports_fwd_array[out_port].tx_func = &rte_eth_tx_burst; + + RTE_LOG(DEBUG, SPP_NFV, "STATUS: in port %d in_port_id %d\n", in_port, + ports_fwd_array[in_port].in_port_id); + RTE_LOG(DEBUG, SPP_NFV, "STATUS: in port %d patch out port id %d\n", + in_port, ports_fwd_array[in_port].out_port_id); + RTE_LOG(DEBUG, SPP_NFV, "STATUS: outport %d in_port_id %d\n", out_port, + ports_fwd_array[out_port].in_port_id); + + return 0; +} + +static void +forward_array_reset(void) +{ + unsigned int i; + + /* initialize port forward array*/ + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (ports_fwd_array[i].in_port_id != PORT_RESET) { + ports_fwd_array[i].out_port_id = PORT_RESET; + RTE_LOG(INFO, SPP_NFV, "Port ID %d\n", i); + RTE_LOG(INFO, SPP_NFV, "out_port_id %d\n", + ports_fwd_array[i].out_port_id); + } + } +} + +/* Return a type of port as a enum member of porttype_map structure. */ +static enum port_type get_port_type(char *portname) +{ + for (int i = 0; portmap[i].port_name != NULL; i++) { + const char *port_name = portmap[i].port_name; + if (strncmp(portname, port_name, strlen(port_name)) == 0) + return portmap[i].port_type; + } + return UNDEF; +} + +#endif // _NFV_COMMAND_UTILS_H_ diff --git a/src/shared/secondary.c b/src/shared/secondary.c deleted file mode 100644 index 2e986d9..0000000 --- a/src/shared/secondary.c +++ /dev/null @@ -1,359 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation - */ - -#include -#include "common.h" -#include "secondary.h" - -#define RTE_LOGTYPE_SHARED RTE_LOGTYPE_USER1 - -/* - * Get status of spp_nfv or spp_vm as JSON format. It consists of running - * status and patch info of ports. - * - * Here is an example of well-formatted JSON status to better understand. - * Actual status has no spaces and new lines inserted as - * '{"status":"running","ports":[{"src":"phy:0","dst":"ring:0"},...]}' - * - * { - * "status": "running", - * "ports": ["phy:0", "phy:1", "ring:0", "vhost:0"], - * "patches": [ - * {"src":"phy:0","dst": "ring:0"}, - * {"src":"ring:0","dst": "vhost:0"} - * ] - * } - */ -void -get_sec_stats_json(char *str, uint16_t client_id, - const char *running_stat, - struct port *ports_fwd_array, - struct port_map *port_map) -{ - sprintf(str, "{\"client-id\":%d,", client_id); - - sprintf(str + strlen(str), "\"status\":"); - sprintf(str + strlen(str), "\"%s\",", running_stat); - - append_port_info_json(str, ports_fwd_array, port_map); - sprintf(str + strlen(str), ","); - - append_patch_info_json(str, ports_fwd_array, port_map); - sprintf(str + strlen(str), "}"); - - // make sure to be terminated with null character - sprintf(str + strlen(str), "%c", '\0'); -} - - -/* - * Append patch info to sec status. It is called from get_sec_stats_json() - * to add a JSON formatted patch info to given 'str'. Here is an example. - * - * "ports": ["phy:0", "phy:1", "ring:0", "vhost:0"] - */ -int -append_port_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) -{ - unsigned int i; - unsigned int has_port = 0; // for checking having port at last - - sprintf(str + strlen(str), "\"ports\":["); - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - - if (ports_fwd_array[i].in_port_id == PORT_RESET) - continue; - - has_port = 1; - switch (port_map[i].port_type) { - case PHY: - sprintf(str + strlen(str), "\"phy:%u\",", - port_map[i].id); - break; - case RING: - sprintf(str + strlen(str), "\"ring:%u\",", - port_map[i].id); - break; - case VHOST: - sprintf(str + strlen(str), "\"vhost:%u\",", - port_map[i].id); - break; - case PCAP: - sprintf(str + strlen(str), "\"pcap:%u\",", - port_map[i].id); - break; - case NULLPMD: - sprintf(str + strlen(str), "\"nullpmd:%u\",", - port_map[i].id); - break; - case UNDEF: - /* TODO(yasufum) Need to remove print for undefined ? */ - sprintf(str + strlen(str), "\"udf\","); - break; - } - } - - // Check if it has at least one port to remove ",". - if (has_port == 0) { - sprintf(str + strlen(str), "]"); - } else { // Remove last ',' - sprintf(str + strlen(str) - 1, "]"); - } - - return 0; -} - -/* - * Append patch info to sec status. It is called from get_sec_stats_json() - * to add a JSON formatted patch info to given 'str'. Here is an example. - * - * "patches": [ - * {"src":"phy:0","dst": "ring:0"}, - * {"src":"ring:0","dst": "vhost:0"} - * ] - */ -int -append_patch_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) -{ - unsigned int i; - unsigned int has_patch = 0; // for checking having patch at last - - char patch_str[128]; - sprintf(str + strlen(str), "\"patches\":["); - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - - if (ports_fwd_array[i].in_port_id == PORT_RESET) - continue; - - RTE_LOG(INFO, SHARED, "Port ID %d\n", i); - RTE_LOG(INFO, SHARED, "Status %d\n", - ports_fwd_array[i].in_port_id); - - memset(patch_str, '\0', sizeof(patch_str)); - - sprintf(patch_str, "{\"src\":"); - - switch (port_map[i].port_type) { - case PHY: - RTE_LOG(INFO, SHARED, "Type: PHY\n"); - sprintf(patch_str + strlen(patch_str), - "\"phy:%u\",", - port_map[i].id); - break; - case RING: - RTE_LOG(INFO, SHARED, "Type: RING\n"); - sprintf(patch_str + strlen(patch_str), - "\"ring:%u\",", - port_map[i].id); - break; - case VHOST: - RTE_LOG(INFO, SHARED, "Type: VHOST\n"); - sprintf(patch_str + strlen(patch_str), - "\"vhost:%u\",", - port_map[i].id); - break; - case PCAP: - RTE_LOG(INFO, SHARED, "Type: PCAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"pcap:%u\",", - port_map[i].id); - break; - case NULLPMD: - RTE_LOG(INFO, SHARED, "Type: NULLPMD\n"); - sprintf(patch_str + strlen(patch_str), - "\"nullpmd:%u\",", - port_map[i].id); - break; - case UNDEF: - RTE_LOG(INFO, SHARED, "Type: UDF\n"); - /* TODO(yasufum) Need to remove print for undefined ? */ - sprintf(patch_str + strlen(patch_str), - "\"udf\","); - break; - } - - sprintf(patch_str + strlen(patch_str), "\"dst\":"); - - RTE_LOG(INFO, SHARED, "Out Port ID %d\n", - ports_fwd_array[i].out_port_id); - - if (ports_fwd_array[i].out_port_id == PORT_RESET) { - //sprintf(patch_str + strlen(patch_str), "%s", "\"\""); - continue; - } else { - has_patch = 1; - unsigned int j = ports_fwd_array[i].out_port_id; - switch (port_map[j].port_type) { - case PHY: - RTE_LOG(INFO, SHARED, "Type: PHY\n"); - sprintf(patch_str + strlen(patch_str), - "\"phy:%u\"", - port_map[j].id); - break; - case RING: - RTE_LOG(INFO, SHARED, "Type: RING\n"); - sprintf(patch_str + strlen(patch_str), - "\"ring:%u\"", - port_map[j].id); - break; - case VHOST: - RTE_LOG(INFO, SHARED, "Type: VHOST\n"); - sprintf(patch_str + strlen(patch_str), - "\"vhost:%u\"", - port_map[j].id); - break; - case PCAP: - RTE_LOG(INFO, SHARED, "Type: PCAP\n"); - sprintf(patch_str + strlen(patch_str), - "\"pcap:%u\"", - port_map[j].id); - break; - case NULLPMD: - RTE_LOG(INFO, SHARED, "Type: NULLPMD\n"); - sprintf(patch_str + strlen(patch_str), - "\"nullpmd:%u\"", - port_map[j].id); - break; - case UNDEF: - RTE_LOG(INFO, SHARED, "Type: UDF\n"); - /* - * TODO(yasufum) Need to remove print for - * undefined ? - */ - sprintf(patch_str + strlen(patch_str), - "\"udf\""); - break; - } - } - - sprintf(patch_str + strlen(patch_str), "},"); - - if (has_patch != 0) - sprintf(str + strlen(str), "%s", patch_str); - } - - - // Check if it has at least one patch to remove ",". - if (has_patch == 0) { - sprintf(str + strlen(str), "]"); - } else { // Remove last ',' - sprintf(str + strlen(str) - 1, "]"); - } - - return 0; -} - -/** - * Retieve port type and ID from resource UID. For example, resource UID - * 'ring:0' is parsed to retrieve port tyep 'ring' and ID '0'. - */ -int -parse_resource_uid(char *str, char **port_type, int *port_id) -{ - char *token; - char delim[] = ":"; - char *endp; - - RTE_LOG(DEBUG, SHARED, "Parsing resource UID: '%s\n'", str); - if (strstr(str, delim) == NULL) { - RTE_LOG(ERR, SHARED, "Invalid resource UID: '%s'\n", str); - return -1; - } - RTE_LOG(DEBUG, SHARED, "Delimiter %s is included\n", delim); - - *port_type = strtok(str, delim); - - token = strtok(NULL, delim); - *port_id = strtol(token, &endp, 10); - - if (*endp) { - RTE_LOG(ERR, SHARED, "Bad integer value: %s\n", str); - return -1; - } - - return 0; -} - -int -spp_atoi(const char *str, int *val) -{ - char *end; - - *val = strtol(str, &end, 10); - - if (*end) { - RTE_LOG(ERR, SHARED, "Bad integer value: %s\n", str); - return -1; - } - - return 0; -} - -/* attach the new device, then store port_id of the device */ -int -dev_attach_by_devargs(const char *devargs, uint16_t *port_id) -{ - int ret = -1; - struct rte_devargs da; - - memset(&da, 0, sizeof(da)); - - /* parse devargs */ - if (rte_devargs_parse(&da, devargs)) - return -1; - - ret = rte_eal_hotplug_add(da.bus->name, da.name, da.args); - if (ret < 0) { - free(da.args); - return ret; - } - - ret = rte_eth_dev_get_port_by_name(da.name, port_id); - - free(da.args); - - return ret; -} - -/* detach the device, then store the name of the device */ -int -dev_detach_by_port_id(uint16_t port_id) -{ - struct rte_device *dev; - struct rte_bus *bus; - uint32_t dev_flags; - int ret = -1; - - if (rte_eth_devices[port_id].data == NULL) { - RTE_LOG(INFO, SHARED, - "rte_eth_devices[%"PRIu16"].data is NULL\n", port_id); - return 0; - } - dev_flags = rte_eth_devices[port_id].data->dev_flags; - if (dev_flags & RTE_ETH_DEV_BONDED_SLAVE) { - RTE_LOG(ERR, SHARED, - "Port %"PRIu16" is bonded, cannot detach\n", port_id); - return -ENOTSUP; - } - - dev = rte_eth_devices[port_id].device; - if (dev == NULL) - return -EINVAL; - - bus = rte_bus_find_by_device(dev); - if (bus == NULL) - return -ENOENT; - - ret = rte_eal_hotplug_remove(bus->name, dev->name); - if (ret < 0) - return ret; - - rte_eth_dev_release_port(&rte_eth_devices[port_id]); - - return 0; -} diff --git a/src/shared/secondary.h b/src/shared/secondary.h deleted file mode 100644 index c6a1fde..0000000 --- a/src/shared/secondary.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation - */ - -#ifndef SHARED_SECONDARY_H -#define SHARED_SECONDARY_H - -#define VHOST_IFACE_NAME "/tmp/sock%u" -#define VHOST_BACKEND_NAME "eth_vhost%u" - -#define PCAP_PMD_DEV_NAME "eth_pcap%u" -#define NULL_PMD_DEV_NAME "eth_null%u" - -static inline const char * -get_vhost_backend_name(unsigned int id) -{ - /* - * buffer for return value. Size calculated by %u being replaced - * by maximum 3 digits (plus an extra byte for safety) - */ - static char buffer[sizeof(VHOST_BACKEND_NAME) + 2]; - - snprintf(buffer, sizeof(buffer) - 1, VHOST_BACKEND_NAME, id); - return buffer; -} - -static inline char * -get_vhost_iface_name(unsigned int id) -{ - /* - * buffer for return value. Size calculated by %u being replaced - * by maximum 3 digits (plus an extra byte for safety) - */ - static char buffer[sizeof(VHOST_IFACE_NAME) + 2]; - - snprintf(buffer, sizeof(buffer) - 1, VHOST_IFACE_NAME, id); - return buffer; -} - -static inline const char * -get_pcap_pmd_name(int id) -{ - static char buffer[sizeof(PCAP_PMD_DEV_NAME) + 2]; - snprintf(buffer, sizeof(buffer) - 1, PCAP_PMD_DEV_NAME, id); - return buffer; -} - -static inline const char * -get_null_pmd_name(int id) -{ - static char buffer[sizeof(NULL_PMD_DEV_NAME) + 2]; - snprintf(buffer, sizeof(buffer) - 1, NULL_PMD_DEV_NAME, id); - return buffer; -} - -/* Get status of spp_nfv or spp_vm as JSON format. */ -void get_sec_stats_json(char *str, uint16_t client_id, - const char *running_stat, - struct port *ports_fwd_array, - struct port_map *port_map); - -/* Append port info to sec status, called from get_sec_stats_json(). */ -int append_port_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map); - -/* Append patch info to sec status, called from get_sec_stats_json(). */ -int append_patch_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map); - -int parse_resource_uid(char *str, char **port_type, int *port_id); -int spp_atoi(const char *str, int *val); - -/** - * Attach a new Ethernet device specified by arguments. - * - * @param devargs - * A pointer to a strings array describing the new device - * to be attached. The strings should be a pci address like - * '0000:01:00.0' or virtual device name like 'net_pcap0'. - * @param port_id - * A pointer to a port identifier actually attached. - * @return - * 0 on success and port_id is filled, negative on error - */ -int -dev_attach_by_devargs(const char *devargs, uint16_t *port_id); - -/** - * Detach a Ethernet device specified by port identifier. - * This function must be called when the device is in the - * closed state. - * - * @param port_id - * The port identifier of the device to detach. - * @return - * 0 on success and devname is filled, negative on error - */ -int dev_detach_by_port_id(uint16_t port_id); - -#endif diff --git a/src/nfv/command_utils.h b/src/shared/secondary/add_port.h similarity index 61% rename from src/nfv/command_utils.h rename to src/shared/secondary/add_port.h index f026732..83f2514 100644 --- a/src/nfv/command_utils.h +++ b/src/shared/secondary/add_port.h @@ -3,122 +3,66 @@ * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation */ -#ifndef _NFV_COMMAND_UTILS_H_ -#define _NFV_COMMAND_UTILS_H_ +#ifndef _SHARED_SECONDARY_ADD_PORT_H_ +#define _SHARED_SECONDARY_ADD_PORT_H_ -#include "common.h" -#include "secondary.h" - -#define RTE_LOGTYPE_SPP_NFV RTE_LOGTYPE_USER1 +#include +#include "utils.h" // The number of receive descriptors to allocate for the receive ring. #define NR_DESCS 128 -#define PCAP_IFACE_RX "/tmp/spp-rx%d.pcap" -#define PCAP_IFACE_TX "/tmp/spp-tx%d.pcap" - -static void -forward_array_init_one(unsigned int i) -{ - ports_fwd_array[i].in_port_id = PORT_RESET; - ports_fwd_array[i].out_port_id = PORT_RESET; -} - -static void -forward_array_remove(int port_id) -{ - unsigned int i; - - /* Update ports_fwd_array */ - forward_array_init_one(port_id); +#define VHOST_IFACE_NAME "/tmp/sock%u" +#define VHOST_BACKEND_NAME "eth_vhost%u" - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - if (ports_fwd_array[i].in_port_id == PORT_RESET) - continue; +#define PCAP_PMD_DEV_NAME "eth_pcap%u" +#define NULL_PMD_DEV_NAME "eth_null%u" - if (ports_fwd_array[i].out_port_id == port_id) { - ports_fwd_array[i].out_port_id = PORT_RESET; - break; - } - } -} +#define PCAP_IFACE_RX "/tmp/spp-rx%d.pcap" +#define PCAP_IFACE_TX "/tmp/spp-tx%d.pcap" -static void -port_map_init_one(unsigned int i) -{ - port_map[i].id = PORT_RESET; - port_map[i].port_type = UNDEF; - port_map[i].stats = &port_map[i].default_stats; -} +#define RTE_LOGTYPE_SHARED RTE_LOGTYPE_USER1 -static void -port_map_init(void) +static inline const char * +get_vhost_backend_name(unsigned int id) { - unsigned int i; - - for (i = 0; i < RTE_MAX_ETHPORTS; i++) - port_map_init_one(i); + /* + * buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) + */ + static char buffer[sizeof(VHOST_BACKEND_NAME) + 2]; + + snprintf(buffer, sizeof(buffer) - 1, VHOST_BACKEND_NAME, id); + return buffer; } -/* Return 0 if invalid */ -static int -is_valid_port(uint16_t port_id) +static inline char * +get_vhost_iface_name(unsigned int id) { - if (port_id > RTE_MAX_ETHPORTS) - return 0; - - return port_map[port_id].id != PORT_RESET; + /* + * buffer for return value. Size calculated by %u being replaced + * by maximum 3 digits (plus an extra byte for safety) + */ + static char buffer[sizeof(VHOST_IFACE_NAME) + 2]; + + snprintf(buffer, sizeof(buffer) - 1, VHOST_IFACE_NAME, id); + return buffer; } -/* - * Return actual port ID which is assigned by system internally, or PORT_RESET - * if port is not found. - */ -static uint16_t -find_port_id(int id, enum port_type type) +static inline const char * +get_pcap_pmd_name(int id) { - uint16_t port_id = PORT_RESET; - uint16_t i; - - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - if (port_map[i].port_type != type) - continue; - - if (port_map[i].id == id) { - port_id = i; - break; - } - } - - return port_id; + static char buffer[sizeof(PCAP_PMD_DEV_NAME) + 2]; + snprintf(buffer, sizeof(buffer) - 1, PCAP_PMD_DEV_NAME, id); + return buffer; } -/* Return -1 as an error if given patch is invalid */ -static int -add_patch(uint16_t in_port, uint16_t out_port) +static inline const char * +get_null_pmd_name(int id) { - if (!is_valid_port(in_port) || !is_valid_port(out_port)) - return -1; - - /* Populate in port data */ - ports_fwd_array[in_port].in_port_id = in_port; - ports_fwd_array[in_port].rx_func = &rte_eth_rx_burst; - ports_fwd_array[in_port].tx_func = &rte_eth_tx_burst; - ports_fwd_array[in_port].out_port_id = out_port; - - /* Populate out port data */ - ports_fwd_array[out_port].in_port_id = out_port; - ports_fwd_array[out_port].rx_func = &rte_eth_rx_burst; - ports_fwd_array[out_port].tx_func = &rte_eth_tx_burst; - - RTE_LOG(DEBUG, SPP_NFV, "STATUS: in port %d in_port_id %d\n", in_port, - ports_fwd_array[in_port].in_port_id); - RTE_LOG(DEBUG, SPP_NFV, "STATUS: in port %d patch out port id %d\n", - in_port, ports_fwd_array[in_port].out_port_id); - RTE_LOG(DEBUG, SPP_NFV, "STATUS: outport %d in_port_id %d\n", out_port, - ports_fwd_array[out_port].in_port_id); - - return 0; + static char buffer[sizeof(NULL_PMD_DEV_NAME) + 2]; + snprintf(buffer, sizeof(buffer) - 1, NULL_PMD_DEV_NAME, id); + return buffer; } /* @@ -141,7 +85,7 @@ create_pcap_rx(char *rx_fpath) if (tmp_fp == NULL) { (tmp_fp = fopen(template, "w")); if (tmp_fp == NULL) { - RTE_LOG(ERR, SPP_NFV, "Failed to open %s\n", template); + RTE_LOG(ERR, SHARED, "Failed to open %s\n", template); return -1; } } @@ -149,12 +93,12 @@ create_pcap_rx(char *rx_fpath) sprintf(cmd_str, "text2pcap %s %s", template, rx_fpath); res = system(cmd_str); if (res != 0) { - RTE_LOG(ERR, SPP_NFV, + RTE_LOG(ERR, SHARED, "Failed to create pcap device %s\n", rx_fpath); return -1; } - RTE_LOG(INFO, SPP_NFV, "PCAP device created\n"); + RTE_LOG(INFO, SHARED, "PCAP device created\n"); fclose(tmp_fp); return 0; } @@ -175,21 +119,21 @@ add_ring_pmd(int ring_id) /* Look up ring with provided ring_id */ ring = rte_ring_lookup(rx_queue_name); if (ring == NULL) { - RTE_LOG(ERR, SPP_NFV, + RTE_LOG(ERR, SHARED, "Failed to get RX ring %s - is primary running?\n", rx_queue_name); return -1; } - RTE_LOG(INFO, SPP_NFV, "Looked up ring '%s'\n", rx_queue_name); + RTE_LOG(INFO, SHARED, "Looked up ring '%s'\n", rx_queue_name); /* create ring pmd*/ res = rte_eth_from_ring(ring); if (res < 0) { - RTE_LOG(ERR, SPP_NFV, + RTE_LOG(ERR, SHARED, "Cannot create eth dev with rte_eth_from_ring()\n"); return -1; } - RTE_LOG(INFO, SPP_NFV, "Created ring PMD: %d\n", res); + RTE_LOG(INFO, SHARED, "Created ring PMD: %d\n", res); return res; } @@ -248,7 +192,7 @@ add_vhost_pmd(int index) if (ret < 0) return ret; - RTE_LOG(DEBUG, SPP_NFV, "vhost port id %d\n", vhost_port_id); + RTE_LOG(DEBUG, SHARED, "vhost port id %d\n", vhost_port_id); return vhost_port_id; } @@ -335,7 +279,7 @@ add_pcap_pmd(int index) if (ret < 0) return ret; - RTE_LOG(DEBUG, SPP_NFV, "pcap port id %d\n", pcap_pmd_port_id); + RTE_LOG(DEBUG, SHARED, "pcap port id %d\n", pcap_pmd_port_id); return pcap_pmd_port_id; } @@ -397,47 +341,9 @@ add_null_pmd(int index) if (ret < 0) return ret; - RTE_LOG(DEBUG, SPP_NFV, "null port id %d\n", null_pmd_port_id); + RTE_LOG(DEBUG, SHARED, "null port id %d\n", null_pmd_port_id); return null_pmd_port_id; } -/* initialize forward array with default value*/ -static void -forward_array_init(void) -{ - unsigned int i; - - /* initialize port forward array*/ - for (i = 0; i < RTE_MAX_ETHPORTS; i++) - forward_array_init_one(i); -} - -static void -forward_array_reset(void) -{ - unsigned int i; - - /* initialize port forward array*/ - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - if (ports_fwd_array[i].in_port_id != PORT_RESET) { - ports_fwd_array[i].out_port_id = PORT_RESET; - RTE_LOG(INFO, SPP_NFV, "Port ID %d\n", i); - RTE_LOG(INFO, SPP_NFV, "out_port_id %d\n", - ports_fwd_array[i].out_port_id); - } - } -} - -/* Return a type of port as a enum member of porttype_map structure. */ -static enum port_type get_port_type(char *portname) -{ - for (int i = 0; portmap[i].port_name != NULL; i++) { - const char *port_name = portmap[i].port_name; - if (strncmp(portname, port_name, strlen(port_name)) == 0) - return portmap[i].port_type; - } - return UNDEF; -} - -#endif // _NFV_COMMAND_UTILS_H_ +#endif diff --git a/src/shared/secondary/utils.c b/src/shared/secondary/utils.c new file mode 100644 index 0000000..8f2e830 --- /dev/null +++ b/src/shared/secondary/utils.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#include +#include "shared/common.h" +#include "shared/secondary/utils.h" + +#define RTE_LOGTYPE_SHARED RTE_LOGTYPE_USER1 + +/** + * Retieve port type and ID from resource UID. For example, resource UID + * 'ring:0' is parsed to retrieve port tyep 'ring' and ID '0'. + */ +int +parse_resource_uid(char *str, char **port_type, int *port_id) +{ + char *token; + char delim[] = ":"; + char *endp; + + RTE_LOG(DEBUG, SHARED, "Parsing resource UID: '%s\n'", str); + if (strstr(str, delim) == NULL) { + RTE_LOG(ERR, SHARED, "Invalid resource UID: '%s'\n", str); + return -1; + } + RTE_LOG(DEBUG, SHARED, "Delimiter %s is included\n", delim); + + *port_type = strtok(str, delim); + + token = strtok(NULL, delim); + *port_id = strtol(token, &endp, 10); + + if (*endp) { + RTE_LOG(ERR, SHARED, "Bad integer value: %s\n", str); + return -1; + } + + return 0; +} + +int +spp_atoi(const char *str, int *val) +{ + char *end; + + *val = strtol(str, &end, 10); + + if (*end) { + RTE_LOG(ERR, SHARED, "Bad integer value: %s\n", str); + return -1; + } + + return 0; +} + +/* attach the new device, then store port_id of the device */ +int +dev_attach_by_devargs(const char *devargs, uint16_t *port_id) +{ + int ret = -1; + struct rte_devargs da; + + memset(&da, 0, sizeof(da)); + + /* parse devargs */ + if (rte_devargs_parse(&da, devargs)) + return -1; + + ret = rte_eal_hotplug_add(da.bus->name, da.name, da.args); + if (ret < 0) { + free(da.args); + return ret; + } + + ret = rte_eth_dev_get_port_by_name(da.name, port_id); + + free(da.args); + + return ret; +} + +/* detach the device, then store the name of the device */ +int +dev_detach_by_port_id(uint16_t port_id) +{ + struct rte_device *dev; + struct rte_bus *bus; + uint32_t dev_flags; + int ret = -1; + + if (rte_eth_devices[port_id].data == NULL) { + RTE_LOG(INFO, SHARED, + "rte_eth_devices[%"PRIu16"].data is NULL\n", port_id); + return 0; + } + dev_flags = rte_eth_devices[port_id].data->dev_flags; + if (dev_flags & RTE_ETH_DEV_BONDED_SLAVE) { + RTE_LOG(ERR, SHARED, + "Port %"PRIu16" is bonded, cannot detach\n", port_id); + return -ENOTSUP; + } + + dev = rte_eth_devices[port_id].device; + if (dev == NULL) + return -EINVAL; + + bus = rte_bus_find_by_device(dev); + if (bus == NULL) + return -ENOENT; + + ret = rte_eal_hotplug_remove(bus->name, dev->name); + if (ret < 0) + return ret; + + rte_eth_dev_release_port(&rte_eth_devices[port_id]); + + return 0; +} diff --git a/src/shared/secondary/utils.h b/src/shared/secondary/utils.h new file mode 100644 index 0000000..c905b12 --- /dev/null +++ b/src/shared/secondary/utils.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _SHARED_SECONDARY_UTILS_H_ +#define _SHARED_SECONDARY_UTILS_H_ + +int parse_resource_uid(char *str, char **port_type, int *port_id); + +int spp_atoi(const char *str, int *val); + +/** + * Attach a new Ethernet device specified by arguments. + * + * @param devargs + * A pointer to a strings array describing the new device + * to be attached. The strings should be a pci address like + * '0000:01:00.0' or virtual device name like 'net_pcap0'. + * @param port_id + * A pointer to a port identifier actually attached. + * @return + * 0 on success and port_id is filled, negative on error + */ +int +dev_attach_by_devargs(const char *devargs, uint16_t *port_id); + +/** + * Detach a Ethernet device specified by port identifier. + * This function must be called when the device is in the + * closed state. + * + * @param port_id + * The port identifier of the device to detach. + * @return + * 0 on success and devname is filled, negative on error + */ +int dev_detach_by_port_id(uint16_t port_id); + +#endif -- 2.17.1