DPDK patches and discussions
 help / color / Atom feed
* [dpdk-dev] [PATCH] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing
@ 2019-11-19 23:42 Frank Li
  2019-11-20  0:47 ` [dpdk-dev] [PATCH v2] " Frank Li
  0 siblings, 1 reply; 5+ messages in thread
From: Frank Li @ 2019-11-19 23:42 UTC (permalink / raw)
  To: dev; +Cc: Frank Li

Current IPv6 functionality in pktgen is broken. This fix makes it so that IPv6 
addresses are properly set when using the set, sequence, and save commands and 
that the IP header and UDP/TCP psuedo-header IPV6 addresses are properly set.

To preserve the runtime commands, the `_atoip` function no longer takes in 
flags to specify converting IPv4/6 addresses, and will try both. It returns 
4, 6, or -1 for a valid IPv4/6, invalid address, respectively.

Also print IPv6 addresses in UI properly.

Co-Authored-By: Valentin Andrei <vandrei@fb.com>

Signed-off-by: Frank Li <frank.li.65@gmail.com>
---
 app/cli-functions.c | 42 +++++++++++++++++-------------------------
 app/lpktgenlib.c    | 26 +++++++++-----------------
 app/pktgen-cmds.c   | 38 +++++++++++++++++++++++++++++++++-----
 app/pktgen-cmds.h   |  3 ++-
 app/pktgen-ipv6.c   |  9 ++++-----
 app/pktgen-stats.c  | 17 +++++++++++------
 app/pktgen-tcp.c    |  9 ++++-----
 app/pktgen-udp.c    |  9 ++++-----
 lib/utils/_atoip.c  | 39 +++++++++++++++++++++------------------
 lib/utils/_atoip.h  |  2 +-
 10 files changed, 106 insertions(+), 88 deletions(-)

diff --git a/app/cli-functions.c b/app/cli-functions.c
index f104781..2629147 100644
--- a/app/cli-functions.c
+++ b/app/cli-functions.c
@@ -214,7 +214,7 @@ range_cmd(int argc, char **argv)
 			p = strchr(argv[4], '/');
 			if (p)
 				*p = '\0';
-			_atoip(val, PG_IPADDR_V4, &ip, sizeof(ip));
+			_atoip(val, 0, &ip, sizeof(ip));
 			foreach_port(portlist,
 			     range_set_dst_ip(info, what, &ip));
 			break;
@@ -223,7 +223,7 @@ range_cmd(int argc, char **argv)
 			p = strchr(argv[4], '/');
 			if (p)
 				*p = '\0';
-			_atoip(argv[5], PG_IPADDR_V4, &ip, sizeof(ip));
+			_atoip(argv[5], 0, &ip, sizeof(ip));
 			foreach_port(portlist,
 			     range_set_src_ip(info, what, &ip));
 			break;
@@ -463,6 +463,7 @@ set_cmd(int argc, char **argv)
 	struct pg_ipaddr ip;
 	uint16_t id1, id2;
 	uint32_t u1;
+	int ip_ver;
 
 	m = cli_mapping(set_map, argc, argv);
 	if (!m)
@@ -527,13 +528,10 @@ set_cmd(int argc, char **argv)
 		case 30:
 			p = strchr(argv[4], '/');
 			if (!p) {
-				char buf[32];
-				snprintf(buf, sizeof(buf), "%s/32", argv[4]);
-				cli_printf("src IP address should contain /NN subnet value, default /32\n");
-				_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &ip, sizeof(ip));
-			} else
-				_atoip(argv[4], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &ip, sizeof(ip));
-			foreach_port(portlist, single_set_ipaddr(info, 's', &ip));
+				cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+			}
+			ip_ver = _atoip(argv[4], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &ip, sizeof(ip));
+			foreach_port(portlist, single_set_ipaddr(info, 's', &ip, ip_ver));
 			break;
 		case 31:
 			/* Remove the /XX mask value if supplied */
@@ -542,8 +540,8 @@ set_cmd(int argc, char **argv)
 				cli_printf("Subnet mask not required, removing subnet mask value\n");
 				*p = '\0';
 			}
-			_atoip(argv[4], PG_IPADDR_V4, &ip, sizeof(ip));
-			foreach_port(portlist, single_set_ipaddr(info, 'd', &ip));
+			ip_ver = _atoip(argv[4], 0, &ip, sizeof(ip));
+			foreach_port(portlist, single_set_ipaddr(info, 'd', &ip, ip_ver));
 			break;
 		case 40:
 			pktgen_set_page_size(atoi(argv[2]));
@@ -1116,15 +1114,12 @@ seq_1_set_cmd(int argc __rte_unused, char **argv)
 	p = strchr(argv[5], '/'); /* remove subnet if found */
 	if (p)
 		*p = '\0';
-	_atoip(argv[5], PG_IPADDR_V4, &dst, sizeof(dst));
+	_atoip(argv[5], 0, &dst, sizeof(dst));
 	p = strchr(argv[6], '/');
 	if (!p) {
-		char buf[32];
-		cli_printf("src IP address should contain /NN subnet value, default /32\n");
-		snprintf(buf, sizeof(buf), "%s/32", argv[6]);
-		_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
-	} else
-		_atoip(argv[6], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
+		cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+	}
+	_atoip(argv[6], PG_IPADDR_NETWORK, &src, sizeof(src));
 	portlist_parse(argv[2], &portlist);
 	pg_ether_aton(argv[3], &dmac);
 	pg_ether_aton(argv[4], &smac);
@@ -1179,15 +1174,12 @@ seq_2_set_cmd(int argc __rte_unused, char **argv)
 	p = strchr(argv[8], '/'); /* remove subnet if found */
 	if (p)
 		*p = '\0';
-	_atoip(argv[8], PG_IPADDR_V4, &dst, sizeof(dst));
+	_atoip(argv[8], 0, &dst, sizeof(dst));
 	p = strchr(argv[10], '/');
 	if (p == NULL) {
-		char buf[32];
-		snprintf(buf, sizeof(buf), "%s/32", argv[10]);
-		cli_printf("src IP address should contain /NN subnet value, default /32");
-		_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
-	} else
-		_atoip(argv[10], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
+		cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+	}
+	_atoip(argv[10], PG_IPADDR_NETWORK, &src, sizeof(src));
 	portlist_parse(argv[2], &portlist);
 	pg_ether_aton(argv[4], &dmac);
 	pg_ether_aton(argv[6], &smac);
diff --git a/app/lpktgenlib.c b/app/lpktgenlib.c
index c29e6ac..2b75a80 100644
--- a/app/lpktgenlib.c
+++ b/app/lpktgenlib.c
@@ -295,19 +295,11 @@ set_seq(lua_State *L, uint32_t seqnum)
 
 	/* Determine if we are IPv4 or IPv6 packets */
 	ip      = (char *)luaL_checkstring(L, 9);
-	if (ip[3] == '6') {
-		_atoip(luaL_checkstring(L, 5), PG_IPADDR_V6,
-				  &ip_daddr, sizeof(struct pg_ipaddr));
-		_atoip(luaL_checkstring(L, 6),
-				  PG_IPADDR_NETWORK | PG_IPADDR_V6,
-				  &ip_saddr, sizeof(struct pg_ipaddr));
-	} else {
-		_atoip(luaL_checkstring(L, 5), PG_IPADDR_V4,
-				  &ip_daddr, sizeof(struct pg_ipaddr));
-		_atoip(luaL_checkstring(L, 6),
-				  PG_IPADDR_NETWORK | PG_IPADDR_V4,
-				  &ip_saddr, sizeof(struct pg_ipaddr));
-	}
+	_atoip(luaL_checkstring(L, 5), 0,
+			&ip_daddr, sizeof(struct pg_ipaddr));
+	_atoip(luaL_checkstring(L, 6),
+			PG_IPADDR_NETWORK,
+			&ip_saddr, sizeof(struct pg_ipaddr));
 	proto   = (char *)luaL_checkstring(L, 10);
 	vlanid  = luaL_checkinteger(L, 11);
 	pktsize = luaL_checkinteger(L, 12);
@@ -657,6 +649,7 @@ pktgen_set_ip_addr(lua_State *L) {
 	struct pg_ipaddr ipaddr;
 	int flags;
 	char      *type;
+	int ip_ver;
 
 	switch (lua_gettop(L) ) {
 	default: return luaL_error(L, "set_ipaddr, wrong number of arguments");
@@ -665,14 +658,13 @@ pktgen_set_ip_addr(lua_State *L) {
 	}
 	type = (char *)luaL_checkstring(L, 2);
 	portlist_parse(luaL_checkstring(L, 1), &portlist);
-	flags = PG_IPADDR_V4;
 	if (type[0] == 's')
-		flags |= PG_IPADDR_NETWORK;
-	_atoip(luaL_checkstring(L, 3), flags,
+		flags = PG_IPADDR_NETWORK;
+	ip_ver = _atoip(luaL_checkstring(L, 3), flags,
 			  &ipaddr, sizeof(struct pg_ipaddr));
 
 	foreach_port(portlist,
-	             single_set_ipaddr(info, type[0], &ipaddr) );
+	             single_set_ipaddr(info, type[0], &ipaddr, ip_ver) );
 
 	pktgen_update_display();
 	return 0;
diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
index 0e9af7c..8e2e1f5 100644
--- a/app/pktgen-cmds.c
+++ b/app/pktgen-cmds.c
@@ -173,10 +173,14 @@ pktgen_script_save(char *path)
 			(pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
 			(pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp");
 		fprintf(fd, "set %d dst ip %s\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 				   0xFFFFFFFF));
 		fprintf(fd, "set %d src ip %s\n", i,
+		(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),
 				   pkt->ip_mask));
@@ -370,11 +374,15 @@ pktgen_script_save(char *path)
 					  sizeof(buff),
 					  &pkt->eth_src_addr));
 			fprintf(fd, "%s ",
+				(pkt->ethType == ETHER_TYPE_IPv6) ?
+				inet_ntop6(buff, sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 				inet_ntop4(buff, sizeof(buff),
 					   htonl(pkt->ip_dst_addr.addr.ipv4.
 						 s_addr),
 					   0xFFFFFFFF));
 			fprintf(fd, "%s ",
+				(pkt->ethType == ETHER_TYPE_IPv6) ?
+				inet_ntop6(buff, sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr) :
 				inet_ntop4(buff, sizeof(buff),
 					   htonl(pkt->ip_src_addr.addr.ipv4.
 						 s_addr),
@@ -537,10 +545,14 @@ pktgen_lua_save(char *path)
 			(pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
 			(pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp");
 		fprintf(fd, "pktgen.set_ipaddr('%d', 'dst', '%s');\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 				   0xFFFFFFFF));
 		fprintf(fd, "pktgen.set_ipaddr('%d', 'src','%s');\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),
 				   pkt->ip_mask));
@@ -729,11 +741,15 @@ pktgen_lua_save(char *path)
 						  sizeof(buff),
 						  &pkt->eth_src_addr));
 				fprintf(fd, "'%s', ",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_dst_addr.addr.ipv4.
 							 s_addr),
 						   0xFFFFFFFF));
 				fprintf(fd, "'%s', ",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_src_addr.addr.ipv4.
 							 s_addr),
@@ -762,10 +778,14 @@ pktgen_lua_save(char *path)
 				fprintf(fd, "  ['eth_src_addr'] = '%s',\n",
 					inet_mtoa(buff, sizeof(buff), &pkt->eth_src_addr));
 				fprintf(fd, "  ['ip_dst_addr'] = '%s',\n",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 						   0xFFFFFFFF));
 				fprintf(fd, "  ['ip_src_addr'] = '%s',\n",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_src_addr.addr.ipv4.s_addr),
 						   0xFFFFFFFF));
@@ -3037,15 +3057,23 @@ single_set_tx_rate(port_info_t *info, const char *r)
  */
 
 void
-single_set_ipaddr(port_info_t *info, char type, struct pg_ipaddr *ip)
+single_set_ipaddr(port_info_t* info, char type, struct pg_ipaddr* ip,
+			int ip_ver)
 {
-	if (type == 's') {
+	if (type == 's' && ip_ver == 4) {
 		info->seq_pkt[SINGLE_PKT].ip_mask = size_to_mask(ip->prefixlen);
 		info->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv4.s_addr = ntohl(
-		                ip->ipv4.s_addr);
-	} else
+										ip->ipv4.s_addr);
+	} else if (type == 'd' && ip_ver == 4) {
 		info->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv4.s_addr = ntohl(
-		                ip->ipv4.s_addr);
+										ip->ipv4.s_addr);
+	} else if (type == 's' && ip_ver == 6) {
+		rte_memcpy(info->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv6.s6_addr,
+			ip->ipv6.s6_addr, sizeof(struct in6_addr));
+	} else if (type == 'd' && ip_ver == 6){
+		rte_memcpy(info->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv6.s6_addr,
+			ip->ipv6.s6_addr, sizeof(struct in6_addr));
+	}
 	pktgen_packet_ctor(info, SINGLE_PKT, -1);
 	pktgen_set_tx_update(info);
 }
diff --git a/app/pktgen-cmds.h b/app/pktgen-cmds.h
index 46055fe..033c1b9 100644
--- a/app/pktgen-cmds.h
+++ b/app/pktgen-cmds.h
@@ -66,7 +66,8 @@ void pktgen_port_defaults(uint32_t pid, uint8_t seq);
 struct pg_ipaddr;
 
 /* Single */
-void single_set_ipaddr(port_info_t *info, char type, struct pg_ipaddr *ip);
+void single_set_ipaddr(port_info_t *info, char type,
+					struct pg_ipaddr *ip, int ip_ver);
 void single_set_proto(port_info_t *info, char *type);
 void single_set_vlan_id(port_info_t *info, uint16_t vlanid);
 void single_set_cos(port_info_t *info, uint8_t cos);
diff --git a/app/pktgen-ipv6.c b/app/pktgen-ipv6.c
index e8d3874..0430e7f 100644
--- a/app/pktgen-ipv6.c
+++ b/app/pktgen-ipv6.c
@@ -29,7 +29,6 @@ void
 pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 {
 	struct pg_ipv6_hdr *ip = hdr;
-	uint32_t addr;
 	uint16_t tlen;
 
 	/* IPv6 Header constructor */
@@ -42,10 +41,10 @@ pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 	ip->hop_limits = 4;
 	ip->proto = pkt->ipProto;
 
-	addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-	(void)rte_memcpy(&ip->dst_addr[8], &addr, sizeof(uint32_t));
-	addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-	(void)rte_memcpy(&ip->src_addr[8], &addr, sizeof(uint32_t));
+	rte_memcpy(&ip->dst_addr, pkt->ip_dst_addr.addr.ipv6.s6_addr,
+			sizeof(struct in6_addr));
+	rte_memcpy(&ip->src_addr, pkt->ip_src_addr.addr.ipv6.s6_addr,
+			sizeof(struct in6_addr));
 }
 
 /**************************************************************************//**
diff --git a/app/pktgen-stats.c b/app/pktgen-stats.c
index 572b10d..0e00a04 100644
--- a/app/pktgen-stats.c
+++ b/app/pktgen-stats.c
@@ -168,12 +168,17 @@ pktgen_print_static_data(void)
 		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, buff);
 
 		pktgen_display_set_color("stats.ip");
-		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
-		            inet_ntop4(buff, sizeof(buff),
-		                       htonl(pkt->ip_dst_addr.addr.ipv4.s_addr), 0xFFFFFFFF));
-		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
-		            inet_ntop4(buff, sizeof(buff),
-		                       htonl(pkt->ip_src_addr.addr.ipv4.s_addr), pkt->ip_mask));
+		if (pkt->ethType == PG_ETHER_TYPE_IPv6) {
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, inet_ntop6(buff,
+					sizeof(buff), pkt->ip_dst_addr.addr.ipv6.s6_addr));
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, inet_ntop6(buff,
+					sizeof(buff), pkt->ip_src_addr.addr.ipv6.s6_addr));
+		} else {
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, inet_ntop4(buff,
+					sizeof(buff), htonl(pkt->ip_dst_addr.addr.ipv4.s_addr), 0xFFFFFFFF));
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, inet_ntop4(buff,
+					sizeof(buff), htonl(pkt->ip_src_addr.addr.ipv4.s_addr), pkt->ip_mask));
+		}
 		pktgen_display_set_color("stats.mac");
 		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
 		            inet_mtoa(buff, sizeof(buff), &pkt->eth_dst_addr));
diff --git a/app/pktgen-tcp.c b/app/pktgen-tcp.c
index 7c31960..089c93a 100644
--- a/app/pktgen-tcp.c
+++ b/app/pktgen-tcp.c
@@ -55,15 +55,14 @@ pktgen_tcp_hdr_ctor(pkt_seq_t *pkt, void * hdr, int type)
 	} else {
 		struct pg_ipv6_hdr *ipv6 = (struct pg_ipv6_hdr *)hdr;
 		struct pg_tcp_hdr *tcp = (struct pg_tcp_hdr *)&ipv6[1];
-		uint32_t addr;
 
 		/* Create the pseudo header and TCP information */
 		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
 		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
-		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
-		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
+		rte_memcpy(ipv6->dst_addr, &pkt->ip_dst_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
+		rte_memcpy(ipv6->src_addr, &pkt->ip_src_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
 
 		tlen = pkt->pktSize - (pkt->ether_hdr_size + sizeof(struct pg_ipv6_hdr));
 		ipv6->payload_len = htons(tlen);
diff --git a/app/pktgen-udp.c b/app/pktgen-udp.c
index 41bb5c6..6e5dd03 100644
--- a/app/pktgen-udp.c
+++ b/app/pktgen-udp.c
@@ -59,17 +59,16 @@ pktgen_udp_hdr_ctor(pkt_seq_t *pkt, void *hdr, int type)
 		if (udp->dgram_cksum == 0)
 			udp->dgram_cksum = 0xFFFF;
 	} else {
-		uint32_t addr;
 		struct pg_ipv6_hdr *ipv6 = hdr;
 		struct pg_udp_hdr *udp = (struct pg_udp_hdr *)&ipv6[1];
 
 		/* Create the pseudo header and TCP information */
 		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
 		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
-		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
-		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
+		rte_memcpy(ipv6->dst_addr, &pkt->ip_dst_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
+		rte_memcpy(ipv6->src_addr, &pkt->ip_src_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
 
 		tlen = pkt->pktSize - (pkt->ether_hdr_size +
 				       sizeof(struct pg_ipv6_hdr));
diff --git a/lib/utils/_atoip.c b/lib/utils/_atoip.c
index c33e6ae..1ba142c 100644
--- a/lib/utils/_atoip.c
+++ b/lib/utils/_atoip.c
@@ -228,6 +228,7 @@ _atoip(const char *buf, int flags, void *res, unsigned ressize)
 	struct rte_ipaddr ipaddr;
 	char *prefix, *prefix_end;
 	long prefixlen = 0;
+	int default_max_prefix = 0;
 
 	if (res && ressize < sizeof(struct rte_ipaddr))
 		return -1;
@@ -247,35 +248,37 @@ _atoip(const char *buf, int flags, void *res, unsigned ressize)
 	/* convert the network prefix */
 	if (flags & RTE_IPADDR_NETWORK) {
 		prefix = strrchr(ip_str, '/');
-		if (prefix == NULL)
-			return -1;
-		*prefix = '\0';
-		prefix++;
-		errno = 0;
-		prefixlen = strtol(prefix, &prefix_end, 10);
-		if (errno || (*prefix_end != '\0')
-		    || prefixlen < 0 || prefixlen > RTE_PREFIXMAX)
-			return -1;
-		ipaddr.prefixlen = prefixlen;
+		if (prefix == NULL) {
+			default_max_prefix = 1;
+		}	else {
+			*prefix = '\0';
+			prefix++;
+			errno = 0;
+			prefixlen = strtol(prefix, &prefix_end, 10);
+			if (errno || (*prefix_end != '\0')
+			    || prefixlen < 0 || prefixlen > RTE_PREFIXMAX)
+				return -1;
+			ipaddr.prefixlen = prefixlen;
+		}
 	} else
 		ipaddr.prefixlen = 0;
 
 	/* convert the IP addr */
-	if ((flags & RTE_IPADDR_V4) &&
-	    inet_ipton(AF_INET, ip_str, &ipaddr.ipv4) == 1 &&
+	if (inet_ipton(AF_INET, ip_str, &ipaddr.ipv4) == 1 &&
 	    prefixlen <= RTE_V4PREFIXMAX) {
+		if (default_max_prefix)
+			ipaddr.prefixlen = RTE_V4PREFIXMAX;
 		ipaddr.family = AF_INET;
 		if (res)
 			memcpy(res, &ipaddr, sizeof(ipaddr));
-		return token_len;
-	}
-
-	if ((flags & RTE_IPADDR_V6) &&
-	    inet_ipton(AF_INET6, ip_str, &ipaddr.ipv6) == 1) {
+		return 4;
+	} else if (inet_ipton(AF_INET6, ip_str, &ipaddr.ipv6) == 1) {
 		ipaddr.family = AF_INET6;
+		if (default_max_prefix)
+			ipaddr.prefixlen = RTE_PREFIXMAX;
 		if (res)
 			memcpy(res, &ipaddr, sizeof(ipaddr));
-		return token_len;
+		return 6;
 	}
 	return -1;
 
diff --git a/lib/utils/_atoip.h b/lib/utils/_atoip.h
index c03093a..322ee2d 100644
--- a/lib/utils/_atoip.h
+++ b/lib/utils/_atoip.h
@@ -49,7 +49,7 @@ struct rte_ipaddr {
  * @param ressize
  *   Length of res in bytes.
  * @return
- *   0 on OK and -1 on error
+ *   4 or 6 on OK, indicating an IPv4/v6 address, respectively, and -1 on error
  */
 int _atoip(const char *buf, int flags, void *res, unsigned ressize);
 
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing
  2019-11-19 23:42 [dpdk-dev] [PATCH] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing Frank Li
@ 2019-11-20  0:47 ` " Frank Li
  2019-11-30  0:03   ` Wiles, Keith
  0 siblings, 1 reply; 5+ messages in thread
From: Frank Li @ 2019-11-20  0:47 UTC (permalink / raw)
  To: dev; +Cc: Frank Li

Current IPv6 functionality in pktgen is broken. This fix makes it so that
IPv6 addresses are properly set when using the set, sequence, and save
commands and that the IP header and UDP/TCP psuedo-header IPV6 addresses
are properly set.

To preserve the runtime commands, the `_atoip` function no longer takes
in flags to specify converting IPv4/6 addresses, and will try both,
returning, 4, 6, or -1 for a valid IPv4/6, invalid address, respectively.

Also print IPv6 addresses in UI properly.

Co-authored-by Valentin Andrei <vandrei@fb.com>

Signed-off-by: Frank Li <frank.li.65@gmail.com>
---
 app/cli-functions.c | 46 +++++++++++++++++++----------------------
 app/lpktgenlib.c    | 26 ++++++++---------------
 app/pktgen-cmds.c   | 50 ++++++++++++++++++++++++++++++++++++++++-----
 app/pktgen-cmds.h   |  3 ++-
 app/pktgen-ipv6.c   |  9 ++++----
 app/pktgen-stats.c  | 23 +++++++++++++++------
 app/pktgen-tcp.c    |  9 ++++----
 app/pktgen-udp.c    |  9 ++++----
 lib/utils/_atoip.c  | 39 +++++++++++++++++++----------------
 lib/utils/_atoip.h  |  2 +-
 10 files changed, 128 insertions(+), 88 deletions(-)

diff --git a/app/cli-functions.c b/app/cli-functions.c
index f104781..b906e86 100644
--- a/app/cli-functions.c
+++ b/app/cli-functions.c
@@ -214,7 +214,7 @@ range_cmd(int argc, char **argv)
 			p = strchr(argv[4], '/');
 			if (p)
 				*p = '\0';
-			_atoip(val, PG_IPADDR_V4, &ip, sizeof(ip));
+			_atoip(val, 0, &ip, sizeof(ip));
 			foreach_port(portlist,
 			     range_set_dst_ip(info, what, &ip));
 			break;
@@ -223,7 +223,7 @@ range_cmd(int argc, char **argv)
 			p = strchr(argv[4], '/');
 			if (p)
 				*p = '\0';
-			_atoip(argv[5], PG_IPADDR_V4, &ip, sizeof(ip));
+			_atoip(argv[5], 0, &ip, sizeof(ip));
 			foreach_port(portlist,
 			     range_set_src_ip(info, what, &ip));
 			break;
@@ -463,6 +463,7 @@ set_cmd(int argc, char **argv)
 	struct pg_ipaddr ip;
 	uint16_t id1, id2;
 	uint32_t u1;
+	int ip_ver;
 
 	m = cli_mapping(set_map, argc, argv);
 	if (!m)
@@ -527,13 +528,13 @@ set_cmd(int argc, char **argv)
 		case 30:
 			p = strchr(argv[4], '/');
 			if (!p) {
-				char buf[32];
-				snprintf(buf, sizeof(buf), "%s/32", argv[4]);
-				cli_printf("src IP address should contain /NN subnet value, default /32\n");
-				_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &ip, sizeof(ip));
-			} else
-				_atoip(argv[4], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &ip, sizeof(ip));
-			foreach_port(portlist, single_set_ipaddr(info, 's', &ip));
+				cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+			}
+			ip_ver = _atoip(argv[4],
+				PG_IPADDR_V4 | PG_IPADDR_NETWORK,
+				&ip, sizeof(ip));
+			foreach_port(portlist,
+				single_set_ipaddr(info, 's', &ip, ip_ver));
 			break;
 		case 31:
 			/* Remove the /XX mask value if supplied */
@@ -542,8 +543,9 @@ set_cmd(int argc, char **argv)
 				cli_printf("Subnet mask not required, removing subnet mask value\n");
 				*p = '\0';
 			}
-			_atoip(argv[4], PG_IPADDR_V4, &ip, sizeof(ip));
-			foreach_port(portlist, single_set_ipaddr(info, 'd', &ip));
+			ip_ver = _atoip(argv[4], 0, &ip, sizeof(ip));
+			foreach_port(portlist,
+				single_set_ipaddr(info, 'd', &ip, ip_ver));
 			break;
 		case 40:
 			pktgen_set_page_size(atoi(argv[2]));
@@ -1116,15 +1118,12 @@ seq_1_set_cmd(int argc __rte_unused, char **argv)
 	p = strchr(argv[5], '/'); /* remove subnet if found */
 	if (p)
 		*p = '\0';
-	_atoip(argv[5], PG_IPADDR_V4, &dst, sizeof(dst));
+	_atoip(argv[5], 0, &dst, sizeof(dst));
 	p = strchr(argv[6], '/');
 	if (!p) {
-		char buf[32];
-		cli_printf("src IP address should contain /NN subnet value, default /32\n");
-		snprintf(buf, sizeof(buf), "%s/32", argv[6]);
-		_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
-	} else
-		_atoip(argv[6], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
+		cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+	}
+	_atoip(argv[6], PG_IPADDR_NETWORK, &src, sizeof(src));
 	portlist_parse(argv[2], &portlist);
 	pg_ether_aton(argv[3], &dmac);
 	pg_ether_aton(argv[4], &smac);
@@ -1179,15 +1178,12 @@ seq_2_set_cmd(int argc __rte_unused, char **argv)
 	p = strchr(argv[8], '/'); /* remove subnet if found */
 	if (p)
 		*p = '\0';
-	_atoip(argv[8], PG_IPADDR_V4, &dst, sizeof(dst));
+	_atoip(argv[8], 0, &dst, sizeof(dst));
 	p = strchr(argv[10], '/');
 	if (p == NULL) {
-		char buf[32];
-		snprintf(buf, sizeof(buf), "%s/32", argv[10]);
-		cli_printf("src IP address should contain /NN subnet value, default /32");
-		_atoip(buf, PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
-	} else
-		_atoip(argv[10], PG_IPADDR_V4 | PG_IPADDR_NETWORK, &src, sizeof(src));
+		cli_printf("src IP address should contain subnet value, default /32 for IPv4, /128 for IPv6\n");
+	}
+	_atoip(argv[10], PG_IPADDR_NETWORK, &src, sizeof(src));
 	portlist_parse(argv[2], &portlist);
 	pg_ether_aton(argv[4], &dmac);
 	pg_ether_aton(argv[6], &smac);
diff --git a/app/lpktgenlib.c b/app/lpktgenlib.c
index c29e6ac..263bb27 100644
--- a/app/lpktgenlib.c
+++ b/app/lpktgenlib.c
@@ -295,19 +295,11 @@ set_seq(lua_State *L, uint32_t seqnum)
 
 	/* Determine if we are IPv4 or IPv6 packets */
 	ip      = (char *)luaL_checkstring(L, 9);
-	if (ip[3] == '6') {
-		_atoip(luaL_checkstring(L, 5), PG_IPADDR_V6,
-				  &ip_daddr, sizeof(struct pg_ipaddr));
-		_atoip(luaL_checkstring(L, 6),
-				  PG_IPADDR_NETWORK | PG_IPADDR_V6,
-				  &ip_saddr, sizeof(struct pg_ipaddr));
-	} else {
-		_atoip(luaL_checkstring(L, 5), PG_IPADDR_V4,
-				  &ip_daddr, sizeof(struct pg_ipaddr));
-		_atoip(luaL_checkstring(L, 6),
-				  PG_IPADDR_NETWORK | PG_IPADDR_V4,
-				  &ip_saddr, sizeof(struct pg_ipaddr));
-	}
+	_atoip(luaL_checkstring(L, 5), 0,
+			&ip_daddr, sizeof(struct pg_ipaddr));
+	_atoip(luaL_checkstring(L, 6),
+			PG_IPADDR_NETWORK,
+			&ip_saddr, sizeof(struct pg_ipaddr));
 	proto   = (char *)luaL_checkstring(L, 10);
 	vlanid  = luaL_checkinteger(L, 11);
 	pktsize = luaL_checkinteger(L, 12);
@@ -657,6 +649,7 @@ pktgen_set_ip_addr(lua_State *L) {
 	struct pg_ipaddr ipaddr;
 	int flags;
 	char      *type;
+	int ip_ver;
 
 	switch (lua_gettop(L) ) {
 	default: return luaL_error(L, "set_ipaddr, wrong number of arguments");
@@ -665,14 +658,13 @@ pktgen_set_ip_addr(lua_State *L) {
 	}
 	type = (char *)luaL_checkstring(L, 2);
 	portlist_parse(luaL_checkstring(L, 1), &portlist);
-	flags = PG_IPADDR_V4;
 	if (type[0] == 's')
-		flags |= PG_IPADDR_NETWORK;
-	_atoip(luaL_checkstring(L, 3), flags,
+		flags = PG_IPADDR_NETWORK;
+	ip_ver = _atoip(luaL_checkstring(L, 3), flags,
 			  &ipaddr, sizeof(struct pg_ipaddr));
 
 	foreach_port(portlist,
-	             single_set_ipaddr(info, type[0], &ipaddr) );
+		single_set_ipaddr(info, type[0], &ipaddr, ip_ver));
 
 	pktgen_update_display();
 	return 0;
diff --git a/app/pktgen-cmds.c b/app/pktgen-cmds.c
index 0e9af7c..91312a7 100644
--- a/app/pktgen-cmds.c
+++ b/app/pktgen-cmds.c
@@ -173,10 +173,16 @@ pktgen_script_save(char *path)
 			(pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
 			(pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp");
 		fprintf(fd, "set %d dst ip %s\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff),
+					 pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 				   0xFFFFFFFF));
 		fprintf(fd, "set %d src ip %s\n", i,
+		(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff),
+					 pkt->ip_src_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),
 				   pkt->ip_mask));
@@ -370,11 +376,17 @@ pktgen_script_save(char *path)
 					  sizeof(buff),
 					  &pkt->eth_src_addr));
 			fprintf(fd, "%s ",
+				(pkt->ethType == ETHER_TYPE_IPv6) ?
+				inet_ntop6(buff, sizeof(buff),
+					pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 				inet_ntop4(buff, sizeof(buff),
 					   htonl(pkt->ip_dst_addr.addr.ipv4.
 						 s_addr),
 					   0xFFFFFFFF));
 			fprintf(fd, "%s ",
+				(pkt->ethType == ETHER_TYPE_IPv6) ?
+				inet_ntop6(buff, sizeof(buff),
+					pkt->ip_src_addr.addr.ipv6.s6_addr) :
 				inet_ntop4(buff, sizeof(buff),
 					   htonl(pkt->ip_src_addr.addr.ipv4.
 						 s_addr),
@@ -537,10 +549,16 @@ pktgen_lua_save(char *path)
 			(pkt->ipProto == PG_IPPROTO_TCP) ? "tcp" :
 			(pkt->ipProto == PG_IPPROTO_ICMP) ? "icmp" : "udp");
 		fprintf(fd, "pktgen.set_ipaddr('%d', 'dst', '%s');\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff),
+					 pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 				   0xFFFFFFFF));
 		fprintf(fd, "pktgen.set_ipaddr('%d', 'src','%s');\n", i,
+			(pkt->ethType == ETHER_TYPE_IPv6) ?
+			inet_ntop6(buff, sizeof(buff),
+					 pkt->ip_src_addr.addr.ipv6.s6_addr) :
 			inet_ntop4(buff, sizeof(buff),
 				   ntohl(pkt->ip_src_addr.addr.ipv4.s_addr),
 				   pkt->ip_mask));
@@ -729,11 +747,17 @@ pktgen_lua_save(char *path)
 						  sizeof(buff),
 						  &pkt->eth_src_addr));
 				fprintf(fd, "'%s', ",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff),
+					  pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_dst_addr.addr.ipv4.
 							 s_addr),
 						   0xFFFFFFFF));
 				fprintf(fd, "'%s', ",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff),
+					  pkt->ip_src_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_src_addr.addr.ipv4.
 							 s_addr),
@@ -762,10 +786,16 @@ pktgen_lua_save(char *path)
 				fprintf(fd, "  ['eth_src_addr'] = '%s',\n",
 					inet_mtoa(buff, sizeof(buff), &pkt->eth_src_addr));
 				fprintf(fd, "  ['ip_dst_addr'] = '%s',\n",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff),
+					  pkt->ip_dst_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_dst_addr.addr.ipv4.s_addr),
 						   0xFFFFFFFF));
 				fprintf(fd, "  ['ip_src_addr'] = '%s',\n",
+					(pkt->ethType == ETHER_TYPE_IPv6) ?
+					inet_ntop6(buff, sizeof(buff),
+					  pkt->ip_src_addr.addr.ipv6.s6_addr) :
 					inet_ntop4(buff, sizeof(buff),
 						   htonl(pkt->ip_src_addr.addr.ipv4.s_addr),
 						   0xFFFFFFFF));
@@ -3037,15 +3067,25 @@ single_set_tx_rate(port_info_t *info, const char *r)
  */
 
 void
-single_set_ipaddr(port_info_t *info, char type, struct pg_ipaddr *ip)
+single_set_ipaddr(port_info_t *info, char type, struct pg_ipaddr *ip,
+			int ip_ver)
 {
-	if (type == 's') {
+	if (type == 's' && ip_ver == 4) {
 		info->seq_pkt[SINGLE_PKT].ip_mask = size_to_mask(ip->prefixlen);
 		info->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv4.s_addr = ntohl(
-		                ip->ipv4.s_addr);
-	} else
+				ip->ipv4.s_addr);
+	} else if (type == 'd' && ip_ver == 4) {
 		info->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv4.s_addr = ntohl(
-		                ip->ipv4.s_addr);
+				ip->ipv4.s_addr);
+	} else if (type == 's' && ip_ver == 6) {
+		rte_memcpy(
+			info->seq_pkt[SINGLE_PKT].ip_src_addr.addr.ipv6.s6_addr,
+			ip->ipv6.s6_addr, sizeof(struct in6_addr));
+	} else if (type == 'd' && ip_ver == 6) {
+		rte_memcpy(
+			info->seq_pkt[SINGLE_PKT].ip_dst_addr.addr.ipv6.s6_addr,
+			ip->ipv6.s6_addr, sizeof(struct in6_addr));
+	}
 	pktgen_packet_ctor(info, SINGLE_PKT, -1);
 	pktgen_set_tx_update(info);
 }
diff --git a/app/pktgen-cmds.h b/app/pktgen-cmds.h
index 46055fe..033c1b9 100644
--- a/app/pktgen-cmds.h
+++ b/app/pktgen-cmds.h
@@ -66,7 +66,8 @@ void pktgen_port_defaults(uint32_t pid, uint8_t seq);
 struct pg_ipaddr;
 
 /* Single */
-void single_set_ipaddr(port_info_t *info, char type, struct pg_ipaddr *ip);
+void single_set_ipaddr(port_info_t *info, char type,
+					struct pg_ipaddr *ip, int ip_ver);
 void single_set_proto(port_info_t *info, char *type);
 void single_set_vlan_id(port_info_t *info, uint16_t vlanid);
 void single_set_cos(port_info_t *info, uint8_t cos);
diff --git a/app/pktgen-ipv6.c b/app/pktgen-ipv6.c
index e8d3874..0430e7f 100644
--- a/app/pktgen-ipv6.c
+++ b/app/pktgen-ipv6.c
@@ -29,7 +29,6 @@ void
 pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 {
 	struct pg_ipv6_hdr *ip = hdr;
-	uint32_t addr;
 	uint16_t tlen;
 
 	/* IPv6 Header constructor */
@@ -42,10 +41,10 @@ pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 	ip->hop_limits = 4;
 	ip->proto = pkt->ipProto;
 
-	addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-	(void)rte_memcpy(&ip->dst_addr[8], &addr, sizeof(uint32_t));
-	addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-	(void)rte_memcpy(&ip->src_addr[8], &addr, sizeof(uint32_t));
+	rte_memcpy(&ip->dst_addr, pkt->ip_dst_addr.addr.ipv6.s6_addr,
+			sizeof(struct in6_addr));
+	rte_memcpy(&ip->src_addr, pkt->ip_src_addr.addr.ipv6.s6_addr,
+			sizeof(struct in6_addr));
 }
 
 /**************************************************************************//**
diff --git a/app/pktgen-stats.c b/app/pktgen-stats.c
index 572b10d..367a3b7 100644
--- a/app/pktgen-stats.c
+++ b/app/pktgen-stats.c
@@ -168,12 +168,23 @@ pktgen_print_static_data(void)
 		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1, buff);
 
 		pktgen_display_set_color("stats.ip");
-		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
-		            inet_ntop4(buff, sizeof(buff),
-		                       htonl(pkt->ip_dst_addr.addr.ipv4.s_addr), 0xFFFFFFFF));
-		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
-		            inet_ntop4(buff, sizeof(buff),
-		                       htonl(pkt->ip_src_addr.addr.ipv4.s_addr), pkt->ip_mask));
+		if (pkt->ethType == PG_ETHER_TYPE_IPv6) {
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
+				inet_ntop6(buff, sizeof(buff),
+				pkt->ip_dst_addr.addr.ipv6.s6_addr));
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
+				inet_ntop6(buff, sizeof(buff),
+				pkt->ip_src_addr.addr.ipv6.s6_addr));
+		} else {
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
+				inet_ntop4(buff, sizeof(buff),
+				htonl(pkt->ip_dst_addr.addr.ipv4.s_addr),
+				0xFFFFFFFF));
+			scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
+				inet_ntop4(buff, sizeof(buff),
+				htonl(pkt->ip_src_addr.addr.ipv4.s_addr),
+				pkt->ip_mask));
+		}
 		pktgen_display_set_color("stats.mac");
 		scrn_printf(row++, col, "%*s", COLUMN_WIDTH_1,
 		            inet_mtoa(buff, sizeof(buff), &pkt->eth_dst_addr));
diff --git a/app/pktgen-tcp.c b/app/pktgen-tcp.c
index 7c31960..089c93a 100644
--- a/app/pktgen-tcp.c
+++ b/app/pktgen-tcp.c
@@ -55,15 +55,14 @@ pktgen_tcp_hdr_ctor(pkt_seq_t *pkt, void * hdr, int type)
 	} else {
 		struct pg_ipv6_hdr *ipv6 = (struct pg_ipv6_hdr *)hdr;
 		struct pg_tcp_hdr *tcp = (struct pg_tcp_hdr *)&ipv6[1];
-		uint32_t addr;
 
 		/* Create the pseudo header and TCP information */
 		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
 		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
-		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
-		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
+		rte_memcpy(ipv6->dst_addr, &pkt->ip_dst_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
+		rte_memcpy(ipv6->src_addr, &pkt->ip_src_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
 
 		tlen = pkt->pktSize - (pkt->ether_hdr_size + sizeof(struct pg_ipv6_hdr));
 		ipv6->payload_len = htons(tlen);
diff --git a/app/pktgen-udp.c b/app/pktgen-udp.c
index 41bb5c6..6e5dd03 100644
--- a/app/pktgen-udp.c
+++ b/app/pktgen-udp.c
@@ -59,17 +59,16 @@ pktgen_udp_hdr_ctor(pkt_seq_t *pkt, void *hdr, int type)
 		if (udp->dgram_cksum == 0)
 			udp->dgram_cksum = 0xFFFF;
 	} else {
-		uint32_t addr;
 		struct pg_ipv6_hdr *ipv6 = hdr;
 		struct pg_udp_hdr *udp = (struct pg_udp_hdr *)&ipv6[1];
 
 		/* Create the pseudo header and TCP information */
 		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
 		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
-		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
-		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
-		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
+		rte_memcpy(ipv6->dst_addr, &pkt->ip_dst_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
+		rte_memcpy(ipv6->src_addr, &pkt->ip_src_addr.addr.ipv6.s6_addr,
+				sizeof(struct in6_addr));
 
 		tlen = pkt->pktSize - (pkt->ether_hdr_size +
 				       sizeof(struct pg_ipv6_hdr));
diff --git a/lib/utils/_atoip.c b/lib/utils/_atoip.c
index c33e6ae..1ba142c 100644
--- a/lib/utils/_atoip.c
+++ b/lib/utils/_atoip.c
@@ -228,6 +228,7 @@ _atoip(const char *buf, int flags, void *res, unsigned ressize)
 	struct rte_ipaddr ipaddr;
 	char *prefix, *prefix_end;
 	long prefixlen = 0;
+	int default_max_prefix = 0;
 
 	if (res && ressize < sizeof(struct rte_ipaddr))
 		return -1;
@@ -247,35 +248,37 @@ _atoip(const char *buf, int flags, void *res, unsigned ressize)
 	/* convert the network prefix */
 	if (flags & RTE_IPADDR_NETWORK) {
 		prefix = strrchr(ip_str, '/');
-		if (prefix == NULL)
-			return -1;
-		*prefix = '\0';
-		prefix++;
-		errno = 0;
-		prefixlen = strtol(prefix, &prefix_end, 10);
-		if (errno || (*prefix_end != '\0')
-		    || prefixlen < 0 || prefixlen > RTE_PREFIXMAX)
-			return -1;
-		ipaddr.prefixlen = prefixlen;
+		if (prefix == NULL) {
+			default_max_prefix = 1;
+		}	else {
+			*prefix = '\0';
+			prefix++;
+			errno = 0;
+			prefixlen = strtol(prefix, &prefix_end, 10);
+			if (errno || (*prefix_end != '\0')
+			    || prefixlen < 0 || prefixlen > RTE_PREFIXMAX)
+				return -1;
+			ipaddr.prefixlen = prefixlen;
+		}
 	} else
 		ipaddr.prefixlen = 0;
 
 	/* convert the IP addr */
-	if ((flags & RTE_IPADDR_V4) &&
-	    inet_ipton(AF_INET, ip_str, &ipaddr.ipv4) == 1 &&
+	if (inet_ipton(AF_INET, ip_str, &ipaddr.ipv4) == 1 &&
 	    prefixlen <= RTE_V4PREFIXMAX) {
+		if (default_max_prefix)
+			ipaddr.prefixlen = RTE_V4PREFIXMAX;
 		ipaddr.family = AF_INET;
 		if (res)
 			memcpy(res, &ipaddr, sizeof(ipaddr));
-		return token_len;
-	}
-
-	if ((flags & RTE_IPADDR_V6) &&
-	    inet_ipton(AF_INET6, ip_str, &ipaddr.ipv6) == 1) {
+		return 4;
+	} else if (inet_ipton(AF_INET6, ip_str, &ipaddr.ipv6) == 1) {
 		ipaddr.family = AF_INET6;
+		if (default_max_prefix)
+			ipaddr.prefixlen = RTE_PREFIXMAX;
 		if (res)
 			memcpy(res, &ipaddr, sizeof(ipaddr));
-		return token_len;
+		return 6;
 	}
 	return -1;
 
diff --git a/lib/utils/_atoip.h b/lib/utils/_atoip.h
index c03093a..322ee2d 100644
--- a/lib/utils/_atoip.h
+++ b/lib/utils/_atoip.h
@@ -49,7 +49,7 @@ struct rte_ipaddr {
  * @param ressize
  *   Length of res in bytes.
  * @return
- *   0 on OK and -1 on error
+ *   4 or 6 on OK, indicating an IPv4/v6 address, respectively, and -1 on error
  */
 int _atoip(const char *buf, int flags, void *res, unsigned ressize);
 
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v2] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing
  2019-11-20  0:47 ` [dpdk-dev] [PATCH v2] " Frank Li
