static int lxcNetworkParseDataType(virConfValuePtr value, lxcNetworkParseData *parseData) { virDomainDefPtr def = parseData->def; size_t networks = parseData->networks; bool privnet = parseData->privnet; int status; /* Store the previous NIC */ status = lxcAddNetworkDefinition(parseData); if (status < 0) return -1; else if (status > 0) networks++; else if (parseData->type != NULL && STREQ(parseData->type, "none")) privnet = false; /* clean NIC to store a new one */ memset(parseData, 0, sizeof(*parseData)); parseData->def = def; parseData->networks = networks; parseData->privnet = privnet; /* Keep the new value */ parseData->type = value->str; return 0; }
static int lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) { int status; int result = -1; size_t i; lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, true, 0}; if (virConfWalk(properties, lxcNetworkWalkCallback, &data) < 0) goto error; /* Add the last network definition found */ status = lxcAddNetworkDefinition(&data); if (status < 0) goto error; else if (status > 0) data.networks++; else if (data.type != NULL && STREQ(data.type, "none")) data.privnet = false; if (data.networks == 0 && data.privnet) { /* When no network type is provided LXC only adds loopback */ def->features[VIR_DOMAIN_FEATURE_PRIVNET] = VIR_TRISTATE_SWITCH_ON; } result = 0; return result; error: for (i = 0; i < data.nips; i++) VIR_FREE(data.ips[i]); VIR_FREE(data.ips); return -1; }
static int lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) { lxcNetworkParseData *parseData = data; int status; if (STREQ(name, "lxc.network.type")) { /* Store the previous NIC */ status = lxcAddNetworkDefinition(parseData); if (status < 0) return -1; else if (status > 0) parseData->networks++; else if (parseData->type != NULL && STREQ(parseData->type, "none")) parseData->privnet = false; /* Start a new network interface config */ parseData->type = NULL; parseData->link = NULL; parseData->mac = NULL; parseData->flag = NULL; parseData->macvlanmode = NULL; parseData->vlanid = NULL; parseData->name = NULL; parseData->ips = NULL; parseData->nips = 0; /* Keep the new value */ parseData->type = value->str; } else if (STREQ(name, "lxc.network.link")) parseData->link = value->str; else if (STREQ(name, "lxc.network.hwaddr")) parseData->mac = value->str; else if (STREQ(name, "lxc.network.flags")) parseData->flag = value->str; else if (STREQ(name, "lxc.network.macvlan.mode")) parseData->macvlanmode = value->str; else if (STREQ(name, "lxc.network.vlan.id")) parseData->vlanid = value->str; else if (STREQ(name, "lxc.network.name")) parseData->name = value->str; else if (STREQ(name, "lxc.network.ipv4") || STREQ(name, "lxc.network.ipv6")) { int family = AF_INET; char **ipparts = NULL; virDomainNetIpDefPtr ip = NULL; if (VIR_ALLOC(ip) < 0) return -1; if (STREQ(name, "lxc.network.ipv6")) family = AF_INET6; ipparts = virStringSplit(value->str, "/", 2); if (virStringListLength((const char * const *)ipparts) != 2 || virSocketAddrParse(&ip->address, ipparts[0], family) < 0 || virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid CIDR address: '%s'"), value->str); virStringFreeList(ipparts); VIR_FREE(ip); return -1; } virStringFreeList(ipparts); if (VIR_APPEND_ELEMENT(parseData->ips, parseData->nips, ip) < 0) { VIR_FREE(ip); return -1; } } else if (STREQ(name, "lxc.network.ipv4.gateway")) { parseData->gateway_ipv4 = value->str; } else if (STREQ(name, "lxc.network.ipv6.gateway")) { parseData->gateway_ipv6 = value->str; } else if (STRPREFIX(name, "lxc.network")) { VIR_WARN("Unhandled network property: %s = %s", name, value->str); } return 0; }