[libvirt PATCH] hypervisor: Move interface mgmt methods to hypervisor

Praveen K Paladugu prapal at linux.microsoft.com
Thu Oct 12 19:37:42 UTC 2023


Move guest interface management methods from qemu to hypervisor. These
methods will be shared by networking support in ch driver.

Signed-off-by: Praveen K Paladugu <prapal at linux.microsoft.com>
---
 po/POTFILES                       |   1 +
 src/hypervisor/domain_interface.c | 279 ++++++++++++++++++++++++++++++
 src/hypervisor/domain_interface.h |  38 ++++
 src/hypervisor/meson.build        |   1 +
 src/libvirt_private.syms          |   6 +
 src/qemu/qemu_command.c           |   7 +-
 src/qemu/qemu_hotplug.c           |   3 +-
 src/qemu/qemu_interface.c         | 246 +-------------------------
 src/qemu/qemu_interface.h         |   6 -
 src/qemu/qemu_process.c           |   3 +-
 10 files changed, 341 insertions(+), 249 deletions(-)
 create mode 100644 src/hypervisor/domain_interface.c
 create mode 100644 src/hypervisor/domain_interface.h

diff --git a/po/POTFILES b/po/POTFILES
index 3a51aea5cb..023c041f61 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -92,6 +92,7 @@ src/hyperv/hyperv_util.c
 src/hyperv/hyperv_wmi.c
 src/hypervisor/domain_cgroup.c
 src/hypervisor/domain_driver.c
+src/hypervisor/domain_interface.c
 src/hypervisor/virhostdev.c
 src/interface/interface_backend_netcf.c
 src/interface/interface_backend_udev.c
