On Sun, Oct 15, 2023 at 03:03:40PM -0400, Laine Stump wrote:
> On 10/12/23 3:37 PM, Praveen K Paladugu wrote:
> >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 <pra...@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
> 
> I haven't had time to look through the rest of this yet (although it
> seems pretty straightforward, and I think it might have been me who
> suggested it in the first place :-)), I did want to bring up this
> one topic now:
> 
> 
> Best practices for the copyright notice in a new file have changed
> over the years (for example, we no longer list the "Author" of new
> files and even removed Author from existing files, since a more
> accurate and complete version of that info is all available from
> git), and I haven't paid close attention, but since this entire file
> is comprised of functions that were just moved from an existing file
> and renamed (rather than actual new code), I don't think it's
> appropriate for it to erase all trace of the original copyright
> holder and simply assign the copyright entirely to Microsoft.
> 
> What are others' opinions on this?
> 
> 
Thanks for the pointing this out. It was a miss on my part. I will send
an updated version with the original copyrights included.

- Praveen
> >+ *
> >+ * 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));

Reply via email to