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(a)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?
+ *
+ * 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));