[libvirt] [PATCH] "static" ip address

Daniel Veillard veillard at redhat.com
Tue Aug 12 19:39:28 UTC 2008


On Tue, Aug 12, 2008 at 06:49:59PM +0200, Olivier Deckmyn wrote:
> On Tue, Aug 12, 2008 at 5:17 PM, Daniel Veillard <veillard at redhat.com>wrote:
> >
> > That said I'm working on a new version of the patch which would be adequate
[...]
> Once again, if I can do anything to help, I will.

  Then please try the following patch, tell me if it works for you, I didn't
really tried it yet and parallel testing would help.
  The things to test are:
    - no crash
    - the network definition is correctly parsed
    - virsh network define and dump still work
    - and IP as provided by dnsmasq as suggested
in case of mismatches try to grab the full command line used by libvirtd
for dnsmasq and report it in parallel of the XML file used,

  thanks in advance,

Daniel

-- 
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
veillard at redhat.com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/
-------------- next part --------------
Index: src/network_conf.c
===================================================================
RCS file: /data/cvs/libxen/src/network_conf.c,v
retrieving revision 1.6
diff -u -r1.6 network_conf.c
--- src/network_conf.c	12 Aug 2008 08:25:48 -0000	1.6
+++ src/network_conf.c	12 Aug 2008 19:32:48 -0000
@@ -40,6 +40,7 @@
 #include "uuid.h"
 #include "util.h"
 #include "buf.h"
+#include "c-ctype.h"
 
 VIR_ENUM_DECL(virNetworkForward)
 
@@ -115,6 +116,13 @@
     }
     VIR_FREE(def->ranges);
 
+    for (i = 0 ; i < def->nhosts && def->hosts ; i++) {
+        VIR_FREE(def->hosts[i].mac);
+        VIR_FREE(def->hosts[i].ip);
+        VIR_FREE(def->hosts[i].host);
+    }
+    VIR_FREE(def->hosts);
+
     VIR_FREE(def);
 }
 
@@ -197,33 +205,82 @@
 
     cur = node->children;
     while (cur != NULL) {
-        xmlChar *start, *end;
-
-        if (cur->type != XML_ELEMENT_NODE ||
-            !xmlStrEqual(cur->name, BAD_CAST "range")) {
-            cur = cur->next;
-            continue;
-        }
-
-        if (!(start = xmlGetProp(cur, BAD_CAST "start"))) {
-            cur = cur->next;
-            continue;
-        }
-        if (!(end = xmlGetProp(cur, BAD_CAST "end"))) {
-            cur = cur->next;
-            xmlFree(start);
-            continue;
-        }
+        if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "range")) {
+            xmlChar *start, *end;
+
+            if (!(start = xmlGetProp(cur, BAD_CAST "start"))) {
+                cur = cur->next;
+                continue;
+            }
+            if (!(end = xmlGetProp(cur, BAD_CAST "end"))) {
+                cur = cur->next;
+                xmlFree(start);
+                continue;
+            }
 
-        if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
-            xmlFree(start);
-            xmlFree(end);
-            virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
-            return -1;
+            if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
+                xmlFree(start);
+                xmlFree(end);
+                virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+                return -1;
+            }
+            def->ranges[def->nranges].start = (char *)start;
+            def->ranges[def->nranges].end = (char *)end;
+            def->nranges++;
+        } else if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "hosts")) {
+            xmlChar *mac, *host, *ip;
+            unsigned char addr[6];
+            struct in_addr inaddress;
+
+            mac = xmlGetProp(cur, BAD_CAST "mac");
+            if ((mac != NULL) &&
+                (virParseMacAddr((const char *) mac, &addr[0]) != 0)) {
+                virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                      _("cannot parse MAC address '%s'"),
+                                      mac);
+                VIR_FREE(mac);
+            }
+            host = xmlGetProp(cur, BAD_CAST "host");
+            if ((host != NULL) && (!c_isalpha(host[0]))) {
+                virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                      _("cannot use host address '%s'"),
+                                      host);
+                VIR_FREE(host);
+            }
+            /*
+             * You need at least one MAC address or one host name
+             */
+            if ((mac == NULL) && (host == NULL)) {
+                VIR_FREE(mac);
+                VIR_FREE(host);
+                cur = cur->next;
+                continue;
+            }
+            ip = xmlGetProp(cur, BAD_CAST "ip");
+            if (inet_pton(AF_INET, (const char *) ip, &inaddress) <= 0) {
+                virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                      _("cannot parse IP address '%s'"),
+                                      ip);
+                VIR_FREE(ip);
+                VIR_FREE(mac);
+                VIR_FREE(host);
+                cur = cur->next;
+                continue;
+            }
+            if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) {
+                VIR_FREE(ip);
+                VIR_FREE(mac);
+                VIR_FREE(host);
+                virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+                return -1;
+            }
+            def->hosts[def->nhosts].mac = (char *)mac;
+            def->hosts[def->nhosts].host = (char *)host;
+            def->hosts[def->nhosts].ip = (char *)ip;
+            def->nhosts++;
         }
