From nobody Tue Feb 10 08:27:11 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 15489843148251014.7668781824121; Thu, 31 Jan 2019 17:25:14 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5147DC0CD16A; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6D4B160C54; Fri, 1 Feb 2019 01:25:11 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E21D218033A2; Fri, 1 Feb 2019 01:25:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111P8W4002416 for ; Thu, 31 Jan 2019 20:25:08 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1B6B919742; Fri, 1 Feb 2019 01:25:08 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 846B71992A; Fri, 1 Feb 2019 01:25:07 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:53 -0500 Message-Id: <20190201012458.25703-3-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 2/7] util: move all firewalld-specific stuff into its own files X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 01 Feb 2019 01:25:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In preparation for adding several other firewalld-specific functions, separate the code that's unique to firewalld from the more-generic "firewall" file. Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- Change from V1: define VIR_FIREWALL_FIREWALLD_SERVICE in virfirewalldpriv.h, since it should only be used by virfirewalld.c and unit test programs. (no, I haven't done anything about the awkward error checking that was already existing in the code I moved - not only is that a separate issue, but there no existing way to fix it anyway - that would take changes to firewalld) include/libvirt/virterror.h | 1 + src/libvirt_private.syms | 5 ++ src/util/Makefile.inc.am | 3 + src/util/virerror.c | 3 +- src/util/virfirewall.c | 86 +------------------- src/util/virfirewalld.c | 151 ++++++++++++++++++++++++++++++++++++ src/util/virfirewalld.h | 33 ++++++++ src/util/virfirewalldpriv.h | 30 +++++++ src/util/virfirewallpriv.h | 2 - tests/virfirewalltest.c | 2 + 10 files changed, 231 insertions(+), 85 deletions(-) create mode 100644 src/util/virfirewalld.c create mode 100644 src/util/virfirewalld.h create mode 100644 src/util/virfirewalldpriv.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index fbbe2d5624..3c19ff5e2e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -131,6 +131,7 @@ typedef enum { VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ VIR_FROM_RESCTRL =3D 67, /* Error from resource control */ + VIR_FROM_FIREWALLD =3D 68, /* Error from firewalld */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e53ae0dbeb..d52e2412fa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1921,6 +1921,11 @@ virFirewallStartRollback; virFirewallStartTransaction; =20 =20 +# util/virfirewalld.h +virFirewallDApplyRule; +virFirewallDIsRegistered; + + # util/virfirmware.h virFirmwareFreeList; virFirmwareParse; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 4295babac3..aa5c6cbe03 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -64,6 +64,9 @@ UTIL_SOURCES =3D \ util/virfirewall.c \ util/virfirewall.h \ util/virfirewallpriv.h \ + util/virfirewalld.c \ + util/virfirewalld.h \ + util/virfirewalldpriv.h \ util/virfirmware.c \ util/virfirmware.h \ util/virgettext.c \ diff --git a/src/util/virerror.c b/src/util/virerror.c index 61b47d2be0..740f3b84b3 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -138,7 +138,8 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, "Perf", /* 65 */ "Libssh transport layer", "Resource control", - ) + "FirewallD", + ); =20 =20 /* diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 0ed54d6228..7582ce5b5d 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -24,12 +24,12 @@ =20 #define LIBVIRT_VIRFIREWALLPRIV_H_ALLOW #include "virfirewallpriv.h" +#include "virfirewalld.h" #include "virerror.h" #include "virutil.h" #include "virstring.h" #include "vircommand.h" #include "virlog.h" -#include "virdbus.h" #include "virfile.h" #include "virthread.h" =20 @@ -46,11 +46,6 @@ VIR_ENUM_IMPL(virFirewallLayerCommand, VIR_FIREWALL_LAYE= R_LAST, IPTABLES_PATH, IP6TABLES_PATH); =20 -VIR_ENUM_DECL(virFirewallLayerFirewallD) -VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LAYER_LAST, - "eb", "ipv4", "ipv6") - - struct _virFirewallRule { virFirewallLayer layer; =20 @@ -152,7 +147,7 @@ virFirewallValidateBackend(virFirewallBackend backend) VIR_DEBUG("Validating backend %d", backend); if (backend =3D=3D VIR_FIREWALL_BACKEND_AUTOMATIC || backend =3D=3D VIR_FIREWALL_BACKEND_FIREWALLD) { - int rv =3D virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVI= CE); + int rv =3D virFirewallDIsRegistered(); =20 VIR_DEBUG("Firewalld is registered ? %d", rv); if (rv < 0) { @@ -712,81 +707,8 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, bool ignoreErrors, char **output) { - const char *ipv =3D virFirewallLayerFirewallDTypeToString(rule->layer); - DBusConnection *sysbus =3D virDBusGetSystemBus(); - DBusMessage *reply =3D NULL; - virError error; - int ret =3D -1; - - if (!sysbus) - return -1; - - memset(&error, 0, sizeof(error)); - - if (!ipv) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unknown firewall layer %d"), - rule->layer); - goto cleanup; - } - - if (virDBusCallMethod(sysbus, - &reply, - &error, - VIR_FIREWALL_FIREWALLD_SERVICE, - "/org/fedoraproject/FirewallD1", - "org.fedoraproject.FirewallD1.direct", - "passthrough", - "sa&s", - ipv, - (int)rule->argsLen, - rule->args) < 0) - goto cleanup; - - if (error.level =3D=3D VIR_ERR_ERROR) { - /* - * As of firewalld-0.3.9.3-1.fc20.noarch the name and - * message fields in the error look like - * - * name=3D"org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption" - * message=3D"COMMAND_FAILED: '/sbin/iptables --table filter --del= ete - * INPUT --in-interface virbr0 --protocol udp --destinati= on-port 53 - * --jump ACCEPT' failed: iptables: Bad rule (does a matc= hing rule - * exist in that chain?)." - * - * We'd like to only ignore DBus errors precisely related to the f= ailure - * of iptables/ebtables commands. A well designed DBus interface w= ould - * return specific named exceptions not the top level generic pyth= on dbus - * exception name. With this current scheme our only option is tod= o a - * sub-string match for 'COMMAND_FAILED' on the message. eg like - * - * if (ignoreErrors && - * STREQ(error.name, - * "org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption") && - * STRPREFIX(error.message, "COMMAND_FAILED")) - * ... - * - * But this risks our error detecting code being broken if firewal= ld changes - * ever alter the message string, so we're avoiding doing that. - */ - if (ignoreErrors) { - VIR_DEBUG("Ignoring error '%s': '%s'", - error.str1, error.message); - } else { - virReportErrorObject(&error); - goto cleanup; - } - } else { - if (virDBusMessageRead(reply, "s", output) < 0) - goto cleanup; - } - - ret =3D 0; - - cleanup: - virResetError(&error); - virDBusMessageUnref(reply); - return ret; + /* wrapper necessary because virFirewallRule is a private struct */ + return virFirewallDApplyRule(rule->layer, rule->args, rule->argsLen, i= gnoreErrors, output); } =20 static int diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c new file mode 100644 index 0000000000..f27ec9c124 --- /dev/null +++ b/src/util/virfirewalld.c @@ -0,0 +1,151 @@ +/* + * virfirewalld.c: support for firewalld (https://firewalld.org) + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include + +#include "virfirewall.h" +#include "virfirewalld.h" +#define LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +#include "virfirewalldpriv.h" +#include "virerror.h" +#include "virutil.h" +#include "virlog.h" +#include "virdbus.h" + +#define VIR_FROM_THIS VIR_FROM_FIREWALLD + +VIR_LOG_INIT("util.firewalld"); + +/* used to convert virFirewallLayer enum values to strings + * understood by the firewalld.direct "passthrough" method + */ +VIR_ENUM_DECL(virFirewallLayerFirewallD); +VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LAYER_LAST, + "eb", + "ipv4", + "ipv6", + ); + + +/** + * virFirewallDIsRegistered: + * + * Returns 0 if service is registered, -1 on fatal error, or -2 if service= is not registered + */ +int +virFirewallDIsRegistered(void) +{ + return virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVICE); +} + + +/** + * virFirewallDApplyRule: + * @layer: which layer to apply the rule to + * @args: list of args to send to this layer's passthrough command. + * @argsLen: number of items in @args + * @ignoreErrors: true to suppress logging of errors and return success + * false to log errors and return actual status + * @output: output of the direct passthrough command, if it was succ= essful + */ +int +virFirewallDApplyRule(virFirewallLayer layer, + char **args, size_t argsLen, + bool ignoreErrors, + char **output) +{ + const char *ipv =3D virFirewallLayerFirewallDTypeToString(layer); + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + virError error; + int ret =3D -1; + + if (!sysbus) + return -1; + + memset(&error, 0, sizeof(error)); + + if (!ipv) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown firewall layer %d"), + layer); + goto cleanup; + } + + if (virDBusCallMethod(sysbus, + &reply, + &error, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1", + "org.fedoraproject.FirewallD1.direct", + "passthrough", + "sa&s", + ipv, + (int)argsLen, + args) < 0) + goto cleanup; + + if (error.level =3D=3D VIR_ERR_ERROR) { + /* + * As of firewalld-0.3.9.3-1.fc20.noarch the name and + * message fields in the error look like + * + * name=3D"org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption" + * message=3D"COMMAND_FAILED: '/sbin/iptables --table filter --del= ete + * INPUT --in-interface virbr0 --protocol udp --destinati= on-port 53 + * --jump ACCEPT' failed: iptables: Bad rule (does a matc= hing rule + * exist in that chain?)." + * + * We'd like to only ignore DBus errors precisely related to the f= ailure + * of iptables/ebtables commands. A well designed DBus interface w= ould + * return specific named exceptions not the top level generic pyth= on dbus + * exception name. With this current scheme our only option is tod= o a + * sub-string match for 'COMMAND_FAILED' on the message. eg like + * + * if (ignoreErrors && + * STREQ(error.name, + * "org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption") && + * STRPREFIX(error.message, "COMMAND_FAILED")) + * ... + * + * But this risks our error detecting code being broken if firewal= ld changes + * ever alter the message string, so we're avoiding doing that. + */ + if (ignoreErrors) { + VIR_DEBUG("Ignoring error '%s': '%s'", + error.str1, error.message); + } else { + virReportErrorObject(&error); + goto cleanup; + } + } else { + if (virDBusMessageRead(reply, "s", output) < 0) + goto cleanup; + } + + ret =3D 0; + + cleanup: + virResetError(&error); + virDBusMessageUnref(reply); + return ret; +} diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h new file mode 100644 index 0000000000..83fe1149cc --- /dev/null +++ b/src/util/virfirewalld.h @@ -0,0 +1,33 @@ +/* + * virfirewalld.h: support for firewalld (https://firewalld.org) + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef LIBVIRT_VIRFIREWALLD_H +# define LIBVIRT_VIRFIREWALLD_H + +# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" + +int virFirewallDIsRegistered(void); + +int virFirewallDApplyRule(virFirewallLayer layer, + char **args, size_t argsLen, + bool ignoreErrors, + char **output); + +#endif /* LIBVIRT_VIRFIREWALLD_H */ diff --git a/src/util/virfirewalldpriv.h b/src/util/virfirewalldpriv.h new file mode 100644 index 0000000000..6c03b467c9 --- /dev/null +++ b/src/util/virfirewalldpriv.h @@ -0,0 +1,30 @@ +/* + * virfirewalldpriv.h: private APIs for firewalld + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +# error "virfirewalldpriv.h may only be included by virfirewalld.c or test= suites" +#endif /* LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW */ + +#ifndef LIBVIRT_VIRFIREWALLDPRIV_H +# define LIBVIRT_VIRFIREWALLDPRIV_H + +# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" + +#endif /* LIBVIRT_VIRFIREWALLDPRIV_H */ diff --git a/src/util/virfirewallpriv.h b/src/util/virfirewallpriv.h index efa94a7da4..7c31d0680d 100644 --- a/src/util/virfirewallpriv.h +++ b/src/util/virfirewallpriv.h @@ -27,8 +27,6 @@ =20 # include "virfirewall.h" =20 -# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" - typedef enum { VIR_FIREWALL_BACKEND_AUTOMATIC, VIR_FIREWALL_BACKEND_DIRECT, diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c index 5fde25d8f6..7c586877d3 100644 --- a/tests/virfirewalltest.c +++ b/tests/virfirewalltest.c @@ -27,6 +27,8 @@ # include "vircommandpriv.h" # define LIBVIRT_VIRFIREWALLPRIV_H_ALLOW # include "virfirewallpriv.h" +# define LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +# include "virfirewalldpriv.h" # include "virmock.h" # define LIBVIRT_VIRDBUSPRIV_H_ALLOW # include "virdbuspriv.h" --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list