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