0

I am trying to learn ebpf map. Compiling the code with libbpf but getting the error like "Error fixing up map structure, incompatible struct bpf_elf_map used?". Here is my ebpf code:


#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#include <stdint.h>
#include <iproute2/bpf_elf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

#ifndef __section
# define __section(NAME)                  \
    __attribute__((section(NAME), used))
#endif

#ifndef __inline
# define __inline                         \
        inline __attribute__((always_inline))
#endif

struct bpf_map_def SEC("maps") port_h = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 1,
};

static __always_inline int do_inline_hash_lookup(void *inner_map, int port)
{
    int *result;
    if (inner_map != &port_h)
        return 99;
    result = bpf_map_lookup_elem(&port_h, &port);
    return result ? *result : 99;
}

__section("ingress")
int tc_ingress(struct __sk_buff *skb)
{

    void *outer_map, *inner_map;
    do_inline_hash_lookup(inner_map, 100);
    return TC_ACT_OK;
}

__section("egress")
int tc_egress(struct __sk_buff *skb)
{
    return TC_ACT_OK;
}

char LICENSE[] SEC("license") = "GPL";

Here is how I am loading the code into kernel:


tc filter del dev lo ingress
tc filter del dev lo egress

tc filter show dev lo ingress 
# use right device like eth0 or lo

# Add qdisc to a particular interface like eth0 or lo
tc qdisc add dev lo clsact   
# Load the object file into kernel
tc filter add dev lo ingress bpf da obj ./.output/map.bpf.o sec ingress
tc filter add dev lo egress bpf da obj ./.output/map.bpf.o sec egress

Any idea, what I am doing wrong? It will be a great help.

pchaigno
  • 11,313
  • 2
  • 29
  • 54
Omar Faroque Anik
  • 2,531
  • 1
  • 29
  • 42

1 Answers1

2

I think you need to declare your map according to the libbpf style:

#define __uint(name, val) int(*(name))[val]
#define __type(name, val) typeof(val) *(name)

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __type(key, int);
    __type(value, int);
    __uint(max_entries, 1);
} port_h __section(".maps");
pchaigno
  • 11,313
  • 2
  • 29
  • 54
  • Do you have or seen any example? Your answer does not even compile. Thanks – Omar Faroque Anik Feb 21 '22 at 17:39
  • Sorry, my answer was incomplete. It should be fixed now. You can find examples in the Cilium sources: https://github.com/cilium/cilium/blob/v1.11.1/bpf/lib/maps.h. Note you will also need the libbpf version of `tc`. – pchaigno Feb 22 '22 at 11:34