[Dnsmasq-discuss] FreeBSD complement to Linux's netlink: route(4) socket (was: 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle)

Matthias Andree matthias.andree at gmx.de
Thu Dec 5 00:13:13 GMT 2013

Am 03.12.2013 12:11, schrieb Simon Kelley:

> The standard fix is to use --bind-dynamic, which can rely  on the
> existence of the extended API. Unfortunately that doesn't work on
> FreeBSD because it also relies on a a method of getting asynchronous
> events when interfaces/address come and go. Does FreeBSD have an
> equivalent of the Linux netlink socket?

Following up on this question, I asked the FreeBSD-hackers@ list and got
a useful pointer from Ian Lepore to the PF_ROUTE SOCK_RAW socket.
The family can be used as an address filter, I used AF_UNSPEC.

If a user-space application has such a route socket open, it can change
the route table, or receive information from the kernel - not only about
route changes, but also address changes, interface flag changes,
interfaces appearing or dematerializing.  You could use

The relevant information is in man 4 route, and in the headers
(sys/socket.h, net/if.h, for instance).

I dug around and have come up with a demo program that opens a route
socket, selects() for messages, receives them, and decodes those I would
find interesting for dnsmasq.  It took quite a bit of debugging to get
the addresses in the messages decoded properly.

It's not pretty in that it's mostly undocumented, contains some
arbitrarily sized buffers, but compiles and runs without warnings in the
strictest standard settings on FreeBSD 9.1 i386, 9.2 amd64 and 10-STABLE
amd64, and should not have blatant bugs (buffer overruns).

Sorry for not decoding the names of the message types (RTM_*) either, I
am out of energy for tonight ;)

The route socket exposes more information, but we probably don't care -
those message types are listed, but not decoded.

The demo program is at
<http://people.freebsd.org/%7Emandree/try-rtsock.c>, a copy is attached,
and to use it, fire up two logins.

In one, compile the program, f. i.:

   cc -O -Wall -o try-rtsock try-rtsock.c

Run it (does not require root permissions):


and in the other login, try around with adding aliases whilst watching
the output of try-rtsock.

(If two logins are too cumbersome, you can also use one, and run
"./try-rtsock &" in the background.)

ifconfig lo0 inet alias	# add alias
ifconfig lo0 inet -alias	# kill it

ifconfig em0 inet6 2001:.... -alias	# kill global address
ifconfig em0 inet6 accept_rtadv		# accept autoconf
rtsol -a				# solicit autoconf
# ...

ifconfig gif0 plumb up			# create new i'face
ifconfig gif0 down			# mark it down
ifconfig gif0 unplumb			# destroy it

and after each command see what you've got from try-rtsock.

Hope that helps.

Best regards

-------------- next part --------------
A non-text attachment was scrubbed...
Name: try-rtsock.c
Type: text/x-csrc
Size: 4572 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20131205/fb92accf/attachment.c>

More information about the Dnsmasq-discuss mailing list