DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] example/l2fwd-event: add option to configure forwarding info
@ 2020-03-24 12:34 pbhagavatula
  2020-03-24 12:34 ` [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs pbhagavatula
  0 siblings, 1 reply; 10+ messages in thread
From: pbhagavatula @ 2020-03-24 12:34 UTC (permalink / raw)
  To: jerinj, Marko Kovacevic, Ori Kam, Bruce Richardson, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Sunil Kumar Kori, Pavan Nikhilesh,
	John McNamara
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Current l2fwd-event application statically configures adjacent ports as
destination ports for forwarding the traffic.

Add a config option to pass the forwarding port pair mapping which allows
the user to configure forwarding port mapping.

If no config argument is specified, destination port map is not
changed and traffic gets forwarded with existing mapping.

To align port/queue configuration of each lcore with destination port
map, port/queue configuration of each lcore gets modified when config
option is specificed.

Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"

With above config option, traffic received from portid = 0 gets forwarded
to port = 3 and vice versa, similarly traffic gets forwarded on other port
pairs (1,4) and (2,5).

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 doc/guides/sample_app_ug/l2_forward_event.rst |   2 +
 examples/l2fwd-event/l2fwd_common.h           |   1 +
 examples/l2fwd-event/main.c                   | 180 +++++++++++++++---
 3 files changed, 158 insertions(+), 25 deletions(-)

diff --git a/doc/guides/sample_app_ug/l2_forward_event.rst b/doc/guides/sample_app_ug/l2_forward_event.rst
index 8c519c304..8bdf352c4 100644
--- a/doc/guides/sample_app_ug/l2_forward_event.rst
+++ b/doc/guides/sample_app_ug/l2_forward_event.rst
@@ -66,6 +66,8 @@ where,
 
 *   --eventq-sched=SCHED_MODE: Event queue schedule mode, Ordered, Atomic or Parallel. Atomic by default.
 
+*   --config: Configure forwarding port pair mapping. Alternate port pairs by default.
+
 Sample usage commands are given below to run the application into different mode:
 
 Poll mode with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address updating enabled,
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
index 7e33ee749..4e8b2fe14 100644
--- a/examples/l2fwd-event/l2fwd_common.h
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -69,6 +69,7 @@ struct l2fwd_resources {
 	uint8_t sched_type;
 	uint8_t mac_updating;
 	uint8_t rx_queue_per_lcore;
+	uint8_t port_pairs;
 	uint16_t nb_rxd;
 	uint16_t nb_txd;
 	uint32_t enabled_port_mask;
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 89a6bb9a4..92890d1ae 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2019 Marvell International Ltd.
  */
 
+#include <rte_string_fns.h>
+
 #include "l2fwd_event.h"
 #include "l2fwd_poll.h"
 
@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
 	       "          Default mode = eventdev\n"
 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n"
 	       "                  Default: atomic\n"
-	       "                  Valid only if --mode=eventdev\n\n",
+	       "                  Valid only if --mode=eventdev\n"
+	       "  --config: Configure forwarding port pair mapping\n"
+	       "	    Default: alternate port pairs\n\n",
 	       prgname);
 }
 
@@ -99,6 +103,69 @@ l2fwd_event_parse_eventq_sched(const char *optarg,
 		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
 }
 
+static int
+l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
+{
+	enum fieldnames {
+		FLD_PORT1 = 0,
+		FLD_PORT2,
+		_NUM_FLD
+	};
+	const char *p, *p0 = q_arg;
+	uint16_t int_fld[_NUM_FLD];
+	char *str_fld[_NUM_FLD];
+	uint16_t port_pair = 0;
+	unsigned int size;
+	char s[256];
+	char *end;
+	int i;
+
+	while ((p = strchr(p0, '(')) != NULL) {
+		++p;
+		p0 = strchr(p, ')');
+		if (p0 == NULL)
+			return -1;
+
+		size = p0 - p;
+		if (size >= sizeof(s))
+			return -1;
+
+		snprintf(s, sizeof(s), "%.*s", size, p);
+		if (rte_strsplit(s, sizeof(s), str_fld,
+					_NUM_FLD, ',') != _NUM_FLD)
+			return -1;
+
+		for (i = 0; i < _NUM_FLD; i++) {
+			errno = 0;
+			int_fld[i] = strtoul(str_fld[i], &end, 0);
+			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+				return -1;
+		}
+
+		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
+			printf("exceeded max number of port pair params: Current %d Max = %d\n",
+			       port_pair, RTE_MAX_ETHPORTS / 2);
+			return -1;
+		}
+
+		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
+			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
+			printf("Duplicate port pair (%d,%d) config\n",
+					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
+			return -1;
+		}
+
+		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
+		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
+
+		port_pair++;
+	}
+
+	rsrc->port_pairs = true;
+
+	return 0;
+}
+
 static const char short_options[] =
 	"p:"  /* portmask */
 	"q:"  /* number of queues */
@@ -109,6 +176,7 @@ static const char short_options[] =
 #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
 #define CMD_LINE_OPT_MODE "mode"
 #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched"
+#define CMD_LINE_OPT_PORT_PAIR_CONF "config"
 
 enum {
 	/* long options mapped to a short option */
@@ -119,12 +187,12 @@ enum {
 	CMD_LINE_OPT_MIN_NUM = 256,
 	CMD_LINE_OPT_MODE_NUM,
 	CMD_LINE_OPT_EVENTQ_SCHED_NUM,
+	CMD_LINE_OPT_PORT_PAIR_CONF_NUM,
 };
 
 /* Parse the argument given in the command line of the application */
 static int
-l2fwd_event_parse_args(int argc, char **argv,
-		struct l2fwd_resources *rsrc)
+l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc)
 {
 	int mac_updating = 1;
 	struct option lgopts[] = {
@@ -134,12 +202,18 @@ l2fwd_event_parse_args(int argc, char **argv,
 							CMD_LINE_OPT_MODE_NUM},
 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
 						CMD_LINE_OPT_EVENTQ_SCHED_NUM},
+		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL,
+					CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
 		{NULL, 0, 0, 0}
 	};
 	int opt, ret, timer_secs;
 	char *prgname = argv[0];
-	char **argvopt;
+	uint16_t port_id;
 	int option_index;
+	char **argvopt;
+	/* reset l2fwd_dst_ports */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		rsrc->dst_ports[port_id] = UINT32_MAX;
 
 	argvopt = argv;
 	while ((opt = getopt_long(argc, argvopt, short_options,
@@ -189,6 +263,15 @@ l2fwd_event_parse_args(int argc, char **argv,
 			l2fwd_event_parse_eventq_sched(optarg, rsrc);
 			break;
 
+		case CMD_LINE_OPT_PORT_PAIR_CONF_NUM:
+			ret = l2fwd_parse_port_pair_config(optarg, rsrc);
+			if (ret) {
+				printf("Invalid port pair config\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
 		/* long options */
 		case 0:
 			break;
@@ -209,6 +292,51 @@ l2fwd_event_parse_args(int argc, char **argv,
 	return ret;
 }
 
+/*
+ * Check port pair config with enabled port mask,
+ * and for valid port pair combinations.
+ */
+static int
+check_port_pair_config(struct l2fwd_resources *rsrc)
+{
+	uint32_t port_pair_mask = 0;
+	uint32_t portid;
+	uint16_t index;
+
+	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
+		if ((rsrc->enabled_port_mask & (1 << index)) == 0)
+			continue;
+
+		portid = rsrc->dst_ports[index];
+		if (portid == UINT32_MAX) {
+			printf("port %u is enabled in but no valid port pair\n",
+			       index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(index)) {
+			printf("port %u is not valid\n", index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(portid)) {
+			printf("port %u is not valid\n", portid);
+			return -1;
+		}
+
+		if (port_pair_mask & (1 << portid) &&
+				rsrc->dst_ports[portid] != index) {
+			printf("port %u is used in other port pairs\n", portid);
+			return -1;
+		}
+
+		port_pair_mask |= (1 << portid);
+		port_pair_mask |= (1 << index);
+	}
+
+	return 0;
+}
+
 static int
 l2fwd_launch_one_lcore(void *args)
 {
@@ -465,31 +593,33 @@ main(int argc, char **argv)
 		rte_panic("Invalid portmask; possible (0x%x)\n",
 			(1 << nb_ports) - 1);
 
-	/* reset l2fwd_dst_ports */
-	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
-		rsrc->dst_ports[port_id] = 0;
-	last_port = 0;
+	if (!rsrc->port_pairs) {
+		last_port = 0;
+		/*
+		 * Each logical core is assigned a dedicated TX queue on each
+		 * port.
+		 */
+		RTE_ETH_FOREACH_DEV(port_id) {
+			/* skip ports that are not enabled */
+			if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+				continue;
 
-	/*
-	 * Each logical core is assigned a dedicated TX queue on each port.
-	 */
-	RTE_ETH_FOREACH_DEV(port_id) {
-		/* skip ports that are not enabled */
-		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
-			continue;
+			if (nb_ports_in_mask % 2) {
+				rsrc->dst_ports[port_id] = last_port;
+				rsrc->dst_ports[last_port] = port_id;
+			} else {
+				last_port = port_id;
+			}
 
+			nb_ports_in_mask++;
+		}
 		if (nb_ports_in_mask % 2) {
-			rsrc->dst_ports[port_id] = last_port;
-			rsrc->dst_ports[last_port] = port_id;
-		} else {
-			last_port = port_id;
+			printf("Notice: odd number of ports in portmask.\n");
+			rsrc->dst_ports[last_port] = last_port;
 		}
-
-		nb_ports_in_mask++;
-	}
-	if (nb_ports_in_mask % 2) {
-		printf("Notice: odd number of ports in portmask.\n");
-		rsrc->dst_ports[last_port] = last_port;
+	} else {
+		if (check_port_pair_config(rsrc) < 0)
+			rte_panic("Invalid port pair config\n");
 	}
 
 	nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT +
-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-24 12:34 [dpdk-dev] [PATCH] example/l2fwd-event: add option to configure forwarding info pbhagavatula
@ 2020-03-24 12:34 ` pbhagavatula
  2020-03-25 10:40   ` Sunil Kumar Kori
  2020-03-26  6:42   ` [dpdk-dev] [dpdk-dev v2] " pbhagavatula
  0 siblings, 2 replies; 10+ messages in thread
