From: Robin Jarry <ro...@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 <ro...@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