diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 95bdc6e9c1..f581676227 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2149,6 +2149,7 @@ virFileCacheSetPriv; # util/virfirewall.h virFirewallAddRuleFull; virFirewallApply; +virFirewallBackendSynchronize; virFirewallFree; virFirewallNew; virFirewallRemoveRule; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 0b022b14af..307825331d 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -649,6 +649,36 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, return virFirewallDApplyRule(rule->layer, rule->args, rule->argsLen, ignoreErrors, output); } + +void +virFirewallBackendSynchronize(void) +{ + const char *arg = "-V"; + g_autofree char *output = NULL; + + switch (currentBackend) { + case VIR_FIREWALL_BACKEND_DIRECT: + /* nobody to synchronize with */ + break; + case VIR_FIREWALL_BACKEND_FIREWALLD: + /* Send a simple rule via firewalld's passthrough iptables + * command so that we'll be sure firewalld has fully + * initialized and caught up with its internal queue of + * iptables commands. Waiting for this will prevent our own + * directly-executed iptables commands from being run while + * firewalld is still initializing. + */ + ignore_value(virFirewallDApplyRule(VIR_FIREWALL_LAYER_IPV4, + (char **)&arg, 1, true, &output)); + VIR_DEBUG("Result of 'iptables -V' via firewalld: %s", NULLSTR(output)); + break; + case VIR_FIREWALL_BACKEND_AUTOMATIC: + case VIR_FIREWALL_BACKEND_LAST: + break; + } +} + + static int virFirewallApplyRule(virFirewallPtr firewall, virFirewallRulePtr rule, diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index fda3cdec01..3db0864380 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -111,4 +111,6 @@ void virFirewallStartRollback(virFirewallPtr firewall, int virFirewallApply(virFirewallPtr firewall); +void virFirewallBackendSynchronize(void); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree); diff --git a/src/util/viriptables.c b/src/util/viriptables.c index 9cfbc9f2aa..5fbb77fd5b 100644 --- a/src/util/viriptables.c +++ b/src/util/viriptables.c @@ -150,6 +150,13 @@ iptablesSetupPrivateChains(virFirewallLayer layer) }; size_t i; + /* When the backend is firewalld, we need to make sure that + * firewalld has been fully started and completed its + * initialization, otherwise firewalld might delete our rules soon + * after we add them! + */ + virFirewallBackendSynchronize(); + virFirewallStartTransaction(fw, 0); for (i = 0; i < G_N_ELEMENTS(data); i++)