]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: new function virFirewallNewFromRollback()
authorLaine Stump <laine@redhat.com>
Sat, 20 Apr 2024 02:19:42 +0000 (22:19 -0400)
committerLaine Stump <laine@redhat.com>
Thu, 23 May 2024 03:19:48 +0000 (23:19 -0400)
virFirewallNewFromRollback() creates a new virFirewall object that
contains a copy of the "rollback" commands from an existing
virFirewall object, but in reverse order. The intent is that this
virFirewall be saved and used later to remove the firewall rules that
were added for a network.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/libvirt_private.syms
src/util/virfirewall.c
src/util/virfirewall.h

index 9897caea213a6ffa0010d3d6b56502a20b5c949c..4e6a113ba1a45acebcc081ac14acb5db934d3b8d 100644 (file)
@@ -2419,6 +2419,7 @@ virFirewallFree;
 virFirewallGetBackend;
 virFirewallGetName;
 virFirewallNew;
+virFirewallNewFromRollback;
 virFirewallRemoveCmd;
 virFirewallSetName;
 virFirewallStartRollback;
index fe8c09c0ed4f5cf21d5e5de1159f0b36f66e9179..2f4f128cd1612752d9be37d7adca496661427424 100644 (file)
@@ -768,3 +768,62 @@ virFirewallApply(virFirewall *firewall)
 
     return 0;
 }
+
+
+/**
+ * virFirewallNewFromRollback:
+
+ * @original: the original virFirewall object containing the rollback
+ *            of interest
+ * @fwRemoval: a firewall object that, when applied, will remove @original
+ *
+ * Copy the rollback rules from the current virFirewall object as a
+ * new virFirewall. This virFirewall can then be saved to apply later
+ * and counteract everything done by the original.
+ *
+ * Returns 0 on success, -1 on error
+ */
+int
+virFirewallNewFromRollback(virFirewall *original,
+                           virFirewall **fwRemoval)
+{
+    size_t g;
+    g_autoptr(virFirewall) firewall = NULL;
+
+    if (original->err) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("error in original firewall object"));
+        return -1;
+    }
+
+    firewall = virFirewallNew(original->backend);
+
+    /* add the rollback commands in reverse order of actions/groups of
+     * what was applied in the original firewall.
+     */
+    for (g = original->ngroups; g > 0; g--) {
+        size_t r;
+        virFirewallGroup *group = original->groups[g - 1];
+
+        if (group->nrollback == 0)
+            continue;
+
+        virFirewallStartTransaction(firewall, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
+
+        for (r = group->nrollback; r > 0; r--) {
+            size_t i;
+            virFirewallCmd *origCmd = group->rollback[r - 1];
+            virFirewallCmd *rbCmd = virFirewallAddCmd(firewall, origCmd->layer, NULL);
+
+            for (i = 0; i < origCmd->argsLen; i++)
+                ADD_ARG(rbCmd, origCmd->args[i]);
+        }
+    }
+
+    if (firewall->ngroups == 0)
+        VIR_DEBUG("original firewall object is empty");
+    else
+        *fwRemoval = g_steal_pointer(&firewall);
+
+    return 0;
+}
index e8ad81056fe94a5958e72cf69e006b70c7acaaa8..931dfb04cf90ba4c1ab26376862ec43c00cb8c41 100644 (file)
@@ -44,6 +44,7 @@ typedef enum {
 VIR_ENUM_DECL(virFirewallBackend);
 
 virFirewall *virFirewallNew(virFirewallBackend backend);
+int virFirewallNewFromRollback(virFirewall *original, virFirewall **fwRemoval);
 void virFirewallFree(virFirewall *firewall);
 virFirewallBackend virFirewallGetBackend(virFirewall *firewall);
 const char *virFirewallGetName(virFirewall *firewall);