net: support globbing and disjunction in Match logic

Match{Name,OrginalName,Type,Driver,Path} can now take a space-separated glob of matches.
This commit is contained in:
Tom Gundersen 2015-02-10 18:30:16 +01:00
parent ea6ec096db
commit 5256e00e8b
10 changed files with 143 additions and 60 deletions

View File

@ -103,10 +103,10 @@
<varlistentry> <varlistentry>
<term><varname>OriginalName=</varname></term> <term><varname>OriginalName=</varname></term>
<listitem> <listitem>
<para>The device name, as exposed by the udev property <para>A whitespace-separated list of shell-style globs matching
"INTERFACE". May contain shell style globs. This can not be the device name, as exposed by the udev property
used to match on names that have already been changed from "INTERFACE". This can not be used to match on names that have
userspace. Caution is advised when matching on already been changed from userspace. Caution is advised when matching on
kernel-assigned names, as they are known to be unstable kernel-assigned names, as they are known to be unstable
between reboots.</para> between reboots.</para>
</listitem> </listitem>
@ -114,15 +114,16 @@
<varlistentry> <varlistentry>
<term><varname>Path=</varname></term> <term><varname>Path=</varname></term>
<listitem> <listitem>
<para>The persistent path, as exposed by the <para>A whitespace-separated list of shell-style globs matching
udev property <literal>ID_PATH</literal>. May the persistent path, as exposed by the udev property
contain shell style globs.</para> <literal>ID_PATH</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Driver=</varname></term> <term><varname>Driver=</varname></term>
<listitem> <listitem>
<para>The driver currently bound to the device, <para>A whitespace-separated list of shell-style globs matching
the driver currently bound to the device,
as exposed by the udev property <literal>DRIVER</literal> as exposed by the udev property <literal>DRIVER</literal>
of its parent device, or if that is not set, the of its parent device, or if that is not set, the
driver as exposed by <literal>ethtool -i</literal> driver as exposed by <literal>ethtool -i</literal>
@ -132,7 +133,8 @@
<varlistentry> <varlistentry>
<term><varname>Type=</varname></term> <term><varname>Type=</varname></term>
<listitem> <listitem>
<para>The device type, as exposed by the udev <para>A whitespace-separated list of shell-style globs matching
the device type, as exposed by the udev
property <literal>DEVTYPE</literal>.</para> property <literal>DEVTYPE</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -107,15 +107,16 @@
<varlistentry> <varlistentry>
<term><varname>Path=</varname></term> <term><varname>Path=</varname></term>
<listitem> <listitem>
<para>The persistent path, as exposed by the udev <para>A whitespace-separated list of shell-style globs
property <literal>ID_PATH</literal>. May contain shell matching the persistent path, as exposed by the udev
style globs.</para> property <literal>ID_PATH</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Driver=</varname></term> <term><varname>Driver=</varname></term>
<listitem> <listitem>
<para>The driver currently bound to the device, as <para>A whitespace-separated list of shell-style globs
matching the driver currently bound to the device, as
exposed by the udev property <literal>DRIVER</literal> exposed by the udev property <literal>DRIVER</literal>
of its parent device, or if that is not set the driver of its parent device, or if that is not set the driver
as exposed by <literal>ethtool -i</literal> of the as exposed by <literal>ethtool -i</literal> of the
@ -125,16 +126,17 @@
<varlistentry> <varlistentry>
<term><varname>Type=</varname></term> <term><varname>Type=</varname></term>
<listitem> <listitem>
<para>The device type, as exposed by the udev property <para>A whitespace-separated list of shell-style globs
matching the device type, as exposed by the udev property
<literal>DEVTYPE</literal>.</para> <literal>DEVTYPE</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Name=</varname></term> <term><varname>Name=</varname></term>
<listitem> <listitem>
<para>The device name, as exposed by the udev property <para>A whitespace-separated list of shell-style globs
<literal>INTERFACE</literal>. May contain shell style matching the device name, as exposed by the udev property
globs.</para> <literal>INTERFACE</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -83,10 +83,10 @@ int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8
} }
bool net_match_config(const struct ether_addr *match_mac, bool net_match_config(const struct ether_addr *match_mac,
const char *match_path, char * const *match_paths,
const char *match_driver, char * const *match_drivers,
const char *match_type, char * const *match_types,
const char *match_name, char * const *match_names,
Condition *match_host, Condition *match_host,
Condition *match_virt, Condition *match_virt,
Condition *match_kernel, Condition *match_kernel,
@ -97,6 +97,10 @@ bool net_match_config(const struct ether_addr *match_mac,
const char *dev_driver, const char *dev_driver,
const char *dev_type, const char *dev_type,
const char *dev_name) { const char *dev_name) {
char * const *match_path;
char * const *match_driver;
char * const *match_type;
char * const *match_name;
if (match_host && !condition_test(match_host)) if (match_host && !condition_test(match_host))
return false; return false;
@ -113,22 +117,50 @@ bool net_match_config(const struct ether_addr *match_mac,
if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
return false; return false;
if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0))) if (!strv_isempty(match_paths)) {
return false; if (!dev_path)
return false;
if (match_driver) { STRV_FOREACH(match_path, match_paths)
if (dev_parent_driver && !streq(match_driver, dev_parent_driver)) if (fnmatch(*match_path, dev_path, 0) != 0)
return false; return true;
else if (!streq_ptr(match_driver, dev_driver))
return false; return false;
} }
if (match_type && !streq_ptr(match_type, dev_type)) if (!strv_isempty(match_drivers)) {
return false; if (!dev_driver)
if (match_name && (!dev_name || fnmatch(match_name, dev_name, 0)))
return false; return false;
STRV_FOREACH(match_driver, match_drivers)
if (fnmatch(*match_driver, dev_driver, 0) != 0)
return true;
return false;
}
if (!strv_isempty(match_types)) {
if (!dev_type)
return false;
STRV_FOREACH(match_type, match_types)
if (fnmatch(*match_type, dev_type, 0) != 0)
return true;
return false;
}
if (!strv_isempty(match_names)) {
if (!dev_name)
return false;
STRV_FOREACH(match_name, match_names)
if (fnmatch(*match_name, dev_name, 0) != 0)
return true;
return false;
}
return true; return true;
} }
@ -212,6 +244,49 @@ int config_parse_ifname(const char *unit,
return 0; return 0;
} }
int config_parse_ifnames(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char ***sv = data;
const char *word, *state;
size_t l;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
FOREACH_WORD(word, l, rvalue, state) {
char *n;
n = strndup(word, l);
if (!n)
return log_oom();
if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
r = strv_consume(sv, n);
if (r < 0)
return log_oom();
}
return 0;
}
int config_parse_ifalias(const char *unit, int config_parse_ifalias(const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -29,10 +29,10 @@
#include "condition.h" #include "condition.h"
bool net_match_config(const struct ether_addr *match_mac, bool net_match_config(const struct ether_addr *match_mac,
const char *match_path, char * const *match_path,
const char *match_driver, char * const *match_driver,
const char *match_type, char * const *match_type,
const char *match_name, char * const *match_name,
Condition *match_host, Condition *match_host,
Condition *match_virt, Condition *match_virt,
Condition *match_kernel, Condition *match_kernel,
@ -56,6 +56,10 @@ int config_parse_ifname(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue, const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata); int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ifnames(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ifalias(const char *unit, const char *filename, unsigned line, int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue, const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata); int ltype, const char *rvalue, void *data, void *userdata);

View File

@ -68,10 +68,10 @@ const sd_bus_vtable network_vtable[] = {
SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchPath", "s", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchDriver", "s", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchType", "s", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchName", "s", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_VTABLE_END SD_BUS_VTABLE_END
}; };

View File

@ -16,10 +16,10 @@ struct ConfigPerfItem;
%includes %includes
%% %%
Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac)
Match.Path, config_parse_string, 0, offsetof(Network, match_path) Match.Path, config_parse_strv, 0, offsetof(Network, match_path)
Match.Driver, config_parse_string, 0, offsetof(Network, match_driver) Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver)
Match.Type, config_parse_string, 0, offsetof(Network, match_type) Match.Type, config_parse_strv, 0, offsetof(Network, match_type)
Match.Name, config_parse_ifname, 0, offsetof(Network, match_name) Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) 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.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)

