xdp-project / xdp-tools

Utilities and example programs for use with XDP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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