All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ronan Randles <ronan.randles@intel.com>
To: dev@dpdk.org
Cc: Harry van Haaren <harry.van.haaren@intel.com>,
	Ronan Randles <ronan.randles@intel.com>
Subject: [PATCH v2 07/15] gen: add gen IP parsing
Date: Fri, 21 Jan 2022 10:31:14 +0000	[thread overview]
Message-ID: <20220121103122.2926856-8-ronan.randles@intel.com> (raw)
In-Reply-To: <20220121103122.2926856-1-ronan.randles@intel.com>

From: Harry van Haaren <harry.van.haaren@intel.com>

This commit adds support for the parsing of "IP(src=...,dst=...)"
strings. Parse string API improvement for app RCU.
Appropriate unit tests also added.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
Signed-off-by: Ronan Randles <ronan.randles@intel.com>
---
 app/test/test_gen.c |  29 +++++++--
 lib/gen/rte_gen.c   | 153 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 177 insertions(+), 5 deletions(-)

diff --git a/app/test/test_gen.c b/app/test/test_gen.c
index 324582d0a5..7b67835c80 100644
--- a/app/test/test_gen.c
+++ b/app/test/test_gen.c
@@ -117,26 +117,47 @@ test_gen_packet_parse_string(void)
 {
 	struct rte_gen *gen = rte_gen_create(mp);
 	TEST_ASSERT_FAIL(gen, "Expected valid pointer after create()");
-
 	struct str_parse_t {
 		const char *str;
+		uint32_t expected_to_fail;
 	} pkt_strings[] = {
 		{ .str = "Ether()"},
 		{ .str = "Ether()/"},
 		{ .str = "/Ether()"},
-		{ .str = "/Ether()/"}
+		{ .str = "/Ether()/"},
+		{ .str = "Ether()/IP()"},
+		{ .str = "Ether()/IP(src=1.2.3.4,dst=5.6.7.8)"},
+		{ .str = "Ether()/IP(src=1.2.3.4,dst=192.168.255.255)"},
+		{ .str = "Ether()/IP(dst=172.16.0.9,src=1.2.3.4)"},
+		{ .str = "Ether()/IP(src=1.2.3.4)"},
+		{ .str = "Ether()/IP(srdst=5.6.7.8)", .expected_to_fail = 1},
+		{ .str = "Ether()/IP(src=1.2.3.4,ds=)", .expected_to_fail = 1},
+		{ .str = "Ether()/IP(src=1.2.3.4,dst=)", .expected_to_fail = 1},
+		{ .str = "Ether()/IP(src=,dst=5.6.7.8)", .expected_to_fail = 1},
+		{ .str = "Ether()/IP(sr=,dst=5.6.7.8)", .expected_to_fail = 1},
+		{ .str = "Ether()/IP(src=1.2.3.fail,dst=5.6.7.8)",
+					.expected_to_fail = 1},
 	};
 
 	uint32_t i;
 	for (i = 0; i < RTE_DIM(pkt_strings); i++) {
 		const char *pkt_str = pkt_strings[i].str;
 		int32_t err = rte_gen_packet_parse_string(gen, pkt_str, NULL);
-		TEST_ASSERT_EQUAL(err, 0, "Expected string %s to parse.",
-				pkt_str);
+
+		if (err && pkt_strings[i].expected_to_fail != 1) {
+			printf("Expected string %s to parse.", pkt_str);
+			return -1;
+		}
+		/* False pass if reached with no err when e_t_f = 1 */
+		if (!err && pkt_strings[i].expected_to_fail) {
+			printf("False Pass on string: %s\n", pkt_str);
+			return -1;
+		}
 	}
 
 	rte_gen_destroy(gen);
 	return 0;
+
 }
 
 
diff --git a/lib/gen/rte_gen.c b/lib/gen/rte_gen.c
index 4d3fe4017f..4020150712 100644
--- a/lib/gen/rte_gen.c
+++ b/lib/gen/rte_gen.c
@@ -10,6 +10,7 @@
 #include <rte_log.h>
 
 #include <rte_ether.h>
+#include <rte_ip.h>
 
 RTE_LOG_REGISTER(gen_logtype, lib.gen, NOTICE);
 
