[libvirt] [PATCH v4 02/17] Domain conf: allow more than one IP address for net devices

Dmitry Guryanov dguryanov at parallels.com
Tue Dec 2 13:43:15 UTC 2014


On Thursday 13 November 2014 10:33:01 Cédric Bosdonnat wrote:
> Add the possibility to have more than one IP address configured for a
> domain network interface. IP addresses can also have a prefix to define
> the corresponding netmask.

I totally agree with this patch. IP configuration must be separated from 
device type and connection configuration.

ACK

> ---
>  docs/formatdomain.html.in                       |  22 ++++
>  docs/schemas/domaincommon.rng                   |  16 ++-
>  src/conf/domain_conf.c                          | 149
> ++++++++++++++++++++---- src/conf/domain_conf.h                          | 
> 15 ++-
>  src/libvirt_private.syms                        |   1 +
>  src/openvz/openvz_conf.c                        |   2 +-
>  src/openvz/openvz_driver.c                      |   7 +-
>  src/qemu/qemu_driver.c                          |  29 ++++-
>  src/qemu/qemu_hotplug.c                         |   5 +-
>  src/uml/uml_conf.c                              |   2 +-
>  src/vbox/vbox_common.c                          |   6 +-
>  src/xenconfig/xen_common.c                      |  21 ++--
>  src/xenconfig/xen_sxpr.c                        |  18 ++-
>  tests/lxcxml2xmldata/lxc-idmap.xml              |   2 +
>  tests/openvzutilstest.c                         |   2 +-
>  tests/sexpr2xmldata/sexpr2xml-bridge-ipaddr.xml |   2 +-
>  tests/sexpr2xmldata/sexpr2xml-net-routed.xml    |   2 +-
>  17 files changed, 242 insertions(+), 59 deletions(-)
> 
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index d4189e6..d414371 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -4283,6 +4283,28 @@ qemu-kvm -net nic,model=? /dev/null
>        <span class="since">Since 0.9.5</span>
>      </p>
> 
> +    <h5><a name="ipconfig">IP configuration</a></h5>
> +<pre>
> +  ...
> +  <devices>
> +    <interface type='network'>
> +      <source network='default'/>
> +      <target dev='vnet0'/>
> +      <b><ip address='192.168.122.5' prefix='24'/></b>
> +    </interface>
> +  </devices>
> +  ...
> +</pre>
> +
> +    <p>
> +    <span class="since">Since 1.2.10</span> the network devices can be
> provided +    zero or more IP addresses to set
> +    on the target device. Note that some hypervisors or network device
> types +    will simply ignore them or only use the first one. The
> <code>address</code> +    attribute can hold either an IPv4 or IPv6
> address. The <code>prefix</code> +    is not mandatory since some
> hypervisors do not handle it.
> +    </p>
> +
>      <h5><a name="elementVhostuser">vhost-user interface</a></h5>
> 
>      <p>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 6863ec6..cd82461 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -2295,14 +2295,24 @@
>            <empty/>
>          </element>
>        </optional>
> -      <optional>
> +      <zeroOrMore>
>          <element name="ip">
>            <attribute name="address">
> -            <ref name="ipv4Addr"/>
> +            <ref name="ipAddr"/>
>            </attribute>
> +          <optional>
> +            <attribute name="family">
> +              <ref name="addr-family"/>
> +            </attribute>
> +          </optional>
> +          <optional>
> +            <attribute name="prefix">
> +              <ref name="ipPrefix"/>
> +            </attribute>
> +          </optional>
>            <empty/>
>          </element>
> -      </optional>
> +      </zeroOrMore>
>        <optional>
>          <element name="script">
>            <attribute name="path">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 8c00dd1..44741a9 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1367,6 +1367,8 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr
> def)
> 
>  void virDomainNetDefFree(virDomainNetDefPtr def)
>  {
> +    size_t i;
> +
>      if (!def)
>          return;
> 
> @@ -1375,7 +1377,6 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
>      switch (def->type) {
>      case VIR_DOMAIN_NET_TYPE_ETHERNET:
>          VIR_FREE(def->data.ethernet.dev);
> -        VIR_FREE(def->data.ethernet.ipaddr);
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> @@ -1396,7 +1397,6 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
> 
>      case VIR_DOMAIN_NET_TYPE_BRIDGE:
>          VIR_FREE(def->data.bridge.brname);
> -        VIR_FREE(def->data.bridge.ipaddr);
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_INTERNAL:
> @@ -1424,6 +1424,10 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
>      VIR_FREE(def->ifname_guest);
>      VIR_FREE(def->ifname_guest_actual);
> 
> +    for (i = 0; i < def->nips; i++)
> +        VIR_FREE(def->ips[i]);
> +    VIR_FREE(def->ips);
> +
>      virDomainDeviceInfoClear(&def->info);
> 
>      VIR_FREE(def->filter);
> @@ -4667,6 +4671,58 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
>      return ret;
>  }
> 
> +static virDomainNetIpDefPtr
> +virDomainNetIpParseXML(xmlNodePtr node)
> +{
> +    /* Parse the prefix in every case */
> +    virDomainNetIpDefPtr ip = NULL;
> +    char *prefixStr = NULL;
> +    unsigned int prefixValue = 0;
> +    char *familyStr = NULL;
> +    int family = AF_UNSPEC;
> +    char *address = NULL;
> +
> +    if (!(prefixStr = virXMLPropString(node, "prefix")) ||
> +        (virStrToLong_ui(prefixStr, NULL, 10, &prefixValue) < 0)) {
> +        // Don't shout, just warn as some old config may not have a prefix
> +        VIR_WARN("Missing or invalid network prefix");
> +    }
> +
> +    if (!(address = virXMLPropString(node, "address"))) {
> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("Missing network address"));
> +        goto error;
> +    }
> +
> +    familyStr = virXMLPropString(node, "family");
> +    if (familyStr && STREQ(familyStr, "ipv4"))
> +        family = AF_INET;
> +    else if (familyStr && STREQ(familyStr, "ipv6"))
> +        family = AF_INET6;
> +    else
> +        family = virSocketAddrNumericFamily(address);
> +
> +    if (VIR_ALLOC(ip) < 0)
> +        goto error;
> +
> +    if (virSocketAddrParse(&ip->address, address, family) < 0) {
> +        virReportError(VIR_ERR_INVALID_ARG,
> +                       _("Failed to parse IP address: '%s'"),
> +                       address);
> +        goto error;
> +    }
> +    ip->prefix = prefixValue;
> +
> +    return ip;
> +
> + error:
> +    VIR_FREE(prefixStr);
> +    VIR_FREE(familyStr);
> +    VIR_FREE(address);
> +    VIR_FREE(ip);
> +    return NULL;
> +}
> +
>  static int
>  virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
>                                  xmlXPathContextPtr ctxt,
> @@ -7077,6 +7133,31 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
>  #define NET_MODEL_CHARS \
>      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
> 
> +
> +int
> +virDomainNetAppendIpAddress(virDomainNetDefPtr def,
> +                            const char *address,
> +                            int family,
> +                            unsigned int prefix)
> +{
> +    virDomainNetIpDefPtr ipDef = NULL;
> +    if (VIR_ALLOC(ipDef) < 0)
> +        return -1;
> +
> +    if (virSocketAddrParse(&ipDef->address, address, family) < 0)
> +        goto error;
> +    ipDef->prefix = prefix;
> +
> +    if (VIR_APPEND_ELEMENT(def->ips, def->nips, ipDef) < 0)
> +        goto error;
> +
> +    return 0;
> +
> + error:
> +    VIR_FREE(ipDef);
> +    return -1;
> +}
> +
>  /* Parse the XML definition for a network interface
>   * @param node XML nodeset to parse for net definition
>   * @return 0 on success, -1 on failure
> @@ -7124,6 +7205,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
>      virDomainActualNetDefPtr actual = NULL;
>      xmlNodePtr oldnode = ctxt->node;
>      int ret, val;
> +    size_t i;
> +    size_t nips = 0;
> +    virDomainNetIpDefPtr *ips = NULL;
> 
>      if (VIR_ALLOC(def) < 0)
>          return NULL;
> @@ -7212,11 +7296,14 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr
> xmlopt, xmlStrEqual(cur->name, BAD_CAST "source")) { address =
> virXMLPropString(cur, "address");
>                  port = virXMLPropString(cur, "port");
> -            } else if (!address &&
> -                       (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET ||
> -                        def->type == VIR_DOMAIN_NET_TYPE_BRIDGE) &&
> -                       xmlStrEqual(cur->name, BAD_CAST "ip")) {
> -                address = virXMLPropString(cur, "address");
> +            } else if (xmlStrEqual(cur->name, BAD_CAST "ip")) {
> +                virDomainNetIpDefPtr ip = NULL;
> +
> +                if (!(ip = virDomainNetIpParseXML(cur)))
> +                    goto error;
> +
> +                if (VIR_APPEND_ELEMENT(ips, nips, ip) < 0)
> +                    goto error;
>              } else if (!ifname &&
>                         xmlStrEqual(cur->name, BAD_CAST "target")) {
>                  ifname = virXMLPropString(cur, "dev");
> @@ -7416,10 +7503,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
> def->data.ethernet.dev = dev;
>              dev = NULL;
>          }
> -        if (address != NULL) {
> -            def->data.ethernet.ipaddr = address;
> -            address = NULL;
> -        }
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_BRIDGE:
> @@ -7431,10 +7514,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
> }
>          def->data.bridge.brname = bridge;
>          bridge = NULL;
> -        if (address != NULL) {
> -            def->data.bridge.ipaddr = address;
> -            address = NULL;
> -        }
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_CLIENT:
> @@ -7531,6 +7610,11 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
> break;
>      }
> 
> +    for (i = 0; i < nips; i++) {
> +        if (VIR_APPEND_ELEMENT(def->ips, def->nips, ips[i]) < 0)
> +            goto error;
> +    }
> +
>      if (script != NULL) {
>          def->script = script;
>          script = NULL;
> @@ -7793,6 +7877,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
>      VIR_FREE(linkstate);
>      VIR_FREE(addrtype);
>      VIR_FREE(trustGuestRxFilters);
> +    VIR_FREE(ips);
>      virNWFilterHashTableFree(filterparams);
> 
>      return def;
> @@ -16753,6 +16838,30 @@ virDomainFSDefFormat(virBufferPtr buf,
>      return 0;
>  }
> 
> +static void
> +virDomainNetIpsFormat(virBufferPtr buf, virDomainNetIpDefPtr *ips, size_t
> nips) +{
> +    size_t i;
> +
> +    /* Output IP addresses */
> +    for (i = 0; i < nips; i++) {
> +        virSocketAddrPtr address = &ips[i]->address;
> +        char *ipStr = virSocketAddrFormat(address);
> +        const char *familyStr = NULL;
> +        if (VIR_SOCKET_ADDR_IS_FAMILY(address, AF_INET6))
> +            familyStr = "ipv6";
> +        else if (VIR_SOCKET_ADDR_IS_FAMILY(address, AF_INET))
> +            familyStr = "ipv4";
> +        virBufferAsprintf(buf, "<ip address='%s'",
> +                          ipStr);
> +        if (familyStr)
> +            virBufferAsprintf(buf, " family='%s'", familyStr);
> +        if (ips[i]->prefix != 0)
> +            virBufferAsprintf(buf, " prefix='%u'", ips[i]->prefix);
> +        virBufferAddLit(buf, "/>\n");
> +    }
> +}
> +
>  static int
>  virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>                                  virDomainHostdevDefPtr def,
> @@ -16980,7 +17089,6 @@ virDomainActualNetDefContentsFormat(virBufferPtr
> buf, return 0;
>  }
> 
> -
>  /* virDomainActualNetDefFormat() - format the ActualNetDef
>   * info inside an <actual> element, as required for internal storage
>   * of domain status
> @@ -17217,9 +17325,6 @@ virDomainNetDefFormat(virBufferPtr buf,
>          case VIR_DOMAIN_NET_TYPE_ETHERNET:
>              virBufferEscapeString(buf, "<source dev='%s'/>\n",
>                                    def->data.ethernet.dev);
> -            if (def->data.ethernet.ipaddr)
> -                virBufferAsprintf(buf, "<ip address='%s'/>\n",
> -                                  def->data.ethernet.ipaddr);
>              break;
> 
>          case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> @@ -17237,10 +17342,6 @@ virDomainNetDefFormat(virBufferPtr buf,
>          case VIR_DOMAIN_NET_TYPE_BRIDGE:
>              virBufferEscapeString(buf, "<source bridge='%s'/>\n",
>                                    def->data.bridge.brname);
> -            if (def->data.bridge.ipaddr) {
> -                virBufferAsprintf(buf, "<ip address='%s'/>\n",
> -                                  def->data.bridge.ipaddr);
> -            }
>              break;
> 
>          case VIR_DOMAIN_NET_TYPE_SERVER:
> @@ -17288,6 +17389,8 @@ virDomainNetDefFormat(virBufferPtr buf,
>              return -1;
>      }
> 
> +    virDomainNetIpsFormat(buf, def->ips, def->nips);
> +
>      virBufferEscapeString(buf, "<script path='%s'/>\n",
>                            def->script);
>      if (def->ifname &&
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 530a3ca..fbf6067 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -471,6 +471,13 @@ typedef enum {
>      VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST
>  } virDomainHostdevCapsType;
> 
> +typedef struct _virDomainNetIpDef virDomainNetIpDef;
> +typedef virDomainNetIpDef *virDomainNetIpDefPtr;
> +struct _virDomainNetIpDef {
> +    virSocketAddr address;       /* ipv4 or ipv6 address */
> +    unsigned int prefix; /* number of 1 bits in the net mask */
> +};
> +
>  typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
>  typedef virDomainHostdevCaps *virDomainHostdevCapsPtr;
>  struct _virDomainHostdevCaps {
> @@ -932,7 +939,6 @@ struct _virDomainNetDef {
>      union {
>          struct {
>              char *dev;
> -            char *ipaddr;
>          } ethernet;
>          virDomainChrSourceDefPtr vhostuser;
>          struct {
> @@ -954,7 +960,6 @@ struct _virDomainNetDef {
>          } network;
>          struct {
>              char *brname;
> -            char *ipaddr;
>          } bridge;
>          struct {
>              char *name;
> @@ -984,6 +989,8 @@ struct _virDomainNetDef {
>      virNetDevVlan vlan;
>      int trustGuestRxFilters; /* enum virTristateBool */
>      int linkstate;
> +    size_t nips;
> +    virDomainNetIpDefPtr *ips;
>  };
> 
>  /* Used for prefix of ifname of any network name generated dynamically
> @@ -2522,6 +2529,10 @@ virNetDevBandwidthPtr
>  virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
>  virNetDevVlanPtr virDomainNetGetActualVlan(virDomainNetDefPtr iface);
>  bool virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface);
> +int virDomainNetAppendIpAddress(virDomainNetDefPtr def,
> +                                const char *address,
> +                                int family,
> +                                unsigned int prefix);
> 
>  int virDomainControllerInsert(virDomainDefPtr def,
>                                virDomainControllerDefPtr controller)
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 0864618..8d02438 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -321,6 +321,7 @@ virDomainLockFailureTypeFromString;
>  virDomainLockFailureTypeToString;
>  virDomainMemballoonModelTypeFromString;
>  virDomainMemballoonModelTypeToString;
> +virDomainNetAppendIpAddress;
>  virDomainNetDefFormat;
>  virDomainNetDefFree;
>  virDomainNetFind;
> diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
> index 856c9f5..b6fdc37 100644
> --- a/src/openvz/openvz_conf.c
> +++ b/src/openvz/openvz_conf.c
> @@ -230,7 +230,7 @@ openvzReadNetworkConf(virDomainDefPtr def,
>                  goto error;
> 
>              net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
> -            if (VIR_STRDUP(net->data.ethernet.ipaddr, token) < 0)
> +            if (virDomainNetAppendIpAddress(net, token, AF_UNSPEC, 0) < 0)
>                  goto error;
> 
>              if (VIR_APPEND_ELEMENT_COPY(def->nets, def->nnets, net) < 0)
> diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
> index a0346b4..273bac1 100644
> --- a/src/openvz/openvz_driver.c
> +++ b/src/openvz/openvz_driver.c
> @@ -855,7 +855,7 @@ openvzDomainSetNetwork(virConnectPtr conn, const char
> *vpsid,
> 
>      if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>          (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
> -         net->data.ethernet.ipaddr == NULL)) {
> +         net->nips == 0)) {
>          virBuffer buf = VIR_BUFFER_INITIALIZER;
>          int veid = openvzGetVEID(vpsid);
> 
> @@ -906,9 +906,10 @@ openvzDomainSetNetwork(virConnectPtr conn, const char
> *vpsid, virCommandAddArg(cmd, "--netif_add");
>          virCommandAddArgBuffer(cmd, &buf);
>      } else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
> -              net->data.ethernet.ipaddr != NULL) {
> +              net->nips > 0) {
>          /* --ipadd ip */
> -        virCommandAddArgList(cmd, "--ipadd", net->data.ethernet.ipaddr,
> NULL); +        char *ipStr = virSocketAddrFormat(&net->ips[0]->address); +
>        virCommandAddArgList(cmd, "--ipadd", ipStr, NULL);
>      }
> 
>      /* TODO: processing NAT and physical device */
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index acf2b9a..2863db4 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -6352,6 +6352,8 @@ static char
> *qemuConnectDomainXMLToNative(virConnectPtr conn, (brname =
> virDomainNetGetActualBridgeName(net))) {
> 
>                  char *brnamecopy;
> +                size_t j;
> +
>                  if (VIR_STRDUP(brnamecopy, brname) < 0)
>                      goto cleanup;
> 
> @@ -6362,20 +6364,31 @@ static char
> *qemuConnectDomainXMLToNative(virConnectPtr conn, net->type =
> VIR_DOMAIN_NET_TYPE_ETHERNET;
>                  net->script = NULL;
>                  net->data.ethernet.dev = brnamecopy;
> -                net->data.ethernet.ipaddr = NULL;
> +                for (j = 0; j < net->nips; j++) {
> +                    VIR_FREE(net->ips[j]);
> +                }
> +                VIR_FREE(net->ips);
> +                net->nips = 0;
> +
>              } else {
>                  /* actualType is either NETWORK or DIRECT. In either
>                   * case, the best we can do is NULL everything out.
>                   */
> +                size_t j;
>                  virDomainActualNetDefFree(net->data.network.actual);
>                  memset(net, 0, sizeof(*net));
> 
>                  net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
>                  net->script = NULL;
>                  net->data.ethernet.dev = NULL;
> -                net->data.ethernet.ipaddr = NULL;
> +                for (j = 0; j < net->nips; j++) {
> +                    VIR_FREE(net->ips[j]);
> +                }
> +                VIR_FREE(net->ips);
> +                net->nips = 0;
>              }
>          } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
> +            size_t j;
>              VIR_FREE(net->data.direct.linkdev);
> 
>              memset(net, 0, sizeof(*net));
> @@ -6383,18 +6396,24 @@ static char
> *qemuConnectDomainXMLToNative(virConnectPtr conn, net->type =
> VIR_DOMAIN_NET_TYPE_ETHERNET;
>              net->script = NULL;
>              net->data.ethernet.dev = NULL;
> -            net->data.ethernet.ipaddr = NULL;
> +            for (j = 0; j < net->nips; j++) {
> +                VIR_FREE(net->ips[j]);
> +            }
> +            VIR_FREE(net->ips);
> +            net->nips = 0;
>          } else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
>              char *script = net->script;
>              char *brname = net->data.bridge.brname;
> -            char *ipaddr = net->data.bridge.ipaddr;
> +            size_t nips = net->nips;
> +            virDomainNetIpDefPtr *ips = net->ips;
> 
>              memset(net, 0, sizeof(*net));
> 
>              net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
>              net->script = script;
>              net->data.ethernet.dev = brname;
> -            net->data.ethernet.ipaddr = ipaddr;
> +            net->nips = nips;
> +            net->ips = ips;
>          }
> 
>          VIR_FREE(net->virtPortProfile);
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 13bcd88..60a6fd9 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -2101,8 +2101,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
>          case VIR_DOMAIN_NET_TYPE_ETHERNET:
>              if (STRNEQ_NULLABLE(olddev->data.ethernet.dev,
>                                  newdev->data.ethernet.dev) ||
> -                STRNEQ_NULLABLE(olddev->data.ethernet.ipaddr,
> -                                newdev->data.ethernet.ipaddr)) {
> +                olddev->nips == 0 || newdev->nips == 0 ||
> +                !virSocketAddrEqual(&olddev->ips[0]->address,
> +                                    &newdev->ips[0]->address)) {
>                  needReconnect = true;
>              }
>          break;
> diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
> index a99e8e9..ac6a7da 100644
> --- a/src/uml/uml_conf.c
> +++ b/src/uml/uml_conf.c
> @@ -175,7 +175,7 @@ umlBuildCommandLineNet(virConnectPtr conn,
>          if (def->ifname) {
>              virBufferAdd(&buf, def->ifname, -1);
>          }
> -        if (def->data.ethernet.ipaddr) {
> +        if (def->nips > 0) {
>              virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>                             _("IP address not supported for ethernet
> interface")); goto error;
> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index cd5b478..fa1e12d 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c
> @@ -1307,7 +1307,11 @@ vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData
> *data, IMachine *machine) } else if (def->nets[i]->type ==
> VIR_DOMAIN_NET_TYPE_BRIDGE) { VIR_DEBUG("NIC(%zu): brname: %s", i,
> def->nets[i]->data.bridge.brname); VIR_DEBUG("NIC(%zu): script: %s", i,
> def->nets[i]->script); -            VIR_DEBUG("NIC(%zu): ipaddr: %s", i,
> def->nets[i]->data.bridge.ipaddr); +            if (def->nets[i]->nips > 0)
> {
> +                char *ipStr =
> virSocketAddrFormat(&def->nets[i]->ips[0]->address); +               
> VIR_DEBUG("NIC(%zu): ipaddr: %s", i, ipStr);
> +                VIR_FREE(ipStr);
> +            }
>          }
> 
>          gVBoxAPI.UIMachine.GetNetworkAdapter(machine, i, &adapter);
> diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c
> index 32954f3..bcb3bd3 100644
> --- a/src/xenconfig/xen_common.c
> +++ b/src/xenconfig/xen_common.c
> @@ -922,12 +922,9 @@ xenParseVif(virConfPtr conf, virDomainDefPtr def)
>              if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
>                  if (bridge[0] && VIR_STRDUP(net->data.bridge.brname,
> bridge) < 0) goto cleanup;
> -                if (ip[0] && VIR_STRDUP(net->data.bridge.ipaddr, ip) < 0)
> -                    goto cleanup;
> -            } else {
> -                if (ip[0] && VIR_STRDUP(net->data.ethernet.ipaddr, ip) < 0)
> -                    goto cleanup;
>              }
> +            if (ip[0] && virDomainNetAppendIpAddress(net, ip, AF_INET, 0) <
> 0) +                goto cleanup;
> 
>              if (script && script[0] &&
>                  VIR_STRDUP(net->script, script) < 0)
> @@ -1225,16 +1222,22 @@ xenFormatNet(virConnectPtr conn,
>      switch (net->type) {
>      case VIR_DOMAIN_NET_TYPE_BRIDGE:
>          virBufferAsprintf(&buf, ",bridge=%s", net->data.bridge.brname);
> -        if (net->data.bridge.ipaddr)
> -            virBufferAsprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
> +        if (net->nips > 0) {
> +            char *ipStr = virSocketAddrFormat(&net->ips[0]->address);
> +            virBufferAsprintf(&buf, ",ip=%s", ipStr);
> +            VIR_FREE(ipStr);
> +        }
>          virBufferAsprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_ETHERNET:
>          if (net->script)
>              virBufferAsprintf(&buf, ",script=%s", net->script);
> -        if (net->data.ethernet.ipaddr)
> -            virBufferAsprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
> +        if (net->nips > 0) {
> +            char *ipStr = virSocketAddrFormat(&net->ips[0]->address);
> +            virBufferAsprintf(&buf, ",ip=%s", ipStr);
> +            VIR_FREE(ipStr);
> +        }
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_NETWORK:
> diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c
> index 6623ea8..caeb464 100644
> --- a/src/xenconfig/xen_sxpr.c
> +++ b/src/xenconfig/xen_sxpr.c
> @@ -565,14 +565,14 @@ xenParseSxprNets(virDomainDefPtr def,
>                      VIR_STRDUP(net->script, tmp2) < 0)
>                      goto cleanup;
>                  tmp = sexpr_node(node, "device/vif/ip");
> -                if (VIR_STRDUP(net->data.bridge.ipaddr, tmp) < 0)
> +                if (tmp && virDomainNetAppendIpAddress(net, tmp, AF_UNSPEC,
> 0) < 0) goto cleanup;
>              } else {
>                  net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
>                  if (VIR_STRDUP(net->script, tmp2) < 0)
>                      goto cleanup;
>                  tmp = sexpr_node(node, "device/vif/ip");
> -                if (VIR_STRDUP(net->data.ethernet.ipaddr, tmp) < 0)
> +                if (tmp && virDomainNetAppendIpAddress(net, tmp, AF_UNSPEC,
> 0) < 0) goto cleanup;
>              }
> 
> @@ -1898,8 +1898,11 @@ xenFormatSxprNet(virConnectPtr conn,
>              script = def->script;
> 
>          virBufferEscapeSexpr(buf, "(script '%s')", script);
> -        if (def->data.bridge.ipaddr != NULL)
> -            virBufferEscapeSexpr(buf, "(ip '%s')",
> def->data.bridge.ipaddr); +        if (def->nips > 0) {
> +            char *ipStr = virSocketAddrFormat(&def->ips[0]->address);
> +            virBufferEscapeSexpr(buf, "(ip '%s')", ipStr);
> +            VIR_FREE(ipStr);
> +        }
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_NETWORK:
> @@ -1932,8 +1935,11 @@ xenFormatSxprNet(virConnectPtr conn,
>          if (def->script)
>              virBufferEscapeSexpr(buf, "(script '%s')",
>                                   def->script);
> -        if (def->data.ethernet.ipaddr != NULL)
> -            virBufferEscapeSexpr(buf, "(ip '%s')",
> def->data.ethernet.ipaddr); +        if (def->nips > 0) {
> +            char *ipStr = virSocketAddrFormat(&def->ips[0]->address);
> +            virBufferEscapeSexpr(buf, "(ip '%s')", ipStr);
> +            VIR_FREE(ipStr);
> +        }
>          break;
> 
>      case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
> diff --git a/tests/lxcxml2xmldata/lxc-idmap.xml
> b/tests/lxcxml2xmldata/lxc-idmap.xml index 946d363..d011927 100644
> --- a/tests/lxcxml2xmldata/lxc-idmap.xml
> +++ b/tests/lxcxml2xmldata/lxc-idmap.xml
> @@ -28,6 +28,8 @@
>      <interface type='bridge'>
>        <mac address='00:16:3e:0f:ef:8a'/>
>        <source bridge='bri0'/>
> +      <ip address='192.168.122.12' family='ipv4' prefix='24'/>
> +      <ip address='192.168.122.13' family='ipv4' prefix='24'/>
>        <target dev='veth0'/>
>        <guest dev='eth2'/>
>      </interface>
> diff --git a/tests/openvzutilstest.c b/tests/openvzutilstest.c
> index ed2c098..bcf48db 100644
> --- a/tests/openvzutilstest.c
> +++ b/tests/openvzutilstest.c
> @@ -95,7 +95,7 @@ testReadNetworkConf(const void *data ATTRIBUTE_UNUSED)
>          "  <devices>\n"
>          "    <interface type='ethernet'>\n"
>          "      <mac address='00:00:00:00:00:00'/>\n"
> -        "      <ip address='194.44.18.88'/>\n"
> +        "      <ip address='194.44.18.88' family='ipv4'/>\n"
>          "    </interface>\n"
>          "    <interface type='bridge'>\n"
>          "      <mac address='00:18:51:c1:05:ee'/>\n"
> diff --git a/tests/sexpr2xmldata/sexpr2xml-bridge-ipaddr.xml
> b/tests/sexpr2xmldata/sexpr2xml-bridge-ipaddr.xml index 9b5cc3a..25a29fd
> 100644
> --- a/tests/sexpr2xmldata/sexpr2xml-bridge-ipaddr.xml
> +++ b/tests/sexpr2xmldata/sexpr2xml-bridge-ipaddr.xml
> @@ -24,7 +24,7 @@
>      <interface type='bridge'>
>        <mac address='00:11:22:33:44:55'/>
>        <source bridge='xenbr2'/>
> -      <ip address='192.0.2.1'/>
> +      <ip address='192.0.2.1' family='ipv4'/>
>        <script path='vif-bridge'/>
>        <target dev='vif6.0'/>
>      </interface>
> diff --git a/tests/sexpr2xmldata/sexpr2xml-net-routed.xml
> b/tests/sexpr2xmldata/sexpr2xml-net-routed.xml index 0ab3b6d..c03e40b
> 100644
> --- a/tests/sexpr2xmldata/sexpr2xml-net-routed.xml
> +++ b/tests/sexpr2xmldata/sexpr2xml-net-routed.xml
> @@ -23,7 +23,7 @@
>      </disk>
>      <interface type='ethernet'>
>        <mac address='00:11:22:33:44:55'/>
> -      <ip address='172.14.5.6'/>
> +      <ip address='172.14.5.6' family='ipv4'/>
>        <script path='vif-routed'/>
>        <target dev='vif6.0'/>
>      </interface>

-- 
Dmitry Guryanov




More information about the libvir-list mailing list