@@ -49,8 +49,9 @@ static void __exit_with_error(int error, const char *file, const char *func, int
4949#define exit_with_error (error ) __exit_with_error(error, __FILE__, __func__, __LINE__)
5050
5151#define print_ksft_result (void )\
52- (ksft_test_result_pass("PASS: %s %s %s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\
53- "NOPOLL", opt_teardown ? "Socket Teardown" : ""))
52+ (ksft_test_result_pass("PASS: %s %s %s%s\n", uut ? "DRV" : "SKB", opt_poll ? "POLL" :\
53+ "NOPOLL", opt_teardown ? "Socket Teardown" : "",\
54+ opt_bidi ? "Bi-directional Sockets" : ""))
5455
5556static void pthread_init_mutex (void )
5657{
@@ -256,8 +257,13 @@ static int xsk_configure_socket(struct ifobject *ifobject)
256257 cfg .xdp_flags = opt_xdp_flags ;
257258 cfg .bind_flags = opt_xdp_bind_flags ;
258259
259- rxr = (ifobject -> fv .vector == rx ) ? & ifobject -> xsk -> rx : NULL ;
260- txr = (ifobject -> fv .vector == tx ) ? & ifobject -> xsk -> tx : NULL ;
260+ if (!opt_bidi ) {
261+ rxr = (ifobject -> fv .vector == rx ) ? & ifobject -> xsk -> rx : NULL ;
262+ txr = (ifobject -> fv .vector == tx ) ? & ifobject -> xsk -> tx : NULL ;
263+ } else {
264+ rxr = & ifobject -> xsk -> rx ;
265+ txr = & ifobject -> xsk -> tx ;
266+ }
261267
262268 ret = xsk_socket__create (& ifobject -> xsk -> xsk , ifobject -> ifname ,
263269 opt_queue , ifobject -> umem -> umem , rxr , txr , & cfg );
@@ -276,6 +282,7 @@ static struct option long_options[] = {
276282 {"xdp-native" , no_argument , 0 , 'N' },
277283 {"copy" , no_argument , 0 , 'c' },
278284 {"tear-down" , no_argument , 0 , 'T' },
285+ {"bidi" , optional_argument , 0 , 'B' },
279286 {"debug" , optional_argument , 0 , 'D' },
280287 {"tx-pkt-count" , optional_argument , 0 , 'C' },
281288 {0 , 0 , 0 , 0 }
@@ -293,6 +300,7 @@ static void usage(const char *prog)
293300 " -N, --xdp-native=n Enforce XDP DRV (native) mode\n"
294301 " -c, --copy Force copy mode\n"
295302 " -T, --tear-down Tear down sockets by repeatedly recreating them\n"
303+ " -B, --bidi Bi-directional sockets test\n"
296304 " -D, --debug Debug mode - dump packets L2 - L5\n"
297305 " -C, --tx-pkt-count=n Number of packets to send\n" ;
298306 ksft_print_msg (str , prog );
@@ -383,7 +391,7 @@ static void parse_command_line(int argc, char **argv)
383391 opterr = 0 ;
384392
385393 for (;;) {
386- c = getopt_long (argc , argv , "i:q:pSNcTDC :" , long_options , & option_index );
394+ c = getopt_long (argc , argv , "i:q:pSNcTBDC :" , long_options , & option_index );
387395
388396 if (c == -1 )
389397 break ;
@@ -424,6 +432,9 @@ static void parse_command_line(int argc, char **argv)
424432 case 'T' :
425433 opt_teardown = 1 ;
426434 break ;
435+ case 'B' :
436+ opt_bidi = 1 ;
437+ break ;
427438 case 'D' :
428439 debug_pkt_dump = 1 ;
429440 break ;
@@ -733,22 +744,25 @@ static void *worker_testapp_validate(void *arg)
733744 struct generic_data * data = (struct generic_data * )malloc (sizeof (struct generic_data ));
734745 struct iphdr * ip_hdr = (struct iphdr * )(pkt_data + sizeof (struct ethhdr ));
735746 struct ethhdr * eth_hdr = (struct ethhdr * )pkt_data ;
736- void * bufs ;
747+ void * bufs = NULL ;
737748
738749 pthread_attr_setstacksize (& attr , THREAD_STACK );
739750
740- bufs = mmap (NULL , num_frames * XSK_UMEM__DEFAULT_FRAME_SIZE ,
741- PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
742- if (bufs == MAP_FAILED )
743- exit_with_error (errno );
751+ if (!bidi_pass ) {
752+ bufs = mmap (NULL , num_frames * XSK_UMEM__DEFAULT_FRAME_SIZE ,
753+ PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
754+ if (bufs == MAP_FAILED )
755+ exit_with_error (errno );
744756
745- if (strcmp (((struct ifobject * )arg )-> nsname , "" ))
746- switch_namespace (((struct ifobject * )arg )-> ifdict_index );
757+ if (strcmp (((struct ifobject * )arg )-> nsname , "" ))
758+ switch_namespace (((struct ifobject * )arg )-> ifdict_index );
759+ }
747760
748761 if (((struct ifobject * )arg )-> fv .vector == tx ) {
749762 int spinningrxctr = 0 ;
750763
751- thread_common_ops (arg , bufs , & sync_mutex_tx , & spinning_tx );
764+ if (!bidi_pass )
765+ thread_common_ops (arg , bufs , & sync_mutex_tx , & spinning_tx );
752766
753767 while (atomic_load (& spinning_rx ) && spinningrxctr < SOCK_RECONF_CTR ) {
754768 spinningrxctr ++ ;
@@ -778,7 +792,8 @@ static void *worker_testapp_validate(void *arg)
778792 struct pollfd fds [MAX_SOCKS ] = { };
779793 int ret ;
780794
781- thread_common_ops (arg , bufs , & sync_mutex_tx , & spinning_rx );
795+ if (!bidi_pass )
796+ thread_common_ops (arg , bufs , & sync_mutex_tx , & spinning_rx );
782797
783798 ksft_print_msg ("Interface [%s] vector [Rx]\n" , ((struct ifobject * )arg )-> ifname );
784799 xsk_populate_fill_ring (((struct ifobject * )arg )-> umem );
@@ -817,8 +832,10 @@ static void *worker_testapp_validate(void *arg)
817832 ksft_print_msg ("Destroying socket\n" );
818833 }
819834
820- xsk_socket__delete (((struct ifobject * )arg )-> xsk -> xsk );
821- (void )xsk_umem__delete (((struct ifobject * )arg )-> umem -> umem );
835+ if (!opt_bidi || (opt_bidi && bidi_pass )) {
836+ xsk_socket__delete (((struct ifobject * )arg )-> xsk -> xsk );
837+ (void )xsk_umem__delete (((struct ifobject * )arg )-> umem -> umem );
838+ }
822839 pthread_exit (NULL );
823840}
824841
@@ -827,11 +844,26 @@ static void testapp_validate(void)
827844 pthread_attr_init (& attr );
828845 pthread_attr_setstacksize (& attr , THREAD_STACK );
829846
847+ if (opt_bidi && bidi_pass ) {
848+ pthread_init_mutex ();
849+ if (!switching_notify ) {
850+ ksft_print_msg ("Switching Tx/Rx vectors\n" );
851+ switching_notify ++ ;
852+ }
853+ }
854+
830855 pthread_mutex_lock (& sync_mutex );
831856
832857 /*Spawn RX thread */
833- if (pthread_create (& t0 , & attr , worker_testapp_validate , (void * )ifdict [1 ]))
834- exit_with_error (errno );
858+ if (!opt_bidi || (opt_bidi && !bidi_pass )) {
859+ if (pthread_create (& t0 , & attr , worker_testapp_validate , (void * )ifdict [1 ]))
860+ exit_with_error (errno );
861+ } else if (opt_bidi && bidi_pass ) {
862+ /*switch Tx/Rx vectors */
863+ ifdict [0 ]-> fv .vector = rx ;
864+ if (pthread_create (& t0 , & attr , worker_testapp_validate , (void * )ifdict [0 ]))
865+ exit_with_error (errno );
866+ }
835867
836868 struct timespec max_wait = { 0 , 0 };
837869
@@ -845,8 +877,15 @@ static void testapp_validate(void)
845877 pthread_mutex_unlock (& sync_mutex );
846878
847879 /*Spawn TX thread */
848- if (pthread_create (& t1 , & attr , worker_testapp_validate , (void * )ifdict [0 ]))
849- exit_with_error (errno );
880+ if (!opt_bidi || (opt_bidi && !bidi_pass )) {
881+ if (pthread_create (& t1 , & attr , worker_testapp_validate , (void * )ifdict [0 ]))
882+ exit_with_error (errno );
883+ } else if (opt_bidi && bidi_pass ) {
884+ /*switch Tx/Rx vectors */
885+ ifdict [1 ]-> fv .vector = tx ;
886+ if (pthread_create (& t1 , & attr , worker_testapp_validate , (void * )ifdict [1 ]))
887+ exit_with_error (errno );
888+ }
850889
851890 pthread_join (t1 , NULL );
852891 pthread_join (t0 , NULL );
@@ -860,18 +899,19 @@ static void testapp_validate(void)
860899 free (pkt_buf );
861900 }
862901
863- if (!opt_teardown )
902+ if (!opt_teardown && ! opt_bidi )
864903 print_ksft_result ();
865904}
866905
867906static void testapp_sockets (void )
868907{
869- for (int i = 0 ; i < MAX_TEARDOWN_ITER ; i ++ ) {
908+ for (int i = 0 ; i < ( opt_teardown ? MAX_TEARDOWN_ITER : MAX_BIDI_ITER ) ; i ++ ) {
870909 pkt_counter = 0 ;
871910 prev_pkt = -1 ;
872911 sigvar = 0 ;
873912 ksft_print_msg ("Creating socket\n" );
874913 testapp_validate ();
914+ opt_bidi ? bidi_pass ++ : bidi_pass ;
875915 }
876916
877917 print_ksft_result ();
@@ -940,7 +980,14 @@ int main(int argc, char **argv)
940980
941981 ksft_set_plan (1 );
942982
943- opt_teardown ? testapp_sockets () : testapp_validate ();
983+ if (!opt_teardown && !opt_bidi ) {
984+ testapp_validate ();
985+ } else if (opt_teardown && opt_bidi ) {
986+ ksft_test_result_fail ("ERROR: parameters -T and -B cannot be used together\n" );
987+ ksft_exit_xfail ();
988+ } else {
989+ testapp_sockets ();
990+ }
944991
945992 for (int i = 0 ; i < MAX_INTERFACES ; i ++ )
946993 free (ifdict [i ]);
0 commit comments