[Dnsmasq-discuss] multiple dhcp6 servers

Gene Czarcinski gene at czarc.net
Sat Oct 13 18:20:09 BST 2012


On 10/12/2012 04:41 PM, Simon Kelley wrote:
> On 12/10/12 13:56, Gene Czarcinski wrote:
>> On 10/12/2012 06:44 AM, Simon Kelley wrote:
>>>> >OK, it is what is. Is there some practical way to "tell" dnsmasq an
>>>> >association for a hostname and an IPv6 address? I cannot see 
>>>> something
>>>> >like that used to update an authoritative name server but it would be
>>>> >useful to have some kind of an update capability with dnsmasq.
>>> If I've understood your question right, that's what dhcp-host does.
>> I guess I am not making myself clear.
>>
>> First of all, my problem is running qemu/kvm/libvirt virtual
>> networks/guests and will not likely occur in a real/hardware-only
>> situation. It is also possible that my problem is unique but then, it
>> may or may not be ... I might be just out front and getting some arrows
>> in my back.
>>
>> With the cost and availability of today's hardware, it is possible to
>> create large networks (multiple networks) of virtual guests ... my
>> virtualization host runs Fedora 17 on hardware consisting of an 8-core
>> AMD processor, 16GB memory, an SDD for root and home, and a couple of
>> large SATA-III disks for data storage [those virtual systems run faster
>> than real systems did a few years ago].
>>
>> So, I wanted to run some IPv6 virtual networks (currently, I have 16
>> virtual networks defined). Now, if dns was invented because those little
>> IPv4 numbers were hard to remember, then trying to remember IPv6
>> addresses is impossible. One of the things I want to do is access some
>> of those guests from the virtualization host and (sometimes) from other
>> hosts. Host names are much easier to remember and, using dnsmasq, it all
>> works for IPv4. Well, I wanted the same thing for IPv6.
>>
>> One of the things libvirt does is to start a dnsmasq process for every
>> virtual network -- you have 10 virtual networks started, you have 10
>> separate dnsmasqs started. If you add an IPv6 address to your virtual
>> network definition, then libvirt adds a --listen-address=<ip6-address>
>> to the dnsmasq command line and also starts radvd for that network (yes,
>> you now have lots of radvd processes running too).
>>
>> I wanted libvirt to support dhcp6 for virtual networks. Before investing
>> a lot of time into adding this support to libvirt, I thought I would run
>> a little test to see how things worked. I created a little patch to
>> modify the radvd parameters to use "AdvManagedFlag on" and a test-only
>> kludge to add --dhcp-range <ip6-address-range> to the dnsmasq command
>> line. Installed the modified libvirt and started the first virtual IPv6
>> network ... looks good. Started the second IPv6 network ... bang! The
>> dnsmasq did not start because it could not get exclusive use of server
>> port 547. [BTW, the first dnsmasq did not work because of the
>> listen-address=/interface= which I covered in another message]
>>
>> Now if the networks were pretty static then it is possible to have one,
>> "big" dnsmasq service all of the virtual networks. I do not know about
>> others but I am bringing networks up and down. defining new networks,
>> etc. in my test/research environment (like I said, maybe my situation is
>> unique). A single dnsmasq is not practical and would be a significant
>> change to libvirt.
>>
>> As things currently exist, I am using SLAAC IPv6 addresses and radvd for
>> the default route. This works in that, via IPv6, I can access the
>> virtualization host as well as other systems on my local network. But, I
>> cannot go the other way because I have no idea what the IPv6 address are
>> for individual virtual systems. Yes, I can use manual configuration for
>> IPv6 and add entries in the /etc/hosts file for each of those systems
>> but this does not scale.
>>
>> Note -- On second and third level virtual networks, I run my own virtual
>> services with radvd and dnsmasq and that works fine.
>>
>> So, as i see it, here are the alternatives:
>>
>> 1. Get multiple copies of dnsmasq to run on a single hardware system so
>> that I can use dhcp6.
>>
>> 2. Have some way to update the dnsmasq cache with the hostname and
>> related IPv6 address.
>>
>> Any suggestions/comments?
>
>
> All understood.
>
> It's worth trying the following, to see if makes DHCPv6 with multiple 
> instance work.
>
> In src/dhcp.c, the function make_fd() has the following code:
>
>   if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
>     {
> #ifdef SO_REUSEPORT
>       int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, 
> sizeof(oneopt));
> #else
>       int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, 
> sizeof(oneopt));
> #endif
>       if (rc == -1)
>         die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), 
> NULL, EC_BADNET);
>     }
>
>
> Add morally equivalent code to dhcp6_init() in src/dhcp6.c. That might 
> be enough.
>
> I'm hoping that since you already have a test system in place, you can 
> check this quickly, and see if does the trick.
>
The test system was almost in place.  A little quick editing and to 
sepearated conf files for two different networks on the same (virtual) 
system.  Attached is the patch but is the basic part is:
-----------------------------
+  /* When bind-interfaces is set, there might be more than one dnmsasq
+     instance binding port 547. That's OK if they serve different networks.
+     Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
+  if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
+    {
+      int oneopt = 1;
+#ifdef SO_REUSEPORT
+      int rc = setsockopt(fd, IPPROTO_IPV6, SO_REUSEPORT, &oneopt, 
sizeof(oneopt));
+#else
+      int rc = setsockopt(fd, IPPROTO_IPV6, SO_REUSEADDR, &oneopt, 
sizeof(oneopt));
+#endif
+      if (rc == -1)
+    die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), 
NULL, EC_BADNET);
+    }
+
---------------------------

When I looked at the ip4 code and understood that it work, this looked 
like it should work for ip6 too.

Unfortunately, it did not work.  I get:
> dnsmasq: failed to bind DHCPv6 server socket: Address already in use
Searching the code, the only place this is issued is right "below" the 
patch.

Did a little googling and came across an item that sounded like this 
problem and it said to specify IPV6_V6ONLY for the socket so I added:
-------------------------
+      rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,  &oneopt, 
sizeof(oneopt));
+      if (rc == -1)
+    die(_("failed to set IPV6_V6_ONLY on DHCPv6 socket: %s"), NULL, 
EC_BADNET);
----------------------------

Tried the test again ... same result.  Either there is something we do 
not understand or REUSEADDR is not being honored for ip6.

OK, before I read your message for a possible fix, I did a little 
thinking and "research" into mDNS.  I have read the discussion thread 
about multicast dns written back in 2007 and agree that dnsmasq should 
not "act like" it is mDNS we have ahahi for that. However, is there 
information provided (published) by avahi that could be used by dnsmasq 
to establish a host-name.ip6-address to be added to dnsmasq's cache?

It turns out that I believe there is.  I started wireshark running on 
the virtulaization host and capturing the packets on a virtual network 
device.  I then went to a vituals guest system and started the 
avahi-daemon service.  Going back to wireshark I found six IPv6 MDNS 
packets.  There were three identical queries and three identical query 
responses ( I have no idea why three).  Each of those packets included 
the <hostname>.local and the IPv6 address. An enhancement (optional) to 
dnsmasq could use this.

This is interesting enough that I would like to see it done in addition 
being able to run multiple copies of dnsmasq for DHCP6 support.

Well, I am going to see if I can find out anything more about IPv6 and 
SO_REUSEADDR because it sure looked to me like it should have worked.

Gene


-------------- next part --------------
A non-text attachment was scrubbed...
Name: dnsmasq-gc-ip6-reuseaddr-2.patch
Type: text/x-patch
Size: 1286 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20121013/1cb18370/attachment.bin>


More information about the Dnsmasq-discuss mailing list