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

dnsmasq.20.masuefke at spamgourmet.com dnsmasq.20.masuefke at spamgourmet.com
Thu Dec 1 13:45:54 GMT 2011


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 ?

Yours,
  Martin





More information about the Dnsmasq-discuss mailing list