1818#include "bpf_rlimit.h"
1919#include "cgroup_helpers.h"
2020
21- static int start_server (const struct sockaddr * addr , socklen_t len )
21+ static int start_server (const struct sockaddr * addr , socklen_t len , bool dual )
2222{
23+ int mode = !dual ;
2324 int fd ;
2425
2526 fd = socket (addr -> sa_family , SOCK_STREAM , 0 );
@@ -28,6 +29,14 @@ static int start_server(const struct sockaddr *addr, socklen_t len)
2829 goto out ;
2930 }
3031
32+ if (addr -> sa_family == AF_INET6 ) {
33+ if (setsockopt (fd , IPPROTO_IPV6 , IPV6_V6ONLY , (char * )& mode ,
34+ sizeof (mode )) == -1 ) {
35+ log_err ("Failed to set the dual-stack mode" );
36+ goto close_out ;
37+ }
38+ }
39+
3140 if (bind (fd , addr , len ) == -1 ) {
3241 log_err ("Failed to bind server socket" );
3342 goto close_out ;
@@ -47,24 +56,17 @@ static int start_server(const struct sockaddr *addr, socklen_t len)
4756 return fd ;
4857}
4958
50- static int connect_to_server (int server_fd )
59+ static int connect_to_server (const struct sockaddr * addr , socklen_t len )
5160{
52- struct sockaddr_storage addr ;
53- socklen_t len = sizeof (addr );
5461 int fd = -1 ;
5562
56- if (getsockname (server_fd , (struct sockaddr * )& addr , & len )) {
57- log_err ("Failed to get server addr" );
58- goto out ;
59- }
60-
61- fd = socket (addr .ss_family , SOCK_STREAM , 0 );
63+ fd = socket (addr -> sa_family , SOCK_STREAM , 0 );
6264 if (fd == -1 ) {
6365 log_err ("Failed to create client socket" );
6466 goto out ;
6567 }
6668
67- if (connect (fd , (const struct sockaddr * )& addr , len ) == -1 ) {
69+ if (connect (fd , (const struct sockaddr * )addr , len ) == -1 ) {
6870 log_err ("Fail to connect to server" );
6971 goto close_out ;
7072 }
@@ -116,7 +118,8 @@ static int get_map_fd_by_prog_id(int prog_id, bool *xdp)
116118 return map_fd ;
117119}
118120
119- static int run_test (int server_fd , int results_fd , bool xdp )
121+ static int run_test (int server_fd , int results_fd , bool xdp ,
122+ const struct sockaddr * addr , socklen_t len )
120123{
121124 int client = -1 , srv_client = -1 ;
122125 int ret = 0 ;
@@ -142,7 +145,7 @@ static int run_test(int server_fd, int results_fd, bool xdp)
142145 goto err ;
143146 }
144147
145- client = connect_to_server (server_fd );
148+ client = connect_to_server (addr , len );
146149 if (client == -1 )
147150 goto err ;
148151
@@ -199,12 +202,30 @@ static int run_test(int server_fd, int results_fd, bool xdp)
199202 return ret ;
200203}
201204
205+ static bool get_port (int server_fd , in_port_t * port )
206+ {
207+ struct sockaddr_in addr ;
208+ socklen_t len = sizeof (addr );
209+
210+ if (getsockname (server_fd , (struct sockaddr * )& addr , & len )) {
211+ log_err ("Failed to get server addr" );
212+ return false;
213+ }
214+
215+ /* sin_port and sin6_port are located at the same offset. */
216+ * port = addr .sin_port ;
217+ return true;
218+ }
219+
202220int main (int argc , char * * argv )
203221{
204222 struct sockaddr_in addr4 ;
205223 struct sockaddr_in6 addr6 ;
224+ struct sockaddr_in addr4dual ;
225+ struct sockaddr_in6 addr6dual ;
206226 int server = -1 ;
207227 int server_v6 = -1 ;
228+ int server_dual = -1 ;
208229 int results = -1 ;
209230 int err = 0 ;
210231 bool xdp ;
@@ -224,25 +245,43 @@ int main(int argc, char **argv)
224245 addr4 .sin_family = AF_INET ;
225246 addr4 .sin_addr .s_addr = htonl (INADDR_LOOPBACK );
226247 addr4 .sin_port = 0 ;
248+ memcpy (& addr4dual , & addr4 , sizeof (addr4dual ));
227249
228250 memset (& addr6 , 0 , sizeof (addr6 ));
229251 addr6 .sin6_family = AF_INET6 ;
230252 addr6 .sin6_addr = in6addr_loopback ;
231253 addr6 .sin6_port = 0 ;
232254
233- server = start_server ((const struct sockaddr * )& addr4 , sizeof (addr4 ));
234- if (server == -1 )
255+ memset (& addr6dual , 0 , sizeof (addr6dual ));
256+ addr6dual .sin6_family = AF_INET6 ;
257+ addr6dual .sin6_addr = in6addr_any ;
258+ addr6dual .sin6_port = 0 ;
259+
260+ server = start_server ((const struct sockaddr * )& addr4 , sizeof (addr4 ),
261+ false);
262+ if (server == -1 || !get_port (server , & addr4 .sin_port ))
235263 goto err ;
236264
237265 server_v6 = start_server ((const struct sockaddr * )& addr6 ,
238- sizeof (addr6 ));
239- if (server_v6 == -1 )
266+ sizeof (addr6 ), false);
267+ if (server_v6 == -1 || !get_port (server_v6 , & addr6 .sin6_port ))
268+ goto err ;
269+
270+ server_dual = start_server ((const struct sockaddr * )& addr6dual ,
271+ sizeof (addr6dual ), true);
272+ if (server_dual == -1 || !get_port (server_dual , & addr4dual .sin_port ))
273+ goto err ;
274+
275+ if (run_test (server , results , xdp ,
276+ (const struct sockaddr * )& addr4 , sizeof (addr4 )))
240277 goto err ;
241278
242- if (run_test (server , results , xdp ))
279+ if (run_test (server_v6 , results , xdp ,
280+ (const struct sockaddr * )& addr6 , sizeof (addr6 )))
243281 goto err ;
244282
245- if (run_test (server_v6 , results , xdp ))
283+ if (run_test (server_dual , results , xdp ,
284+ (const struct sockaddr * )& addr4dual , sizeof (addr4dual )))
246285 goto err ;
247286
248287 printf ("ok\n" );
@@ -252,6 +291,7 @@ int main(int argc, char **argv)
252291out :
253292 close (server );
254293 close (server_v6 );
294+ close (server_dual );
255295 close (results );
256296 return err ;
257297}
0 commit comments