@@ -524,6 +524,8 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
524524 test -> nb_sockets = 1 ;
525525 test -> fail = false;
526526 test -> set_ring = false;
527+ test -> adjust_tail = false;
528+ test -> adjust_tail_support = false;
527529 test -> mtu = MAX_ETH_PKT_SIZE ;
528530 test -> xdp_prog_rx = ifobj_rx -> xdp_progs -> progs .xsk_def_prog ;
529531 test -> xskmap_rx = ifobj_rx -> xdp_progs -> maps .xsk ;
@@ -757,14 +759,15 @@ static struct pkt_stream *pkt_stream_clone(struct pkt_stream *pkt_stream)
757759 return pkt_stream_generate (pkt_stream -> nb_pkts , pkt_stream -> pkts [0 ].len );
758760}
759761
760- static void pkt_stream_replace (struct test_spec * test , u32 nb_pkts , u32 pkt_len )
762+ static void pkt_stream_replace_ifobject (struct ifobject * ifobj , u32 nb_pkts , u32 pkt_len )
761763{
762- struct pkt_stream * pkt_stream ;
764+ ifobj -> xsk -> pkt_stream = pkt_stream_generate (nb_pkts , pkt_len );
765+ }
763766
764- pkt_stream = pkt_stream_generate ( nb_pkts , pkt_len );
765- test -> ifobj_tx -> xsk -> pkt_stream = pkt_stream ;
766- pkt_stream = pkt_stream_generate ( nb_pkts , pkt_len );
767- test -> ifobj_rx -> xsk -> pkt_stream = pkt_stream ;
767+ static void pkt_stream_replace ( struct test_spec * test , u32 nb_pkts , u32 pkt_len )
768+ {
769+ pkt_stream_replace_ifobject ( test -> ifobj_tx , nb_pkts , pkt_len );
770+ pkt_stream_replace_ifobject ( test -> ifobj_rx , nb_pkts , pkt_len ) ;
768771}
769772
770773static void __pkt_stream_replace_half (struct ifobject * ifobj , u32 pkt_len ,
@@ -991,6 +994,31 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
991994 return true;
992995}
993996
997+ static bool is_adjust_tail_supported (struct xsk_xdp_progs * skel_rx )
998+ {
999+ struct bpf_map * data_map ;
1000+ int adjust_value = 0 ;
1001+ int key = 0 ;
1002+ int ret ;
1003+
1004+ data_map = bpf_object__find_map_by_name (skel_rx -> obj , "xsk_xdp_.bss" );
1005+ if (!data_map || !bpf_map__is_internal (data_map )) {
1006+ ksft_print_msg ("Error: could not find bss section of XDP program\n" );
1007+ exit_with_error (errno );
1008+ }
1009+
1010+ ret = bpf_map_lookup_elem (bpf_map__fd (data_map ), & key , & adjust_value );
1011+ if (ret ) {
1012+ ksft_print_msg ("Error: bpf_map_lookup_elem failed with error %d\n" , ret );
1013+ exit_with_error (errno );
1014+ }
1015+
1016+ /* Set the 'adjust_value' variable to -EOPNOTSUPP in the XDP program if the adjust_tail
1017+ * helper is not supported. Skip the adjust_tail test case in this scenario.
1018+ */
1019+ return adjust_value != - EOPNOTSUPP ;
1020+ }
1021+
9941022static bool is_frag_valid (struct xsk_umem_info * umem , u64 addr , u32 len , u32 expected_pkt_nb ,
9951023 u32 bytes_processed )
9961024{
@@ -1767,8 +1795,13 @@ static void *worker_testapp_validate_rx(void *arg)
17671795
17681796 if (!err && ifobject -> validation_func )
17691797 err = ifobject -> validation_func (ifobject );
1770- if (err )
1771- report_failure (test );
1798+
1799+ if (err ) {
1800+ if (test -> adjust_tail && !is_adjust_tail_supported (ifobject -> xdp_progs ))
1801+ test -> adjust_tail_support = false;
1802+ else
1803+ report_failure (test );
1804+ }
17721805
17731806 pthread_exit (NULL );
17741807}
@@ -2515,6 +2548,71 @@ static int testapp_hw_sw_max_ring_size(struct test_spec *test)
25152548 return testapp_validate_traffic (test );
25162549}
25172550
2551+ static int testapp_xdp_adjust_tail (struct test_spec * test , int adjust_value )
2552+ {
2553+ struct xsk_xdp_progs * skel_rx = test -> ifobj_rx -> xdp_progs ;
2554+ struct xsk_xdp_progs * skel_tx = test -> ifobj_tx -> xdp_progs ;
2555+
2556+ test_spec_set_xdp_prog (test , skel_rx -> progs .xsk_xdp_adjust_tail ,
2557+ skel_tx -> progs .xsk_xdp_adjust_tail ,
2558+ skel_rx -> maps .xsk , skel_tx -> maps .xsk );
2559+
2560+ skel_rx -> bss -> adjust_value = adjust_value ;
2561+
2562+ return testapp_validate_traffic (test );
2563+ }
2564+
2565+ static int testapp_adjust_tail (struct test_spec * test , u32 value , u32 pkt_len )
2566+ {
2567+ int ret ;
2568+
2569+ test -> adjust_tail_support = true;
2570+ test -> adjust_tail = true;
2571+ test -> total_steps = 1 ;
2572+
2573+ pkt_stream_replace_ifobject (test -> ifobj_tx , DEFAULT_BATCH_SIZE , pkt_len );
2574+ pkt_stream_replace_ifobject (test -> ifobj_rx , DEFAULT_BATCH_SIZE , pkt_len + value );
2575+
2576+ ret = testapp_xdp_adjust_tail (test , value );
2577+ if (ret )
2578+ return ret ;
2579+
2580+ if (!test -> adjust_tail_support ) {
2581+ ksft_test_result_skip ("%s %sResize pkt with bpf_xdp_adjust_tail() not supported\n" ,
2582+ mode_string (test ), busy_poll_string (test ));
2583+ return TEST_SKIP ;
2584+ }
2585+
2586+ return 0 ;
2587+ }
2588+
2589+ static int testapp_adjust_tail_shrink (struct test_spec * test )
2590+ {
2591+ /* Shrink by 4 bytes for testing purpose */
2592+ return testapp_adjust_tail (test , -4 , MIN_PKT_SIZE * 2 );
2593+ }
2594+
2595+ static int testapp_adjust_tail_shrink_mb (struct test_spec * test )
2596+ {
2597+ test -> mtu = MAX_ETH_JUMBO_SIZE ;
2598+ /* Shrink by the frag size */
2599+ return testapp_adjust_tail (test , - XSK_UMEM__MAX_FRAME_SIZE , XSK_UMEM__LARGE_FRAME_SIZE * 2 );
2600+ }
2601+
2602+ static int testapp_adjust_tail_grow (struct test_spec * test )
2603+ {
2604+ /* Grow by 4 bytes for testing purpose */
2605+ return testapp_adjust_tail (test , 4 , MIN_PKT_SIZE * 2 );
2606+ }
2607+
2608+ static int testapp_adjust_tail_grow_mb (struct test_spec * test )
2609+ {
2610+ test -> mtu = MAX_ETH_JUMBO_SIZE ;
2611+ /* Grow by (frag_size - last_frag_Size) - 1 to stay inside the last fragment */
2612+ return testapp_adjust_tail (test , (XSK_UMEM__MAX_FRAME_SIZE / 2 ) - 1 ,
2613+ XSK_UMEM__LARGE_FRAME_SIZE * 2 );
2614+ }
2615+
25182616static void run_pkt_test (struct test_spec * test )
25192617{
25202618 int ret ;
@@ -2621,6 +2719,10 @@ static const struct test_spec tests[] = {
26212719 {.name = "TOO_MANY_FRAGS" , .test_func = testapp_too_many_frags },
26222720 {.name = "HW_SW_MIN_RING_SIZE" , .test_func = testapp_hw_sw_min_ring_size },
26232721 {.name = "HW_SW_MAX_RING_SIZE" , .test_func = testapp_hw_sw_max_ring_size },
2722+ {.name = "XDP_ADJUST_TAIL_SHRINK" , .test_func = testapp_adjust_tail_shrink },
2723+ {.name = "XDP_ADJUST_TAIL_SHRINK_MULTI_BUFF" , .test_func = testapp_adjust_tail_shrink_mb },
2724+ {.name = "XDP_ADJUST_TAIL_GROW" , .test_func = testapp_adjust_tail_grow },
2725+ {.name = "XDP_ADJUST_TAIL_GROW_MULTI_BUFF" , .test_func = testapp_adjust_tail_grow_mb },
26242726 };
26252727
26262728static void print_tests (void )
0 commit comments