]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add support for <option> tag in network config
authorPieter Hollants <pieter@hollants.com>
Thu, 21 Feb 2013 22:40:17 +0000 (23:40 +0100)
committerLaine Stump <laine@laine.org>
Sat, 23 Feb 2013 00:45:19 +0000 (19:45 -0500)
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>
Signed-off-by: Laine Stump <laine@laine.org>
docs/schemas/network.rng
src/conf/network_conf.c
src/conf/network_conf.h
src/network/bridge_driver.c
tests/networkxml2confdata/nat-network.conf
tests/networkxml2confdata/nat-network.xml
tests/networkxml2xmlin/netboot-network.xml
tests/networkxml2xmlin/netboot-proxy-network.xml
tests/networkxml2xmlout/netboot-network.xml
tests/networkxml2xmlout/netboot-proxy-network.xml

index 09d7c7350e06e2cba32353efcab30217ae244615..66f32a44df02a19fd55db634681a57ea2278641c 100644 (file)
                     </optional>
                   </element>
                 </optional>
+                <zeroOrMore>
+                  <element name="option">
+                    <attribute name="number"><ref name="uint8range"/></attribute>
+                    <attribute name="value"><text/></attribute>
+                  </element>
+                </zeroOrMore>
               </element>
             </optional>
           </element>
index cdffd19585cde81e7babe5f8a64107de9b652e94..34fd05abe70db62053e04174f6b77f38404563c1 100644 (file)
@@ -776,6 +776,37 @@ cleanup:
     return ret;
 }
 
+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 (virStrToLong_ui(number, NULL, 10, &option->number) < 0) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Malformed <option> number attribute: %s"),
+                       number);
+        goto cleanup;
+    }
+    option->value = virXMLPropString(node, "value");
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(number);
+    return ret;
+}
+
+
 static int
 virNetworkDHCPDefParseXML(const char *networkName,
                           xmlNodePtr node,
@@ -837,6 +868,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;
@@ -2171,6 +2213,12 @@ virNetworkIpDefFormat(virBufferPtr buf,
             virBufferAddLit(buf, "/>\n");
 
         }
+        for (ii = 0 ; ii < def->noptions ; ii++) {
+            virBufferAsprintf(buf, "<option number='%u'",
+                              def->options[ii].number);
+            virBufferEscapeString(buf, " value='%s'", def->options[ii].value);
+            virBufferAddLit(buf, "/>\n");
+        }
 
         virBufferAdjustIndent(buf, -2);
         virBufferAddLit(buf, "</dhcp>\n");
index d5de7d138ec1b6df5c8abc41af3422ff644f78ce..e7a4f95f2b9b14678e9f74cbdf3136725532f5ac 100644 (file)
@@ -70,6 +70,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 {
@@ -129,9 +136,13 @@ struct _virNetworkIpDef {
     size_t nhosts;              /* Zero or more dhcp hosts */
     virNetworkDHCPHostDefPtr hosts;
 
+    size_t noptions;            /* Zero or more additional dhcp options */
+    virNetworkDHCPOptionDefPtr options;
+
     char *tftproot;
     char *bootfile;
     virSocketAddr bootserver;
+
    };
 
 typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
index d7f6df9f152719bdbc0a97a8556c9f2281b89c0a..0c3f778da87e881758b0493b58699e8f41e8ae8d 100644 (file)
@@ -926,6 +926,23 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
                     virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile);
                 }
             }
+
+            for (r = 0 ; r < ipdef->noptions ; r++) {
+                virBufferAsprintf(&configbuf, "dhcp-option=%u",
+                                  ipdef->options[r].number);
+                /* value is optional, and only needs quoting if it contains spaces */
+                if (ipdef->options[r].value) {
+                    const char *quote = "";
+
+                    if (strchr(ipdef->options[r].value, ' ') ||
+                        strchr(ipdef->options[r].value, '\\')) {
+                        quote = "\"";
+                    }
+                    virBufferAsprintf(&configbuf, ",%s%s%s",
+                                      quote, ipdef->options[r].value, quote);
+                }
+                virBufferAddLit(&configbuf, "\n");
+            }
         }
         ipdef = (ipdef == ipv6def) ? NULL : ipv6def;
     }
index beb714b134c3401281ad76e3713cf51537308406..ee41e2ae9907ffe0fb99cc65c8a18faed6a9b81b 100644 (file)
@@ -12,6 +12,11 @@ bind-dynamic
 interface=virbr0
 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=252,"\n"
+dhcp-option=253," leading and trailing spaces "
 dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
 dhcp-lease-max=253
 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
index eb71d9ea382e001fba20d9b6467e83dba1656822..22ec533de445adeafbabd18aa01cf33ab71a35d7 100644 (file)
@@ -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'/>
+      <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'>
index ed756630534aa3487c6d6977eba734a426a711a0..09c11d4957626779cad4a69abf29e4c8127d2331 100644 (file)
@@ -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>
index ecb6738694fdda5e4ee8877087cc9f1590aed810..77b353ddc5b40570438b9d97aa675ed005d22966 100644 (file)
@@ -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>
index b8a4d996fb394d9f853f4faf9ede0784e6df6a26..f3a4c6bcfb5af48e485884e47d37c6c3c1959e27 100644 (file)
@@ -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>
index e11c50b3eee0d4ca018ae81f2da4ade4f8dceaa3..2c97bd0a81e4449b4b60e095444fb9c2339c1b95 100644 (file)
@@ -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>