diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfa4ab4dc..ae23901329 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2308,7 +2308,6 @@ virFileCacheSetPriv; # util/virfirewall.h virFirewallAddRuleFull; virFirewallApply; -virFirewallBackendSynchronize; virFirewallFree; virFirewallNew; virFirewallRemoveRule; @@ -2329,6 +2328,7 @@ virFirewallDGetVersion; virFirewallDGetZones; virFirewallDInterfaceSetZone; virFirewallDIsRegistered; +virFirewallDSynchronize; virFirewallDZoneExists; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 2fc9f94729..f3172e5c96 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -611,49 +611,6 @@ virFirewallApplyRuleFirewallD(virFirewallRule *rule, } -void -virFirewallBackendSynchronize(void) -{ - const char *arg = "-V"; - g_autofree char *output = NULL; - int firewallDRegistered = virFirewallDIsRegistered(); - - /* - * virFirewallBackendSynchronize() should be called after - * receiving an ownership-change event or reload event for - * firewalld from dbus, prior to performing any operations on the - * default table "filter". - * - * Our iptables filter rules are added to (private chains within) - * the default table named "filter", which is flushed by firewalld - * any time it is restarted or reloads its rules. libvirt watches - * for notifications that firewalld has been restarted / its rules - * reloaded, and then reloads the libvirt rules. But it's possible - * for libvirt to be notified that firewalld has restarted prior - * to firewalld completing initialization, and when that race - * happens, firewalld can potentially flush out rules that libvirt - * has just added! - * - * To prevent this, we send a simple command ("iptables -V") via - * firewalld's passthrough iptables API, and wait until it's - * finished before sending our own directly-executed iptables - * commands. This assures that firewalld has fully initialized and - * caught up with its internal queue of iptables commands, and - * won't stomp all over the new rules we subsequently add. - * - */ - - VIR_DEBUG("Firewalld is registered ? %d", firewallDRegistered); - - if (firewallDRegistered < 0) - return; /* firewalld (or dbus?) not functional, don't sync */ - - ignore_value(virFirewallDApplyRule(VIR_FIREWALL_LAYER_IPV4, - (char **)&arg, 1, true, &output)); - VIR_DEBUG("Result of 'iptables -V' via firewalld: %s", NULLSTR(output)); -} - - static int virFirewallApplyRule(virFirewall *firewall, virFirewallRule *rule, diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index 169d99fe2b..7448825dbc 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -109,6 +109,4 @@ void virFirewallStartRollback(virFirewall *firewall, int virFirewallApply(virFirewall *firewall); -void virFirewallBackendSynchronize(void); - G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree); diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c index 3178bf4b3d..4795bf7925 100644 --- a/src/util/virfirewalld.c +++ b/src/util/virfirewalld.c @@ -368,3 +368,46 @@ virFirewallDInterfaceSetZone(const char *iface, "changeZoneOfInterface", message); } + + +void +virFirewallDSynchronize(void) +{ + const char *arg = "-V"; + g_autofree char *output = NULL; + int firewallDRegistered = virFirewallDIsRegistered(); + + /* + * virFirewallDSynchronize() should be called after receiving an + * ownership-change event or reload event for firewalld from dbus, + * prior to performing any operations on the default table + * "filter". + * + * Our iptables filter rules are added to (private chains within) + * the default table named "filter", which is flushed by firewalld + * any time it is restarted or reloads its rules. libvirt watches + * for notifications that firewalld has been restarted / its rules + * reloaded, and then reloads the libvirt rules. But it's possible + * for libvirt to be notified that firewalld has restarted prior + * to firewalld completing initialization, and when that race + * happens, firewalld can potentially flush out rules that libvirt + * has just added! + * + * To prevent this, we send a simple command ("iptables -V") via + * firewalld's passthrough iptables API, and wait until it's + * finished before sending our own directly-executed iptables + * commands. This assures that firewalld has fully initialized and + * caught up with its internal queue of iptables commands, and + * won't stomp all over the new rules we subsequently add. + * + */ + + VIR_DEBUG("Firewalld is registered ? %d", firewallDRegistered); + + if (firewallDRegistered < 0) + return; /* firewalld (or dbus?) not functional, don't sync */ + + ignore_value(virFirewallDApplyRule(VIR_FIREWALL_LAYER_IPV4, + (char **)&arg, 1, true, &output)); + VIR_DEBUG("Result of 'iptables -V' via firewalld: %s", NULLSTR(output)); +} diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h index d2db3b6f47..c396802a2f 100644 --- a/src/util/virfirewalld.h +++ b/src/util/virfirewalld.h @@ -41,3 +41,5 @@ int virFirewallDApplyRule(virFirewallLayer layer, int virFirewallDInterfaceSetZone(const char *iface, const char *zone); + +void virFirewallDSynchronize(void); diff --git a/src/util/viriptables.c b/src/util/viriptables.c index 34ce9cd018..7db09a0d80 100644 --- a/src/util/viriptables.c +++ b/src/util/viriptables.c @@ -28,6 +28,7 @@ #include "internal.h" #include "viriptables.h" +#include "virfirewalld.h" #include "vircommand.h" #include "viralloc.h" #include "virerror.h" @@ -143,7 +144,7 @@ iptablesSetupPrivateChains(virFirewallLayer layer) * initialization, otherwise it might delete our rules soon after * we add them! */ - virFirewallBackendSynchronize(); + virFirewallDSynchronize(); virFirewallStartTransaction(fw, 0);