* [Devel] [PATCH hci-8.1] selftests/bpf: run the xsk veth tests in a network namespace of their own
@ 2026-10-20 4:12 Eva Kurchatova
2026-10-20 4:18 ` no-reply
0 siblings, 1 reply; 2+ messages in thread
From: Eva Kurchatova @ 2026-10-20 4:12 UTC (permalink / raw)
To: khorenko; +Cc: devel
test_xsk.sh makes its veth pair in the namespace it runs in. Whatever
the host does with a new interface, address configuration, neighbour
discovery, happens on that pair, and the AF_XDP sockets under test
receive the host's packets among their own. The tests count and
inspect what they receive, so a preconfigured host fails some of them
in every mode, and a bare one passes.
Run the veth part in a network namespace of its own. The max_skb_frags
sysctl has no file outside the initial namespace, so xskxceiver takes
the limit from a new -f option ahead of the file, and the script hands
it the host's value, or the one given to its own -f. An interface
given with -i is used where it is.
https://virtuozzo.atlassian.net/browse/VSTOR-150731
Feature: fix selftests
Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
---
tools/testing/selftests/bpf/test_xsk.sh | 25 ++++++++++++++++++++++--
tools/testing/selftests/bpf/xskxceiver.c | 13 ++++++++++--
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xsk.sh b/tools/testing/selftests/bpf/test_xsk.sh
index 65aafe0003db..7859c1d31195 100755
--- a/tools/testing/selftests/bpf/test_xsk.sh
+++ b/tools/testing/selftests/bpf/test_xsk.sh
@@ -83,6 +83,9 @@
# Run a specific test from the test suite
# sudo ./test_xsk.sh -t TEST_NAME
#
+# Run with a max_skb_frags limit other than the host's
+# sudo ./test_xsk.sh -f FRAGS
+#
# Display the available command line options
# ./test_xsk.sh -h
@@ -90,7 +93,7 @@
ETH=""
-while getopts "vi:dm:lt:h" flag
+while getopts "vi:dm:lt:f:h" flag
do
case "${flag}" in
v) verbose=1;;
@@ -99,6 +102,7 @@ do
m) MODE=${OPTARG};;
l) list=1;;
t) TEST=${OPTARG};;
+ f) FRAGS=${OPTARG};;
h) help=1;;
esac
done
@@ -162,8 +166,21 @@ if [ ! -z $ETH ]; then
VETH1=${ETH}
else
validate_root_exec
- validate_veth_support ${VETH0}
validate_ip_utility
+ # The host configures and talks on any new interface in its namespace
+ if [ -z "$XSK_NETNS" ]; then
+ XSK_NETNS=xsk${VETH0_POSTFIX}
+ ip netns add ${XSK_NETNS} || test_exit $ksft_fail
+ trap "ip netns del ${XSK_NETNS}" EXIT
+ # The max_skb_frags sysctl has no file outside the initial namespace
+ [ -n "$FRAGS" ] || FRAGS=$(cat /proc/sys/net/core/max_skb_frags)
+ XSK_NETNS=${XSK_NETNS} ip netns exec ${XSK_NETNS} bash "$0" "$@" -f ${FRAGS}
+ retval=$?
+ # The pair stays up for a run by hand
+ [[ $debug -eq 1 ]] && trap - EXIT && echo "ip netns exec ${XSK_NETNS}"
+ exit $retval
+ fi
+ validate_veth_support ${VETH0}
setup_vethPairs
retval=$?
@@ -187,6 +204,10 @@ if [ -n "$TEST" ]; then
ARGS+="-t ${TEST} "
fi
+if [ -n "$FRAGS" ]; then
+ ARGS+="-f ${FRAGS} "
+fi
+
retval=$?
test_status $retval "${TEST_NAME}"
diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
index 11f047b8af75..c26cc31d21fe 100644
--- a/tools/testing/selftests/bpf/xskxceiver.c
+++ b/tools/testing/selftests/bpf/xskxceiver.c
@@ -113,6 +113,7 @@ static bool opt_verbose;
static bool opt_print_tests;
static enum test_mode opt_mode = TEST_MODE_ALL;
static u32 opt_run_test = RUN_ALL_TESTS;
+static u32 opt_max_skb_frags;
void test__fail(void) { /* for network_helpers.c */ }
@@ -351,6 +352,7 @@ static struct option long_options[] = {
{"mode", required_argument, 0, 'm'},
{"list", no_argument, 0, 'l'},
{"test", required_argument, 0, 't'},
+ {"frags", required_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
@@ -366,6 +368,7 @@ static void print_usage(char **argv)
" -m, --mode Run only mode skb, drv, or zc\n"
" -l, --list List all available tests\n"
" -t, --test Run a specific test. Enter number from -l option.\n"
+ " -f, --frags Use this max_skb_frags instead of the sysctl\n"
" -h, --help Display this help and exit\n";
ksft_print_msg(str, basename(argv[0]));
@@ -389,7 +392,7 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
opterr = 0;
for (;;) {
- c = getopt_long(argc, argv, "i:vbm:lt:", long_options, &option_index);
+ c = getopt_long(argc, argv, "i:vbm:lt:f:", long_options, &option_index);
if (c == -1)
break;
@@ -437,6 +440,12 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
if (errno)
print_usage(argv);
break;
+ case 'f':
+ errno = 0;
+ opt_max_skb_frags = strtoul(optarg, NULL, 0);
+ if (errno || !opt_max_skb_frags)
+ print_usage(argv);
+ break;
case 'h':
default:
print_usage(argv);
@@ -2271,7 +2280,7 @@ static int testapp_too_many_frags(struct test_spec *test)
if (test->mode == TEST_MODE_ZC) {
max_frags = test->ifobj_tx->xdp_zc_max_segs;
} else {
- max_frags = get_max_skb_frags();
+ max_frags = opt_max_skb_frags ? : get_max_skb_frags();
if (!max_frags) {
ksft_print_msg("Couldn't retrieve MAX_SKB_FRAGS from system, using default (17) value\n");
max_frags = 17;
--
2.56.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Devel] [PATCH hci-8.1] selftests/bpf: run the xsk veth tests in a network namespace of their own
2026-10-20 4:12 [Devel] [PATCH hci-8.1] selftests/bpf: run the xsk veth tests in a network namespace of their own Eva Kurchatova
@ 2026-10-20 4:18 ` no-reply
0 siblings, 0 replies; 2+ messages in thread
From: no-reply @ 2026-10-20 4:18 UTC (permalink / raw)
To: Eva Kurchatova, khorenko; +Cc: devel
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Low] selftests/bpf: test_xsk.sh passes a bare -f when max_skb_frags is unreadable
- [Low] selftests/bpf: xskxceiver -f parsing can wrap u32 and the calloc() size
- [Low] selftests/bpf: test_xsk.sh -f only changes the test's assumed max_skb_frags
- [Low] selftests/bpf: test_xsk.sh reports FAIL when the netns cannot be created
--
commit 035a16fff590cf5d4d3fde38f45f552e4cab308c
Author: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
selftests/bpf: run the xsk veth tests in a network namespace of their own
This patch makes test_xsk.sh create its veth pair inside a private network
namespace, so host traffic does not reach the AF_XDP sockets under test. It
adds a -f option to both test_xsk.sh and xskxceiver so the max_skb_frags
value can be passed in from outside the namespace.
Link: https://virtuozzo.atlassian.net/browse/VSTOR-150731
> diff --git a/tools/testing/selftests/bpf/test_xsk.sh b/tools/testing/selftests/bpf/test_xsk.sh
> --- a/tools/testing/selftests/bpf/test_xsk.sh
> +++ b/tools/testing/selftests/bpf/test_xsk.sh
[ ... ]
> @@ -83,6 +83,9 @@
> # Run a specific test from the test suite
> # sudo ./test_xsk.sh -t TEST_NAME
> #
> +# Run with a max_skb_frags limit other than the host's
> +# sudo ./test_xsk.sh -f FRAGS
> +#
[Severity: Low]
This isn't a regression in the mechanics, but is this description accurate?
Nothing writes net.core.max_skb_frags. The -f value is only forwarded to
xskxceiver, where testapp_too_many_frags() uses it to size the packet
stream, while the kernel keeps enforcing its real limit.
If FRAGS differs from the host's sysctl, can the too-many-frags test build
the wrong fragment count and fail or give misleading results? Should the
comment and the commit message wording say that -f only changes the value
the test assumes?
[ ... ]
> @@ -162,8 +166,21 @@ if [ ! -z $ETH ]; then
> VETH1=${ETH}
> else
> validate_root_exec
> - validate_veth_support ${VETH0}
> validate_ip_utility
> + # The host configures and talks on any new interface in its namespace
> + if [ -z "$XSK_NETNS" ]; then
> + XSK_NETNS=xsk${VETH0_POSTFIX}
> + ip netns add ${XSK_NETNS} || test_exit $ksft_fail
[Severity: Low]
When "ip netns add" fails (no CONFIG_NET_NS, a container without
/run/netns, or a collision on the random suffix), this now reports a
failure through test_exit $ksft_fail. Before the patch the test simply ran
in the current namespace.
The script uses ksft_skip for other missing prerequisites. Should this case
skip rather than fail?
> + trap "ip netns del ${XSK_NETNS}" EXIT
> + # The max_skb_frags sysctl has no file outside the initial namespace
> + [ -n "$FRAGS" ] || FRAGS=$(cat /proc/sys/net/core/max_skb_frags)
> + XSK_NETNS=${XSK_NETNS} ip netns exec ${XSK_NETNS} bash "$0" "$@" -f ${FRAGS}
[Severity: Low]
If /proc/sys/net/core/max_skb_frags is missing or unreadable (for example
on a kernel without the sysctl), the failed cat is not checked and FRAGS
stays empty.
The unquoted ${FRAGS} then expands to nothing, so the child is started
with a trailing "-f" and no argument. The child's getopts "vi:dm:lt:f:h"
prints "option requires an argument -- f". The case statement has no "?"
arm, so the run continues with FRAGS empty and xskxceiver falls back to 17.
Can the "-f ${FRAGS}" be appended only when FRAGS is non-empty?
> + retval=$?
> + # The pair stays up for a run by hand
> + [[ $debug -eq 1 ]] && trap - EXIT && echo "ip netns exec ${XSK_NETNS}"
In the -d case, the hint printed is only "ip netns exec ${XSK_NETNS}",
which is not a complete command. The inner script has already exited and
the namespace and veth pair are left behind. Could the hint include a
command to run, or the namespace name in a more useful form?
> + exit $retval
> + fi
> + validate_veth_support ${VETH0}
> setup_vethPairs
[ ... ]
> diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> --- a/tools/testing/selftests/bpf/xskxceiver.c
> +++ b/tools/testing/selftests/bpf/xskxceiver.c
[ ... ]
> @@ -437,6 +440,12 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
> if (errno)
> print_usage(argv);
> break;
> + case 'f':
> + errno = 0;
> + opt_max_skb_frags = strtoul(optarg, NULL, 0);
> + if (errno || !opt_max_skb_frags)
> + print_usage(argv);
> + break;
[Severity: Low]
Can this wrap opt_max_skb_frags? strtoul() returns an unsigned long that
is stored in a u32, and only errno and zero are checked. There is no upper
bound and no endptr check, so input such as "17abc" is accepted too.
> @@ -2271,7 +2280,7 @@ static int testapp_too_many_frags(struct test_spec *test)
> if (test->mode == TEST_MODE_ZC) {
> max_frags = test->ifobj_tx->xdp_zc_max_segs;
> } else {
> - max_frags = get_max_skb_frags();
> + max_frags = opt_max_skb_frags ? : get_max_skb_frags();
> if (!max_frags) {
> ksft_print_msg("Couldn't retrieve MAX_SKB_FRAGS from system, using default (17) value\n");
> max_frags = 17;
> }
> max_frags += 1;
Can this overflow the pkts[] allocation in testapp_too_many_frags()? With
-f 4294967295, max_frags += 1 wraps to 0. With a value around 0x80000000,
the size in calloc(2 * max_frags + 2, sizeof(struct pkt)) wraps to a tiny
value.
The later loops that fill pkts[i] up to 2 * max_frags + 1 would then write
far beyond the allocation. Before this patch the value came only from the
range-limited sysctl. test_xsk.sh -f forwards the value verbatim to
xskxceiver, so both entry points can reach this. Should -f be validated
with an upper bound and an endptr check?
--
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261020041218.1659392-1-eva.kurchatova@virtuozzo.com?part=1
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-20 4:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-20 4:12 [Devel] [PATCH hci-8.1] selftests/bpf: run the xsk veth tests in a network namespace of their own Eva Kurchatova
2026-10-20 4:18 ` no-reply
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox