[libvirt] [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 = networkDnsmasqConfLeaseValueTo String(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 = networkDnsmasqConfLeaseValueTo String(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 -- Alberto Ruiz Associate Engineering Manager - Desktop Management Tools Red Hat

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

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. On Thu, Oct 13, 2016 at 7:07 AM, Michal Privoznik <mprivozn@redhat.com> 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 Tools Red Hat

Sorry, we missed this 2nd patch posting. FYI, when sending updated versions of patches, we generally recommend to send them as a new top level thread, with 'PATCH v2' in the subject line, not as reply to the v1 patch. We find that makes it less likely to miss the second version when processing email.
From d48f957ab78310d864b356b4a25b9a29722ca736 Mon Sep 17 00:00:00 2001 From: Alberto Ruiz <aruiz@gnome.org> 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)
What does '0' mean - i guess we're considering '0' to mean the default dnsmasq lease time for sake of upgrade from previous versions ? Using this syntax means that applications processing XML need to first extract the attribute, and then parse it to separate the value from the unit. In most other places, we use separate attribute to denote the units. So I think we'd probably be better doing <dhcp> <leasetime unit="hours">24</leasetime> ... </dhcp> and <dhcp> <host leasetime="7" leaseunit="days" .../> </dhcp> Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
participants (3)
-
Alberto Ruiz
-
Daniel P. Berrange
-
Michal Privoznik