diff options
-rw-r--r-- | include/nm-macros-internal.h | 15 | ||||
-rw-r--r-- | man/NetworkManager.conf.xml.in | 89 | ||||
-rw-r--r-- | src/NetworkManagerUtils.c | 118 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 1 | ||||
-rw-r--r-- | src/nm-config.c | 66 | ||||
-rw-r--r-- | src/nm-config.h | 6 | ||||
-rw-r--r-- | src/tests/config/Makefile.am | 1 | ||||
-rw-r--r-- | src/tests/config/conf.d/20-config-enable-1.conf | 5 | ||||
-rw-r--r-- | src/tests/config/test-config.c | 36 | ||||
-rw-r--r-- | src/tests/test-general.c | 143 |
10 files changed, 474 insertions, 6 deletions
diff --git a/include/nm-macros-internal.h b/include/nm-macros-internal.h index b1d75e68ed..0bf25821ad 100644 --- a/include/nm-macros-internal.h +++ b/include/nm-macros-internal.h @@ -286,4 +286,19 @@ nm_strstrip (char *str) /*****************************************************************************/ +static inline guint +nm_encode_version (guint major, guint minor, guint micro) { + /* analog to the preprocessor macro NM_ENCODE_VERSION(). */ + return (major << 16) | (minor << 8) | micro; +} + +static inline void +nm_decode_version (guint version, guint *major, guint *minor, guint *micro) { + *major = (version & 0xFFFF0000u) >> 16; + *minor = (version & 0x0000FF00u) >> 8; + *micro = (version & 0x000000FFu); +} + +/*****************************************************************************/ + #endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in index a8b7f3a38d..0fccc84dc6 100644 --- a/man/NetworkManager.conf.xml.in +++ b/man/NetworkManager.conf.xml.in @@ -703,6 +703,95 @@ ipv6.ip6-privacy=1 </refsect1> <refsect1> + <title><literal>.config</literal> sections</title> + <para>This is a special section that contains options which apply + to the configuration file that contains the option. + </para> + <para> + <variablelist> + <varlistentry> + <term><varname>enable</varname></term> + <listitem> + <para> + Defaults to "<literal>true</literal>". If "<literal>false</literal>", + the configuration file will be skipped during loading. + Note that the main configation file <literal>NetworkManger.conf</literal> + cannot be disabled. +<programlisting> +# always skip loading the config file +[.config] +enable=false +</programlisting> + </para> + <para> + You can also match against the version of NetworkManager. For example + the following are valid configurations: +<programlisting> +# only load on version 1.0.6 +[.config] +enable=nm-version:1.0.6 + +# load on all versions 1.0.x, but not 1.2.x +[.config] +enable=nm-version:1.0 + +# only load on versions >= 1.1.6. This does not match +# with version 1.2.0 or 1.4.4. Only the last digit is considered. +[.config] +enable=nm-version-min:1.1.6 + +# only load on versions >= 1.2. Contrary to the previous +# example, this also matches with 1.2.0, 1.2.10, 1.4.4, etc. +[.config] +enable=nm-version-min:1.2 + +# Match against the maximum allowed version. The example matches +# versions 1.2.0, 1.2.2, 1.2.4. Again, only the last version digit +# is allowed to be smaller. So this would not match match on 1.1.10. +[.config] +enable=nm-version-max:1.2.6 +</programlisting> + </para> + <para> + You can also match against the value of the environment variable + <literal>NM_CONFIG_ENABLE_TAG</literal>, like: +<programlisting> +# always skip loading the file when running NetworkManager with +# environment variable "NM_CONFIG_ENABLE_TAG=TAG1" +[.config] +enable=env:TAG1 +</programlisting> + </para> + <para> + More then one match can be specified. The configuration will be + enabled if one of the predicates matches ("or"). The special prefix "except:" can + 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. +<programlisting> +# enable the configuration either when the environment variable +# is present or the version is at least 1.2.0. +[.config] +enable=env:TAG2,nm-version-min:1.2 + +# enable the configuration for version >= 1.2.0, but disable +# it when the environment variable is set to "TAG3" +[.config] +enable=except:env:TAG3,nm-version-min:1.2 + +# enable the configuration on >= 1.3, >= 1.2.6, and >= 1.0.16. +# Useful if a certain feature is only present since those releases. +[.config] +enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16 +</programlisting> + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </refsect1> + + <refsect1> <title>Plugins</title> <variablelist> diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 5d9df4ec8c..726ceb9b4a 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1193,6 +1193,22 @@ nm_utils_find_helper(const char *progname, const char *try_first, GError **error #define DEVICE_TYPE_TAG "type:" #define SUBCHAN_TAG "s390-subchannels:" #define EXCEPT_TAG "except:" +#define MATCH_TAG_CONFIG_NM_VERSION "nm-version:" +#define MATCH_TAG_CONFIG_NM_VERSION_MIN "nm-version-min:" +#define MATCH_TAG_CONFIG_NM_VERSION_MAX "nm-version-max:" +#define MATCH_TAG_CONFIG_ENV "env:" + +#define _spec_has_prefix(pspec, tag) \ + ({ \ + const char **_spec = (pspec); \ + gboolean _has = FALSE; \ + \ + if (!g_ascii_strncasecmp (*_spec, (""tag), STRLEN (tag))) { \ + *_spec += STRLEN (tag); \ + _has = TRUE; \ + } \ + _has; \ + }) static const char * _match_except (const char *spec_str, gboolean *out_except) @@ -1422,6 +1438,108 @@ nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels) return match; } +static gboolean +_match_config_nm_version (const char *str, const char *tag, guint cur_nm_version) +{ + gs_free char *s_ver = NULL; + gs_strfreev char **s_ver_tokens = NULL; + gint v_maj = -1, v_min = -1, v_mic = -1; + guint c_maj = -1, c_min = -1, c_mic = -1; + guint n_tokens; + + s_ver = g_strdup (str); + g_strstrip (s_ver); + + /* Let's be strict with the accepted format here. No funny stuff!! */ + + if (s_ver[strspn (s_ver, ".0123456789")] != '\0') + return FALSE; + + s_ver_tokens = g_strsplit (s_ver, ".", -1); + n_tokens = g_strv_length (s_ver_tokens); + if (n_tokens == 0 || n_tokens > 3) + return FALSE; + + v_maj = _nm_utils_ascii_str_to_int64 (s_ver_tokens[0], 10, 0, 0xFFFF, -1); + if (v_maj < 0) + return FALSE; + if (n_tokens >= 2) { + v_min = _nm_utils_ascii_str_to_int64 (s_ver_tokens[1], 10, 0, 0xFF, -1); + if (v_min < 0) + return FALSE; + } + if (n_tokens >= 3) { + v_mic = _nm_utils_ascii_str_to_int64 (s_ver_tokens[2], 10, 0, 0xFF, -1); + if (v_mic < 0) + return FALSE; + } + + nm_decode_version (cur_nm_version, &c_maj, &c_min, &c_mic); + +#define CHECK_AND_RETURN_FALSE(cur, val, tag, is_last_digit) \ + G_STMT_START { \ + if (!strcmp (tag, MATCH_TAG_CONFIG_NM_VERSION_MIN)) { \ + if (cur < val) \ + return FALSE; \ + } else if (!strcmp (tag, MATCH_TAG_CONFIG_NM_VERSION_MAX)) { \ + if (cur > val) \ + return FALSE; \ + } else { \ + if (cur != val) \ + return FALSE; \ + } \ + if (!(is_last_digit)) { \ + if (cur != val) \ + return FALSE; \ + } \ + } G_STMT_END + if (v_mic >= 0) + CHECK_AND_RETURN_FALSE (c_mic, v_mic, tag, TRUE); + if (v_min >= 0) + CHECK_AND_RETURN_FALSE (c_min, v_min, tag, v_mic < 0); + CHECK_AND_RETURN_FALSE (c_maj, v_maj, tag, v_min < 0); + return TRUE; +} + +NMMatchSpecMatchType +nm_match_spec_match_config (const GSList *specs, guint cur_nm_version, const char *env) +{ + const GSList *iter; + NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH; + + if (!specs) + return NM_MATCH_SPEC_NO_MATCH; + + for (iter = specs; iter; iter = g_slist_next (iter)) { + const char *spec_str = iter->data; + gboolean except; + gboolean v_match; + + if (!spec_str || !*spec_str) + continue; + + spec_str = _match_except (spec_str, &except); + + if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION_MIN)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION_MIN, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_NM_VERSION_MAX)) + v_match = _match_config_nm_version (spec_str, MATCH_TAG_CONFIG_NM_VERSION_MAX, cur_nm_version); + else if (_spec_has_prefix (&spec_str, MATCH_TAG_CONFIG_ENV)) + v_match = env && env[0] && !strcmp (spec_str, env); + else + continue; + + if (v_match) { + if (except) + return NM_MATCH_SPEC_NEG_MATCH; + match = NM_MATCH_SPEC_MATCH; + } + } + return match; +} + /** * nm_match_spec_split: * @value: the string of device specs diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index ceaa2c0c77..bf90e741cd 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -187,6 +187,7 @@ NMMatchSpecMatchType nm_match_spec_device_type (const GSList *specs, const char NMMatchSpecMatchType nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); NMMatchSpecMatchType nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels); NMMatchSpecMatchType nm_match_spec_interface_name (const GSList *specs, const char *interface_name); +NMMatchSpecMatchType nm_match_spec_match_config (const GSList *specs, guint nm_version, const char *env); GSList *nm_match_spec_split (const char *value); char *nm_match_spec_join (GSList *specs); diff --git a/src/nm-config.c b/src/nm-config.c index fb9f0be988..f8c4ee817d 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -495,6 +495,47 @@ nm_config_create_keyfile () return keyfile; } +/* this is an external variable, to make loading testable. Other then that, + * no code is supposed to change this. */ +guint _nm_config_match_nm_version = NM_VERSION_CUR_STABLE; +char *_nm_config_match_env = NULL; + +static gboolean +ignore_config_snippet (GKeyFile *keyfile, gboolean is_base_config) +{ + GSList *specs; + gboolean as_bool; + NMMatchSpecMatchType match_type; + + if (is_base_config) + return FALSE; + + if (!g_key_file_has_key (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, NULL)) + return FALSE; + + /* first, let's try to parse the value as plain boolean. If that is possible, we don't treat + * the value as match-spec. */ + as_bool = nm_config_keyfile_get_boolean (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, -1); + if (as_bool != -1) + return !as_bool; + + if (G_UNLIKELY (!_nm_config_match_env)) { + const char *e; + + e = g_getenv ("NM_CONFIG_ENABLE_TAG"); + _nm_config_match_env = g_strdup (e ? e : ""); + } + + /* second, interpret the value as match-spec. */ + specs = nm_config_get_match_spec (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE, NULL); + match_type = nm_match_spec_match_config (specs, + _nm_config_match_nm_version, + _nm_config_match_env); + g_slist_free_full (specs, g_free); + + return match_type != NM_MATCH_SPEC_MATCH; +} + static int _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy) { @@ -568,7 +609,7 @@ _setting_is_string_list (const char *group, const char *key) } static gboolean -read_config (GKeyFile *keyfile, const char *dirname, const char *path, GError **error) +read_config (GKeyFile *keyfile, gboolean is_base_config, const char *dirname, const char *path, GError **error) { GKeyFile *kf; char **groups, **keys; @@ -598,6 +639,16 @@ read_config (GKeyFile *keyfile, const char *dirname, const char *path, GError ** return FALSE; } + if (ignore_config_snippet (kf, is_base_config)) { + g_key_file_free (kf); + return TRUE; + } + + /* the config-group is internal to every configuration snippets. It doesn't make sense + * to merge the into the global configuration, and it doesn't make sense to preserve the + * group beyond this point. */ + g_key_file_remove_group (keyfile, NM_CONFIG_KEYFILE_GROUP_CONFIG, NULL); + /* Override the current settings with the new ones */ groups = g_key_file_get_groups (kf, &ngroups); if (!groups) @@ -744,7 +795,7 @@ read_base_config (GKeyFile *keyfile, /* Try a user-specified config file first */ if (cli_config_main_file) { /* Bad user-specific config file path is a hard error */ - if (read_config (keyfile, NULL, cli_config_main_file, error)) { + if (read_config (keyfile, TRUE, NULL, cli_config_main_file, error)) { *out_config_main_file = g_strdup (cli_config_main_file); return TRUE; } else @@ -759,7 +810,7 @@ read_base_config (GKeyFile *keyfile, */ /* Try deprecated nm-system-settings.conf first */ - if (read_config (keyfile, NULL, DEFAULT_CONFIG_MAIN_FILE_OLD, &my_error)) { + if (read_config (keyfile, TRUE, NULL, DEFAULT_CONFIG_MAIN_FILE_OLD, &my_error)) { *out_config_main_file = g_strdup (DEFAULT_CONFIG_MAIN_FILE_OLD); return TRUE; } @@ -772,7 +823,7 @@ read_base_config (GKeyFile *keyfile, g_clear_error (&my_error); /* Try the standard config file location next */ - if (read_config (keyfile, NULL, DEFAULT_CONFIG_MAIN_FILE, &my_error)) { + if (read_config (keyfile, TRUE, NULL, DEFAULT_CONFIG_MAIN_FILE, &my_error)) { *out_config_main_file = g_strdup (DEFAULT_CONFIG_MAIN_FILE); return TRUE; } @@ -878,7 +929,7 @@ read_entire_config (const NMConfigCmdLineOptions *cli, continue; } - if (!read_config (keyfile, system_config_dir, filename, error)) { + if (!read_config (keyfile, FALSE, system_config_dir, filename, error)) { g_key_file_free (keyfile); return NULL; } @@ -894,7 +945,7 @@ read_entire_config (const NMConfigCmdLineOptions *cli, g_assert (o_config_main_file); for (i = 0; i < confs->len; i++) { - if (!read_config (keyfile, config_dir, confs->pdata[i], error)) { + if (!read_config (keyfile, FALSE, config_dir, confs->pdata[i], error)) { g_key_file_free (keyfile); return NULL; } @@ -1067,6 +1118,9 @@ intern_config_read (const char *filename, const char *group = groups[g]; gboolean is_intern, is_atomic; + if (!strcmp (group, NM_CONFIG_KEYFILE_GROUP_CONFIG)) + continue; + keys = g_key_file_get_keys (keyfile, group, NULL, NULL); if (!keys) continue; diff --git a/src/nm-config.h b/src/nm-config.h index 46b2ac85ff..59a3e854b2 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -56,6 +56,7 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_GROUP_LOGGING "logging" #define NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY "connectivity" #define NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS "global-dns" +#define NM_CONFIG_KEYFILE_GROUP_CONFIG ".config" #define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile" #define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown" @@ -63,6 +64,7 @@ G_BEGIN_DECLS #define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend" #define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_ENABLE "enable" +#define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable" #define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was" #define NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH "auto_refresh" #define NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED "managed" @@ -149,6 +151,10 @@ void _nm_config_sort_groups (char **groups, gsize ngroups); gboolean nm_config_set_global_dns (NMConfig *self, NMGlobalDnsConfig *global_dns, GError **error); +/* internal defines ... */ +extern guint _nm_config_match_nm_version; +extern char *_nm_config_match_env; + G_END_DECLS #endif /* __NETWORKMANAGER_CONFIG_H__ */ diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am index 6ad9876f1f..4f3d7805d8 100644 --- a/src/tests/config/Makefile.am +++ b/src/tests/config/Makefile.am @@ -34,4 +34,5 @@ EXTRA_DIST = \ global-dns-invalid.conf \ conf.d/00-overrides.conf \ conf.d/10-more.conf \ + conf.d/20-config-enable-1.conf \ conf.d/90-last.conf diff --git a/src/tests/config/conf.d/20-config-enable-1.conf b/src/tests/config/conf.d/20-config-enable-1.conf new file mode 100644 index 0000000000..e6800f5236 --- /dev/null +++ b/src/tests/config/conf.d/20-config-enable-1.conf @@ -0,0 +1,5 @@ +[.config] +enable=nm-version:1.5.32,env:test-match-env-1 + +[test-group-config-enable-1] +key1=enabled diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index d3b2db6920..5eee306a9e 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -905,6 +905,40 @@ test_config_signal (void) /*****************************************************************************/ +static void +test_config_enable (void) +{ + gs_unref_object NMConfig *config = NULL; + guint match_nm_version = _nm_config_match_nm_version; + char *match_env = g_strdup (_nm_config_match_env); + + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = g_strdup ("something-else"); + + _nm_config_match_nm_version = nm_encode_version (1, 3, 4); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", NULL); + g_clear_object (&config); + + _nm_config_match_nm_version = nm_encode_version (1, 5, 32); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled"); + g_clear_object (&config); + + _nm_config_match_nm_version = nm_encode_version (1, 5, 3); + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = g_strdup ("test-match-env-1"); + config = setup_config (NULL, SRCDIR "/NetworkManager.conf", "", NULL, SRCDIR "/conf.d", "", NULL); + assert_config_value (nm_config_get_data_orig (config), "test-group-config-enable-1", "key1", "enabled"); + g_clear_object (&config); + + _nm_config_match_nm_version = match_nm_version; + g_clear_pointer (&_nm_config_match_env, g_free); + _nm_config_match_env = match_env; +} + +/*****************************************************************************/ + NMTST_DEFINE (); int @@ -933,6 +967,8 @@ main (int argc, char **argv) g_test_add_func ("/config/signal", test_config_signal); + g_test_add_func ("/config/enable", test_config_enable); + /* This one has to come last, because it leaves its values in * nm-config.c's global variables, and there's no way to reset * those to NULL. diff --git a/src/tests/test-general.c b/src/tests/test-general.c index ba3d958fb3..3c2a33a97d 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -773,6 +773,148 @@ test_nm_match_spec_interface_name (void) /*******************************************/ +static void +_do_test_match_spec_match_config (const char *file, gint line, const char *spec_str, guint version, guint v_maj, guint v_min, guint v_mic, NMMatchSpecMatchType expected) +{ + GSList *specs; + NMMatchSpecMatchType match_result; + guint c_maj, c_min, c_mic; + + g_assert_cmpint (version, ==, nm_encode_version (v_maj, v_min, v_mic)); + + nm_decode_version (version, &c_maj, &c_min, &c_mic); + g_assert_cmpint (c_maj, ==, c_maj); + g_assert_cmpint (c_min, ==, c_min); + g_assert_cmpint (c_mic, ==, c_mic); + + specs = nm_match_spec_split (spec_str); + + match_result = nm_match_spec_match_config (specs, version, NULL); + + 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) { + /* 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); + NMMatchSpecMatchType match_result2; + + + match_result2 = nm_match_spec_match_config (specs2, version, NULL); + if (match_result == NM_MATCH_SPEC_NO_MATCH) + g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NO_MATCH); + else + g_assert_cmpint (match_result2, ==, NM_MATCH_SPEC_NEG_MATCH); + + g_slist_free_full (specs2, g_free); + } + + g_slist_free_full (specs, g_free); +} +#define do_test_match_spec_match_config(spec, v_maj, v_min, v_mic, expected) \ + _do_test_match_spec_match_config (__FILE__, __LINE__, (""spec), NM_ENCODE_VERSION ((v_maj), (v_min), (v_mic)), (v_maj), (v_min), (v_mic), (expected)) + +static void +test_nm_match_spec_match_config (void) +{ + do_test_match_spec_match_config ("", 1, 2, 3, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2.3", 1, 2, 4, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version:1.2", 1, 1, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 2, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 2, 4, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 2, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.2", 1, 4, 30, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_config ("nm-version-min:1", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-min:1", 1, 4, 30, NM_MATCH_SPEC_MATCH); + + + do_test_match_spec_match_config ("nm-version-max:1.2.3", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 1, 1, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 2, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 2, 5, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2.3", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-max:1.2", 0, 2, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 3, 30, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-max:1.2", 1, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("nm-version-max:1", 0, 2, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 1, 1, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 3, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 2, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 3, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 1, 4, 30, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_config ("nm-version-max:1", 2, 4, 30, NM_MATCH_SPEC_NO_MATCH); + + do_test_match_spec_match_config ("except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_config ("nm-version-min:1.6,except:nm-version:1.4.8", 1, 6, 0, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_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); + do_test_match_spec_match_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); + do_test_match_spec_match_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, 15, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_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, 16, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 17, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 20, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_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, 3, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_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, 4, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_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, 4, 5, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_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, 4, 6, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 4, 7, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 4, 8, NM_MATCH_SPEC_NEG_MATCH); + do_test_match_spec_match_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, 4, 9, NM_MATCH_SPEC_MATCH); + + do_test_match_spec_match_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, 5, 0, NM_MATCH_SPEC_NO_MATCH); + do_test_match_spec_match_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, 6, 0, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 6, 5, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 7, 7, NM_MATCH_SPEC_MATCH); + do_test_match_spec_match_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, 8, 8, NM_MATCH_SPEC_MATCH); +} + +/*******************************************/ + NMTST_DEFINE (); int @@ -796,6 +938,7 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); g_test_add_func ("/general/nm_match_spec_interface_name", test_nm_match_spec_interface_name); + g_test_add_func ("/general/nm_match_spec_match_config", test_nm_match_spec_match_config); return g_test_run (); } |