[PATCH dpdk v3 09/17] cmdline: replace in6_addr with rte_ipv6_addr

Robin Jarry rjarry at redhat.com
Thu Oct 10 21:41:39 CEST 2024


From: Robin Jarry <robin at jarry.cc>

The previous commits introduced a new rte_ipv6_addr structure without
any alignment requirements. It is not compatible with the in6_addr POSIX
type available in netinet/in.h.

The main issue is that in6_addr is not uniform on all platforms which
causes unaligned access warnings when compiling without
-Wno-address-of-packed-member (set in dpdk by default).

In order to have a consistent code base, replace in6_addr with
rte_ipv6_addr in the cmdline library. Update all code accordingly.

Signed-off-by: Robin Jarry <robin at jarry.cc>
---

Notes:
    v3: new patch

 app/graph/ethdev.c                     |  4 +--
 app/graph/ip6_route.c                  |  6 ++--
 app/graph/neigh.c                      |  2 +-
 app/test-pmd/cmdline.c                 |  4 +--
 app/test-pmd/cmdline_flow.c            | 14 +++-----
 app/test-pmd/testpmd.h                 | 16 ++++-----
 app/test/test_cmdline_ipaddr.c         | 49 ++++----------------------
 doc/guides/rel_notes/release_24_11.rst |  1 +
 examples/cmdline/commands.c            | 30 +++-------------
 lib/cmdline/cmdline_parse_ipaddr.h     |  3 +-
 10 files changed, 33 insertions(+), 96 deletions(-)

