Skip to content
Advertisement

When using PF_PACKET type of socket, what does PACKET_ADD_MEMBERSHIP?

When using a PF_PACKET type of socket with protocol type ETH_P_IP, the man packet documentation talks about a socket option for multicast. The socket option is PACKET_ADD_MEMBERSHIP.

Assuming you use PACKET_ADD_MEMBERSHIP socket option on a PF_PACKET socket correctly, what features and benefits and use cases is this socket option for?

Right now I receive all incoming IP packets so I look at each packet to see if it has the correct IP dst-address and UDP dst-port and I skip over all the other packets. Would using PACKET_ADD_MEMBERSHIP socket option mean I don’t need to do my own filter because the kernel or driver would filter for me?


I dug into the linux-kernel source and traced down the code a little bit. I found that the ethernet-mac-address you pass in via setsockopt() is added to a list of ethernet-mac-addresses. And then the list is sent to the network-device hardware to do something… but I can’t find any authoritative documentation telling me what happens next.

My educated guess is that the ethernet-mac-address list is used by the hardware to filter at the layer-2 ethernet protocol (i.e. the hardware only accepts packets that have a destination ethernet-address that matches one on the list). If there is some good documentation I would welcome that.

(I’m more familiar with TCP/UDP sockets and so this looks very similar to AF_INET type of socket‘s IP_ADD_MEMBERSHIP socket option… so I was expecting IGMP reports to be generated which would start multicast traffic from the router… but I found out experimentally that no IGMP reports are generated when you use this socket option.)

Advertisement

Answer

Your guess is correct. PACKET_ADD_MEMBERSHIP should add addresses to the NIC’s hardware filter. As you’ve surmised, it’s intended to allow you to receive multicasts for a number of different addresses without incurring the load(*) of full promiscuous mode.

(* With modern full duplex ethernet, there’s generally not a lot of traffic coming to the NIC that it wouldn’t want to receive anyway, unless it’s in a virtualized environment.)

Note that there is also a separate PACKET_MR_UNICAST which does not appear in the packet(7) man page but works analogously. I would use the appropriate one (unicast vs multicast) for the type of address you’re filtering on, as it’s conceivable (though unlikely) that a driver would refuse to put a unicast address into the multicast filtering table.

All that being said, you’ll still need to keep your software filtering as backup. There are some older drivers that don’t implement MAC filtering at all (particularly for multiple unicast addresses). The core kernel or the driver handles this by simply turning on promiscuous mode if the feature isn’t available.

As for the relationship with IP_ADD_MEMBERSHIP, the IP_ADD_MEMBERSHIP code will automatically construct the appropriate multicast MAC address and add it to the interface. See ip_mc_filter_add.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement