1 // SPDX-License-Identifier: GPL-2.0 2 #include <net/if.h> 3 #include <test_progs.h> 4 #include <network_helpers.h> 5 6 #define LOCAL_NETNS "xdp_dev_bound_only_netns" 7 8 static int load_dummy_prog(char *name, __u32 ifindex, __u32 flags) 9 { 10 struct bpf_insn insns[] = { BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN() }; 11 LIBBPF_OPTS(bpf_prog_load_opts, opts); 12 13 opts.prog_flags = flags; 14 opts.prog_ifindex = ifindex; 15 return bpf_prog_load(BPF_PROG_TYPE_XDP, name, "GPL", insns, ARRAY_SIZE(insns), &opts); 16 } 17 18 /* A test case for bpf_offload_netdev->offload handling bug: 19 * - create a veth device (does not support offload); 20 * - create a device bound XDP program with BPF_F_XDP_DEV_BOUND_ONLY flag 21 * (such programs are not offloaded); 22 * - create a device bound XDP program without flags (such programs are offloaded). 23 * This might lead to 'BUG: kernel NULL pointer dereference'. 24 */ 25 void test_xdp_dev_bound_only_offdev(void) 26 { 27 struct nstoken *tok = NULL; 28 __u32 ifindex; 29 int fd1 = -1; 30 int fd2 = -1; 31 32 SYS(out, "ip netns add " LOCAL_NETNS); 33 tok = open_netns(LOCAL_NETNS); 34 if (!ASSERT_OK_PTR(tok, "open_netns")) 35 goto out; 36 SYS(out, "ip link add eth42 type veth"); 37 ifindex = if_nametoindex("eth42"); 38 if (!ASSERT_NEQ(ifindex, 0, "if_nametoindex")) { 39 perror("if_nametoindex"); 40 goto out; 41 } 42 fd1 = load_dummy_prog("dummy1", ifindex, BPF_F_XDP_DEV_BOUND_ONLY); 43 if (!ASSERT_GE(fd1, 0, "load_dummy_prog #1")) { 44 perror("load_dummy_prog #1"); 45 goto out; 46 } 47 /* Program with ifindex is considered offloaded, however veth 48 * does not support offload => error should be reported. 49 */ 50 fd2 = load_dummy_prog("dummy2", ifindex, 0); 51 ASSERT_EQ(fd2, -EINVAL, "load_dummy_prog #2 (offloaded)"); 52 53 out: 54 close(fd1); 55 close(fd2); 56 close_netns(tok); 57 /* eth42 was added inside netns, removing the netns will 58 * also remove eth42 veth pair. 59 */ 60 SYS_NOFAIL("ip netns del " LOCAL_NETNS); 61 } 62