diff --git a/app/graph/ethdev.c b/app/graph/ethdev.c
index cfc1b1856910..13ed791412e1 100644
--- a/app/graph/ethdev.c
+++ b/app/graph/ethdev.c
@@ -627,10 +627,10 @@ cmd_ethdev_dev_ip6_addr_add_parsed(void *parsed_result, __rte_unused struct cmdl
 	int rc = -EINVAL, i;
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		config.ip[i] = res->ip.addr.ipv6.s6_addr[i];
+		config.ip[i] = res->ip.addr.ipv6.a[i];
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		config.mask[i] = res->mask.addr.ipv6.s6_addr[i];
+		config.mask[i] = res->mask.addr.ipv6.a[i];
 
 	rc = ethdev_ip6_addr_add(res->dev, &config);
 	if (rc < 0)
diff --git a/app/graph/ip6_route.c b/app/graph/ip6_route.c
index 834719ecaeb4..d91466cd78d6 100644
--- a/app/graph/ip6_route.c
+++ b/app/graph/ip6_route.c
@@ -157,13 +157,13 @@ cmd_ipv6_lookup_route_add_ipv6_parsed(void *parsed_result, __rte_unused struct c
 	int rc = -EINVAL, i;
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		config.ip[i] = res->ip.addr.ipv6.s6_addr[i];
+		config.ip[i] = res->ip.addr.ipv6.a[i];
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		config.mask[i] = res->mask.addr.ipv6.s6_addr[i];
+		config.mask[i] = res->mask.addr.ipv6.a[i];
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		config.gateway[i] = res->via_ip.addr.ipv6.s6_addr[i];
+		config.gateway[i] = res->via_ip.addr.ipv6.a[i];
 
 	rc = route_ip6_add(&config);
 	if (rc)
diff --git a/app/graph/neigh.c b/app/graph/neigh.c
index 79fd542c8948..eb7a09f1f145 100644
--- a/app/graph/neigh.c
+++ b/app/graph/neigh.c
@@ -266,7 +266,7 @@ cmd_neigh_add_ipv6_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
 	uint64_t mac;
 
 	for (i = 0; i < ETHDEV_IPV6_ADDR_LEN; i++)
-		ip[i] = res->ip.addr.ipv6.s6_addr[i];
+		ip[i] = res->ip.addr.ipv6.a[i];
 
 	if (parser_mac_read(&mac, res->mac)) {
 		printf(MSG_ARG_INVALID, "mac");
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b7759e38a871..9de626f20850 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -8603,9 +8603,7 @@ do { \
 #define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \
 do { \
 	if ((ip_addr).family == AF_INET6) \
-		rte_memcpy(&(ip), \
-				 &((ip_addr).addr.ipv6), \
-				 sizeof(struct in6_addr)); \
+		ip = ip_addr.addr.ipv6; \
 	else { \
 		fprintf(stderr, "invalid parameter.\n"); \
 		return; \
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d04280eb3e46..ff3041b37543 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -900,10 +900,8 @@ struct vxlan_encap_conf vxlan_encap_conf = {
 	.udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT),
 	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
 	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
-	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
-		"\x00\x00\x00\x00\x00\x00\x00\x01",
-	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
-		"\x00\x00\x00\x00\x00\x00\x11\x11",
+	.ipv6_src = RTE_IPV6_ADDR_LOOPBACK,
+	.ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111),
 	.vlan_tci = 0,
 	.ip_tos = 0,
 	.ip_ttl = 255,
@@ -934,10 +932,8 @@ struct nvgre_encap_conf nvgre_encap_conf = {
 	.tni = "\x00\x00\x00",
 	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
 	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
-	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
-		"\x00\x00\x00\x00\x00\x00\x00\x01",
-	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
-		"\x00\x00\x00\x00\x00\x00\x11\x11",
+	.ipv6_src = RTE_IPV6_ADDR_LOOPBACK,
+	.ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111),
 	.vlan_tci = 0,
 	.eth_src = "\x00\x00\x00\x00\x00\x00",
 	.eth_dst = "\xff\xff\xff\xff\xff\xff",
@@ -11890,7 +11886,7 @@ parse_ipv6_addr(struct context *ctx, const struct token *token,
 {
 	const struct arg *arg = pop_args(ctx);
 	char str2[len + 1];
-	struct in6_addr tmp;
+	struct rte_ipv6_addr tmp;
 	int ret;
 
 	(void)token;
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9facd7f281d9..2751c441112b 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -712,8 +712,8 @@ struct vxlan_encap_conf {
 	rte_be16_t udp_dst;
 	rte_be32_t ipv4_src;
 	rte_be32_t ipv4_dst;
-	uint8_t ipv6_src[16];
-	uint8_t ipv6_dst[16];
+	struct rte_ipv6_addr ipv6_src;
+	struct rte_ipv6_addr ipv6_dst;
 	rte_be16_t vlan_tci;
 	uint8_t ip_tos;
 	uint8_t ip_ttl;
@@ -730,8 +730,8 @@ struct nvgre_encap_conf {
 	uint8_t tni[3];
 	rte_be32_t ipv4_src;
 	rte_be32_t ipv4_dst;
-	uint8_t ipv6_src[16];
-	uint8_t ipv6_dst[16];
+	struct rte_ipv6_addr ipv6_src;
+	struct rte_ipv6_addr ipv6_dst;
 	rte_be16_t vlan_tci;
 	uint8_t eth_src[RTE_ETHER_ADDR_LEN];
 	uint8_t eth_dst[RTE_ETHER_ADDR_LEN];
@@ -762,8 +762,8 @@ struct mplsogre_encap_conf {
 	uint8_t label[3];
 	rte_be32_t ipv4_src;
 	rte_be32_t ipv4_dst;
-	uint8_t ipv6_src[16];
-	uint8_t ipv6_dst[16];
+	struct rte_ipv6_addr ipv6_src;
+	struct rte_ipv6_addr ipv6_dst;
 	rte_be16_t vlan_tci;
 	uint8_t eth_src[RTE_ETHER_ADDR_LEN];
 	uint8_t eth_dst[RTE_ETHER_ADDR_LEN];
@@ -786,8 +786,8 @@ struct mplsoudp_encap_conf {
 	rte_be16_t udp_dst;
 	rte_be32_t ipv4_src;
 	rte_be32_t ipv4_dst;
-	uint8_t ipv6_src[16];
-	uint8_t ipv6_dst[16];
+	struct rte_ipv6_addr ipv6_src;
+	struct rte_ipv6_addr ipv6_dst;
 	rte_be16_t vlan_tci;
 	uint8_t eth_src[RTE_ETHER_ADDR_LEN];
 	uint8_t eth_dst[RTE_ETHER_ADDR_LEN];
diff --git a/app/test/test_cmdline_ipaddr.c b/app/test/test_cmdline_ipaddr.c
index f540063508ae..dcd9c521eb5f 100644
--- a/app/test/test_cmdline_ipaddr.c
+++ b/app/test/test_cmdline_ipaddr.c
@@ -17,21 +17,7 @@
 					   (((c) & 0xff) << 16)  | \
 					   ((d) & 0xff)  << 24)}
 
-#define U16_SWAP(x) \
-		(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
-
-/* create IPv6 address, swapping bytes where needed */
-#ifndef s6_addr16
-#ifdef RTE_EXEC_ENV_WINDOWS
-#define s6_addr16 u.Word
-#else
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#endif
-#define IP6(a,b,c,d,e,f,g,h) .ipv6 = \
-		{.s6_addr16 = \
-		{U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\
-		 U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}}
+#define IP6(a, b, c, d, e, f, g, h) .ipv6 = RTE_IPV6(a, b, c, d, e, f, g, h)
 
 /** these are defined in netinet/in.h but not present in linux headers */
 #ifndef NIPQUAD
@@ -42,30 +28,8 @@
 	(unsigned)((unsigned char *)&addr)[1],	\
 	(unsigned)((unsigned char *)&addr)[2],	\
 	(unsigned)((unsigned char *)&addr)[3]
-
-#define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
-#define NIP6(addr)					\
-	(unsigned)((addr).s6_addr[0]),			\
-	(unsigned)((addr).s6_addr[1]),			\
-	(unsigned)((addr).s6_addr[2]),			\
-	(unsigned)((addr).s6_addr[3]),			\
-	(unsigned)((addr).s6_addr[4]),			\
-	(unsigned)((addr).s6_addr[5]),			\
-	(unsigned)((addr).s6_addr[6]),			\
-	(unsigned)((addr).s6_addr[7]),			\
-	(unsigned)((addr).s6_addr[8]),			\
-	(unsigned)((addr).s6_addr[9]),			\
-	(unsigned)((addr).s6_addr[10]),			\
-	(unsigned)((addr).s6_addr[11]),			\
-	(unsigned)((addr).s6_addr[12]),			\
-	(unsigned)((addr).s6_addr[13]),			\
-	(unsigned)((addr).s6_addr[14]),			\
-	(unsigned)((addr).s6_addr[15])
-
 #endif
 
-
-
 struct ipaddr_str {
 	const char * str;
 	cmdline_ipaddr_t addr;
@@ -273,8 +237,8 @@ dump_addr(cmdline_ipaddr_t addr)
 	}
 	case AF_INET6:
 	{
-		printf(NIP6_FMT " prefixlen=%u\n",
-				NIP6(addr.addr.ipv6), addr.prefixlen);
+		printf(RTE_IPV6_ADDR_FMT " prefixlen=%u\n",
+				RTE_IPV6_ADDR_SPLIT(&addr.addr.ipv6), addr.prefixlen);
 		break;
 	}
 	default:
@@ -303,8 +267,7 @@ is_addr_different(cmdline_ipaddr_t addr1, cmdline_ipaddr_t addr2)
 	/* IPv6 */
 	case AF_INET6:
 	{
-		if (memcmp(&addr1.addr.ipv6, &addr2.addr.ipv6,
-				sizeof(struct in6_addr)) != 0)
+		if (!rte_ipv6_addr_eq(&addr1.addr.ipv6, &addr2.addr.ipv6))
 			return 1;
 		break;
 	}
@@ -476,7 +439,7 @@ test_parse_ipaddr_valid(void)
 				return -1;
 			}
 			if (ret != -1 &&
-					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
+					!rte_ipv6_addr_eq(&result.addr.ipv6, &tmp.addr.ipv6)) {
 				printf("Error: result mismatch when parsing %s as %s!\n",
 						ipaddr_garbage_addr6_strs[i], buf);
 				return -1;
@@ -561,7 +524,7 @@ test_parse_ipaddr_valid(void)
 				return -1;
 			}
 			if (ret != -1 &&
-					memcmp(&result.addr.ipv6, &tmp.addr.ipv6, sizeof(struct in6_addr))) {
+					!rte_ipv6_addr_eq(&result.addr.ipv6, &tmp.addr.ipv6)) {
 				printf("Error: result mismatch when parsing %s as %s!\n",
 						ipaddr_garbage_network6_strs[i], buf);
 				return -1;
diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst
index dc8926a6078e..f5a2ac3cfb4f 100644
--- a/doc/guides/rel_notes/release_24_11.rst
+++ b/doc/guides/rel_notes/release_24_11.rst
@@ -145,6 +145,7 @@ API Changes
 * net: IPv6 related symbols were moved from ``<rte_ip.h>`` to the new ``<rte_ip6.h>`` header.
 * net: The ``rte_ipv6_hdr`` structure was modified to use ``struct rte_ipv6_addr`` instead of ``uint8_t[16]`` fields.
 * rib6,fib6,lpm6: All public API functions were modified to use ``struct rte_ipv6_addr`` instead of ``uint8_t[16]`` parameters.
+* cmdline: ``cmdline_ipaddr_t`` was modified to use ``struct rte_ipv6_addr`` instead of ``in6_addr``.
 
 ABI Changes
 -----------
diff --git a/examples/cmdline/commands.c b/examples/cmdline/commands.c
index aec151d08987..09a42a9917cb 100644
--- a/examples/cmdline/commands.c
+++ b/examples/cmdline/commands.c
@@ -33,28 +33,6 @@ struct object_list global_obj_list;
 	(unsigned)((unsigned char *)&addr)[3]
 #endif
 
-#ifndef NIP6
-#define NIP6_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
-#define NIP6(addr)					\
-	(unsigned)((addr).s6_addr[0]),			\
-	(unsigned)((addr).s6_addr[1]),			\
-	(unsigned)((addr).s6_addr[2]),			\
-	(unsigned)((addr).s6_addr[3]),			\
-	(unsigned)((addr).s6_addr[4]),			\
-	(unsigned)((addr).s6_addr[5]),			\
-	(unsigned)((addr).s6_addr[6]),			\
-	(unsigned)((addr).s6_addr[7]),			\
-	(unsigned)((addr).s6_addr[8]),			\
-	(unsigned)((addr).s6_addr[9]),			\
-	(unsigned)((addr).s6_addr[10]),			\
-	(unsigned)((addr).s6_addr[11]),			\
-	(unsigned)((addr).s6_addr[12]),			\
-	(unsigned)((addr).s6_addr[13]),			\
-	(unsigned)((addr).s6_addr[14]),			\
-	(unsigned)((addr).s6_addr[15])
-#endif
-
-
 /**********************************************************/
 
 /* Show or delete tokens. 8< */
@@ -74,8 +52,8 @@ static void cmd_obj_del_show_parsed(void *parsed_result,
 		snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT,
 			 NIPQUAD(res->obj->ip.addr.ipv4));
 	else
-		snprintf(ip_str, sizeof(ip_str), NIP6_FMT,
-			 NIP6(res->obj->ip.addr.ipv6));
+		snprintf(ip_str, sizeof(ip_str), RTE_IPV6_ADDR_FMT,
+			 RTE_IPV6_ADDR_SPLIT(&res->obj->ip.addr.ipv6));
 
 	if (strcmp(res->action, "del") == 0) {
 		SLIST_REMOVE(&global_obj_list, res->obj, object, next);
@@ -145,8 +123,8 @@ static void cmd_obj_add_parsed(void *parsed_result,
 		snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT,
 			 NIPQUAD(o->ip.addr.ipv4));
 	else
-		snprintf(ip_str, sizeof(ip_str), NIP6_FMT,
-			 NIP6(o->ip.addr.ipv6));
+		snprintf(ip_str, sizeof(ip_str), RTE_IPV6_ADDR_FMT,
+			 RTE_IPV6_ADDR_SPLIT(&o->ip.addr.ipv6));
 
 	cmdline_printf(cl, "Object %s added, ip=%s\n",
 		       o->name, ip_str);
diff --git a/lib/cmdline/cmdline_parse_ipaddr.h b/lib/cmdline/cmdline_parse_ipaddr.h
index 0118c31d4484..8653de8237fc 100644
--- a/lib/cmdline/cmdline_parse_ipaddr.h
+++ b/lib/cmdline/cmdline_parse_ipaddr.h
@@ -9,6 +9,7 @@
 
 #include <cmdline_parse.h>
 #include <rte_ip.h>
+#include <rte_ip6.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,7 +23,7 @@ struct cmdline_ipaddr {
 	uint8_t family;
 	union {
 		struct in_addr ipv4;
-		struct in6_addr ipv6;
+		struct rte_ipv6_addr ipv6;
 	} addr;
 	unsigned int prefixlen; /* in case of network only */
 };
-- 
2.46.2



More information about the dev mailing list