summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-06-23 08:39:04 +0200
committerThomas Haller <thaller@redhat.com>2020-06-26 13:22:04 +0200
commite0f481714871d587c215c8b6511474043728f8de (patch)
treebb23ecb91728976e76bde5bb1d1fe676ce191892
parent1641cc1d03941e543da716bc68ff059c5a984f37 (diff)
downloadNetworkManager-e0f481714871d587c215c8b6511474043728f8de.tar.gz
core: move matching of kernel command line to separate function
-rw-r--r--src/devices/nm-device.c86
-rw-r--r--src/nm-core-utils.c85
-rw-r--r--src/nm-core-utils.h5
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,