a41c76
From 653245c4de76aba4e75131da8d40eed5b15ffd0d Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <653245c4de76aba4e75131da8d40eed5b15ffd0d@dist-git>
a41c76
From: Laine Stump <laine@redhat.com>
a41c76
Date: Thu, 30 Jan 2020 14:12:40 -0500
a41c76
Subject: [PATCH] conf: parse/format <teaming> subelement of <interface>
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
The subelement <teaming> of <interface> devices is used to configure a
a41c76
simple teaming association between two interfaces in a domain. Example:
a41c76
a41c76
  <interface type='bridge'>
a41c76
    <source bridge='br0'/>
a41c76
    <model type='virtio'/>
a41c76
    <mac address='00:11:22:33:44:55'/>
a41c76
    <alias name='ua-backup0'/>
a41c76
    <teaming type='persistent'/>
a41c76
  </interface>
a41c76
  <interface type='hostdev'>
a41c76
    <source>
a41c76
      <address type='pci' bus='0x02' slot='0x10' function='0x4'/>
a41c76
    </source>
a41c76
    <mac address='00:11:22:33:44:55'/>
a41c76
    <teaming type='transient' persistent='ua-backup0'/>
a41c76
  </interface>
a41c76
a41c76
The interface with <teaming type='persistent'/> is assumed to always
a41c76
be present, while the interface with type='transient' may be be
a41c76
unplugged and later re-plugged; the persistent='blah' attribute (and
a41c76
in the one currently available implementation, also the matching MAC
a41c76
addresses) is what associates the two devices with each other. It is
a41c76
up to the hypervisor and the guest network drivers to determine what
a41c76
to do with this information.
a41c76
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
a41c76
(cherry picked from commit fb0509d06ac57434c2edbd81ee63deb32a0e598a)
a41c76
a41c76
https://bugzilla.redhat.com/1693587
a41c76
Signed-off-by: Laine Stump <laine@redhat.com>
a41c76
Message-Id: <20200130191244.24174-3-laine@redhat.com>
a41c76
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
a41c76
---
a41c76
 docs/schemas/domaincommon.rng                 | 19 ++++++
a41c76
 src/conf/domain_conf.c                        | 47 +++++++++++++
a41c76
 src/conf/domain_conf.h                        | 14 ++++
a41c76
 .../net-virtio-teaming-network.xml            | 37 +++++++++++
a41c76
 tests/qemuxml2argvdata/net-virtio-teaming.xml | 50 ++++++++++++++
a41c76
 .../net-virtio-teaming-network.xml            | 51 ++++++++++++++
a41c76
 .../qemuxml2xmloutdata/net-virtio-teaming.xml | 66 +++++++++++++++++++
a41c76
 tests/qemuxml2xmltest.c                       |  6 ++
a41c76
 8 files changed, 290 insertions(+)
a41c76
 create mode 100644 tests/qemuxml2argvdata/net-virtio-teaming-network.xml
a41c76
 create mode 100644 tests/qemuxml2argvdata/net-virtio-teaming.xml
a41c76
 create mode 100644 tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
a41c76
 create mode 100644 tests/qemuxml2xmloutdata/net-virtio-teaming.xml
a41c76
a41c76
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
a41c76
index 76d94b156f..026e753567 100644
a41c76
--- a/docs/schemas/domaincommon.rng
a41c76
+++ b/docs/schemas/domaincommon.rng
a41c76
@@ -3158,6 +3158,25 @@
a41c76
       <optional>
a41c76
         <ref name="vlan"/>
a41c76
       </optional>
a41c76
+      <optional>
a41c76
+        <element name="teaming">
a41c76
+          <choice>
a41c76
+            <group>
a41c76
+              <attribute name="type">
a41c76
+                <value>persistent</value>
a41c76
+              </attribute>
a41c76
+            </group>
a41c76
+            <group>
a41c76
+              <attribute name="type">
a41c76
+                <value>transient</value>
a41c76
+              </attribute>
a41c76
+              <attribute name="persistent">
a41c76
+                <ref name="aliasName"/>
a41c76
+              </attribute>
a41c76
+            </group>
a41c76
+          </choice>
a41c76
+        </element>
a41c76
+      </optional>
a41c76
     </interleave>
a41c76
   </define>
a41c76
 
