mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
parent
b38de0e9cc
commit
44005bfb4e
@ -115,6 +115,21 @@
|
|||||||
property <varname>DEVTYPE</varname>.</para>
|
property <varname>DEVTYPE</varname>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>Property=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A whitespace-separated list of udev property name with its value after a equal
|
||||||
|
(<literal>=</literal>). If multiple properties are specified, the test results are ANDed.
|
||||||
|
If the list is prefixed with a "!", the test is inverted. If a value contains white
|
||||||
|
spaces, then please quote whole key and value pair. If a value contains quotation, then
|
||||||
|
please escape the quotation with <literal>\</literal>.</para>
|
||||||
|
|
||||||
|
<para>Example: if a .link file has the following:
|
||||||
|
<programlisting>Property=ID_MODEL_ID=9999 "ID_VENDOR_FROM_DATABASE=vendor name" "KEY=with \"quotation\""</programlisting>
|
||||||
|
then, the .link file matches only when an interface has all the above three properties.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Host=</varname></term>
|
<term><varname>Host=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -138,6 +138,21 @@
|
|||||||
with a "!", the test is inverted.</para>
|
with a "!", the test is inverted.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>Property=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A whitespace-separated list of udev property name with its value after a equal
|
||||||
|
(<literal>=</literal>). If multiple properties are specified, the test results are ANDed.
|
||||||
|
If the list is prefixed with a "!", the test is inverted. If a value contains white
|
||||||
|
spaces, then please quote whole key and value pair. If a value contains quotation, then
|
||||||
|
please escape the quotation with <literal>\</literal>.</para>
|
||||||
|
|
||||||
|
<para>Example: if a .network file has the following:
|
||||||
|
<programlisting>Property=ID_MODEL_ID=9999 "ID_VENDOR_FROM_DATABASE=vendor name" "KEY=with \"quotation\""</programlisting>
|
||||||
|
then, the .network file matches only when an interface has all the above three properties.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Host=</varname></term>
|
<term><varname>Host=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
#include "dhcp-lease-internal.h"
|
#include "dhcp-lease-internal.h"
|
||||||
|
#include "env-util.h"
|
||||||
#include "ether-addr-util.h"
|
#include "ether-addr-util.h"
|
||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -101,11 +102,46 @@ static bool net_condition_test_strv(char * const *patterns, const char *string)
|
|||||||
return has_positive_rule ? match : true;
|
return has_positive_rule ? match : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int net_condition_test_property(char * const *match_property, sd_device *device) {
|
||||||
|
char * const *p;
|
||||||
|
|
||||||
|
if (strv_isempty(match_property))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
STRV_FOREACH(p, match_property) {
|
||||||
|
_cleanup_free_ char *key = NULL;
|
||||||
|
const char *val, *dev_val;
|
||||||
|
bool invert, v;
|
||||||
|
|
||||||
|
invert = **p == '!';
|
||||||
|
|
||||||
|
val = strchr(*p + invert, '=');
|
||||||
|
if (!val)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
key = strndup(*p + invert, val - *p - invert);
|
||||||
|
if (!key)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
val++;
|
||||||
|
|
||||||
|
v = device &&
|
||||||
|
sd_device_get_property_value(device, key, &dev_val) >= 0 &&
|
||||||
|
fnmatch(val, dev_val, 0) == 0;
|
||||||
|
|
||||||
|
if (invert ? v : !v)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool net_match_config(Set *match_mac,
|
bool net_match_config(Set *match_mac,
|
||||||
char * const *match_paths,
|
char * const *match_paths,
|
||||||
char * const *match_drivers,
|
char * const *match_drivers,
|
||||||
char * const *match_types,
|
char * const *match_types,
|
||||||
char * const *match_names,
|
char * const *match_names,
|
||||||
|
char * const *match_property,
|
||||||
sd_device *device,
|
sd_device *device,
|
||||||
const struct ether_addr *dev_mac,
|
const struct ether_addr *dev_mac,
|
||||||
const char *dev_name) {
|
const char *dev_name) {
|
||||||
@ -139,6 +175,9 @@ bool net_match_config(Set *match_mac,
|
|||||||
if (!net_condition_test_strv(match_names, dev_name))
|
if (!net_condition_test_strv(match_names, dev_name))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!net_condition_test_property(match_property, device))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +335,64 @@ int config_parse_match_ifnames(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_match_property(
|
||||||
|
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) {
|
||||||
|
|
||||||
|
const char *p = rvalue;
|
||||||
|
char ***sv = data;
|
||||||
|
bool invert;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
invert = *p == '!';
|
||||||
|
p += invert;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *word = NULL, *k = NULL;
|
||||||
|
|
||||||
|
r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!env_assignment_is_valid(word)) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Invalid property or value, ignoring assignment: %s", word);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invert) {
|
||||||
|
k = strjoin("!", word);
|
||||||
|
if (!k)
|
||||||
|
return log_oom();
|
||||||
|
} else
|
||||||
|
k = TAKE_PTR(word);
|
||||||
|
|
||||||
|
r = strv_consume(sv, TAKE_PTR(k));
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_ifalias(const char *unit,
|
int config_parse_ifalias(const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
|
@ -19,6 +19,7 @@ bool net_match_config(Set *match_mac,
|
|||||||
char * const *match_driver,
|
char * const *match_driver,
|
||||||
char * const *match_type,
|
char * const *match_type,
|
||||||
char * const *match_name,
|
char * const *match_name,
|
||||||
|
char * const *match_property,
|
||||||
sd_device *device,
|
sd_device *device,
|
||||||
const struct ether_addr *dev_mac,
|
const struct ether_addr *dev_mac,
|
||||||
const char *dev_name);
|
const char *dev_name);
|
||||||
@ -28,6 +29,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
|
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
|
CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
|
CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ Match.Path, config_parse_match_strv,
|
|||||||
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
|
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
|
||||||
Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
|
Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
|
||||||
Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
|
Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
|
||||||
|
Match.Property, config_parse_match_property, 0, offsetof(Network, match_property)
|
||||||
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
|
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
|
||||||
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, 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.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, conditions)
|
||||||
|
@ -157,7 +157,8 @@ int network_verify(Network *network) {
|
|||||||
|
|
||||||
if (set_isempty(network->match_mac) && strv_isempty(network->match_path) &&
|
if (set_isempty(network->match_mac) && strv_isempty(network->match_path) &&
|
||||||
strv_isempty(network->match_driver) && strv_isempty(network->match_type) &&
|
strv_isempty(network->match_driver) && strv_isempty(network->match_type) &&
|
||||||
strv_isempty(network->match_name) && !network->conditions)
|
strv_isempty(network->match_name) && strv_isempty(network->match_property) &&
|
||||||
|
!network->conditions)
|
||||||
log_warning("%s: No valid settings found in the [Match] section. "
|
log_warning("%s: No valid settings found in the [Match] section. "
|
||||||
"The file will match all interfaces. "
|
"The file will match all interfaces. "
|
||||||
"If that is intended, please add Name=* in the [Match] section.",
|
"If that is intended, please add Name=* in the [Match] section.",
|
||||||
@ -507,6 +508,7 @@ static Network *network_free(Network *network) {
|
|||||||
strv_free(network->match_driver);
|
strv_free(network->match_driver);
|
||||||
strv_free(network->match_type);
|
strv_free(network->match_type);
|
||||||
strv_free(network->match_name);
|
strv_free(network->match_name);
|
||||||
|
strv_free(network->match_property);
|
||||||
condition_free_list(network->conditions);
|
condition_free_list(network->conditions);
|
||||||
|
|
||||||
free(network->description);
|
free(network->description);
|
||||||
@ -614,9 +616,8 @@ int network_get(Manager *manager, sd_device *device,
|
|||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
|
ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
|
||||||
if (net_match_config(network->match_mac, network->match_path,
|
if (net_match_config(network->match_mac, network->match_path, network->match_driver,
|
||||||
network->match_driver, network->match_type,
|
network->match_type, network->match_name, network->match_property,
|
||||||
network->match_name,
|
|
||||||
device, address, ifname)) {
|
device, address, ifname)) {
|
||||||
if (network->match_name && device) {
|
if (network->match_name && device) {
|
||||||
const char *attr;
|
const char *attr;
|
||||||
|
@ -104,6 +104,7 @@ struct Network {
|
|||||||
char **match_driver;
|
char **match_driver;
|
||||||
char **match_type;
|
char **match_type;
|
||||||
char **match_name;
|
char **match_name;
|
||||||
|
char **match_property;
|
||||||
LIST_HEAD(Condition, conditions);
|
LIST_HEAD(Condition, conditions);
|
||||||
|
|
||||||
char *description;
|
char *description;
|
||||||
|
@ -24,6 +24,7 @@ Match.OriginalName, config_parse_match_ifnames, 0,
|
|||||||
Match.Path, config_parse_match_strv, 0, offsetof(link_config, match_path)
|
Match.Path, config_parse_match_strv, 0, offsetof(link_config, match_path)
|
||||||
Match.Driver, config_parse_match_strv, 0, offsetof(link_config, match_driver)
|
Match.Driver, config_parse_match_strv, 0, offsetof(link_config, match_driver)
|
||||||
Match.Type, config_parse_match_strv, 0, offsetof(link_config, match_type)
|
Match.Type, config_parse_match_strv, 0, offsetof(link_config, match_type)
|
||||||
|
Match.Property, config_parse_match_property, 0, offsetof(link_config, match_property)
|
||||||
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions)
|
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.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.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions)
|
||||||
|
@ -51,6 +51,7 @@ static void link_config_free(link_config *link) {
|
|||||||
strv_free(link->match_driver);
|
strv_free(link->match_driver);
|
||||||
strv_free(link->match_type);
|
strv_free(link->match_type);
|
||||||
strv_free(link->match_name);
|
strv_free(link->match_name);
|
||||||
|
strv_free(link->match_property);
|
||||||
condition_free_list(link->conditions);
|
condition_free_list(link->conditions);
|
||||||
|
|
||||||
free(link->description);
|
free(link->description);
|
||||||
@ -161,7 +162,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
|
|||||||
|
|
||||||
if (set_isempty(link->match_mac) && strv_isempty(link->match_path) &&
|
if (set_isempty(link->match_mac) && strv_isempty(link->match_path) &&
|
||||||
strv_isempty(link->match_driver) && strv_isempty(link->match_type) &&
|
strv_isempty(link->match_driver) && strv_isempty(link->match_type) &&
|
||||||
strv_isempty(link->match_name) && !link->conditions)
|
strv_isempty(link->match_name) && strv_isempty(link->match_property) && !link->conditions)
|
||||||
log_warning("%s: No valid settings found in the [Match] section. "
|
log_warning("%s: No valid settings found in the [Match] section. "
|
||||||
"The file will match all interfaces. "
|
"The file will match all interfaces. "
|
||||||
"If that is intended, please add OriginalName=* in the [Match] section.",
|
"If that is intended, please add OriginalName=* in the [Match] section.",
|
||||||
@ -241,7 +242,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
|
|||||||
|
|
||||||
LIST_FOREACH(links, link, ctx->links) {
|
LIST_FOREACH(links, link, ctx->links) {
|
||||||
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
|
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
|
||||||
link->match_type, link->match_name,
|
link->match_type, link->match_name, link->match_property,
|
||||||
device, NULL, NULL)) {
|
device, NULL, NULL)) {
|
||||||
if (link->match_name) {
|
if (link->match_name) {
|
||||||
unsigned name_assign_type = NET_NAME_UNKNOWN;
|
unsigned name_assign_type = NET_NAME_UNKNOWN;
|
||||||
|
@ -40,6 +40,7 @@ struct link_config {
|
|||||||
char **match_driver;
|
char **match_driver;
|
||||||
char **match_type;
|
char **match_type;
|
||||||
char **match_name;
|
char **match_name;
|
||||||
|
char **match_property;
|
||||||
LIST_HEAD(Condition, conditions);
|
LIST_HEAD(Condition, conditions);
|
||||||
|
|
||||||
char *description;
|
char *description;
|
||||||
|
@ -4,6 +4,7 @@ OriginalName=
|
|||||||
Path=
|
Path=
|
||||||
Driver=
|
Driver=
|
||||||
Type=
|
Type=
|
||||||
|
Property=
|
||||||
Host=
|
Host=
|
||||||
Virtualization=
|
Virtualization=
|
||||||
KernelCommandLine=
|
KernelCommandLine=
|
||||||
|
@ -20,6 +20,7 @@ Driver=
|
|||||||
Architecture=
|
Architecture=
|
||||||
Path=
|
Path=
|
||||||
Name=
|
Name=
|
||||||
|
Property=
|
||||||
Virtualization=
|
Virtualization=
|
||||||
KernelCommandLine=
|
KernelCommandLine=
|
||||||
Host=
|
Host=
|
||||||
|
Loading…
Reference in New Issue
Block a user