1 // SPDX-License-Identifier: GPL-2.0 2 #include <uapi/linux/bpf.h> 3 #include <linux/if_link.h> 4 #include <test_progs.h> 5 6 #include "test_xdp_devmap_helpers.skel.h" 7 #include "test_xdp_with_devmap_helpers.skel.h" 8 9 #define IFINDEX_LO 1 10 11 struct bpf_devmap_val { 12 u32 ifindex; /* device index */ 13 union { 14 int fd; /* prog fd on map write */ 15 u32 id; /* prog id on map read */ 16 } bpf_prog; 17 }; 18 19 void test_xdp_with_devmap_helpers(void) 20 { 21 struct test_xdp_with_devmap_helpers *skel; 22 struct bpf_prog_info info = {}; 23 struct bpf_devmap_val val = { 24 .ifindex = IFINDEX_LO, 25 }; 26 __u32 len = sizeof(info); 27 __u32 duration = 0, idx = 0; 28 int err, dm_fd, map_fd; 29 30 31 skel = test_xdp_with_devmap_helpers__open_and_load(); 32 if (CHECK_FAIL(!skel)) { 33 perror("test_xdp_with_devmap_helpers__open_and_load"); 34 return; 35 } 36 37 /* can not attach program with DEVMAPs that allow programs 38 * as xdp generic 39 */ 40 dm_fd = bpf_program__fd(skel->progs.xdp_redir_prog); 41 err = bpf_set_link_xdp_fd(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE); 42 CHECK(err == 0, "Generic attach of program with 8-byte devmap", 43 "should have failed\n"); 44 45 dm_fd = bpf_program__fd(skel->progs.xdp_dummy_dm); 46 map_fd = bpf_map__fd(skel->maps.dm_ports); 47 err = bpf_obj_get_info_by_fd(dm_fd, &info, &len); 48 if (CHECK_FAIL(err)) 49 goto out_close; 50 51 val.bpf_prog.fd = dm_fd; 52 err = bpf_map_update_elem(map_fd, &idx, &val, 0); 53 CHECK(err, "Add program to devmap entry", 54 "err %d errno %d\n", err, errno); 55 56 err = bpf_map_lookup_elem(map_fd, &idx, &val); 57 CHECK(err, "Read devmap entry", "err %d errno %d\n", err, errno); 58 CHECK(info.id != val.bpf_prog.id, "Expected program id in devmap entry", 59 "expected %u read %u\n", info.id, val.bpf_prog.id); 60 61 /* can not attach BPF_XDP_DEVMAP program to a device */ 62 err = bpf_set_link_xdp_fd(IFINDEX_LO, dm_fd, XDP_FLAGS_SKB_MODE); 63 CHECK(err == 0, "Attach of BPF_XDP_DEVMAP program", 64 "should have failed\n"); 65 66 val.ifindex = 1; 67 val.bpf_prog.fd = bpf_program__fd(skel->progs.xdp_dummy_prog); 68 err = bpf_map_update_elem(map_fd, &idx, &val, 0); 69 CHECK(err == 0, "Add non-BPF_XDP_DEVMAP program to devmap entry", 70 "should have failed\n"); 71 72 out_close: 73 test_xdp_with_devmap_helpers__destroy(skel); 74 } 75 76 void test_neg_xdp_devmap_helpers(void) 77 { 78 struct test_xdp_devmap_helpers *skel; 79 __u32 duration = 0; 80 81 skel = test_xdp_devmap_helpers__open_and_load(); 82 if (CHECK(skel, 83 "Load of XDP program accessing egress ifindex without attach type", 84 "should have failed\n")) { 85 test_xdp_devmap_helpers__destroy(skel); 86 } 87 } 88 89 90 void test_xdp_devmap_attach(void) 91 { 92 if (test__start_subtest("DEVMAP with programs in entries")) 93 test_xdp_with_devmap_helpers(); 94 95 if (test__start_subtest("Verifier check of DEVMAP programs")) 96 test_neg_xdp_devmap_helpers(); 97 } 98