DPDK patches and discussions
 help / color / mirror / Atom feed
From: Fan Zhang <roy.fan.zhang@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v3 2/4] example/ip_pipeline: add PCAP file support
Date: Wed,  9 Mar 2016 16:07:30 +0000	[thread overview]
Message-ID: <1457539652-17337-3-git-send-email-roy.fan.zhang@intel.com> (raw)
In-Reply-To: <1457539652-17337-1-git-send-email-roy.fan.zhang@intel.com>

This patch add PCAP file support to ip_pipeline. Input port type SOURCE
now supports loading specific PCAP file and sends the packets in it to
pipeline instance. The packets are then released by SINK output port. This
feature can be applied by specifying parameters in configuration file as
shown below;

[PIPELINE1]
type = PASS-THROUGH
core = 1
pktq_in = SOURCE0 SOURCE1
pktq_out = SINK0 SINK1
pcap_file_rd = /path/to/eth1.PCAP /path/to/eth2.PCAP
pcap_bytes_rd_per_pkt = 0 64

The configuration section "pcap_file_rd" contains full path and name of
the PCAP file to be loaded. If multiple SOURCEs exists, each shall have
its own PCAP file path listed in this section, separated by spaces.
Multiple SOURCE ports may share same PCAP file to be copied.

The configuration section "pcap_bytes_rd_per_pkt" contains integer value
and indicates the maximum number of bytes to be copied from each packet
in the PCAP file. If this value is "0", all packets in the file will be
copied fully; if the packet size is smaller than the assigned value, the
entire packet is copied. Same as "pcap_file_rd", every SOURCE shall have
its own maximum copy byte number.

To enable PCAP support to IP pipeline, the compiler option
CONFIG_RTE_PORT_PCAP must be set to 'y'. It is possible to disable PCAP
support by removing "pcap_file_rd" and "pcap_bytes_rd_per_pkt" lines
from the configuration file.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/app.h          |   4 +-
 examples/ip_pipeline/config_parse.c | 119 +++++++++++++++++++++++++++++++++++-
 examples/ip_pipeline/init.c         |  17 +++++-
 3 files changed, 137 insertions(+), 3 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index f55aef8..0c22f7f 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -149,6 +149,8 @@ struct app_pktq_source_params {
 	uint32_t parsed;
 	uint32_t mempool_id; /* Position in the app->mempool_params array */
 	uint32_t burst;
+	char *file_name; /* Full path of PCAP file to be copied to mbufs */
+	uint32_t n_bytes_per_pkt;
 };
 
 struct app_pktq_sink_params {
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 4695ac1..291dbfb 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -181,6 +181,8 @@ struct app_pktq_source_params default_source_params = {
 	.parsed = 0,
 	.mempool_id = 0,
 	.burst = 32,
+	.file_name = NULL,
+	.n_bytes_per_pkt = 0,
 };
 
 struct app_pktq_sink_params default_sink_params = {
@@ -955,6 +957,85 @@ parse_eal(struct app_params *app,
 }
 
 static int
+parse_pipeline_pcap_source(struct app_params *app,
+	struct app_pipeline_params *p,
+	const char *file_name, const char *cp_size)
+{
+	const char *next = NULL;
+	char *end;
+	uint32_t i;
+	int parse_file = 0;
+
+	if (file_name && !cp_size) {
+		next = file_name;
+		parse_file = 1; /* parse file path */
+	} else if (cp_size && !file_name) {
+		next = cp_size;
+		parse_file = 0; /* parse copy size */
+	} else
+		return -EINVAL;
+
+	char name[APP_PARAM_NAME_SIZE];
+	size_t name_len;
+
+	if (p->n_pktq_in == 0)
+		return -EINVAL;
+
+	for (i = 0; i < p->n_pktq_in; i++) {
+		if (p->pktq_in[i].type != APP_PKTQ_IN_SOURCE)
+			return -EINVAL;
+	}
+
+	i = 0;
+	while (*next != '\0') {
+		uint32_t id;
+
+		if (i >= p->n_pktq_in)
+			return -EINVAL;
+
+		id = p->pktq_in[i].id;
+
+		end = strchr(next, ' ');
+		if (!end)
+			name_len = strlen(next);
+		else
+			name_len = end - next;
+
+		if (name_len == 0 || name_len == sizeof(name))
+			return -EINVAL;
+
+		strncpy(name, next, name_len);
+		name[name_len] = '\0';
+		next += name_len;
+		if (*next != '\0')
+			next++;
+
+		if (parse_file) {
+			app->source_params[id].file_name = strdup(name);
+			if (app->source_params[id].file_name == NULL)
+				return -ENOMEM;
+		} else {
+			if (parser_read_uint32(
+				&app->source_params[id].n_bytes_per_pkt,
+				name) != 0) {
+				if (app->source_params[id].
+					file_name != NULL)
+					free(app->source_params[id].
+						file_name);
+				return -EINVAL;
+			}
+		}
+
+		i++;
+
+		if (i == p->n_pktq_in)
+			return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int
 parse_pipeline_pktq_in(struct app_params *app,
 	struct app_pipeline_params *p,
 	const char *value)
@@ -1309,6 +1390,24 @@ parse_pipeline(struct app_params *app,
 			continue;
 		}
 
+		if (strcmp(ent->name, "pcap_file_rd") == 0) {
+			int status = parse_pipeline_pcap_source(app,
+				param, ent->value, NULL);
+
+			PARSE_ERROR((status == 0), section_name,
+				ent->name);
+			continue;
+		}
+
+		if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) {
+			int status = parse_pipeline_pcap_source(app,
+				param, NULL, ent->value);
+
+			PARSE_ERROR((status == 0), section_name,
+				ent->name);
+			continue;
+		}
+
 		/* pipeline type specific items */
 		APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
 			"Parse error in section \"%s\": too many "
@@ -2000,6 +2099,21 @@ parse_source(struct app_params *app,
 			continue;
 		}
 
+		if (strcmp(ent->name, "pcap_file_rd")) {
+			param->file_name = strdup(ent->value);
+
+			PARSE_ERROR_MALLOC(param->file_name != NULL);
+			continue;
+		}
+
+		if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) {
+			int status = parser_read_uint32(
+				&param->n_bytes_per_pkt, ent->value);
+
+			PARSE_ERROR((status == 0), section_name,
+				ent->name);
+		}
+
 		/* unrecognized */
 		PARSE_ERROR_INVALID(0, section_name, ent->name);
 	}
@@ -2604,6 +2718,9 @@ save_source_params(struct app_params *app, FILE *f)
 			"mempool",
 			app->mempool_params[p->mempool_id].name);
 		fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
