ebpfxdp-bpf

bpf_prog_test_run_opts error 524 when running an XDP program


When I try to call bpf_prog_test_run_opts I receive error number 524 back. I found this other post where the person was facing the same problem, but it was because they were trying to call this function for a program of type tracepoint. It seems that their solution was to create a XDP program instead of a tracepoint. However, in my case my program is a XDP program, and it seems that XDP programs are supported.

This is how the userspace program is looking like:

int main(int argc, char **argv) {
    struct xdp_program *program;
    int err;

    /* Jumping over part that loads and attaches the program */

    int prog_fd = xdp_program__fd(program);

    unsigned char data[1500];

    // Fills the packet with headers
    create_packet(data);

    struct bpf_test_run_opts opts = {
        .sz = sizeof(struct bpf_test_run_opts),
        .data_in = &data,
        .data_size_in = sizeof(data),
    };

    err = bpf_prog_test_run_opts(prog_fd, &opts);
    if (err != 0) {
        perror("bpf_prog_test_run_opts");
        return -1;
    }

    return 0;
}

Meanwhile the XDP program can be really simple, and yet, it shows that error.

SEC("xdp")
int  simply_drop(struct xdp_md *ctx)
{
    return XDP_DROP;
}

I also tried calling the syscall directly, and it still shows the same error. The version of my kernel is 6.5.0.


Solution

  • It seems that this problem was being caused by the fact that xdp_dispatcher was being loaded by default. When an xdp_dispatcher is loaded, all XDP programs attached to it are classified as "ext". So, since extension program type doesn't seem to be supported by bpf_prog_run, it looks to me that when I tried to do the syscall, it returned me errno 524 ENOTSUPP, because the the operation wasn't supported for programs of type "ext".

    So my solution was to load the XDP program directly without xdp_dispatcher. To do so, I did something like:

    // Open the object file and gets the bpf_object
    struct bpf_object *obj = bpf_object__open_file(object_filename, NULL);
    
    // Loads the object
    bpf_object__load(obj);
    
    // Gets the bpf_program from the object
    struct bpf_program *prog = bpf_object__next_program(obj, NULL);
    
    // Gets file descriptor
    int prog_fd = bpf_program__fd(prog);
    
    // Attaches the XDP program without xdp_dispatcher
    bpf_xdp_attach(interface_index, prog_fd, 0, NULL);