[libvirt] [PATCHv3 05/16] Allow network capabilities hostdev to configure IP addresses

Daniel P. Berrange berrange at redhat.com
Wed Oct 22 10:09:57 UTC 2014


On Fri, Oct 10, 2014 at 02:03:57PM +0200, Cédric Bosdonnat wrote:
> ---
>  docs/formatdomain.html.in            | 12 +++++++--
>  docs/schemas/domaincommon.rng        | 23 +++++++++++++++---
>  src/conf/domain_conf.c               | 47 ++++++++++++++++++++++++++++++++++++
>  src/conf/domain_conf.h               |  2 ++
>  tests/lxcxml2xmldata/lxc-hostdev.xml |  2 ++
>  5 files changed, 80 insertions(+), 6 deletions(-)
> 
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 8e3a522..e07a298 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -4249,13 +4249,21 @@ qemu-kvm -net nic,model=? /dev/null
>        <target dev='vnet0'/>
>        <b><ip address='192.168.122.5' prefix='24'/></b>
>      </interface>
> +    ...
> +    <hostdev mode='capabilities' type='net'>
> +      <source>
> +        <interface>eth0</interface>
> +      </source>
> +      <b><ip address='192.168.122.6' prefix='24'/></b>
> +    </hostdev>
> +
>    </devices>
>    ...
>  </pre>
>  
>      <p>
> -    <span class="since">Since 1.2.10</span> the network devices can be provided
> -    zero or more IP addresses to set
> +    <span class="since">Since 1.2.10</span> the network devices and host devices
> +    with network capabilities 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>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index a82d705..5d955b0 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -3769,11 +3769,26 @@
>      <attribute name="type">
>        <value>net</value>
>      </attribute>
> -    <element name="source">
> -      <element name="interface">
> -        <ref name="deviceName"/>
> +    <interleave>
> +      <element name="source">
> +        <element name="interface">
> +          <ref name="deviceName"/>
> +        </element>
>        </element>
> -    </element>
> +      <zeroOrMore>
> +        <element name="ip">
> +          <attribute name="address">
> +            <ref name="ipAddr"/>
> +          </attribute>
> +          <optional>
> +            <attribute name="prefix">
> +              <ref name="ipPrefix"/>
> +            </attribute>
> +          </optional>
> +          <empty/>
> +        </element>
> +      </zeroOrMore>
> +    </interleave>
>    </define>
>  
>    <define name="usbproduct">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index c7ab962..f39be87 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1776,6 +1776,8 @@ virDomainHostdevSubsysSCSIiSCSIClear(virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc
>  
>  void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
>  {
> +    size_t i;
> +
>      if (!def)
>          return;
>  
> @@ -1800,6 +1802,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
>              break;
>          case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
>              VIR_FREE(def->source.caps.u.net.iface);
> +            for (i = 0; i < def->source.caps.u.net.nips; i++)
> +                virDomainNetIpDefFree(def->source.caps.u.net.ips[i]);
> +            VIR_FREE(def->source.caps.u.net.ips);
>              break;
>          }
>          break;
> @@ -4678,6 +4683,8 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
>                                  virDomainHostdevDefPtr def)
>  {
>      xmlNodePtr sourcenode;
> +    xmlNodePtr *ipnodes = NULL;
> +    int nipnodes;
>      int ret = -1;
>  
>      /* @type is passed in from the caller rather than read from the
> @@ -4732,6 +4739,40 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
>                             _("Missing <interface> element in hostdev net device"));
>              goto error;
>          }
> +
> +        /* Parse possible IP addresses */
> +        if ((nipnodes = virXPathNodeSet("./ip", ctxt, &ipnodes)) < 0)
> +            goto error;
> +
> +        if (nipnodes) {
> +            size_t i;
> +            for (i = 0; i < nipnodes; i++) {
> +                char *prefixStr = NULL;
> +                virDomainNetIpDefPtr ip = NULL;
> +
> +                if (VIR_ALLOC(ip) < 0)
> +                    goto error;
> +
> +                ip->address = virXMLPropString(ipnodes[i], "address");
> +
> +                if ((prefixStr = virXMLPropString(ipnodes[i], "prefix")) &&
> +                    (virStrToLong_ui(prefixStr, NULL, 10, &ip->prefix) < 0)) {
> +
> +                    virReportError(VIR_ERR_INVALID_ARG,
> +                                   _("Invalid network prefix: '%s'"),
> +                                   prefixStr);
> +                    VIR_FREE(prefixStr);
> +                    goto error;
> +                }
> +                VIR_FREE(prefixStr);
> +
> +                if (ip->address != NULL &&
> +                    VIR_APPEND_ELEMENT(def->source.caps.u.net.ips,
> +                                       def->source.caps.u.net.nips, ip) < 0)
> +                    goto error;
> +            }
> +            VIR_FREE(ipnodes);
> +        }

It would be nice if we can share the parsing of this with the parsingdone
in the <network> xml block. Since the XML schema is the same, I'd expect
we can have a single function that contains everything from the virXPathNodeSet("./ip")
onwards.


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