cfreebsdsystems-programming

Network interfaces status tracking on FreeBSD


I'm porting some software to FreeBSD 12 (it's never been run on FreeBSD). The software needs to track the system network interfaces and react immediately on status changes. It's assumed to run with root privileges. In FreeBSD 7 there was combination of kevent and EVFILT_NETDEV but this flag has been removed from FreeBSD 8 and later with no clear replacement.

I know there is a way to retrieve the interfaces using getifaddrs but no idea how to proceed and set handlers on AF_INET and AF_INET6 devices tracking the up/down events.

devd looks promising given that it can catch the respective IFNET events, alas it's prohibited to adjust devd.conf on the target system, therefore I need to implement similar mechanism in my sfw. I have not much time to inspect the source code of devd even though I've tried and it made it even more cryptic.

Could anybody show me the right direction to go? Maybe some of the libdev* system-wide libraries?

Thanks.


Solution

  • Found the respective library which uses devd's multiplexing pipe. It's called libdevdctl and its source code resides in /usr/src/lib/libdevdctl, written in C++, has no extra dependencies. Combination of DevdCtl::Event::NOTIFY and DevdCtl::Consumer was enough. For some reason the shared library in /usr/lib is called libprivatedevdctl.so and according to nm output exposes the needed interface. I reckon it's just an internal library so it's easier to grab the source and use as is in your software.

    Also, it has a severe drawback, it polls the socket with zero timeout in DevdCtl::Consumer::EventsPending which drastically increases CPU usage.