0

I'm currently using 2 interfaces and 1 program, im trying to share the maps between the 2 programs, but I have no idea how to do that.

I have looked on the internet and found people explaining how to do it, but I don't know how to apply it to the code.

Here are the maps im using :

struct bpf_map_def SEC("maps") map1 = {
    .type = BPF_MAP_TYPE_PERCPU_ARRAY,
    .key_size = sizeof(__u32),
    .value_size = sizeof(__u64),
    .max_entries = 2,
};


struct bpf_map_def SEC("maps") map2 = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u32),
    .value_size = sizeof(__u64) * 2,
    .max_entries = 10240000,
};


struct bpf_map_def SEC("maps") map3 = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(__u32),
    .value_size = sizeof(__u64) * 2,
    .max_entries = 10240000,
};

I tried using the XDP-LOADER but when I run it I get :

Couldn't open file 'XDP_prog.o': Operation not supported

I also tried to pin the maps using the .pinning but no success, I get an error when compiling.

I'm also new to ebpf code and I would like to understand how to make this work.

Thanks in advance.

Fyu Sub
  • 1
  • 1

1 Answers1

1

You are onto something. The easiest way to get this to work would be pinning. To make xdploader and libbpf automatically prefer existing pins over creating a new map you need to use the LIBBPF_PIN_BY_NAME pinning option.

However, you are currently defining your maps in the old/legacy way. To use the pinning option we have to refactor the map definition to use BTF style map defintions.

struct {
    __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
    __type(key, __u32);
    __type(value, __u64);
    __uint(max_entries, 2);
    __uint(pinning, LIBBPF_PIN_BY_NAME);
} map1 SEC(".maps");

struct map2_value {__u64 a; __u64 b};
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __type(key, __u32);
    __type(value, struct map2_value);
    __uint(max_entries, 10240000);
    __uint(pinning, LIBBPF_PIN_BY_NAME);
} map2 SEC(".maps");

struct map3_value {__u64 a; __u64 b};
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __type(key, __u32);
    __type(value, struct map3_value);
    __uint(max_entries, 10240000);
    __uint(pinning, LIBBPF_PIN_BY_NAME);
} map3 SEC(".maps");

Note that you should include https://github.com/libbpf/libbpf/blob/master/src/bpf_helpers.h if you had not done so already to provide the macros used in BTF style maps.

I made up map2_value and map3_value I assume you have an existing struct somewhere that was not included in your question, so replace them with the real deal.

This pinning option will tell libbpf (called by xdploader) to look for existing pins with the same name, use those, else create a new map and pin it with the name of the map. Thus two programs with the same map name and definition should share the same map.

After declaring the maps like this, you will be required to specify a pin path with the -p option on the xdploader command which should be a directory in /sys/fs/bpf, that path should be the same when loading both programs.

Dylan Reimerink
  • 5,874
  • 2
  • 15
  • 21
  • Ah, I think the ordering matters when using `SEC`, sorry about that, I edited the answer. Same goes for the order of type and field name in the map values. – Dylan Reimerink Mar 24 '23 at 14:50
  • Thank you for the answer, i don't really get what you mean by "I made up map2_value and map3_value I assume you have an existing struct somewhere that was not included in your question, so replace them with the real deal." I have something like this : struct map2_value {a __u64; b __u64}; struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, __u32); __type(value, struct map2_value); __uint(max_entries, 10240000); __uint(pinning, LIBBPF_PIN_BY_NAME); } SEC(".maps") allowed_ips_map; But i get compilation errors : xdp.c:12:20: error: unknown type name 'a' etc. – Fyu Sub Mar 24 '23 at 14:52
  • Originally you were using sizeof(__u64) * 2 to set the value size, so I assumed that you have a value type somewhere that is 16 bytes big, and _u64[2] or a struct. Its cleaner to use the actual value type if you have it. As for the compilation error, in my original response I had the name and type reversed in the dummy value type, I have since edited to answer, should work now – Dylan Reimerink Mar 24 '23 at 14:57
  • Do you happen to have discord or anything similar ?, I don't want to share all the code here. – Fyu Sub Mar 24 '23 at 15:27
  • I am active on the Cilium & eBPF slack: https://slack.cilium.io/ – Dylan Reimerink Mar 24 '23 at 15:32