Kernel 6.3 supported for some NIC offloads for XDP programs.
The feature in XDP is known to be XDP hints. XDP hints are only
supported if the XDP program is bound to the NIC device using the
BPF_F_XDP_DEV_BOUND_ONLY binding flag.
The device binding flag is represented through `XDP_ATTACH_DEVBIND',
a new attach flag for `xdp_program__attach`. Device binding is
propagated to the dispatcher. Any subsequent programs attachments
are rejected if they are different from the already running dispatcher
on a network interface.
The flag is recored using a new variable in `struct xdp_dispatcher_config`.
Jalal Mostafa [Sun, 23 Mar 2025 17:14:37 +0000 (18:14 +0100)]
headers/linux: Update bpf.h to kernel version 6.3
Update the bpf.h UAPI header from the Linux to that from kernel version
6.3. We need the definition of BPF_F_XDP_DEV_BOUND_ONLY to support it
in libxdp.
configure: Avoid populating .rodata in libbpf test
When checking for a working libbpf, the test includes constant strings
which end up in .rodata. This can cause compilation failures when
LDFLAGS contain values that enforces position-independent code. We don't
really need the string values, so just replace the constants with NULL
values in the test program to avoid the error.
util/params.c: Fix option help printer definitions
The helper print definitions were not updated with the addition of a u8
argument type, breaking help output for enums. Add another member to
realign things.
Daniel Golle [Mon, 24 Nov 2025 11:09:58 +0000 (12:09 +0100)]
configure: Respect LDFLAGS in test compilations
The build environment may set LDFLAGS, but the test compilations in the
configure script doesn't respect this, which can lead to compilation
failures, and thus false negatives for the tested features.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
[Imported the downstream patch from OpenWrt] Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
xdp-loader: Make feature flags printing future-proof
In netdev.h, NETDEV_XDP_ACT_MASK is declared as private, so it should
only be used inside the kernel, and according to Jakub Kicinski then
"user space should not care about it"[1].
In this specific case, then this code is buggy. If a new feature flag
is added to the uapi header, and hence included in NETDEV_XDP_ACT_MASK,
and xdp-tools is not updated, or an older version is re-build in a
distro, with newer linux headers, then NETDEV_XDP_ACT_MASK can contain
a new feature flag, and if the new flag is observed, then it will neither
be checked nor trigger the unknown feature printing.
This patch moves the flags into a constant array, and while looping over
them in iface_print_xdp_features(), it builds a local mask consisting only
of the tested flags. The local mask is used to replace NETDEV_XDP_ACT_MASK.
test_runner: Wait for background output file to appear before moving it
On slow test execution systems (vm-in-vm setups), spawning a background
process can take so long that the output file is not created before the
test script tries to move it into place. This in turns leads to lost
output and subsequent test failures.
Fix this by waiting on the temporary file to appear before moving it.
There can be multiple bpffs instances mounted on top of each other, so
when unmounting them for the test, run in a loop until we succeed (or
get an error).
libxdp/tests: Load test BPF programs from TESTS_DIR
Use open_bpf_file() and the embedded libxdp program search to make sure
we can open the test objects used in the libxdp tests regardless of the
current working directory. This is needed to make the libxdp tests run
after installation.
libxdp/tests: Always link some test programs statically
A few of the libxdp selftests uses hidden libxdp symbols, and so cannot
be linked statically. This causes the test builds to fail if
DYNAMIC_LIBXDP is set. Fix this by always linking these utilities
statically, regardless of the value of DYNAMIC_LIBXDP.
The missing include means that the libxdp version was not defined which
caused a build dependency on libxdp.so. (with a trailing dot) that never
existed, which can lead to an infinite build recursion.
Like with ARP packets for IPv4, make sure we pass neighbour
solicitations and advertisements through the filter rules for IPv6, to
avoid connectivity breaking in deny-all mode.
In deny-all mode xdp-filter breaks connectivity because it ends up
dropping ARP packets. Add parsing of ARP packets and run the src/target
IP of the ARP request/response through the same IP filter rules as the
IP packets themselves.
Frank Liang [Mon, 14 Jul 2025 07:32:52 +0000 (15:32 +0800)]
test_runner: skip cleanup proc dir in teardown if no STATEDIR
teardown() tries to cleanup /proc dir and cannot exit normally
when misses required tool.
time /usr/share/xdp-tools/run_tests.sh
Running all tests from /usr/share/xdp-tools/tests
Executing tests in separate net- and mount namespaces
Missing required tool: socat
^C
.github/workflows: Update to Ubuntu 24.04 and use system packages
Update the Ubuntu version used for the selftests to 24.04, and use the
system libbpf and bpftool packages. This should hopefully cut down on
test runner time.
xdp-dump/tests: Don't assume a particular length of program IDs
The test script was using character-based 'cut' to extract the program
IDs from the xdpdump output, which fails once program IDs become
6-digit. Replace with awk field-based extraction to avoid this.
Make sure to output the "listening on" message as the very last thing
before entering the reporting loop; this way the message can be used as
an indicator that setup is complete and the capture is running.
Make sure to flush the stdout stream when exiting, before outputting the
end-of-run stats. This avoids output being interleaved because the stats
are written to stderr before stdout has finished flushing.
xdp-forward/tests: Remove sleep and use start_socat function
Remove the sleep after installing nft rules and use the start_socat
function to start the socat listener, while also decreasing the client
timeout to socat in the xdp-forward tests, in an attempt to make things
run faster.
test_runner: Don't sleep after spawning background processes
Remove the sleep delays after spawning background processes. This delays
tests and is not deterministic. Instead, add a new start_tcpdump()
function which will explicitly wait for the "listening on" output to
appear in the output file, which indicates that the process has started
up successfully.
test-runner: Monitor process exit instead of sleeping
Instead of sleeping and re-issuing a kill unconditionally, loop and wait
for processes to exit; this avoids the wait in most cases, speeding up
test runs.
test-runner: Disable ARP and multicast on test interfaces
We still see the occasional multicast listener report on interfaces,
which makes tests fail. Completely disable ARP and multicast on the test
interfaces to avoid this.
testing/test_runner: Enable realtime output in verbose mode
When running in verbose mode, the test output was still cached until the
end of a test run, which makes it impossible to follow the progress of a
test. Rework the test execution function to enable real-time output in
verbose mode.
Vincent Li [Sun, 27 Jul 2025 19:04:15 +0000 (12:04 -0700)]
Doc: update libxdp README.org and man page with architecture support
XDP multiprog on a single interface generally is supported by
architectures supporting BPF trampoline.
Signed-off-by: Vincent Li <vincent.mc.li@gmail.com>
[ squash commits, rerun man page export on newer Emacs ] Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
libxdp/tests: Mount bpffs before compatibility check
The compatibility checks were failing because there was no bpffs, which
means tests were skipped that shouldn't have. Reorder things so the
bpffs is mounted before the compatibility check.
Turns out the debug package build failure was something that only
occurred on my own machine, because ~/rpmbuild was a symlink. Fixing
this, there is no failure, so let's reinstate the debuginfo package.
xdp-bench: Fix --extended switch for redirect-cpu mode
The option parsing for redirect-cpu contained a copy-paste error that
broke the --extended switch for that mode because it referred to the
wrong options struct. Fix this by referring to the right struct.
tests/xdp-trafficgen: Skip tests if probe fails for any reason
The xdp-trafficgen tests were looking at particular return codes from
xdp-trafficgen; since the return code is not binary 1/0 depending on
probe results, just skip the tests if the probe fails for any reason.
xdp-trafficgen: Fix automatic loading of xdp_pass program
The automatic loading of an xdp_pass program in xdp-trafficgen would
fail on systems that don't allow multi-attach of programs, because it's
attaching an already-loaded program. Switch to loading a separate
program from the dispatcher BPF object file. Also check if an XDP
program is already loaded on an interface, and don't try to load a new
one if it is.
xdp-trafficgen: Output helpful suggestions if interface probing fails
In some cases we can say something more about why probing for XDP
feature support for an interface fails (because of particular driver
quirks). Add output to the 'probe' command for these cases.
xdp-trafficgen: Drop "the driver is missing support in this kernel version" text
The "Most likely the driver is missing support in this kernel version"
may not always be true (for instance because the support is just
disabled), so let's drop it from the check_iface_support() function.
lib/util: Fix build on old versions of libbpf without XDP feature flag support
The build errors out with old libbpf versions because the ifdef'ed
version of iface_get_xdp_feature_flags() doesn't use any of its
arguments. Change the ifdef'ed version to mark the arguments as __unused
to avoid this.
The xdp_redirect_map and xdp_redirect_map_err tracepoints have been
deprecated since kernel 5.6 (returning no data) and are slated for
removal in kernel 6.16[0]. Remove them from xdp_sample so xdp-bench will
keep working after the tracepoints are removed.
.github/workflows: Add a 6.14 kernel to the test matrix
The 6.14 kernel introduced the change that disallows attaching programs
that modify the packet pointer on top of functions that don't, so let's
add that version to the test matrix so we exercise the workaround.
xdp-loader: Add a test for loading a program that modifies the packet pointer
Newer versions of the kernel disallow attaching freplace programs that
modify the packet pointer on top of functions that don't. The libxdp
dispatcher was updated to include a workaround for this, so let's add a
test that exercises this workaround.
This affects libxdp, because the stub programs that are replaced by the
user programs do not modify the packet pointer. Implement the workaround
suggested in the posting above, by adding a no-op call to
bpf_xdp_adjust_tail() to the stub programs being replaced. This does not
affect performance, nor backwards compatibility of the dispatcher, since
the stub programs are never actually executed when libxdp is used. The
only effect will be that on newer kernels, a version of libxdp that
includes these changes will work with programs that modify the packet
pointer, while older versions of libxdp won't.
xdpdump: Adapt the behavior of util.c find_bpf_file() to the libxdp.c variant
In contrast to the libxdp.c variant, the function find_bpf_file() in the util.c file does not use the environment variable LIBXDP_OBJECT_PATH to overwrite the default path, but always uses the default variable BPF_OBJECT_PATH, which is set at compile time.
To unify the behavior, the behavior of the util.c variant is adapted to that of the libxdp.c variant.
xdp-trafficgen: Add missing comma in list of drivers
Coverity pointed out that there's a comma missing in the list of
drivers, leading two of the strings to be concatenated instead of being
separate items in the list.
xdp-trafficgen: Support probing an interface in 'probe' command
Add an -i option to the 'xdp-trafficgen probe' command which will cause
xdp-trafficgen to issue a feature probe of the specified interface. This
can be used to detect if an interface is usable before trying to run on
it.
xdp-trafficgen: Error out if interface doesn't support sending packets
If a device doesn't support sending packets via XDP, xdp-trafficgen will
still happily load and try to send packets, but no packets will actually
be sent. Add a check for the NDO_XMIT XDP feature flag in
xdp-trafficgen, and error out if the flag it not set. This should make
it clearer to users why things don't work.
xdp-trafficgen: Load a dummy XDP program if needed
Add logic in xdp-trafficgen to load a dummy XDP program on devices that
need this to be able to send packets via ndo_xdp_xmit(). We use a
hard-coded list of driver names to determine if an interface needs such
an XDP program, and check the XDP feature flags to skip the loading if
the NDO_XMIT feature is already set.
Installation path macros cannot be safely used to specify the location of dependencies.
For instance, even when building xdg-tools for flatpaks in /app,
the buildroot llvm/clang may be used from /usr.
lib/defines: Propagate include directories to BPF_CFLAGS
The configure script may add extra include directories to CFLAGS, but
these were not propagated to BPF_CFLAGS, which leads to build errors
when libbpf is in an unusual place. Add an explicit propagation of
any CFLAGS starting with -I to BPF_CFLAGS.
xdp-trafficgen: Fix data size when probing for kernel support
Kernel commit 6b3d638ca897 ("bpf, test_run: Fix use-after-free issue in
eth_skb_pkt_type()") started returning EINVAL if the data size passed to
BPF_PROG_RUN is < ETH_HLEN, which breaks the feature probing of
xdp-trafficgen. Fix this by making the probe use a full ETH_HLEN worth
of data.
Get rid of llc and use clang to build BPF object files directly
It turns out we pass both -S and -c to clang, which has become an error
starting from clang 20. The two-stage build using 'clang -S' followed by
llc was used in the early days of BPF development, but these days, clang
is perfectly happy to produce BPF object files directly.
So use this opportunity to get rid of llc entirely, and simplify the BPF
object build rules while we're add it, by moving all of the -W* defines
to BPF_CFLAGS.
Newer Emacs versions changed the org-mode man page export code, which
results in whitespace changes to all generated man pages. Keep these in
a separate commit to avoid bloating the subsequent version bump commit.
The flowtable test for xdp-forward did not unload the programs after
running, which is why it didn't catch the ambiguous program name error.
Add an unload to the text to make sure this keeps working.
Converting errno returns to program exit status means we may end up
returning SKIPPED_TEST, which messes with the selftests. Change this to
always use EXIT_SUCCESS/EXIT_FAILURE instead.
The DEVMAP map types used by xdp-forward prevents installing xdp-forward
on ifindexes larger than the map size, because the ifindex is also used
as the lookup key. Change to DEVMAP_HASH to avoid this.
xdp-forward: Don't use ambiguous function names for flowtable mode
The BPF function names used by xdp-forward in flowtable mode end up
being ambiguous when truncated by the kernel. This causes xdp-forward to
be unable to unload the programs. Fix this by using shorter function
names.
Lucas Crijns [Mon, 3 Mar 2025 13:28:13 +0000 (14:28 +0100)]
xdp-dump/xdpdump.h: Increase MAX_CPUS to 512
Previously, MAX_CPUS was set to 256. This causes the tool to exit with a failure on systems with more than 256 CPUs.
For example, an AMD EPYC server with two AMD EPYC 9684X 96-Core Processors reports 384 CPUs to the kernel due to hyperthreading.
This fix allows such systems to run the xdpdump utility.
Signed-off-by: Lucas Crijns <lucascrijns@gmail.com>
util/xdp_sample: Collect PPS values for stats_get_devmap_xmit_multi()
Also store the PPS values into the output container in
stats_get_devmap_xmit_multi(), since the PPS values are what we are
printing in the summary lines now.
Fixes: 7b3bbe2f6f16 ("util/xdp_sample: Print PPS values in summary line instead of totals") Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Robert Edmonds [Thu, 13 Feb 2025 05:32:48 +0000 (00:32 -0500)]
Explicitly set PREFIX=/ when installing libbpf headers
When xdp-tools builds the embedded copy of libbpf, it invokes the libbpf
build system to installs it headers, and then constructs a path to
those embedded libbpf headers [0] based on the assumption that libbpf
installed its headers into its default PREFIX value of /usr.
However, if PREFIX is passed to the xdp-tools build system, this
variable gets passed down to the invocation of the libbpf build system
as well, and libbpf installs its headers into a different directory
that doesn't match xdp-tools' LIBBPF_INCLUDE_DIR variable, and the build
fails like this:
$ make PREFIX=/usr/local
[…]
libbpf support: Submodule 'libbpf' (https://github.com/libbpf/libbpf.git) registered for path 'lib/libbpf'
Cloning into '/home/edmonds/src/xdp-tools/lib/libbpf'...
Submodule path 'lib/libbpf': checked out 'fdf402b384cc42ce29bb9e27011633be3cbafe1e'
submodule v1.4.0
[…]
lib
libbpf
CC libbpf/src/libbpf.a
INSTALL libbpf/src/libbpf.a
libxdp
CC staticobjs/libxdp.o
libxdp.c:31:10: fatal error: bpf/libbpf.h: No such file or directory
31 | #include <bpf/libbpf.h>
| ^~~~~~~~~~~~~~
compilation terminated.
This commit explicitly passes PREFIX=/ to the libbpf build system
when installing the embedded libbpf headers, and also updates the
LIBBPF_INCLUDE_DIR variable in the xdp-tools build system to match the
resulting include path, so that the embedded libbpf headers are
installed into a fixed location.