[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