@@ -524,6 +524,8 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
524
524
test -> nb_sockets = 1 ;
525
525
test -> fail = false;
526
526
test -> set_ring = false;
527
+ test -> adjust_tail = false;
528
+ test -> adjust_tail_support = false;
527
529
test -> mtu = MAX_ETH_PKT_SIZE ;
528
530
test -> xdp_prog_rx = ifobj_rx -> xdp_progs -> progs .xsk_def_prog ;
529
531
test -> xskmap_rx = ifobj_rx -> xdp_progs -> maps .xsk ;
@@ -992,6 +994,31 @@ static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
992
994
return true;
993
995
}
994
996
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
+
995
1022
static bool is_frag_valid (struct xsk_umem_info * umem , u64 addr , u32 len , u32 expected_pkt_nb ,
996
1023
u32 bytes_processed )
997
1024
{
@@ -1768,8 +1795,13 @@ static void *worker_testapp_validate_rx(void *arg)
1768
1795
1769
1796
if (!err && ifobject -> validation_func )
1770
1797
err = ifobject -> validation_func (ifobject );
1771
- if (err )
1772
- 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
+ }
1773
1805
1774
1806
pthread_exit (NULL );
1775
1807
}
@@ -2516,6 +2548,71 @@ static int testapp_hw_sw_max_ring_size(struct test_spec *test)
2516
2548
return testapp_validate_traffic (test );
2517
2549
}
2518
2550
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
+
2519
2616
static void run_pkt_test (struct test_spec * test )
2520
2617
{
2521
2618
int ret ;
@@ -2622,6 +2719,10 @@ static const struct test_spec tests[] = {
2622
2719
{.name = "TOO_MANY_FRAGS" , .test_func = testapp_too_many_frags },
2623
2720
{.name = "HW_SW_MIN_RING_SIZE" , .test_func = testapp_hw_sw_min_ring_size },
2624
2721
{.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 },
2625
2726
};
2626
2727
2627
2728
static void print_tests (void )
0 commit comments