I'm attaching the patch because I've been unable to use send-email properly.
2) is a good point, I wanted to discuss it here. Yes 120 is the minimum allowed by dnsmasq, erroring out seems fine to me, I'll change the patch accordingly.
2) is a good point, I wanted to discuss it here. Yes 120 is the minimum allowed by dnsmasq, erroring out seems fine to me, I'll change the patch accordingly.
On Thu, Oct 13, 2016 at 7:07 AM, Michal Privoznik <mprivozn@xxxxxxxxxx> wrote:
On 13.10.2016 00:03, Alberto Ruiz wrote:
> Support for custom dhcp wide and per host leasetime.
>
> It is specified as a child tag for <dhcp>:
> <dhcp>
> <leasetime>24h</leasetime>
> ...
> </dhcp>
>
> And as an attribute for <host>:
> <dhcp>
> <host leasetime="7d" .../>
> </dhcp>
>
> These are the different notations:
>
> -1 (infinite/unlimited lease)
> 120 (seconds are the default unit, 120 seconds is the minimum, if less is
> specified it will use 120)
> 300s (seconds)
> 5m (minutes)
> 24h (hours)
> 7d (days)
> ---
I know I'm stepping on a moving train (sorry for that), but I have two
points to raise:
1) use git send-email, this patch is mangled by your MTA and does not apply.
2) 120 seconds is minimum because of dnsmasq? If so, I think we should
error out instead of silently changing this to a different value behind
user's back.
Michal
Alberto Ruiz
Associate Engineering Manager - Desktop Management ToolsFrom d48f957ab78310d864b356b4a25b9a29722ca736 Mon Sep 17 00:00:00 2001 From: Alberto Ruiz <aruiz@xxxxxxxxx> Date: Thu, 6 Oct 2016 21:29:40 +0100 Subject: [PATCH] leasetime support per <dhcp> and <host> Support for custom dhcp wide and per host leasetime. It is specified as a child tag for <dhcp>: <dhcp> <leasetime>24h</leasetime> ... </dhcp> And as an attribute for <host>: <dhcp> <host leasetime="7d" .../> </dhcp> These are the different notations: -1 (infinite/unlimited lease) 120 (seconds are the default unit, 120 seconds is the minimum, if less is specified it will use 120) 300s (seconds) 5m (minutes) 24h (hours) 7d (days) --- docs/schemas/basictypes.rng | 5 + docs/schemas/network.rng | 8 ++ src/conf/network_conf.c | 86 +++++++++++++- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 1 + src/network/bridge_driver.c | 132 +++++++++++++++++---- src/network/bridge_driver.h | 1 + src/util/virdnsmasq.c | 106 +++++++++++------ src/util/virdnsmasq.h | 2 + .../dhcp6-nat-network.hostsfile | 7 ++ tests/networkxml2confdata/dhcp6-network.hostsfile | 5 + .../dhcp6host-routed-network.hostsfile | 7 ++ tests/networkxml2confdata/leasetime-days.conf | 17 +++ tests/networkxml2confdata/leasetime-days.xml | 18 +++ tests/networkxml2confdata/leasetime-host.conf | 16 +++ tests/networkxml2confdata/leasetime-host.hostsfile | 6 + tests/networkxml2confdata/leasetime-host.xml | 22 ++++ tests/networkxml2confdata/leasetime-hours.conf | 17 +++ tests/networkxml2confdata/leasetime-hours.xml | 18 +++ tests/networkxml2confdata/leasetime-infinite.conf | 17 +++ tests/networkxml2confdata/leasetime-infinite.xml | 18 +++ tests/networkxml2confdata/leasetime-minutes.conf | 17 +++ tests/networkxml2confdata/leasetime-minutes.xml | 18 +++ tests/networkxml2confdata/leasetime-seconds.conf | 17 +++ tests/networkxml2confdata/leasetime-seconds.xml | 18 +++ tests/networkxml2confdata/leasetime.conf | 17 +++ tests/networkxml2confdata/leasetime.xml | 18 +++ .../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 | 47 ++++++-- 33 files changed, 597 insertions(+), 78 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/leasetime-days.conf create mode 100644 tests/networkxml2confdata/leasetime-days.xml create mode 100644 tests/networkxml2confdata/leasetime-host.conf create mode 100644 tests/networkxml2confdata/leasetime-host.hostsfile create mode 100644 tests/networkxml2confdata/leasetime-host.xml create mode 100644 tests/networkxml2confdata/leasetime-hours.conf create mode 100644 tests/networkxml2confdata/leasetime-hours.xml create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml create mode 100644 tests/networkxml2confdata/leasetime.conf create mode 100644 tests/networkxml2confdata/leasetime.xml 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/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng index 1b4f980..11fbe2b 100644 --- a/docs/schemas/basictypes.rng +++ b/docs/schemas/basictypes.rng @@ -518,4 +518,9 @@ </element> </define> + <define name="leaseTime"> + <data type="string"> + <param name="pattern">-?[0-9]*[smhd]?</param> + </data> + </define> </grammar> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 1a18e64..e6ddb63 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -340,6 +340,11 @@ <!-- Define the range(s) of IP addresses that the DHCP server should hand out --> <element name="dhcp"> + <optional> + <element name="leasetime"> + <ref name="leaseTime"/> + </element> + </optional> <zeroOrMore> <element name="range"> <attribute name="start"><ref name="ipAddr"/></attribute> @@ -361,6 +366,9 @@ <attribute name="name"><text/></attribute> </choice> <attribute name="ip"><ref name="ipAddr"/></attribute> + <optional> + <attribute name="leasetime"><ref name="leaseTime"/></attribute> + </optional> </element> </zeroOrMore> <optional> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index aa39776..bcc4bbb 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -30,6 +30,8 @@ #include <fcntl.h> #include <string.h> #include <dirent.h> +#include <stdlib.h> +#include <inttypes.h> #include "virerror.h" #include "datatypes.h" @@ -911,16 +913,83 @@ virSocketAddrRangeParseXML(const char *networkName, return ret; } +static int64_t +virNetworkDHCPDefGetLeaseTime (xmlNodePtr node, + xmlXPathContextPtr ctxt, + const char* query, + bool *error) +{ + int64_t multiplier = 1, result = -1; + char *leaseString; + xmlNodePtr save; + size_t len; + + *error = 0; + + save = ctxt->node; + ctxt->node = node; + + leaseString = virXPathString (query, ctxt); + + /* If value is not present we set the value to -2 */ + if (leaseString == NULL) { + result = -2; + goto cleanup; + } + + len = strlen (leaseString) - 1; + + if (leaseString[len] == 'm') + multiplier = 60; + else if (leaseString[len] == 'h') + multiplier = 60 * 60; + else if (leaseString[len] == 'd') + multiplier = 60 * 60 * 24; + + /* Remove the time unit suffix */ + if (leaseString[len] < 48 || leaseString[len] > 57) + leaseString[len] = '\0'; + + errno = 0; + result = (int64_t) strtoll((const char*)leaseString, NULL, 10); + + /* Report any errors parsing the string */ + if (errno != 0) { + virReportError(VIR_ERR_XML_ERROR, + _("<leasetime> value could not be converted to a signed integer: %s"), + leaseString); + *error = 1; + goto cleanup; + } + + result = result * multiplier; + + if (result > UINT32_MAX || result < -1) { + virReportError(VIR_ERR_XML_ERROR, + _("<leasetime> value cannot be greater than the equivalent of %" PRIo32 " seconds or less than -1: %" PRId64), + UINT32_MAX, result); + *error = 1; + } + +cleanup: + VIR_FREE(leaseString); + ctxt->node = save; + return result; +} + static int virNetworkDHCPHostDefParseXML(const char *networkName, virNetworkIPDefPtr def, xmlNodePtr node, + xmlXPathContextPtr ctxt, virNetworkDHCPHostDefPtr host, bool partialOkay) { char *mac = NULL, *name = NULL, *ip = NULL, *id = NULL; virMacAddr addr; virSocketAddr inaddr; + int64_t leasetime; + bool error; int ret = -1; mac = virXMLPropString(node, "mac"); @@ -1013,6 +1082,10 @@ virNetworkDHCPHostDefParseXML(const char *networkName, } } + leasetime = virNetworkDHCPDefGetLeaseTime (node, ctxt, "string(./@leasetime)", &error); + if (error) + goto cleanup; + host->mac = mac; mac = NULL; host->id = id; @@ -1021,6 +1094,7 @@ virNetworkDHCPHostDefParseXML(const char *networkName, name = NULL; if (ip) host->ip = inaddr; + host->leasetime = leasetime; ret = 0; cleanup: @@ -1034,9 +1108,11 @@ virNetworkDHCPHostDefParseXML(const char *networkName, static int virNetworkDHCPDefParseXML(const char *networkName, xmlNodePtr node, + xmlXPathContextPtr ctxt, virNetworkIPDefPtr def) { int ret = -1; + bool error; xmlNodePtr cur; virSocketAddrRange range; virNetworkDHCPHostDef host; @@ -1044,6 +1120,10 @@ virNetworkDHCPDefParseXML(const char *networkName, memset(&range, 0, sizeof(range)); memset(&host, 0, sizeof(host)); + def->leasetime = virNetworkDHCPDefGetLeaseTime (node, ctxt, "string(./leasetime/text())", &error); + if (error) + goto cleanup; + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE && @@ -1057,7 +1137,7 @@ virNetworkDHCPDefParseXML(const char *networkName, } else if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "host")) { - if (virNetworkDHCPHostDefParseXML(networkName, def, cur, + if (virNetworkDHCPHostDefParseXML(networkName, def, cur, ctxt, &host, false) < 0) goto cleanup; if (VIR_APPEND_ELEMENT(def->hosts, def->nhosts, host) < 0) @@ -1607,7 +1687,7 @@ virNetworkIPDefParseXML(const char *networkName, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "dhcp")) { - if (virNetworkDHCPDefParseXML(networkName, cur, def) < 0) + if (virNetworkDHCPDefParseXML(networkName, cur, ctxt, def) < 0) goto cleanup; } else if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "tftp")) { @@ -3659,7 +3739,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def, if (!ipdef) goto cleanup; - if (virNetworkDHCPHostDefParseXML(def->name, ipdef, ctxt->node, + if (virNetworkDHCPHostDefParseXML(def->name, ipdef, ctxt->node, ctxt, &host, partialOkay) < 0) goto cleanup; diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 3b227db..df687df 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -96,6 +96,7 @@ struct _virNetworkDHCPHostDef { char *id; char *name; virSocketAddr ip; + int64_t leasetime; }; typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef; @@ -170,7 +171,8 @@ struct _virNetworkIPDef { char *tftproot; char *bootfile; virSocketAddr bootserver; - }; + int64_t leasetime; +}; typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef; typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b88e903..84fb62e 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 7b99aca..dccf743 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -41,6 +41,8 @@ #include <sys/ioctl.h> #include <net/if.h> #include <dirent.h> +#include <inttypes.h> +#include <stdint.h> #if HAVE_SYS_SYSCTL_H # include <sys/sysctl.h> #endif @@ -859,30 +861,6 @@ networkKillDaemon(pid_t pid, const char *daemonName, const char *networkName) return ret; } -/* the following does not build a file, it builds a list - * which is later saved into a file - */ - -static int -networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx, - virNetworkIPDefPtr ipdef) -{ - size_t i; - bool ipv6 = false; - - if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) - ipv6 = true; - for (i = 0; i < ipdef->nhosts; i++) { - virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]); - if (VIR_SOCKET_ADDR_VALID(&host->ip)) - if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, - host->name, host->id, ipv6) < 0) - return -1; - } - - return 0; -} - static int networkBuildDnsmasqHostsList(dnsmasqContext *dctx, virNetworkDNSDefPtr dnsdef) @@ -903,11 +881,93 @@ networkBuildDnsmasqHostsList(dnsmasqContext *dctx, return 0; } +/* translates the leasetime value into a dnsmasq configuration string for dhcp-range/host */ +static char * +networkDnsmasqConfLeaseValueToString (int64_t leasetime) +{ + char *result = NULL; + virBuffer leasebuf = VIR_BUFFER_INITIALIZER; + + /* Leasetime parameter set on the XML */ + /* Less than -1 means there was no value set */ + if (leasetime < -1) { + virBufferAsprintf(&leasebuf, "%s", ""); + } + /* -1 means no expiration */ + else if (leasetime == -1) + virBufferAsprintf(&leasebuf, ",infinite"); + /* Minimum expiry value is 120 */ + /* TODO: Discuss if we should up as we do here or just forward whatever value to dnsmasq */ + else if (leasetime < 120) + virBufferAsprintf(&leasebuf, ",120"); + /* DHCP value for lease time is a unsigned four octect integer */ + else if (leasetime <= UINT32_MAX) + virBufferAsprintf(&leasebuf, ",%" PRId64, leasetime); + /* TODO: Discuss the use of "deprecated" for ipv6*/ + /* TODO: Discuss what is the default value that we want as dnsmasq's is 1 hour */ + /* TODO: Discuss what to do if value exceeds maximum, use default value for now */ + else { + virBufferAsprintf(&leasebuf, "%s", ""); + } + + result = virBufferContentAndReset(&leasebuf); + virBufferFreeAndReset (&leasebuf); + + return result; +} + +/* the following does not build a file, it builds a list + * which is later saved into a file + */ + +static int +networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx, + virNetworkIPDefPtr ipdef) +{ + int ret = -1; + size_t i; + bool ipv6 = false; + char *leasetime = networkDnsmasqConfLeaseValueToString(ipdef->leasetime); + + if (!leasetime) + goto cleanup; + + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) + ipv6 = true; + for (i = 0; i < ipdef->nhosts; i++) { + virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]); + if (VIR_SOCKET_ADDR_VALID(&host->ip)) { + /* If the host has its own leasetime we get its specific string */ + if (host->leasetime > -2) { + char *hostlease = networkDnsmasqConfLeaseValueToString(host->leasetime); + if (!hostlease) + goto cleanup; + if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, + host->name, host->id, hostlease, ipv6) < 0) { + VIR_FREE(hostlease); + goto cleanup; + } + VIR_FREE(hostlease); + } else { + /* Otherwise we use the leasetime from dhcp */ + if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, + host->name, host->id, leasetime, ipv6) < 0) + goto cleanup; + } + } + } + + ret = 0; +cleanup: + VIR_FREE(leasetime); + return ret; +} int networkDnsmasqConfContents(virNetworkObjPtr network, const char *pidfile, char **configstr, + char **hostsfilestr, dnsmasqContext *dctx, dnsmasqCapsPtr caps ATTRIBUTE_UNUSED) { @@ -1213,6 +1273,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, } for (r = 0; r < ipdef->nranges; r++) { int thisRange; + char *leasestr; if (!(saddr = virSocketAddrFormat(&ipdef->ranges[r].start)) || !(eaddr = virSocketAddrFormat(&ipdef->ranges[r].end))) @@ -1220,12 +1281,22 @@ networkDnsmasqConfContents(virNetworkObjPtr network, virBufferAsprintf(&configbuf, "dhcp-range=%s,%s", saddr, eaddr); - if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) + + /* Add ipv6 prefix length parameter if needed */ + if (ipdef == ipv6def) virBufferAsprintf(&configbuf, ",%d", prefix); + + leasestr = networkDnsmasqConfLeaseValueToString (ipdef->leasetime); + if (!leasestr) + goto cleanup; + virBufferAsprintf(&configbuf, "%s", leasestr); + + /* Add the newline */ virBufferAddLit(&configbuf, "\n"); VIR_FREE(saddr); VIR_FREE(eaddr); + VIR_FREE(leasestr); thisRange = virSocketAddrGetRange(&ipdef->ranges[r].start, &ipdef->ranges[r].end, &ipdef->address, @@ -1256,6 +1327,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) @@ -1355,7 +1435,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 ff7f921..c653c50 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 1b78c1f..94c9a3b 100644 --- a/src/util/virdnsmasq.c +++ b/src/util/virdnsmasq.c @@ -308,52 +308,47 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile, virSocketAddr *ip, const char *name, const char *id, + const char *leasetime, bool ipv6) { + int ret = -1; char *ipstr = NULL; + virBuffer hostbuf = VIR_BUFFER_INITIALIZER; + if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0) goto error; if (!(ipstr = virSocketAddrFormat(ip))) - return -1; + goto error; /* the first test determines if it is a dhcpv6 host */ if (ipv6) { - if (name && id) { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, - "id:%s,%s,[%s]", id, name, ipstr) < 0) - goto error; - } else if (name && !id) { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, - "%s,[%s]", name, ipstr) < 0) - goto error; - } else if (!name && id) { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, - "id:%s,[%s]", id, ipstr) < 0) - goto error; - } + if (name && id) + virBufferAsprintf(&hostbuf, "id:%s,%s,[%s]", id, name, ipstr); + else if (name && !id) + virBufferAsprintf(&hostbuf, "%s,[%s]", name, ipstr); + else if (!name && id) + virBufferAsprintf(&hostbuf, "id:%s,[%s]", id, ipstr); } else if (name && mac) { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s,%s", - mac, ipstr, name) < 0) - goto error; + virBufferAsprintf(&hostbuf, "%s,%s,%s", mac, ipstr, name); } else if (name && !mac) { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s", - name, ipstr) < 0) - goto error; + virBufferAsprintf(&hostbuf, "%s,%s", name, ipstr); } else { - if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s", - mac, ipstr) < 0) - goto error; + virBufferAsprintf(&hostbuf, "%s,%s", mac, ipstr); } - VIR_FREE(ipstr); - hostsfile->nhosts++; + /* The leasetime string already includes comma if there's any value at all */ + virBufferAsprintf(&hostbuf, "%s", leasetime); - return 0; + if (!(hostsfile->hosts[hostsfile->nhosts].host = virBufferContentAndReset (&hostbuf))) + goto error; + hostsfile->nhosts++; + ret = 0; error: + virBufferFreeAndReset(&hostbuf); VIR_FREE(ipstr); - return -1; + return ret; } static dnsmasqHostsfile * @@ -391,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 @@ -412,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; @@ -436,6 +434,7 @@ hostsfileWrite(const char *path, } cleanup: + VIR_FREE(content); VIR_FREE(tmp); return rc; @@ -524,9 +523,10 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx, virSocketAddr *ip, const char *name, const char *id, + const char *leasetime, bool ipv6) { - return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, ipv6); + return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, leasetime, ipv6); } /* @@ -892,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 f47bea3..1795bc8 100644 --- a/src/util/virdnsmasq.h +++ b/src/util/virdnsmasq.h @@ -88,6 +88,7 @@ int dnsmasqAddDhcpHost(dnsmasqContext *ctx, virSocketAddr *ip, const char *name, const char *id, + const char *leastime, bool ipv6); int dnsmasqAddHost(dnsmasqContext *ctx, virSocketAddr *ip, @@ -105,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 0000000..de659b9 --- /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 0000000..9dfb172 --- /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 0000000..de659b9 --- /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/leasetime-days.conf b/tests/networkxml2confdata/leasetime-days.conf new file mode 100644 index 0000000..9501e2f --- /dev/null +++ b/tests/networkxml2confdata/leasetime-days.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,86400 +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,86400 +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime-days.xml b/tests/networkxml2confdata/leasetime-days.xml new file mode 100644 index 0000000..1a507d5 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-days.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>1d</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>1d</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime-host.conf b/tests/networkxml2confdata/leasetime-host.conf new file mode 100644 index 0000000..7bd2054 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-host.conf @@ -0,0 +1,16 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +srv-host=_name._tcp +dhcp-range=192.168.122.2,192.168.122.254 +dhcp-no-override +dhcp-lease-max=253 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts diff --git a/tests/networkxml2confdata/leasetime-host.hostsfile b/tests/networkxml2confdata/leasetime-host.hostsfile new file mode 100644 index 0000000..fd20ca2 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-host.hostsfile @@ -0,0 +1,6 @@ +00:16:3e:3e:a9:01,192.168.122.11,a.example.com,3600 +00:16:3e:3e:a9:02,192.168.122.12,b.example.com,3600 +00:16:3e:3e:a9:03,192.168.122.13,c.example.com,3600 +00:16:3e:3e:a9:04,192.168.122.14,d.example.com,86400 +00:16:3e:3e:a9:05,192.168.122.15,e.example.com,3600 +00:16:3e:3e:a9:06,192.168.122.16,f.example.com,infinite diff --git a/tests/networkxml2confdata/leasetime-host.xml b/tests/networkxml2confdata/leasetime-host.xml new file mode 100644 index 0000000..276d3e5 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-host.xml @@ -0,0 +1,22 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'> + <interface dev='eth1'/> + </forward> + <bridge name='virbr0' stp='on' delay='0'/> + <dns> + <srv service='name' protocol='tcp'/> + </dns> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <range start='192.168.122.2' end='192.168.122.254'/> + <host mac='00:16:3e:3e:a9:1a' name='a.example.com' ip='192.168.122.11' leasetime="3600s"/> + <host mac='00:16:3e:3e:a9:1b' name='b.example.com' ip='192.168.122.12' leasetime="60m"/> + <host mac='00:16:3e:3e:a9:1c' name='c.example.com' ip='192.168.122.13' leasetime="1h"/> + <host mac='00:16:3e:3e:a9:1d' name='d.example.com' ip='192.168.122.14' leasetime="1d"/> + <host mac='00:16:3e:3e:a9:1e' name='e.example.com' ip='192.168.122.15' leasetime="3600"/> + <host mac='00:16:3e:3e:a9:1f' name='f.example.com' ip='192.168.122.16' leasetime="-1"/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime-hours.conf b/tests/networkxml2confdata/leasetime-hours.conf new file mode 100644 index 0000000..021a769 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-hours.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,3600 +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,3600 +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime-hours.xml b/tests/networkxml2confdata/leasetime-hours.xml new file mode 100644 index 0000000..36dc600 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-hours.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>1h</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>1h</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime-infinite.conf b/tests/networkxml2confdata/leasetime-infinite.conf new file mode 100644 index 0000000..cc21135 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-infinite.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,infinite +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,infinite +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime-infinite.xml b/tests/networkxml2confdata/leasetime-infinite.xml new file mode 100644 index 0000000..bc8740e --- /dev/null +++ b/tests/networkxml2confdata/leasetime-infinite.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>-1</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>-1</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime-minutes.conf b/tests/networkxml2confdata/leasetime-minutes.conf new file mode 100644 index 0000000..db68895 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-minutes.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,300 +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,300 +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime-minutes.xml b/tests/networkxml2confdata/leasetime-minutes.xml new file mode 100644 index 0000000..7c1df25 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-minutes.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>5m</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>5m</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime-seconds.conf b/tests/networkxml2confdata/leasetime-seconds.conf new file mode 100644 index 0000000..635896b --- /dev/null +++ b/tests/networkxml2confdata/leasetime-seconds.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,125 +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,125 +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime-seconds.xml b/tests/networkxml2confdata/leasetime-seconds.xml new file mode 100644 index 0000000..dcb3f91 --- /dev/null +++ b/tests/networkxml2confdata/leasetime-seconds.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>125s</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>125s</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> diff --git a/tests/networkxml2confdata/leasetime.conf b/tests/networkxml2confdata/leasetime.conf new file mode 100644 index 0000000..72a2f69 --- /dev/null +++ b/tests/networkxml2confdata/leasetime.conf @@ -0,0 +1,17 @@ +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE +##OVERWRITTEN AND LOST. Changes to this configuration should be made using: +## virsh net-edit default +## or other application using the libvirt API. +## +## dnsmasq conf file created by libvirt +strict-order +except-interface=lo +bind-dynamic +interface=virbr0 +dhcp-range=192.168.122.2,192.168.122.254,122 +dhcp-no-override +dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,121 +dhcp-lease-max=493 +dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts +enable-ra diff --git a/tests/networkxml2confdata/leasetime.xml b/tests/networkxml2confdata/leasetime.xml new file mode 100644 index 0000000..fdbb15f --- /dev/null +++ b/tests/networkxml2confdata/leasetime.xml @@ -0,0 +1,18 @@ +<network> + <name>default</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward dev='eth1' mode='nat'/> + <bridge name='virbr0' stp='on' delay='0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <leasetime>122</leasetime> + <range start='192.168.122.2' end='192.168.122.254'/> + </dhcp> + </ip> + <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'> + <dhcp> + <leasetime>121</leasetime> + <range start='2001:db8:ac10:fd01::1:10' end='2001:db8:ac10:fd01::1:ff'/> + </dhcp> + </ip> +</network> 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 0000000..deb3f00 --- /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 0000000..deb3f00 --- /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 0000000..deb3f00 --- /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 0000000..deb3f00 --- /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 0000000..deb3f00 --- /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 65a0e32..8e1f8be 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; } @@ -129,6 +150,14 @@ mymain(void) DO_TEST("dhcp6-network", dhcpv6); DO_TEST("dhcp6-nat-network", dhcpv6); DO_TEST("dhcp6host-routed-network", dhcpv6); + DO_TEST("leasetime", dhcpv6); + DO_TEST("leasetime-seconds", dhcpv6); + DO_TEST("leasetime-hours", dhcpv6); + DO_TEST("leasetime-minutes", dhcpv6); + DO_TEST("leasetime-hours", dhcpv6); + DO_TEST("leasetime-days", dhcpv6); + DO_TEST("leasetime-infinite", dhcpv6); + DO_TEST("leasetime-host", dhcpv6); virObjectUnref(dhcpv6); virObjectUnref(full); -- 2.9.3
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list