From nobody Thu Sep 19 01:03:45 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1715968312507228.6998620557457; Fri, 17 May 2024 10:51:52 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 4AE411D91; Fri, 17 May 2024 13:51:51 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 4D71F1DB7; Fri, 17 May 2024 13:31:26 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id DFDCC179F; Fri, 17 May 2024 13:30:18 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 3EF8319CF for ; Fri, 17 May 2024 13:30:12 -0400 (EDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-262-ZUHf57vNOyyinFerTx4NSw-1; Fri, 17 May 2024 13:30:10 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 153DB18485E6 for ; Fri, 17 May 2024 17:30:10 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.16.223]) by smtp.corp.redhat.com (Postfix) with ESMTP id F2C2740C6EB7 for ; Fri, 17 May 2024 17:30:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715967011; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WltuRNPMwMqXM8m2KPfGGDzyf8pOSp7egcIf4uTxFVo=; b=KHr0NF12DMo26Lrcw+SL9BC6zMeLzF74Zd8hiKtXgppwHDLjyWVdiADF1NkCTyu+kcMqFF WugQIQ31bLPCYhO2u1BIiq3fSE9VR0mBoWEHfFDr8LMFf6aBCQIF2c4/kE4Z/xTcXKI/hK 6aqzZ062bDFDUd2nZ1944VAD3MoplYY= X-MC-Unique: ZUHf57vNOyyinFerTx4NSw-1 From: Laine Stump To: devel@lists.libvirt.org Subject: [PATCH v5 15/30] util: implement rollback rule autocreation for iptables commands Date: Fri, 17 May 2024 13:29:52 -0400 Message-ID: <20240517173007.8125-16-laine@redhat.com> In-Reply-To: <20240517173007.8125-1-laine@redhat.com> References: <20240517173007.8125-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 2UBJAWDDZSQ345LADTDPXEM5V2CLODWQ X-Message-ID-Hash: 2UBJAWDDZSQ345LADTDPXEM5V2CLODWQ X-MailFrom: laine@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1715968313105100001 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 9def8999d5..b9b4140ad6 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -470,7 +470,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; @@ -525,16 +525,25 @@ virFirewallCmdToString(const char *cmd, } =20 =20 +#define VIR_IPTABLES_ARG_IS_CREATE(arg) \ + (STREQ(arg, "--insert") || STREQ(arg, "-I") || \ + STREQ(arg, "--append") || STREQ(arg, "-A")) + + static int -virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, - char **output) +virFirewallCmdIptablesApply(virFirewall *firewall, + virFirewallCmd *fwCmd, + char **output) { - size_t i; const char *bin =3D virFirewallLayerCommandTypeToString(fwCmd->layer); + bool checkRollback =3D (virFirewallTransactionGetFlags(firewall) & + VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK); + bool needRollback =3D false; g_autoptr(virCommand) cmd =3D NULL; g_autofree char *cmdStr =3D NULL; - int status; g_autofree char *error =3D NULL; + size_t i; + int status; =20 if (!bin) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -558,8 +567,13 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, break; } =20 - for (i =3D 0; i < fwCmd->argsLen; i++) + for (i =3D 0; i < fwCmd->argsLen; i++) { + /* the -I/-A arg could be at any position in the list */ + if (checkRollback && VIR_IPTABLES_ARG_IS_CREATE(fwCmd->args[i])) + needRollback =3D true; + virCommandAddArg(cmd, fwCmd->args[i]); + } =20 cmdStr =3D virCommandToString(cmd, false); VIR_INFO("Running firewall command '%s'", NULLSTR(cmdStr)); @@ -571,8 +585,10 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, return -1; =20 if (status !=3D 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"), @@ -582,6 +598,31 @@ virFirewallApplyCmdDirect(virFirewallCmd *fwCmd, } } =20 + /* the command was successful, see if we need to add a + * rollback command + */ + + if (needRollback) { + virFirewallCmd *rollback + =3D virFirewallAddRollbackCmd(firewall, fwCmd->layer, NULL); + g_autofree char *rollbackStr =3D NULL; + + for (i =3D 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_CREATE(fwCmd->args[i])) { + virFirewallCmdAddArg(firewall, rollback, "--delete"); + } else { + virFirewallCmdAddArg(firewall, rollback, fwCmd->args[i]); + } + } + + rollbackStr =3D virFirewallCmdToString(virFirewallLayerCommandType= ToString(fwCmd->layer), + rollback); + VIR_DEBUG("Recording Rollback command '%s'", NULLSTR(rollbackStr)); + } + return 0; } =20 @@ -599,7 +640,7 @@ virFirewallApplyCmd(virFirewall *firewall, return -1; } =20 - if (virFirewallApplyCmdDirect(fwCmd, &output) < 0) + if (virFirewallCmdIptablesApply(firewall, fwCmd, &output) < 0) return -1; =20 if (fwCmd->queryCB && output) { --=20 2.45.0