11// SPDX-License-Identifier: GPL-2.0
22// Copyright (c) 2024 Meta
33
4+ #include <poll.h>
45#include <test_progs.h>
56#include "network_helpers.h"
67#include "sock_iter_batch.skel.h"
@@ -153,8 +154,71 @@ static void check_n_were_seen_once(int *fds, int fds_len, int n,
153154 ASSERT_EQ (seen_once , n , "seen_once" );
154155}
155156
157+ static int accept_from_one (struct pollfd * server_poll_fds ,
158+ int server_poll_fds_len )
159+ {
160+ static const int poll_timeout_ms = 5000 ; /* 5s */
161+ int ret ;
162+ int i ;
163+
164+ ret = poll (server_poll_fds , server_poll_fds_len , poll_timeout_ms );
165+ if (!ASSERT_EQ (ret , 1 , "poll" ))
166+ return -1 ;
167+
168+ for (i = 0 ; i < server_poll_fds_len ; i ++ )
169+ if (server_poll_fds [i ].revents & POLLIN )
170+ return accept (server_poll_fds [i ].fd , NULL , NULL );
171+
172+ return -1 ;
173+ }
174+
175+ static int * connect_to_server (int family , int sock_type , const char * addr ,
176+ __u16 port , int nr_connects , int * server_fds ,
177+ int server_fds_len )
178+ {
179+ struct pollfd * server_poll_fds = NULL ;
180+ int * established_socks = NULL ;
181+ int i ;
182+
183+ server_poll_fds = calloc (server_fds_len , sizeof (* server_poll_fds ));
184+ if (!ASSERT_OK_PTR (server_poll_fds , "server_poll_fds" ))
185+ return NULL ;
186+
187+ for (i = 0 ; i < server_fds_len ; i ++ ) {
188+ server_poll_fds [i ].fd = server_fds [i ];
189+ server_poll_fds [i ].events = POLLIN ;
190+ }
191+
192+ i = 0 ;
193+
194+ established_socks = malloc (sizeof (* established_socks ) * nr_connects * 2 );
195+ if (!ASSERT_OK_PTR (established_socks , "established_socks" ))
196+ goto error ;
197+
198+ while (nr_connects -- ) {
199+ established_socks [i ] = connect_to_addr_str (family , sock_type ,
200+ addr , port , NULL );
201+ if (!ASSERT_OK_FD (established_socks [i ], "connect_to_addr_str" ))
202+ goto error ;
203+ i ++ ;
204+ established_socks [i ] = accept_from_one (server_poll_fds ,
205+ server_fds_len );
206+ if (!ASSERT_OK_FD (established_socks [i ], "accept_from_one" ))
207+ goto error ;
208+ i ++ ;
209+ }
210+
211+ free (server_poll_fds );
212+ return established_socks ;
213+ error :
214+ free_fds (established_socks , i );
215+ free (server_poll_fds );
216+ return NULL ;
217+ }
218+
156219static void remove_seen (int family , int sock_type , const char * addr , __u16 port ,
157- int * socks , int socks_len , struct sock_count * counts ,
220+ int * socks , int socks_len , int * established_socks ,
221+ int established_socks_len , struct sock_count * counts ,
158222 int counts_len , struct bpf_link * link , int iter_fd )
159223{
160224 int close_idx ;
@@ -185,6 +249,7 @@ static void remove_seen(int family, int sock_type, const char *addr, __u16 port,
185249
186250static void remove_unseen (int family , int sock_type , const char * addr ,
187251 __u16 port , int * socks , int socks_len ,
252+ int * established_socks , int established_socks_len ,
188253 struct sock_count * counts , int counts_len ,
189254 struct bpf_link * link , int iter_fd )
190255{
@@ -217,6 +282,7 @@ static void remove_unseen(int family, int sock_type, const char *addr,
217282
218283static void remove_all (int family , int sock_type , const char * addr ,
219284 __u16 port , int * socks , int socks_len ,
285+ int * established_socks , int established_socks_len ,
220286 struct sock_count * counts , int counts_len ,
221287 struct bpf_link * link , int iter_fd )
222288{
@@ -244,7 +310,8 @@ static void remove_all(int family, int sock_type, const char *addr,
244310}
245311
246312static void add_some (int family , int sock_type , const char * addr , __u16 port ,
247- int * socks , int socks_len , struct sock_count * counts ,
313+ int * socks , int socks_len , int * established_socks ,
314+ int established_socks_len , struct sock_count * counts ,
248315 int counts_len , struct bpf_link * link , int iter_fd )
249316{
250317 int * new_socks = NULL ;
@@ -274,6 +341,7 @@ static void add_some(int family, int sock_type, const char *addr, __u16 port,
274341
275342static void force_realloc (int family , int sock_type , const char * addr ,
276343 __u16 port , int * socks , int socks_len ,
344+ int * established_socks , int established_socks_len ,
277345 struct sock_count * counts , int counts_len ,
278346 struct bpf_link * link , int iter_fd )
279347{
@@ -302,10 +370,12 @@ static void force_realloc(int family, int sock_type, const char *addr,
302370
303371struct test_case {
304372 void (* test )(int family , int sock_type , const char * addr , __u16 port ,
305- int * socks , int socks_len , struct sock_count * counts ,
373+ int * socks , int socks_len , int * established_socks ,
374+ int established_socks_len , struct sock_count * counts ,
306375 int counts_len , struct bpf_link * link , int iter_fd );
307376 const char * description ;
308377 int ehash_buckets ;
378+ int connections ;
309379 int init_socks ;
310380 int max_socks ;
311381 int sock_type ;
@@ -416,6 +486,7 @@ static void do_resume_test(struct test_case *tc)
416486 static const __u16 port = 10001 ;
417487 struct nstoken * nstoken = NULL ;
418488 struct bpf_link * link = NULL ;
489+ int * established_fds = NULL ;
419490 int err , iter_fd = -1 ;
420491 const char * addr ;
421492 int * fds = NULL ;
@@ -444,6 +515,14 @@ static void do_resume_test(struct test_case *tc)
444515 tc -> init_socks );
445516 if (!ASSERT_OK_PTR (fds , "start_reuseport_server" ))
446517 goto done ;
518+ if (tc -> connections ) {
519+ established_fds = connect_to_server (tc -> family , tc -> sock_type ,
520+ addr , port ,
521+ tc -> connections , fds ,
522+ tc -> init_socks );
523+ if (!ASSERT_OK_PTR (established_fds , "connect_to_server" ))
524+ goto done ;
525+ }
447526 skel -> rodata -> ports [0 ] = 0 ;
448527 skel -> rodata -> ports [1 ] = 0 ;
449528 skel -> rodata -> sf = tc -> family ;
@@ -465,13 +544,15 @@ static void do_resume_test(struct test_case *tc)
465544 goto done ;
466545
467546 tc -> test (tc -> family , tc -> sock_type , addr , port , fds , tc -> init_socks ,
468- counts , tc -> max_socks , link , iter_fd );
547+ established_fds , tc -> connections * 2 , counts , tc -> max_socks ,
548+ link , iter_fd );
469549done :
470550 close_netns (nstoken );
471551 SYS_NOFAIL ("ip netns del " TEST_CHILD_NS );
472552 SYS_NOFAIL ("sysctl -w net.ipv4.tcp_child_ehash_entries=0" );
473553 free (counts );
474554 free_fds (fds , tc -> init_socks );
555+ free_fds (established_fds , tc -> connections * 2 );
475556 if (iter_fd >= 0 )
476557 close (iter_fd );
477558 bpf_link__destroy (link );
0 commit comments