[dpdk-dev] [PATCH 2/5] [pktgen] different PCAP per each queue

Rafal Kozik rk at semihalf.com
Thu Jan 10 17:14:03 CET 2019


In some test scenario it is necessary to configure different flow per each
Tx queue. This patch adds possibility to provide list of PCAPs files.

If number of files is smaller than number of queues, first PCAP file
is used for the queues which number is above the number of files.
To achieve uniform throughput, average length of packets in each PCAP
needs to be the same.

Signed-off-by: Rafal Kozik <rk at semihalf.com>
---
 app/pktgen-main.c     | 40 ++++++++++++++++++++++++++++++----------
 app/pktgen-pcap.c     | 12 ++++++------
 app/pktgen-port-cfg.c |  8 +++++++-
 app/pktgen-port-cfg.h |  1 +
 4 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/app/pktgen-main.c b/app/pktgen-main.c
index b90da0c..68ffa13 100644
--- a/app/pktgen-main.c
+++ b/app/pktgen-main.c
@@ -81,6 +81,7 @@ pktgen_usage(const char *prgname)
 	printf(
 		"Usage: %s [EAL options] -- [-h] [-v] [-P] [-G] [-T] [-f cmd_file] [-l log_file] [-s P:PCAP_file] [-m <string>]\n"
 		"  -s P:file    PCAP packet stream file, 'P' is the port number\n"
+		"  -s P:file0,file1,... list of PCAP packet stream files per queue, 'P' is the port number\n"
 		"  -f filename  Command file (.pkt) to execute or a Lua script (.lua) file\n"
 		"  -l filename  Write log to filename\n"
 		"  -P           Enable PROMISCUOUS mode on all ports\n"
@@ -142,10 +143,10 @@ pktgen_usage(const char *prgname)
 static int
 pktgen_parse_args(int argc, char **argv)
 {
-	int opt, ret, port;
+	int opt, ret, port, q;
 	char **argvopt;
 	int option_index;
-	char *prgname = argv[0], *p;
+	char *prgname = argv[0], *p, *pc;
 	static struct option lgopts[] = {
 		{"crc-strip", 0, 0, 0},
 		{NULL, 0, 0, 0}
@@ -187,14 +188,27 @@ pktgen_parse_args(int argc, char **argv)
 		case 's':	/* Read a PCAP packet capture file (stream) */
 			port = strtol(optarg, NULL, 10);
 			p = strchr(optarg, ':');
-			if ( (p == NULL) ||
-			     (pktgen.info[port].pcap =
-				      _pcap_open(++p, port)) == NULL) {
-				pktgen_log_error(
-					"Invalid PCAP filename (%s) must include port number as P:filename",
-					optarg);
-				pktgen_usage(prgname);
-				return -1;
+			pc = strchr(optarg, ',');
+			if (p == NULL)
+				goto pcap_err;
+			if (pc == NULL) {
+				pktgen.info[port].pcap = _pcap_open(++p, port);
+				if (pktgen.info[port].pcap == NULL)
+					goto pcap_err;
+			} else {
+				q = 0;
+				while (p != NULL && q < NUM_Q) {
+					p++;
+					pc = strchr(p, ',');
+					if (pc != NULL)
+						*pc = '\0';
+					pktgen.info[port].pcaps[q] = _pcap_open(p, port);
+					if (pktgen.info[port].pcaps[q] == NULL)
+						goto pcap_err;
+					p = pc;
+					q++;
+				}
+				pktgen.info[port].pcap = pktgen.info[port].pcaps[0];
 			}
 			break;
 		case 'P':	/* Enable promiscuous mode on the ports */
@@ -257,6 +271,12 @@ pktgen_parse_args(int argc, char **argv)
 	ret = optind - 1;
 	optind = 1;	/* reset getopt lib */
 	return ret;
+
+pcap_err:
+	pktgen_log_error("Invalid PCAP filename (%s) must include port number as P:filename",
+			 optarg);
+	pktgen_usage(prgname);
+	return -1;
 }
 
 #define MAX_BACKTRACE	32
diff --git a/app/pktgen-pcap.c b/app/pktgen-pcap.c
index dffdd13..e7ef9a2 100644
--- a/app/pktgen-pcap.c
+++ b/app/pktgen-pcap.c
@@ -343,9 +343,9 @@ pktgen_pcap_parse(pcap_info_t *pcap, port_info_t *info, unsigned qid)
 	/* If count is greater then zero then we allocate and create the PCAP mbuf pool. */
 	if (elt_count > 0) {
 		/* Create the average size packet */
-		info->pcap->pkt_size    = (pkt_sizes / elt_count);
-		info->pcap->pkt_count   = elt_count;
-		info->pcap->pkt_idx     = 0;
+		pcap->pkt_size    = (pkt_sizes / elt_count);
+		pcap->pkt_count   = elt_count;
+		pcap->pkt_idx     = 0;
 
 		_pcap_rewind(pcap);
 
@@ -374,15 +374,15 @@ pktgen_pcap_parse(pcap_info_t *pcap, port_info_t *info, unsigned qid)
 		scrn_printf(0, 0, "\r");
 		if (info->q[qid].pcap_mp == NULL)
 			pktgen_log_panic("Cannot init port %d for %d PCAP packets",
-					 info->pid, info->pcap->pkt_count);
+					 info->pid, pcap->pkt_count);
 
-		data_size = (info->pcap->pkt_count * DEFAULT_MBUF_SIZE);
+		data_size = (pcap->pkt_count * DEFAULT_MBUF_SIZE);
 		scrn_printf(0, 0,
 		        "    Create: %-*s - Number of MBUFs %6u for %5d packets                 = %6u KB\n",
 		        16,
 		        name,
 		        elt_count,
-		        info->pcap->pkt_count,
+		        pcap->pkt_count,
 		        (data_size + 1023) / 1024);
 		pktgen.mem_used         += data_size;
 		pktgen.total_mem_used   += data_size;
diff --git a/app/pktgen-port-cfg.c b/app/pktgen-port-cfg.c
index a1da13c..91ce694 100644
--- a/app/pktgen-port-cfg.c
+++ b/app/pktgen-port-cfg.c
@@ -318,7 +318,13 @@ pktgen_config_ports(void)
 				pktgen_log_panic("Cannot init port %d for Special TX mbufs", pid);
 
 			/* Setup the PCAP file for each port */
-			if (pktgen.info[pid].pcap != NULL)
+			if (pktgen.info[pid].pcaps[q] != NULL) {
+				if (pktgen_pcap_parse(pktgen.info[pid].pcaps[q], info, q) == -1) {
+					pktgen_log_panic(
+						"Cannot load PCAP file for port %d queue %d",
+						pid, q);
+				}
+			} else if (pktgen.info[pid].pcap != NULL)
 				if (pktgen_pcap_parse(pktgen.info[pid].pcap, info, q) == -1)
 					pktgen_log_panic("Cannot load PCAP file for port %d", pid);
 
diff --git a/app/pktgen-port-cfg.h b/app/pktgen-port-cfg.h
index 89019e4..381ddfe 100644
--- a/app/pktgen-port-cfg.h
+++ b/app/pktgen-port-cfg.h
@@ -214,6 +214,7 @@ typedef struct port_info_s {
 	int32_t rx_tapfd;	/**< Rx Tap file descriptor */
 	int32_t tx_tapfd;	/**< Tx Tap file descriptor */
 	pcap_info_t *pcap;	/**< PCAP information header */
+	pcap_info_t *pcaps[NUM_Q];	/**< Per Tx queue PCAP information headers */
 	uint64_t pcap_cycles;	/**< number of cycles for pcap sending */
 
 	int32_t pcap_result;	/**< PCAP result of filter compile */
-- 
2.7.4



More information about the dev mailing list