[Dnsmasq-discuss] DHCPv6: Problems w/ multiple interfaces that have identical MACs

Simon Kelley simon at thekelleys.org.uk
Mon Jan 12 20:46:36 GMT 2015


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

You're well on the trail.

In src/network.c in iface_allowed() there's some code

 /* check whether the interface IP has been added already
     we call this routine multiple times. */
  for (iface = daemon->interfaces; iface; iface = iface->next)
    if (sockaddr_isequal(&iface->addr, addr))
      < return success without actually doing anything >

sockaddr_isequal DOESN'T compare the scope_ids.

It's debatable if sockaddr_isequal should be changed - I'd have to
look where else it's called - or if there should be a scope_id check
just in the loop; that would be a good start to see if it fixes things.

That should fix the binding, and probably the multicast issues too.


Cheers,

Simon.


On 12/01/15 16:47, Cory Benfield wrote:
> All,
> 
> I'm trying to use dnsmasq to provide DHCPv6 service on a number of 
> tap interfaces. For some slightly boring technical reasons, each
> of these tap interfaces needs to have the same MAC address (for
> the purposes of the remainder of this email, that MAC is 
> de:ad:be:ef:00:01). Using this topology I believe I've revealed a
> bug in the way dnsmasq handles multiple interfaces with the same
> IPv6 link-local address.
> 
> I observe three different behaviours depending on what I do. First
> I bring up a number of tap interfaces ahead of time. I then start 
> dnsmasq. dnsmasq correctly locates all the interfaces, binds 
> listening sockets for them, and joins the multicast group for
> DHCPv6 (as verified by running netstat -g and showing such a bind
> on the relevant interface).
> 
> The second behaviour is observed when I add a new tap interface. 
> Nothing exciting happens here, but dnsmasq does not join the 
> multicast group for that interface (as verified by running netstat 
> -g), so DHCPv6 does not function for that interface.  Running
> strace reveals that dnsmasq never binds a listening socket for the 
> interface, despite finding it in an enumeration of the interfaces. 
> You can see this with the configuration below (where interface 22 
> existed before dnsmasq started, and interface 28 was created
> after):
> 
> 
> ubuntu at hostname:~$ ip link show 22: tap9c17245e-ef: 
> <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP mode DEFAULT group default qlen 500 link/ether de:ad:be:ef:00:01
> brd ff:ff:ff:ff:ff:ff 28: tap6dea49ab-27: 
> <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP mode DEFAULT group default qlen 500 link/ether de:ad:be:ef:00:01
> brd ff:ff:ff:ff:ff:ff
> 
> 
> strace reveals that dnsmasq does know the interface exists,
> because it makes the three ioctl calls I'd expect at the top of
> the iface_allowed function:
> 
> 
> ioctl(18, SIOCGIFNAME, {ifr_index=22, ifr_name="tap9c17245e-ef"})
> = 0 ioctl(18, SIOCGIFFLAGS, {ifr_name="tap9c17245e-ef", 
> ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0 
> ioctl(18, SIOCGIFMTU, {ifr_name="tap9c17245e-ef", ifr_mtu=1500}) =
> 0 ioctl(18, SIOCGIFNAME, {ifr_index=28, ifr_name="tap6dea49ab-27"})
> = 0 ioctl(18, SIOCGIFFLAGS, {ifr_name="tap6dea49ab-27", 
> ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0 
> ioctl(18, SIOCGIFMTU, {ifr_name="tap6dea49ab-27", ifr_mtu=1500}) =
> 0
> 
> 
> Note that dnsmasq has also correctly got the two interface IDs. 
> Checking netstat reveals no DHCPv6 join multicast join for
> interface 28 (tap6dea49ab-27), which should have joined group
> ff02::1:2:
> 
> 
> ubuntu at hostname:~$ netstat -g IPv6/IPv4 Group Memberships
> Interface RefCnt Group --------------- ------ ---------------------
>  tap9c17245e-ef  1      ff05::1:3 tap9c17245e-ef  1      ff02::1:2
>  tap9c17245e-ef  1      ff02::fb tap9c17245e-ef  1 ff02::1:ff00:0
> tap9c17245e-ef  1      ff02::1:ffef:1 tap9c17245e-ef 2
> ip6-allrouters tap9c17245e-ef  1      ip6-allnodes tap9c17245e-ef
> 1      ff01::1 tap6dea49ab-27  1      ff02::fb tap6dea49ab-27  1
> ff02::1:ff00:0 tap6dea49ab-27  1 ff02::1:ffef:1 tap6dea49ab-27  1
> ip6-allrouters tap6dea49ab-27 1      ip6-allnodes tap6dea49ab-27  1
> ff01::1
> 
> 
> This gets worse if I remove all the extant tap interfaces and
> create a new one. In this case, dnsmasq prints the following to
> syslog:
> 
> 
> Jan 12 16:26:09 hostname dnsmasq[31994]: failed to create
> listening socket for fe80::dcad:beff:feef:1: No such device
> 
> 
> Again, strace reveals that dnsmasq has spotted the new interface,
> but this time also reveals that it fails in its attempt to bind
> the interface:
> 
> 
> ioctl(9, SIOCGIFNAME, {ifr_index=29, ifr_name="tap375ee24b-5a"}) =
> 0 ioctl(9, SIOCGIFFLAGS, {ifr_name="tap375ee24b-5a", 
> ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0 
> ioctl(9, SIOCGIFMTU, {ifr_name="tap375ee24b-5a", ifr_mtu=1500}) = 0
>  ... bind(9, {sa_family=AF_INET6, sin6_port=htons(53), 
> inet_pton(AF_INET6, "fe80::dcad:beff:feef:1", &sin6_addr), 
> sin6_flowinfo=0, sin6_scope_id=22}, 28) = -1 ENODEV (No such
> device)
> 
> 
> Note the sin6_scope_id of this call, which is set to 22. 22 was
> the only interface on which dnsmasq correctly joined the multicast
> group in this run: all subsequent interface creations failed to
> bind. This strongly suggests to me that dnsmasq is incorrectly
> caching information about interfaces and re-using address
> structures when their information does not match. This is almost
> certainly caused by assuming that IPv6 link-local addresses are
> unique, which they needn't be.
> 
> Unfortunately, I've begin to run low on ideas for where in the
> code this is going wrong. The closest I've gotten so far is to
> look suspiciously at the iface_check function, which looks like it
> could possibly be getting this wrong. If someone can point me in
> the correct direction that would be extremely helpful for
> formulating a patch for this problem.
> 
> Thanks in advance!
> 
> Cory
> 
> _______________________________________________ Dnsmasq-discuss 
> mailing list Dnsmasq-discuss at lists.thekelleys.org.uk 
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJUtDKsAAoJEBXN2mrhkTWigx8P/ieml51LJrmKFUjn+tMSrain
oEovH4Nvjq+hdxCtaFabc+FZmp1BRyYMndayK/rSL5fuHKBA5s4rxAvcvBwUXUZo
lKbtusqhnUEqOR6IkG8CD6KP0njRngddd2LPJUj5M7KlMNYSKvyraFhj4o5netJ3
R+ylgSgDbgyqpFQOVrPr0SuLF6Hrne+8hGSzd/XtexuRZK6IZ/1yqUnZMTMcDXnI
4wwQ7uf00f7817vEvUpfieKHO3x1184Fj2Boxd1eoLRAleA0bMzJU12hsC3vv7Or
Zu5CGS3VZCwtvWXWBg8pw5qI7XgCnC1t6E2VuDMo/yngPq/dzjEHzA5LVpYf8HJh
aIpLuBOVyY1oUzu9zohRz2F3rn5QQiTWrx0CgQ2zgpSTbZx7h4geMxW6YR/mL9Tv
H+jDbLkMyove6wi1LEyosbCksoTmJJdXP/BaybMCekzz71N87Orjiu9JRM4/ZWqK
GZpj8EN1M0glCQquEsSi6FHZJT+yNoklUzAKGN0185ep5cMhpuewoYaoXD3IS9eV
ltBVNqLAarjnAglBuAjt4MrAaoIwGzOJuF9jA/6scODNtYWzLn5FZZBfENKVMO7a
xJFWOC7NxKiNamRy3SwrMasRf8iUM9P4OaJOzC630t51FYdTtEutkvqkDthuu0Ar
Gzun3k5e6ZjFpB9aZwee
=7A/+
-----END PGP SIGNATURE-----



More information about the Dnsmasq-discuss mailing list