libvirt-10.8.0-2.el10

- Revert "network: *un*set the firewalld zone while shutting down a network" (RHEL-61752)
- Revert "network: support setting firewalld zone for bridge device of open networks" (RHEL-61752)
- network: call network(Add|Remove)FirewallRules() for forward mode='open' (RHEL-61752)
- network: a different way of supporting firewalld zone for mode='open' networks (RHEL-61752)
- network: a different implementation of *un*setting firewalld zone when network is destroyed (RHEL-61752)

Resolves: RHEL-61752
This commit is contained in:
Jiri Denemark 2024-10-10 13:44:13 +02:00
parent 257e6a9915
commit 6c915788a6
6 changed files with 993 additions and 1 deletions

View File

@ -0,0 +1,178 @@
From b6684fe79ec6b119a1ff7ade68149bf65b127b1a Mon Sep 17 00:00:00 2001
Message-ID: <b6684fe79ec6b119a1ff7ade68149bf65b127b1a.1728560653.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 4 Oct 2024 13:46:20 -0400
Subject: [PATCH] Revert "network: support setting firewalld zone for bridge
device of open networks"
This reverts commit 1a72b83d566df952033529001b0f88a66d7f4393. That
patch had made the incorrect assumption that the firewalld zone of a
bridge would not be changed/removed when firewalld reloaded its rules
(e.g. with "killall -HUP firewalld"). It turns out my memory was
faulty, and this *does* remove the bridge interface's zone, which
results in guest networking failure after a firewalld reload, until
the virtual network is restarted.
The functionality reverted as a result of this patch reversion will be
added back in an upcoming patch that keeps the zone setting in
networkAddFirewallRules() (rather than moving it into a separate
function) so that it is called every time the network's firewall rules
are reloaded (including the reload that happens in response to a
reload notification from firewalld).
Signed-off-by: Laine Stump
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit ef760a413361a8992a3e56884a1ec09290954c71)
https://issues.redhat.com/browse/RHEL-61752
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/network/bridge_driver.c | 4 --
src/network/bridge_driver_linux.c | 61 ++++++++++++----------------
src/network/bridge_driver_nop.c | 13 ------
src/network/bridge_driver_platform.h | 2 -
4 files changed, 26 insertions(+), 54 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c9c6fcbccc..fe053f423a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1999,10 +1999,6 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
if (networkSetIPv6Sysctls(obj) < 0)
goto error;
- /* set the firewall zone for the bridge device on the host */
- if (networkSetBridgeZone(def) < 0)
- goto error;
-
/* Add "once per network" rules */
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval) < 0) {
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index af758d4f3d..5981e3bd19 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -333,8 +333,28 @@ int networkCheckRouteCollision(virNetworkDef *def)
int
-networkSetBridgeZone(virNetworkDef *def)
+networkAddFirewallRules(virNetworkDef *def,
+ virFirewallBackend firewallBackend,
+ virFirewall **fwRemoval)
{
+
+ networkSetupPrivateChains(firewallBackend, false);
+
+ if (errInitV4 &&
+ (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
+ virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
+ virSetError(errInitV4);
+ return -1;
+ }
+
+ if (errInitV6 &&
+ (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
+ virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
+ def->ipv6nogw)) {
+ virSetError(errInitV6);
+ return -1;
+ }
+
if (def->bridgeZone) {
/* if a firewalld zone has been specified, fail/log an error
@@ -350,14 +370,12 @@ networkSetBridgeZone(virNetworkDef *def)
if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
return -1;
- } else if (def->forward.type != VIR_NETWORK_FORWARD_OPEN) {
+ } else {
- /* if firewalld is active, try to set the "libvirt" zone by
- * default (forward mode='open' networks have no zone set by
- * default, but we honor it if one is specified). This is
- * desirable (for consistency) if firewalld is using the
- * iptables backend, but is necessary (for basic network
- * connectivity) if firewalld is using the nftables backend
+ /* if firewalld is active, try to set the "libvirt" zone. This is
+ * desirable (for consistency) if firewalld is using the iptables
+ * backend, but is necessary (for basic network connectivity) if
+ * firewalld is using the nftables backend
*/
if (virFirewallDIsRegistered() == 0) {
@@ -388,33 +406,6 @@ networkSetBridgeZone(virNetworkDef *def)
}
}
- return 0;
-}
-
-
-int
-networkAddFirewallRules(virNetworkDef *def,
- virFirewallBackend firewallBackend,
- virFirewall **fwRemoval)
-{
-
- networkSetupPrivateChains(firewallBackend, false);
-
- if (errInitV4 &&
- (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
- virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
- virSetError(errInitV4);
- return -1;
- }
-
- if (errInitV6 &&
- (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
- virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
- def->ipv6nogw)) {
- virSetError(errInitV6);
- return -1;
- }
-
switch (firewallBackend) {
case VIR_FIREWALL_BACKEND_NONE:
virReportError(VIR_ERR_NO_SUPPORT, "%s",
diff --git a/src/network/bridge_driver_nop.c b/src/network/bridge_driver_nop.c
index 20c7a2a595..8bf3367bff 100644
--- a/src/network/bridge_driver_nop.c
+++ b/src/network/bridge_driver_nop.c
@@ -38,19 +38,6 @@ int networkCheckRouteCollision(virNetworkDef *def G_GNUC_UNUSED)
return 0;
}
-
-int
-networkSetBridgeZone(virNetworkDef *def)
-{
- if (def->bridgeZone) {
- virReportError(VIR_ERR_NO_SUPPORT, "%s",
- _("This platform does not support setting the bridge device zone"));
- return -1;
- }
- return 0;
-}
-
-
int networkAddFirewallRules(virNetworkDef *def G_GNUC_UNUSED,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval G_GNUC_UNUSED)
diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h
index 02abdc197f..cd2e3fa7b5 100644
--- a/src/network/bridge_driver_platform.h
+++ b/src/network/bridge_driver_platform.h
@@ -32,8 +32,6 @@ void networkPostReloadFirewallRules(bool startup);
int networkCheckRouteCollision(virNetworkDef *def);
-int networkSetBridgeZone(virNetworkDef *def);
-
int networkAddFirewallRules(virNetworkDef *def,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval);
--
2.47.0

View File

@ -0,0 +1,161 @@
From 645dab5d9dde36dcef8527bb4aedc2b1cd007890 Mon Sep 17 00:00:00 2001
Message-ID: <645dab5d9dde36dcef8527bb4aedc2b1cd007890.1728560653.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 4 Oct 2024 13:44:32 -0400
Subject: [PATCH] Revert "network: *un*set the firewalld zone while shutting
down a network"
This reverts commit 200f60b2e12e68d618f6d59f0173bb507b678838. The same
functionality will be re-added in a different way in an upcoming patch.
Signed-off-by: Laine Stump
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 816876f51740da8b73c2176de3a64646772218f3)
https://issues.redhat.com/browse/RHEL-61752
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 -
src/network/bridge_driver.c | 4 ----
src/network/bridge_driver_linux.c | 14 --------------
src/network/bridge_driver_nop.c | 6 ------
src/network/bridge_driver_platform.h | 2 --
src/util/virfirewalld.c | 23 -----------------------
src/util/virfirewalld.h | 2 --
7 files changed, 52 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 02dacea857..d186dc40df 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2451,7 +2451,6 @@ virFirewallDGetPolicies;
virFirewallDGetVersion;
virFirewallDGetZones;
virFirewallDInterfaceSetZone;
-virFirewallDInterfaceUnsetZone;
virFirewallDIsRegistered;
virFirewallDPolicyExists;
virFirewallDSynchronize;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 74ba59b4e9..c9c6fcbccc 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2127,8 +2127,6 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
def->forward.type != VIR_NETWORK_FORWARD_OPEN)
networkRemoveFirewallRules(obj);
- networkUnsetBridgeZone(def);
-
virNetworkObjUnrefMacMap(obj);
ignore_value(virNetDevBridgeDelete(def->bridge));
@@ -2167,8 +2165,6 @@ networkShutdownNetworkVirtual(virNetworkObj *obj)
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN)
networkRemoveFirewallRules(obj);
- networkUnsetBridgeZone(def);
-
ignore_value(virNetDevBridgeDelete(def->bridge));
/* See if its still alive and really really kill it */
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index 3b3608c085..af758d4f3d 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -392,20 +392,6 @@ networkSetBridgeZone(virNetworkDef *def)
}
-void
-networkUnsetBridgeZone(virNetworkDef *def)
-{
- /* If there is a libvirt-managed bridge device remove it from any
- * zone it had been placed in as a part of deleting the bridge.
- * DO NOT CALL THIS FOR 'bridge' forward mode, since that
- * bridge is not managed by libvirt.
- */
- if (def->bridge && def->forward.type != VIR_NETWORK_FORWARD_BRIDGE
- && virFirewallDIsRegistered() == 0) {
- virFirewallDInterfaceUnsetZone(def->bridge);
- }
-}
-
int
networkAddFirewallRules(virNetworkDef *def,
virFirewallBackend firewallBackend,
diff --git a/src/network/bridge_driver_nop.c b/src/network/bridge_driver_nop.c
index 831a5a5010..20c7a2a595 100644
--- a/src/network/bridge_driver_nop.c
+++ b/src/network/bridge_driver_nop.c
@@ -51,12 +51,6 @@ networkSetBridgeZone(virNetworkDef *def)
}
-void
-networkUnsetBridgeZone(virNetworkDef *def G_GNUC_UNUSED)
-{
-}
-
-
int networkAddFirewallRules(virNetworkDef *def G_GNUC_UNUSED,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval G_GNUC_UNUSED)
diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driver_platform.h
index a0291532a1..02abdc197f 100644
--- a/src/network/bridge_driver_platform.h
+++ b/src/network/bridge_driver_platform.h
@@ -38,6 +38,4 @@ int networkAddFirewallRules(virNetworkDef *def,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval);
-void networkUnsetBridgeZone(virNetworkDef *def);
-
void networkRemoveFirewallRules(virNetworkObj *obj);
diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c
index 4aec33ac45..827e201dbb 100644
--- a/src/util/virfirewalld.c
+++ b/src/util/virfirewalld.c
@@ -449,29 +449,6 @@ virFirewallDInterfaceSetZone(const char *iface,
}
-int
-virFirewallDInterfaceUnsetZone(const char *iface)
-{
- GDBusConnection *sysbus = virGDBusGetSystemBus();
- g_autoptr(GVariant) message = NULL;
-
- if (!sysbus)
- return -1;
-
- message = g_variant_new("(ss)", "", iface);
-
- return virGDBusCallMethod(sysbus,
- NULL,
- NULL,
- NULL,
- VIR_FIREWALL_FIREWALLD_SERVICE,
- "/org/fedoraproject/FirewallD1",
- "org.fedoraproject.FirewallD1.zone",
- "removeInterface",
- message);
-}
-
-
void
virFirewallDSynchronize(void)
{
diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h
index 0dbe66d435..0e94d3507b 100644
--- a/src/util/virfirewalld.h
+++ b/src/util/virfirewalld.h
@@ -46,6 +46,4 @@ int virFirewallDApplyRule(virFirewallLayer layer,
int virFirewallDInterfaceSetZone(const char *iface,
const char *zone);
-int virFirewallDInterfaceUnsetZone(const char *iface);
-
void virFirewallDSynchronize(void);
--
2.47.0

View File

@ -0,0 +1,136 @@
From e143cec8c08e42995198dc1c75fba7d3379751bd Mon Sep 17 00:00:00 2001
Message-ID: <e143cec8c08e42995198dc1c75fba7d3379751bd.1728560653.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 4 Oct 2024 18:43:02 -0400
Subject: [PATCH] network: a different implementation of *un*setting firewalld
zone when network is destroyed
(this is a remake of commit v10.7.0-78-g200f60b2e1, which was reverted
due to a regression in another patch it was dependent on. The new
implementation just adds the call to virFirewallDInterfaceUnsetZone()
into the existing networkRemoveFirewallRules() (but only if we had set
a zone when the network was first started).
Replaces: 200f60b2e12e68d618f6d59f0173bb507b678838
Resolves: https://issues.redhat.com/browse/RHEL-61576
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit c0ba3ed69d14a4b9a03475d1ba1d734b27a141f8)
https://issues.redhat.com/browse/RHEL-61752
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 +
src/network/bridge_driver_linux.c | 30 ++++++++++++++++++++++++------
src/util/virfirewalld.c | 23 +++++++++++++++++++++++
src/util/virfirewalld.h | 2 ++
4 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d186dc40df..02dacea857 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2451,6 +2451,7 @@ virFirewallDGetPolicies;
virFirewallDGetVersion;
virFirewallDGetZones;
virFirewallDInterfaceSetZone;
+virFirewallDInterfaceUnsetZone;
virFirewallDIsRegistered;
virFirewallDPolicyExists;
virFirewallDSynchronize;
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index 8956d38ab1..6c3ec403a4 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -459,19 +459,37 @@ networkRemoveFirewallRules(virNetworkObj *obj)
} else {
if ((fw = virNetworkObjGetFwRemoval(obj)) == NULL) {
+
/* No information about firewall rules in the network status,
* so we assume the old iptables-based rules from 10.2.0 and
* earlier.
*/
VIR_DEBUG("No firewall info in status of network '%s', assuming old-style iptables", def->name);
iptablesRemoveFirewallRules(def);
- return;
+
+ } else {
+
+ /* fwRemoval info was stored in the network status, so use that to
+ * remove the firewall
+ */
+ VIR_DEBUG("Removing firewall rules of network '%s' using commands saved in status", def->name);
+ virFirewallApply(fw);
}
+ }
- /* fwRemoval info was stored in the network status, so use that to
- * remove the firewall
- */
- VIR_DEBUG("Removing firewall rules of network '%s' using commands saved in status", def->name);
- virFirewallApply(fw);
+ /* all forward modes could have had a zone set, even 'open' mode
+ * iff it was specified in the config. firewalld preserves the
+ * name of an interface in a zone's list even after the interface
+ * has been deleted, which is problematic if the next use of that
+ * same interface name wants *no* zone set. To avoid this, we must
+ * "unset" the zone if we set it when the network was started.
+ */
+ if (virFirewallDIsRegistered() == 0 &&
+ (def->forward.type != VIR_NETWORK_FORWARD_OPEN ||
+ def->bridgeZone)) {
+
+ VIR_DEBUG("unsetting zone for '%s' (current zone is '%s')",
+ def->bridge, def->bridgeZone);
+ virFirewallDInterfaceUnsetZone(def->bridge);
}
}
diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c
index 827e201dbb..ca61ed5ac0 100644
--- a/src/util/virfirewalld.c
+++ b/src/util/virfirewalld.c
@@ -449,6 +449,29 @@ virFirewallDInterfaceSetZone(const char *iface,
}
+int
+virFirewallDInterfaceUnsetZone(const char *iface)
+{
+ GDBusConnection *sysbus = virGDBusGetSystemBus();
+ g_autoptr(GVariant) message = NULL;
+
+ if (!sysbus)
+ return -1;
+
+ message = g_variant_new("(ss)", "", iface);
+
+ return virGDBusCallMethod(sysbus,
+ NULL,
+ NULL,
+ NULL,
+ VIR_FIREWALL_FIREWALLD_SERVICE,
+ "/org/fedoraproject/FirewallD1",
+ "org.fedoraproject.FirewallD1.zone",
+ "removeInterface",
+ message);
+}
+
+
void
virFirewallDSynchronize(void)
{
diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h
index 0e94d3507b..0dbe66d435 100644
--- a/src/util/virfirewalld.h
+++ b/src/util/virfirewalld.h
@@ -46,4 +46,6 @@ int virFirewallDApplyRule(virFirewallLayer layer,
int virFirewallDInterfaceSetZone(const char *iface,
const char *zone);
+int virFirewallDInterfaceUnsetZone(const char *iface);
+
void virFirewallDSynchronize(void);
--
2.47.0

View File

@ -0,0 +1,171 @@
From d0efb1123f1e2d4b4792e5eca8ff3d69fa9d46e7 Mon Sep 17 00:00:00 2001
Message-ID: <d0efb1123f1e2d4b4792e5eca8ff3d69fa9d46e7.1728560653.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 4 Oct 2024 18:14:36 -0400
Subject: [PATCH] network: a different way of supporting firewalld zone for
mode='open' networks
Now that networkAddFirewallRules and networkRemoveFirewallRules() are
being called for mode='open' networks, we just need to move the code
that sets the zone outside of the if (mode != ...OPEN) clause, so that
it's done for all forward modes, with the exception of setting the
implied 'libvirt*' zones, which are set when no zone is specified for
all forward modes *except* 'open'.
This was previously done in commit v10.7.0-76-g1a72b83d56, but in a
manner that caused the zone to be unset whenever firewalld reloaded
its rules. That patch was reverted, and this new better patch takes
its place.
Replaces: 1a72b83d566df952033529001b0f88a66d7f4393
Resolves: https://issues.redhat.com/browse/RHEL-61576
Re-Resolves: https://gitlab.com/libvirt/libvirt/-/issues/215
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit cb4e38d4b1e947d0718232a59f964f35ad156c74)
https://issues.redhat.com/browse/RHEL-61752
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/network/bridge_driver_linux.c | 111 ++++++++++++++++--------------
1 file changed, 60 insertions(+), 51 deletions(-)
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index 31feec9c9f..8956d38ab1 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -337,6 +337,64 @@ networkAddFirewallRules(virNetworkDef *def,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval)
{
+ /* If firewalld is running on the system, a firewalld zone is
+ * always set for the bridge device of all bridge-based managed
+ * networks of all forward modes *except* 'open', which is only
+ * set if specifically requested in the config.
+ */
+ if (def->bridgeZone) {
+
+ /* if a firewalld zone has been specified, fail/log an error
+ * if we can't honor it
+ */
+ if (virFirewallDIsRegistered() < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("zone %1$s requested for network %2$s but firewalld is not active"),
+ def->bridgeZone, def->name);
+ return -1;
+ }
+
+ if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
+ return -1;
+
+ } else if (def->forward.type != VIR_NETWORK_FORWARD_OPEN) {
+
+ /* if firewalld is active, try to set the "libvirt" zone by
+ * default (forward mode='open' networks have no zone set by
+ * default, but we honor it if one is specified). This is
+ * desirable (for consistency) if firewalld is using the
+ * iptables backend, but is necessary (for basic network
+ * connectivity) if firewalld is using the nftables backend
+ */
+ if (virFirewallDIsRegistered() == 0) {
+
+ /* if the "libvirt" zone exists, then set it. If not, and
+ * if firewalld is using the nftables backend, then we
+ * need to log an error because the combination of
+ * nftables + default zone means that traffic cannot be
+ * forwarded (and even DHCP and DNS from guest to host
+ * will probably no be permitted by the default zone
+ *
+ * Routed networks use a different zone and policy which we also
+ * need to verify exist. Probing for the policy guarantees the
+ * running firewalld has support for policies (firewalld >= 0.9.0).
+ */
+ if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
+ virFirewallDPolicyExists("libvirt-routed-out") &&
+ virFirewallDZoneExists("libvirt-routed")) {
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
+ return -1;
+ } else if (virFirewallDZoneExists("libvirt")) {
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
+ return -1;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
+ return -1;
+ }
+ }
+ }
+
if (def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
VIR_DEBUG("No firewall rules to add for mode='open' network '%s'", def->name);
@@ -348,6 +406,7 @@ networkAddFirewallRules(virNetworkDef *def,
def->name,
virFirewallBackendTypeToString(firewallBackend));
+ /* one-time (per system boot) initialization */
networkSetupPrivateChains(firewallBackend, false);
if (errInitV4 &&
@@ -365,57 +424,7 @@ networkAddFirewallRules(virNetworkDef *def,
return -1;
}
- if (def->bridgeZone) {
-
- /* if a firewalld zone has been specified, fail/log an error
- * if we can't honor it
- */
- if (virFirewallDIsRegistered() < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("zone %1$s requested for network %2$s but firewalld is not active"),
- def->bridgeZone, def->name);
- return -1;
- }
-
- if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
- return -1;
-
- } else {
-
- /* if firewalld is active, try to set the "libvirt" zone. This is
- * desirable (for consistency) if firewalld is using the iptables
- * backend, but is necessary (for basic network connectivity) if
- * firewalld is using the nftables backend
- */
- if (virFirewallDIsRegistered() == 0) {
-
- /* if the "libvirt" zone exists, then set it. If not, and
- * if firewalld is using the nftables backend, then we
- * need to log an error because the combination of
- * nftables + default zone means that traffic cannot be
- * forwarded (and even DHCP and DNS from guest to host
- * will probably no be permitted by the default zone
- *
- * Routed networks use a different zone and policy which we also
- * need to verify exist. Probing for the policy guarantees the
- * running firewalld has support for policies (firewalld >= 0.9.0).
- */
- if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
- virFirewallDPolicyExists("libvirt-routed-out") &&
- virFirewallDZoneExists("libvirt-routed")) {
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
- return -1;
- } else if (virFirewallDZoneExists("libvirt")) {
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
- return -1;
- } else {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
- return -1;
- }
- }
- }
-
+ /* now actually add the rules */
switch (firewallBackend) {
case VIR_FIREWALL_BACKEND_NONE:
virReportError(VIR_ERR_NO_SUPPORT, "%s",
--
2.47.0

View File

@ -0,0 +1,333 @@
From 383ace4feee4ae610917edf8a583257a67a7d52c Mon Sep 17 00:00:00 2001
Message-ID: <383ace4feee4ae610917edf8a583257a67a7d52c.1728560653.git.jdenemar@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Fri, 4 Oct 2024 17:17:59 -0400
Subject: [PATCH] network: call network(Add|Remove)FirewallRules() for forward
mode='open'
Previously networkAddFirewallRules() and networkRemoveFirewallRules()
were only called if the forward mode was none, 'route', or 'nat', so
those functions didn't check the forward mode. Although their current
contents shouldn't be executed for forward mode='open', soon they will
have extra functionality that should be executed for all the current
forward modes and also mode='open'.
This patch modifies all places either of the functions are called to
make sure they are called for mode='open' in addition to current modes
(by either adding 'case ..._OPEN:' to the case of a switch statement,
or just removing an 'if (mode != ...OPEN)' around the calls; to
balance out for that, it puts the entirety of the contents of both
functions inside if (mode != ...OPEN) to retain current behavior. (an
upcoming patch will add code outside that if clause).
debug log messages were also added to make it easier to test that the
right thing is being done in all cases.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit d552d810b97d478675eac830164349d8a1a35e63)
https://issues.redhat.com/browse/RHEL-61752
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/network/bridge_driver.c | 26 ++---
src/network/bridge_driver_linux.c | 175 +++++++++++++++++-------------
2 files changed, 110 insertions(+), 91 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index fe053f423a..f604b2695c 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1735,10 +1735,15 @@ networkReloadFirewallRulesHelper(virNetworkObj *obj,
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
- /* Only three of the L3 network types that are configured by
- * libvirt need to have iptables rules reloaded. The 4th L3
- * network type, forward='open', doesn't need this because it
- * has no iptables rules.
+ case VIR_NETWORK_FORWARD_OPEN:
+ /* even 'open' forward type networks need to call
+ * networkAdd/RemoveFirewallRules() in spite of the fact
+ * that, by definition, libvirt doesn't add any firewall
+ * rules for those networks.. This is because libvirt
+ * *does* support explicitly naming (in the config) a
+ * firewalld zone the network's bridge should be added to,
+ * and this functionality is also handled by
+ * networkAdd/RemoveFirewallRules()
*/
networkRemoveFirewallRules(obj);
ignore_value(networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval));
@@ -1746,7 +1751,6 @@ networkReloadFirewallRulesHelper(virNetworkObj *obj,
saveStatus = true;
break;
- case VIR_NETWORK_FORWARD_OPEN:
case VIR_NETWORK_FORWARD_BRIDGE:
case VIR_NETWORK_FORWARD_PRIVATE:
case VIR_NETWORK_FORWARD_VEPA:
@@ -2000,10 +2004,8 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
goto error;
/* Add "once per network" rules */
- if (def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
- networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval) < 0) {
+ if (networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval) < 0)
goto error;
- }
virNetworkObjSetFwRemoval(obj, fwRemoval);
firewalRulesAdded = true;
@@ -2119,8 +2121,7 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
if (devOnline)
ignore_value(virNetDevSetOnline(def->bridge, false));
- if (firewalRulesAdded &&
- def->forward.type != VIR_NETWORK_FORWARD_OPEN)
+ if (firewalRulesAdded)
networkRemoveFirewallRules(obj);
virNetworkObjUnrefMacMap(obj);
@@ -2158,8 +2159,7 @@ networkShutdownNetworkVirtual(virNetworkObj *obj)
ignore_value(virNetDevSetOnline(def->bridge, false));
- if (def->forward.type != VIR_NETWORK_FORWARD_OPEN)
- networkRemoveFirewallRules(obj);
+ networkRemoveFirewallRules(obj);
ignore_value(virNetDevBridgeDelete(def->bridge));
@@ -3307,6 +3307,7 @@ networkUpdate(virNetworkPtr net,
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
switch (section) {
case VIR_NETWORK_SECTION_FORWARD:
case VIR_NETWORK_SECTION_FORWARD_INTERFACE:
@@ -3325,7 +3326,6 @@ networkUpdate(virNetworkPtr net,
}
break;
- case VIR_NETWORK_FORWARD_OPEN:
case VIR_NETWORK_FORWARD_BRIDGE:
case VIR_NETWORK_FORWARD_PRIVATE:
case VIR_NETWORK_FORWARD_VEPA:
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
index 5981e3bd19..31feec9c9f 100644
--- a/src/network/bridge_driver_linux.c
+++ b/src/network/bridge_driver_linux.c
@@ -337,90 +337,101 @@ networkAddFirewallRules(virNetworkDef *def,
virFirewallBackend firewallBackend,
virFirewall **fwRemoval)
{
+ if (def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
- networkSetupPrivateChains(firewallBackend, false);
+ VIR_DEBUG("No firewall rules to add for mode='open' network '%s'", def->name);
- if (errInitV4 &&
- (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
- virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
- virSetError(errInitV4);
- return -1;
- }
+ } else {
- if (errInitV6 &&
- (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
- virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
- def->ipv6nogw)) {
- virSetError(errInitV6);
- return -1;
- }
+ VIR_DEBUG("Adding firewall rules for mode='%s' network '%s' using %s",
+ virNetworkForwardTypeToString(def->forward.type),
+ def->name,
+ virFirewallBackendTypeToString(firewallBackend));
- if (def->bridgeZone) {
+ networkSetupPrivateChains(firewallBackend, false);
- /* if a firewalld zone has been specified, fail/log an error
- * if we can't honor it
- */
- if (virFirewallDIsRegistered() < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("zone %1$s requested for network %2$s but firewalld is not active"),
- def->bridgeZone, def->name);
+ if (errInitV4 &&
+ (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
+ virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
+ virSetError(errInitV4);
return -1;
}
- if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
+ if (errInitV6 &&
+ (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
+ virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
+ def->ipv6nogw)) {
+ virSetError(errInitV6);
return -1;
+ }
- } else {
+ if (def->bridgeZone) {
- /* if firewalld is active, try to set the "libvirt" zone. This is
- * desirable (for consistency) if firewalld is using the iptables
- * backend, but is necessary (for basic network connectivity) if
- * firewalld is using the nftables backend
- */
- if (virFirewallDIsRegistered() == 0) {
-
- /* if the "libvirt" zone exists, then set it. If not, and
- * if firewalld is using the nftables backend, then we
- * need to log an error because the combination of
- * nftables + default zone means that traffic cannot be
- * forwarded (and even DHCP and DNS from guest to host
- * will probably no be permitted by the default zone
- *
- * Routed networks use a different zone and policy which we also
- * need to verify exist. Probing for the policy guarantees the
- * running firewalld has support for policies (firewalld >= 0.9.0).
+ /* if a firewalld zone has been specified, fail/log an error
+ * if we can't honor it
*/
- if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
- virFirewallDPolicyExists("libvirt-routed-out") &&
- virFirewallDZoneExists("libvirt-routed")) {
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
- return -1;
- } else if (virFirewallDZoneExists("libvirt")) {
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
- return -1;
- } else {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
+ if (virFirewallDIsRegistered() < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("zone %1$s requested for network %2$s but firewalld is not active"),
+ def->bridgeZone, def->name);
return -1;
}
+
+ if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
+ return -1;
+
+ } else {
+
+ /* if firewalld is active, try to set the "libvirt" zone. This is
+ * desirable (for consistency) if firewalld is using the iptables
+ * backend, but is necessary (for basic network connectivity) if
+ * firewalld is using the nftables backend
+ */
+ if (virFirewallDIsRegistered() == 0) {
+
+ /* if the "libvirt" zone exists, then set it. If not, and
+ * if firewalld is using the nftables backend, then we
+ * need to log an error because the combination of
+ * nftables + default zone means that traffic cannot be
+ * forwarded (and even DHCP and DNS from guest to host
+ * will probably no be permitted by the default zone
+ *
+ * Routed networks use a different zone and policy which we also
+ * need to verify exist. Probing for the policy guarantees the
+ * running firewalld has support for policies (firewalld >= 0.9.0).
+ */
+ if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
+ virFirewallDPolicyExists("libvirt-routed-out") &&
+ virFirewallDZoneExists("libvirt-routed")) {
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
+ return -1;
+ } else if (virFirewallDZoneExists("libvirt")) {
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
+ return -1;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
+ return -1;
+ }
+ }
}
- }
- switch (firewallBackend) {
- case VIR_FIREWALL_BACKEND_NONE:
- virReportError(VIR_ERR_NO_SUPPORT, "%s",
- _("No firewall backend is available"));
- return -1;
+ switch (firewallBackend) {
+ case VIR_FIREWALL_BACKEND_NONE:
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("No firewall backend is available"));
+ return -1;
- case VIR_FIREWALL_BACKEND_IPTABLES:
- return iptablesAddFirewallRules(def, fwRemoval);
+ case VIR_FIREWALL_BACKEND_IPTABLES:
+ return iptablesAddFirewallRules(def, fwRemoval);
- case VIR_FIREWALL_BACKEND_NFTABLES:
- return nftablesAddFirewallRules(def, fwRemoval);
+ case VIR_FIREWALL_BACKEND_NFTABLES:
+ return nftablesAddFirewallRules(def, fwRemoval);
- case VIR_FIREWALL_BACKEND_LAST:
- virReportEnumRangeError(virFirewallBackend, firewallBackend);
- return -1;
+ case VIR_FIREWALL_BACKEND_LAST:
+ virReportEnumRangeError(virFirewallBackend, firewallBackend);
+ return -1;
+ }
}
return 0;
}
@@ -429,21 +440,29 @@ networkAddFirewallRules(virNetworkDef *def,
void
networkRemoveFirewallRules(virNetworkObj *obj)
{
+ virNetworkDef *def = virNetworkObjGetDef(obj);
virFirewall *fw;
- if ((fw = virNetworkObjGetFwRemoval(obj)) == NULL) {
- /* No information about firewall rules in the network status,
- * so we assume the old iptables-based rules from 10.2.0 and
- * earlier.
+ if (def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
+
+ VIR_DEBUG("No firewall rules to remove for mode='open' network '%s'", def->name);
+
+ } else {
+
+ if ((fw = virNetworkObjGetFwRemoval(obj)) == NULL) {
+ /* No information about firewall rules in the network status,
+ * so we assume the old iptables-based rules from 10.2.0 and
+ * earlier.
+ */
+ VIR_DEBUG("No firewall info in status of network '%s', assuming old-style iptables", def->name);
+ iptablesRemoveFirewallRules(def);
+ return;
+ }
+
+ /* fwRemoval info was stored in the network status, so use that to
+ * remove the firewall
*/
- VIR_DEBUG("No firewall info in network status, assuming old-style iptables");
- iptablesRemoveFirewallRules(virNetworkObjGetDef(obj));
- return;
+ VIR_DEBUG("Removing firewall rules of network '%s' using commands saved in status", def->name);
+ virFirewallApply(fw);
}
-
- /* fwRemoval info was stored in the network status, so use that to
- * remove the firewall
- */
- VIR_DEBUG("Removing firewall rules with commands saved in network status");
- virFirewallApply(fw);
}
--
2.47.0

View File

@ -289,7 +289,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 10.8.0
Release: 1%{?dist}%{?extra_release}
Release: 2%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -297,6 +297,12 @@ URL: https://libvirt.org/
%define mainturl stable_updates/
%endif
Source: https://download.libvirt.org/%{?mainturl}libvirt-%{version}.tar.xz
Patch1: libvirt-Revert-network-un-set-the-firewalld-zone-while-shutting-down-a-network.patch
Patch2: libvirt-Revert-network-support-setting-firewalld-zone-for-bridge-device-of-open-networks.patch
Patch3: libvirt-network-call-network-Add-Remove-FirewallRules-for-forward-mode-open.patch
Patch4: libvirt-network-a-different-way-of-supporting-firewalld-zone-for-mode-open-networks.patch
Patch5: libvirt-network-a-different-implementation-of-un-setting-firewalld-zone-when-network-is-destroyed.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -2622,6 +2628,13 @@ exit 0
%endif
%changelog
* Thu Oct 10 2024 Jiri Denemark <jdenemar@redhat.com> - 10.8.0-2
- Revert "network: *un*set the firewalld zone while shutting down a network" (RHEL-61752)
- Revert "network: support setting firewalld zone for bridge device of open networks" (RHEL-61752)
- network: call network(Add|Remove)FirewallRules() for forward mode='open' (RHEL-61752)
- network: a different way of supporting firewalld zone for mode='open' networks (RHEL-61752)
- network: a different implementation of *un*setting firewalld zone when network is destroyed (RHEL-61752)
* Tue Oct 1 2024 Jiri Denemark <jdenemar@redhat.com> - 10.8.0-1
- Rebased to libvirt-10.8.0 (RHEL-50577)
- The rebase also fixes the following bugs: