Soft Patch Panel
 help / color / mirror / Atom feed
From: x-fn-spp-ml@ntt-tx.co.jp
To: spp@dpdk.org, ferruh.yigit@intel.com, yasufum.o@gmail.com
Subject: [spp] [PATCH v2 07/17] spp_primary: add common function of rte_flow
Date: Wed, 19 Feb 2020 20:49:37 +0900
Message-ID: <20200219114947.14134-8-x-fn-spp-ml@ntt-tx.co.jp> (raw)
In-Reply-To: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp>

From: Hideyuki Yamashita <yamashita.hideyuki@ntt-tx.co.jp>

To support rte_flow in SPP, this patch provides parse functions those
are commonly used by primary application.

Signed-off-by: Hideyuki Yamashita <yamashita.hideyuki@ntt-tx.co.jp>
Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
---
 src/primary/flow/common.c | 646 ++++++++++++++++++++++++++++++++++++++
 src/primary/flow/common.h |  53 ++++
 src/primary/main.c        |  48 +--
 3 files changed, 725 insertions(+), 22 deletions(-)
 create mode 100644 src/primary/flow/common.c
 create mode 100644 src/primary/flow/common.h

diff --git a/src/primary/flow/common.c b/src/primary/flow/common.c
new file mode 100644
index 0000000..da34619
--- /dev/null
+++ b/src/primary/flow/common.c
@@ -0,0 +1,646 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation
+ */
+
+#include <rte_ethdev.h>
+
+#include "shared/secondary/spp_worker_th/data_types.h"
+#include "shared/secondary/utils.h"
+#include "flow.h"
+#include "common.h"
+
+/*
+ * Check if port_id is used
+ * Return 0: Port_id used
+ * Return 1: Unused port_id
+ */
+int
+is_portid_used(int port_id)
+{
+	uint16_t pid;
+
+	RTE_ETH_FOREACH_DEV(pid) {
+		if (port_id == pid)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Retrieve port ID from source UID of phy port. Return error code if port
+ * type is other than phy.
+ */
+int
+parse_phy_port_id(char *res_uid, int *port_id)
+{
+	int ret;
+	char *port_type;
+	uint16_t queue_id;
+
+	if (res_uid == NULL) {
+		RTE_LOG(ERR, SPP_FLOW,
+			"RES UID is NULL(%s:%d)\n", __func__, __LINE__);
+		return -1;
+	}
+
+	ret = parse_resource_uid(res_uid, &port_type, port_id, &queue_id);
+	if (ret < 0) {
+		RTE_LOG(ERR, SPP_FLOW,
+			"Failed to parse RES UID(%s:%d)\n",
+			__func__, __LINE__);
+		return -1;
+	}
+
+	if (strcmp(port_type, SPPWK_PHY_STR) != 0) {
+		RTE_LOG(ERR, SPP_FLOW,
+			"It's not phy type(%s:%d)\n", __func__, __LINE__);
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * Convert string to rte_ether_addr.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_rte_ether_addr(char *mac_str, void *output)
+{
+	int i = 0;
+	uint8_t byte;
+	char *end, *token;
+	char tmp_mac_str[32] = { 0 };
+	struct rte_ether_addr *mac_addr = output;
+
+	strncpy(tmp_mac_str, mac_str, 32);
+	token = strtok(tmp_mac_str, ":");
+
+	while (token != NULL) {
+		if (i >= RTE_ETHER_ADDR_LEN)
+			return -1;
+
+		byte = (uint8_t)strtoul(token, &end, 16);
+		if (end == NULL || *end != '\0')
+			return -1;
+
+		mac_addr->addr_bytes[i] = byte;
+		i++;
+		token = strtok(NULL, ":");
+	}
+
+	return 0;
+}
+
+/*
+ * Convert string to tci.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_tci(char *tci_str, void *output)
+{
+	char *end;
+	rte_be16_t *tci = output;
+
+	*tci = (rte_be16_t)strtoul(tci_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Convert string to pcp.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_pcp(char *pcp_str, void *output)
+{
+	char *end;
+	uint8_t *pcp = output;
+
+	*pcp = (uint8_t)strtoul(pcp_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	/* 3bit check */
+	if (*pcp > 0x7)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Set PCP in TCI. TCI is a 16bits value and consists of 3bits PCP,
+ * 1bit DEI and the rest 12bits VID.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+set_pcp_in_tci(char *pcp_str, void *output)
+{
+	int ret;
+	uint8_t pcp = 0;
+	rte_be16_t *tci = output;
+
+	ret = str_to_pcp(pcp_str, &pcp);
+	if (ret != 0)
+		return -1;
+
+	/* Assign to the first 3 bits */
+	pcp = pcp << 1;
+	((char *)tci)[0] = ((char *)tci)[0] | pcp;
+
+	return 0;
+}
+
+/*
+ * Set DEI in TCI. TCI is a 16bits value and consists of 3bits PCP,
+ * 1bit DEI and the rest 12bits VID.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+set_dei_in_tci(char *dei_str, void *output)
+{
+	char *end;
+	uint8_t dei = 0;
+	rte_be16_t *tci = output;
+
+	dei = (uint8_t)strtoul(dei_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	/* 1bit check */
+	if (dei > 0x1)
+		return -1;
+
+	/* Assign to 4th bit */
+	((char *)tci)[0] = ((char *)tci)[0] | dei;
+
+	return 0;
+}
+
+/*
+ * Set VID in TCI. TCI is a 16bits value and consists of 3bits PCP,
+ * 1bit DEI and the rest 12bits VID.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+set_vid_in_tci(char *vid_str, void *output)
+{
+	char *end;
+	rte_be16_t vid = 0;
+	rte_be16_t *tci = output;
+
+	vid = (rte_be16_t)strtoul(vid_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	/* 12bit check */
+	if (vid > 0x0fff)
+		return -1;
+
+	/* Convert vid to big endian if system is little endian. */
+	int i = 1;
+	if (*(char *)&i) { /* check if little endian */
+		uint8_t b1 = ((char *)&vid)[0];
+		uint8_t b2 = ((char *)&vid)[1];
+		((char *)&vid)[0] = b2;
+		((char *)&vid)[1] = b1;
+	}
+
+	/* Assign to 5-16 bit */
+	*tci = *tci | vid;
+
+	return 0;
+}
+
+/*
+ * Convert string to rte_be16_t.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_rte_be16_t(char *target_str, void *output)
+{
+	char *end;
+	rte_be16_t *value = output;
+
+	*value = (rte_be16_t)strtoul(target_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+	/* Convert vid to big endian if system is little endian. */
+	int i = 1;
+	if (*(char *)&i) { /* check if little endian */
+		uint8_t b1 = ((char *)value)[0];
+		uint8_t b2 = ((char *)value)[1];
+		((char *)value)[0] = b2;
+		((char *)value)[1] = b1;
+	}
+
+	return 0;
+}
+
+/*
+ * Convert string to uint16_t.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_uint16_t(char *target_str, void *output)
+{
+	char *end;
+	uint16_t *value = output;
+
+	*value = (uint16_t)strtoul(target_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Convert string to uint32_t.
+ * This function is intended to be called as a function pointer to
+ * 'parse_detail' in 'struct flow_detail_ops'.
+ */
+int
+str_to_uint32_t(char *target_str, void *output)
+{
+	char *end;
+	uint32_t *value = output;
+
+	*value = (uint32_t)strtoul(target_str, &end, 0);
+	if (end == NULL || *end != '\0')
+		return -1;
+
+	return 0;
+}
+
+int
+parse_rte_flow_item_field(char *token_list[], int *index,
+	struct flow_detail_ops *detail_list, size_t size,
+	void **spec, void **last, void **mask
+	)
+{
+	int ret = 0;
+	uint32_t prefix, i, j, bitmask;
+	char *end, *target;
+
+	if (!strcmp(token_list[*index], "is")) {
+		/* Match value perfectly (with full bit-mask). */
+		(*index)++;
+
+		if (*spec == NULL) {
+			ret = malloc_object(spec, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		ret = detail_list->parse_detail(token_list[*index],
+			(char *)(*spec) + detail_list->offset);
+		if (ret != 0) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"parse_detail error (%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+		/* Set full bit-mask */
+		if (*mask == NULL) {
+			ret = malloc_object(mask, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		memset((char *)(*mask) + detail_list->offset, 0xff,
+			detail_list->size);
+
+	} else if (!strcmp(token_list[*index], "spec")) {
+		/* Match value according to configured bit-mask. */
+		(*index)++;
+
+		if (*spec == NULL) {
+			ret = malloc_object(spec, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		ret = detail_list->parse_detail(token_list[*index],
+			(char *)(*spec) + detail_list->offset);
+		if (ret != 0) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"parse_detail error (%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+	} else if (!strcmp(token_list[*index], "last")) {
+		/* Specify upper bound to establish a range. */
+		(*index)++;
+
+		if (*last == NULL) {
+			ret = malloc_object(last, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		ret = detail_list->parse_detail(token_list[*index],
+			(char *)(*last) + detail_list->offset);
+		if (ret != 0) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"parse_detail error (%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+	} else if (!strcmp(token_list[*index], "mask")) {
+		/* Specify bit-mask with relevant bits set to one. */
+		(*index)++;
+
+		if (*mask == NULL) {
+			ret = malloc_object(mask, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		ret = detail_list->parse_detail(token_list[*index],
+			(char *)(*mask) + detail_list->offset);
+		if (ret != 0) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"parse_detail error (%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+	} else if (!strcmp(token_list[*index], "prefix")) {
+		/*
+		 * generate bit-mask with <prefix-length>
+		 * most-significant bits set to one.
+		 */
+		(*index)++;
+
+		if (*mask == NULL) {
+			ret = malloc_object(mask, size);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Failed to alloc memory (%s:%d)\n",
+					__func__, __LINE__);
+				return -1;
+			}
+		}
+
+		prefix = strtoul(token_list[*index], &end, 10);
+		if (end == NULL || *end != '\0') {
+			RTE_LOG(ERR, SPP_FLOW,
+				"Prefix is not a number(%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+		/* Compare prefix (bit) and size (byte). */
+		if (prefix > detail_list->size * 8) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"Prefix value is too large(%s:%d)\n",
+				__func__, __LINE__);
+			return -1;
+		}
+
+		target = (char *)(*mask) + detail_list->offset;
+		memset(target, 0, detail_list->size);
+		for (i = 0; i < detail_list->size; i++) {
+			if (prefix <= 0)
+				break;
+
+			bitmask = 0x80;
+
+			for (j = 0; j < 8; j++) {
+				if (prefix <= 0)
+					break;
+
+				target[i] = target[i] | bitmask;
+				bitmask = bitmask >> 1;
+				prefix--;
+			}
+		}
+
+	} else {
+		RTE_LOG(ERR, SPP_FLOW,
+			"Invalid parameter is %s(%s:%d)\n",
+			token_list[*index], __func__, __LINE__);
+		return -1;
+	}
+
+	return 0;
+}
+
+int
+parse_item_common(char *token_list[], int *index,
+	struct rte_flow_item *item,
+	struct flow_item_ops *ops)
+{
+	int ret = 0;
+	int i = 0;
+	//void *spec, *last, *mask;
+	void *spec = NULL, *last = NULL, *mask = NULL;
+	struct flow_detail_ops *detail_list = ops->detail_list;
+
+	/* Next to pattern word */
+	(*index)++;
+
+	while (token_list[*index] != NULL) {
+
+		/* Exit if "/" */
+		if (!strcmp(token_list[*index], "/"))
+			break;
+
+		/* First is value type */
+		i = 0;
+		while (detail_list[i].token != NULL) {
+			if (!strcmp(token_list[*index],
+				detail_list[i].token)) {
+				break;
+			}
+
+			i++;
+		}
+		if (detail_list[i].token == NULL) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"Invalid \"%s\" pattern arguments(%s:%d)\n",
+				ops->str_type, __func__, __LINE__);
+			ret = -1;
+			break;
+		}
+
+		/* Parse token value */
+		if (detail_list[i].flg_value == 1) {
+			(*index)++;
+
+			ret = parse_rte_flow_item_field(token_list, index,
+				&detail_list[i], ops->size,
+				&spec, &last, &mask);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Invalid \"%s\" pattern arguments"
+					"(%s:%d)\n",
+					ops->str_type, __func__, __LINE__);
+				ret = -1;
+				break;
+			}
+		}
+
+		(*index)++;
+	}
+
+	/* Free memory allocated in case of failure. */
+	if (ret != 0) {
+		if (spec != NULL)
+			free(spec);
+
+		if (last != NULL)
+			free(last);
+
+		if (mask != NULL)
+			free(mask);
+	}
+
+	/* Parse result to item. */
+	item->spec = spec;
+	item->last = last;
+	item->mask = mask;
+
+	return ret;
+}
+
+int
+parse_action_common(char *token_list[], int *index,
+	struct rte_flow_action *action,
+	struct flow_action_ops *ops)
+{
+	int ret = 0;
+	int i = 0;
+	struct rte_flow_action_queue  *conf;
+	struct flow_detail_ops *detail_list = ops->detail_list;
+
+	conf = malloc(ops->size);
+	if (conf == NULL) {
+		RTE_LOG(ERR, SPP_FLOW,
+			"Memory allocation failure(%s:%d)\n",
+			__func__, __LINE__);
+		return -1;
+	}
+	memset(conf, 0, ops->size);
+
+	/* Next to word */
+	(*index)++;
+
+	while (token_list[*index] != NULL) {
+
+		/* Exit if "/" */
+		if (!strcmp(token_list[*index], "/"))
+			break;
+
+		/* First is value type */
+		i = 0;
+		while (detail_list[i].token != NULL) {
+			if (!strcmp(token_list[*index],
+				detail_list[i].token)) {
+				break;
+			}
+
+			i++;
+		}
+		if (detail_list[i].token == NULL) {
+			RTE_LOG(ERR, SPP_FLOW,
+				"Invalid \"%s\" pattern arguments(%s:%d)\n",
+				ops->str_type, __func__, __LINE__);
+			ret = -1;
+			break;
+		}
+
+		/* Parse token value */
+		if (detail_list[i].flg_value == 1) {
+			(*index)++;
+
+			ret = detail_list[i].parse_detail(
+				token_list[*index],
+				(char *)conf + detail_list[i].offset);
+			if (ret != 0) {
+				RTE_LOG(ERR, SPP_FLOW,
+					"Invalid \"%s\" pattern arguments"
+					"(%s:%d)\n",
+					detail_list[i].token,
+					__func__, __LINE__);
+				ret = -1;
+				break;
+			}
+		}
+
+		(*index)++;
+	}
+
+	/* Free memory allocated in case of failure. */
+	if ((ret != 0) && (conf != NULL))
+		free(conf);
+
+	/* Parse result to action. */
+	action->conf = conf;
+
+	return ret;
+}
+
+/* Append action json, conf field is null */
+int
+append_action_null_json(const void *conf __attribute__ ((unused)),
+	int buf_size, char *action_str)
+{
+	char null_str[] = "null";
+
+	if ((int)strlen(action_str) + (int)strlen(null_str)
+		> buf_size)
+		return -1;
+
+	strncat(action_str, null_str, strlen(null_str));
+
+	return 0;
+}
+
+int
+malloc_object(void **ptr, size_t size)
+{
+	*ptr = malloc(size);
+	if (*ptr == NULL) {
+		RTE_LOG(ERR, SPP_FLOW,
+			"Memory allocation failure(%s:%d)\n",
+			__func__, __LINE__);
+		return -1;
+	}
+
+	memset(*ptr, 0, size);
+	return 0;
+}
diff --git a/src/primary/flow/common.h b/src/primary/flow/common.h
new file mode 100644
index 0000000..998fd12
--- /dev/null
+++ b/src/primary/flow/common.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation
+ */
+
+#ifndef _PRIMARY_FLOW_COMMON_H_
+#define _PRIMARY_FLOW_COMMON_H_
+
+int is_portid_used(int port_id);
+
+/* Function for flow command parse */
+int parse_phy_port_id(char *res_uid, int *port_id);
+
+/* Functions for converting string to data */
+int str_to_rte_ether_addr(char *mac_str, void *output);
+int str_to_tci(char *tci_str, void *output);
+int str_to_pcp(char *pcp_str, void *output);
+int str_to_rte_be16_t(char *target_str, void *output);
+int str_to_uint16_t(char *target_str, void *output);
+int str_to_uint32_t(char *target_str, void *output);
+
+/* Functions for setting string to data */
+int set_pcp_in_tci(char *pcp_str, void *output);
+int set_dei_in_tci(char *dei_str, void *output);
+int set_vid_in_tci(char *vid_str, void *output);
+
+/* Parse rte_flow_item for each field */
+int parse_rte_flow_item_field(char *token_list[], int *index,
+	struct flow_detail_ops *detail_list, size_t size,
+	void **spec, void **last, void **mask);
+
+/*
+ * Common parse for item type. Perform detailed parse with
+ * flow_detail_ops according to type.
+ */
+int parse_item_common(char *token_list[], int *index,
+	struct rte_flow_item *item,
+	struct flow_item_ops *ops);
+
+/*
+ * Common parse for action type. Perform detailed parse with
+ * flow_detail_ops according to type.
+ */
+int parse_action_common(char *token_list[], int *index,
+	struct rte_flow_action *action,
+	struct flow_action_ops *ops);
+
+/* Append action json, conf field is null */
+int append_action_null_json(const void *conf, int buf_size, char *action_str);
+
+/* Allocate memory for the size */
+int malloc_object(void **ptr, size_t size);
+
+#endif
diff --git a/src/primary/main.c b/src/primary/main.c
index ca81636..4ef9cb1 100644
--- a/src/primary/main.c
+++ b/src/primary/main.c
@@ -395,9 +395,7 @@ append_lcore_info_json(char *str,
 
 /* TODO(yasufum): change to use shared */
 static int
-append_port_info_json(char *str,
-		struct port *ports_fwd_array,
-		struct port_map *port_map)
+append_port_info_json(char *str)
 {
 	unsigned int i;
 	unsigned int has_port = 0;  // for checking having port at last
@@ -405,7 +403,7 @@ append_port_info_json(char *str,
 	sprintf(str + strlen(str), "\"ports\":[");
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
 
-		if (ports_fwd_array[i].in_port_id == PORT_RESET)
+		if (ports_fwd_array[i][0].in_port_id == PORT_RESET)
 			continue;
 
 		has_port = 1;
@@ -457,9 +455,7 @@ append_port_info_json(char *str,
 
 /* TODO(yasufum): change to use shared */
 static int
-append_patch_info_json(char *str,
-		struct port *ports_fwd_array,
-		struct port_map *port_map)
+append_patch_info_json(char *str)
 {
 	unsigned int i;
 	unsigned int has_patch = 0;  // for checking having patch at last
@@ -468,12 +464,12 @@ append_patch_info_json(char *str,
 	sprintf(str + strlen(str), "\"patches\":[");
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
 
-		if (ports_fwd_array[i].in_port_id == PORT_RESET)
+		if (ports_fwd_array[i][0].in_port_id == PORT_RESET)
 			continue;
 
 		RTE_LOG(INFO, PRIMARY, "Port ID %d\n", i);
 		RTE_LOG(INFO, PRIMARY, "Status %d\n",
-			ports_fwd_array[i].in_port_id);
+			ports_fwd_array[i][0].in_port_id);
 
 		memset(patch_str, '\0', sizeof(patch_str));
 
@@ -533,14 +529,14 @@ append_patch_info_json(char *str,
 		sprintf(patch_str + strlen(patch_str), "\"dst\":");
 
 		RTE_LOG(INFO, PRIMARY, "Out Port ID %d\n",
-				ports_fwd_array[i].out_port_id);
+				ports_fwd_array[i][0].out_port_id);
 
-		if (ports_fwd_array[i].out_port_id == PORT_RESET) {
+		if (ports_fwd_array[i][0].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;
+			unsigned int j = ports_fwd_array[i][0].out_port_id;
 			switch (port_map[j].port_type) {
 			case PHY:
 				RTE_LOG(INFO, PRIMARY, "Type: PHY\n");
@@ -629,8 +625,8 @@ forwarder_status_json(char *str)
 	else
 		sprintf(buf_running + strlen(buf_running), "\"%s\"", "idling");
 
-	append_port_info_json(buf_ports, ports_fwd_array, port_map);
-	append_patch_info_json(buf_patches, ports_fwd_array, port_map);
+	append_port_info_json(buf_ports);
+	append_patch_info_json(buf_patches);
 
 	sprintf(str, "\"forwarder\":{%s,%s,%s}", buf_running, buf_ports,
 			buf_patches);
@@ -871,7 +867,7 @@ add_port(char *p_type, int p_id)
 	 */
 
 	/* Update ports_fwd_array with port id */
-	ports_fwd_array[port_id].in_port_id = port_id;
+	ports_fwd_array[port_id][0].in_port_id = port_id;
 	return 0;
 }
 
@@ -942,7 +938,7 @@ del_port(char *p_type, int p_id)
 	port_id_list[dev_id].port_id = PORT_RESET;
 	port_id_list[dev_id].type = UNDEF;
 
-	forward_array_remove(dev_id);
+	forward_array_remove(dev_id, 0);
 	port_map_init_one(dev_id);
 
 	return 0;
@@ -964,6 +960,7 @@ parse_command(char *str)
 	char *p_type;
 	int p_id;
 	char tmp_response[MSG_SIZE];
+	uint16_t queue_id;
 
 	memset(sec_name, '\0', 16);
 	memset(tmp_response, '\0', MSG_SIZE);
@@ -1033,7 +1030,8 @@ parse_command(char *str)
 		RTE_LOG(DEBUG, PRIMARY, "'%s' command received.\n",
 				token_list[0]);
 
-		ret = parse_resource_uid(token_list[1], &p_type, &p_id);
+		ret = parse_resource_uid(token_list[1], &p_type, &p_id,
+			&queue_id);
 		if (ret < 0) {
 			RTE_LOG(ERR, PRIMARY, "Failed to parse RES UID.\n");
 			return ret;
@@ -1055,7 +1053,8 @@ parse_command(char *str)
 	} else if (!strcmp(token_list[0], "del")) {
 		RTE_LOG(DEBUG, PRIMARY, "Received del command\n");
 
-		ret = parse_resource_uid(token_list[1], &p_type, &p_id);
+		ret = parse_resource_uid(token_list[1], &p_type, &p_id,
+			&queue_id);
 		if (ret < 0) {
 			RTE_LOG(ERR, PRIMARY, "Failed to parse RES UID.\n");
 			return ret;
@@ -1094,13 +1093,15 @@ parse_command(char *str)
 			char *out_p_type;
 			int in_p_id;
 			int out_p_id;
+			uint16_t in_queue_id, out_queue_id;
 
-			parse_resource_uid(token_list[1], &in_p_type, &in_p_id);
+			parse_resource_uid(token_list[1], &in_p_type, &in_p_id,
+				&in_queue_id);
 			in_port = find_port_id(in_p_id,
 					get_port_type(in_p_type));
 
 			parse_resource_uid(token_list[2],
-					&out_p_type, &out_p_id);
+					&out_p_type, &out_p_id, &out_queue_id);
 			out_port = find_port_id(out_p_id,
 					get_port_type(out_p_type));
 
@@ -1128,7 +1129,8 @@ parse_command(char *str)
 				RTE_LOG(ERR, PRIMARY, "%s\n", err_msg);
 			}
 
-			if (add_patch(in_port, out_port) == 0) {
+			if (add_patch(in_port, in_queue_id, out_port,
+				out_queue_id) == 0) {
 				RTE_LOG(INFO, PRIMARY,
 					"Patched '%s:%d' and '%s:%d'\n",
 					in_p_type, in_p_id,
@@ -1323,10 +1325,12 @@ main(int argc, char *argv[])
 			}
 
 			/* Update ports_fwd_array with phy port. */
-			ports_fwd_array[i].in_port_id = i;
+			ports_fwd_array[i][0].in_port_id = i;
+			ports_fwd_array[i][0].in_queue_id = 0;
 			port_map[i].port_type = port_type;
 			port_map[i].id = port_id;
 			port_map[i].stats = &ports->port_stats[i];
+			port_map[i].queue_info = NULL;
 
 			/* TODO(yasufum) convert type of port_type to char */
 			RTE_LOG(DEBUG, PRIMARY, "Add port, type: %d, id: %d\n",
-- 
2.17.1


  parent reply	other threads:[~2020-02-19 11:50 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-18  6:37 [spp] [PATCH 00/17] Adding Hardware offload capability x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 01/17] shared: add support of multi-queue x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 02/17] spp_vf: " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 03/17] spp_mirror: " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 04/17] spp_pcap: " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 05/17] spp_primary: " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 06/17] spp_primary: add support of rte_flow x-fn-spp-ml
2020-02-19  2:24   ` Yasufumi Ogawa
2020-02-19 11:57     ` [spp] (x-fn-spp-ml 118) " Hideyuki Yamashita
2020-02-18  6:37 ` [spp] [PATCH 07/17] spp_primary: add common function " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 08/17] spp_primary: add attribute " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 09/17] spp_primary: add patterns " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 10/17] spp_primary: add actions " x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 11/17] bin: add parameter for hardrare offload x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 12/17] cli: add support of hardware offload x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 13/17] cli: add support of rte_flow in vf x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 14/17] cli: add support of rte_flow in mirror x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 15/17] cli: add support of rte_flow in nfv x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 16/17] spp-ctl: add APIs for flow rules x-fn-spp-ml
2020-02-18  6:37 ` [spp] [PATCH 17/17] spp_nfv: add support of multi-queue x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 00/17] Adding Hardware offload capability x-fn-spp-ml
2020-02-21  8:17   ` Yasufumi Ogawa
2020-02-25  5:49     ` [spp] (x-fn-spp-ml 177) " Hideyuki Yamashita
2020-02-19 11:49 ` [spp] [PATCH v2 01/17] shared: add support of multi-queue x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 02/17] spp_vf: " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 03/17] spp_mirror: " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 04/17] spp_pcap: " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 05/17] spp_primary: " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 06/17] spp_primary: add support of rte_flow x-fn-spp-ml
2020-02-19 11:49 ` x-fn-spp-ml [this message]
2020-02-19 11:49 ` [spp] [PATCH v2 08/17] spp_primary: add attribute " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 09/17] spp_primary: add patterns " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 10/17] spp_primary: add actions " x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 11/17] bin: add parameter for hardrare offload x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 12/17] cli: add support of hardware offload x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 13/17] cli: add support of rte_flow in vf x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 14/17] cli: add support of rte_flow in mirror x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 15/17] cli: add support of rte_flow in nfv x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 16/17] spp-ctl: add APIs for flow rules x-fn-spp-ml
2020-02-19 11:49 ` [spp] [PATCH v2 17/17] spp_nfv: add support of multi-queue x-fn-spp-ml

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=20200219114947.14134-8-x-fn-spp-ml@ntt-tx.co.jp \
    --to=x-fn-spp-ml@ntt-tx.co.jp \
    --cc=ferruh.yigit@intel.com \
    --cc=spp@dpdk.org \
    --cc=yasufum.o@gmail.com \
    /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

Soft Patch Panel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/spp/0 spp/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 spp spp/ https://inbox.dpdk.org/spp \
		spp@dpdk.org
	public-inbox-index spp

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.spp


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git