On Sun, Apr 21, 2024 at 10:53:23PM -0400, Laine Stump wrote: > If the VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK flag is set, each time > an iptables command is executed that is adding a rule or chain, a > corresponding command that will *delete* the same rule/chain is > constructed and added to the list of rollback commands. If we later > want to undo the entire firewall, we can just run those commands. > > This isn't yet used anywhere, since > VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK isn't being set. > > Signed-off-by: Laine Stump <laine@xxxxxxxxxx> > --- > src/util/virfirewall.c | 55 ++++++++++++++++++++++++++++++++++++------ > 1 file changed, 48 insertions(+), 7 deletions(-) > > diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c > index 274c5179ed..8cc551d6e2 100644 > --- a/src/util/virfirewall.c > +++ b/src/util/virfirewall.c > @@ -471,7 +471,7 @@ void virFirewallStartTransaction(virFirewall *firewall, > * Returns the virFirewallTransactionFlags for the currently active > * group (transaction) in @firewall. > */ > -static virFirewallTransactionFlags G_GNUC_UNUSED > +static virFirewallTransactionFlags > virFirewallTransactionGetFlags(virFirewall *firewall) > { > return firewall->groups[firewall->currentGroup]->actionFlags; > @@ -526,16 +526,25 @@ virFirewallCmdToString(const char *cmd, > } > > > +#define VIR_IPTABLES_ARG_IS_INSERT(arg) \ > + (STREQ(arg, "--insert") || STREQ(arg, "-I") || \ > + STREQ(arg, "--append") || STREQ(arg, "-A")) IS_CREATE feels like slightly less misleadnig name, given this matches "append" too, and 'create' pairs with 'delete' nicely. > static int > -virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, > - char **output) > +virFirewallCmdIptablesApply(virFirewall *firewall, > + virFirewallCmd *fwCmd, > + char **output) > { > - size_t i; > const char *bin = virFirewallLayerCommandTypeToString(fwCmd->layer); > + bool checkRollback = (virFirewallTransactionGetFlags(firewall) & > + VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK); > + bool needRollback = false; > g_autoptr(virCommand) cmd = NULL; > g_autofree char *cmdStr = NULL; > - int status; > g_autofree char *error = NULL; > + size_t i; > + int status; > > if (!bin) { > virReportError(VIR_ERR_INTERNAL_ERROR, > @@ -559,8 +568,13 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, > break; > } > > - for (i = 0; i < fwCmd->argsLen; i++) > + for (i = 0; i < fwCmd->argsLen; i++) { > + /* the -I/-A arg could be at any position in the list */ > + if (checkRollback && VIR_IPTABLES_ARG_IS_INSERT(fwCmd->args[i])) > + needRollback = true; > + > virCommandAddArg(cmd, fwCmd->args[i]); > + } > > cmdStr = virCommandToString(cmd, false); > VIR_INFO("Running firewall command '%s'", NULLSTR(cmdStr)); > @@ -572,8 +586,10 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, > return -1; > > if (status != 0) { > + /* the command failed, decide whether or not to report it */ > if (fwCmd->ignoreErrors) { > VIR_DEBUG("Ignoring error running command"); > + return 0; > } else { > virReportError(VIR_ERR_INTERNAL_ERROR, > _("Failed to run firewall command %1$s: %2$s"), > @@ -583,6 +599,31 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, > } > } > > + /* the command was successful, see if we need to add a > + * rollback command > + */ > + > + if (needRollback) { > + virFirewallCmd *rollback > + = virFirewallAddRollbackCmd(firewall, fwCmd->layer, NULL); > + g_autofree char *rollbackStr = NULL; > + > + for (i = 0; i < fwCmd->argsLen; i++) { > + /* iptables --delete wants the entire commandline that > + * was used for --insert but with s/insert/delete/ > + */ > + if (VIR_IPTABLES_ARG_IS_INSERT(fwCmd->args[i])) { > + virFirewallCmdAddArg(firewall, rollback, "--delete"); > + } else { > + virFirewallCmdAddArg(firewall, rollback, fwCmd->args[i]); > + } > + } > + > + rollbackStr = virFirewallCmdToString(virFirewallLayerCommandTypeToString(fwCmd->layer), > + rollback); > + VIR_DEBUG("Recording Rollback command '%s'", NULLSTR(rollbackStr)); > + } > + > return 0; > } > > @@ -600,7 +641,7 @@ virFirewallApplyCmd(virFirewall *firewall, > return -1; > } > > - if (virFirewallApplyCmdDirect(fwCmd, &output) < 0) > + if (virFirewallCmdIptablesApply(firewall, fwCmd, &output) < 0) > return -1; > > if (fwCmd->queryCB && output) { > -- > 2.44.0 > _______________________________________________ > Devel mailing list -- devel@xxxxxxxxxxxxxxxxx > To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx