[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