a41c76
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
a41c76
index 0478914c69..58f72b3b0f 100644
a41c76
--- a/src/conf/domain_conf.c
a41c76
+++ b/src/conf/domain_conf.c
a41c76
@@ -554,6 +554,13 @@ VIR_ENUM_IMPL(virDomainNetVirtioTxMode,
a41c76
               "timer",
a41c76
 );
a41c76
 
a41c76
+VIR_ENUM_IMPL(virDomainNetTeaming,
a41c76
+              VIR_DOMAIN_NET_TEAMING_TYPE_LAST,
a41c76
+              "none",
a41c76
+              "persistent",
a41c76
+              "transient",
a41c76
+);
a41c76
+
a41c76
 VIR_ENUM_IMPL(virDomainNetInterfaceLinkState,
a41c76
               VIR_DOMAIN_NET_INTERFACE_LINK_STATE_LAST,
a41c76
               "default",
a41c76
@@ -6276,6 +6283,21 @@ virDomainNetDefValidate(const virDomainNetDef *net)
a41c76
                        virDomainNetTypeToString(net->type));
a41c76
         return -1;
a41c76
     }
a41c76
+
a41c76
+    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) {
a41c76
+        if (!net->teaming.persistent) {
a41c76
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
a41c76
+                           _("teaming persistent attribute must be set if teaming type is 'transient'"));
a41c76
+            return -1;
a41c76
+        }
a41c76
+    } else {
a41c76
+        if (net->teaming.persistent) {
a41c76
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
a41c76
+                           _("teaming persistent attribute not allowed if teaming type is '%s'"),
a41c76
+                           virDomainNetTeamingTypeToString(net->teaming.type));
a41c76
+            return -1;
a41c76
+        }
a41c76
+    }
a41c76
     return 0;
a41c76
 }
a41c76
 
a41c76
@@ -11574,6 +11596,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
a41c76
     g_autofree char *vhostuser_type = NULL;
a41c76
     g_autofree char *trustGuestRxFilters = NULL;
a41c76
     g_autofree char *vhost_path = NULL;
a41c76
+    g_autofree char *teamingType = NULL;
a41c76
+    g_autofree char *teamingPersistent = NULL;
a41c76
     const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL;
a41c76
 
a41c76
     if (!(def = virDomainNetDefNew(xmlopt)))
a41c76
@@ -11775,6 +11799,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
a41c76
                 if (!vhost_path && (tmp = virXMLPropString(cur, "vhost")))
a41c76
                     vhost_path = virFileSanitizePath(tmp);
a41c76
                 VIR_FREE(tmp);
a41c76
+            } else if (virXMLNodeNameEqual(cur, "teaming") &&
a41c76
+                       !teamingType && !teamingPersistent) {
a41c76
+                teamingType = virXMLPropString(cur, "type");
a41c76
+                teamingPersistent =  virXMLPropString(cur, "persistent");
a41c76
             }
a41c76
         }
a41c76
         cur = cur->next;
a41c76
@@ -12296,6 +12324,19 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
a41c76
         }
a41c76
     }
a41c76
 
a41c76
+    if (teamingType) {
a41c76
+        int tmpTeaming;
a41c76
+
a41c76
+        if ((tmpTeaming = virDomainNetTeamingTypeFromString(teamingType)) <= 0) {
a41c76
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
a41c76
+                           _("unknown teaming type '%s'"),
a41c76
+                           teamingType);
a41c76
+            goto error;
a41c76
+        }
a41c76
+        def->teaming.type = tmpTeaming;
a41c76
+    }
a41c76
+    def->teaming.persistent = g_steal_pointer(&teamingPersistent);
a41c76
+
a41c76
     rv = virXPathULong("string(./tune/sndbuf)", ctxt, &def->tune.sndbuf);
