]> git.feebdaed.xyz Git - 0xmirror/xdp-tools.git/commitdiff
xdp-trafficgen: Fix automatic loading of xdp_pass program
authorToke Høiland-Jørgensen <toke@redhat.com>
Wed, 13 Aug 2025 15:11:56 +0000 (17:11 +0200)
committerToke Høiland-Jørgensen <toke@redhat.com>
Wed, 13 Aug 2025 15:11:56 +0000 (17:11 +0200)
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.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
xdp-trafficgen/xdp-trafficgen.c

index 46b2d0b7b748c15bf89202b18c07bf1e16c06ffd..5d336feeaa6d368e097ca7adc497cf218b042999 100644 (file)
@@ -71,6 +71,7 @@ static const char *driver_pass_list[] = {
 static bool driver_needs_xdp_pass(const struct iface *iface)
 {
        const char *name = get_driver_name(iface->ifindex);
+       struct xdp_multiprog *mp;
        __u64 feature_flags;
        size_t i;
        int err;
@@ -80,6 +81,13 @@ static bool driver_needs_xdp_pass(const struct iface *iface)
        if (!err && feature_flags & NETDEV_XDP_ACT_NDO_XMIT)
                return false;
 
+       mp = xdp_multiprog__get_from_ifindex(iface->ifindex);
+       if (!IS_ERR_OR_NULL(mp)) {
+               pr_debug("Interface %s already has an XDP program loaded\n", iface->ifname);
+               xdp_multiprog__close(mp);
+               return false;
+       }
+
        for (i = 0; i < ARRAY_SIZE(driver_pass_list); i++) {
                if (!strcmp(name, driver_pass_list[i])) {
                        pr_debug("Driver %s on interface %s needs an xdp_pass program to use XDP_REDIRECT\n",
@@ -522,8 +530,10 @@ int do_udp(const void *opt, __unused const char *pin_root_path)
        }
 
        if (driver_needs_xdp_pass(&cfg->iface)) {
-               opts.prog_name = "xdp_pass";
-               pass_prog = xdp_program__create(&opts);
+               DECLARE_LIBXDP_OPTS(xdp_program_opts, pass_opts);
+               pass_opts.prog_name = "xdp_pass";
+               pass_opts.find_filename = "xdp-dispatcher.o";
+               pass_prog = xdp_program__create(&pass_opts);
                if (!pass_prog) {
                        err = -errno;
                        pr_warn("Couldn't load xdp_pass program\n");
@@ -539,7 +549,7 @@ int do_udp(const void *opt, __unused const char *pin_root_path)
                err = xdp_program__attach(pass_prog, cfg->iface.ifindex,
                                          XDP_MODE_NATIVE, 0);
                if (err) {
-                       pr_warn("Couldn't attach xdp_pass program");
+                       pr_warn("Couldn't attach xdp_pass program\n");
                        xdp_program__close(pass_prog);
                        pass_prog = NULL;
                        goto out;