g_autoptr(virNetworkDriverConfig) cfg = virNetworkDriverGetConfig(networkGetDriver());
VIR_LOCK_GUARD lock = virObjectLockGuard(obj);
virNetworkDef *def = virNetworkObjGetDef(obj);
+ virFirewall *fwRemoval = NULL;
if (virNetworkObjIsActive(obj)) {
switch ((virNetworkForwardType) def->forward.type) {
* network type, forward='open', doesn't need this because it
* has no iptables rules.
*/
- networkRemoveFirewallRules(def, cfg->firewallBackend);
- ignore_value(networkAddFirewallRules(def, cfg->firewallBackend));
+ networkRemoveFirewallRules(obj);
+ ignore_value(networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval));
+ virNetworkObjSetFwRemoval(obj, fwRemoval);
break;
case VIR_NETWORK_FORWARD_OPEN:
bool devOnline = false;
bool firewalRulesAdded = false;
virSocketAddr *dnsServer = NULL;
+ virFirewall *fwRemoval = NULL;
/* Check to see if any network IP collides with an existing route */
if (networkCheckRouteCollision(def) < 0)
/* Add "once per network" rules */
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
- networkAddFirewallRules(def, cfg->firewallBackend) < 0)
+ networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval) < 0) {
goto error;
+ }
+ virNetworkObjSetFwRemoval(obj, fwRemoval);
firewalRulesAdded = true;
for (i = 0; (ipdef = virNetworkDefGetIPByIndex(def, AF_UNSPEC, i)); i++) {
if (firewalRulesAdded &&
def->forward.type != VIR_NETWORK_FORWARD_OPEN)
- networkRemoveFirewallRules(def, cfg->firewallBackend);
+ networkRemoveFirewallRules(obj);
virNetworkObjUnrefMacMap(obj);
static int
-networkShutdownNetworkVirtual(virNetworkObj *obj,
- virNetworkDriverConfig *cfg)
+networkShutdownNetworkVirtual(virNetworkObj *obj)
{
virNetworkDef *def = virNetworkObjGetDef(obj);
pid_t dnsmasqPid;
ignore_value(virNetDevSetOnline(def->bridge, false));
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN)
- networkRemoveFirewallRules(def, cfg->firewallBackend);
+ networkRemoveFirewallRules(obj);
ignore_value(virNetDevBridgeDelete(def->bridge));
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
- ret = networkShutdownNetworkVirtual(obj, cfg);
+ ret = networkShutdownNetworkVirtual(obj);
break;
case VIR_NETWORK_FORWARD_BRIDGE:
virNetworkIPDef *ipdef;
bool oldDhcpActive = false;
bool needFirewallRefresh = false;
+ virFirewall *fwRemoval = NULL;
+
virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE |
* old rules (and remember to load new ones after the
* update).
*/
- networkRemoveFirewallRules(def, cfg->firewallBackend);
+ networkRemoveFirewallRules(obj);
needFirewallRefresh = true;
break;
default:
if (virNetworkObjUpdate(obj, command, section,
parentIndex, xml,
network_driver->xmlopt, flags) < 0) {
- if (needFirewallRefresh)
- ignore_value(networkAddFirewallRules(def, cfg->firewallBackend));
+ if (needFirewallRefresh) {
+ ignore_value(networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval));
+ virNetworkObjSetFwRemoval(obj, fwRemoval);
+ }
goto cleanup;
}
/* @def is replaced */
def = virNetworkObjGetDef(obj);
- if (needFirewallRefresh && networkAddFirewallRules(def, cfg->firewallBackend) < 0)
+ if (needFirewallRefresh &&
+ networkAddFirewallRules(def, cfg->firewallBackend, &fwRemoval) < 0) {
goto cleanup;
+ }
+ virNetworkObjSetFwRemoval(obj, fwRemoval);
if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
/* save updated persistent config to disk */
int
networkAddFirewallRules(virNetworkDef *def,
- virFirewallBackend firewallBackend)
+ virFirewallBackend firewallBackend,
+ virFirewall **fwRemoval)
{
networkSetupPrivateChains(firewallBackend, false);
}
}
- return iptablesAddFirewallRules(def);
+ return iptablesAddFirewallRules(def, fwRemoval);
}
void
-networkRemoveFirewallRules(virNetworkDef *def,
- virFirewallBackend firewallBackend G_GNUC_UNUSED)
+networkRemoveFirewallRules(virNetworkObj *obj)
{
- iptablesRemoveFirewallRules(def);
+ 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.
+ */
+ VIR_DEBUG("No firewall info in network status, assuming old-style iptables");
+ iptablesRemoveFirewallRules(virNetworkObjGetDef(obj));
+ return;
+ }
+
+ /* 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);
}
}
-/* Add all rules for all ip addresses (and general rules) on a network */
+/* iptablesAddFirewallrules:
+ *
+ * @def - the network that needs an iptables firewall added
+ * @fwRemoval - if this is not NULL, it points to a pointer
+ * that should be filled in with a virFirewall object containing
+ * all the commands needed to remove this firewall at a later time.
+ *
+ * Add all rules for all ip addresses (and general rules) on a
+ * network, and optionally return a virFirewall object containing all
+ * the rules needed to later remove the firewall that has been added.
+*/
int
-iptablesAddFirewallRules(virNetworkDef *def)
+iptablesAddFirewallRules(virNetworkDef *def, virFirewall **fwRemoval)
{
size_t i;
virNetworkIPDef *ipdef;
VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK));
iptablesAddChecksumFirewallRules(fw, def);
- return virFirewallApply(fw);
+ if (virFirewallApply(fw) < 0)
+ return -1;
+
+ if (fwRemoval) {
+ /* caller wants us to create a virFirewall object that can be
+ * applied to undo everything that was just done by * virFirewallApply()
+ */
+
+ if (virFirewallNewFromRollback(fw, fwRemoval) < 0)
+ return -1;
+ }
+
+ return 0;
}
-/* Remove all rules for all ip addresses (and general rules) on a network */
+/* iptablesRemoveFirewallRules:
+ *
+ * @def - the network that needs its iptables firewall rules removed
+ *
+ * Remove all rules for all ip addresses (and general rules) on a
+ * network that is being shut down.
+ *
+ * This function assumes the set of iptables rules that were added by
+ * all versions of libvirt prior to 10.4.0; any libvirt of that
+ * release or newer may or may not have this same set of rules, and
+ * should be using the list of commands saved in NetworkObj::fwRemoval
+ * (<fwRemoval> element in the network status XML) to remove the
+ * network's firewall rules.
+ */
void
iptablesRemoveFirewallRules(virNetworkDef *def)
{