mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-27 19:50:08 +01:00
core: merge branch 'th/device-match-fix'
https://bugzilla.redhat.com/show_bug.cgi?id=1658057
(cherry picked from commit 066c464576)
This commit is contained in:
commit
429c311275
5 changed files with 87 additions and 34 deletions
|
|
@ -2,5 +2,5 @@
|
|||
# But don't do so for dhclient DHCP plugin, as the default of dhclient may
|
||||
# be specified via /etc/dhcp (and anyway defaults to "hardware" already).
|
||||
[connection-00-server-dhcp-client-id]
|
||||
match-device=except:dhcp-plugin:dhclient
|
||||
match-device=*,except:dhcp-plugin:dhclient
|
||||
ipv4.dhcp-client-id=mac
|
||||
|
|
|
|||
|
|
@ -1170,6 +1170,8 @@ enable=env:TAG1
|
|||
be used to negate the match. Note that if one except-predicate
|
||||
matches, the entire configuration will be disabled.
|
||||
In other words, a except predicate always wins over other predicates.
|
||||
If the setting only consists of "except:" matches and none of the
|
||||
negative conditions are satisfied, the configuration is still enabled.
|
||||
<programlisting>
|
||||
# enable the configuration either when the environment variable
|
||||
# is present or the version is at least 1.2.0.
|
||||
|
|
@ -1364,7 +1366,11 @@ enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16
|
|||
<term>except:SPEC</term>
|
||||
<listitem><para>Negative match of a device. <literal>SPEC</literal> must be explicitly qualified with
|
||||
a prefix such as <literal>interface-name:</literal>. A negative match has higher priority then the positive
|
||||
matches above.</para></listitem>
|
||||
matches above.</para>
|
||||
<para>If there is a list consisting only of negative matches, the behavior is the same as if there
|
||||
is also match-all. That means, if none of all the negative matches is satisfied, the overall result is
|
||||
still a positive match. That means, <literal>"except:interface-name:eth0"</literal> is the same as
|
||||
<literal>"*,except:interface-name:eth0"</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>SPEC[,;]SPEC</term>
|
||||
|
|
|
|||
|
|
@ -15778,8 +15778,8 @@ nm_device_spec_match_list_full (NMDevice *self, const GSList *specs, int no_matc
|
|||
nm_device_get_driver (self),
|
||||
nm_device_get_driver_version (self),
|
||||
nm_device_get_permanent_hw_address (self),
|
||||
nm_dhcp_manager_get_config (nm_dhcp_manager_get ()),
|
||||
klass->get_s390_subchannels ? klass->get_s390_subchannels (self) : NULL);
|
||||
klass->get_s390_subchannels ? klass->get_s390_subchannels (self) : NULL,
|
||||
nm_dhcp_manager_get_config (nm_dhcp_manager_get ()));
|
||||
|
||||
switch (m) {
|
||||
case NM_MATCH_SPEC_MATCH:
|
||||
|
|
|
|||
|
|
@ -1295,6 +1295,34 @@ match_device_hwaddr_eval (const char *spec_str,
|
|||
_has; \
|
||||
})
|
||||
|
||||
static NMMatchSpecMatchType
|
||||
_match_result (gboolean has_except,
|
||||
gboolean has_not_except,
|
||||
gboolean has_match,
|
||||
gboolean has_match_except)
|
||||
{
|
||||
if ( has_except
|
||||
&& !has_not_except) {
|
||||
/* a match spec that only consists of a list of except matches is treated specially. */
|
||||
nm_assert (!has_match);
|
||||
if (has_match_except) {
|
||||
/* one of the "except:" matches matched. The result is an explicit
|
||||
* negative match. */
|
||||
return NM_MATCH_SPEC_NEG_MATCH;
|
||||
} else {
|
||||
/* none of the "except:" matches matched. The result is a positive match,
|
||||
* despite there being no positive match. */
|
||||
return NM_MATCH_SPEC_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_match_except)
|
||||
return NM_MATCH_SPEC_NEG_MATCH;
|
||||
if (has_match)
|
||||
return NM_MATCH_SPEC_MATCH;
|
||||
return NM_MATCH_SPEC_NO_MATCH;
|
||||
}
|
||||
|
||||
static const char *
|
||||
match_except (const char *spec_str, gboolean *out_except)
|
||||
{
|
||||
|
|
@ -1401,9 +1429,11 @@ nm_match_spec_device (const GSList *specs,
|
|||
const char *dhcp_plugin)
|
||||
{
|
||||
const GSList *iter;
|
||||
NMMatchSpecMatchType match;
|
||||
gboolean has_match = FALSE;
|
||||
gboolean has_match_except = FALSE;
|
||||
gboolean has_except = FALSE;
|
||||
gboolean has_not_except = FALSE;
|
||||
const char *spec_str;
|
||||
gboolean except;
|
||||
MatchDeviceData match_data = {
|
||||
.interface_name = interface_name,
|
||||
.device_type = nm_str_not_empty (device_type),
|
||||
|
|
@ -1423,19 +1453,9 @@ nm_match_spec_device (const GSList *specs,
|
|||
if (!specs)
|
||||
return NM_MATCH_SPEC_NO_MATCH;
|
||||
|
||||
match = NM_MATCH_SPEC_NO_MATCH;
|
||||
|
||||
/* pre-search for "*" */
|
||||
for (iter = specs; iter; iter = iter->next) {
|
||||
spec_str = iter->data;
|
||||
gboolean except;
|
||||
|
||||
if (spec_str && spec_str[0] == '*' && spec_str[1] == '\0') {
|
||||
match = NM_MATCH_SPEC_MATCH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (iter = specs; iter; iter = iter->next) {
|
||||
spec_str = iter->data;
|
||||
|
||||
if (!spec_str || !*spec_str)
|
||||
|
|
@ -1443,10 +1463,14 @@ nm_match_spec_device (const GSList *specs,
|
|||
|
||||
spec_str = match_except (spec_str, &except);
|
||||
|
||||
if ( !except
|
||||
&& match == NM_MATCH_SPEC_MATCH) {
|
||||
/* we have no "except-match" but already match. No need to evaluate
|
||||
* the match, we cannot match stronger. */
|
||||
if (except)
|
||||
has_except = TRUE;
|
||||
else
|
||||
has_not_except = TRUE;
|
||||
|
||||
if ( ( except && has_match_except)
|
||||
|| (!except && has_match)) {
|
||||
/* evaluating the match does not give new information. Skip it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1456,11 +1480,12 @@ nm_match_spec_device (const GSList *specs,
|
|||
continue;
|
||||
|
||||
if (except)
|
||||
return NM_MATCH_SPEC_NEG_MATCH;
|
||||
match = NM_MATCH_SPEC_MATCH;
|
||||
has_match_except = TRUE;
|
||||
else
|
||||
has_match = TRUE;
|
||||
}
|
||||
|
||||
return match;
|
||||
return _match_result (has_except, has_not_except, has_match, has_match_except);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -1530,7 +1555,10 @@ NMMatchSpecMatchType
|
|||
nm_match_spec_config (const GSList *specs, guint cur_nm_version, const char *env)
|
||||
{
|
||||
const GSList *iter;
|
||||
NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH;
|
||||
gboolean has_match = FALSE;
|
||||
gboolean has_match_except = FALSE;
|
||||
gboolean has_except = FALSE;
|
||||
gboolean has_not_except = FALSE;
|
||||
|
||||
if (!specs)
|
||||
return NM_MATCH_SPEC_NO_MATCH;
|
||||
|
|
@ -1545,6 +1573,17 @@ nm_match_spec_config (const GSList *specs, guint cur_nm_version, const char *env
|
|||
|
||||
spec_str = match_except (spec_str, &except);
|
||||
|
||||
if (except)
|
||||
has_except = TRUE;
|
||||
else
|
||||
has_not_except = TRUE;
|
||||
|
||||
if ( ( except && has_match_except)
|
||||
|| (!except && has_match)) {
|
||||
/* evaluating the match does not give new information. Skip it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_MATCH_CHECK (spec_str, MATCH_TAG_CONFIG_NM_VERSION))
|
||||
v_match = match_config_eval (spec_str, MATCH_TAG_CONFIG_NM_VERSION, cur_nm_version);
|
||||
else if (_MATCH_CHECK (spec_str, MATCH_TAG_CONFIG_NM_VERSION_MIN))
|
||||
|
|
@ -1554,15 +1593,18 @@ nm_match_spec_config (const GSList *specs, guint cur_nm_version, const char *env
|
|||
else if (_MATCH_CHECK (spec_str, MATCH_TAG_CONFIG_ENV))
|
||||
v_match = env && env[0] && !strcmp (spec_str, env);
|
||||
else
|
||||
v_match = FALSE;
|
||||
|
||||
if (!v_match)
|
||||
continue;
|
||||
|
||||
if (v_match) {
|
||||
if (except)
|
||||
return NM_MATCH_SPEC_NEG_MATCH;
|
||||
match = NM_MATCH_SPEC_MATCH;
|
||||
}
|
||||
if (except)
|
||||
has_match_except = TRUE;
|
||||
else
|
||||
has_match = TRUE;
|
||||
}
|
||||
return match;
|
||||
|
||||
return _match_result (has_except, has_not_except, has_match, has_match_except);
|
||||
}
|
||||
|
||||
#undef _MATCH_CHECK
|
||||
|
|
|
|||
|
|
@ -1233,6 +1233,10 @@ test_match_spec_device (void)
|
|||
S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
|
||||
NULL,
|
||||
S ("em*"));
|
||||
_do_test_match_spec_device ("except:interface-name:em*",
|
||||
S ("", "eth", "eth1", "e1"),
|
||||
S (NULL),
|
||||
S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"));
|
||||
_do_test_match_spec_device ("aa,bb,cc\\,dd,e,,",
|
||||
S ("aa", "bb", "cc,dd", "e"),
|
||||
NULL,
|
||||
|
|
@ -1305,7 +1309,8 @@ _do_test_match_spec_config (const char *file, int line, const char *spec_str, gu
|
|||
if (expected != match_result)
|
||||
g_error ("%s:%d: faild comparing \"%s\" with %u.%u.%u. Expected %d, but got %d", file, line, spec_str, v_maj, v_min, v_mic, (int) expected, (int) match_result);
|
||||
|
||||
if (g_slist_length (specs) == 1 && match_result != NM_MATCH_SPEC_NEG_MATCH) {
|
||||
if ( g_slist_length (specs) == 1
|
||||
&& !g_str_has_prefix (specs->data, "except:")) {
|
||||
/* there is only one spec in the list... test that we match except: */
|
||||
char *sss = g_strdup_printf ("except:%s", (char *) specs->data);
|
||||
GSList *specs2 = g_slist_append (NULL, sss);
|
||||
|
|
@ -1313,7 +1318,7 @@ _do_test_match_spec_config (const char *file, int line, const char *spec_str, gu
|
|||
|
||||
match_result2 = nm_match_spec_config (specs2, version, NULL);
|
||||
if (match_result == NM_MATCH_SPEC_NO_MATCH)
|
||||
g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NO_MATCH);
|
||||
g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_MATCH);
|
||||
else
|
||||
g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NEG_MATCH);
|
||||
|
||||
|
|
@ -1397,7 +1402,7 @@ test_match_spec_config (void)
|
|||
do_test_match_spec_config ("nm-version-max:1", 1, 4, 30, NM_MATCH_SPEC_MATCH);
|
||||
do_test_match_spec_config ("nm-version-max:1", 2, 4, 30, NM_MATCH_SPEC_NO_MATCH);
|
||||
|
||||
do_test_match_spec_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_NO_MATCH);
|
||||
do_test_match_spec_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH);
|
||||
do_test_match_spec_config ("nm-version-min:1.6,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH);
|
||||
|
||||
do_test_match_spec_config ("nm-version-min:1.6,nm-version-min:1.4.6,nm-version-min:1.2.16,except:nm-version:1.4.8", 1, 2, 0, NM_MATCH_SPEC_NO_MATCH);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue