[libvirt] [PATCHv2] network: add force attribute for dhcp options

Laine Stump laine at laine.org
Mon Feb 25 18:30:25 UTC 2013


If a dhcp option has "force='yes'", the dhcp server will send that
option back to every client regardless of whether or not the client
requests that option (without "force='yes'", an option will only be
sent to those clients that ask for it in their request packet). For example:

  <option number='40' value='libvirt' force='yes'/>

This information is relayed to dnsmasq by using the
"dhcp-option-force" option, rather than "dhcp-option".
---
Changes from V1:
* add forgotten addition to RNG
* add forgotten addition to virNetworkIpDefFormat
* add networkxml2xml test (which would have caught the above)

 docs/formatnetwork.html.in                 | 21 +++++++++++++++++++++
 docs/schemas/network.rng                   |  8 ++++++++
 src/conf/network_conf.c                    | 16 ++++++++++++++++
 src/conf/network_conf.h                    |  3 ++-
 src/network/bridge_driver.c                |  3 ++-
 tests/networkxml2confdata/nat-network.conf |  2 +-
 tests/networkxml2confdata/nat-network.xml  |  2 +-
 tests/networkxml2xmlin/nat-network.xml     |  5 +++++
 tests/networkxml2xmlout/nat-network.xml    |  5 +++++
 9 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 41a83fa..97e3bd4 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -557,6 +557,10 @@
             <range start="192.168.122.100" end="192.168.122.254" />
             <host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" />
             <host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" />
+            <option number='252' value='\n'/>
+            <option number='4' value='192.168.122.11'/>
+            <option number='6' value='192.168.145.23'/>
+            <option number='23' value='64' force='yes'/>
           </dhcp>
         </ip>
         <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
@@ -699,6 +703,23 @@
                 for all address ranges and statically assigned addresses.<span
                 class="since">Since 0.7.1 (<code>server</code> since 0.7.3).</span>
               </dd>
+              <dt><code>option</code></dt>
+              <dd>The optional <code>option</code> element (which can
+                be repeated for multiple DHCP options) specifies
+                generic DHCP options (as defined in RFC 2132, or later
+                RFCs in some cases) that will be sent by the DHCP
+                server to requesting clients (IPv4 only).  There are
+                three possible attributes: <code>number</code> is
+                mandatory and gives the standard option
+                number; <code>value</code> is optional and gives the
+                value of that option to be provided to the client
+                <code>force</code> is also optional, and defaults to
+                "no"; if <code>force</code> is "yes", the option will
+                be sent to all DHCP clients regardless of whether or
+                not the client requests it (usually only options
+                specifically requested by the client are sent in the
+                DHCP response).<span class="since">Since 1.0.3</span>
+              </dd>
             </dl>
           </dd>
         </dl>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index da7d8ad..ed6964a 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -305,6 +305,14 @@
                   <element name="option">
                     <attribute name="number"><ref name="uint8range"/></attribute>
                     <attribute name="value"><text/></attribute>
+                    <optional>
+                      <attribute name="force">
+                        <choice>
+                          <value>yes</value>
+                          <value>no</value>
+                        </choice>
+                      </attribute>
+                    </optional>
                   </element>
                 </zeroOrMore>
               </element>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 8b57242..4d07bac 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -796,6 +796,7 @@ virNetworkDHCPOptionDefParseXML(const char *networkName,
                                 virNetworkDHCPOptionDefPtr option)
 {
     char *number = NULL;
+    char *force = NULL;
     int ret = -1;
 
     if (!(number = virXMLPropString(node, "number"))) {
@@ -811,12 +812,25 @@ virNetworkDHCPOptionDefParseXML(const char *networkName,
                        number);
         goto cleanup;
     }
+
     option->value = virXMLPropString(node, "value");
 
+    if ((force = virXMLPropString(node, "force"))) {
+       if (STRCASEEQ(force, "yes")) {
+          option->force = true;
+       } else if (STRCASENEQ(force, "no")) {
+           virReportError(VIR_ERR_XML_ERROR,
+                          _("Invalid <option> force attribute %s "
+                            "in network '%s'"), force, networkName);
+           goto cleanup;
+       }
+    }
+
     ret = 0;
 
 cleanup:
     VIR_FREE(number);
+    VIR_FREE(force);
     return ret;
 }
 
