On 5/28/24 11:49 AM, Andrea Bolognani wrote:
The current implementation requires users to configure the
preference as such:
-Dfirewall_backend_default_1=iptables
-Dfirewall_backend_default_2=nftables
In addition to being more verbose than one would hope, there
are several things that could go wrong.
First of all, meson performs no validation on the provided
values, so mistakes will only be caught by the compiler.
Additionally, it's entirely possible to provide nonsensical
combinations, such as repeating the same value twice.
Change things so that the preference can now be configured
as such:
-Dfirewall_backend_priority=iptables,nftables
Checks have been added to prevent invalid values from being
accepted.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
meson.build | 16 +++++++++-------
meson_options.txt | 3 +--
src/network/bridge_driver_conf.c | 6 +++++-
src/network/meson.build | 6 ++++--
src/network/network.conf.in | 13 +++++++------
5 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/meson.build b/meson.build
index f67c3d2724..ed0e9686f8 100644
--- a/meson.build
+++ b/meson.build
@@ -1635,15 +1635,17 @@ endif
if not get_option('driver_network').disabled() and
conf.has('WITH_LIBVIRTD')
conf.set('WITH_NETWORK', 1)
- firewall_backend_default_1 = get_option('firewall_backend_default_1')
- firewall_backend_default_conf = firewall_backend_default_1
- firewall_backend_default_1 = 'VIR_FIREWALL_BACKEND_' +
firewall_backend_default_1.to_upper()
- conf.set('FIREWALL_BACKEND_DEFAULT_1', firewall_backend_default_1)
- firewall_backend_default_2 = get_option('firewall_backend_default_2')
- firewall_backend_default_2 = 'VIR_FIREWALL_BACKEND_' +
firewall_backend_default_2.to_upper()
- conf.set('FIREWALL_BACKEND_DEFAULT_2', firewall_backend_default_2)
+ firewall_backend_priority = get_option('firewall_backend_priority')
+ if (not firewall_backend_priority.contains('nftables') or
+ not firewall_backend_priority.contains('iptables') or
+ firewall_backend_priority.length() != 2)
Okay, yeah. That does actually make sure that both possibilities are in
the list, and (indirectly) that none is duplicated.
+ error('invalid value for firewall_backend_priority
option')
+ endif
+ conf.set('FIREWALL_BACKEND_PRIORITY_0', 'VIR_FIREWALL_BACKEND_' +
firewall_backend_priority[0].to_upper())
+ conf.set('FIREWALL_BACKEND_PRIORITY_1', 'VIR_FIREWALL_BACKEND_' +
firewall_backend_priority[1].to_upper())
+ conf.set('FIREWALL_BACKEND_PRIORITY_NUM', firewall_backend_priority.length())
elif get_option('driver_network').enabled()
error('libvirtd must be enabled to build the network driver')
endif
diff --git a/meson_options.txt b/meson_options.txt
index ad354a8668..8723d13231 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -115,8 +115,7 @@ option('dtrace', type: 'feature', value:
'auto', description: 'use dtrace for st
option('firewalld', type: 'feature', value: 'auto',
description: 'firewalld support')
# dep:firewalld
option('firewalld_zone', type: 'feature', value: 'auto',
description: 'whether to install firewalld libvirt zone')
-option('firewall_backend_default_1', type: 'string', value:
'nftables', description: 'first firewall backend to try when none is
specified')
-option('firewall_backend_default_2', type: 'string', value:
'iptables', description: 'second firewall backend to try when none is
specified (and first is unavailable)')
+option('firewall_backend_priority', type: 'array', choices:
['nftables', 'iptables'], description: 'firewall backends to try,
preferred ones first')
Yes! This is the way I initially wanted to do it, but didn't have enough
meson-foo to make it work.
option('host_validate', type: 'feature', value:
'auto', description: 'build virt-host-validate')
option('init_script', type: 'combo', choices: ['systemd',
'openrc', 'check', 'none'], value: 'check', description:
'Style of init script to install')
option('loader_nvram', type: 'string', value: '', description:
'Pass list of pairs of <loader>:<nvram> paths. Both pairs and list items
are separated by a colon.')
diff --git a/src/network/bridge_driver_conf.c b/src/network/bridge_driver_conf.c
index 8f4956dace..e2f3613a41 100644
--- a/src/network/bridge_driver_conf.c
+++ b/src/network/bridge_driver_conf.c
@@ -67,8 +67,12 @@ virNetworkLoadDriverConfig(virNetworkDriverConfig *cfg G_GNUC_UNUSED,
g_autofree char *fwBackendStr = NULL;
bool fwBackendSelected = false;
size_t i;
- int fwBackends[] = { FIREWALL_BACKEND_DEFAULT_1, FIREWALL_BACKEND_DEFAULT_2 };
+ int fwBackends[] = {
+ FIREWALL_BACKEND_PRIORITY_0,
+ FIREWALL_BACKEND_PRIORITY_1,
+ };
G_STATIC_ASSERT(G_N_ELEMENTS(fwBackends) == VIR_FIREWALL_BACKEND_LAST);
+ G_STATIC_ASSERT(G_N_ELEMENTS(fwBackends) == FIREWALL_BACKEND_PRIORITY_NUM);
I had to think about this for a minute, since at first glance those both
seem kind of the same. you want to continue checking that the backends
priority list has an entry for every item, and also make sure that there
wasn't an extra item in the priorities list given to the build.
int nFwBackends = G_N_ELEMENTS(fwBackends);
if (access(filename, R_OK) == 0) {
diff --git a/src/network/meson.build b/src/network/meson.build
index bf2893accc..07cd5cda55 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -51,7 +51,8 @@ if conf.has('WITH_NETWORK')
}
network_options_conf = configuration_data({
- 'FIREWALL_BACKEND': firewall_backend_default_conf,
+ 'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority),
+ 'FIREWALL_BACKEND': firewall_backend_priority[0],
})
network_conf = configure_file(
@@ -61,7 +62,8 @@ if conf.has('WITH_NETWORK')
)
network_options_hack_conf = configuration_data({
- 'FIREWALL_BACKEND': firewall_backend_default_conf,
+ 'FIREWALL_BACKEND_PRIORITY': ', '.join(firewall_backend_priority),
+ 'FIREWALL_BACKEND': firewall_backend_priority[0],
# This hack is necessary because the output file is going to be
# used as input for another configure_file() call later, which
# will take care of substituting @CONFIG@ with useful data
diff --git a/src/network/network.conf.in b/src/network/network.conf.in
index f579f39fcd..5ed64a04a5 100644
--- a/src/network/network.conf.in
+++ b/src/network/network.conf.in
@@ -12,12 +12,13 @@
# iptables - use iptables commands to construct the firewall
# nftables - use nft commands to construct the firewall
#
-# If firewall_backend isn't set in this file, libvirt will
-# prefer the @FIREWALL_BACKEND@ backend *if the necessary package.
-# binary is installed*, otherwise it will look for the package/binary
-# needed for the other backend and use that if available. If neither
-# is available on the host, then the network driver will fail to
-# start, and an error will be logged.
+# If firewall_backend isn't configured, libvirt will choose the
+# first available backend from the following list:
+#
+# [@FIREWALL_BACKEND_PRIORITY@]
+#
+# If no backend is available on the host, then the network driver
+# will fail to start, and an error will be logged.
#
# (NB: switching from one backend to another while there are active
# virtual networks *is* supported. The change will take place the