From: pbhagavatula @ 2020-03-24 12:34 UTC (permalink / raw)
  To: jerinj, Marko Kovacevic, Ori Kam, Bruce Richardson, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Sunil Kumar Kori, Pavan Nikhilesh,
	John McNamara
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Current l2fwd-event application statically configures adjacent ports as
destination ports for forwarding the traffic.

Add a config option to pass the forwarding port pair mapping which allows
the user to configure forwarding port mapping.

If no config argument is specified, destination port map is not
changed and traffic gets forwarded with existing mapping.

To align port/queue configuration of each lcore with destination port
map, port/queue configuration of each lcore gets modified when config
option is specificed.

Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"

With above config option, traffic received from portid = 0 gets forwarded
to port = 3 and vice versa, similarly traffic gets forwarded on other port
pairs (1,4) and (2,5).

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 doc/guides/sample_app_ug/l2_forward_event.rst |   2 +
 examples/l2fwd-event/l2fwd_common.h           |   1 +
 examples/l2fwd-event/main.c                   | 180 +++++++++++++++---
 3 files changed, 158 insertions(+), 25 deletions(-)

diff --git a/doc/guides/sample_app_ug/l2_forward_event.rst b/doc/guides/sample_app_ug/l2_forward_event.rst
index 8c519c304..8bdf352c4 100644
--- a/doc/guides/sample_app_ug/l2_forward_event.rst
+++ b/doc/guides/sample_app_ug/l2_forward_event.rst
@@ -66,6 +66,8 @@ where,
 
 *   --eventq-sched=SCHED_MODE: Event queue schedule mode, Ordered, Atomic or Parallel. Atomic by default.
 
+*   --config: Configure forwarding port pair mapping. Alternate port pairs by default.
+
 Sample usage commands are given below to run the application into different mode:
 
 Poll mode with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address updating enabled,
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
index 7e33ee749..4e8b2fe14 100644
--- a/examples/l2fwd-event/l2fwd_common.h
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -69,6 +69,7 @@ struct l2fwd_resources {
 	uint8_t sched_type;
 	uint8_t mac_updating;
 	uint8_t rx_queue_per_lcore;
+	uint8_t port_pairs;
 	uint16_t nb_rxd;
 	uint16_t nb_txd;
 	uint32_t enabled_port_mask;
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 89a6bb9a4..92890d1ae 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2019 Marvell International Ltd.
  */
 
+#include <rte_string_fns.h>
+
 #include "l2fwd_event.h"
 #include "l2fwd_poll.h"
 
@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
 	       "          Default mode = eventdev\n"
 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n"
 	       "                  Default: atomic\n"
-	       "                  Valid only if --mode=eventdev\n\n",
+	       "                  Valid only if --mode=eventdev\n"
+	       "  --config: Configure forwarding port pair mapping\n"
+	       "	    Default: alternate port pairs\n\n",
 	       prgname);
 }
 
@@ -99,6 +103,69 @@ l2fwd_event_parse_eventq_sched(const char *optarg,
 		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
 }
 
+static int
+l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
+{
+	enum fieldnames {
+		FLD_PORT1 = 0,
+		FLD_PORT2,
+		_NUM_FLD
+	};
+	const char *p, *p0 = q_arg;
+	uint16_t int_fld[_NUM_FLD];
+	char *str_fld[_NUM_FLD];
+	uint16_t port_pair = 0;
+	unsigned int size;
+	char s[256];
+	char *end;
+	int i;
+
+	while ((p = strchr(p0, '(')) != NULL) {
+		++p;
+		p0 = strchr(p, ')');
+		if (p0 == NULL)
+			return -1;
+
+		size = p0 - p;
+		if (size >= sizeof(s))
+			return -1;
+
+		snprintf(s, sizeof(s), "%.*s", size, p);
+		if (rte_strsplit(s, sizeof(s), str_fld,
+					_NUM_FLD, ',') != _NUM_FLD)
+			return -1;
+
+		for (i = 0; i < _NUM_FLD; i++) {
+			errno = 0;
+			int_fld[i] = strtoul(str_fld[i], &end, 0);
+			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+				return -1;
+		}
+
+		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
+			printf("exceeded max number of port pair params: Current %d Max = %d\n",
+			       port_pair, RTE_MAX_ETHPORTS / 2);
+			return -1;
+		}
+
+		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
+			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
+			printf("Duplicate port pair (%d,%d) config\n",
+					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
+			return -1;
+		}
+
+		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
+		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
+
+		port_pair++;
+	}
+
+	rsrc->port_pairs = true;
+
+	return 0;
+}
+
 static const char short_options[] =
 	"p:"  /* portmask */
 	"q:"  /* number of queues */
@@ -109,6 +176,7 @@ static const char short_options[] =
 #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
 #define CMD_LINE_OPT_MODE "mode"
 #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched"
+#define CMD_LINE_OPT_PORT_PAIR_CONF "config"
 
 enum {
 	/* long options mapped to a short option */
@@ -119,12 +187,12 @@ enum {
 	CMD_LINE_OPT_MIN_NUM = 256,
 	CMD_LINE_OPT_MODE_NUM,
 	CMD_LINE_OPT_EVENTQ_SCHED_NUM,
+	CMD_LINE_OPT_PORT_PAIR_CONF_NUM,
 };
 
 /* Parse the argument given in the command line of the application */
 static int
-l2fwd_event_parse_args(int argc, char **argv,
-		struct l2fwd_resources *rsrc)
+l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc)
 {
 	int mac_updating = 1;
 	struct option lgopts[] = {
@@ -134,12 +202,18 @@ l2fwd_event_parse_args(int argc, char **argv,
 							CMD_LINE_OPT_MODE_NUM},
 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
 						CMD_LINE_OPT_EVENTQ_SCHED_NUM},
+		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL,
+					CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
 		{NULL, 0, 0, 0}
 	};
 	int opt, ret, timer_secs;
 	char *prgname = argv[0];
-	char **argvopt;
+	uint16_t port_id;
 	int option_index;
+	char **argvopt;
+	/* reset l2fwd_dst_ports */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		rsrc->dst_ports[port_id] = UINT32_MAX;
 
 	argvopt = argv;
 	while ((opt = getopt_long(argc, argvopt, short_options,
@@ -189,6 +263,15 @@ l2fwd_event_parse_args(int argc, char **argv,
 			l2fwd_event_parse_eventq_sched(optarg, rsrc);
 			break;
 
+		case CMD_LINE_OPT_PORT_PAIR_CONF_NUM:
+			ret = l2fwd_parse_port_pair_config(optarg, rsrc);
+			if (ret) {
+				printf("Invalid port pair config\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
 		/* long options */
 		case 0:
 			break;
@@ -209,6 +292,51 @@ l2fwd_event_parse_args(int argc, char **argv,
 	return ret;
 }
 
+/*
+ * Check port pair config with enabled port mask,
+ * and for valid port pair combinations.
+ */
+static int
+check_port_pair_config(struct l2fwd_resources *rsrc)
+{
+	uint32_t port_pair_mask = 0;
+	uint32_t portid;
+	uint16_t index;
+
+	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
+		if ((rsrc->enabled_port_mask & (1 << index)) == 0)
+			continue;
+
+		portid = rsrc->dst_ports[index];
+		if (portid == UINT32_MAX) {
+			printf("port %u is enabled in but no valid port pair\n",
+			       index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(index)) {
+			printf("port %u is not valid\n", index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(portid)) {
+			printf("port %u is not valid\n", portid);
+			return -1;
+		}
+
+		if (port_pair_mask & (1 << portid) &&
+				rsrc->dst_ports[portid] != index) {
+			printf("port %u is used in other port pairs\n", portid);
+			return -1;
+		}
+
+		port_pair_mask |= (1 << portid);
+		port_pair_mask |= (1 << index);
+	}
+
+	return 0;
+}
+
 static int
 l2fwd_launch_one_lcore(void *args)
 {
@@ -465,31 +593,33 @@ main(int argc, char **argv)
 		rte_panic("Invalid portmask; possible (0x%x)\n",
 			(1 << nb_ports) - 1);
 
-	/* reset l2fwd_dst_ports */
-	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
-		rsrc->dst_ports[port_id] = 0;
-	last_port = 0;
+	if (!rsrc->port_pairs) {
+		last_port = 0;
+		/*
+		 * Each logical core is assigned a dedicated TX queue on each
+		 * port.
+		 */
+		RTE_ETH_FOREACH_DEV(port_id) {
+			/* skip ports that are not enabled */
+			if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+				continue;
 
-	/*
-	 * Each logical core is assigned a dedicated TX queue on each port.
-	 */
-	RTE_ETH_FOREACH_DEV(port_id) {
-		/* skip ports that are not enabled */
-		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
-			continue;
+			if (nb_ports_in_mask % 2) {
+				rsrc->dst_ports[port_id] = last_port;
+				rsrc->dst_ports[last_port] = port_id;
+			} else {
+				last_port = port_id;
+			}
 
+			nb_ports_in_mask++;
+		}
 		if (nb_ports_in_mask % 2) {
-			rsrc->dst_ports[port_id] = last_port;
-			rsrc->dst_ports[last_port] = port_id;
-		} else {
-			last_port = port_id;
+			printf("Notice: odd number of ports in portmask.\n");
+			rsrc->dst_ports[last_port] = last_port;
 		}
-
-		nb_ports_in_mask++;
-	}
-	if (nb_ports_in_mask % 2) {
-		printf("Notice: odd number of ports in portmask.\n");
-		rsrc->dst_ports[last_port] = last_port;
+	} else {
+		if (check_port_pair_config(rsrc) < 0)
+			rte_panic("Invalid port pair config\n");
 	}
 
 	nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT +
-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-24 12:34 ` [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs pbhagavatula
@ 2020-03-25 10:40   ` Sunil Kumar Kori
  2020-03-26  6:37     ` Pavan Nikhilesh Bhagavatula
  2020-03-26  6:42   ` [dpdk-dev] [dpdk-dev v2] " pbhagavatula
  1 sibling, 1 reply; 10+ messages in thread
From: Sunil Kumar Kori @ 2020-03-25 10:40 UTC (permalink / raw)
  To: Pavan Nikhilesh Bhagavatula, Jerin Jacob Kollanukkaran,
	Marko Kovacevic, Ori Kam, Bruce Richardson, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Pavan Nikhilesh Bhagavatula,
	John McNamara
  Cc: dev

Comments inline.

Regards
Sunil Kumar Kori

>-----Original Message-----
>From: pbhagavatula@marvell.com <pbhagavatula@marvell.com>
>Sent: Tuesday, March 24, 2020 6:05 PM
>To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Marko Kovacevic
><marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Bruce
>Richardson <bruce.richardson@intel.com>; Radu Nicolau
><radu.nicolau@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; Tomasz
>Kantecki <tomasz.kantecki@intel.com>; Sunil Kumar Kori
><skori@marvell.com>; Pavan Nikhilesh Bhagavatula
><pbhagavatula@marvell.com>; John McNamara
><john.mcnamara@intel.com>
>Cc: dev@dpdk.org
>Subject: [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure
>port pairs
>
>From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
>Current l2fwd-event application statically configures adjacent ports as
>destination ports for forwarding the traffic.
>
>Add a config option to pass the forwarding port pair mapping which allows
>the user to configure forwarding port mapping.
>
>If no config argument is specified, destination port map is not changed and
>traffic gets forwarded with existing mapping.
>
>To align port/queue configuration of each lcore with destination port map,
>port/queue configuration of each lcore gets modified when config option is
>specificed.
>
>Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"
>
>With above config option, traffic received from portid = 0 gets forwarded to
>port = 3 and vice versa, similarly traffic gets forwarded on other port pairs
>(1,4) and (2,5).
>
Is this config required to be updated for l2fwd also ?

>Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
>---
>updating enabled, diff --git a/examples/l2fwd-event/l2fwd_common.h
>b/examples/l2fwd-event/l2fwd_common.h
>index 7e33ee749..4e8b2fe14 100644
>--- a/examples/l2fwd-event/l2fwd_common.h
>+++ b/examples/l2fwd-event/l2fwd_common.h
>@@ -69,6 +69,7 @@ struct l2fwd_resources {
> 	uint8_t sched_type;
> 	uint8_t mac_updating;
> 	uint8_t rx_queue_per_lcore;
>+	uint8_t port_pairs;
It can be changed to bool.

> 	uint16_t nb_rxd;
> 	uint16_t nb_txd;
> 	uint32_t enabled_port_mask;
>diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
>index 89a6bb9a4..92890d1ae 100644
>--- a/examples/l2fwd-event/main.c
>+++ b/examples/l2fwd-event/main.c
>@@ -2,6 +2,8 @@
>  * Copyright(C) 2019 Marvell International Ltd.
>  */
>
>+#include <rte_string_fns.h>
>+
> #include "l2fwd_event.h"
> #include "l2fwd_poll.h"
>
>@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
> 	       "          Default mode = eventdev\n"
> 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or
>parallel.\n"
> 	       "                  Default: atomic\n"
>-	       "                  Valid only if --mode=eventdev\n\n",
>+	       "                  Valid only if --mode=eventdev\n"
>+	       "  --config: Configure forwarding port pair mapping\n"
>+	       "	    Default: alternate port pairs\n\n",
> 	       prgname);
> }
>
>+l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources
>+*rsrc)
> {
> 	int mac_updating = 1;
> 	struct option lgopts[] = {
>@@ -134,12 +202,18 @@ l2fwd_event_parse_args(int argc, char **argv,
>
>	CMD_LINE_OPT_MODE_NUM},
> 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
>
>	CMD_LINE_OPT_EVENTQ_SCHED_NUM},
>+		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument,
>NULL,
>+
>	CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
> 		{NULL, 0, 0, 0}
> 	};
> 	int opt, ret, timer_secs;
> 	char *prgname = argv[0];
>-	char **argvopt;
>+	uint16_t port_id;
> 	int option_index;
>+	char **argvopt;
New line is required.

>+	/* reset l2fwd_dst_ports */
>+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
>+		rsrc->dst_ports[port_id] = UINT32_MAX;
>
> 	argvopt = argv;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-25 10:40   ` Sunil Kumar Kori
@ 2020-03-26  6:37     ` Pavan Nikhilesh Bhagavatula
  0 siblings, 0 replies; 10+ messages in thread
From: Pavan Nikhilesh Bhagavatula @ 2020-03-26  6:37 UTC (permalink / raw)
  To: Sunil Kumar Kori, Jerin Jacob Kollanukkaran, Marko Kovacevic,
	Ori Kam, Bruce Richardson, Radu Nicolau, Akhil Goyal,
	Tomasz Kantecki, John McNamara
  Cc: dev



>-----Original Message-----
>From: Sunil Kumar Kori <skori@marvell.com>
>Sent: Wednesday, March 25, 2020 4:10 PM
>To: Pavan Nikhilesh Bhagavatula <pbhagavatula@marvell.com>; Jerin
>Jacob Kollanukkaran <jerinj@marvell.com>; Marko Kovacevic
><marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Bruce
>Richardson <bruce.richardson@intel.com>; Radu Nicolau
><radu.nicolau@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; Tomasz
>Kantecki <tomasz.kantecki@intel.com>; Pavan Nikhilesh Bhagavatula
><pbhagavatula@marvell.com>; John McNamara
><john.mcnamara@intel.com>
>Cc: dev@dpdk.org
>Subject: RE: [dpdk-dev] [PATCH] examples/l2fwd-event: add option to
>configure port pairs
>
>Comments inline.
>
>Regards
>Sunil Kumar Kori
>
>>-----Original Message-----
>>From: pbhagavatula@marvell.com <pbhagavatula@marvell.com>
>>Sent: Tuesday, March 24, 2020 6:05 PM
>>To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Marko Kovacevic
>><marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>;
>Bruce
>>Richardson <bruce.richardson@intel.com>; Radu Nicolau
>><radu.nicolau@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>;
>Tomasz
>>Kantecki <tomasz.kantecki@intel.com>; Sunil Kumar Kori
>><skori@marvell.com>; Pavan Nikhilesh Bhagavatula
>><pbhagavatula@marvell.com>; John McNamara
>><john.mcnamara@intel.com>
>>Cc: dev@dpdk.org
>>Subject: [dpdk-dev] [PATCH] examples/l2fwd-event: add option to
>configure
>>port pairs
>>
>>From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>>
>>Current l2fwd-event application statically configures adjacent ports as
>>destination ports for forwarding the traffic.
>>
>>Add a config option to pass the forwarding port pair mapping which
>allows
>>the user to configure forwarding port mapping.
>>
>>If no config argument is specified, destination port map is not changed
>and
>>traffic gets forwarded with existing mapping.
>>
>>To align port/queue configuration of each lcore with destination port
>map,
>>port/queue configuration of each lcore gets modified when config
>option is
>>specificed.
>>
>>Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"
>>
>>With above config option, traffic received from portid = 0 gets
>forwarded to
>>port = 3 and vice versa, similarly traffic gets forwarded on other port
>pairs
>>(1,4) and (2,5).
>>
>Is this config required to be updated for l2fwd also ?

In pipeline.

>
>>Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
>>---
>>updating enabled, diff --git a/examples/l2fwd-
>event/l2fwd_common.h
>>b/examples/l2fwd-event/l2fwd_common.h
>>index 7e33ee749..4e8b2fe14 100644
>>--- a/examples/l2fwd-event/l2fwd_common.h
>>+++ b/examples/l2fwd-event/l2fwd_common.h
>>@@ -69,6 +69,7 @@ struct l2fwd_resources {
>> 	uint8_t sched_type;
>> 	uint8_t mac_updating;
>> 	uint8_t rx_queue_per_lcore;
>>+	uint8_t port_pairs;
>It can be changed to bool.

Will change in v2.

>
>> 	uint16_t nb_rxd;
>> 	uint16_t nb_txd;
>> 	uint32_t enabled_port_mask;
>>diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-
>event/main.c
>>index 89a6bb9a4..92890d1ae 100644
>>--- a/examples/l2fwd-event/main.c
>>+++ b/examples/l2fwd-event/main.c
>>@@ -2,6 +2,8 @@
>>  * Copyright(C) 2019 Marvell International Ltd.
>>  */
>>
>>+#include <rte_string_fns.h>
>>+
>> #include "l2fwd_event.h"
>> #include "l2fwd_poll.h"
>>
>>@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
>> 	       "          Default mode = eventdev\n"
>> 	       "  --eventq-sched: Event queue schedule type, ordered,
>atomic or
>>parallel.\n"
>> 	       "                  Default: atomic\n"
>>-	       "                  Valid only if --mode=eventdev\n\n",
>>+	       "                  Valid only if --mode=eventdev\n"
>>+	       "  --config: Configure forwarding port pair mapping\n"
>>+	       "	    Default: alternate port pairs\n\n",
>> 	       prgname);
>> }
>>
>>+l2fwd_event_parse_args(int argc, char **argv, struct
>l2fwd_resources
>>+*rsrc)
>> {
>> 	int mac_updating = 1;
>> 	struct option lgopts[] = {
>>@@ -134,12 +202,18 @@ l2fwd_event_parse_args(int argc, char
>**argv,
>>
>>	CMD_LINE_OPT_MODE_NUM},
>> 		{ CMD_LINE_OPT_EVENTQ_SCHED,
>required_argument, NULL,
>>
>>	CMD_LINE_OPT_EVENTQ_SCHED_NUM},
>>+		{ CMD_LINE_OPT_PORT_PAIR_CONF,
>required_argument,
>>NULL,
>>+
>>	CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
>> 		{NULL, 0, 0, 0}
>> 	};
>> 	int opt, ret, timer_secs;
>> 	char *prgname = argv[0];
>>-	char **argvopt;
>>+	uint16_t port_id;
>> 	int option_index;
>>+	char **argvopt;
>New line is required.

Will fix in v2.
>
>>+	/* reset l2fwd_dst_ports */
>>+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
>>+		rsrc->dst_ports[port_id] = UINT32_MAX;
>>
>> 	argvopt = argv;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [dpdk-dev v2] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-24 12:34 ` [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs pbhagavatula
  2020-03-25 10:40   ` Sunil Kumar Kori
@ 2020-03-26  6:42   ` pbhagavatula
  2020-03-31 10:23     ` Andrzej Ostruszka
  2020-03-31 12:53     ` [dpdk-dev] [PATCH v3] " pbhagavatula
  1 sibling, 2 replies; 10+ messages in thread
From: pbhagavatula @ 2020-03-26  6:42 UTC (permalink / raw)
  To: jerinj, Marko Kovacevic, Ori Kam, Bruce Richardson, Radu Nicolau,
	Akhil Goyal, Tomasz Kantecki, Sunil Kumar Kori, Pavan Nikhilesh,
	John McNamara
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Current l2fwd-event application statically configures adjacent ports as
destination ports for forwarding the traffic.

Add a config option to pass the forwarding port pair mapping which allows
the user to configure forwarding port mapping.

If no config argument is specified, destination port map is not
changed and traffic gets forwarded with existing mapping.

To align port/queue configuration of each lcore with destination port
map, port/queue configuration of each lcore gets modified when config
option is specificed.

Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"

With above config option, traffic received from portid = 0 gets forwarded
to port = 3 and vice versa, similarly traffic gets forwarded on other port
pairs (1,4) and (2,5).

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 v2 Changes:
 - Fix minor formatting error.
 - Change uint8_t to bool.

 doc/guides/sample_app_ug/l2_forward_event.rst |   2 +
 examples/l2fwd-event/l2fwd_common.h           |   1 +
 examples/l2fwd-event/main.c                   | 181 +++++++++++++++---
 3 files changed, 159 insertions(+), 25 deletions(-)

diff --git a/doc/guides/sample_app_ug/l2_forward_event.rst b/doc/guides/sample_app_ug/l2_forward_event.rst
index 8c519c304..8bdf352c4 100644
--- a/doc/guides/sample_app_ug/l2_forward_event.rst
+++ b/doc/guides/sample_app_ug/l2_forward_event.rst
@@ -66,6 +66,8 @@ where,

 *   --eventq-sched=SCHED_MODE: Event queue schedule mode, Ordered, Atomic or Parallel. Atomic by default.

+*   --config: Configure forwarding port pair mapping. Alternate port pairs by default.
+
 Sample usage commands are given below to run the application into different mode:

 Poll mode with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address updating enabled,
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
index 7e33ee749..939221d45 100644
--- a/examples/l2fwd-event/l2fwd_common.h
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -69,6 +69,7 @@ struct l2fwd_resources {
 	uint8_t sched_type;
 	uint8_t mac_updating;
 	uint8_t rx_queue_per_lcore;
+	bool port_pairs;
 	uint16_t nb_rxd;
 	uint16_t nb_txd;
 	uint32_t enabled_port_mask;
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 89a6bb9a4..bb71d15ab 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2019 Marvell International Ltd.
  */

+#include <rte_string_fns.h>
+
 #include "l2fwd_event.h"
 #include "l2fwd_poll.h"

@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
 	       "          Default mode = eventdev\n"
 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n"
 	       "                  Default: atomic\n"
-	       "                  Valid only if --mode=eventdev\n\n",
+	       "                  Valid only if --mode=eventdev\n"
+	       "  --config: Configure forwarding port pair mapping\n"
+	       "	    Default: alternate port pairs\n\n",
 	       prgname);
 }

@@ -99,6 +103,69 @@ l2fwd_event_parse_eventq_sched(const char *optarg,
 		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
 }

+static int
+l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
+{
+	enum fieldnames {
+		FLD_PORT1 = 0,
+		FLD_PORT2,
+		_NUM_FLD
+	};
+	const char *p, *p0 = q_arg;
+	uint16_t int_fld[_NUM_FLD];
+	char *str_fld[_NUM_FLD];
+	uint16_t port_pair = 0;
+	unsigned int size;
+	char s[256];
+	char *end;
+	int i;
+
+	while ((p = strchr(p0, '(')) != NULL) {
+		++p;
+		p0 = strchr(p, ')');
+		if (p0 == NULL)
+			return -1;
+
+		size = p0 - p;
+		if (size >= sizeof(s))
+			return -1;
+
+		snprintf(s, sizeof(s), "%.*s", size, p);
+		if (rte_strsplit(s, sizeof(s), str_fld,
+					_NUM_FLD, ',') != _NUM_FLD)
+			return -1;
+
+		for (i = 0; i < _NUM_FLD; i++) {
+			errno = 0;
+			int_fld[i] = strtoul(str_fld[i], &end, 0);
+			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+				return -1;
+		}
+
+		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
+			printf("exceeded max number of port pair params: Current %d Max = %d\n",
+			       port_pair, RTE_MAX_ETHPORTS / 2);
+			return -1;
+		}
+
+		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
+			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
+			printf("Duplicate port pair (%d,%d) config\n",
+					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
+			return -1;
+		}
+
+		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
+		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
+
+		port_pair++;
+	}
+
+	rsrc->port_pairs = true;
+
+	return 0;
+}
+
 static const char short_options[] =
 	"p:"  /* portmask */
 	"q:"  /* number of queues */
@@ -109,6 +176,7 @@ static const char short_options[] =
 #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
 #define CMD_LINE_OPT_MODE "mode"
 #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched"
+#define CMD_LINE_OPT_PORT_PAIR_CONF "config"

 enum {
 	/* long options mapped to a short option */
@@ -119,12 +187,12 @@ enum {
 	CMD_LINE_OPT_MIN_NUM = 256,
 	CMD_LINE_OPT_MODE_NUM,
 	CMD_LINE_OPT_EVENTQ_SCHED_NUM,
+	CMD_LINE_OPT_PORT_PAIR_CONF_NUM,
 };

 /* Parse the argument given in the command line of the application */
 static int
-l2fwd_event_parse_args(int argc, char **argv,
-		struct l2fwd_resources *rsrc)
+l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc)
 {
 	int mac_updating = 1;
 	struct option lgopts[] = {
@@ -134,12 +202,19 @@ l2fwd_event_parse_args(int argc, char **argv,
 							CMD_LINE_OPT_MODE_NUM},
 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
 						CMD_LINE_OPT_EVENTQ_SCHED_NUM},
+		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL,
+					CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
 		{NULL, 0, 0, 0}
 	};
 	int opt, ret, timer_secs;
 	char *prgname = argv[0];
-	char **argvopt;
+	uint16_t port_id;
 	int option_index;
+	char **argvopt;
+
+	/* reset l2fwd_dst_ports */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		rsrc->dst_ports[port_id] = UINT32_MAX;

 	argvopt = argv;
 	while ((opt = getopt_long(argc, argvopt, short_options,
@@ -189,6 +264,15 @@ l2fwd_event_parse_args(int argc, char **argv,
 			l2fwd_event_parse_eventq_sched(optarg, rsrc);
 			break;

+		case CMD_LINE_OPT_PORT_PAIR_CONF_NUM:
+			ret = l2fwd_parse_port_pair_config(optarg, rsrc);
+			if (ret) {
+				printf("Invalid port pair config\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
 		/* long options */
 		case 0:
 			break;
@@ -209,6 +293,51 @@ l2fwd_event_parse_args(int argc, char **argv,
 	return ret;
 }

+/*
+ * Check port pair config with enabled port mask,
+ * and for valid port pair combinations.
+ */
+static int
+check_port_pair_config(struct l2fwd_resources *rsrc)
+{
+	uint32_t port_pair_mask = 0;
+	uint32_t portid;
+	uint16_t index;
+
+	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
+		if ((rsrc->enabled_port_mask & (1 << index)) == 0)
+			continue;
+
+		portid = rsrc->dst_ports[index];
+		if (portid == UINT32_MAX) {
+			printf("port %u is enabled in but no valid port pair\n",
+			       index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(index)) {
+			printf("port %u is not valid\n", index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(portid)) {
+			printf("port %u is not valid\n", portid);
+			return -1;
+		}
+
+		if (port_pair_mask & (1 << portid) &&
+				rsrc->dst_ports[portid] != index) {
+			printf("port %u is used in other port pairs\n", portid);
+			return -1;
+		}
+
+		port_pair_mask |= (1 << portid);
+		port_pair_mask |= (1 << index);
+	}
+
+	return 0;
+}
+
 static int
 l2fwd_launch_one_lcore(void *args)
 {
@@ -465,31 +594,33 @@ main(int argc, char **argv)
 		rte_panic("Invalid portmask; possible (0x%x)\n",
 			(1 << nb_ports) - 1);

-	/* reset l2fwd_dst_ports */
-	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
-		rsrc->dst_ports[port_id] = 0;
-	last_port = 0;
+	if (!rsrc->port_pairs) {
+		last_port = 0;
+		/*
+		 * Each logical core is assigned a dedicated TX queue on each
+		 * port.
+		 */
+		RTE_ETH_FOREACH_DEV(port_id) {
+			/* skip ports that are not enabled */
+			if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+				continue;

-	/*
-	 * Each logical core is assigned a dedicated TX queue on each port.
-	 */
-	RTE_ETH_FOREACH_DEV(port_id) {
-		/* skip ports that are not enabled */
-		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
-			continue;
+			if (nb_ports_in_mask % 2) {
+				rsrc->dst_ports[port_id] = last_port;
+				rsrc->dst_ports[last_port] = port_id;
+			} else {
+				last_port = port_id;
+			}

+			nb_ports_in_mask++;
+		}
 		if (nb_ports_in_mask % 2) {
-			rsrc->dst_ports[port_id] = last_port;
-			rsrc->dst_ports[last_port] = port_id;
-		} else {
-			last_port = port_id;
+			printf("Notice: odd number of ports in portmask.\n");
+			rsrc->dst_ports[last_port] = last_port;
 		}
-
-		nb_ports_in_mask++;
-	}
-	if (nb_ports_in_mask % 2) {
-		printf("Notice: odd number of ports in portmask.\n");
-		rsrc->dst_ports[last_port] = last_port;
+	} else {
+		if (check_port_pair_config(rsrc) < 0)
+			rte_panic("Invalid port pair config\n");
 	}

 	nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT +
--
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [dpdk-dev v2] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-26  6:42   ` [dpdk-dev] [dpdk-dev v2] " pbhagavatula
@ 2020-03-31 10:23     ` Andrzej Ostruszka
  2020-03-31 12:17       ` Pavan Nikhilesh Bhagavatula
  2020-03-31 12:53     ` [dpdk-dev] [PATCH v3] " pbhagavatula
  1 sibling, 1 reply; 10+ messages in thread
From: Andrzej Ostruszka @ 2020-03-31 10:23 UTC (permalink / raw)
  To: dev

On 3/26/20 7:42 AM, pbhagavatula@marvell.com wrote:
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Current l2fwd-event application statically configures adjacent ports as
> destination ports for forwarding the traffic.
> 
> Add a config option to pass the forwarding port pair mapping which allows
> the user to configure forwarding port mapping.
> 
> If no config argument is specified, destination port map is not
> changed and traffic gets forwarded with existing mapping.
> 
> To align port/queue configuration of each lcore with destination port
> map, port/queue configuration of each lcore gets modified when config
> option is specificed.
> 
> Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"
> 
> With above config option, traffic received from portid = 0 gets forwarded
> to port = 3 and vice versa, similarly traffic gets forwarded on other port
> pairs (1,4) and (2,5).
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
>  v2 Changes:
>  - Fix minor formatting error.
>  - Change uint8_t to bool.
[...]
> @@ -99,6 +103,69 @@ l2fwd_event_parse_eventq_sched(const char *optarg,
>  		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
>  }
> 
> +static int
> +l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
> +{
> +	enum fieldnames {
> +		FLD_PORT1 = 0,
> +		FLD_PORT2,
> +		_NUM_FLD
> +	};
> +	const char *p, *p0 = q_arg;
> +	uint16_t int_fld[_NUM_FLD];
> +	char *str_fld[_NUM_FLD];
> +	uint16_t port_pair = 0;
> +	unsigned int size;
> +	char s[256];
> +	char *end;
> +	int i;
> +
> +	while ((p = strchr(p0, '(')) != NULL) {
> +		++p;
> +		p0 = strchr(p, ')');
> +		if (p0 == NULL)
> +			return -1;
> +
> +		size = p0 - p;
> +		if (size >= sizeof(s))
> +			return -1;
> +
> +		snprintf(s, sizeof(s), "%.*s", size, p);

This is a bit peculiar form of memcpy - you want no more than sizeof(s)
copied but that you checked above so here simple memcpy should be enough.

> +		if (rte_strsplit(s, sizeof(s), str_fld,
> +					_NUM_FLD, ',') != _NUM_FLD)
> +			return -1;
> +
> +		for (i = 0; i < _NUM_FLD; i++) {
> +			errno = 0;
> +			int_fld[i] = strtoul(str_fld[i], &end, 0);
> +			if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)

Replace 255 with check on ">= RTE_MAX_ETHPORTS".

> +				return -1;
> +		}
> +
> +		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
> +			printf("exceeded max number of port pair params: Current %d Max = %d\n",
> +			       port_pair, RTE_MAX_ETHPORTS / 2);
> +			return -1;
> +		}
> +
> +		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
> +			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
> +			printf("Duplicate port pair (%d,%d) config\n",
> +					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
> +			return -1;
> +		}
> +
> +		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
> +		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
> +
> +		port_pair++;
> +	}
> +
> +	rsrc->port_pairs = true;
> +
> +	return 0;
> +}
> +
[...]
> @@ -209,6 +293,51 @@ l2fwd_event_parse_args(int argc, char **argv,
>  	return ret;
>  }
> 
> +/*
> + * Check port pair config with enabled port mask,
> + * and for valid port pair combinations.
> + */
> +static int
> +check_port_pair_config(struct l2fwd_resources *rsrc)
> +{
> +	uint32_t port_pair_mask = 0;
> +	uint32_t portid;
> +	uint16_t index;
> +
> +	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
> +		if ((rsrc->enabled_port_mask & (1 << index)) == 0)
> +			continue;
> +
> +		portid = rsrc->dst_ports[index];
> +		if (portid == UINT32_MAX) {
> +			printf("port %u is enabled in but no valid port pair\n",
> +			       index);
> +			return -1;
> +		}
> +
> +		if (!rte_eth_dev_is_valid_port(index)) {
> +			printf("port %u is not valid\n", index);
> +			return -1;
> +		}
> +
> +		if (!rte_eth_dev_is_valid_port(portid)) {
> +			printf("port %u is not valid\n", portid);
> +			return -1;
> +		}
> +
> +		if (port_pair_mask & (1 << portid) &&
> +				rsrc->dst_ports[portid] != index) {
> +			printf("port %u is used in other port pairs\n", portid);
> +			return -1;
> +		}
> +
> +		port_pair_mask |= (1 << portid);
> +		port_pair_mask |= (1 << index);
> +	}

In the above loop you are doing checks twice.  Suppose you have pair
(2,3) and you go by index from 0 (like you do) and reach point i=2.
Then you check i=2 and p=3, then on next iteration you do the same
checks (this time i=3,p=2).  I guess simple fix would be to skip loop
iteration both on not enabled (like you do) and on check if the port was
already checked (test bit in port_pair_mask).

With regards
Andrzej Ostruszka


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [dpdk-dev v2] [PATCH] examples/l2fwd-event: add option to configure port pairs
  2020-03-31 10:23     ` Andrzej Ostruszka
@ 2020-03-31 12:17       ` Pavan Nikhilesh Bhagavatula
  0 siblings, 0 replies; 10+ messages in thread
From: Pavan Nikhilesh Bhagavatula @ 2020-03-31 12:17 UTC (permalink / raw)
  To: Andrzej Ostruszka, dev

>> ---
>>  v2 Changes:
>>  - Fix minor formatting error.
>>  - Change uint8_t to bool.
>[...]
>> @@ -99,6 +103,69 @@ l2fwd_event_parse_eventq_sched(const char
>*optarg,
>>  		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
>>  }
>>
>> +static int
>> +l2fwd_parse_port_pair_config(const char *q_arg, struct
>l2fwd_resources *rsrc)
>> +{
>> +	enum fieldnames {
>> +		FLD_PORT1 = 0,
>> +		FLD_PORT2,
>> +		_NUM_FLD
>> +	};
>> +	const char *p, *p0 = q_arg;
>> +	uint16_t int_fld[_NUM_FLD];
>> +	char *str_fld[_NUM_FLD];
>> +	uint16_t port_pair = 0;
>> +	unsigned int size;
>> +	char s[256];
>> +	char *end;
>> +	int i;
>> +
>> +	while ((p = strchr(p0, '(')) != NULL) {
>> +		++p;
>> +		p0 = strchr(p, ')');
>> +		if (p0 == NULL)
>> +			return -1;
>> +
>> +		size = p0 - p;
>> +		if (size >= sizeof(s))
>> +			return -1;
>> +
>> +		snprintf(s, sizeof(s), "%.*s", size, p);
>
>This is a bit peculiar form of memcpy - you want no more than sizeof(s)
>copied but that you checked above so here simple memcpy should be
>enough.

This is a remnant of l3fwd --config options parsing, I will change it to memcpy in 
next version.

>
>> +		if (rte_strsplit(s, sizeof(s), str_fld,
>> +					_NUM_FLD, ',') != _NUM_FLD)
>> +			return -1;
>> +
>> +		for (i = 0; i < _NUM_FLD; i++) {
>> +			errno = 0;
>> +			int_fld[i] = strtoul(str_fld[i], &end, 0);
>> +			if (errno != 0 || end == str_fld[i] || int_fld[i] >
>255)
>
>Replace 255 with check on ">= RTE_MAX_ETHPORTS".	

Will fix in next version.

>
>> +				return -1;
>> +		}
>> +
>> +		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
>> +			printf("exceeded max number of port pair
>params: Current %d Max = %d\n",
>> +			       port_pair, RTE_MAX_ETHPORTS / 2);
>> +			return -1;
>> +		}
>> +
>> +		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] !=
>UINT32_MAX) ||
>> +			(rsrc->dst_ports[int_fld[FLD_PORT2]] !=
>UINT32_MAX)) {
>> +			printf("Duplicate port pair (%d,%d) config\n",
>> +					int_fld[FLD_PORT1],
>int_fld[FLD_PORT2]);
>> +			return -1;
>> +		}
>> +
>> +		rsrc->dst_ports[int_fld[FLD_PORT1]] =
>int_fld[FLD_PORT2];
>> +		rsrc->dst_ports[int_fld[FLD_PORT2]] =
>int_fld[FLD_PORT1];
>> +
>> +		port_pair++;
>> +	}
>> +
>> +	rsrc->port_pairs = true;
>> +
>> +	return 0;
>> +}
>> +
>[...]
>> @@ -209,6 +293,51 @@ l2fwd_event_parse_args(int argc, char
>**argv,
>>  	return ret;
>>  }
>>
>> +/*
>> + * Check port pair config with enabled port mask,
>> + * and for valid port pair combinations.
>> + */
>> +static int
>> +check_port_pair_config(struct l2fwd_resources *rsrc)
>> +{
>> +	uint32_t port_pair_mask = 0;
>> +	uint32_t portid;
>> +	uint16_t index;
>> +
>> +	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
>> +		if ((rsrc->enabled_port_mask & (1 << index)) == 0)
>> +			continue;
>> +
>> +		portid = rsrc->dst_ports[index];
>> +		if (portid == UINT32_MAX) {
>> +			printf("port %u is enabled in but no valid port
>pair\n",
>> +			       index);
>> +			return -1;
>> +		}
>> +
>> +		if (!rte_eth_dev_is_valid_port(index)) {
>> +			printf("port %u is not valid\n", index);
>> +			return -1;
>> +		}
>> +
>> +		if (!rte_eth_dev_is_valid_port(portid)) {
>> +			printf("port %u is not valid\n", portid);
>> +			return -1;
>> +		}
>> +
>> +		if (port_pair_mask & (1 << portid) &&
>> +				rsrc->dst_ports[portid] != index) {
>> +			printf("port %u is used in other port pairs\n",
>portid);
>> +			return -1;
>> +		}
>> +
>> +		port_pair_mask |= (1 << portid);
>> +		port_pair_mask |= (1 << index);
>> +	}
>
>In the above loop you are doing checks twice.  Suppose you have pair
>(2,3) and you go by index from 0 (like you do) and reach point i=2.
>Then you check i=2 and p=3, then on next iteration you do the same
>checks (this time i=3,p=2).  I guess simple fix would be to skip loop
>iteration both on not enabled (like you do) and on check if the port was
>already checked (test bit in port_pair_mask).

Ack, will fix in v3.

>
>With regards
>Andrzej Ostruszka

Thanks,
Pavan.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v3] examples/l2fwd-event: add option to configure port pairs
  2020-03-26  6:42   ` [dpdk-dev] [dpdk-dev v2] " pbhagavatula
  2020-03-31 10:23     ` Andrzej Ostruszka
@ 2020-03-31 12:53     ` pbhagavatula
  2020-03-31 17:07       ` Andrzej Ostruszka
  1 sibling, 1 reply; 10+ messages in thread
From: pbhagavatula @ 2020-03-31 12:53 UTC (permalink / raw)
  To: jerinj, aostruszka, Marko Kovacevic, Ori Kam, Bruce Richardson,
	Radu Nicolau, Akhil Goyal, Tomasz Kantecki, Sunil Kumar Kori,
	Pavan Nikhilesh, John McNamara
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Current l2fwd-event application statically configures adjacent ports as
destination ports for forwarding the traffic.

Add a config option to pass the forwarding port pair mapping which allows
the user to configure forwarding port mapping.

If no config argument is specified, destination port map is not
changed and traffic gets forwarded with existing mapping.

To align port/queue configuration of each lcore with destination port
map, port/queue configuration of each lcore gets modified when config
option is specificed.

Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"

With above config option, traffic received from portid = 0 gets forwarded
to port = 3 and vice versa, similarly traffic gets forwarded on other port
pairs (1,4) and (2,5).

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 v3 Changes:
  - Use simple memcpy instead of snprintf. (Andrzej)
  - Skip redudant loop iterations. (Andrzej)
  - Use RTE_MAX_ETHPORTS instead of hardcoding to 255. (Andrzej)

 v2 Changes:
  - Fix minor formatting error.
  - Change uint8_t to bool.

 doc/guides/sample_app_ug/l2_forward_event.rst |   2 +
 examples/l2fwd-event/l2fwd_common.h           |   1 +
 examples/l2fwd-event/main.c                   | 183 +++++++++++++++---
 3 files changed, 161 insertions(+), 25 deletions(-)

diff --git a/doc/guides/sample_app_ug/l2_forward_event.rst b/doc/guides/sample_app_ug/l2_forward_event.rst
index 8c519c304..8bdf352c4 100644
--- a/doc/guides/sample_app_ug/l2_forward_event.rst
+++ b/doc/guides/sample_app_ug/l2_forward_event.rst
@@ -66,6 +66,8 @@ where,

 *   --eventq-sched=SCHED_MODE: Event queue schedule mode, Ordered, Atomic or Parallel. Atomic by default.

+*   --config: Configure forwarding port pair mapping. Alternate port pairs by default.
+
 Sample usage commands are given below to run the application into different mode:

 Poll mode with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address updating enabled,
diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h
index 7e33ee749..939221d45 100644
--- a/examples/l2fwd-event/l2fwd_common.h
+++ b/examples/l2fwd-event/l2fwd_common.h
@@ -69,6 +69,7 @@ struct l2fwd_resources {
 	uint8_t sched_type;
 	uint8_t mac_updating;
 	uint8_t rx_queue_per_lcore;
+	bool port_pairs;
 	uint16_t nb_rxd;
 	uint16_t nb_txd;
 	uint32_t enabled_port_mask;
diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c
index 89a6bb9a4..9cc29d732 100644
--- a/examples/l2fwd-event/main.c
+++ b/examples/l2fwd-event/main.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2019 Marvell International Ltd.
  */

+#include <rte_string_fns.h>
+
 #include "l2fwd_event.h"
 #include "l2fwd_poll.h"

@@ -22,7 +24,9 @@ l2fwd_event_usage(const char *prgname)
 	       "          Default mode = eventdev\n"
 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n"
 	       "                  Default: atomic\n"
-	       "                  Valid only if --mode=eventdev\n\n",
+	       "                  Valid only if --mode=eventdev\n"
+	       "  --config: Configure forwarding port pair mapping\n"
+	       "	    Default: alternate port pairs\n\n",
 	       prgname);
 }

@@ -99,6 +103,70 @@ l2fwd_event_parse_eventq_sched(const char *optarg,
 		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
 }

+static int
+l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
+{
+	enum fieldnames {
+		FLD_PORT1 = 0,
+		FLD_PORT2,
+		_NUM_FLD
+	};
+	const char *p, *p0 = q_arg;
+	uint16_t int_fld[_NUM_FLD];
+	char *str_fld[_NUM_FLD];
+	uint16_t port_pair = 0;
+	unsigned int size;
+	char s[256];
+	char *end;
+	int i;
+
+	while ((p = strchr(p0, '(')) != NULL) {
+		++p;
+		p0 = strchr(p, ')');
+		if (p0 == NULL)
+			return -1;
+
+		size = p0 - p;
+		if (size >= sizeof(s))
+			return -1;
+
+		memcpy(s, p, size);
+		if (rte_strsplit(s, sizeof(s), str_fld,
+					_NUM_FLD, ',') != _NUM_FLD)
+			return -1;
+
+		for (i = 0; i < _NUM_FLD; i++) {
+			errno = 0;
+			int_fld[i] = strtoul(str_fld[i], &end, 0);
+			if (errno != 0 || end == str_fld[i] ||
+			    int_fld[i] >= RTE_MAX_ETHPORTS)
+				return -1;
+		}
+
+		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
+			printf("exceeded max number of port pair params: Current %d Max = %d\n",
+			       port_pair, RTE_MAX_ETHPORTS / 2);
+			return -1;
+		}
+
+		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
+			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
+			printf("Duplicate port pair (%d,%d) config\n",
+					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
+			return -1;
+		}
+
+		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
+		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
+
+		port_pair++;
+	}
+
+	rsrc->port_pairs = true;
+
+	return 0;
+}
+
 static const char short_options[] =
 	"p:"  /* portmask */
 	"q:"  /* number of queues */
@@ -109,6 +177,7 @@ static const char short_options[] =
 #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
 #define CMD_LINE_OPT_MODE "mode"
 #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched"
+#define CMD_LINE_OPT_PORT_PAIR_CONF "config"

 enum {
 	/* long options mapped to a short option */
@@ -119,12 +188,12 @@ enum {
 	CMD_LINE_OPT_MIN_NUM = 256,
 	CMD_LINE_OPT_MODE_NUM,
 	CMD_LINE_OPT_EVENTQ_SCHED_NUM,
+	CMD_LINE_OPT_PORT_PAIR_CONF_NUM,
 };

 /* Parse the argument given in the command line of the application */
 static int
-l2fwd_event_parse_args(int argc, char **argv,
-		struct l2fwd_resources *rsrc)
+l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc)
 {
 	int mac_updating = 1;
 	struct option lgopts[] = {
@@ -134,12 +203,19 @@ l2fwd_event_parse_args(int argc, char **argv,
 							CMD_LINE_OPT_MODE_NUM},
 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
 						CMD_LINE_OPT_EVENTQ_SCHED_NUM},
+		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL,
+					CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
 		{NULL, 0, 0, 0}
 	};
 	int opt, ret, timer_secs;
 	char *prgname = argv[0];
-	char **argvopt;
+	uint16_t port_id;
 	int option_index;
+	char **argvopt;
+
+	/* reset l2fwd_dst_ports */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		rsrc->dst_ports[port_id] = UINT32_MAX;

 	argvopt = argv;
 	while ((opt = getopt_long(argc, argvopt, short_options,
@@ -189,6 +265,15 @@ l2fwd_event_parse_args(int argc, char **argv,
 			l2fwd_event_parse_eventq_sched(optarg, rsrc);
 			break;

+		case CMD_LINE_OPT_PORT_PAIR_CONF_NUM:
+			ret = l2fwd_parse_port_pair_config(optarg, rsrc);
+			if (ret) {
+				printf("Invalid port pair config\n");
+				l2fwd_event_usage(prgname);
+				return -1;
+			}
+			break;
+
 		/* long options */
 		case 0:
 			break;
@@ -209,6 +294,52 @@ l2fwd_event_parse_args(int argc, char **argv,
 	return ret;
 }

+/*
+ * Check port pair config with enabled port mask,
+ * and for valid port pair combinations.
+ */
+static int
+check_port_pair_config(struct l2fwd_resources *rsrc)
+{
+	uint32_t port_pair_mask = 0;
+	uint32_t portid;
+	uint16_t index;
+
+	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
+		if ((rsrc->enabled_port_mask & (1 << index)) == 0 ||
+		    (port_pair_mask & (1 << index)))
+			continue;
+
+		portid = rsrc->dst_ports[index];
+		if (portid == UINT32_MAX) {
+			printf("port %u is enabled in but no valid port pair\n",
+			       index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(index)) {
+			printf("port %u is not valid\n", index);
+			return -1;
+		}
+
+		if (!rte_eth_dev_is_valid_port(portid)) {
+			printf("port %u is not valid\n", portid);
+			return -1;
+		}
+
+		if (port_pair_mask & (1 << portid) &&
+				rsrc->dst_ports[portid] != index) {
+			printf("port %u is used in other port pairs\n", portid);
+			return -1;
+		}
+
+		port_pair_mask |= (1 << portid);
+		port_pair_mask |= (1 << index);
+	}
+
+	return 0;
+}
+
 static int
 l2fwd_launch_one_lcore(void *args)
 {
@@ -465,31 +596,33 @@ main(int argc, char **argv)
 		rte_panic("Invalid portmask; possible (0x%x)\n",
 			(1 << nb_ports) - 1);

-	/* reset l2fwd_dst_ports */
-	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
-		rsrc->dst_ports[port_id] = 0;
-	last_port = 0;
+	if (!rsrc->port_pairs) {
+		last_port = 0;
+		/*
+		 * Each logical core is assigned a dedicated TX queue on each
+		 * port.
+		 */
+		RTE_ETH_FOREACH_DEV(port_id) {
+			/* skip ports that are not enabled */
+			if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
+				continue;

-	/*
-	 * Each logical core is assigned a dedicated TX queue on each port.
-	 */
-	RTE_ETH_FOREACH_DEV(port_id) {
-		/* skip ports that are not enabled */
-		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
-			continue;
+			if (nb_ports_in_mask % 2) {
+				rsrc->dst_ports[port_id] = last_port;
+				rsrc->dst_ports[last_port] = port_id;
+			} else {
+				last_port = port_id;
+			}

+			nb_ports_in_mask++;
+		}
 		if (nb_ports_in_mask % 2) {
-			rsrc->dst_ports[port_id] = last_port;
-			rsrc->dst_ports[last_port] = port_id;
-		} else {
-			last_port = port_id;
+			printf("Notice: odd number of ports in portmask.\n");
+			rsrc->dst_ports[last_port] = last_port;
 		}
-
-		nb_ports_in_mask++;
-	}
-	if (nb_ports_in_mask % 2) {
-		printf("Notice: odd number of ports in portmask.\n");
-		rsrc->dst_ports[last_port] = last_port;
+	} else {
+		if (check_port_pair_config(rsrc) < 0)
+			rte_panic("Invalid port pair config\n");
 	}

 	nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT +
--
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v3] examples/l2fwd-event: add option to configure port pairs
  2020-03-31 12:53     ` [dpdk-dev] [PATCH v3] " pbhagavatula
@ 2020-03-31 17:07       ` Andrzej Ostruszka
  2020-04-04 16:10         ` Jerin Jacob
  0 siblings, 1 reply; 10+ messages in thread
From: Andrzej Ostruszka @ 2020-03-31 17:07 UTC (permalink / raw)
  To: dev

On 3/31/20 2:53 PM, pbhagavatula@marvell.com wrote:
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> 
> Current l2fwd-event application statically configures adjacent ports as
> destination ports for forwarding the traffic.
> 
> Add a config option to pass the forwarding port pair mapping which allows
> the user to configure forwarding port mapping.
> 
> If no config argument is specified, destination port map is not
> changed and traffic gets forwarded with existing mapping.
> 
> To align port/queue configuration of each lcore with destination port
> map, port/queue configuration of each lcore gets modified when config
> option is specificed.
> 
> Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"
> 
> With above config option, traffic received from portid = 0 gets forwarded
> to port = 3 and vice versa, similarly traffic gets forwarded on other port
> pairs (1,4) and (2,5).
> 
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
>  v3 Changes:
>   - Use simple memcpy instead of snprintf. (Andrzej)
>   - Skip redudant loop iterations. (Andrzej)
>   - Use RTE_MAX_ETHPORTS instead of hardcoding to 255. (Andrzej)
> 
>  v2 Changes:
>   - Fix minor formatting error.
>   - Change uint8_t to bool.

Reviewed-by: Andrzej Ostruszka <aostruszka@marvell.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v3] examples/l2fwd-event: add option to configure port pairs
  2020-03-31 17:07       ` Andrzej Ostruszka
@ 2020-04-04 16:10         ` Jerin Jacob
  0 siblings, 0 replies; 10+ messages in thread
From: Jerin Jacob @ 2020-04-04 16:10 UTC (permalink / raw)
  To: Andrzej Ostruszka; +Cc: dpdk-dev

On Tue, Mar 31, 2020 at 10:37 PM Andrzej Ostruszka <amo@semihalf.com> wrote:
>
> On 3/31/20 2:53 PM, pbhagavatula@marvell.com wrote:
> > From: Pavan Nikhilesh <pbhagavatula@marvell.com>
> >
> > Current l2fwd-event application statically configures adjacent ports as
> > destination ports for forwarding the traffic.
> >
> > Add a config option to pass the forwarding port pair mapping which allows
> > the user to configure forwarding port mapping.
> >
> > If no config argument is specified, destination port map is not
> > changed and traffic gets forwarded with existing mapping.
> >
> > To align port/queue configuration of each lcore with destination port
> > map, port/queue configuration of each lcore gets modified when config
> > option is specificed.
> >
> > Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)"
> >
> > With above config option, traffic received from portid = 0 gets forwarded
> > to port = 3 and vice versa, similarly traffic gets forwarded on other port
> > pairs (1,4) and (2,5).
> >
> > Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> > ---
> >  v3 Changes:
> >   - Use simple memcpy instead of snprintf. (Andrzej)
> >   - Skip redudant loop iterations. (Andrzej)
> >   - Use RTE_MAX_ETHPORTS instead of hardcoding to 255. (Andrzej)
> >
> >  v2 Changes:
> >   - Fix minor formatting error.
> >   - Change uint8_t to bool.
>
> Reviewed-by: Andrzej Ostruszka <aostruszka@marvell.com>

Applied to dpdk-next-eventdev/master. Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-04-04 16:10 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-24 12:34 [dpdk-dev] [PATCH] example/l2fwd-event: add option to configure forwarding info pbhagavatula
2020-03-24 12:34 ` [dpdk-dev] [PATCH] examples/l2fwd-event: add option to configure port pairs pbhagavatula
2020-03-25 10:40   ` Sunil Kumar Kori
2020-03-26  6:37     ` Pavan Nikhilesh Bhagavatula
2020-03-26  6:42   ` [dpdk-dev] [dpdk-dev v2] " pbhagavatula
2020-03-31 10:23     ` Andrzej Ostruszka
2020-03-31 12:17       ` Pavan Nikhilesh Bhagavatula
2020-03-31 12:53     ` [dpdk-dev] [PATCH v3] " pbhagavatula
2020-03-31 17:07       ` Andrzej Ostruszka
2020-04-04 16:10         ` Jerin Jacob

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).