Devel
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
October 2023
- 55 participants
- 85 discussions
This is v11 of the multifd save prototype, which focuses on saving
to a single file instead of requiring multiple separate files for
multifd channels.
This series demonstrates a way to save and restore from a single file
by using interleaved channels of a size equal to the transfer buffer
size (1MB), and relying on UNIX holes to avoid wasting physical disk
space due to channels of different size.
KNOWN ISSUES:
a) still applies only to save/restore (no managed save etc)
b) this is not not done in QEMU, where it could be possible to teach
QEMU to migrate directly to a file or block device in a
block-aligned way by altering the migration stream code and the
state migration code of all devices.
changes from v10:
* virfile: add new API virFileDiskCopyChannel, which extends the
existing virFileDiskCopy to work with parallel channels in the file.
* drop use of virthread API, use GLIB for threads.
* pass only a single FD to the multifd-helper, which will then open
additional FDs as required for the multithreaded I/O.
* simplify virQEMUSaveFd API, separating the initialization from the
addition of extra channels.
* adapt all documentation to mention a single file instead of multiple.
* remove the "Lim" versions of virFileDirectRead and Write, they are
not needed.
---
changes from v9:
* exposed virFileDirectAlign
* separated the >= 2 QEMU_SAVE_VERSION change in own patch
* reworked the write code to add the alignment padding to the
data_len, making the on disk format compatible when loaded
from an older libvirt.
* reworked the read code to use direct I/O APIs only for actual
direct I/O file descriptors, so as to make old images work
with newer libvirt.
---
changes from v8:
* rebased on master
* reordered patches to add more upstreamable content at the start
* split introduction of virQEMUSaveFd, so the first part is multifd-free
* new virQEMUSaveDataRead as a mirror of virQEMUSaveDataWrite
* introduced virFileDirect API, using it in virFileDisk operations and
for virQEMUSaveRead and virQEMUSaveWrite
---
changes from v7:
* [ base params API and iohelper refactoring upstreamed ]
* extended the QEMU save image format more, to record the nr
of multifd channels on save. Made the data header struct packed.
* removed --parallel-connections from the restore command, as now
it is useless due to QEMU save image format extension.
* separate out patches to expose migration_params APIs to saveimage,
including qemuMigrationParamsSetString, SetCap, SetInt.
* fixed bugs in the ImageOpen patch (missing saveFd init), removed
some whitespace, and fixed some convoluted code paths for return
value -3.
---
changes from v6:
* improved error path handling, with error messages and especially
cancellation of qemu process on error during restore.
* split patches more and reordered them to keep general refactoring
at the beginning before the --parallel stuff is introduced.
* improved multifd compression support, including adding an enum
and extending the QEMU save image format to record the compression
used on save, and pick it up automatically on restore.
---
changes from v4:
* runIO renamed to virFileDiskCopy and rethought arguments
* renamed new APIs from ...ParametersFlags to ...Params
* introduce the new virDomainSaveParams and virDomainRestoreParams
without any additional parameters, so they can be upstreamed first.
* solved the issue in the gendispatch.pl script generating code that
was missing the conn parameter.
---
changes from v3:
* reordered series to have all helper-related change at the start
* solved all reported issues from ninja test, including documentation
* fixed most broken migration capabilities code (still imperfect likely)
* added G_GNUC_UNUSED as needed
* after multifd restore, added what I think were the missing operations:
qemuProcessRefreshState(),
qemuProcessStartCPUs() - most importantly,
virDomainObjSave()
The domain now starts running after restore without further encouragement
* removed the sleep(10) from the multifd-helper
---
changes from v2:
* added ability to restore the VM from disk using multifd
* fixed the multifd-helper to work in both directions,
assuming the need to listen for save, and connect for restore.
* fixed a large number of bugs, and probably introduced some :-)
---
Claudio Fontana (33):
virfile: introduce virFileDirect APIs
virfile: use virFileDirect API in runIOCopy
qemu: saveimage: rework image read/write to be O_DIRECT friendly
qemu: saveimage: assume future formats will also support compression
virfile: virFileDiskCopy: prepare for O_DIRECT files without wrapper
qemu: saveimage: introduce virQEMUSaveFd
qemu: saveimage: convert qemuSaveImageCreate to use virQEMUSaveFd
qemu: saveimage: convert qemuSaveImageOpen to use virQEMUSaveFd
tools: prepare doSave to use parameters
tools: prepare cmdRestore to use parameters
libvirt: add new VIR_DOMAIN_SAVE_PARALLEL flag and parameter
qemu: add stub support for VIR_DOMAIN_SAVE_PARALLEL in save
qemu: add stub support for VIR_DOMAIN_SAVE_PARALLEL in restore
virfile: add new API virFileDiskCopyChannel
multifd-helper: new helper for parallel save/restore
qemu: saveimage: update virQEMUSaveFd struct for parallel save
qemu: saveimage: wire up saveimage code with the multifd helper
qemu: capabilities: add multifd to the probed migration capabilities
qemu: saveimage: add multifd related fields to save format
qemu: migration_params: add APIs to set Int and Cap
qemu: migration: implement qemuMigrationSrcToFilesMultiFd for save
qemu: add parameter to qemuMigrationDstRun to skip waiting
qemu: implement qemuSaveImageLoadMultiFd for restore
tools: add parallel parameter to virsh save command
tools: add parallel parameter to virsh restore command
qemu: add migration parameter multifd-compression
libvirt: add new VIR_DOMAIN_SAVE_PARAM_PARALLEL_COMPRESSION
qemu: saveimage: add parallel compression argument to ImageCreate
qemu: saveimage: add stub support for multifd compression parameter
qemu: migration: expose qemuMigrationParamsSetString
qemu: saveimage: implement multifd-compression in parallel save
qemu: saveimage: restore compressed parallel images
tools: add parallel-compression parameter to virsh save command
docs/manpages/virsh.rst | 26 +-
include/libvirt/libvirt-domain.h | 24 +
po/POTFILES | 1 +
src/libvirt_private.syms | 6 +
src/qemu/qemu_capabilities.c | 4 +
src/qemu/qemu_capabilities.h | 2 +
src/qemu/qemu_driver.c | 146 ++--
src/qemu/qemu_migration.c | 160 ++--
src/qemu/qemu_migration.h | 16 +-
src/qemu/qemu_migration_params.c | 71 +-
src/qemu/qemu_migration_params.h | 15 +
src/qemu/qemu_process.c | 3 +-
src/qemu/qemu_process.h | 5 +-
src/qemu/qemu_saveimage.c | 703 +++++++++++++-----
src/qemu/qemu_saveimage.h | 69 +-
src/qemu/qemu_snapshot.c | 6 +-
src/util/iohelper.c | 3 +
src/util/meson.build | 16 +
src/util/multifd-helper.c | 359 +++++++++
src/util/virfile.c | 391 +++++++---
src/util/virfile.h | 11 +
.../caps_4.0.0.aarch64.xml | 1 +
.../qemucapabilitiesdata/caps_4.0.0.ppc64.xml | 1 +
.../caps_4.0.0.riscv32.xml | 1 +
.../caps_4.0.0.riscv64.xml | 1 +
.../qemucapabilitiesdata/caps_4.0.0.s390x.xml | 1 +
.../caps_4.0.0.x86_64.xml | 1 +
.../caps_4.1.0.x86_64.xml | 1 +
.../caps_4.2.0.aarch64.xml | 1 +
.../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 1 +
.../qemucapabilitiesdata/caps_4.2.0.s390x.xml | 1 +
.../caps_4.2.0.x86_64.xml | 1 +
.../caps_5.0.0.aarch64.xml | 2 +
.../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 2 +
.../caps_5.0.0.riscv64.xml | 2 +
.../caps_5.0.0.x86_64.xml | 2 +
.../qemucapabilitiesdata/caps_5.1.0.sparc.xml | 2 +
.../caps_5.1.0.x86_64.xml | 2 +
.../caps_5.2.0.aarch64.xml | 2 +
.../qemucapabilitiesdata/caps_5.2.0.ppc64.xml | 2 +
.../caps_5.2.0.riscv64.xml | 2 +
.../qemucapabilitiesdata/caps_5.2.0.s390x.xml | 2 +
.../caps_5.2.0.x86_64.xml | 2 +
.../caps_6.0.0.aarch64.xml | 2 +
.../qemucapabilitiesdata/caps_6.0.0.s390x.xml | 2 +
.../caps_6.0.0.x86_64.xml | 2 +
.../caps_6.1.0.x86_64.xml | 2 +
.../caps_6.2.0.aarch64.xml | 2 +
.../qemucapabilitiesdata/caps_6.2.0.ppc64.xml | 2 +
.../caps_6.2.0.x86_64.xml | 2 +
.../caps_7.0.0.aarch64.xml | 2 +
.../qemucapabilitiesdata/caps_7.0.0.ppc64.xml | 2 +
.../caps_7.0.0.x86_64.xml | 2 +
.../caps_7.1.0.x86_64.xml | 2 +
tools/virsh-domain.c | 101 ++-
55 files changed, 1748 insertions(+), 445 deletions(-)
create mode 100644 src/util/multifd-helper.c
--
2.26.2
2
40
Part 1 (which simply made it possible to use virsh nodedev-detach to
bind a device to a manually-specified variant driver, and at guest
runtime allowed libvirt to ignore the fact that the driver found to
the device was something other than exactly "vfio-pci") was here:
https://listman.redhat.com/archives/libvir-list/2023-August/241338.html
and pushed upstream as of commit v9.6.0-153-g24beaffec3
Part 2 adds two new pieces of functionality:
1) It is possible to manually specify a VFIO variant driver (or force
the generic vfio-pci driver) for a device in the domain XML with,
e.g.:
<driver name='mlx5_vfio_pci'/>
(for the former) or:
<driver name='vfio-pci'/>
(for the latter).
2) By default libvirt will now find the "best match" VFIO or VFIO
variant driver by comparing the device's modalias file contents (in
sysfs) with vfio drivers found in the running kernel's
modules.alias file. This means that "virsh nodedev-detach" of a
host device will bind it to its appropriate VFIO variant driver (if
one is available), and also if a <hostdev> decice in a domain
config has "managed='yes'", libvirt will bind it to a variant
driver if possible (in order to force binding to the basic vfio-pci
driver instead, you just need to add the <driver> element mentioned
above).
The first 12 patches are all just getting (1) going (a lot of it is
refactoring code to use common code for the four places that use the
hostdev <driver> element), and the final 3 patches implement (2).
More details are spread along the way.
Laine Stump (15):
util: properly deal with module vs. driver when binding device to
driver
schema: consolidate RNG for all hostdev <driver> elements
conf: move/rename hostdev PCI driver type enum to device_conf.h
conf: normalize hostdev <driver> parsing to simplify adding new attr
conf: put hostdev PCI backend into a struct
conf: use virDeviceHostdevPCIDriverInfo in network and networkport
objects
conf: split out hostdev <driver> parse/format to their own functions
conf: use new common parser/formatter for hostdev driver in network
XML
tests: remove explicit <driver name='vfio'/> from hostdev test cases
xen: explicitly set hostdev driver.type at runtime, not in postparse
conf: replace virHostdevIsVFIODevice with virHostdevIsPCIDevice
conf: support manually specifying VFIO variant driver in <hostdev> XML
util: new function virStringSkipToSpace()
util: new function virPCIDeviceFindBestVFIOVariant()
qemu: automatically bind to a vfio variant driver, if available
src/conf/device_conf.c | 75 +++
src/conf/device_conf.h | 27 ++
src/conf/domain_capabilities.c | 2 +-
src/conf/domain_capabilities.h | 2 +-
src/conf/domain_conf.c | 98 +---
src/conf/domain_conf.h | 18 +-
src/conf/network_conf.c | 44 +-
src/conf/network_conf.h | 17 +-
src/conf/schemas/basictypes.rng | 20 +
src/conf/schemas/domaincommon.rng | 173 ++++---
src/conf/schemas/network.rng | 10 +-
src/conf/schemas/networkport.rng | 10 +-
src/conf/virconftypes.h | 2 +
src/conf/virnetworkportdef.c | 23 +-
src/conf/virnetworkportdef.h | 4 +-
src/hypervisor/virhostdev.c | 16 +-
src/hypervisor/virhostdev.h | 2 -
src/libvirt_private.syms | 8 +-
src/libxl/libxl_capabilities.c | 2 +-
src/libxl/libxl_domain.c | 65 ++-
src/libxl/libxl_driver.c | 25 +-
src/network/bridge_driver.c | 2 +-
src/qemu/qemu_capabilities.c | 4 +-
src/qemu/qemu_command.c | 14 +-
src/qemu/qemu_domain.c | 29 +-
src/qemu/qemu_hostdev.c | 2 +-
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_validate.c | 6 +-
src/security/security_apparmor.c | 2 +-
src/security/security_dac.c | 4 +-
src/security/security_selinux.c | 4 +-
src/security/virt-aa-helper.c | 8 +-
src/util/virpci.c | 434 ++++++++++++++++--
src/util/virpci.h | 2 +
src/util/virstring.c | 17 +
src/util/virstring.h | 1 +
tests/domaincapstest.c | 4 +-
tests/libxlxml2domconfigdata/moredevs-hvm.xml | 1 -
tests/networkxml2xmlin/hostdev-pf-old.xml | 8 +
tests/networkxml2xmlin/hostdev-pf.xml | 2 +-
tests/networkxml2xmlout/hostdev-pf-old.xml | 8 +
tests/networkxml2xmlout/hostdev-pf.xml | 2 +-
tests/networkxml2xmltest.c | 6 +
.../qemuhotplug-hostdev-pci.xml | 1 -
.../qemuhotplug-base-live+hostdev-pci.xml | 2 +-
...uhotplug-pseries-base-live+hostdev-pci.xml | 2 +-
tests/qemustatusxml2xmldata/modern-in.xml | 2 +-
.../hostdev-pci-address-unassigned.xml | 4 -
.../hostdev-pci-multifunction.xml | 7 -
.../hostdev-vfio-multidomain.xml | 1 -
.../hostdev-vfio-zpci-autogenerate-fids.xml | 2 -
.../hostdev-vfio-zpci-autogenerate-uids.xml | 2 -
.../hostdev-vfio-zpci-autogenerate.xml | 1 -
.../hostdev-vfio-zpci-boundaries.xml | 2 -
.../hostdev-vfio-zpci-ccw-memballoon.xml | 1 -
.../hostdev-vfio-zpci-duplicate.xml | 2 -
...ostdev-vfio-zpci-invalid-uid-valid-fid.xml | 1 -
.../hostdev-vfio-zpci-multidomain-many.xml | 8 -
.../hostdev-vfio-zpci-set-zero.xml | 1 -
.../hostdev-vfio-zpci-uid-set-zero.xml | 1 -
.../hostdev-vfio-zpci-wrong-arch.xml | 1 -
tests/qemuxml2argvdata/hostdev-vfio-zpci.xml | 1 -
.../hostdev-vfio.x86_64-latest.args | 5 +-
tests/qemuxml2argvdata/hostdev-vfio.xml | 19 +-
.../net-hostdev-vfio-multidomain.xml | 1 -
tests/qemuxml2argvdata/net-hostdev-vfio.xml | 1 -
tests/qemuxml2argvdata/pseries-hostdevs-1.xml | 3 -
tests/qemuxml2argvdata/pseries-hostdevs-2.xml | 2 -
tests/qemuxml2argvdata/pseries-hostdevs-3.xml | 2 -
...v-pci-address-unassigned.x86_64-latest.xml | 4 -
...ostdev-pci-multifunction.x86_64-latest.xml | 7 -
...io-zpci-autogenerate-fids.s390x-latest.xml | 2 -
...io-zpci-autogenerate-uids.s390x-latest.xml | 2 -
...ev-vfio-zpci-autogenerate.s390x-latest.xml | 1 -
...tdev-vfio-zpci-boundaries.s390x-latest.xml | 2 -
...-vfio-zpci-ccw-memballoon.s390x-latest.xml | 1 -
...fio-zpci-multidomain-many.s390x-latest.xml | 8 -
.../hostdev-vfio-zpci.s390x-latest.xml | 1 -
.../hostdev-vfio.x86_64-latest.xml | 24 +-
.../net-hostdev-vfio.x86_64-latest.xml | 1 -
.../pseries-hostdevs-1.ppc64-latest.xml | 3 -
.../pseries-hostdevs-2.ppc64-latest.xml | 2 -
.../pseries-hostdevs-3.ppc64-latest.xml | 2 -
tests/virhostdevtest.c | 2 +-
.../plug-hostdev-pci-unmanaged.xml | 2 +-
.../plug-hostdev-pci.xml | 2 +-
tests/xlconfigdata/test-fullvirt-pci.xml | 2 -
tests/xmconfigdata/test-pci-dev-syntax.xml | 2 -
tests/xmconfigdata/test-pci-devs.xml | 2 -
tools/virsh-completer-nodedev.c | 4 +-
90 files changed, 875 insertions(+), 481 deletions(-)
create mode 100644 tests/networkxml2xmlin/hostdev-pf-old.xml
create mode 100644 tests/networkxml2xmlout/hostdev-pf-old.xml
--
2.41.0
2
16
commit v9.8.0-40-g7cbd8c4230 changed the name of the option that
enables/disables nbdkit support in the build from "libnbd" to
"nbdkit", but one use of "-Dlibnbd=disabled" was missed in
libvirt.specfile.in - the meson commandline for mingw, causing the
build to fail.
This patch changes that line to "-Dnbdkit=disabled", thus unbreaking
the rpm build.
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
This patch does fix a build-breaker, but I didn't want to push it in
case my comment was incorrect (I won't pretend that I've paid
attention to nbdkit)
libvirt.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index fe54c45c5c..262c59eb5b 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1356,7 +1356,7 @@ export SOURCE_DATE_EPOCH=$(stat --printf='%Y' %{_specdir}/libvirt.spec)
-Dglusterfs=disabled \
-Dhost_validate=disabled \
-Dlibiscsi=disabled \
- -Dlibnbd=disabled \
+ -Dnbdkit=disabled \
-Dlibnl=disabled \
-Dlibpcap=disabled \
-Dlibssh2=disabled \
--
2.41.0
2
1
20 Oct '23
vmDef->fss[i]->src->path may be NULL,
so check is needed before passing it to VIR_DEBUG.
Also removed checking vmDef->fss[i]->src for NULL, since it may not be NULL.
Fixes: 57487085dc ("lxc: don't try to reference NULL when mounting filesystems")
Signed-off-by: Dmitry Frolov <frolov(a)swemel.ru>
---
src/lxc/lxc_container.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 21220661f7..9601061b23 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1467,12 +1467,12 @@ static int lxcContainerMountAllFS(virDomainDef *vmDef,
if (STREQ(vmDef->fss[i]->dst, "/"))
continue;
- VIR_DEBUG("Mounting '%s' -> '%s'", vmDef->fss[i]->src->path, vmDef->fss[i]->dst);
+ VIR_DEBUG("Mounting '%s' -> '%s'", NULLSTR(vmDef->fss[i]->src->path), vmDef->fss[i]->dst);
if (lxcContainerResolveSymlinks(vmDef->fss[i], false) < 0)
return -1;
- if (!(vmDef->fss[i]->src && vmDef->fss[i]->src->path &&
+ if (!(vmDef->fss[i]->src->path &&
STRPREFIX(vmDef->fss[i]->src->path, vmDef->fss[i]->dst)) &&
lxcContainerUnmountSubtree(vmDef->fss[i]->dst, false) < 0)
return -1;
--
2.34.1
3
2
Currently, libvirt doesn't send events when devices are attached,
detached or updated. Thus, any services that listen to events are
unaware of the change to persistent config.
Signed-off-by: Fima Shevrin <efim.shevrin(a)virtuozzo.com>
---
src/qemu/qemu_driver.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 43d96739d5..86da8da777 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7209,6 +7209,7 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObj *vm,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
+ virObjectEvent *event = NULL;
g_autoptr(virDomainDef) vmdef = NULL;
g_autoptr(virQEMUDriverConfig) cfg = NULL;
g_autoptr(virDomainDeviceDef) devConf = NULL;
@@ -7292,6 +7293,12 @@ qemuDomainAttachDeviceLiveAndConfig(virDomainObj *vm,
return -1;
virDomainObjAssignDef(vm, &vmdef, false, NULL);
+
+ /* Event sending if persistent config has changed */
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_UPDATED);
+ virObjectEventStateQueue(driver->domainEventState, event);
}
return 0;
@@ -7348,6 +7355,7 @@ qemuDomainUpdateDeviceFlags(virDomainPtr dom,
virQEMUDriver *driver = dom->conn->privateData;
virDomainObj *vm = NULL;
qemuDomainObjPrivate *priv;
+ virObjectEvent *event = NULL;
g_autoptr(virDomainDef) vmdef = NULL;
g_autoptr(virDomainDeviceDef) dev_config = NULL;
g_autoptr(virDomainDeviceDef) dev_live = NULL;
@@ -7419,8 +7427,16 @@ qemuDomainUpdateDeviceFlags(virDomainPtr dom,
/* Finally, if no error until here, we can save config. */
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
ret = virDomainDefSave(vmdef, driver->xmlopt, cfg->configDir);
- if (!ret)
+ if (!ret) {
virDomainObjAssignDef(vm, &vmdef, false, NULL);
+
+ /* Event sending if persistent config has changed */
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_UPDATED);
+
+ virObjectEventStateQueue(driver->domainEventState, event);
+ }
}
endjob:
@@ -7438,6 +7454,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriver *driver,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
+ virObjectEvent *event = NULL;
g_autoptr(virQEMUDriverConfig) cfg = NULL;
g_autoptr(virDomainDeviceDef) dev_config = NULL;
g_autoptr(virDomainDeviceDef) dev_live = NULL;
@@ -7495,6 +7512,12 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriver *driver,
return -1;
virDomainObjAssignDef(vm, &vmdef, false, NULL);
+
+ /* Event sending if persistent config has changed */
+ event = virDomainEventLifecycleNewFromObj(vm,
+ VIR_DOMAIN_EVENT_DEFINED,
+ VIR_DOMAIN_EVENT_DEFINED_UPDATED);
+ virObjectEventStateQueue(driver->domainEventState, event);
}
return 0;
--
2.39.3
2
1
[PATCH 0/1] Dead code in the virSecuritySELinuxSetImageLabelInternal function
by Sergey Mironov 20 Oct '23
by Sergey Mironov 20 Oct '23
20 Oct '23
The virSecuritySELinuxSetFilecon function (by definition) always return values 0 or -1.
Sergey Mironov (1):
Checking the value returned by the function
src/security/security_selinux.c | 11 -----------
1 file changed, 11 deletions(-)
--
2.31.1
2
2
use '%u' to printf unsigned int
Signed-off-by: zhujun2 <zhujun2(a)cmss.chinamobile.com>
---
examples/c/misc/event-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c
index 813bca2699..07d86500cd 100644
--- a/examples/c/misc/event-test.c
+++ b/examples/c/misc/event-test.c
@@ -969,7 +969,7 @@ myDomainEventMemoryFailureCallback(virConnectPtr conn G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED)
{
printf("%s EVENT: Domain %s(%d) memory failure: recipient '%d', "
- "aciont '%d', flags '%d'\n", __func__, virDomainGetName(dom),
+ "aciont '%d', flags '%u'\n", __func__, virDomainGetName(dom),
virDomainGetID(dom), recipient, action, flags);
return 0;
}
--
2.17.1
2
1
[libvirt PATCH] logging: lockdown the systemd service configuration
by Daniel P. Berrangé 20 Oct '23
by Daniel P. Berrangé 20 Oct '23
20 Oct '23
The 'systemd-analyze security' command looks at the unit file
configuration and reports on any settings which increase the
attack surface for the daemon. Since most systemd units are
fairly minimalist, this is generally informing us about settings
that we never put any thought into using before.
In its current configuration it reports
# systemd-analyze security virtlogd.service
...snip...
→ Overall exposure level for virtlogd.service: 9.6 UNSAFE 😨
which is pretty terrible as a score.
If we apply all of the recommendations that appear possible
without (knowingly) breaking functionality it reports:
# systemd-analyze security virtlogd.service
...snip...
→ Overall exposure level for virtlogd.service: 2.2 OK 🙂
which is a pretty decent improvement.
Some of the settings we would like to enable require a systemd
version that is newer than that available in our oldest distro
target - RHEL-8 at v239.
NB, RestrictSUIDSGID is technically newer than 239, but RHEL-8
backported it, and other distros we target have it by default.
Remaining recommendations are
✗ CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER)
We block FOWNER/IPC_OWNER, but can't block the two DAC
capabilities. Historically apps/users might point QEMU
to log files in $HOME, pre-created with their own user
ID.
✗ IPAddressDeny=
Not required since RestrictAddressFamilies blocks IP
usage. Ignoring this avoids the overhead of creating
a traffic filter than will never be used.
✗ NoNewPrivileges=
Highly desirable, but cannot enable it yet, because it
will block the ability to transition to the virtlogd_t
SELinux domain during execve. The SELinux policy needs
fixing to permit this transition under NNP first.
✗ PrivateTmp=
There is a decent chance people have VMs configured
with a serial port logfile pointing at /tmp. We would
cause a regression to use private /tmp for logging
✗ PrivateUsers=
This would put virtlogd inside a user namespace where
its root is in fact unprivileged. Same problem as the
User= setting below
✗ ProcSubset=
Libraries we link to might read certain non-PID related
files from /proc
✗ ProtectClock=
Requires v245
✗ ProtectHome=
Same problem as PrivateTmp=. There's a decent chance
that someone has a VM configured to write a logfile
to /home
✗ ProtectHostname=
Requires v241
✗ ProtectKernelLogs
Requires v244
✗ ProtectProc
Requires v247
✗ ProtectSystem=
We only set it to 'full', as 'strict' is not viable for
our required usage
✗ RootDirectory=/RootImage=
We are not capable of running inside a custom chroot
given needs to write log files to arbitrary places
✗ RestrictAddressFamilies=~AF_UNIX
We need AF_UNIX to communicate with other libvirt daemons
✗ SystemCallFilter=~@resources
We link to libvirt.so which links to libnuma.so which has
a constructor that calls set_mempolicy. This is highly
undesirable todo during a constructor.
✗ User=/DynamicUser=
This is highly desirable, but we currently read/write
logs as root, and directories we're told to write into
could be anywhere. So using a non-root user would have
a major risk of regressions for applications and also
have upgrade implications
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/logging/virtlogd.service.in | 94 +++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/src/logging/virtlogd.service.in b/src/logging/virtlogd.service.in
index 8e245ddb43..9e3838ff34 100644
--- a/src/logging/virtlogd.service.in
+++ b/src/logging/virtlogd.service.in
@@ -20,5 +20,99 @@ OOMScoreAdjust=-900
# per systemd recommendations
LimitNOFILE=1024:524288
+CapabilityBoundingSet=~CAP_AUDIT_CONTROL
+CapabilityBoundingSet=~CAP_AUDIT_READ
+CapabilityBoundingSet=~CAP_AUDIT_WRITE
+CapabilityBoundingSet=~CAP_BLOCK_SUSPEND
+CapabilityBoundingSet=~CAP_CHOWN
+# Mgmt app/user might have pre-created log files that we're
+# told to open and write to, or be storing them in otherwise
+# inaccessible locations like $HOME. So we need to ignore
+# DAC permission checks.
+#CapabilityBoundingSet=~CAP_DAC_OVERRIDE
+#CapabilityBoundingSet=~CAP_DAC_READ_SEARCH
+CapabilityBoundingSet=~CAP_FOWNER
+CapabilityBoundingSet=~CAP_FSETID
+CapabilityBoundingSet=~CAP_IPC_LOCK
+CapabilityBoundingSet=~CAP_IPC_OWNER
+CapabilityBoundingSet=~CAP_KILL
+CapabilityBoundingSet=~CAP_LEASE
+CapabilityBoundingSet=~CAP_LINUX_IMMUTABLE
+CapabilityBoundingSet=~CAP_MAC_ADMIN
+CapabilityBoundingSet=~CAP_MAC_OVERRIDE
+CapabilityBoundingSet=~CAP_MKNOD
+CapabilityBoundingSet=~CAP_NET_ADMIN
+CapabilityBoundingSet=~CAP_NET_BIND_SERVICE
+CapabilityBoundingSet=~CAP_NET_BROADCAST
+CapabilityBoundingSet=~CAP_NET_RAW
+CapabilityBoundingSet=~CAP_SETFCAP
+CapabilityBoundingSet=~CAP_SETPCAP
+CapabilityBoundingSet=~CAP_SETGID
+CapabilityBoundingSet=~CAP_SETUID
+CapabilityBoundingSet=~CAP_SYSLOG
+CapabilityBoundingSet=~CAP_SYS_ADMIN
+CapabilityBoundingSet=~CAP_SYS_BOOT
+CapabilityBoundingSet=~CAP_SYS_CHROOT
+CapabilityBoundingSet=~CAP_SYS_MODULE
+CapabilityBoundingSet=~CAP_SYS_NICE
+CapabilityBoundingSet=~CAP_SYS_PACCT
+CapabilityBoundingSet=~CAP_SYS_PTRACE
+CapabilityBoundingSet=~CAP_SYS_RAWIO
+CapabilityBoundingSet=~CAP_SYS_RESOURCE
+CapabilityBoundingSet=~CAP_SYS_TIME
+CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
+CapabilityBoundingSet=~CAP_WAKE_ALARM
+
+LockPersonality=true
+MemoryDenyWriteExecute=true
+# Cannot enable this as it prevents transitioning to
+# the confined SELinux virtlogd_t domain on execve
+# unless we modify the policy to allow this.
+#NoNewPrivileges=true
+PrivateDevices=true
+PrivateMounts=true
+PrivateNetwork=true
+# XXX someone could configure QEMU to log a serial port to an
+# arbitrary directory, including /tmp, even if this is ill-advised
+#PrivateTmp=true
+# Not until oldest build target has systemd >= v245
+#ProtectClock=true
+ProtectControlGroups=true
+# Not until oldest build target has systemd >= v241
+#ProtectHostname=true
+# Not until oldest build target has systemd >= v244
+#ProtectKernelLogs=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+# Not until oldest build target has systemd >= v247
+#ProtectProc=invisible
+ProtectSystem=full
+RestrictAddressFamilies=AF_UNIX
+RestrictNamespaces=~cgroup
+RestrictNamespaces=~ipc
+RestrictNamespaces=~mnt
+RestrictNamespaces=~net
+RestrictNamespaces=~pid
+RestrictNamespaces=~user
+RestrictNamespaces=~uts
+RestrictRealtime=true
+RestrictSUIDSGID=true
+SystemCallArchitectures=native
+SystemCallFilter=~@clock
+SystemCallFilter=~@debug
+SystemCallFilter=~@module
+SystemCallFilter=~@mount
+SystemCallFilter=~@raw-io
+SystemCallFilter=~@reboot
+SystemCallFilter=~@swap
+SystemCallFilter=~@privileged
+# Unfortunately we link to libnuma via libvirt.so which
+# has a constructor that runs unconditionally that invokes
+# set_mempolicy()
+#SystemCallFilter=~@resources
+SystemCallFilter=~@cpu-emulation
+SystemCallFilter=~@obsolete
+UMask=077
+
[Install]
Also=virtlogd.socket
--
2.41.0
2
2
[libvirt PATCH v3] hypervisor: Move interface mgmt methods to hypervisor
by Praveen K Paladugu 19 Oct '23
by Praveen K Paladugu 19 Oct '23
19 Oct '23
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 | 368 ++++++++++++++++++++++++++++++
src/hypervisor/domain_interface.h | 41 ++++
src/hypervisor/meson.build | 1 +
src/libvirt_private.syms | 8 +
src/qemu/qemu_command.c | 6 +-
src/qemu/qemu_hotplug.c | 5 +-
src/qemu/qemu_interface.c | 339 +--------------------------
src/qemu/qemu_interface.h | 11 -
src/qemu/qemu_process.c | 5 +-
10 files changed, 434 insertions(+), 351 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..f726cb2bea
--- /dev/null
+++ b/src/hypervisor/domain_interface.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2015-2016 Red Hat, Inc.
+ * Copyright IBM Corp. 2014
+ *
+ * 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 "virconftypes.h"
+#include "virmacaddr.h"
+#include "virnetdevtap.h"
+#include "domain_audit.h"
+#include "domain_conf.h"
+#include "domain_interface.h"
+#include "domain_nwfilter.h"
+#include "viralloc.h"
+#include "virebtables.h"
+#include "virfile.h"
+#include "virlog.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;
+ }
+ }
+
+ 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;
+}
+
+/**
+ * virDomainInterfaceStartDevice:
+ * @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;
+}
+
+/**
+ * virDomainInterfaceStopDevice:
+ * @net: net device to stop
+ *
+ * Based upon the type of device provided, perform the appropriate
+ * work to deactivate the device so that packets aren't forwarded to
+ * it from the rest of the network.
+ */
+int
+virDomainInterfaceStopDevice(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) {
+ /* remove the FDB entries that were added during
+ * virDomainInterfaceStartDevices()
+ */
+ if (virNetDevBridgeFDBDel(&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);
+
+ /* macvtap interfaces need to be marked !IFF_UP (ie "down") to
+ * prevent any host-generated traffic sent from this interface
+ * from putting bad info into the arp caches of other machines
+ * on this network.
+ */
+ if (virNetDevSetOnline(net->ifname, false) < 0)
+ return -1;
+
+ /* also mark the physdev down for passthrough macvtap, as the
+ * physdev has the same MAC address as the macvtap device.
+ */
+ if (virDomainNetGetActualDirectMode(net) ==
+ VIR_NETDEV_MACVLAN_MODE_PASSTHRU &&
+ physdev && virNetDevSetOnline(physdev, false) < 0)
+ return -1;
+ break;
+ }
+
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ 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;
+}
+
+/**
+ * virDomainInterfaceStopDevices:
+ * @def: domain definition
+ *
+ * Make all interfaces associated with this domain inaccessible from
+ * the rest of the network.
+ */
+int
+virDomainInterfaceStopDevices(virDomainDef *def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nnets; i++) {
+ if (virDomainInterfaceStopDevice(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..68bf2ae51d
--- /dev/null
+++ b/src/hypervisor/domain_interface.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015-2016 Red Hat, Inc.
+ * Copyright IBM Corp. 2014
+ *
+ * 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);
+int virDomainInterfaceStopDevice(virDomainNetDef *net);
+int virDomainInterfaceStopDevices(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 553b01b8c0..b7f329be43 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1630,6 +1630,14 @@ virDomainDriverNodeDeviceReset;
virDomainDriverParseBlkioDeviceStr;
virDomainDriverSetupPersistentDefBlkioParams;
+# hypervisor/domain_interface.h
+virDomainInterfaceEthernetConnect;
+virDomainInterfaceIsVnetCompatModel;
+virDomainInterfaceStartDevice;
+virDomainInterfaceStartDevices;
+virDomainInterfaceStopDevice;
+virDomainInterfaceStopDevices;
+
# hypervisor/virclosecallbacks.h
virCloseCallbacksDomainAdd;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d40d3a4e13..1ac39937b9 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"
@@ -8525,7 +8526,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..76e911c8b0 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);
@@ -4769,7 +4770,7 @@ qemuDomainRemoveNetDevice(virQEMUDriver *driver,
* affect the parent device (e.g. macvtap passthrough mode sets
* the parent device offline)
*/
- ignore_value(qemuInterfaceStopDevice(net));
+ ignore_value(virDomainInterfaceStopDevice(net));
qemuDomainObjEnterMonitor(vm);
if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index 8856bb95a8..c2007c7043 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,211 +42,6 @@
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;
-}
-
-
-/**
- * qemuInterfaceStopDevice:
- * @net: net device to stop
- *
- * Based upon the type of device provided, perform the appropriate
- * work to deactivate the device so that packets aren't forwarded to
- * it from the rest of the network.
- */
-int
-qemuInterfaceStopDevice(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) {
- /* remove the FDB entries that were added during
- * qemuInterfaceStartDevices()
- */
- if (virNetDevBridgeFDBDel(&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);
-
- /* macvtap interfaces need to be marked !IFF_UP (ie "down") to
- * prevent any host-generated traffic sent from this interface
- * from putting bad info into the arp caches of other machines
- * on this network.
- */
- if (virNetDevSetOnline(net->ifname, false) < 0)
- return -1;
-
- /* also mark the physdev down for passthrough macvtap, as the
- * physdev has the same MAC address as the macvtap device.
- */
- if (virDomainNetGetActualDirectMode(net) ==
- VIR_NETDEV_MACVLAN_MODE_PASSTHRU &&
- physdev && virNetDevSetOnline(physdev, false) < 0)
- return -1;
- break;
- }
-
- case VIR_DOMAIN_NET_TYPE_ETHERNET:
- 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;
-}
-
-/**
- * qemuInterfaceStopDevices:
- * @def: domain definition
- *
- * Make all interfaces associated with this domain inaccessible from
- * the rest of the network.
- */
-int
-qemuInterfaceStopDevices(virDomainDef *def)
-{
- size_t i;
-
- for (i = 0; i < def->nnets; i++) {
- if (qemuInterfaceStopDevice(def->nets[i]) < 0)
- return -1;
- }
- return 0;
-}
-
-
-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);
-}
-
-
/**
* qemuInterfaceDirectConnect:
* @def: the definition of the VM (needed by 802.1Qbh and audit)
@@ -271,7 +67,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 +205,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 +247,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 +267,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..47d7ec03fd 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -25,11 +25,6 @@
#include "qemu_domain.h"
#include "qemu_slirp.h"
-int qemuInterfaceStartDevice(virDomainNetDef *net);
-int qemuInterfaceStartDevices(virDomainDef *def);
-int qemuInterfaceStopDevice(virDomainNetDef *net);
-int qemuInterfaceStopDevices(virDomainDef *def);
-
int qemuInterfaceDirectConnect(virDomainDef *def,
virQEMUDriver *driver,
virDomainNetDef *net,
@@ -37,12 +32,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 63c0c62a46..991609beac 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));
@@ -3184,7 +3185,7 @@ int qemuProcessStopCPUs(virQEMUDriver *driver,
goto cleanup;
/* de-activate netdevs after stopping CPUs */
- ignore_value(qemuInterfaceStopDevices(vm->def));
+ ignore_value(virDomainInterfaceStopDevices(vm->def));
if (vm->job->current)
ignore_value(virTimeMillisNow(&vm->job->current->stopped));
--
2.41.0
1
0
[libvirt PATCH v2] hypervisor: Move interface mgmt methods to hypervisor
by Praveen K Paladugu 19 Oct '23
by Praveen K Paladugu 19 Oct '23
19 Oct '23
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 | 280 ++++++++++++++++++++++++++++++
src/hypervisor/domain_interface.h | 39 +++++
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, 343 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..592c4253df
--- /dev/null
+++ b/src/hypervisor/domain_interface.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2015-2016 Red Hat, Inc.
+ * Copyright IBM Corp. 2014
+ *
+ * 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 "virconftypes.h"
+#include "virmacaddr.h"
+#include "virnetdevtap.h"
+#include "domain_audit.h"
+#include "domain_conf.h"
+#include "domain_interface.h"
+#include "domain_nwfilter.h"
+#include "viralloc.h"
+#include "virebtables.h"
+#include "virfile.h"
+#include "virlog.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..5594b79bdd
--- /dev/null
+++ b/src/hypervisor/domain_interface.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015-2016 Red Hat, Inc.
+ * Copyright IBM Corp. 2014
+ *
+ * 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));
--
2.41.0
3
2