[PATCH v3 1/2] conf: Add <lease/> option for <dhcp/> settings
Michal Privoznik
mprivozn at redhat.com
Thu Apr 23 09:01:14 UTC 2020
On 4/22/20 10:05 PM, Julio Faracco wrote:
> If an user is trying to configure a dhcp neetwork settings, it is not
> possible to change the leasetime of a range or a host entry. This is
> available using dnsmasq extra options, but they are associated with
> dhcp-range or dhcp-hosts fields. This patch implements a leasetime for
> range and hosts tags. They can be defined under that settings:
>
> <dhcp>
> <range ...>
> <lease/>
> </range>
> <host ...>
> <lease/>
> </host>
> </dhcp>
>
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=913446
>
> Signed-off-by: Julio Faracco <jcfaracco at gmail.com>
> ---
> docs/schemas/basictypes.rng | 8 ++
> docs/schemas/network.rng | 20 +++++
> src/conf/network_conf.c | 159 +++++++++++++++++++++++++++++++-----
> src/conf/network_conf.h | 27 +++++-
> src/libvirt_private.syms | 3 +
> src/network/bridge_driver.c | 56 +++++++++++--
> src/network/bridge_driver.h | 1 +
> src/test/test_driver.c | 2 +-
> src/util/virdnsmasq.c | 60 +++++++++-----
> src/util/virdnsmasq.h | 3 +
> src/vbox/vbox_network.c | 16 ++--
> tests/networkxml2conftest.c | 15 ++--
> 12 files changed, 306 insertions(+), 64 deletions(-)
>
> diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
> index 81465273c8..271ed18afb 100644
> --- a/docs/schemas/basictypes.rng
> +++ b/docs/schemas/basictypes.rng
> @@ -607,4 +607,12 @@
> </element>
> </define>
>
> + <define name="leaseUnit">
> + <choice>
> + <value>seconds</value>
> + <value>mins</value>
> + <value>hours</value>
Since seconds and hours are specified fully, I think "mins" should be
too. It's not any longer than "seconds" anyway :-)
> + </choice>
> + </define>
> +
> </grammar>
> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> index 60453225d6..88b6f4dfdd 100644
> --- a/docs/schemas/network.rng
> +++ b/docs/schemas/network.rng
> @@ -371,6 +371,16 @@
> <element name="range">
> <attribute name="start"><ref name="ipAddr"/></attribute>
> <attribute name="end"><ref name="ipAddr"/></attribute>
> + <interleave>
> + <optional>
> + <element name="lease">
> + <attribute name="expiry"><ref name="unsignedLong"/></attribute>
> + <optional>
> + <attribute name="unit"><ref name="leaseUnit"/></attribute>
> + </optional>
> + </element>
> + </optional>
> + </interleave>
> </element>
> </zeroOrMore>
> <zeroOrMore>
> @@ -388,6 +398,16 @@
> <attribute name="name"><text/></attribute>
> </choice>
> <attribute name="ip"><ref name="ipAddr"/></attribute>
> + <interleave>
> + <optional>
> + <element name="lease">
> + <attribute name="expiry"><ref name="unsignedLong"/></attribute>
> + <optional>
> + <attribute name="unit"><ref name="leaseUnit"/></attribute>
> + </optional>
> + </element>
> + </optional>
> + </interleave>
> </element>
> </zeroOrMore>
> <optional>
> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> index 819b645df7..286a0edb7c 100644
> --- a/src/conf/network_conf.c
> +++ b/src/conf/network_conf.c
> @@ -70,6 +70,13 @@ VIR_ENUM_IMPL(virNetworkTaint,
> "hook-script",
> );
>
> +VIR_ENUM_IMPL(virNetworkDHCPLeaseTimeUnit,
> + VIR_NETWORK_DHCP_LEASETIME_UNIT_LAST,
> + "seconds",
> + "mins",
> + "hours",
> +);
> +
> static virClassPtr virNetworkXMLOptionClass;
>
> static void
> @@ -132,12 +139,20 @@ virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def)
> }
>
>
> +static void
> +virNetworkDHCPLeaseTimeDefClear(virNetworkDHCPLeaseTimeDefPtr lease)
> +{
> + VIR_FREE(lease);
> +}
> +
> +
> static void
> virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def)
> {
> VIR_FREE(def->mac);
> VIR_FREE(def->id);
> VIR_FREE(def->name);
> + VIR_FREE(def->lease);
> }
>
>
> @@ -145,6 +160,9 @@ static void
> virNetworkIPDefClear(virNetworkIPDefPtr def)
> {
> VIR_FREE(def->family);
> +
> + while (def->nranges)
> + virNetworkDHCPLeaseTimeDefClear(def->ranges[--def->nranges].lease);
> VIR_FREE(def->ranges);
>
> while (def->nhosts)
> @@ -391,11 +409,55 @@ int virNetworkIPDefNetmask(const virNetworkIPDef *def,
>
>
> static int
> -virSocketAddrRangeParseXML(const char *networkName,
> - virNetworkIPDefPtr ipdef,
> - xmlNodePtr node,
> - virSocketAddrRangePtr range)
> +virNetworkDHCPLeaseTimeDefParseXML(virNetworkDHCPLeaseTimeDefPtr *lease,
> + xmlNodePtr node)
> +{
> + virNetworkDHCPLeaseTimeDefPtr new_lease = *lease;
> + g_autofree char *expiry = NULL, *unit = NULL;
> +
> + if (!(expiry = virXMLPropString(node, "expiry")))
> + return 0;
> +
> + if (VIR_ALLOC(new_lease) < 0)
> + return -1;
> +
> + if (virStrToLong_ul(expiry, NULL, 10, &new_lease->expiry) < 0)
> + return -1;
> +
> + if (!(unit = virXMLPropString(node, "unit")))
> + new_lease->unit = VIR_NETWORK_DHCP_LEASETIME_UNIT_MINUTES;
> + else
> + new_lease->unit = virNetworkDHCPLeaseTimeUnitTypeFromString(unit);
Ouch. This is unsafe. Firstly, if an uses specifies say
unit="microfornight" TypeFromString() will return -1 because the string
is not from the enum. Then, assigning -1 to the
virNetworkDHCPLeaseTimeUnitType enum which doesn't contain that value is
dangerous too...
> +
> + /* infinite */
> + if (new_lease->expiry > 0) {
> + /* This boundary check is related to dnsmasq man page settings:
> + * "The minimum lease time is two minutes." */
> + if ((new_lease->unit == VIR_NETWORK_DHCP_LEASETIME_UNIT_SECONDS &&
> + new_lease->expiry < 120) ||
> + (new_lease->unit == VIR_NETWORK_DHCP_LEASETIME_UNIT_MINUTES &&
> + new_lease->expiry < 2)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("The minimum lease time should be greater "
> + "than 2 minutes"));
> + return -1;
> + }
> + }
> +
> + *lease = new_lease;
> +
> + return 0;
> +}
> +
> +
> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> index f06099297a..87f0452611 100644
> --- a/src/network/bridge_driver.c
> +++ b/src/network/bridge_driver.c
> @@ -966,6 +966,30 @@ static int networkConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED)
> }
>
>
> +static char *
> +networkBuildDnsmasqLeaseTime(virNetworkDHCPLeaseTimeDefPtr lease)
> +{
> + char *leasetime = NULL;
> + const char *unit;
> + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
> +
> + if (!lease)
> + return NULL;
> +
> + if (lease->expiry == 0) {
> + virBufferAddLit(&buf, "infinite");
> + } else {
> + unit = virNetworkDHCPLeaseTimeUnitTypeToString(lease->unit);
> + /* We get only first compatible char from string: 's', 'm' or 'h' */
> + virBufferAsprintf(&buf, "%lu%c", lease->expiry, unit[0]);
... because here unit will be NULL and dereferenced.
Michal
More information about the libvir-list
mailing list