使用PF_PACKET类型的套接字时,PACKET_ADD_MEMBERSHIP是什么意思?

When using PF_PACKET type of socket, what does PACKET_ADD_MEMBERSHIP?

当使用协议类型为 ETH_P_IPPF_PACKET 套接字时,man packet 文档讨论了用于多播的套接字选项。套接字选项是PACKET_ADD_MEMBERSHIP.

假设您在 PF_PACKET 套接字上正确使用 PACKET_ADD_MEMBERSHIP 套接字选项,那么此套接字选项有哪些功能、优点和用例?

现在我收到所有传入的 IP 数据包,所以我查看每个数据包以查看它是否具有正确的 IP dst-address 和 UDP dst-port,然后我跳过所有其他数据包。 使用 PACKET_ADD_MEMBERSHIP 套接字选项是否意味着我不需要做我自己的过滤器,因为内核或驱动程序会为我过滤?


我深入研究了 linux-kernel 源代码并稍微追踪了代码。我发现您通过 setsockopt() 传入的以太网-mac-地址已添加到以太网-mac-地址列表中。然后列表被发送到网络设备硬件做一些事情......但我找不到任何权威文档告诉我接下来会发生什么。

我有根据的猜测是硬件使用以太网-mac-地址列表来过滤第 2 层以太网协议(即硬件只接受目标以太网地址为匹配列表中的一个)。如果有一些好的文档,我会很欢迎。

(我更熟悉 TCP/UDP 套接字,所以这看起来与 AF_INET type of socketIP_ADD_MEMBERSHIP 套接字选项非常相似......所以我期待 IGMP 报告生成的将启动来自路由器的多播流量...但我通过实验发现当您使用此套接字选项时不会生成 IGMP 报告。)

你猜对了。 PACKET_ADD_MEMBERSHIP 应该将地址添加到 NIC 的硬件过滤器。正如您所猜测的那样,它旨在允许您接收多个不同地址的多播,而不会产生完全混杂模式的负载(*)。

(* 使用现代全双工以太网,通常不会有大量流量进入 NIC,它无论如何也不想接收,除非它处于虚拟化环境中。)

请注意,还有一个单独的 PACKET_MR_UNICAST,它没有出现在 packet(7) 手册页中,但工作方式类似。对于要过滤的地址类型,我会使用适当的地址(单播与多播),因为可以想象(尽管不太可能)驱动程序会拒绝将单播地址放入多播过滤 table。

综上所述,您仍然需要保留软件过滤作为备份。有一些较旧的驱动程序根本不实现 MAC 过滤(特别是对于多个单播地址)。如果该功能不可用,核心内核或驱动程序会通过简单地打开混杂模式来处理此问题。

至于与IP_ADD_MEMBERSHIP的关系,IP_ADD_MEMBERSHIP代码会自动构造出合适的多播MAC地址,并添加到接口中。参见 ip_mc_filter_add。