mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
Switch QEMU driver over to generic network APIs
This commit is contained in:
parent
d78c0a6800
commit
381fa1fc46
@ -1,3 +1,8 @@
|
||||
Fri Jul 11 18:32:59 BST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* 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 <berrange@redhat.com>
|
||||
|
||||
* src/test.c, src/test.h: Convert to the new domain XML apis
|
||||
|
65
src/bridge.c
65
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
626
src/qemu_conf.c
626
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, "<network>\n");
|
||||
|
||||
virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
|
||||
|
||||
uuid = def->uuid;
|
||||
virUUIDFormat(uuid, uuidstr);
|
||||
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
|
||||
|
||||
if (def->forward) {
|
||||
if (def->forwardDev[0]) {
|
||||
virBufferVSprintf(&buf, " <forward dev='%s' mode='%s'/>\n",
|
||||
def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
|
||||
} else {
|
||||
virBufferVSprintf(&buf, " <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
|
||||
}
|
||||
}
|
||||
|
||||
virBufferAddLit(&buf, " <bridge");
|
||||
if (qemudIsActiveNetwork(network)) {
|
||||
virBufferVSprintf(&buf, " name='%s'", network->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, " <ip");
|
||||
|
||||
if (def->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, " <dhcp>\n");
|
||||
while (range) {
|
||||
virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n",
|
||||
range->start, range->end);
|
||||
range = range->next;
|
||||
}
|
||||
virBufferAddLit(&buf, " </dhcp>\n");
|
||||
}
|
||||
|
||||
virBufferAddLit(&buf, " </ip>\n");
|
||||
}
|
||||
|
||||
virBufferAddLit(&buf, "</network>\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,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "bridge.h"
|
||||
#include "iptables.h"
|
||||
#include "capabilities.h"
|
||||
#include "network_conf.h"
|
||||
#include <netinet/in.h>
|
||||
#include <sched.h>
|
||||
|
||||
@ -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 */
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user