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 <prapal@xxxxxxxxxxxxxxxxxxx> > >--- > > 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));