[Dnsmasq-discuss] Answer DHCP requests when dnsmasq is not bound to the 1st IP of an interface

Simon Kelley simon at thekelleys.org.uk
Fri Dec 2 10:12:00 GMT 2011


On 01/12/11 13:45, dnsmasq.20.masuefke at spamgourmet.com wrote:
> Hello,
>> In the meantime, I re-implemented your
>> patch  to fit in a bit better with the existing code and tidy up some of
>> the network access code. In most cases, it will still use the primary
>> address for the server-id in the case I talked about above, but if there
>> is a --listen-address for a secondary address, and _no_ listen address
>> for the primary address, it will used the secondary address. I think
>> that should avoid surprises in most cases.
>>
>> http://www.thekelleys.org.uk/dnsmasq/test-releases/dnsmasq-2.60.tar.gz
>>
>> I'd be grateful if you could test it and see if it works as expected.
>>
> I tested today, the dnsmasq -v says this:
> Dnsmasq version 2.60test1  Copyright (c) 2000-2011 Simon Kelley
> Compile time options IPv6 GNU-getopt no-DBus no-i18n DHCP TFTP
> no-conntrack no-IDN
>
> Unfortunately, it does not work at all. DHCP DISCOVER packets are not
> answered and there is no indication that dnsmasq has processed the
> broadcast message more than checking the interface it arrived on. This
> last step seems to fail.
>
> Setup:
> br0 is a bridge interface, comprising eth0 and some other devices.
> I redacted addresses as a.b.c.xx . The same letter sequence is kept
> constant for the same addresses in all of the following.
>
>
> Output of  "ip a s br0":
> 7: br0:<BROADCAST,MULTICAST,UP,LOWER_UP>  mtu 1500 qdisc noqueue state UP
>      link/ether ii:jj:kk:ll:mm:nn brd ff:ff:ff:ff:ff:ff
>      inet a.b.c.10/24 brd a.b.c.255 scope global br0
>      inet a.b.c.11/24 scope global secondary br0
>      inet6 fe80::iijj:kkoo:ppll:mmnn/64 scope link
>         valid_lft forever preferred_lft forever
>
>
> Dnsmasq configuration file excerpt:
> bridge-interface=br0,eth0
> listen-address=a.b.c.11
> listen-address=127.0.0.1
> bind-interfaces
> log-dhcp
> dhcp-range=a.b.c.50,a.b.c.150,255.255.255.0,24h
>
>
> Netstat'ing the ports for DNS and DHCP:
> $ netstat -nulp | grep dnsmasq
> udp        0      0 127.0.0.1:53 0.0.0.0:* 14188/dnsmasq
> udp        0      0 a.b.c.11:53  0.0.0.0:* 14188/dnsmasq
> udp        0      0 0.0.0.0:67   0.0.0.0:* 14188/dnsmasq
>
>
> Stracing the running dnsmasq when a dhcp packet is expected leads to this:
> $ strace -p 14188 -p 14189
> Process 14188 attached - interrupt to quit
> Process 14189 attached - interrupt to quit
> [pid 14189] read(13,<unfinished ...>
> [pid 14188] select(11, [3 5 6 7 8 9 10], [], [], NULL) = 1 (in [5])
> [pid 14188] time(NULL)                  = 1322742647
> [pid 14188] recvmsg(5, {msg_name(16)={sa_family=AF_INET,
> sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")},
> msg_iov(1)=[{"\1\1\6\0\266z\204(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\23)"...,
>
> 548}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=,
> ...}, msg_flags=0}, MSG_PEEK|MSG_TRUNC) = 309
> [pid 14188] recvmsg(5, {msg_name(16)={sa_family=AF_INET,
> sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")},
> msg_iov(1)=[{"\1\1\6\0\266z\204(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\23)"...,
>
> 548}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=,
> ...}, msg_flags=0}, 0) = 309
> [pid 14188] ioctl(5, SIOCGIFNAME, {ifr_index=7, ifr_name="br0"}) = 0
> [pid 14188] ioctl(5, SIOCGIFADDR, {ifr_name="br0", ifr_addr={AF_INET,
> inet_addr("a.b.c.10")}}) = 0
> [pid 14188] select(11, [3 5 6 7 8 9 10], [], [], NULL) = 1 (in [5])
> [pid 14188] time(NULL)                  = 1322742647
> [pid 14188] recvmsg(5, {msg_name(16)={sa_family=AF_INET,
> sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")},
> msg_iov(1)=[{"\1\1\6\0\266z\204(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\23)"...,
>
> 548}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=,
> ...}, msg_flags=0}, MSG_PEEK|MSG_TRUNC) = 321
> [pid 14188] recvmsg(5, {msg_name(16)={sa_family=AF_INET,
> sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")},
> msg_iov(1)=[{"\1\1\6\0\266z\204(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\23)"...,
>
> 548}], msg_controllen=32, {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=,
> ...}, msg_flags=0}, 0) = 321
> [pid 14188] ioctl(5, SIOCGIFNAME, {ifr_index=7, ifr_name="br0"}) = 0
> [pid 14188] ioctl(5, SIOCGIFADDR, {ifr_name="br0", ifr_addr={AF_INET,
> inet_addr("a.b.c.10")}}) = 0
> [pid 14188] select(11, [3 5 6 7 8 9 10], [], [], NULL) = 1 (in [6])
>
>
> Conclusion:
> The behaviour of dnsmasq-2.60test1 is the same as that of the unpached 2.57
> Upon reception of a DHCP DISCOVER packet on br0, the packet is seen by
> the dnsmasq code, but after dnsmasq inspects the interface, it finds a
> wrong ip (a.b.c.10) for the br0 interface and no further processing
> takes place.
>
> This line in the above strace snippet tells it all:
> [pid 14188] ioctl(5, SIOCGIFADDR, {ifr_name="br0", ifr_addr={AF_INET,
> inet_addr("a.b.c.10")}}) = 0
>
> I suppose that happens because the ip (a.b.c.11) is set in the
> configuration, not the primary (a.b.c.10) address.
>
> Btw, I found no reference of "getifaddrs" in the source code of
> 2.60test1. How do you get/check the interface's secondary addresses then ?
> Or did I get the wrong source tar.gz ?
>

You got the wrong source tarball, because I put the wrong one up. 
Sincere apologies for the waste of your time.

The correct code is now at:

http://www.thekelleys.org.uk/dnsmasq/test-releases/dnsmasq-2.60test2.tar.gz


There are still no calls to getifaddrs, but the code uses the internal 
function "iface_enumerate" which calls back for each address on the 
interface. That's been in use in dnsmasq since before getifaddrs was 
commonly available and it's portable to all the platforms we support 
(there are two completely different implementations for Linux and *BSD)



Cheers,

Simon.



More information about the Dnsmasq-discuss mailing list