@@ -2233,6 +2247,8 @@ virNetworkIpDefFormat(virBufferPtr buf,
             virBufferAsprintf(buf, "<option number='%u'",
                               def->options[ii].number);
             virBufferEscapeString(buf, " value='%s'", def->options[ii].value);
+            if (def->options[ii].force)
+               virBufferAddLit(buf, " force='yes'");
             virBufferAddLit(buf, "/>\n");
         }
 
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index c509915..93ea371 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -1,7 +1,7 @@
 /*
  * network_conf.h: network XML handling
  *
- * Copyright (C) 2006-2008, 2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -76,6 +76,7 @@ typedef virNetworkDHCPOptionDef *virNetworkDHCPOptionDefPtr;
 struct _virNetworkDHCPOptionDef {
     unsigned int number;
     char *value;
+    bool force;
 };
 
 typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 0932cf8..3f271d9 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -929,7 +929,8 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
             }
 
             for (r = 0 ; r < ipdef->noptions ; r++) {
-                virBufferAsprintf(&configbuf, "dhcp-option=%u",
+                virBufferAsprintf(&configbuf, "dhcp-option%s=%u",
+                                  ipdef->options[r].force ? "-force" : "",
                                   ipdef->options[r].number);
                 /* value is optional, and only needs quoting if it contains spaces */
                 if (ipdef->options[r].value) {
diff --git a/tests/networkxml2confdata/nat-network.conf b/tests/networkxml2confdata/nat-network.conf
index ee41e2a..2e855f4 100644
--- a/tests/networkxml2confdata/nat-network.conf
+++ b/tests/networkxml2confdata/nat-network.conf
@@ -14,7 +14,7 @@ dhcp-range=192.168.122.2,192.168.122.254
 dhcp-no-override
 dhcp-option=42,192.168.122.20
 dhcp-option=23,50
-dhcp-option=40,libvirt
+dhcp-option-force=40,libvirt
 dhcp-option=252,"\n"
 dhcp-option=253," leading and trailing spaces "
 dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
diff --git a/tests/networkxml2confdata/nat-network.xml b/tests/networkxml2confdata/nat-network.xml
index 22ec533..0062cb4 100644
--- a/tests/networkxml2confdata/nat-network.xml
+++ b/tests/networkxml2confdata/nat-network.xml
@@ -10,7 +10,7 @@
       <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
       <option number='42' value='192.168.122.20'/>
       <option number='23' value='50'/>
-      <option number='40' value='libvirt'/>
+      <option number='40' value='libvirt' force='yes'/>
       <option number='252' value='\n'/>
       <option number='253' value=' leading and trailing spaces '/>
     </dhcp>
diff --git a/tests/networkxml2xmlin/nat-network.xml b/tests/networkxml2xmlin/nat-network.xml
index 23f7fcb..d6a174b 100644
--- a/tests/networkxml2xmlin/nat-network.xml
+++ b/tests/networkxml2xmlin/nat-network.xml
@@ -8,6 +8,11 @@
       <range start="192.168.122.2" end="192.168.122.254" />
       <host mac="00:16:3e:77:e2:ed" name="a.example.com" ip="192.168.122.10" />
       <host mac="00:16:3e:3e:a9:1a" name="b.example.com" ip="192.168.122.11" />
+      <option number='42' value='192.168.122.20'/>
+      <option number='23' value='50'/>
+      <option number='40' value='libvirt' force='yes'/>
+      <option number='252' value='\n'/>
+      <option number='253' value=' leading and trailing spaces '/>
     </dhcp>
   </ip>
   <ip family="ipv4" address="192.168.123.1" netmask="255.255.255.0">
diff --git a/tests/networkxml2xmlout/nat-network.xml b/tests/networkxml2xmlout/nat-network.xml
index 02d6849..55c051e 100644
--- a/tests/networkxml2xmlout/nat-network.xml
+++ b/tests/networkxml2xmlout/nat-network.xml
@@ -10,6 +10,11 @@
       <range start='192.168.122.2' end='192.168.122.254' />
       <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
       <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
+      <option number='42' value='192.168.122.20'/>
+      <option number='23' value='50'/>
+      <option number='40' value='libvirt' force='yes'/>
+      <option number='252' value='\n'/>
+      <option number='253' value=' leading and trailing spaces '/>
     </dhcp>
   </ip>
   <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
-- 
1.7.11.7




More information about the libvir-list mailing list