-        def->ranges[def->nranges].start = (char *)start;
-        def->ranges[def->nranges].end = (char *)end;
-        def->nranges++;
 
         cur = cur->next;
     }
@@ -524,12 +581,22 @@
 
         virBufferAddLit(&buf, ">\n");
 
-        if (def->nranges) {
+        if ((def->nranges || def->nhosts)) {
             int i;
             virBufferAddLit(&buf, "    <dhcp>\n");
             for (i = 0 ; i < def->nranges ; i++)
                 virBufferVSprintf(&buf, "      <range start='%s' end='%s' />\n",
                                   def->ranges[i].start, def->ranges[i].end);
+            for (i = 0 ; i < def->nhosts ; i++) {
+                virBufferAddLit(&buf, "      <host ");
+                if (def->hosts[i].mac)
+                    virBufferVSprintf(&buf, "mac='%s' ", def->hosts[i].mac);
+                if (def->hosts[i].host)
+                    virBufferVSprintf(&buf, "host='%s' ", def->hosts[i].host);
+                if (def->hosts[i].ip)
+                    virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip);
+                virBufferAddLit(&buf, "/>");
+            }
             virBufferAddLit(&buf, "    </dhcp>\n");
         }
 
Index: src/network_conf.h
===================================================================
RCS file: /data/cvs/libxen/src/network_conf.h,v
retrieving revision 1.1
diff -u -r1.1 network_conf.h
--- src/network_conf.h	11 Jul 2008 10:48:34 -0000	1.1
+++ src/network_conf.h	12 Aug 2008 19:32:48 -0000
@@ -42,6 +42,14 @@
     char *end;
 };
 
+typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef;
+typedef virNetworkDHCPHostDef *virNetworkDHCPHostDefPtr;
+struct _virNetworkDHCPHostDef {
+    char *mac;
+    char *host;
+    char *ip;
+};
+
 typedef struct _virNetworkDef virNetworkDef;
 typedef virNetworkDef *virNetworkDefPtr;
 struct _virNetworkDef {
@@ -61,6 +69,9 @@
 
     unsigned int nranges;        /* Zero or more dhcp ranges */
     virNetworkDHCPRangeDefPtr ranges;
+
+    unsigned int nhosts;         /* Zero or more dhcp hosts */
+    virNetworkDHCPHostDefPtr hosts;
 };
 
 typedef struct _virNetworkObj virNetworkObj;
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libxen/src/qemu_driver.c,v
retrieving revision 1.105
diff -u -r1.105 qemu_driver.c
--- src/qemu_driver.c	12 Aug 2008 08:38:22 -0000	1.105
+++ src/qemu_driver.c	12 Aug 2008 19:32:48 -0000
@@ -1103,6 +1103,8 @@
         2 + /* --listen-address 10.0.0.1 */
         1 + /* --dhcp-leasefile=path */
         (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
+        /*  --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
+        (2 * network->def->nhosts) +
         1;  /* NULL */
 
     if (VIR_ALLOC_N(*argv, len) < 0)
@@ -1164,6 +1166,24 @@
         APPEND_ARG(*argv, i++, buf);
     }
 
+    for (r = 0 ; r < network->def->nhosts ; r++) {
+        virNetworkDHCPHostDefPtr host = &(network->def->hosts[r]);
+        if ((host->mac) && (host->host)) {
+            snprintf(buf, sizeof(buf), "%s,%s,%s",
+                     host->mac, host->host, host->ip);
+        } else if (host->mac) {
+            snprintf(buf, sizeof(buf), "%s,%s",
+                     host->mac, host->ip);
+        } else if (host->host) {
+            snprintf(buf, sizeof(buf), "%s,%s",
+                     host->host, host->ip);
+        } else
+            continue;
+
+        APPEND_ARG(*argv, i++, "--dhcp-host");
+        APPEND_ARG(*argv, i++, buf);
+    }
+
 #undef APPEND_ARG
 
     return 0;


More information about the libvir-list mailing list