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?
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 setSO_REUSEPORT
before binding.