+		fprintf(f, "%s = %s\n", "pcap_file_rd", p->file_name);
+		fprintf(f, "%s = %" PRIu32 "\n", "pcap_bytes_rd_per_pkt",
+			p->n_bytes_per_pkt);
 		fputc('\n', f);
 	}
 }
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 2d9fae4..ad5afd2 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -1221,6 +1221,21 @@ static void app_pipeline_params_get(struct app_params *app,
 			out->type = PIPELINE_PORT_IN_SOURCE;
 			out->params.source.mempool = app->mempool[mempool_id];
 			out->burst_size = app->source_params[in->id].burst;
+
+			if (app->source_params[in->id].file_name
+				!= NULL) {
+				out->params.source.file_name = strdup(
+					app->source_params[in->id].
+					file_name);
+				if (out->params.source.file_name == NULL) {
+					out->params.source.
+						n_bytes_per_pkt = 0;
+					break;
+				}
+				out->params.source.n_bytes_per_pkt =
+					app->source_params[in->id].
+					n_bytes_per_pkt;
+			}
 			break;
 		default:
 			break;
-- 
2.5.0

  parent reply	other threads:[~2016-03-09 16:08 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-17 11:11 [dpdk-dev] [PATCH v2 0/4] Add PCAP support to source and sink port Fan Zhang
2016-02-17 11:11 ` [dpdk-dev] [PATCH v2 1/4] lib/librte_port: add PCAP file support to source port Fan Zhang
2016-03-07 11:17   ` Thomas Monjalon
2016-03-08  8:36     ` Dumitrescu, Cristian
2016-03-08  9:06       ` Panu Matilainen
2016-03-08 10:14       ` Thomas Monjalon
2016-02-17 11:11 ` [dpdk-dev] [PATCH v2 2/4] example/ip_pipeline: add PCAP file support Fan Zhang
2016-02-17 11:11 ` [dpdk-dev] [PATCH v2 3/4] lib/librte_port: add packet dumping to PCAP file support in sink port Fan Zhang
2016-02-17 11:11 ` [dpdk-dev] [PATCH v2 4/4] examples/ip_pipeline: add packets dumping to PCAP file support Fan Zhang
2016-03-09 16:07 ` [dpdk-dev] [PATCH v3 0/4] Add PCAP support to source and sink port Fan Zhang
2016-03-09 16:07   ` [dpdk-dev] [PATCH v3 1/4] lib/librte_port: add PCAP file support to source port Fan Zhang
2016-03-09 16:07   ` Fan Zhang [this message]
2016-03-11 11:10     ` [dpdk-dev] [PATCH v3 2/4] example/ip_pipeline: add PCAP file support Thomas Monjalon
2016-03-25 12:00       ` Zhang, Roy Fan
2016-03-09 16:07   ` [dpdk-dev] [PATCH v3 3/4] lib/librte_port: add packet dumping to PCAP file support in sink port Fan Zhang
2016-03-09 16:07   ` [dpdk-dev] [PATCH v3 4/4] examples/ip_pipeline: add packets dumping to PCAP file support Fan Zhang
2016-03-11 17:08   ` [dpdk-dev] [PATCH v4 0/4] Add PCAP support to source and sink port Fan Zhang
2016-03-11 17:08     ` [dpdk-dev] [PATCH v4 1/4] lib/librte_port: add PCAP file support to source port Fan Zhang
2016-03-11 17:08     ` [dpdk-dev] [PATCH v4 2/4] example/ip_pipeline: add PCAP file support Fan Zhang
2016-03-11 17:08     ` [dpdk-dev] [PATCH v4 3/4] lib/librte_port: add packet dumping to PCAP file support in sink port Fan Zhang
2016-03-11 17:08     ` [dpdk-dev] [PATCH v4 4/4] examples/ip_pipeline: add packets dumping to PCAP file support Fan Zhang

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=1457539652-17337-3-git-send-email-roy.fan.zhang@intel.com \
    --to=roy.fan.zhang@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

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

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