mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-10 01:17:44 +03:00
network,udev: fix multiple invert matching lines
Previously, ``` [Match] Name=!aaa Name=!bbb ``` does not work. This fixes the issue.
This commit is contained in:
parent
64e7ebde8b
commit
54a8423788
@ -73,26 +73,32 @@ int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool net_condition_test_strv(char * const *raw_patterns,
|
||||
const char *string) {
|
||||
if (strv_isempty(raw_patterns))
|
||||
static bool net_condition_test_strv(char * const *patterns, const char *string) {
|
||||
char * const *p;
|
||||
bool match = false, has_positive_rule = false;
|
||||
|
||||
if (strv_isempty(patterns))
|
||||
return true;
|
||||
|
||||
/* If the patterns begin with "!", edit it out and negate the test. */
|
||||
if (raw_patterns[0][0] == '!') {
|
||||
char **patterns;
|
||||
size_t i, length;
|
||||
STRV_FOREACH(p, patterns) {
|
||||
const char *q = *p;
|
||||
bool invert;
|
||||
|
||||
length = strv_length(raw_patterns) + 1; /* Include the NULL. */
|
||||
patterns = newa(char*, length);
|
||||
patterns[0] = raw_patterns[0] + 1; /* Skip the "!". */
|
||||
for (i = 1; i < length; i++)
|
||||
patterns[i] = raw_patterns[i];
|
||||
invert = *q == '!';
|
||||
q += invert;
|
||||
|
||||
return !string || !strv_fnmatch(patterns, string, 0);
|
||||
if (!invert)
|
||||
has_positive_rule = true;
|
||||
|
||||
if (string && fnmatch(q, string, 0) == 0) {
|
||||
if (invert)
|
||||
return false;
|
||||
else
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
return string && strv_fnmatch(raw_patterns, string, 0);
|
||||
return has_positive_rule ? match : true;
|
||||
}
|
||||
|
||||
bool net_match_config(Set *match_mac,
|
||||
@ -164,7 +170,7 @@ int config_parse_net_condition(const char *unit,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_ifnames(
|
||||
int config_parse_match_strv(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@ -176,7 +182,9 @@ int config_parse_ifnames(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
const char *p = rvalue;
|
||||
char ***sv = data;
|
||||
bool invert;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -184,30 +192,96 @@ int config_parse_ifnames(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&rvalue, &word, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse interface name list: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (!ifname_valid(word)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = strv_push(sv, word);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
word = NULL;
|
||||
if (isempty(rvalue)) {
|
||||
*sv = strv_free(*sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
invert = *p == '!';
|
||||
p += invert;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL, *k = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_match_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) {
|
||||
|
||||
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, 0);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Failed to parse interface name list: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ifname_valid(word)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||
"Interface name is not valid or too long, 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,
|
||||
|
@ -28,7 +28,8 @@ bool net_match_config(Set *match_mac,
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
||||
|
||||
|
@ -22,10 +22,10 @@ struct ConfigPerfItem;
|
||||
%includes
|
||||
%%
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(Network, match_mac)
|
||||
Match.Path, config_parse_strv, 0, offsetof(Network, match_path)
|
||||
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.Path, config_parse_match_strv, 0, offsetof(Network, match_path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
|
||||
Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
|
||||
Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
|
||||
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)
|
||||
|
@ -174,7 +174,7 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign
|
||||
assert_se(network = new0(Network, 1));
|
||||
network->n_ref = 1;
|
||||
assert_se(network->filename = strdup("hogehoge.network"));
|
||||
assert_se(config_parse_ifnames("network", "filename", 1, "section", 1, "Name", 0, "*", &network->match_name, network) == 0);
|
||||
assert_se(config_parse_match_ifnames("network", "filename", 1, "section", 1, "Name", 0, "*", &network->match_name, network) == 0);
|
||||
assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0);
|
||||
assert_se(network->n_static_addresses == 1);
|
||||
assert_se(network_verify(network) >= 0);
|
||||
|
@ -20,10 +20,10 @@ struct ConfigPerfItem;
|
||||
%includes
|
||||
%%
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac)
|
||||
Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name)
|
||||
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.OriginalName, config_parse_match_ifnames, 0, offsetof(link_config, match_name)
|
||||
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.Type, config_parse_match_strv, 0, offsetof(link_config, match_type)
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user