
On Fri, Oct 10, 2014 at 02:03:56PM +0200, Cédric Bosdonnat wrote:
--- src/lxc/lxc_native.c | 153 ++++++++++++++++-------- tests/lxcconf2xmldata/lxcconf2xml-simple.config | 2 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 2 + 3 files changed, 106 insertions(+), 51 deletions(-)
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 41e069f..f695a00 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -413,93 +413,124 @@ lxcCreateHostdevDef(int mode, int type, const char *data) return hostdev; }
+typedef struct { + virDomainDefPtr def; + char *type; + char *link; + char *mac; + char *flag; + char *macvlanmode; + char *vlanid; + char *name; + char **ips; + size_t nips; + bool privnet; + size_t networks; +} lxcNetworkParseData; + static int -lxcAddNetworkDefinition(virDomainDefPtr def, - const char *type, - const char *linkdev, - const char *mac, - const char *flag, - const char *macvlanmode, - const char *vlanid, - const char *name) +lxcAddNetworkDefinition(lxcNetworkParseData *data) { virDomainNetDefPtr net = NULL; virDomainHostdevDefPtr hostdev = NULL; bool isPhys, isVlan = false; + size_t nips = 0; + virDomainNetIpDefPtr *ips = NULL; + virDomainNetIpDefPtr ip = NULL; + char **ipparts = NULL; + size_t i;
- if ((type == NULL) || STREQ(type, "empty") || STREQ(type, "") || - STREQ(type, "none")) + if ((data->type == NULL) || STREQ(data->type, "empty") || + STREQ(data->type, "") || STREQ(data->type, "none")) return 0;
- isPhys = STREQ(type, "phys"); - isVlan = STREQ(type, "vlan"); - if (type != NULL && (isPhys || isVlan)) { - if (!linkdev) { + /* Add the IP addresses */ + for (i = 0; i < data->nips; i++) { + if (VIR_ALLOC(ip) < 0) + goto error; + + ipparts = virStringSplit(data->ips[i], "/", 2); + if (virStringListLength(ipparts) != 2 || + strlen(ipparts[0]) == 0 || + virStrToLong_ui(ipparts[1], NULL, 10, &ip->prefix) < 0) { + + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid CIDR address: '%s'"), data->ips[i]); + goto error; + } + + if (VIR_STRDUP(ip->address, ipparts[0]) < 0) + goto error; + + if (VIR_APPEND_ELEMENT(ips, nips, ip) < 0) + goto error; + + virStringFreeList(ipparts); + } + + isPhys = STREQ(data->type, "phys"); + isVlan = STREQ(data->type, "vlan"); + if (data->type != NULL && (isPhys || isVlan)) { + if (!data->link) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Missing 'link' attribute for NIC")); goto error; } if (!(hostdev = lxcCreateHostdevDef(VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET, - linkdev))) + data->link))) goto error;
/* This still requires the user to manually setup the vlan interface * on the host */ - if (isVlan && vlanid) { + if (isVlan && data->vlanid) { VIR_FREE(hostdev->source.caps.u.net.iface); if (virAsprintf(&hostdev->source.caps.u.net.iface, - "%s.%s", linkdev, vlanid) < 0) + "%s.%s", data->link, data->vlanid) < 0) goto error; }
- if (VIR_EXPAND_N(def->hostdevs, def->nhostdevs, 1) < 0) + if (VIR_EXPAND_N(data->def->hostdevs, data->def->nhostdevs, 1) < 0) goto error; - def->hostdevs[def->nhostdevs - 1] = hostdev; + data->def->hostdevs[data->def->nhostdevs - 1] = hostdev; } else { - if (!(net = lxcCreateNetDef(type, linkdev, mac, flag, macvlanmode, name))) + if (!(net = lxcCreateNetDef(data->type, data->link, data->mac, + data->flag, data->macvlanmode, + data->name))) goto error;
- if (VIR_EXPAND_N(def->nets, def->nnets, 1) < 0) + net->ips = ips; + net->nips = nips; + + if (VIR_EXPAND_N(data->def->nets, data->def->nnets, 1) < 0) goto error; - def->nets[def->nnets - 1] = net; + data->def->nets[data->def->nnets - 1] = net; }
return 1;
error: + for (i = 0; i < nips; i++) { + virDomainNetIpDefFree(ips[i]); + } + VIR_FREE(ips); + virStringFreeList(ipparts); + virDomainNetIpDefFree(ip); virDomainNetDefFree(net); virDomainHostdevDefFree(hostdev); return -1; }
-typedef struct { - virDomainDefPtr def; - char *type; - char *link; - char *mac; - char *flag; - char *macvlanmode; - char *vlanid; - char *name; - bool privnet; - size_t networks; -} lxcNetworkParseData; - static int lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) { lxcNetworkParseData *parseData = data; int status; + size_t i;
if (STREQ(name, "lxc.network.type")) { /* Store the previous NIC */ - status = lxcAddNetworkDefinition(parseData->def, parseData->type, - parseData->link, parseData->mac, - parseData->flag, - parseData->macvlanmode, - parseData->vlanid, - parseData->name); + status = lxcAddNetworkDefinition(parseData);
if (status < 0) return -1; @@ -517,6 +548,12 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData->vlanid = NULL; parseData->name = NULL;
+ /* IPs array needs to be free'd as all IPs are dup'ed there */ + for (i = 0; i < parseData->nips; i++) + VIR_FREE(parseData->ips[i]); + VIR_FREE(parseData->ips); + parseData->nips = 0; + /* Keep the new value */ parseData->type = value->str; } @@ -532,7 +569,14 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData->vlanid = value->str; else if (STREQ(name, "lxc.network.name")) parseData->name = value->str; - else if (STRPREFIX(name, "lxc.network")) + else if (STREQ(name, "lxc.network.ipv4") || + STREQ(name, "lxc.network.ipv6")) { + + if (VIR_EXPAND_N(parseData->ips, parseData->nips, 1) < 0) + return -1; + if (VIR_STRDUP(parseData->ips[parseData->nips - 1], value->str) < 0) + return -1;
It would be nice to record the address family here, and then copy that into the XML config explicitly.
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.config b/tests/lxcconf2xmldata/lxcconf2xml-simple.config index b90abc1..d417ba0 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.config +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.config @@ -6,6 +6,8 @@ lxc.network.flags = up lxc.network.link = virbr0 lxc.network.hwaddr = 02:00:15:8f:05:c1 lxc.network.name = eth0 +lxc.network.ipv4 = 192.168.122.2/24 +lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596/64
#remove next line if host DNS configuration should not be available to container lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index 10428ec..a73d05c 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml @@ -37,6 +37,8 @@ <interface type='bridge'> <mac address='02:00:15:8f:05:c1'/> <source bridge='virbr0'/> + <ip address='192.168.122.2' prefix='24'/> + <ip address='2003:db8:1:0:214:1234:fe0b:3596' prefix='64'/>
I'd like to see this become <ip family="ipv4" address='192.168.122.2' prefix='24'/> <ip family="ipv6" address='2003:db8:1:0:214:1234:fe0b:3596' prefix='64'/> Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|