Merge pull request #7629 from poettering/condition-kernel-version

core,udev,networkd: add ConditionKernelVersion=
This commit is contained in:
Lennart Poettering 2017-12-26 20:48:58 +01:00 committed by GitHub
commit 559fdfa3e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 338 additions and 78 deletions

View file

@ -172,6 +172,17 @@
for details.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KernelVersion=</varname></term>
<listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
expression (or if prefixed with the exclamation mark does not match it). See
<literal>ConditionKernelVersion=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>

View file

@ -232,6 +232,16 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KernelVersion=</varname></term>
<listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
expression (or if prefixed with the exclamation mark does not match it). See
<literal>ConditionKernelVersion=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>

View file

@ -193,6 +193,17 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KernelVersion=</varname></term>
<listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
expression (or if prefixed with the exclamation mark does not match it). See
<literal>ConditionKernelVersion=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>

View file

@ -923,6 +923,7 @@
<term><varname>ConditionVirtualization=</varname></term>
<term><varname>ConditionHost=</varname></term>
<term><varname>ConditionKernelCommandLine=</varname></term>
<term><varname>ConditionKernelVersion=</varname></term>
<term><varname>ConditionSecurity=</varname></term>
<term><varname>ConditionCapability=</varname></term>
<term><varname>ConditionACPower=</varname></term>
@ -1050,6 +1051,17 @@
the exact assignment is looked for with right and left hand
side matching.</para>
<para><varname>ConditionKernelVersion=</varname> may be used to check whether the kernel version (as reported
by <command>uname -r</command>) matches a certain expression (or if prefixed with the exclamation mark does not
match it). The argument must be a single string. If the string starts with one of <literal>&lt;</literal>,
<literal>&lt;=</literal>, <literal>=</literal>, <literal>&gt;=</literal>, <literal>&gt;</literal> a relative
version comparison is done, otherwise the specified string is matched with shell-style globs.</para>
<para>Note that using the kernel version string is an unreliable way to determine which features are supported
by a kernel, because of the widespread practice of backporting drivers, features, and fixes from newer upstream
kernels into older versions provided by distributions. Hence, this check is inherently unportable and should
not be used for units which may be used on different distributions.</para>
<para><varname>ConditionSecurity=</varname> may be used to
check whether the given security module is enabled on the
system. Currently, the recognized values are
@ -1201,6 +1213,7 @@
<term><varname>AssertVirtualization=</varname></term>
<term><varname>AssertHost=</varname></term>
<term><varname>AssertKernelCommandLine=</varname></term>
<term><varname>AssertKernelVersion=</varname></term>
<term><varname>AssertSecurity=</varname></term>
<term><varname>AssertCapability=</varname></term>
<term><varname>AssertACPower=</varname></term>

View file

@ -553,3 +553,65 @@ int version(void) {
SYSTEMD_FEATURES);
return 0;
}
/* This is a direct translation of str_verscmp from boot.c */
static bool is_digit(int c) {
return c >= '0' && c <= '9';
}
static int c_order(int c) {
if (c == 0 || is_digit(c))
return 0;
if ((c >= 'a') && (c <= 'z'))
return c;
return c + 0x10000;
}
int str_verscmp(const char *s1, const char *s2) {
const char *os1, *os2;
assert(s1);
assert(s2);
os1 = s1;
os2 = s2;
while (*s1 || *s2) {
int first;
while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) {
int order;
order = c_order(*s1) - c_order(*s2);
if (order != 0)
return order;
s1++;
s2++;
}
while (*s1 == '0')
s1++;
while (*s2 == '0')
s2++;
first = 0;
while (is_digit(*s1) && is_digit(*s2)) {
if (first == 0)
first = *s1 - *s2;
s1++;
s2++;
}
if (is_digit(*s1))
return 1;
if (is_digit(*s2))
return -1;
if (first != 0)
return first;
}
return strcmp(os1, os2);
}

View file

@ -189,3 +189,5 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
int update_reboot_parameter_and_warn(const char *param);
int version(void);
int str_verscmp(const char *s1, const char *s2);

View file

@ -241,6 +241,7 @@ Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_F
Unit.ConditionNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, conditions)
Unit.ConditionFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, conditions)
Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, conditions)
Unit.ConditionKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, conditions)
Unit.ConditionArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, conditions)
Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, conditions)
Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, conditions)
@ -263,6 +264,7 @@ Unit.AssertFileIsExecutable, config_parse_unit_condition_path, CONDITION_F
Unit.AssertNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, asserts)
Unit.AssertFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, asserts)
Unit.AssertKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, asserts)
Unit.AssertKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, asserts)
Unit.AssertArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, asserts)
Unit.AssertVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, asserts)
Unit.AssertSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, asserts)