a41c76
     if (rv >= 0) {
a41c76
         def->tune.sndbuf_specified = true;
a41c76
@@ -25741,6 +25782,12 @@ virDomainNetDefFormat(virBufferPtr buf,
a41c76
         virBufferAddLit(buf,   "</tune>\n");
a41c76
     }
a41c76
 
a41c76
+    if (def->teaming.type != VIR_DOMAIN_NET_TEAMING_TYPE_NONE) {
a41c76
+        virBufferAsprintf(buf, "
a41c76
+                          virDomainNetTeamingTypeToString(def->teaming.type));
a41c76
+        virBufferEscapeString(buf, " persistent='%s'", def->teaming.persistent);
a41c76
+        virBufferAddLit(buf, "/>\n");
a41c76
+    }
a41c76
     if (def->linkstate) {
a41c76
         virBufferAsprintf(buf, "<link state='%s'/>\n",
a41c76
                           virDomainNetInterfaceLinkStateTypeToString(def->linkstate));
a41c76
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
a41c76
index 6ae89fa498..ee8eb3ddc0 100644
a41c76
--- a/src/conf/domain_conf.h
a41c76
+++ b/src/conf/domain_conf.h
a41c76
@@ -884,6 +884,15 @@ typedef enum {
a41c76
     VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST
a41c76
 } virDomainNetVirtioTxModeType;
a41c76
 
a41c76
+/* the type of teaming device */
a41c76
+typedef enum {
a41c76
+    VIR_DOMAIN_NET_TEAMING_TYPE_NONE,
a41c76
+    VIR_DOMAIN_NET_TEAMING_TYPE_PERSISTENT,
a41c76
+    VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT,
a41c76
+
a41c76
+    VIR_DOMAIN_NET_TEAMING_TYPE_LAST
a41c76
+} virDomainNetTeamingType;
a41c76
+
a41c76
 /* link interface states */
a41c76
 typedef enum {
a41c76
         VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT = 0, /* Default link state (up) */
a41c76
@@ -958,6 +967,10 @@ struct _virDomainNetDef {
a41c76
         char *tap;
a41c76
         char *vhost;
a41c76
     } backend;
a41c76
+    struct {
a41c76
+        virDomainNetTeamingType type;
a41c76
+        char *persistent; /* alias name of persistent device */
a41c76
+    } teaming;
a41c76
     union {
a41c76
         virDomainChrSourceDefPtr vhostuser;
a41c76
         struct {
a41c76
@@ -3425,6 +3438,7 @@ VIR_ENUM_DECL(virDomainFSModel);
a41c76
 VIR_ENUM_DECL(virDomainNet);
a41c76
 VIR_ENUM_DECL(virDomainNetBackend);
a41c76
 VIR_ENUM_DECL(virDomainNetVirtioTxMode);
a41c76
+VIR_ENUM_DECL(virDomainNetTeaming);
a41c76
 VIR_ENUM_DECL(virDomainNetInterfaceLinkState);
a41c76
 VIR_ENUM_DECL(virDomainNetModel);
a41c76
 VIR_ENUM_DECL(virDomainChrDevice);
a41c76
diff --git a/tests/qemuxml2argvdata/net-virtio-teaming-network.xml b/tests/qemuxml2argvdata/net-virtio-teaming-network.xml
a41c76
new file mode 100644
a41c76
index 0000000000..edab52f3a1
a41c76
--- /dev/null
a41c76
+++ b/tests/qemuxml2argvdata/net-virtio-teaming-network.xml
a41c76
@@ -0,0 +1,37 @@
a41c76
+<domain type='qemu'>
a41c76
+  <name>QEMUGuest1</name>
a41c76
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
a41c76
+  <memory unit='KiB'>219100</memory>
a41c76
+  <currentMemory unit='KiB'>219100</currentMemory>
a41c76
+  <vcpu placement='static'>1</vcpu>
a41c76
+  <os>
a41c76
+    <type arch='i686' machine='pc'>hvm</type>
a41c76
+    <boot dev='hd'/>
a41c76
+  </os>
a41c76
+  <clock offset='utc'/>
a41c76
+  <on_poweroff>destroy</on_poweroff>
a41c76
+  <on_reboot>restart</on_reboot>
a41c76
+  <on_crash>destroy</on_crash>
a41c76
+  <devices>
a41c76
+    <emulator>/usr/bin/qemu-system-i386</emulator>
a41c76
+    <disk type='block' device='disk'>
a41c76
+      <source dev='/dev/HostVG/QEMUGuest1'/>
a41c76
+      <target dev='hda' bus='ide'/>
a41c76
+    </disk>
a41c76
+    <controller type='usb' index='0'/>
a41c76
+    <interface type='network'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source network='mybridge'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup0'/>
a41c76
+    </interface>
a41c76
+    <interface type='network'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source network='myhostdevpool'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='transient' persistent='ua-backup0'/>
a41c76
+    </interface>
a41c76
+    <memballoon model='virtio'/>
a41c76
+  </devices>
a41c76
+</domain>
a41c76
diff --git a/tests/qemuxml2argvdata/net-virtio-teaming.xml b/tests/qemuxml2argvdata/net-virtio-teaming.xml
a41c76
new file mode 100644
a41c76
index 0000000000..830ce28524
a41c76
--- /dev/null
a41c76
+++ b/tests/qemuxml2argvdata/net-virtio-teaming.xml
a41c76
@@ -0,0 +1,50 @@
a41c76
+<domain type='qemu'>
a41c76
+  <name>QEMUGuest1</name>
a41c76
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
a41c76
+  <memory unit='KiB'>219100</memory>
a41c76
+  <currentMemory unit='KiB'>219100</currentMemory>
a41c76
+  <vcpu placement='static'>1</vcpu>
a41c76
+  <os>
a41c76
+    <type arch='i686' machine='pc'>hvm</type>
a41c76
+    <boot dev='hd'/>
a41c76
+  </os>
a41c76
+  <clock offset='utc'/>
a41c76
+  <on_poweroff>destroy</on_poweroff>
a41c76
+  <on_reboot>restart</on_reboot>
a41c76
+  <on_crash>destroy</on_crash>
a41c76
+  <devices>
a41c76
+    <emulator>/usr/bin/qemu-system-i386</emulator>
a41c76
+    <disk type='block' device='disk'>
a41c76
+      <source dev='/dev/HostVG/QEMUGuest1'/>
a41c76
+      <target dev='hda' bus='ide'/>
a41c76
+    </disk>
a41c76
+    <controller type='usb' index='0'/>
a41c76
+    <interface type='user'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup0'/>
a41c76
+    </interface>
a41c76
+    <interface type='user'>
a41c76
+      <mac address='66:44:33:22:11:00'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup1'/>
a41c76
+    </interface>
a41c76
+    <interface type='hostdev' managed='yes'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source>
a41c76
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
a41c76
+      </source>
a41c76
+      <teaming type='transient' persistent='ua-backup0'/>
a41c76
+    </interface>
a41c76
+    <interface type='hostdev' managed='yes'>
a41c76
+      <mac address='66:44:33:22:11:00'/>
a41c76
+      <source>
a41c76
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
a41c76
+      </source>
a41c76
+      <teaming type='transient' persistent='ua-backup1'/>
a41c76
+    </interface>
a41c76
+    <memballoon model='virtio'/>
a41c76
+  </devices>
a41c76
+</domain>
a41c76
diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
a41c76
new file mode 100644
a41c76
index 0000000000..e0dbeafe02
a41c76
--- /dev/null
a41c76
+++ b/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
a41c76
@@ -0,0 +1,51 @@
a41c76
+<domain type='qemu'>
a41c76
+  <name>QEMUGuest1</name>
a41c76
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
a41c76
+  <memory unit='KiB'>219100</memory>
a41c76
+  <currentMemory unit='KiB'>219100</currentMemory>
a41c76
+  <vcpu placement='static'>1</vcpu>
a41c76
+  <os>
a41c76
+    <type arch='i686' machine='pc'>hvm</type>
a41c76
+    <boot dev='hd'/>
a41c76
+  </os>
a41c76
+  <clock offset='utc'/>
a41c76
+  <on_poweroff>destroy</on_poweroff>
a41c76
+  <on_reboot>restart</on_reboot>
a41c76
+  <on_crash>destroy</on_crash>
a41c76
+  <devices>
a41c76
+    <emulator>/usr/bin/qemu-system-i386</emulator>
a41c76
+    <disk type='block' device='disk'>
a41c76
+      <driver name='qemu' type='raw'/>
a41c76
+      <source dev='/dev/HostVG/QEMUGuest1'/>
a41c76
+      <target dev='hda' bus='ide'/>
a41c76
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
a41c76
+    </disk>
a41c76
+    <controller type='usb' index='0'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
a41c76
+    </controller>
a41c76
+    <controller type='pci' index='0' model='pci-root'/>
a41c76
+    <controller type='ide' index='0'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
a41c76
+    </controller>
a41c76
+    <interface type='network'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source network='mybridge'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup0'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <interface type='network'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source network='myhostdevpool'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='transient' persistent='ua-backup0'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <input type='mouse' bus='ps2'/>
a41c76
+    <input type='keyboard' bus='ps2'/>
a41c76
+    <memballoon model='virtio'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
a41c76
+    </memballoon>
a41c76
+  </devices>
a41c76
+</domain>
a41c76
diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming.xml
a41c76
new file mode 100644
a41c76
index 0000000000..5a5695794a
a41c76
--- /dev/null
a41c76
+++ b/tests/qemuxml2xmloutdata/net-virtio-teaming.xml
a41c76
@@ -0,0 +1,66 @@
a41c76
+<domain type='qemu'>
a41c76
+  <name>QEMUGuest1</name>
a41c76
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
a41c76
+  <memory unit='KiB'>219100</memory>
a41c76
+  <currentMemory unit='KiB'>219100</currentMemory>
a41c76
+  <vcpu placement='static'>1</vcpu>
a41c76
+  <os>
a41c76
+    <type arch='i686' machine='pc'>hvm</type>
a41c76
+    <boot dev='hd'/>
a41c76
+  </os>
a41c76
+  <clock offset='utc'/>
a41c76
+  <on_poweroff>destroy</on_poweroff>
a41c76
+  <on_reboot>restart</on_reboot>
a41c76
+  <on_crash>destroy</on_crash>
a41c76
+  <devices>
a41c76
+    <emulator>/usr/bin/qemu-system-i386</emulator>
a41c76
+    <disk type='block' device='disk'>
a41c76
+      <driver name='qemu' type='raw'/>
a41c76
+      <source dev='/dev/HostVG/QEMUGuest1'/>
a41c76
+      <target dev='hda' bus='ide'/>
a41c76
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
a41c76
+    </disk>
a41c76
+    <controller type='usb' index='0'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
a41c76
+    </controller>
a41c76
+    <controller type='pci' index='0' model='pci-root'/>
a41c76
+    <controller type='ide' index='0'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
a41c76
+    </controller>
a41c76
+    <interface type='user'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup0'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <interface type='user'>
a41c76
+      <mac address='66:44:33:22:11:00'/>
a41c76
+      <model type='virtio'/>
a41c76
+      <teaming type='persistent'/>
a41c76
+      <alias name='ua-backup1'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <interface type='hostdev' managed='yes'>
a41c76
+      <mac address='00:11:22:33:44:55'/>
a41c76
+      <source>
a41c76
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
a41c76
+      </source>
a41c76
+      <teaming type='transient' persistent='ua-backup0'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <interface type='hostdev' managed='yes'>
a41c76
+      <mac address='66:44:33:22:11:00'/>
a41c76
+      <source>
a41c76
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
a41c76
+      </source>
a41c76
+      <teaming type='transient' persistent='ua-backup1'/>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
a41c76
+    </interface>
a41c76
+    <input type='mouse' bus='ps2'/>
a41c76
+    <input type='keyboard' bus='ps2'/>
a41c76
+    <memballoon model='virtio'>
a41c76
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
a41c76
+    </memballoon>
a41c76
+  </devices>
a41c76
+</domain>
a41c76
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
a41c76
index 3cefc64833..e54c540ef6 100644
a41c76
--- a/tests/qemuxml2xmltest.c
a41c76
+++ b/tests/qemuxml2xmltest.c
a41c76
@@ -451,6 +451,12 @@ mymain(void)
a41c76
     DO_TEST("net-eth-unmanaged-tap", NONE);
a41c76
     DO_TEST("net-virtio-network-portgroup", NONE);
a41c76
     DO_TEST("net-virtio-rxtxqueuesize", NONE);
a41c76
+    DO_TEST("net-virtio-teaming",
a41c76
+            QEMU_CAPS_VIRTIO_NET_FAILOVER,
a41c76
+            QEMU_CAPS_DEVICE_VFIO_PCI);
a41c76
+    DO_TEST("net-virtio-teaming-network",
a41c76
+            QEMU_CAPS_VIRTIO_NET_FAILOVER,
a41c76
+            QEMU_CAPS_DEVICE_VFIO_PCI);
a41c76
     DO_TEST("net-hostdev", NONE);
a41c76
     DO_TEST("net-hostdev-bootorder", NONE);
a41c76
     DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI);
a41c76
-- 
a41c76
2.25.0
a41c76