diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 1cbb061d3d..7594c4996e 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -113,52 +113,55 @@
Host=
- Matches against the hostname or machine
- ID of the host. See ConditionHost= in
+ Matches against the hostname or machine ID of the host. See ConditionHost= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
+ Virtualization=
- Checks whether the system is executed in
- a virtualized environment and optionally test
- whether it is a specific implementation. See
- ConditionVirtualization= in
+ Checks whether the system is executed in a virtualized environment and optionally test
+ whether it is a specific implementation. See ConditionVirtualization= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
+ KernelCommandLine=
- Checks whether a specific kernel command line option
- is set (or if prefixed with the exclamation mark unset). See
+ Checks whether a specific kernel command line option is set. See
ConditionKernelCommandLine= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
+
+
+
+
+ KernelVersion=
+
+ Checks whether the kernel version (as reported by uname -r) matches a certain
+ expression. See ConditionKernelVersion= in
+ systemd.unit5 for
+ details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
+
-
- KernelVersion=
-
- Checks whether the kernel version (as reported by uname -r) matches a certain
- expression (or if prefixed with the exclamation mark does not match it). See
- ConditionKernelVersion= in
- systemd.unit5 for
- details.
-
-
- Architecture=
- Checks whether the system is running on a specific
- architecture. See ConditionArchitecture=
- in
+ Checks whether the system is running on a specific architecture. See
+ ConditionArchitecture= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
+
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 72fa7d4de3..c361f070be 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -190,53 +190,55 @@
Host=
- Matches against the hostname or machine ID of the
- host. See ConditionHost= in
+ Matches against the hostname or machine ID of the host. See
+ ConditionHost= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
Virtualization=
- Checks whether the system is executed in a virtualized
- environment and optionally test whether it is a specific
- implementation. See
- ConditionVirtualization= in
+ Checks whether the system is executed in a virtualized environment and optionally test
+ whether it is a specific implementation. See ConditionVirtualization= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
KernelCommandLine=
- Checks whether a specific kernel command line option
- is set (or if prefixed with the exclamation mark unset). See
+ Checks whether a specific kernel command line option is set. See
ConditionKernelCommandLine= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
KernelVersion=
- Checks whether the kernel version (as reported by uname -r) matches a certain
- expression (or if prefixed with the exclamation mark does not match it). See
- ConditionKernelVersion= in
- systemd.unit5 for details.
+ Checks whether the kernel version (as reported by uname -r) matches a
+ certain expression. See ConditionKernelVersion= in
+ systemd.unit5
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
Architecture=
- Checks whether the system is running on a specific
- architecture. See ConditionArchitecture= in
+ Checks whether the system is running on a specific architecture. See
+ ConditionArchitecture= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 268ae22d91..4127084703 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -137,53 +137,55 @@
Host=
- Matches against the hostname or machine ID of the
- host. See ConditionHost= in
+ Matches against the hostname or machine ID of the host. See
+ ConditionHost= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
Virtualization=
- Checks whether the system is executed in a virtualized
- environment and optionally test whether it is a specific
- implementation. See ConditionVirtualization= in
+ Checks whether the system is executed in a virtualized environment and optionally test
+ whether it is a specific implementation. See ConditionVirtualization= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
KernelCommandLine=
- Checks whether a specific kernel command line option is
- set (or if prefixed with the exclamation mark unset). See
+ Checks whether a specific kernel command line option is set. See
ConditionKernelCommandLine= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
KernelVersion=
- Checks whether the kernel version (as reported by uname -r) matches a certain
- expression (or if prefixed with the exclamation mark does not match it). See
- ConditionKernelVersion= in
- systemd.unit5 for
- details.
+ Checks whether the kernel version (as reported by uname -r) matches a
+ certain expression. See ConditionKernelVersion= in
+ systemd.unit5
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
Architecture=
- Checks whether the system is running on a specific
- architecture. See ConditionArchitecture= in
+ Checks whether the system is running on a specific architecture. See
+ ConditionArchitecture= in
systemd.unit5
- for details.
+ for details. When prefixed with an exclamation mark (!), the result is negated.
+ If an empty string is assigned, then previously assigned value is cleared.
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 7338b11280..9281c2c4ae 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1021,35 +1021,35 @@
ConditionArchitecture= may be used to
check whether the system is running on a specific
architecture. Takes one of
- x86,
- x86-64,
- ppc,
- ppc-le,
- ppc64,
- ppc64-le,
- ia64,
- parisc,
- parisc64,
- s390,
- s390x,
- sparc,
- sparc64,
- mips,
- mips-le,
- mips64,
- mips64-le,
- alpha,
- arm,
- arm-be,
- arm64,
- arm64-be,
- sh,
- sh64,
- m68k,
- tilegx,
- cris,
- arc,
- arc-be to test
+ x86,
+ x86-64,
+ ppc,
+ ppc-le,
+ ppc64,
+ ppc64-le,
+ ia64,
+ parisc,
+ parisc64,
+ s390,
+ s390x,
+ sparc,
+ sparc64,
+ mips,
+ mips-le,
+ mips64,
+ mips64-le,
+ alpha,
+ arm,
+ arm-be,
+ arm64,
+ arm64-be,
+ sh,
+ sh64,
+ m68k,
+ tilegx,
+ cris,
+ arc,
+ arc-be to test
against a specific architecture. The architecture is
determined from the information returned by
uname2
@@ -1057,7 +1057,7 @@
personality2.
Note that a Personality= setting in the
same unit file has no effect on this condition. A special
- architecture name native is mapped to the
+ architecture name native is mapped to the
architecture the system manager itself is compiled for. The
test may be negated by prepending an exclamation mark.
@@ -1066,30 +1066,30 @@
environment and optionally test whether it is a specific
implementation. Takes either boolean value to check if being
executed in any virtualized environment, or one of
- vm and
- container to test against a generic type of
+ vm and
+ container to test against a generic type of
virtualization solution, or one of
- qemu,
- kvm,
- zvm,
- vmware,
- microsoft,
- oracle,
- xen,
- bochs,
- uml,
- bhyve,
- qnx,
- openvz,
- lxc,
- lxc-libvirt,
- systemd-nspawn,
- docker,
- rkt,
- wsl,
- acrn to test
+ qemu,
+ kvm,
+ zvm,
+ vmware,
+ microsoft,
+ oracle,
+ xen,
+ bochs,
+ uml,
+ bhyve,
+ qnx,
+ openvz,
+ lxc,
+ lxc-libvirt,
+ systemd-nspawn,
+ docker,
+ rkt,
+ wsl,
+ acrn to test
against a specific implementation, or
- private-users to check whether we are running in a user namespace. See
+ private-users to check whether we are running in a user namespace. See
systemd-detect-virt1
for a full list of known virtualization technologies and their
identifiers. If multiple virtualization technologies are
@@ -1131,10 +1131,10 @@
ConditionSecurity= may be used to check
whether the given security technology is enabled on the
system. Currently, the recognized values are
- selinux, apparmor,
- tomoyo, ima,
- smack, audit and
- uefi-secureboot. The test may be negated by
+ selinux, apparmor,
+ tomoyo, ima,
+ smack, audit and
+ uefi-secureboot. The test may be negated by
prepending an exclamation mark.ConditionCapability= may be used to
@@ -1150,11 +1150,11 @@
ConditionACPower= may be used to
check whether the system has AC power, or is exclusively
battery powered at the time of activation of the unit. This
- takes a boolean argument. If set to true,
+ takes a boolean argument. If set to true,
the condition will hold only if at least one AC connector of
the system is connected to a power source, or if no AC
connectors are known. Conversely, if set to
- false, the condition will hold only if
+ false, the condition will hold only if
there is at least one AC connector known and all AC connectors
are disconnected from a power source.
@@ -1244,16 +1244,16 @@
does not have a special value @system.ConditionControlGroupController= takes a
- cgroup controller name (eg. ), verifying that it is
+ cgroup controller name (eg. cpu), verifying that it is
available for use on the system. For example, a particular controller
may not be available if it was disabled on the kernel command line with
cgroup_disable=controller. Multiple controllers may
be passed with a space separating them; in this case the condition will
only pass if all listed controllers are available for use. Controllers
unknown to systemd are ignored. Valid controllers are
- , , ,
- , ,
- , and .
+ cpu, cpuacct, io,
+ blkio, memory,
+ devices, and pids.
If multiple conditions are specified, the unit will be
executed if all of them apply (i.e. a logical AND is applied).
diff --git a/src/basic/log.c b/src/basic/log.c
index 3b7bff3a97..37a5ffa74f 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -699,8 +699,7 @@ int log_internal_realm(
return r;
}
-_printf_(10,0)
-static int log_object_internalv(
+int log_object_internalv(
int level,
int error,
const char *file,
diff --git a/src/basic/log.h b/src/basic/log.h
index 113e0dedee..aa3d5b75f1 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -115,6 +115,19 @@ int log_internalv_realm(
log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
/* Realm is fixed to LOG_REALM_SYSTEMD for those */
+int log_object_internalv(
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ const char *object_field,
+ const char *object,
+ const char *extra_field,
+ const char *extra,
+ const char *format,
+ va_list ap) _printf_(10,0);
+
int log_object_internal(
int level,
int error,
diff --git a/src/core/unit.c b/src/core/unit.c
index 5620fd9017..d559cfca12 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1589,55 +1589,32 @@ fail:
return log_unit_debug_errno(u, r, "Failed to load configuration: %m");
}
-static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to_string)(ConditionType t)) {
- Condition *c;
- int triggered = -1;
+_printf_(7, 8)
+static int log_unit_internal(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) {
+ Unit *u = userdata;
+ va_list ap;
+ int r;
- assert(u);
- assert(to_string);
+ va_start(ap, format);
+ if (u)
+ r = log_object_internalv(level, error, file, line, func,
+ u->manager->unit_log_field,
+ u->id,
+ u->manager->invocation_log_field,
+ u->invocation_id_string,
+ format, ap);
+ else
+ r = log_internalv(level, error, file, line, func, format, ap);
+ va_end(ap);
- /* If the condition list is empty, then it is true */
- if (!first)
- return true;
-
- /* Otherwise, if all of the non-trigger conditions apply and
- * if any of the trigger conditions apply (unless there are
- * none) we return true */
- LIST_FOREACH(conditions, c, first) {
- int r;
-
- r = condition_test(c);
- if (r < 0)
- log_unit_warning(u,
- "Couldn't determine result for %s=%s%s%s, assuming failed: %m",
- to_string(c->type),
- c->trigger ? "|" : "",
- c->negate ? "!" : "",
- c->parameter);
- else
- log_unit_debug(u,
- "%s=%s%s%s %s.",
- to_string(c->type),
- c->trigger ? "|" : "",
- c->negate ? "!" : "",
- c->parameter,
- condition_result_to_string(c->result));
-
- if (!c->trigger && r <= 0)
- return false;
-
- if (c->trigger && triggered <= 0)
- triggered = r > 0;
- }
-
- return triggered != 0;
+ return r;
}
static bool unit_test_condition(Unit *u) {
assert(u);
dual_timestamp_get(&u->condition_timestamp);
- u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string);
+ u->condition_result = condition_test_list(u->conditions, condition_type_to_string, log_unit_internal, u);
unit_add_to_dbus_queue(u);
@@ -1648,7 +1625,7 @@ static bool unit_test_assert(Unit *u) {
assert(u);
dual_timestamp_get(&u->assert_timestamp);
- u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string);
+ u->assert_result = condition_test_list(u->asserts, assert_type_to_string, log_unit_internal, u);
unit_add_to_dbus_queue(u);
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index c8fc10d0c4..2154cf7eac 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -100,32 +100,12 @@ bool net_match_config(Set *match_mac,
char * const *match_drivers,
char * const *match_types,
char * const *match_names,
- Condition *match_host,
- Condition *match_virt,
- Condition *match_kernel_cmdline,
- Condition *match_kernel_version,
- Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
const char *dev_driver,
const char *dev_type,
const char *dev_name) {
- if (match_host && condition_test(match_host) <= 0)
- return false;
-
- if (match_virt && condition_test(match_virt) <= 0)
- return false;
-
- if (match_kernel_cmdline && condition_test(match_kernel_cmdline) <= 0)
- return false;
-
- if (match_kernel_version && condition_test(match_kernel_version) <= 0)
- return false;
-
- if (match_arch && condition_test(match_arch) <= 0)
- return false;
-
if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
return false;
@@ -156,32 +136,31 @@ int config_parse_net_condition(const char *unit,
void *userdata) {
ConditionType cond = ltype;
- Condition **ret = data;
+ Condition **list = data, *c;
bool negate;
- Condition *c;
- _cleanup_free_ char *s = NULL;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
+ if (isempty(rvalue)) {
+ *list = condition_free_list_type(*list, cond);
+ return 0;
+ }
+
negate = rvalue[0] == '!';
if (negate)
rvalue++;
- s = strdup(rvalue);
- if (!s)
- return log_oom();
-
- c = condition_new(cond, s, false, negate);
+ c = condition_new(cond, rvalue, false, negate);
if (!c)
return log_oom();
- if (*ret)
- condition_free(*ret);
+ /* Drop previous assignment. */
+ *list = condition_free_list_type(*list, cond);
- *ret = c;
+ LIST_PREPEND(conditions, *list, c);
return 0;
}
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 9d30c52eea..62f5a4a76c 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -6,7 +6,6 @@
#include "sd-device.h"
#include "sd-dhcp-lease.h"
-#include "condition.h"
#include "conf-parser.h"
#include "def.h"
#include "set.h"
@@ -20,11 +19,6 @@ bool net_match_config(Set *match_mac,
char * const *match_driver,
char * const *match_type,
char * const *match_name,
- Condition *match_host,
- Condition *match_virt,
- Condition *match_kernel_cmdline,
- Condition *match_kernel_version,
- Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
const char *dev_driver,
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 3365023b32..96632da0b6 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -34,11 +34,11 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel_cmdline)
-Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, match_kernel_version)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, conditions)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, conditions)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, conditions)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, conditions)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, conditions)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index f60214ae11..5cdd09d775 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -174,12 +174,7 @@ static NetDev *netdev_free(NetDev *netdev) {
free(netdev->description);
free(netdev->ifname);
free(netdev->mac);
-
- condition_free_list(netdev->match_host);
- condition_free_list(netdev->match_virt);
- condition_free_list(netdev->match_kernel_cmdline);
- condition_free_list(netdev->match_kernel_version);
- condition_free_list(netdev->match_arch);
+ condition_free_list(netdev->conditions);
/* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
* because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
@@ -683,11 +678,7 @@ int netdev_load_one(Manager *manager, const char *filename) {
return r;
/* skip out early if configuration does not match the environment */
- if (!net_match_config(NULL, NULL, NULL, NULL, NULL,
- netdev_raw->match_host, netdev_raw->match_virt,
- netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
- netdev_raw->match_arch,
- NULL, NULL, NULL, NULL, NULL)) {
+ if (!condition_test_list(netdev_raw->conditions, NULL, NULL, NULL)) {
log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename);
return 0;
}
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index c46ed4d719..3c6990236f 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -81,11 +81,7 @@ typedef struct NetDev {
char *filename;
- Condition *match_host;
- Condition *match_virt;
- Condition *match_kernel_cmdline;
- Condition *match_kernel_version;
- Condition *match_arch;
+ Condition *conditions;
NetDevState state;
NetDevKind kind;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 2db8299b13..47a9f7d808 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -25,11 +25,11 @@ Match.Path, config_parse_strv,
Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver)
Match.Type, config_parse_strv, 0, offsetof(Network, match_type)
Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name)
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline)
-Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, match_kernel_version)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch)
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, conditions)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, conditions)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 33055d9e3d..c6c3480cd1 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -174,10 +174,7 @@ int network_verify(Network *network) {
assert(network->filename);
/* skip out early if configuration does not match the environment */
- if (!net_match_config(NULL, NULL, NULL, NULL, NULL,
- network->match_host, network->match_virt, network->match_kernel_cmdline,
- network->match_kernel_version, network->match_arch,
- NULL, NULL, NULL, NULL, NULL))
+ if (!condition_test_list(network->conditions, NULL, NULL, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Conditions in the file do not match the system environment, skipping.",
network->filename);
@@ -497,6 +494,7 @@ void network_free(Network *network) {
strv_free(network->match_driver);
strv_free(network->match_type);
strv_free(network->match_name);
+ condition_free_list(network->conditions);
free(network->description);
free(network->dhcp_vendor_class_identifier);
@@ -568,12 +566,6 @@ void network_free(Network *network) {
free(network->name);
- condition_free_list(network->match_host);
- condition_free_list(network->match_virt);
- condition_free_list(network->match_kernel_cmdline);
- condition_free_list(network->match_kernel_version);
- condition_free_list(network->match_arch);
-
free(network->dhcp_server_timezone);
free(network->dhcp_server_dns);
free(network->dhcp_server_ntp);
@@ -619,9 +611,7 @@ int network_get(Manager *manager, sd_device *device,
LIST_FOREACH(networks, network, manager->networks) {
if (net_match_config(network->match_mac, network->match_path,
network->match_driver, network->match_type,
- network->match_name, network->match_host,
- network->match_virt, network->match_kernel_cmdline,
- network->match_kernel_version, network->match_arch,
+ network->match_name,
address, path, driver, devtype, ifname)) {
if (network->match_name && device) {
const char *attr;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index e7f9a68162..7211aee8c6 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -97,12 +97,7 @@ struct Network {
char **match_driver;
char **match_type;
char **match_name;
-
- Condition *match_host;
- Condition *match_virt;
- Condition *match_kernel_cmdline;
- Condition *match_kernel_version;
- Condition *match_arch;
+ Condition *conditions;
char *description;
diff --git a/src/shared/condition.c b/src/shared/condition.c
index fb77966264..69d65fffbc 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -77,13 +77,17 @@ void condition_free(Condition *c) {
free(c);
}
-Condition* condition_free_list(Condition *first) {
- Condition *c, *n;
+Condition* condition_free_list_type(Condition *first, ConditionType type) {
+ Condition *c, *n, *r = NULL;
LIST_FOREACH_SAFE(conditions, c, n, first)
- condition_free(c);
+ if (type < 0 || c->type == type)
+ condition_free(c);
+ else if (!r)
+ r = c;
- return NULL;
+ assert(type >= 0 || !r);
+ return r;
}
static int condition_test_kernel_command_line(Condition *c) {
@@ -644,6 +648,52 @@ int condition_test(Condition *c) {
return b;
}
+bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata) {
+ Condition *c;
+ int triggered = -1;
+
+ assert(!!logger == !!to_string);
+
+ /* If the condition list is empty, then it is true */
+ if (!first)
+ return true;
+
+ /* Otherwise, if all of the non-trigger conditions apply and
+ * if any of the trigger conditions apply (unless there are
+ * none) we return true */
+ LIST_FOREACH(conditions, c, first) {
+ int r;
+
+ r = condition_test(c);
+
+ if (logger) {
+ if (r < 0)
+ logger(userdata, LOG_WARNING, r, __FILE__, __LINE__, __func__,
+ "Couldn't determine result for %s=%s%s%s, assuming failed: %m",
+ to_string(c->type),
+ c->trigger ? "|" : "",
+ c->negate ? "!" : "",
+ c->parameter);
+ else
+ logger(userdata, LOG_DEBUG, 0, __FILE__, __LINE__, __func__,
+ "%s=%s%s%s %s.",
+ to_string(c->type),
+ c->trigger ? "|" : "",
+ c->negate ? "!" : "",
+ c->parameter,
+ condition_result_to_string(c->result));
+ }
+
+ if (!c->trigger && r <= 0)
+ return false;
+
+ if (c->trigger && triggered <= 0)
+ triggered = r > 0;
+ }
+
+ return triggered != 0;
+}
+
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
assert(c);
assert(f);
diff --git a/src/shared/condition.h b/src/shared/condition.h
index e69fc366f7..594c12d5a7 100644
--- a/src/shared/condition.h
+++ b/src/shared/condition.h
@@ -65,9 +65,14 @@ typedef struct Condition {
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
void condition_free(Condition *c);
-Condition* condition_free_list(Condition *c);
+Condition* condition_free_list_type(Condition *first, ConditionType type);
+static inline Condition* condition_free_list(Condition *first) {
+ return condition_free_list_type(first, _CONDITION_TYPE_INVALID);
+}
int condition_test(Condition *c);
+typedef int (*condition_test_logger_t)(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
+bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata);
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 2bc18bff56..558996cf2e 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -24,11 +24,11 @@ Match.OriginalName, config_parse_ifnames, 0,
Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
Match.Type, config_parse_strv, 0, offsetof(link_config, match_type)
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel_cmdline)
-Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, match_kernel_version)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch)
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, conditions)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, conditions)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, conditions)
Link.Description, config_parse_string, 0, offsetof(link_config, description)
Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 438ff473ae..58d5d27883 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -51,12 +51,7 @@ static void link_config_free(link_config *link) {
strv_free(link->match_driver);
strv_free(link->match_type);
strv_free(link->match_name);
-
- condition_free_list(link->match_host);
- condition_free_list(link->match_virt);
- condition_free_list(link->match_kernel_cmdline);
- condition_free_list(link->match_kernel_version);
- condition_free_list(link->match_arch);
+ condition_free_list(link->conditions);
free(link->description);
free(link->mac);
@@ -164,10 +159,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
if (link->speed > UINT_MAX)
return -ERANGE;
- if (!net_match_config(NULL, NULL, NULL, NULL, NULL,
- link->match_host, link->match_virt, link->match_kernel_cmdline,
- link->match_kernel_version, link->match_arch,
- NULL, NULL, NULL, NULL, NULL)) {
+ if (!condition_test_list(link->conditions, NULL, NULL, NULL)) {
log_debug("%s: Conditions do not match the system environment, skipping.", filename);
return 0;
}
@@ -251,9 +243,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
(void) sd_device_get_sysname(device, &sysname);
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
- link->match_type, link->match_name, link->match_host,
- link->match_virt, link->match_kernel_cmdline,
- link->match_kernel_version, link->match_arch,
+ link->match_type, link->match_name,
address ? ether_aton(address) : NULL,
id_path,
id_net_driver,
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 4335b593d1..f18b2afa79 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -40,11 +40,7 @@ struct link_config {
char **match_driver;
char **match_type;
char **match_name;
- Condition *match_host;
- Condition *match_virt;
- Condition *match_kernel_cmdline;
- Condition *match_kernel_version;
- Condition *match_arch;
+ Condition *conditions;
char *description;
struct ether_addr *mac;