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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list