From nobody Mon Sep 16 20:05:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1682911220; cv=none; d=zohomail.com; s=zohoarc; b=SyEndlsKS+C4qpp5PsZgn5Rj9EJCuhDBXurkmfq2VNb6CsrQVq4Qa4+AUY2RjX5psf3LKbRD+drmW4ZOCe/0bMTvzeRmrsRpcoOuYjlqZz1t0br8OQfjxm4a2qEZ+eVet/GVzmwdjmfkxYjqpI9iMGZHxZqPZW38kXmVtF1c1IQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1682911220; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=dUFzO0Tde3CyzNvbK6ieJPO1PSamFlh6Gu2K1Y1jq+Q=; b=lVbbRcenPDKvI/L66WfCgf6Sf6CAHFrN5cEei7itJrd5FRykO+hxbjQLosdyz5uFuUynhsGhwQyhmpXzfX+JBAMRsSGI5e+PtauxFtGIgYE+I07y8mq4hqyYczSei00HEESOcIBxqHatIgtuj3nuTBc7vSQjDDZYyJT6K3vmqto= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1682911220090679.1182637743883; Sun, 30 Apr 2023 20:20:20 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-549-Fj1DFqCvMTK7IZ53wiwdZQ-1; Sun, 30 Apr 2023 23:20:14 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7AF02857FBA; Mon, 1 May 2023 03:20:11 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 594D0C16047; Mon, 1 May 2023 03:20:11 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 7A371194974F; Mon, 1 May 2023 03:20:08 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id D4DE61946A50 for ; Mon, 1 May 2023 03:20:05 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id D4D1E475022; Mon, 1 May 2023 03:19:47 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.8.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id BA23A463ED1 for ; Mon, 1 May 2023 03:19:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1682911219; h=from:from:sender:sender: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:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=dUFzO0Tde3CyzNvbK6ieJPO1PSamFlh6Gu2K1Y1jq+Q=; b=gxnKMmfiE+gmSCCxmw/A7vfT7pcHTmKlPtL1EeMHMIM/5Y+98AbdEi9Jjh74nY4Be2FbRB LXTs1EIxFv20F2IU+GuCJwNOhPxGh/aoScMOkZImnPJSfF0NLqIRf6tzcD5bmNVI6LLzjj UZQ9HYzuQNMra4N2kYpcBQo1K5/bkjs= X-MC-Unique: Fj1DFqCvMTK7IZ53wiwdZQ-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Laine Stump To: libvir-list@redhat.com Subject: [libvirt PATCH 24/28] util: new functions virFirewallParseXML() and virFirewallFormat() Date: Sun, 30 Apr 2023 23:19:39 -0400 Message-Id: <20230501031943.288145-25-laine@redhat.com> In-Reply-To: <20230501031943.288145-1-laine@redhat.com> References: <20230501031943.288145-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1682911221401100005 Content-Type: text/plain; charset="utf-8"; x-default="true" These functions convert a virFirewall object to/from XML so that it can be serialized to disk (in a virNetworkObj's status file) and restored later (e.g. after libvirtd/virtnetworkd is restarted). Signed-off-by: Laine Stump --- src/libvirt_private.syms | 2 + src/util/virfirewall.c | 220 +++++++++++++++++++++++++++++++++++++++ src/util/virfirewall.h | 9 ++ 3 files changed, 231 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7eeed1efd4..1666da633d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2376,10 +2376,12 @@ virFirewallAddRuleFull; virFirewallApply; virFirewallBackendTypeFromString; virFirewallBackendTypeToString; +virFirewallFormat; virFirewallFree; virFirewallGetBackend; virFirewallNew; virFirewallNewFromRollback; +virFirewallParseXML; virFirewallRemoveRule; virFirewallRuleAddArg; virFirewallRuleAddArgFormat; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index f598cc9d79..d292ef60c6 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -42,6 +42,14 @@ VIR_ENUM_IMPL(virFirewallBackend, "iptables", "nftables"); =20 +VIR_ENUM_DECL(virFirewallLayer); +VIR_ENUM_IMPL(virFirewallLayer, + VIR_FIREWALL_LAYER_LAST, + "ethernet", + "ipv4", + "ipv6", +); + typedef struct _virFirewallGroup virFirewallGroup; =20 struct _virFirewallRule { @@ -739,3 +747,215 @@ virFirewallNewFromRollback(virFirewall *original, =20 return 0; } + + +/* virFirewallGetFlagsFromNode: + * @node: the xmlNode to check for an ignoreErrors attribute + * + * A short helper to get the setting of the ignorErrors attribute from + * an xmlNode. Returns -1 on error (with error reported), or the + * VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS bit set/reset according to + * the value of the attribute. + */ +static int +virFirewallGetFlagsFromNode(xmlNodePtr node) +{ + virTristateBool ignoreErrors; + + if (virXMLPropTristateBool(node, "ignoreErrors", VIR_XML_PROP_NONE, &i= gnoreErrors) < 0) + return -1; + + if (ignoreErrors =3D=3D VIR_TRISTATE_BOOL_YES) + return VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS; + return 0; +} + + +/** + * virFirewallParseXML: + * @firewall: pointer to virFirewall* to fill in with new virFirewall obje= ct + * + * Construct a new virFirewall object according to the XML in + * xmlNodePtr. Return 0 (and new object) on success, or -1 (with + * error reported) on error. + * + * Example of element XML: + * + * + * + * + * + * arg1 + * arg2 + * ... + * + * + * + * ... + + * ... + * + * ... + * + */ +int +virFirewallParseXML(virFirewall **firewall, + xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + g_autoptr(virFirewall) newfw =3D NULL; + virFirewallBackend backend; + g_autofree xmlNodePtr *groupNodes =3D NULL; + ssize_t ngroups; + size_t g; + VIR_XPATH_NODE_AUTORESTORE(ctxt); + + ctxt->node =3D node; + + ngroups =3D virXPathNodeSet("./group", ctxt, &groupNodes); + if (ngroups < 0) + return -1; + if (ngroups =3D=3D 0) + return 0; + + if (virXMLPropEnum(node, "backend", virFirewallBackendTypeFromString, + VIR_XML_PROP_REQUIRED, &backend) < 0) { + return -1; + } + + newfw =3D virFirewallNew(backend); + + for (g =3D 0; g < ngroups; g++) { + int flags =3D 0; + g_autofree xmlNodePtr *actionNodes =3D NULL; + ssize_t nactions; + size_t a; + + ctxt->node =3D groupNodes[g]; + nactions =3D virXPathNodeSet("./action", ctxt, &actionNodes); + if (nactions < 0) + return -1; + if (nactions =3D=3D 0) + continue; + + if ((flags =3D virFirewallGetFlagsFromNode(groupNodes[g])) < 0) + return -1; + + virFirewallStartTransaction(newfw, flags); + + for (a =3D 0; a < nactions; a++) { + g_autofree xmlNodePtr *argsNodes =3D NULL; + ssize_t nargs; + size_t i; + virFirewallLayer layer; + virFirewallRule *action; + bool ignoreErrors; + + ctxt->node =3D actionNodes[a]; + + if (!(ctxt->node =3D virXPathNode("./args", ctxt))) + continue; + + if ((flags =3D virFirewallGetFlagsFromNode(actionNodes[a])) < = 0) + return -1; + + ignoreErrors =3D flags & VIR_FIREWALL_TRANSACTION_IGNORE_ERROR= S; + + if (virXMLPropEnum(actionNodes[a], "layer", + virFirewallLayerTypeFromString, + VIR_XML_PROP_REQUIRED, &layer) < 0) { + return -1; + } + + nargs =3D virXPathNodeSet("./item", ctxt, &argsNodes); + if (nargs < 0) + return -1; + if (nargs =3D=3D 0) + continue; + + action =3D virFirewallAddRuleFull(newfw, layer, ignoreErrors, + NULL, NULL, NULL); + for (i =3D 0; i < nargs; i++) { + + char *arg =3D virXMLNodeContentString(argsNodes[i]); + if (!arg) + return -1; + + virFirewallRuleAddArg(newfw, action, arg); + } + } + } + + *firewall =3D g_steal_pointer(&newfw); + return 0; +} + + +/** + * virFirewallFormat: + * @buf: output buffer + * @firewall: the virFirewall object to format as XML + * + * Format virFirewall object @firewall into @buf as XML. + * Returns 0 on success, -1 on failure. + * + */ +int +virFirewallFormat(virBuffer *buf, + virFirewall *firewall) +{ + size_t g; + + if (firewall->ngroups =3D=3D 0) + return 0; + + virBufferAsprintf(buf, "\n", + virFirewallBackendTypeToString(virFirewallGetBackend= (firewall))); + virBufferAdjustIndent(buf, 2); + for (g =3D 0; g < firewall->ngroups; g++) { + virFirewallGroup *group =3D firewall->groups[g]; + bool groupIgnoreErrors =3D (group->actionFlags + & VIR_FIREWALL_TRANSACTION_IGNORE_ERROR= S); + size_t a; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + + for (a =3D 0; a < group->naction; a++) { + virFirewallRule *action =3D group->action[a]; + size_t i; + + virBufferAsprintf(buf, "\n"); + + virBufferAdjustIndent(buf, 2); + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + for (i =3D 0; i < virFirewallRuleGetArgCount(action); i++) { + virBufferEscapeString(buf, "%s\n", + virFirewallRuleGetArg(action, i)); + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + return 0; +} diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index 9017c12b5c..651cf32fed 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -22,6 +22,8 @@ =20 #include "internal.h" #include "virenum.h" +#include "virbuffer.h" +#include "virxml.h" =20 typedef struct _virFirewall virFirewall; =20 @@ -152,4 +154,11 @@ void virFirewallStartRollback(virFirewall *firewall, =20 int virFirewallApply(virFirewall *firewall); =20 +int virFirewallParseXML(virFirewall **firewall, + xmlNodePtr node, + xmlXPathContextPtr ctxt); + +int virFirewallFormat(virBuffer *buf, + virFirewall *firewall); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree); --=20 2.39.2