@ 2019-11-30  0:03   ` Wiles, Keith
  2019-12-02 21:20     ` Frank Li
  0 siblings, 1 reply; 5+ messages in thread
From: Wiles, Keith @ 2019-11-30  0:03 UTC (permalink / raw)
  To: Frank Li; +Cc: dev



> On Nov 19, 2019, at 6:47 PM, Frank Li <frank.li.65@gmail.com> wrote:
> 
> Current IPv6 functionality in pktgen is broken. This fix makes it so that
> IPv6 addresses are properly set when using the set, sequence, and save
> commands and that the IP header and UDP/TCP psuedo-header IPV6 addresses
> are properly set.
> 
> To preserve the runtime commands, the `_atoip` function no longer takes
> in flags to specify converting IPv4/6 addresses, and will try both,
> returning, 4, 6, or -1 for a valid IPv4/6, invalid address, respectively.
> 
> Also print IPv6 addresses in UI properly.
> 
> Co-authored-by Valentin Andrei <vandrei@fb.com>
> 
> Signed-off-by: Frank Li <frank.li.65@gmail.com>
> ---

I applied this patch and if you have time do a pull on the pktgen repo and switch over to the ‘dev’ branch and see if this version works for you.

Regards,
Keith


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

* Re: [dpdk-dev] [PATCH v2] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing
  2019-11-30  0:03   ` Wiles, Keith
@ 2019-12-02 21:20     ` Frank Li
  2019-12-02 23:43       ` Wiles, Keith
  0 siblings, 1 reply; 5+ messages in thread
From: Frank Li @ 2019-12-02 21:20 UTC (permalink / raw)
  To: Wiles, Keith; +Cc: dev

Hi Keith,

Thanks for fixing my macros from ETHER_TYPE_IPv6 to PG_ETHER_TYPE_IPv6 in
your latest commit.

I tested the 'dev' branch with tap interfaces running the command:
`pktgen l 1-5 -n 4 --proc-type auto --log-level debug --file-prefix pg
--vdev=net_tap0 --vdev=net_tap1 -- -T -P -m [2:3].0 -m [4:5].1`

When I use the latest commit, pktgen crashes. When I go back 1 commit to my
changes (manually fixing the ether type macros), my IPv6 changes do work as
expected running the same command.

Here is the error I saw:

Initialize Port 0 -- TxQ 1, RxQ 1
Src MAC 5a:d7:d5:38:f8:a7
 <Promiscuous mode Enabled>
Initialize Port 1 -- TxQ 1, RxQ 1
!PANIC!: Cannot create mbuf pool (Default TX  1:0) port 1, queue 0,
nb_mbufs 16384, socket_id 0: Cannot allocate memory
PANIC in pktgen_mbuf_pool_create():
Cannot create mbuf pool (Default TX  1:0) port 1, queue 0, nb_mbufs 16384,
socket_id 0: Cannot allocate memory
6: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen()
[0x53b853]]
5: [/lib64/libc.so.6(__libc_start_main+0xf5) [0x7fc787ed73d5]]
4:
[/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(main+0xf03)
[0x4977f3]]
3:
[/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(pktgen_config_ports+0x1d02)
[0x567832]]
2:
[/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(__rte_panic+0xb8)
[0x488bf2]]
1:
[/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(rte_dump_stack+0x16)
[0x667ca6]]

I haven't tried running pktgen with any other options, and I do believe my
changes are incorporated properly, just wanted to bring this error to your
attention in case it may be helpful for you.

Best,
Frank


On Fri, Nov 29, 2019 at 4:03 PM Wiles, Keith <keith.wiles@intel.com> wrote:

>
>
> > On Nov 19, 2019, at 6:47 PM, Frank Li <frank.li.65@gmail.com> wrote:
> >
> > Current IPv6 functionality in pktgen is broken. This fix makes it so that
> > IPv6 addresses are properly set when using the set, sequence, and save
> > commands and that the IP header and UDP/TCP psuedo-header IPV6 addresses
> > are properly set.
> >
> > To preserve the runtime commands, the `_atoip` function no longer takes
> > in flags to specify converting IPv4/6 addresses, and will try both,
> > returning, 4, 6, or -1 for a valid IPv4/6, invalid address, respectively.
> >
> > Also print IPv6 addresses in UI properly.
> >
> > Co-authored-by Valentin Andrei <vandrei@fb.com>
> >
> > Signed-off-by: Frank Li <frank.li.65@gmail.com>
> > ---
>
> I applied this patch and if you have time do a pull on the pktgen repo and
> switch over to the ‘dev’ branch and see if this version works for you.
>
> Regards,
> Keith
>
>

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

* Re: [dpdk-dev] [PATCH v2] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing
  2019-12-02 21:20     ` Frank Li
