d759b5
From ac2be13722d4533246a4ec3bc37b07d6e3fc9882 Mon Sep 17 00:00:00 2001
d759b5
Message-Id: <ac2be13722d4533246a4ec3bc37b07d6e3fc9882@dist-git>
d759b5
From: Laine Stump <laine@redhat.com>
d759b5
Date: Mon, 16 Sep 2019 09:54:05 -0400
d759b5
Subject: [PATCH] qemu: move runtime netdev validation into a separate function
d759b5
MIME-Version: 1.0
d759b5
Content-Type: text/plain; charset=UTF-8
d759b5
Content-Transfer-Encoding: 8bit
d759b5
d759b5
The same validation should be done for both static network devices and
d759b5
hotplugged devices, but they are currently inconsistent. Move all the
d759b5
relevant validation from qemuBuildInterfaceCommandLine() into the new
d759b5
function qemuDomainValidateActualNetDef() and call the latter from
d759b5
the former.
d759b5
d759b5
Signed-off-by: Laine Stump <laine@redhat.com>
d759b5
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
d759b5
(cherry picked from commit 3cff23f7f16dc2b74d54f14b77790dc37df01ded)
d759b5
d759b5
  https://bugzilla.redhat.com/1502754
d759b5
d759b5
Conflicts:
d759b5
 * src/qemu/qemu_command.c - vhostuser check for queues > 1 was
d759b5
     moved upstream in commit 4de4e4bc9, so had to be removed from
d759b5
     the old location downstream.
d759b5
d759b5
 * src/qemu/qemu_domain.h - other functions were also added
d759b5
d759b5
Signed-off-by: Laine Stump <laine@redhat.com>
d759b5
Message-Id: <20190916135406.18523-3-laine@redhat.com>
d759b5
Reviewed-by: Ján Tomko <jtomko@redhat.com>
d759b5
---
d759b5
 src/qemu/qemu_command.c | 52 +--------------------------
d759b5
 src/qemu/qemu_domain.c  | 80 +++++++++++++++++++++++++++++++++++++++++
d759b5
 src/qemu/qemu_domain.h  |  4 +++
d759b5
 3 files changed, 85 insertions(+), 51 deletions(-)
d759b5
d759b5
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
d759b5
index 08660abbe4..237f8878b9 100644
d759b5
--- a/src/qemu/qemu_command.c
d759b5
+++ b/src/qemu/qemu_command.c
d759b5
@@ -8335,14 +8335,6 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
d759b5
         goto cleanup;
d759b5
     }
d759b5
 
d759b5
-    if (queues > 1 &&
d759b5
-        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
d759b5
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d759b5
-                       _("multi-queue is not supported for vhost-user "
d759b5
-                         "with this QEMU binary"));
d759b5
-        goto cleanup;
d759b5
-    }
d759b5
-
d759b5
     if (!(netdev = qemuBuildHostNetStr(net, driver,
d759b5
                                        NULL, 0, NULL, 0)))
d759b5
         goto cleanup;
d759b5
@@ -8404,50 +8396,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
d759b5
     if (!bootindex)
d759b5
         bootindex = net->info.bootIndex;
d759b5
 
d759b5
-    /* Currently nothing besides TAP devices supports multiqueue. */
d759b5
-    if (net->driver.virtio.queues > 0 &&
d759b5
-        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
d759b5
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
-                       _("Multiqueue network is not supported for: %s"),
d759b5
-                       virDomainNetTypeToString(actualType));
d759b5
+    if (qemuDomainValidateActualNetDef(net, qemuCaps) < 0)
d759b5
         return -1;
d759b5
-    }
d759b5
-
d759b5
-    /* and only TAP devices support nwfilter rules */
d759b5
-    if (net->filter) {
d759b5
-        virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net);
d759b5
-        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
-              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
-              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
d759b5
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
-                           _("filterref is not supported for "
d759b5
-                             "network interfaces of type %s"),
d759b5
-                           virDomainNetTypeToString(actualType));
d759b5
-            return -1;
d759b5
-        }
d759b5
-        if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) {
d759b5
-            /* currently none of the defined virtualport types support iptables */
d759b5
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
-                           _("filterref is not supported for "
d759b5
-                             "network interfaces with virtualport type %s"),
d759b5
-                           virNetDevVPortTypeToString(vport->virtPortType));
d759b5
-            return -1;
d759b5
-        }
d759b5
-    }
d759b5
-
d759b5
-    if (net->backend.tap &&
d759b5
-        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
-          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
d759b5
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
-                       _("Custom tap device path is not supported for: %s"),
d759b5
-                       virDomainNetTypeToString(actualType));
d759b5
-        return -1;
d759b5
-    }
d759b5
 
