Blob Blame History Raw
From ac2be13722d4533246a4ec3bc37b07d6e3fc9882 Mon Sep 17 00:00:00 2001
Message-Id: <ac2be13722d4533246a4ec3bc37b07d6e3fc9882@dist-git>
From: Laine Stump <laine@redhat.com>
Date: Mon, 16 Sep 2019 09:54:05 -0400
Subject: [PATCH] qemu: move runtime netdev validation into a separate function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The same validation should be done for both static network devices and
hotplugged devices, but they are currently inconsistent. Move all the
relevant validation from qemuBuildInterfaceCommandLine() into the new
function qemuDomainValidateActualNetDef() and call the latter from
the former.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3cff23f7f16dc2b74d54f14b77790dc37df01ded)

  https://bugzilla.redhat.com/1502754

Conflicts:
 * src/qemu/qemu_command.c - vhostuser check for queues > 1 was
     moved upstream in commit 4de4e4bc9, so had to be removed from
     the old location downstream.

 * src/qemu/qemu_domain.h - other functions were also added

Signed-off-by: Laine Stump <laine@redhat.com>
Message-Id: <20190916135406.18523-3-laine@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
---
 src/qemu/qemu_command.c | 52 +--------------------------
 src/qemu/qemu_domain.c  | 80 +++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h  |  4 +++
 3 files changed, 85 insertions(+), 51 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 08660abbe4..237f8878b9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8335,14 +8335,6 @@ qemuBuildVhostuserCommandLine(virQEMUDriverPtr driver,
         goto cleanup;
     }
 
-    if (queues > 1 &&
-        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                       _("multi-queue is not supported for vhost-user "
-                         "with this QEMU binary"));
-        goto cleanup;
-    }
-
     if (!(netdev = qemuBuildHostNetStr(net, driver,
                                        NULL, 0, NULL, 0)))
         goto cleanup;
@@ -8404,50 +8396,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
     if (!bootindex)
         bootindex = net->info.bootIndex;
 
-    /* Currently nothing besides TAP devices supports multiqueue. */
-    if (net->driver.virtio.queues > 0 &&
-        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
-          actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
-          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
-          actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Multiqueue network is not supported for: %s"),
-                       virDomainNetTypeToString(actualType));
+    if (qemuDomainValidateActualNetDef(net, qemuCaps) < 0)
         return -1;
-    }
-
-    /* and only TAP devices support nwfilter rules */
-    if (net->filter) {
-        virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net);
-        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
-              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("filterref is not supported for "
-                             "network interfaces of type %s"),
-                           virDomainNetTypeToString(actualType));
-            return -1;
-        }
-        if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) {
-            /* currently none of the defined virtualport types support iptables */
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("filterref is not supported for "
-                             "network interfaces with virtualport type %s"),
-                           virNetDevVPortTypeToString(vport->virtPortType));
-            return -1;
-        }
-    }
-
-    if (net->backend.tap &&
-        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
-          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Custom tap device path is not supported for: %s"),
-                       virDomainNetTypeToString(actualType));
-        return -1;
-    }
 
     switch (actualType) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 249ec4d259..e7d7a3baeb 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4353,6 +4353,86 @@ qemuDomainWatchdogDefValidate(const virDomainWatchdogDef *dev,
 }
 
 
+int
+qemuDomainValidateActualNetDef(const virDomainNetDef *net,
+                               virQEMUCapsPtr qemuCaps)
+{
+    /*
+     * Validations that can only be properly checked at runtime (after
+     * an <interface type='network'> has been resolved to its actual
+     * type.
+     *
+     * (In its current form this function can still be called before
+     * the actual type has been resolved (e.g. at domain definition
+     * time), but only if the validations would SUCCEED for
+     * type='network'.)
+     */
+    virDomainNetType actualType = virDomainNetGetActualType(net);
+
+    /* Only tap/macvtap devices support multiqueue. */
+    if (net->driver.virtio.queues > 0) {
+
+        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+              actualType == VIR_DOMAIN_NET_TYPE_DIRECT ||
+              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
+              actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("multiqueue network is not supported for: %s"),
+                           virDomainNetTypeToString(actualType));
+            return -1;
+        }
+
+        if (net->driver.virtio.queues > 1 &&
+            actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("multiqueue network is not supported for vhost-user "
+                             "with this QEMU binary"));
+            return -1;
+        }
+    }
+
+    /*
+     * Only standard tap devices support nwfilter rules, and even then only
+     * when *not* connected to an OVS bridge or midonet (indicated by having
+     * a <virtualport> element in the config)
+     */
+    if (net->filter) {
+        virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net);
+        if (!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+              actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+              actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("filterref is not supported for "
+                             "network interfaces of type %s"),
+                           virDomainNetTypeToString(actualType));
+            return -1;
+        }
+        if (vport && vport->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) {
+            /* currently none of the defined virtualport types support iptables */
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("filterref is not supported for "
+                             "network interfaces with virtualport type %s"),
+                           virNetDevVPortTypeToString(vport->virtPortType));
+            return -1;
+        }
+    }
+
+    if (net->backend.tap &&
+        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+          actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Custom tap device path is not supported for: %s"),
+                       virDomainNetTypeToString(actualType));
+        return -1;
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainDeviceDefValidateNetwork(const virDomainNetDef *net)
 {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 9546216f30..daed69e856 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1074,4 +1074,8 @@ char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv);
 virDomainEventResumedDetailType
 qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason);
 
+int
+qemuDomainValidateActualNetDef(const virDomainNetDef *net,
+                               virQEMUCapsPtr qemuCaps);
+
 #endif /* __QEMU_DOMAIN_H__ */
-- 
2.23.0