about summary refs log tree commit diff
path: root/libnm-core/nm-keyfile
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-keyfile')
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile-internal.h181
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile-utils.c1061
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile-utils.h112
-rw-r--r--libnm-core/nm-keyfile/nm-keyfile.c7547
4 files changed, 4366 insertions, 4535 deletions
diff --git a/libnm-core/nm-keyfile/nm-keyfile-internal.h b/libnm-core/nm-keyfile/nm-keyfile-internal.h
index b6ac71d6..77372f3a 100644
--- a/libnm-core/nm-keyfile/nm-keyfile-internal.h
+++ b/libnm-core/nm-keyfile/nm-keyfile-internal.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2015 Red Hat, Inc.
@@ -7,8 +7,8 @@
 #ifndef __NM_KEYFILE_INTERNAL_H__
 #define __NM_KEYFILE_INTERNAL_H__
 
-#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL)
-#error Cannot use this header.
+#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL)
+    #error Cannot use this header.
 #endif
 
 #include <sys/types.h>
@@ -21,23 +21,23 @@
 
 /*****************************************************************************/
 
-#define NM_KEYFILE_CERT_SCHEME_PREFIX_PATH "file://"
+#define NM_KEYFILE_CERT_SCHEME_PREFIX_PATH   "file://"
 #define NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11 "pkcs11:"
-#define NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB "data:;base64,"
+#define NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB   "data:;base64,"
 
-char *nm_keyfile_detect_unqualified_path_scheme (const char *base_dir,
-                                                 gconstpointer pdata,
-                                                 gsize data_len,
-                                                 gboolean consider_exists,
-                                                 gboolean *out_exists);
+char *nm_keyfile_detect_unqualified_path_scheme(const char *  base_dir,
+                                                gconstpointer pdata,
+                                                gsize         data_len,
+                                                gboolean      consider_exists,
+                                                gboolean *    out_exists);
 
 typedef enum { /*< flags >*/
-	NM_KEYFILE_HANDLER_FLAGS_NONE = 0,
+               NM_KEYFILE_HANDLER_FLAGS_NONE = 0,
 } NMKeyfileHandlerFlags;
 
 typedef enum {
-	NM_KEYFILE_HANDLER_TYPE_WARN  = 1,
-	NM_KEYFILE_HANDLER_TYPE_WRITE_CERT = 2,
+    NM_KEYFILE_HANDLER_TYPE_WARN       = 1,
+    NM_KEYFILE_HANDLER_TYPE_WRITE_CERT = 2,
 } NMKeyfileHandlerType;
 
 typedef struct _NMKeyfileHandlerData NMKeyfileHandlerData;
@@ -52,31 +52,29 @@ typedef struct _NMKeyfileHandlerData NMKeyfileHandlerData;
  * a default action will be performed that depends on the @handler_type.
  * For %NM_KEYFILE_HANDLER_TYPE_WARN handler_type, the default action is doing nothing.
  */
-typedef gboolean (*NMKeyfileReadHandler) (GKeyFile *keyfile,
-                                          NMConnection *connection,
-                                          NMKeyfileHandlerType handler_type,
-                                          NMKeyfileHandlerData *handler_data,
-                                          void *user_data);
+typedef gboolean (*NMKeyfileReadHandler)(GKeyFile *            keyfile,
+                                         NMConnection *        connection,
+                                         NMKeyfileHandlerType  handler_type,
+                                         NMKeyfileHandlerData *handler_data,
+                                         void *                user_data);
 
 typedef enum {
-	NM_KEYFILE_WARN_SEVERITY_DEBUG                  = 1000,
-	NM_KEYFILE_WARN_SEVERITY_INFO                   = 2000,
-	NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE      = 2901,
-	NM_KEYFILE_WARN_SEVERITY_WARN                   = 3000,
+    NM_KEYFILE_WARN_SEVERITY_DEBUG             = 1000,
+    NM_KEYFILE_WARN_SEVERITY_INFO              = 2000,
+    NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE = 2901,
+    NM_KEYFILE_WARN_SEVERITY_WARN              = 3000,
 } NMKeyfileWarnSeverity;
 
-NMConnection *nm_keyfile_read (GKeyFile *keyfile,
-                               const char *base_dir,
-                               NMKeyfileHandlerFlags handler_flags,
-                               NMKeyfileReadHandler handler,
-                               void *user_data,
-                               GError **error);
+NMConnection *nm_keyfile_read(GKeyFile *            keyfile,
+                              const char *          base_dir,
+                              NMKeyfileHandlerFlags handler_flags,
+                              NMKeyfileReadHandler  handler,
+                              void *                user_data,
+                              GError **             error);
 
-gboolean nm_keyfile_read_ensure_id (NMConnection *connection,
-                                    const char *fallback_id);
+gboolean nm_keyfile_read_ensure_id(NMConnection *connection, const char *fallback_id);
 
-gboolean nm_keyfile_read_ensure_uuid (NMConnection *connection,
-                                      const char *fallback_uuid_seed);
+gboolean nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_seed);
 
 /*****************************************************************************/
 
@@ -103,17 +101,17 @@ gboolean nm_keyfile_read_ensure_uuid (NMConnection *connection,
  * a default action will be performed. This might be raise an error,
  * do some fallback parsing, or do nothing.
  */
-typedef gboolean (*NMKeyfileWriteHandler) (NMConnection *connection,
-                                           GKeyFile *keyfile,
-                                           NMKeyfileHandlerType handler_type,
-                                           NMKeyfileHandlerData *handler_data,
-                                           void *user_data);
-
-GKeyFile *nm_keyfile_write (NMConnection *connection,
-                            NMKeyfileHandlerFlags handler_flags,
-                            NMKeyfileWriteHandler handler,
-                            void *user_data,
-                            GError **error);
+typedef gboolean (*NMKeyfileWriteHandler)(NMConnection *        connection,
+                                          GKeyFile *            keyfile,
+                                          NMKeyfileHandlerType  handler_type,
+                                          NMKeyfileHandlerData *handler_data,
+                                          void *                user_data);
+
+GKeyFile *nm_keyfile_write(NMConnection *        connection,
+                           NMKeyfileHandlerFlags handler_flags,
+                           NMKeyfileWriteHandler handler,
+                           void *                user_data,
+                           GError **             error);
 
 /*****************************************************************************/
 
@@ -124,10 +122,10 @@ GKeyFile *nm_keyfile_write (NMConnection *connection,
  * handler_type %NM_KEYFILE_HANDLER_TYPE_WARN.
  */
 typedef struct {
-	NMKeyfileWarnSeverity severity;
-	char *message;
-	const char *fmt;
-	va_list ap;
+    NMKeyfileWarnSeverity severity;
+    char *                message;
+    const char *          fmt;
+    va_list               ap;
 } NMKeyfileHandlerDataWarn;
 
 /**
@@ -137,76 +135,79 @@ typedef struct {
  * handler_type %NM_KEYFILE_HANDLER_TYPE_WRITE_CERT.
  */
 typedef struct {
-	const NMSetting8021xSchemeVtable *vtable;
+    const NMSetting8021xSchemeVtable *vtable;
 } NMKeyfileHandlerDataWriteCert;
 
 struct _NMKeyfileHandlerData {
-	NMKeyfileHandlerType type;
+    NMKeyfileHandlerType type;
 
-	GError **p_error;
+    GError **p_error;
 
-	const char *kf_group_name;
-	const char *kf_key;
+    const char *kf_group_name;
+    const char *kf_key;
 
-	NMSetting *cur_setting;
-	const char *cur_property;
+    NMSetting * cur_setting;
+    const char *cur_property;
 
-	union {
-		NMKeyfileHandlerDataWarn      warn;
-		NMKeyfileHandlerDataWriteCert write_cert;
-	};
+    union {
+        NMKeyfileHandlerDataWarn      warn;
+        NMKeyfileHandlerDataWriteCert write_cert;
+    };
 };
 
 /*****************************************************************************/
 
-void nm_keyfile_handler_data_fail_with_error (NMKeyfileHandlerData *handler_data,
-                                              GError *src);
+void nm_keyfile_handler_data_fail_with_error(NMKeyfileHandlerData *handler_data, GError *src);
 
-void nm_keyfile_handler_data_get_context (const NMKeyfileHandlerData *handler_data,
-                                          const char **out_kf_group_name,
-                                          const char **out_kf_key_name,
-                                          NMSetting **out_cur_setting,
-                                          const char **out_cur_property_name);
+void nm_keyfile_handler_data_get_context(const NMKeyfileHandlerData *handler_data,
+                                         const char **               out_kf_group_name,
+                                         const char **               out_kf_key_name,
+                                         NMSetting **                out_cur_setting,
+                                         const char **               out_cur_property_name);
 
-void nm_keyfile_handler_data_warn_get (const NMKeyfileHandlerData *handler_data,
-                                       const char **out_message,
-                                       NMKeyfileWarnSeverity *out_severity);
+void nm_keyfile_handler_data_warn_get(const NMKeyfileHandlerData *handler_data,
+                                      const char **               out_message,
+                                      NMKeyfileWarnSeverity *     out_severity);
 
-const char *_nm_keyfile_handler_data_warn_get_message (const NMKeyfileHandlerData *handler_data);
+const char *_nm_keyfile_handler_data_warn_get_message(const NMKeyfileHandlerData *handler_data);
 
 /*****************************************************************************/
 
-char *nm_keyfile_plugin_kf_get_string (GKeyFile *kf, const char *group, const char *key, GError **error);
-void nm_keyfile_plugin_kf_set_string (GKeyFile *kf, const char *group, const char *key, const char *value);
+char *
+nm_keyfile_plugin_kf_get_string(GKeyFile *kf, const char *group, const char *key, GError **error);
+void nm_keyfile_plugin_kf_set_string(GKeyFile *  kf,
+                                     const char *group,
+                                     const char *key,
+                                     const char *value);
 
-int nm_key_file_get_boolean (GKeyFile *kf, const char *group, const char *key, int default_value);
+int nm_key_file_get_boolean(GKeyFile *kf, const char *group, const char *key, int default_value);
 
-void _nm_keyfile_copy (GKeyFile *dst, GKeyFile *src);
-gboolean _nm_keyfile_a_contains_all_in_b (GKeyFile *kf_a, GKeyFile *kf_b);
-gboolean _nm_keyfile_equals (GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order);
-gboolean _nm_keyfile_has_values (GKeyFile *keyfile);
+void     _nm_keyfile_copy(GKeyFile *dst, GKeyFile *src);
+gboolean _nm_keyfile_a_contains_all_in_b(GKeyFile *kf_a, GKeyFile *kf_b);
+gboolean _nm_keyfile_equals(GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order);
+gboolean _nm_keyfile_has_values(GKeyFile *keyfile);
 
 /*****************************************************************************/
 
-#define NM_KEYFILE_GROUP_NMMETA                 ".nmmeta"
-#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED      "nm-generated"
-#define NM_KEYFILE_KEY_NMMETA_VOLATILE          "volatile"
-#define NM_KEYFILE_KEY_NMMETA_EXTERNAL          "external"
-#define NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE  "shadowed-storage"
-#define NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED    "shadowed-owned"
+#define NM_KEYFILE_GROUP_NMMETA                ".nmmeta"
+#define NM_KEYFILE_KEY_NMMETA_NM_GENERATED     "nm-generated"
+#define NM_KEYFILE_KEY_NMMETA_VOLATILE         "volatile"
+#define NM_KEYFILE_KEY_NMMETA_EXTERNAL         "external"
+#define NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE "shadowed-storage"
+#define NM_KEYFILE_KEY_NMMETA_SHADOWED_OWNED   "shadowed-owned"
 
-#define NM_KEYFILE_PATH_NAME_LIB                 NMLIBDIR  "/system-connections"
-#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT         NMCONFDIR "/system-connections"
-#define NM_KEYFILE_PATH_NAME_RUN                 NMRUNDIR  "/system-connections"
+#define NM_KEYFILE_PATH_NAME_LIB         NMLIBDIR "/system-connections"
+#define NM_KEYFILE_PATH_NAME_ETC_DEFAULT NMCONFDIR "/system-connections"
+#define NM_KEYFILE_PATH_NAME_RUN         NMRUNDIR "/system-connections"
 
-#define NM_KEYFILE_PATH_SUFFIX_NMCONNECTION      ".nmconnection"
+#define NM_KEYFILE_PATH_SUFFIX_NMCONNECTION ".nmconnection"
 
-#define NM_KEYFILE_PATH_SUFFIX_NMMETA            ".nmmeta"
+#define NM_KEYFILE_PATH_SUFFIX_NMMETA ".nmmeta"
 
-#define NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL      "/dev/null"
+#define NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL "/dev/null"
 
-gboolean nm_keyfile_utils_ignore_filename (const char *filename, gboolean require_extension);
+gboolean nm_keyfile_utils_ignore_filename(const char *filename, gboolean require_extension);
 
-char *nm_keyfile_utils_create_filename (const char *filename, gboolean with_extension);
+char *nm_keyfile_utils_create_filename(const char *filename, gboolean with_extension);
 
 #endif /* __NM_KEYFILE_INTERNAL_H__ */
diff --git a/libnm-core/nm-keyfile/nm-keyfile-utils.c b/libnm-core/nm-keyfile/nm-keyfile-utils.c
index 01b42ac7..be12f8a8 100644
--- a/libnm-core/nm-keyfile/nm-keyfile-utils.c
+++ b/libnm-core/nm-keyfile/nm-keyfile-utils.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2010 Red Hat, Inc.
  */
@@ -41,661 +41,642 @@
  *   the key exists, whether the value is invalid, or success.
  */
 int
-nm_key_file_get_boolean (GKeyFile *kf, const char *group, const char *key, int default_value)
+nm_key_file_get_boolean(GKeyFile *kf, const char *group, const char *key, int default_value)
 {
-	int v;
-	gs_free char *value = NULL;
-
-	value = g_key_file_get_value (kf, group, key, NULL);
-
-	if (!value) {
-		errno = ENODATA;
-		return default_value;
-	}
-	v = _nm_utils_ascii_str_to_bool (value, -1);
-	if (v != -1) {
-		errno = 0;
-		return v;
-	}
-	errno = EINVAL;
-	return default_value;
+    int           v;
+    gs_free char *value = NULL;
+
+    value = g_key_file_get_value(kf, group, key, NULL);
+
+    if (!value) {
+        errno = ENODATA;
+        return default_value;
+    }
+    v = _nm_utils_ascii_str_to_bool(value, -1);
+    if (v != -1) {
+        errno = 0;
+        return v;
+    }
+    errno = EINVAL;
+    return default_value;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	const char *setting;
-	const char *alias;
+    const char *setting;
+    const char *alias;
 } SettingAlias;
 
 static const SettingAlias alias_list[] = {
-	{ NM_SETTING_WIRED_SETTING_NAME, "ethernet" },
-	{ NM_SETTING_WIRELESS_SETTING_NAME, "wifi" },
-	{ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security" },
+    {NM_SETTING_WIRED_SETTING_NAME, "ethernet"},
+    {NM_SETTING_WIRELESS_SETTING_NAME, "wifi"},
+    {NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security"},
 };
 
 const char *
-nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name)
+nm_keyfile_plugin_get_alias_for_setting_name(const char *setting_name)
 {
-	guint i;
+    guint i;
 
-	g_return_val_if_fail (setting_name != NULL, NULL);
+    g_return_val_if_fail(setting_name != NULL, NULL);
 
-	for (i = 0; i < G_N_ELEMENTS (alias_list); i++) {
-		if (nm_streq (setting_name, alias_list[i].setting))
-			return alias_list[i].alias;
-	}
-	return NULL;
+    for (i = 0; i < G_N_ELEMENTS(alias_list); i++) {
+        if (nm_streq(setting_name, alias_list[i].setting))
+            return alias_list[i].alias;
+    }
+    return NULL;
 }
 
 const char *
-nm_keyfile_plugin_get_setting_name_for_alias (const char *alias)
+nm_keyfile_plugin_get_setting_name_for_alias(const char *alias)
 {
-	guint i;
+    guint i;
 
-	g_return_val_if_fail (alias != NULL, NULL);
+    g_return_val_if_fail(alias != NULL, NULL);
 
-	for (i = 0; i < G_N_ELEMENTS (alias_list); i++) {
-		if (nm_streq (alias, alias_list[i].alias))
-			return alias_list[i].setting;
-	}
-	return NULL;
+    for (i = 0; i < G_N_ELEMENTS(alias_list); i++) {
+        if (nm_streq(alias, alias_list[i].alias))
+            return alias_list[i].setting;
+    }
+    return NULL;
 }
 
 /*****************************************************************************/
 
 char **
-nm_keyfile_plugin_kf_get_string_list (GKeyFile *kf,
-                                      const char *group,
-                                      const char *key,
-                                      gsize *out_length,
-                                      GError **error)
+nm_keyfile_plugin_kf_get_string_list(GKeyFile *  kf,
+                                     const char *group,
+                                     const char *key,
+                                     gsize *     out_length,
+                                     GError **   error)
 {
-	char **list;
-	const char *alias;
-	GError *local = NULL;
-	gsize l;
-
-	list = g_key_file_get_string_list (kf, group, key, &l, &local);
-	if (nm_g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-		alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
-		if (alias) {
-			g_clear_error (&local);
-			list = g_key_file_get_string_list (kf, alias, key, &l, &local);
-		}
-	}
-	if (local)
-		g_propagate_error (error, local);
-	if (!list)
-		l = 0;
-	NM_SET_OUT (out_length, l);
-	return list;
+    char **     list;
+    const char *alias;
+    GError *    local = NULL;
+    gsize       l;
+
+    list = g_key_file_get_string_list(kf, group, key, &l, &local);
+    if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+        alias = nm_keyfile_plugin_get_alias_for_setting_name(group);
+        if (alias) {
+            g_clear_error(&local);
+            list = g_key_file_get_string_list(kf, alias, key, &l, &local);
+        }
+    }
+    if (local)
+        g_propagate_error(error, local);
+    if (!list)
+        l = 0;
+    NM_SET_OUT(out_length, l);
+    return list;
 }
 
 guint *
-nm_keyfile_plugin_kf_get_integer_list_uint (GKeyFile *key_file,
-                                            const char *group_name,
-                                            const char *key,
-                                            gsize *out_length,
-                                            GError **error)
+nm_keyfile_plugin_kf_get_integer_list_uint(GKeyFile *  key_file,
+                                           const char *group_name,
+                                           const char *key,
+                                           gsize *     out_length,
+                                           GError **   error)
 {
-	GError *key_file_error = NULL;
-	gs_strfreev char **values = NULL;
-	gs_free guint *int_values = NULL;
-	gsize i, num_ints;
+    GError *           key_file_error = NULL;
+    gs_strfreev char **values         = NULL;
+    gs_free guint *int_values         = NULL;
+    gsize          i, num_ints;
 
-	NM_SET_OUT (out_length, 0);
+    NM_SET_OUT(out_length, 0);
 
-	g_return_val_if_fail (key_file != NULL, NULL);
-	g_return_val_if_fail (group_name != NULL, NULL);
-	g_return_val_if_fail (key != NULL, NULL);
+    g_return_val_if_fail(key_file != NULL, NULL);
+    g_return_val_if_fail(group_name != NULL, NULL);
+    g_return_val_if_fail(key != NULL, NULL);
 
-	values = nm_keyfile_plugin_kf_get_string_list (key_file, group_name, key, &num_ints, &key_file_error);
+    values =
+        nm_keyfile_plugin_kf_get_string_list(key_file, group_name, key, &num_ints, &key_file_error);
 
-	if (key_file_error)
-		g_propagate_error (error, key_file_error);
-	if (!values)
-		return NULL;
+    if (key_file_error)
+        g_propagate_error(error, key_file_error);
+    if (!values)
+        return NULL;
 
-	int_values = g_new (guint, num_ints);
+    int_values = g_new(guint, num_ints);
 
-	for (i = 0; i < num_ints; i++) {
-		gint64 v;
+    for (i = 0; i < num_ints; i++) {
+        gint64 v;
 
-		G_STATIC_ASSERT_EXPR (sizeof (v) > sizeof (guint));
-		v = _nm_utils_ascii_str_to_int64 (values[i], 10, 0, G_MAXUINT, -1);
-		if (v == -1) {
-			g_set_error (error,
-			             G_KEY_FILE_ERROR,
-			             G_KEY_FILE_ERROR_INVALID_VALUE,
-			             _("Value cannot be interpreted as a list of numbers."));
-			return NULL;
-		}
+        G_STATIC_ASSERT_EXPR(sizeof(v) > sizeof(guint));
+        v = _nm_utils_ascii_str_to_int64(values[i], 10, 0, G_MAXUINT, -1);
+        if (v == -1) {
+            g_set_error(error,
+                        G_KEY_FILE_ERROR,
+                        G_KEY_FILE_ERROR_INVALID_VALUE,
+                        _("Value cannot be interpreted as a list of numbers."));
+            return NULL;
+        }
 
-		int_values[i] = v;
-	}
+        int_values[i] = v;
+    }
 
-	NM_SET_OUT (out_length, num_ints);
-	return g_steal_pointer (&int_values);
+    NM_SET_OUT(out_length, num_ints);
+    return g_steal_pointer(&int_values);
 }
 
 void
-nm_keyfile_plugin_kf_set_string_list (GKeyFile *kf,
-                                      const char *group,
-                                      const char *key,
-                                      const char *const*list,
-                                      gsize length)
+nm_keyfile_plugin_kf_set_string_list(GKeyFile *         kf,
+                                     const char *       group,
+                                     const char *       key,
+                                     const char *const *list,
+                                     gsize              length)
 {
-	const char *alias;
+    const char *alias;
 
-	alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
-	g_key_file_set_string_list (kf, alias ?: group, key, list, length);
+    alias = nm_keyfile_plugin_get_alias_for_setting_name(group);
+    g_key_file_set_string_list(kf, alias ?: group, key, list, length);
 }
 
 void
-nm_keyfile_plugin_kf_set_integer_list_uint (GKeyFile *kf,
-                                            const char *group,
-                                            const char *key,
-                                            const guint *data,
-                                            gsize length)
+nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile *   kf,
+                                           const char * group,
+                                           const char * key,
+                                           const guint *data,
+                                           gsize        length)
 {
-	nm_auto_str_buf NMStrBuf strbuf = { };
-	gsize i;
-
-	g_return_if_fail (kf);
-	g_return_if_fail (!length || data);
-	g_return_if_fail (group && group[0]);
-	g_return_if_fail (key && key[0]);
-
-	nm_str_buf_init (&strbuf, length * 4u + 2u, FALSE);
-	for (i = 0; i < length; i++)
-		nm_str_buf_append_printf (&strbuf, "%u;", data[i]);
-	nm_keyfile_plugin_kf_set_value (kf, group, key, nm_str_buf_get_str (&strbuf));
+    nm_auto_str_buf NMStrBuf strbuf = {};
+    gsize                    i;
+
+    g_return_if_fail(kf);
+    g_return_if_fail(!length || data);
+    g_return_if_fail(group && group[0]);
+    g_return_if_fail(key && key[0]);
+
+    nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE);
+    for (i = 0; i < length; i++)
+        nm_str_buf_append_printf(&strbuf, "%u;", data[i]);
+    nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf));
 }
 
 void
-nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf,
-                                             const char *group,
-                                             const char *key,
-                                             const guint8 *data,
-                                             gsize length)
+nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile *    kf,
+                                            const char *  group,
+                                            const char *  key,
+                                            const guint8 *data,
+                                            gsize         length)
 {
-	nm_auto_str_buf NMStrBuf strbuf = { };
-	gsize i;
-
-	g_return_if_fail (kf);
-	g_return_if_fail (!length || data);
-	g_return_if_fail (group && group[0]);
-	g_return_if_fail (key && key[0]);
-
-	nm_str_buf_init (&strbuf, length * 4u + 2u, FALSE);
-	for (i = 0; i < length; i++)
-		nm_str_buf_append_printf (&strbuf, "%u;", (guint) data[i]);
-	nm_keyfile_plugin_kf_set_value (kf, group, key, nm_str_buf_get_str (&strbuf));
+    nm_auto_str_buf NMStrBuf strbuf = {};
+    gsize                    i;
+
+    g_return_if_fail(kf);
+    g_return_if_fail(!length || data);
+    g_return_if_fail(group && group[0]);
+    g_return_if_fail(key && key[0]);
+
+    nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE);
+    for (i = 0; i < length; i++)
+        nm_str_buf_append_printf(&strbuf, "%u;", (guint) data[i]);
+    nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf));
 }
 
-#define DEFINE_KF_WRAPPER_GET(fcn_name, get_ctype, key_file_get_fcn) \
-get_ctype \
-fcn_name (GKeyFile *kf, \
-          const char *group, \
-          const char *key, \
-          GError **error) \
-{ \
-	get_ctype val; \
-	const char *alias; \
-	GError *local = NULL; \
-\
-	val = key_file_get_fcn (kf, group, key, &local); \
-	if (nm_g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \
-		alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
-		if (alias) { \
-			g_clear_error (&local); \
-			val = key_file_get_fcn (kf, alias, key, &local); \
-		} \
-	} \
-	if (local) \
-		g_propagate_error (error, local); \
-	return val; \
-}
-
-DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_string,  char *,   g_key_file_get_string);
-DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_boolean, gboolean, g_key_file_get_boolean);
-DEFINE_KF_WRAPPER_GET (nm_keyfile_plugin_kf_get_value,   char *,   g_key_file_get_value);
-
-#define DEFINE_KF_WRAPPER_SET(fcn_name, set_ctype, key_file_set_fcn) \
-void \
-fcn_name (GKeyFile *kf, \
-          const char *group, \
-          const char *key, \
-          set_ctype value) \
-{ \
-	const char *alias; \
-\
-	alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
-	key_file_set_fcn (kf, alias ?: group, key, value); \
-}
-
-DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_string,  const char *, g_key_file_set_string);
-DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_boolean, gboolean,     g_key_file_set_boolean);
-DEFINE_KF_WRAPPER_SET (nm_keyfile_plugin_kf_set_value,   const char *, g_key_file_set_value);
+#define DEFINE_KF_WRAPPER_GET(fcn_name, get_ctype, key_file_get_fcn)                         \
+    get_ctype fcn_name(GKeyFile *kf, const char *group, const char *key, GError **error)     \
+    {                                                                                        \
+        get_ctype   val;                                                                     \
+        const char *alias;                                                                   \
+        GError *    local = NULL;                                                            \
+                                                                                             \
+        val = key_file_get_fcn(kf, group, key, &local);                                      \
+        if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \
+            alias = nm_keyfile_plugin_get_alias_for_setting_name(group);                     \
+            if (alias) {                                                                     \
+                g_clear_error(&local);                                                       \
+                val = key_file_get_fcn(kf, alias, key, &local);                              \
+            }                                                                                \
+        }                                                                                    \
+        if (local)                                                                           \
+            g_propagate_error(error, local);                                                 \
+        return val;                                                                          \
+    }
+
+DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_string, char *, g_key_file_get_string);
+DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_boolean, gboolean, g_key_file_get_boolean);
+DEFINE_KF_WRAPPER_GET(nm_keyfile_plugin_kf_get_value, char *, g_key_file_get_value);
+
+#define DEFINE_KF_WRAPPER_SET(fcn_name, set_ctype, key_file_set_fcn)                 \
+    void fcn_name(GKeyFile *kf, const char *group, const char *key, set_ctype value) \
+    {                                                                                \
+        const char *alias;                                                           \
+                                                                                     \
+        alias = nm_keyfile_plugin_get_alias_for_setting_name(group);                 \
+        key_file_set_fcn(kf, alias ?: group, key, value);                            \
+    }
+
+DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_string, const char *, g_key_file_set_string);
+DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_boolean, gboolean, g_key_file_set_boolean);
+DEFINE_KF_WRAPPER_SET(nm_keyfile_plugin_kf_set_value, const char *, g_key_file_set_value);
 
 gint64
-nm_keyfile_plugin_kf_get_int64 (GKeyFile *kf,
-                                const char *group,
-                                const char *key,
-                                guint base,
-                                gint64 min,
-                                gint64 max,
-                                gint64 fallback,
-                                GError **error)
+nm_keyfile_plugin_kf_get_int64(GKeyFile *  kf,
+                               const char *group,
+                               const char *key,
+                               guint       base,
+                               gint64      min,
+                               gint64      max,
+                               gint64      fallback,
+                               GError **   error)
 {
-	gs_free char *s = NULL;
-	int errsv;
-	gint64 v;
-
-	s = nm_keyfile_plugin_kf_get_value (kf, group, key, error);
-	if (!s) {
-		errno = ENODATA;
-		return fallback;
-	}
-
-	v = _nm_utils_ascii_str_to_int64 (s, base, min, max, fallback);
-	errsv = errno;
-	if (   errsv != 0
-	    && error) {
-		g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-		             _("value is not an integer in range [%lld, %lld]"),
-		             (long long) min, (long long) max);
-		errno = errsv;
-	}
-	return v;
+    gs_free char *s = NULL;
+    int           errsv;
+    gint64        v;
+
+    s = nm_keyfile_plugin_kf_get_value(kf, group, key, error);
+    if (!s) {
+        errno = ENODATA;
+        return fallback;
+    }
+
+    v     = _nm_utils_ascii_str_to_int64(s, base, min, max, fallback);
+    errsv = errno;
+    if (errsv != 0 && error) {
+        g_set_error(error,
+                    G_KEY_FILE_ERROR,
+                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                    _("value is not an integer in range [%lld, %lld]"),
+                    (long long) min,
+                    (long long) max);
+        errno = errsv;
+    }
+    return v;
 }
 
 char **
-nm_keyfile_plugin_kf_get_keys (GKeyFile *kf,
-                               const char *group,
-                               gsize *out_length,
-                               GError **error)
+nm_keyfile_plugin_kf_get_keys(GKeyFile *kf, const char *group, gsize *out_length, GError **error)
 {
-	char **keys;
-	const char *alias;
-	GError *local = NULL;
-	gsize l;
-
-	keys = g_key_file_get_keys (kf, group, &l, &local);
-	if (nm_g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-		alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
-		if (alias) {
-			g_clear_error (&local);
-			keys = g_key_file_get_keys (kf, alias, &l, error ? &local : NULL);
-		}
-	}
-	nm_assert ((!local) != (!keys));
-	if (!keys)
-		l = 0;
-	nm_assert (l == NM_PTRARRAY_LEN (keys));
-	NM_SET_OUT (out_length, l);
-	if (local)
-		g_propagate_error (error, local);
-	return keys;
+    char **     keys;
+    const char *alias;
+    GError *    local = NULL;
+    gsize       l;
+
+    keys = g_key_file_get_keys(kf, group, &l, &local);
+    if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+        alias = nm_keyfile_plugin_get_alias_for_setting_name(group);
+        if (alias) {
+            g_clear_error(&local);
+            keys = g_key_file_get_keys(kf, alias, &l, error ? &local : NULL);
+        }
+    }
+    nm_assert((!local) != (!keys));
+    if (!keys)
+        l = 0;
+    nm_assert(l == NM_PTRARRAY_LEN(keys));
+    NM_SET_OUT(out_length, l);
+    if (local)
+        g_propagate_error(error, local);
+    return keys;
 }
 
 gboolean
-nm_keyfile_plugin_kf_has_key (GKeyFile *kf,
-                              const char *group,
-                              const char *key,
-                              GError **error)
+nm_keyfile_plugin_kf_has_key(GKeyFile *kf, const char *group, const char *key, GError **error)
 {
-	gboolean has;
-	const char *alias;
-	GError *local = NULL;
-
-	has = g_key_file_has_key (kf, group, key, &local);
-	if (nm_g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
-		alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
-		if (alias) {
-			g_clear_error (&local);
-			has = g_key_file_has_key (kf, alias, key, &local);
-		}
-	}
-	if (local)
-		g_propagate_error (error, local);
-	return has;
+    gboolean    has;
+    const char *alias;
+    GError *    local = NULL;
+
+    has = g_key_file_has_key(kf, group, key, &local);
+    if (nm_g_error_matches(local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
+        alias = nm_keyfile_plugin_get_alias_for_setting_name(group);
+        if (alias) {
+            g_clear_error(&local);
+            has = g_key_file_has_key(kf, alias, key, &local);
+        }
+    }
+    if (local)
+        g_propagate_error(error, local);
+    return has;
 }
 
 /*****************************************************************************/
 
 void
-_nm_keyfile_copy (GKeyFile *dst, GKeyFile *src)
+_nm_keyfile_copy(GKeyFile *dst, GKeyFile *src)
 {
-	gs_strfreev char **groups = NULL;
-	guint g, k;
-
-	groups = g_key_file_get_groups (src, NULL);
-	for (g = 0; groups && groups[g]; g++) {
-		const char *group = groups[g];
-		gs_strfreev char **keys = NULL;
-
-		keys = g_key_file_get_keys (src, group, NULL, NULL);
-		if (!keys)
-			continue;
-
-		for (k = 0; keys[k]; k++) {
-			const char *key = keys[k];
-			gs_free char *value = NULL;
-
-			value = g_key_file_get_value (src, group, key, NULL);
-			if (value)
-				g_key_file_set_value (dst, group, key, value);
-			else
-				g_key_file_remove_key (dst, group, key, NULL);
-		}
-	}
+    gs_strfreev char **groups = NULL;
+    guint              g, k;
+
+    groups = g_key_file_get_groups(src, NULL);
+    for (g = 0; groups && groups[g]; g++) {
+        const char *       group = groups[g];
+        gs_strfreev char **keys  = NULL;
+
+        keys = g_key_file_get_keys(src, group, NULL, NULL);
+        if (!keys)
+            continue;
+
+        for (k = 0; keys[k]; k++) {
+            const char *  key   = keys[k];
+            gs_free char *value = NULL;
+
+            value = g_key_file_get_value(src, group, key, NULL);
+            if (value)
+                g_key_file_set_value(dst, group, key, value);
+            else
+                g_key_file_remove_key(dst, group, key, NULL);
+        }
+    }
 }
 
 /*****************************************************************************/
 
 gboolean
-_nm_keyfile_a_contains_all_in_b (GKeyFile *kf_a, GKeyFile *kf_b)
+_nm_keyfile_a_contains_all_in_b(GKeyFile *kf_a, GKeyFile *kf_b)
 {
-	gs_strfreev char **groups = NULL;
-	guint i, j;
-
-	if (kf_a == kf_b)
-		return TRUE;
-	if (!kf_a || !kf_b)
-		return FALSE;
-
-	groups = g_key_file_get_groups (kf_a, NULL);
-	for (i = 0; groups && groups[i]; i++) {
-		gs_strfreev char **keys = NULL;
-
-		keys = g_key_file_get_keys (kf_a, groups[i], NULL, NULL);
-		if (!keys)
-			continue;
-
-		for (j = 0; keys[j]; j++) {
-			gs_free char *key_a = g_key_file_get_value (kf_a, groups[i], keys[j], NULL);
-			gs_free char *key_b = g_key_file_get_value (kf_b, groups[i], keys[j], NULL);
-
-			if (g_strcmp0 (key_a, key_b) != 0)
-				return FALSE;
-		}
-	}
-	return TRUE;
+    gs_strfreev char **groups = NULL;
+    guint              i, j;
+
+    if (kf_a == kf_b)
+        return TRUE;
+    if (!kf_a || !kf_b)
+        return FALSE;
+
+    groups = g_key_file_get_groups(kf_a, NULL);
+    for (i = 0; groups && groups[i]; i++) {
+        gs_strfreev char **keys = NULL;
+
+        keys = g_key_file_get_keys(kf_a, groups[i], NULL, NULL);
+        if (!keys)
+            continue;
+
+        for (j = 0; keys[j]; j++) {
+            gs_free char *key_a = g_key_file_get_value(kf_a, groups[i], keys[j], NULL);
+            gs_free char *key_b = g_key_file_get_value(kf_b, groups[i], keys[j], NULL);
+
+            if (g_strcmp0(key_a, key_b) != 0)
+                return FALSE;
+        }
+    }
+    return TRUE;
 }
 
 static gboolean
-_nm_keyfile_equals_ordered (GKeyFile *kf_a, GKeyFile *kf_b)
+_nm_keyfile_equals_ordered(GKeyFile *kf_a, GKeyFile *kf_b)
 {
-	gs_strfreev char **groups = NULL;
-	gs_strfreev char **groups_b = NULL;
-	guint i, j;
-
-	if (kf_a == kf_b)
-		return TRUE;
-	if (!kf_a || !kf_b)
-		return FALSE;
-
-	groups = g_key_file_get_groups (kf_a, NULL);
-	groups_b = g_key_file_get_groups (kf_b, NULL);
-	if (!groups && !groups_b)
-		return TRUE;
-	if (!groups || !groups_b)
-		return FALSE;
-	for (i = 0; groups[i] && groups_b[i] && !strcmp (groups[i], groups_b[i]); i++)
-		;
-	if (groups[i] || groups_b[i])
-		return FALSE;
-
-	for (i = 0; groups[i]; i++) {
-		gs_strfreev char **keys = NULL;
-		gs_strfreev char **keys_b = NULL;
-
-		keys = g_key_file_get_keys (kf_a, groups[i], NULL, NULL);
-		keys_b = g_key_file_get_keys (kf_b, groups[i], NULL, NULL);
-
-		if ((!keys) != (!keys_b))
-			return FALSE;
-		if (!keys)
-			continue;
-
-		for (j = 0; keys[j] && keys_b[j] && !strcmp (keys[j], keys_b[j]); j++)
-			;
-		if (keys[j] || keys_b[j])
-			return FALSE;
-
-		for (j = 0; keys[j]; j++) {
-			gs_free char *key_a = g_key_file_get_value (kf_a, groups[i], keys[j], NULL);
-			gs_free char *key_b = g_key_file_get_value (kf_b, groups[i], keys[j], NULL);
-
-			if (g_strcmp0 (key_a, key_b) != 0)
-				return FALSE;
-		}
-	}
-	return TRUE;
+    gs_strfreev char **groups   = NULL;
+    gs_strfreev char **groups_b = NULL;
+    guint              i, j;
+
+    if (kf_a == kf_b)
+        return TRUE;
+    if (!kf_a || !kf_b)
+        return FALSE;
+
+    groups   = g_key_file_get_groups(kf_a, NULL);
+    groups_b = g_key_file_get_groups(kf_b, NULL);
+    if (!groups && !groups_b)
+        return TRUE;
+    if (!groups || !groups_b)
+        return FALSE;
+    for (i = 0; groups[i] && groups_b[i] && !strcmp(groups[i], groups_b[i]); i++)
+        ;
+    if (groups[i] || groups_b[i])
+        return FALSE;
+
+    for (i = 0; groups[i]; i++) {
+        gs_strfreev char **keys   = NULL;
+        gs_strfreev char **keys_b = NULL;
+
+        keys   = g_key_file_get_keys(kf_a, groups[i], NULL, NULL);
+        keys_b = g_key_file_get_keys(kf_b, groups[i], NULL, NULL);
+
+        if ((!keys) != (!keys_b))
+            return FALSE;
+        if (!keys)
+            continue;
+
+        for (j = 0; keys[j] && keys_b[j] && !strcmp(keys[j], keys_b[j]); j++)
+            ;
+        if (keys[j] || keys_b[j])
+            return FALSE;
+
+        for (j = 0; keys[j]; j++) {
+            gs_free char *key_a = g_key_file_get_value(kf_a, groups[i], keys[j], NULL);
+            gs_free char *key_b = g_key_file_get_value(kf_b, groups[i], keys[j], NULL);
+
+            if (g_strcmp0(key_a, key_b) != 0)
+                return FALSE;
+        }
+    }
+    return TRUE;
 }
 
 gboolean
-_nm_keyfile_equals (GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order)
+_nm_keyfile_equals(GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order)
 {
-	if (!consider_order) {
-		return    _nm_keyfile_a_contains_all_in_b (kf_a, kf_b)
-		       && _nm_keyfile_a_contains_all_in_b (kf_b, kf_a);
-	} else {
-		return _nm_keyfile_equals_ordered (kf_a, kf_b);
-	}
+    if (!consider_order) {
+        return _nm_keyfile_a_contains_all_in_b(kf_a, kf_b)
+               && _nm_keyfile_a_contains_all_in_b(kf_b, kf_a);
+    } else {
+        return _nm_keyfile_equals_ordered(kf_a, kf_b);
+    }
 }
 
 gboolean
-_nm_keyfile_has_values (GKeyFile *keyfile)
+_nm_keyfile_has_values(GKeyFile *keyfile)
 {
-	gs_strfreev char **groups = NULL;
+    gs_strfreev char **groups = NULL;
 
-	g_return_val_if_fail (keyfile, FALSE);
+    g_return_val_if_fail(keyfile, FALSE);
 
-	groups = g_key_file_get_groups (keyfile, NULL);
-	return groups && groups[0];
+    groups = g_key_file_get_groups(keyfile, NULL);
+    return groups && groups[0];
 }
 
 /*****************************************************************************/
 
 static const char *
-_keyfile_key_encode (const char *name,
-                     char **out_to_free)
+_keyfile_key_encode(const char *name, char **out_to_free)
 {
-	gsize len, i;
-	GString *str;
-
-	nm_assert (name);
-	nm_assert (out_to_free && !*out_to_free);
-
-	/* See g_key_file_is_key_name().
-	 *
-	 * GKeyFile allows all UTF-8 characters (even non-well formed sequences),
-	 * except:
-	 *  - no empty keys
-	 *  - no leading/trailing ' '
-	 *  - no '=', '[', ']'
-	 *
-	 * We do something more strict here. All non-ASCII characters, all non-printable
-	 * characters, and all invalid characters are escaped with "\\XX".
-	 *
-	 * We don't escape \\, unless it is followed by two hex digits.
-	 */
-
-	if (!name[0]) {
-		/* empty keys are are backslash encoded. Note that usually
-		 * \\00 is not a valid encode, the only exception is the empty
-		 * word. */
-		return "\\00";
-	}
-
-	/* find the first character that needs escaping. */
-	i = 0;
-	if (name[0] != ' ') {
-		for (;; i++) {
-			const guchar ch = (guchar) name[i];
-
-			if (ch == '\0')
-				return name;
-
-			if (   ch < 0x20
-			    || ch >= 127
-			    || NM_IN_SET (ch, '=', '[', ']')
-			    || (   ch == '\\'
-			        && g_ascii_isxdigit (name[i + 1])
-			        && g_ascii_isxdigit (name[i + 2]))
-			    || (   ch == ' '
-			        && name[i + 1] == '\0'))
-				break;
-		}
-	} else if (name[1] == '\0')
-		return "\\20";
-
-	len = i + strlen (&name[i]);
-	nm_assert (len == strlen (name));
-	str = g_string_sized_new (len + 15);
-
-	if (name[0] == ' ') {
-		nm_assert (i == 0);
-		g_string_append (str, "\\20");
-		i = 1;
-	} else
-		g_string_append_len (str, name, i);
-
-	for (;; i++) {
-		const guchar ch = (guchar) name[i];
-
-		if (ch == '\0')
-			break;
-
-		if (   ch < 0x20
-		    || ch >= 127
-		    || NM_IN_SET (ch, '=', '[', ']')
-		    || (   ch == '\\'
-		        && g_ascii_isxdigit (name[i + 1])
-		        && g_ascii_isxdigit (name[i + 2]))
-		    || (   ch == ' '
-		        && name[i + 1] == '\0'))
-			g_string_append_printf (str, "\\%02X", ch);
-		else
-			g_string_append_c (str, (char) ch);
-	}
-
-	return (*out_to_free = g_string_free (str, FALSE));
+    NMStrBuf str;
+    gsize    len;
+    gsize    i;
+
+    nm_assert(name);
+    nm_assert(out_to_free && !*out_to_free);
+
+    /* See g_key_file_is_key_name().
+     *
+     * GKeyFile allows all UTF-8 characters (even non-well formed sequences),
+     * except:
+     *  - no empty keys
+     *  - no leading/trailing ' '
+     *  - no '=', '[', ']'
+     *
+     * We do something more strict here. All non-ASCII characters, all non-printable
+     * characters, and all invalid characters are escaped with "\\XX".
+     *
+     * We don't escape \\, unless it is followed by two hex digits.
+     */
+
+    if (!name[0]) {
+        /* empty keys are backslash encoded. Note that usually
+         * \\00 is not a valid encode, the only exception is the empty
+         * word. */
+        return "\\00";
+    }
+
+    /* find the first character that needs escaping. */
+    i = 0;
+    if (name[0] != ' ') {
+        for (;; i++) {
+            const guchar ch = (guchar) name[i];
+
+            if (ch == '\0')
+                return name;
+
+            if (ch < 0x20 || ch >= 127 || NM_IN_SET(ch, '=', '[', ']')
+                || (ch == '\\' && g_ascii_isxdigit(name[i + 1]) && g_ascii_isxdigit(name[i + 2]))
+                || (ch == ' ' && name[i + 1] == '\0'))
+                break;
+        }
+    } else if (name[1] == '\0')
+        return "\\20";
+
+    len = i + strlen(&name[i]);
+    nm_assert(len == strlen(name));
+
+    nm_str_buf_init(&str, len + 15u, FALSE);
+
+    if (name[0] == ' ') {
+        nm_assert(i == 0);
+        nm_str_buf_append(&str, "\\20");
+        i = 1;
+    } else
+        nm_str_buf_append_len(&str, name, i);
+
+    for (;; i++) {
+        const guchar ch = (guchar) name[i];
+
+        if (ch == '\0')
+            break;
+
+        if (ch < 0x20 || ch >= 127 || NM_IN_SET(ch, '=', '[', ']')
+            || (ch == '\\' && g_ascii_isxdigit(name[i + 1]) && g_ascii_isxdigit(name[i + 2]))
+            || (ch == ' ' && name[i + 1] == '\0')) {
+            nm_str_buf_append_c(&str, '\\');
+            nm_str_buf_append_c_hex(&str, ch, TRUE);
+        } else
+            nm_str_buf_append_c(&str, (char) ch);
+    }
+
+    return (*out_to_free = nm_str_buf_finalize(&str, NULL));
 }
 
 static const char *
-_keyfile_key_decode (const char *key,
-                     char **out_to_free)
+_keyfile_key_decode(const char *key, char **out_to_free)
 {
-	gsize i, len;
-	GString *str;
-
-	nm_assert (key);
-	nm_assert (out_to_free && !*out_to_free);
-
-	if (!key[0])
-		return "";
-
-	for (i = 0; TRUE; i++) {
-		const char ch = key[i];
-
-		if (ch == '\0')
-			return key;
-		if (   ch == '\\'
-		    && g_ascii_isxdigit (key[i + 1])
-		    && g_ascii_isxdigit (key[i + 2]))
-			break;
-	}
-
-	len = i + strlen (&key[i]);
-
-	if (   len == 3
-	    && nm_streq (key, "\\00"))
-		return "";
-
-	nm_assert (len == strlen (key));
-	str = g_string_sized_new (len + 3);
-
-	g_string_append_len (str, key, i);
-	for (;;) {
-		const char ch = key[i];
-		char ch1, ch2;
-		unsigned v;
-
-		if (ch == '\0')
-			break;
-
-		if (   ch == '\\'
-		    && g_ascii_isxdigit ((ch1 = key[i + 1]))
-		    && g_ascii_isxdigit ((ch2 = key[i + 2]))) {
-			v = (g_ascii_xdigit_value (ch1) << 4) + g_ascii_xdigit_value (ch2);
-			if (v != 0) {
-				g_string_append_c (str, (char) v);
-				i += 3;
-				continue;
-			}
-		}
-		g_string_append_c (str, ch);
-		i++;
-	}
-
-	return (*out_to_free = g_string_free (str, FALSE));
+    char *out;
+    gsize len;
+    gsize i;
+    gsize j;
+
+    nm_assert(key);
+    nm_assert(out_to_free && !*out_to_free);
+
+    if (!key[0])
+        return "";
+
+    for (i = 0; TRUE; i++) {
+        const char ch = key[i];
+
+        if (ch == '\0')
+            return key;
+        if (ch == '\\' && g_ascii_isxdigit(key[i + 1]) && g_ascii_isxdigit(key[i + 2]))
+            break;
+    }
+
+    len = i + strlen(&key[i]);
+
+    if (len == 3 && nm_streq(key, "\\00"))
+        return "";
+
+    nm_assert(len == strlen(key));
+
+    out = g_new(char, len + 1u);
+
+    memcpy(out, key, sizeof(char) * i);
+
+    j = i;
+    for (;;) {
+        const char ch = key[i];
+        char       ch1, ch2;
+        unsigned   v;
+
+        if (ch == '\0')
+            break;
+
+        if (ch == '\\' && g_ascii_isxdigit((ch1 = key[i + 1]))
+            && g_ascii_isxdigit((ch2 = key[i + 2]))) {
+            v = (g_ascii_xdigit_value(ch1) << 4) + g_ascii_xdigit_value(ch2);
+            if (v != 0) {
+                out[j++] = (char) v;
+                i += 3;
+                continue;
+            }
+        }
+        out[j++] = ch;
+        i++;
+    }
+
+    nm_assert(j <= len);
+    out[j] = '\0';
+    return (*out_to_free = out);
 }
 
 /*****************************************************************************/
 
 const char *
-nm_keyfile_key_encode (const char *name,
-                       char **out_to_free)
+nm_keyfile_key_encode(const char *name, char **out_to_free)
 {
-	const char *key;
+    const char *key;
 
-	key = _keyfile_key_encode (name, out_to_free);
+    key = _keyfile_key_encode(name, out_to_free);
 #if NM_MORE_ASSERTS > 5
-	nm_assert (key);
-	nm_assert (!*out_to_free || key == *out_to_free);
-	nm_assert (!*out_to_free || !nm_streq0 (name, key));
-	{
-		gs_free char *to_free2 = NULL;
-		const char *name2;
-
-		name2 = _keyfile_key_decode (key, &to_free2);
-		/* name2, the result of encode()+decode() is identical to name.
-		 * That is because
-		 *   - encode() is a injective function.
-		 *   - decode() is a surjective function, however for output
-		 *     values of encode() is behaves injective too. */
-		nm_assert (nm_streq0 (name2, name));
-	}
+    nm_assert(key);
+    nm_assert(!*out_to_free || key == *out_to_free);
+    nm_assert(!*out_to_free || !nm_streq0(name, key));
+    {
+        gs_free char *to_free2 = NULL;
+        const char *  name2;
+
+        name2 = _keyfile_key_decode(key, &to_free2);
+        /* name2, the result of encode()+decode() is identical to name.
+         * That is because
+         *   - encode() is a injective function.
+         *   - decode() is a surjective function, however for output
+         *     values of encode() is behaves injective too. */
+        nm_assert(nm_streq0(name2, name));
+    }
 #endif
-	return key;
+    return key;
 }
 
 const char *
-nm_keyfile_key_decode (const char *key,
-                       char **out_to_free)
+nm_keyfile_key_decode(const char *key, char **out_to_free)
 {
-	const char *name;
+    const char *name;
 
-	name = _keyfile_key_decode (key, out_to_free);
+    name = _keyfile_key_decode(key, out_to_free);
 #if NM_MORE_ASSERTS > 5
-	nm_assert (name);
-	nm_assert (!*out_to_free || name == *out_to_free);
-	{
-		gs_free char *to_free2 = NULL;
-		const char *key2;
-
-		key2 = _keyfile_key_encode (name, &to_free2);
-		/* key2, the result of decode+encode may not be idential
-		 * to the original key. That is, decode() is a surjective
-		 * function mapping different keys to the same name.
-		 * However, decode() behaves injective for input that
-		 * are valid output of encode(). */
-		nm_assert (key2);
-	}
+    nm_assert(name);
+    nm_assert(!*out_to_free || name == *out_to_free);
+    {
+        gs_free char *to_free2 = NULL;
+        const char *  key2;
+
+        key2 = _keyfile_key_encode(name, &to_free2);
+        /* key2, the result of decode+encode may not be identical
+         * to the original key. That is, decode() is a surjective
+         * function mapping different keys to the same name.
+         * However, decode() behaves injective for input that
+         * are valid output of encode(). */
+        nm_assert(key2);
+    }
 #endif
-	return name;
+    return name;
 }
diff --git a/libnm-core/nm-keyfile/nm-keyfile-utils.h b/libnm-core/nm-keyfile/nm-keyfile-utils.h
index 4764311b..efad8317 100644
--- a/libnm-core/nm-keyfile/nm-keyfile-utils.h
+++ b/libnm-core/nm-keyfile/nm-keyfile-utils.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2010 - 2015 Red Hat, Inc.
  */
@@ -6,8 +6,8 @@
 #ifndef __NM_KEYFILE_UTILS_H__
 #define __NM_KEYFILE_UTILS_H__
 
-#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL)
-#error Cannot use this header.
+#if !((NETWORKMANAGER_COMPILATION) &NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL)
+    #error Cannot use this header.
 #endif
 
 /*****************************************************************************/
@@ -19,55 +19,77 @@
 #define NM_KEYFILE_GROUP_VPN_SECRETS          "vpn-secrets"
 #define NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER "wireguard-peer."
 
-#define nm_keyfile_error_is_not_found(error) \
-	nm_g_error_matches (error, \
-	                    G_KEY_FILE_ERROR, \
-	                    G_KEY_FILE_ERROR_GROUP_NOT_FOUND, \
-	                    G_KEY_FILE_ERROR_KEY_NOT_FOUND)
+#define nm_keyfile_error_is_not_found(error)             \
+    nm_g_error_matches(error,                            \
+                       G_KEY_FILE_ERROR,                 \
+                       G_KEY_FILE_ERROR_GROUP_NOT_FOUND, \
+                       G_KEY_FILE_ERROR_KEY_NOT_FOUND)
 
-const char *nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name);
+const char *nm_keyfile_plugin_get_alias_for_setting_name(const char *setting_name);
 
-const char *nm_keyfile_plugin_get_setting_name_for_alias (const char *alias);
+const char *nm_keyfile_plugin_get_setting_name_for_alias(const char *alias);
 
 /*****************************************************************************/
 
-guint   *nm_keyfile_plugin_kf_get_integer_list_uint (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error);
-char   **nm_keyfile_plugin_kf_get_string_list       (GKeyFile *kf, const char *group, const char *key, gsize *out_length, GError **error);
-char    *nm_keyfile_plugin_kf_get_string            (GKeyFile *kf, const char *group, const char *key, GError **error);
-gboolean nm_keyfile_plugin_kf_get_boolean           (GKeyFile *kf, const char *group, const char *key, GError **error);
-char    *nm_keyfile_plugin_kf_get_value             (GKeyFile *kf, const char *group, const char *key, GError **error);
-
-void nm_keyfile_plugin_kf_set_integer_list_uint8 (GKeyFile *kf, const char *group, const char *key, const guint8     *list, gsize length);
-void nm_keyfile_plugin_kf_set_integer_list_uint  (GKeyFile *kf, const char *group, const char *key, const guint      *list, gsize length);
-void nm_keyfile_plugin_kf_set_string_list        (GKeyFile *kf, const char *group, const char *key, const char *const*list, gsize length);
-
-void nm_keyfile_plugin_kf_set_string       (GKeyFile *kf, const char *group, const char *key, const char *value);
-void nm_keyfile_plugin_kf_set_boolean      (GKeyFile *kf, const char *group, const char *key, gboolean    value);
-void nm_keyfile_plugin_kf_set_value        (GKeyFile *kf, const char *group, const char *key, const char *value);
-
-gint64 nm_keyfile_plugin_kf_get_int64 (GKeyFile *kf,
-                                       const char *group,
-                                       const char *key,
-                                       guint base,
-                                       gint64 min,
-                                       gint64 max,
-                                       gint64 fallback,
-                                       GError **error);
-
-char **nm_keyfile_plugin_kf_get_keys (GKeyFile *kf,
+guint *nm_keyfile_plugin_kf_get_integer_list_uint(GKeyFile *  kf,
+                                                  const char *group,
+                                                  const char *key,
+                                                  gsize *     out_length,
+                                                  GError **   error);
+char **nm_keyfile_plugin_kf_get_string_list(GKeyFile *  kf,
+                                            const char *group,
+                                            const char *key,
+                                            gsize *     out_length,
+                                            GError **   error);
+char *
+nm_keyfile_plugin_kf_get_string(GKeyFile *kf, const char *group, const char *key, GError **error);
+gboolean
+nm_keyfile_plugin_kf_get_boolean(GKeyFile *kf, const char *group, const char *key, GError **error);
+char *
+nm_keyfile_plugin_kf_get_value(GKeyFile *kf, const char *group, const char *key, GError **error);
+
+void nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile *    kf,
+                                                 const char *  group,
+                                                 const char *  key,
+                                                 const guint8 *list,
+                                                 gsize         length);
+void nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile *   kf,
+                                                const char * group,
+                                                const char * key,
+                                                const guint *list,
+                                                gsize        length);
+void nm_keyfile_plugin_kf_set_string_list(GKeyFile *         kf,
+                                          const char *       group,
+                                          const char *       key,
+                                          const char *const *list,
+                                          gsize              length);
+
+void nm_keyfile_plugin_kf_set_string(GKeyFile *  kf,
+                                     const char *group,
+                                     const char *key,
+                                     const char *value);
+void
+nm_keyfile_plugin_kf_set_boolean(GKeyFile *kf, const char *group, const char *key, gboolean value);
+void
+nm_keyfile_plugin_kf_set_value(GKeyFile *kf, const char *group, const char *key, const char *value);
+
+gint64 nm_keyfile_plugin_kf_get_int64(GKeyFile *  kf,
                                       const char *group,
-                                      gsize *out_length,
-                                      GError **error);
+                                      const char *key,
+                                      guint       base,
+                                      gint64      min,
+                                      gint64      max,
+                                      gint64      fallback,
+                                      GError **   error);
 
-gboolean nm_keyfile_plugin_kf_has_key (GKeyFile *kf,
-                                       const char *group,
-                                       const char *key,
-                                       GError **error);
+char **
+nm_keyfile_plugin_kf_get_keys(GKeyFile *kf, const char *group, gsize *out_length, GError **error);
 
-const char *nm_keyfile_key_encode (const char *name,
-                                   char **out_to_free);
+gboolean
+nm_keyfile_plugin_kf_has_key(GKeyFile *kf, const char *group, const char *key, GError **error);
 
-const char *nm_keyfile_key_decode (const char *key,
-                                   char **out_to_free);
+const char *nm_keyfile_key_encode(const char *name, char **out_to_free);
 
-#endif  /* __NM_KEYFILE_UTILS_H__ */
+const char *nm_keyfile_key_decode(const char *key, char **out_to_free);
+
+#endif /* __NM_KEYFILE_UTILS_H__ */
diff --git a/libnm-core/nm-keyfile/nm-keyfile.c b/libnm-core/nm-keyfile/nm-keyfile.c
index 79f9c5f9..395af1db 100644
--- a/libnm-core/nm-keyfile/nm-keyfile.c
+++ b/libnm-core/nm-keyfile/nm-keyfile.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2008 - 2009 Novell, Inc.
  * Copyright (C) 2008 - 2017 Red Hat, Inc.
@@ -16,6 +16,7 @@
 #include <arpa/inet.h>
 #include <linux/pkt_sched.h>
 
+#include "nm-glib-aux/nm-str-buf.h"
 #include "nm-glib-aux/nm-secret-utils.h"
 #include "systemd/nm-sd-utils-shared.h"
 #include "nm-libnm-core-intern/nm-common-macros.h"
@@ -29,137 +30,131 @@
 typedef struct _ParseInfoProperty ParseInfoProperty;
 
 typedef struct {
-	NMConnection *connection;
-	GKeyFile *keyfile;
-	const char *base_dir;
-	NMKeyfileReadHandler read_handler;
-	void *user_data;
-	GError *error;
-	const char *group;
-	NMSetting *setting;
+    NMConnection *       connection;
+    GKeyFile *           keyfile;
+    const char *         base_dir;
+    NMKeyfileReadHandler read_handler;
+    void *               user_data;
+    GError *             error;
+    const char *         group;
+    NMSetting *          setting;
 } KeyfileReaderInfo;
 
 typedef struct {
-	NMConnection *connection;
-	GKeyFile *keyfile;
-	GError *error;
-	NMKeyfileWriteHandler write_handler;
-	void *user_data;
+    NMConnection *        connection;
+    GKeyFile *            keyfile;
+    GError *              error;
+    NMKeyfileWriteHandler write_handler;
+    void *                user_data;
 } KeyfileWriterInfo;
 
 /*****************************************************************************/
 
 static void
-_key_file_handler_data_init (NMKeyfileHandlerData *handler_data,
-                             NMKeyfileHandlerType handler_type,
-                             const char *kf_group_name,
-                             const char *kf_key,
-                             NMSetting *cur_setting,
-                             const char *cur_property,
-                             GError **p_error)
+_key_file_handler_data_init(NMKeyfileHandlerData *handler_data,
+                            NMKeyfileHandlerType  handler_type,
+                            const char *          kf_group_name,
+                            const char *          kf_key,
+                            NMSetting *           cur_setting,
+                            const char *          cur_property,
+                            GError **             p_error)
 {
-	nm_assert (handler_data);
-	nm_assert (p_error && !*p_error);
-
-	handler_data->type = handler_type;
-	handler_data->p_error = p_error;
-	handler_data->kf_group_name = kf_group_name;
-	handler_data->kf_key = kf_key;
-	handler_data->cur_setting = cur_setting;
-	handler_data->cur_property = cur_property;
+    nm_assert(handler_data);
+    nm_assert(p_error && !*p_error);
+
+    handler_data->type          = handler_type;
+    handler_data->p_error       = p_error;
+    handler_data->kf_group_name = kf_group_name;
+    handler_data->kf_key        = kf_key;
+    handler_data->cur_setting   = cur_setting;
+    handler_data->cur_property  = cur_property;
 }
 
 static void
-_key_file_handler_data_init_read (NMKeyfileHandlerData *handler_data,
-                                  NMKeyfileHandlerType handler_type,
-                                  KeyfileReaderInfo *info,
-                                  const char *kf_key,
-                                  const char *cur_property)
+_key_file_handler_data_init_read(NMKeyfileHandlerData *handler_data,
+                                 NMKeyfileHandlerType  handler_type,
+                                 KeyfileReaderInfo *   info,
+                                 const char *          kf_key,
+                                 const char *          cur_property)
 {
-	_key_file_handler_data_init (handler_data,
-	                             handler_type,
-	                             info->group,
-	                             kf_key,
-	                             info->setting,
-	                             cur_property,
-	                             &info->error);
+    _key_file_handler_data_init(handler_data,
+                                handler_type,
+                                info->group,
+                                kf_key,
+                                info->setting,
+                                cur_property,
+                                &info->error);
 }
 
 static void
-_key_file_handler_data_init_write (NMKeyfileHandlerData *handler_data,
-                                   NMKeyfileHandlerType handler_type,
-                                   KeyfileWriterInfo *info,
-                                   const char *kf_group,
-                                   const char *kf_key,
-                                   NMSetting *cur_setting,
-                                   const char *cur_property)
+_key_file_handler_data_init_write(NMKeyfileHandlerData *handler_data,
+                                  NMKeyfileHandlerType  handler_type,
+                                  KeyfileWriterInfo *   info,
+                                  const char *          kf_group,
+                                  const char *          kf_key,
+                                  NMSetting *           cur_setting,
+                                  const char *          cur_property)
 {
-	_key_file_handler_data_init (handler_data,
-	                             handler_type,
-	                             kf_group,
-	                             kf_key,
-	                             cur_setting,
-	                             cur_property,
-	                             &info->error);
+    _key_file_handler_data_init(handler_data,
+                                handler_type,
+                                kf_group,
+                                kf_key,
+                                cur_setting,
+                                cur_property,
+                                &info->error);
 }
 
-_nm_printf (5, 6)
-static void
-_handle_warn (KeyfileReaderInfo *info,
-              const char *kf_key,
-              const char *cur_property,
-              NMKeyfileWarnSeverity severity,
-              const char *fmt,
-              ...)
+_nm_printf(5, 6) static void _handle_warn(KeyfileReaderInfo *   info,
+                                          const char *          kf_key,
+                                          const char *          cur_property,
+                                          NMKeyfileWarnSeverity severity,
+                                          const char *          fmt,
+                                          ...)
 {
-	NMKeyfileHandlerData handler_data;
-
-	_key_file_handler_data_init_read (&handler_data,
-	                                  NM_KEYFILE_HANDLER_TYPE_WARN,
-	                                  info,
-	                                  kf_key,
-	                                  cur_property);
-	handler_data.warn = (NMKeyfileHandlerDataWarn) {
-		.severity = severity,
-		.message  = NULL,
-		.fmt      = fmt,
-	};
-
-	va_start (handler_data.warn.ap, fmt);
-
-	info->read_handler (info->keyfile,
-	                    info->connection,
-	                    NM_KEYFILE_HANDLER_TYPE_WARN,
-	                    &handler_data,
-	                    info->user_data);
-
-	va_end (handler_data.warn.ap);
-
-	g_free (handler_data.warn.message);
+    NMKeyfileHandlerData handler_data;
+
+    _key_file_handler_data_init_read(&handler_data,
+                                     NM_KEYFILE_HANDLER_TYPE_WARN,
+                                     info,
+                                     kf_key,
+                                     cur_property);
+    handler_data.warn = (NMKeyfileHandlerDataWarn){
+        .severity = severity,
+        .message  = NULL,
+        .fmt      = fmt,
+    };
+
+    va_start(handler_data.warn.ap, fmt);
+
+    info->read_handler(info->keyfile,
+                       info->connection,
+                       NM_KEYFILE_HANDLER_TYPE_WARN,
+                       &handler_data,
+                       info->user_data);
+
+    va_end(handler_data.warn.ap);
+
+    g_free(handler_data.warn.message);
 }
 
-#define handle_warn(arg_info, arg_kf_key, arg_property_name, arg_severity, ...) \
-	({ \
-		KeyfileReaderInfo *_info = (arg_info); \
-		\
-		nm_assert (!_info->error); \
-		\
-		if (_info->read_handler) { \
-			_handle_warn (_info, \
-			              (arg_kf_key), \
-			              (arg_property_name), \
-			              (arg_severity), \
-			              __VA_ARGS__); \
-		} \
-		_info->error == NULL; \
-	})
+#define handle_warn(arg_info, arg_kf_key, arg_property_name, arg_severity, ...)                  \
+    ({                                                                                           \
+        KeyfileReaderInfo *_info = (arg_info);                                                   \
+                                                                                                 \
+        nm_assert(!_info->error);                                                                \
+                                                                                                 \
+        if (_info->read_handler) {                                                               \
+            _handle_warn(_info, (arg_kf_key), (arg_property_name), (arg_severity), __VA_ARGS__); \
+        }                                                                                        \
+        _info->error == NULL;                                                                    \
+    })
 
 /*****************************************************************************/
 
 static gboolean
-_secret_flags_persist_secret (NMSettingSecretFlags flags)
+_secret_flags_persist_secret(NMSettingSecretFlags flags)
 {
-	return flags == NM_SETTING_SECRET_FLAG_NONE;
+    return flags == NM_SETTING_SECRET_FLAG_NONE;
 }
 
 /*****************************************************************************/
@@ -170,231 +165,214 @@ _secret_flags_persist_secret (NMSettingSecretFlags flags)
  * properties' values to the real setting name if they are an alias.
  */
 static void
-setting_alias_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+setting_alias_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	const char *key_setting_name;
-	gs_free char *s = NULL;
-
-	s = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
-	if (!s)
-		return;
-
-	key_setting_name = nm_keyfile_plugin_get_setting_name_for_alias (s);
-	g_object_set (G_OBJECT (setting),
-	              key,
-	              key_setting_name ?: s,
-	              NULL);
+    const char *  setting_name = nm_setting_get_name(setting);
+    const char *  key_setting_name;
+    gs_free char *s = NULL;
+
+    s = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
+    if (!s)
+        return;
+
+    key_setting_name = nm_keyfile_plugin_get_setting_name_for_alias(s);
+    g_object_set(G_OBJECT(setting), key, key_setting_name ?: s, NULL);
 }
 
 static void
-sriov_vfs_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+sriov_vfs_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_ptrarray GPtrArray *vfs = NULL;
-	gs_strfreev char **keys = NULL;
-	gsize n_keys = 0;
-	int i;
+    const char *      setting_name      = nm_setting_get_name(setting);
+    gs_unref_ptrarray GPtrArray *vfs    = NULL;
+    gs_strfreev char **          keys   = NULL;
+    gsize                        n_keys = 0;
+    int                          i;
 
-	keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, setting_name, &n_keys, NULL);
-	if (n_keys == 0)
-		return;
+    keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL);
+    if (n_keys == 0)
+        return;
 
-	vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref);
+    vfs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_sriov_vf_unref);
 
-	for (i = 0; i < n_keys; i++) {
-		gs_free char *value = NULL;
-		NMSriovVF *vf;
-		const char *rest;
+    for (i = 0; i < n_keys; i++) {
+        gs_free char *value = NULL;
+        NMSriovVF *   vf;
+        const char *  rest;
 
-		if (!g_str_has_prefix (keys[i], "vf."))
-			continue;
+        if (!g_str_has_prefix(keys[i], "vf."))
+            continue;
 
-		rest = &keys[i][3];
+        rest = &keys[i][3];
 
-		if (!NM_STRCHAR_ALL (rest, ch, g_ascii_isdigit (ch)))
-			continue;
+        if (!NM_STRCHAR_ALL(rest, ch, g_ascii_isdigit(ch)))
+            continue;
 
-		value = nm_keyfile_plugin_kf_get_string (info->keyfile,
-		                                         setting_name,
-		                                         keys[i],
-		                                         NULL);
+        value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL);
 
-		vf = _nm_utils_sriov_vf_from_strparts (rest, value, TRUE, NULL);
-		if (vf)
-			g_ptr_array_add (vfs, vf);
-	}
+        vf = _nm_utils_sriov_vf_from_strparts(rest, value, TRUE, NULL);
+        if (vf)
+            g_ptr_array_add(vfs, vf);
+    }
 
-	g_object_set (G_OBJECT (setting),
-	              key, vfs,
-	              NULL);
+    g_object_set(G_OBJECT(setting), key, vfs, NULL);
 }
 
 static void
-read_array_of_uint (GKeyFile *file,
-                    NMSetting *setting,
-                    const char *key)
+read_array_of_uint(GKeyFile *file, NMSetting *setting, const char *key)
 {
-	gs_unref_array GArray *array = NULL;
-	gs_free_error GError *error = NULL;
-	gs_free guint *tmp = NULL;
-	gsize length;
-
-	tmp = nm_keyfile_plugin_kf_get_integer_list_uint (file, nm_setting_get_name (setting), key, &length, &error);
-	if (error)
-		return;
-
-	array = g_array_sized_new (FALSE, FALSE, sizeof (guint), length);
-	g_array_append_vals (array, tmp, length);
-	g_object_set (setting, key, array, NULL);
+    gs_unref_array GArray *array = NULL;
+    gs_free_error GError *error  = NULL;
+    gs_free guint *tmp           = NULL;
+    gsize          length;
+
+    tmp = nm_keyfile_plugin_kf_get_integer_list_uint(file,
+                                                     nm_setting_get_name(setting),
+                                                     key,
+                                                     &length,
+                                                     &error);
+    if (error)
+        return;
+
+    array = g_array_sized_new(FALSE, FALSE, sizeof(guint), length);
+    g_array_append_vals(array, tmp, length);
+    g_object_set(setting, key, array, NULL);
 }
 
 static gboolean
-get_one_int (KeyfileReaderInfo *info,
-             const char *kf_key,
-             const char *property_name,
-             const char *str,
-             guint32 max_val,
-             guint32 *out)
+get_one_int(KeyfileReaderInfo *info,
+            const char *       kf_key,
+            const char *       property_name,
+            const char *       str,
+            guint32            max_val,
+            guint32 *          out)
 {
-	gint64 tmp;
-
-	nm_assert ((!info) == (!property_name));
-	nm_assert ((!info) == (!kf_key));
-
-	if (!str || !str[0]) {
-		if (info) {
-			handle_warn (info,
-			             kf_key,
-			             property_name,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("ignoring missing number"));
-		}
-		return FALSE;
-	}
-
-	tmp = _nm_utils_ascii_str_to_int64 (str, 10, 0, max_val, -1);
-	if (tmp == -1) {
-		if (info) {
-			handle_warn (info,
-			             kf_key,
-			             property_name,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("ignoring invalid number '%s'"),
-			             str);
-		}
-		return FALSE;
-	}
-
-	*out = (guint32) tmp;
-	return TRUE;
+    gint64 tmp;
+
+    nm_assert((!info) == (!property_name));
+    nm_assert((!info) == (!kf_key));
+
+    if (!str || !str[0]) {
+        if (info) {
+            handle_warn(info,
+                        kf_key,
+                        property_name,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("ignoring missing number"));
+        }
+        return FALSE;
+    }
+
+    tmp = _nm_utils_ascii_str_to_int64(str, 10, 0, max_val, -1);
+    if (tmp == -1) {
+        if (info) {
+            handle_warn(info,
+                        kf_key,
+                        property_name,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("ignoring invalid number '%s'"),
+                        str);
+        }
+        return FALSE;
+    }
+
+    *out = (guint32) tmp;
+    return TRUE;
 }
 
 static gpointer
-build_address (KeyfileReaderInfo *info,
-               const char *kf_key,
-               const char *property_name,
-               int family,
-               const char *address_str,
-               guint32 plen)
+build_address(KeyfileReaderInfo *info,
+              const char *       kf_key,
+              const char *       property_name,
+              int                family,
+              const char *       address_str,
+              guint32            plen)
 {
-	NMIPAddress *addr;
-	GError *error = NULL;
-
-	g_return_val_if_fail (address_str, NULL);
-
-	addr = nm_ip_address_new (family, address_str, plen, &error);
-	if (!addr) {
-		handle_warn (info,
-		             kf_key,
-		             property_name,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("ignoring invalid %s address: %s"),
-		             family == AF_INET ? "IPv4" : "IPv6",
-		             error->message);
-		g_error_free (error);
-	}
-
-	return addr;
+    NMIPAddress *addr;
+    GError *     error = NULL;
+
+    g_return_val_if_fail(address_str, NULL);
+
+    addr = nm_ip_address_new(family, address_str, plen, &error);
+    if (!addr) {
+        handle_warn(info,
+                    kf_key,
+                    property_name,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("ignoring invalid %s address: %s"),
+                    family == AF_INET ? "IPv4" : "IPv6",
+                    error->message);
+        g_error_free(error);
+    }
+
+    return addr;
 }
 
 static gpointer
-build_route (KeyfileReaderInfo *info,
-             const char *kf_key,
-             const char *property_name,
-             int family,
-             const char *dest_str,
-             guint32 plen,
-             const char *gateway_str,
-             const char *metric_str)
+build_route(KeyfileReaderInfo *info,
+            const char *       kf_key,
+            const char *       property_name,
+            int                family,
+            const char *       dest_str,
+            guint32            plen,
+            const char *       gateway_str,
+            const char *       metric_str)
 {
-	NMIPRoute *route;
-	guint32 u32;
-	gint64 metric = -1;
-	GError *error = NULL;
-
-	g_return_val_if_fail (dest_str, NULL);
-
-	/* Next hop */
-	if (gateway_str && gateway_str[0]) {
-		if (!nm_utils_ipaddr_is_valid (family, gateway_str)) {
-			/* Try workaround for routes written by broken keyfile writer.
-			 * Due to bug bgo#719851, an older version of writer would have
-			 * written "a:b:c:d::/plen,metric" if the gateway was ::, instead
-			 * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric"
-			 * Try workaround by interpreting gateway_str as metric to accept such
-			 * invalid routes. This broken syntax should not be not officially
-			 * supported.
-			 **/
-			if (   family == AF_INET6
-			    && !metric_str
-			    && get_one_int (NULL, NULL, NULL, gateway_str, G_MAXUINT32, &u32)) {
-				metric = u32;
-				gateway_str = NULL;
-			} else {
-				handle_warn (info,
-				             kf_key,
-				             property_name,
-				             NM_KEYFILE_WARN_SEVERITY_WARN,
-				             _("ignoring invalid gateway '%s' for %s route"),
-				             gateway_str,
-				             family == AF_INET ? "IPv4" : "IPv6");
-				return NULL;
-			}
-		}
-	} else
-		gateway_str = NULL;
-
-	/* parse metric, default to -1 */
-	if (metric_str) {
-		if (!get_one_int (info,
-		                  kf_key,
-		                  property_name,
-		                  metric_str,
-		                  G_MAXUINT32,
-		                  &u32))
-			return NULL;
-		metric = u32;
-	}
-
-	route = nm_ip_route_new (family,
-	                         dest_str,
-	                         plen,
-	                         gateway_str,
-	                         metric,
-	                         &error);
-	if (!route) {
-		handle_warn (info,
-		             kf_key,
-		             property_name,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("ignoring invalid %s route: %s"),
-		             family == AF_INET ? "IPv4" : "IPv6",
-		             error->message);
-		g_error_free (error);
-	}
-
-	return route;
+    NMIPRoute *route;
+    guint32    u32;
+    gint64     metric = -1;
+    GError *   error  = NULL;
+
+    g_return_val_if_fail(dest_str, NULL);
+
+    /* Next hop */
+    if (gateway_str && gateway_str[0]) {
+        if (!nm_utils_ipaddr_is_valid(family, gateway_str)) {
+            /* Try workaround for routes written by broken keyfile writer.
+             * Due to bug bgo#719851, an older version of writer would have
+             * written "a:b:c:d::/plen,metric" if the gateway was ::, instead
+             * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric"
+             * Try workaround by interpreting gateway_str as metric to accept such
+             * invalid routes. This broken syntax should not be not officially
+             * supported.
+             **/
+            if (family == AF_INET6 && !metric_str
+                && get_one_int(NULL, NULL, NULL, gateway_str, G_MAXUINT32, &u32)) {
+                metric      = u32;
+                gateway_str = NULL;
+            } else {
+                handle_warn(info,
+                            kf_key,
+                            property_name,
+                            NM_KEYFILE_WARN_SEVERITY_WARN,
+                            _("ignoring invalid gateway '%s' for %s route"),
+                            gateway_str,
+                            family == AF_INET ? "IPv4" : "IPv6");
+                return NULL;
+            }
+        }
+    } else
+        gateway_str = NULL;
+
+    /* parse metric, default to -1 */
+    if (metric_str) {
+        if (!get_one_int(info, kf_key, property_name, metric_str, G_MAXUINT32, &u32))
+            return NULL;
+        metric = u32;
+    }
+
+    route = nm_ip_route_new(family, dest_str, plen, gateway_str, metric, &error);
+    if (!route) {
+        handle_warn(info,
+                    kf_key,
+                    property_name,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("ignoring invalid %s route: %s"),
+                    family == AF_INET ? "IPv4" : "IPv6",
+                    error->message);
+        g_error_free(error);
+    }
+
+    return route;
 }
 
 /* On success, returns pointer to the zero-terminated field (original @current).
@@ -409,47 +387,47 @@ build_route (KeyfileReaderInfo *info,
  * leaving the @current target %NULL end setting @error to %NULL;
  */
 static const char *
-read_field (char **current, const char **out_err_str, const char *characters, const char *delimiters)
+read_field(char **current, const char **out_err_str, const char *characters, const char *delimiters)
 {
-	const char *start;
-
-	nm_assert (current);
-	nm_assert (out_err_str);
-	nm_assert (characters);
-	nm_assert (delimiters);
-
-	*out_err_str = NULL;
-
-	if (!*current) {
-		/* graceful failure, leave '*current' NULL */
-		return NULL;
-	}
-
-	/* fail on empty input */
-	if (!**current)
-		return NULL;
-
-	/* remember beginning of input */
-	start = *current;
-
-	while (**current && strchr (characters, **current))
-		(*current)++;
-	if (**current)
-		if (strchr (delimiters, **current)) {
-			/* success, more data available */
-			*(*current)++ = '\0';
-			return start;
-		} else {
-			/* error, bad character */
-			*out_err_str = *current;
-			*current = (char *) start;
-			return NULL;
-		}
-	else {
-		/* success, end of input */
-		*current = NULL;
-		return start;
-	}
+    const char *start;
+
+    nm_assert(current);
+    nm_assert(out_err_str);
+    nm_assert(characters);
+    nm_assert(delimiters);
+
+    *out_err_str = NULL;
+
+    if (!*current) {
+        /* graceful failure, leave '*current' NULL */
+        return NULL;
+    }
+
+    /* fail on empty input */
+    if (!**current)
+        return NULL;
+
+    /* remember beginning of input */
+    start = *current;
+
+    while (**current && strchr(characters, **current))
+        (*current)++;
+    if (**current)
+        if (strchr(delimiters, **current)) {
+            /* success, more data available */
+            *(*current)++ = '\0';
+            return start;
+        } else {
+            /* error, bad character */
+            *out_err_str = *current;
+            *current     = (char *) start;
+            return NULL;
+        }
+    else {
+        /* success, end of input */
+        *current = NULL;
+        return start;
+    }
 }
 
 /*****************************************************************************/
@@ -464,44 +442,44 @@ read_field (char **current, const char **out_err_str, const char *characters, co
 #define NM_OPENCONNECT_KEY_CERTSIGS    "certsigs"
 
 static void
-openconnect_fix_secret_flags (NMSetting *setting)
+openconnect_fix_secret_flags(NMSetting *setting)
 {
-	NMSettingVpn *s_vpn;
-	NMSettingSecretFlags flags;
-
-	/* Huge hack.  There were some openconnect changes that needed to happen
-	 * pretty late, too late to get into distros.  Migration has already
-	 * happened for many people, and their secret flags are wrong.  But we
-	 * don't want to requrie re-migration, so we have to fix it up here. Ugh.
-	 */
-
-	if (!NM_IS_SETTING_VPN (setting))
-		return;
-
-	s_vpn = NM_SETTING_VPN (setting);
-
-	if (!nm_streq0 (nm_setting_vpn_get_service_type (s_vpn), NM_DBUS_SERVICE_OPENCONNECT))
-		return;
-
-	/* These are different for every login session, and should not be stored */
-	flags = NM_SETTING_SECRET_FLAG_NOT_SAVED;
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GATEWAY, flags, NULL);
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_COOKIE, flags, NULL);
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_GWCERT, flags, NULL);
-
-	/* These are purely internal data for the auth-dialog, and should be stored */
-	flags = 0;
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_XMLCONFIG, flags, NULL);
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_LASTHOST, flags, NULL);
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_AUTOCONNECT, flags, NULL);
-	nm_setting_set_secret_flags (NM_SETTING (s_vpn), NM_OPENCONNECT_KEY_CERTSIGS, flags, NULL);
+    NMSettingVpn *       s_vpn;
+    NMSettingSecretFlags flags;
+
+    /* Huge hack.  There were some openconnect changes that needed to happen
+     * pretty late, too late to get into distros.  Migration has already
+     * happened for many people, and their secret flags are wrong.  But we
+     * don't want to require re-migration, so we have to fix it up here. Ugh.
+     */
+
+    if (!NM_IS_SETTING_VPN(setting))
+        return;
+
+    s_vpn = NM_SETTING_VPN(setting);
+
+    if (!nm_streq0(nm_setting_vpn_get_service_type(s_vpn), NM_DBUS_SERVICE_OPENCONNECT))
+        return;
+
+    /* These are different for every login session, and should not be stored */
+    flags = NM_SETTING_SECRET_FLAG_NOT_SAVED;
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_GATEWAY, flags, NULL);
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_COOKIE, flags, NULL);
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_GWCERT, flags, NULL);
+
+    /* These are purely internal data for the auth-dialog, and should be stored */
+    flags = 0;
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_XMLCONFIG, flags, NULL);
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_LASTHOST, flags, NULL);
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_AUTOCONNECT, flags, NULL);
+    nm_setting_set_secret_flags(NM_SETTING(s_vpn), NM_OPENCONNECT_KEY_CERTSIGS, flags, NULL);
 }
 
 /*****************************************************************************/
 
 #define IP_ADDRESS_CHARS "0123456789abcdefABCDEF:.%"
-#define DIGITS "0123456789"
-#define DELIMITERS "/;,"
+#define DIGITS           "0123456789"
+#define DELIMITERS       "/;,"
 
 /* The following IPv4 and IPv6 address formats are supported:
  *
@@ -528,1465 +506,1457 @@ openconnect_fix_secret_flags (NMSetting *setting)
  * match the iproute2 defaults (32 for IPv4 and 128 for IPv6).
  */
 static gpointer
-read_one_ip_address_or_route (KeyfileReaderInfo *info,
-                              const char *property_name,
-                              const char *setting_name,
-                              const char *kf_key,
-                              gboolean ipv6,
-                              gboolean route,
-                              char **out_gateway,
-                              NMSetting *setting)
+read_one_ip_address_or_route(KeyfileReaderInfo *info,
+                             const char *       property_name,
+                             const char *       setting_name,
+                             const char *       kf_key,
+                             gboolean           ipv6,
+                             gboolean           route,
+                             char **            out_gateway,
+                             NMSetting *        setting)
 {
-	guint plen;
-	gpointer result;
-	const char *address_str;
-	const char *plen_str;
-	const char *gateway_str;
-	const char *metric_str;
-	const char *err_str = NULL;
-	char *current;
-	gs_free char *value = NULL;
-	gs_free char *value_orig = NULL;
-
-#define VALUE_ORIG()   (value_orig ?: (value_orig = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, kf_key, NULL)))
-
-	value = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, kf_key, NULL);
-	if (!value)
-		return NULL;
-
-	current = value;
-
-	/* get address field */
-	address_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
-	if (err_str) {
-		handle_warn (info,
-		             kf_key,
-		             property_name,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("unexpected character '%c' for address %s: '%s' (position %td)"),
-		             *err_str,
-		             kf_key,
-		             VALUE_ORIG (),
-		             err_str - current);
-		return NULL;
-	}
-	/* get prefix length field (skippable) */
-	plen_str = read_field (&current, &err_str, DIGITS, DELIMITERS);
-	/* get gateway field */
-	gateway_str = read_field (&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
-	if (err_str) {
-		handle_warn (info,
-		             kf_key,
-		             property_name,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("unexpected character '%c' for %s: '%s' (position %td)"),
-		             *err_str,
-		             kf_key,
-		             VALUE_ORIG (),
-		             err_str - current);
-		return NULL;
-	}
-	/* for routes, get metric */
-	if (route) {
-		metric_str = read_field (&current, &err_str, DIGITS, DELIMITERS);
-		if (err_str) {
-			handle_warn (info,
-			             kf_key,
-			             property_name,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("unexpected character '%c' in prefix length for %s: '%s' (position %td)"),
-			             *err_str,
-			             kf_key,
-			             VALUE_ORIG (),
-			             err_str - current);
-			return NULL;
-		}
-	} else
-		metric_str = NULL;
-	if (current) {
-		/* there is still some data */
-		if (*current) {
-			/* another field follows */
-			handle_warn (info,
-			             kf_key,
-			             property_name,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("garbage at the end of value %s: '%s'"),
-			             kf_key,
-			             VALUE_ORIG ());
-			return NULL;
-		} else {
-			/* semicolon at the end of input */
-			if (!handle_warn (info,
-			                  kf_key,
-			                  property_name,
-			                  NM_KEYFILE_WARN_SEVERITY_INFO,
-			                  _("deprecated semicolon at the end of value %s: '%s'"),
-			                  kf_key,
-			                  VALUE_ORIG ()))
-				return NULL;
-		}
-	}
-
-#define DEFAULT_PREFIX(for_route, for_ipv6) ( (for_route) ? ( (for_ipv6) ? 128 : 24 ) : ( (for_ipv6) ? 64 : 24 ) )
-
-	/* parse plen, fallback to defaults */
-	if (plen_str) {
-		if (!get_one_int (info,
-		                  kf_key,
-		                  property_name,
-		                  plen_str,
-		                  ipv6 ? 128 : 32,
-		                  &plen)) {
-			plen = DEFAULT_PREFIX (route, ipv6);
-			if (   info->error
-			    || !handle_warn (info,
-			                     kf_key,
-			                     property_name,
-			                     NM_KEYFILE_WARN_SEVERITY_WARN,
-			                     _("invalid prefix length for %s '%s', defaulting to %d"),
-			                     kf_key,
-			                     VALUE_ORIG (),
-			                     plen))
-				return NULL;
-		}
-	} else {
-		plen = DEFAULT_PREFIX (route, ipv6);
-		if (!handle_warn (info,
-		                  kf_key,
-		                  property_name,
-		                  NM_KEYFILE_WARN_SEVERITY_WARN,
-		                  _("missing prefix length for %s '%s', defaulting to %d"),
-		                  kf_key,
-		                  VALUE_ORIG (),
-		                  plen))
-			return NULL;
-	}
-
-	/* build the appropriate data structure for NetworkManager settings */
-	if (route) {
-		result = build_route (info,
-		                      kf_key,
-		                      property_name,
-		                      ipv6 ? AF_INET6 : AF_INET,
-		                      address_str,
-		                      plen,
-		                      gateway_str,
-		                      metric_str);
-	} else {
-		result = build_address (info,
-		                        kf_key,
-		                        property_name,
-		                        ipv6 ? AF_INET6 : AF_INET,
-		                        address_str,
-		                        plen);
-		if (!result)
-			return NULL;
-		if (gateway_str)
-			NM_SET_OUT (out_gateway, g_strdup (gateway_str));
-	}
+    guint         plen;
+    gpointer      result;
+    const char *  address_str;
+    const char *  plen_str;
+    const char *  gateway_str;
+    const char *  metric_str;
+    const char *  err_str = NULL;
+    char *        current;
+    gs_free char *value      = NULL;
+    gs_free char *value_orig = NULL;
+
+#define VALUE_ORIG()      \
+    (value_orig           \
+         ?: (value_orig = \
+                 nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, kf_key, NULL)))
+
+    value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, kf_key, NULL);
+    if (!value)
+        return NULL;
+
+    current = value;
+
+    /* get address field */
+    address_str = read_field(&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
+    if (err_str) {
+        handle_warn(info,
+                    kf_key,
+                    property_name,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("unexpected character '%c' for address %s: '%s' (position %td)"),
+                    *err_str,
+                    kf_key,
+                    VALUE_ORIG(),
+                    err_str - current);
+        return NULL;
+    }
+    /* get prefix length field (skippable) */
+    plen_str = read_field(&current, &err_str, DIGITS, DELIMITERS);
+    /* get gateway field */
+    gateway_str = read_field(&current, &err_str, IP_ADDRESS_CHARS, DELIMITERS);
+    if (err_str) {
+        handle_warn(info,
+                    kf_key,
+                    property_name,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("unexpected character '%c' for %s: '%s' (position %td)"),
+                    *err_str,
+                    kf_key,
+                    VALUE_ORIG(),
+                    err_str - current);
+        return NULL;
+    }
+    /* for routes, get metric */
+    if (route) {
+        metric_str = read_field(&current, &err_str, DIGITS, DELIMITERS);
+        if (err_str) {
+            handle_warn(info,
+                        kf_key,
+                        property_name,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("unexpected character '%c' in prefix length for %s: '%s' (position %td)"),
+                        *err_str,
+                        kf_key,
+                        VALUE_ORIG(),
+                        err_str - current);
+            return NULL;
+        }
+    } else
+        metric_str = NULL;
+    if (current) {
+        /* there is still some data */
+        if (*current) {
+            /* another field follows */
+            handle_warn(info,
+                        kf_key,
+                        property_name,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("garbage at the end of value %s: '%s'"),
+                        kf_key,
+                        VALUE_ORIG());
+            return NULL;
+        } else {
+            /* semicolon at the end of input */
+            if (!handle_warn(info,
+                             kf_key,
+                             property_name,
+                             NM_KEYFILE_WARN_SEVERITY_INFO,
+                             _("deprecated semicolon at the end of value %s: '%s'"),
+                             kf_key,
+                             VALUE_ORIG()))
+                return NULL;
+        }
+    }
+
+#define DEFAULT_PREFIX(for_route, for_ipv6) \
+    ((for_route) ? ((for_ipv6) ? 128 : 24) : ((for_ipv6) ? 64 : 24))
+
+    /* parse plen, fallback to defaults */
+    if (plen_str) {
+        if (!get_one_int(info, kf_key, property_name, plen_str, ipv6 ? 128 : 32, &plen)) {
+            plen = DEFAULT_PREFIX(route, ipv6);
+            if (info->error
+                || !handle_warn(info,
+                                kf_key,
+                                property_name,
+                                NM_KEYFILE_WARN_SEVERITY_WARN,
+                                _("invalid prefix length for %s '%s', defaulting to %d"),
+                                kf_key,
+                                VALUE_ORIG(),
+                                plen))
+                return NULL;
+        }
+    } else {
+        plen = DEFAULT_PREFIX(route, ipv6);
+        if (!handle_warn(info,
+                         kf_key,
+                         property_name,
+                         NM_KEYFILE_WARN_SEVERITY_WARN,
+                         _("missing prefix length for %s '%s', defaulting to %d"),
+                         kf_key,
+                         VALUE_ORIG(),
+                         plen))
+            return NULL;
+    }
+
+    /* build the appropriate data structure for NetworkManager settings */
+    if (route) {
+        result = build_route(info,
+                             kf_key,
+                             property_name,
+                             ipv6 ? AF_INET6 : AF_INET,
+                             address_str,
+                             plen,
+                             gateway_str,
+                             metric_str);
+    } else {
+        result = build_address(info,
+                               kf_key,
+                               property_name,
+                               ipv6 ? AF_INET6 : AF_INET,
+                               address_str,
+                               plen);
+        if (!result)
+            return NULL;
+        if (gateway_str)
+            NM_SET_OUT(out_gateway, g_strdup(gateway_str));
+    }
 
 #undef VALUE_ORIG
 
-	return result;
+    return result;
 }
 
 static void
-fill_route_attributes (GKeyFile *kf, NMIPRoute *route, const char *setting, const char *key, int family)
+fill_route_attributes(GKeyFile *  kf,
+                      NMIPRoute * route,
+                      const char *setting,
+                      const char *key,
+                      int         family)
 {
-	gs_free char *value = NULL;
-	gs_unref_hashtable GHashTable *hash = NULL;
-	GHashTableIter iter;
-	char *name;
-	GVariant *variant;
-
-	value = nm_keyfile_plugin_kf_get_string (kf, setting, key, NULL);
-	if (!value || !value[0])
-		return;
-
-	hash = nm_utils_parse_variant_attributes (value, ',', '=', TRUE,
-	                                          nm_ip_route_get_variant_attribute_spec (),
-	                                          NULL);
-	if (hash) {
-		g_hash_table_iter_init (&iter, hash);
-		while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
-			if (nm_ip_route_attribute_validate (name, variant, family, NULL, NULL))
-				nm_ip_route_set_attribute (route, name, g_variant_ref (variant));
-		}
-	}
+    gs_free char *     value            = NULL;
+    gs_unref_hashtable GHashTable *hash = NULL;
+    GHashTableIter                 iter;
+    char *                         name;
+    GVariant *                     variant;
+
+    value = nm_keyfile_plugin_kf_get_string(kf, setting, key, NULL);
+    if (!value || !value[0])
+        return;
+
+    hash = nm_utils_parse_variant_attributes(value,
+                                             ',',
+                                             '=',
+                                             TRUE,
+                                             nm_ip_route_get_variant_attribute_spec(),
+                                             NULL);
+    if (hash) {
+        g_hash_table_iter_init(&iter, hash);
+        while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) {
+            if (nm_ip_route_attribute_validate(name, variant, family, NULL, NULL))
+                nm_ip_route_set_attribute(route, name, g_variant_ref(variant));
+        }
+    }
 }
 
 typedef struct {
-	const char *s_key;
-	gint32 key_idx;
-	gint8 key_type;
+    const char *s_key;
+    gint32      key_idx;
+    gint8       key_type;
 } BuildListData;
 
 typedef enum {
-	BUILD_LIST_TYPE_ADDRESSES,
-	BUILD_LIST_TYPE_ROUTES,
-	BUILD_LIST_TYPE_ROUTING_RULES,
+    BUILD_LIST_TYPE_ADDRESSES,
+    BUILD_LIST_TYPE_ROUTES,
+    BUILD_LIST_TYPE_ROUTING_RULES,
 } BuildListType;
 
 static int
-_build_list_data_cmp (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
+_build_list_data_cmp(gconstpointer p_a, gconstpointer p_b, gpointer user_data)
 {
-	const BuildListData *a = p_a;
-	const BuildListData *b = p_b;
+    const BuildListData *a = p_a;
+    const BuildListData *b = p_b;
 
-	NM_CMP_FIELD (a, b, key_idx);
-	NM_CMP_FIELD (a, b, key_type);
-	NM_CMP_FIELD_STR (a, b, s_key);
-	return 0;
+    NM_CMP_FIELD(a, b, key_idx);
+    NM_CMP_FIELD(a, b, key_type);
+    NM_CMP_FIELD_STR(a, b, s_key);
+    return 0;
 }
 
 static gboolean
-_build_list_data_is_shadowed (const BuildListData *build_list,
-                              gsize build_list_len,
-                              gsize idx)
+_build_list_data_is_shadowed(const BuildListData *build_list, gsize build_list_len, gsize idx)
 {
-	/* the keyfile contains duplicate keys, which are both returned
-	 * by g_key_file_get_keys() (WHY??).
-	 *
-	 * Skip the earlier one. */
-	return    idx + 1 < build_list_len
-	       && build_list[idx].key_idx == build_list[idx + 1].key_idx
-	       && build_list[idx].key_type == build_list[idx + 1].key_type
-	       && nm_streq (build_list[idx].s_key, build_list[idx + 1].s_key);
+    /* the keyfile contains duplicate keys, which are both returned
+     * by g_key_file_get_keys() (WHY??).
+     *
+     * Skip the earlier one. */
+    return idx + 1 < build_list_len && build_list[idx].key_idx == build_list[idx + 1].key_idx
+           && build_list[idx].key_type == build_list[idx + 1].key_type
+           && nm_streq(build_list[idx].s_key, build_list[idx + 1].s_key);
 }
 
 static gboolean
-_build_list_match_key_w_name_impl (const char *key,
-                                   const char *base_name,
-                                   gsize base_name_l,
-                                   gint32 *out_key_idx)
+_build_list_match_key_w_name_impl(const char *key,
+                                  const char *base_name,
+                                  gsize       base_name_l,
+                                  gint32 *    out_key_idx)
 {
-	gint64 v;
-
-	/* some very strict parsing. */
-
-	/* the key must start with base_name. */
-	if (strncmp (key, base_name, base_name_l) != 0)
-		return FALSE;
-
-	key += base_name_l;
-	if (key[0] == '\0') {
-		/* if key is identical to base_name, that's good. */
-		NM_SET_OUT (out_key_idx, -1);
-		return TRUE;
-	}
-
-	/* if base_name is followed by a zero, then it must be
-	 * only a zero, nothing else. */
-	if (key[0] == '0') {
-		if (key[1] != '\0')
-			return FALSE;
-		NM_SET_OUT (out_key_idx, 0);
-		return TRUE;
-	}
-
-	/* otherwise, it can only be followed by a non-zero decimal. */
-	if (!(key[0] >= '1' && key[0] <= '9'))
-		return FALSE;
-	/* and all remaining chars must be decimals too. */
-	if (!NM_STRCHAR_ALL (&key[1], ch, g_ascii_isdigit (ch)))
-		return FALSE;
-
-	/* and it must be convertible to a (positive) int. */
-	v = _nm_utils_ascii_str_to_int64 (key, 10, 0, G_MAXINT32, -1);
-	if (v < 0)
-		return FALSE;
-
-	/* good */
-	NM_SET_OUT (out_key_idx, v);
-	return TRUE;
+    gint64 v;
+
+    /* some very strict parsing. */
+
+    /* the key must start with base_name. */
+    if (strncmp(key, base_name, base_name_l) != 0)
+        return FALSE;
+
+    key += base_name_l;
+    if (key[0] == '\0') {
+        /* if key is identical to base_name, that's good. */
+        NM_SET_OUT(out_key_idx, -1);
+        return TRUE;
+    }
+
+    /* if base_name is followed by a zero, then it must be
+     * only a zero, nothing else. */
+    if (key[0] == '0') {
+        if (key[1] != '\0')
+            return FALSE;
+        NM_SET_OUT(out_key_idx, 0);
+        return TRUE;
+    }
+
+    /* otherwise, it can only be followed by a non-zero decimal. */
+    if (!(key[0] >= '1' && key[0] <= '9'))
+        return FALSE;
+    /* and all remaining chars must be decimals too. */
+    if (!NM_STRCHAR_ALL(&key[1], ch, g_ascii_isdigit(ch)))
+        return FALSE;
+
+    /* and it must be convertible to a (positive) int. */
+    v = _nm_utils_ascii_str_to_int64(key, 10, 0, G_MAXINT32, -1);
+    if (v < 0)
+        return FALSE;
+
+    /* good */
+    NM_SET_OUT(out_key_idx, v);
+    return TRUE;
 }
 
 #define _build_list_match_key_w_name(key, base_name, out_key_idx) \
-	_build_list_match_key_w_name_impl (key, base_name, NM_STRLEN (base_name), out_key_idx)
+    _build_list_match_key_w_name_impl(key, base_name, NM_STRLEN(base_name), out_key_idx)
 
 static BuildListData *
-_build_list_create (GKeyFile *keyfile,
-                    const char *group_name,
-                    BuildListType build_list_type,
-                    gsize *out_build_list_len,
-                    char ***out_keys_strv)
+_build_list_create(GKeyFile *    keyfile,
+                   const char *  group_name,
+                   BuildListType build_list_type,
+                   gsize *       out_build_list_len,
+                   char ***      out_keys_strv)
 {
-	gs_strfreev char **keys = NULL;
-	gsize i_keys, n_keys;
-	gs_free BuildListData *build_list = NULL;
-	gsize build_list_len = 0;
-
-	nm_assert (out_build_list_len && *out_build_list_len == 0);
-	nm_assert (out_keys_strv && !*out_keys_strv);
-
-	keys = nm_keyfile_plugin_kf_get_keys (keyfile, group_name, &n_keys, NULL);
-	if (n_keys == 0)
-		return NULL;
-
-	for (i_keys = 0; i_keys < n_keys; i_keys++) {
-		const char *s_key = keys[i_keys];
-		gint32 key_idx;
-		gint8 key_type = 0;
-
-		switch (build_list_type) {
-		case BUILD_LIST_TYPE_ROUTES:
-			if (_build_list_match_key_w_name (s_key, "route", &key_idx))
-				key_type = 0;
-			else if (_build_list_match_key_w_name (s_key, "routes", &key_idx))
-				key_type = 1;
-			else
-				continue;
-			break;
-		case BUILD_LIST_TYPE_ADDRESSES:
-			if (_build_list_match_key_w_name (s_key, "address", &key_idx))
-				key_type = 0;
-			else if (_build_list_match_key_w_name (s_key, "addresses", &key_idx))
-				key_type = 1;
-			else
-				continue;
-			break;
-		case BUILD_LIST_TYPE_ROUTING_RULES:
-			if (_build_list_match_key_w_name (s_key, "routing-rule", &key_idx))
-				key_type = 0;
-			else
-				continue;
-			break;
-		default:
-			nm_assert_not_reached ();
-			break;
-		}
-
-		if (G_UNLIKELY (!build_list))
-			build_list = g_new (BuildListData, n_keys - i_keys);
-
-		build_list[build_list_len++] = (BuildListData) {
-			.s_key    = s_key,
-			.key_idx  = key_idx,
-			.key_type = key_type,
-		};
-	}
-
-	if (build_list_len == 0)
-		return NULL;
-
-	if (build_list_len > 1) {
-		g_qsort_with_data (build_list,
-		                   build_list_len,
-		                   sizeof (BuildListData),
-		                   _build_list_data_cmp,
-		                   NULL);
-	}
-
-	*out_build_list_len = build_list_len;
-	*out_keys_strv = g_steal_pointer (&keys);
-	return g_steal_pointer (&build_list);
+    gs_strfreev char **keys = NULL;
+    gsize              i_keys, n_keys;
+    gs_free BuildListData *build_list     = NULL;
+    gsize                  build_list_len = 0;
+
+    nm_assert(out_build_list_len && *out_build_list_len == 0);
+    nm_assert(out_keys_strv && !*out_keys_strv);
+
+    keys = nm_keyfile_plugin_kf_get_keys(keyfile, group_name, &n_keys, NULL);
+    if (n_keys == 0)
+        return NULL;
+
+    for (i_keys = 0; i_keys < n_keys; i_keys++) {
+        const char *s_key = keys[i_keys];
+        gint32      key_idx;
+        gint8       key_type = 0;
+
+        switch (build_list_type) {
+        case BUILD_LIST_TYPE_ROUTES:
+            if (_build_list_match_key_w_name(s_key, "route", &key_idx))
+                key_type = 0;
+            else if (_build_list_match_key_w_name(s_key, "routes", &key_idx))
+                key_type = 1;
+            else
+                continue;
+            break;
+        case BUILD_LIST_TYPE_ADDRESSES:
+            if (_build_list_match_key_w_name(s_key, "address", &key_idx))
+                key_type = 0;
+            else if (_build_list_match_key_w_name(s_key, "addresses", &key_idx))
+                key_type = 1;
+            else
+                continue;
+            break;
+        case BUILD_LIST_TYPE_ROUTING_RULES:
+            if (_build_list_match_key_w_name(s_key, "routing-rule", &key_idx))
+                key_type = 0;
+            else
+                continue;
+            break;
+        default:
+            nm_assert_not_reached();
+            break;
+        }
+
+        if (G_UNLIKELY(!build_list))
+            build_list = g_new(BuildListData, n_keys - i_keys);
+
+        build_list[build_list_len++] = (BuildListData){
+            .s_key    = s_key,
+            .key_idx  = key_idx,
+            .key_type = key_type,
+        };
+    }
+
+    if (build_list_len == 0)
+        return NULL;
+
+    if (build_list_len > 1) {
+        g_qsort_with_data(build_list,
+                          build_list_len,
+                          sizeof(BuildListData),
+                          _build_list_data_cmp,
+                          NULL);
+    }
+
+    *out_build_list_len = build_list_len;
+    *out_keys_strv      = g_steal_pointer(&keys);
+    return g_steal_pointer(&build_list);
 }
 
 static void
-ip_address_or_route_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *setting_key)
+ip_address_or_route_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *setting_key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gboolean is_ipv6 = nm_streq (setting_name, "ipv6");
-	gboolean is_routes = nm_streq (setting_key, "routes");
-	gs_free char *gateway = NULL;
-	gs_unref_ptrarray GPtrArray *list = NULL;
-	gs_strfreev char **keys = NULL;
-	gs_free BuildListData *build_list = NULL;
-	gsize i_build_list, build_list_len = 0;
-
-	build_list = _build_list_create (info->keyfile,
-	                                 setting_name,
-	                                   is_routes
-	                                 ? BUILD_LIST_TYPE_ROUTES
-	                                 : BUILD_LIST_TYPE_ADDRESSES,
-	                                 &build_list_len,
-	                                 &keys);
-	if (!build_list)
-		return;
-
-	list = g_ptr_array_new_with_free_func (is_routes
-	                                       ? (GDestroyNotify) nm_ip_route_unref
-	                                       : (GDestroyNotify) nm_ip_address_unref);
-
-	for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) {
-		const char *s_key;
-		gpointer item;
-
-		if (_build_list_data_is_shadowed (build_list, build_list_len, i_build_list))
-			continue;
-
-		s_key = build_list[i_build_list].s_key;
-		item = read_one_ip_address_or_route (info,
-		                                     setting_key,
-		                                     setting_name,
-		                                     s_key,
-		                                     is_ipv6,
-		                                     is_routes,
-		                                     gateway ? NULL : &gateway,
-		                                     setting);
-		if (item && is_routes) {
-			char options_key[128];
-
-			nm_sprintf_buf (options_key, "%s_options", s_key);
-			fill_route_attributes (info->keyfile,
-			                       item,
-			                       setting_name,
-			                       options_key,
-			                       is_ipv6 ? AF_INET6 : AF_INET);
-		}
-
-		if (info->error)
-			return;
-
-		if (item)
-			g_ptr_array_add (list, item);
-	}
-
-	if (list->len >= 1)
-		g_object_set (setting, setting_key, list, NULL);
-
-	if (gateway)
-		g_object_set (setting, "gateway", gateway, NULL);
+    const char *      setting_name    = nm_setting_get_name(setting);
+    gboolean          is_ipv6         = nm_streq(setting_name, "ipv6");
+    gboolean          is_routes       = nm_streq(setting_key, "routes");
+    gs_free char *    gateway         = NULL;
+    gs_unref_ptrarray GPtrArray *list = NULL;
+    gs_strfreev char **          keys = NULL;
+    gs_free BuildListData *build_list = NULL;
+    gsize                  i_build_list, build_list_len = 0;
+
+    build_list = _build_list_create(info->keyfile,
+                                    setting_name,
+                                    is_routes ? BUILD_LIST_TYPE_ROUTES : BUILD_LIST_TYPE_ADDRESSES,
+                                    &build_list_len,
+                                    &keys);
+    if (!build_list)
+        return;
+
+    list = g_ptr_array_new_with_free_func(is_routes ? (GDestroyNotify) nm_ip_route_unref
+                                                    : (GDestroyNotify) nm_ip_address_unref);
+
+    for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) {
+        const char *s_key;
+        gpointer    item;
+
+        if (_build_list_data_is_shadowed(build_list, build_list_len, i_build_list))
+            continue;
+
+        s_key = build_list[i_build_list].s_key;
+        item  = read_one_ip_address_or_route(info,
+                                            setting_key,
+                                            setting_name,
+                                            s_key,
+                                            is_ipv6,
+                                            is_routes,
+                                            gateway ? NULL : &gateway,
+                                            setting);
+        if (item && is_routes) {
+            char options_key[128];
+
+            nm_sprintf_buf(options_key, "%s_options", s_key);
+            fill_route_attributes(info->keyfile,
+                                  item,
+                                  setting_name,
+                                  options_key,
+                                  is_ipv6 ? AF_INET6 : AF_INET);
+        }
+
+        if (info->error)
+            return;
+
+        if (item)
+            g_ptr_array_add(list, item);
+    }
+
+    if (list->len >= 1)
+        g_object_set(setting, setting_key, list, NULL);
+
+    if (gateway)
+        g_object_set(setting, "gateway", gateway, NULL);
 }
 
 static void
-ip_routing_rule_parser_full (KeyfileReaderInfo *info,
-                             const NMMetaSettingInfo *setting_info,
-                             const NMSettInfoProperty *property_info,
-                             const ParseInfoProperty *pip,
-                             NMSetting *setting)
+ip_routing_rule_parser_full(KeyfileReaderInfo *       info,
+                            const NMMetaSettingInfo * setting_info,
+                            const NMSettInfoProperty *property_info,
+                            const ParseInfoProperty * pip,
+                            NMSetting *               setting)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gboolean is_ipv6 = nm_streq (setting_name, "ipv6");
-	gs_strfreev char **keys = NULL;
-	gs_free BuildListData *build_list = NULL;
-	gsize i_build_list, build_list_len = 0;
-
-	build_list = _build_list_create (info->keyfile,
-	                                 setting_name,
-	                                 BUILD_LIST_TYPE_ROUTING_RULES,
-	                                 &build_list_len,
-	                                 &keys);
-	if (!build_list)
-		return;
-
-	for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) {
-		nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL;
-		gs_free char *value = NULL;
-		gs_free_error GError *local = NULL;
-
-		if (_build_list_data_is_shadowed (build_list, build_list_len, i_build_list))
-			continue;
-
-		value = nm_keyfile_plugin_kf_get_string (info->keyfile,
-		                                         setting_name,
-		                                         build_list[i_build_list].s_key,
-		                                         NULL);
-		if (!value)
-			continue;
-
-		rule = nm_ip_routing_rule_from_string (value,
-		                                       (  NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE
-		                                        | (  is_ipv6
-		                                           ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6
-		                                           : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET)),
-		                                       NULL,
-		                                       &local);
-		if (!rule) {
-			if (!handle_warn (info,
-			                  build_list[i_build_list].s_key,
-			                  property_info->name,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("invalid value for \"%s\": %s"),
-			                  build_list[i_build_list].s_key,
-			                  local->message))
-				return;
-			continue;
-		}
-
-		nm_setting_ip_config_add_routing_rule (NM_SETTING_IP_CONFIG (setting), rule);
-	}
+    const char *       setting_name   = nm_setting_get_name(setting);
+    gboolean           is_ipv6        = nm_streq(setting_name, "ipv6");
+    gs_strfreev char **keys           = NULL;
+    gs_free BuildListData *build_list = NULL;
+    gsize                  i_build_list, build_list_len = 0;
+
+    build_list = _build_list_create(info->keyfile,
+                                    setting_name,
+                                    BUILD_LIST_TYPE_ROUTING_RULES,
+                                    &build_list_len,
+                                    &keys);
+    if (!build_list)
+        return;
+
+    for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) {
+        nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule  = NULL;
+        gs_free char *                                 value = NULL;
+        gs_free_error GError *local                          = NULL;
+
+        if (_build_list_data_is_shadowed(build_list, build_list_len, i_build_list))
+            continue;
+
+        value = nm_keyfile_plugin_kf_get_string(info->keyfile,
+                                                setting_name,
+                                                build_list[i_build_list].s_key,
+                                                NULL);
+        if (!value)
+            continue;
+
+        rule = nm_ip_routing_rule_from_string(
+            value,
+            (NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE
+             | (is_ipv6 ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6
+                        : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET)),
+            NULL,
+            &local);
+        if (!rule) {
+            if (!handle_warn(info,
+                             build_list[i_build_list].s_key,
+                             property_info->name,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("invalid value for \"%s\": %s"),
+                             build_list[i_build_list].s_key,
+                             local->message))
+                return;
+            continue;
+        }
+
+        nm_setting_ip_config_add_routing_rule(NM_SETTING_IP_CONFIG(setting), rule);
+    }
 }
 
 static void
-ip_dns_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+ip_dns_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	int addr_family;
-	gs_strfreev char **list = NULL;
-	gsize i, n, length;
-
-	nm_assert (NM_IS_SETTING_IP4_CONFIG (setting) || NM_IS_SETTING_IP6_CONFIG (setting));
-
-	list = nm_keyfile_plugin_kf_get_string_list (info->keyfile,
-	                                             nm_setting_get_name (setting),
-	                                             key,
-	                                             &length,
-	                                             NULL);
-	nm_assert (length == NM_PTRARRAY_LEN (list));
-	if (length == 0)
-		return;
-
-	addr_family = NM_IS_SETTING_IP4_CONFIG (setting) ? AF_INET : AF_INET6;
-
-	n = 0;
-	for (i = 0; i < length; i++) {
-		NMIPAddr addr;
-
-		if (inet_pton (addr_family, list[i], &addr) <= 0) {
-			if (!handle_warn (info,
-			                  key,
-			                  key,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("ignoring invalid DNS server IPv%c address '%s'"),
-			                  nm_utils_addr_family_to_char (addr_family),
-			                  list[i])) {
-				do {
-					nm_clear_g_free (&list[i]);
-				} while (++i < length);
-				return;
-			}
-			nm_clear_g_free (&list[i]);
-			continue;
-		}
-
-		if (n != i)
-			list[n] = g_steal_pointer (&list[i]);
-		n++;
-	}
-
-	g_object_set (setting, key, list, NULL);
+    int                addr_family;
+    gs_strfreev char **list = NULL;
+    gsize              i, n, length;
+
+    nm_assert(NM_IS_SETTING_IP4_CONFIG(setting) || NM_IS_SETTING_IP6_CONFIG(setting));
+
+    list = nm_keyfile_plugin_kf_get_string_list(info->keyfile,
+                                                nm_setting_get_name(setting),
+                                                key,
+                                                &length,
+                                                NULL);
+    nm_assert(length == NM_PTRARRAY_LEN(list));
+    if (length == 0)
+        return;
+
+    addr_family = NM_IS_SETTING_IP4_CONFIG(setting) ? AF_INET : AF_INET6;
+
+    n = 0;
+    for (i = 0; i < length; i++) {
+        NMIPAddr addr;
+
+        if (inet_pton(addr_family, list[i], &addr) <= 0) {
+            if (!handle_warn(info,
+                             key,
+                             key,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("ignoring invalid DNS server IPv%c address '%s'"),
+                             nm_utils_addr_family_to_char(addr_family),
+                             list[i])) {
+                do {
+                    nm_clear_g_free(&list[i]);
+                } while (++i < length);
+                return;
+            }
+            nm_clear_g_free(&list[i]);
+            continue;
+        }
+
+        if (n != i)
+            list[n] = g_steal_pointer(&list[i]);
+        n++;
+    }
+
+    g_object_set(setting, key, list, NULL);
 }
 
 static void
-ip6_addr_gen_mode_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+ip6_addr_gen_mode_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	NMSettingIP6ConfigAddrGenMode addr_gen_mode;
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_free char *s = NULL;
-
-	s = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
-	if (s) {
-		if (!nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), s,
-		                             (int *) &addr_gen_mode, NULL)) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid option '%s', use one of [%s]"),
-			             s,
-			             "eui64,stable-privacy");
-			return;
-		}
-	} else
-		addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64;
-
-	g_object_set (G_OBJECT (setting), key, (int) addr_gen_mode, NULL);
+    NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+    const char *                  setting_name = nm_setting_get_name(setting);
+    gs_free char *                s            = NULL;
+
+    s = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
+    if (s) {
+        if (!nm_utils_enum_from_str(nm_setting_ip6_config_addr_gen_mode_get_type(),
+                                    s,
+                                    (int *) &addr_gen_mode,
+                                    NULL)) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid option '%s', use one of [%s]"),
+                        s,
+                        "eui64,stable-privacy");
+            return;
+        }
+    } else
+        addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64;
+
+    g_object_set(G_OBJECT(setting), key, (int) addr_gen_mode, NULL);
 }
 
 static void
-mac_address_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key, gsize addr_len, gboolean cloned_mac_addr)
+mac_address_parser(KeyfileReaderInfo *info,
+                   NMSetting *        setting,
+                   const char *       key,
+                   gsize              addr_len,
+                   gboolean           cloned_mac_addr)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	char addr_str[NM_UTILS_HWADDR_LEN_MAX * 3];
-	guint8 addr_bin[NM_UTILS_HWADDR_LEN_MAX];
-	gs_free char *tmp_string = NULL;
-	gs_free guint *int_list = NULL;
-	const char *mac_str;
-	gsize int_list_len;
-	gsize i;
-
-	nm_assert (addr_len > 0);
-	nm_assert (addr_len <= NM_UTILS_HWADDR_LEN_MAX);
-
-	tmp_string = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
-
-	if (   cloned_mac_addr
-	    && NM_CLONED_MAC_IS_SPECIAL (tmp_string)) {
-		mac_str = tmp_string;
-		goto out;
-	}
-
-	if (   tmp_string
-	    && nm_utils_hwaddr_aton (tmp_string, addr_bin, addr_len))
-		goto good_addr_bin;
-
-	/* Old format; list of ints */
-	int_list = nm_keyfile_plugin_kf_get_integer_list_uint (info->keyfile, setting_name, key, &int_list_len, NULL);
-	if (int_list_len == addr_len) {
-		for (i = 0; i < addr_len; i++) {
-			const guint val = int_list[i];
-
-			if (val > 255)
-				break;
-			addr_bin[i] = (guint8) val;
-		}
-		if (i == addr_len)
-			goto good_addr_bin;
-	}
-
-	handle_warn (info,
-	             key,
-	             key,
-	             NM_KEYFILE_WARN_SEVERITY_WARN,
-	             _("ignoring invalid MAC address"));
-	return;
+    const char *  setting_name = nm_setting_get_name(setting);
+    char          addr_str[NM_UTILS_HWADDR_LEN_MAX * 3];
+    guint8        addr_bin[NM_UTILS_HWADDR_LEN_MAX];
+    gs_free char *tmp_string = NULL;
+    gs_free guint *int_list  = NULL;
+    const char *   mac_str;
+    gsize          int_list_len;
+    gsize          i;
+
+    nm_assert(addr_len > 0);
+    nm_assert(addr_len <= NM_UTILS_HWADDR_LEN_MAX);
+
+    tmp_string = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
+
+    if (cloned_mac_addr && NM_CLONED_MAC_IS_SPECIAL(tmp_string)) {
+        mac_str = tmp_string;
+        goto out;
+    }
+
+    if (tmp_string && nm_utils_hwaddr_aton(tmp_string, addr_bin, addr_len))
+        goto good_addr_bin;
+
+    /* Old format; list of ints */
+    int_list = nm_keyfile_plugin_kf_get_integer_list_uint(info->keyfile,
+                                                          setting_name,
+                                                          key,
+                                                          &int_list_len,
+                                                          NULL);
+    if (int_list_len == addr_len) {
+        for (i = 0; i < addr_len; i++) {
+            const guint val = int_list[i];
+
+            if (val > 255)
+                break;
+            addr_bin[i] = (guint8) val;
+        }
+        if (i == addr_len)
+            goto good_addr_bin;
+    }
+
+    handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("ignoring invalid MAC address"));
+    return;
 
 good_addr_bin:
-	nm_utils_bin2hexstr_full (addr_bin, addr_len, ':', TRUE, addr_str);
-	mac_str = addr_str;
+    nm_utils_bin2hexstr_full(addr_bin, addr_len, ':', TRUE, addr_str);
+    mac_str = addr_str;
 
 out:
-	g_object_set (setting, key, mac_str, NULL);
+    g_object_set(setting, key, mac_str, NULL);
 }
 
 static void
-mac_address_parser_ETHER (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+mac_address_parser_ETHER(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	mac_address_parser (info, setting, key, ETH_ALEN, FALSE);
+    mac_address_parser(info, setting, key, ETH_ALEN, FALSE);
 }
 
 static void
-mac_address_parser_ETHER_cloned (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+mac_address_parser_ETHER_cloned(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	mac_address_parser (info, setting, key, ETH_ALEN, TRUE);
+    mac_address_parser(info, setting, key, ETH_ALEN, TRUE);
 }
 
 static void
-mac_address_parser_INFINIBAND (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+mac_address_parser_INFINIBAND(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	mac_address_parser (info, setting, key, INFINIBAND_ALEN, FALSE);
+    mac_address_parser(info, setting, key, INFINIBAND_ALEN, FALSE);
 }
 
 static void
-read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
+read_hash_of_string(GKeyFile *file, NMSetting *setting, const char *key)
 {
-	gs_strfreev char **keys = NULL;
-	const char *const*iter;
-	const char *setting_name = nm_setting_get_name (setting);
-	gboolean is_vpn;
-	gsize n_keys;
-
-	nm_assert (   (NM_IS_SETTING_VPN (setting)  && nm_streq (key, NM_SETTING_VPN_DATA))
-	           || (NM_IS_SETTING_VPN (setting)  && nm_streq (key, NM_SETTING_VPN_SECRETS))
-	           || (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
-	           || (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
-
-	keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, &n_keys, NULL);
-	if (n_keys == 0)
-		return;
-
-	if (   (is_vpn = NM_IS_SETTING_VPN (setting))
-	    || NM_IS_SETTING_BOND (setting)) {
-		for (iter = (const char *const*) keys; *iter; iter++) {
-			gs_free char *to_free = NULL;
-			gs_free char *value = NULL;
-			const char *name;
-
-			value = nm_keyfile_plugin_kf_get_string (file, setting_name, *iter, NULL);
-			if (!value)
-				continue;
-
-			name = nm_keyfile_key_decode (*iter, &to_free);
-
-			if (is_vpn) {
-				/* Add any item that's not a class property to the data hash */
-				if (!g_object_class_find_property (G_OBJECT_GET_CLASS (setting), name))
-					nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), name, value);
-			} else {
-				if (!nm_streq (name, "interface-name"))
-					nm_setting_bond_add_option (NM_SETTING_BOND (setting), name, value);
-			}
-		}
-		openconnect_fix_secret_flags (setting);
-		return;
-	}
-
-	if (NM_IS_SETTING_USER (setting)) {
-		gs_unref_hashtable GHashTable *data = NULL;
-
-		data = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
-		for (iter = (const char *const*) keys; *iter; iter++) {
-			gs_free char *to_free = NULL;
-			char *value = NULL;
-			const char *name;
-
-			value = nm_keyfile_plugin_kf_get_string (file, setting_name, *iter, NULL);
-			if (!value)
-				continue;
-			name = nm_keyfile_key_decode (*iter, &to_free);
-			g_hash_table_insert (data,
-			                     g_steal_pointer (&to_free) ?: g_strdup (name),
-			                     value);
-		}
-		g_object_set (setting, NM_SETTING_USER_DATA, data, NULL);
-		return;
-	}
-
-	nm_assert_not_reached ();
+    gs_strfreev char **keys = NULL;
+    const char *const *iter;
+    const char *       setting_name = nm_setting_get_name(setting);
+    gboolean           is_vpn;
+    gsize              n_keys;
+
+    nm_assert((NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_DATA))
+              || (NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_SECRETS))
+              || (NM_IS_SETTING_BOND(setting) && nm_streq(key, NM_SETTING_BOND_OPTIONS))
+              || (NM_IS_SETTING_USER(setting) && nm_streq(key, NM_SETTING_USER_DATA)));
+
+    keys = nm_keyfile_plugin_kf_get_keys(file, setting_name, &n_keys, NULL);
+    if (n_keys == 0)
+        return;
+
+    if ((is_vpn = NM_IS_SETTING_VPN(setting)) || NM_IS_SETTING_BOND(setting)) {
+        for (iter = (const char *const *) keys; *iter; iter++) {
+            gs_free char *to_free = NULL;
+            gs_free char *value   = NULL;
+            const char *  name;
+
+            value = nm_keyfile_plugin_kf_get_string(file, setting_name, *iter, NULL);
+            if (!value)
+                continue;
+
+            name = nm_keyfile_key_decode(*iter, &to_free);
+
+            if (is_vpn) {
+                /* Add any item that's not a class property to the data hash */
+                if (!g_object_class_find_property(G_OBJECT_GET_CLASS(setting), name))
+                    nm_setting_vpn_add_data_item(NM_SETTING_VPN(setting), name, value);
+            } else {
+                if (!nm_streq(name, "interface-name"))
+                    nm_setting_bond_add_option(NM_SETTING_BOND(setting), name, value);
+            }
+        }
+        openconnect_fix_secret_flags(setting);
+        return;
+    }
+
+    if (NM_IS_SETTING_USER(setting)) {
+        gs_unref_hashtable GHashTable *data = NULL;
+
+        data = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
+        for (iter = (const char *const *) keys; *iter; iter++) {
+            gs_free char *to_free = NULL;
+            char *        value   = NULL;
+            const char *  name;
+
+            value = nm_keyfile_plugin_kf_get_string(file, setting_name, *iter, NULL);
+            if (!value)
+                continue;
+            name = nm_keyfile_key_decode(*iter, &to_free);
+            g_hash_table_insert(data, g_steal_pointer(&to_free) ?: g_strdup(name), value);
+        }
+        g_object_set(setting, NM_SETTING_USER_DATA, data, NULL);
+        return;
+    }
+
+    nm_assert_not_reached();
 }
 
 static gsize
-unescape_semicolons (char *str)
+unescape_semicolons(char *str)
 {
-	gsize i, j;
-
-	for (i = 0, j = 0; str[i]; ) {
-		if (str[i] == '\\' && str[i+1] == ';')
-			i++;
-		str[j++] = str[i++];;
-	}
-	nm_explicit_bzero (&str[j], i - j);
-	return j;
+    gsize i, j;
+
+    for (i = 0, j = 0; str[i];) {
+        if (str[i] == '\\' && str[i + 1] == ';')
+            i++;
+        str[j++] = str[i++];
+    }
+    nm_explicit_bzero(&str[j], i - j);
+    return j;
 }
 
 static GBytes *
-get_bytes (KeyfileReaderInfo *info,
-           const char *setting_name,
-           const char *key,
-           gboolean zero_terminate,
-           gboolean unescape_semicolon)
+get_bytes(KeyfileReaderInfo *info,
+          const char *       setting_name,
+          const char *       key,
+          gboolean           zero_terminate,
+          gboolean           unescape_semicolon)
 {
-	nm_auto_free_secret char *tmp_string = NULL;
-	gboolean may_be_int_list = TRUE;
-	gsize length;
-	GBytes *result;
-
-	/* New format: just a string
-	 * Old format: integer list; e.g. 11;25;38;
-	 */
-	tmp_string = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
-	if (!tmp_string)
-		return NULL;
-
-	/* if the string is empty, we return an empty GBytes array.
-	 * Note that for NM_SETTING_802_1X_PASSWORD_RAW both %NULL and
-	 * an empty GBytes are valid, and shall be destinguished. */
-	if (!tmp_string[0]) {
-		/* note that even if @zero_terminate is TRUE, we return an empty
-		 * byte-array. The reason is that zero_terminate is there to terminate
-		 * *valid* strings. It's not there to terminated invalid (empty) strings.
-		 */
-		return g_bytes_new_static ("", 0);
-	}
-
-	for (length = 0; tmp_string[length]; length++) {
-		const char ch = tmp_string[length];
-
-		if (   !g_ascii_isspace (ch)
-		    && !g_ascii_isdigit (ch)
-		    && ch != ';') {
-			may_be_int_list = FALSE;
-			length += strlen (&tmp_string[length]);
-			break;
-		}
-	}
-
-	/* Try to parse the string as a integer list. */
-	if (may_be_int_list && length > 0) {
-		nm_auto_free_secret_buf NMSecretBuf *bin = NULL;
-		const char *const s = tmp_string;
-		gsize i, d;
-
-		bin = nm_secret_buf_new (length / 2 + 3);
+    nm_auto_free_secret char *tmp_string      = NULL;
+    gboolean                  may_be_int_list = TRUE;
+    gsize                     length;
+    GBytes *                  result;
+
+    /* New format: just a string
+     * Old format: integer list; e.g. 11;25;38;
+     */
+    tmp_string = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
+    if (!tmp_string)
+        return NULL;
+
+    /* if the string is empty, we return an empty GBytes array.
+     * Note that for NM_SETTING_802_1X_PASSWORD_RAW both %NULL and
+     * an empty GBytes are valid, and shall be destinguished. */
+    if (!tmp_string[0]) {
+        /* note that even if @zero_terminate is TRUE, we return an empty
+         * byte-array. The reason is that zero_terminate is there to terminate
+         * *valid* strings. It's not there to terminated invalid (empty) strings.
+         */
+        return g_bytes_new_static("", 0);
+    }
+
+    for (length = 0; tmp_string[length]; length++) {
+        const char ch = tmp_string[length];
+
+        if (!g_ascii_isspace(ch) && !g_ascii_isdigit(ch) && ch != ';') {
+            may_be_int_list = FALSE;
+            length += strlen(&tmp_string[length]);
+            break;
+        }
+    }
+
+    /* Try to parse the string as a integer list. */
+    if (may_be_int_list && length > 0) {
+        nm_auto_free_secret_buf NMSecretBuf *bin = NULL;
+        const char *const                    s   = tmp_string;
+        gsize                                i, d;
+
+        bin = nm_secret_buf_new(length / 2 + 3);
 
 #define DIGIT(c) ((c) - '0')
-		i = 0;
-		d = 0;
-		while (TRUE) {
-			int n;
-
-			/* leading whitespace */
-			while (g_ascii_isspace (s[i]))
-				i++;
-			if (s[i] == '\0')
-				break;
-			/* then expect 1 to 3 digits */
-			if (!g_ascii_isdigit (s[i])) {
-				d = 0;
-				break;
-			}
-			n = DIGIT (s[i]);
-			i++;
-			if (g_ascii_isdigit (s[i])) {
-				n = 10 * n + DIGIT (s[i]);
-				i++;
-				if (g_ascii_isdigit (s[i])) {
-					n = 10 * n + DIGIT (s[i]);
-					i++;
-				}
-			}
-			if (n > 255) {
-				d = 0;
-				break;
-			}
-
-			nm_assert (d < bin->len);
-			bin->bin[d++] = n;
-
-			/* allow whitespace after the digit. */
-			while (g_ascii_isspace (s[i]))
-				i++;
-			/* need a semicolon as separator. */
-			if (s[i] != ';') {
-				d = 0;
-				break;
-			}
-			i++;
-		}
+        i = 0;
+        d = 0;
+        while (TRUE) {
+            int n;
+
+            /* leading whitespace */
+            while (g_ascii_isspace(s[i]))
+                i++;
+            if (s[i] == '\0')
+                break;
+            /* then expect 1 to 3 digits */
+            if (!g_ascii_isdigit(s[i])) {
+                d = 0;
+                break;
+            }
+            n = DIGIT(s[i]);
+            i++;
+            if (g_ascii_isdigit(s[i])) {
+                n = 10 * n + DIGIT(s[i]);
+                i++;
+                if (g_ascii_isdigit(s[i])) {
+                    n = 10 * n + DIGIT(s[i]);
+                    i++;
+                }
+            }
+            if (n > 255) {
+                d = 0;
+                break;
+            }
+
+            nm_assert(d < bin->len);
+            bin->bin[d++] = n;
+
+            /* allow whitespace after the digit. */
+            while (g_ascii_isspace(s[i]))
+                i++;
+            /* need a semicolon as separator. */
+            if (s[i] != ';') {
+                d = 0;
+                break;
+            }
+            i++;
+        }
 #undef DIGIT
 
-		/* Old format; list of ints. We already did a strict validation of the
-		 * string format before. We expect that this conversion cannot fail. */
-		if (d > 0) {
-			/* note that @zero_terminate does not add a terminating '\0' to
-			 * binary data as an integer list. If the bytes are expressed as
-			 * an integer list, all potential NUL characters are supposed to
-			 * be included there explicitly.
-			 *
-			 * However, in the spirit of defensive programming, we do append a
-			 * NUL character to the buffer, although this character is hidden
-			 * and only a mitigation for bugs. */
-
-			if (d + 10 < bin->len) {
-				/* hm, too much unused memory. Copy the memory to a suitable
-				 * sized buffer. */
-				return nm_secret_copy_to_gbytes (bin->bin, d);
-			}
-
-			nm_assert (d < bin->len);
-			bin->bin[d] = '\0';
-			return nm_secret_buf_to_gbytes_take (g_steal_pointer (&bin), d);
-		}
-	}
-
-	/* Handle as a simple string (ie, new format) */
-	if (unescape_semicolon)
-		length = unescape_semicolons (tmp_string);
-	if (zero_terminate)
-		length++;
-	if (length == 0)
-		return NULL;
-
-	result = g_bytes_new_with_free_func (tmp_string,
-	                                     length,
-	                                     (GDestroyNotify) nm_free_secret,
-	                                     tmp_string);
-	tmp_string = NULL;
-	return result;
+        /* Old format; list of ints. We already did a strict validation of the
+         * string format before. We expect that this conversion cannot fail. */
+        if (d > 0) {
+            /* note that @zero_terminate does not add a terminating '\0' to
+             * binary data as an integer list. If the bytes are expressed as
+             * an integer list, all potential NUL characters are supposed to
+             * be included there explicitly.
+             *
+             * However, in the spirit of defensive programming, we do append a
+             * NUL character to the buffer, although this character is hidden
+             * and only a mitigation for bugs. */
+
+            if (d + 10 < bin->len) {
+                /* hm, too much unused memory. Copy the memory to a suitable
+                 * sized buffer. */
+                return nm_secret_copy_to_gbytes(bin->bin, d);
+            }
+
+            nm_assert(d < bin->len);
+            bin->bin[d] = '\0';
+            return nm_secret_buf_to_gbytes_take(g_steal_pointer(&bin), d);
+        }
+    }
+
+    /* Handle as a simple string (ie, new format) */
+    if (unescape_semicolon)
+        length = unescape_semicolons(tmp_string);
+    if (zero_terminate)
+        length++;
+    if (length == 0)
+        return NULL;
+
+    result =
+        g_bytes_new_with_free_func(tmp_string, length, (GDestroyNotify) nm_free_secret, tmp_string);
+    tmp_string = NULL;
+    return result;
 }
 
 static void
-ssid_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+ssid_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_bytes GBytes *bytes = NULL;
-
-	bytes = get_bytes (info, setting_name, key, FALSE, TRUE);
-	if (!bytes) {
-		handle_warn (info,
-		             key,
-		             key,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("ignoring invalid SSID"));
-		return;
-	}
-	g_object_set (setting, key, bytes, NULL);
+    const char *   setting_name  = nm_setting_get_name(setting);
+    gs_unref_bytes GBytes *bytes = NULL;
+
+    bytes = get_bytes(info, setting_name, key, FALSE, TRUE);
+    if (!bytes) {
+        handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("ignoring invalid SSID"));
+        return;
+    }
+    g_object_set(setting, key, bytes, NULL);
 }
 
 static void
-password_raw_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+password_raw_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_bytes GBytes *bytes = NULL;
-
-	bytes = get_bytes (info, setting_name, key, FALSE, TRUE);
-	if (!bytes) {
-		handle_warn (info,
-		             key,
-		             key,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("ignoring invalid raw password"));
-		return;
-	}
-	g_object_set (setting, key, bytes, NULL);
+    const char *   setting_name  = nm_setting_get_name(setting);
+    gs_unref_bytes GBytes *bytes = NULL;
+
+    bytes = get_bytes(info, setting_name, key, FALSE, TRUE);
+    if (!bytes) {
+        handle_warn(info,
+                    key,
+                    key,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("ignoring invalid raw password"));
+        return;
+    }
+    g_object_set(setting, key, bytes, NULL);
 }
 
 static char *
-get_cert_path (const char *base_dir, const guint8 *cert_path, gsize cert_path_len)
+get_cert_path(const char *base_dir, const guint8 *cert_path, gsize cert_path_len)
 {
-	const char *base;
-	char *p = NULL, *path, *tmp;
+    const char *base;
+    char *      p = NULL, *path, *tmp;
 
-	g_return_val_if_fail (base_dir != NULL, NULL);
-	g_return_val_if_fail (cert_path != NULL, NULL);
+    g_return_val_if_fail(base_dir != NULL, NULL);
+    g_return_val_if_fail(cert_path != NULL, NULL);
 
-	path = g_strndup ((char *) cert_path, cert_path_len);
+    path = g_strndup((char *) cert_path, cert_path_len);
 
-	if (path[0] == '/')
-		return path;
+    if (path[0] == '/')
+        return path;
 
-	base = path;
-	p = strrchr (path, '/');
-	if (p)
-		base = p + 1;
+    base = path;
+    p    = strrchr(path, '/');
+    if (p)
+        base = p + 1;
 
-	tmp = g_build_path ("/", base_dir, base, NULL);
-	g_free (path);
-	return tmp;
+    tmp = g_build_path("/", base_dir, base, NULL);
+    g_free(path);
+    return tmp;
 }
 
-static const char *certext[] = { ".pem", ".cert", ".crt", ".cer", ".p12", ".der", ".key" };
+static const char *certext[] = {".pem", ".cert", ".crt", ".cer", ".p12", ".der", ".key"};
 
 static gboolean
-has_cert_ext (const char *path)
+has_cert_ext(const char *path)
 {
-	int i;
+    int i;
 
-	for (i = 0; i < G_N_ELEMENTS (certext); i++) {
-		if (g_str_has_suffix (path, certext[i]))
-			return TRUE;
-	}
-	return FALSE;
+    for (i = 0; i < G_N_ELEMENTS(certext); i++) {
+        if (g_str_has_suffix(path, certext[i]))
+            return TRUE;
+    }
+    return FALSE;
 }
 
 char *
-nm_keyfile_detect_unqualified_path_scheme (const char *base_dir,
-                                           gconstpointer pdata,
-                                           gsize data_len,
-                                           gboolean consider_exists,
-                                           gboolean *out_exists)
+nm_keyfile_detect_unqualified_path_scheme(const char *  base_dir,
+                                          gconstpointer pdata,
+                                          gsize         data_len,
+                                          gboolean      consider_exists,
+                                          gboolean *    out_exists)
 {
-	const char *data = pdata;
-	gboolean exists = FALSE;
-	gsize validate_len;
-	gsize path_len, pathuri_len;
-	gs_free char *path = NULL;
-	gs_free char *pathuri = NULL;
-
-	g_return_val_if_fail (base_dir && base_dir[0] == '/', NULL);
-
-	if (!pdata)
-		return NULL;
-	if (data_len == -1)
-		data_len = strlen (data);
-	if (data_len > 500 || data_len < 1)
-		return NULL;
-
-	/* If there's a trailing zero tell g_utf8_validate() to validate until the zero */
-	if (data[data_len - 1] == '\0') {
-		/* setting it to -1, would mean we accept data to contain NUL characters before the
-		 * end. Don't accept any NUL in [0 .. data_len-1[ . */
-		validate_len = data_len - 1;
-	} else
-		validate_len = data_len;
-	if (   validate_len == 0
-	    || g_utf8_validate ((const char *) data, validate_len, NULL) == FALSE)
-		 return NULL;
-
-	/* Might be a bare path without the file:// prefix; in that case
-	 * if it's an absolute path, use that, otherwise treat it as a
-	 * relative path to the current directory.
-	 */
-
-	path = get_cert_path (base_dir, (const guint8 *) data, data_len);
-
-	/* FIXME(keyfile-parse-in-memory): it is wrong that keyfile reader makes decisions based on
-	 * the file systems content. The serialization/parsing should be entirely in-memory. */
-	if (   !memchr (data, '/', data_len)
-	    && !has_cert_ext (path)) {
-		if (!consider_exists)
-			return NULL;
-		exists = g_file_test (path, G_FILE_TEST_EXISTS);
-		if (!exists)
-			return NULL;
-	} else if (out_exists)
-		exists = g_file_test (path, G_FILE_TEST_EXISTS);
-
-	/* Construct the proper value as required for the PATH scheme.
-	 *
-	 * When returning TRUE, we must also be sure that @data_len does not look like
-	 * the deprecated format of list of integers. With this implementation that is the
-	 * case, as long as @consider_exists is FALSE. */
-	path_len = strlen (path);
-	pathuri_len = (NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) + 1) + path_len;
-	pathuri = g_new (char, pathuri_len);
-	memcpy (pathuri, NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH));
-	memcpy (&pathuri[NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)], path, path_len + 1);
-	if (nm_setting_802_1x_check_cert_scheme (pathuri, pathuri_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH)
-		return NULL;
-
-	NM_SET_OUT (out_exists, exists);
-	return g_steal_pointer (&pathuri);
+    const char *  data   = pdata;
+    gboolean      exists = FALSE;
+    gsize         validate_len;
+    gsize         path_len, pathuri_len;
+    gs_free char *path    = NULL;
+    gs_free char *pathuri = NULL;
+
+    g_return_val_if_fail(base_dir && base_dir[0] == '/', NULL);
+
+    if (!pdata)
+        return NULL;
+    if (data_len == -1)
+        data_len = strlen(data);
+    if (data_len > 500 || data_len < 1)
+        return NULL;
+
+    /* If there's a trailing zero tell g_utf8_validate() to validate until the zero */
+    if (data[data_len - 1] == '\0') {
+        /* setting it to -1, would mean we accept data to contain NUL characters before the
+         * end. Don't accept any NUL in [0 .. data_len-1[ . */
+        validate_len = data_len - 1;
+    } else
+        validate_len = data_len;
+    if (validate_len == 0 || g_utf8_validate((const char *) data, validate_len, NULL) == FALSE)
+        return NULL;
+
+    /* Might be a bare path without the file:// prefix; in that case
+     * if it's an absolute path, use that, otherwise treat it as a
+     * relative path to the current directory.
+     */
+
+    path = get_cert_path(base_dir, (const guint8 *) data, data_len);
+
+    /* FIXME(keyfile-parse-in-memory): it is wrong that keyfile reader makes decisions based on
+     * the file systems content. The serialization/parsing should be entirely in-memory. */
+    if (!memchr(data, '/', data_len) && !has_cert_ext(path)) {
+        if (!consider_exists)
+            return NULL;
+        exists = g_file_test(path, G_FILE_TEST_EXISTS);
+        if (!exists)
+            return NULL;
+    } else if (out_exists)
+        exists = g_file_test(path, G_FILE_TEST_EXISTS);
+
+    /* Construct the proper value as required for the PATH scheme.
+     *
+     * When returning TRUE, we must also be sure that @data_len does not look like
+     * the deprecated format of list of integers. With this implementation that is the
+     * case, as long as @consider_exists is FALSE. */
+    path_len    = strlen(path);
+    pathuri_len = (NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) + 1) + path_len;
+    pathuri     = g_new(char, pathuri_len);
+    memcpy(pathuri,
+           NM_KEYFILE_CERT_SCHEME_PREFIX_PATH,
+           NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH));
+    memcpy(&pathuri[NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)], path, path_len + 1);
+    if (nm_setting_802_1x_check_cert_scheme(pathuri, pathuri_len, NULL)
+        != NM_SETTING_802_1X_CK_SCHEME_PATH)
+        return NULL;
+
+    NM_SET_OUT(out_exists, exists);
+    return g_steal_pointer(&pathuri);
 }
 
-#define HAS_SCHEME_PREFIX(bin, bin_len, scheme) \
-	({ \
-		const char *const _bin = (bin); \
-		const gsize _bin_len = (bin_len); \
-		\
-		nm_assert (_bin && _bin_len > 0); \
-		\
-		(   _bin_len > NM_STRLEN (scheme) + 1 \
-		 && _bin[_bin_len - 1] == '\0' \
-		 && memcmp (_bin, scheme, NM_STRLEN (scheme)) == 0); \
-	})
+#define HAS_SCHEME_PREFIX(bin, bin_len, scheme)                         \
+    ({                                                                  \
+        const char *const _bin     = (bin);                             \
+        const gsize       _bin_len = (bin_len);                         \
+                                                                        \
+        nm_assert(_bin &&_bin_len > 0);                                 \
+                                                                        \
+        (_bin_len > NM_STRLEN(scheme) + 1 && _bin[_bin_len - 1] == '\0' \
+         && memcmp(_bin, scheme, NM_STRLEN(scheme)) == 0);              \
+    })
 
 static void
-cert_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+cert_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_bytes GBytes *bytes = NULL;
-	const char *bin = NULL;
-	gsize bin_len = 0;
-	char *path;
-	gboolean path_exists;
-
-	bytes = get_bytes (info, setting_name, key, TRUE, FALSE);
-	if (bytes)
-		bin = g_bytes_get_data (bytes, &bin_len);
-	if (bin_len == 0) {
-		if (!info->error) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid key/cert value"));
-		}
-		return;
-	}
-
-	if (HAS_SCHEME_PREFIX (bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)) {
-		const char *path2 = &bin[NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)];
-		gs_free char *path2_free = NULL;
-
-		if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PATH) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid key/cert value path \"%s\""),
-			             bin);
-			return;
-		}
-
-		g_object_set (setting, key, bytes, NULL);
-
-		if (path2[0] != '/') {
-			/* we want to read absolute paths because we use keyfile as exchange
-			 * between different processes which might not have the same cwd. */
-			path2_free = get_cert_path (info->base_dir, (const guint8 *) path2,
-			                            bin_len - NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) - 1);
-			path2 = path2_free;
-		}
-
-		/* FIXME(keyfile-parse-in-memory): keyfile reader must not access the file system and
-		 * (in a first step) only operate in memory-only. If the presence of files should be checked,
-		 * then by invoking a callback (and possibly keyfile settings plugin would
-		 * collect the file names to be checked and check them later). */
-		if (!g_file_test (path2, G_FILE_TEST_EXISTS)) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
-			             _("certificate or key file '%s' does not exist"),
-			             path2);
-		}
-		return;
-	}
-
-	if (HAS_SCHEME_PREFIX (bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11)) {
-		if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid PKCS#11 URI \"%s\""),
-			             bin);
-			return;
-		}
-
-		g_object_set (setting, key, bytes, NULL);
-		return;
-	}
-
-	if (HAS_SCHEME_PREFIX (bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB)) {
-		const char *cdata = bin + NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB);
-		gsize cdata_len = bin_len - NM_STRLEN (NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB) - 1;
-		gs_free guchar *bin_decoded = NULL;
-		gsize bin_decoded_len = 0;
-		gsize i;
-		gboolean valid_base64;
-		gs_unref_bytes GBytes *val = NULL;
-
-		/* Let's be strict here. We expect valid base64, no funny stuff!!
-		 * We didn't write such invalid data ourselfes and refuse to read it as blob. */
-		if ((valid_base64 = (cdata_len % 4 == 0))) {
-			for (i = 0; i < cdata_len; i++) {
-				char c = cdata[i];
-
-				if (!(   (c >= 'a' && c <= 'z')
-				      || (c >= 'A' && c <= 'Z')
-				      || (c >= '0' && c <= '9')
-				      || (c == '+' || c == '/'))) {
-					if (c != '=' || i < cdata_len - 2)
-						valid_base64 = FALSE;
-					else {
-						for (; i < cdata_len; i++) {
-							if (cdata[i] != '=')
-								valid_base64 = FALSE;
-						}
-					}
-					break;
-				}
-			}
-		}
-		if (valid_base64)
-			bin_decoded = g_base64_decode (cdata, &bin_decoded_len);
-
-		if (bin_decoded_len == 0) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid key/cert value data:;base64, is not base64"));
-			return;
-		}
-
-		if (nm_setting_802_1x_check_cert_scheme (bin_decoded, bin_decoded_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_BLOB) {
-			/* The blob probably starts with "file://". Setting the cert data will confuse NMSetting8021x.
-			 * In fact this is a limitation of NMSetting8021x which does not support setting blobs that start
-			 * with file://. Just warn and return TRUE to signal that we ~handled~ the setting. */
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid key/cert value data:;base64,file://"));
-			return;
-		}
-
-		val = g_bytes_new_take (g_steal_pointer (&bin_decoded), bin_decoded_len);
-		g_object_set (setting, key, val, NULL);
-		return;
-	}
-
-	/* If not, it might be a plain path */
-	path = nm_keyfile_detect_unqualified_path_scheme (info->base_dir, bin, bin_len, TRUE, &path_exists);
-	if (path) {
-		gs_unref_bytes GBytes *val = NULL;
-
-		/* Construct the proper value as required for the PATH scheme */
-		val = g_bytes_new_take (path, strlen (path) + 1);
-		g_object_set (setting, key, val, NULL);
-
-		/* Warn if the certificate didn't exist */
-		if (!path_exists) {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
-			             _("certificate or key file '%s' does not exist"),
-			             path);
-		}
-		return;
-	}
-
-	if (nm_setting_802_1x_check_cert_scheme (bin, bin_len, NULL) != NM_SETTING_802_1X_CK_SCHEME_BLOB) {
-		/* The blob probably starts with "file://" but contains invalid characters for a path.
-		 * Setting the cert data will confuse NMSetting8021x.
-		 * In fact, NMSetting8021x does not support setting such binary data, so just warn and
-		 * continue. */
-		handle_warn (info,
-		             key,
-		             key,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("invalid key/cert value is not a valid blob"));
-		return;
-	}
-
-	g_object_set (setting, key, bytes, NULL);
+    const char *   setting_name    = nm_setting_get_name(setting);
+    gs_unref_bytes GBytes *bytes   = NULL;
+    const char *           bin     = NULL;
+    gsize                  bin_len = 0;
+    char *                 path;
+    gboolean               path_exists;
+
+    bytes = get_bytes(info, setting_name, key, TRUE, FALSE);
+    if (bytes)
+        bin = g_bytes_get_data(bytes, &bin_len);
+    if (bin_len == 0) {
+        if (!info->error) {
+            handle_warn(info, key, key, NM_KEYFILE_WARN_SEVERITY_WARN, _("invalid key/cert value"));
+        }
+        return;
+    }
+
+    if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)) {
+        const char *  path2      = &bin[NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH)];
+        gs_free char *path2_free = NULL;
+
+        if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL)
+            != NM_SETTING_802_1X_CK_SCHEME_PATH) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid key/cert value path \"%s\""),
+                        bin);
+            return;
+        }
+
+        g_object_set(setting, key, bytes, NULL);
+
+        if (path2[0] != '/') {
+            /* we want to read absolute paths because we use keyfile as exchange
+             * between different processes which might not have the same cwd. */
+            path2_free = get_cert_path(info->base_dir,
+                                       (const guint8 *) path2,
+                                       bin_len - NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH) - 1);
+            path2      = path2_free;
+        }
+
+        /* FIXME(keyfile-parse-in-memory): keyfile reader must not access the file system and
+         * (in a first step) only operate in memory-only. If the presence of files should be checked,
+         * then by invoking a callback (and possibly keyfile settings plugin would
+         * collect the file names to be checked and check them later). */
+        if (!g_file_test(path2, G_FILE_TEST_EXISTS)) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
+                        _("certificate or key file '%s' does not exist"),
+                        path2);
+        }
+        return;
+    }
+
+    if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_PKCS11)) {
+        if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL)
+            != NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid PKCS#11 URI \"%s\""),
+                        bin);
+            return;
+        }
+
+        g_object_set(setting, key, bytes, NULL);
+        return;
+    }
+
+    if (HAS_SCHEME_PREFIX(bin, bin_len, NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB)) {
+        const char *cdata           = bin + NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB);
+        gsize       cdata_len       = bin_len - NM_STRLEN(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB) - 1;
+        gs_free guchar *bin_decoded = NULL;
+        gsize           bin_decoded_len = 0;
+        gsize           i;
+        gboolean        valid_base64;
+        gs_unref_bytes GBytes *val = NULL;
+
+        /* Let's be strict here. We expect valid base64, no funny stuff!!
+         * We didn't write such invalid data ourselfes and refuse to read it as blob. */
+        if ((valid_base64 = (cdata_len % 4 == 0))) {
+            for (i = 0; i < cdata_len; i++) {
+                char c = cdata[i];
+
+                if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
+                      || (c == '+' || c == '/'))) {
+                    if (c != '=' || i < cdata_len - 2)
+                        valid_base64 = FALSE;
+                    else {
+                        for (; i < cdata_len; i++) {
+                            if (cdata[i] != '=')
+                                valid_base64 = FALSE;
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        if (valid_base64)
+            bin_decoded = g_base64_decode(cdata, &bin_decoded_len);
+
+        if (bin_decoded_len == 0) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid key/cert value data:;base64, is not base64"));
+            return;
+        }
+
+        if (nm_setting_802_1x_check_cert_scheme(bin_decoded, bin_decoded_len, NULL)
+            != NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+            /* The blob probably starts with "file://". Setting the cert data will confuse NMSetting8021x.
+             * In fact this is a limitation of NMSetting8021x which does not support setting blobs that start
+             * with file://. Just warn and return TRUE to signal that we ~handled~ the setting. */
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid key/cert value data:;base64,file://"));
+            return;
+        }
+
+        val = g_bytes_new_take(g_steal_pointer(&bin_decoded), bin_decoded_len);
+        g_object_set(setting, key, val, NULL);
+        return;
+    }
+
+    /* If not, it might be a plain path */
+    path =
+        nm_keyfile_detect_unqualified_path_scheme(info->base_dir, bin, bin_len, TRUE, &path_exists);
+    if (path) {
+        gs_unref_bytes GBytes *val = NULL;
+
+        /* Construct the proper value as required for the PATH scheme */
+        val = g_bytes_new_take(path, strlen(path) + 1);
+        g_object_set(setting, key, val, NULL);
+
+        /* Warn if the certificate didn't exist */
+        if (!path_exists) {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_INFO_MISSING_FILE,
+                        _("certificate or key file '%s' does not exist"),
+                        path);
+        }
+        return;
+    }
+
+    if (nm_setting_802_1x_check_cert_scheme(bin, bin_len, NULL)
+        != NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+        /* The blob probably starts with "file://" but contains invalid characters for a path.
+         * Setting the cert data will confuse NMSetting8021x.
+         * In fact, NMSetting8021x does not support setting such binary data, so just warn and
+         * continue. */
+        handle_warn(info,
+                    key,
+                    key,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("invalid key/cert value is not a valid blob"));
+        return;
+    }
+
+    g_object_set(setting, key, bytes, NULL);
 }
 
 static int
-_parity_from_char (int ch)
+_parity_from_char(int ch)
 {
 #if NM_MORE_ASSERTS > 5
-	{
-		static char check = 0;
-
-		if (check == 0) {
-			nm_auto_unref_gtypeclass GEnumClass *klass = g_type_class_ref (NM_TYPE_SETTING_SERIAL_PARITY);
-			guint i;
-
-			check = 1;
-
-			/* In older versions, parity was G_TYPE_CHAR/gint8, and the character
-			 * value was stored as integer.
-			 * For example parity=69 equals parity=E, meaning NM_SETTING_SERIAL_PARITY_EVEN.
-			 *
-			 * That means, certain values are reserved. Assert that these numbers
-			 * are not reused when we extend NMSettingSerialParity enum.
-			 * Actually, since NM_SETTING_SERIAL_PARITY is g_param_spec_enum(),
-			 * we anyway cannot extend the enum without breaking API...
-			 *
-			 * [1] commit "a91e60902e libnm-core: make NMSettingSerial:parity an enum"
-			 * [2] https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=a91e60902eabae1de93d61323dae6ac894b5d40f
-			 */
-			g_assert (G_IS_ENUM_CLASS (klass));
-			for (i = 0; i < klass->n_values; i++) {
-				const GEnumValue *v = &klass->values[i];
-				int num = v->value;
-
-				g_assert (_parity_from_char (num) == -1);
-				g_assert (!NM_IN_SET (num, 'e', 'E', 'o', 'O', 'n', 'N'));
-			}
-		}
-	}
+    {
+        static char check = 0;
+
+        if (check == 0) {
+            nm_auto_unref_gtypeclass GEnumClass *klass =
+                g_type_class_ref(NM_TYPE_SETTING_SERIAL_PARITY);
+            guint i;
+
+            check = 1;
+
+            /* In older versions, parity was G_TYPE_CHAR/gint8, and the character
+             * value was stored as integer.
+             * For example parity=69 equals parity=E, meaning NM_SETTING_SERIAL_PARITY_EVEN.
+             *
+             * That means, certain values are reserved. Assert that these numbers
+             * are not reused when we extend NMSettingSerialParity enum.
+             * Actually, since NM_SETTING_SERIAL_PARITY is g_param_spec_enum(),
+             * we anyway cannot extend the enum without breaking API...
+             *
+             * [1] commit "a91e60902e libnm-core: make NMSettingSerial:parity an enum"
+             * [2] https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=a91e60902eabae1de93d61323dae6ac894b5d40f
+             */
+            g_assert(G_IS_ENUM_CLASS(klass));
+            for (i = 0; i < klass->n_values; i++) {
+                const GEnumValue *v   = &klass->values[i];
+                int               num = v->value;
+
+                g_assert(_parity_from_char(num) == -1);
+                g_assert(!NM_IN_SET(num, 'e', 'E', 'o', 'O', 'n', 'N'));
+            }
+        }
+    }
 #endif
 
-	switch (ch) {
-	case 'E':
-	case 'e':
-		return NM_SETTING_SERIAL_PARITY_EVEN;
-	case 'O':
-	case 'o':
-		return NM_SETTING_SERIAL_PARITY_ODD;
-	case 'N':
-	case 'n':
-		return NM_SETTING_SERIAL_PARITY_NONE;
-	}
-
-	return -1;
+    switch (ch) {
+    case 'E':
+    case 'e':
+        return NM_SETTING_SERIAL_PARITY_EVEN;
+    case 'O':
+    case 'o':
+        return NM_SETTING_SERIAL_PARITY_ODD;
+    case 'N':
+    case 'n':
+        return NM_SETTING_SERIAL_PARITY_NONE;
+    }
+
+    return -1;
 }
 
 static void
-parity_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+parity_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_free_error GError *err = NULL;
-	int parity;
-	gs_free char *tmp_str = NULL;
-	gint64 i64;
-
-	/* Keyfile traditionally stored this as the ASCII value for 'E', 'o', or 'n'.
-	 * We now accept either that or the (case-insensitive) character itself (but
-	 * still always write it the old way, for backward compatibility).
-	 */
-	tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, &err);
-	if (err)
-		goto out_err;
-
-	if (   tmp_str
-	    && tmp_str[0] != '\0'
-	    && tmp_str[1] == '\0') {
-		/* the ASCII characters like 'E' are taken directly... */
-		parity = _parity_from_char (tmp_str[0]);
-		if (parity >= 0)
-			goto parity_good;
-	}
-
-	i64 = _nm_utils_ascii_str_to_int64 (tmp_str, 0, G_MININT, G_MAXINT, G_MININT64);
-	if (   i64 != G_MININT64
-	    && errno == 0) {
-
-		if ((parity = _parity_from_char (i64)) >= 0) {
-			/* another oddity: the string is a valid number. However, if the numeric values
-			 * is one of the supported ASCII codes, accept it (like 69 for 'E').
-			 */
-			goto parity_good;
-		}
-
-		/* Finally, take the numeric value as is. */
-		parity = i64;
-		goto parity_good;
-	}
-
-	handle_warn (info,
-	             key,
-	             key,
-	             NM_KEYFILE_WARN_SEVERITY_WARN,
-	             _("invalid parity value '%s'"),
-	             tmp_str ?: "");
-	return;
+    const char *  setting_name = nm_setting_get_name(setting);
+    gs_free_error GError *err  = NULL;
+    int                   parity;
+    gs_free char *        tmp_str = NULL;
+    gint64                i64;
+
+    /* Keyfile traditionally stored this as the ASCII value for 'E', 'o', or 'n'.
+     * We now accept either that or the (case-insensitive) character itself (but
+     * still always write it the old way, for backward compatibility).
+     */
+    tmp_str = nm_keyfile_plugin_kf_get_value(info->keyfile, setting_name, key, &err);
+    if (err)
+        goto out_err;
+
+    if (tmp_str && tmp_str[0] != '\0' && tmp_str[1] == '\0') {
+        /* the ASCII characters like 'E' are taken directly... */
+        parity = _parity_from_char(tmp_str[0]);
+        if (parity >= 0)
+            goto parity_good;
+    }
+
+    i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MININT64);
+    if (i64 != G_MININT64 && errno == 0) {
+        if ((parity = _parity_from_char(i64)) >= 0) {
+            /* another oddity: the string is a valid number. However, if the numeric values
+             * is one of the supported ASCII codes, accept it (like 69 for 'E').
+             */
+            goto parity_good;
+        }
+
+        /* Finally, take the numeric value as is. */
+        parity = i64;
+        goto parity_good;
+    }
+
+    handle_warn(info,
+                key,
+                key,
+                NM_KEYFILE_WARN_SEVERITY_WARN,
+                _("invalid parity value '%s'"),
+                tmp_str ?: "");
+    return;
 
 parity_good:
-	nm_g_object_set_property_enum (G_OBJECT (setting), key, NM_TYPE_SETTING_SERIAL_PARITY, parity, &err);
+    nm_g_object_set_property_enum(G_OBJECT(setting),
+                                  key,
+                                  NM_TYPE_SETTING_SERIAL_PARITY,
+                                  parity,
+                                  &err);
 
 out_err:
-	if (!err)
-		return;
-	if (nm_keyfile_error_is_not_found (err)) {
-		/* ignore such errors. The key is not present. */
-		return;
-	}
-	handle_warn (info,
-	             key,
-	             key,
-	             NM_KEYFILE_WARN_SEVERITY_WARN,
-	             _("invalid setting: %s"),
-	             err->message);
+    if (!err)
+        return;
+    if (nm_keyfile_error_is_not_found(err)) {
+        /* ignore such errors. The key is not present. */
+        return;
+    }
+    handle_warn(info,
+                key,
+                key,
+                NM_KEYFILE_WARN_SEVERITY_WARN,
+                _("invalid setting: %s"),
+                err->message);
 }
 
 static void
-team_config_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+team_config_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_free char *conf = NULL;
-	gs_free_error GError *error = NULL;
-
-	conf = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
-
-	g_object_set (G_OBJECT (setting), key, conf, NULL);
-
-	if (   conf
-	    && !nm_setting_verify (setting, NULL, &error)) {
-		handle_warn (info,
-		             key,
-		             key,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("ignoring invalid team configuration: %s"),
-		             error->message);
-		g_object_set (G_OBJECT (setting), key, NULL, NULL);
-	}
+    const char *  setting_name  = nm_setting_get_name(setting);
+    gs_free char *conf          = NULL;
+    gs_free_error GError *error = NULL;
+
+    conf = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
+
+    g_object_set(G_OBJECT(setting), key, conf, NULL);
+
+    if (conf && !nm_setting_verify(setting, NULL, &error)) {
+        handle_warn(info,
+                    key,
+                    key,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("ignoring invalid team configuration: %s"),
+                    error->message);
+        g_object_set(G_OBJECT(setting), key, NULL, NULL);
+    }
 }
 
 static void
-bridge_vlan_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+bridge_vlan_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	gs_unref_ptrarray GPtrArray *vlans = NULL;
-	gs_free char *value = NULL;
-	gs_free const char **strv = NULL;
-	const char *const *iter;
-	GError *local = NULL;
-	NMBridgeVlan *vlan;
-
-	value = nm_keyfile_plugin_kf_get_string (info->keyfile,
-	                                         nm_setting_get_name (setting),
-	                                         key,
-	                                         NULL);
-	if (!value || !value[0])
-		return;
-
-	vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
-
-	strv = nm_utils_escaped_tokens_split (value, ",");
-	if (strv) {
-		for (iter = strv; *iter; iter++) {
-			vlan = nm_bridge_vlan_from_str (*iter, &local);
-			if (!vlan) {
-				handle_warn (info,
-				             key,
-				             key,
-				             NM_KEYFILE_WARN_SEVERITY_WARN,
-				             "invalid bridge VLAN: %s",
-				             local->message);
-				g_clear_error (&local);
-				continue;
-			}
-			g_ptr_array_add (vlans, vlan);
-		}
-	}
-
-	if (vlans->len > 0)
-		g_object_set (setting, key, vlans, NULL);
+    gs_unref_ptrarray GPtrArray *vlans = NULL;
+    gs_free char *               value = NULL;
+    gs_free const char **        strv  = NULL;
+    const char *const *          iter;
+    GError *                     local = NULL;
+    NMBridgeVlan *               vlan;
+
+    value = nm_keyfile_plugin_kf_get_string(info->keyfile, nm_setting_get_name(setting), key, NULL);
+    if (!value || !value[0])
+        return;
+
+    vlans = g_ptr_array_new_with_free_func((GDestroyNotify) nm_bridge_vlan_unref);
+
+    strv = nm_utils_escaped_tokens_split(value, ",");
+    if (strv) {
+        for (iter = strv; *iter; iter++) {
+            vlan = nm_bridge_vlan_from_str(*iter, &local);
+            if (!vlan) {
+                handle_warn(info,
+                            key,
+                            key,
+                            NM_KEYFILE_WARN_SEVERITY_WARN,
+                            "invalid bridge VLAN: %s",
+                            local->message);
+                g_clear_error(&local);
+                continue;
+            }
+            g_ptr_array_add(vlans, vlan);
+        }
+    }
+
+    if (vlans->len > 0)
+        g_object_set(setting, key, vlans, NULL);
 }
 
 static void
-qdisc_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+qdisc_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_ptrarray GPtrArray *qdiscs = NULL;
-	gs_strfreev char **keys = NULL;
-	gsize n_keys = 0;
-	int i;
-
-	keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, setting_name, &n_keys, NULL);
-	if (n_keys == 0)
-		return;
-
-	qdiscs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_qdisc_unref);
-
-	for (i = 0; i < n_keys; i++) {
-		NMTCQdisc *qdisc;
-		const char *qdisc_parent;
-		gs_free char *qdisc_rest = NULL;
-		gs_free char *qdisc_str = NULL;
-		gs_free_error GError *err = NULL;
-
-		if (!g_str_has_prefix (keys[i], "qdisc."))
-			continue;
-
-		qdisc_parent = keys[i] + sizeof ("qdisc.") - 1;
-		qdisc_rest = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, keys[i], NULL);
-		qdisc_str = g_strdup_printf ("%s%s %s",
-		                             _nm_utils_parse_tc_handle (qdisc_parent, NULL) != TC_H_UNSPEC ? "parent " : "",
-		                             qdisc_parent,
-		                             qdisc_rest);
-
-		qdisc = nm_utils_tc_qdisc_from_str (qdisc_str, &err);
-		if (!qdisc) {
-			handle_warn (info,
-			             keys[i],
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid qdisc: %s"),
-			             err->message);
-		} else {
-			g_ptr_array_add (qdiscs, qdisc);
-		}
-	}
-
-	if (qdiscs->len >= 1)
-		g_object_set (setting, key, qdiscs, NULL);
+    const char *      setting_name      = nm_setting_get_name(setting);
+    gs_unref_ptrarray GPtrArray *qdiscs = NULL;
+    gs_strfreev char **          keys   = NULL;
+    gsize                        n_keys = 0;
+    int                          i;
+
+    keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL);
+    if (n_keys == 0)
+        return;
+
+    qdiscs = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_qdisc_unref);
+
+    for (i = 0; i < n_keys; i++) {
+        NMTCQdisc *   qdisc;
+        const char *  qdisc_parent;
+        gs_free char *qdisc_rest  = NULL;
+        gs_free char *qdisc_str   = NULL;
+        gs_free_error GError *err = NULL;
+
+        if (!g_str_has_prefix(keys[i], "qdisc."))
+            continue;
+
+        qdisc_parent = keys[i] + sizeof("qdisc.") - 1;
+        qdisc_rest   = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL);
+        qdisc_str    = g_strdup_printf(
+            "%s%s %s",
+            _nm_utils_parse_tc_handle(qdisc_parent, NULL) != TC_H_UNSPEC ? "parent " : "",
+            qdisc_parent,
+            qdisc_rest);
+
+        qdisc = nm_utils_tc_qdisc_from_str(qdisc_str, &err);
+        if (!qdisc) {
+            handle_warn(info,
+                        keys[i],
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid qdisc: %s"),
+                        err->message);
+        } else {
+            g_ptr_array_add(qdiscs, qdisc);
+        }
+    }
+
+    if (qdiscs->len >= 1)
+        g_object_set(setting, key, qdiscs, NULL);
 }
 
 static void
-tfilter_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
+tfilter_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	gs_unref_ptrarray GPtrArray *tfilters = NULL;
-	gs_strfreev char **keys = NULL;
-	gsize n_keys = 0;
-	int i;
-
-	keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, setting_name, &n_keys, NULL);
-	if (n_keys == 0)
-		return;
-
-	tfilters = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_tc_tfilter_unref);
-
-	for (i = 0; i < n_keys; i++) {
-		NMTCTfilter *tfilter;
-		const char *tfilter_parent;
-		gs_free char *tfilter_rest = NULL;
-		gs_free char *tfilter_str = NULL;
-		gs_free_error GError *err = NULL;
-
-		if (!g_str_has_prefix (keys[i], "tfilter."))
-			continue;
-
-		tfilter_parent = keys[i] + sizeof ("tfilter.") - 1;
-		tfilter_rest = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, keys[i], NULL);
-		tfilter_str = g_strdup_printf ("%s%s %s",
-		                             _nm_utils_parse_tc_handle (tfilter_parent, NULL) != TC_H_UNSPEC ? "parent " : "",
-		                             tfilter_parent,
-		                             tfilter_rest);
-
-		tfilter = nm_utils_tc_tfilter_from_str (tfilter_str, &err);
-		if (!tfilter) {
-			handle_warn (info,
-			             keys[i],
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid tfilter: %s"),
-			             err->message);
-		} else {
-			g_ptr_array_add (tfilters, tfilter);
-		}
-	}
-
-	if (tfilters->len >= 1)
-		g_object_set (setting, key, tfilters, NULL);
+    const char *      setting_name        = nm_setting_get_name(setting);
+    gs_unref_ptrarray GPtrArray *tfilters = NULL;
+    gs_strfreev char **          keys     = NULL;
+    gsize                        n_keys   = 0;
+    int                          i;
+
+    keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL);
+    if (n_keys == 0)
+        return;
+
+    tfilters = g_ptr_array_new_with_free_func((GDestroyNotify) nm_tc_tfilter_unref);
+
+    for (i = 0; i < n_keys; i++) {
+        NMTCTfilter * tfilter;
+        const char *  tfilter_parent;
+        gs_free char *tfilter_rest = NULL;
+        gs_free char *tfilter_str  = NULL;
+        gs_free_error GError *err  = NULL;
+
+        if (!g_str_has_prefix(keys[i], "tfilter."))
+            continue;
+
+        tfilter_parent = keys[i] + sizeof("tfilter.") - 1;
+        tfilter_rest = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, keys[i], NULL);
+        tfilter_str  = g_strdup_printf(
+            "%s%s %s",
+            _nm_utils_parse_tc_handle(tfilter_parent, NULL) != TC_H_UNSPEC ? "parent " : "",
+            tfilter_parent,
+            tfilter_rest);
+
+        tfilter = nm_utils_tc_tfilter_from_str(tfilter_str, &err);
+        if (!tfilter) {
+            handle_warn(info,
+                        keys[i],
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid tfilter: %s"),
+                        err->message);
+        } else {
+            g_ptr_array_add(tfilters, tfilter);
+        }
+    }
+
+    if (tfilters->len >= 1)
+        g_object_set(setting, key, tfilters, NULL);
 }
 
 /*****************************************************************************/
@@ -1999,1757 +1969,1610 @@ tfilter_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
  * from the real setting name to the more-readable alias.
  */
 static void
-setting_alias_writer (KeyfileWriterInfo *info,
-                      NMSetting *setting,
-                      const char *key,
-                      const GValue *value)
+setting_alias_writer(KeyfileWriterInfo *info,
+                     NMSetting *        setting,
+                     const char *       key,
+                     const GValue *     value)
 {
-	const char *str, *alias;
-
-	str = g_value_get_string (value);
-	alias = nm_keyfile_plugin_get_alias_for_setting_name (str);
-	nm_keyfile_plugin_kf_set_string (info->keyfile,
-	                                 nm_setting_get_name (setting),
-	                                 key,
-	                                 alias ?: str);
+    const char *str, *alias;
+
+    str   = g_value_get_string(value);
+    alias = nm_keyfile_plugin_get_alias_for_setting_name(str);
+    nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, alias ?: str);
 }
 
 static void
-sriov_vfs_writer (KeyfileWriterInfo *info,
-                  NMSetting *setting,
-                  const char *key,
-                  const GValue *value)
+sriov_vfs_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	GPtrArray *vfs;
-	guint i;
+    GPtrArray *vfs;
+    guint      i;
 
-	vfs = g_value_get_boxed (value);
-	if (!vfs)
-		return;
+    vfs = g_value_get_boxed(value);
+    if (!vfs)
+        return;
 
-	for (i = 0; i < vfs->len; i++) {
-		const NMSriovVF *vf = vfs->pdata[i];
-		gs_free char *kf_value = NULL;
-		char kf_key[32];
+    for (i = 0; i < vfs->len; i++) {
+        const NMSriovVF *vf       = vfs->pdata[i];
+        gs_free char *   kf_value = NULL;
+        char             kf_key[32];
 
-		kf_value = nm_utils_sriov_vf_to_str (vf, TRUE, NULL);
-		if (!kf_value)
-			continue;
+        kf_value = nm_utils_sriov_vf_to_str(vf, TRUE, NULL);
+        if (!kf_value)
+            continue;
 
-		nm_sprintf_buf (kf_key, "vf.%u", nm_sriov_vf_get_index (vf));
+        nm_sprintf_buf(kf_key, "vf.%u", nm_sriov_vf_get_index(vf));
 
-		nm_keyfile_plugin_kf_set_string (info->keyfile,
-		                                 nm_setting_get_name (setting),
-		                                 kf_key,
-		                                 kf_value);
-	}
+        nm_keyfile_plugin_kf_set_string(info->keyfile,
+                                        nm_setting_get_name(setting),
+                                        kf_key,
+                                        kf_value);
+    }
 }
 
 static void
-write_array_of_uint (GKeyFile *file,
-                     NMSetting *setting,
-                     const char *key,
-                     const GValue *value)
+write_array_of_uint(GKeyFile *file, NMSetting *setting, const char *key, const GValue *value)
 {
-	GArray *array;
+    GArray *array;
 
-	array = g_value_get_boxed (value);
+    array = g_value_get_boxed(value);
 
-	nm_assert (!array || g_array_get_element_size (array) == sizeof (guint));
+    nm_assert(!array || g_array_get_element_size(array) == sizeof(guint));
 
-	if (!array || !array->len)
-		return;
+    if (!array || !array->len)
+        return;
 
-	nm_keyfile_plugin_kf_set_integer_list_uint (file,
-	                                            nm_setting_get_name (setting),
-	                                            key,
-	                                            (const guint *) array->data,
-	                                            array->len);
+    nm_keyfile_plugin_kf_set_integer_list_uint(file,
+                                               nm_setting_get_name(setting),
+                                               key,
+                                               (const guint *) array->data,
+                                               array->len);
 }
 
 static void
-dns_writer (KeyfileWriterInfo *info,
-            NMSetting *setting,
-            const char *key,
-            const GValue *value)
+dns_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	char **list;
-
-	list = g_value_get_boxed (value);
-	if (list && list[0]) {
-		nm_keyfile_plugin_kf_set_string_list (info->keyfile, nm_setting_get_name (setting), key,
-		                                      (const char **) list, g_strv_length (list));
-	}
+    char **list;
+
+    list = g_value_get_boxed(value);
+    if (list && list[0]) {
+        nm_keyfile_plugin_kf_set_string_list(info->keyfile,
+                                             nm_setting_get_name(setting),
+                                             key,
+                                             (const char **) list,
+                                             g_strv_length(list));
+    }
 }
 
 static void
-ip6_addr_gen_mode_writer (KeyfileWriterInfo *info,
-                          NMSetting *setting,
-                          const char *key,
-                          const GValue *value)
+ip6_addr_gen_mode_writer(KeyfileWriterInfo *info,
+                         NMSetting *        setting,
+                         const char *       key,
+                         const GValue *     value)
 {
-	NMSettingIP6ConfigAddrGenMode addr_gen_mode;
-	gs_free char *str = NULL;
-
-	addr_gen_mode = (NMSettingIP6ConfigAddrGenMode) g_value_get_int (value);
-	str = nm_utils_enum_to_str (nm_setting_ip6_config_addr_gen_mode_get_type (),
-	                            addr_gen_mode);
-	nm_keyfile_plugin_kf_set_string (info->keyfile,
-	                                 nm_setting_get_name (setting),
-	                                 key,
-	                                 str);
+    NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+    gs_free char *                str = NULL;
+
+    addr_gen_mode = (NMSettingIP6ConfigAddrGenMode) g_value_get_int(value);
+    str = nm_utils_enum_to_str(nm_setting_ip6_config_addr_gen_mode_get_type(), addr_gen_mode);
+    nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, str);
 }
 
 static void
-write_ip_values (GKeyFile *file,
-                 const char *setting_name,
-                 GPtrArray *array,
-                 const char *gateway,
-                 gboolean is_route)
+write_ip_values(GKeyFile *  file,
+                const char *setting_name,
+                GPtrArray * array,
+                const char *gateway,
+                gboolean    is_route)
 {
-	nm_auto_free_gstring GString *output = NULL;
-	int addr_family;
-	guint i;
-	const char *addr;
-	const char *gw;
-	guint32 plen;
-	char key_name[64];
-	char *key_name_idx;
-
-	if (!array->len)
-		return;
-
-	addr_family =   nm_streq (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME)
-	              ? AF_INET
-	              : AF_INET6;
-
-	strcpy (key_name, is_route ? "route" : "address");
-	key_name_idx = key_name + strlen (key_name);
-
-	output = g_string_sized_new (2*INET_ADDRSTRLEN + 10);
-	for (i = 0; i < array->len; i++) {
-		gint64 metric = -1;
-
-		if (is_route) {
-			NMIPRoute *route = array->pdata[i];
-
-			addr = nm_ip_route_get_dest (route);
-			plen = nm_ip_route_get_prefix (route);
-			gw = nm_ip_route_get_next_hop (route);
-			metric = nm_ip_route_get_metric (route);
-		} else {
-			NMIPAddress *address = array->pdata[i];
-
-			addr = nm_ip_address_get_address (address);
-			plen = nm_ip_address_get_prefix (address);
-			gw =   (i == 0)
-			     ? gateway
-			     : NULL;
-		}
-
-		g_string_set_size (output, 0);
-		g_string_append_printf (output, "%s/%u", addr, plen);
-		if (   metric != -1
-		    || gw) {
-			/* Older versions of the plugin do not support the form
-			 * "a.b.c.d/plen,,metric", so, we always have to write the
-			 * gateway, even if there isn't one.
-			 * The current version supports reading of the above form.
-			 */
-			if (!gw) {
-				if (addr_family == AF_INET)
-					gw = "0.0.0.0";
-				else
-					gw = "::";
-			}
-
-			g_string_append_printf (output, ",%s", gw);
-			if (   is_route
-			    && metric != -1)
-				g_string_append_printf (output, ",%lu", (unsigned long) metric);
-		}
-
-		sprintf (key_name_idx, "%u", i + 1);
-		nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str);
-
-		if (is_route) {
-			gs_free char *attributes = NULL;
-
-			attributes = nm_utils_format_variant_attributes (_nm_ip_route_get_attributes (array->pdata[i]),
-			                                                 ',', '=');
-			if (attributes) {
-				g_strlcat (key_name, "_options", sizeof (key_name));
-				nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes);
-			}
-		}
-	}
+    if (array->len > 0) {
+        nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT(2 * INET_ADDRSTRLEN + 10, FALSE);
+        int                      addr_family;
+        guint                    i;
+        const char *             addr;
+        const char *             gw;
+        guint32                  plen;
+        char                     key_name[64];
+        char *                   key_name_idx;
+
+        addr_family =
+            nm_streq(setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) ? AF_INET : AF_INET6;
+
+        strcpy(key_name, is_route ? "route" : "address");
+        key_name_idx = key_name + strlen(key_name);
+
+        for (i = 0; i < array->len; i++) {
+            gint64 metric = -1;
+
+            if (is_route) {
+                NMIPRoute *route = array->pdata[i];
+
+                addr   = nm_ip_route_get_dest(route);
+                plen   = nm_ip_route_get_prefix(route);
+                gw     = nm_ip_route_get_next_hop(route);
+                metric = nm_ip_route_get_metric(route);
+            } else {
+                NMIPAddress *address = array->pdata[i];
+
+                addr = nm_ip_address_get_address(address);
+                plen = nm_ip_address_get_prefix(address);
+                gw   = (i == 0) ? gateway : NULL;
+            }
+
+            nm_str_buf_set_size(&output, 0, FALSE, FALSE);
+            nm_str_buf_append_printf(&output, "%s/%u", addr, plen);
+            if (metric != -1 || gw) {
+                /* Older versions of the plugin do not support the form
+                 * "a.b.c.d/plen,,metric", so, we always have to write the
+                 * gateway, even if there isn't one.
+                 * The current version supports reading of the above form.
+                 */
+                if (!gw) {
+                    if (addr_family == AF_INET)
+                        gw = "0.0.0.0";
+                    else
+                        gw = "::";
+                }
+
+                nm_str_buf_append_c(&output, ',');
+                nm_str_buf_append(&output, gw);
+                if (is_route && metric != -1)
+                    nm_str_buf_append_printf(&output, ",%lu", (unsigned long) metric);
+            }
+
+            sprintf(key_name_idx, "%u", i + 1);
+            nm_keyfile_plugin_kf_set_string(file,
+                                            setting_name,
+                                            key_name,
+                                            nm_str_buf_get_str(&output));
+
+            if (is_route) {
+                gs_free char *attributes = NULL;
+
+                attributes =
+                    nm_utils_format_variant_attributes(_nm_ip_route_get_attributes(array->pdata[i]),
+                                                       ',',
+                                                       '=');
+                if (attributes) {
+                    g_strlcat(key_name, "_options", sizeof(key_name));
+                    nm_keyfile_plugin_kf_set_string(file, setting_name, key_name, attributes);
+                }
+            }
+        }
+    }
 }
 
 static void
-addr_writer (KeyfileWriterInfo *info,
-             NMSetting *setting,
-             const char *key,
-             const GValue *value)
+addr_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	GPtrArray *array;
-	const char *setting_name = nm_setting_get_name (setting);
-	const char *gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
+    GPtrArray * array;
+    const char *setting_name = nm_setting_get_name(setting);
+    const char *gateway      = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting));
 
-	array = (GPtrArray *) g_value_get_boxed (value);
-	if (array && array->len)
-		write_ip_values (info->keyfile, setting_name, array, gateway, FALSE);
+    array = (GPtrArray *) g_value_get_boxed(value);
+    if (array && array->len)
+        write_ip_values(info->keyfile, setting_name, array, gateway, FALSE);
 }
 
 static void
-route_writer (KeyfileWriterInfo *info,
-              NMSetting *setting,
-              const char *key,
-              const GValue *value)
+route_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	GPtrArray *array;
-	const char *setting_name = nm_setting_get_name (setting);
+    GPtrArray * array;
+    const char *setting_name = nm_setting_get_name(setting);
 
-	array = (GPtrArray *) g_value_get_boxed (value);
-	if (array && array->len)
-		write_ip_values (info->keyfile, setting_name, array, NULL, TRUE);
+    array = (GPtrArray *) g_value_get_boxed(value);
+    if (array && array->len)
+        write_ip_values(info->keyfile, setting_name, array, NULL, TRUE);
 }
 
 static void
-bridge_vlan_writer (KeyfileWriterInfo *info,
-                    NMSetting *setting,
-                    const char *key,
-                    const GValue *value)
+bridge_vlan_writer(KeyfileWriterInfo *info,
+                   NMSetting *        setting,
+                   const char *       key,
+                   const GValue *     value)
 {
-	NMBridgeVlan *vlan;
-	GPtrArray *vlans;
-	GString *string;
-	guint i;
-
-	vlans = (GPtrArray *) g_value_get_boxed (value);
-	if (!vlans || !vlans->len)
-		return;
-
-	string = g_string_new ("");
-	for (i = 0; i < vlans->len; i++) {
-		gs_free char *vlan_str = NULL;
-
-		vlan = vlans->pdata[i];
-		vlan_str = nm_bridge_vlan_to_str (vlan, NULL);
-		if (!vlan_str)
-			continue;
-		if (string->len > 0)
-			g_string_append (string, ",");
-		nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string);
-	}
-
-	nm_keyfile_plugin_kf_set_string (info->keyfile,
-	                                 nm_setting_get_name (setting),
-	                                 "vlans",
-	                                 string->str);
-
-	g_string_free (string, TRUE);
+    GPtrArray *vlans;
+
+    vlans = g_value_get_boxed(value);
+    if (vlans && vlans->len > 0) {
+        const guint              string_initial_size = vlans->len * 10u;
+        nm_auto_str_buf NMStrBuf string              = NM_STR_BUF_INIT(string_initial_size, FALSE);
+        guint                    i;
+
+        for (i = 0; i < vlans->len; i++) {
+            gs_free char *vlan_str = NULL;
+
+            vlan_str = nm_bridge_vlan_to_str(vlans->pdata[i], NULL);
+            if (i > 0)
+                nm_str_buf_append_c(&string, ',');
+            nm_utils_escaped_tokens_escape_strbuf_assert(vlan_str, ",", &string);
+        }
+
+        nm_keyfile_plugin_kf_set_string(info->keyfile,
+                                        nm_setting_get_name(setting),
+                                        "vlans",
+                                        nm_str_buf_get_str(&string));
+    }
 }
 
-
 #define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options"
 
 static void
-wired_s390_options_parser_full (KeyfileReaderInfo *info,
-                                const NMMetaSettingInfo *setting_info,
-                                const NMSettInfoProperty *property_info,
-                                const ParseInfoProperty *pip,
-                                NMSetting *setting)
+wired_s390_options_parser_full(KeyfileReaderInfo *       info,
+                               const NMMetaSettingInfo * setting_info,
+                               const NMSettInfoProperty *property_info,
+                               const ParseInfoProperty * pip,
+                               NMSetting *               setting)
 {
-	NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
-	gs_strfreev char **keys = NULL;
-	gsize n_keys;
-	gsize i;
-
-	keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, ETHERNET_S390_OPTIONS_GROUP_NAME, &n_keys, NULL);
-	for (i = 0; i < n_keys; i++) {
-		gs_free char *value = NULL;
-		gs_free char *key_to_free = NULL;
-
-		value = nm_keyfile_plugin_kf_get_string (info->keyfile,
-		                                         ETHERNET_S390_OPTIONS_GROUP_NAME,
-		                                         keys[i],
-		                                         NULL);
-		if (!value)
-			continue;
-
-		nm_setting_wired_add_s390_option (s_wired,
-		                                  nm_keyfile_key_decode (keys[i],
-		                                                         &key_to_free),
-		                                  value);
-	}
+    NMSettingWired *   s_wired = NM_SETTING_WIRED(setting);
+    gs_strfreev char **keys    = NULL;
+    gsize              n_keys;
+    gsize              i;
+
+    keys = nm_keyfile_plugin_kf_get_keys(info->keyfile,
+                                         ETHERNET_S390_OPTIONS_GROUP_NAME,
+                                         &n_keys,
+                                         NULL);
+    for (i = 0; i < n_keys; i++) {
+        gs_free char *value       = NULL;
+        gs_free char *key_to_free = NULL;
+
+        value = nm_keyfile_plugin_kf_get_string(info->keyfile,
+                                                ETHERNET_S390_OPTIONS_GROUP_NAME,
+                                                keys[i],
+                                                NULL);
+        if (!value)
+            continue;
+
+        nm_setting_wired_add_s390_option(s_wired,
+                                         nm_keyfile_key_decode(keys[i], &key_to_free),
+                                         value);
+    }
 }
 
 static void
-wired_s390_options_writer_full (KeyfileWriterInfo *info,
-                                const NMMetaSettingInfo *setting_info,
-                                const NMSettInfoProperty *property_info,
-                                const ParseInfoProperty *pip,
-                                NMSetting *setting)
+wired_s390_options_writer_full(KeyfileWriterInfo *       info,
+                               const NMMetaSettingInfo * setting_info,
+                               const NMSettInfoProperty *property_info,
+                               const ParseInfoProperty * pip,
+                               NMSetting *               setting)
 {
-	NMSettingWired *s_wired = NM_SETTING_WIRED (setting);
-	guint i, n;
-
-	n = nm_setting_wired_get_num_s390_options (s_wired);
-	for (i = 0; i < n; i++) {
-		gs_free char *key_to_free = NULL;
-		const char *opt_key;
-		const char *opt_val;
-
-		nm_setting_wired_get_s390_option (s_wired, i, &opt_key, &opt_val);
-		nm_keyfile_plugin_kf_set_string (info->keyfile,
-		                                 ETHERNET_S390_OPTIONS_GROUP_NAME,
-		                                 nm_keyfile_key_encode (opt_key, &key_to_free),
-		                                 opt_val);
-	}
+    NMSettingWired *s_wired = NM_SETTING_WIRED(setting);
+    guint           i, n;
+
+    n = nm_setting_wired_get_num_s390_options(s_wired);
+    for (i = 0; i < n; i++) {
+        gs_free char *key_to_free = NULL;
+        const char *  opt_key;
+        const char *  opt_val;
+
+        nm_setting_wired_get_s390_option(s_wired, i, &opt_key, &opt_val);
+        nm_keyfile_plugin_kf_set_string(info->keyfile,
+                                        ETHERNET_S390_OPTIONS_GROUP_NAME,
+                                        nm_keyfile_key_encode(opt_key, &key_to_free),
+                                        opt_val);
+    }
 }
 
 static void
-ip_routing_rule_writer_full (KeyfileWriterInfo *info,
-                             const NMMetaSettingInfo *setting_info,
-                             const NMSettInfoProperty *property_info,
-                             const ParseInfoProperty *pip,
-                             NMSetting *setting)
+ip_routing_rule_writer_full(KeyfileWriterInfo *       info,
+                            const NMMetaSettingInfo * setting_info,
+                            const NMSettInfoProperty *property_info,
+                            const ParseInfoProperty * pip,
+                            NMSetting *               setting)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
-	guint i, j, n;
-	char key_name_full[100] = "routing-rule";
-	char *key_name_num = &key_name_full[NM_STRLEN ("routing-rule")];
-
-	n = nm_setting_ip_config_get_num_routing_rules (s_ip);
-	j = 0;
-	for (i = 0; i < n; i++) {
-		NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule (s_ip, i);
-		gs_free char *str = NULL;
-
-		str = nm_ip_routing_rule_to_string (rule,
-		                                    NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE,
-		                                    NULL,
-		                                    NULL);
-		if (!str)
-			continue;
-
-		sprintf (key_name_num, "%u", ++j);
-		nm_keyfile_plugin_kf_set_string (info->keyfile,
-		                                 setting_name,
-		                                 key_name_full,
-		                                 str);
-	}
+    const char *       setting_name = nm_setting_get_name(setting);
+    NMSettingIPConfig *s_ip         = NM_SETTING_IP_CONFIG(setting);
+    guint              i, j, n;
+    char               key_name_full[100] = "routing-rule";
+    char *             key_name_num       = &key_name_full[NM_STRLEN("routing-rule")];
+
+    n = nm_setting_ip_config_get_num_routing_rules(s_ip);
+    j = 0;
+    for (i = 0; i < n; i++) {
+        NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule(s_ip, i);
+        gs_free char *   str  = NULL;
+
+        str =
+            nm_ip_routing_rule_to_string(rule, NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, NULL, NULL);
+        if (!str)
+            continue;
+
+        sprintf(key_name_num, "%u", ++j);
+        nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key_name_full, str);
+    }
 }
 
 static void
-qdisc_writer (KeyfileWriterInfo *info,
-              NMSetting *setting,
-              const char *key,
-              const GValue *value)
+qdisc_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	gsize i;
-	GPtrArray *array;
-
-	array = (GPtrArray *) g_value_get_boxed (value);
-	if (!array || !array->len)
-		return;
-
-	for (i = 0; i < array->len; i++) {
-		NMTCQdisc *qdisc = array->pdata[i];
-		GString *key_name = g_string_sized_new (16);
-		GString *value_str = g_string_sized_new (60);
-
-		g_string_append (key_name, "qdisc.");
-		_nm_utils_string_append_tc_parent (key_name, NULL,
-		                                   nm_tc_qdisc_get_parent (qdisc));
-		_nm_utils_string_append_tc_qdisc_rest (value_str, qdisc);
-
-		nm_keyfile_plugin_kf_set_string (info->keyfile,
-		                                 NM_SETTING_TC_CONFIG_SETTING_NAME,
-		                                 key_name->str,
-		                                 value_str->str);
-
-		g_string_free (key_name, TRUE);
-		g_string_free (value_str, TRUE);
-	}
+    nm_auto_free_gstring GString *key_name  = NULL;
+    nm_auto_free_gstring GString *value_str = NULL;
+    GPtrArray *                   array;
+    guint                         i;
+
+    array = g_value_get_boxed(value);
+    if (!array || !array->len)
+        return;
+
+    for (i = 0; i < array->len; i++) {
+        NMTCQdisc *qdisc = array->pdata[i];
+
+        nm_gstring_prepare(&key_name);
+        nm_gstring_prepare(&value_str);
+
+        g_string_append(key_name, "qdisc.");
+        _nm_utils_string_append_tc_parent(key_name, NULL, nm_tc_qdisc_get_parent(qdisc));
+        _nm_utils_string_append_tc_qdisc_rest(value_str, qdisc);
+
+        nm_keyfile_plugin_kf_set_string(info->keyfile,
+                                        NM_SETTING_TC_CONFIG_SETTING_NAME,
+                                        key_name->str,
+                                        value_str->str);
+    }
 }
 
 static void
-tfilter_writer (KeyfileWriterInfo *info,
-              NMSetting *setting,
-              const char *key,
-              const GValue *value)
+tfilter_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	gsize i;
-	GPtrArray *array;
-
-	array = (GPtrArray *) g_value_get_boxed (value);
-	if (!array || !array->len)
-		return;
-
-	for (i = 0; i < array->len; i++) {
-		NMTCTfilter *tfilter = array->pdata[i];
-		GString *key_name = g_string_sized_new (16);
-		GString *value_str = g_string_sized_new (60);
-
-		g_string_append (key_name, "tfilter.");
-		_nm_utils_string_append_tc_parent (key_name, NULL,
-		                                   nm_tc_tfilter_get_parent (tfilter));
-		_nm_utils_string_append_tc_tfilter_rest (value_str, tfilter, NULL);
-
-		nm_keyfile_plugin_kf_set_string (info->keyfile,
-		                                 NM_SETTING_TC_CONFIG_SETTING_NAME,
-		                                 key_name->str,
-		                                 value_str->str);
-
-		g_string_free (key_name, TRUE);
-		g_string_free (value_str, TRUE);
-	}
+    nm_auto_free_gstring GString *key_name  = NULL;
+    nm_auto_free_gstring GString *value_str = NULL;
+    GPtrArray *                   array;
+    guint                         i;
+
+    array = g_value_get_boxed(value);
+    if (!array || !array->len)
+        return;
+
+    for (i = 0; i < array->len; i++) {
+        NMTCTfilter *tfilter = array->pdata[i];
+
+        nm_gstring_prepare(&key_name);
+        nm_gstring_prepare(&value_str);
+
+        g_string_append(key_name, "tfilter.");
+        _nm_utils_string_append_tc_parent(key_name, NULL, nm_tc_tfilter_get_parent(tfilter));
+        _nm_utils_string_append_tc_tfilter_rest(value_str, tfilter, NULL);
+
+        nm_keyfile_plugin_kf_set_string(info->keyfile,
+                                        NM_SETTING_TC_CONFIG_SETTING_NAME,
+                                        key_name->str,
+                                        value_str->str);
+    }
 }
 
 static void
-write_hash_of_string (GKeyFile *file,
-                      NMSetting *setting,
-                      const char *key,
-                      const GValue *value)
+write_hash_of_string(GKeyFile *file, NMSetting *setting, const char *key, const GValue *value)
 {
-	GHashTable *hash;
-	const char *group_name = nm_setting_get_name (setting);
-	gboolean vpn_secrets = FALSE;
-	gs_free const char **keys = NULL;
-	guint i, l;
-
-	nm_assert (   (NM_IS_SETTING_VPN (setting)  && nm_streq (key, NM_SETTING_VPN_DATA))
-	           || (NM_IS_SETTING_VPN (setting)  && nm_streq (key, NM_SETTING_VPN_SECRETS))
-	           || (NM_IS_SETTING_BOND (setting) && nm_streq (key, NM_SETTING_BOND_OPTIONS))
-	           || (NM_IS_SETTING_USER (setting) && nm_streq (key, NM_SETTING_USER_DATA)));
-
-	/* Write VPN secrets out to a different group to keep them separate */
-	if (   NM_IS_SETTING_VPN (setting)
-	    && nm_streq (key, NM_SETTING_VPN_SECRETS)) {
-		group_name = NM_KEYFILE_GROUP_VPN_SECRETS;
-		vpn_secrets = TRUE;
-	}
-
-	hash = g_value_get_boxed (value);
-
-	keys = nm_utils_strdict_get_keys (hash, TRUE, &l);
-	for (i = 0; i < l; i++) {
-		gs_free char *to_free = NULL;
-		const char *property, *data;
-
-		property = keys[i];
-
-		/* Handle VPN secrets specially; they are nested in the property's hash;
-		 * we don't want to write them if the secret is not saved, not required,
-		 * or owned by a user's secret agent.
-		 */
-		if (vpn_secrets) {
-			NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-
-			if (!nm_setting_get_secret_flags (setting, property, &secret_flags, NULL))
-				nm_assert_not_reached ();
-			if (!_secret_flags_persist_secret (secret_flags))
-				continue;
-		}
-
-		data = g_hash_table_lookup (hash, property);
-		nm_keyfile_plugin_kf_set_string (file, group_name,
-		                                 nm_keyfile_key_encode (property, &to_free),
-		                                 data);
-	}
+    GHashTable *         hash;
+    const char *         group_name  = nm_setting_get_name(setting);
+    gboolean             vpn_secrets = FALSE;
+    gs_free const char **keys        = NULL;
+    guint                i, l;
+
+    nm_assert((NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_DATA))
+              || (NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_SECRETS))
+              || (NM_IS_SETTING_BOND(setting) && nm_streq(key, NM_SETTING_BOND_OPTIONS))
+              || (NM_IS_SETTING_USER(setting) && nm_streq(key, NM_SETTING_USER_DATA)));
+
+    /* Write VPN secrets out to a different group to keep them separate */
+    if (NM_IS_SETTING_VPN(setting) && nm_streq(key, NM_SETTING_VPN_SECRETS)) {
+        group_name  = NM_KEYFILE_GROUP_VPN_SECRETS;
+        vpn_secrets = TRUE;
+    }
+
+    hash = g_value_get_boxed(value);
+
+    keys = nm_utils_strdict_get_keys(hash, TRUE, &l);
+    for (i = 0; i < l; i++) {
+        gs_free char *to_free = NULL;
+        const char *  property, *data;
+
+        property = keys[i];
+
+        /* Handle VPN secrets specially; they are nested in the property's hash;
+         * we don't want to write them if the secret is not saved, not required,
+         * or owned by a user's secret agent.
+         */
+        if (vpn_secrets) {
+            NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+            if (!nm_setting_get_secret_flags(setting, property, &secret_flags, NULL))
+                nm_assert_not_reached();
+            if (!_secret_flags_persist_secret(secret_flags))
+                continue;
+        }
+
+        data = g_hash_table_lookup(hash, property);
+        nm_keyfile_plugin_kf_set_string(file,
+                                        group_name,
+                                        nm_keyfile_key_encode(property, &to_free),
+                                        data);
+    }
 }
 
 static void
-ssid_writer (KeyfileWriterInfo *info,
-             NMSetting *setting,
-             const char *key,
-             const GValue *value)
+ssid_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	GBytes *bytes;
-	const guint8 *ssid_data;
-	gsize ssid_len;
-	const char *setting_name = nm_setting_get_name (setting);
-	gboolean new_format = TRUE;
-	gsize semicolons = 0;
-	gsize i;
-
-	g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES));
-
-	bytes = g_value_get_boxed (value);
-	if (!bytes)
-		return;
-	ssid_data = g_bytes_get_data (bytes, &ssid_len);
-	if (!ssid_data || !ssid_len) {
-		nm_keyfile_plugin_kf_set_string (info->keyfile, setting_name, key, "");
-		return;
-	}
-
-	/* Check whether each byte is printable.  If not, we have to use an
-	 * integer list, otherwise we can just use a string.
-	 */
-	for (i = 0; i < ssid_len; i++) {
-		const char c = ssid_data[i];
-
-		if (!g_ascii_isprint (c)) {
-			new_format = FALSE;
-			break;
-		}
-		if (c == ';')
-			semicolons++;
-	}
-
-	if (new_format) {
-		gs_free char *ssid = NULL;
-
-		if (semicolons == 0)
-			ssid = g_strndup ((char *) ssid_data, ssid_len);
-		else {
-			/* Escape semicolons with backslashes to make strings
-			 * containing ';', such as '16;17;' unambiguous */
-			gsize j = 0;
-
-			ssid = g_malloc (ssid_len + semicolons + 1);
-			for (i = 0; i < ssid_len; i++) {
-				if (ssid_data[i] == ';')
-					ssid[j++] = '\\';
-				ssid[j++] = ssid_data[i];
-			}
-			ssid[j] = '\0';
-		}
-		nm_keyfile_plugin_kf_set_string (info->keyfile, setting_name, key, ssid);
-	} else
-		nm_keyfile_plugin_kf_set_integer_list_uint8 (info->keyfile, setting_name, key, ssid_data, ssid_len);
+    GBytes *      bytes;
+    const guint8 *ssid_data;
+    gsize         ssid_len;
+    const char *  setting_name = nm_setting_get_name(setting);
+    gboolean      new_format   = TRUE;
+    gsize         semicolons   = 0;
+    gsize         i;
+
+    g_return_if_fail(G_VALUE_HOLDS(value, G_TYPE_BYTES));
+
+    bytes = g_value_get_boxed(value);
+    if (!bytes)
+        return;
+    ssid_data = g_bytes_get_data(bytes, &ssid_len);
+    if (!ssid_data || !ssid_len) {
+        nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key, "");
+        return;
+    }
+
+    /* Check whether each byte is printable.  If not, we have to use an
+     * integer list, otherwise we can just use a string.
+     */
+    for (i = 0; i < ssid_len; i++) {
+        const char c = ssid_data[i];
+
+        if (!g_ascii_isprint(c)) {
+            new_format = FALSE;
+            break;
+        }
+        if (c == ';')
+            semicolons++;
+    }
+
+    if (new_format) {
+        gs_free char *ssid = NULL;
+
+        if (semicolons == 0)
+            ssid = g_strndup((char *) ssid_data, ssid_len);
+        else {
+            /* Escape semicolons with backslashes to make strings
+             * containing ';', such as '16;17;' unambiguous */
+            gsize j = 0;
+
+            ssid = g_malloc(ssid_len + semicolons + 1);
+            for (i = 0; i < ssid_len; i++) {
+                if (ssid_data[i] == ';')
+                    ssid[j++] = '\\';
+                ssid[j++] = ssid_data[i];
+            }
+            ssid[j] = '\0';
+        }
+        nm_keyfile_plugin_kf_set_string(info->keyfile, setting_name, key, ssid);
+    } else
+        nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile,
+                                                    setting_name,
+                                                    key,
+                                                    ssid_data,
+                                                    ssid_len);
 }
 
 static void
-password_raw_writer (KeyfileWriterInfo *info,
-                     NMSetting *setting,
-                     const char *key,
-                     const GValue *value)
+password_raw_writer(KeyfileWriterInfo *info,
+                    NMSetting *        setting,
+                    const char *       key,
+                    const GValue *     value)
 {
-	const char *setting_name = nm_setting_get_name (setting);
-	GBytes *array;
-	gsize len;
-	const guint8 *data;
-
-	g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES));
-
-	array = (GBytes *) g_value_get_boxed (value);
-	if (!array)
-		return;
-	data = g_bytes_get_data (array, &len);
-	if (!data)
-		len = 0;
-	nm_keyfile_plugin_kf_set_integer_list_uint8 (info->keyfile, setting_name, key, data, len);
+    const char *  setting_name = nm_setting_get_name(setting);
+    GBytes *      array;
+    gsize         len;
+    const guint8 *data;
+
+    g_return_if_fail(G_VALUE_HOLDS(value, G_TYPE_BYTES));
+
+    array = (GBytes *) g_value_get_boxed(value);
+    if (!array)
+        return;
+    data = g_bytes_get_data(array, &len);
+    if (!data)
+        len = 0;
+    nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile, setting_name, key, data, len);
 }
 
 /*****************************************************************************/
 
 static void
-cert_writer_default (NMConnection *connection,
-                     GKeyFile *file,
-                     NMSetting8021x *setting,
-                     const char *setting_name,
-                     const NMSetting8021xSchemeVtable *vtable)
+cert_writer_default(NMConnection *                    connection,
+                    GKeyFile *                        file,
+                    NMSetting8021x *                  setting,
+                    const char *                      setting_name,
+                    const NMSetting8021xSchemeVtable *vtable)
 {
-	NMSetting8021xCKScheme scheme;
-
-	scheme = vtable->scheme_func (setting);
-	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
-		gs_free char *path_free = NULL;
-		gs_free char *base_dir = NULL;
-		gs_free char *tmp = NULL;
-		const char *path;
-
-		path = vtable->path_func (setting);
-		g_assert (path);
-
-		/* If the path is relative, make it an absolute path.
-		 * Relative paths make a keyfile not easily usable in another
-		 * context. */
-		if (path[0] && path[0] != '/') {
-			base_dir = g_get_current_dir ();
-			path_free = g_strconcat (base_dir, "/", path, NULL);
-			path = path_free;
-		} else
-			base_dir = g_path_get_dirname (path);
-
-		/* path cannot start with "file://" or "data:;base64,", because it is an absolute path.
-		 * Still, make sure that a prefix-less path will be recognized. This can happen
-		 * for example if the path is longer then 500 chars. */
-		tmp = nm_keyfile_detect_unqualified_path_scheme (base_dir, path, -1, FALSE, NULL);
-		if (tmp)
-			nm_clear_g_free (&tmp);
-		else {
-			tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
-			path = tmp;
-		}
-
-		/* Path contains at least a '/', hence it cannot be recognized as the old
-		 * binary format consisting of a list of integers. */
-
-		nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, path);
-	} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
-		GBytes *blob;
-		const guint8 *blob_data;
-		gsize blob_len;
-		gs_free char *blob_base64 = NULL;
-		gs_free char *val = NULL;
-
-		blob = vtable->blob_func (setting);
-		g_assert (blob);
-		blob_data = g_bytes_get_data (blob, &blob_len);
-
-		blob_base64 = g_base64_encode (blob_data, blob_len);
-		val = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB, blob_base64, NULL);
-
-		nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, val);
-	} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
-		nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key,
-		                                 vtable->uri_func (setting));
-	} else {
-		/* scheme_func() returns UNKNOWN in all other cases. The only valid case
-		 * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this
-		 * case, we don't expect the writer to be called, because the default value
-		 * will not be serialized.
-		 * The only other reason for the scheme to be UNKNOWN is an invalid cert.
-		 * But our connection verifies, so that cannot happen either. */
-		g_return_if_reached ();
-	}
+    NMSetting8021xCKScheme scheme;
+
+    scheme = vtable->scheme_func(setting);
+    if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+        gs_free char *path_free = NULL;
+        gs_free char *base_dir  = NULL;
+        gs_free char *tmp       = NULL;
+        const char *  path;
+
+        path = vtable->path_func(setting);
+        g_assert(path);
+
+        /* If the path is relative, make it an absolute path.
+         * Relative paths make a keyfile not easily usable in another
+         * context. */
+        if (path[0] && path[0] != '/') {
+            base_dir  = g_get_current_dir();
+            path_free = g_strconcat(base_dir, "/", path, NULL);
+            path      = path_free;
+        } else
+            base_dir = g_path_get_dirname(path);
+
+        /* path cannot start with "file://" or "data:;base64,", because it is an absolute path.
+         * Still, make sure that a prefix-less path will be recognized. This can happen
+         * for example if the path is longer then 500 chars. */
+        tmp = nm_keyfile_detect_unqualified_path_scheme(base_dir, path, -1, FALSE, NULL);
+        if (tmp)
+            nm_clear_g_free(&tmp);
+        else {
+            tmp  = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
+            path = tmp;
+        }
+
+        /* Path contains at least a '/', hence it cannot be recognized as the old
+         * binary format consisting of a list of integers. */
+
+        nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, path);
+    } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+        GBytes *      blob;
+        const guint8 *blob_data;
+        gsize         blob_len;
+        gs_free char *blob_base64 = NULL;
+        gs_free char *val         = NULL;
+
+        blob = vtable->blob_func(setting);
+        g_assert(blob);
+        blob_data = g_bytes_get_data(blob, &blob_len);
+
+        blob_base64 = g_base64_encode(blob_data, blob_len);
+        val         = g_strconcat(NM_KEYFILE_CERT_SCHEME_PREFIX_BLOB, blob_base64, NULL);
+
+        nm_keyfile_plugin_kf_set_string(file, setting_name, vtable->setting_key, val);
+    } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
+        nm_keyfile_plugin_kf_set_string(file,
+                                        setting_name,
+                                        vtable->setting_key,
+                                        vtable->uri_func(setting));
+    } else {
+        /* scheme_func() returns UNKNOWN in all other cases. The only valid case
+         * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this
+         * case, we don't expect the writer to be called, because the default value
+         * will not be serialized.
+         * The only other reason for the scheme to be UNKNOWN is an invalid cert.
+         * But our connection verifies, so that cannot happen either. */
+        g_return_if_reached();
+    }
 }
 
 static void
-cert_writer (KeyfileWriterInfo *info,
-             NMSetting *setting,
-             const char *key,
-             const GValue *value)
+cert_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
 {
-	const NMSetting8021xSchemeVtable *vtable = NULL;
-	const char *setting_name;
-	guint i;
-
-	for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) {
-		if (nm_streq0 (nm_setting_8021x_scheme_vtable[i].setting_key, key)) {
-			vtable = &nm_setting_8021x_scheme_vtable[i];
-			break;
-		}
-	}
-	if (!vtable)
-		g_return_if_reached ();
-
-	setting_name = nm_setting_get_name (NM_SETTING (setting));
-
-	if (info->write_handler) {
-		NMKeyfileHandlerData handler_data;
-
-		_key_file_handler_data_init_write (&handler_data,
-		                                   NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
-		                                   info,
-		                                   setting_name,
-		                                   vtable->setting_key,
-		                                   setting,
-		                                   key);
-		handler_data.write_cert = (NMKeyfileHandlerDataWriteCert) {
-			.vtable  = vtable,
-		};
-
-		if (info->write_handler (info->connection,
-		                         info->keyfile,
-		                         NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
-		                         &handler_data,
-		                         info->user_data))
-			return;
-		if (info->error)
-			return;
-	}
-
-	cert_writer_default (info->connection,
-	                     info->keyfile,
-	                     NM_SETTING_802_1X (setting),
-	                     setting_name,
-	                     vtable);
+    const NMSetting8021xSchemeVtable *vtable = NULL;
+    const char *                      setting_name;
+    guint                             i;
+
+    for (i = 0; nm_setting_8021x_scheme_vtable[i].setting_key; i++) {
+        if (nm_streq0(nm_setting_8021x_scheme_vtable[i].setting_key, key)) {
+            vtable = &nm_setting_8021x_scheme_vtable[i];
+            break;
+        }
+    }
+    if (!vtable)
+        g_return_if_reached();
+
+    setting_name = nm_setting_get_name(NM_SETTING(setting));
+
+    if (info->write_handler) {
+        NMKeyfileHandlerData handler_data;
+
+        _key_file_handler_data_init_write(&handler_data,
+                                          NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
+                                          info,
+                                          setting_name,
+                                          vtable->setting_key,
+                                          setting,
+                                          key);
+        handler_data.write_cert = (NMKeyfileHandlerDataWriteCert){
+            .vtable = vtable,
+        };
+
+        if (info->write_handler(info->connection,
+                                info->keyfile,
+                                NM_KEYFILE_HANDLER_TYPE_WRITE_CERT,
+                                &handler_data,
+                                info->user_data))
+            return;
+        if (info->error)
+            return;
+    }
+
+    cert_writer_default(info->connection,
+                        info->keyfile,
+                        NM_SETTING_802_1X(setting),
+                        setting_name,
+                        vtable);
 }
 
 /*****************************************************************************/
 
 struct _ParseInfoProperty {
-	const char *property_name;
-	union {
-		void (*parser) (KeyfileReaderInfo *info,
-		                NMSetting *setting,
-		                const char *key);
-		void (*parser_full) (KeyfileReaderInfo *info,
-		                     const NMMetaSettingInfo *setting_info,
-		                     const NMSettInfoProperty *property_info,
-		                     const ParseInfoProperty *pip,
-		                     NMSetting *setting);
-	};
-	union {
-		void (*writer) (KeyfileWriterInfo *info,
-		                NMSetting *setting,
-		                const char *key,
-		                const GValue *value);
-		void (*writer_full) (KeyfileWriterInfo *info,
-		                     const NMMetaSettingInfo *setting_info,
-		                     const NMSettInfoProperty *property_info,
-		                     const ParseInfoProperty *pip,
-		                     NMSetting *setting);
-	};
-	bool parser_skip;
-	bool parser_no_check_key:1;
-	bool writer_skip:1;
-	bool has_writer_full:1;
-	bool has_parser_full:1;
-
-	/* usually, we skip to write values that have their
-	 * default value. By setting this flag to TRUE, also
-	 * default values are written. */
-	bool writer_persist_default:1;
+    const char *property_name;
+    union {
+        void (*parser)(KeyfileReaderInfo *info, NMSetting *setting, const char *key);
+        void (*parser_full)(KeyfileReaderInfo *       info,
+                            const NMMetaSettingInfo * setting_info,
+                            const NMSettInfoProperty *property_info,
+                            const ParseInfoProperty * pip,
+                            NMSetting *               setting);
+    };
+    union {
+        void (*writer)(KeyfileWriterInfo *info,
+                       NMSetting *        setting,
+                       const char *       key,
+                       const GValue *     value);
+        void (*writer_full)(KeyfileWriterInfo *       info,
+                            const NMMetaSettingInfo * setting_info,
+                            const NMSettInfoProperty *property_info,
+                            const ParseInfoProperty * pip,
+                            NMSetting *               setting);
+    };
+    bool parser_skip;
+    bool parser_no_check_key : 1;
+    bool writer_skip : 1;
+    bool has_writer_full : 1;
+    bool has_parser_full : 1;
+
+    /* usually, we skip to write values that have their
+     * default value. By setting this flag to TRUE, also
+     * default values are written. */
+    bool writer_persist_default : 1;
 };
 
 #define PARSE_INFO_PROPERTY(_property_name, ...) \
-	(&((const ParseInfoProperty) { \
-		.property_name = _property_name, \
-		__VA_ARGS__ \
-	}))
+    (&((const ParseInfoProperty){.property_name = _property_name, __VA_ARGS__}))
 
-#define PARSE_INFO_PROPERTIES(...) \
-	.properties = ((const ParseInfoProperty*const[]) { \
-		__VA_ARGS__ \
-		NULL, \
-	})
+#define PARSE_INFO_PROPERTIES(...)                     \
+    .properties = ((const ParseInfoProperty *const[]){ \
+        __VA_ARGS__ NULL,                              \
+    })
 
 typedef struct {
-	const ParseInfoProperty*const*properties;
+    const ParseInfoProperty *const *properties;
 } ParseInfoSetting;
 
 #define PARSE_INFO_SETTING(setting_type, ...) \
-	[setting_type] = (&((const ParseInfoSetting) { \
-		__VA_ARGS__ \
-	}))
+    [setting_type] = (&((const ParseInfoSetting){__VA_ARGS__}))
 
 static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRELESS,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_BSSID,
-				.parser        = mac_address_parser_ETHER,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER_cloned,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRELESS_SSID,
-				.parser        = ssid_parser,
-				.writer        = ssid_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_802_1X,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_CA_CERT,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_CLIENT_CERT,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_PASSWORD_RAW,
-				.parser        = password_raw_parser,
-				.writer        = password_raw_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_PHASE2_CA_CERT,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_802_1X_PRIVATE_KEY,
-				.parser        = cert_parser,
-				.writer        = cert_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIRED,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER_cloned,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRED_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_WIRED_S390_OPTIONS,
-				.parser_no_check_key = TRUE,
-				.parser_full   = wired_s390_options_parser_full,
-				.writer_full   = wired_s390_options_writer_full,
-				.has_parser_full = TRUE,
-				.has_writer_full = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BLUETOOTH,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_BLUETOOTH_BDADDR,
-				.parser        = mac_address_parser_ETHER,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BOND,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_BOND_OPTIONS,
-				.parser_no_check_key = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BRIDGE,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_BRIDGE_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_BRIDGE_VLANS,
-				.parser_no_check_key = TRUE,
-				.parser        = bridge_vlan_parser,
-				.writer        = bridge_vlan_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_BRIDGE_PORT,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_BRIDGE_PORT_VLANS,
-				.parser_no_check_key = TRUE,
-				.parser        = bridge_vlan_parser,
-				.writer        = bridge_vlan_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_CONNECTION,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_CONNECTION_READ_ONLY,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_CONNECTION_TYPE,
-				.parser        = setting_alias_parser,
-				.writer        = setting_alias_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_INFINIBAND,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_INFINIBAND_MAC_ADDRESS,
-				.parser        = mac_address_parser_INFINIBAND,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP4_CONFIG,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ADDRESSES,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_address_or_route_parser,
-				.writer        = addr_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_DNS,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_dns_parser,
-				.writer        = dns_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_GATEWAY,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTES,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_address_or_route_parser,
-				.writer        = route_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTING_RULES,
-				.parser_no_check_key = TRUE,
-				.parser_full   = ip_routing_rule_parser_full,
-				.writer_full   = ip_routing_rule_writer_full,
-				.has_parser_full = TRUE,
-				.has_writer_full = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP6_CONFIG,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
-				.parser_no_check_key = TRUE,
-				.parser        = ip6_addr_gen_mode_parser,
-				.writer        = ip6_addr_gen_mode_writer,
-				.writer_persist_default = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ADDRESSES,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_address_or_route_parser,
-				.writer        = addr_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_DNS,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_dns_parser,
-				.writer        = dns_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_GATEWAY,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTES,
-				.parser_no_check_key = TRUE,
-				.parser        = ip_address_or_route_parser,
-				.writer        = route_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTING_RULES,
-				.parser_no_check_key = TRUE,
-				.parser_full   = ip_routing_rule_parser_full,
-				.writer_full   = ip_routing_rule_writer_full,
-				.has_parser_full = TRUE,
-				.has_writer_full = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SERIAL,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_SERIAL_PARITY,
-				.parser        = parity_parser,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SRIOV,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_SRIOV_VFS,
-				.parser_no_check_key = TRUE,
-				.parser        = sriov_vfs_parser,
-				.writer        = sriov_vfs_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TC_CONFIG,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_TC_CONFIG_QDISCS,
-				.parser_no_check_key = TRUE,
-				.parser        = qdisc_parser,
-				.writer        = qdisc_writer,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TC_CONFIG_TFILTERS,
-				.parser_no_check_key = TRUE,
-				.parser        = tfilter_parser,
-				.writer        = tfilter_writer,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG,
-				.parser        = team_config_parser,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_LINK_WATCHERS,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_MCAST_REJOIN_COUNT,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_ACTIVE,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_FAST_RATE,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_MIN_PORTS,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_SYS_PRIO,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_TX_BALANCER,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_RUNNER_TX_HASH,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_TEAM_PORT,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_CONFIG,
-				.parser        = team_config_parser,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_LACP_KEY,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_LACP_PRIO,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_LINK_WATCHERS,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_PRIO,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_QUEUE_ID,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_TEAM_PORT_STICKY,
-				.parser_skip   = TRUE,
-				.writer_skip   = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_USER,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_USER_DATA,
-				.parser_no_check_key = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VLAN,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_VLAN_FLAGS,
-				.writer_persist_default = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_VPN,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_DATA,
-				.parser_no_check_key = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_PERSISTENT,
-				.parser_no_check_key = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_SECRETS,
-				.parser_no_check_key = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_SERVICE_TYPE,
-				.parser_no_check_key = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_TIMEOUT,
-				.parser_no_check_key = TRUE,
-			),
-			PARSE_INFO_PROPERTY (NM_SETTING_VPN_USER_NAME,
-				.parser_no_check_key = TRUE,
-			),
-		),
-	),
-	PARSE_INFO_SETTING (NM_META_SETTING_TYPE_WIMAX,
-		PARSE_INFO_PROPERTIES (
-			PARSE_INFO_PROPERTY (NM_SETTING_WIMAX_MAC_ADDRESS,
-				.parser        = mac_address_parser_ETHER,
-			),
-		),
-	),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_WIRELESS,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_BSSID, .parser = mac_address_parser_ETHER, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
+                                .parser = mac_address_parser_ETHER_cloned, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_MAC_ADDRESS,
+                                .parser = mac_address_parser_ETHER, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRELESS_SSID,
+                                .parser = ssid_parser,
+                                .writer = ssid_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_802_1X,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_802_1X_CA_CERT,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_CLIENT_CERT,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PASSWORD_RAW,
+                                                  .parser = password_raw_parser,
+                                                  .writer = password_raw_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_CA_CERT,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_802_1X_PRIVATE_KEY,
+                                                  .parser = cert_parser,
+                                                  .writer = cert_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_WIRED,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
+                                .parser = mac_address_parser_ETHER_cloned, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRED_MAC_ADDRESS, .parser = mac_address_parser_ETHER, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_WIRED_S390_OPTIONS,
+                                .parser_no_check_key = TRUE,
+                                .parser_full         = wired_s390_options_parser_full,
+                                .writer_full         = wired_s390_options_writer_full,
+                                .has_parser_full     = TRUE,
+                                .has_writer_full     = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_BLUETOOTH,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BLUETOOTH_BDADDR,
+                                                  .parser = mac_address_parser_ETHER, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_BOND,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_BOND_OPTIONS, .parser_no_check_key = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_BRIDGE,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_MAC_ADDRESS,
+                                                  .parser = mac_address_parser_ETHER, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_VLANS,
+                                                  .parser_no_check_key = TRUE,
+                                                  .parser              = bridge_vlan_parser,
+                                                  .writer = bridge_vlan_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_BRIDGE_PORT,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_PORT_VLANS,
+                                                  .parser_no_check_key = TRUE,
+                                                  .parser              = bridge_vlan_parser,
+                                                  .writer = bridge_vlan_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_CONNECTION,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_CONNECTION_READ_ONLY,
+                                                  .parser_skip = TRUE,
+                                                  .writer_skip = TRUE, ),
+                              PARSE_INFO_PROPERTY(NM_SETTING_CONNECTION_TYPE,
+                                                  .parser = setting_alias_parser,
+                                                  .writer = setting_alias_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_INFINIBAND,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_INFINIBAND_MAC_ADDRESS,
+                                                  .parser = mac_address_parser_INFINIBAND, ), ), ),
+    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP4_CONFIG,
+                       PARSE_INFO_PROPERTIES(
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_address_or_route_parser,
+                                               .writer              = addr_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_dns_parser,
+                                               .writer              = dns_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_address_or_route_parser,
+                                               .writer              = route_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser_full         = ip_routing_rule_parser_full,
+                                               .writer_full         = ip_routing_rule_writer_full,
+                                               .has_parser_full     = TRUE,
+                                               .has_writer_full     = TRUE, ), ), ),
+    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP6_CONFIG,
+                       PARSE_INFO_PROPERTIES(
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
+                                               .parser_no_check_key    = TRUE,
+                                               .parser                 = ip6_addr_gen_mode_parser,
+                                               .writer                 = ip6_addr_gen_mode_writer,
+                                               .writer_persist_default = TRUE, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_address_or_route_parser,
+                                               .writer              = addr_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_dns_parser,
+                                               .writer              = dns_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser              = ip_address_or_route_parser,
+                                               .writer              = route_writer, ),
+                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
+                                               .parser_no_check_key = TRUE,
+                                               .parser_full         = ip_routing_rule_parser_full,
+                                               .writer_full         = ip_routing_rule_writer_full,
+                                               .has_parser_full     = TRUE,
+                                               .has_writer_full     = TRUE, ), ), ),
+    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_SERIAL,
+                       PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_SERIAL_PARITY,
+                                                                 .parser = parity_parser, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_SRIOV,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_SRIOV_VFS,
+                                                  .parser_no_check_key = TRUE,
+                                                  .parser              = sriov_vfs_parser,
+                                                  .writer              = sriov_vfs_writer, ), ), ),
+    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_TC_CONFIG,
+                       PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_TC_CONFIG_QDISCS,
+                                                                 .parser_no_check_key = TRUE,
+                                                                 .parser = qdisc_parser,
+                                                                 .writer = qdisc_writer, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TC_CONFIG_TFILTERS,
+                                                                 .parser_no_check_key = TRUE,
+                                                                 .parser = tfilter_parser,
+                                                                 .writer = tfilter_writer, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_TEAM,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_CONFIG, .parser = team_config_parser, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_LINK_WATCHERS,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_MCAST_REJOIN_COUNT,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER, .parser_skip = TRUE, .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_ACTIVE,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_FAST_RATE,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_MIN_PORTS,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_SYS_PRIO,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_BALANCER,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_TEAM_RUNNER_TX_HASH,
+                                .parser_skip = TRUE,
+                                .writer_skip = TRUE, ), ), ),
+    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_TEAM_PORT,
+                       PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_TEAM_CONFIG,
+                                                                 .parser = team_config_parser, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LACP_KEY,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LACP_PRIO,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_PRIO,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_QUEUE_ID,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ),
+                                             PARSE_INFO_PROPERTY(NM_SETTING_TEAM_PORT_STICKY,
+                                                                 .parser_skip = TRUE,
+                                                                 .writer_skip = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_USER,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_USER_DATA, .parser_no_check_key = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_VLAN,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_VLAN_FLAGS, .writer_persist_default = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_VPN,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_DATA, .parser_no_check_key = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_PERSISTENT, .parser_no_check_key = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_SECRETS, .parser_no_check_key = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_SERVICE_TYPE, .parser_no_check_key = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_TIMEOUT, .parser_no_check_key = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_VPN_USER_NAME, .parser_no_check_key = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_WIMAX,
+        PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_WIMAX_MAC_ADDRESS,
+                                                  .parser = mac_address_parser_ETHER, ), ), ),
 };
 
 static void
-_parse_info_find (NMSetting *setting,
-                  const char *property_name,
-                  const NMMetaSettingInfo **out_setting_info,
-                  const ParseInfoSetting **out_parse_info_setting,
-                  const ParseInfoProperty **out_parse_info_property)
+_parse_info_find(NMSetting *               setting,
+                 const char *              property_name,
+                 const NMMetaSettingInfo **out_setting_info,
+                 const ParseInfoSetting ** out_parse_info_setting,
+                 const ParseInfoProperty **out_parse_info_property)
 {
-	const NMMetaSettingInfo *setting_info;
-	const ParseInfoSetting *pis;
-	const ParseInfoProperty *pip;
+    const NMMetaSettingInfo *setting_info;
+    const ParseInfoSetting * pis;
+    const ParseInfoProperty *pip;
 
 #if NM_MORE_ASSERTS > 10
-	{
-		guint i, j;
-		static int asserted = FALSE;
-
-		if (!asserted) {
-			for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) {
-				pis = parse_infos[i];
-
-				if (!pis)
-					continue;
-				if (!pis->properties)
-					continue;
-
-				g_assert (pis->properties[0]);
-				for (j = 0; pis->properties[j]; j++) {
-					const ParseInfoProperty *pip0;
-					const ParseInfoProperty *pipj = pis->properties[j];
-
-					g_assert (pipj->property_name);
-					if (   j > 0
-					    && (pip0 = pis->properties[j - 1])
-					    && strcmp (pip0->property_name, pipj->property_name) >= 0) {
-						g_error ("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"",
-						         i, j - 1,
-						         nm_meta_setting_infos[i].setting_name, pip0->property_name,
-						         nm_meta_setting_infos[i].setting_name, pipj->property_name);
-					}
-				}
-			}
-			asserted = TRUE;
-		}
-	}
+    {
+        guint      i, j;
+        static int asserted = FALSE;
+
+        if (!asserted) {
+            for (i = 0; i < G_N_ELEMENTS(parse_infos); i++) {
+                pis = parse_infos[i];
+
+                if (!pis)
+                    continue;
+                if (!pis->properties)
+                    continue;
+
+                g_assert(pis->properties[0]);
+                for (j = 0; pis->properties[j]; j++) {
+                    const ParseInfoProperty *pip0;
+                    const ParseInfoProperty *pipj = pis->properties[j];
+
+                    g_assert(pipj->property_name);
+                    if (j > 0 && (pip0 = pis->properties[j - 1])
+                        && strcmp(pip0->property_name, pipj->property_name) >= 0) {
+                        g_error("Wrong order at index #%d.%d: \"%s.%s\" before \"%s.%s\"",
+                                i,
+                                j - 1,
+                                nm_meta_setting_infos[i].setting_name,
+                                pip0->property_name,
+                                nm_meta_setting_infos[i].setting_name,
+                                pipj->property_name);
+                    }
+                }
+            }
+            asserted = TRUE;
+        }
+    }
 #endif
 
-	if (   !NM_IS_SETTING (setting)
-	    || !(setting_info = NM_SETTING_GET_CLASS (setting)->setting_info)) {
-		/* handle invalid setting objects gracefully. */
-		NM_SET_OUT (out_setting_info, NULL);
-		NM_SET_OUT (out_parse_info_setting, NULL);
-		NM_SET_OUT (out_parse_info_property, NULL);
-		return;
-	}
-
-	nm_assert (setting_info->setting_name);
-	nm_assert (_NM_INT_NOT_NEGATIVE (setting_info->meta_type));
-	nm_assert (setting_info->meta_type < G_N_ELEMENTS (parse_infos));
-
-	pis = parse_infos[setting_info->meta_type];
-
-	pip = NULL;
-	if (   pis
-	    && property_name) {
-		gssize idx;
-
-		G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (ParseInfoProperty, property_name) == 0);
-
-		idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) pis->properties,
-		                                            NM_PTRARRAY_LEN (pis->properties),
-		                                            &property_name,
-		                                            nm_strcmp_p_with_data,
-		                                            NULL,
-		                                            NULL,
-		                                            NULL);
-		if (idx >= 0)
-			pip = pis->properties[idx];
-	}
-
-	NM_SET_OUT (out_setting_info, setting_info);
-	NM_SET_OUT (out_parse_info_setting, pis);
-	NM_SET_OUT (out_parse_info_property, pip);
+    if (!NM_IS_SETTING(setting) || !(setting_info = NM_SETTING_GET_CLASS(setting)->setting_info)) {
+        /* handle invalid setting objects gracefully. */
+        NM_SET_OUT(out_setting_info, NULL);
+        NM_SET_OUT(out_parse_info_setting, NULL);
+        NM_SET_OUT(out_parse_info_property, NULL);
+        return;
+    }
+
+    nm_assert(setting_info->setting_name);
+    nm_assert(_NM_INT_NOT_NEGATIVE(setting_info->meta_type));
+    nm_assert(setting_info->meta_type < G_N_ELEMENTS(parse_infos));
+
+    pis = parse_infos[setting_info->meta_type];
+
+    pip = NULL;
+    if (pis && property_name) {
+        gssize idx;
+
+        G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(ParseInfoProperty, property_name) == 0);
+
+        idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) pis->properties,
+                                                   NM_PTRARRAY_LEN(pis->properties),
+                                                   &property_name,
+                                                   nm_strcmp_p_with_data,
+                                                   NULL,
+                                                   NULL,
+                                                   NULL);
+        if (idx >= 0)
+            pip = pis->properties[idx];
+    }
+
+    NM_SET_OUT(out_setting_info, setting_info);
+    NM_SET_OUT(out_parse_info_setting, pis);
+    NM_SET_OUT(out_parse_info_property, pip);
 }
 
 /*****************************************************************************/
 
 static void
-read_one_setting_value (KeyfileReaderInfo *info,
-                        NMSetting *setting,
-                        const NMSettInfoProperty *property_info)
+read_one_setting_value(KeyfileReaderInfo *       info,
+                       NMSetting *               setting,
+                       const NMSettInfoProperty *property_info)
 {
-	GKeyFile *keyfile = info->keyfile;
-	gs_free_error GError *err = NULL;
-	const NMMetaSettingInfo *setting_info;
-	const ParseInfoProperty *pip;
-	gs_free char *tmp_str = NULL;
-	const char *key;
-	GType type;
-	guint64 u64;
-	gint64 i64;
-
-	nm_assert (!info->error);
-	nm_assert (   !property_info->param_spec
-	           || nm_streq (property_info->param_spec->name, property_info->name));
-
-	key = property_info->name;
-
-	_parse_info_find (setting, key, &setting_info, NULL, &pip);
-
-	nm_assert (setting_info);
-
-	if (!pip) {
-		if (nm_streq (key, NM_SETTING_NAME))
-			return;
-		if (!property_info->param_spec)
-			return;
-		if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) != G_PARAM_WRITABLE)
-			return;
-	} else {
-		if (pip->parser_skip)
-			return;
-		if (pip->has_parser_full) {
-			pip->parser_full (info, setting_info, property_info, pip, setting);
-			return;
-		}
-	}
-
-	nm_assert (property_info->param_spec);
-	nm_assert ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) == G_PARAM_WRITABLE);
-
-	/* Check for the exact key in the GKeyFile if required.  Most setting
-	 * properties map 1:1 to a key in the GKeyFile, but for those properties
-	 * like IP addresses and routes where more than one value is actually
-	 * encoded by the setting property, this won't be true.
-	 */
-	if (   (!pip || !pip->parser_no_check_key)
-	    && !nm_keyfile_plugin_kf_has_key (keyfile, setting_info->setting_name, key, &err)) {
-		/* Key doesn't exist or an error occurred, thus nothing to do. */
-		if (err) {
-			if (!handle_warn (info,
-			                  key,
-			                  key,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("error loading setting value: %s"),
-			                  err->message))
-				return;
-		}
-		return;
-	}
-
-	if (   pip
-	    && pip->parser) {
-		pip->parser (info, setting, key);
-		return;
-	}
-
-	type = G_PARAM_SPEC_VALUE_TYPE (property_info->param_spec);
-
-	if (type == G_TYPE_STRING) {
-		gs_free char *str_val = NULL;
-
-		str_val = nm_keyfile_plugin_kf_get_string (keyfile, setting_info->setting_name, key, &err);
-		if (!err)
-			nm_g_object_set_property_string_take (G_OBJECT (setting), key, g_steal_pointer (&str_val), &err);
-	} else if (type == G_TYPE_UINT) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			u64 = _nm_utils_ascii_str_to_uint64 (tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64);
-			if (   u64 == G_MAXUINT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_uint (G_OBJECT (setting), key, u64, &err);
-		}
-	} else if (type == G_TYPE_INT) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			i64 = _nm_utils_ascii_str_to_int64 (tmp_str, 0, G_MININT, G_MAXINT, G_MININT64);
-			if (   i64 == G_MININT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_int (G_OBJECT (setting), key, i64, &err);
-		}
-	} else if (type == G_TYPE_BOOLEAN) {
-		gboolean bool_val;
-
-		bool_val = nm_keyfile_plugin_kf_get_boolean (keyfile, setting_info->setting_name, key, &err);
-		if (!err)
-			nm_g_object_set_property_boolean (G_OBJECT (setting), key, bool_val, &err);
-	} else if (type == G_TYPE_CHAR) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			/* As documented by glib, G_TYPE_CHAR is really a (signed!) gint8. */
-			i64 = _nm_utils_ascii_str_to_int64 (tmp_str, 0, G_MININT8, G_MAXINT8, G_MININT64);
-			if (   i64 == G_MININT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_char (G_OBJECT (setting), key, i64, &err);
-		}
-	} else if (type == G_TYPE_UINT64) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			u64 = _nm_utils_ascii_str_to_uint64 (tmp_str, 0, 0, G_MAXUINT64, G_MAXUINT64);
-			if (   u64 == G_MAXUINT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_uint64 (G_OBJECT (setting), key, u64, &err);
-		}
-	} else if (type == G_TYPE_INT64) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			i64 = _nm_utils_ascii_str_to_int64 (tmp_str, 0, G_MININT64, G_MAXINT64, G_MAXINT64);
-			if (   i64 == G_MAXINT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_int64 (G_OBJECT (setting), key, i64, &err);
-		}
-	} else if (type == G_TYPE_BYTES) {
-		nm_auto_unref_bytearray GByteArray *array = NULL;
-		gs_unref_bytes GBytes *bytes= NULL;
-		gs_free guint *tmp = NULL;
-		gsize length;
-		int i;
-		gboolean already_warned = FALSE;
-
-		tmp = nm_keyfile_plugin_kf_get_integer_list_uint (keyfile, setting_info->setting_name, key, &length, NULL);
-
-		array = g_byte_array_sized_new (length);
-		for (i = 0; i < length; i++) {
-			const guint val = tmp[i];
-			unsigned char v = (unsigned char) (val & 0xFF);
-
-			if (val > 255u) {
-				if (   !already_warned
-				    && !handle_warn (info,
-				                     key,
-				                     key,
-				                     NM_KEYFILE_WARN_SEVERITY_WARN,
-				                     _("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"),
-				                     val))
-					return;
-				already_warned = TRUE;
-			} else
-				g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
-		}
-
-		bytes = g_byte_array_free_to_bytes (g_steal_pointer (&array));
-		g_object_set (setting, key, bytes, NULL);
-	} else if (type == G_TYPE_STRV) {
-		gs_strfreev char **sa = NULL;
-		gsize length;
-
-		sa = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_info->setting_name, key, &length, NULL);
-		g_object_set (setting, key, sa, NULL);
-	} else if (type == G_TYPE_HASH_TABLE) {
-		read_hash_of_string (keyfile, setting, key);
-	} else if (type == G_TYPE_ARRAY) {
-		read_array_of_uint (keyfile, setting, key);
-	} else if (G_TYPE_IS_FLAGS (type)) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			u64 = _nm_utils_ascii_str_to_uint64 (tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64);
-			if (   u64 == G_MAXUINT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_flags (G_OBJECT (setting), key, type, u64, &err);
-		}
-	} else if (G_TYPE_IS_ENUM (type)) {
-		tmp_str = nm_keyfile_plugin_kf_get_value (keyfile, setting_info->setting_name, key, &err);
-		if (!err) {
-			i64 = _nm_utils_ascii_str_to_int64 (tmp_str, 0, G_MININT, G_MAXINT, G_MAXINT64);
-			if (   i64 == G_MAXINT64
-			    && errno != 0) {
-				g_set_error_literal (&err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
-				                     _("value cannot be interpreted as integer"));
-			} else
-				nm_g_object_set_property_enum (G_OBJECT (setting), key, type, i64, &err);
-		}
-	} else
-		g_return_if_reached ();
-
-	if (err) {
-		if (nm_keyfile_error_is_not_found (err)) {
-			/* ignore such errors. The key is not present. */
-		} else {
-			handle_warn (info,
-			             key,
-			             key,
-			             NM_KEYFILE_WARN_SEVERITY_WARN,
-			             _("invalid setting: %s"),
-			             err->message);
-		}
-	}
+    GKeyFile *    keyfile        = info->keyfile;
+    gs_free_error GError *   err = NULL;
+    const NMMetaSettingInfo *setting_info;
+    const ParseInfoProperty *pip;
+    gs_free char *           tmp_str = NULL;
+    const char *             key;
+    GType                    type;
+    guint64                  u64;
+    gint64                   i64;
+
+    nm_assert(!info->error);
+    nm_assert(!property_info->param_spec
+              || nm_streq(property_info->param_spec->name, property_info->name));
+
+    key = property_info->name;
+
+    _parse_info_find(setting, key, &setting_info, NULL, &pip);
+
+    nm_assert(setting_info);
+
+    if (!pip) {
+        if (nm_streq(key, NM_SETTING_NAME))
+            return;
+        if (!property_info->param_spec)
+            return;
+        if ((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))
+            != G_PARAM_WRITABLE)
+            return;
+    } else {
+        if (pip->parser_skip)
+            return;
+        if (pip->has_parser_full) {
+            pip->parser_full(info, setting_info, property_info, pip, setting);
+            return;
+        }
+    }
+
+    nm_assert(property_info->param_spec);
+    nm_assert((property_info->param_spec->flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))
+              == G_PARAM_WRITABLE);
+
+    /* Check for the exact key in the GKeyFile if required.  Most setting
+     * properties map 1:1 to a key in the GKeyFile, but for those properties
+     * like IP addresses and routes where more than one value is actually
+     * encoded by the setting property, this won't be true.
+     */
+    if ((!pip || !pip->parser_no_check_key)
+        && !nm_keyfile_plugin_kf_has_key(keyfile, setting_info->setting_name, key, &err)) {
+        /* Key doesn't exist or an error occurred, thus nothing to do. */
+        if (err) {
+            if (!handle_warn(info,
+                             key,
+                             key,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("error loading setting value: %s"),
+                             err->message))
+                return;
+        }
+        return;
+    }
+
+    if (pip && pip->parser) {
+        pip->parser(info, setting, key);
+        return;
+    }
+
+    type = G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec);
+
+    if (type == G_TYPE_STRING) {
+        gs_free char *str_val = NULL;
+
+        str_val = nm_keyfile_plugin_kf_get_string(keyfile, setting_info->setting_name, key, &err);
+        if (!err)
+            nm_g_object_set_property_string_take(G_OBJECT(setting),
+                                                 key,
+                                                 g_steal_pointer(&str_val),
+                                                 &err);
+    } else if (type == G_TYPE_UINT) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64);
+            if (u64 == G_MAXUINT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_uint(G_OBJECT(setting), key, u64, &err);
+        }
+    } else if (type == G_TYPE_INT) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MININT64);
+            if (i64 == G_MININT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_int(G_OBJECT(setting), key, i64, &err);
+        }
+    } else if (type == G_TYPE_BOOLEAN) {
+        gboolean bool_val;
+
+        bool_val = nm_keyfile_plugin_kf_get_boolean(keyfile, setting_info->setting_name, key, &err);
+        if (!err)
+            nm_g_object_set_property_boolean(G_OBJECT(setting), key, bool_val, &err);
+    } else if (type == G_TYPE_CHAR) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            /* As documented by glib, G_TYPE_CHAR is really a (signed!) gint8. */
+            i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT8, G_MAXINT8, G_MININT64);
+            if (i64 == G_MININT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_char(G_OBJECT(setting), key, i64, &err);
+        }
+    } else if (type == G_TYPE_UINT64) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT64, G_MAXUINT64);
+            if (u64 == G_MAXUINT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_uint64(G_OBJECT(setting), key, u64, &err);
+        }
+    } else if (type == G_TYPE_INT64) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT64, G_MAXINT64, G_MAXINT64);
+            if (i64 == G_MAXINT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_int64(G_OBJECT(setting), key, i64, &err);
+        }
+    } else if (type == G_TYPE_BYTES) {
+        nm_auto_unref_bytearray GByteArray *array = NULL;
+        gs_unref_bytes GBytes *bytes              = NULL;
+        gs_free guint *tmp                        = NULL;
+        gsize          length;
+        int            i;
+        gboolean       already_warned = FALSE;
+
+        tmp = nm_keyfile_plugin_kf_get_integer_list_uint(keyfile,
+                                                         setting_info->setting_name,
+                                                         key,
+                                                         &length,
+                                                         NULL);
+
+        array = g_byte_array_sized_new(length);
+        for (i = 0; i < length; i++) {
+            const guint   val = tmp[i];
+            unsigned char v   = (unsigned char) (val & 0xFF);
+
+            if (val > 255u) {
+                if (!already_warned
+                    && !handle_warn(
+                        info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("ignoring invalid byte element '%u' (not between 0 and 255 inclusive)"),
+                        val))
+                    return;
+                already_warned = TRUE;
+            } else
+                g_byte_array_append(array, (const unsigned char *) &v, sizeof(v));
+        }
+
+        bytes = g_byte_array_free_to_bytes(g_steal_pointer(&array));
+        g_object_set(setting, key, bytes, NULL);
+    } else if (type == G_TYPE_STRV) {
+        gs_strfreev char **sa = NULL;
+        gsize              length;
+
+        sa = nm_keyfile_plugin_kf_get_string_list(keyfile,
+                                                  setting_info->setting_name,
+                                                  key,
+                                                  &length,
+                                                  NULL);
+        g_object_set(setting, key, sa, NULL);
+    } else if (type == G_TYPE_HASH_TABLE) {
+        read_hash_of_string(keyfile, setting, key);
+    } else if (type == G_TYPE_ARRAY) {
+        read_array_of_uint(keyfile, setting, key);
+    } else if (G_TYPE_IS_FLAGS(type)) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            u64 = _nm_utils_ascii_str_to_uint64(tmp_str, 0, 0, G_MAXUINT, G_MAXUINT64);
+            if (u64 == G_MAXUINT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_flags(G_OBJECT(setting), key, type, u64, &err);
+        }
+    } else if (G_TYPE_IS_ENUM(type)) {
+        tmp_str = nm_keyfile_plugin_kf_get_value(keyfile, setting_info->setting_name, key, &err);
+        if (!err) {
+            i64 = _nm_utils_ascii_str_to_int64(tmp_str, 0, G_MININT, G_MAXINT, G_MAXINT64);
+            if (i64 == G_MAXINT64 && errno != 0) {
+                g_set_error_literal(&err,
+                                    G_KEY_FILE_ERROR,
+                                    G_KEY_FILE_ERROR_INVALID_VALUE,
+                                    _("value cannot be interpreted as integer"));
+            } else
+                nm_g_object_set_property_enum(G_OBJECT(setting), key, type, i64, &err);
+        }
+    } else
+        g_return_if_reached();
+
+    if (err) {
+        if (nm_keyfile_error_is_not_found(err)) {
+            /* ignore such errors. The key is not present. */
+        } else {
+            handle_warn(info,
+                        key,
+                        key,
+                        NM_KEYFILE_WARN_SEVERITY_WARN,
+                        _("invalid setting: %s"),
+                        err->message);
+        }
+    }
 }
 
 static void
-_read_setting (KeyfileReaderInfo *info)
+_read_setting(KeyfileReaderInfo *info)
 {
-	const NMSettInfoSetting *sett_info;
-	gs_unref_object NMSetting *setting = NULL;
-	const char *alias;
-	GType type;
-	guint i;
-
-	alias = nm_keyfile_plugin_get_setting_name_for_alias (info->group);
-	if (!alias)
-		alias = info->group;
-
-	type = nm_setting_lookup_type (alias);
-	if (!type) {
-		handle_warn (info,
-		             NULL,
-		             NULL,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("invalid setting name '%s'"),
-		             info->group);
-		return;
-	}
-
-	setting = g_object_new (type, NULL);
-
-	info->setting = setting;
-
-	sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
-
-	if (sett_info->detail.gendata_info) {
-		gs_free char **keys = NULL;
-		gsize k, n_keys;
-
-		keys = g_key_file_get_keys (info->keyfile, info->group, &n_keys, NULL);
-		if (!keys)
-			n_keys = 0;
-		if (n_keys > 0) {
-			GHashTable *h = _nm_setting_option_hash (setting, TRUE);
-
-			nm_utils_strv_sort (keys, n_keys);
-			for (k = 0; k < n_keys; k++) {
-				gs_free char *key = keys[k];
-				gs_free_error GError *local = NULL;
-				const GVariantType *variant_type;
-				GVariant *variant;
-
-				/* a GKeyFile can return duplicate keys, there is just no API to make sense
-				 * of them. Skip them. */
-				if (   k + 1 < n_keys
-				    && nm_streq (key, keys[k + 1]))
-					continue;
-
-				/* currently, the API is very simple. The setting class just returns
-				 * the desired variant type, and keyfile reader will try to parse
-				 * it accordingly. Note, that this does currently not allow, that
-				 * a particular key can contain different variant types, nor is it
-				 * very flexible in general.
-				 *
-				 * We add flexibility when we need it. Keep it simple for now. */
-				variant_type = sett_info->detail.gendata_info->get_variant_type (sett_info,
-				                                                                 key,
-				                                                                 &local);
-				if (!variant_type) {
-					if (!handle_warn (info,
-					                  key,
-					                  NULL,
-					                  NM_KEYFILE_WARN_SEVERITY_WARN,
-					                  _("invalid key '%s.%s'"),
-					                  info->group,
-					                  key))
-						break;
-					continue;
-				}
-
-				if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN)) {
-					gboolean v;
-
-					v = g_key_file_get_boolean (info->keyfile,
-					                            info->group,
-					                            key,
-					                            &local);
-					if (local) {
-						if (!handle_warn (info,
-						                  key,
-						                  key,
-						                  NM_KEYFILE_WARN_SEVERITY_WARN,
-						                  _("key '%s.%s' is not boolean"),
-						                  info->group,
-						                  key))
-							break;
-						continue;
-					}
-					variant = g_variant_new_boolean (v);
-				} else if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32)) {
-					guint64 v;
-
-					v = g_key_file_get_uint64 (info->keyfile,
-					                           info->group,
-					                           key,
-					                           &local);
-
-					if (local) {
-						if (!handle_warn (info,
-						                  key,
-						                  key,
-						                  NM_KEYFILE_WARN_SEVERITY_WARN,
-						                  _("key '%s.%s' is not a uint32"),
-						                  info->group,
-						                  key))
-							break;
-						continue;
-					}
-					variant = g_variant_new_uint32 ((guint32) v);
-				} else {
-					nm_assert_not_reached ();
-					continue;
-				}
-
-				g_hash_table_insert (h,
-				                     g_steal_pointer (&key),
-				                     g_variant_take_ref (variant));
-			}
-			for (; k < n_keys; k++)
-				g_free (keys[k]);
-		}
-	}
-
-	for (i = 0; i < sett_info->property_infos_len; i++) {
-		read_one_setting_value (info,
-		                        setting,
-		                        &sett_info->property_infos[i]);
-		if (info->error)
-			goto out;
-	}
+    const NMSettInfoSetting *sett_info;
+    gs_unref_object NMSetting *setting = NULL;
+    const char *               alias;
+    GType                      type;
+    guint                      i;
+
+    alias = nm_keyfile_plugin_get_setting_name_for_alias(info->group);
+    if (!alias)
+        alias = info->group;
+
+    type = nm_setting_lookup_type(alias);
+    if (!type) {
+        handle_warn(info,
+                    NULL,
+                    NULL,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("invalid setting name '%s'"),
+                    info->group);
+        return;
+    }
+
+    setting = g_object_new(type, NULL);
+
+    info->setting = setting;
+
+    sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting));
+
+    if (sett_info->detail.gendata_info) {
+        gs_free char **keys = NULL;
+        gsize          k, n_keys;
+
+        keys = g_key_file_get_keys(info->keyfile, info->group, &n_keys, NULL);
+        if (!keys)
+            n_keys = 0;
+        if (n_keys > 0) {
+            GHashTable *h = _nm_setting_option_hash(setting, TRUE);
+
+            nm_utils_strv_sort(keys, n_keys);
+            for (k = 0; k < n_keys; k++) {
+                gs_free char *key           = keys[k];
+                gs_free_error GError *local = NULL;
+                const GVariantType *  variant_type;
+                GVariant *            variant;
+
+                /* a GKeyFile can return duplicate keys, there is just no API to make sense
+                 * of them. Skip them. */
+                if (k + 1 < n_keys && nm_streq(key, keys[k + 1]))
+                    continue;
+
+                /* currently, the API is very simple. The setting class just returns
+                 * the desired variant type, and keyfile reader will try to parse
+                 * it accordingly. Note, that this does currently not allow, that
+                 * a particular key can contain different variant types, nor is it
+                 * very flexible in general.
+                 *
+                 * We add flexibility when we need it. Keep it simple for now. */
+                variant_type =
+                    sett_info->detail.gendata_info->get_variant_type(sett_info, key, &local);
+                if (!variant_type) {
+                    if (!handle_warn(info,
+                                     key,
+                                     NULL,
+                                     NM_KEYFILE_WARN_SEVERITY_WARN,
+                                     _("invalid key '%s.%s'"),
+                                     info->group,
+                                     key))
+                        break;
+                    continue;
+                }
+
+                if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BOOLEAN)) {
+                    gboolean v;
+
+                    v = g_key_file_get_boolean(info->keyfile, info->group, key, &local);
+                    if (local) {
+                        if (!handle_warn(info,
+                                         key,
+                                         key,
+                                         NM_KEYFILE_WARN_SEVERITY_WARN,
+                                         _("key '%s.%s' is not boolean"),
+                                         info->group,
+                                         key))
+                            break;
+                        continue;
+                    }
+                    variant = g_variant_new_boolean(v);
+                } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT32)) {
+                    guint64 v;
+
+                    v = g_key_file_get_uint64(info->keyfile, info->group, key, &local);
+
+                    if (local) {
+                        if (!handle_warn(info,
+                                         key,
+                                         key,
+                                         NM_KEYFILE_WARN_SEVERITY_WARN,
+                                         _("key '%s.%s' is not a uint32"),
+                                         info->group,
+                                         key))
+                            break;
+                        continue;
+                    }
+                    variant = g_variant_new_uint32((guint32) v);
+                } else {
+                    nm_assert_not_reached();
+                    continue;
+                }
+
+                g_hash_table_insert(h, g_steal_pointer(&key), g_variant_take_ref(variant));
+            }
+            for (; k < n_keys; k++)
+                g_free(keys[k]);
+        }
+    }
+
+    for (i = 0; i < sett_info->property_infos_len; i++) {
+        read_one_setting_value(info, setting, &sett_info->property_infos[i]);
+        if (info->error)
+            goto out;
+    }
 
 out:
-	info->setting = NULL;
-	if (!info->error)
-		nm_connection_add_setting (info->connection, g_steal_pointer (&setting));
+    info->setting = NULL;
+    if (!info->error)
+        nm_connection_add_setting(info->connection, g_steal_pointer(&setting));
 }
 
 static void
-_read_setting_wireguard_peer (KeyfileReaderInfo *info)
+_read_setting_wireguard_peer(KeyfileReaderInfo *info)
 {
-	gs_unref_object NMSettingWireGuard *s_wg_new = NULL;
-	nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL;
-	gs_free_error GError *error = NULL;
-	NMSettingWireGuard *s_wg;
-	gs_free char *str = NULL;
-	const char *cstr = NULL;
-	const char *key;
-	gint64 i64;
-	gs_strfreev char **sa = NULL;
-	gsize n_sa;
-
-	peer = nm_wireguard_peer_new ();
-
-	nm_assert (g_str_has_prefix (info->group, NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER));
-	cstr = &info->group[NM_STRLEN (NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)];
-	if (   !nm_utils_base64secret_normalize (cstr, NM_WIREGUARD_PUBLIC_KEY_LEN, &str)
-	    || !nm_streq0 (str, cstr)) {
-		/* the group name must be identical to the normalized(!) key, so that it
-		 * is uniquely identified. */
-		handle_warn (info,
-		             NULL,
-		             NM_SETTING_WIREGUARD_PEERS,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("invalid peer public key in section '%s'"),
-		             info->group);
-		return;
-	}
-	nm_wireguard_peer_set_public_key (peer, cstr, TRUE);
-	nm_clear_g_free (&str);
-
-	key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY;
-	str = nm_keyfile_plugin_kf_get_string (info->keyfile, info->group, key, NULL);
-	if (str) {
-		if (!nm_wireguard_peer_set_preshared_key (peer, str, FALSE)) {
-			if (!handle_warn (info,
-			                  key,
-			                  NM_SETTING_WIREGUARD_PEERS,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("key '%s.%s' is not a valid 256 bit key in base64 encoding"),
-			                  info->group,
-			                  key))
-				return;
-		}
-		nm_clear_g_free (&str);
-	}
-
-	key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS;
-	i64 = nm_keyfile_plugin_kf_get_int64 (info->keyfile, info->group, key, 0, 0, NM_SETTING_SECRET_FLAG_ALL, -1, NULL);
-	if (errno != ENODATA) {
-		if (   i64 == -1
-		    || !_nm_setting_secret_flags_valid (i64)) {
-			if (!handle_warn (info,
-			                  key,
-			                  NM_SETTING_WIREGUARD_PEERS,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("key '%s.%s' is not a valid secret flag"),
-			                  info->group,
-			                  key))
-				return;
-		} else
-			nm_wireguard_peer_set_preshared_key_flags (peer, i64);
-	}
-
-	key = NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE;
-	i64 = nm_keyfile_plugin_kf_get_int64 (info->keyfile, info->group, key, 0, 0, G_MAXUINT32, -1, NULL);
-	if (errno != ENODATA) {
-		if (i64 == -1) {
-			if (!handle_warn (info,
-			                  key,
-			                  NM_SETTING_WIREGUARD_PEERS,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("key '%s.%s' is not a integer in range 0 to 2^32"),
-			                  info->group,
-			                  key))
-				return;
-		} else
-			nm_wireguard_peer_set_persistent_keepalive (peer, i64);
-	}
-
-	key = NM_WIREGUARD_PEER_ATTR_ENDPOINT;
-	str = nm_keyfile_plugin_kf_get_string (info->keyfile, info->group, key, NULL);
-	if (str && str[0]) {
-		if (!nm_wireguard_peer_set_endpoint (peer, str, FALSE)) {
-			if (!handle_warn (info,
-			                  key,
-			                  NM_SETTING_WIREGUARD_PEERS,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("key '%s.%s' is not a valid endpoint"),
-			                  info->group,
-			                  key))
-				return;
-		}
-	}
-	nm_clear_g_free (&str);
-
-	key = NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS;
-	sa = nm_keyfile_plugin_kf_get_string_list (info->keyfile, info->group, key, &n_sa, NULL);
-	if (n_sa > 0) {
-		gboolean has_error = FALSE;
-		gsize i;
-
-		for (i = 0; i < n_sa; i++) {
-			if (!nm_utils_parse_inaddr_prefix_bin (AF_UNSPEC, sa[i], NULL, NULL, NULL)) {
-				has_error = TRUE;
-				continue;
-			}
-			nm_wireguard_peer_append_allowed_ip (peer, sa[i], TRUE);
-		}
-		if (has_error) {
-			if (!handle_warn (info,
-			                  key,
-			                  NM_SETTING_WIREGUARD_PEERS,
-			                  NM_KEYFILE_WARN_SEVERITY_WARN,
-			                  _("key '%s.%s' has invalid allowed-ips"),
-			                  info->group,
-			                  key))
-				return;
-		}
-	}
-
-	if (info->error)
-		return;
-
-	if (!nm_wireguard_peer_is_valid (peer, TRUE, TRUE, &error)) {
-		handle_warn (info,
-		             NULL,
-		             NM_SETTING_WIREGUARD_PEERS,
-		             NM_KEYFILE_WARN_SEVERITY_WARN,
-		             _("peer '%s' is invalid: %s"),
-		             info->group,
-		             error->message);
-		return;
-	}
-
-	s_wg = NM_SETTING_WIREGUARD (nm_connection_get_setting (info->connection, NM_TYPE_SETTING_WIREGUARD));
-	if (!s_wg) {
-		s_wg_new = NM_SETTING_WIREGUARD (nm_setting_wireguard_new ());
-		s_wg = s_wg_new;
-	}
-
-	nm_setting_wireguard_append_peer (s_wg, peer);
-
-	if (s_wg_new) {
-		nm_connection_add_setting (info->connection,
-		                           NM_SETTING (g_steal_pointer (&s_wg_new)));
-	}
+    gs_unref_object NMSettingWireGuard *s_wg_new = NULL;
+    nm_auto_unref_wgpeer NMWireGuardPeer *peer   = NULL;
+    gs_free_error GError *error                  = NULL;
+    NMSettingWireGuard *  s_wg;
+    gs_free char *        str  = NULL;
+    const char *          cstr = NULL;
+    const char *          key;
+    gint64                i64;
+    gs_strfreev char **   sa = NULL;
+    gsize                 n_sa;
+
+    peer = nm_wireguard_peer_new();
+
+    nm_assert(g_str_has_prefix(info->group, NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER));
+    cstr = &info->group[NM_STRLEN(NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)];
+    if (!nm_utils_base64secret_normalize(cstr, NM_WIREGUARD_PUBLIC_KEY_LEN, &str)
+        || !nm_streq0(str, cstr)) {
+        /* the group name must be identical to the normalized(!) key, so that it
+         * is uniquely identified. */
+        handle_warn(info,
+                    NULL,
+                    NM_SETTING_WIREGUARD_PEERS,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("invalid peer public key in section '%s'"),
+                    info->group);
+        return;
+    }
+    nm_wireguard_peer_set_public_key(peer, cstr, TRUE);
+    nm_clear_g_free(&str);
+
+    key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY;
+    str = nm_keyfile_plugin_kf_get_string(info->keyfile, info->group, key, NULL);
+    if (str) {
+        if (!nm_wireguard_peer_set_preshared_key(peer, str, FALSE)) {
+            if (!handle_warn(info,
+                             key,
+                             NM_SETTING_WIREGUARD_PEERS,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("key '%s.%s' is not a valid 256 bit key in base64 encoding"),
+                             info->group,
+                             key))
+                return;
+        }
+        nm_clear_g_free(&str);
+    }
+
+    key = NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS;
+    i64 = nm_keyfile_plugin_kf_get_int64(info->keyfile,
+                                         info->group,
+                                         key,
+                                         0,
+                                         0,
+                                         NM_SETTING_SECRET_FLAG_ALL,
+                                         -1,
+                                         NULL);
+    if (errno != ENODATA) {
+        if (i64 == -1 || !_nm_setting_secret_flags_valid(i64)) {
+            if (!handle_warn(info,
+                             key,
+                             NM_SETTING_WIREGUARD_PEERS,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("key '%s.%s' is not a valid secret flag"),
+                             info->group,
+                             key))
+                return;
+        } else
+            nm_wireguard_peer_set_preshared_key_flags(peer, i64);
+    }
+
+    key = NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE;
+    i64 = nm_keyfile_plugin_kf_get_int64(info->keyfile,
+                                         info->group,
+                                         key,
+                                         0,
+                                         0,
+                                         G_MAXUINT32,
+                                         -1,
+                                         NULL);
+    if (errno != ENODATA) {
+        if (i64 == -1) {
+            if (!handle_warn(info,
+                             key,
+                             NM_SETTING_WIREGUARD_PEERS,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("key '%s.%s' is not a integer in range 0 to 2^32"),
+                             info->group,
+                             key))
+                return;
+        } else
+            nm_wireguard_peer_set_persistent_keepalive(peer, i64);
+    }
+
+    key = NM_WIREGUARD_PEER_ATTR_ENDPOINT;
+    str = nm_keyfile_plugin_kf_get_string(info->keyfile, info->group, key, NULL);
+    if (str && str[0]) {
+        if (!nm_wireguard_peer_set_endpoint(peer, str, FALSE)) {
+            if (!handle_warn(info,
+                             key,
+                             NM_SETTING_WIREGUARD_PEERS,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("key '%s.%s' is not a valid endpoint"),
+                             info->group,
+                             key))
+                return;
+        }
+    }
+    nm_clear_g_free(&str);
+
+    key = NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS;
+    sa  = nm_keyfile_plugin_kf_get_string_list(info->keyfile, info->group, key, &n_sa, NULL);
+    if (n_sa > 0) {
+        gboolean has_error = FALSE;
+        gsize    i;
+
+        for (i = 0; i < n_sa; i++) {
+            if (!nm_utils_parse_inaddr_prefix_bin(AF_UNSPEC, sa[i], NULL, NULL, NULL)) {
+                has_error = TRUE;
+                continue;
+            }
+            nm_wireguard_peer_append_allowed_ip(peer, sa[i], TRUE);
+        }
+        if (has_error) {
+            if (!handle_warn(info,
+                             key,
+                             NM_SETTING_WIREGUARD_PEERS,
+                             NM_KEYFILE_WARN_SEVERITY_WARN,
+                             _("key '%s.%s' has invalid allowed-ips"),
+                             info->group,
+                             key))
+                return;
+        }
+    }
+
+    if (info->error)
+        return;
+
+    if (!nm_wireguard_peer_is_valid(peer, TRUE, TRUE, &error)) {
+        handle_warn(info,
+                    NULL,
+                    NM_SETTING_WIREGUARD_PEERS,
+                    NM_KEYFILE_WARN_SEVERITY_WARN,
+                    _("peer '%s' is invalid: %s"),
+                    info->group,
+                    error->message);
+        return;
+    }
+
+    s_wg = NM_SETTING_WIREGUARD(
+        nm_connection_get_setting(info->connection, NM_TYPE_SETTING_WIREGUARD));
+    if (!s_wg) {
+        s_wg_new = NM_SETTING_WIREGUARD(nm_setting_wireguard_new());
+        s_wg     = s_wg_new;
+    }
+
+    nm_setting_wireguard_append_peer(s_wg, peer);
+
+    if (s_wg_new) {
+        nm_connection_add_setting(info->connection, NM_SETTING(g_steal_pointer(&s_wg_new)));
+    }
 }
 
 static void
-_read_setting_vpn_secrets (KeyfileReaderInfo *info)
+_read_setting_vpn_secrets(KeyfileReaderInfo *info)
 {
-	gs_strfreev char **keys = NULL;
-	gsize i, n_keys;
-	NMSettingVpn *s_vpn;
-
-	s_vpn = nm_connection_get_setting_vpn (info->connection);
-	if (!s_vpn) {
-		/* if we don't also have a [vpn] section (which must be parsed earlier),
-		 * we don't do anything. */
-		nm_assert (!g_key_file_has_group (info->keyfile, "vpn"));
-		return;
-	}
-
-	keys = nm_keyfile_plugin_kf_get_keys (info->keyfile, NM_KEYFILE_GROUP_VPN_SECRETS, &n_keys, NULL);
-	for (i = 0; i < n_keys; i++) {
-		gs_free char *secret = NULL;
-
-		secret = nm_keyfile_plugin_kf_get_string (info->keyfile, NM_KEYFILE_GROUP_VPN_SECRETS, keys[i], NULL);
-		if (secret)
-			nm_setting_vpn_add_secret (s_vpn, keys[i], secret);
-	}
+    gs_strfreev char **keys = NULL;
+    gsize              i, n_keys;
+    NMSettingVpn *     s_vpn;
+
+    s_vpn = nm_connection_get_setting_vpn(info->connection);
+    if (!s_vpn) {
+        /* if we don't also have a [vpn] section (which must be parsed earlier),
+         * we don't do anything. */
+        nm_assert(!g_key_file_has_group(info->keyfile, "vpn"));
+        return;
+    }
+
+    keys =
+        nm_keyfile_plugin_kf_get_keys(info->keyfile, NM_KEYFILE_GROUP_VPN_SECRETS, &n_keys, NULL);
+    for (i = 0; i < n_keys; i++) {
+        gs_free char *secret = NULL;
+
+        secret = nm_keyfile_plugin_kf_get_string(info->keyfile,
+                                                 NM_KEYFILE_GROUP_VPN_SECRETS,
+                                                 keys[i],
+                                                 NULL);
+        if (secret)
+            nm_setting_vpn_add_secret(s_vpn, keys[i], secret);
+    }
 }
 
 gboolean
-nm_keyfile_read_ensure_id (NMConnection *connection,
-                           const char *fallback_id)
+nm_keyfile_read_ensure_id(NMConnection *connection, const char *fallback_id)
 {
-	NMSettingConnection *s_con;
+    NMSettingConnection *s_con;
 
-	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
-	g_return_val_if_fail (fallback_id, FALSE);
+    g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE);
+    g_return_val_if_fail(fallback_id, FALSE);
 
-	s_con = nm_connection_get_setting_connection (connection);
-	g_return_val_if_fail (NM_IS_SETTING_CONNECTION (s_con), FALSE);
+    s_con = nm_connection_get_setting_connection(connection);
+    g_return_val_if_fail(NM_IS_SETTING_CONNECTION(s_con), FALSE);
 
-	if (nm_setting_connection_get_id (s_con))
-		return FALSE;
+    if (nm_setting_connection_get_id(s_con))
+        return FALSE;
 
-	g_object_set (s_con, NM_SETTING_CONNECTION_ID, fallback_id, NULL);
-	return TRUE;
+    g_object_set(s_con, NM_SETTING_CONNECTION_ID, fallback_id, NULL);
+    return TRUE;
 }
 
 gboolean
-nm_keyfile_read_ensure_uuid (NMConnection *connection,
-                             const char *fallback_uuid_seed)
+nm_keyfile_read_ensure_uuid(NMConnection *connection, const char *fallback_uuid_seed)
 {
-	NMSettingConnection *s_con;
-	gs_free char *hashed_uuid = NULL;
+    NMSettingConnection *s_con;
+    gs_free char *       hashed_uuid = NULL;
 
-	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
-	g_return_val_if_fail (fallback_uuid_seed, FALSE);
+    g_return_val_if_fail(NM_IS_CONNECTION(connection), FALSE);
+    g_return_val_if_fail(fallback_uuid_seed, FALSE);
 
-	s_con = nm_connection_get_setting_connection (connection);
-	g_return_val_if_fail (NM_IS_SETTING_CONNECTION (s_con), FALSE);
+    s_con = nm_connection_get_setting_connection(connection);
+    g_return_val_if_fail(NM_IS_SETTING_CONNECTION(s_con), FALSE);
 
-	if (nm_setting_connection_get_uuid (s_con))
-		return FALSE;
+    if (nm_setting_connection_get_uuid(s_con))
+        return FALSE;
 
-	hashed_uuid = _nm_utils_uuid_generate_from_strings ("keyfile", fallback_uuid_seed, NULL);
-	g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
-	return TRUE;
+    hashed_uuid = _nm_utils_uuid_generate_from_strings("keyfile", fallback_uuid_seed, NULL);
+    g_object_set(s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL);
+    return TRUE;
 }
 
 /**
@@ -3769,586 +3592,590 @@ nm_keyfile_read_ensure_uuid (NMConnection *connection,
  * Returns: (transfer full): on success, returns the created connection.
  */
 NMConnection *
-nm_keyfile_read (GKeyFile *keyfile,
-                 const char *base_dir,
-                 NMKeyfileHandlerFlags handler_flags,
-                 NMKeyfileReadHandler handler,
-                 void *user_data,
-                 GError **error)
+nm_keyfile_read(GKeyFile *            keyfile,
+                const char *          base_dir,
+                NMKeyfileHandlerFlags handler_flags,
+                NMKeyfileReadHandler  handler,
+                void *                user_data,
+                GError **             error)
 {
-	gs_unref_object NMConnection *connection = NULL;
-	NMSettingConnection *s_con;
-	gs_strfreev char **groups = NULL;
-	gsize n_groups;
-	gsize i;
-	gboolean vpn_secrets = FALSE;
-	KeyfileReaderInfo info;
-
-	g_return_val_if_fail (keyfile, NULL);
-	g_return_val_if_fail (!error || !*error, NULL);
-	g_return_val_if_fail (base_dir && base_dir[0] == '/', NULL);
-	g_return_val_if_fail (handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL);
-
-	connection = nm_simple_connection_new ();
-
-	info = (KeyfileReaderInfo) {
-		.connection   = connection,
-		.keyfile      = keyfile,
-		.base_dir     = base_dir,
-		.read_handler = handler,
-		.user_data    = user_data,
-	};
-
-	groups = g_key_file_get_groups (keyfile, &n_groups);
-	if (!groups)
-		n_groups = 0;
-
-	for (i = 0; i < n_groups; i++) {
-
-		info.group = groups[i];
-
-		if (nm_streq (groups[i], NM_KEYFILE_GROUP_VPN_SECRETS)) {
-			/* Only read out secrets when needed */
-			vpn_secrets = TRUE;
-		} else if (NM_STR_HAS_PREFIX (groups[i], NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER))
-			_read_setting_wireguard_peer (&info);
-		else if (NM_IN_STRSET (groups[i], NM_KEYFILE_GROUP_NMMETA,
-		                                  ETHERNET_S390_OPTIONS_GROUP_NAME)) {
-			/* pass */
-		} else
-			_read_setting (&info);
-
-		info.group = NULL;
-
-		if (info.error)
-			goto out_with_info_error;
-	}
-
-	s_con = nm_connection_get_setting_connection (connection);
-	if (!s_con) {
-		s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
-		nm_connection_add_setting (connection, NM_SETTING (s_con));
-	}
-
-	/* Make sure that we have 'interface-name' even if it was specified in the
-	 * "wrong" (ie, deprecated) group.
-	 */
-	if (   !nm_setting_connection_get_interface_name (s_con)
-	    && nm_setting_connection_get_connection_type (s_con)) {
-		gs_free char *interface_name = NULL;
-
-		interface_name = g_key_file_get_string (keyfile,
-		                                        nm_setting_connection_get_connection_type (s_con),
-		                                        "interface-name",
-		                                        NULL);
-		if (interface_name)
-			g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL);
-	}
-
-	if (vpn_secrets) {
-		info.group = NM_KEYFILE_GROUP_VPN_SECRETS;
-		_read_setting_vpn_secrets (&info);
-		info.group = NULL;;
-		if (info.error)
-			goto out_with_info_error;
-	}
-
-	return g_steal_pointer (&connection);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    gs_strfreev char **           groups = NULL;
+    gsize                         n_groups;
+    gsize                         i;
+    gboolean                      vpn_secrets = FALSE;
+    KeyfileReaderInfo             info;
+
+    g_return_val_if_fail(keyfile, NULL);
+    g_return_val_if_fail(!error || !*error, NULL);
+    g_return_val_if_fail(base_dir && base_dir[0] == '/', NULL);
+    g_return_val_if_fail(handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL);
+
+    connection = nm_simple_connection_new();
+
+    info = (KeyfileReaderInfo){
+        .connection   = connection,
+        .keyfile      = keyfile,
+        .base_dir     = base_dir,
+        .read_handler = handler,
+        .user_data    = user_data,
+    };
+
+    groups = g_key_file_get_groups(keyfile, &n_groups);
+    if (!groups)
+        n_groups = 0;
+
+    for (i = 0; i < n_groups; i++) {
+        info.group = groups[i];
+
+        if (nm_streq(groups[i], NM_KEYFILE_GROUP_VPN_SECRETS)) {
+            /* Only read out secrets when needed */
+            vpn_secrets = TRUE;
+        } else if (NM_STR_HAS_PREFIX(groups[i], NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER))
+            _read_setting_wireguard_peer(&info);
+        else if (NM_IN_STRSET(groups[i],
+                              NM_KEYFILE_GROUP_NMMETA,
+                              ETHERNET_S390_OPTIONS_GROUP_NAME)) {
+            /* pass */
+        } else
+            _read_setting(&info);
+
+        info.group = NULL;
+
+        if (info.error)
+            goto out_with_info_error;
+    }
+
+    s_con = nm_connection_get_setting_connection(connection);
+    if (!s_con) {
+        s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+        nm_connection_add_setting(connection, NM_SETTING(s_con));
+    }
+
+    /* Make sure that we have 'interface-name' even if it was specified in the
+     * "wrong" (ie, deprecated) group.
+     */
+    if (!nm_setting_connection_get_interface_name(s_con)
+        && nm_setting_connection_get_connection_type(s_con)) {
+        gs_free char *interface_name = NULL;
+
+        interface_name = g_key_file_get_string(keyfile,
+                                               nm_setting_connection_get_connection_type(s_con),
+                                               "interface-name",
+                                               NULL);
+        if (interface_name)
+            g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL);
+    }
+
+    if (vpn_secrets) {
+        info.group = NM_KEYFILE_GROUP_VPN_SECRETS;
+        _read_setting_vpn_secrets(&info);
+        info.group = NULL;
+        if (info.error)
+            goto out_with_info_error;
+    }
+
+    return g_steal_pointer(&connection);
 
 out_with_info_error:
-	g_propagate_error (error, info.error);
-	return NULL;
+    g_propagate_error(error, info.error);
+    return NULL;
 }
 
 /*****************************************************************************/
 
 static void
-write_setting_value (KeyfileWriterInfo *info,
-                     NMSetting *setting,
-                     const NMSettInfoProperty *property_info)
+write_setting_value(KeyfileWriterInfo *       info,
+                    NMSetting *               setting,
+                    const NMSettInfoProperty *property_info)
 {
-	const NMMetaSettingInfo *setting_info;
-	const ParseInfoProperty *pip;
-	const char *key;
-	char numstr[64];
-	GValue value;
-	GType type;
-
-	nm_assert (!info->error);
-	nm_assert (   !property_info->param_spec
-	           || nm_streq (property_info->param_spec->name, property_info->name));
-
-	key = property_info->name;
-
-	_parse_info_find (setting, key, &setting_info, NULL, &pip);
-
-	if (!pip) {
-		if (!setting_info) {
-			/* the setting type is unknown. That is highly unexpected
-			 * (and as this is currently only called from NetworkManager
-			 * daemon, not possible).
-			 *
-			 * Still, handle it gracefully, because later keyfile writer will become
-			 * public API of libnm, where @setting is (untrusted) user input.
-			 *
-			 * Gracefully here just means: ignore the setting. */
-			return;
-		}
-		if (!property_info->param_spec)
-			return;
-		if (nm_streq (key, NM_SETTING_NAME))
-			return;
-	} else {
-		if (pip->has_writer_full) {
-			pip->writer_full (info, setting_info, property_info, pip, setting);
-			return;
-		}
-		if (pip->writer_skip)
-			return;
-	}
-
-	nm_assert (property_info->param_spec);
-
-	/* Don't write secrets that are owned by user secret agents or aren't
-	 * supposed to be saved.  VPN secrets are handled specially though since
-	 * the secret flags there are in a third-level hash in the 'secrets'
-	 * property.
-	 */
-	if (   (property_info->param_spec->flags & NM_SETTING_PARAM_SECRET)
-	    && !NM_IS_SETTING_VPN (setting)) {
-		NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
-
-		if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL))
-			g_return_if_reached ();
-		if (!_secret_flags_persist_secret (secret_flags))
-			return;
-	}
-
-	value = (GValue) { 0 };
-
-	g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (property_info->param_spec));
-	g_object_get_property (G_OBJECT (setting), property_info->param_spec->name, &value);
-
-	if (   (!pip || !pip->writer_persist_default)
-	    && g_param_value_defaults (property_info->param_spec, &value)) {
-		nm_assert (!g_key_file_has_key (info->keyfile, setting_info->setting_name, key, NULL));
-		goto out_unset_value;
-	}
-
-	if (   pip
-	    && pip->writer) {
-		pip->writer (info, setting, key, &value);
-		goto out_unset_value;
-	}
-
-	type = G_VALUE_TYPE (&value);
-	if (type == G_TYPE_STRING) {
-		const char *str;
-
-		str = g_value_get_string (&value);
-		if (str)
-			nm_keyfile_plugin_kf_set_string (info->keyfile, setting_info->setting_name, key, str);
-	} else if (type == G_TYPE_UINT) {
-		nm_sprintf_buf (numstr, "%u", g_value_get_uint (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (type == G_TYPE_INT) {
-		nm_sprintf_buf (numstr, "%d", g_value_get_int (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (type == G_TYPE_UINT64) {
-		nm_sprintf_buf (numstr, "%" G_GUINT64_FORMAT, g_value_get_uint64 (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (type == G_TYPE_INT64) {
-		nm_sprintf_buf (numstr, "%" G_GINT64_FORMAT, g_value_get_int64 (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (type == G_TYPE_BOOLEAN) {
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key,
-		                                  g_value_get_boolean (&value)
-		                                ? "true"
-		                                : "false");
-	} else if (type == G_TYPE_CHAR) {
-		nm_sprintf_buf (numstr, "%d", (int) g_value_get_schar (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (type == G_TYPE_BYTES) {
-		GBytes *bytes;
-		const guint8 *data;
-		gsize len = 0;
-
-		bytes = g_value_get_boxed (&value);
-		data = bytes ? g_bytes_get_data (bytes, &len) : NULL;
-
-		if (data != NULL && len > 0)
-			nm_keyfile_plugin_kf_set_integer_list_uint8 (info->keyfile, setting_info->setting_name, key, data, len);
-	} else if (type == G_TYPE_STRV) {
-		char **array;
-
-		array = (char **) g_value_get_boxed (&value);
-		nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_info->setting_name, key, (const char **const) array, g_strv_length (array));
-	} else if (type == G_TYPE_HASH_TABLE) {
-		write_hash_of_string (info->keyfile, setting, key, &value);
-	} else if (type == G_TYPE_ARRAY) {
-		write_array_of_uint (info->keyfile, setting, key, &value);
-	} else if (G_VALUE_HOLDS_FLAGS (&value)) {
-		nm_sprintf_buf (numstr, "%u", g_value_get_flags (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else if (G_VALUE_HOLDS_ENUM (&value)) {
-		nm_sprintf_buf (numstr, "%d", g_value_get_enum (&value));
-		nm_keyfile_plugin_kf_set_value (info->keyfile, setting_info->setting_name, key, numstr);
-	} else
-		g_return_if_reached ();
+    const NMMetaSettingInfo *setting_info;
+    const ParseInfoProperty *pip;
+    const char *             key;
+    char                     numstr[64];
+    GValue                   value;
+    GType                    type;
+
+    nm_assert(!info->error);
+    nm_assert(!property_info->param_spec
+              || nm_streq(property_info->param_spec->name, property_info->name));
+
+    key = property_info->name;
+
+    _parse_info_find(setting, key, &setting_info, NULL, &pip);
+
+    if (!pip) {
+        if (!setting_info) {
+            /* the setting type is unknown. That is highly unexpected
+             * (and as this is currently only called from NetworkManager
+             * daemon, not possible).
+             *
+             * Still, handle it gracefully, because later keyfile writer will become
+             * public API of libnm, where @setting is (untrusted) user input.
+             *
+             * Gracefully here just means: ignore the setting. */
+            return;
+        }
+        if (!property_info->param_spec)
+            return;
+        if (nm_streq(key, NM_SETTING_NAME))
+            return;
+    } else {
+        if (pip->has_writer_full) {
+            pip->writer_full(info, setting_info, property_info, pip, setting);
+            return;
+        }
+        if (pip->writer_skip)
+            return;
+    }
+
+    nm_assert(property_info->param_spec);
+
+    /* Don't write secrets that are owned by user secret agents or aren't
+     * supposed to be saved.  VPN secrets are handled specially though since
+     * the secret flags there are in a third-level hash in the 'secrets'
+     * property.
+     */
+    if ((property_info->param_spec->flags & NM_SETTING_PARAM_SECRET)
+        && !NM_IS_SETTING_VPN(setting)) {
+        NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+        if (!nm_setting_get_secret_flags(setting, key, &secret_flags, NULL))
+            g_return_if_reached();
+        if (!_secret_flags_persist_secret(secret_flags))
+            return;
+    }
+
+    value = (GValue){0};
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec));
+    g_object_get_property(G_OBJECT(setting), property_info->param_spec->name, &value);
+
+    if ((!pip || !pip->writer_persist_default)
+        && g_param_value_defaults(property_info->param_spec, &value)) {
+        nm_assert(!g_key_file_has_key(info->keyfile, setting_info->setting_name, key, NULL));
+        goto out_unset_value;
+    }
+
+    if (pip && pip->writer) {
+        pip->writer(info, setting, key, &value);
+        goto out_unset_value;
+    }
+
+    type = G_VALUE_TYPE(&value);
+    if (type == G_TYPE_STRING) {
+        const char *str;
+
+        str = g_value_get_string(&value);
+        if (str)
+            nm_keyfile_plugin_kf_set_string(info->keyfile, setting_info->setting_name, key, str);
+    } else if (type == G_TYPE_UINT) {
+        nm_sprintf_buf(numstr, "%u", g_value_get_uint(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (type == G_TYPE_INT) {
+        nm_sprintf_buf(numstr, "%d", g_value_get_int(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (type == G_TYPE_UINT64) {
+        nm_sprintf_buf(numstr, "%" G_GUINT64_FORMAT, g_value_get_uint64(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (type == G_TYPE_INT64) {
+        nm_sprintf_buf(numstr, "%" G_GINT64_FORMAT, g_value_get_int64(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (type == G_TYPE_BOOLEAN) {
+        nm_keyfile_plugin_kf_set_value(info->keyfile,
+                                       setting_info->setting_name,
+                                       key,
+                                       g_value_get_boolean(&value) ? "true" : "false");
+    } else if (type == G_TYPE_CHAR) {
+        nm_sprintf_buf(numstr, "%d", (int) g_value_get_schar(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (type == G_TYPE_BYTES) {
+        GBytes *      bytes;
+        const guint8 *data;
+        gsize         len = 0;
+
+        bytes = g_value_get_boxed(&value);
+        data  = bytes ? g_bytes_get_data(bytes, &len) : NULL;
+
+        if (data != NULL && len > 0)
+            nm_keyfile_plugin_kf_set_integer_list_uint8(info->keyfile,
+                                                        setting_info->setting_name,
+                                                        key,
+                                                        data,
+                                                        len);
+    } else if (type == G_TYPE_STRV) {
+        char **array;
+
+        array = (char **) g_value_get_boxed(&value);
+        nm_keyfile_plugin_kf_set_string_list(info->keyfile,
+                                             setting_info->setting_name,
+                                             key,
+                                             (const char **const) array,
+                                             g_strv_length(array));
+    } else if (type == G_TYPE_HASH_TABLE) {
+        write_hash_of_string(info->keyfile, setting, key, &value);
+    } else if (type == G_TYPE_ARRAY) {
+        write_array_of_uint(info->keyfile, setting, key, &value);
+    } else if (G_VALUE_HOLDS_FLAGS(&value)) {
+        nm_sprintf_buf(numstr, "%u", g_value_get_flags(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else if (G_VALUE_HOLDS_ENUM(&value)) {
+        nm_sprintf_buf(numstr, "%d", g_value_get_enum(&value));
+        nm_keyfile_plugin_kf_set_value(info->keyfile, setting_info->setting_name, key, numstr);
+    } else
+        g_return_if_reached();
 
 out_unset_value:
-	g_value_unset (&value);
+    g_value_unset(&value);
 }
 
 static void
-_write_setting_wireguard (NMSetting *setting, KeyfileWriterInfo *info)
+_write_setting_wireguard(NMSetting *setting, KeyfileWriterInfo *info)
 {
-	NMSettingWireGuard *s_wg;
-	guint i_peer, n_peers;
-
-	s_wg = NM_SETTING_WIREGUARD (setting);
-
-	n_peers = nm_setting_wireguard_get_peers_len (s_wg);
-	for (i_peer = 0; i_peer < n_peers; i_peer++) {
-		NMWireGuardPeer *peer = nm_setting_wireguard_get_peer (s_wg, i_peer);
-		const char *public_key;
-		char group[NM_STRLEN (NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER) + 200];
-		NMSettingSecretFlags secret_flags;
-		gboolean any_key = FALSE;
-		guint i_aip, n_aip;
-		const char *cstr;
-		guint32 u32;
-
-		public_key = nm_wireguard_peer_get_public_key (peer);
-		if (   !public_key
-		    || !public_key[0]
-		    || !NM_STRCHAR_ALL (public_key, ch, nm_sd_utils_unbase64char (ch, TRUE) >= 0)) {
-			/* invalid peer. Skip it */
-			continue;
-		}
-
-		if (g_snprintf (group,
-		                sizeof (group),
-		                "%s%s",
-		                NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER,
-		                nm_wireguard_peer_get_public_key (peer)) >= sizeof (group)) {
-			/* Too long. Not a valid public key. Skip the peer. */
-			continue;
-		}
-
-		cstr = nm_wireguard_peer_get_endpoint (peer);
-		if (cstr) {
-			g_key_file_set_string (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, cstr);
-			any_key = TRUE;
-		}
-
-		secret_flags = nm_wireguard_peer_get_preshared_key_flags (peer);
-		if (_secret_flags_persist_secret (secret_flags)) {
-			cstr = nm_wireguard_peer_get_preshared_key (peer);
-			if (cstr) {
-				g_key_file_set_string (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY, cstr);
-				any_key = TRUE;
-			}
-		}
-
-		/* usually, we don't persist the secret-flags 0 (because they are the default).
-		 * For WireGuard peers, the default secret-flags for preshared-key are 4 (not-required).
-		 * So, in this case behave differently: a missing preshared-key-flag setting means
-		 * "not-required". */
-		if (secret_flags != NM_SETTING_SECRET_FLAG_NOT_REQUIRED) {
-			g_key_file_set_int64 (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS, secret_flags);
-			any_key = TRUE;
-		}
-
-		u32 = nm_wireguard_peer_get_persistent_keepalive (peer);
-		if (u32) {
-			g_key_file_set_uint64 (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE, u32);
-			any_key = TRUE;
-		}
-
-		n_aip = nm_wireguard_peer_get_allowed_ips_len (peer);
-		if (n_aip > 0) {
-			gs_free const char **strv = NULL;
-
-			strv = g_new (const char *, ((gsize) n_aip) + 1);
-			for (i_aip = 0; i_aip < n_aip; i_aip++)
-				strv[i_aip] = nm_wireguard_peer_get_allowed_ip (peer, i_aip, NULL);
-			strv[n_aip] = NULL;
-			g_key_file_set_string_list (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS,
-			                            strv, n_aip);
-			any_key = TRUE;
-		}
-
-		if (!any_key) {
-			/* we cannot omit all keys. At an empty endpoint. */
-			g_key_file_set_string (info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, "");
-		}
-	}
+    NMSettingWireGuard *s_wg;
+    guint               i_peer, n_peers;
+
+    s_wg = NM_SETTING_WIREGUARD(setting);
+
+    n_peers = nm_setting_wireguard_get_peers_len(s_wg);
+    for (i_peer = 0; i_peer < n_peers; i_peer++) {
+        NMWireGuardPeer *    peer = nm_setting_wireguard_get_peer(s_wg, i_peer);
+        const char *         public_key;
+        char                 group[NM_STRLEN(NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER) + 200];
+        NMSettingSecretFlags secret_flags;
+        gboolean             any_key = FALSE;
+        guint                i_aip, n_aip;
+        const char *         cstr;
+        guint32              u32;
+
+        public_key = nm_wireguard_peer_get_public_key(peer);
+        if (!public_key || !public_key[0]
+            || !NM_STRCHAR_ALL(public_key, ch, nm_sd_utils_unbase64char(ch, TRUE) >= 0)) {
+            /* invalid peer. Skip it */
+            continue;
+        }
+
+        if (g_snprintf(group,
+                       sizeof(group),
+                       "%s%s",
+                       NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER,
+                       nm_wireguard_peer_get_public_key(peer))
+            >= sizeof(group)) {
+            /* Too long. Not a valid public key. Skip the peer. */
+            continue;
+        }
+
+        cstr = nm_wireguard_peer_get_endpoint(peer);
+        if (cstr) {
+            g_key_file_set_string(info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, cstr);
+            any_key = TRUE;
+        }
+
+        secret_flags = nm_wireguard_peer_get_preshared_key_flags(peer);
+        if (_secret_flags_persist_secret(secret_flags)) {
+            cstr = nm_wireguard_peer_get_preshared_key(peer);
+            if (cstr) {
+                g_key_file_set_string(info->keyfile,
+                                      group,
+                                      NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY,
+                                      cstr);
+                any_key = TRUE;
+            }
+        }
+
+        /* usually, we don't persist the secret-flags 0 (because they are the default).
+         * For WireGuard peers, the default secret-flags for preshared-key are 4 (not-required).
+         * So, in this case behave differently: a missing preshared-key-flag setting means
+         * "not-required". */
+        if (secret_flags != NM_SETTING_SECRET_FLAG_NOT_REQUIRED) {
+            g_key_file_set_int64(info->keyfile,
+                                 group,
+                                 NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS,
+                                 secret_flags);
+            any_key = TRUE;
+        }
+
+        u32 = nm_wireguard_peer_get_persistent_keepalive(peer);
+        if (u32) {
+            g_key_file_set_uint64(info->keyfile,
+                                  group,
+                                  NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE,
+                                  u32);
+            any_key = TRUE;
+        }
+
+        n_aip = nm_wireguard_peer_get_allowed_ips_len(peer);
+        if (n_aip > 0) {
+            gs_free const char **strv = NULL;
+
+            strv = g_new(const char *, ((gsize) n_aip) + 1);
+            for (i_aip = 0; i_aip < n_aip; i_aip++)
+                strv[i_aip] = nm_wireguard_peer_get_allowed_ip(peer, i_aip, NULL);
+            strv[n_aip] = NULL;
+            g_key_file_set_string_list(info->keyfile,
+                                       group,
+                                       NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS,
+                                       strv,
+                                       n_aip);
+            any_key = TRUE;
+        }
+
+        if (!any_key) {
+            /* we cannot omit all keys. At an empty endpoint. */
+            g_key_file_set_string(info->keyfile, group, NM_WIREGUARD_PEER_ATTR_ENDPOINT, "");
+        }
+    }
 }
 
 GKeyFile *
-nm_keyfile_write (NMConnection *connection,
-                  NMKeyfileHandlerFlags handler_flags,
-                  NMKeyfileWriteHandler handler,
-                  void *user_data,
-                  GError **error)
+nm_keyfile_write(NMConnection *        connection,
+                 NMKeyfileHandlerFlags handler_flags,
+                 NMKeyfileWriteHandler handler,
+                 void *                user_data,
+                 GError **             error)
 {
-	gs_unref_keyfile GKeyFile *keyfile = NULL;
-	KeyfileWriterInfo info;
-	gs_free NMSetting **settings = NULL;
-	guint i, j, n_settings = 0;
-
-	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	g_return_val_if_fail (!error || !*error, NULL);
-	g_return_val_if_fail (handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL);
-
-	if (!nm_connection_verify (connection, error))
-		return NULL;
-
-	keyfile = g_key_file_new ();
-
-	info = (KeyfileWriterInfo) {
-		.connection    = connection,
-		.keyfile       = keyfile,
-		.error         = NULL,
-		.write_handler = handler,
-		.user_data     = user_data,
-	};
-
-	settings = nm_connection_get_settings (connection, &n_settings);
-	for (i = 0; i < n_settings; i++) {
-		const NMSettInfoSetting *sett_info;
-		NMSetting *setting = settings[i];
-		const char *setting_name;
-		const char *setting_alias;
-
-		sett_info = _nm_setting_class_get_sett_info (NM_SETTING_GET_CLASS (setting));
-
-		setting_name = sett_info->setting_class->setting_info->setting_name;
-
-		if (sett_info->detail.gendata_info) {
-			guint k, n_keys;
-			const char *const*keys;
-
-			nm_assert (!nm_keyfile_plugin_get_alias_for_setting_name (sett_info->setting_class->setting_info->setting_name));
-
-			n_keys = _nm_setting_option_get_all (setting, &keys, NULL);
-
-			if (n_keys > 0) {
-				GHashTable *h = _nm_setting_option_hash (setting, FALSE);
-
-				for (k = 0; k < n_keys; k++) {
-					const char *key = keys[k];
-					GVariant *v;
-
-					v = g_hash_table_lookup (h, key);
-
-					if (g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) {
-						g_key_file_set_boolean (info.keyfile,
-						                        setting_name,
-						                        key,
-						                        g_variant_get_boolean (v));
-					} else if (g_variant_is_of_type (v, G_VARIANT_TYPE_UINT32)) {
-						g_key_file_set_uint64 (info.keyfile,
-						                       setting_name,
-						                       key,
-						                       (guint64) g_variant_get_uint32 (v));
-					} else {
-						/* BUG: The variant type is not implemented. Since the connection
-						 * verifies, this can only mean we either wrongly didn't reject
-						 * the connection as invalid, or we didn't properly implement the
-						 * variant type. */
-						nm_assert_not_reached ();
-						continue;
-					}
-				}
-			}
-		}
-
-		for (j = 0; j < sett_info->property_infos_len; j++) {
-			const NMSettInfoProperty *property_info = _nm_sett_info_property_info_get_sorted (sett_info, j);
-
-			write_setting_value (&info, setting, property_info);
-			if (info.error)
-				goto out_with_info_error;
-		}
-
-		setting_alias = nm_keyfile_plugin_get_alias_for_setting_name (setting_name);
-		if (   (   setting_alias
-		        && g_key_file_has_group (info.keyfile, setting_alias))
-		    || g_key_file_has_group (info.keyfile, setting_name)) {
-			/* we have a section for the setting. Nothing to do. */
-		} else {
-			/* ensure the group is present. There is no API for that, so add and remove
-			 * a dummy key. */
-			g_key_file_set_value  (info.keyfile, setting_alias ?: setting_name, ".X", "1");
-			g_key_file_remove_key (info.keyfile, setting_alias ?: setting_name, ".X", NULL);
-		}
-
-		if (NM_IS_SETTING_WIREGUARD (setting)) {
-			_write_setting_wireguard (setting, &info);
-			if (info.error)
-				goto out_with_info_error;
-		}
-
-		nm_assert (!info.error);
-	}
-
-	nm_assert (!info.error);
-
-	return g_steal_pointer (&keyfile);
+    nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
+    KeyfileWriterInfo               info;
+    gs_free NMSetting **settings = NULL;
+    guint               i, j, n_settings = 0;
+
+    g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL);
+    g_return_val_if_fail(!error || !*error, NULL);
+    g_return_val_if_fail(handler_flags == NM_KEYFILE_HANDLER_FLAGS_NONE, NULL);
+
+    if (!nm_connection_verify(connection, error))
+        return NULL;
+
+    keyfile = g_key_file_new();
+
+    info = (KeyfileWriterInfo){
+        .connection    = connection,
+        .keyfile       = keyfile,
+        .error         = NULL,
+        .write_handler = handler,
+        .user_data     = user_data,
+    };
+
+    settings = nm_connection_get_settings(connection, &n_settings);
+    for (i = 0; i < n_settings; i++) {
+        const NMSettInfoSetting *sett_info;
+        NMSetting *              setting = settings[i];
+        const char *             setting_name;
+        const char *             setting_alias;
+
+        sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting));
+
+        setting_name = sett_info->setting_class->setting_info->setting_name;
+
+        if (sett_info->detail.gendata_info) {
+            guint              k, n_keys;
+            const char *const *keys;
+
+            nm_assert(!nm_keyfile_plugin_get_alias_for_setting_name(
+                sett_info->setting_class->setting_info->setting_name));
+
+            n_keys = _nm_setting_option_get_all(setting, &keys, NULL);
+
+            if (n_keys > 0) {
+                GHashTable *h = _nm_setting_option_hash(setting, FALSE);
+
+                for (k = 0; k < n_keys; k++) {
+                    const char *key = keys[k];
+                    GVariant *  v;
+
+                    v = g_hash_table_lookup(h, key);
+
+                    if (g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) {
+                        g_key_file_set_boolean(info.keyfile,
+                                               setting_name,
+                                               key,
+                                               g_variant_get_boolean(v));
+                    } else if (g_variant_is_of_type(v, G_VARIANT_TYPE_UINT32)) {
+                        g_key_file_set_uint64(info.keyfile,
+                                              setting_name,
+                                              key,
+                                              (guint64) g_variant_get_uint32(v));
+                    } else {
+                        /* BUG: The variant type is not implemented. Since the connection
+                         * verifies, this can only mean we either wrongly didn't reject
+                         * the connection as invalid, or we didn't properly implement the
+                         * variant type. */
+                        nm_assert_not_reached();
+                        continue;
+                    }
+                }
+            }
+        }
+
+        for (j = 0; j < sett_info->property_infos_len; j++) {
+            const NMSettInfoProperty *property_info =
+                _nm_sett_info_property_info_get_sorted(sett_info, j);
+
+            write_setting_value(&info, setting, property_info);
+            if (info.error)
+                goto out_with_info_error;
+        }
+
+        setting_alias = nm_keyfile_plugin_get_alias_for_setting_name(setting_name);
+        if ((setting_alias && g_key_file_has_group(info.keyfile, setting_alias))
+            || g_key_file_has_group(info.keyfile, setting_name)) {
+            /* we have a section for the setting. Nothing to do. */
+        } else {
+            /* ensure the group is present. There is no API for that, so add and remove
+             * a dummy key. */
+            g_key_file_set_value(info.keyfile, setting_alias ?: setting_name, ".X", "1");
+            g_key_file_remove_key(info.keyfile, setting_alias ?: setting_name, ".X", NULL);
+        }
+
+        if (NM_IS_SETTING_WIREGUARD(setting)) {
+            _write_setting_wireguard(setting, &info);
+            if (info.error)
+                goto out_with_info_error;
+        }
+
+        nm_assert(!info.error);
+    }
+
+    nm_assert(!info.error);
+
+    return g_steal_pointer(&keyfile);
 
 out_with_info_error:
-	g_propagate_error (error, info.error);
-	return NULL;
+    g_propagate_error(error, info.error);
+    return NULL;
 }
 
 /*****************************************************************************/
 
-static const char temp_letters[] =
-"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+static const char temp_letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 
 /*
  * Check '.[a-zA-Z0-9]{6}' file suffix used for temporary files by g_file_set_contents() (mkstemp()).
  */
 static gboolean
-check_mkstemp_suffix (const char *path)
+check_mkstemp_suffix(const char *path)
 {
-	const char *ptr;
+    const char *ptr;
 
-	nm_assert (path);
+    nm_assert(path);
 
-	/* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */
-	ptr = strrchr (path, '.');
-	if (   ptr
-	    && strspn (&ptr[1], temp_letters) == 6
-	    && ptr[7] == '\0')
-		return TRUE;
-	return FALSE;
+    /* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */
+    ptr = strrchr(path, '.');
+    if (ptr && strspn(&ptr[1], temp_letters) == 6 && ptr[7] == '\0')
+        return TRUE;
+    return FALSE;
 }
 
-static gboolean
-_check_suffix_impl (const char *base, const char *tag, gsize tag_len)
-{
-	gsize len;
-
-	nm_assert (base);
-	nm_assert (tag);
-	nm_assert (strlen (tag) == tag_len);
-
-	len = strlen (base);
-	if (   len > tag_len
-	    && !g_ascii_strcasecmp (base + len - tag_len, tag))
-		return TRUE;
-	return FALSE;
-}
-#define check_suffix(base, tag) _check_suffix_impl ((base), ""tag"", NM_STRLEN (tag))
-
-#define SWP_TAG ".swp"
+#define SWP_TAG  ".swp"
 #define SWPX_TAG ".swpx"
-#define PEM_TAG ".pem"
-#define DER_TAG ".der"
+#define PEM_TAG  ".pem"
+#define DER_TAG  ".der"
 
 gboolean
-nm_keyfile_utils_ignore_filename (const char *filename, gboolean require_extension)
+nm_keyfile_utils_ignore_filename(const char *filename, gboolean require_extension)
 {
-	const char *base;
-	gsize l;
-
-	/* ignore_filename() must mirror nm_keyfile_utils_create_filename() */
-
-	g_return_val_if_fail (filename, TRUE);
-
-	base = strrchr (filename, '/');
-	if (base)
-		base++;
-	else
-		base = filename;
-
-	if (!base[0]) {
-		/* this check above with strrchr() also rejects "/some/path/with/trailing/slash/",
-		 * but that is fine, because such a path would name a directory, and we are not
-		 * interested in directories. */
-		return TRUE;
-	}
-
-	if (base[0] == '.') {
-		/* don't allow hidden files */
-		return TRUE;
-	}
-
-	l = strlen (base);
-
-	if (require_extension) {
-		if (   l <= NM_STRLEN (NM_KEYFILE_PATH_SUFFIX_NMCONNECTION)
-		    || !NM_STR_HAS_SUFFIX (base, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION))
-			return TRUE;
-		return FALSE;
-	}
-
-	/* Ignore backup files */
-	if (base[l - 1] == '~')
-		return TRUE;
-
-	/* Ignore temporary files
-	 *
-	 * This check is also important to ignore .nmload files (see
-	 * %NM_KEYFILE_PATH_SUFFIX_NMMETA). */
-	if (check_mkstemp_suffix (base))
-		return TRUE;
-
-	/* Ignore 802.1x certificates and keys */
-	if (   check_suffix (base, PEM_TAG)
-	    || check_suffix (base, DER_TAG))
-		return TRUE;
-
-	return FALSE;
+    const char *base;
+    gsize       l;
+
+    /* ignore_filename() must mirror nm_keyfile_utils_create_filename() */
+
+    g_return_val_if_fail(filename, TRUE);
+
+    base = strrchr(filename, '/');
+    if (base)
+        base++;
+    else
+        base = filename;
+
+    if (!base[0]) {
+        /* this check above with strrchr() also rejects "/some/path/with/trailing/slash/",
+         * but that is fine, because such a path would name a directory, and we are not
+         * interested in directories. */
+        return TRUE;
+    }
+
+    if (base[0] == '.') {
+        /* don't allow hidden files */
+        return TRUE;
+    }
+
+    if (require_extension) {
+        if (!NM_STR_HAS_SUFFIX_WITH_MORE(base, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION))
+            return TRUE;
+        return FALSE;
+    }
+
+    l = strlen(base);
+
+    /* Ignore backup files */
+    if (base[l - 1] == '~')
+        return TRUE;
+
+    /* Ignore temporary files
+     *
+     * This check is also important to ignore .nmload files (see
+     * %NM_KEYFILE_PATH_SUFFIX_NMMETA). */
+    if (check_mkstemp_suffix(base))
+        return TRUE;
+
+    /* Ignore 802.1x certificates and keys */
+    if (NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(base, PEM_TAG)
+        || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(base, DER_TAG))
+        return TRUE;
+
+    return FALSE;
 }
 
 char *
-nm_keyfile_utils_create_filename (const char *name,
-                                  gboolean with_extension)
+nm_keyfile_utils_create_filename(const char *name, gboolean with_extension)
 {
-	GString *str;
-	const char *f = name;
-	/* keyfile used to escape with '*', do not change that behavior.
-	 *
-	 * But for newly added escapings, use '_' instead.
-	 * Also, @with_extension is new-style. */
-	const char ESCAPE_CHAR = with_extension ? '_' : '*';
-	const char ESCAPE_CHAR2 = '_';
-
-	g_return_val_if_fail (name && name[0], NULL);
-
-	str = g_string_sized_new (60);
-
-	/* Convert '/' to ESCAPE_CHAR */
-	for (f = name; f[0]; f++) {
-		if (f[0] == '/')
-			g_string_append_c (str, ESCAPE_CHAR);
-		else
-			g_string_append_c (str, f[0]);
-	}
-
-	/* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject.
-	 * We can escape here more aggressivly then what we would read back. */
-	if (str->str[0] == '.')
-		str->str[0] = ESCAPE_CHAR2;
-	if (str->str[str->len - 1] == '~')
-		str->str[str->len - 1] = ESCAPE_CHAR2;
-	if (   check_mkstemp_suffix (str->str)
-	    || check_suffix (str->str, PEM_TAG)
-	    || check_suffix (str->str, DER_TAG))
-		g_string_append_c (str, ESCAPE_CHAR2);
-
-	if (with_extension)
-		g_string_append (str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
-
-	/* nm_keyfile_utils_create_filename() must mirror ignore_filename() */
-	nm_assert (!strchr (str->str, '/'));
-	nm_assert (!nm_keyfile_utils_ignore_filename (str->str, with_extension));
-
-	return g_string_free (str, FALSE);;
+    /* keyfile used to escape with '*', do not change that behavior.
+     *
+     * But for newly added escapings, use '_' instead.
+     * Also, @with_extension is new-style. */
+    const char ESCAPE_CHAR  = with_extension ? '_' : '*';
+    const char ESCAPE_CHAR2 = '_';
+    NMStrBuf   str;
+    char *     p;
+    gsize      len;
+    gsize      i;
+
+    g_return_val_if_fail(name && name[0], NULL);
+
+    nm_str_buf_init(&str, 0, FALSE);
+
+    len = strlen(name);
+
+    p = nm_str_buf_append_len0(&str, name, len);
+
+    /* Convert '/' to ESCAPE_CHAR */
+    for (i = 0; i < len; i++) {
+        if (p[i] == '/')
+            p[i] = ESCAPE_CHAR;
+    }
+
+    /* nm_keyfile_utils_create_filename() must avoid anything that ignore_filename() would reject.
+     * We can escape here more aggressively then what we would read back. */
+    if (p[0] == '.')
+        p[0] = ESCAPE_CHAR2;
+    if (p[str.len - 1] == '~')
+        p[str.len - 1] = ESCAPE_CHAR2;
+
+    if (check_mkstemp_suffix(p) || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(p, PEM_TAG)
+        || NM_STR_HAS_SUFFIX_ASCII_CASE_WITH_MORE(p, DER_TAG))
+        nm_str_buf_append_c(&str, ESCAPE_CHAR2);
+
+    if (with_extension)
+        nm_str_buf_append(&str, NM_KEYFILE_PATH_SUFFIX_NMCONNECTION);
+
+    p = nm_str_buf_finalize(&str, NULL);
+
+    /* nm_keyfile_utils_create_filename() must mirror ignore_filename() */
+    nm_assert(!strchr(p, '/'));
+    nm_assert(!nm_keyfile_utils_ignore_filename(p, with_extension));
+
+    return p;
 }
 
 /*****************************************************************************/
@@ -4368,14 +4195,13 @@ nm_keyfile_utils_create_filename (const char *name,
  * after calling this function on it.
  */
 void
-nm_keyfile_handler_data_fail_with_error (NMKeyfileHandlerData *handler_data,
-                                         GError *src)
+nm_keyfile_handler_data_fail_with_error(NMKeyfileHandlerData *handler_data, GError *src)
 {
-	g_return_if_fail (handler_data);
-	g_return_if_fail (handler_data->p_error && !*handler_data->p_error);
-	g_return_if_fail (src);
+    g_return_if_fail(handler_data);
+    g_return_if_fail(handler_data->p_error && !*handler_data->p_error);
+    g_return_if_fail(src);
 
-	*handler_data->p_error = src;
+    *handler_data->p_error = src;
 }
 
 /**
@@ -4393,36 +4219,37 @@ nm_keyfile_handler_data_fail_with_error (NMKeyfileHandlerData *handler_data,
  * on all events, but the context information may be unset.
  */
 void
-nm_keyfile_handler_data_get_context (const NMKeyfileHandlerData *handler_data,
-                                     const char **out_kf_group_name,
-                                     const char **out_kf_key_name,
-                                     NMSetting **out_cur_setting,
-                                     const char **out_cur_property_name)
+nm_keyfile_handler_data_get_context(const NMKeyfileHandlerData *handler_data,
+                                    const char **               out_kf_group_name,
+                                    const char **               out_kf_key_name,
+                                    NMSetting **                out_cur_setting,
+                                    const char **               out_cur_property_name)
 {
-	g_return_if_fail (handler_data);
+    g_return_if_fail(handler_data);
 
-	NM_SET_OUT (out_kf_group_name, handler_data->kf_group_name);
-	NM_SET_OUT (out_kf_key_name, handler_data->kf_key);
-	NM_SET_OUT (out_cur_setting, handler_data->cur_setting);
-	NM_SET_OUT (out_cur_property_name, handler_data->cur_property);
+    NM_SET_OUT(out_kf_group_name, handler_data->kf_group_name);
+    NM_SET_OUT(out_kf_key_name, handler_data->kf_key);
+    NM_SET_OUT(out_cur_setting, handler_data->cur_setting);
+    NM_SET_OUT(out_cur_property_name, handler_data->cur_property);
 }
 
 const char *
-_nm_keyfile_handler_data_warn_get_message (const NMKeyfileHandlerData *handler_data)
+_nm_keyfile_handler_data_warn_get_message(const NMKeyfileHandlerData *handler_data)
 {
-	nm_assert (handler_data);
-	nm_assert (handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
-
-	if (!handler_data->warn.message) {
-		/* we cast the const away. @handler_data is const w.r.t. visible mutations
-		 * from POV of the user. Internally, we construct the message in
-		 * a lazy manner. It's like a mutable field in C++. */
-		NM_PRAGMA_WARNING_DISABLE ("-Wformat-nonliteral")
-		((NMKeyfileHandlerData *) handler_data)->warn.message = g_strdup_vprintf (handler_data->warn.fmt,
-		                                                                          ((NMKeyfileHandlerData *) handler_data)->warn.ap);
-		NM_PRAGMA_WARNING_REENABLE
-	}
-	return handler_data->warn.message;
+    nm_assert(handler_data);
+    nm_assert(handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
+
+    if (!handler_data->warn.message) {
+        /* we cast the const away. @handler_data is const w.r.t. visible mutations
+         * from POV of the user. Internally, we construct the message in
+         * a lazy manner. It's like a mutable field in C++. */
+        NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral")
+        ((NMKeyfileHandlerData *) handler_data)->warn.message =
+            g_strdup_vprintf(handler_data->warn.fmt,
+                             ((NMKeyfileHandlerData *) handler_data)->warn.ap);
+        NM_PRAGMA_WARNING_REENABLE
+    }
+    return handler_data->warn.message;
 }
 
 /**
@@ -4433,13 +4260,13 @@ _nm_keyfile_handler_data_warn_get_message (const NMKeyfileHandlerData *handler_d
  * @out_severity: (out) (allow-none): the #NMKeyfileWarnSeverity warning severity.
  */
 void
-nm_keyfile_handler_data_warn_get (const NMKeyfileHandlerData *handler_data,
-                                  const char **out_message,
-                                  NMKeyfileWarnSeverity *out_severity)
+nm_keyfile_handler_data_warn_get(const NMKeyfileHandlerData *handler_data,
+                                 const char **               out_message,
+                                 NMKeyfileWarnSeverity *     out_severity)
 {
-	g_return_if_fail (handler_data);
-	g_return_if_fail (handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
+    g_return_if_fail(handler_data);
+    g_return_if_fail(handler_data->type == NM_KEYFILE_HANDLER_TYPE_WARN);
 
-	NM_SET_OUT (out_message, _nm_keyfile_handler_data_warn_get_message (handler_data));
-	NM_SET_OUT (out_severity, handler_data->warn.severity);
+    NM_SET_OUT(out_message, _nm_keyfile_handler_data_warn_get_message(handler_data));
+    NM_SET_OUT(out_severity, handler_data->warn.severity);
 }