@@ -1975,6 +1975,40 @@ static int testapp_poll_rxq_tmout(struct test_spec *test)
return testapp_validate_traffic_single_thread(test, test->ifobj_rx);
}
+static int testapp_too_many_frags(struct test_spec *test)
+{
+ struct pkt pkts[XSK_DESC__MAX_FRAGS + 3] = {};
+ u32 i;
+
+ test_spec_set_name(test, "TOO_MANY_FRAGS");
+ if (test->mode == TEST_MODE_ZC) {
+ /* Limit is up to driver for zero-copy mode so not testable. */
+ ksft_test_result_skip("Cannot be run for zero-copy mode.\n");
+ return TEST_SKIP;
+ }
+
+ test->mtu = MAX_ETH_JUMBO_SIZE;
+
+ /* Valid packet for synch */
+ pkts[0].len = MIN_PKT_SIZE;
+ pkts[0].valid = true;
+
+ /* Do not signal end-of-packet in the 17th frag. This is not legal. */
+ for (i = 1; i < XSK_DESC__MAX_FRAGS + 2; i++) {
+ pkts[i].len = MIN_PKT_SIZE;
+ pkts[i].options = XDP_PKT_CONTD;
+ pkts[i].valid = true;
+ }
+ pkts[XSK_DESC__MAX_FRAGS + 1].valid = false;
+
+ /* Valid packet for synch */
+ pkts[XSK_DESC__MAX_FRAGS + 2].len = MIN_PKT_SIZE;
+ pkts[XSK_DESC__MAX_FRAGS + 2].valid = true;
+
+ pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
+ return testapp_validate_traffic(test);
+}
+
static int xsk_load_xdp_programs(struct ifobject *ifobj)
{
ifobj->xdp_progs = xsk_xdp_progs__open_and_load();
@@ -2160,6 +2194,9 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
test->mtu = MAX_ETH_JUMBO_SIZE;
ret = testapp_xdp_metadata_count(test);
break;
+ case TEST_TYPE_TOO_MANY_FRAGS:
+ ret = testapp_too_many_frags(test);
+ break;
default:
break;
}
@@ -53,6 +53,7 @@
#define XSK_UMEM__LARGE_FRAME_SIZE (3 * 1024)
#define XSK_UMEM__MAX_FRAME_SIZE (4 * 1024)
#define XSK_DESC__INVALID_OPTION (0xffff)
+#define XSK_DESC__MAX_FRAGS 17
#define HUGEPAGE_SIZE (2 * 1024 * 1024)
#define PKT_DUMP_NB_TO_PRINT 16
@@ -93,6 +94,7 @@ enum test_type {
TEST_TYPE_UNALIGNED_MB,
TEST_TYPE_ALIGNED_INV_DESC_MB,
TEST_TYPE_UNALIGNED_INV_DESC_MB,
+ TEST_TYPE_TOO_MANY_FRAGS,
TEST_TYPE_MAX
};