1
votes

Context

Studying Berkeley packet filter on Linux Debian 64 bits to filter the packets received by the opened socket.

I use AF_PACKET so i manage even the layer 2 of packets.

So far it works beautifully. But i have to filter every packet on every socket and it is not efficient. Hence I use BPF.

Question

Since I have my applications set the filters by themselves with

setsockopt(sd, SOL_PACKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0 )

I would like to know :

if the kernel will filter and direct the packets to the right socket (filtering happens once per packet on the system at the kernel level)

  • or

if the kernel will send all the packets as before and bpf will take filter in every socket (each packet will be analyzed + filtered as many times as there are open sockets on the system because every application will see the packet coming <-> promiscuous mode. This is not efficient).

I am not sure.

Thanks

2
@Skynet: Thanks for the edit ;)Larry
no problem bro @LarrySkynet

2 Answers

0
votes

Negro - but the question shows a fundamental misunderstanding of AF_PACKET socket vs. promiscuous mode and I would like to outline that using BPF filters on AF_PACKET sockets in LINUX is implemented in a efficient way (for the usual use-case).

About the general issue with the question:

Using an AF_PACKET socket does not mean that the NIC is switched to promiscuous mode - it just forwards all frames directed to the host to the user space (so filter based on L2 address is still applied - in contrast to a NIC in promiscuous mode that happily ignores a non-matching destination-MAC). This should relax your question at all as the usual frame/packet distribution process is applied even if there is an AF_PACKET socket.

About efficiency:

Only AF_PACKET sockets will see all frames directed to the host. A filter attached to a socket is evaluated per socket. There is no central spot in the kernel that handles all the filters and distributes the frames to its direction. Usually an AF_PACKET socket is used to implement a protocol(handler) in user space. Therefore those old wise guys who implemented AF_PACKET assumed that most frames directed to an AF_PACKET socket will be filtered/dropped cause the user would like to handle only a very specific subset of the frames.

The filter is applied on a socket buffer (skb - a container that holds the frame and its associated control/status data) that is shared by all entities taking part in the frame processing. Only if the filter matches a clone of this buffer is created and handed over to the user. There is even a comment on top of the function responsible for processing the skb in context of a AF_PACKET socket that says:

 * This function makes lazy skb cloning in hope that most of packets
 * are discarded by BPF.

For further information on packet filter on AF_PACKET sockets see the kernel doc for network filter.

-1
votes

The bpf program will sit in the kernel. It will process the data going to the particular socket identified in the setsockopt call. If a particular packet passes the filter, it will get delivered, else it is filtered out.

I mean to emphasize that two parallel invocations of the API with different socket do not affect the other, and should work correctly.

Regarding internal implementation in the kernel, I am not sure.

tx