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, " \n"); for (i = 0 ; i < def->nranges ; i++) virBufferVSprintf(&buf, " \n", def->ranges[i].start, def->ranges[i].end); + for (i = 0 ; i < def->nhosts ; i++) { + virBufferAddLit(&buf, " 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, " \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;