[PATCH] qemuDomainDiskChangeSupported: Fill in missing check
by Adam Julis
Any modification of iothreads attribute is prohibit, the original setup
must be identical with updated version of xml.
Resolves: https://issues.redhat.com/browse/RHEL-23607
Signed-off-by: Adam Julis <ajulis(a)redhat.com>
---
src/qemu/qemu_domain.c | 47 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 1a90311ca5..6d7b939a31 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8484,6 +8484,53 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk,
CHECK_EQ(discard, "discard", true);
CHECK_EQ(iothread, "iothread", true);
+ /* check if new or original disk contains iothreads information
+ * if yes, they must be identical, any changes are prohibit*/
+
+ if (!!disk->iothreads != !!orig_disk->iothreads) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("cannot modify field '%1$s' of the disk"),
+ "iothreads");
+ return false;
+ }
+
+ if (disk->iothreads && orig_disk->iothreads) {
+ GSList *n, *m;
+
+ m = disk->iothreads;
+
+ for (n = orig_disk->iothreads; n; n = n->next) {
+ size_t i;
+ virDomainDiskIothreadDef *n_data = (virDomainDiskIothreadDef *) n->data;
+ virDomainDiskIothreadDef *m_data = (virDomainDiskIothreadDef *) m->data;
+
+ if (n_data->id != m_data->id || n_data->nqueues != m_data->nqueues) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("cannot modify field '%1$s' of the disk"),
+ "iothreads");
+ return false;
+ }
+
+ for (i = 0; i < n_data->nqueues; i++) {
+ if (n_data->queues[i] != m_data->queues[i]) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("cannot modify field '%1$s' of the disk"),
+ "iothreads");
+ return false;
+ }
+ }
+
+ m = m->next;
+
+ if (!m && n->next) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("cannot modify field '%1$s' of the disk"),
+ "iothreads");
+ return false;
+ }
+ }
+ }
+
CHECK_STREQ_NULLABLE(domain_name,
"backenddomain");
--
2.45.2
4 months, 1 week
[PATCH 0/8] Expose SEV-SNP in domcaps and virt-host-validate
by Michal Privoznik
This is a promised follow up to:
https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/message/7...
Michal Prívozník (8):
libvirt_private.syms: Export virDomainLaunchSecurity enum handlers
qemuxmlconftest; Explicitly enable QEMU_CAPS_SEV_SNP_GUEST for
"launch-security-sev-snp"
qemu_capabilities: Probe SEV capabilities even for
QEMU_CAPS_SEV_SNP_GUEST
domcaps: Report launchSecurity
qemu: Fill launchSecurity in domaincaps
qemu_validate: Use domaincaps to validate supported launchSecurity
type
virt-host-validate: Move AMD SEV into a separate func
virt-host-validate: Detect SEV-ES and SEV-SNP
docs/formatdomaincaps.rst | 10 +++
src/conf/domain_capabilities.c | 14 ++++
src/conf/domain_capabilities.h | 9 ++
src/conf/schemas/domaincaps.rng | 10 +++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 24 +++++-
src/qemu/qemu_capabilities.h | 3 +
src/qemu/qemu_validate.c | 29 +++----
.../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 3 +
.../qemu_4.2.0-virt.aarch64.xml | 3 +
tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_4.2.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_4.2.0.s390x.xml | 3 +
tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 3 +
.../qemu_5.0.0-tcg-virt.riscv64.xml | 3 +
.../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 3 +
.../qemu_5.0.0-virt.aarch64.xml | 3 +
.../qemu_5.0.0-virt.riscv64.xml | 3 +
tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_5.1.0.sparc.xml | 3 +
tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 3 +
.../qemu_5.2.0-tcg-virt.riscv64.xml | 3 +
.../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 3 +
.../qemu_5.2.0-virt.aarch64.xml | 3 +
.../qemu_5.2.0-virt.riscv64.xml | 3 +
tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_5.2.0.s390x.xml | 3 +
tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 5 ++
.../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 5 ++
.../qemu_6.0.0-virt.aarch64.xml | 3 +
tests/domaincapsdata/qemu_6.0.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_6.0.0.s390x.xml | 5 ++
tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 5 ++
.../domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 3 +
.../qemu_6.2.0-virt.aarch64.xml | 3 +
tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 3 +
.../qemu_7.0.0-hvf.aarch64+hvf.xml | 3 +
.../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 3 +
.../qemu_7.0.0-virt.aarch64.xml | 3 +
tests/domaincapsdata/qemu_7.0.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_7.1.0.ppc64.xml | 3 +
tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 3 +
.../qemu_7.2.0-hvf.x86_64+hvf.xml | 3 +
.../domaincapsdata/qemu_7.2.0-q35.x86_64.xml | 3 +
.../qemu_7.2.0-tcg.x86_64+hvf.xml | 3 +
.../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_7.2.0.ppc.xml | 3 +
tests/domaincapsdata/qemu_7.2.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_8.0.0-q35.x86_64.xml | 3 +
.../qemu_8.0.0-tcg-virt.riscv64.xml | 3 +
.../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml | 3 +
.../qemu_8.0.0-virt.riscv64.xml | 3 +
tests/domaincapsdata/qemu_8.0.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_8.1.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_8.1.0.s390x.xml | 5 ++
tests/domaincapsdata/qemu_8.1.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_8.2.0-q35.x86_64.xml | 3 +
.../qemu_8.2.0-tcg-virt.loongarch64.xml | 3 +
.../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml | 3 +
.../qemu_8.2.0-virt.aarch64.xml | 3 +
.../qemu_8.2.0-virt.loongarch64.xml | 3 +
tests/domaincapsdata/qemu_8.2.0.aarch64.xml | 3 +
tests/domaincapsdata/qemu_8.2.0.armv7l.xml | 3 +
tests/domaincapsdata/qemu_8.2.0.s390x.xml | 5 ++
tests/domaincapsdata/qemu_8.2.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_9.0.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_9.0.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_9.0.0.x86_64.xml | 3 +
.../domaincapsdata/qemu_9.1.0-q35.x86_64.xml | 3 +
.../domaincapsdata/qemu_9.1.0-tcg.x86_64.xml | 3 +
tests/domaincapsdata/qemu_9.1.0.x86_64.xml | 3 +
.../caps_9.1.0_x86_64.xml | 1 -
tests/qemuxmlconftest.c | 6 +-
tools/virt-host-validate-common.c | 83 ++++++++++++++-----
95 files changed, 413 insertions(+), 42 deletions(-)
--
2.44.2
4 months, 1 week
[PATCH 0/2] qemu_command: Enable sev-guest.legacy-vm-type when possible
by Michal Privoznik
*** IMPORTANT ***
There's a competing patch sent to qemu-devel which when merged renders
these patches unnecessary:
https://mail.gnu.org/archive/html/qemu-devel/2024-06/msg02776.html
But I accumulated this change whilst working on previous patches that
enabled SEV SNP and figured might as well send them if QEMU patch
doesn't make it in time for our release.
Michal Prívozník (2):
qemu_capabilities: Introduce QEMU_CAPS_SEV_GUEST_LEGACY_VM_TYPE
qemu_command: Enable sev-guest.legacy-vm-type when possible
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 9 +++++++++
tests/qemucapabilitiesdata/caps_9.1.0_x86_64.xml | 1 +
.../launch-security-sev-direct.x86_64-latest.args | 2 +-
5 files changed, 14 insertions(+), 1 deletion(-)
--
2.44.2
4 months, 1 week
[PATCH v2] qemu_block: Validate number of hosts for iSCSI disk device
by Rayhan Faizel
An iSCSI device with zero hosts will result in a segmentation fault. This patch
adds a check for the number of hosts, which must be one in the case of iSCSI.
Minimal reproducing XML:
<domain type='qemu'>
<name>MyGuest</name>
<uuid>4dea22b3-1d52-d8f3-2516-782e98ab3fa0</uuid>
<os>
<type arch='x86_64'>hvm</type>
</os>
<memory>4096</memory>
<devices>
<disk type='network'>
<source name='dummy' protocol='iscsi'/>
<target dev='vda'/>
</disk>
</devices>
</domain>
Signed-off-by: Rayhan Faizel <rayhan.faizel(a)gmail.com>
---
This crashing XML was detected by the WIP fuzzer which is being developed
as part of Google Summer of Code 2024.
[Changes in v2]
- Added testcase for iSCSI disk definitions with zero hosts
src/qemu/qemu_block.c | 6 ++++
...iscsi-zero-hosts-invalid.x86_64-latest.err | 1 +
...iscsi-zero-hosts-invalid.x86_64-latest.xml | 35 +++++++++++++++++++
.../disk-network-iscsi-zero-hosts-invalid.xml | 27 ++++++++++++++
tests/qemuxmlconftest.c | 2 ++
5 files changed, 71 insertions(+)
create mode 100644 tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.xml
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 738b72d7ea..d6cdf521c4 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -602,6 +602,12 @@ qemuBlockStorageSourceGetISCSIProps(virStorageSource *src,
* }
*/
+ if (src->nhosts != 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("iSCSI protocol accepts only one host"));
+ return NULL;
+ }
+
target = g_strdup(src->path);
/* Separate the target and lun */
diff --git a/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.err b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.err
new file mode 100644
index 0000000000..ec66bebf22
--- /dev/null
+++ b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.err
@@ -0,0 +1 @@
+internal error: iSCSI protocol accepts only one host
diff --git a/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.xml b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.xml
new file mode 100644
index 0000000000..ad556180ab
--- /dev/null
+++ b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.x86_64-latest.xml
@@ -0,0 +1,35 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='network' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='iscsi' name='iqn.1992-01.com.example:storage/1'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <controller type='usb' index='0' model='piix3-uhci'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.xml b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.xml
new file mode 100644
index 0000000000..6369f01644
--- /dev/null
+++ b/tests/qemuxmlconfdata/disk-network-iscsi-zero-hosts-invalid.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='network' device='disk'>
+ <source protocol='iscsi' name='iqn.1992-01.com.example:storage/1'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 2842b44b3e..0c71db1f22 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2987,6 +2987,8 @@ mymain(void)
DO_TEST_CAPS_LATEST("net-usb")
DO_TEST_CAPS_LATEST("sound-device-virtio")
+ DO_TEST_CAPS_LATEST_FAILURE("disk-network-iscsi-zero-hosts-invalid")
+
/* check that all input files were actually used here */
if (testConfXMLCheck(existingTestCases) < 0)
ret = -1;
--
2.34.1
4 months, 1 week
[PATCH v2] qemu: add support for qemu switchover-ack
by Jon Kohler
Add plumbing for QEMU's switchover-ack migration capability, which
helps lower the downtime during VFIO migrations. This capability is
enabled by default as long as both the source and destination support
it.
Note: switchover-ack depends on the return path capability, so this may
not be used when VIR_MIGRATE_TUNNELLED flag is set.
Extensive details about the qemu switchover-ack implementation are
available in the qemu series v6 cover letter [1] where the highlight is
the extreme reduction in guest visible downtime. In addition to the
original test results below, I saw a roughly ~20% reduction in downtime
for VFIO VGPU devices at minimum.
=== Test results ===
The below table shows the downtime of two identical migrations. In the
first migration swithcover ack is disabled and in the second it is
enabled. The migrated VM is assigned with a mlx5 VFIO device which has
300MB of device data to be migrated.
+----------------------+-----------------------+----------+
| Switchover ack | VFIO device data size | Downtime |
+----------------------+-----------------------+----------+
| Disabled | 300MB | 1900ms |
| Enabled | 300MB | 420ms |
+----------------------+-----------------------+----------+
Switchover ack gives a roughly 4.5 times improvement in downtime.
The 1480ms difference is time that is used for resource allocation for
the VFIO device in the destination. Without switchover ack, this time is
spent when the source VM is stopped and thus the downtime is much
higher. With switchover ack, the time is spent when the source VM is
still running.
[1] https://patchwork.kernel.org/project/qemu-devel/cover/20230621111201.2972...
Signed-off-by: Jon Kohler <jon(a)nutanix.com>
Cc: Alex Williamson <alex.williamson(a)redhat.com>
Cc: Avihai Horon <avihaih(a)nvidia.com>
Cc: Markus Armbruster <armbru(a)redhat.com>
Cc: Peter Xu <peterx(a)redhat.com>
Cc: YangHang Liu <yanghliu(a)redhat.com>
---
v1
- https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/2X...
v1 -> v2:
- Addressed comments to simplify approach (Daniel, Jiri)
---
src/qemu/qemu_migration.h | 1 +
src/qemu/qemu_migration_params.c | 8 +++++++-
src/qemu/qemu_migration_params.h | 1 +
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ed62fd4a91..cd89e100e1 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -62,6 +62,7 @@
VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES | \
VIR_MIGRATE_POSTCOPY_RESUME | \
VIR_MIGRATE_ZEROCOPY | \
+ VIR_MIGRATE_SWITCHOVER_ACK | \
0)
/* All supported migration parameters and their types. */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 48f8657f71..9593b6ba65 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -105,6 +105,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability,
"return-path",
"zero-copy-send",
"postcopy-preempt",
+ "switchover-ack",
);
@@ -138,7 +139,7 @@ struct _qemuMigrationParamsAlwaysOnItem {
typedef struct _qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMapItem;
struct _qemuMigrationParamsFlagMapItem {
/* Describes what to do with the capability if @flag is found.
- * When se to QEMU_MIGRATION_FLAG_REQUIRED, the capability will be
+ * When set to QEMU_MIGRATION_FLAG_REQUIRED, the capability will be
* enabled iff the specified migration flag is enabled. On the other hand
* QEMU_MIGRATION_FLAG_FORBIDDEN will enable the capability as long as
* the specified migration flag is not enabled. */
@@ -215,6 +216,11 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = {
.flag = VIR_MIGRATE_ZEROCOPY,
.cap = QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
.party = QEMU_MIGRATION_SOURCE},
+
+ {.match = QEMU_MIGRATION_FLAG_FORBIDDEN,
+ .flag = VIR_MIGRATE_TUNNELLED,
+ .cap = QEMU_MIGRATION_CAP_SWITCHOVER_ACK,
+ .party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
};
/* Translation from VIR_MIGRATE_PARAM_* typed parameters to
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 91bc6792cd..df67f1fb92 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -41,6 +41,7 @@ typedef enum {
QEMU_MIGRATION_CAP_RETURN_PATH,
QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
QEMU_MIGRATION_CAP_POSTCOPY_PREEMPT,
+ QEMU_MIGRATION_CAP_SWITCHOVER_ACK,
QEMU_MIGRATION_CAP_LAST
} qemuMigrationCapability;
--
2.43.0
4 months, 1 week
[PATCH] qemu: Fix migration with disabled vmx-* CPU features
by Jiri Denemark
When starting a domain on a host which lacks a vmx-* CPU feature which
is expected to be enabled by the CPU model specified in the domain XML,
libvirt properly marks such feature as disabled in the active domain
XML. But migrating the domain to a similar host which lacks the same
vmx-* feature will fail with libvirt reporting the feature as missing.
This is because of a bug in the hack ensuring backward compatibility
libvirt running on the destination thinks the missing feature is
expected to be enabled.
https://issues.redhat.com/browse/RHEL-40899
Fixes: v10.1.0-85-g5fbfa5ab8a
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/cpu/cpu_x86.c | 44 +++++++++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 7a70eed9e7..fcbce0ec46 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -3021,10 +3021,7 @@ virCPUx86UpdateLive(virCPUDef *cpu,
if (!(map = virCPUx86GetMap()))
return -1;
- if (!(model = x86ModelFromCPU(cpu, map, -1)))
- return -1;
-
- if (hostPassthrough &&
+ if (!(model = x86ModelFromCPU(cpu, map, -1)) ||
!(modelDisabled = x86ModelFromCPU(cpu, map, VIR_CPU_FEATURE_DISABLE)))
return -1;
@@ -3037,12 +3034,19 @@ virCPUx86UpdateLive(virCPUDef *cpu,
for (i = 0; i < map->nfeatures; i++) {
virCPUx86Feature *feature = map->features[i];
virCPUFeaturePolicy expected = VIR_CPU_FEATURE_LAST;
+ bool explicit = false;
+ bool ignore = false;
- if (x86DataIsSubset(&model->data, &feature->data))
+ if (x86DataIsSubset(&model->data, &feature->data)) {
+ explicit = true;
expected = VIR_CPU_FEATURE_REQUIRE;
- else if (!hostPassthrough ||
- x86DataIsSubset(&modelDisabled->data, &feature->data))
+ } else if (x86DataIsSubset(&modelDisabled->data, &feature->data)) {
+ explicit = true;
+ expected = VIR_CPU_FEATURE_DISABLE;
+ } else if (!hostPassthrough) {
+ /* implicitly disabled */
expected = VIR_CPU_FEATURE_DISABLE;
+ }
if (x86DataIsSubset(&enabled, &feature->data) &&
x86DataIsSubset(&disabled, &feature->data)) {
@@ -3052,30 +3056,36 @@ virCPUx86UpdateLive(virCPUDef *cpu,
return -1;
}
+ /* Features enabled or disabled by the hypervisor are ignored by
+ * check='full' in case they were added to the model later and not
+ * explicitly mentioned in the CPU definition. This matches how libvirt
+ * behaved before the features were added.
+ */
+ if (!explicit &&
+ g_strv_contains((const char **) model->addedFeatures, feature->name))
+ ignore = true;
+
if (expected == VIR_CPU_FEATURE_DISABLE &&
x86DataIsSubset(&enabled, &feature->data)) {
VIR_DEBUG("Feature '%s' enabled by the hypervisor", feature->name);
- /* Extra features enabled by the hypervisor are ignored by
- * check='full' in case they were added to the model later for
- * backward compatibility with the older definition of the model.
- */
- if (cpu->check == VIR_CPU_CHECK_FULL &&
- !g_strv_contains((const char **) model->addedFeatures, feature->name)) {
+ if (cpu->check == VIR_CPU_CHECK_FULL && !ignore)
virBufferAsprintf(&bufAdded, "%s,", feature->name);
- } else {
+ else
virCPUDefUpdateFeature(cpu, feature->name, VIR_CPU_FEATURE_REQUIRE);
- }
}
if (x86DataIsSubset(&disabled, &feature->data) ||
(expected == VIR_CPU_FEATURE_REQUIRE &&
!x86DataIsSubset(&enabled, &feature->data))) {
VIR_DEBUG("Feature '%s' disabled by the hypervisor", feature->name);
- if (cpu->check == VIR_CPU_CHECK_FULL)
+
+ if (cpu->check == VIR_CPU_CHECK_FULL && !ignore) {
virBufferAsprintf(&bufRemoved, "%s,", feature->name);
- else
+ } else {
virCPUDefUpdateFeature(cpu, feature->name, VIR_CPU_FEATURE_DISABLE);
+ x86DataSubtract(&disabled, &feature->data);
+ }
}
}
--
2.45.1
4 months, 1 week
[PATCH] qemu: add support for qemu switchover-ack
by Jon Kohler
Add plumbing for QEMU's switchover-ack migration capability, which
helps lower the downtime during VFIO migrations. This capability is
enabled by default as long as both the source and destination support
it.
Note: switchover-ack depends on the return path capability, so this may
not be used when VIR_MIGRATE_TUNNELLED flag is set.
Extensive details about the qemu switchover-ack implementation are
available in the qemu series v6 cover letter [1] where the highlight is
the extreme reduction in guest visible downtime. In addition to the
original test results below, I saw a roughly ~20% reduction in downtime
for VFIO VGPU devices at minimum.
=== Test results ===
The below table shows the downtime of two identical migrations. In the
first migration swithcover ack is disabled and in the second it is
enabled. The migrated VM is assigned with a mlx5 VFIO device which has
300MB of device data to be migrated.
+----------------------+-----------------------+----------+
| Switchover ack | VFIO device data size | Downtime |
+----------------------+-----------------------+----------+
| Disabled | 300MB | 1900ms |
| Enabled | 300MB | 420ms |
+----------------------+-----------------------+----------+
Switchover ack gives a roughly 4.5 times improvement in downtime.
The 1480ms difference is time that is used for resource allocation for
the VFIO device in the destination. Without switchover ack, this time is
spent when the source VM is stopped and thus the downtime is much
higher. With switchover ack, the time is spent when the source VM is
still running.
[1] https://patchwork.kernel.org/project/qemu-devel/cover/20230621111201.2972...
Signed-off-by: Jon Kohler <jon(a)nutanix.com>
Cc: Alex Williamson <alex.williamson(a)redhat.com>
Cc: Avihai Horon <avihaih(a)nvidia.com>
Cc: Markus Armbruster <armbru(a)redhat.com>
Cc: Peter Xu <peterx(a)redhat.com>
Cc: YangHang Liu <yanghliu(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 11 +++++++++++
src/libvirt-domain.c | 20 ++++++++++++++++++++
src/qemu/qemu_migration.h | 1 +
src/qemu/qemu_migration_params.c | 8 +++++++-
src/qemu/qemu_migration_params.h | 1 +
5 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 2f5b01bbfe..9543629f30 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1100,6 +1100,17 @@ typedef enum {
* Since: 8.5.0
*/
VIR_MIGRATE_ZEROCOPY = (1 << 20),
+
+ /* Use switchover ack migration capability to reduce downtime on VFIO
+ * device migration. This prevents the source from stopping the VM and
+ * completing the migration until an ACK is received from the destination
+ * that it's OK to do so. Thus, a VFIO device can make sure that its
+ * initial bytes were sent and loaded in the destination before the
+ * source VM is stopped.
+ *
+ * Since: 10.5.0
+ */
+ VIR_MIGRATE_SWITCHOVER_ACK = (1 << 21),
} virDomainMigrateFlags;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 7c6b93963c..786fef317d 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -3822,6 +3822,10 @@ virDomainMigrate(virDomainPtr domain,
VIR_MIGRATE_PARALLEL,
error);
+ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED,
+ VIR_MIGRATE_SWITCHOVER_ACK,
+ error);
+
VIR_REQUIRE_FLAG_GOTO(VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES,
VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC,
error);
@@ -4021,6 +4025,10 @@ virDomainMigrate2(virDomainPtr domain,
VIR_MIGRATE_PARALLEL,
error);
+ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED,
+ VIR_MIGRATE_SWITCHOVER_ACK,
+ error);
+
VIR_REQUIRE_FLAG_GOTO(VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES,
VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC,
error);
@@ -4497,6 +4505,10 @@ virDomainMigrateToURI(virDomainPtr domain,
VIR_MIGRATE_PARALLEL,
error);
+ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED,
+ VIR_MIGRATE_SWITCHOVER_ACK,
+ error);
+
if (virDomainMigrateUnmanagedCheckCompat(domain, flags) < 0)
goto error;
@@ -4577,6 +4589,10 @@ virDomainMigrateToURI2(virDomainPtr domain,
VIR_MIGRATE_PARALLEL,
error);
+ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED,
+ VIR_MIGRATE_SWITCHOVER_ACK,
+ error);
+
if (virDomainMigrateUnmanagedCheckCompat(domain, flags) < 0)
goto error;
@@ -4656,6 +4672,10 @@ virDomainMigrateToURI3(virDomainPtr domain,
VIR_MIGRATE_PARALLEL,
error);
+ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_MIGRATE_TUNNELLED,
+ VIR_MIGRATE_SWITCHOVER_ACK,
+ error);
+
if (virDomainMigrateUnmanagedCheckCompat(domain, flags) < 0)
goto error;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ed62fd4a91..cd89e100e1 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -62,6 +62,7 @@
VIR_MIGRATE_NON_SHARED_SYNCHRONOUS_WRITES | \
VIR_MIGRATE_POSTCOPY_RESUME | \
VIR_MIGRATE_ZEROCOPY | \
+ VIR_MIGRATE_SWITCHOVER_ACK | \
0)
/* All supported migration parameters and their types. */
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 48f8657f71..9593b6ba65 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -105,6 +105,7 @@ VIR_ENUM_IMPL(qemuMigrationCapability,
"return-path",
"zero-copy-send",
"postcopy-preempt",
+ "switchover-ack",
);
@@ -138,7 +139,7 @@ struct _qemuMigrationParamsAlwaysOnItem {
typedef struct _qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMapItem;
struct _qemuMigrationParamsFlagMapItem {
/* Describes what to do with the capability if @flag is found.
- * When se to QEMU_MIGRATION_FLAG_REQUIRED, the capability will be
+ * When set to QEMU_MIGRATION_FLAG_REQUIRED, the capability will be
* enabled iff the specified migration flag is enabled. On the other hand
* QEMU_MIGRATION_FLAG_FORBIDDEN will enable the capability as long as
* the specified migration flag is not enabled. */
@@ -215,6 +216,11 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = {
.flag = VIR_MIGRATE_ZEROCOPY,
.cap = QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
.party = QEMU_MIGRATION_SOURCE},
+
+ {.match = QEMU_MIGRATION_FLAG_FORBIDDEN,
+ .flag = VIR_MIGRATE_TUNNELLED,
+ .cap = QEMU_MIGRATION_CAP_SWITCHOVER_ACK,
+ .party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
};
/* Translation from VIR_MIGRATE_PARAM_* typed parameters to
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 91bc6792cd..df67f1fb92 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -41,6 +41,7 @@ typedef enum {
QEMU_MIGRATION_CAP_RETURN_PATH,
QEMU_MIGRATION_CAP_ZERO_COPY_SEND,
QEMU_MIGRATION_CAP_POSTCOPY_PREEMPT,
+ QEMU_MIGRATION_CAP_SWITCHOVER_ACK,
QEMU_MIGRATION_CAP_LAST
} qemuMigrationCapability;
--
2.43.0
4 months, 1 week
[PATCH] network: add more firewall test cases
by Laine Stump
This patch adds some previously missing test cases that test for
proper firewall rule creation when the following are included in the
network definition:
* <forward dev='blah'>
* no forward element (an "isolated" network)
* nat port range when only ipv4 is nat-ed
* nat port range when both ipv4 & ipv6 are nated
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
If you ack this, please also push it, as I'm on vacation and only
sporadically connected.
.../forward-dev-linux.iptables | 154 +++++++
.../forward-dev-linux.nftables | 158 +++++++
tests/networkxml2firewalldata/forward-dev.xml | 10 +
.../isolated-linux.iptables | 159 ++++++++
.../isolated-linux.nftables | 64 +++
tests/networkxml2firewalldata/isolated.xml | 15 +
.../nat-port-range-ipv6-linux.iptables | 317 ++++++++++++++
.../nat-port-range-ipv6-linux.nftables | 386 ++++++++++++++++++
.../nat-port-range-ipv6.xml | 20 +
.../nat-port-range-linux.iptables | 283 +++++++++++++
.../nat-port-range-linux.nftables | 314 ++++++++++++++
.../nat-port-range.xml | 20 +
tests/networkxml2firewalltest.c | 5 +
13 files changed, 1905 insertions(+)
create mode 100644 tests/networkxml2firewalldata/forward-dev-linux.iptables
create mode 100644 tests/networkxml2firewalldata/forward-dev-linux.nftables
create mode 100644 tests/networkxml2firewalldata/forward-dev.xml
create mode 100644 tests/networkxml2firewalldata/isolated-linux.iptables
create mode 100644 tests/networkxml2firewalldata/isolated-linux.nftables
create mode 100644 tests/networkxml2firewalldata/isolated.xml
create mode 100644 tests/networkxml2firewalldata/nat-port-range-ipv6-linux.iptables
create mode 100644 tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
create mode 100644 tests/networkxml2firewalldata/nat-port-range-ipv6.xml
create mode 100644 tests/networkxml2firewalldata/nat-port-range-linux.iptables
create mode 100644 tests/networkxml2firewalldata/nat-port-range-linux.nftables
create mode 100644 tests/networkxml2firewalldata/nat-port-range.xml
diff --git a/tests/networkxml2firewalldata/forward-dev-linux.iptables b/tests/networkxml2firewalldata/forward-dev-linux.iptables
new file mode 100644
index 0000000000..bc483c4512
--- /dev/null
+++ b/tests/networkxml2firewalldata/forward-dev-linux.iptables
@@ -0,0 +1,154 @@
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.122.0/24 \
+--in-interface virbr0 \
+--out-interface enp0s7 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.122.0/24 \
+--in-interface enp0s7 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 '!' \
+--destination 192.168.122.0/24 \
+--out-interface enp0s7 \
+--jump MASQUERADE
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p udp '!' \
+--destination 192.168.122.0/24 \
+--out-interface enp0s7 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p tcp '!' \
+--destination 192.168.122.0/24 \
+--out-interface enp0s7 \
+--jump MASQUERADE \
+--to-ports 1024-65535
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--out-interface enp0s7 \
+--source 192.168.122.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--out-interface enp0s7 \
+--source 192.168.122.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+iptables \
+-w \
+--table mangle \
+--insert LIBVIRT_PRT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump CHECKSUM \
+--checksum-fill
diff --git a/tests/networkxml2firewalldata/forward-dev-linux.nftables b/tests/networkxml2firewalldata/forward-dev-linux.nftables
new file mode 100644
index 0000000000..8badb74beb
--- /dev/null
+++ b/tests/networkxml2firewalldata/forward-dev-linux.nftables
@@ -0,0 +1,158 @@
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+ip \
+saddr \
+192.168.122.0/24 \
+iif \
+virbr0 \
+oifname \
+enp0s7 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+iifname \
+enp0s7 \
+oif \
+virbr0 \
+ip \
+daddr \
+192.168.122.0/24 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+oifname \
+enp0s7 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+oifname \
+enp0s7 \
+counter \
+masquerade \
+to \
+:1024-65535
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+oifname \
+enp0s7 \
+counter \
+masquerade \
+to \
+:1024-65535
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+oifname \
+enp0s7 \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+255.255.255.255/32 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+oifname \
+enp0s7 \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+224.0.0.0/24 \
+counter \
+return
diff --git a/tests/networkxml2firewalldata/forward-dev.xml b/tests/networkxml2firewalldata/forward-dev.xml
new file mode 100644
index 0000000000..8e49d3984d
--- /dev/null
+++ b/tests/networkxml2firewalldata/forward-dev.xml
@@ -0,0 +1,10 @@
+<network>
+ <name>default</name>
+ <bridge name="virbr0"/>
+ <forward mode='nat' dev='enp0s7'/>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2firewalldata/isolated-linux.iptables b/tests/networkxml2firewalldata/isolated-linux.iptables
new file mode 100644
index 0000000000..135189ce41
--- /dev/null
+++ b/tests/networkxml2firewalldata/isolated-linux.iptables
@@ -0,0 +1,159 @@
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 547 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 546 \
+--jump ACCEPT
+iptables \
+-w \
+--table mangle \
+--insert LIBVIRT_PRT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump CHECKSUM \
+--checksum-fill
diff --git a/tests/networkxml2firewalldata/isolated-linux.nftables b/tests/networkxml2firewalldata/isolated-linux.nftables
new file mode 100644
index 0000000000..d1b4dac178
--- /dev/null
+++ b/tests/networkxml2firewalldata/isolated-linux.nftables
@@ -0,0 +1,64 @@
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
diff --git a/tests/networkxml2firewalldata/isolated.xml b/tests/networkxml2firewalldata/isolated.xml
new file mode 100644
index 0000000000..0e3bed10d1
--- /dev/null
+++ b/tests/networkxml2firewalldata/isolated.xml
@@ -0,0 +1,15 @@
+<network>
+ <name>default</name>
+ <bridge name="virbr0"/>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ </dhcp>
+ </ip>
+ <ip address="192.168.128.1" netmask="255.255.255.0"/>
+ <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" >
+ <dhcp>
+ <range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" />
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.iptables b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.iptables
new file mode 100644
index 0000000000..c2e845cc4f
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.iptables
@@ -0,0 +1,317 @@
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 547 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 546 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.122.0/24 \
+--in-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.122.0/24 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p udp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p tcp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.128.0/24 \
+--in-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.128.0/24 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+-p udp '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+-p tcp '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 2001:db8:ca2:2::/64 \
+--in-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 2001:db8:ca2:2::/64 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+ip6tables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE
+ip6tables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+-p udp '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE \
+--to-ports 500-1000
+ip6tables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+-p tcp '!' \
+--destination 2001:db8:ca2:2::/64 \
+--jump MASQUERADE \
+--to-ports 500-1000
+ip6tables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 2001:db8:ca2:2::/64 \
+--destination ff02::/16 \
+--jump RETURN
+iptables \
+-w \
+--table mangle \
+--insert LIBVIRT_PRT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump CHECKSUM \
+--checksum-fill
diff --git a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
new file mode 100644
index 0000000000..ceaed6fa40
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
@@ -0,0 +1,386 @@
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+ip \
+saddr \
+192.168.122.0/24 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+ip \
+daddr \
+192.168.122.0/24 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+255.255.255.255/32 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+224.0.0.0/24 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+ip \
+saddr \
+192.168.128.0/24 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+ip \
+daddr \
+192.168.128.0/24 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+255.255.255.255/32 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+224.0.0.0/24 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_output \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+ip6 \
+daddr \
+2001:db8:ca2:2::/64 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_nat \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+ip6 \
+daddr \
+'!=' \
+2001:db8:ca2:2::/64 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+ip6 \
+daddr \
+'!=' \
+2001:db8:ca2:2::/64 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+ip6 \
+daddr \
+'!=' \
+2001:db8:ca2:2::/64 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_nat \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+ip6 \
+daddr \
+ff02::/16 \
+counter \
+return
diff --git a/tests/networkxml2firewalldata/nat-port-range-ipv6.xml b/tests/networkxml2firewalldata/nat-port-range-ipv6.xml
new file mode 100644
index 0000000000..9a70764fa0
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range-ipv6.xml
@@ -0,0 +1,20 @@
+<network>
+ <name>default</name>
+ <bridge name="virbr0"/>
+ <forward mode='nat'>
+ <nat ipv6='yes'>
+ <port start='500' end='1000'/>
+ </nat>
+ </forward>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ </dhcp>
+ </ip>
+ <ip address="192.168.128.1" netmask="255.255.255.0"/>
+ <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" >
+ <dhcp>
+ <range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" />
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2firewalldata/nat-port-range-linux.iptables b/tests/networkxml2firewalldata/nat-port-range-linux.iptables
new file mode 100644
index 0000000000..8e5c2c8193
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range-linux.iptables
@@ -0,0 +1,283 @@
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 67 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--in-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--out-interface virbr0 \
+--jump REJECT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWX \
+--in-interface virbr0 \
+--out-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol tcp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 53 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_INP \
+--in-interface virbr0 \
+--protocol udp \
+--destination-port 547 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_OUT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 546 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.122.0/24 \
+--in-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.122.0/24 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p udp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+-p tcp '!' \
+--destination 192.168.122.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.122.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 192.168.128.0/24 \
+--in-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 192.168.128.0/24 \
+--out-interface virbr0 \
+--match conntrack \
+--ctstate ESTABLISHED,RELATED \
+--jump ACCEPT
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+-p udp '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+-p tcp '!' \
+--destination 192.168.128.0/24 \
+--jump MASQUERADE \
+--to-ports 500-1000
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+--destination 255.255.255.255/32 \
+--jump RETURN
+iptables \
+-w \
+--table nat \
+--insert LIBVIRT_PRT \
+--source 192.168.128.0/24 \
+--destination 224.0.0.0/24 \
+--jump RETURN
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWO \
+--source 2001:db8:ca2:2::/64 \
+--in-interface virbr0 \
+--jump ACCEPT
+ip6tables \
+-w \
+--table filter \
+--insert LIBVIRT_FWI \
+--destination 2001:db8:ca2:2::/64 \
+--out-interface virbr0 \
+--jump ACCEPT
+iptables \
+-w \
+--table mangle \
+--insert LIBVIRT_PRT \
+--out-interface virbr0 \
+--protocol udp \
+--destination-port 68 \
+--jump CHECKSUM \
+--checksum-fill
diff --git a/tests/networkxml2firewalldata/nat-port-range-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
new file mode 100644
index 0000000000..1dc37a26ec
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
@@ -0,0 +1,314 @@
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_output \
+iif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+counter \
+reject
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_cross \
+iif \
+virbr0 \
+oif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+ip \
+saddr \
+192.168.122.0/24 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+ip \
+daddr \
+192.168.122.0/24 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.122.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+255.255.255.255/32 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.122.0/24 \
+ip \
+daddr \
+224.0.0.0/24 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_output \
+ip \
+saddr \
+192.168.128.0/24 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_input \
+oif \
+virbr0 \
+ip \
+daddr \
+192.168.128.0/24 \
+ct \
+state \
+related,established \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+udp \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+meta \
+l4proto \
+tcp \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+'!=' \
+192.168.128.0/24 \
+counter \
+masquerade \
+to \
+:500-1000
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+255.255.255.255/32 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip \
+libvirt_network \
+guest_nat \
+ip \
+saddr \
+192.168.128.0/24 \
+ip \
+daddr \
+224.0.0.0/24 \
+counter \
+return
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_output \
+ip6 \
+saddr \
+2001:db8:ca2:2::/64 \
+iif \
+virbr0 \
+counter \
+accept
+nft \
+-ae insert \
+rule \
+ip6 \
+libvirt_network \
+guest_input \
+ip6 \
+daddr \
+2001:db8:ca2:2::/64 \
+oif \
+virbr0 \
+counter \
+accept
diff --git a/tests/networkxml2firewalldata/nat-port-range.xml b/tests/networkxml2firewalldata/nat-port-range.xml
new file mode 100644
index 0000000000..81b29d3b72
--- /dev/null
+++ b/tests/networkxml2firewalldata/nat-port-range.xml
@@ -0,0 +1,20 @@
+<network>
+ <name>default</name>
+ <bridge name="virbr0"/>
+ <forward mode='nat'>
+ <nat>
+ <port start='500' end='1000'/>
+ </nat>
+ </forward>
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.2" end="192.168.122.254"/>
+ </dhcp>
+ </ip>
+ <ip address="192.168.128.1" netmask="255.255.255.0"/>
+ <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" >
+ <dhcp>
+ <range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff" />
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2firewalltest.c b/tests/networkxml2firewalltest.c
index 4cabe39d1d..f7b87ff798 100644
--- a/tests/networkxml2firewalltest.c
+++ b/tests/networkxml2firewalltest.c
@@ -198,6 +198,11 @@ mymain(void)
DO_TEST("nat-ipv6");
DO_TEST("nat-ipv6-masquerade");
DO_TEST("route-default");
+ DO_TEST("forward-dev");
+ DO_TEST("isolated");
+ DO_TEST("forward-dev");
+ DO_TEST("nat-port-range");
+ DO_TEST("nat-port-range-ipv6");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
2.45.2
4 months, 1 week
[PATCH] tests: fix broken nftables test data so that individual tests are successful
by Laine Stump
When the chain names and table name used by the nftables firewall
backend were changed in commit
958aa7f274904eb8e4678a43eac845044f0dcc38, I forgot to change the test
data file base.nftables, which has the extra "list" and "add
chain/table" commands that are generated for the first test case of
networkxml2firewalltest.c. When the full set of tests is run, the
first test will be an iptables test case, so those extra commands
won't be added to any of the nftables cases, and so the data in
base.nftables never matches, and the tests are all successful.
However, if the test are limited with, e.g. VIR_TEST_RANGE=2 (test #2
will be the nftables version of the 1st test case), then the commands
to add nftables table/chains *will* be generated in the test output,
and so the test will fail. Because I was only running the entire test
series after the initial commits of nftables tests, I didn't notice
this. Until now.
base.nftables has now been updated to reflect the current names for
chains/table, and running individual test cases is once again
successful.
Fixes: 958aa7f274904eb8e4678a43eac845044f0dcc38
Signed-off-by: Laine Stump <laine(a)redhat.com>
---
tests/networkxml2firewalldata/base.nftables | 202 ++++----------------
1 file changed, 42 insertions(+), 160 deletions(-)
diff --git a/tests/networkxml2firewalldata/base.nftables b/tests/networkxml2firewalldata/base.nftables
index 4f1f475a85..a064318739 100644
--- a/tests/networkxml2firewalldata/base.nftables
+++ b/tests/networkxml2firewalldata/base.nftables
@@ -2,255 +2,137 @@ nft \
list \
table \
ip \
-libvirt
+libvirt_network
nft \
add \
table \
ip \
-libvirt
+libvirt_network
nft \
add \
chain \
ip \
-libvirt \
-INPUT \
-'{ type filter hook input priority 0; policy accept; }'
-nft \
-add \
-chain \
-ip \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
'{ type filter hook forward priority 0; policy accept; }'
nft \
add \
chain \
ip \
-libvirt \
-OUTPUT \
-'{ type filter hook output priority 0; policy accept; }'
-nft \
-add \
-chain \
-ip \
-libvirt \
-LIBVIRT_INP
-nft \
-insert \
-rule \
-ip \
-libvirt \
-INPUT \
-counter \
-jump \
-LIBVIRT_INP
-nft \
-add \
-chain \
-ip \
-libvirt \
-LIBVIRT_OUT
-nft \
-insert \
-rule \
-ip \
-libvirt \
-OUTPUT \
-counter \
-jump \
-LIBVIRT_OUT
-nft \
-add \
-chain \
-ip \
-libvirt \
-LIBVIRT_FWO
+libvirt_network \
+guest_output
nft \
insert \
rule \
ip \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWO
+guest_output
nft \
add \
chain \
ip \
-libvirt \
-LIBVIRT_FWI
+libvirt_network \
+guest_input
nft \
insert \
rule \
ip \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWI
+guest_input
nft \
add \
chain \
ip \
-libvirt \
-LIBVIRT_FWX
+libvirt_network \
+guest_cross
nft \
insert \
rule \
ip \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWX
+guest_cross
nft \
add \
chain \
ip \
-libvirt \
-POSTROUTING \
+libvirt_network \
+guest_nat \
'{ type nat hook postrouting priority 100; policy accept; }'
nft \
-add \
-chain \
-ip \
-libvirt \
-LIBVIRT_PRT
-nft \
-insert \
-rule \
-ip \
-libvirt \
-POSTROUTING \
-counter \
-jump \
-LIBVIRT_PRT
-nft \
list \
table \
ip6 \
-libvirt
+libvirt_network
nft \
add \
table \
ip6 \
-libvirt
+libvirt_network
nft \
add \
chain \
ip6 \
-libvirt \
-INPUT \
-'{ type filter hook input priority 0; policy accept; }'
-nft \
-add \
-chain \
-ip6 \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
'{ type filter hook forward priority 0; policy accept; }'
nft \
add \
chain \
ip6 \
-libvirt \
-OUTPUT \
-'{ type filter hook output priority 0; policy accept; }'
-nft \
-add \
-chain \
-ip6 \
-libvirt \
-LIBVIRT_INP
-nft \
-insert \
-rule \
-ip6 \
-libvirt \
-INPUT \
-counter \
-jump \
-LIBVIRT_INP
-nft \
-add \
-chain \
-ip6 \
-libvirt \
-LIBVIRT_OUT
-nft \
-insert \
-rule \
-ip6 \
-libvirt \
-OUTPUT \
-counter \
-jump \
-LIBVIRT_OUT
-nft \
-add \
-chain \
-ip6 \
-libvirt \
-LIBVIRT_FWO
+libvirt_network \
+guest_output
nft \
insert \
rule \
ip6 \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWO
+guest_output
nft \
add \
chain \
ip6 \
-libvirt \
-LIBVIRT_FWI
+libvirt_network \
+guest_input
nft \
insert \
rule \
ip6 \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWI
+guest_input
nft \
add \
chain \
ip6 \
-libvirt \
-LIBVIRT_FWX
+libvirt_network \
+guest_cross
nft \
insert \
rule \
ip6 \
-libvirt \
-FORWARD \
+libvirt_network \
+forward \
counter \
jump \
-LIBVIRT_FWX
+guest_cross
nft \
add \
chain \
ip6 \
-libvirt \
-POSTROUTING \
+libvirt_network \
+guest_nat \
'{ type nat hook postrouting priority 100; policy accept; }'
-nft \
-add \
-chain \
-ip6 \
-libvirt \
-LIBVIRT_PRT
-nft \
-insert \
-rule \
-ip6 \
-libvirt \
-POSTROUTING \
-counter \
-jump \
-LIBVIRT_PRT
--
2.45.2
4 months, 1 week