How to bind a UDP socket using SO_ATTACH_REUSEPORT_CBPF?

63 views Asked by At

My program works fine without all the lines below SO_REUSEPORT, but each flow of UDP packets is statically assigned to one listener, causing uneven utilisation of cores.

When I add the code to randomly assign UDP packets to listeners, using SO_ATTACH_REUSEPORT_CBPF, it fails.

int optval = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));

struct sock_filter code[3] = {
    /* Load random to A */
    { BPF_LD  | BPF_W | BPF_ABS,  0,  0, 0xfffff038 },
    
    /* A = A % mod */
    { BPF_ALU | BPF_MOD, 0, 0, 8 /* threads */ },
    
    /* return A */
    { BPF_RET | BPF_A, 0, 0, 0 },
};
struct sock_fprog bpf = {
    .len = 3,
    .filter = code,
};

setsockopt(sock, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf));

What is my mistake?

1

There are 1 answers

0
fadedbee On

My first mistake was calling setsockopt(sock, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf)); before I had bound the socket.

My second mistake was not including the bind() in my question's code snippet.

You must bind the socket before using SO_ATTACH_REUSEPORT_CBPF, whereas you need to set SO_REUSEPORT before binding.