diff options
author | Sowmini Varadhan <sowmini.varadhan@oracle.com> | 2017-12-25 17:43:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-02 13:26:58 -0500 |
commit | d36f45e5b46723cf2d4147173e18c52d4143176d (patch) | |
tree | cfa17d9a6de3dc8f3702e753b6b786e3d650606a /tools/testing/selftests/net/msg_zerocopy.c | |
parent | 41584f67d243a87105536bfab6865b6c4e23f365 (diff) |
selftests/net: fix bugs in address and port initialization
Address/port initialization should work correctly regardless
of the order in which command line arguments are supplied,
E.g, cfg_port should be used to connect to the remote host
even if it is processed after -D, src/dst address initialization
should not require that [-4|-6] be specified before
the -S or -D args, receiver should be able to bind to *.<cfg_port>
Achieve this by making sure that the address/port structures
are initialized after all command line options are parsed.
Store cfg_port in host-byte order, and use htons()
to set up the sin_port/sin6_port before bind/connect,
so that the network system calls get the correct values
in network-byte order.
Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/net/msg_zerocopy.c')
-rw-r--r-- | tools/testing/selftests/net/msg_zerocopy.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/tools/testing/selftests/net/msg_zerocopy.c b/tools/testing/selftests/net/msg_zerocopy.c index 3ab6ec403905..e11fe84de0fd 100644 --- a/tools/testing/selftests/net/msg_zerocopy.c +++ b/tools/testing/selftests/net/msg_zerocopy.c | |||
@@ -259,22 +259,28 @@ static int setup_ip6h(struct ipv6hdr *ip6h, uint16_t payload_len) | |||
259 | return sizeof(*ip6h); | 259 | return sizeof(*ip6h); |
260 | } | 260 | } |
261 | 261 | ||
262 | static void setup_sockaddr(int domain, const char *str_addr, void *sockaddr) | 262 | |
263 | static void setup_sockaddr(int domain, const char *str_addr, | ||
264 | struct sockaddr_storage *sockaddr) | ||
263 | { | 265 | { |
264 | struct sockaddr_in6 *addr6 = (void *) sockaddr; | 266 | struct sockaddr_in6 *addr6 = (void *) sockaddr; |
265 | struct sockaddr_in *addr4 = (void *) sockaddr; | 267 | struct sockaddr_in *addr4 = (void *) sockaddr; |
266 | 268 | ||
267 | switch (domain) { | 269 | switch (domain) { |
268 | case PF_INET: | 270 | case PF_INET: |
271 | memset(addr4, 0, sizeof(*addr4)); | ||
269 | addr4->sin_family = AF_INET; | 272 | addr4->sin_family = AF_INET; |
270 | addr4->sin_port = htons(cfg_port); | 273 | addr4->sin_port = htons(cfg_port); |
271 | if (inet_pton(AF_INET, str_addr, &(addr4->sin_addr)) != 1) | 274 | if (str_addr && |
275 | inet_pton(AF_INET, str_addr, &(addr4->sin_addr)) != 1) | ||
272 | error(1, 0, "ipv4 parse error: %s", str_addr); | 276 | error(1, 0, "ipv4 parse error: %s", str_addr); |
273 | break; | 277 | break; |
274 | case PF_INET6: | 278 | case PF_INET6: |
279 | memset(addr6, 0, sizeof(*addr6)); | ||
275 | addr6->sin6_family = AF_INET6; | 280 | addr6->sin6_family = AF_INET6; |
276 | addr6->sin6_port = htons(cfg_port); | 281 | addr6->sin6_port = htons(cfg_port); |
277 | if (inet_pton(AF_INET6, str_addr, &(addr6->sin6_addr)) != 1) | 282 | if (str_addr && |
283 | inet_pton(AF_INET6, str_addr, &(addr6->sin6_addr)) != 1) | ||
278 | error(1, 0, "ipv6 parse error: %s", str_addr); | 284 | error(1, 0, "ipv6 parse error: %s", str_addr); |
279 | break; | 285 | break; |
280 | default: | 286 | default: |
@@ -603,6 +609,7 @@ static void parse_opts(int argc, char **argv) | |||
603 | sizeof(struct tcphdr) - | 609 | sizeof(struct tcphdr) - |
604 | 40 /* max tcp options */; | 610 | 40 /* max tcp options */; |
605 | int c; | 611 | int c; |
612 | char *daddr = NULL, *saddr = NULL; | ||
606 | 613 | ||
607 | cfg_payload_len = max_payload_len; | 614 | cfg_payload_len = max_payload_len; |
608 | 615 | ||
@@ -627,7 +634,7 @@ static void parse_opts(int argc, char **argv) | |||
627 | cfg_cpu = strtol(optarg, NULL, 0); | 634 | cfg_cpu = strtol(optarg, NULL, 0); |
628 | break; | 635 | break; |
629 | case 'D': | 636 | case 'D': |
630 | setup_sockaddr(cfg_family, optarg, &cfg_dst_addr); | 637 | daddr = optarg; |
631 | break; | 638 | break; |
632 | case 'i': | 639 | case 'i': |
633 | cfg_ifindex = if_nametoindex(optarg); | 640 | cfg_ifindex = if_nametoindex(optarg); |
@@ -638,7 +645,7 @@ static void parse_opts(int argc, char **argv) | |||
638 | cfg_cork_mixed = true; | 645 | cfg_cork_mixed = true; |
639 | break; | 646 | break; |
640 | case 'p': | 647 | case 'p': |
641 | cfg_port = htons(strtoul(optarg, NULL, 0)); | 648 | cfg_port = strtoul(optarg, NULL, 0); |
642 | break; | 649 | break; |
643 | case 'r': | 650 | case 'r': |
644 | cfg_rx = true; | 651 | cfg_rx = true; |
@@ -647,7 +654,7 @@ static void parse_opts(int argc, char **argv) | |||
647 | cfg_payload_len = strtoul(optarg, NULL, 0); | 654 | cfg_payload_len = strtoul(optarg, NULL, 0); |
648 | break; | 655 | break; |
649 | case 'S': | 656 | case 'S': |
650 | setup_sockaddr(cfg_family, optarg, &cfg_src_addr); | 657 | saddr = optarg; |
651 | break; | 658 | break; |
652 | case 't': | 659 | case 't': |
653 | cfg_runtime_ms = 200 + strtoul(optarg, NULL, 10) * 1000; | 660 | cfg_runtime_ms = 200 + strtoul(optarg, NULL, 10) * 1000; |
@@ -660,6 +667,8 @@ static void parse_opts(int argc, char **argv) | |||
660 | break; | 667 | break; |
661 | } | 668 | } |
662 | } | 669 | } |
670 | setup_sockaddr(cfg_family, daddr, &cfg_dst_addr); | ||
671 | setup_sockaddr(cfg_family, saddr, &cfg_src_addr); | ||
663 | 672 | ||
664 | if (cfg_payload_len > max_payload_len) | 673 | if (cfg_payload_len > max_payload_len) |
665 | error(1, 0, "-s: payload exceeds max (%d)", max_payload_len); | 674 | error(1, 0, "-s: payload exceeds max (%d)", max_payload_len); |