d759b5
     switch (actualType) {
d759b5
     case VIR_DOMAIN_NET_TYPE_NETWORK:
d759b5
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
d759b5
index 249ec4d259..e7d7a3baeb 100644
d759b5
--- a/src/qemu/qemu_domain.c
d759b5
+++ b/src/qemu/qemu_domain.c
d759b5
@@ -4353,6 +4353,86 @@ qemuDomainWatchdogDefValidate(const virDomainWatchdogDef *dev,
d759b5
 }
d759b5
 
d759b5
 
d759b5
+int
d759b5
+qemuDomainValidateActualNetDef(const virDomainNetDef *net,
d759b5
+                               virQEMUCapsPtr qemuCaps)
d759b5
+{
d759b5
+    /*
d759b5
+     * Validations that can only be properly checked at runtime (after
d759b5
+     * an <interface type='network'> has been resolved to its actual
d759b5
+     * type.
d759b5
+     *
d759b5
+     * (In its current form this function can still be called before
d759b5
+     * the actual type has been resolved (e.g. at domain definition
d759b5
+     * time), but only if the validations would SUCCEED for
d759b5
+     * type='network'.)
d759b5
+     */
d759b5
+    virDomainNetType actualType = virDomainNetGetActualType(net);
d759b5
+
d759b5
+    /* Only tap/macvtap devices support multiqueue. */
d759b5
+    if (net->driver.virtio.queues > 0) {
d759b5
+
d759b5
+        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
d759b5
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
+                           _("multiqueue network is not supported for: %s"),
d759b5
+                           virDomainNetTypeToString(actualType));
d759b5
+            return -1;
d759b5
+        }
d759b5
+
d759b5
+        if (net->driver.virtio.queues > 1 &&
d759b5
+            actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
d759b5
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
d759b5
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
d759b5
+                           _("multiqueue network is not supported for vhost-user "
d759b5
+                             "with this QEMU binary"));
d759b5
+            return -1;
d759b5
+        }
d759b5
+    }
d759b5
+
d759b5
+    /*
d759b5
+     * Only standard tap devices support nwfilter rules, and even then only
d759b5
+     * when *not* connected to an OVS bridge or midonet (indicated by having
d759b5
+     * a <virtualport> element in the config)
d759b5
+     */
d759b5
+    if (net->filter) {
d759b5
+        virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net);
d759b5
+        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
+              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
d759b5
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
+                           _("filterref is not supported for "
d759b5
+                             "network interfaces of type %s"),
d759b5
+                           virDomainNetTypeToString(actualType));
d759b5
+            return -1;
d759b5
+        }
d759b5
+        if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) {
d759b5
+            /* currently none of the defined virtualport types support iptables */
d759b5
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
+                           _("filterref is not supported for "
d759b5
+                             "network interfaces with virtualport type %s"),
d759b5
+                           virNetDevVPortTypeToString(vport->virtPortType));
d759b5
+            return -1;
d759b5
+        }
d759b5
+    }
d759b5
+
d759b5
+    if (net->backend.tap &&
d759b5
+        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
d759b5
+          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
d759b5
+          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
d759b5
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
d759b5
+                       _("Custom tap device path is not supported for: %s"),
d759b5
+                       virDomainNetTypeToString(actualType));
d759b5
+        return -1;
d759b5
+    }
d759b5
+
d759b5
+    return 0;
d759b5
+}
d759b5
+
d759b5
+
d759b5
 static int
d759b5
 qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net)
d759b5
 {
d759b5
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
d759b5
index 9546216f30..daed69e856 100644
d759b5
--- a/src/qemu/qemu_domain.h
d759b5
+++ b/src/qemu/qemu_domain.h
d759b5
@@ -1074,4 +1074,8 @@ char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv);
d759b5
 virDomainEventResumedDetailType
d759b5
 qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason);
d759b5
 
d759b5
+int
d759b5
+qemuDomainValidateActualNetDef(const virDomainNetDef *net,
d759b5
+                               virQEMUCapsPtr qemuCaps);
d759b5
+
d759b5
 #endif /* __QEMU_DOMAIN_H__ */
d759b5
-- 
d759b5
2.23.0
d759b5