diff --git a/libvirt-Revert-network-support-setting-firewalld-zone-for-bridge-device-of-open-networks.patch b/libvirt-Revert-network-support-setting-firewalld-zone-for-bridge-device-of-open-networks.patch new file mode 100644 index 0000000..da5cce7 --- /dev/null +++ b/libvirt-Revert-network-support-setting-firewalld-zone-for-bridge-device-of-open-networks.patch @@ -0,0 +1,178 @@ +From 6ff21bba02737104c43e21c7ff640428c77b7656 Mon Sep 17 00:00:00 2001 +Message-ID: <6ff21bba02737104c43e21c7ff640428c77b7656.1728549391.git.jdenemar@redhat.com> +From: Laine Stump +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 +(cherry picked from commit ef760a413361a8992a3e56884a1ec09290954c71) + +https://issues.redhat.com/browse/RHEL-61576 + +Signed-off-by: Jiri Denemark +--- + 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 diff --git a/libvirt-Revert-network-un-set-the-firewalld-zone-while-shutting-down-a-network.patch b/libvirt-Revert-network-un-set-the-firewalld-zone-while-shutting-down-a-network.patch new file mode 100644 index 0000000..d7028e8 --- /dev/null +++ b/libvirt-Revert-network-un-set-the-firewalld-zone-while-shutting-down-a-network.patch @@ -0,0 +1,161 @@ +From b22e871fe2e611e54594b27009abf0dff94403ca Mon Sep 17 00:00:00 2001 +Message-ID: +From: Laine Stump +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 +(cherry picked from commit 816876f51740da8b73c2176de3a64646772218f3) + +https://issues.redhat.com/browse/RHEL-61576 + +Signed-off-by: Jiri Denemark +--- + 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 diff --git a/libvirt-network-a-different-implementation-of-un-setting-firewalld-zone-when-network-is-destroyed.patch b/libvirt-network-a-different-implementation-of-un-setting-firewalld-zone-when-network-is-destroyed.patch new file mode 100644 index 0000000..100b0dc --- /dev/null +++ b/libvirt-network-a-different-implementation-of-un-setting-firewalld-zone-when-network-is-destroyed.patch @@ -0,0 +1,133 @@ +From 48337ce4950f6681fb7d52cf4e4ee6f85f36125b Mon Sep 17 00:00:00 2001 +Message-ID: <48337ce4950f6681fb7d52cf4e4ee6f85f36125b.1728549391.git.jdenemar@redhat.com> +From: Laine Stump +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 +Reviewed-by: Jiri Denemark +(cherry picked from commit c0ba3ed69d14a4b9a03475d1ba1d734b27a141f8) +Signed-off-by: Jiri Denemark +--- + 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 diff --git a/libvirt-network-a-different-way-of-supporting-firewalld-zone-for-mode-open-networks.patch b/libvirt-network-a-different-way-of-supporting-firewalld-zone-for-mode-open-networks.patch new file mode 100644 index 0000000..d42e744 --- /dev/null +++ b/libvirt-network-a-different-way-of-supporting-firewalld-zone-for-mode-open-networks.patch @@ -0,0 +1,168 @@ +From 1801682651a8b3123d4e7a95b26055b521ce0818 Mon Sep 17 00:00:00 2001 +Message-ID: <1801682651a8b3123d4e7a95b26055b521ce0818.1728549391.git.jdenemar@redhat.com> +From: Laine Stump +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 +Reviewed-by: Jiri Denemark +(cherry picked from commit cb4e38d4b1e947d0718232a59f964f35ad156c74) +Signed-off-by: Jiri Denemark +--- + 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 diff --git a/libvirt-network-call-network-Add-Remove-FirewallRules-for-forward-mode-open.patch b/libvirt-network-call-network-Add-Remove-FirewallRules-for-forward-mode-open.patch new file mode 100644 index 0000000..49bc153 --- /dev/null +++ b/libvirt-network-call-network-Add-Remove-FirewallRules-for-forward-mode-open.patch @@ -0,0 +1,333 @@ +From 1c58e627b6825d53e875e3555ad7268499bb0ead Mon Sep 17 00:00:00 2001 +Message-ID: <1c58e627b6825d53e875e3555ad7268499bb0ead.1728549391.git.jdenemar@redhat.com> +From: Laine Stump +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 +Reviewed-by: Jiri Denemark +(cherry picked from commit d552d810b97d478675eac830164349d8a1a35e63) + +https://issues.redhat.com/browse/RHEL-61576 + +Signed-off-by: Jiri Denemark +--- + 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 diff --git a/libvirt.spec b/libvirt.spec index 5f0f670..84829e1 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -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 - 10.8.0-2 +- Revert "network: *un*set the firewalld zone while shutting down a network" (RHEL-61576) +- Revert "network: support setting firewalld zone for bridge device of open networks" (RHEL-61576) +- network: call network(Add|Remove)FirewallRules() for forward mode='open' (RHEL-61576) +- network: a different way of supporting firewalld zone for mode='open' networks (RHEL-61576) +- network: a different implementation of *un*setting firewalld zone when network is destroyed (RHEL-61576) + * Wed Oct 2 2024 Jiri Denemark - 10.8.0-1 - Rebased to libvirt-10.8.0 (RHEL-50574) - The rebase also fixes the following bugs: