1

语境

在 Linux Debian 64 位上研究 Berkeley 数据包过滤器,对打开的套接字接收到的数据包进行过滤。

我使用AF_PACKET所以我甚至管理第 2 层数据包。

到目前为止,它工作得很好。但是我必须过滤每个套接字上的每个数据包,而且效率不高。因此我使用 BPF。

问题

因为我有我的应用程序自己设置过滤器

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

我想知道 :

如果内核将过滤数据包并将其定向到正确的套接字(过滤在内核级别的系统上每个数据包发生一次)

  • 或者

如果内核将像以前一样发送所有数据包,并且 bpf 将在每个套接字中进行过滤(每个数据包将被分析 + 过滤的次数与系统上打开的套接字一样多,因为每个应用程序都会看到数据包进入 <-> 混杂模式. 这效率不高)。

我不知道。

谢谢

4

2 回答 2

0

黑人 - 但这个问题显示了对 AF_PACKET 套接字与混杂模式的根本误解,我想概述一下,在 LINUX 中的 AF_PACKET 套接字上使用 BPF 过滤器是以一种有效的方式实现的(对于通常的用例)。

关于问题的一般问题:

使用 AF_PACKET 套接字并不意味着 NIC 切换到混杂模式 - 它只是将所有指向主机的帧转发到用户空间(因此仍然应用基于 L2 地址的过滤器 - 与混杂模式下的 NIC 相比,它很高兴忽略不匹配的目标 MAC)。这应该完全放松您的问题,因为即使存在 AF_PACKET 套接字,也会应用通常的帧/数据包分发过程。

关于效率:

只有 AF_PACKET 套接字会看到定向到主机的所有帧。连接到套接字的过滤器按套接字进行评估。内核中没有处理所有过滤器并将帧分配到其方向的中心点。通常一个 AF_PACKET 套接字用于在用户空间中实现一个协议(处理程序)。因此,那些实现 AF_PACKET 的老聪明人假设大多数指向 AF_PACKET 套接字的帧都将被过滤/丢弃,因为用户只想处理非常特定的帧子集。

过滤器应用于套接字缓冲区(skb - 保存帧及其相关控制/状态数据的容器),该缓冲区由参与帧处理的所有实体共享。仅当过滤器匹配此缓冲区的克隆时,才会创建并移交给用户。甚至在负责处理 AF_PACKET 套接字上下文中的 skb的函数顶部还有一条注释,上面写着:

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

有关 AF_PACKET 套接字上的数据包过滤器的更多信息,请参阅网络过滤器的内核文档

于 2017-10-18T22:12:06.323 回答
-1

bpf 程序将位于内核中。它将处理进入 setsockopt 调用中标识的特定套接字的数据。如果一个特定的数据包通过了过滤器,它将被传递,否则它被过滤掉。

我的意思是要强调,具有不同套接字的 API 的两个并行调用不会影响另一个,并且应该可以正常工作。

关于内核中的内部实现,我不确定。

发送

于 2017-05-02T06:28:41.830 回答