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)
elif get_option('driver_network').enabled()
error('libvirtd must be enabled to build the network driver')
endif
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: 'iptables', description: 'first firewall backend to try when none is specified')
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.')
networkReloadFirewallRulesHelper(virNetworkObj *obj,
void *opaque G_GNUC_UNUSED)
{
+ g_autoptr(virNetworkDriverConfig) cfg = virNetworkDriverGetConfig(networkGetDriver());
VIR_LOCK_GUARD lock = virObjectLockGuard(obj);
virNetworkDef *def = virNetworkObjGetDef(obj);
* network type, forward='open', doesn't need this because it
* has no iptables rules.
*/
- networkRemoveFirewallRules(def);
- ignore_value(networkAddFirewallRules(def));
+ networkRemoveFirewallRules(def, cfg->firewallBackend);
+ ignore_value(networkAddFirewallRules(def, cfg->firewallBackend));
break;
case VIR_NETWORK_FORWARD_OPEN:
/* Add "once per network" rules */
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
- networkAddFirewallRules(def) < 0)
+ networkAddFirewallRules(def, cfg->firewallBackend) < 0)
goto error;
firewalRulesAdded = true;
if (firewalRulesAdded &&
def->forward.type != VIR_NETWORK_FORWARD_OPEN)
- networkRemoveFirewallRules(def);
+ networkRemoveFirewallRules(def, cfg->firewallBackend);
virNetworkObjUnrefMacMap(obj);
static int
-networkShutdownNetworkVirtual(virNetworkObj *obj)
+networkShutdownNetworkVirtual(virNetworkObj *obj,
+ virNetworkDriverConfig *cfg)
{
virNetworkDef *def = virNetworkObjGetDef(obj);
pid_t dnsmasqPid;
ignore_value(virNetDevSetOnline(def->bridge, false));
if (def->forward.type != VIR_NETWORK_FORWARD_OPEN)
- networkRemoveFirewallRules(def);
+ networkRemoveFirewallRules(def, cfg->firewallBackend);
ignore_value(virNetDevBridgeDelete(def->bridge));
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
- ret = networkShutdownNetworkVirtual(obj);
+ ret = networkShutdownNetworkVirtual(obj, cfg);
break;
case VIR_NETWORK_FORWARD_BRIDGE:
* old rules (and remember to load new ones after the
* update).
*/
- networkRemoveFirewallRules(def);
+ networkRemoveFirewallRules(def, cfg->firewallBackend);
needFirewallRefresh = true;
break;
default:
parentIndex, xml,
network_driver->xmlopt, flags) < 0) {
if (needFirewallRefresh)
- ignore_value(networkAddFirewallRules(def));
+ ignore_value(networkAddFirewallRules(def, cfg->firewallBackend));
goto cleanup;
}
/* @def is replaced */
def = virNetworkObjGetDef(obj);
- if (needFirewallRefresh && networkAddFirewallRules(def) < 0)
+ if (needFirewallRefresh && networkAddFirewallRules(def, cfg->firewallBackend) < 0)
goto cleanup;
if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
#include "datatypes.h"
#include "virlog.h"
#include "virerror.h"
+#include "virfile.h"
#include "virutil.h"
#include "bridge_driver_conf.h"
VIR_LOG_INIT("network.bridge_driver");
-
static virClass *virNetworkDriverConfigClass;
static void virNetworkDriverConfigDispose(void *obj);
const char *filename)
{
g_autoptr(virConf) conf = NULL;
+ g_autofree char *fwBackendStr = NULL;
+ bool fwBackendSelected = false;
+ size_t i;
+ int fwBackends[] = { FIREWALL_BACKEND_DEFAULT_1 };
+ G_STATIC_ASSERT(G_N_ELEMENTS(fwBackends) == VIR_FIREWALL_BACKEND_LAST);
+ int nFwBackends = G_N_ELEMENTS(fwBackends);
+
+ if (access(filename, R_OK) == 0) {
+
+ conf = virConfReadFile(filename, 0);
+ if (!conf)
+ return -1;
+
+ /* use virConfGetValue*(conf, ...) functions to read any settings into cfg */
+
+ if (virConfGetValueString(conf, "firewall_backend", &fwBackendStr) < 0)
+ return -1;
+
+ if (fwBackendStr) {
+ fwBackends[0] = virFirewallBackendTypeFromString(fwBackendStr);
+ nFwBackends = 1;
+
+ if (fwBackends[0] < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unrecognized 'firewall_backend = '%1$s' set in network driver config file %2$s"),
+ fwBackendStr, filename);
+ return -1;
+ }
+ VIR_INFO("firewall_backend setting requested from config file %s: '%s'",
+ virFirewallBackendTypeToString(fwBackends[0]), filename);
+ }
+ }
+
+ for (i = 0; i < nFwBackends && !fwBackendSelected; i++) {
+
+ switch ((virFirewallBackend)fwBackends[i]) {
+ case VIR_FIREWALL_BACKEND_IPTABLES: {
+ g_autofree char *iptablesInPath = virFindFileInPath(IPTABLES);
+
+ if (iptablesInPath)
+ fwBackendSelected = true;
+ break;
+ }
+ case VIR_FIREWALL_BACKEND_LAST:
+ virReportEnumRangeError(virFirewallBackend, fwBackends[i]);
+ return -1;
+ }
+
+ if (fwBackendSelected)
+ cfg->firewallBackend = fwBackends[i];
+ }
- /* if file doesn't exist or is unreadable, ignore the "error" */
- if (access(filename, R_OK) == -1)
+ if (fwBackendSelected) {
+ VIR_INFO("using firewall_backend: '%s'",
+ virFirewallBackendTypeToString(cfg->firewallBackend));
return 0;
- conf = virConfReadFile(filename, 0);
- if (!conf)
- return -1;
+ } else if (fwBackendStr) {
- /* use virConfGetValue*(conf, ...) functions to read any settings into cfg */
+ /* the explicitly requested backend wasn't found - this is a failure */
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("requested firewall_backend '%1$s' is not available"),
+ fwBackendStr);
+ return -1;
- return 0;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("could not find a usable firewall backend"));
+ return -1;
+ }
}
#include "virdnsmasq.h"
#include "virnetworkobj.h"
#include "object_event.h"
+#include "virfirewall.h"
typedef struct _virNetworkDriverConfig virNetworkDriverConfig;
struct _virNetworkDriverConfig {
char *stateDir;
char *pidDir;
char *dnsmasqStateDir;
+
+ virFirewallBackend firewallBackend;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetworkDriverConfig, virObjectUnref);
int
-networkAddFirewallRules(virNetworkDef *def)
+networkAddFirewallRules(virNetworkDef *def,
+ virFirewallBackend firewallBackend G_GNUC_UNUSED)
{
if (virOnce(&createdOnce, networkSetupPrivateChains) < 0)
return -1;
void
-networkRemoveFirewallRules(virNetworkDef *def)
+networkRemoveFirewallRules(virNetworkDef *def,
+ virFirewallBackend firewallBackend G_GNUC_UNUSED)
{
iptablesRemoveFirewallRules(def);
}
return 0;
}
-int networkAddFirewallRules(virNetworkDef *def G_GNUC_UNUSED)
+int networkAddFirewallRules(virNetworkDef *def G_GNUC_UNUSED,
+ virFirewallBackend firewallBackend G_GNUC_UNUSED)
{
return 0;
}
-void networkRemoveFirewallRules(virNetworkDef *def G_GNUC_UNUSED)
+void networkRemoveFirewallRules(virNetworkDef *def G_GNUC_UNUSED,
+ virFirewallBackend firewallBackend G_GNUC_UNUSED)
{
}
int networkCheckRouteCollision(virNetworkDef *def);
-int networkAddFirewallRules(virNetworkDef *def);
+int networkAddFirewallRules(virNetworkDef *def,
+ virFirewallBackend firewallBackend);
-void networkRemoveFirewallRules(virNetworkDef *def);
+void networkRemoveFirewallRules(virNetworkDef *def,
+ virFirewallBackend firewallBackend);
let int_entry (kw:string) = [ key kw . value_sep . int_val ]
let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ]
+ let firewall_backend_entry = str_entry "firewall_backend"
+
(* Each entry in the config is one of the following *)
+ let entry = firewall_backend_entry
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
let empty = [ label "#empty" . eol ]
- let record = indent . eol
+ let record = indent . entry . eol
let lns = ( record | comment | empty ) *
],
}
+ network_options_conf = configuration_data({
+ 'FIREWALL_BACKEND': firewall_backend_default_conf,
+ })
+
network_conf = configure_file(
input: 'network.conf.in',
output: 'network.conf',
- configuration: configmake_conf,
+ configuration: network_options_conf,
)
+
+ network_options_hack_conf = configuration_data({
+ 'FIREWALL_BACKEND': firewall_backend_default_conf,
+ # 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
+ 'CONFIG': '@CONFIG@',
+ })
+ test_libvirtd_network_aug_tmp = configure_file(
+ input: 'test_libvirtd_network.aug.in',
+ output: 'test_libvirtd_network.aug.tmp',
+ configuration: network_options_hack_conf,
+ )
+
virt_conf_files += network_conf
virt_aug_files += files('libvirtd_network.aug')
virt_test_aug_files += {
'name': 'test_libvirtd_network.aug',
- 'aug': files('test_libvirtd_network.aug.in'),
+ 'aug': test_libvirtd_network_aug_tmp,
'conf': network_conf,
'test_name': 'libvirtd_network',
'test_srcdir': meson.current_source_dir(),
# Master configuration file for the network driver.
# All settings described here are optional - if omitted, sensible
# defaults are used.
+
+# firewall_backend:
+#
+# determines which subsystem to use to setup firewall packet
+# filtering rules for virtual networks. Currently the only supported
+# selection is "iptables".
+#
+#firewall_backend = "@FIREWALL_BACKEND@"
module Test_libvirtd_network =
@CONFIG@
+
+ test Libvirtd_network.lns get conf =
+{ "firewall_backend" = "@FIREWALL_BACKEND@" }
if (!(def = virNetworkDefParse(NULL, xml, NULL, false)))
return -1;
- if (networkAddFirewallRules(def) < 0)
+ if (networkAddFirewallRules(def, VIR_FIREWALL_BACKEND_IPTABLES) < 0)
return -1;
actual = actualargv = virBufferContentAndReset(&buf);