>上下文
在 Linux Debian 64 位上研究伯克利数据包过滤器,以过滤打开的套接字接收的数据包。
我使用AF_PACKET
所以我甚至管理数据包的第 2 层。
到目前为止,它工作得很好。但是我必须过滤每个套接字上的每个数据包,而且效率不高。因此,我使用 BPF。
问题
由于我让我的应用程序自己设置了过滤器
setsockopt(sd, SOL_PACKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0 )
我想知道:
如果内核将过滤数据包并将其定向到正确的套接字(在内核级别,系统上每个数据包进行一次过滤)
- 或
如果内核将像以前一样发送所有数据包,并且 BPF 将在每个套接字中过滤(每个数据包将被分析 + 过滤的次数与系统上有打开的套接字一样多,因为每个应用程序都会看到数据包<>混杂模式。这是没有效率的)。
我不确定。
谢谢
黑人 - 但这个问题显示了对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套接字上的数据包过滤器的更多信息,请参阅网络过滤器的内核文档。
bpf 程序将位于内核中。它将处理发送到 setsockopt 调用中标识的特定套接字的数据。如果特定数据包通过过滤器,它将被传递,否则将被过滤掉。
我的意思是强调,使用不同套接字对 API 的两次并行调用不会影响另一个,并且应该正常工作。
关于内核中的内部实现,我不确定。
德克萨斯州