diff --git a/src/hypervisor/domain_interface.c b/src/hypervisor/domain_interface.c
new file mode 100644
index 0000000000..b01b6ee767
--- /dev/null
+++ b/src/hypervisor/domain_interface.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright Microsoft Corp. 2023
+ *
+ * domain_interface.c: methods to manage guest/domain interfaces
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "virmacaddr.h"
+#include "virnetdevtap.h"
+#include "virconftypes.h"
+#include "domain_conf.h"
+#include "domain_interface.h"
+#include "domain_nwfilter.h"
+#include "domain_audit.h"
+#include "virebtables.h"
+#include "virlog.h"
+#include "virfile.h"
+#include "viralloc.h"
+#include "virnetdevbridge.h"
+#include "network_conf.h"
+
+#define VIR_FROM_THIS VIR_FROM_INTERFACE
+
+VIR_LOG_INIT("interface.interface_connect");
+
+bool
+virDomainInterfaceIsVnetCompatModel(const virDomainNetDef *net)
+{
+    return (virDomainNetIsVirtioModel(net) ||
+            net->model == VIR_DOMAIN_NET_MODEL_E1000E ||
+            net->model == VIR_DOMAIN_NET_MODEL_IGB ||
+            net->model == VIR_DOMAIN_NET_MODEL_VMXNET3);
+}
+
+/* virDomainInterfaceEthernetConnect:
+ * @def: the definition of the VM
+ * @driver: qemu driver data
+ * @net: pointer to the VM's interface description
+ * @tapfd: array of file descriptor return value for the new device
+ * @tapfdsize: number of file descriptors in @tapfd
+ *
+ * Called *only* called if actualType is VIR_DOMAIN_NET_TYPE_ETHERNET
+ * (i.e. if the connection is made with a tap device)
+ */
+int
+virDomainInterfaceEthernetConnect(virDomainDef *def,
+                                    virDomainNetDef *net,
+                                    ebtablesContext *ebtables,
+                                    bool macFilter,
+                                    bool privileged,
+                                    int *tapfd,
+                                    size_t tapfdSize)
+{
+    virMacAddr tapmac;
+    int ret = -1;
+    unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
+    bool template_ifname = false;
+    const char *tunpath = "/dev/net/tun";
+    const char *auditdev = tunpath;
+
+    if (net->backend.tap) {
+        tunpath = net->backend.tap;
+        if (!privileged) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("cannot use custom tap device in session mode"));
+            goto cleanup;
+        }
+    }
+    VIR_WARN("PPK: interfaceEthernetConnect Called\n");
+    if (virDomainInterfaceIsVnetCompatModel(net))
+        tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
+
+    if (net->managed_tap == VIR_TRISTATE_BOOL_NO) {
+        if (!net->ifname) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("target dev must be supplied when managed='no'"));
+            goto cleanup;
+        }
+        if (virNetDevExists(net->ifname) != 1) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("target managed='no' but specified dev doesn't exist"));
+            goto cleanup;
+        }
+
+        tap_create_flags |= VIR_NETDEV_TAP_CREATE_ALLOW_EXISTING;
+
+        if (virNetDevMacVLanIsMacvtap(net->ifname)) {
+            auditdev = net->ifname;
+            if (virNetDevMacVLanTapOpen(net->ifname, tapfd, tapfdSize) < 0)
+                goto cleanup;
+            if (virNetDevMacVLanTapSetup(tapfd, tapfdSize,
+                                         virDomainInterfaceIsVnetCompatModel(net)) < 0) {
+                goto cleanup;
+            }
+        } else {
+            if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize,
+                                   tap_create_flags) < 0)
+                goto cleanup;
+        }
+    } else {
+
+        if (!net->ifname)
+            template_ifname = true;
+
+        if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize,
+                               tap_create_flags) < 0) {
+            goto cleanup;
+        }
+
+        /* The tap device's MAC address cannot match the MAC address
+         * used by the guest. This results in "received packet on
+         * vnetX with own address as source address" error logs from
+         * the kernel.
+         */
+        virMacAddrSet(&tapmac, &net->mac);
+        if (tapmac.addr[0] == 0xFE)
+            tapmac.addr[0] = 0xFA;
+        else
+            tapmac.addr[0] = 0xFE;
+
+        if (virNetDevSetMAC(net->ifname, &tapmac) < 0)
+            goto cleanup;
+
+        if (virNetDevSetOnline(net->ifname, true) < 0)
+            goto cleanup;
+    }
+
+    if (net->script &&
+        virNetDevRunEthernetScript(net->ifname, net->script) < 0)
+        goto cleanup;
+
+    if (macFilter &&
+        ebtablesAddForwardAllowIn(ebtables,
+                                  net->ifname,
+                                  &net->mac) < 0)
+        goto cleanup;
+
+    if (net->filter &&
+        virDomainConfNWFilterInstantiate(def->name, def->uuid, net, false) < 0) {
+        goto cleanup;
+    }
+
+    virDomainAuditNetDevice(def, net, auditdev, true);
+
+    ret = 0;
+
+ cleanup:
+    if (ret < 0) {
+        size_t i;
+
+        virDomainAuditNetDevice(def, net, auditdev, false);
+        for (i = 0; i < tapfdSize && tapfd[i] >= 0; i++)
+            VIR_FORCE_CLOSE(tapfd[i]);
+        if (template_ifname)
+            VIR_FREE(net->ifname);
+    }
+
+    return ret;
+}
+
+/**
+ * qemuInterfaceStartDevice:
+ * @net: net device to start
+ *
+ * Based upon the type of device provided, perform the appropriate
+ * work to completely activate the device and make it reachable from
+ * the rest of the network.
+ */
+int
+virDomainInterfaceStartDevice(virDomainNetDef *net)
+{
+    virDomainNetType actualType = virDomainNetGetActualType(net);
+
+    switch (actualType) {
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+        if (virDomainNetGetActualBridgeMACTableManager(net)
+            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
+            /* libvirt is managing the FDB of the bridge this device
+             * is attaching to, so we have turned off learning and
+             * unicast_flood on the device to prevent the kernel from
+             * adding any FDB entries for it. This means we need to
+             * add an fdb entry ourselves, using the MAC address from
+             * the interface config.
+             */
+            if (virNetDevBridgeFDBAdd(&net->mac, net->ifname,
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
+                                      VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
+                return -1;
+        }
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_DIRECT: {
+        const char *physdev = virDomainNetGetActualDirectDev(net);
+        bool isOnline = true;
+
+        /* set the physdev online if necessary. It may already be up,
+         * in which case we shouldn't re-up it just in case that causes
+         * some sort of "blip" in the physdev's status.
+         */
+        if (physdev && virNetDevGetOnline(physdev, &isOnline) < 0)
+            return -1;
+        if (!isOnline && virNetDevSetOnline(physdev, true) < 0)
+            return -1;
+
+        /* macvtap devices share their MAC address with the guest
+         * domain, and if they are set online prior to the domain CPUs
+         * being started, the host may send out traffic from this
+         * device that could confuse other entities on the network (in
+         * particular, if this new domain is the destination of a
+         * migration, and the source domain is still running, another
+         * host may mistakenly direct traffic for the guest to the
+         * destination domain rather than source domain). To prevent
+         * this, we create the macvtap device with IFF_UP false
+         * (i.e. "offline") then wait to bring it online until just as
+         * we are starting the domain CPUs.
+         */
+        if (virNetDevSetOnline(net->ifname, true) < 0)
+            return -1;
+        break;
+    }
+
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+        if (virNetDevIPInfoAddToDev(net->ifname, &net->hostIP) < 0)
+            return -1;
+
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_USER:
+    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+    case VIR_DOMAIN_NET_TYPE_SERVER:
+    case VIR_DOMAIN_NET_TYPE_CLIENT:
+    case VIR_DOMAIN_NET_TYPE_MCAST:
+    case VIR_DOMAIN_NET_TYPE_UDP:
+    case VIR_DOMAIN_NET_TYPE_INTERNAL:
+    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+    case VIR_DOMAIN_NET_TYPE_VDPA:
+    case VIR_DOMAIN_NET_TYPE_NULL:
+    case VIR_DOMAIN_NET_TYPE_VDS:
+    case VIR_DOMAIN_NET_TYPE_LAST:
+        /* these types all require no action */
+        break;
+    }
+
+    return 0;
+}
+
+/**
+ * virDomainInterfaceStartDevices:
+ * @def: domain definition
+ *
+ * Set all ifaces associated with this domain to the online state.
+ */
+int
+virDomainInterfaceStartDevices(virDomainDef *def)
+{
+    size_t i;
+
+    for (i = 0; i < def->nnets; i++) {
+        if (virDomainInterfaceStartDevice(def->nets[i]) < 0)
+            return -1;
+    }
+    return 0;
+}
diff --git a/src/hypervisor/domain_interface.h b/src/hypervisor/domain_interface.h
new file mode 100644
index 0000000000..4e76b84990
--- /dev/null
+++ b/src/hypervisor/domain_interface.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright Microsoft Corp. 2023
+ *
+ * domain_interface.h: methods to manage guest/domain interfaces
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "virebtables.h"
+
+int
+virDomainInterfaceEthernetConnect(virDomainDef *def,
+                           virDomainNetDef *net,
+                           ebtablesContext *ebtables,
+                           bool macFilter,
+                           bool privileged,
+                           int *tapfd,
+                           size_t tapfdSize);
+
+bool
+virDomainInterfaceIsVnetCompatModel(const virDomainNetDef *net);
+
+int virDomainInterfaceStartDevice(virDomainNetDef *net);
+int virDomainInterfaceStartDevices(virDomainDef *def);
diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build
index f35565b16b..819a9a82a2 100644
--- a/src/hypervisor/meson.build
+++ b/src/hypervisor/meson.build
@@ -1,6 +1,7 @@
 hypervisor_sources = [
   'domain_cgroup.c',
   'domain_driver.c',
+  'domain_interface.c',
   'virclosecallbacks.c',
   'virhostdev.c',
 ]
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4e475d5b1a..cae0ecb857 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1630,6 +1630,12 @@ virDomainDriverNodeDeviceReset;
 virDomainDriverParseBlkioDeviceStr;
 virDomainDriverSetupPersistentDefBlkioParams;
 
+# hypervisor/domain_interface.h
+virDomainInterfaceEthernetConnect;
+virDomainInterfaceIsVnetCompatModel;
+virDomainInterfaceStartDevice;
+virDomainInterfaceStartDevices;
+
 
 # hypervisor/virclosecallbacks.h
 virCloseCallbacksDomainAdd;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8a7b80719f..eda5327293 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -43,6 +43,7 @@
 #include "domain_nwfilter.h"
 #include "domain_addr.h"
 #include "domain_conf.h"
+#include "domain_interface.h"
 #include "netdev_bandwidth_conf.h"
 #include "virnetdevopenvswitch.h"
 #include "device_conf.h"
@@ -53,6 +54,7 @@
 #include "virmdev.h"
 #include "virutil.h"
 
+
 #include <sys/stat.h>
 #include <fcntl.h>
 
@@ -8523,7 +8525,10 @@ qemuBuildInterfaceConnect(virDomainObj *vm,
         break;
 
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        if (qemuInterfaceEthernetConnect(vm->def, priv->driver, net,
+        if (virDomainInterfaceEthernetConnect(vm->def, net,
+                                        priv->driver->ebtables,
+                                        priv->driver->config->macFilter,
+                                        priv->driver->privileged,
                                          tapfd, tapfdSize) < 0)
             return -1;
         vhostfd = true;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1f7f5bdd26..8e76cb8b38 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -39,6 +39,7 @@
 #include "qemu_virtiofs.h"
 #include "domain_audit.h"
 #include "domain_cgroup.h"
+#include "domain_interface.h"
 #include "netdev_bandwidth_conf.h"
 #include "domain_nwfilter.h"
 #include "virlog.h"
@@ -1269,7 +1270,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
     }
 
     /* Set device online immediately */
-    if (qemuInterfaceStartDevice(net) < 0)
+    if (virDomainInterfaceStartDevice(net) < 0)
         goto cleanup;
 
     qemuDomainInterfaceSetDefaultQDisc(driver, net);
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index 8856bb95a8..48e3422ae1 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -24,6 +24,7 @@
 #include "network_conf.h"
 #include "domain_audit.h"
 #include "domain_nwfilter.h"
+#include "domain_interface.h"
 #include "qemu_interface.h"
 #include "viralloc.h"
 #include "virlog.h"
@@ -41,110 +42,9 @@
 
 VIR_LOG_INIT("qemu.qemu_interface");
 
-/**
- * qemuInterfaceStartDevice:
- * @net: net device to start
- *
- * Based upon the type of device provided, perform the appropriate
- * work to completely activate the device and make it reachable from
- * the rest of the network.
- */
-int
-qemuInterfaceStartDevice(virDomainNetDef *net)
-{
-    virDomainNetType actualType = virDomainNetGetActualType(net);
-
-    switch (actualType) {
-    case VIR_DOMAIN_NET_TYPE_BRIDGE:
-    case VIR_DOMAIN_NET_TYPE_NETWORK:
-        if (virDomainNetGetActualBridgeMACTableManager(net)
-            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
-            /* libvirt is managing the FDB of the bridge this device
-             * is attaching to, so we have turned off learning and
-             * unicast_flood on the device to prevent the kernel from
-             * adding any FDB entries for it. This means we need to
-             * add an fdb entry ourselves, using the MAC address from
-             * the interface config.
-             */
-            if (virNetDevBridgeFDBAdd(&net->mac, net->ifname,
-                                      VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
-                                      VIR_NETDEVBRIDGE_FDB_FLAG_TEMP) < 0)
-                return -1;
-        }
-        break;
-
-    case VIR_DOMAIN_NET_TYPE_DIRECT: {
-        const char *physdev = virDomainNetGetActualDirectDev(net);
-        bool isOnline = true;
-
-        /* set the physdev online if necessary. It may already be up,
-         * in which case we shouldn't re-up it just in case that causes
-         * some sort of "blip" in the physdev's status.
-         */
-        if (physdev && virNetDevGetOnline(physdev, &isOnline) < 0)
-            return -1;
-        if (!isOnline && virNetDevSetOnline(physdev, true) < 0)
-            return -1;
-
-        /* macvtap devices share their MAC address with the guest
-         * domain, and if they are set online prior to the domain CPUs
-         * being started, the host may send out traffic from this
-         * device that could confuse other entities on the network (in
-         * particular, if this new domain is the destination of a
-         * migration, and the source domain is still running, another
-         * host may mistakenly direct traffic for the guest to the
-         * destination domain rather than source domain). To prevent
-         * this, we create the macvtap device with IFF_UP false
-         * (i.e. "offline") then wait to bring it online until just as
-         * we are starting the domain CPUs.
-         */
-        if (virNetDevSetOnline(net->ifname, true) < 0)
-            return -1;
-        break;
-    }
-
-    case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        if (virNetDevIPInfoAddToDev(net->ifname, &net->hostIP) < 0)
-            return -1;
-
-        break;
 
-    case VIR_DOMAIN_NET_TYPE_USER:
-    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
-    case VIR_DOMAIN_NET_TYPE_SERVER:
-    case VIR_DOMAIN_NET_TYPE_CLIENT:
-    case VIR_DOMAIN_NET_TYPE_MCAST:
-    case VIR_DOMAIN_NET_TYPE_UDP:
-    case VIR_DOMAIN_NET_TYPE_INTERNAL:
-    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
-    case VIR_DOMAIN_NET_TYPE_VDPA:
-    case VIR_DOMAIN_NET_TYPE_NULL:
-    case VIR_DOMAIN_NET_TYPE_VDS:
-    case VIR_DOMAIN_NET_TYPE_LAST:
-        /* these types all require no action */
-        break;
-    }
 
-    return 0;
-}
 
-/**
- * qemuInterfaceStartDevices:
- * @def: domain definition
- *
- * Set all ifaces associated with this domain to the online state.
- */
-int
-qemuInterfaceStartDevices(virDomainDef *def)
-{
-    size_t i;
-
-    for (i = 0; i < def->nnets; i++) {
-        if (qemuInterfaceStartDevice(def->nets[i]) < 0)
-            return -1;
-    }
-    return 0;
-}
 
 
 /**
@@ -166,7 +66,7 @@ qemuInterfaceStopDevice(virDomainNetDef *net)
         if (virDomainNetGetActualBridgeMACTableManager(net)
             == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
             /* remove the FDB entries that were added during
-             * qemuInterfaceStartDevices()
+             * virDomainInterfaceStartDevices()
              */
             if (virNetDevBridgeFDBDel(&net->mac, net->ifname,
                                       VIR_NETDEVBRIDGE_FDB_FLAG_MASTER |
@@ -236,14 +136,7 @@ qemuInterfaceStopDevices(virDomainDef *def)
 }
 
 
-static bool
-qemuInterfaceIsVnetCompatModel(const virDomainNetDef *net)
-{
-    return (virDomainNetIsVirtioModel(net) ||
-            net->model == VIR_DOMAIN_NET_MODEL_E1000E ||
-            net->model == VIR_DOMAIN_NET_MODEL_IGB ||
-            net->model == VIR_DOMAIN_NET_MODEL_VMXNET3);
-}
+
 
 
 /**
@@ -271,7 +164,7 @@ qemuInterfaceDirectConnect(virDomainDef *def,
     unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
     qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net);
 
-    if (qemuInterfaceIsVnetCompatModel(net))
+    if (virDomainInterfaceIsVnetCompatModel(net))
         macvlan_create_flags |= VIR_NETDEV_MACVLAN_VNET_HDR;
 
     if (virNetDevMacVLanCreateWithVPortProfile(net->ifname,
@@ -409,133 +302,6 @@ qemuCreateInBridgePortWithHelper(virQEMUDriverConfig *cfg,
     return *tapfd < 0 ? -1 : 0;
 }
 
-
-/* qemuInterfaceEthernetConnect:
- * @def: the definition of the VM
- * @driver: qemu driver data
- * @net: pointer to the VM's interface description
- * @tapfd: array of file descriptor return value for the new device
- * @tapfdsize: number of file descriptors in @tapfd
- *
- * Called *only* called if actualType is VIR_DOMAIN_NET_TYPE_ETHERNET
- * (i.e. if the connection is made with a tap device)
- */
-int
-qemuInterfaceEthernetConnect(virDomainDef *def,
-                           virQEMUDriver *driver,
-                           virDomainNetDef *net,
-                           int *tapfd,
-                           size_t tapfdSize)
-{
-    virMacAddr tapmac;
-    int ret = -1;
-    unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
-    bool template_ifname = false;
-    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
-    const char *tunpath = "/dev/net/tun";
-    const char *auditdev = tunpath;
-
-    if (net->backend.tap) {
-        tunpath = net->backend.tap;
-        if (!driver->privileged) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("cannot use custom tap device in session mode"));
-            goto cleanup;
-        }
-    }
-
-    if (qemuInterfaceIsVnetCompatModel(net))
-        tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
-
-    if (net->managed_tap == VIR_TRISTATE_BOOL_NO) {
-        if (!net->ifname) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("target dev must be supplied when managed='no'"));
-            goto cleanup;
-        }
-        if (virNetDevExists(net->ifname) != 1) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("target managed='no' but specified dev doesn't exist"));
-            goto cleanup;
-        }
-
-        tap_create_flags |= VIR_NETDEV_TAP_CREATE_ALLOW_EXISTING;
-
-        if (virNetDevMacVLanIsMacvtap(net->ifname)) {
-            auditdev = net->ifname;
-            if (virNetDevMacVLanTapOpen(net->ifname, tapfd, tapfdSize) < 0)
-                goto cleanup;
-            if (virNetDevMacVLanTapSetup(tapfd, tapfdSize,
-                                         qemuInterfaceIsVnetCompatModel(net)) < 0) {
-                goto cleanup;
-            }
-        } else {
-            if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize,
-                                   tap_create_flags) < 0)
-                goto cleanup;
-        }
-    } else {
-
-        if (!net->ifname)
-            template_ifname = true;
-
-        if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize,
-                               tap_create_flags) < 0) {
-            goto cleanup;
-        }
-
-        /* The tap device's MAC address cannot match the MAC address
-         * used by the guest. This results in "received packet on
-         * vnetX with own address as source address" error logs from
-         * the kernel.
-         */
-        virMacAddrSet(&tapmac, &net->mac);
-        if (tapmac.addr[0] == 0xFE)
-            tapmac.addr[0] = 0xFA;
-        else
-            tapmac.addr[0] = 0xFE;
-
-        if (virNetDevSetMAC(net->ifname, &tapmac) < 0)
-            goto cleanup;
-
-        if (virNetDevSetOnline(net->ifname, true) < 0)
-            goto cleanup;
-    }
-
-    if (net->script &&
-        virNetDevRunEthernetScript(net->ifname, net->script) < 0)
-        goto cleanup;
-
-    if (cfg->macFilter &&
-        ebtablesAddForwardAllowIn(driver->ebtables,
-                                  net->ifname,
-                                  &net->mac) < 0)
-        goto cleanup;
-
-    if (net->filter &&
-        virDomainConfNWFilterInstantiate(def->name, def->uuid, net, false) < 0) {
-        goto cleanup;
-    }
-
-    virDomainAuditNetDevice(def, net, auditdev, true);
-
-    ret = 0;
-
- cleanup:
-    if (ret < 0) {
-        size_t i;
-
-        virDomainAuditNetDevice(def, net, auditdev, false);
-        for (i = 0; i < tapfdSize && tapfd[i] >= 0; i++)
-            VIR_FORCE_CLOSE(tapfd[i]);
-        if (template_ifname)
-            VIR_FREE(net->ifname);
-    }
-
-    return ret;
-}
-
-
 /* qemuInterfaceBridgeConnect:
  * @def: the definition of the VM
  * @driver: qemu driver data
@@ -578,7 +344,7 @@ qemuInterfaceBridgeConnect(virDomainDef *def,
     if (!net->ifname)
         template_ifname = true;
 
-    if (qemuInterfaceIsVnetCompatModel(net))
+    if (virDomainInterfaceIsVnetCompatModel(net))
         tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
 
     if (driver->privileged) {
@@ -598,7 +364,7 @@ qemuInterfaceBridgeConnect(virDomainDef *def,
              * is attaching to, so we need to turn off learning and
              * unicast_flood on the device to prevent the kernel from
              * adding any FDB entries for it. We will add an fdb
-             * entry ourselves (during qemuInterfaceStartDevices(),
+             * entry ourselves (during virDomainInterfaceStartDevices(),
              * using the MAC address from the interface config.
              */
             if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index 6eed3e6bd7..feb299dd6c 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -37,12 +37,6 @@ int qemuInterfaceDirectConnect(virDomainDef *def,
                                size_t tapfdSize,
                                virNetDevVPortProfileOp vmop);
 
-int qemuInterfaceEthernetConnect(virDomainDef *def,
-                                 virQEMUDriver *driver,
-                                 virDomainNetDef *net,
-                                 int *tapfd,
-                                 size_t tapfdSize);
-
 int qemuInterfaceBridgeConnect(virDomainDef *def,
                                virQEMUDriver *driver,
                                virDomainNetDef *net,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ae0bb7bf80..8a87e7e685 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -74,6 +74,7 @@
 #include "virhostcpu.h"
 #include "domain_audit.h"
 #include "domain_cgroup.h"
+#include "domain_interface.h"
 #include "domain_nwfilter.h"
 #include "domain_postparse.h"
 #include "domain_validate.h"
@@ -3121,7 +3122,7 @@ qemuProcessStartCPUs(virQEMUDriver *driver, virDomainObj *vm,
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
 
     /* Bring up netdevs before starting CPUs */
-    if (qemuInterfaceStartDevices(vm->def) < 0)
+    if (virDomainInterfaceStartDevices(vm->def) < 0)
        return -1;
 
     VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
-- 
2.41.0



More information about the libvir-list mailing list