[libvirt] [PATCHv3 04/16] lxc conf2xml: convert IP addresses
Daniel P. Berrange
berrange at redhat.com
Wed Oct 22 10:08:03 UTC 2014
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 :|
More information about the libvir-list
mailing list