Search code examples
linuxsocketsethernetraw-socketsbpf

How to flush raw AF_PACKET socket to get correct filtered packets


sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &f, sizeof (f)) 

With this simple BPF/LPF attach code, when I try to receive packet on the socket, will get some wrong packets that doesn't match with the filter. Seems those packets got into the socket before I call setsockopt().

Seems like should first create the AF_PACKET SOCK_RAW socket, then attach the filter, then flush the socket to get rid of those wrong packets.

So the question is, how to flush those packet?


Solution

  • The "bug" you're describing is real and I've seen it at multiple companies in my career. There is something like an "oral tradition" around this bug that is passed from one network engineer to another. Here are the common fixes:

    1. Just call recv on the socket until it is empty
    2. Double-filter by filtering packets in usermode as well as using the bpf
    3. Use the zero-bpf technique just like libpcap where you apply an empty bpf first, then empty the socket, and then apply the real bpf.

    I've written about this problem extensively on my blog to try and codify the oral tradition around this bug into a concrete recommendation and best-practice.