selftests/bpf: Export send_recv_data helper
authorGeliang Tang <tanggeliang@kylinos.cn>
Thu, 11 Apr 2024 05:43:12 +0000 (13:43 +0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Thu, 11 Apr 2024 19:06:42 +0000 (12:06 -0700)
This patch extracts the code to send and receive data into a new
helper named send_recv_data() in network_helpers.c and export it
in network_helpers.h.

This helper will be used for MPTCP BPF selftests.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Link: https://lore.kernel.org/r/5231103be91fadcce3674a589542c63b6a5eedd4.1712813933.git.tanggeliang@kylinos.cn
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
tools/testing/selftests/bpf/network_helpers.c
tools/testing/selftests/bpf/network_helpers.h
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c

index 04175e16195a83fb5a3a46a1eb46c25492dcc7a4..dc1fd7af9c7a3af5ae11c81016cbbe6c7c6ebfb4 100644 (file)
@@ -545,3 +545,105 @@ int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param)
        close(sockfd);
        return 0;
 }
+
+struct send_recv_arg {
+       int             fd;
+       uint32_t        bytes;
+       int             stop;
+};
+
+static void *send_recv_server(void *arg)
+{
+       struct send_recv_arg *a = (struct send_recv_arg *)arg;
+       ssize_t nr_sent = 0, bytes = 0;
+       char batch[1500];
+       int err = 0, fd;
+
+       fd = accept(a->fd, NULL, NULL);
+       while (fd == -1) {
+               if (errno == EINTR)
+                       continue;
+               err = -errno;
+               goto done;
+       }
+
+       if (settimeo(fd, 0)) {
+               err = -errno;
+               goto done;
+       }
+
+       while (bytes < a->bytes && !READ_ONCE(a->stop)) {
+               nr_sent = send(fd, &batch,
+                              MIN(a->bytes - bytes, sizeof(batch)), 0);
+               if (nr_sent == -1 && errno == EINTR)
+                       continue;
+               if (nr_sent == -1) {
+                       err = -errno;
+                       break;
+               }
+               bytes += nr_sent;
+       }
+
+       if (bytes != a->bytes) {
+               log_err("send %zd expected %u", bytes, a->bytes);
+               if (!err)
+                       err = bytes > a->bytes ? -E2BIG : -EINTR;
+       }
+
+done:
+       if (fd >= 0)
+               close(fd);
+       if (err) {
+               WRITE_ONCE(a->stop, 1);
+               return ERR_PTR(err);
+       }
+       return NULL;
+}
+
+int send_recv_data(int lfd, int fd, uint32_t total_bytes)
+{
+       ssize_t nr_recv = 0, bytes = 0;
+       struct send_recv_arg arg = {
+               .fd     = lfd,
+               .bytes  = total_bytes,
+               .stop   = 0,
+       };
+       pthread_t srv_thread;
+       void *thread_ret;
+       char batch[1500];
+       int err = 0;
+
+       err = pthread_create(&srv_thread, NULL, send_recv_server, (void *)&arg);
+       if (err) {
+               log_err("Failed to pthread_create");
+               return err;
+       }
+
+       /* recv total_bytes */
+       while (bytes < total_bytes && !READ_ONCE(arg.stop)) {
+               nr_recv = recv(fd, &batch,
+                              MIN(total_bytes - bytes, sizeof(batch)), 0);
+               if (nr_recv == -1 && errno == EINTR)
+                       continue;
+               if (nr_recv == -1) {
+                       err = -errno;
+                       break;
+               }
+               bytes += nr_recv;
+       }
+
+       if (bytes != total_bytes) {
+               log_err("recv %zd expected %u", bytes, total_bytes);
+               if (!err)
+                       err = bytes > total_bytes ? -E2BIG : -EINTR;
+       }
+
+       WRITE_ONCE(arg.stop, 1);
+       pthread_join(srv_thread, &thread_ret);
+       if (IS_ERR(thread_ret)) {
+               log_err("Failed in thread_ret %ld", PTR_ERR(thread_ret));
+               err = err ? : PTR_ERR(thread_ret);
+       }
+
+       return err;
+}
index 6457445cc6e24d5028bebb8c59d463455b796425..70f4e4c927335ea9bd1589ebecffc0830ade8946 100644 (file)
@@ -76,6 +76,7 @@ struct nstoken;
  */
 struct nstoken *open_netns(const char *name);
 void close_netns(struct nstoken *token);
