[libvirt PATCH] hypervisor: Move interface mgmt methods to hypervisor
Laine Stump
laine at laine.org
Sun Oct 15 19:03:40 UTC 2023
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 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
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));
More information about the libvir-list
mailing list