On 2/18/19 6:21 PM, Laine Stump wrote:
dnsmasq documentation says that the *IPv4* prefix/network
address/broadcast address sent to dhcp clients will be automatically
determined by dnsmasq by looking at the interface it's listening on,
so the original libvirt code did not add a netmask to the dnsmasq
commandline (or later, the dnsmasq conf file).
For *IPv6* however, dnsmasq apparently cannot automatically determine
the prefix (functionally the same as a netmask), and it must be
explicitly provided in the conf file (as a part of the dhcp-range
option). So many years after IPv4 DHCP support had been added, when
IPv6 dhcp support was added the prefix was included at the end of the
dhcp-range setting, but only for IPv6.
Recently a user reported (privately, because they suspected a possible
security implication, which turned out to be unfounded) a bug on a
host where one of the interfaces was a superset of the libvirt network
where dhcp is needed (e.g., the host's ethernet is 10.0.0.20/8, and
the libvirt network is 10.10.0.1/24). For some reason dnsmasq was
supplying the netmask for the /8 network to clients requesting an
address on the /24 interface.
This seems like a bug in dnsmasq, but even if/when it gets fixed
there, it looks like there is no harm in just always adding the
netmask to all IPv4 dhcp-range options similar to how prefix is added
to all IPv6 dhcp-range options.
Signed-off-by: Laine Stump <laine(a)laine.org>
---
src/network/bridge_driver.c | 27 +++++++++++++++----
.../dhcp6-nat-network.conf | 2 +-
.../networkxml2confdata/isolated-network.conf | 2 +-
.../nat-network-dns-srv-record-minimal.conf | 2 +-
.../nat-network-dns-srv-record.conf | 2 +-
.../nat-network-dns-txt-record.conf | 2 +-
.../networkxml2confdata/nat-network-mtu.conf | 2 +-
.../nat-network-name-with-quotes.conf | 2 +-
tests/networkxml2confdata/nat-network.conf | 2 +-
.../networkxml2confdata/netboot-network.conf | 2 +-
.../netboot-proxy-network.conf | 2 +-
.../networkxml2confdata/ptr-domains-auto.conf | 2 +-
12 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 6d80818e40..9fa902896b 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1320,11 +1320,28 @@ networkDnsmasqConfContents(virNetworkObjPtr obj,
!(eaddr = virSocketAddrFormat(&ipdef->ranges[r].end)))
goto cleanup;
- 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");
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
+ virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%d\n",
+ saddr, eaddr, prefix);
+ } else {
+ /* IPv4 - dnsmasq requires a netmask rather than prefix */
+ virSocketAddr netmask;
Does it matter if this isn't initialized? e.g. "= { 0 };"
+ char *netmaskStr;
VIR_AUTOFREE(char *) netmaskStr = NULL;
+
+ if (virSocketAddrPrefixToNetmask(prefix, &netmask, AF_INET) < 0)
{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to translate bridge '%s'
"
+ "prefix %d to netmask"),
+ def->bridge, prefix);
+ goto cleanup;
+ }
+
+ if (!(netmaskStr = virSocketAddrFormat(&netmask)))
+ goto cleanup;
+ virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%s\n",
+ saddr, eaddr, netmaskStr);
+ VIR_FREE(netmaskStr);
w/ VIR_AUTOFREE, this isn't necessary
I know bridge_driver doesn't use it yet, but doesn't harm to start.
Reviewed-by: John Ferlan <jferlan(a)redhat.com>
John
[...]