+int send_recv_data(int lfd, int fd, uint32_t total_bytes);
 
 static __u16 csum_fold(__u32 csum)
 {
index 64f172f02a9a2ff0c5952e5af09122595458479e..907bac46c774c8857e8179f0097ce597590cbba9 100644 (file)
@@ -33,75 +33,15 @@ static int settcpca(int fd, const char *tcp_ca)
        return 0;
 }
 
-struct send_recv_arg {
-       int             fd;
-       uint32_t        bytes;
-       int             stop;
-};
-
-static void *server(void *arg)
-{
-       struct send_recv_arg *a = (struct send_recv_arg *)arg;
-       ssize_t nr_sent = 0, bytes = 0;
-       char batch[1500];
-       int err = 0, fd;
-
-       fd = accept(a->fd, NULL, NULL);
-       while (fd == -1) {
-               if (errno == EINTR)
-                       continue;
-               err = -errno;
-               goto done;
-       }
-
-       if (settimeo(fd, 0)) {
-               err = -errno;
-               goto done;
-       }
-
-       while (bytes < a->bytes && !READ_ONCE(a->stop)) {
-               nr_sent = send(fd, &batch,
-                              MIN(a->bytes - bytes, sizeof(batch)), 0);
-               if (nr_sent == -1 && errno == EINTR)
-                       continue;
-               if (nr_sent == -1) {
-                       err = -errno;
-                       break;
-               }
-               bytes += nr_sent;
-       }
-
-       ASSERT_EQ(bytes, a->bytes, "send");
-
-done:
-       if (fd >= 0)
-               close(fd);
-       if (err) {
-               WRITE_ONCE(a->stop, 1);
-               return ERR_PTR(err);
-       }
-       return NULL;
-}
-
 static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map)
 {
-       ssize_t nr_recv = 0, bytes = 0;
-       struct send_recv_arg arg = {
-               .bytes  = total_bytes,
-               .stop   = 0,
-       };
        int lfd = -1, fd = -1;
-       pthread_t srv_thread;
-       void *thread_ret;
-       char batch[1500];
        int err;
 
        lfd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
        if (!ASSERT_NEQ(lfd, -1, "socket"))
                return;
 
-       arg.fd = lfd;
-
        fd = socket(AF_INET6, SOCK_STREAM, 0);
        if (!ASSERT_NEQ(fd, -1, "socket")) {
                close(lfd);
@@ -133,26 +73,7 @@ static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map)
                        goto done;
        }
 
-       err = pthread_create(&srv_thread, NULL, server, (void *)&arg);
-       if (!ASSERT_OK(err, "pthread_create"))
-               goto done;
-
-       /* recv total_bytes */
-       while (bytes < total_bytes && !READ_ONCE(arg.stop)) {
-               nr_recv = recv(fd, &batch,
-                              MIN(total_bytes - bytes, sizeof(batch)), 0);
-               if (nr_recv == -1 && errno == EINTR)
-                       continue;
-               if (nr_recv == -1)
-                       break;
-               bytes += nr_recv;
-       }
-
-       ASSERT_EQ(bytes, total_bytes, "recv");
-
-       WRITE_ONCE(arg.stop, 1);
-       pthread_join(srv_thread, &thread_ret);
-       ASSERT_OK(IS_ERR(thread_ret), "thread_ret");
+       ASSERT_OK(send_recv_data(lfd, fd, total_bytes), "send_recv_data");
 
 done:
        close(lfd);