@ 2019-12-02 23:43       ` Wiles, Keith
  0 siblings, 0 replies; 5+ messages in thread
From: Wiles, Keith @ 2019-12-02 23:43 UTC (permalink / raw)
  To: Frank Li; +Cc: dev



> On Dec 2, 2019, at 3:20 PM, Frank Li <frank.li.65@gmail.com> wrote:
> 
> Hi Keith,
> 
> Thanks for fixing my macros from ETHER_TYPE_IPv6 to PG_ETHER_TYPE_IPv6 in your latest commit.
> 
> I tested the 'dev' branch with tap interfaces running the command:
> `pktgen l 1-5 -n 4 --proc-type auto --log-level debug --file-prefix pg --vdev=net_tap0 --vdev=net_tap1 -- -T -P -m [2:3].0 -m [4:5].1`
> 
> When I use the latest commit, pktgen crashes. When I go back 1 commit to my changes (manually fixing the ether type macros), my IPv6 changes do work as expected running the same command.
> 
> Here is the error I saw:
> 
> Initialize Port 0 -- TxQ 1, RxQ 1
> Src MAC 5a:d7:d5:38:f8:a7
>  <Promiscuous mode Enabled>
> Initialize Port 1 -- TxQ 1, RxQ 1
> !PANIC!: Cannot create mbuf pool (Default TX  1:0) port 1, queue 0, nb_mbufs 16384, socket_id 0: Cannot allocate memory
> PANIC in pktgen_mbuf_pool_create():
> Cannot create mbuf pool (Default TX  1:0) port 1, queue 0, nb_mbufs 16384, socket_id 0: Cannot allocate memory
> 6: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen() [0x53b853]]
> 5: [/lib64/libc.so.6(__libc_start_main+0xf5) [0x7fc787ed73d5]]
> 4: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(main+0xf03) [0x4977f3]]
> 3: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(pktgen_config_ports+0x1d02) [0x567832]]
> 2: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(__rte_panic+0xb8) [0x488bf2]]
> 1: [/home/frankli1/pktgen-dpdk/app/x86_64-native-linuxapp-gcc/app/pktgen(rte_dump_stack+0x16) [0x667ca6]] 
> 
> I haven't tried running pktgen with any other options, and I do believe my changes are incorporated properly, just wanted to bring this error to your attention in case it may be helpful for you.

The error is normally centered around the issue that no memory was allocated for socket 0 or all of the memory was consumed by previous allocations. To support jumbo frames I did need to increase the packet info structure to hold the largest frame. Please check to see if you can increase the amount of memory for socket 0 and socket 1 if you have two to see if that fixes the problem. I may have to rework this make jumbo frame support more dynamic.
> 
> Best,
> Frank
> 
> 
> On Fri, Nov 29, 2019 at 4:03 PM Wiles, Keith <keith.wiles@intel.com> wrote:
> 
> 
> > On Nov 19, 2019, at 6:47 PM, Frank Li <frank.li.65@gmail.com> wrote:
> > 
> > Current IPv6 functionality in pktgen is broken. This fix makes it so that
> > IPv6 addresses are properly set when using the set, sequence, and save
> > commands and that the IP header and UDP/TCP psuedo-header IPV6 addresses
> > are properly set.
> > 
> > To preserve the runtime commands, the `_atoip` function no longer takes
> > in flags to specify converting IPv4/6 addresses, and will try both,
> > returning, 4, 6, or -1 for a valid IPv4/6, invalid address, respectively.
> > 
> > Also print IPv6 addresses in UI properly.
> > 
> > Co-authored-by Valentin Andrei <vandrei@fb.com>
> > 
> > Signed-off-by: Frank Li <frank.li.65@gmail.com>
> > ---
> 
> I applied this patch and if you have time do a pull on the pktgen repo and switch over to the ‘dev’ branch and see if this version works for you.
> 
> Regards,
> Keith
> 

Regards,
Keith


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

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-19 23:42 [dpdk-dev] [PATCH] [pktgen] Fix IPv6 addressing for set/sequence/save commands, packet headers, UI printing Frank Li
2019-11-20  0:47 ` [dpdk-dev] [PATCH v2] " Frank Li
2019-11-30  0:03   ` Wiles, Keith
2019-12-02 21:20     ` Frank Li
2019-12-02 23:43       ` Wiles, Keith

DPDK patches and discussions

Archives are clonable:
	git clone --mirror http://inbox.dpdk.org/dev/0 dev/git/0.git

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


Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


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