Prepare for bucket resume tests for established TCP sockets by creating established sockets. Collect socket fds from connect() and accept() sides and pass them to test cases. Signed-off-by: Jordan Rife --- .../bpf/prog_tests/sock_iter_batch.c | 83 ++++++++++++++++++- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c b/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c index 18da2d901af7..d21b7a918700 100644 --- a/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c +++ b/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c @@ -153,8 +153,66 @@ static void check_n_were_seen_once(int *fds, int fds_len, int n, ASSERT_EQ(seen_once, n, "seen_once"); } +static int accept_from_one(int *server_fds, int server_fds_len) +{ + int fd; + int i; + + for (i = 0; i < server_fds_len; i++) { + fd = accept(server_fds[i], NULL, NULL); + if (fd >= 0) + return fd; + if (!ASSERT_EQ(errno, EWOULDBLOCK, "EWOULDBLOCK")) + return -1; + } + + return -1; +} + +static int *connect_to_server(int family, int sock_type, const char *addr, + __u16 port, int nr_connects, int *server_fds, + int server_fds_len) +{ + struct network_helper_opts opts = { + .timeout_ms = 0, + }; + int *established_socks; + int i; + + /* Make sure accept() doesn't block. */ + for (i = 0; i < server_fds_len; i++) + if (!ASSERT_OK(fcntl(server_fds[i], F_SETFL, O_NONBLOCK), + "fcntl(O_NONBLOCK)")) + return NULL; + + established_socks = malloc(sizeof(int) * nr_connects*2); + if (!ASSERT_OK_PTR(established_socks, "established_socks")) + return NULL; + + i = 0; + + while (nr_connects--) { + established_socks[i] = connect_to_addr_str(family, sock_type, + addr, port, &opts); + if (!ASSERT_OK_FD(established_socks[i], "connect_to_addr_str")) + goto error; + i++; + established_socks[i] = accept_from_one(server_fds, + server_fds_len); + if (!ASSERT_OK_FD(established_socks[i], "accept_from_one")) + goto error; + i++; + } + + return established_socks; +error: + free_fds(established_socks, i); + return NULL; +} + static void remove_seen(int family, int sock_type, const char *addr, __u16 port, - int *socks, int socks_len, struct sock_count *counts, + int *socks, int socks_len, int *established_socks, + int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd) { int close_idx; @@ -185,6 +243,7 @@ static void remove_seen(int family, int sock_type, const char *addr, __u16 port, static void remove_unseen(int family, int sock_type, const char *addr, __u16 port, int *socks, int socks_len, + int *established_socks, int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd) { @@ -217,6 +276,7 @@ static void remove_unseen(int family, int sock_type, const char *addr, static void remove_all(int family, int sock_type, const char *addr, __u16 port, int *socks, int socks_len, + int *established_socks, int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd) { @@ -244,7 +304,8 @@ static void remove_all(int family, int sock_type, const char *addr, } static void add_some(int family, int sock_type, const char *addr, __u16 port, - int *socks, int socks_len, struct sock_count *counts, + int *socks, int socks_len, int *established_socks, + int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd) { int *new_socks = NULL; @@ -274,6 +335,7 @@ static void add_some(int family, int sock_type, const char *addr, __u16 port, static void force_realloc(int family, int sock_type, const char *addr, __u16 port, int *socks, int socks_len, + int *established_socks, int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd) { @@ -302,10 +364,12 @@ static void force_realloc(int family, int sock_type, const char *addr, struct test_case { void (*test)(int family, int sock_type, const char *addr, __u16 port, - int *socks, int socks_len, struct sock_count *counts, + int *socks, int socks_len, int *established_socks, + int established_socks_len, struct sock_count *counts, int counts_len, struct bpf_link *link, int iter_fd); const char *description; int ehash_buckets; + int connections; int init_socks; int max_socks; int sock_type; @@ -416,6 +480,7 @@ static void do_resume_test(struct test_case *tc) static const __u16 port = 10001; struct nstoken *nstoken = NULL; struct bpf_link *link = NULL; + int *established_fds = NULL; int err, iter_fd = -1; const char *addr; int *fds = NULL; @@ -444,6 +509,14 @@ static void do_resume_test(struct test_case *tc) tc->init_socks); if (!ASSERT_OK_PTR(fds, "start_reuseport_server")) goto done; + if (tc->connections) { + established_fds = connect_to_server(tc->family, tc->sock_type, + addr, port, + tc->connections, fds, + tc->init_socks); + if (!ASSERT_OK_PTR(established_fds, "connect_to_server")) + goto done; + } skel->rodata->ports[0] = 0; skel->rodata->ports[1] = 0; skel->rodata->sf = tc->family; @@ -465,13 +538,15 @@ static void do_resume_test(struct test_case *tc) goto done; tc->test(tc->family, tc->sock_type, addr, port, fds, tc->init_socks, - counts, tc->max_socks, link, iter_fd); + established_fds, tc->connections*2, counts, tc->max_socks, + link, iter_fd); done: close_netns(nstoken); SYS_NOFAIL("ip netns del " TEST_CHILD_NS); SYS_NOFAIL("sysctl -w net.ipv4.tcp_child_ehash_entries=0"); free(counts); free_fds(fds, tc->init_socks); + free_fds(established_fds, tc->connections*2); if (iter_fd >= 0) close(iter_fd); bpf_link__destroy(link); -- 2.43.0