about summary refs log tree commit diff
path: root/src/nm-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-config.c')
-rw-r--r--src/nm-config.c153
1 files changed, 76 insertions, 77 deletions
diff --git a/src/nm-config.c b/src/nm-config.c
index 63347db7..4fa85319 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -15,6 +15,7 @@
 #include "NetworkManagerUtils.h"
 #include "nm-core-internal.h"
 #include "nm-keyfile/nm-keyfile-internal.h"
+#include "nm-keyfile/nm-keyfile-utils.h"
 
 #define DEFAULT_CONFIG_MAIN_FILE        NMCONFDIR "/NetworkManager.conf"
 #define DEFAULT_CONFIG_DIR              NMCONFDIR "/conf.d"
@@ -144,14 +145,6 @@ static void _set_config_data (NMConfig *self, NMConfigData *new_data, NMConfigCh
 
 /*****************************************************************************/
 
-#define _HAS_PREFIX(str, prefix) \
-	({ \
-		const char *_str = (str); \
-		g_str_has_prefix ( _str, ""prefix"") && _str[NM_STRLEN(prefix)] != '\0'; \
-	})
-
-/*****************************************************************************/
-
 int
 nm_config_parse_boolean (const char *str,
                          int default_value)
@@ -351,7 +344,7 @@ no_auto_default_from_file (const char *no_auto_default_file)
 
 	if (list) {
 		for (i = 0; list[i]; i++)
-			list[i] = nm_utils_str_utf8safe_unescape_cp (list[i]);
+			list[i] = nm_utils_str_utf8safe_unescape_cp (list[i], NM_UTILS_STR_UTF8_SAFE_FLAG_NONE);
 	}
 
 	/* The returned buffer here is not at all compact. That means, it has additional
@@ -548,7 +541,7 @@ string_to_configure_and_quit (const char *value, GError **error)
 	if (value == NULL)
 		return NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED;
 
-	if (strcmp (value, "initrd") == 0)
+	if (nm_streq (value, "initrd"))
 		return NM_CONFIG_CONFIGURE_AND_QUIT_INITRD;
 
 	ret = nm_config_parse_boolean (value, NM_CONFIG_CONFIGURE_AND_QUIT_INVALID);
@@ -664,15 +657,13 @@ ignore_config_snippet (GKeyFile *keyfile, gboolean is_base_config)
 static int
 _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
 {
-	const char *a, *b;
+	const char *a = *pa;
+	const char *b = *pb;
 	gboolean a_is_connection, b_is_connection;
 	gboolean a_is_device, b_is_device;
 
-	a = *pa;
-	b = *pb;
-
-	a_is_connection = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
-	b_is_connection = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
+	a_is_connection = NM_STR_HAS_PREFIX (a, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
+	b_is_connection = NM_STR_HAS_PREFIX (b, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION);
 
 	if (a_is_connection != b_is_connection) {
 		/* one is a [connection*] entry, the other not. We sort [connection*] entries
@@ -689,8 +680,8 @@ _sort_groups_cmp (const char **pa, const char **pb, gpointer dummy)
 		return pa > pb ? -1 : 1;
 	}
 
-	a_is_device = g_str_has_prefix (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
-	b_is_device = g_str_has_prefix (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
+	a_is_device = NM_STR_HAS_PREFIX (a, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
+	b_is_device = NM_STR_HAS_PREFIX (b, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE);
 
 	if (a_is_device != b_is_device) {
 		/* one is a [device*] entry, the other not. We sort [device*] entries
@@ -726,13 +717,13 @@ _nm_config_sort_groups (char **groups, gsize ngroups)
 static gboolean
 _setting_is_device_spec (const char *group, const char *key)
 {
-#define _IS(group_v, key_v) (strcmp (group, (""group_v)) == 0 && strcmp (key, (""key_v)) == 0)
+#define _IS(group_v, key_v) (nm_streq (group, ""group_v"") && nm_streq (key, ""key_v""))
 	return    _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_NO_AUTO_DEFAULT)
 	       || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_IGNORE_CARRIER)
 	       || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_ASSUME_IPV6LL_ONLY)
 	       || _IS (NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES)
-	       || (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && !strcmp (key, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE))
-	       || (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE    ) && !strcmp (key, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE));
+	       || (NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION) && nm_streq (key, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE))
+	       || (NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE    ) && nm_streq (key, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE));
 }
 
 static gboolean
@@ -741,7 +732,7 @@ _setting_is_string_list (const char *group, const char *key)
 	return    _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_PLUGINS)
 	       || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG)
 	       || _IS (NM_CONFIG_KEYFILE_GROUP_LOGGING, NM_CONFIG_KEYFILE_KEY_LOGGING_DOMAINS)
-	       || g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST);
+	       || NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST);
 #undef _IS
 }
 
@@ -902,15 +893,20 @@ check_config_key (const char *group, const char *key)
 }
 
 static gboolean
-read_config (GKeyFile *keyfile, gboolean is_base_config,
-             const char *dirname, const char *path,
-             GPtrArray *warnings, GError **error)
-{
-	GKeyFile *kf;
-	char **groups, **keys;
-	gsize ngroups, nkeys;
-	int g, k;
+read_config (GKeyFile *keyfile,
+             gboolean is_base_config,
+             const char *dirname,
+             const char *path,
+             GPtrArray *warnings,
+             GError **error)
+{
+	gs_unref_keyfile GKeyFile *kf = NULL;
+	gs_strfreev char **groups = NULL;
 	gs_free char *path_free = NULL;
+	gsize ngroups;
+	gsize nkeys;
+	int g;
+	int k;
 
 	g_return_val_if_fail (keyfile, FALSE);
 	g_return_val_if_fail (path, FALSE);
@@ -931,14 +927,11 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 	kf = nm_config_create_keyfile ();
 	if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) {
 		g_prefix_error (error, "%s: ", path);
-		g_key_file_free (kf);
 		return FALSE;
 	}
 
-	if (ignore_config_snippet (kf, is_base_config)) {
-		g_key_file_free (kf);
+	if (ignore_config_snippet (kf, is_base_config))
 		return TRUE;
-	}
 
 	/* the config-group is internal to every configuration snippets. It doesn't make sense
 	 * to merge it into the global configuration, and it doesn't make sense to preserve the
@@ -962,8 +955,9 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 
 	for (g = 0; groups && groups[g]; g++) {
 		const char *group = groups[g];
+		gs_strfreev char **keys = NULL;
 
-		if (g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN)) {
+		if (NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN)) {
 			/* internal groups cannot be set by user configuration. */
 			continue;
 		}
@@ -971,21 +965,21 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 		if (!keys)
 			continue;
 		for (k = 0; keys[k]; k++) {
+			gs_free char *new_value = NULL;
 			const char *key;
-			char *new_value;
 			char last_char;
 			gsize key_len;
 
 			key = keys[k];
-			g_assert (key && *key);
+			nm_assert (key && *key);
 
-			if (   _HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)
-			    || _HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
+			if (   NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)
+			    || NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
 				/* these keys are protected. We ignore them if the user sets them. */
 				continue;
 			}
 
-			if (!strcmp (key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS)) {
+			if (nm_streq (key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS)) {
 				/* the "was" key is protected and it cannot be set by user configuration. */
 				continue;
 			}
@@ -996,6 +990,7 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 			    && (last_char == '+' || last_char == '-')) {
 				gs_free char *base_key = g_strndup (key, key_len - 1);
 				gboolean is_string_list;
+				gboolean old_val_was_set = FALSE;
 
 				is_string_list = _setting_is_string_list (group, base_key);
 
@@ -1007,13 +1002,19 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 					gs_free char **new_val = NULL;
 
 					if (is_string_list) {
-						old_val = g_key_file_get_string_list (keyfile, group, base_key, NULL, NULL);
+						gs_free_error GError *old_error = NULL;
+
+						old_val = g_key_file_get_string_list (keyfile, group, base_key, NULL, &old_error);
 						new_val = g_key_file_get_string_list (kf, group, key, NULL, NULL);
-						if (!old_val && !g_key_file_has_key (keyfile, group, base_key, NULL)) {
-							/* we must fill the unspecified value with the compile-time default. */
-							if (nm_streq (group, NM_CONFIG_KEYFILE_GROUP_MAIN) && nm_streq (base_key, "plugins")) {
+						if (   nm_streq (group, NM_CONFIG_KEYFILE_GROUP_MAIN)
+						    && nm_streq (base_key, "plugins")) {
+							old_val_was_set = !nm_keyfile_error_is_not_found (old_error);
+							if (   !old_val
+							    && !old_val_was_set) {
+								/* we must fill the unspecified value with the compile-time default. */
 								g_key_file_set_value (keyfile, group, base_key, NM_CONFIG_DEFAULT_MAIN_PLUGINS);
 								old_val = g_key_file_get_string_list (keyfile, group, base_key, NULL, NULL);
+								old_val_was_set = TRUE;
 							}
 						}
 					} else {
@@ -1059,7 +1060,7 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 							g_key_file_set_value (keyfile, group, base_key, specs_joined);
 						}
 					} else {
-						if (is_string_list)
+						if (is_string_list && !old_val_was_set)
 							g_key_file_remove_key (keyfile, group, base_key, NULL);
 						else
 							g_key_file_set_value (keyfile, group, base_key, "");
@@ -1079,12 +1080,8 @@ read_config (GKeyFile *keyfile, gboolean is_base_config,
 				                 g_strdup_printf ("unknown key '%s' in section [%s] of file '%s'",
 				                                  key, group, path));
 			}
-			g_free (new_value);
 		}
-		g_strfreev (keys);
 	}
-	g_strfreev (groups);
-	g_key_file_free (kf);
 
 	return TRUE;
 }
@@ -1174,7 +1171,7 @@ _get_config_dir_files (const char *config_dir)
 	if (direnum) {
 		while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) {
 			name = g_file_info_get_name (info);
-			if (g_str_has_suffix (name, ".conf"))
+			if (NM_STR_HAS_SUFFIX (name, ".conf"))
 				g_ptr_array_add (confs, g_strdup (name));
 			g_object_unref (info);
 		}
@@ -1472,14 +1469,14 @@ intern_config_read (const char *filename,
 		const char *group = groups[g];
 		gboolean is_intern, is_atomic;
 
-		if (!strcmp (group, NM_CONFIG_KEYFILE_GROUP_CONFIG))
+		if (nm_streq (group, NM_CONFIG_KEYFILE_GROUP_CONFIG))
 			continue;
 
 		keys = g_key_file_get_keys (keyfile, group, NULL, NULL);
 		if (!keys)
 			continue;
 
-		is_intern = g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
+		is_intern = NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
 		is_atomic = !is_intern && _is_atomic_section (atomic_section_prefixes, group);
 
 		if (is_atomic) {
@@ -1489,7 +1486,7 @@ intern_config_read (const char *filename,
 			conf_section_is = _keyfile_serialize_section (keyfile_conf, group);
 			conf_section_was = g_key_file_get_string (keyfile, group, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS, NULL);
 
-			if (g_strcmp0 (conf_section_was, conf_section_is) != 0) {
+			if (!nm_streq0 (conf_section_was, conf_section_is)) {
 				/* the section no longer matches. Skip it entirely. */
 				needs_rewrite = TRUE;
 				continue;
@@ -1510,10 +1507,10 @@ intern_config_read (const char *filename,
 				has_intern = TRUE;
 				g_key_file_set_value (keyfile_intern, group, key, value_set);
 			} else if (is_atomic) {
-				if (strcmp (key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS) == 0)
+				if (nm_streq (key, NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS))
 					continue;
 				g_key_file_set_value (keyfile_intern, group, key, value_set);
-			} else if (_HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
+			} else if (NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
 				const char *key_base = &key[NM_STRLEN (NM_CONFIG_KEYFILE_KEYPREFIX_SET)];
 				gs_free char *value_was = NULL;
 				gs_free char *value_conf = NULL;
@@ -1523,7 +1520,7 @@ intern_config_read (const char *filename,
 					value_conf = g_key_file_get_value (keyfile_conf, group, key_base, NULL);
 				value_was = g_key_file_get_value (keyfile, group, key_was, NULL);
 
-				if (g_strcmp0 (value_conf, value_was) != 0) {
+				if (!nm_streq0 (value_conf, value_was)) {
 					/* if value_was is no longer the same as @value_conf, it means the user
 					 * changed the configuration since the last write. In this case, we
 					 * drop the value. It also means our file is out-of-date, and we should
@@ -1533,7 +1530,7 @@ intern_config_read (const char *filename,
 				}
 				has_intern = TRUE;
 				g_key_file_set_value (keyfile_intern, group, key_base, value_set);
-			} else if (_HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
+			} else if (NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
 				const char *key_base = &key[NM_STRLEN (NM_CONFIG_KEYFILE_KEYPREFIX_WAS)];
 				gs_free char *key_set = g_strdup_printf (NM_CONFIG_KEYFILE_KEYPREFIX_SET"%s", key_base);
 				gs_free char *value_was = NULL;
@@ -1548,7 +1545,7 @@ intern_config_read (const char *filename,
 					value_conf = g_key_file_get_value (keyfile_conf, group, key_base, NULL);
 				value_was = g_key_file_get_value (keyfile, group, key, NULL);
 
-				if (g_strcmp0 (value_conf, value_was) != 0) {
+				if (!nm_streq0 (value_conf, value_was)) {
 					/* if value_was is no longer the same as @value_conf, it means the user
 					 * changed the configuration since the last write. In this case, we
 					 * don't overwrite the user-provided value. It also means our file is
@@ -1577,7 +1574,7 @@ out:
 		if (g_key_file_remove_group (keyfile_intern, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, NULL))
 			needs_rewrite = TRUE;
 		for (g = 0; groups && groups[g]; g++) {
-			if (   g_str_has_prefix (groups[g], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)
+			if (   NM_STR_HAS_PREFIX (groups[g], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)
 			    && groups[g][NM_STRLEN (NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN)]) {
 				g_key_file_remove_group (keyfile_intern, groups[g], NULL);
 				needs_rewrite = TRUE;
@@ -1602,12 +1599,12 @@ out:
 static int
 _intern_config_write_sort_fcn (const char **a, const char **b, const char *const*atomic_section_prefixes)
 {
-	const char *g_a = (a ? *a : NULL);
-	const char *g_b = (b ? *b : NULL);
+	const char *g_a = *a;
+	const char *g_b = *b;
 	gboolean a_is, b_is;
 
-	a_is = g_str_has_prefix (g_a, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
-	b_is = g_str_has_prefix (g_b, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
+	a_is = NM_STR_HAS_PREFIX (g_a, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
+	b_is = NM_STR_HAS_PREFIX (g_b, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
 
 	if (a_is != b_is) {
 		if (a_is)
@@ -1668,7 +1665,7 @@ intern_config_write (const char *filename,
 		if (!keys)
 			continue;
 
-		is_intern = g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
+		is_intern = NM_STR_HAS_PREFIX (group, NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN);
 		is_atomic = !is_intern && _is_atomic_section (atomic_section_prefixes, group);
 
 		if (is_atomic) {
@@ -1707,16 +1704,16 @@ intern_config_write (const char *filename,
 			else {
 				gs_free char *value_was = NULL;
 
-				if (_HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
+				if (NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_SET)) {
 					/* Setting a key with .set prefix has no meaning, as these keys
 					 * are protected. Just set the value you want to set instead.
 					 * Why did this happen?? */
 					g_warn_if_reached ();
-				} else if (_HAS_PREFIX (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
+				} else if (NM_STR_HAS_PREFIX_WITH_MORE (key, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
 					const char *key_base = &key[NM_STRLEN (NM_CONFIG_KEYFILE_KEYPREFIX_WAS)];
 
-					if (   _HAS_PREFIX (key_base, NM_CONFIG_KEYFILE_KEYPREFIX_SET)
-					    || _HAS_PREFIX (key_base, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
+					if (   NM_STR_HAS_PREFIX_WITH_MORE (key_base, NM_CONFIG_KEYFILE_KEYPREFIX_SET)
+					    || NM_STR_HAS_PREFIX_WITH_MORE (key_base, NM_CONFIG_KEYFILE_KEYPREFIX_WAS)) {
 						g_warn_if_reached ();
 						continue;
 					}
@@ -1735,7 +1732,7 @@ intern_config_write (const char *filename,
 				} else {
 					if (keyfile_conf) {
 						value_was = g_key_file_get_value (keyfile_conf, group, key, NULL);
-						if (g_strcmp0 (value_set, value_was) == 0) {
+						if (nm_streq0 (value_set, value_was)) {
 							/* there is no point in storing the identical value as we have via
 							 * user configuration. Skip it. */
 							continue;
@@ -1837,7 +1834,7 @@ nm_config_set_global_dns (NMConfig *self, NMGlobalDnsConfig *global_dns, GError
 	g_key_file_remove_group (keyfile, NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS, NULL);
 	groups = g_key_file_get_groups (keyfile, NULL);
 	for (i = 0; groups[i]; i++) {
-		if (g_str_has_prefix (groups[i], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN))
+		if (NM_STR_HAS_PREFIX (groups[i], NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN))
 			g_key_file_remove_group (keyfile, groups[i], NULL);
 	}
 	g_strfreev (groups);
@@ -2210,7 +2207,7 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
 	gs_free char *perm_hw_addr_fake = NULL;
 	gsize connection_uuid_len;
 	gsize perm_hw_addr_fake_len;
-	int nm_owned = -1;
+	NMTernary nm_owned;
 	char *p;
 	guint32 route_metric_default_effective;
 	guint32 route_metric_default_aspired;
@@ -2252,7 +2249,7 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
 	nm_owned = nm_config_keyfile_get_boolean (kf,
 	                                          DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
 	                                          DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED,
-	                                          -1);
+	                                          NM_TERNARY_DEFAULT);
 
 	/* metric zero is not a valid metric. While zero valid for IPv4, for IPv6 it is an alias
 	 * for 1024. Since we handle here IPv4 and IPv6 the same, we cannot allow zero. */
@@ -2325,9 +2322,11 @@ nm_config_device_state_load (int ifindex)
 		return NULL;
 
 	device_state = _config_device_state_data_new (ifindex, kf);
-	nm_owned_str = device_state->nm_owned == TRUE ?
-	               ", nm-owned=1" :
-	               (device_state->nm_owned == FALSE ? ", nm-owned=0" : "");
+	nm_owned_str =   device_state->nm_owned == NM_TERNARY_TRUE
+	               ? ", nm-owned=1"
+	               : (  device_state->nm_owned == NM_TERNARY_FALSE
+	                  ? ", nm-owned=0"
+	                  : "");
 
 	_LOGT ("device-state: %s #%d (%s); managed=%s%s%s%s%s%s%s%s, route-metric-default=%"G_GUINT32_FORMAT"-%"G_GUINT32_FORMAT"",
 	       kf ? "read" : "miss",
@@ -2390,7 +2389,7 @@ nm_config_device_state_write (int ifindex,
                               NMConfigDeviceStateManagedType managed,
                               const char *perm_hw_addr_fake,
                               const char *connection_uuid,
-                              int nm_owned,
+                              NMTernary nm_owned,
                               guint32 route_metric_default_aspired,
                               guint32 route_metric_default_effective,
                               const char *next_server,
@@ -2429,7 +2428,7 @@ nm_config_device_state_write (int ifindex,
 		                       DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_CONNECTION_UUID,
 		                       connection_uuid);
 	}
-	if (nm_owned >= 0) {
+	if (nm_owned != NM_TERNARY_DEFAULT) {
 		g_key_file_set_boolean (kf,
 		                        DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
 		                        DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED,