Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests: netfilter: nft_queue.sh: avoid flakes on debug kernels

Jakub reports test flakes on debug kernels:
FAIL: test_udp_gro_ct: Expected software segmentation to occur, had 23 and 17

This test assumes that the kernels nfnetlink_queue module sees N GSO
packets, segments them into M skbs and queues them to userspace for
reinjection.

Hence, if M >= N, no segmentation occurred.

However, its possible that this happens:
- nfnetlink_queue gets GSO packet
- segments that into n skbs
- userspace buffer is full, kernel drops the segmented skbs

-> "toqueue" counter incremented by 1, "fromqueue" is unchanged.

If this happens often enough in a single run, M >= N check triggers
incorrectly.

To solve this, allow the nf_queue.c test program to set the FAIL_OPEN
flag so that the segmented skbs bypass the queueing step in the kernel
if the receive buffer is full.

Also, reduce number of sending socat instances, decrease their priority
and increase nice value for the nf_queue program itself to reduce the
probability of overruns happening in the first place.

Fixes: 59ecffa3995e ("selftests: netfilter: nft_queue.sh: add udp fraglist gro test case")
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/netdev/20260218184114.0b405b72@kernel.org/
Signed-off-by: Florian Westphal <fw@strlen.de>
Link: https://patch.msgid.link/20260226161920.1205-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Florian Westphal and committed by
Jakub Kicinski
ba147986 71347b9d

+17 -6
+8 -2
tools/testing/selftests/net/netfilter/nf_queue.c
··· 18 18 struct options { 19 19 bool count_packets; 20 20 bool gso_enabled; 21 + bool failopen; 21 22 int verbose; 22 23 unsigned int queue_num; 23 24 unsigned int timeout; ··· 31 30 32 31 static void help(const char *p) 33 32 { 34 - printf("Usage: %s [-c|-v [-vv] ] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p); 33 + printf("Usage: %s [-c|-v [-vv] ] [-o] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p); 35 34 } 36 35 37 36 static int parse_attr_cb(const struct nlattr *attr, void *data) ··· 237 236 238 237 flags = opts.gso_enabled ? NFQA_CFG_F_GSO : 0; 239 238 flags |= NFQA_CFG_F_UID_GID; 239 + if (opts.failopen) 240 + flags |= NFQA_CFG_F_FAIL_OPEN; 240 241 mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(flags)); 241 242 mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(flags)); 242 243 ··· 332 329 { 333 330 int c; 334 331 335 - while ((c = getopt(argc, argv, "chvt:q:Q:d:G")) != -1) { 332 + while ((c = getopt(argc, argv, "chvot:q:Q:d:G")) != -1) { 336 333 switch (c) { 337 334 case 'c': 338 335 opts.count_packets = true; ··· 368 365 break; 369 366 case 'G': 370 367 opts.gso_enabled = false; 368 + break; 369 + case 'o': 370 + opts.failopen = true; 371 371 break; 372 372 case 'v': 373 373 opts.verbose++;
+9 -4
tools/testing/selftests/net/netfilter/nft_queue.sh
··· 591 591 test_udp_gro_ct() 592 592 { 593 593 local errprefix="FAIL: test_udp_gro_ct:" 594 + local timeout=5 594 595 595 596 ip netns exec "$nsrouter" conntrack -F 2>/dev/null 596 597 ··· 631 630 } 632 631 } 633 632 EOF 634 - timeout 10 ip netns exec "$ns2" socat UDP-LISTEN:12346,fork,pf=ipv4 OPEN:"$TMPFILE1",trunc & 633 + timeout "$timeout" ip netns exec "$ns2" socat UDP-LISTEN:12346,fork,pf=ipv4 OPEN:"$TMPFILE1",trunc & 635 634 local rpid=$! 636 635 637 - ip netns exec "$nsrouter" ./nf_queue -G -c -q 1 -t 2 > "$TMPFILE2" & 636 + ip netns exec "$nsrouter" nice -n -19 ./nf_queue -G -c -q 1 -o -t 2 > "$TMPFILE2" & 638 637 local nfqpid=$! 639 638 640 639 ip netns exec "$nsrouter" ethtool -K "veth0" rx-udp-gro-forwarding on rx-gro-list on generic-receive-offload on ··· 644 643 645 644 local bs=512 646 645 local count=$(((32 * 1024 * 1024) / bs)) 647 - dd if=/dev/zero bs="$bs" count="$count" 2>/dev/null | for i in $(seq 1 16); do 648 - timeout 5 ip netns exec "$ns1" \ 646 + 647 + local nprocs=$(nproc) 648 + [ $nprocs -gt 1 ] && nprocs=$((nprocs - 1)) 649 + 650 + dd if=/dev/zero bs="$bs" count="$count" 2>/dev/null | for i in $(seq 1 $nprocs); do 651 + timeout "$timeout" nice -n 19 ip netns exec "$ns1" \ 649 652 socat -u -b 512 STDIN UDP-DATAGRAM:10.0.2.99:12346,reuseport,bind=0.0.0.0:55221 & 650 653 done 651 654