diff options
author | Thomas Haller <thaller@redhat.com> | 2020-06-23 08:39:04 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-06-26 13:22:04 +0200 |
commit | e0f481714871d587c215c8b6511474043728f8de (patch) | |
tree | bb23ecb91728976e76bde5bb1d1fe676ce191892 | |
parent | 1641cc1d03941e543da716bc68ff059c5a984f37 (diff) | |
download | NetworkManager-e0f481714871d587c215c8b6511474043728f8de.tar.gz |
core: move matching of kernel command line to separate function
-rw-r--r-- | src/devices/nm-device.c | 86 | ||||
-rw-r--r-- | src/nm-core-utils.c | 85 | ||||
-rw-r--r-- | src/nm-core-utils.h | 5 |
3 files changed, 97 insertions, 79 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 63fa5a5cc9..99b3c5f68c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6353,85 +6353,13 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** return FALSE; } - { - const char *const*proc_cmdline; - gboolean pos_patterns = FALSE; - guint i; - - patterns = nm_setting_match_get_kernel_command_lines (s_match, &num_patterns); - proc_cmdline = nm_utils_proc_cmdline_split (); - - for (i = 0; i < num_patterns; i++) { - const char *patterns_i = patterns[i]; - const char *const*proc_cmdline_i; - gboolean negative = FALSE; - gboolean found = FALSE; - const char *equal; - - if (patterns_i[0] == '!') { - ++patterns_i; - negative = TRUE; - } else - pos_patterns = TRUE; - - equal = strchr (patterns_i, '='); - - proc_cmdline_i = proc_cmdline; - while (*proc_cmdline_i) { - if (equal) { - /* if pattern contains = compare full key=value */ - found = nm_streq (*proc_cmdline_i, patterns_i); - } else { - gsize l = strlen (patterns_i); - - /* otherwise consider pattern as key only */ - if ( strncmp (*proc_cmdline_i, patterns_i, l) == 0 - && NM_IN_SET ((*proc_cmdline_i)[l], '\0', '=')) - found = TRUE; - } - if ( found - && negative) { - /* first negative match */ - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not satisfy match.kernel-command-line property %s", - patterns[i]); - return FALSE; - } - proc_cmdline_i++; - } - - /* FIXME(release-blocker): match.interface-name and match.driver have the meaning, - * that any of the matches may yield success. For match.kernel-command-line, we - * do here that all must match. This inconsistency is undesired. - * - * 1) improve gtk-doc documentation explaining how these options match. - * - * 2) possibly unify the behavior so that kernel-command-line behaves like other - * matches (and ANY may match). Note that this would be contrary to systemd's - * Conditions, which by default requires that ALL conditions match (AND). We - * should be consistent within our match options, and not with systemd here. - * - * 2b) Note that systemd supports special token like "=|", to indicate that - * ANY behavior. If we want, we could also introduce two special prefixes - * "&..." and "|...", to support either. It's slightly complicated how - * these work in combinations with "!". - * Unless we fully decide what we do about this, NMSettingMatch.verify() should - * reject matches that start with '&' or '|', because these will be reserved for - * future use. - * - * 3) while fixing this, this code should move to a separate function so we - * can unit test the match of kernel command lines. - */ - if ( pos_patterns - && !found) { - /* positive patterns configured but no match */ - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not satisfy any match.kernel-command-line property %s...", - patterns[0]); - return FALSE; - } - } - } + patterns = nm_setting_match_get_kernel_command_lines (s_match, &num_patterns); + if ( num_patterns > 0 + && !nm_utils_kernel_cmdline_match_check (nm_utils_proc_cmdline_split (), + patterns, + num_patterns, + error)) + return FALSE; device_driver = nm_device_get_driver (self); patterns = nm_setting_match_get_drivers (s_match, &num_patterns); diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index dc76d1fd9d..8019775a96 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -1731,6 +1731,91 @@ nm_wildcard_match_check (const char *str, /*****************************************************************************/ +gboolean +nm_utils_kernel_cmdline_match_check (const char *const*proc_cmdline, + const char *const*patterns, + guint num_patterns, + GError **error) +{ + gboolean pos_patterns = FALSE; + guint i; + + for (i = 0; i < num_patterns; i++) { + const char *patterns_i = patterns[i]; + const char *const*proc_cmdline_i; + gboolean negative = FALSE; + gboolean found = FALSE; + const char *equal; + + if (patterns_i[0] == '!') { + ++patterns_i; + negative = TRUE; + } else + pos_patterns = TRUE; + + equal = strchr (patterns_i, '='); + + proc_cmdline_i = proc_cmdline; + while (*proc_cmdline_i) { + if (equal) { + /* if pattern contains = compare full key=value */ + found = nm_streq (*proc_cmdline_i, patterns_i); + } else { + gsize l = strlen (patterns_i); + + /* otherwise consider pattern as key only */ + if ( strncmp (*proc_cmdline_i, patterns_i, l) == 0 + && NM_IN_SET ((*proc_cmdline_i)[l], '\0', '=')) + found = TRUE; + } + if ( found + && negative) { + /* first negative match */ + nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not satisfy match.kernel-command-line property %s", + patterns[i]); + return FALSE; + } + proc_cmdline_i++; + } + + /* FIXME(release-blocker): match.interface-name and match.driver have the meaning, + * that any of the matches may yield success. For match.kernel-command-line, we + * do here that all must match. This inconsistency is undesired. + * + * 1) improve gtk-doc documentation explaining how these options match. + * + * 2) possibly unify the behavior so that kernel-command-line behaves like other + * matches (and ANY may match). Note that this would be contrary to systemd's + * Conditions, which by default requires that ALL conditions match (AND). We + * should be consistent within our match options, and not with systemd here. + * + * 2b) Note that systemd supports special token like "=|", to indicate that + * ANY behavior. If we want, we could also introduce two special prefixes + * "&..." and "|...", to support either. It's slightly complicated how + * these work in combinations with "!". + * Unless we fully decide what we do about this, NMSettingMatch.verify() should + * reject matches that start with '&' or '|', because these will be reserved for + * future use. + * + * 3) while fixing this, this code should move to a separate function so we + * can unit test the match of kernel command lines. + */ + if ( pos_patterns + && !found) { + /* positive patterns configured but no match */ + nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "device does not satisfy any match.kernel-command-line property %s...", + patterns[0]); + return FALSE; + } + } + + return TRUE; +} + +/*****************************************************************************/ + char * nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id) { diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index b36c9b581f..1b911894c9 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -230,6 +230,11 @@ gboolean nm_wildcard_match_check (const char *str, const char *const *patterns, guint num_patterns); +gboolean nm_utils_kernel_cmdline_match_check (const char *const*proc_cmdline, + const char *const*patterns, + guint num_patterns, + GError **error); + /*****************************************************************************/ gboolean nm_utils_connection_has_default_route (NMConnection *connection, |