From: Alberto Ruiz <aruiz@xxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list