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