[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] Add support for <option> tag in network config



This patch adds support for a new <option>-Tag in the <dhcp> block of network configs,
based on a subset of the fifth proposal by Laine Stump in the mailing list discussion at
https://www.redhat.com/archives/libvir-list/2012-November/msg01054.html. Any such defined
option will result in a dhcp-option=<number>,"<value>" statement in the generated dnsmasq
configuration file.

Currently, DHCP options can be specified by number only and there is no whitelisting or
blacklisting of option numbers, which should probably be added.

Signed-off-by: Pieter Hollants <pieter hollants com>
---
 AUTHORS.in                                        |    1 +
 docs/schemas/network.rng                          |    6 +++
 docs/schemas/networkcommon.rng                    |    6 +++
 src/conf/network_conf.c                           |   54 +++++++++++++++++++++
 src/conf/network_conf.h                           |   10 ++++
 src/network/bridge_driver.c                       |   10 ++++
 tests/networkxml2xmlin/netboot-network.xml        |    1 +
 tests/networkxml2xmlin/netboot-proxy-network.xml  |    1 +
 tests/networkxml2xmlout/netboot-network.xml       |    1 +
 tests/networkxml2xmlout/netboot-proxy-network.xml |    1 +
 10 Dateien geändert, 91 Zeilen hinzugefügt(+)

diff --git a/AUTHORS.in b/AUTHORS.in
index 39fe68d..074185e 100644
--- a/AUTHORS.in
+++ b/AUTHORS.in
@@ -74,6 +74,7 @@ Michel Ponceau <michel ponceau bull net>
 Nobuhiro Itou <fj0873gn aa jp fujitsu com>
 Pete Vetere <pvetere redhat com>
 Philippe Berthault <philippe berthault Bull net>
+Pieter Hollants <pieter hollants com>
 Saori Fukuta <fukuta saori jp fujitsu com>
 Shigeki Sakamoto <fj0588di aa jp fujitsu com>
 Shuveb Hussain <shuveb binarykarma com>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 09d7c73..a2ce1c9 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -293,6 +293,12 @@
                     </optional>
                   </element>
                 </optional>
+                <zeroOrMore>
+                  <element name="option">
+                    <attribute name="number"><ref name="unsignedByte"/></attribute>
+                    <attribute name="value"><text/></attribute>
+                  </element>
+                </zeroOrMore>
               </element>
             </optional>
           </element>
diff --git a/docs/schemas/networkcommon.rng b/docs/schemas/networkcommon.rng
index 51ff759..3510928 100644
--- a/docs/schemas/networkcommon.rng
+++ b/docs/schemas/networkcommon.rng
@@ -173,6 +173,12 @@
     </data>
   </define>
 
+  <define name='unsignedByte'>
+    <data type='integer'>
+      <param name="minInclusive">0</param>
+      <param name="maxInclusive">255</param>
+    </data>
+  </define>
   <define name='unsignedShort'>
     <data type='integer'>
       <param name="minInclusive">0</param>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 3604ff7..9d84c7e 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -777,6 +777,45 @@ cleanup:
 }
 
 static int
+virNetworkDHCPOptionDefParseXML(const char *networkName,
+                                xmlNodePtr node,
+                                virNetworkDHCPOptionDefPtr option)
+{
+    char *number = NULL;
+    int ret = -1;
+
+    if (!(number = virXMLPropString(node, "number"))) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Option definition in IPv4 network '%s' "
+                         "must have number attribute"),
+                       networkName);
+        goto cleanup;
+    }
+    if (number &&
+        virStrToLong_ui(number, NULL, 10, &option->number) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Cannot parse <option> 'number' attribute"));
+        goto cleanup;
+    }
+    /* TODO: either whitelist numbers or blacklist numbers already occupied
+     *       by other XML statements (eg. submask) */
+    if (!(option->value = virXMLPropString(node, "value"))) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Option definition in IPv4 network '%s' "
+                         "must have value attribute"),
+                       networkName);
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(number);
+    return ret;
+}
+
+
+static int
 virNetworkDHCPDefParseXML(const char *networkName,
                           xmlNodePtr node,
                           virNetworkIpDefPtr def)
@@ -837,6 +876,17 @@ virNetworkDHCPDefParseXML(const char *networkName,
             def->bootfile = file;
             def->bootserver = inaddr;
             VIR_FREE(server);
+        } else if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "option")) {
+            if (VIR_REALLOC_N(def->options, def->noptions + 1) < 0) {
+                virReportOOMError();
+                return -1;
+            }
+            if (virNetworkDHCPOptionDefParseXML(networkName, cur,
+                                                &def->options[def->noptions])) {
+                return -1;
+            }
+            def->noptions++;
         }
 
         cur = cur->next;
