I'm in the process of porting a user-space network driver to a newer linux version.
The idea is to get rid of a custom kernel module that connected the network stack of the kernel to the driver and use TUN/TAP instead.
The problem I face now is with adding/removing multicast addresses that the driver should listen to on the wire.
I know how to obtain the list of current multicast addresses for the interface with
cat /proc/net/dev_mcast
But I don't get any event when the list changes.
When the driver should listen to a new multicast address, user space calls:
struct ip_mreq group;
group.imr_multiaddr.s_addr = inet_addr("226.1.1.1"); // multicast address
group.imr_interface.s_addr = inet_addr("172.16.72.100"); // interface address
setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(group));
This leads in the kernel to a call of
struct net_device_op.ndo_set_rx_mode
The driver then can update its (hardware) multicast filters.
Unfortunately the callback in the TAP driver is empty.
Is there any alternative way to detect changes in the multicast reception (without polling)?
I tried netlink messages, but the RTNLGRP_NEIGH doesn't report changes to the multicast addresses.
Monitoring /proc/net/dev_mcast with inotify also doesn't work, as inotify is not supported on virtual file systems.
Thanks, Wolfgang
Usespace routing daemons normally listen to a routing netlink socket and epoll for status to react to events. I think that should give you the desired behavior.
If you have to do more advanced multicast routing you may want to look into a special Linux kernel hook meant for multicast routing daemons to manage the multicast route table labeled CONFIG_IP_MROUTE.
The mechanism is explained well in this article: http://www.linuxjournal.com/article/6070
An example of a simple multicast routing daemon that uses this hook is: http://troglobit.com/projects/smcroute/