From bf3d9f305ebad9d8abd68e4600d2db996b860e68 Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Thu, 21 Apr 2016 14:03:18 -0400 Subject: [PATCH] network: fix DHCPv6 on networks with prefix != 64 According to the dnsmasq manpage, the netmask for IPv4 address ranges will be auto-deteremined from the interface dnsmasq is listening on, but it can't do this for IPv6 for some reason - it instead assumes a network prefix of 64 for all IPv6 address ranges. If this is incorrect, dnsmasq will refuse to give out an address to clients, instead logging this message: dnsmasq-dhcp[2380]: no address range available for DHCPv6 request via virbr0 The solution is for libvirt to add ",$prefix" to all IPv6 dhcp-range arguments when building the dnsmasq.conf file. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1033739 --- src/network/bridge_driver.c | 21 +++++++++++++++++-- .../dhcp6-nat-network.conf | 2 +- tests/networkxml2confdata/dhcp6-network.conf | 2 +- .../dhcp6host-routed-network.conf | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 73236ffe1c..29c5febc76 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1180,6 +1180,15 @@ networkDnsmasqConfContents(virNetworkObjPtr network, ipdef = ipv4def ? ipv4def : ipv6def; while (ipdef) { + int prefix; + + prefix = virNetworkIpDefPrefix(ipdef); + if (prefix < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("bridge '%s' has an invalid prefix"), + network->def->bridge); + goto cleanup; + } for (r = 0; r < ipdef->nranges; r++) { int thisRange; @@ -1187,8 +1196,12 @@ networkDnsmasqConfContents(virNetworkObjPtr network, !(eaddr = virSocketAddrFormat(&ipdef->ranges[r].end))) goto cleanup; - virBufferAsprintf(&configbuf, "dhcp-range=%s,%s\n", + virBufferAsprintf(&configbuf, "dhcp-range=%s,%s", saddr, eaddr); + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) + virBufferAsprintf(&configbuf, ",%d", prefix); + virBufferAddLit(&configbuf, "\n"); + VIR_FREE(saddr); VIR_FREE(eaddr); thisRange = virSocketAddrGetRange(&ipdef->ranges[r].start, @@ -1210,7 +1223,11 @@ networkDnsmasqConfContents(virNetworkObjPtr network, char *bridgeaddr = virSocketAddrFormat(&ipdef->address); if (!bridgeaddr) goto cleanup; - virBufferAsprintf(&configbuf, "dhcp-range=%s,static\n", bridgeaddr); + virBufferAsprintf(&configbuf, "dhcp-range=%s,static", + bridgeaddr); + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) + virBufferAsprintf(&configbuf, ",%d", prefix); + virBufferAddLit(&configbuf, "\n"); VIR_FREE(bridgeaddr); } diff --git a/tests/networkxml2confdata/dhcp6-nat-network.conf b/tests/networkxml2confdata/dhcp6-nat-network.conf index 922eb7a32c..17076b89d9 100644 --- a/tests/networkxml2confdata/dhcp6-nat-network.conf +++ b/tests/networkxml2confdata/dhcp6-nat-network.conf @@ -10,7 +10,7 @@ bind-dynamic interface=virbr0 dhcp-range=192.168.122.2,192.168.122.254 dhcp-no-override -dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64 dhcp-lease-max=493 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2confdata/dhcp6-network.conf b/tests/networkxml2confdata/dhcp6-network.conf index 064515f816..82706903b3 100644 --- a/tests/networkxml2confdata/dhcp6-network.conf +++ b/tests/networkxml2confdata/dhcp6-network.conf @@ -10,7 +10,7 @@ expand-hosts except-interface=lo bind-dynamic interface=virbr0 -dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64 dhcp-lease-max=240 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2confdata/dhcp6host-routed-network.conf b/tests/networkxml2confdata/dhcp6host-routed-network.conf index ad6db36dfc..5728ee4308 100644 --- a/tests/networkxml2confdata/dhcp6host-routed-network.conf +++ b/tests/networkxml2confdata/dhcp6host-routed-network.conf @@ -10,7 +10,7 @@ bind-dynamic interface=virbr1 dhcp-range=192.168.122.1,static dhcp-no-override -dhcp-range=2001:db8:ac10:fd01::1,static +dhcp-range=2001:db8:ac10:fd01::1,static,64 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/local.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts enable-ra