Commit dc34e44e authored by Geliang Tang's avatar Geliang Tang Committed by Martin KaFai Lau

selftests/bpf: Export send_recv_data helper

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: default avatarGeliang Tang <tanggeliang@kylinos.cn>
Link: https://lore.kernel.org/r/5231103be91fadcce3674a589542c63b6a5eedd4.1712813933.git.tanggeliang@kylinos.cnSigned-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent 68acca6e
...@@ -545,3 +545,105 @@ int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param) ...@@ -545,3 +545,105 @@ int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param)
close(sockfd); close(sockfd);
return 0; 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;
}
...@@ -76,6 +76,7 @@ struct nstoken; ...@@ -76,6 +76,7 @@ struct nstoken;
*/ */
struct nstoken *open_netns(const char *name); struct nstoken *open_netns(const char *name);
void close_netns(struct nstoken *token); void close_netns(struct nstoken *token);
int send_recv_data(int lfd, int fd, uint32_t total_bytes);
static __u16 csum_fold(__u32 csum) static __u16 csum_fold(__u32 csum)
{ {
......
...@@ -33,75 +33,15 @@ static int settcpca(int fd, const char *tcp_ca) ...@@ -33,75 +33,15 @@ static int settcpca(int fd, const char *tcp_ca)
return 0; 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) 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; int lfd = -1, fd = -1;
pthread_t srv_thread;
void *thread_ret;
char batch[1500];
int err; int err;
lfd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0); lfd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
if (!ASSERT_NEQ(lfd, -1, "socket")) if (!ASSERT_NEQ(lfd, -1, "socket"))
return; return;
arg.fd = lfd;
fd = socket(AF_INET6, SOCK_STREAM, 0); fd = socket(AF_INET6, SOCK_STREAM, 0);
if (!ASSERT_NEQ(fd, -1, "socket")) { if (!ASSERT_NEQ(fd, -1, "socket")) {
close(lfd); close(lfd);
...@@ -133,26 +73,7 @@ static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map) ...@@ -133,26 +73,7 @@ static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map)
goto done; goto done;
} }
err = pthread_create(&srv_thread, NULL, server, (void *)&arg); ASSERT_OK(send_recv_data(lfd, fd, total_bytes), "send_recv_data");
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");
done: done:
close(lfd); close(lfd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment