SO_ATTACH_REUSEPORT_CBPF socket option unexpected behavior

Viewed 1177

I am trying use a port from two applications and have each of them receive the packet from a different set of IP addresses. In order to achieve this, I use the SO_REUSEPORT and SO_ATTACH_REUSEPORT_CBPF socket options. My code is as follows:

parentfd = socket(AF_INET, SOCK_STREAM, 0);
if (parentfd < 0)
  error( "ERROR opening socket");

struct sock_filter code[]={
  { 0x28, 0, 0, 0x0000000c },
  { 0x15, 0, 3, 0x00000800 },
  { 0x20, 0, 0, 0x0000001a },
  { 0x15, 2, 0, 0xc0a8ff01 },
  { 0x6, 0, 0, 0x00000000 },
  { 0x6, 0, 0, 0x00040000 },
  { 0x6, 0, 0, 0x00000001 },
};

struct sock_fprog bpf = {
  .len = ARRAY_SIZE(code),
  .filter = code,
};

if (setsockopt(parentfd, SOL_SOCKET, SO_REUSEPORT, (const void *)&optval,sizeof(optval)))
  error("ERROR setting SO_REUSEPORT");

if (setsockopt(parentfd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, (const void *)&bpf, sizeof(bpf)))
  error("ERROR setting SO_ATTACH_REUSEPORT_CBPF);

I also have a different process that listens to the same port using only the SO_REUSEPORT flag. From a machine with IP 192.168.255.1 I am running echo 1234 | ncat 192.168.255.150 1234. Based on my filter I would expect all traffic from that IP address to be received by the second process. However, it is all received by the first. When I change the filter to a simple:

struct sock_filter code[]={ { 0x6, 0, 0, 0x00000001 }, };

It works as expected and all packets are received by the second process. Any idea why this might be happening?

2 Answers
Related