[Dnsmasq-discuss] Issue with SO_BINDTODEVICE for dhcp
Martin.Wilck at suse.com
Fri Jul 5 11:55:24 BST 2019
I've just found a strange issue with dnsmasq's dhcp server, which I
believe is caused by the commit 9380ba7 "Set SO_BINDTODEVICE on DHCP
sockets when doing DHCP on one interface".
I was running a single instance dnsmasq for on various local interfaces
on my system. At the same time, I was running libvirt managed networks,
which spawn a separate dnsmasq instance for every network created.
(That's the way it has to be with libvirt). The configuration of the
first, multiple-interface instance was done with "listen-address" and
"bind-dynamic"; the listen addresses were 127.0.0.1 plus one address on
every VLAN on this server.
Anyway, the above-mentioned commit causes strange behavior for the
multi-interface dnsmasq instance. SO_BINDTODEVICE will be used if and
only if exactly one of the configured interfaces is up when dnsmasq is
started. In this case, if other interfaces are brought up later, dhcp
queries via these new interfaces don't work, because the dhcp socket is
bound to the first interface only. If at the time of dnsmasq startup,
either 0 or >= 2 interfaces are up, dhcp queries work just fine from
any interface, including those brought up later.
While this is certainly a corner case, it strongly violates the
principle of least surprise - the status at the time of dnsmasq startup
has an effect on whether freshly brought-up interfaces will be serviced
later. Especially with "bind-dynamic", my expectation was that
dynamically added interfaces would be served.
According to the bug report that motivated the mentioned patch (
http://codeha.us/openstack/msg09684.html), such a mixture of multi-
interface and single-interface instances would be doomed to fail
anyway, because of the issues related to receiving DHCP unicast
packets. Thus perhaps this configuration should be generally forbidden
- but I, for one, have not observed the reported unicast-packet issues
(failing dhcp requests or renewals) up to now.
Would it perhaps be possible to re-run the SO_BINDTODEVICE logic in the
newaddress() code path, and dynamically bind/undbind the socket if the
number of dhcp interfaces changed between 1 and something else?
More information about the Dnsmasq-discuss