From: Alberto Ruiz <aruiz@xxxxxxxxx> --- docs/schemas/basictypes.rng | 16 +++++ docs/schemas/network.rng | 8 +++ src/conf/network_conf.c | 78 ++++++++++++++++++++++- src/conf/network_conf.h | 3 +- src/network/bridge_driver.c | 49 +++++++++++++- tests/networkxml2confdata/leasetime-days.conf | 17 +++++ tests/networkxml2confdata/leasetime-days.xml | 18 ++++++ 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 ++++++ tests/networkxml2conftest.c | 7 ++ 18 files changed, 368 insertions(+), 3 deletions(-) create mode 100644 tests/networkxml2confdata/leasetime-days.conf create mode 100644 tests/networkxml2confdata/leasetime-days.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 diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng index 1b4f980e7..8a76c235a 100644 --- a/docs/schemas/basictypes.rng +++ b/docs/schemas/basictypes.rng @@ -518,4 +518,20 @@ </element> </define> + <define name="leaseTimeUnit"> + <choice> + <value>seconds</value> + <value>minutes</value> + <value>hours</value> + <value>days</value> + </choice> + </define> + + <define name="leaseTime"> + <data type="long"> + <param name="minInclusive">-1</param> + <param name="maxInclusive">4294967295</param> + </data> + </define> + </grammar> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 1a18e64b2..4b8056ab6 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -340,6 +340,14 @@ <!-- Define the range(s) of IP addresses that the DHCP server should hand out --> <element name="dhcp"> + <optional> + <element name="leasetime"> + <optional> + <attribute name="unit"><ref name="leaseTimeUnit"/></attribute> + </optional> + <ref name="leaseTime"/> + </element> + </optional> <zeroOrMore> <element name="range"> <attribute name="start"><ref name="ipAddr"/></attribute> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index aa397768c..6f051493f 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" @@ -1031,12 +1033,82 @@ virNetworkDHCPHostDefParseXML(const char *networkName, return ret; } +static int64_t +virNetworkDHCPDefGetLeaseTime (xmlNodePtr node, + xmlXPathContextPtr ctxt, + bool *error) +{ + int64_t multiplier, result = -1; + char *leaseString, *leaseUnit; + xmlNodePtr save; + + *error = 0; + + save = ctxt->node; + ctxt->node = node; + + leaseString = virXPathString ("string(./leasetime/text())", ctxt); + leaseUnit = virXPathString ("string(./leasetime/@unit)", ctxt); + + /* If value is not present we set the value to -2 */ + if (leaseString == NULL) { + result = -2; + goto cleanup; + } + + if (leaseUnit == NULL || strcmp (leaseUnit, "seconds") == 0) + multiplier = 1; + else if (strcmp (leaseUnit, "minutes") == 0) + multiplier = 60; + else if (strcmp (leaseUnit, "hours") == 0) + multiplier = 60 * 60; + else if (strcmp (leaseUnit, "days") == 0) + multiplier = 60 * 60 * 24; + else { + virReportError(VIR_ERR_XML_ERROR, + _("invalid value for unit parameter in <leasetime> element found in <dhcp> network, " + "only 'seconds', 'minutes', 'hours' or 'days' are valid: %s"), + leaseUnit); + *error = 1; + goto cleanup; + } + + 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) { + virReportError(VIR_ERR_XML_ERROR, + _("<leasetime> value cannot be greater than the equivalent of %" PRIo32 " seconds : %" PRId64), + UINT32_MAX, result); + *error = 1; + } + +cleanup: + VIR_FREE(leaseString); + VIR_FREE(leaseUnit); + ctxt->node = save; + return result; +} + 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 +1116,10 @@ virNetworkDHCPDefParseXML(const char *networkName, memset(&range, 0, sizeof(range)); memset(&host, 0, sizeof(host)); + def->leasetime = virNetworkDHCPDefGetLeaseTime (node, ctxt, &error); + if (error) + goto cleanup; + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE && @@ -1607,7 +1683,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")) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 3b227db6f..f7557f581 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -170,7 +170,8 @@ struct _virNetworkIPDef { char *tftproot; char *bootfile; virSocketAddr bootserver; - }; + int64_t leasetime; +}; typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef; typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 7b99acafa..e51e469c8 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 @@ -903,6 +905,40 @@ 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; +} int networkDnsmasqConfContents(virNetworkObjPtr network, @@ -1213,6 +1249,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 +1257,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, diff --git a/tests/networkxml2confdata/leasetime-days.conf b/tests/networkxml2confdata/leasetime-days.conf new file mode 100644 index 000000000..9501e2f8a --- /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 000000000..b990b4d68 --- /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 unit="days">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 unit="days">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-hours.conf b/tests/networkxml2confdata/leasetime-hours.conf new file mode 100644 index 000000000..021a769bc --- /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 000000000..3b9609601 --- /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 unit="hours">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 unit="hours">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-infinite.conf b/tests/networkxml2confdata/leasetime-infinite.conf new file mode 100644 index 000000000..cc21135de --- /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 000000000..bc8740ee6 --- /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 000000000..db688951b --- /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 000000000..e7a27afe6 --- /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 unit="minutes">5</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 unit="minutes">5</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 000000000..635896b29 --- /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 000000000..56b07f8ae --- /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 unit="seconds">125</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 unit="seconds">125</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 000000000..72a2f6926 --- /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 000000000..fdbb15fc0 --- /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/networkxml2conftest.c b/tests/networkxml2conftest.c index 65a0e3218..223a56f54 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -129,6 +129,13 @@ 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); virObjectUnref(dhcpv6); virObjectUnref(full); -- 2.13.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list