[PATCH 4/5] conf, docs, schemas: Add support for interface type vds

Martin Kletzander mkletzan at redhat.com
Tue Aug 30 12:44:38 UTC 2022


On Tue, Aug 30, 2022 at 12:48:49PM +0100, Daniel P. Berrangé wrote:
>On Wed, Aug 17, 2022 at 02:50:39PM +0200, Martin Kletzander wrote:
>> This represents an interface connected to a VMWare Distributed Switch,
>> previously obscured as a dummy interface.
>>
>> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
>> ---
>>  docs/formatdomain.rst             | 30 +++++++++++----
>>  src/ch/ch_monitor.c               |  1 +
>>  src/conf/domain_conf.c            | 64 +++++++++++++++++++++++++++++++
>>  src/conf/domain_conf.h            |  7 ++++
>>  src/conf/netdev_bandwidth_conf.c  |  1 +
>>  src/conf/schemas/domaincommon.rng | 23 +++++++++++
>>  src/libxl/libxl_conf.c            |  1 +
>>  src/libxl/xen_common.c            |  1 +
>>  src/lxc/lxc_controller.c          |  1 +
>>  src/lxc/lxc_driver.c              |  3 ++
>>  src/lxc/lxc_process.c             |  2 +
>>  src/qemu/qemu_command.c           |  4 ++
>>  src/qemu/qemu_domain.c            |  1 +
>>  src/qemu/qemu_hotplug.c           |  3 ++
>>  src/qemu/qemu_interface.c         |  2 +
>>  src/qemu/qemu_process.c           |  2 +
>>  src/qemu/qemu_validate.c          |  1 +
>>  src/vmx/vmx.c                     |  1 +
>>  tools/virsh-domain.c              |  1 +
>>  19 files changed, 141 insertions(+), 8 deletions(-)
>>
>> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
>> index ed0d9c19593b..3a8aa96fdc0a 100644
>> --- a/docs/formatdomain.rst
>> +++ b/docs/formatdomain.rst
>> @@ -5244,22 +5244,36 @@ Dummy network interface
>>  ^^^^^^^^^^^^^^^^^^^^^^^
>>
>>  An unconnected network interface sounds pretty pointless, but can show up for
>> -example with VMWare when libvirt does not have any more information to provide.
>> -Two such scenarios are currently known:
>> +example with VMWare without any specified network to be connected to.
>> +:since:`Since 8.7.0`
>>
>> -1) network interface exists, but is not connected to any existing network
>> -2) the interface is connected to something known as VMWare Distributed Switch
>> +::
>> +
>> +   ...
>> +   <devices>
>> +     <interface type='dummy'>
>> +       <mac address='52:54:00:22:c9:42'/>
>> +     </interface>
>> +   </devices>
>> +   ...
>>
>> -The difference between these two is not (yet?) discoverable by libvirt, so at
>> -least the information gathered from the hypervisor is provided in the
>> -element. :since:`Since 8.7.0`
>> +VMWare Distributed Switch
>> +^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +Interface can be connected to VMWare Distributed Switch, but since libvirt
>> +cannot provide information about that architecture, the information presented
>> +here is only what can be gathered from the VM configuration.  VMs with this
>> +interface type can be created, so that editing of the XML works properly,
>> +however libvirt cannot guarantee that any changes in these parameters will be
>> +valid in the hypervisor. :since:`Since 8.7.0`
>>
>>  ::
>>
>>     ...
>>     <devices>
>> -     <interface type='dummy'>
>> +     <interface type='vds'>
>>         <mac address='52:54:00:22:c9:42'/>
>> +       <source switchid='12345678-1234-1234-1234-123456789abc' portid='6' portgroupid='pg-4321' connectionid='12345'/>
>>       </interface>
>>     </devices>
>>     ...
>
>
>
>> @@ -8899,6 +8905,8 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
>>      g_autofree char *vhost_path = NULL;
>>      g_autofree char *tap = NULL;
>>      g_autofree char *vhost = NULL;
>> +    g_autofree char *switchid = NULL;
>> +    g_autofree char *connectionid = NULL;
>>      const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL;
>>
>>      if (!(def = virDomainNetDefNew(xmlopt)))
>> @@ -8932,6 +8940,13 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
>>                  portid = virXMLPropString(source_node, "portid");
>>          }
>>
>> +        if (def->type == VIR_DOMAIN_NET_TYPE_VDS) {
>> +            switchid = virXMLPropString(source_node, "switchid");
>> +            portid = virXMLPropString(source_node, "portid");
>> +            portgroup = virXMLPropString(source_node, "portgroupid");
>> +            connectionid = virXMLPropString(source_node, "connectionid");
>> +        }
>> +
>>          if (def->type == VIR_DOMAIN_NET_TYPE_INTERNAL)
>>              internal = virXMLPropString(source_node, "name");
>>
>> @@ -9313,6 +9328,36 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
>>          }
>>          break;
>>
>> +    case VIR_DOMAIN_NET_TYPE_VDS:
>> +        if (!switchid) {
>> +            virReportError(VIR_ERR_XML_ERROR,
>> +                           _("Missing source switchid for interface type '%s'"),
>> +                           virDomainNetTypeToString(def->type));
>> +            goto error;
>> +        }
>> +
>> +        if (virUUIDParse(switchid, def->data.vds.switch_id) < 0) {
>> +            virReportError(VIR_ERR_INTERNAL_ERROR,
>> +                           _("Unable to parse switchid '%s'"), switchid);
>> +            goto error;
>> +        }
>
>Report if  switch id is missing, which is good.
>
>> +
>> +        if (virStrToLong_ll(portid, NULL, 0, &def->data.vds.port_id) < 0) {
>> +            virReportError(VIR_ERR_INTERNAL_ERROR,
>> +                           _("Unable to parse portid '%s'"), portid);
>> +            goto error;
>> +        }
>> +
>> +        if (virStrToLong_ll(connectionid, NULL, 0, &def->data.vds.connection_id) < 0) {
>> +            virReportError(VIR_ERR_INTERNAL_ERROR,
>> +                           _("Unable to parse connectionid '%s'"), connectionid);
>> +            goto error;
>> +        }
>
>AFAICT, this may well crash if port id or connedtion id are missing,
>since it ends up passing NULL to strtol which is not defined to
>allow NULL IIUC.
>
>> +
>> +        def->data.vds.portgroup_id = g_steal_pointer(&portgroup);
>
>Allows portgroup id to be missing
>
>> +
>> +        break;
>> +
>>      case VIR_DOMAIN_NET_TYPE_ETHERNET:
>>      case VIR_DOMAIN_NET_TYPE_USER:
>>      case VIR_DOMAIN_NET_TYPE_DUMMY:
>> @@ -9495,6 +9540,7 @@ virDomainNetDefParseXML(virDomainXMLOption *xmlopt,
>>          case VIR_DOMAIN_NET_TYPE_HOSTDEV:
>>          case VIR_DOMAIN_NET_TYPE_UDP:
>>          case VIR_DOMAIN_NET_TYPE_DUMMY:
>> +        case VIR_DOMAIN_NET_TYPE_VDS:
>>          case VIR_DOMAIN_NET_TYPE_VDPA:
>>              break;
>>          case VIR_DOMAIN_NET_TYPE_LAST:
>> @@ -23683,7 +23729,21 @@ virDomainNetDefFormat(virBuffer *buf,
>>                                       def->data.vdpa.devicepath);
>>                 sourceLines++;
>>             }
>> +           break;
>> +
>> +        case VIR_DOMAIN_NET_TYPE_VDS: {
>> +            char switchidstr[VIR_UUID_STRING_BUFLEN];
>> +
>> +            virUUIDFormat(def->data.vds.switch_id, switchidstr);
>> +            virBufferEscapeString(buf, "<source switchid='%s'", switchidstr);
>> +            virBufferAsprintf(buf, " portid='%lld'", def->data.vds.port_id);
>> +            virBufferEscapeString(buf, " portgroupid='%s'", def->data.vds.portgroup_id);
>> +            virBufferAsprintf(buf, " connectionid='%lld'", def->data.vds.connection_id);
>
>Based on this logic  switch id, port id and connection id are mandatory, but
>missing portgroup_id would be handled gracefully.
>
>> +
>> +            sourceLines++;
>> +
>>              break;
>> +        }
>>
>>          case VIR_DOMAIN_NET_TYPE_USER:
>>          case VIR_DOMAIN_NET_TYPE_DUMMY:
>
>> diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
>> index 5d530f957b0d..7f6ea1d8887d 100644
>> --- a/src/conf/schemas/domaincommon.rng
>> +++ b/src/conf/schemas/domaincommon.rng
>> @@ -3440,6 +3440,29 @@
>>            <ref name="interface-options"/>
>>          </group>
>>
>> +        <group>
>> +          <attribute name="type">
>> +            <value>vds</value>
>> +          </attribute>
>> +          <interleave>
>> +            <element name="source">
>> +              <attribute name="switchid">
>> +                <ref name="UUID"/>
>> +              </attribute>
>> +              <attribute name="portid">
>> +                <data type="long"/>
>> +              </attribute>
>> +              <attribute name="portgroupid">
>> +                <data type="string"/>
>> +              </attribute>
>> +              <attribute name="connectionid">
>> +                <data type="long"/>
>> +              </attribute>
>
>Indicates all attributes are mandatory even though the code gracefully
>handles port group ID being missing.
>
>Overall there's some error checking missing when parsing I believe,
>or this needs relaxing for port group ID.
>

Definitely more checks, I sent them now so that we can make it before
release.  Thanks for finding this out.

>> +            </element>
>> +            <ref name="interface-options"/>
>> +          </interleave>
>> +        </group>
>> +
>>        </choice>
>>        <optional>
>>          <attribute name="trustGuestRxFilters">
>
>With regards,
>Daniel
>-- 
>|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
>|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
>|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20220830/3cf43fcd/attachment.sig>


More information about the libvir-list mailing list