View File

@ -196,10 +196,10 @@ void network_free(Network *network) {
free(network->filename); free(network->filename);
free(network->match_mac); free(network->match_mac);
free(network->match_path); strv_free(network->match_path);
free(network->match_driver); strv_free(network->match_driver);
free(network->match_type); strv_free(network->match_type);
free(network->match_name); strv_free(network->match_name);
free(network->description); free(network->description);
free(network->dhcp_vendor_class_identifier); free(network->dhcp_vendor_class_identifier);

View File

@ -100,10 +100,10 @@ struct Network {
char *name; char *name;
struct ether_addr *match_mac; struct ether_addr *match_mac;
char *match_path; char **match_path;
char *match_driver; char **match_driver;
char *match_type; char **match_type;
char *match_name; char **match_name;
Condition *match_host; Condition *match_host;
Condition *match_virt; Condition *match_virt;

View File

@ -17,10 +17,10 @@ struct ConfigPerfItem;
%includes %includes
%% %%
Match.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, match_mac) Match.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, match_mac)
Match.OriginalName, config_parse_ifname, 0, offsetof(link_config, match_name) Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name)
Match.Path, config_parse_string, 0, offsetof(link_config, match_path) Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
Match.Driver, config_parse_string, 0, offsetof(link_config, match_driver) Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
Match.Type, config_parse_string, 0, offsetof(link_config, match_type) 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.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.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)

View File

@ -52,10 +52,10 @@ struct link_config {
char *filename; char *filename;
struct ether_addr *match_mac; struct ether_addr *match_mac;
char *match_path; char **match_path;
char *match_driver; char **match_driver;
char *match_type; char **match_type;
char *match_name; char **match_name;
Condition *match_host; Condition *match_host;
Condition *match_virt; Condition *match_virt;
Condition *match_kernel; Condition *match_kernel;