Re: [PATCH v2 15/27] util: implement rollback rule autocreation for iptables commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux