util: move and rename virFirewallBackendSynchronize()

This function doesn't have anything to do with manipulating
virFirewall objects, but rather should be called in response to dbus
events about the firewalld service. Move this function into
virfirewalld.c, and rename it to virFirewallDSynchronize().

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Laine Stump 2021-11-17 16:58:40 -05:00
parent be670a91b4
commit d3cd0d19ee
6 changed files with 48 additions and 47 deletions

View File

@ -2308,7 +2308,6 @@ virFileCacheSetPriv;
# util/virfirewall.h
virFirewallAddRuleFull;
virFirewallApply;
virFirewallBackendSynchronize;
virFirewallFree;
virFirewallNew;
virFirewallRemoveRule;
@ -2329,6 +2328,7 @@ virFirewallDGetVersion;
virFirewallDGetZones;
virFirewallDInterfaceSetZone;
virFirewallDIsRegistered;
virFirewallDSynchronize;
virFirewallDZoneExists;

View File

@ -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,

View File

@ -109,6 +109,4 @@ void virFirewallStartRollback(virFirewall *firewall,
int virFirewallApply(virFirewall *firewall);
void virFirewallBackendSynchronize(void);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree);

View File

@ -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));
}

View File

@ -41,3 +41,5 @@ int virFirewallDApplyRule(virFirewallLayer layer,
int virFirewallDInterfaceSetZone(const char *iface,
const char *zone);
void virFirewallDSynchronize(void);

View File

@ -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);