networkShutdownNetworkExternal(virNetworkObjPtr obj);
static void
-networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup);
+networkReloadFirewallRules(virNetworkDriverStatePtr driver,
+ bool startup,
+ bool force);
static void
networkRefreshDaemons(virNetworkDriverStatePtr driver);
if (reload) {
VIR_DEBUG("Reload in bridge_driver because of firewalld.");
- networkReloadFirewallRules(driver, false);
+ networkReloadFirewallRules(driver, false, true);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
virNetworkObjListPrune(network_driver->networks,
VIR_CONNECT_LIST_NETWORKS_INACTIVE |
VIR_CONNECT_LIST_NETWORKS_TRANSIENT);
- networkReloadFirewallRules(network_driver, true);
+ networkReloadFirewallRules(network_driver, true, false);
networkRefreshDaemons(network_driver);
if (virDriverShouldAutostart(network_driver->stateDir, &autostart) < 0)
network_driver->networkConfigDir,
network_driver->networkAutostartDir,
network_driver->xmlopt);
- networkReloadFirewallRules(network_driver, false);
+ networkReloadFirewallRules(network_driver, false, false);
networkRefreshDaemons(network_driver);
virNetworkObjListForEach(network_driver->networks,
networkAutostartConfig,
static void
-networkReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
+networkReloadFirewallRules(virNetworkDriverStatePtr driver,
+ bool startup,
+ bool force)
{
VIR_INFO("Reloading iptables rules");
/* Ideally we'd not even register the driver when unprivilegd
* but until we untangle the virt driver that's not viable */
if (!driver->privileged)
return;
- networkPreReloadFirewallRules(driver, startup);
+ networkPreReloadFirewallRules(driver, startup, force);
virNetworkObjListForEach(driver->networks,
networkReloadFirewallRulesHelper,
NULL);
#define PROC_NET_ROUTE "/proc/net/route"
static virOnceControl createdOnce;
-static bool createdChains;
+static bool chainInitDone; /* true iff networkSetupPrivateChains was ever called */
+static bool createdChains; /* true iff networkSetupPrivateChains created chains during most recent call */
static virErrorPtr errInitV4;
static virErrorPtr errInitV6;
-/* Only call via virOnce */
+/* Usually only called via virOnce, but can also be called directly in
+ * response to firewalld reload (if chainInitDone == true)
+ */
static void networkSetupPrivateChains(void)
{
int rc;
VIR_DEBUG("Global IPv6 chains already exist");
}
}
+
+ chainInitDone = true;
}
}
-void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
+void
+networkPreReloadFirewallRules(virNetworkDriverStatePtr driver,
+ bool startup,
+ bool force)
{
/*
* If there are any running networks, we need to
* of starting the network though as that makes them
* more likely to be seen by a human
*/
- if (!networkHasRunningNetworks(driver)) {
- VIR_DEBUG("Delayed global rule setup as no networks are running");
- return;
- }
+ if (chainInitDone && force) {
+ /* The Private chains have already been initialized once
+ * during this run of libvirtd, so 1) we can't do it again via
+ * virOnce(), and 2) we need to re-add the private chains even
+ * if there are currently no running networks, because the
+ * next time a network is started, libvirt will expect that
+ * the chains have already been added. So we call directly
+ * instead of via virOnce().
+ */
+ networkSetupPrivateChains();
- ignore_value(virOnce(&createdOnce, networkSetupPrivateChains));
+ } else {
+ if (!networkHasRunningNetworks(driver)) {
+ VIR_DEBUG("Delayed global rule setup as no networks are running");
+ return;
+ }
- /*
- * If this is initial startup, and we just created the
- * top level private chains we either
- *
- * - upgraded from old libvirt
- * - freshly booted from clean state
- *
- * In the first case we must delete the old rules from
- * the built-in chains, instead of our new private chains.
- * In the second case it doesn't matter, since no existing
- * rules will be present. Thus we can safely just tell it
- * to always delete from the builin chain
- */
- if (startup && createdChains) {
- VIR_DEBUG("Requesting cleanup of legacy firewall rules");
- iptablesSetDeletePrivate(false);
+ ignore_value(virOnce(&createdOnce, networkSetupPrivateChains));
+
+ /*
+ * If this is initial startup, and we just created the
+ * top level private chains we either
+ *
+ * - upgraded from old libvirt
+ * - freshly booted from clean state
+ *
+ * In the first case we must delete the old rules from
+ * the built-in chains, instead of our new private chains.
+ * In the second case it doesn't matter, since no existing
+ * rules will be present. Thus we can safely just tell it
+ * to always delete from the builin chain
+ */
+ if (startup && createdChains) {
+ VIR_DEBUG("Requesting cleanup of legacy firewall rules");
+ iptablesSetDeletePrivate(false);
+ }
}
}