util/network: new virFirewallBackend enum

(This paragraph is for historical reference only, described only to
avoid confusion of past use of the name with its new use) In a past
life, virFirewallBackend had been a private static in virfirewall.c
that was set at daemon init time, and used to globally (i.e. for all
drivers in the daemon) determine whether to directly execute iptables
commands, or to run them indirectly via the firewalld passthrough
API. This was removed in commit d566cc55, since we decided that using
the firewalld passthrough API is never appropriate.

Now the same enum, virFirewallBackend, is being reintroduced, with a
different meaning and usage pattern. It will be used to pick between
using nftables commands or iptables commands (in either case directly
handled by libvirt, *not* via firewalld). Additionally, rather than
being a static known only within virfirewall.c and applying to all
firewall commands for all drivers, each virFirewall object will have
its own backend setting, which will be set during virFirewallNew() by
the driver who wants to add a firewall rule.

This will allow the nwfilter and network drivers to each have their
own backend setting, even when they coexist in a single unified
daemon. At least as important as that, it will also allow an instance
of the network driver to remove iptables rules that had been added by
a previous instance, and then add nftables rules for the new instance
(in the case that an admin, or possibly an update, switches the driver
backend from iptables to nftable)

Initially, the enum will only have one usable value -
VIR_FIREWALL_BACKEND_IPTABLES, and that will be hardcoded into all
calls to virFirewallNew(). The other enum value (along with a method
of setting it for each driver) will be added later, when it can be
used (when the nftables backend is in the code).

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Laine Stump 2024-04-19 22:19:42 -04:00
parent 5543179cea
commit 9293644d8a
7 changed files with 50 additions and 25 deletions

View File

@ -2406,6 +2406,8 @@ virFileCacheSetPriv;
# util/virfirewall.h # util/virfirewall.h
virFirewallAddCmdFull; virFirewallAddCmdFull;
virFirewallApply; virFirewallApply;
virFirewallBackendTypeFromString;
virFirewallBackendTypeToString;
virFirewallCmdAddArg; virFirewallCmdAddArg;
virFirewallCmdAddArgFormat; virFirewallCmdAddArgFormat;
virFirewallCmdAddArgList; virFirewallCmdAddArgList;
@ -2413,6 +2415,7 @@ virFirewallCmdAddArgSet;
virFirewallCmdGetArgCount; virFirewallCmdGetArgCount;
virFirewallCmdToString; virFirewallCmdToString;
virFirewallFree; virFirewallFree;
virFirewallGetBackend;
virFirewallNew; virFirewallNew;
virFirewallRemoveCmd; virFirewallRemoveCmd;
virFirewallStartRollback; virFirewallStartRollback;

View File