@@ -2045,6 +2095,10 @@ virNetworkIpDefFormat(virBufferPtr buf,
             virBufferAddLit(buf, "/>\n");
 
         }
+        for (ii = 0 ; ii < def->noptions ; ii++) {
+            virBufferAsprintf(buf, "<option number='%u' value='%s' />\n",
+                              def->options[ii].number, def->options[ii].value);
+        }
 
         virBufferAdjustIndent(buf, -2);
         virBufferAddLit(buf, "</dhcp>\n");
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 4c634ed..14f852a 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -77,6 +77,13 @@ struct _virNetworkDHCPHostDef {
     virSocketAddr ip;
 };
 
+typedef struct _virNetworkDHCPOptionDef virNetworkDHCPOptionDef;
+typedef virNetworkDHCPOptionDef *virNetworkDHCPOptionDefPtr;
+struct _virNetworkDHCPOptionDef {
+    unsigned int number;
+    char *value;
+};
+
 typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
 typedef virNetworkDNSTxtDef *virNetworkDNSTxtDefPtr;
 struct _virNetworkDNSTxtDef {
@@ -139,6 +146,9 @@ struct _virNetworkIpDef {
     char *tftproot;
     char *bootfile;
     virSocketAddr bootserver;
+
+    size_t noptions;            /* Zero or more additional dhcp options */
+    virNetworkDHCPOptionDefPtr options;
    };
 
 typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c834f83..c7c0a9e 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -926,6 +926,15 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
                     virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile);
                 }
             }
+
+            /* Any additional DHCP options? */
+            if (ipdef->noptions > 0) {
+                for (r = 0 ; r < ipdef->noptions ; r++) {
+                    virBufferAsprintf(&configbuf, "dhcp-option=%u,\"%s\"\n",
+                                      ipdef->options[r].number,
+                                      ipdef->options[r].value);
+                }
+            }
         }
         ipdef = (ipdef == ipv6def) ? NULL : ipv6def;
     }
@@ -959,6 +968,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
     virBufferAsprintf(&configbuf, "addn-hosts=%s\n",
                       dctx->addnhostsfile->path);
 
+
     /* Are we doing RA instead of radvd? */
     if (DNSMASQ_RA_SUPPORT(caps)) {
         if (ipv6def)
diff --git a/tests/networkxml2xmlin/netboot-network.xml b/tests/networkxml2xmlin/netboot-network.xml
index ed75663..4de8976 100644
--- a/tests/networkxml2xmlin/netboot-network.xml
+++ b/tests/networkxml2xmlin/netboot-network.xml
@@ -9,6 +9,7 @@
     <dhcp>
       <range start="192.168.122.2" end="192.168.122.254" />
       <bootp file="pxeboot.img" />
+      <option number="252" value="\n" />
     </dhcp>
   </ip>
 </network>
diff --git a/tests/networkxml2xmlin/netboot-proxy-network.xml b/tests/networkxml2xmlin/netboot-proxy-network.xml
index ecb6738..4c5c480 100644
--- a/tests/networkxml2xmlin/netboot-proxy-network.xml
+++ b/tests/networkxml2xmlin/netboot-proxy-network.xml
@@ -8,6 +8,7 @@
     <dhcp>
       <range start="192.168.122.2" end="192.168.122.254" />
       <bootp file="pxeboot.img" server="10.20.30.40" />
+      <option number="252" value="\n" />
     </dhcp>
   </ip>
 </network>
diff --git a/tests/networkxml2xmlout/netboot-network.xml b/tests/networkxml2xmlout/netboot-network.xml
index b8a4d99..c3ea95a 100644
--- a/tests/networkxml2xmlout/netboot-network.xml
+++ b/tests/networkxml2xmlout/netboot-network.xml
@@ -9,6 +9,7 @@
     <dhcp>
       <range start='192.168.122.2' end='192.168.122.254' />
       <bootp file='pxeboot.img' />
+      <option number='252' value='\n' />
     </dhcp>
   </ip>
 </network>
diff --git a/tests/networkxml2xmlout/netboot-proxy-network.xml b/tests/networkxml2xmlout/netboot-proxy-network.xml
index e11c50b..f5f2c0d 100644
--- a/tests/networkxml2xmlout/netboot-proxy-network.xml
+++ b/tests/networkxml2xmlout/netboot-proxy-network.xml
@@ -8,6 +8,7 @@
     <dhcp>
       <range start='192.168.122.2' end='192.168.122.254' />
       <bootp file='pxeboot.img' server='10.20.30.40' />
+      <option number='252' value='\n' />
     </dhcp>
   </ip>
 </network>
-- 
1.7.10.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]