Search code examples
ebpf

bpf_prog_test_run_opts returns "Unknown error 524" when trying to run eBPF program


I'm trying to load and run a very simple eBPF program and I am faced with an obscure error code (524). The program that I'm trying to load is very simple:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

SEC("tracepoint/syscalls/sys_exit_open")
int tracepoint__syscalls__sys_exit_open(struct trace_event_raw_sys_exit* ctx)
{
    return 0;
}

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

The eBPF program is loaded using the generated skeleton:

int main (int argc, char *argv[]) {
        struct __sk_buff skb = {0};
        struct hello_bpf *skel;
        int prog_fd, err = 0;

        // define our BPF_PROG_RUN options with our mock data.
        struct bpf_test_run_opts opts = {
                // required, or else bpf_prog_test_run_opts will fail
                .sz = sizeof(struct bpf_test_run_opts),
                // ctx is an skb in this case
                .ctx_in = &skb,
                .ctx_size_in = sizeof(skb)
        };

        // load our fib lookup test program into the Kernel and return our
        // skeleton handle to it.
        skel = hello_bpf__open_and_load();
        if (!skel) {
                printf("[error]: failed to open and load skeleton: %d\n", err);
                return -1;
        }

        // get the prog_fd from the skeleton, and run our test.
        prog_fd = bpf_program__fd(skel->progs.tracepoint__syscalls__sys_exit_open);
        err = bpf_prog_test_run_opts(prog_fd, &opts);
        if (err != 0) {
                printf("[error]: bpf test run failed: %d\n", err); // -1
                perror("bpf_prog_test_run_opts"); // bpf_prog_test_run_opts: Unknown error 524
                return -2;
        }

        return 0;
}

When trying to run the compiled binary I'm faced with the error: "Unknown error 524". Can anybody point me in the right direction?

Kernel Configuration

CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
# BPF subsystem
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
# CONFIG_BPF_PRELOAD is not set
CONFIG_BPF_LSM=y
# end of BPF subsystem
CONFIG_CGROUP_BPF=y
CONFIG_IPV6_SEG6_BPF=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_BPFILTER=y
CONFIG_BPFILTER_UMH=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_BPF_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_TEST_BPF=m

Makefile

all: hello.bpf.o hello.skel.h test

hello.bpf.o: hello.bpf.c
    clang -target bpf -Wall -O2 -c $<

hello.skel.h: hello.bpf.o
    bpftool gen skeleton $< > $@

test: test.c
    gcc -Wall -o $@ $< -lbpf
    

.PHONY:
clean:
    rm -rf hello.bpf.o
    rm -rf hello.skel.h
    rm -rf test

Solution

  • 524 is the error code for ENOTSUPP, meaning the operation is not supported.

    And checking the sources, BPF_PROG_RUN is indeed not supported for programs of type tracepoint. It seems to be supported for raw tracepoints, so you could try that (though that will depend on the kernel version).