View file

@ -116,7 +116,8 @@ bool net_match_config(const struct ether_addr *match_mac,
char * const *match_names,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel,
Condition *match_kernel_cmdline,
Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
@ -131,7 +132,10 @@ bool net_match_config(const struct ether_addr *match_mac,
if (match_virt && condition_test(match_virt) <= 0)
return false;
if (match_kernel && condition_test(match_kernel) <= 0)
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)

View file

@ -37,7 +37,8 @@ bool net_match_config(const struct ether_addr *match_mac,
char * const *match_name,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel,
Condition *match_kernel_cmdline,
Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,

View file

@ -33,7 +33,8 @@ struct ConfigPerfItem;
%%
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)
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)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)

View file

@ -149,7 +149,8 @@ static void netdev_free(NetDev *netdev) {
condition_free_list(netdev->match_host);
condition_free_list(netdev->match_virt);
condition_free_list(netdev->match_kernel);
condition_free_list(netdev->match_kernel_cmdline);
condition_free_list(netdev->match_kernel_version);
condition_free_list(netdev->match_arch);
if (NETDEV_VTABLE(netdev) &&
@ -642,7 +643,8 @@ static int netdev_load_one(Manager *manager, const char *filename) {
/* 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, netdev_raw->match_arch,
netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
netdev_raw->match_arch,
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;

View file

@ -93,7 +93,8 @@ typedef struct NetDev {
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
NetDevState state;

View file

@ -27,7 +27,8 @@ Match.Type, config_parse_strv,
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)
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)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu)

View file

@ -431,7 +431,8 @@ void network_free(Network *network) {
condition_free_list(network->match_host);
condition_free_list(network->match_virt);
condition_free_list(network->match_kernel);
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);
@ -485,8 +486,8 @@ int network_get(Manager *manager, struct udev_device *device,
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,
network->match_arch,
network->match_virt, network->match_kernel_cmdline,
network->match_kernel_version, network->match_arch,
address, path, parent_driver, driver,
devtype, ifname)) {
if (network->match_name && device) {

View file

@ -112,7 +112,8 @@ struct Network {
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
char *description;

View file

@ -203,67 +203,8 @@ int boot_loader_read_conf(const char *path, BootConfig *config) {
return 0;
}
/* This is a direct translation of str_verscmp from boot.c */
static bool is_digit(int c) {
return c >= '0' && c <= '9';
}
static int c_order(int c) {
if (c == '\0')
return 0;
if (is_digit(c))
return 0;
else if ((c >= 'a') && (c <= 'z'))
return c;
else
return c + 0x10000;
}
static int str_verscmp(const char *s1, const char *s2) {
const char *os1 = s1;
const char *os2 = s2;
while (*s1 || *s2) {
int first;
while ((*s1 && !is_digit(*s1)) || (*s2 && !is_digit(*s2))) {
int order;
order = c_order(*s1) - c_order(*s2);
if (order)
return order;
s1++;
s2++;
}
while (*s1 == '0')
s1++;
while (*s2 == '0')
s2++;
first = 0;
while (is_digit(*s1) && is_digit(*s2)) {
if (first == 0)
first = *s1 - *s2;
s1++;
s2++;
}
if (is_digit(*s1))
return 1;
if (is_digit(*s2))
return -1;
if (first != 0)
return first;
}
return strcmp(os1, os2);
}
static int boot_entry_compare(const void *a, const void *b) {
const BootEntry *aa = a;
const BootEntry *bb = b;
const BootEntry *aa = a, *bb = b;
return str_verscmp(aa->filename, bb->filename);
}

View file

@ -26,6 +26,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
@ -143,6 +144,70 @@ static int condition_test_kernel_command_line(Condition *c) {
return false;
}
static int condition_test_kernel_version(Condition *c) {
enum {
/* Listed in order of checking. Note that some comparators are prefixes of others, hence the longest
* should be listed first. */
LOWER_OR_EQUAL,
GREATER_OR_EQUAL,
LOWER,
GREATER,
EQUAL,
_ORDER_MAX,
};
static const char *const prefix[_ORDER_MAX] = {
[LOWER_OR_EQUAL] = "<=",
[GREATER_OR_EQUAL] = ">=",
[LOWER] = "<",
[GREATER] = ">",
[EQUAL] = "=",
};
const char *p = NULL;
struct utsname u;
size_t i;
int k;
assert(c);
assert(c->parameter);
assert(c->type == CONDITION_KERNEL_VERSION);
assert_se(uname(&u) >= 0);
for (i = 0; i < _ORDER_MAX; i++) {
p = startswith(c->parameter, prefix[i]);
if (p)
break;
}
/* No prefix? Then treat as glob string */
if (!p)
return fnmatch(skip_leading_chars(c->parameter, NULL), u.release, 0) == 0;
k = str_verscmp(u.release, skip_leading_chars(p, NULL));
switch (i) {
case LOWER:
return k < 0;
case LOWER_OR_EQUAL:
return k <= 0;
case EQUAL:
return k == 0;
case GREATER_OR_EQUAL:
return k >= 0;
case GREATER:
return k > 0;
default:
assert_not_reached("Can't compare");
}
}
static int condition_test_user(Condition *c) {
uid_t id;
int r;
@ -552,6 +617,7 @@ int condition_test(Condition *c) {
[CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
[CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
[CONDITION_KERNEL_COMMAND_LINE] = condition_test_kernel_command_line,
[CONDITION_KERNEL_VERSION] = condition_test_kernel_version,
[CONDITION_VIRTUALIZATION] = condition_test_virtualization,
[CONDITION_SECURITY] = condition_test_security,
[CONDITION_CAPABILITY] = condition_test_capability,
@ -612,6 +678,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
[CONDITION_HOST] = "ConditionHost",
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
[CONDITION_KERNEL_VERSION] = "ConditionKernelVersion",
[CONDITION_SECURITY] = "ConditionSecurity",
[CONDITION_CAPABILITY] = "ConditionCapability",
[CONDITION_AC_POWER] = "ConditionACPower",
@ -639,6 +706,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_VIRTUALIZATION] = "AssertVirtualization",
[CONDITION_HOST] = "AssertHost",
[CONDITION_KERNEL_COMMAND_LINE] = "AssertKernelCommandLine",
[CONDITION_KERNEL_VERSION] = "AssertKernelVersion",
[CONDITION_SECURITY] = "AssertSecurity",
[CONDITION_CAPABILITY] = "AssertCapability",
[CONDITION_AC_POWER] = "AssertACPower",

View file

@ -31,6 +31,7 @@ typedef enum ConditionType {
CONDITION_VIRTUALIZATION,
CONDITION_HOST,
CONDITION_KERNEL_COMMAND_LINE,
CONDITION_KERNEL_VERSION,
CONDITION_SECURITY,
CONDITION_CAPABILITY,
CONDITION_AC_POWER,

View file

@ -20,6 +20,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>
#include "sd-id128.h"
@ -38,10 +39,11 @@
#include "selinux-util.h"
#include "set.h"
#include "smack-util.h"
#include "string-util.h"
#include "strv.h"
#include "virt.h"
#include "util.h"
#include "user-util.h"
#include "util.h"
#include "virt.h"
static void test_condition_test_path(void) {
Condition *condition;
@ -298,6 +300,126 @@ static void test_condition_test_kernel_command_line(void) {
condition_free(condition);
}
static void test_condition_test_kernel_version(void) {
Condition *condition;
struct utsname u;
const char *v;
condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
assert_se(uname(&u) >= 0);
condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
strshorten(u.release, 4);
strcpy(strchr(u.release, 0), "*");
condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
/* 0.1.2 would be a very very very old kernel */
condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
/* 4711.8.15 is a very very very future kernel */
condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_VERSION, ">= 4711.8.15", false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
assert_se(uname(&u) >= 0);
v = strjoina(">=", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
v = strjoina("= ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
v = strjoina("<=", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
v = strjoina("> ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
v = strjoina("< ", u.release);
condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
}
static void test_condition_test_null(void) {
Condition *condition;
@ -556,6 +678,7 @@ int main(int argc, char *argv[]) {
test_condition_test_host();
test_condition_test_architecture();
test_condition_test_kernel_command_line();
test_condition_test_kernel_version();
test_condition_test_null();
test_condition_test_security();
test_condition_test_virtualization();

View file

@ -26,7 +26,8 @@ Match.Driver, config_parse_strv, 0,
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)
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)
Link.Description, config_parse_string, 0, offsetof(link_config, description)
Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)

View file

@ -77,7 +77,8 @@ static void link_config_free(link_config *link) {
free(link->match_name);
free(link->match_host);
free(link->match_virt);
free(link->match_kernel);
free(link->match_kernel_cmdline);
free(link->match_kernel_version);
free(link->match_arch);
free(link->description);
@ -248,7 +249,8 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device,
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, link->match_arch,
link->match_virt, link->match_kernel_cmdline,
link->match_kernel_version, link->match_arch,
attr_value ? ether_aton(attr_value) : NULL,
udev_device_get_property_value(device, "ID_PATH"),
udev_device_get_driver(udev_device_get_parent(device)),

View file

@ -58,7 +58,8 @@ struct link_config {
char **match_name;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
char *description;