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>
|
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
|
* 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:
|
* brAddBridge:
|
||||||
* @ctl: bridge control pointer
|
* @ctl: bridge control pointer
|
||||||
* @nameOrFmt: the bridge name (or name template)
|
* @name: the bridge name
|
||||||
* @name: pointer to @maxlen bytes to store the bridge name
|
|
||||||
* @maxlen: size of @name array
|
|
||||||
*
|
*
|
||||||
* This function register a new bridge, @nameOrFmt can be either
|
* This function register a new bridge
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Returns 0 in case of success or an errno code in case of failure.
|
* Returns 0 in case of success or an errno code in case of failure.
|
||||||
*/
|
*/
|
||||||
#ifdef SIOCBRADDBR
|
#ifdef SIOCBRADDBR
|
||||||
int
|
int
|
||||||
brAddBridge(brControl *ctl,
|
brAddBridge(brControl *ctl,
|
||||||
const char *nameOrFmt,
|
char **name)
|
||||||
char *name,
|
|
||||||
int maxlen)
|
|
||||||
{
|
{
|
||||||
int id, subst;
|
if (!ctl || !ctl->fd || !name)
|
||||||
|
|
||||||
if (!ctl || !ctl->fd || !nameOrFmt || !name)
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (maxlen >= BR_IFNAME_MAXLEN)
|
if (*name) {
|
||||||
maxlen = BR_IFNAME_MAXLEN;
|
if (ioctl(ctl->fd, SIOCBRADDBR, *name) == 0)
|
||||||
|
|
||||||
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);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
|
int id = 0;
|
||||||
|
do {
|
||||||
|
char try[50];
|
||||||
|
|
||||||
id++;
|
snprintf(try, sizeof(try), "virbr%d", id);
|
||||||
} while (subst && id <= MAX_BRIDGE_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;
|
return errno;
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,7 @@ int brInit (brControl **ctl);
|
|||||||
void brShutdown (brControl *ctl);
|
void brShutdown (brControl *ctl);
|
||||||
|
|
||||||
int brAddBridge (brControl *ctl,
|
int brAddBridge (brControl *ctl,
|
||||||
const char *nameOrFmt,
|
char **name);
|
||||||
char *name,
|
|
||||||
int maxlen);
|
|
||||||
int brDeleteBridge (brControl *ctl,
|
int brDeleteBridge (brControl *ctl,
|
||||||
const char *name);
|
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;
|
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 */
|
/* Free all memory associated with a struct qemud_vm object */
|
||||||
void qemudFreeVMDef(struct qemud_vm_def *def) {
|
void qemudFreeVMDef(struct qemud_vm_def *def) {
|
||||||
@ -2254,7 +2228,7 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
|
|||||||
struct qemud_vm_net_def *net,
|
struct qemud_vm_net_def *net,
|
||||||
int vlan)
|
int vlan)
|
||||||
{
|
{
|
||||||
struct qemud_network *network = NULL;
|
virNetworkObjPtr network = NULL;
|
||||||
char *brname;
|
char *brname;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
char tapfdstr[4+3+32+7];
|
char tapfdstr[4+3+32+7];
|
||||||
@ -2263,18 +2237,18 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
|
|||||||
int tapfd = -1;
|
int tapfd = -1;
|
||||||
|
|
||||||
if (net->type == QEMUD_NET_NETWORK) {
|
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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Network '%s' not found"),
|
_("Network '%s' not found"),
|
||||||
net->dst.network.name);
|
net->dst.network.name);
|
||||||
goto error;
|
goto error;
|
||||||
} else if (network->bridge[0] == '\0') {
|
} else if (network->def->bridge == NULL) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Network '%s' not active"),
|
_("Network '%s' not active"),
|
||||||
net->dst.network.name);
|
net->dst.network.name);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
brname = network->bridge;
|
brname = network->def->bridge;
|
||||||
if (net->dst.network.ifname[0] == '\0' ||
|
if (net->dst.network.ifname[0] == '\0' ||
|
||||||
STRPREFIX(net->dst.network.ifname, "vnet") ||
|
STRPREFIX(net->dst.network.ifname, "vnet") ||
|
||||||
strchr(net->dst.network.ifname, '%')) {
|
strchr(net->dst.network.ifname, '%')) {
|
||||||
@ -3122,465 +3096,6 @@ qemudSaveVMDef(virConnectPtr conn,
|
|||||||
return qemudSaveConfig(conn, driver, vm, def);
|
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 *
|
static struct qemud_vm *
|
||||||
qemudLoadConfig(struct qemud_driver *driver,
|
qemudLoadConfig(struct qemud_driver *driver,
|
||||||
@ -3627,54 +3142,10 @@ qemudLoadConfig(struct qemud_driver *driver,
|
|||||||
return vm;
|
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
|
static
|
||||||
int qemudScanConfigDir(struct qemud_driver *driver,
|
int qemudScanConfigDir(struct qemud_driver *driver,
|
||||||
const char *configDir,
|
const char *configDir,
|
||||||
const char *autostartDir,
|
const char *autostartDir) {
|
||||||
int isGuest) {
|
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
|
||||||
@ -3713,10 +3184,7 @@ int qemudScanConfigDir(struct qemud_driver *driver,
|
|||||||
if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0)
|
if (virFileReadAll(path, QEMUD_MAX_XML_LEN, &xml) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isGuest)
|
qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink);
|
||||||
qemudLoadConfig(driver, entry->d_name, path, xml, autostartLink);
|
|
||||||
else
|
|
||||||
qemudLoadNetworkConfig(driver, entry->d_name, path, xml, autostartLink);
|
|
||||||
|
|
||||||
VIR_FREE(xml);
|
VIR_FREE(xml);
|
||||||
}
|
}
|
||||||
@ -3728,10 +3196,7 @@ int qemudScanConfigDir(struct qemud_driver *driver,
|
|||||||
|
|
||||||
/* Scan for all guest and network config files */
|
/* Scan for all guest and network config files */
|
||||||
int qemudScanConfigs(struct qemud_driver *driver) {
|
int qemudScanConfigs(struct qemud_driver *driver) {
|
||||||
if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir, 1) < 0)
|
if (qemudScanConfigDir(driver, driver->configDir, driver->autostartDir) < 0)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (qemudScanConfigDir(driver, driver->networkConfigDir, driver->networkAutostartDir, 0) < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
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,
|
int qemudDeleteConfig(virConnectPtr conn,
|
||||||
struct qemud_driver *driver ATTRIBUTE_UNUSED,
|
struct qemud_driver *driver ATTRIBUTE_UNUSED,
|
||||||
const char *configFile,
|
const char *configFile,
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "iptables.h"
|
#include "iptables.h"
|
||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
|
#include "network_conf.h"
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
@ -96,12 +97,6 @@ enum qemud_vm_net_type {
|
|||||||
QEMUD_NET_BRIDGE,
|
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_NAME_LEN 50
|
||||||
#define QEMUD_MAX_XML_LEN 4096
|
#define QEMUD_MAX_XML_LEN 4096
|
||||||
#define QEMUD_MAX_ERROR_LEN 1024
|
#define QEMUD_MAX_ERROR_LEN 1024
|
||||||
@ -349,53 +344,6 @@ struct qemud_vm {
|
|||||||
struct qemud_vm *next;
|
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 */
|
/* Main driver state */
|
||||||
struct qemud_driver {
|
struct qemud_driver {
|
||||||
int qemuVersion;
|
int qemuVersion;
|
||||||
@ -403,9 +351,9 @@ struct qemud_driver {
|
|||||||
int ninactivevms;
|
int ninactivevms;
|
||||||
struct qemud_vm *vms;
|
struct qemud_vm *vms;
|
||||||
int nextvmid;
|
int nextvmid;
|
||||||
int nactivenetworks;
|
|
||||||
int ninactivenetworks;
|
virNetworkObjPtr networks;
|
||||||
struct qemud_network *networks;
|
|
||||||
brControl *brctl;
|
brControl *brctl;
|
||||||
iptablesContext *iptables;
|
iptablesContext *iptables;
|
||||||
char *configDir;
|
char *configDir;
|
||||||
@ -428,12 +376,6 @@ qemudIsActiveVM(const struct qemud_vm *vm)
|
|||||||
return vm->id != -1;
|
return vm->id != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
qemudIsActiveNetwork(const struct qemud_network *network)
|
|
||||||
{
|
|
||||||
return network->active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qemudReportError(virConnectPtr conn,
|
void qemudReportError(virConnectPtr conn,
|
||||||
virDomainPtr dom,
|
virDomainPtr dom,
|
||||||
virNetworkPtr net,
|
virNetworkPtr net,
|
||||||
@ -451,11 +393,6 @@ struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver,
|
|||||||
struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
|
struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
|
||||||
const char *name);
|
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);
|
virCapsPtr qemudCapsInit (void);
|
||||||
|
|
||||||
int qemudExtractVersion (virConnectPtr conn,
|
int qemudExtractVersion (virConnectPtr conn,
|
||||||
@ -501,30 +438,6 @@ char * qemudGenerateXML (virConnectPtr conn,
|
|||||||
struct qemud_vm_def *def,
|
struct qemud_vm_def *def,
|
||||||
int live);
|
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);
|
const char *qemudVirtTypeToString (int type);
|
||||||
|
|
||||||
#endif /* WITH_QEMU */
|
#endif /* WITH_QEMU */
|
||||||
|
@ -120,11 +120,11 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
|
|||||||
|
|
||||||
static int qemudStartNetworkDaemon(virConnectPtr conn,
|
static int qemudStartNetworkDaemon(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network);
|
virNetworkObjPtr network);
|
||||||
|
|
||||||
static int qemudShutdownNetworkDaemon(virConnectPtr conn,
|
static int qemudShutdownNetworkDaemon(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network);
|
virNetworkObjPtr network);
|
||||||
|
|
||||||
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
|
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
|
||||||
static int qemudMonitorCommand (const struct qemud_driver *driver,
|
static int qemudMonitorCommand (const struct qemud_driver *driver,
|
||||||
@ -137,15 +137,15 @@ static struct qemud_driver *qemu_driver = NULL;
|
|||||||
|
|
||||||
static
|
static
|
||||||
void qemudAutostartConfigs(struct qemud_driver *driver) {
|
void qemudAutostartConfigs(struct qemud_driver *driver) {
|
||||||
struct qemud_network *network;
|
virNetworkObjPtr network;
|
||||||
struct qemud_vm *vm;
|
struct qemud_vm *vm;
|
||||||
|
|
||||||
network = driver->networks;
|
network = driver->networks;
|
||||||
while (network != NULL) {
|
while (network != NULL) {
|
||||||
struct qemud_network *next = network->next;
|
virNetworkObjPtr next = network->next;
|
||||||
|
|
||||||
if (network->autostart &&
|
if (network->autostart &&
|
||||||
!qemudIsActiveNetwork(network) &&
|
!virNetworkIsActive(network) &&
|
||||||
qemudStartNetworkDaemon(NULL, driver, network) < 0) {
|
qemudStartNetworkDaemon(NULL, driver, network) < 0) {
|
||||||
virErrorPtr err = virGetLastError();
|
virErrorPtr err = virGetLastError();
|
||||||
qemudLog(QEMUD_ERR, _("Failed to autostart network '%s': %s"),
|
qemudLog(QEMUD_ERR, _("Failed to autostart network '%s': %s"),
|
||||||
@ -247,6 +247,13 @@ qemudStartup(void) {
|
|||||||
qemudShutdown();
|
qemudShutdown();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (virNetworkLoadAllConfigs(NULL,
|
||||||
|
&qemu_driver->networks,
|
||||||
|
qemu_driver->networkConfigDir,
|
||||||
|
qemu_driver->networkAutostartDir) < 0) {
|
||||||
|
qemudShutdown();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
qemudAutostartConfigs(qemu_driver);
|
qemudAutostartConfigs(qemu_driver);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -273,6 +280,10 @@ qemudStartup(void) {
|
|||||||
static int
|
static int
|
||||||
qemudReload(void) {
|
qemudReload(void) {
|
||||||
qemudScanConfigs(qemu_driver);
|
qemudScanConfigs(qemu_driver);
|
||||||
|
virNetworkLoadAllConfigs(NULL,
|
||||||
|
&qemu_driver->networks,
|
||||||
|
qemu_driver->networkConfigDir,
|
||||||
|
qemu_driver->networkAutostartDir);
|
||||||
|
|
||||||
if (qemu_driver->iptables) {
|
if (qemu_driver->iptables) {
|
||||||
qemudLog(QEMUD_INFO,
|
qemudLog(QEMUD_INFO,
|
||||||
@ -295,11 +306,14 @@ qemudReload(void) {
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
qemudActive(void) {
|
qemudActive(void) {
|
||||||
/* If we've any active networks or guests, then we
|
virNetworkObjPtr net = qemu_driver->networks;
|
||||||
* mark this driver as active
|
while (net) {
|
||||||
*/
|
if (net->active)
|
||||||
if (qemu_driver->nactivenetworks &&
|
return 1;
|
||||||
qemu_driver->nactivevms)
|
net = net->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemu_driver->nactivevms)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Otherwise we're happy to deal with a shutdown */
|
/* Otherwise we're happy to deal with a shutdown */
|
||||||
@ -314,7 +328,7 @@ qemudActive(void) {
|
|||||||
static int
|
static int
|
||||||
qemudShutdown(void) {
|
qemudShutdown(void) {
|
||||||
struct qemud_vm *vm;
|
struct qemud_vm *vm;
|
||||||
struct qemud_network *network;
|
virNetworkObjPtr network;
|
||||||
|
|
||||||
if (!qemu_driver)
|
if (!qemu_driver)
|
||||||
return -1;
|
return -1;
|
||||||
@ -346,8 +360,8 @@ qemudShutdown(void) {
|
|||||||
/* shutdown active networks */
|
/* shutdown active networks */
|
||||||
network = qemu_driver->networks;
|
network = qemu_driver->networks;
|
||||||
while (network) {
|
while (network) {
|
||||||
struct qemud_network *next = network->next;
|
virNetworkObjPtr next = network->next;
|
||||||
if (qemudIsActiveNetwork(network))
|
if (virNetworkIsActive(network))
|
||||||
qemudShutdownNetworkDaemon(NULL, qemu_driver, network);
|
qemudShutdownNetworkDaemon(NULL, qemu_driver, network);
|
||||||
network = next;
|
network = next;
|
||||||
}
|
}
|
||||||
@ -355,13 +369,11 @@ qemudShutdown(void) {
|
|||||||
/* free inactive networks */
|
/* free inactive networks */
|
||||||
network = qemu_driver->networks;
|
network = qemu_driver->networks;
|
||||||
while (network) {
|
while (network) {
|
||||||
struct qemud_network *next = network->next;
|
virNetworkObjPtr next = network->next;
|
||||||
qemudFreeNetwork(network);
|
virNetworkObjFree(network);
|
||||||
network = next;
|
network = next;
|
||||||
}
|
}
|
||||||
qemu_driver->networks = NULL;
|
qemu_driver->networks = NULL;
|
||||||
qemu_driver->nactivenetworks = 0;
|
|
||||||
qemu_driver->ninactivenetworks = 0;
|
|
||||||
|
|
||||||
VIR_FREE(qemu_driver->configDir);
|
VIR_FREE(qemu_driver->configDir);
|
||||||
VIR_FREE(qemu_driver->autostartDir);
|
VIR_FREE(qemu_driver->autostartDir);
|
||||||
@ -1043,11 +1055,10 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, struct qemud_vm *
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
qemudBuildDnsmasqArgv(virConnectPtr conn,
|
qemudBuildDnsmasqArgv(virConnectPtr conn,
|
||||||
struct qemud_network *network,
|
virNetworkObjPtr network,
|
||||||
char ***argv) {
|
char ***argv) {
|
||||||
int i, len;
|
int i, len, r;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
struct qemud_dhcp_range_def *range;
|
|
||||||
|
|
||||||
len =
|
len =
|
||||||
1 + /* dnsmasq */
|
1 + /* dnsmasq */
|
||||||
@ -1113,15 +1124,13 @@ qemudBuildDnsmasqArgv(virConnectPtr conn,
|
|||||||
LOCAL_STATE_DIR, network->def->name);
|
LOCAL_STATE_DIR, network->def->name);
|
||||||
APPEND_ARG(*argv, i++, buf);
|
APPEND_ARG(*argv, i++, buf);
|
||||||
|
|
||||||
range = network->def->ranges;
|
for (r = 0 ; r < network->def->nranges ; r++) {
|
||||||
while (range) {
|
|
||||||
snprintf(buf, sizeof(buf), "%s,%s",
|
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++, "--dhcp-range");
|
||||||
APPEND_ARG(*argv, i++, buf);
|
APPEND_ARG(*argv, i++, buf);
|
||||||
|
|
||||||
range = range->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef APPEND_ARG
|
#undef APPEND_ARG
|
||||||
@ -1142,12 +1151,12 @@ qemudBuildDnsmasqArgv(virConnectPtr conn,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
dhcpStartDhcpDaemon(virConnectPtr conn,
|
dhcpStartDhcpDaemon(virConnectPtr conn,
|
||||||
struct qemud_network *network)
|
virNetworkObjPtr network)
|
||||||
{
|
{
|
||||||
char **argv;
|
char **argv;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
if (network->def->ipAddress[0] == '\0') {
|
if (network->def->ipAddress == NULL) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("cannot start dhcp daemon without IP address for server"));
|
"%s", _("cannot start dhcp daemon without IP address for server"));
|
||||||
return -1;
|
return -1;
|
||||||
@ -1169,27 +1178,27 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
|
|||||||
static int
|
static int
|
||||||
qemudAddMasqueradingIptablesRules(virConnectPtr conn,
|
qemudAddMasqueradingIptablesRules(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
int err;
|
int err;
|
||||||
/* allow forwarding packets from the bridge interface */
|
/* allow forwarding packets from the bridge interface */
|
||||||
if ((err = iptablesAddForwardAllowOut(driver->iptables,
|
if ((err = iptablesAddForwardAllowOut(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev))) {
|
network->def->forwardDev))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
|
_("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto masqerr1;
|
goto masqerr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow forwarding packets to the bridge interface if they are part of an existing connection */
|
/* allow forwarding packets to the bridge interface if they are part of an existing connection */
|
||||||
if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
|
if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev))) {
|
network->def->forwardDev))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
|
_("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto masqerr2;
|
goto masqerr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1208,12 +1217,12 @@ qemudAddMasqueradingIptablesRules(virConnectPtr conn,
|
|||||||
masqerr3:
|
masqerr3:
|
||||||
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
masqerr2:
|
masqerr2:
|
||||||
iptablesRemoveForwardAllowOut(driver->iptables,
|
iptablesRemoveForwardAllowOut(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
masqerr1:
|
masqerr1:
|
||||||
return 0;
|
return 0;
|
||||||
@ -1222,27 +1231,27 @@ qemudAddMasqueradingIptablesRules(virConnectPtr conn,
|
|||||||
static int
|
static int
|
||||||
qemudAddRoutingIptablesRules(virConnectPtr conn,
|
qemudAddRoutingIptablesRules(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
int err;
|
int err;
|
||||||
/* allow routing packets from the bridge interface */
|
/* allow routing packets from the bridge interface */
|
||||||
if ((err = iptablesAddForwardAllowOut(driver->iptables,
|
if ((err = iptablesAddForwardAllowOut(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev))) {
|
network->def->forwardDev))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow routing from '%s' : %s\n"),
|
_("failed to add iptables rule to allow routing from '%s' : %s\n"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto routeerr1;
|
goto routeerr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow routing packets to the bridge interface */
|
/* allow routing packets to the bridge interface */
|
||||||
if ((err = iptablesAddForwardAllowIn(driver->iptables,
|
if ((err = iptablesAddForwardAllowIn(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev))) {
|
network->def->forwardDev))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow routing to '%s' : %s\n"),
|
_("failed to add iptables rule to allow routing to '%s' : %s\n"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto routeerr2;
|
goto routeerr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,7 +1261,7 @@ qemudAddRoutingIptablesRules(virConnectPtr conn,
|
|||||||
routeerr2:
|
routeerr2:
|
||||||
iptablesRemoveForwardAllowOut(driver->iptables,
|
iptablesRemoveForwardAllowOut(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
routeerr1:
|
routeerr1:
|
||||||
return 0;
|
return 0;
|
||||||
@ -1261,7 +1270,7 @@ qemudAddRoutingIptablesRules(virConnectPtr conn,
|
|||||||
static int
|
static int
|
||||||
qemudAddIptablesRules(virConnectPtr conn,
|
qemudAddIptablesRules(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!driver->iptables && !(driver->iptables = iptablesContextNew())) {
|
if (!driver->iptables && !(driver->iptables = iptablesContextNew())) {
|
||||||
@ -1272,71 +1281,69 @@ qemudAddIptablesRules(virConnectPtr conn,
|
|||||||
|
|
||||||
|
|
||||||
/* allow DHCP requests through to dnsmasq */
|
/* 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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
|
_("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err1;
|
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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
|
_("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow DNS requests through to dnsmasq */
|
/* 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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow DNS requests from '%s' : %s"),
|
_("failed to add iptables rule to allow DNS requests from '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err3;
|
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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow DNS requests from '%s' : %s"),
|
_("failed to add iptables rule to allow DNS requests from '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err4;
|
goto err4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Catch all rules to block forwarding to/from bridges */
|
/* 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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to block outbound traffic from '%s' : %s"),
|
_("failed to add iptables rule to block outbound traffic from '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err5;
|
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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to block inbound traffic to '%s' : %s"),
|
_("failed to add iptables rule to block inbound traffic to '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err6;
|
goto err6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow traffic between guests on the same bridge */
|
/* 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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"),
|
_("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err7;
|
goto err7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (network->def->forward) {
|
/* If masquerading is enabled, set up the rules*/
|
||||||
/* If masquerading is enabled, set up the rules*/
|
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT &&
|
||||||
if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT &&
|
!qemudAddMasqueradingIptablesRules(conn, driver, network))
|
||||||
!qemudAddMasqueradingIptablesRules(conn, driver, network))
|
goto err8;
|
||||||
goto err8;
|
/* else if routing is enabled, set up the rules*/
|
||||||
/* else if routing is enabled, set up the rules*/
|
else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE &&
|
||||||
else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE &&
|
!qemudAddRoutingIptablesRules(conn, driver, network))
|
||||||
!qemudAddRoutingIptablesRules(conn, driver, network))
|
goto err8;
|
||||||
goto err8;
|
|
||||||
}
|
|
||||||
|
|
||||||
iptablesSaveRules(driver->iptables);
|
iptablesSaveRules(driver->iptables);
|
||||||
|
|
||||||
@ -1344,56 +1351,56 @@ qemudAddIptablesRules(virConnectPtr conn,
|
|||||||
|
|
||||||
err8:
|
err8:
|
||||||
iptablesRemoveForwardAllowCross(driver->iptables,
|
iptablesRemoveForwardAllowCross(driver->iptables,
|
||||||
network->bridge);
|
network->def->bridge);
|
||||||
err7:
|
err7:
|
||||||
iptablesRemoveForwardRejectIn(driver->iptables,
|
iptablesRemoveForwardRejectIn(driver->iptables,
|
||||||
network->bridge);
|
network->def->bridge);
|
||||||
err6:
|
err6:
|
||||||
iptablesRemoveForwardRejectOut(driver->iptables,
|
iptablesRemoveForwardRejectOut(driver->iptables,
|
||||||
network->bridge);
|
network->def->bridge);
|
||||||
err5:
|
err5:
|
||||||
iptablesRemoveUdpInput(driver->iptables, network->bridge, 53);
|
iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
|
||||||
err4:
|
err4:
|
||||||
iptablesRemoveTcpInput(driver->iptables, network->bridge, 53);
|
iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
|
||||||
err3:
|
err3:
|
||||||
iptablesRemoveUdpInput(driver->iptables, network->bridge, 67);
|
iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
|
||||||
err2:
|
err2:
|
||||||
iptablesRemoveTcpInput(driver->iptables, network->bridge, 67);
|
iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
|
||||||
err1:
|
err1:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemudRemoveIptablesRules(struct qemud_driver *driver,
|
qemudRemoveIptablesRules(struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
if (network->def->forward) {
|
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
|
||||||
iptablesRemoveForwardMasquerade(driver->iptables,
|
iptablesRemoveForwardMasquerade(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
|
|
||||||
if (network->def->forwardMode == QEMUD_NET_FORWARD_NAT)
|
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT)
|
||||||
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
else if (network->def->forwardMode == QEMUD_NET_FORWARD_ROUTE)
|
else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE)
|
||||||
iptablesRemoveForwardAllowIn(driver->iptables,
|
iptablesRemoveForwardAllowIn(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
|
|
||||||
iptablesRemoveForwardAllowOut(driver->iptables,
|
iptablesRemoveForwardAllowOut(driver->iptables,
|
||||||
network->def->network,
|
network->def->network,
|
||||||
network->bridge,
|
network->def->bridge,
|
||||||
network->def->forwardDev);
|
network->def->forwardDev);
|
||||||
}
|
}
|
||||||
iptablesRemoveForwardAllowCross(driver->iptables, network->bridge);
|
iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge);
|
||||||
iptablesRemoveForwardRejectIn(driver->iptables, network->bridge);
|
iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge);
|
||||||
iptablesRemoveForwardRejectOut(driver->iptables, network->bridge);
|
iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge);
|
||||||
iptablesRemoveUdpInput(driver->iptables, network->bridge, 53);
|
iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
|
||||||
iptablesRemoveTcpInput(driver->iptables, network->bridge, 53);
|
iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
|
||||||
iptablesRemoveUdpInput(driver->iptables, network->bridge, 67);
|
iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
|
||||||
iptablesRemoveTcpInput(driver->iptables, network->bridge, 67);
|
iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
|
||||||
iptablesSaveRules(driver->iptables);
|
iptablesSaveRules(driver->iptables);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1419,11 +1426,10 @@ qemudEnableIpForwarding(void)
|
|||||||
|
|
||||||
static int qemudStartNetworkDaemon(virConnectPtr conn,
|
static int qemudStartNetworkDaemon(virConnectPtr conn,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
const char *name;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (qemudIsActiveNetwork(network)) {
|
if (virNetworkIsActive(network)) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("network is already active"));
|
"%s", _("network is already active"));
|
||||||
return -1;
|
return -1;
|
||||||
@ -1435,94 +1441,85 @@ static int qemudStartNetworkDaemon(virConnectPtr conn,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->def->bridge[0] == '\0' ||
|
if ((err = brAddBridge(driver->brctl, &network->def->bridge))) {
|
||||||
strchr(network->def->bridge, '%')) {
|
|
||||||
name = "vnet%d";
|
|
||||||
} else {
|
|
||||||
name = network->def->bridge;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = brAddBridge(driver->brctl, name, network->bridge, sizeof(network->bridge)))) {
|
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (network->def->forwardDelay &&
|
if (network->def->delay &&
|
||||||
(err = brSetForwardDelay(driver->brctl, network->bridge, network->def->forwardDelay))) {
|
(err = brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to set bridge forward delay to %d"),
|
_("failed to set bridge forward delay to %ld"),
|
||||||
network->def->forwardDelay);
|
network->def->delay);
|
||||||
goto err_delbr;
|
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,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to set bridge STP to %s"),
|
_("failed to set bridge STP to %s"),
|
||||||
network->def->disableSTP ? "off" : "on");
|
network->def->stp ? "on" : "off");
|
||||||
goto err_delbr;
|
goto err_delbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->def->ipAddress[0] &&
|
if (network->def->ipAddress &&
|
||||||
(err = brSetInetAddress(driver->brctl, network->bridge, network->def->ipAddress))) {
|
(err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot set IP address on bridge '%s' to '%s' : %s"),
|
_("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;
|
goto err_delbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->def->netmask[0] &&
|
if (network->def->netmask &&
|
||||||
(err = brSetInetNetmask(driver->brctl, network->bridge, network->def->netmask))) {
|
(err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot set netmask on bridge '%s' to '%s' : %s"),
|
_("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;
|
goto err_delbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->def->ipAddress[0] &&
|
if (network->def->ipAddress &&
|
||||||
(err = brSetInterfaceUp(driver->brctl, network->bridge, 1))) {
|
(err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to bring the bridge '%s' up : %s"),
|
_("failed to bring the bridge '%s' up : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
goto err_delbr;
|
goto err_delbr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!qemudAddIptablesRules(conn, driver, network))
|
if (!qemudAddIptablesRules(conn, driver, network))
|
||||||
goto err_delbr1;
|
goto err_delbr1;
|
||||||
|
|
||||||
if (network->def->forward &&
|
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
|
||||||
!qemudEnableIpForwarding()) {
|
!qemudEnableIpForwarding()) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("failed to enable IP forwarding : %s"), strerror(err));
|
_("failed to enable IP forwarding : %s"), strerror(err));
|
||||||
goto err_delbr2;
|
goto err_delbr2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->def->ranges &&
|
if (network->def->nranges &&
|
||||||
dhcpStartDhcpDaemon(conn, network) < 0)
|
dhcpStartDhcpDaemon(conn, network) < 0)
|
||||||
goto err_delbr2;
|
goto err_delbr2;
|
||||||
|
|
||||||
network->active = 1;
|
network->active = 1;
|
||||||
|
|
||||||
driver->ninactivenetworks--;
|
|
||||||
driver->nactivenetworks++;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_delbr2:
|
err_delbr2:
|
||||||
qemudRemoveIptablesRules(driver, network);
|
qemudRemoveIptablesRules(driver, network);
|
||||||
|
|
||||||
err_delbr1:
|
err_delbr1:
|
||||||
if (network->def->ipAddress[0] &&
|
if (network->def->ipAddress &&
|
||||||
(err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) {
|
(err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
|
||||||
qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"),
|
qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
err_delbr:
|
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"),
|
qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -1531,12 +1528,12 @@ static int qemudStartNetworkDaemon(virConnectPtr conn,
|
|||||||
|
|
||||||
static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
struct qemud_driver *driver,
|
struct qemud_driver *driver,
|
||||||
struct qemud_network *network) {
|
virNetworkObjPtr network) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
qemudLog(QEMUD_INFO, _("Shutting down network '%s'"), network->def->name);
|
qemudLog(QEMUD_INFO, _("Shutting down network '%s'"), network->def->name);
|
||||||
|
|
||||||
if (!qemudIsActiveNetwork(network))
|
if (!virNetworkIsActive(network))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (network->dnsmasqPid > 0)
|
if (network->dnsmasqPid > 0)
|
||||||
@ -1544,15 +1541,15 @@ static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
qemudRemoveIptablesRules(driver, network);
|
qemudRemoveIptablesRules(driver, network);
|
||||||
|
|
||||||
if (network->def->ipAddress[0] &&
|
if (network->def->ipAddress &&
|
||||||
(err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) {
|
(err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
|
||||||
qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s"),
|
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"),
|
qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s"),
|
||||||
network->bridge, strerror(err));
|
network->def->bridge, strerror(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network->dnsmasqPid > 0 &&
|
if (network->dnsmasqPid > 0 &&
|
||||||
@ -1563,21 +1560,18 @@ static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
"%s", _("Got unexpected pid for dnsmasq"));
|
"%s", _("Got unexpected pid for dnsmasq"));
|
||||||
}
|
}
|
||||||
|
|
||||||
network->bridge[0] = '\0';
|
|
||||||
network->dnsmasqPid = -1;
|
network->dnsmasqPid = -1;
|
||||||
network->active = 0;
|
network->active = 0;
|
||||||
|
|
||||||
if (network->newDef) {
|
if (network->newDef) {
|
||||||
qemudFreeNetworkDef(network->def);
|
virNetworkDefFree(network->def);
|
||||||
network->def = network->newDef;
|
network->def = network->newDef;
|
||||||
network->newDef = NULL;
|
network->newDef = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver->nactivenetworks--;
|
if (!network->configFile)
|
||||||
driver->ninactivenetworks++;
|
virNetworkRemoveInactive(&driver->networks,
|
||||||
|
network);
|
||||||
if (!network->configFile[0])
|
|
||||||
qemudRemoveInactiveNetwork(driver, network);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3294,9 +3288,9 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED,
|
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_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network *network = qemudFindNetworkByUUID(driver, uuid);
|
virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, uuid);
|
||||||
virNetworkPtr net;
|
virNetworkPtr net;
|
||||||
|
|
||||||
if (!network) {
|
if (!network) {
|
||||||
@ -3309,9 +3303,9 @@ static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSE
|
|||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
static virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED,
|
static virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network *network = qemudFindNetworkByName(driver, name);
|
virNetworkObjPtr network = virNetworkFindByName(driver->networks, name);
|
||||||
virNetworkPtr net;
|
virNetworkPtr net;
|
||||||
|
|
||||||
if (!network) {
|
if (!network) {
|
||||||
@ -3341,16 +3335,23 @@ static int qemudCloseNetwork(virConnectPtr conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int qemudNumNetworks(virConnectPtr conn) {
|
static int qemudNumNetworks(virConnectPtr conn) {
|
||||||
|
int nactive = 0;
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
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) {
|
static int qemudListNetworks(virConnectPtr conn, char **const names, int nnames) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network *network = driver->networks;
|
virNetworkObjPtr network = driver->networks;
|
||||||
int got = 0, i;
|
int got = 0, i;
|
||||||
while (network && got < nnames) {
|
while (network && got < nnames) {
|
||||||
if (qemudIsActiveNetwork(network)) {
|
if (virNetworkIsActive(network)) {
|
||||||
if (!(names[got] = strdup(network->def->name))) {
|
if (!(names[got] = strdup(network->def->name))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
||||||
"%s", _("failed to allocate space for VM name string"));
|
"%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) {
|
static int qemudNumDefinedNetworks(virConnectPtr conn) {
|
||||||
|
int ninactive = 0;
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
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) {
|
static int qemudListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network *network = driver->networks;
|
virNetworkObjPtr network = driver->networks;
|
||||||
int got = 0, i;
|
int got = 0, i;
|
||||||
while (network && got < nnames) {
|
while (network && got < nnames) {
|
||||||
if (!qemudIsActiveNetwork(network)) {
|
if (!virNetworkIsActive(network)) {
|
||||||
if (!(names[got] = strdup(network->def->name))) {
|
if (!(names[got] = strdup(network->def->name))) {
|
||||||
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
|
||||||
"%s", _("failed to allocate space for VM name string"));
|
"%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) {
|
static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network_def *def;
|
virNetworkDefPtr def;
|
||||||
struct qemud_network *network;
|
virNetworkObjPtr network;
|
||||||
virNetworkPtr net;
|
virNetworkPtr net;
|
||||||
|
|
||||||
if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL)))
|
if (!(def = virNetworkDefParseString(conn, xml)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(network = qemudAssignNetworkDef(conn, driver, def))) {
|
if (!(network = virNetworkAssignDef(conn,
|
||||||
qemudFreeNetworkDef(def);
|
&driver->networks,
|
||||||
|
def))) {
|
||||||
|
virNetworkDefFree(def);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemudStartNetworkDaemon(conn, driver, network) < 0) {
|
if (qemudStartNetworkDaemon(conn, driver, network) < 0) {
|
||||||
qemudRemoveInactiveNetwork(driver, network);
|
virNetworkRemoveInactive(&driver->networks,
|
||||||
|
network);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3421,30 +3432,34 @@ static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) {
|
|||||||
|
|
||||||
static virNetworkPtr qemudNetworkDefine(virConnectPtr conn, const char *xml) {
|
static virNetworkPtr qemudNetworkDefine(virConnectPtr conn, const char *xml) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
|
||||||
struct qemud_network_def *def;
|
virNetworkDefPtr def;
|
||||||
struct qemud_network *network;
|
virNetworkObjPtr network;
|
||||||
virNetworkPtr net;
|
|
||||||
|
|
||||||
if (!(def = qemudParseNetworkDef(conn, driver, xml, NULL)))
|
if (!(def = virNetworkDefParseString(conn, xml)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(network = qemudAssignNetworkDef(conn, driver, def))) {
|
if (!(network = virNetworkAssignDef(conn,
|
||||||
qemudFreeNetworkDef(def);
|
&driver->networks,
|
||||||
|
def))) {
|
||||||
|
virNetworkDefFree(def);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemudSaveNetworkDef(conn, driver, network, def) < 0) {
|
if (virNetworkSaveConfig(conn,
|
||||||
qemudRemoveInactiveNetwork(driver, network);
|
driver->networkConfigDir,
|
||||||
|
driver->networkAutostartDir,
|
||||||
|
network) < 0) {
|
||||||
|
virNetworkRemoveInactive(&driver->networks,
|
||||||
|
network);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
net = virGetNetwork(conn, network->def->name, network->def->uuid);
|
return virGetNetwork(conn, network->def->name, network->def->uuid);
|
||||||
return net;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudNetworkUndefine(virNetworkPtr net) {
|
static int qemudNetworkUndefine(virNetworkPtr net) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN,
|
||||||
@ -3452,24 +3467,24 @@ static int qemudNetworkUndefine(virNetworkPtr net) {
|
|||||||
return -1;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR)
|
virNetworkRemoveInactive(&driver->networks,
|
||||||
qemudLog(QEMUD_WARN, _("Failed to delete autostart link '%s': %s"),
|
network);
|
||||||
network->autostartLink, strerror(errno));
|
|
||||||
|
|
||||||
network->configFile[0] = '\0';
|
|
||||||
network->autostartLink[0] = '\0';
|
|
||||||
|
|
||||||
qemudRemoveInactiveNetwork(driver, network);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemudNetworkStart(virNetworkPtr net) {
|
static int qemudNetworkStart(virNetworkPtr net) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
||||||
@ -3482,7 +3497,7 @@ static int qemudNetworkStart(virNetworkPtr net) {
|
|||||||
|
|
||||||
static int qemudNetworkDestroy(virNetworkPtr net) {
|
static int qemudNetworkDestroy(virNetworkPtr net) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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;
|
int ret;
|
||||||
|
|
||||||
if (!network) {
|
if (!network) {
|
||||||
@ -3498,7 +3513,7 @@ static int qemudNetworkDestroy(virNetworkPtr net) {
|
|||||||
|
|
||||||
static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) {
|
static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_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 NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qemudGenerateNetworkXML(net->conn, driver, network, network->def);
|
return virNetworkDefFormat(net->conn, network->def);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *qemudNetworkGetBridgeName(virNetworkPtr net) {
|
static char *qemudNetworkGetBridgeName(virNetworkPtr net) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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;
|
char *bridge;
|
||||||
if (!network) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
||||||
@ -3519,7 +3534,7 @@ static char *qemudNetworkGetBridgeName(virNetworkPtr net) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge = strdup(network->bridge);
|
bridge = strdup(network->def->bridge);
|
||||||
if (!bridge) {
|
if (!bridge) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY,
|
||||||
"%s", _("failed to allocate space for network bridge string"));
|
"%s", _("failed to allocate space for network bridge string"));
|
||||||
@ -3531,7 +3546,7 @@ static char *qemudNetworkGetBridgeName(virNetworkPtr net) {
|
|||||||
static int qemudNetworkGetAutostart(virNetworkPtr net,
|
static int qemudNetworkGetAutostart(virNetworkPtr net,
|
||||||
int *autostart) {
|
int *autostart) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
||||||
@ -3547,7 +3562,7 @@ static int qemudNetworkGetAutostart(virNetworkPtr net,
|
|||||||
static int qemudNetworkSetAutostart(virNetworkPtr net,
|
static int qemudNetworkSetAutostart(virNetworkPtr net,
|
||||||
int autostart) {
|
int autostart) {
|
||||||
struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
|
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) {
|
if (!network) {
|
||||||
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
|
||||||
|
Loading…
Reference in New Issue
Block a user