diff --git a/ChangeLog b/ChangeLog index cc42fa7ce1..837cae3670 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Jul 11 18:32:59 BST 2008 Daniel P. Berrange + + * src/bridge.c, src/bridge.h, src/qemu_conf.c, src/qemu_conf.h, + src/qemu_driver.c: Switch over to generic network APIs + Fri Jul 11 17:39:59 BST 2008 Daniel P. Berrange * src/test.c, src/test.h: Convert to the new domain XML apis diff --git a/src/bridge.c b/src/bridge.c index 15917b3254..9a77f2b981 100644 --- a/src/bridge.c +++ b/src/bridge.c @@ -116,60 +116,41 @@ brShutdown(brControl *ctl) /** * brAddBridge: * @ctl: bridge control pointer - * @nameOrFmt: the bridge name (or name template) - * @name: pointer to @maxlen bytes to store the bridge name - * @maxlen: size of @name array + * @name: the bridge name * - * This function register a new bridge, @nameOrFmt can be either - * a fixed name or a name template with '%d' for dynamic name allocation. - * in either case the final name for the bridge will be stored in @name. + * This function register a new bridge * * Returns 0 in case of success or an errno code in case of failure. */ #ifdef SIOCBRADDBR int brAddBridge(brControl *ctl, - const char *nameOrFmt, - char *name, - int maxlen) + char **name) { - int id, subst; - - if (!ctl || !ctl->fd || !nameOrFmt || !name) + if (!ctl || !ctl->fd || !name) return EINVAL; - if (maxlen >= BR_IFNAME_MAXLEN) - maxlen = BR_IFNAME_MAXLEN; - - subst = id = 0; - - if (strstr(nameOrFmt, "%d")) - subst = 1; - - do { - char try[BR_IFNAME_MAXLEN]; - int len; - - if (subst) { - len = snprintf(try, maxlen, nameOrFmt, id); - if (len >= maxlen) - return EADDRINUSE; - } else { - len = strlen(nameOrFmt); - if (len >= maxlen - 1) - return EINVAL; - - strncpy(try, nameOrFmt, len); - try[len] = '\0'; - } - - if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) { - strncpy(name, try, maxlen); + if (*name) { + if (ioctl(ctl->fd, SIOCBRADDBR, *name) == 0) return 0; - } + } else { + int id = 0; + do { + char try[50]; - id++; - } while (subst && id <= MAX_BRIDGE_ID); + snprintf(try, sizeof(try), "virbr%d", id); + + if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) { + if (!(*name = strdup(try))) { + ioctl(ctl->fd, SIOCBRDELBR, name); + return ENOMEM; + } + return 0; + } + + id++; + } while (id < MAX_BRIDGE_ID); + } return errno; } diff --git a/src/bridge.h b/src/bridge.h index cf444e0969..ac4559b4b1 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -47,9 +47,7 @@ int brInit (brControl **ctl); void brShutdown (brControl *ctl); int brAddBridge (brControl *ctl, - const char *nameOrFmt, - char *name, - int maxlen); + char **name); int brDeleteBridge (brControl *ctl, const char *name); diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 82797aa321..d0fc777581 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -180,32 +180,6 @@ struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver, return NULL; } -struct qemud_network *qemudFindNetworkByUUID(const struct qemud_driver *driver, - const unsigned char *uuid) { - struct qemud_network *network = driver->networks; - - while (network) { - if (!memcmp(network->def->uuid, uuid, VIR_UUID_BUFLEN)) - return network; - network = network->next; - } - - return NULL; -} - -struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver, - const char *name) { - struct qemud_network *network = driver->networks; - - while (network) { - if (STREQ(network->def->name, name)) - return network; - network = network->next; - } - - return NULL; -} - /* Free all memory associated with a struct qemud_vm object */ void qemudFreeVMDef(struct qemud_vm_def *def) { @@ -2254,7 +2228,7 @@ qemudNetworkIfaceConnect(virConnectPtr conn, struct qemud_vm_net_def *net, int vlan) { - struct qemud_network *network = NULL; + virNetworkObjPtr network = NULL; char *brname; char *ifname; char tapfdstr[4+3+32+7]; @@ -2263,18 +2237,18 @@ qemudNetworkIfaceConnect(virConnectPtr conn, int tapfd = -1; if (net->type == QEMUD_NET_NETWORK) { - if (!(network = qemudFindNetworkByName(driver, net->dst.network.name))) { + if (!(network = virNetworkFindByName(driver->networks, net->dst.network.name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("Network '%s' not found"), net->dst.network.name); goto error; - } else if (network->bridge[0] == '\0') { + } else if (network->def->bridge == NULL) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("Network '%s' not active"), net->dst.network.name); goto error; } - brname = network->bridge; + brname = network->def->bridge; if (net->dst.network.ifname[0] == '\0' || STRPREFIX(net->dst.network.ifname, "vnet") || strchr(net->dst.network.ifname, '%')) { @@ -3122,465 +3096,6 @@ qemudSaveVMDef(virConnectPtr conn, return qemudSaveConfig(conn, driver, vm, def); } -static int qemudSaveNetworkConfig(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def) { - char *xml; - int fd, ret = -1; - int towrite; - int err; - - if (!(xml = qemudGenerateNetworkXML(conn, driver, network, def))) { - return -1; - } - - if ((err = virFileMakePath(driver->networkConfigDir))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config directory %s: %s"), - driver->networkConfigDir, strerror(err)); - goto cleanup; - } - - if ((fd = open(network->configFile, - O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR )) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - towrite = strlen(xml); - if (safewrite(fd, xml, towrite) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot write config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - if (close(fd) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot save config file %s: %s"), - network->configFile, strerror(errno)); - goto cleanup; - } - - ret = 0; - - cleanup: - - VIR_FREE(xml); - - return ret; -} - -void qemudFreeNetworkDef(struct qemud_network_def *def) { - struct qemud_dhcp_range_def *range = def->ranges; - while (range) { - struct qemud_dhcp_range_def *next = range->next; - VIR_FREE(range); - range = next; - } - VIR_FREE(def); -} - -void qemudFreeNetwork(struct qemud_network *network) { - qemudFreeNetworkDef(network->def); - if (network->newDef) - qemudFreeNetworkDef(network->newDef); - VIR_FREE(network); -} - -static int qemudParseBridgeXML(struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - xmlChar *name, *stp, *delay; - - name = xmlGetProp(node, BAD_CAST "name"); - if (name != NULL) { - strncpy(def->bridge, (const char *)name, IF_NAMESIZE-1); - def->bridge[IF_NAMESIZE-1] = '\0'; - xmlFree(name); - name = NULL; - } - - stp = xmlGetProp(node, BAD_CAST "stp"); - if (stp != NULL) { - if (xmlStrEqual(stp, BAD_CAST "off")) { - def->disableSTP = 1; - } - xmlFree(stp); - stp = NULL; - } - - delay = xmlGetProp(node, BAD_CAST "delay"); - if (delay != NULL) { - def->forwardDelay = strtol((const char *)delay, NULL, 10); - xmlFree(delay); - delay = NULL; - } - - return 1; -} - -static int qemudParseDhcpRangesXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - - xmlNodePtr cur; - - cur = node->children; - while (cur != NULL) { - struct qemud_dhcp_range_def *range; - xmlChar *start, *end; - - if (cur->type != XML_ELEMENT_NODE || - !xmlStrEqual(cur->name, BAD_CAST "range")) { - cur = cur->next; - continue; - } - - if (VIR_ALLOC(range) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for range string")); - return 0; - } - - start = xmlGetProp(cur, BAD_CAST "start"); - end = xmlGetProp(cur, BAD_CAST "end"); - - if (start && start[0] && end && end[0]) { - strncpy(range->start, (const char *)start, BR_INET_ADDR_MAXLEN-1); - range->start[BR_INET_ADDR_MAXLEN-1] = '\0'; - - strncpy(range->end, (const char *)end, BR_INET_ADDR_MAXLEN-1); - range->end[BR_INET_ADDR_MAXLEN-1] = '\0'; - - range->next = def->ranges; - def->ranges = range; - def->nranges++; - } else { - VIR_FREE(range); - } - - xmlFree(start); - xmlFree(end); - - cur = cur->next; - } - - return 1; -} - -static int qemudParseInetXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network_def *def, - xmlNodePtr node) { - xmlChar *address, *netmask; - xmlNodePtr cur; - - address = xmlGetProp(node, BAD_CAST "address"); - if (address != NULL) { - strncpy(def->ipAddress, (const char *)address, BR_INET_ADDR_MAXLEN-1); - def->ipAddress[BR_INET_ADDR_MAXLEN-1] = '\0'; - xmlFree(address); - address = NULL; - } - - netmask = xmlGetProp(node, BAD_CAST "netmask"); - if (netmask != NULL) { - strncpy(def->netmask, (const char *)netmask, BR_INET_ADDR_MAXLEN-1); - def->netmask[BR_INET_ADDR_MAXLEN-1] = '\0'; - xmlFree(netmask); - netmask = NULL; - } - - if (def->ipAddress[0] && def->netmask[0]) { - struct in_addr inaddress, innetmask; - char *netaddr; - - inet_aton((const char*)def->ipAddress, &inaddress); - inet_aton((const char*)def->netmask, &innetmask); - - inaddress.s_addr &= innetmask.s_addr; - - netaddr = inet_ntoa(inaddress); - - snprintf(def->network,sizeof(def->network)-1, - "%s/%s", netaddr, (const char *)def->netmask); - } - - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE && - xmlStrEqual(cur->name, BAD_CAST "dhcp") && - !qemudParseDhcpRangesXML(conn, driver, def, cur)) - return 0; - cur = cur->next; - } - - return 1; -} - - -static struct qemud_network_def *qemudParseNetworkXML(virConnectPtr conn, - struct qemud_driver *driver, - xmlDocPtr xml) { - xmlNodePtr root = NULL; - xmlXPathContextPtr ctxt = NULL; - xmlXPathObjectPtr obj = NULL, tmp = NULL; - struct qemud_network_def *def; - - if (VIR_ALLOC(def) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for network_def string")); - return NULL; - } - - /* Prepare parser / xpath context */ - root = xmlDocGetRootElement(xml); - if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("incorrect root element")); - goto error; - } - - ctxt = xmlXPathNewContext(xml); - if (ctxt == NULL) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for xmlXPathContext string")); - goto error; - } - - - /* Extract network name */ - obj = xmlXPathEval(BAD_CAST "string(/network/name[1])", ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NAME, NULL); - goto error; - } - if (strlen((const char *)obj->stringval) >= (QEMUD_MAX_NAME_LEN-1)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("network name length too long")); - goto error; - } - strcpy(def->name, (const char *)obj->stringval); - xmlXPathFreeObject(obj); - - - /* Extract network uuid */ - obj = xmlXPathEval(BAD_CAST "string(/network/uuid[1])", ctxt); - if ((obj == NULL) || (obj->type != XPATH_STRING) || - (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - int err; - if ((err = virUUIDGenerate(def->uuid))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("Failed to generate UUID: %s"), strerror(err)); - goto error; - } - } else if (virUUIDParse((const char *)obj->stringval, def->uuid) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("malformed uuid element")); - goto error; - } - xmlXPathFreeObject(obj); - - /* Parse bridge information */ - obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - if (!qemudParseBridgeXML(driver, def, obj->nodesetval->nodeTab[0])) { - goto error; - } - } - xmlXPathFreeObject(obj); - - /* Parse IP information */ - obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt); - if ((obj != NULL) && (obj->type == XPATH_NODESET) && - (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) { - if (!qemudParseInetXML(conn, driver, def, obj->nodesetval->nodeTab[0])) { - goto error; - } - } - xmlXPathFreeObject(obj); - - /* IPv4 forwarding setup */ - obj = xmlXPathEval(BAD_CAST "count(/network/forward) > 0", ctxt); - if ((obj != NULL) && (obj->type == XPATH_BOOLEAN) && - obj->boolval) { - if (!def->ipAddress[0] || - !def->netmask[0]) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("Forwarding requested, but no IPv4 address/netmask provided")); - goto error; - } - - def->forward = 1; - - tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@mode)", ctxt); - if ((tmp != NULL) && (tmp->type == XPATH_STRING) && - (tmp->stringval != NULL) && (xmlStrEqual(tmp->stringval, BAD_CAST "route"))) { - def->forwardMode = QEMUD_NET_FORWARD_ROUTE; - } else { - def->forwardMode = QEMUD_NET_FORWARD_NAT; - } - xmlXPathFreeObject(tmp); - tmp = NULL; - - tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@dev)", ctxt); - if ((tmp != NULL) && (tmp->type == XPATH_STRING) && - (tmp->stringval != NULL) && (tmp->stringval[0] != 0)) { - int len; - if ((len = xmlStrlen(tmp->stringval)) >= (BR_IFNAME_MAXLEN-1)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("forward device name '%s' is too long"), - (char*)tmp->stringval); - goto error; - } - strcpy(def->forwardDev, (char*)tmp->stringval); - } else { - def->forwardDev[0] = '\0'; - } - xmlXPathFreeObject(tmp); - tmp = NULL; - } else { - def->forward = 0; - } - xmlXPathFreeObject(obj); - - xmlXPathFreeContext(ctxt); - - return def; - - error: - /* XXX free all the stuff in the qemud_network struct, or leave it upto - the caller ? */ - xmlXPathFreeObject(obj); - xmlXPathFreeObject(tmp); - xmlXPathFreeContext(ctxt); - qemudFreeNetworkDef(def); - return NULL; -} - -struct qemud_network_def * -qemudParseNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - const char *xmlStr, - const char *displayName) { - xmlDocPtr xml; - struct qemud_network_def *def; - - if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL, - XML_PARSE_NOENT | XML_PARSE_NONET | - XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_XML_ERROR, NULL); - return NULL; - } - - def = qemudParseNetworkXML(conn, driver, xml); - - xmlFreeDoc(xml); - - return def; -} - -struct qemud_network * -qemudAssignNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network_def *def) { - struct qemud_network *network; - - if ((network = qemudFindNetworkByName(driver, def->name))) { - if (!qemudIsActiveNetwork(network)) { - qemudFreeNetworkDef(network->def); - network->def = def; - } else { - if (network->newDef) - qemudFreeNetworkDef(network->newDef); - network->newDef = def; - } - - return network; - } - - if (VIR_ALLOC(network) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to allocate space for network string")); - return NULL; - } - - network->def = def; - network->next = driver->networks; - - driver->networks = network; - driver->ninactivenetworks++; - - return network; -} - -void -qemudRemoveInactiveNetwork(struct qemud_driver *driver, - struct qemud_network *network) -{ - struct qemud_network *prev = NULL, *curr; - - curr = driver->networks; - while (curr != network) { - prev = curr; - curr = curr->next; - } - - if (curr) { - if (prev) - prev->next = curr->next; - else - driver->networks = curr->next; - - driver->ninactivenetworks--; - } - - qemudFreeNetwork(network); -} - -int -qemudSaveNetworkDef(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def) { - - if (network->configFile[0] == '\0') { - int err; - - if ((err = virFileMakePath(driver->networkConfigDir))) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create config directory %s: %s"), - driver->networkConfigDir, strerror(err)); - return -1; - } - - if (virFileBuildPath(driver->networkConfigDir, def->name, ".xml", - network->configFile, PATH_MAX) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot construct config file path")); - return -1; - } - - if (virFileBuildPath(driver->networkAutostartDir, def->name, ".xml", - network->autostartLink, PATH_MAX) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot construct autostart link path")); - network->configFile[0] = '\0'; - return -1; - } - } - - return qemudSaveNetworkConfig(conn, driver, network, def); -} - static struct qemud_vm * qemudLoadConfig(struct qemud_driver *driver, @@ -3627,54 +3142,10 @@ qemudLoadConfig(struct qemud_driver *driver, return vm; } -static struct qemud_network * -qemudLoadNetworkConfig(struct qemud_driver *driver, - const char *file, - const char *path, - const char *xml, - const char *autostartLink) { - struct qemud_network_def *def; - struct qemud_network *network; - - if (!(def = qemudParseNetworkDef(NULL, driver, xml, file))) { - virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_WARN, _("Error parsing network config '%s' : %s"), - path, err->message); - return NULL; - } - - if (!virFileMatchesNameSuffix(file, def->name, ".xml")) { - qemudLog(QEMUD_WARN, - _("Network config filename '%s'" - " does not match network name '%s'"), - path, def->name); - qemudFreeNetworkDef(def); - return NULL; - } - - if (!(network = qemudAssignNetworkDef(NULL, driver, def))) { - qemudLog(QEMUD_WARN, - _("Failed to load network config '%s': out of memory"), path); - qemudFreeNetworkDef(def); - return NULL; - } - - strncpy(network->configFile, path, PATH_MAX); - network->configFile[PATH_MAX-1] = '\0'; - - strncpy(network->autostartLink, autostartLink, PATH_MAX); - network->autostartLink[PATH_MAX-1] = '\0'; - - network->autostart = virFileLinkPointsTo(network->autostartLink, network->configFile); - - return network; -} - static int qemudScanConfigDir(struct qemud_driver *driver, const char *configDir, - const char *autostartDir, - int isGuest) { + const char *autostartDir) { DIR *dir; struct dirent *entry; @@ -3713,10 +3184,7 @@ int qemudScanConfigDir(struct qemud_driver *driver, if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0) continue; - if (isGuest) - qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink); - else - qemudLoadNetworkConfig(driver, entry->d_name, path, xml, autostartLink); + qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink); VIR_FREE(xml); } @@ -3728,10 +3196,7 @@ int qemudScanConfigDir(struct qemud_driver *driver, /* Scan for all guest and network config files */ int qemudScanConfigs(struct qemud_driver *driver) { - if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir, 1) < 0) - return -1; - - if (qemudScanConfigDir(driver, driver->networkConfigDir, driver->networkAutostartDir, 0) < 0) + if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir) < 0) return -1; return 0; @@ -4137,83 +3602,6 @@ char *qemudGenerateXML(virConnectPtr conn, } -char *qemudGenerateNetworkXML(virConnectPtr conn, - struct qemud_driver *driver ATTRIBUTE_UNUSED, - struct qemud_network *network, - struct qemud_network_def *def) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - unsigned char *uuid; - char *tmp; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virBufferAddLit(&buf, "\n"); - - virBufferVSprintf(&buf, " %s\n", def->name); - - uuid = def->uuid; - virUUIDFormat(uuid, uuidstr); - virBufferVSprintf(&buf, " %s\n", uuidstr); - - if (def->forward) { - if (def->forwardDev[0]) { - virBufferVSprintf(&buf, " \n", - def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat")); - } else { - virBufferVSprintf(&buf, " \n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat")); - } - } - - virBufferAddLit(&buf, " bridge); - } else if (def->bridge[0]) { - virBufferVSprintf(&buf, " name='%s'", def->bridge); - } - virBufferVSprintf(&buf, " stp='%s' forwardDelay='%d' />\n", - def->disableSTP ? "off" : "on", - def->forwardDelay); - - if (def->ipAddress[0] || def->netmask[0]) { - virBufferAddLit(&buf, " ipAddress[0]) - virBufferVSprintf(&buf, " address='%s'", def->ipAddress); - - if (def->netmask[0]) - virBufferVSprintf(&buf, " netmask='%s'", def->netmask); - - virBufferAddLit(&buf, ">\n"); - - if (def->ranges) { - struct qemud_dhcp_range_def *range = def->ranges; - virBufferAddLit(&buf, " \n"); - while (range) { - virBufferVSprintf(&buf, " \n", - range->start, range->end); - range = range->next; - } - virBufferAddLit(&buf, " \n"); - } - - virBufferAddLit(&buf, " \n"); - } - - virBufferAddLit(&buf, "\n"); - - if (virBufferError(&buf)) - goto no_memory; - - return virBufferContentAndReset(&buf); - - no_memory: - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, - "%s", _("failed to generate XML: out of memory")); - tmp = virBufferContentAndReset(&buf); - VIR_FREE(tmp); - return NULL; -} - - int qemudDeleteConfig(virConnectPtr conn, struct qemud_driver *driver ATTRIBUTE_UNUSED, const char *configFile, diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 433650a54c..209330b08c 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -32,6 +32,7 @@ #include "bridge.h" #include "iptables.h" #include "capabilities.h" +#include "network_conf.h" #include #include @@ -96,12 +97,6 @@ enum qemud_vm_net_type { QEMUD_NET_BRIDGE, }; -/* 2 possible types of forwarding */ -enum qemud_vm_net_forward_type { - QEMUD_NET_FORWARD_NAT, - QEMUD_NET_FORWARD_ROUTE, -}; - #define QEMUD_MAX_NAME_LEN 50 #define QEMUD_MAX_XML_LEN 4096 #define QEMUD_MAX_ERROR_LEN 1024 @@ -349,53 +344,6 @@ struct qemud_vm { struct qemud_vm *next; }; -/* Store start and end addresses of a dhcp range */ -struct qemud_dhcp_range_def { - char start[BR_INET_ADDR_MAXLEN]; - char end[BR_INET_ADDR_MAXLEN]; - - struct qemud_dhcp_range_def *next; -}; - -/* Virtual Network main configuration */ -struct qemud_network_def { - unsigned char uuid[VIR_UUID_BUFLEN]; - char name[QEMUD_MAX_NAME_LEN]; - - char bridge[BR_IFNAME_MAXLEN]; - int disableSTP; - int forwardDelay; - - int forward; - int forwardMode; /* From qemud_vm_net_forward_type */ - char forwardDev[BR_IFNAME_MAXLEN]; - - char ipAddress[BR_INET_ADDR_MAXLEN]; - char netmask[BR_INET_ADDR_MAXLEN]; - char network[BR_INET_ADDR_MAXLEN+BR_INET_ADDR_MAXLEN+1]; - - int nranges; - struct qemud_dhcp_range_def *ranges; -}; - -/* Virtual Network runtime state */ -struct qemud_network { - char configFile[PATH_MAX]; - char autostartLink[PATH_MAX]; - - struct qemud_network_def *def; /* The current definition */ - struct qemud_network_def *newDef; /* New definition to activate at shutdown */ - - char bridge[BR_IFNAME_MAXLEN]; - int dnsmasqPid; - - unsigned int active : 1; - unsigned int autostart : 1; - - struct qemud_network *next; -}; - - /* Main driver state */ struct qemud_driver { int qemuVersion; @@ -403,9 +351,9 @@ struct qemud_driver { int ninactivevms; struct qemud_vm *vms; int nextvmid; - int nactivenetworks; - int ninactivenetworks; - struct qemud_network *networks; + + virNetworkObjPtr networks; + brControl *brctl; iptablesContext *iptables; char *configDir; @@ -428,12 +376,6 @@ qemudIsActiveVM(const struct qemud_vm *vm) return vm->id != -1; } -static inline int -qemudIsActiveNetwork(const struct qemud_network *network) -{ - return network->active; -} - void qemudReportError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net, @@ -451,11 +393,6 @@ struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver, struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver, const char *name); -struct qemud_network *qemudFindNetworkByUUID(const struct qemud_driver *driver, - const unsigned char *uuid); -struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver, - const char *name); - virCapsPtr qemudCapsInit (void); int qemudExtractVersion (virConnectPtr conn, @@ -501,30 +438,6 @@ char * qemudGenerateXML (virConnectPtr conn, struct qemud_vm_def *def, int live); -void qemudFreeNetworkDef (struct qemud_network_def *def); -void qemudFreeNetwork (struct qemud_network *network); - -struct qemud_network * - qemudAssignNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network_def *def); -void qemudRemoveInactiveNetwork (struct qemud_driver *driver, - struct qemud_network *network); - -struct qemud_network_def * - qemudParseNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - const char *xmlStr, - const char *displayName); -int qemudSaveNetworkDef (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def); -char * qemudGenerateNetworkXML (virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_network *network, - struct qemud_network_def *def); - const char *qemudVirtTypeToString (int type); #endif /* WITH_QEMU */ diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 8d8fcd64b3..26853d1f20 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -120,11 +120,11 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, static int qemudStartNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network); + virNetworkObjPtr network); static int qemudShutdownNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network); + virNetworkObjPtr network); static int qemudDomainGetMaxVcpus(virDomainPtr dom); static int qemudMonitorCommand (const struct qemud_driver *driver, @@ -137,15 +137,15 @@ static struct qemud_driver *qemu_driver = NULL; static void qemudAutostartConfigs(struct qemud_driver *driver) { - struct qemud_network *network; + virNetworkObjPtr network; struct qemud_vm *vm; network = driver->networks; while (network != NULL) { - struct qemud_network *next = network->next; + virNetworkObjPtr next = network->next; if (network->autostart && - !qemudIsActiveNetwork(network) && + !virNetworkIsActive(network) && qemudStartNetworkDaemon(NULL, driver, network) < 0) { virErrorPtr err = virGetLastError(); qemudLog(QEMUD_ERR, _("Failed to autostart network '%s': %s"), @@ -247,6 +247,13 @@ qemudStartup(void) { qemudShutdown(); return -1; } + if (virNetworkLoadAllConfigs(NULL, + &qemu_driver->networks, + qemu_driver->networkConfigDir, + qemu_driver->networkAutostartDir) < 0) { + qemudShutdown(); + return -1; + } qemudAutostartConfigs(qemu_driver); return 0; @@ -273,6 +280,10 @@ qemudStartup(void) { static int qemudReload(void) { qemudScanConfigs(qemu_driver); + virNetworkLoadAllConfigs(NULL, + &qemu_driver->networks, + qemu_driver->networkConfigDir, + qemu_driver->networkAutostartDir); if (qemu_driver->iptables) { qemudLog(QEMUD_INFO, @@ -295,11 +306,14 @@ qemudReload(void) { */ static int qemudActive(void) { - /* If we've any active networks or guests, then we - * mark this driver as active - */ - if (qemu_driver->nactivenetworks && - qemu_driver->nactivevms) + virNetworkObjPtr net = qemu_driver->networks; + while (net) { + if (net->active) + return 1; + net = net->next; + } + + if (qemu_driver->nactivevms) return 1; /* Otherwise we're happy to deal with a shutdown */ @@ -314,7 +328,7 @@ qemudActive(void) { static int qemudShutdown(void) { struct qemud_vm *vm; - struct qemud_network *network; + virNetworkObjPtr network; if (!qemu_driver) return -1; @@ -346,8 +360,8 @@ qemudShutdown(void) { /* shutdown active networks */ network = qemu_driver->networks; while (network) { - struct qemud_network *next = network->next; - if (qemudIsActiveNetwork(network)) + virNetworkObjPtr next = network->next; + if (virNetworkIsActive(network)) qemudShutdownNetworkDaemon(NULL, qemu_driver, network); network = next; } @@ -355,13 +369,11 @@ qemudShutdown(void) { /* free inactive networks */ network = qemu_driver->networks; while (network) { - struct qemud_network *next = network->next; - qemudFreeNetwork(network); + virNetworkObjPtr next = network->next; + virNetworkObjFree(network); network = next; } qemu_driver->networks = NULL; - qemu_driver->nactivenetworks = 0; - qemu_driver->ninactivenetworks = 0; VIR_FREE(qemu_driver->configDir); VIR_FREE(qemu_driver->autostartDir); @@ -1043,11 +1055,10 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, struct qemud_vm * static int qemudBuildDnsmasqArgv(virConnectPtr conn, - struct qemud_network *network, + virNetworkObjPtr network, char ***argv) { - int i, len; + int i, len, r; char buf[PATH_MAX]; - struct qemud_dhcp_range_def *range; len = 1 + /* dnsmasq */ @@ -1113,15 +1124,13 @@ qemudBuildDnsmasqArgv(virConnectPtr conn, LOCAL_STATE_DIR, network->def->name); APPEND_ARG(*argv, i++, buf); - range = network->def->ranges; - while (range) { + for (r = 0 ; r < network->def->nranges ; r++) { snprintf(buf, sizeof(buf), "%s,%s", - range->start, range->end); + network->def->ranges[r].start, + network->def->ranges[r].end); APPEND_ARG(*argv, i++, "--dhcp-range"); APPEND_ARG(*argv, i++, buf); - - range = range->next; } #undef APPEND_ARG @@ -1142,12 +1151,12 @@ qemudBuildDnsmasqArgv(virConnectPtr conn, static int dhcpStartDhcpDaemon(virConnectPtr conn, - struct qemud_network *network) + virNetworkObjPtr network) { char **argv; int ret, i; - if (network->def->ipAddress[0] == '\0') { + if (network->def->ipAddress == NULL) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("cannot start dhcp daemon without IP address for server")); return -1; @@ -1169,27 +1178,27 @@ dhcpStartDhcpDaemon(virConnectPtr conn, static int qemudAddMasqueradingIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; /* allow forwarding packets from the bridge interface */ if ((err = iptablesAddForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow forwarding from '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto masqerr1; } /* allow forwarding packets to the bridge interface if they are part of an existing connection */ if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow forwarding to '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto masqerr2; } @@ -1208,12 +1217,12 @@ qemudAddMasqueradingIptablesRules(virConnectPtr conn, masqerr3: iptablesRemoveForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); masqerr2: iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); masqerr1: return 0; @@ -1222,27 +1231,27 @@ qemudAddMasqueradingIptablesRules(virConnectPtr conn, static int qemudAddRoutingIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; /* allow routing packets from the bridge interface */ if ((err = iptablesAddForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow routing from '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto routeerr1; } /* allow routing packets to the bridge interface */ if ((err = iptablesAddForwardAllowIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow routing to '%s' : %s\n"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto routeerr2; } @@ -1252,7 +1261,7 @@ qemudAddRoutingIptablesRules(virConnectPtr conn, routeerr2: iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); routeerr1: return 0; @@ -1261,7 +1270,7 @@ qemudAddRoutingIptablesRules(virConnectPtr conn, static int qemudAddIptablesRules(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; if (!driver->iptables && !(driver->iptables = iptablesContextNew())) { @@ -1272,71 +1281,69 @@ qemudAddIptablesRules(virConnectPtr conn, /* allow DHCP requests through to dnsmasq */ - if ((err = iptablesAddTcpInput(driver->iptables, network->bridge, 67))) { + if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 67))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err1; } - if ((err = iptablesAddUdpInput(driver->iptables, network->bridge, 67))) { + if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 67))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err2; } /* allow DNS requests through to dnsmasq */ - if ((err = iptablesAddTcpInput(driver->iptables, network->bridge, 53))) { + if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 53))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DNS requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err3; } - if ((err = iptablesAddUdpInput(driver->iptables, network->bridge, 53))) { + if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 53))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow DNS requests from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err4; } /* Catch all rules to block forwarding to/from bridges */ - if ((err = iptablesAddForwardRejectOut(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardRejectOut(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to block outbound traffic from '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err5; } - if ((err = iptablesAddForwardRejectIn(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardRejectIn(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to block inbound traffic to '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err6; } /* Allow traffic between guests on the same bridge */ - if ((err = iptablesAddForwardAllowCross(driver->iptables, network->bridge))) { + if ((err = iptablesAddForwardAllowCross(driver->iptables, network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err7; } - if (network->def->forward) { - /* If masquerading is enabled, set up the rules*/ - if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT && - !qemudAddMasqueradingIptablesRules(conn, driver, network)) - goto err8; - /* else if routing is enabled, set up the rules*/ - else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE && - !qemudAddRoutingIptablesRules(conn, driver, network)) - goto err8; - } + /* If masquerading is enabled, set up the rules*/ + if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT && + !qemudAddMasqueradingIptablesRules(conn, driver, network)) + goto err8; + /* else if routing is enabled, set up the rules*/ + else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE && + !qemudAddRoutingIptablesRules(conn, driver, network)) + goto err8; iptablesSaveRules(driver->iptables); @@ -1344,56 +1351,56 @@ qemudAddIptablesRules(virConnectPtr conn, err8: iptablesRemoveForwardAllowCross(driver->iptables, - network->bridge); + network->def->bridge); err7: iptablesRemoveForwardRejectIn(driver->iptables, - network->bridge); + network->def->bridge); err6: iptablesRemoveForwardRejectOut(driver->iptables, - network->bridge); + network->def->bridge); err5: - iptablesRemoveUdpInput(driver->iptables, network->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); err4: - iptablesRemoveTcpInput(driver->iptables, network->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); err3: - iptablesRemoveUdpInput(driver->iptables, network->bridge, 67); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); err2: - iptablesRemoveTcpInput(driver->iptables, network->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); err1: return 0; } static void qemudRemoveIptablesRules(struct qemud_driver *driver, - struct qemud_network *network) { - if (network->def->forward) { + virNetworkObjPtr network) { + if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) { iptablesRemoveForwardMasquerade(driver->iptables, network->def->network, network->def->forwardDev); - if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT) + if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) iptablesRemoveForwardAllowRelatedIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); - else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE) + else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) iptablesRemoveForwardAllowIn(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); iptablesRemoveForwardAllowOut(driver->iptables, network->def->network, - network->bridge, + network->def->bridge, network->def->forwardDev); } - iptablesRemoveForwardAllowCross(driver->iptables, network->bridge); - iptablesRemoveForwardRejectIn(driver->iptables, network->bridge); - iptablesRemoveForwardRejectOut(driver->iptables, network->bridge); - iptablesRemoveUdpInput(driver->iptables, network->bridge, 53); - iptablesRemoveTcpInput(driver->iptables, network->bridge, 53); - iptablesRemoveUdpInput(driver->iptables, network->bridge, 67); - iptablesRemoveTcpInput(driver->iptables, network->bridge, 67); + iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); iptablesSaveRules(driver->iptables); } @@ -1419,11 +1426,10 @@ qemudEnableIpForwarding(void) static int qemudStartNetworkDaemon(virConnectPtr conn, struct qemud_driver *driver, - struct qemud_network *network) { - const char *name; + virNetworkObjPtr network) { int err; - if (qemudIsActiveNetwork(network)) { + if (virNetworkIsActive(network)) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("network is already active")); return -1; @@ -1435,94 +1441,85 @@ static int qemudStartNetworkDaemon(virConnectPtr conn, return -1; } - if (network->def->bridge[0] == '\0' || - strchr(network->def->bridge, '%')) { - name = "vnet%d"; - } else { - name = network->def->bridge; - } - - if ((err = brAddBridge(driver->brctl, name, network->bridge, sizeof(network->bridge)))) { + if ((err = brAddBridge(driver->brctl, &network->def->bridge))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot create bridge '%s' : %s"), name, strerror(err)); + _("cannot create bridge '%s' : %s"), + network->def->bridge, strerror(err)); return -1; } - if (network->def->forwardDelay && - (err = brSetForwardDelay(driver->brctl, network->bridge, network->def->forwardDelay))) { + if (network->def->delay && + (err = brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("failed to set bridge forward delay to %d"), - network->def->forwardDelay); + _("failed to set bridge forward delay to %ld"), + network->def->delay); goto err_delbr; } - if ((err = brSetEnableSTP(driver->brctl, network->bridge, network->def->disableSTP ? 0 : 1))) { + if ((err = brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to set bridge STP to %s"), - network->def->disableSTP ? "off" : "on"); + network->def->stp ? "on" : "off"); goto err_delbr; } - if (network->def->ipAddress[0] && - (err = brSetInetAddress(driver->brctl, network->bridge, network->def->ipAddress))) { + if (network->def->ipAddress && + (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot set IP address on bridge '%s' to '%s' : %s"), - network->bridge, network->def->ipAddress, strerror(err)); + network->def->bridge, network->def->ipAddress, strerror(err)); goto err_delbr; } - if (network->def->netmask[0] && - (err = brSetInetNetmask(driver->brctl, network->bridge, network->def->netmask))) { + if (network->def->netmask && + (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot set netmask on bridge '%s' to '%s' : %s"), - network->bridge, network->def->netmask, strerror(err)); + network->def->bridge, network->def->netmask, strerror(err)); goto err_delbr; } - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 1))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to bring the bridge '%s' up : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); goto err_delbr; } if (!qemudAddIptablesRules(conn, driver, network)) goto err_delbr1; - if (network->def->forward && + if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE && !qemudEnableIpForwarding()) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("failed to enable IP forwarding : %s"), strerror(err)); goto err_delbr2; } - if (network->def->ranges && + if (network->def->nranges && dhcpStartDhcpDaemon(conn, network) < 0) goto err_delbr2; network->active = 1; - driver->ninactivenetworks--; - driver->nactivenetworks++; - return 0; err_delbr2: qemudRemoveIptablesRules(driver, network); err_delbr1: - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } err_delbr: - if ((err = brDeleteBridge(driver->brctl, network->bridge))) { + if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } return -1; @@ -1531,12 +1528,12 @@ static int qemudStartNetworkDaemon(virConnectPtr conn, static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, struct qemud_driver *driver, - struct qemud_network *network) { + virNetworkObjPtr network) { int err; qemudLog(QEMUD_INFO, _("Shutting down network '%s'"), network->def->name); - if (!qemudIsActiveNetwork(network)) + if (!virNetworkIsActive(network)) return 0; if (network->dnsmasqPid > 0) @@ -1544,15 +1541,15 @@ static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, qemudRemoveIptablesRules(driver, network); - if (network->def->ipAddress[0] && - (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { + if (network->def->ipAddress && + (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } - if ((err = brDeleteBridge(driver->brctl, network->bridge))) { + if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"), - network->bridge, strerror(err)); + network->def->bridge, strerror(err)); } if (network->dnsmasqPid > 0 && @@ -1563,21 +1560,18 @@ static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, "%s", _("Got unexpected pid for dnsmasq")); } - network->bridge[0] = '\0'; network->dnsmasqPid = -1; network->active = 0; if (network->newDef) { - qemudFreeNetworkDef(network->def); + virNetworkDefFree(network->def); network->def = network->newDef; network->newDef = NULL; } - driver->nactivenetworks--; - driver->ninactivenetworks++; - - if (!network->configFile[0]) - qemudRemoveInactiveNetwork(driver, network); + if (!network->configFile) + virNetworkRemoveInactive(&driver->networks, + network); return 0; } @@ -3294,9 +3288,9 @@ done: } static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED, - const unsigned char *uuid) { + const unsigned char *uuid) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, uuid); virNetworkPtr net; if (!network) { @@ -3309,9 +3303,9 @@ static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSE return net; } static virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED, - const char *name) { + const char *name) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByName(driver, name); + virNetworkObjPtr network = virNetworkFindByName(driver->networks, name); virNetworkPtr net; if (!network) { @@ -3341,16 +3335,23 @@ static int qemudCloseNetwork(virConnectPtr conn) { } static int qemudNumNetworks(virConnectPtr conn) { + int nactive = 0; struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - return driver->nactivenetworks; + virNetworkObjPtr net = driver->networks; + while (net) { + if (virNetworkIsActive(net)) + nactive++; + net = net->next; + } + return nactive; } static int qemudListNetworks(virConnectPtr conn, char **const names, int nnames) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = driver->networks; + virNetworkObjPtr network = driver->networks; int got = 0, i; while (network && got < nnames) { - if (qemudIsActiveNetwork(network)) { + if (virNetworkIsActive(network)) { if (!(names[got] = strdup(network->def->name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for VM name string")); @@ -3369,16 +3370,23 @@ static int qemudListNetworks(virConnectPtr conn, char **const names, int nnames) } static int qemudNumDefinedNetworks(virConnectPtr conn) { + int ninactive = 0; struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - return driver->ninactivenetworks; + virNetworkObjPtr net = driver->networks; + while (net) { + if (!virNetworkIsActive(net)) + ninactive++; + net = net->next; + } + return ninactive; } static int qemudListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network *network = driver->networks; + virNetworkObjPtr network = driver->networks; int got = 0, i; while (network && got < nnames) { - if (!qemudIsActiveNetwork(network)) { + if (!virNetworkIsActive(network)) { if (!(names[got] = strdup(network->def->name))) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for VM name string")); @@ -3398,20 +3406,23 @@ static int qemudListDefinedNetworks(virConnectPtr conn, char **const names, int static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network_def *def; - struct qemud_network *network; + virNetworkDefPtr def; + virNetworkObjPtr network; virNetworkPtr net; - if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL))) + if (!(def = virNetworkDefParseString(conn, xml))) return NULL; - if (!(network = qemudAssignNetworkDef(conn, driver, def))) { - qemudFreeNetworkDef(def); + if (!(network = virNetworkAssignDef(conn, + &driver->networks, + def))) { + virNetworkDefFree(def); return NULL; } if (qemudStartNetworkDaemon(conn, driver, network) < 0) { - qemudRemoveInactiveNetwork(driver, network); + virNetworkRemoveInactive(&driver->networks, + network); return NULL; } @@ -3421,30 +3432,34 @@ static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) { static virNetworkPtr qemudNetworkDefine(virConnectPtr conn, const char *xml) { struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData; - struct qemud_network_def *def; - struct qemud_network *network; - virNetworkPtr net; + virNetworkDefPtr def; + virNetworkObjPtr network; - if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL))) + if (!(def = virNetworkDefParseString(conn, xml))) return NULL; - if (!(network = qemudAssignNetworkDef(conn, driver, def))) { - qemudFreeNetworkDef(def); + if (!(network = virNetworkAssignDef(conn, + &driver->networks, + def))) { + virNetworkDefFree(def); return NULL; } - if (qemudSaveNetworkDef(conn, driver, network, def) < 0) { - qemudRemoveInactiveNetwork(driver, network); + if (virNetworkSaveConfig(conn, + driver->networkConfigDir, + driver->networkAutostartDir, + network) < 0) { + virNetworkRemoveInactive(&driver->networks, + network); return NULL; } - net = virGetNetwork(conn, network->def->name, network->def->uuid); - return net; + return virGetNetwork(conn, network->def->name, network->def->uuid); } static int qemudNetworkUndefine(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN, @@ -3452,24 +3467,24 @@ static int qemudNetworkUndefine(virNetworkPtr net) { return -1; } - if (qemudDeleteConfig(net->conn, driver, network->configFile, network->def->name) < 0) + if (virNetworkIsActive(network)) { + qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR, + "%s", _("network is still active")); + return -1; + } + + if (virNetworkDeleteConfig(net->conn, network) < 0) return -1; - if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) - qemudLog(QEMUD_WARN, _("Failed to delete autostart link '%s': %s"), - network->autostartLink, strerror(errno)); - - network->configFile[0] = '\0'; - network->autostartLink[0] = '\0'; - - qemudRemoveInactiveNetwork(driver, network); + virNetworkRemoveInactive(&driver->networks, + network); return 0; } static int qemudNetworkStart(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3482,7 +3497,7 @@ static int qemudNetworkStart(virNetworkPtr net) { static int qemudNetworkDestroy(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); int ret; if (!network) { @@ -3498,7 +3513,7 @@ static int qemudNetworkDestroy(virNetworkPtr net) { static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3506,12 +3521,12 @@ static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) return NULL; } - return qemudGenerateNetworkXML(net->conn, driver, network, network->def); + return virNetworkDefFormat(net->conn, network->def); } static char *qemudNetworkGetBridgeName(virNetworkPtr net) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); char *bridge; if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3519,7 +3534,7 @@ static char *qemudNetworkGetBridgeName(virNetworkPtr net) { return NULL; } - bridge = strdup(network->bridge); + bridge = strdup(network->def->bridge); if (!bridge) { qemudReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY, "%s", _("failed to allocate space for network bridge string")); @@ -3531,7 +3546,7 @@ static char *qemudNetworkGetBridgeName(virNetworkPtr net) { static int qemudNetworkGetAutostart(virNetworkPtr net, int *autostart) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK, @@ -3547,7 +3562,7 @@ static int qemudNetworkGetAutostart(virNetworkPtr net, static int qemudNetworkSetAutostart(virNetworkPtr net, int autostart) { struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData; - struct qemud_network *network = qemudFindNetworkByUUID(driver, net->uuid); + virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid); if (!network) { qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,