From: Alberto Ruiz <aruiz(a)gnome.org>
---
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 12 ++++-
src/network/bridge_driver.h | 1 +
src/util/virdnsmasq.c | 54 +++++++++++++++++-----
src/util/virdnsmasq.h | 1 +
.../dhcp6-nat-network.hostsfile | 7 +++
tests/networkxml2confdata/dhcp6-network.hostsfile | 5 ++
.../dhcp6host-routed-network.hostsfile | 7 +++
.../nat-network-dns-srv-record-minimal.hostsfile | 2 +
.../nat-network-dns-srv-record.hostsfile | 2 +
.../nat-network-dns-txt-record.hostsfile | 2 +
.../nat-network-name-with-quotes.hostsfile | 2 +
tests/networkxml2confdata/nat-network.hostsfile | 2 +
tests/networkxml2conftest.c | 39 ++++++++++++----
14 files changed, 116 insertions(+), 21 deletions(-)
create mode 100644 tests/networkxml2confdata/dhcp6-nat-network.hostsfile
create mode 100644 tests/networkxml2confdata/dhcp6-network.hostsfile
create mode 100644 tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
create mode 100644
tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
create mode 100644 tests/networkxml2confdata/nat-network.hostsfile
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 923afd187..c93385958 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1497,6 +1497,7 @@ dnsmasqCapsRefresh;
dnsmasqContextFree;
dnsmasqContextNew;
dnsmasqDelete;
+dnsmasqDhcpHostsToString;
dnsmasqReload;
dnsmasqSave;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 1cffd4dcf..1d2ada208 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -952,6 +952,7 @@ int
networkDnsmasqConfContents(virNetworkObjPtr network,
const char *pidfile,
char **configstr,
+ char **hostsfilestr,
dnsmasqContext *dctx,
dnsmasqCapsPtr caps ATTRIBUTE_UNUSED)
{
@@ -1311,6 +1312,15 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
if (networkBuildDnsmasqDhcpHostsList(dctx, ipdef) < 0)
goto cleanup;
+ /* Return the contents of the hostsfile if requested */
+ if (hostsfilestr) {
+ *hostsfilestr = dnsmasqDhcpHostsToString (dctx->hostsfile->hosts,
+ dctx->hostsfile->nhosts);
+
+ if (!hostsfilestr)
+ goto cleanup;
+ }
+
/* Note: the following is IPv4 only */
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
if (ipdef->nranges || ipdef->nhosts)
@@ -1410,7 +1420,7 @@ networkBuildDhcpDaemonCommandLine(virNetworkDriverStatePtr driver,
network->dnsmasqPid = -1;
- if (networkDnsmasqConfContents(network, pidfile, &configstr,
+ if (networkDnsmasqConfContents(network, pidfile, &configstr, NULL,
dctx, dnsmasq_caps) < 0)
goto cleanup;
if (!configstr)
diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h
index ff7f921ed..c653c507f 100644
--- a/src/network/bridge_driver.h
+++ b/src/network/bridge_driver.h
@@ -53,6 +53,7 @@ int networkGetActualType(virDomainNetDefPtr iface)
int networkDnsmasqConfContents(virNetworkObjPtr network,
const char *pidfile,
char **configstr,
+ char **hostsfilestr,
dnsmasqContext *dctx,
dnsmasqCapsPtr caps);
diff --git a/src/util/virdnsmasq.c b/src/util/virdnsmasq.c
index 92f834fe7..94c9a3bb1 100644
--- a/src/util/virdnsmasq.c
+++ b/src/util/virdnsmasq.c
@@ -386,10 +386,9 @@ hostsfileWrite(const char *path,
dnsmasqDhcpHost *hosts,
unsigned int nhosts)
{
- char *tmp;
+ char *tmp, *content = NULL;
FILE *f;
bool istmp = true;
- size_t i;
int rc = 0;
/* even if there are 0 hosts, create a 0 length file, to allow
@@ -407,17 +406,21 @@ hostsfileWrite(const char *path,
}
}
- for (i = 0; i < nhosts; i++) {
- if (fputs(hosts[i].host, f) == EOF || fputc('\n', f) == EOF) {
- rc = -errno;
- VIR_FORCE_FCLOSE(f);
+ if (!(content = dnsmasqDhcpHostsToString(hosts, nhosts))) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
- if (istmp)
- unlink(tmp);
+ if (fputs(content, f) == EOF) {
+ rc = -errno;
+ VIR_FORCE_FCLOSE(f);
+
+ if (istmp)
+ unlink(tmp);
+
+ goto cleanup;
+ }
- goto cleanup;
- }
- }
if (VIR_FCLOSE(f) == EOF) {
rc = -errno;
@@ -431,6 +434,7 @@ hostsfileWrite(const char *path,
}
cleanup:
+ VIR_FREE(content);
VIR_FREE(tmp);
return rc;
@@ -888,3 +892,31 @@ dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag)
return caps && virBitmapIsBitSet(caps->flags, flag);
}
+
+/** dnsmasqDhcpHostsToString:
+ *
+ * Turns a vector of dnsmasqDhcpHost into the string that is ought to be
+ * stored in the hostsfile, this functionality is split to make hostsfiles
+ * testable. Returs NULL if nhosts is 0.
+ */
+char *
+dnsmasqDhcpHostsToString (dnsmasqDhcpHost *hosts,
+ unsigned int nhosts)
+{
+ int i;
+ char *result = NULL;
+ virBuffer hostsfilebuf = VIR_BUFFER_INITIALIZER;
+
+ if (nhosts == 0)
+ goto cleanup;
+
+ for (i = 0; i < nhosts; i++) {
+ virBufferAsprintf(&hostsfilebuf, "%s\n", hosts[i].host);
+ }
+
+ result = virBufferContentAndReset(&hostsfilebuf);
+
+cleanup:
+ virBufferFreeAndReset(&hostsfilebuf);
+ return result;
+}
diff --git a/src/util/virdnsmasq.h b/src/util/virdnsmasq.h
index c3ea271d4..1795bc83b 100644
--- a/src/util/virdnsmasq.h
+++ b/src/util/virdnsmasq.h
@@ -106,6 +106,7 @@ int dnsmasqCapsRefresh(dnsmasqCapsPtr *caps, const char *binaryPath);
bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag);
const char *dnsmasqCapsGetBinaryPath(dnsmasqCapsPtr caps);
unsigned long dnsmasqCapsGetVersion(dnsmasqCapsPtr caps);
+char *dnsmasqDhcpHostsToString(dnsmasqDhcpHost *hosts, unsigned int nhosts);
# define DNSMASQ_DHCPv6_MAJOR_REQD 2
# define DNSMASQ_DHCPv6_MINOR_REQD 64
diff --git a/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
b/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
new file mode 100644
index 000000000..de659b98c
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
@@ -0,0 +1,7 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/dhcp6-network.hostsfile
b/tests/networkxml2confdata/dhcp6-network.hostsfile
new file mode 100644
index 000000000..9dfb172ce
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6-network.hostsfile
@@ -0,0 +1,5 @@
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
b/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
new file mode 100644
index 000000000..de659b98c
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
@@ -0,0 +1,7 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
b/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
new file mode 100644
index 000000000..deb3f00ac
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
b/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
new file mode 100644
index 000000000..deb3f00ac
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
b/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
new file mode 100644
index 000000000..deb3f00ac
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
b/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
new file mode 100644
index 000000000..deb3f00ac
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network.hostsfile
b/tests/networkxml2confdata/nat-network.hostsfile
new file mode 100644
index 000000000..deb3f00ac
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 223a56f54..6b8324aa2 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -19,9 +19,13 @@
#define VIR_FROM_THIS VIR_FROM_NONE
static int
-testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr caps)
+testCompareXMLToConfFiles(const char *inxml,
+ const char *outconf,
+ const char *outhostsfile,
+ dnsmasqCapsPtr caps)
{
- char *actual = NULL;
+ char *actualconf = NULL;
+ char *actualhosts = NULL;
int ret = -1;
virNetworkDefPtr dev = NULL;
virNetworkObjPtr obj = NULL;
@@ -41,17 +45,30 @@ testCompareXMLToConfFiles(const char *inxml, const char *outconf,
dnsmasqCapsPtr
if (dctx == NULL)
goto fail;
- if (networkDnsmasqConfContents(obj, pidfile, &actual,
+ if (networkDnsmasqConfContents(obj, pidfile, &actualconf, &actualhosts,
dctx, caps) < 0)
goto fail;
- if (virTestCompareToFile(actual, outconf) < 0)
+ if (virTestCompareToFile(actualconf, outconf) < 0)
goto fail;
+ if (virFileExists(outhostsfile)) {
+ if (!actualhosts) {
+ fprintf(stderr, "%s: hostsfile exists but the configuration did not
specify any host", outhostsfile);
+ goto fail;
+ } else if (virTestCompareToFile(actualhosts, outhostsfile) < 0) {
+ goto fail;
+ }
+ } else if (actualhosts) {
+ fprintf(stderr, "%s: file does not exist but actual data was expected",
outhostsfile);
+ goto fail;
+ }
+
ret = 0;
fail:
- VIR_FREE(actual);
+ VIR_FREE(actualconf);
+ VIR_FREE(actualhosts);
VIR_FREE(pidfile);
virCommandFree(cmd);
virObjectUnref(obj);
@@ -70,20 +87,24 @@ testCompareXMLToConfHelper(const void *data)
int result = -1;
const testInfo *info = data;
char *inxml = NULL;
- char *outxml = NULL;
+ char *outconf = NULL;
+ char *outhostsfile = NULL;
if (virAsprintf(&inxml, "%s/networkxml2confdata/%s.xml",
abs_srcdir, info->name) < 0 ||
- virAsprintf(&outxml, "%s/networkxml2confdata/%s.conf",
+ virAsprintf(&outconf, "%s/networkxml2confdata/%s.conf",
+ abs_srcdir, info->name) < 0 ||
+ virAsprintf(&outhostsfile, "%s/networkxml2confdata/%s.hostsfile",
abs_srcdir, info->name) < 0) {
goto cleanup;
}
- result = testCompareXMLToConfFiles(inxml, outxml, info->caps);
+ result = testCompareXMLToConfFiles(inxml, outconf, outhostsfile, info->caps);
cleanup:
VIR_FREE(inxml);
- VIR_FREE(outxml);
+ VIR_FREE(outconf);
+ VIR_FREE(outhostsfile);
return result;
}
--
2.13.0