xdp-loader seems unable to pin internal .data map?
vincentmli opened this issue · comments
Hi @tohojo
I have fork of xdp-tools, based on that, I added a few xdp program in my fork repo, for example this xdp-udp (https://github.com/vincentmli/xdp-tools/blob/vli-xdp-synproxy/xdp-udp/xdp_udp.bpf.c#L54) has global variable ratelimit
, when I ran command
xdp-loader load red0 -P 90 -p /sys/fs/bpf/xdp-udp -n xdp_udp /usr/lib/bpf/xdp_udp.bpf.o
to pin bpf map to /sys/fs/bpf/xdp-udp
directory, but the .data
map is not pinned under that directory, other maps are pinned
[root@firebee ~]# ls -l /sys/fs/bpf/xdp-udp/
total 0
-rw------- 1 root root 0 Apr 19 09:58 udp_exclude_v4_prefixes
-rw------- 1 root root 0 Apr 19 09:58 udp_rate_table
here is the internal map name for the .data
map from bpftool output
bpftool map | grep -A2 'xdp_udp.data'
202: array name xdp_udp.data flags 0x0
key 4B value 4B max_entries 1 memlock 328B
btf_id 323
in my fork of xdp-tools repo, the xdp-loader had this revert Revert "xdp-loader: Only load the BPF program we need from object files", so I can load xdp program with tail calls, that revert seems should not affect the pin map feature.
I did another test with a simple xdp_pass program with xdp-loader from upstream xdp-tools repo
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <xdp/xdp_helpers.h>
struct {
__uint(priority, 10);
__uint(XDP_PASS, 1);
} XDP_RUN_CONFIG(xdp_pass);
static volatile unsigned int ratelimit = 1000;
SEC("xdp")
int xdp_pass(struct xdp_md *ctx)
{
bpf_printk("ratelimit %d \n",ratelimit);
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
load the program
./xdp-loader/xdp-loader load -m skb lo -p /sys/fs/bpf/xdp-pass ./lib/testing/xdp_pass.o
ls -l /sys/fs/bpf/xdp-pass
ls: cannot access '/sys/fs/bpf/xdp-pass': No such file or directory
bpftool shows the map
bpftool map | grep -A2 'xdp_pass.data'
92: array name xdp_pass.data flags 0x0
key 4B value 4B max_entries 1 memlock 4096B
btf_id 223
it looks xdp-loader can't pin the internal .data
map, I wonder if this is not supported in kernel, not xdp-loader issue.
it looks libbpf does not take the pin_root_path for global data map, Is it intended to not expose global data map to bpf fs ?
https://github.com/libbpf/libbpf/blob/master/src/libbpf.c#L2977-L2993
static int bpf_object__init_maps(struct bpf_object *obj,
const struct bpf_object_open_opts *opts)
{
const char *pin_root_path;
bool strict;
int err = 0;
strict = !OPTS_GET(opts, relaxed_maps, false);
pin_root_path = OPTS_GET(opts, pin_root_path, NULL);
err = bpf_object__init_user_btf_maps(obj, strict, pin_root_path);
err = err ?: bpf_object__init_global_data_maps(obj);
err = err ?: bpf_object__init_kconfig_map(obj);
err = err ?: bpf_object_init_struct_ops(obj);
return err;
}
fyi, bpftool can update global .data map directly by iterate through map ids to get the global data map fd, no need to expose global data map to bpf fs