[PATCH bpf-next v4 3/3] selftests/bpf: xdp: test dev_xdp_install() rejects device-bound program

Jiayuan Chen <[email protected]>
Newsgroups org.kernel.vger.linux-kselftest,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.netdev
Message-ID <[email protected]>
bpf_xdp_link_update() used to skip the checks in dev_xdp_attach(). Add a
test that makes a generic XDP link with a normal program and then tries
to swap in a device-bound program, which must fail.

Signed-off-by: Jiayuan Chen <[email protected]>
---
 .../bpf/prog_tests/xdp_dev_bound_only.c       | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_dev_bound_only.c b/tools/testing/selftests/bpf/prog_tests/xdp_dev_bound_only.c
index 7dd18c6d06c6..4a13f8ec4300 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_dev_bound_only.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_dev_bound_only.c
@@ -1,9 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <net/if.h>
+#include <linux/if_link.h>
 #include <test_progs.h>
 #include <network_helpers.h>
 
 #define LOCAL_NETNS "xdp_dev_bound_only_netns"
+#define LINK_UPDATE_NETNS "xdp_dev_bound_only_lu_netns"
 
 static int load_dummy_prog(char *name, __u32 ifindex, __u32 flags)
 {
@@ -59,3 +61,50 @@ void test_xdp_dev_bound_only_offdev(void)
 	 */
 	SYS_NOFAIL("ip netns del " LOCAL_NETNS);
 }
+
+/* A device-bound program must not run on the XDP software path.
+ * dev_xdp_attach() rejected such programs, but bpf_xdp_link_update() reaches
+ * dev_xdp_install() directly and bypasses it, so the check has to live in
+ * dev_xdp_install(). Create a generic (SKB) XDP link with a normal program,
+ * then try to swap in a device-bound program via BPF_LINK_UPDATE.
+ */
+void test_xdp_dev_bound_only_link_update(void)
+{
+	LIBBPF_OPTS(bpf_link_create_opts, lopts, .flags = XDP_FLAGS_SKB_MODE);
+	int base_fd = -1, devbound_fd = -1, link_fd = -1;
+	struct nstoken *tok = NULL;
+	__u32 ifindex;
+	int err;
+
+	SYS(out, "ip netns add " LINK_UPDATE_NETNS);
+	tok = open_netns(LINK_UPDATE_NETNS);
+	if (!ASSERT_OK_PTR(tok, "open_netns"))
+		goto out;
+
+	SYS(out, "ip link add eth42 type veth");
+	ifindex = if_nametoindex("eth42");
+	if (!ASSERT_NEQ(ifindex, 0, "if_nametoindex"))
+		goto out;
+
+	devbound_fd = load_dummy_prog("devbound", ifindex, BPF_F_XDP_DEV_BOUND_ONLY);
+	if (!ASSERT_GE(devbound_fd, 0, "load_dummy_prog devbound"))
+		goto out;
+
+	base_fd = load_dummy_prog("base", 0, 0);
+	if (!ASSERT_GE(base_fd, 0, "load_dummy_prog base"))
+		goto out;
+
+	link_fd = bpf_link_create(base_fd, ifindex, BPF_XDP, &lopts);
+	if (!ASSERT_GE(link_fd, 0, "bpf_link_create"))
+		goto out;
+
+	err = bpf_link_update(link_fd, devbound_fd, NULL);
+	ASSERT_EQ(err, -EINVAL, "link_update device-bound rejected");
+
+out:
+	close(link_fd);
+	close(base_fd);
+	close(devbound_fd);
+	close_netns(tok);
+	SYS_NOFAIL("ip netns del " LINK_UPDATE_NETNS);
+}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.