@@ -136,6 +137,7 @@ rte_gen_tx_burst(struct rte_gen *gen,
 enum GEN_PROTO {
 	GEN_PROTO_INVALID,
 	GEN_PROTO_ETHER,
+	GEN_PROTO_IPV4,
 
 	/* Must be last. */
 	GEN_PROTO_COUNT,
@@ -219,6 +221,145 @@ gen_parser_init(struct gen_parser *parser, struct rte_gen *gen,
 	return -ENOMEM;
 }
 
+static void
+gen_log_ipv4(void *data, const char *indent)
+{
+	struct rte_ipv4_hdr *ip = data;
+
+	const char *proto_str;
+	switch (ip->next_proto_id) {
+	case 0:
+		proto_str = "hopopt";
+		break;
+	default:
+		proto_str = "unknown next proto";
+		break;
+	}
+
+	GEN_LOG_PROTOCOL(DEBUG,
+		"###[ IP ]###\n%sversion = %d\n%sihl = %d\n%stos = %d\n"
+		"%slen = %d\n%sid = %d\n%sflags = 0x%x\n%sfrag = %d\n"
+		"%sttl = %d\n%sproto = %s (%d)\n%schksum 0x%x\n%ssrc = 0x%x\n"
+		"%sdst = 0x%x\n%soptions = %s\n",
+		indent, ip->version_ihl >> 4,
+		indent, ip->version_ihl & RTE_IPV4_HDR_IHL_MASK,
+		indent, ip->type_of_service,
+		indent, rte_be_to_cpu_16(ip->total_length),
+		indent, rte_be_to_cpu_16(ip->packet_id), /* TODO: Scapy ID? */
+		indent, rte_be_to_cpu_16(ip->packet_id), /*TODO: Scapy Flags?*/
+		indent, rte_be_to_cpu_16(ip->fragment_offset),
+		indent, ip->time_to_live,
+		indent, proto_str, ip->next_proto_id,
+		indent, rte_be_to_cpu_16(ip->hdr_checksum),
+		indent, rte_be_to_cpu_32(ip->src_addr),
+		indent, rte_be_to_cpu_32(ip->dst_addr),
+		indent, "notImplemented");
+}
+
+static int32_t
+gen_parse_ipv4_params(char *protocol_str, struct rte_ipv4_hdr *ip)
+{
+	/* Strings to look for. */
+	static const char * const items[] = {
+		"src=",
+		"dst=",
+	};
+	const uint32_t num_items = RTE_DIM(items);
+
+	char *tok_ptr;
+	uint32_t err = 0;
+	uint32_t i;
+	for (i = 0; i < num_items; i++) {
+		/* Print input string into local buffer for processing. */
+		char buffer[1024];
+		int chars_printed = snprintf(buffer, 1024, "%s", protocol_str);
+		if (chars_printed >= 1024)
+			return -1;
+
+		/* Find substring (e.g. src=) if not found skip to next one. */
+		char *start = strstr(buffer, items[i]);
+		char check_previous[32];
+		if (start != NULL) {
+			snprintf(check_previous, 32, "%.1s", start - 1);
+			if (strcmp(&check_previous[0], "(") &&
+						strcmp(&check_previous[0], ","))
+				return -EINVAL;
+		}
+
+		if (!start) {
+			if (!strstr(buffer, ","))
+				continue;
+			else
+				return -EINVAL;
+		}
+		/* get from start of string till first , character. */
+		char *item = strtok_r(start, ",", &tok_ptr);
+
+		if (strcmp(item, items[i]) == 0)
+			return -EINVAL;
+		/* skip past the src= prefix. We know string is long enough as
+		 * otherwise strstr() wouldn't have matched it.
+		 */
+		item = &item[4];
+
+		if (strcmp(items[i], "src=") == 0) {
+			err = rte_ip_parse_addr(item, &ip->src_addr);
+			ip->src_addr = rte_cpu_to_be_32(ip->src_addr);
+		} else {
+			err = rte_ip_parse_addr(item, &ip->dst_addr);
+			ip->dst_addr = rte_cpu_to_be_32(ip->dst_addr);
+		}
+		if (err) {
+			GEN_LOG(ERR, "parser ip_parse_addr error %d\n", err);
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int32_t
+gen_parse_ipv4(struct gen_parser *parser, char *protocol_str)
+{
+	struct rte_ipv4_hdr *ip = gen_parser_get_data_ptr(parser);
+	uint32_t pre_ip_len = parser->buf_write_offset;
+	memset(ip, 0, sizeof(*ip));
+	ip->version_ihl = RTE_IPV4_VHL_DEF;
+	ip->time_to_live = 64;
+	ip->packet_id = rte_cpu_to_be_16(1);
+
+	/* default addrs */
+	ip->src_addr = rte_cpu_to_be_32(RTE_IPV4(127, 0, 0, 1));
+	ip->dst_addr = rte_cpu_to_be_32(RTE_IPV4(127, 0, 0, 1));
+
+	uint32_t err = 0;
+	if (strcmp("IP()", protocol_str))
+		err = gen_parse_ipv4_params(protocol_str, ip);
+
+	if (err) {
+		GEN_LOG(ERR, "parser parse ipv4 params error %d\n", err);
+		return err;
+	}
+	/* Move up write pointer in packet. */
+	parser->buf_write_offset += sizeof(*ip);
+
+	/* Move up write pointer in packet, recurse to next. */
+	enum GEN_PROTO inner;
+	err = gen_parser_parse_next(parser, &inner);
+	if (err) {
+		GEN_LOG(ERR, "parser parse next() error %d\n", err);
+		return err;
+	}
+
+	switch (inner) {
+	default:
+		/* Default protocol is hopopt (0). */
+		break;
+	};
+
+	ip->total_length = rte_cpu_to_be_16(parser->mbuf->pkt_len - pre_ip_len);
+	return 0;
+}
+
 static void
 gen_log_ether(void *data, const char *indent)
 {
@@ -279,6 +420,9 @@ gen_parse_ether(struct gen_parser *parser, char *protocol_str)
 	}
 
 	switch (inner) {
+	case GEN_PROTO_IPV4:
+		eth->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
+		break;
 	default:
 		eth->ether_type = rte_cpu_to_be_16(0x9000);
 		break;
@@ -304,7 +448,14 @@ static struct gen_parse_func_t gen_protocols[] = {
 		.proto = GEN_PROTO_ETHER,
 		.parse_func = gen_parse_ether,
 		.log_func = gen_log_ether,
-	}
+	},
+	{
+		.name = "IP(",
+		.proto = GEN_PROTO_IPV4,
+		.parse_func = gen_parse_ipv4,
+		.log_func = gen_log_ipv4,
+	},
+
 };
 
 /* Function to tokenize and parse each segment of a string.
-- 
2.25.1


  parent reply	other threads:[~2022-01-21 10:32 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-14 14:12 [PATCH 00/12] add packet generator library and example app Ronan Randles
2021-12-14 14:12 ` [PATCH 01/12] net: add string to IPv4 parse function Ronan Randles
2021-12-14 17:31   ` Morten Brørup
2021-12-15  9:27     ` Bruce Richardson
2021-12-15  9:35       ` Morten Brørup
2021-12-15 10:11         ` Bruce Richardson
2022-01-19 14:20   ` Thomas Monjalon
2021-12-14 14:12 ` [PATCH 02/12] net: add function to pretty print IPv4 Ronan Randles
2021-12-14 16:08   ` Stephen Hemminger
2021-12-14 17:42     ` Morten Brørup
2021-12-14 17:31   ` Morten Brørup
2021-12-15  1:06     ` Ananyev, Konstantin
2021-12-15  3:20       ` Stephen Hemminger
2021-12-15  7:23         ` Morten Brørup
2021-12-15 13:06           ` Ananyev, Konstantin
2022-01-19 14:24             ` Thomas Monjalon
2022-01-19 14:41               ` Van Haaren, Harry
2021-12-14 14:12 ` [PATCH 03/12] gen: add files for initial traffic generation library Ronan Randles
2021-12-14 14:12 ` [PATCH 04/12] gen: add basic Rx and Tx routines and tests Ronan Randles
2021-12-14 14:12 ` [PATCH 05/12] gen: add raw packet data API " Ronan Randles
2021-12-15 12:40   ` Jerin Jacob
2021-12-17 11:40     ` Van Haaren, Harry
2021-12-17 16:19       ` Thomas Monjalon
2021-12-20 10:21         ` Van Haaren, Harry
2022-01-19 14:56           ` Thomas Monjalon
2022-01-20 10:21             ` Van Haaren, Harry
2022-01-21 10:45               ` Van Haaren, Harry
2021-12-20 13:21       ` Jerin Jacob
2022-01-21 14:20         ` Xueming(Steven) Li
2021-12-14 14:12 ` [PATCH 06/12] gen: add parsing infrastructure and Ether protocol Ronan Randles
2021-12-14 14:12 ` [PATCH 07/12] gen: add gen IP parsing Ronan Randles
2021-12-14 14:12 ` [PATCH 08/12] examples/generator: import code from basicfwd.c Ronan Randles
2021-12-14 14:12 ` [PATCH 09/12] examples/generator: enable gen library for traffic gen Ronan Randles
2021-12-14 14:12 ` [PATCH 10/12] examples/generator: telemetry support Ronan Randles
2021-12-14 14:12 ` [PATCH 11/12] examples/generator: link status check added Ronan Randles
2021-12-14 14:12 ` [PATCH 12/12] examples/generator: line rate limiting Ronan Randles
2021-12-14 16:10   ` Stephen Hemminger
2021-12-14 14:57 ` [PATCH 00/12] add packet generator library and example app Bruce Richardson
2021-12-14 15:59   ` Randles, Ronan
2022-01-12 16:18   ` Morten Brørup
2021-12-15 12:31 ` Jerin Jacob
2021-12-15 14:07   ` Bruce Richardson
2022-01-21 10:31 ` [PATCH v2 00/15] " Ronan Randles
2022-01-21 10:31   ` [PATCH v2 01/15] net: add string to IPv4 parse function Ronan Randles
2022-01-21 10:31   ` [PATCH v2 02/15] net: add function to pretty print IPv4 Ronan Randles
2022-01-21 16:20     ` Stephen Hemminger
2022-01-21 10:31   ` [PATCH v2 03/15] gen: add files for initial traffic generation library Ronan Randles
2022-01-21 10:31   ` [PATCH v2 04/15] gen: add basic Rx and Tx routines and tests Ronan Randles
2022-01-21 10:31   ` [PATCH v2 05/15] gen: add raw packet data API " Ronan Randles
2022-01-21 10:31   ` [PATCH v2 06/15] gen: add parsing infrastructure and Ether protocol Ronan Randles
2022-01-21 10:31   ` Ronan Randles [this message]
2022-01-21 10:31   ` [PATCH v2 08/15] examples/generator: import code from basicfwd.c Ronan Randles
2022-01-21 10:31   ` [PATCH v2 09/15] examples/generator: enable gen library for traffic gen Ronan Randles
2022-01-21 10:31   ` [PATCH v2 10/15] examples/generator: telemetry support Ronan Randles
2022-01-21 10:31   ` [PATCH v2 11/15] examples/generator: link status check added Ronan Randles
2022-01-21 10:31   ` [PATCH v2 12/15] examples/generator: line rate limiting Ronan Randles
2022-01-21 10:31   ` [PATCH v2 13/15] gen: add UDP support Ronan Randles
2022-01-21 10:31   ` [PATCH v2 14/15] net/vxlan: instance flag endianness refactored Ronan Randles
2022-01-21 10:31   ` [PATCH v2 15/15] gen: add VXLAN support Ronan Randles
2022-01-21 14:44 ` [PATCH 00/12] add packet generator library and example app Xueming(Steven) Li
2022-01-21 15:24   ` Van Haaren, Harry
2022-01-24 10:48     ` Ananyev, Konstantin

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=20220121103122.2926856-8-ronan.randles@intel.com \
    --to=ronan.randles@intel.com \
    --cc=dev@dpdk.org \
    --cc=harry.van.haaren@intel.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.