Soft Patch Panel
 help / color / mirror / Atom feed
From: ogawa.yasufumi@lab.ntt.co.jp
To: ferruh.yigit@intel.com, spp@dpdk.org, ogawa.yasufumi@lab.ntt.co.jp
Subject: [spp] [PATCH 5/6] shared: refactor libs of SPP secondary
Date: Tue, 15 Jan 2019 12:28:00 +0900	[thread overview]
Message-ID: <1547522881-10105-6-git-send-email-ogawa.yasufumi@lab.ntt.co.jp> (raw)
In-Reply-To: <1547522881-10105-1-git-send-email-ogawa.yasufumi@lab.ntt.co.jp>

From: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

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 <ogawa.yasufumi@lab.ntt.co.jp>
---
 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 <stdint.h>
-#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 <arpa/inet.h>
+#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 <stdint.h>
+#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

  parent reply	other threads:[~2019-01-15  3:30 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-15  3:27 [spp] [PATCH 0/6] Refactor common libs ogawa.yasufumi
2019-01-15  3:27 ` [spp] [PATCH 1/6] spp_primary: refactor common for primary ogawa.yasufumi
2019-01-15  3:27 ` [spp] [PATCH 2/6] shared: refactor common for SPP secondaries ogawa.yasufumi
2019-01-15  3:27 ` [spp] [PATCH 3/6] spp_nfv: refactor common for spp_nfv ogawa.yasufumi
2019-01-15  3:27 ` [spp] [PATCH 4/6] shared: refactor common functions ogawa.yasufumi
2019-01-15  3:28 ` ogawa.yasufumi [this message]
2019-01-15  3:28 ` [spp] [PATCH 6/6] spp_nfv: refactor file structure ogawa.yasufumi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1547522881-10105-6-git-send-email-ogawa.yasufumi@lab.ntt.co.jp \
    --to=ogawa.yasufumi@lab.ntt.co.jp \
    --cc=ferruh.yigit@intel.com \
    --cc=spp@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).