@ -131,7 +131,7 @@ iptablesPrivateChainCreate(virFirewall *fw,
int int
iptablesSetupPrivateChains(virFirewallLayer layer) iptablesSetupPrivateChains(virFirewallLayer layer)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
iptablesGlobalChain filter_chains[] = { iptablesGlobalChain filter_chains[] = {
{"INPUT", VIR_IPTABLES_INPUT_CHAIN}, {"INPUT", VIR_IPTABLES_INPUT_CHAIN},
{"OUTPUT", VIR_IPTABLES_OUTPUT_CHAIN}, {"OUTPUT", VIR_IPTABLES_OUTPUT_CHAIN},
@ -1597,7 +1597,7 @@ iptablesAddFirewallRules(virNetworkDef *def)
{ {
size_t i; size_t i;
virNetworkIPDef *ipdef; virNetworkIPDef *ipdef;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, 0); virFirewallStartTransaction(fw, 0);
@ -1632,7 +1632,7 @@ iptablesRemoveFirewallRules(virNetworkDef *def)
{ {
size_t i; size_t i;
virNetworkIPDef *ipdef; virNetworkIPDef *ipdef;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
iptablesRemoveChecksumFirewallRules(fw, def); iptablesRemoveChecksumFirewallRules(fw, def);

View File

@ -2820,7 +2820,7 @@ static int
ebtablesApplyBasicRules(const char *ifname, ebtablesApplyBasicRules(const char *ifname,
const virMacAddr *macaddr) const virMacAddr *macaddr)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
char chain[MAX_CHAINNAME_LENGTH]; char chain[MAX_CHAINNAME_LENGTH];
char chainPrefix = CHAINPREFIX_HOST_IN_TEMP; char chainPrefix = CHAINPREFIX_HOST_IN_TEMP;
char macaddr_str[VIR_MAC_STRING_BUFLEN]; char macaddr_str[VIR_MAC_STRING_BUFLEN];
@ -2893,7 +2893,7 @@ ebtablesApplyDHCPOnlyRules(const char *ifname,
char macaddr_str[VIR_MAC_STRING_BUFLEN]; char macaddr_str[VIR_MAC_STRING_BUFLEN];
unsigned int idx = 0; unsigned int idx = 0;
unsigned int num_dhcpsrvrs; unsigned int num_dhcpsrvrs;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virMacAddrFormat(macaddr, macaddr_str); virMacAddrFormat(macaddr, macaddr_str);
@ -2995,7 +2995,7 @@ ebtablesApplyDropAllRules(const char *ifname)
{ {
char chain_in [MAX_CHAINNAME_LENGTH], char chain_in [MAX_CHAINNAME_LENGTH],
chain_out[MAX_CHAINNAME_LENGTH]; chain_out[MAX_CHAINNAME_LENGTH];
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
if (ebiptablesAllTeardown(ifname) < 0) if (ebiptablesAllTeardown(ifname) < 0)
return -1; return -1;
@ -3042,7 +3042,7 @@ ebtablesRemoveBasicRules(const char *ifname)
static int static int
ebtablesCleanAll(const char *ifname) ebtablesCleanAll(const char *ifname)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
@ -3302,7 +3302,7 @@ ebiptablesApplyNewRules(const char *ifname,
size_t nrules) size_t nrules)
{ {
size_t i, j; size_t i, j;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
g_autoptr(GHashTable) chains_in_set = virHashNew(NULL); g_autoptr(GHashTable) chains_in_set = virHashNew(NULL);
g_autoptr(GHashTable) chains_out_set = virHashNew(NULL); g_autoptr(GHashTable) chains_out_set = virHashNew(NULL);
bool haveEbtables = false; bool haveEbtables = false;
@ -3527,7 +3527,7 @@ ebiptablesTearNewRulesFW(virFirewall *fw, const char *ifname)
static int static int
ebiptablesTearNewRules(const char *ifname) ebiptablesTearNewRules(const char *ifname)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
@ -3539,7 +3539,7 @@ ebiptablesTearNewRules(const char *ifname)
static int static int
ebiptablesTearOldRules(const char *ifname) ebiptablesTearOldRules(const char *ifname)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
@ -3574,7 +3574,7 @@ ebiptablesTearOldRules(const char *ifname)
static int static int
ebiptablesAllTeardown(const char *ifname) ebiptablesAllTeardown(const char *ifname)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);

View File

@ -78,7 +78,7 @@ ebtablesContextFree(ebtablesContext *ctx)
int int
ebtablesAddForwardPolicyReject(ebtablesContext *ctx) ebtablesAddForwardPolicyReject(ebtablesContext *ctx)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS); virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_IGNORE_ERRORS);
virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET,
@ -106,7 +106,7 @@ ebtablesForwardAllowIn(ebtablesContext *ctx,
const char *macaddr, const char *macaddr,
int action) int action)
{ {
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
virFirewallStartTransaction(fw, 0); virFirewallStartTransaction(fw, 0);
virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET, virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_ETHERNET,

View File

@ -35,6 +35,10 @@
VIR_LOG_INIT("util.firewall"); VIR_LOG_INIT("util.firewall");
VIR_ENUM_IMPL(virFirewallBackend,
VIR_FIREWALL_BACKEND_LAST,
"iptables");
typedef struct _virFirewallGroup virFirewallGroup; typedef struct _virFirewallGroup virFirewallGroup;
VIR_ENUM_DECL(virFirewallLayerCommand); VIR_ENUM_DECL(virFirewallLayerCommand);
@ -77,6 +81,7 @@ struct _virFirewall {
size_t ngroups; size_t ngroups;
virFirewallGroup **groups; virFirewallGroup **groups;
size_t currentGroup; size_t currentGroup;
virFirewallBackend backend;
}; };
static virMutex fwCmdLock = VIR_MUTEX_INITIALIZER; static virMutex fwCmdLock = VIR_MUTEX_INITIALIZER;
@ -98,14 +103,22 @@ virFirewallGroupNew(void)
* *
* Returns the new firewall ruleset * Returns the new firewall ruleset
*/ */
virFirewall *virFirewallNew(void) virFirewall *virFirewallNew(virFirewallBackend backend)
{ {
virFirewall *firewall = g_new0(virFirewall, 1); virFirewall *firewall = g_new0(virFirewall, 1);
firewall->backend = backend;
return firewall; return firewall;
} }
virFirewallBackend
virFirewallGetBackend(virFirewall *firewall)
{
return firewall->backend;
}
static void static void
virFirewallCmdFree(virFirewallCmd *fwCmd) virFirewallCmdFree(virFirewallCmd *fwCmd)
{ {

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include "internal.h" #include "internal.h"
#include "virenum.h"
typedef struct _virFirewall virFirewall; typedef struct _virFirewall virFirewall;
@ -34,9 +35,17 @@ typedef enum {
VIR_FIREWALL_LAYER_LAST, VIR_FIREWALL_LAYER_LAST,
} virFirewallLayer; } virFirewallLayer;
virFirewall *virFirewallNew(void); typedef enum {
VIR_FIREWALL_BACKEND_IPTABLES,
VIR_FIREWALL_BACKEND_LAST,
} virFirewallBackend;
VIR_ENUM_DECL(virFirewallBackend);
virFirewall *virFirewallNew(virFirewallBackend backend);
void virFirewallFree(virFirewall *firewall); void virFirewallFree(virFirewall *firewall);
virFirewallBackend virFirewallGetBackend(virFirewall *firewall);
/** /**
* virFirewallAddCmd: * virFirewallAddCmd:

View File

@ -62,7 +62,7 @@ static int
testFirewallSingleGroup(const void *opaque G_GNUC_UNUSED) testFirewallSingleGroup(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -102,7 +102,7 @@ static int
testFirewallRemoveRule(const void *opaque G_GNUC_UNUSED) testFirewallRemoveRule(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -148,7 +148,7 @@ static int
testFirewallManyGroups(const void *opaque G_GNUC_UNUSED) testFirewallManyGroups(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -222,7 +222,7 @@ static int
testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED) testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -275,7 +275,7 @@ static int
testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED) testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -327,7 +327,7 @@ static int
testFirewallNoRollback(const void *opaque G_GNUC_UNUSED) testFirewallNoRollback(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -372,7 +372,7 @@ static int
testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED) testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -437,7 +437,7 @@ static int
testFirewallManyRollback(const void *opaque G_GNUC_UNUSED) testFirewallManyRollback(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -505,7 +505,7 @@ static int
testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
@ -682,7 +682,7 @@ static int
testFirewallQuery(const void *opaque G_GNUC_UNUSED) testFirewallQuery(const void *opaque G_GNUC_UNUSED)
{ {
g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cmdbuf = VIR_BUFFER_INITIALIZER;
g_autoptr(virFirewall) fw = virFirewallNew(); g_autoptr(virFirewall) fw = virFirewallNew(VIR_FIREWALL_BACKEND_IPTABLES);
const char *actual = NULL; const char *actual = NULL;
const char *expected = const char *expected =
IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" IPTABLES " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"