summary refs log tree commit diff
path: root/src/settings/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins')
-rw-r--r--src/settings/plugins/ifcfg-rh/meson.build37
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h20
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c19
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h19
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c609
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h18
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c18
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h18
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c20
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h20
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c47
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h18
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c41
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.h30
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/meson.build5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp9
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c73
-rw-r--r--src/settings/plugins/ifupdown/meson.build29
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c21
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h21
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-parser.c21
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-parser.h21
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-plugin.c23
-rw-r--r--src/settings/plugins/ifupdown/nms-ifupdown-plugin.h21
-rw-r--r--src/settings/plugins/ifupdown/tests/meson.build3
-rw-r--r--src/settings/plugins/ifupdown/tests/test-ifupdown.c105
-rw-r--r--src/settings/plugins/ifupdown/tests/test22-duplicate-stanzas8
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-plugin.c55
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-plugin.h18
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-reader.c18
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-reader.h18
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-storage.c18
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-storage.h18
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-utils.c52
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-utils.h32
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-writer.c33
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-writer.h18
-rw-r--r--src/settings/plugins/keyfile/tests/meson.build3
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile-settings.c20
41 files changed, 608 insertions, 994 deletions
diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build
index 58acdcfc..d9dd3edb 100644
--- a/src/settings/plugins/ifcfg-rh/meson.build
+++ b/src/settings/plugins/ifcfg-rh/meson.build
@@ -25,23 +25,24 @@ core_sources = files(
   'shvar.c',
 )
 
-deps = [
-  nm_dep,
-]
-
 libnms_ifcfg_rh_core = static_library(
   'nms-ifcfg-rh-core',
   sources: core_sources,
-  dependencies: deps,
+  dependencies: daemon_nm_default_dep,
+  c_args: daemon_c_flags,
 )
 
-sources = [dbus_sources] + core_sources + files('nms-ifcfg-rh-storage.c', 'nms-ifcfg-rh-plugin.c')
+sources = [dbus_sources] + core_sources + files(
+  'nms-ifcfg-rh-storage.c',
+  'nms-ifcfg-rh-plugin.c',
+)
 
 libnm_settings_plugin_ifcfg_rh = shared_module(
   'nm-settings-plugin-ifcfg-rh',
   sources: sources,
-  dependencies: deps,
-  link_with: [libnms_ifcfg_rh_core],
+  dependencies: daemon_nm_default_dep,
+  c_args: daemon_c_flags,
+  link_with: libnms_ifcfg_rh_core,
   link_args: ldflags_linker_script_settings,
   link_depends: linker_script_settings,
   install: true,
@@ -50,27 +51,17 @@ libnm_settings_plugin_ifcfg_rh = shared_module(
 
 core_plugins += libnm_settings_plugin_ifcfg_rh
 
-# FIXME: check_so_symbols replacement
-'''
-run_target(
-  'check-local-symbols-settings-ifcfg-rh',
-  command: [check_so_symbols, libnm_settings_plugin_ifcfg_rh.full_path()],
-  depends: libnm_settings_plugin_ifcfg_rh,
-)
-
-check-local-symbols-settings-ifcfg-rh: src/settings/plugins/ifcfg-rh/libnm-settings-plugin-ifcfg-rh.la
-  $(call check_so_symbols,$(builddir)/src/settings/plugins/ifcfg-rh/.libs/libnm-settings-plugin-ifcfg-rh.so)
-'''
+data = [
+  'nm-ifdown',
+  'nm-ifup',
+]
 
 install_data(
-  ['nm-ifup', 'nm-ifdown'],
+  data,
   install_dir: nm_libexecdir,
   install_mode: 'rwxr-xr-x',
 )
 
-meson.add_install_script('sh', '-c',
-                         'mkdir -p $DESTDIR/@0@/sysconfig/network-scripts'.format(nm_sysconfdir))
-
 if enable_tests
   subdir('tests')
 endif
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h
index ff01fc7a..6a01a5ac 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-common.h
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 - 2013 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2008 - 2013 Red Hat, Inc.
  */
 
 #ifndef __COMMON_H__
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
index cc4fe4ce..f57ca1a7 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c
@@ -1,22 +1,7 @@
-/* NetworkManager system settings service
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Dan Williams <dcbw@redhat.com>
  * Søren Sandmann <sandmann@daimi.au.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  * Copyright (C) 2007 - 2011 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h
index 1db36083..14cadac6 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.h
@@ -1,22 +1,7 @@
-/* NetworkManager system settings service
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Dan Williams <dcbw@redhat.com>
  * Søren Sandmann <sandmann@daimi.au.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  * Copyright (C) 2007 - 2008 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 68ebd781..a1d3236e 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2008 - 2017 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2008 - 2017 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -29,6 +15,7 @@
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
+#include <linux/rtnetlink.h>
 
 #include "nm-glib-aux/nm-secret-utils.h"
 #include "nm-connection.h"
@@ -753,25 +740,36 @@ parse_route_line_is_comment (const char *line)
 
 /*****************************************************************************/
 
+typedef enum {
+	PARSE_LINE_AF_FLAG_FOR_IPV4 = 0x01,
+	PARSE_LINE_AF_FLAG_FOR_IPV6 = 0x02,
+} ParseLineAFFlag;
+
 typedef struct {
 	const char *key;
 
 	/* the element is not available in this case. */
-	bool disabled:1;
+	ParseLineAFFlag disabled:3;
+
+	bool disabled_with_options_route:1;
 
 	/* whether the element is to be ignored. Ignord is different from
 	 * "disabled", because we still parse the option, but don't use it. */
-	bool ignore:1;
+	ParseLineAFFlag ignore:3;
 
 	bool int_base_16:1;
 
+	/* the type, one of PARSE_LINE_TYPE_* */
+	char type;
+
+} ParseLineInfo;
+
+typedef struct {
+
 	/* whether the command line option was found, and @v is
 	 * initialized. */
 	bool has:1;
 
-	/* the type, one of PARSE_LINE_TYPE_* */
-	char type;
-
 	union {
 		guint8 uint8;
 		guint32 uint32;
@@ -786,7 +784,7 @@ typedef struct {
 		} addr;
 	} v;
 
-} ParseLineInfo;
+} ParseLineData;
 
 enum {
 	/* route attributes */
@@ -794,6 +792,7 @@ enum {
 	PARSE_LINE_ATTR_ROUTE_SRC,
 	PARSE_LINE_ATTR_ROUTE_FROM,
 	PARSE_LINE_ATTR_ROUTE_TOS,
+	PARSE_LINE_ATTR_ROUTE_SCOPE,
 	PARSE_LINE_ATTR_ROUTE_ONLINK,
 	PARSE_LINE_ATTR_ROUTE_WINDOW,
 	PARSE_LINE_ATTR_ROUTE_CWND,
@@ -817,6 +816,7 @@ enum {
 #define PARSE_LINE_TYPE_ADDR_WITH_PREFIX  'p'
 #define PARSE_LINE_TYPE_IFNAME            'i'
 #define PARSE_LINE_TYPE_FLAG              'f'
+#define PARSE_LINE_TYPE_ROUTE_SCOPE       'S'
 
 /**
  * parse_route_line:
@@ -847,29 +847,23 @@ parse_route_line (const char *line,
                   NMIPRoute **out_route,
                   GError **error)
 {
-	nm_auto_unref_ip_route NMIPRoute *route = NULL;
-	gs_free const char **words_free = NULL;
-	const char *const*words;
-	const char *s;
-	gsize i_words;
-	guint i;
-	char buf1[256];
-	char buf2[256];
-	ParseLineInfo infos[] = {
+	static const ParseLineInfo parse_infos[] = {
 		[PARSE_LINE_ATTR_ROUTE_TABLE]     = { .key = NM_IP_ROUTE_ATTRIBUTE_TABLE,
 		                                      .type = PARSE_LINE_TYPE_UINT32, },
 		[PARSE_LINE_ATTR_ROUTE_SRC]       = { .key = NM_IP_ROUTE_ATTRIBUTE_SRC,
 		                                      .type = PARSE_LINE_TYPE_ADDR, },
 		[PARSE_LINE_ATTR_ROUTE_FROM]      = { .key = NM_IP_ROUTE_ATTRIBUTE_FROM,
 		                                      .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
-		                                      .disabled = (addr_family != AF_INET6), },
+		                                      .disabled = PARSE_LINE_AF_FLAG_FOR_IPV4, },
 		[PARSE_LINE_ATTR_ROUTE_TOS]       = { .key = NM_IP_ROUTE_ATTRIBUTE_TOS,
 		                                      .type = PARSE_LINE_TYPE_UINT8,
 		                                      .int_base_16 = TRUE,
-		                                      .ignore = (addr_family != AF_INET), },
+		                                      .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, },
+		[PARSE_LINE_ATTR_ROUTE_SCOPE]     = { .key = NM_IP_ROUTE_ATTRIBUTE_SCOPE,
+		                                      .type = PARSE_LINE_TYPE_ROUTE_SCOPE,
+		                                      .ignore = PARSE_LINE_AF_FLAG_FOR_IPV6, },
 		[PARSE_LINE_ATTR_ROUTE_ONLINK]    = { .key = NM_IP_ROUTE_ATTRIBUTE_ONLINK,
-		                                      .type = PARSE_LINE_TYPE_FLAG,
-		                                      .ignore = (addr_family != AF_INET), },
+		                                      .type = PARSE_LINE_TYPE_FLAG, },
 		[PARSE_LINE_ATTR_ROUTE_WINDOW]    = { .key = NM_IP_ROUTE_ATTRIBUTE_WINDOW,
 		                                      .type = PARSE_LINE_TYPE_UINT32_WITH_LOCK, },
 		[PARSE_LINE_ATTR_ROUTE_CWND]      = { .key = NM_IP_ROUTE_ATTRIBUTE_CWND,
@@ -883,19 +877,31 @@ parse_route_line (const char *line,
 
 		[PARSE_LINE_ATTR_ROUTE_TO]        = { .key = "to",
 		                                      .type = PARSE_LINE_TYPE_ADDR_WITH_PREFIX,
-		                                      .disabled = (options_route != NULL), },
+		                                      .disabled_with_options_route = TRUE, },
 		[PARSE_LINE_ATTR_ROUTE_VIA]       = { .key = "via",
 		                                      .type = PARSE_LINE_TYPE_ADDR,
-		                                      .disabled = (options_route != NULL), },
+		                                      .disabled_with_options_route = TRUE, },
 		[PARSE_LINE_ATTR_ROUTE_METRIC]    = { .key = "metric",
 		                                      .type = PARSE_LINE_TYPE_UINT32,
-		                                      .disabled = (options_route != NULL), },
+		                                      .disabled_with_options_route = TRUE, },
 
 		[PARSE_LINE_ATTR_ROUTE_DEV]       = { .key = "dev",
 		                                      .type = PARSE_LINE_TYPE_IFNAME,
-		                                      .ignore = TRUE,
-		                                      .disabled = (options_route != NULL), },
+		                                      .ignore = PARSE_LINE_AF_FLAG_FOR_IPV4 | PARSE_LINE_AF_FLAG_FOR_IPV6,
+		                                      .disabled_with_options_route = TRUE, },
 	};
+	nm_auto_unref_ip_route NMIPRoute *route = NULL;
+	gs_free const char **words_free = NULL;
+	const char *const*words;
+	const char *s;
+	gsize i_words;
+	guint i;
+	char buf1[256];
+	char buf2[256];
+	ParseLineData parse_datas[G_N_ELEMENTS (parse_infos)] = { };
+	const ParseLineAFFlag af_flag =   (addr_family == AF_INET)
+	                                ? PARSE_LINE_AF_FLAG_FOR_IPV4
+	                                : PARSE_LINE_AF_FLAG_FOR_IPV6;
 
 	nm_assert (line);
 	nm_assert_addr_family (addr_family);
@@ -923,19 +929,22 @@ parse_route_line (const char *line,
 	for (i_words = 0; words[i_words]; ) {
 		const gsize i_words0 = i_words;
 		const char *const w = words[i_words0];
-		ParseLineInfo *info;
+		const ParseLineInfo *p_info;
+		ParseLineData *p_data;
 		gboolean unqualified_addr = FALSE;
 
-		for (i = 0; i < G_N_ELEMENTS (infos); i++) {
-			info = &infos[i];
+		for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) {
+			p_info = &parse_infos[i];
+			p_data = &parse_datas[i];
 
-			if (info->disabled)
+			if (   (p_info->disabled & af_flag)
+			    || (p_info->disabled_with_options_route && options_route))
 				continue;
 
-			if (!nm_streq (w, info->key))
+			if (!nm_streq (w, p_info->key))
 				continue;
 
-			if (info->has) {
+			if (p_data->has) {
 				/* iproute2 for most arguments allows specifying them multiple times.
 				 * Let's not do that. */
 				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
@@ -943,8 +952,8 @@ parse_route_line (const char *line,
 				return -EINVAL;
 			}
 
-			info->has = TRUE;
-			switch (info->type) {
+			p_data->has = TRUE;
+			switch (p_info->type) {
 			case PARSE_LINE_TYPE_UINT8:
 				i_words++;
 				goto parse_line_type_uint8;
@@ -966,16 +975,22 @@ parse_route_line (const char *line,
 			case PARSE_LINE_TYPE_FLAG:
 				i_words++;
 				goto next;
+			case PARSE_LINE_TYPE_ROUTE_SCOPE:
+				i_words++;
+				goto parse_line_type_route_scope;
 			default:
 				nm_assert_not_reached ();
 			}
 		}
 
 		/* "to" is also accepted unqualified... (once) */
-		info = &infos[PARSE_LINE_ATTR_ROUTE_TO];
-		if (!info->has && !info->disabled) {
+		p_info = &parse_infos[PARSE_LINE_ATTR_ROUTE_TO];
+		p_data = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO];
+		if (   !p_data->has
+		    && !(p_info->disabled & af_flag)
+		    && !(p_info->disabled_with_options_route && options_route)) {
 			unqualified_addr = TRUE;
-			info->has = TRUE;
+			p_data->has = TRUE;
 			goto parse_line_type_addr;
 		}
 
@@ -983,15 +998,44 @@ parse_route_line (const char *line,
 		             "Unrecognized argument (\"to\" is duplicate or \"%s\" is garbage)", w);
 		return -EINVAL;
 
+parse_line_type_route_scope:
+		s = words[i_words];
+		if (!s)
+			goto err_word_missing_argument;
+		if (nm_streq (s, "global"))
+			p_data->v.uint8 = RT_SCOPE_UNIVERSE;
+		else if (nm_streq (s, "nowhere"))
+			p_data->v.uint8 = RT_SCOPE_NOWHERE;
+		else if (nm_streq (s, "host"))
+			p_data->v.uint8 = RT_SCOPE_HOST;
+		else if (nm_streq (s, "link"))
+			p_data->v.uint8 = RT_SCOPE_LINK;
+		else if (nm_streq (s, "site"))
+			p_data->v.uint8 = RT_SCOPE_SITE;
+		else {
+			p_data->v.uint8 = _nm_utils_ascii_str_to_int64 (s,
+			                                                0,
+			                                                0,
+			                                                G_MAXUINT8,
+			                                                0);;
+			if (errno) {
+				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+				             "Argument for \"%s\" is not a valid number", w);
+				return -EINVAL;
+			}
+		}
+		i_words++;
+		goto next;
+
 parse_line_type_uint8:
 		s = words[i_words];
 		if (!s)
 			goto err_word_missing_argument;
-		info->v.uint8 = _nm_utils_ascii_str_to_int64 (s,
-		                                              info->int_base_16 ? 16 : 10,
-		                                              0,
-		                                              G_MAXUINT8,
-		                                              0);;
+		p_data->v.uint8 = _nm_utils_ascii_str_to_int64 (s,
+		                                                p_info->int_base_16 ? 16 : 10,
+		                                                0,
+		                                                G_MAXUINT8,
+		                                                0);;
 		if (errno) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 			             "Argument for \"%s\" is not a valid number", w);
@@ -1005,17 +1049,17 @@ parse_line_type_uint32_with_lock:
 		s = words[i_words];
 		if (!s)
 			goto err_word_missing_argument;
-		if (info->type == PARSE_LINE_TYPE_UINT32_WITH_LOCK) {
+		if (p_info->type == PARSE_LINE_TYPE_UINT32_WITH_LOCK) {
 			if (nm_streq (s, "lock")) {
 				s = words[++i_words];
 				if (!s)
 					goto err_word_missing_argument;
-				info->v.uint32_with_lock.lock = TRUE;
+				p_data->v.uint32_with_lock.lock = TRUE;
 			} else
-				info->v.uint32_with_lock.lock = FALSE;
-			info->v.uint32_with_lock.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0);;
+				p_data->v.uint32_with_lock.lock = FALSE;
+			p_data->v.uint32_with_lock.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0);;
 		} else {
-			info->v.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0);
+			p_data->v.uint32 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXUINT32, 0);
 		}
 		if (errno) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
@@ -1040,16 +1084,16 @@ parse_line_type_addr_with_prefix:
 		{
 			int prefix = -1;
 
-			if (info->type == PARSE_LINE_TYPE_ADDR) {
+			if (p_info->type == PARSE_LINE_TYPE_ADDR) {
 				if (!nm_utils_parse_inaddr_bin (addr_family,
 				                                s,
 				                                NULL,
-				                                &info->v.addr.addr)) {
-					if (   info == &infos[PARSE_LINE_ATTR_ROUTE_VIA]
+				                                &p_data->v.addr.addr)) {
+					if (   p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_VIA]
 					    && nm_streq (s, "(null)")) {
 						/* Due to a bug, would older versions of NM write "via (null)"
 						 * (rh#1452648). Workaround that, and accept it.*/
-						memset (&info->v.addr.addr, 0, sizeof (info->v.addr.addr));
+						memset (&p_data->v.addr.addr, 0, sizeof (p_data->v.addr.addr));
 					} else {
 						if (unqualified_addr) {
 							g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
@@ -1064,15 +1108,15 @@ parse_line_type_addr_with_prefix:
 					}
 				}
 			} else {
-				nm_assert (info->type == PARSE_LINE_TYPE_ADDR_WITH_PREFIX);
-				if (   info == &infos[PARSE_LINE_ATTR_ROUTE_TO]
+				nm_assert (p_info->type == PARSE_LINE_TYPE_ADDR_WITH_PREFIX);
+				if (   p_info == &parse_infos[PARSE_LINE_ATTR_ROUTE_TO]
 				    && nm_streq (s, "default")) {
-					memset (&info->v.addr.addr, 0, sizeof (info->v.addr.addr));
+					memset (&p_data->v.addr.addr, 0, sizeof (p_data->v.addr.addr));
 					prefix = 0;
 				} else if (!nm_utils_parse_inaddr_prefix_bin (addr_family,
 				                                              s,
 				                                              NULL,
-				                                              &info->v.addr.addr,
+				                                              &p_data->v.addr.addr,
 				                                              &prefix)) {
 					g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 					             "Argument for \"%s\" is not ADDR/PREFIX format", w);
@@ -1080,10 +1124,10 @@ parse_line_type_addr_with_prefix:
 				}
 			}
 			if (prefix == -1)
-				info->v.addr.has_plen = FALSE;
+				p_data->v.addr.has_plen = FALSE;
 			else {
-				info->v.addr.has_plen = TRUE;
-				info->v.addr.plen = prefix;
+				p_data->v.addr.has_plen = TRUE;
+				p_data->v.addr.plen = prefix;
 			}
 		}
 		i_words++;
@@ -1101,79 +1145,76 @@ next:
 		route = options_route;
 		nm_ip_route_ref (route);
 	} else {
-		ParseLineInfo *info_to = &infos[PARSE_LINE_ATTR_ROUTE_TO];
-		ParseLineInfo *info_via = &infos[PARSE_LINE_ATTR_ROUTE_VIA];
-		ParseLineInfo *info_metric = &infos[PARSE_LINE_ATTR_ROUTE_METRIC];
+		ParseLineData *data_to     = &parse_datas[PARSE_LINE_ATTR_ROUTE_TO];
+		ParseLineData *data_via    = &parse_datas[PARSE_LINE_ATTR_ROUTE_VIA];
+		ParseLineData *data_metric = &parse_datas[PARSE_LINE_ATTR_ROUTE_METRIC];
 		guint prefix;
 
-		if (!info_to->has) {
+		if (!data_to->has) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 			             "Missing destination prefix");
 			return -EINVAL;
 		}
 
-		prefix =   info_to->v.addr.has_plen
-		         ? info_to->v.addr.plen
+		prefix =   data_to->v.addr.has_plen
+		         ? data_to->v.addr.plen
 		         : (addr_family == AF_INET ? 32 : 128);
 
-		if (   (   (addr_family == AF_INET  && !info_to->v.addr.addr.addr4)
-		        || (addr_family == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED (&info_to->v.addr.addr.addr6)))
-		    && prefix == 0) {
-			/* we ignore default routes by returning -ERANGE. */
-			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "Ignore manual default route");
-			return -ERANGE;
-		}
-
 		route = nm_ip_route_new_binary (addr_family,
-		                                &info_to->v.addr.addr,
+		                                &data_to->v.addr.addr,
 		                                prefix,
-		                                info_via->has ? &info_via->v.addr.addr : NULL,
-		                                info_metric->has ? (gint64) info_metric->v.uint32 : (gint64) -1,
+		                                data_via->has ? &data_via->v.addr.addr : NULL,
+		                                data_metric->has ? (gint64) data_metric->v.uint32 : (gint64) -1,
 		                                error);
-		info_to->has = FALSE;
-		info_via->has = FALSE;
-		info_metric->has = FALSE;
+		data_to->has = FALSE;
+		data_via->has = FALSE;
+		data_metric->has = FALSE;
 		if (!route)
 			return -EINVAL;
 	}
 
-	for (i = 0; i < G_N_ELEMENTS (infos); i++) {
-		ParseLineInfo *info = &infos[i];
+	for (i = 0; i < G_N_ELEMENTS (parse_infos); i++) {
+		const ParseLineInfo *p_info = &parse_infos[i];
+		ParseLineData *p_data = &parse_datas[i];
 
-		if (!info->has)
+		if (!p_data->has)
 			continue;
-		if (info->ignore || info->disabled)
+
+		if (   (p_info->ignore & af_flag)
+		    || (p_info->disabled & af_flag)
+		    || (p_info->disabled_with_options_route && options_route))
 			continue;
-		switch (info->type) {
+
+		switch (p_info->type) {
 		case PARSE_LINE_TYPE_UINT8:
+		case PARSE_LINE_TYPE_ROUTE_SCOPE:
 			nm_ip_route_set_attribute (route,
-			                           info->key,
-			                           g_variant_new_byte (info->v.uint8));
+			                           p_info->key,
+			                           g_variant_new_byte (p_data->v.uint8));
 			break;
 		case PARSE_LINE_TYPE_UINT32:
 			nm_ip_route_set_attribute (route,
-			                           info->key,
-			                           g_variant_new_uint32 (info->v.uint32));
+			                           p_info->key,
+			                           g_variant_new_uint32 (p_data->v.uint32));
 			break;
 		case PARSE_LINE_TYPE_UINT32_WITH_LOCK:
-			if (info->v.uint32_with_lock.lock) {
+			if (p_data->v.uint32_with_lock.lock) {
 				nm_ip_route_set_attribute (route,
-				                           nm_sprintf_buf (buf1, "lock-%s", info->key),
+				                           nm_sprintf_buf (buf1, "lock-%s", p_info->key),
 				                           g_variant_new_boolean (TRUE));
 			}
 			nm_ip_route_set_attribute (route,
-			                           info->key,
-			                           g_variant_new_uint32 (info->v.uint32_with_lock.uint32));
+			                           p_info->key,
+			                           g_variant_new_uint32 (p_data->v.uint32_with_lock.uint32));
 			break;
 		case PARSE_LINE_TYPE_ADDR:
 		case PARSE_LINE_TYPE_ADDR_WITH_PREFIX:
 			nm_ip_route_set_attribute (route,
-			                           info->key,
+			                           p_info->key,
 			                           g_variant_new_printf ("%s%s",
-			                                                 inet_ntop (addr_family, &info->v.addr.addr, buf1, sizeof (buf1)),
-			                                                 info->v.addr.has_plen
-			                                                    ? nm_sprintf_buf (buf2, "/%u", (unsigned) info->v.addr.plen)
+			                                                 inet_ntop (addr_family, &p_data->v.addr.addr, buf1, sizeof (buf1)),
+			                                                 p_data->v.addr.has_plen
+			                                                    ? nm_sprintf_buf (buf2, "/%u", (unsigned) p_data->v.addr.plen)
 			                                                    : ""));
 			break;
 		case PARSE_LINE_TYPE_FLAG:
@@ -1182,7 +1223,7 @@ next:
 			 * of this attribute, hence, the file format cannot encode
 			 * that configuration. */
 			nm_ip_route_set_attribute (route,
-			                           info->key,
+			                           p_info->key,
 			                           g_variant_new_boolean (TRUE));
 			break;
 		default:
@@ -1244,7 +1285,7 @@ read_one_ip4_route (shvarFile *ifcfg,
 		return FALSE;
 	if (has_key) {
 		prefix = nm_utils_ip4_netmask_to_prefix (netmask);
-		if (prefix == 0 || netmask != _nm_utils_ip4_prefix_to_netmask (prefix)) {
+		if (netmask != _nm_utils_ip4_prefix_to_netmask (prefix)) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 			             "Invalid IP4 netmask '%s' \"%s\"", netmask_tag, nm_utils_inet4_ntop (netmask, inet_buf));
 			return FALSE;
@@ -1538,7 +1579,7 @@ make_ip4_setting (shvarFile *ifcfg,
 	gboolean has_key;
 	shvarFile *route_ifcfg;
 	gboolean never_default;
-	gint64 timeout;
+	gint64 i64;
 	int priority;
 	const char *const *item;
 	guint32 route_table;
@@ -1641,6 +1682,14 @@ make_ip4_setting (shvarFile *ifcfg,
 		              NULL);
 	}
 
+	i64 = svGetValueInt64 (ifcfg, "DHCP_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1);
+	if (i64 > -1) {
+		g_object_set (s_ip4,
+		              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS,
+		              (guint) i64,
+		              NULL);
+	}
+
 	g_object_set (s_ip4,
 	              NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svGetValueBoolean (ifcfg, "DHCP_SEND_HOSTNAME", TRUE),
 	              NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, svGetValueInt64 (ifcfg, "IPV4_DHCP_TIMEOUT", 10, 0, G_MAXINT32, 0),
@@ -1651,6 +1700,11 @@ make_ip4_setting (shvarFile *ifcfg,
 	if (v)
 		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, v, NULL);
 
+	nm_clear_g_free (&value);
+	v = svGetValueStr (ifcfg, "DHCP_IAID", &value);
+	if (v)
+		g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL);
+
 	/* Read static IP addresses.
 	 * Read them even for AUTO method - in this case the addresses are
 	 * added to the automatic ones. Note that this is not currently supported by
@@ -1806,14 +1860,14 @@ make_ip4_setting (shvarFile *ifcfg,
 		}
 	}
 
-	timeout = svGetValueInt64 (ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2);
-	if (timeout == -2) {
-		timeout = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1,
-		                           NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1);
-		if (timeout > 0)
-			timeout *= 1000;
+	i64 = svGetValueInt64 (ifcfg, "ACD_TIMEOUT", 10, -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -2);
+	if (i64 == -2) {
+		i64 = svGetValueInt64 (ifcfg, "ARPING_WAIT", 10, -1,
+		                       NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX / 1000, -1);
+		if (i64 > 0)
+			i64 *= 1000;
 	}
-	g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) timeout, NULL);
+	g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) i64, NULL);
 
 	return NM_SETTING (g_steal_pointer (&s_ip4));
 }
@@ -1947,6 +2001,7 @@ make_ip6_setting (shvarFile *ifcfg,
 	gs_free const char **list = NULL;
 	const char *const *iter;
 	guint32 i;
+	gint64 i64;
 	int i_val;
 	GError *local = NULL;
 	int priority;
@@ -2085,6 +2140,11 @@ make_ip6_setting (shvarFile *ifcfg,
 		g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_DHCP_DUID, v, NULL);
 
 	nm_clear_g_free (&value);
+	v = svGetValueStr (ifcfg, "DHCPV6_IAID", &value);
+	if (v)
+		g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_IAID, v, NULL);
+
+	nm_clear_g_free (&value);
 	v = svGetValueStr (ifcfg, "DHCPV6_HOSTNAME", &value);
 	/* Use DHCP_HOSTNAME as fallback if it is in FQDN format and ipv6.method is
 	 * auto or dhcp: this is required to support old ifcfg files
@@ -2102,6 +2162,15 @@ make_ip6_setting (shvarFile *ifcfg,
 	g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME,
 	              svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), NULL);
 
+
+	i64 = svGetValueInt64 (ifcfg, "DHCPV6_HOSTNAME_FLAGS", 10, 0, G_MAXUINT32, -1);
+	if (i64 > -1) {
+		g_object_set (s_ip6,
+		              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS,
+		              (guint) i64,
+		              NULL);
+	}
+
 	/* Read static IP addresses.
 	 * Read them even for AUTO and DHCP methods - in this case the addresses are
 	 * added to the automatic ones. Note that this is not currently supported by
@@ -2762,7 +2831,7 @@ add_one_wep_key (shvarFile *ifcfg,
 			/* Hexadecimal WEP key */
 			if (NM_STRCHAR_ANY (value, ch, !g_ascii_isxdigit (ch))) {
 				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-				             "Invalid hexadecimal WEP key.");
+				             "Invalid hexadecimal WEP key");
 				return FALSE;
 			}
 			key = value;
@@ -2771,7 +2840,7 @@ add_one_wep_key (shvarFile *ifcfg,
 			/* ASCII key */
 			if (NM_STRCHAR_ANY (value + 2, ch, !g_ascii_isprint (ch))) {
 				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-				             "Invalid ASCII WEP key.");
+				             "Invalid ASCII WEP key");
 				return FALSE;
 			}
 
@@ -2787,7 +2856,7 @@ add_one_wep_key (shvarFile *ifcfg,
 
 	if (!key) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Invalid WEP key length.");
+		             "Invalid WEP key length");
 		return FALSE;
 	}
 
@@ -2934,7 +3003,7 @@ make_wep_setting (shvarFile *ifcfg,
 		if (auth_alg && !strcmp (auth_alg, "shared")) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
 			             "WEP Shared Key authentication is invalid for "
-			             "unencrypted connections.");
+			             "unencrypted connections");
 			return NULL;
 		}
 
@@ -2963,22 +3032,6 @@ fill_wpa_ciphers (shvarFile *ifcfg,
 
 	list = nm_utils_strsplit_set (p, " ");
 	for (iter = list; iter && *iter; iter++, i++) {
-		/* Ad-Hoc configurations cannot have pairwise ciphers, and can only
-		 * have one group cipher.  Ignore any additional group ciphers and
-		 * any pairwise ciphers specified.
-		 */
-		if (adhoc) {
-			if (group && (i > 0)) {
-				PARSE_WARNING ("ignoring group cipher '%s' (only one group cipher allowed "
-				               "in Ad-Hoc mode)", *iter);
-				continue;
-			} else if (!group) {
-				PARSE_WARNING ("ignoring pairwise cipher '%s' (pairwise not used "
-				               "in Ad-Hoc mode)", *iter);
-				continue;
-			}
-		}
-
 		if (!strcmp (*iter, "CCMP")) {
 			if (group)
 				nm_setting_wireless_security_add_group (wsec, "ccmp");
@@ -3184,6 +3237,89 @@ eap_tls_reader (const char *eap_method,
 }
 
 static gboolean
+parse_8021x_phase2_auth (shvarFile *ifcfg,
+                         shvarFile *keys_ifcfg,
+                         NMSetting8021x *s_8021x,
+                         GError **error)
+{
+	gs_free char *inner_auth = NULL;
+	gs_free char *v_free = NULL;
+	const char *v;
+	gs_free const char **list = NULL;
+	const char *const *iter;
+	guint num_auth = 0;
+	guint num_autheap = 0;
+
+	v = svGetValueStr (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", &v_free);
+	if (!v) {
+		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+		             "Missing IEEE_8021X_INNER_AUTH_METHODS");
+		return FALSE;
+	}
+
+	inner_auth = g_ascii_strdown (v, -1);
+	list = nm_utils_strsplit_set (inner_auth, " ");
+	for (iter = list; iter && *iter; iter++) {
+		if (NM_IN_STRSET (*iter, "pap",
+		                         "chap",
+		                         "mschap",
+		                         "mschapv2",
+		                         "gtc",
+		                         "otp",
+		                         "md5")) {
+			if (num_auth == 0) {
+				if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
+					return FALSE;
+				g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL);
+			}
+			num_auth++;
+		} else if (nm_streq (*iter, "tls")) {
+			if (num_auth == 0) {
+				if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
+					return FALSE;
+				g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL);
+			}
+			num_auth++;
+		} else if (NM_IN_STRSET (*iter, "eap-md5",
+		                                "eap-mschapv2",
+		                                "eap-otp",
+		                                "eap-gtc")) {
+			if (num_autheap == 0) {
+				if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
+					return FALSE;
+				g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + NM_STRLEN ("eap-")), NULL);
+			}
+			num_autheap++;
+		} else if (nm_streq (*iter, "eap-tls")) {
+			if (num_autheap == 0) {
+				if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
+					return FALSE;
+				g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL);
+			}
+			num_autheap++;
+		} else {
+			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+			             "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'",
+			             *iter);
+			return FALSE;
+		}
+	}
+
+	if (num_auth > 1)
+		PARSE_WARNING ("Discarded extra phase2 authentication methods");
+	if (num_auth > 1)
+		PARSE_WARNING ("Discarded extra phase2 EAP authentication methods");
+
+	if (!num_auth && !num_autheap) {
+		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+		             "No phase2 authentication method found");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
 eap_peap_reader (const char *eap_method,
                  shvarFile *ifcfg,
                  shvarFile *keys_ifcfg,
@@ -3193,8 +3329,6 @@ eap_peap_reader (const char *eap_method,
 {
 	gs_free char *value = NULL;
 	const char *v;
-	gs_free const char **list = NULL;
-	const char *const *iter;
 
 	if (!_cert_set_from_ifcfg (s_8021x,
 	                           ifcfg,
@@ -3232,46 +3366,8 @@ eap_peap_reader (const char *eap_method,
 	if (v)
 		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL);
 
-	nm_clear_g_free (&value);
-	v = svGetValueStr (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", &value);
-	if (!v) {
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Missing IEEE_8021X_INNER_AUTH_METHODS.");
-		return FALSE;
-	}
-
-	/* Handle options for the inner auth method */
-	list = nm_utils_strsplit_set (v, " ");
-	iter = list;
-	if (iter) {
-		if (NM_IN_STRSET (*iter, "MSCHAPV2",
-		                         "MD5",
-		                         "GTC")) {
-			if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				return FALSE;
-		} else if (nm_streq (*iter, "TLS")) {
-			if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				return FALSE;
-		} else {
-			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
-			             *iter);
-			return FALSE;
-		}
-
-		{
-			gs_free char *lower = NULL;
-
-			lower = g_ascii_strdown (*iter, -1);
-			g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL);
-		}
-	}
-
-	if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "No valid IEEE_8021X_INNER_AUTH_METHODS found.");
+	if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error))
 		return FALSE;
-	}
 
 	return TRUE;
 }
@@ -3284,11 +3380,8 @@ eap_ttls_reader (const char *eap_method,
                  gboolean phase2,
                  GError **error)
 {
-	gs_free char *inner_auth = NULL;
 	gs_free char *value = NULL;
 	const char *v;
-	gs_free const char **list = NULL;
-	const char *const *iter;
 
 	if (!_cert_set_from_ifcfg (s_8021x,
 	                           ifcfg,
@@ -3308,44 +3401,8 @@ eap_ttls_reader (const char *eap_method,
 	if (v)
 		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, v, NULL);
 
-	nm_clear_g_free (&value);
-	v = svGetValueStr (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", &value);
-	if (!v) {
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+	if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error))
 		return FALSE;
-	}
-
-	inner_auth = g_ascii_strdown (v, -1);
-
-	/* Handle options for the inner auth method */
-	list = nm_utils_strsplit_set (inner_auth, " ");
-	iter = list;
-	if (iter) {
-		if (NM_IN_STRSET (*iter, "mschapv2",
-		                         "mschap",
-		                         "pap",
-		                         "chap")) {
-			if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				return FALSE;
-			g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL);
-		} else if (nm_streq (*iter, "eap-tls")) {
-			if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				return FALSE;
-			g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL);
-		} else if (NM_IN_STRSET (*iter, "eap-mschapv2",
-		                                "eap-md5",
-		                                "eap-gtc")) {
-			if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				return FALSE;
-			g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + NM_STRLEN ("eap-")), NULL);
-		} else {
-			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
-			             *iter);
-			return FALSE;
-		}
-	}
 
 	return TRUE;
 }
@@ -3358,17 +3415,13 @@ eap_fast_reader (const char *eap_method,
                  gboolean phase2,
                  GError **error)
 {
-	char *anon_ident = NULL;
-	char *pac_file = NULL;
-	char *real_pac_path = NULL;
-	char *inner_auth = NULL;
-	char *fast_provisioning = NULL;
-	char *lower;
-	gs_free const char **list = NULL;
+	gs_free char *anon_ident = NULL;
+	gs_free char *pac_file = NULL;
+	gs_free char *real_pac_path = NULL;
+	gs_free char *fast_provisioning = NULL;
 	const char *const *iter;
 	const char *pac_prov_str;
 	gboolean allow_unauth = FALSE, allow_auth = FALSE;
-	gboolean success = FALSE;
 
 	pac_file = svGetValueStr_cp (ifcfg, "IEEE_8021X_PAC_FILE");
 	if (pac_file) {
@@ -3378,10 +3431,10 @@ eap_fast_reader (const char *eap_method,
 
 	fast_provisioning = svGetValueStr_cp (ifcfg, "IEEE_8021X_FAST_PROVISIONING");
 	if (fast_provisioning) {
-		gs_free const char **list1 = NULL;
+		gs_free const char **list = NULL;
 
-		list1 = nm_utils_strsplit_set (fast_provisioning, " \t");
-		for (iter = list1; iter && *iter; iter++) {
+		list = nm_utils_strsplit_set (fast_provisioning, " \t");
+		for (iter = list; iter && *iter; iter++) {
 			if (strcmp (*iter, "allow-unauth") == 0)
 				allow_unauth = TRUE;
 			else if (strcmp (*iter, "allow-auth") == 0)
@@ -3398,56 +3451,18 @@ eap_fast_reader (const char *eap_method,
 
 	if (!pac_file && !(allow_unauth || allow_auth)) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled.");
-		goto done;
+		             "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled");
+		return FALSE;
 	}
 
 	anon_ident = svGetValueStr_cp (ifcfg, "IEEE_8021X_ANON_IDENTITY");
 	if (anon_ident)
 		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
 
-	inner_auth = svGetValueStr_cp (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS");
-	if (!inner_auth) {
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Missing IEEE_8021X_INNER_AUTH_METHODS.");
-		goto done;
-	}
-
-	/* Handle options for the inner auth method */
-	list = nm_utils_strsplit_set (inner_auth, " ");
-	iter = list;
-	if (iter) {
-		if (   !strcmp (*iter, "MSCHAPV2")
-		    || !strcmp (*iter, "GTC")) {
-			if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error))
-				goto done;
-		} else {
-			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
-			             *iter);
-			goto done;
-		}
-
-		lower = g_ascii_strdown (*iter, -1);
-		g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL);
-		g_free (lower);
-	}
-
-	if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
-		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "No valid IEEE_8021X_INNER_AUTH_METHODS found.");
-		goto done;
-	}
-
-	success = TRUE;
+	if (!parse_8021x_phase2_auth (ifcfg, keys_ifcfg, s_8021x, error))
+		return FALSE;
 
-done:
-	g_free (inner_auth);
-	g_free (fast_provisioning);
-	g_free (real_pac_path);
-	g_free (pac_file);
-	g_free (anon_ident);
-	return success;
+	return TRUE;
 }
 
 typedef struct {
@@ -3546,7 +3561,7 @@ fill_8021x (shvarFile *ifcfg,
 			 * used with TTLS or PEAP or whatever.
 			 */
 			if (wifi && eap->wifi_phase2_only) {
-				PARSE_WARNING ("ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.",
+				PARSE_WARNING ("ignored invalid IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi",
 				               lower);
 				goto next;
 			}
@@ -3564,12 +3579,12 @@ next:
 		}
 
 		if (!found)
-			PARSE_WARNING ("ignored unknown IEEE_8021X_EAP_METHOD '%s'.", lower);
+			PARSE_WARNING ("ignored unknown IEEE_8021X_EAP_METHOD '%s'", lower);
 	}
 
 	if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "No valid EAP methods found in IEEE_8021X_EAP_METHODS.");
+		             "No valid EAP methods found in IEEE_8021X_EAP_METHODS");
 		return NULL;
 	}
 
@@ -3663,8 +3678,8 @@ make_wpa_setting (shvarFile *ifcfg,
 
 	/* WPA and/or RSN */
 	if (adhoc) {
-		/* Ad-Hoc mode only supports WPA proto for now */
-		nm_setting_wireless_security_add_proto (wsec, "wpa");
+		/* Ad-Hoc mode only supports RSN proto */
+		nm_setting_wireless_security_add_proto (wsec, "rsn");
 	} else {
 		gs_free char *value2 = NULL;
 		const char *v2;
@@ -3698,9 +3713,7 @@ make_wpa_setting (shvarFile *ifcfg,
 			}
 		}
 
-		if (adhoc)
-			g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
-		else if (wpa_psk)
+		if (wpa_psk)
 			g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
 		else {
 			nm_assert (wpa_sae);
@@ -4145,7 +4158,7 @@ wireless_connection_from_ifcfg (const char *file,
 
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -4664,7 +4677,7 @@ make_wired_setting (shvarFile *ifcfg,
 		g_set_error (error,
 		             NM_UTILS_ERROR,
 		             NM_UTILS_ERROR_SETTING_MISSING,
-		             "The setting is missing.");
+		             "The setting is missing");
 		return NULL;
 	}
 
@@ -4690,7 +4703,7 @@ wired_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL);
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -4768,7 +4781,7 @@ parse_infiniband_p_key (shvarFile *ifcfg,
 
 	if (!ret) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create InfiniBand setting.");
+		             "Failed to create InfiniBand setting");
 	}
 	return ret;
 }
@@ -4842,7 +4855,7 @@ infiniband_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL);
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -4946,7 +4959,7 @@ bond_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond"));
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -5019,7 +5032,7 @@ team_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_TEAM_SETTING_NAME, NULL, _("Team"));
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -5301,7 +5314,7 @@ bridge_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BRIDGE_SETTING_NAME, NULL, _("Bridge"));
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -5469,7 +5482,7 @@ make_vlan_setting (shvarFile *ifcfg,
 	iface_name = svGetValueStr_cp (ifcfg, "DEVICE");
 	if (!iface_name && vlan_id < 0) {
 		g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		                     "Missing DEVICE property; cannot determine VLAN ID.");
+		                     "Missing DEVICE property; cannot determine VLAN ID");
 		return NULL;
 	}
 
@@ -5512,7 +5525,7 @@ make_vlan_setting (shvarFile *ifcfg,
 
 	if (vlan_id < 0) {
 		g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		                     "Failed to determine VLAN ID from DEVICE or VLAN_ID.");
+		                     "Failed to determine VLAN ID from DEVICE or VLAN_ID");
 		return NULL;
 	}
 	g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL);
@@ -5583,7 +5596,7 @@ vlan_connection_from_ifcfg (const char *file,
 	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan");
 	if (!con_setting) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Failed to create connection setting.");
+		             "Failed to create connection setting");
 		g_object_unref (connection);
 		return NULL;
 	}
@@ -5726,7 +5739,7 @@ connection_from_file_full (const char *filename,
 	ifcfg_name = utils_get_ifcfg_name (filename, TRUE);
 	if (!ifcfg_name) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-		             "Ignoring connection '%s' because it's not an ifcfg file.", filename);
+		             "Ignoring connection '%s' because it's not an ifcfg file", filename);
 		return NULL;
 	}
 
@@ -5804,14 +5817,14 @@ connection_from_file_full (const char *filename,
 		device = svGetValueStr_cp (main_ifcfg, "DEVICE");
 		if (!device) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "File '%s' had neither TYPE nor DEVICE keys.", filename);
+			             "File '%s' had neither TYPE nor DEVICE keys", filename);
 			return NULL;
 		}
 
 		if (!strcmp (device, "lo")) {
 			NM_SET_OUT (out_ignore_error, TRUE);
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
-			             "Ignoring loopback device config.");
+			             "Ignoring loopback device config");
 			g_free (device);
 			return NULL;
 		}
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
index 8008e052..9319a064 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c
index 2841bedb..79101296 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.c
@@ -1,19 +1,5 @@
-/* NetworkManager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2018 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h
index e1165f50..1b2b58e6 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-storage.h
@@ -1,19 +1,5 @@
-/* NetworkManager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2019 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
index cb1fc23a..ee389bd9 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 - 2017 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2008 - 2017 Red Hat, Inc.
  */
 
 #include "nm-default.h"
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
index 20d6f72d..035146ff 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 - 2017 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2008 - 2017 Red Hat, Inc.
  */
 
 #ifndef _UTILS_H_
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index 809d3769..d33845c2 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2009 - 2015 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2009 - 2015 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -305,6 +291,7 @@ write_blobs (GHashTable *blobs, GError **error)
 		                                 (const char *) g_bytes_get_data (blob, NULL),
 		                                 g_bytes_get_size (blob),
 		                                 0600,
+		                                 NULL,
 		                                 &write_error)) {
 			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
 			             "Could not write certificate to file \"%s\": %s",
@@ -588,7 +575,7 @@ write_wireless_security_setting (NMConnection *connection,
 		svUnsetValue (ifcfg, "KEY_MGMT");
 		wep = TRUE;
 		*no_8021x = TRUE;
-	} else if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) {
+	} else if (!strcmp (key_mgmt, "wpa-psk")) {
 		svSetValueStr (ifcfg, "KEY_MGMT", "WPA-PSK");
 		wpa = TRUE;
 		*no_8021x = TRUE;
@@ -1943,7 +1930,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
 		 * it into an interface name, so that legacy tooling is not confused. */
 		if (!nm_utils_get_testing ()) {
 			/* This is conditional for easier testing. */
-			master_iface = nm_manager_iface_for_uuid (nm_manager_get (), master);
+			master_iface = nm_manager_iface_for_uuid (NM_MANAGER_GET, master);
 		}
 		if (!master_iface) {
 			master_iface = master;
@@ -2097,6 +2084,8 @@ get_route_attributes_string (NMIPRoute *route, int family)
 				/* we also have a corresponding attribute with the numeric value. The
 				 * lock setting is handled above. */
 			}
+		} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_SCOPE)) {
+			g_string_append_printf (str, "%s %u", names[i], (unsigned) g_variant_get_byte (attr));
 		} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TOS)) {
 			g_string_append_printf (str, "%s 0x%02x", names[i], (unsigned) g_variant_get_byte (attr));
 		} else if (nm_streq (names[i], NM_IP_ROUTE_ATTRIBUTE_TABLE)) {
@@ -2449,6 +2438,7 @@ write_ip4_setting (NMConnection *connection,
 	GString *searches;
 	const char *method = NULL;
 	gboolean has_netmask;
+	NMDhcpHostnameFlags flags;
 
 	NM_SET_OUT (out_route_content_svformat, NULL);
 	NM_SET_OUT (out_route_content, NULL);
@@ -2609,6 +2599,12 @@ write_ip4_setting (NMConnection *connection,
 	value = nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4));
 	svSetValueStr (ifcfg, "DHCP_FQDN", value);
 
+	flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip4);
+	svSetValueInt64_cond (ifcfg,
+	                      "DHCP_HOSTNAME_FLAGS",
+	                      flags != NM_DHCP_HOSTNAME_FLAG_NONE,
+	                      flags);
+
 	/* Missing DHCP_SEND_HOSTNAME means TRUE, and we prefer not write it explicitly
 	 * in that case, because it is NM-specific variable
 	 */
@@ -2618,6 +2614,9 @@ write_ip4_setting (NMConnection *connection,
 	value = nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4));
 	svSetValueStr (ifcfg, "DHCP_CLIENT_ID", value);
 
+	value = nm_setting_ip_config_get_dhcp_iaid (s_ip4);
+	svSetValueStr (ifcfg, "DHCP_IAID", value);
+
 	timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip4);
 	svSetValueInt64_cond (ifcfg,
 	                      "IPV4_DHCP_TIMEOUT",
@@ -2752,6 +2751,7 @@ write_ip4_aliases (NMConnection *connection, const char *base_ifcfg_path)
 static void
 write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg)
 {
+	NMDhcpHostnameFlags flags;
 	const char *hostname;
 
 	hostname = nm_setting_ip_config_get_dhcp_hostname (s_ip6);
@@ -2764,6 +2764,12 @@ write_ip6_setting_dhcp_hostname (NMSettingIPConfig *s_ip6, shvarFile *ifcfg)
 		svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME");
 	else
 		svSetValueStr (ifcfg, "DHCPV6_SEND_HOSTNAME", "no");
+
+	flags = nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6);
+	svSetValueInt64_cond (ifcfg,
+	                      "DHCPV6_HOSTNAME_FLAGS",
+	                      flags != NM_DHCP_HOSTNAME_FLAG_NONE,
+	                      flags);
 }
 
 static gboolean
@@ -2796,6 +2802,7 @@ write_ip6_setting (NMConnection *connection,
 		svUnsetValue (ifcfg, "IPV6_AUTOCONF");
 		svUnsetValue (ifcfg, "DHCPV6C");
 		svUnsetValue (ifcfg, "DHCPv6_DUID");
+		svUnsetValue (ifcfg, "DHCPv6_IAID");
 		svUnsetValue (ifcfg, "DHCPV6_HOSTNAME");
 		svUnsetValue (ifcfg, "DHCPV6_SEND_HOSTNAME");
 		svUnsetValue (ifcfg, "IPV6_DEFROUTE");
@@ -2845,6 +2852,8 @@ write_ip6_setting (NMConnection *connection,
 
 	svSetValueStr (ifcfg, "DHCPV6_DUID",
 	               nm_setting_ip6_config_get_dhcp_duid (NM_SETTING_IP6_CONFIG (s_ip6)));
+	svSetValueStr (ifcfg, "DHCPV6_IAID",
+	               nm_setting_ip_config_get_dhcp_iaid (s_ip6));
 
 	write_ip6_setting_dhcp_hostname (s_ip6, ifcfg);
 
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
index 0902daee..c4903a46 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2009 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index d4bc71f3..16b2dd37 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -1,25 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * shvar.c
- *
- * Implementation of non-destructively reading/writing files containing
- * only shell variable declarations and full-line comments.
- *
- * Copyright 1999,2000 Red Hat, Inc.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -790,7 +771,7 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
 	shvarFile *s;
 	gboolean closefd = FALSE;
 	int errsv = 0;
-	char *arena;
+	gs_free char *arena = NULL;
 	const char *p, *q;
 	gs_free_error GError *local = NULL;
 	nm_auto_close int fd = -1;
@@ -816,13 +797,14 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
 		return NULL;
 	}
 
-	if (nm_utils_fd_get_contents (closefd ? nm_steal_fd (&fd) : fd,
-	                              closefd,
-	                              10 * 1024 * 1024,
-	                              NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
-	                              &arena,
-	                              NULL,
-	                              &local) < 0) {
+	if (!nm_utils_fd_get_contents (closefd ? nm_steal_fd (&fd) : fd,
+	                               closefd,
+	                               10 * 1024 * 1024,
+	                               NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
+	                               &arena,
+	                               NULL,
+	                               NULL,
+	                               &local)) {
 		if (create)
 			return svFile_new (name);
 
@@ -839,7 +821,6 @@ svOpenFileInternal (const char *name, gboolean create, GError **error)
 		c_list_link_tail (&s->lst_head, &line_new_parse (p, q - p)->lst);
 	if (p[0])
 		c_list_link_tail (&s->lst_head, &line_new_parse (p, strlen (p))->lst);
-	g_free (arena);
 
 	/* closefd is set if we opened the file read-only, so go ahead and
 	 * close it, because we can't write to it anyway */
diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h
index 2f6912b3..c3bbabab 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.h
+++ b/src/settings/plugins/ifcfg-rh/shvar.h
@@ -1,32 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * shvar.h
- *
- * Interface for non-destructively reading/writing files containing
- * only shell variable declarations and full-line comments.
- *
- * Includes explicit inheritance mechanism intended for use with
- * Red Hat Linux ifcfg-* files.  There is no protection against
- * inheritance loops; they will generally cause stack overflows.
- * Furthermore, they are only intended for one level of inheritance;
- * the value setting algorithm assumes this.
- *
- * Copyright 1999 Red Hat, Inc.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Copyright (C) 1999 Red Hat, Inc.
  */
+
 #ifndef _SHVAR_H
 #define _SHVAR_H
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/meson.build b/src/settings/plugins/ifcfg-rh/tests/meson.build
index f65494bb..21699045 100644
--- a/src/settings/plugins/ifcfg-rh/tests/meson.build
+++ b/src/settings/plugins/ifcfg-rh/tests/meson.build
@@ -1,11 +1,10 @@
 test_unit = 'test-ifcfg-rh'
 
-test_ifcfg_dir = meson.current_source_dir()
-
 exe = executable(
   test_unit,
   test_unit + '.c',
-  dependencies: test_nm_dep,
+  dependencies: libnetwork_manager_test_dep,
+  c_args: test_c_flags,
   link_with: libnms_ifcfg_rh_core,
 )
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc
index aa00925e..c3cadbb8 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc
@@ -12,5 +12,6 @@ USERCTL=yes
 PEERDNS=yes
 IPV6INIT=no
 CIPHER_GROUP=CCMP
+CIPHER_PAIRWISE=CCMP
 KEY_MGMT=WPA-PSK
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp
index 727d2ceb..5d36675a 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp
@@ -8,7 +8,12 @@ USERCTL=yes
 IPV6INIT=no
 NM_CONTROLLED=yes
 PEERDNS=no
-DHCP_HOSTNAME=foobar
+DHCP_FQDN=foo.bar
+DHCP_HOSTNAME_FLAGS=6
 DNS1=4.2.2.1
 DNS2=4.2.2.2
-
+IPV6_AUTOCONF=no
+IPV6INIT=yes
+DHCPV6C=yes
+DHCPV6_HOSTNAME_FLAGS=8
+DHCPV6_HOSTNAME=foo.bar
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes
index 8d6aaac2..5d02c62e 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes
@@ -6,10 +6,10 @@ ADDRESS1=44.55.66.77
 NETMASK1=255.255.255.255
 GATEWAY1=192.168.1.7
 METRIC1=3
-OPTIONS1="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 window 30000 initcwnd lock 13 initrwnd 14"
+OPTIONS1="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 window 30000 scope 10 initcwnd lock 13 initrwnd 14"
 
 ADDRESS2=44.55.66.78
 NETMASK2=255.255.255.255
 GATEWAY2=192.168.1.8
 METRIC2=3
-OPTIONS2="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 onlink window 30000 initcwnd lock 13 initrwnd 14"
+OPTIONS2="mtu lock 9000 cwnd 12 src 1.1.1.1 tos 0x28 onlink window 30000 initcwnd lock 13 initrwnd 14 scope link"
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
index 45e90b91..675421d3 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
@@ -901,6 +887,7 @@ test_read_wired_dhcp (void)
 	NMSettingConnection *s_con;
 	NMSettingWired *s_wired;
 	NMSettingIPConfig *s_ip4;
+	NMSettingIPConfig *s_ip6;
 	char *unmanaged = NULL;
 	char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee };
 	const char *mac;
@@ -930,11 +917,23 @@ test_read_wired_dhcp (void)
 	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	g_assert (s_ip4);
 	g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
-	g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, "foobar");
+	g_assert_cmpstr (nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)), ==, "foo.bar");
 	g_assert (nm_setting_ip_config_get_ignore_auto_dns (s_ip4));
 	g_assert_cmpuint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2);
 	g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1");
 	g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2");
+	g_assert_cmpuint (nm_setting_ip_config_get_dhcp_hostname_flags (s_ip4),
+	                  ==,
+	                  NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED | NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE);
+
+	/* ===== IPv6 SETTING ===== */
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
+	g_assert (s_ip6);
+	g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_DHCP);
+	g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, "foo.bar");
+	g_assert_cmpuint (nm_setting_ip_config_get_dhcp_hostname_flags (s_ip6),
+	                  ==,
+	                  NM_DHCP_HOSTNAME_FLAG_FQDN_CLEAR_FLAGS);
 
 	g_object_unref (connection);
 }
@@ -1348,6 +1347,7 @@ test_read_wired_static_routes (void)
 	nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, TRUE);
 	nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE);
 	nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1");
+	nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 10);
 
 	ip4_route = nm_setting_ip_config_get_route (s_ip4, 2);
 	g_assert (ip4_route);
@@ -1365,6 +1365,7 @@ test_read_wired_static_routes (void)
 	nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, TRUE);
 	nmtst_assert_route_attribute_string (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SRC, "1.1.1.1");
 	nmtst_assert_route_attribute_boolean (ip4_route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, TRUE);
+	nmtst_assert_route_attribute_byte (ip4_route, NM_IP_ROUTE_ATTRIBUTE_SCOPE, 253);
 
 	g_object_unref (connection);
 }
@@ -1520,10 +1521,8 @@ test_read_wired_ipv6_manual (void)
 	NMIPAddress *ip6_addr;
 	NMIPRoute *ip6_route;
 
-	NMTST_EXPECT_NM_WARN ("*ignoring manual default route*");
 	connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-ipv6-manual",
 	                                    NULL, TYPE_ETHERNET, &unmanaged);
-	g_test_assert_expected_messages ();
 	g_assert (!unmanaged);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -1581,7 +1580,7 @@ test_read_wired_ipv6_manual (void)
 	g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 96);
 
 	/* Routes */
-	g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 3);
+	g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 4);
 	/* Route #1 */
 	ip6_route = nm_setting_ip_config_get_route (s_ip6, 0);
 	g_assert (ip6_route);
@@ -1592,12 +1591,19 @@ test_read_wired_ipv6_manual (void)
 	/* Route #2 */
 	ip6_route = nm_setting_ip_config_get_route (s_ip6, 1);
 	g_assert (ip6_route);
+	g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "::");
+	g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 0);
+	g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, "dead::beaf");
+	g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, -1);
+	/* Route #3 */
+	ip6_route = nm_setting_ip_config_get_route (s_ip6, 2);
+	g_assert (ip6_route);
 	g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "abbe::cafe");
 	g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 64);
 	g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, NULL);
 	g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, 777);
-	/* Route #3 */
-	ip6_route = nm_setting_ip_config_get_route (s_ip6, 2);
+	/* Route #4 */
+	ip6_route = nm_setting_ip_config_get_route (s_ip6, 3);
 	g_assert (ip6_route);
 	g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "aaaa::cccc");
 	g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 64);
@@ -3128,17 +3134,17 @@ test_read_wifi_wpa_psk_adhoc (void)
 
 	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec);
-	g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-none");
+	g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk");
 	g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "I wonder what the king is doing tonight?");
 
-	/* Pairwise cipher is unused in adhoc mode */
-	g_assert_cmpint (nm_setting_wireless_security_get_num_pairwise (s_wsec), ==, 0);
+	g_assert_cmpint (nm_setting_wireless_security_get_num_pairwise (s_wsec), ==, 1);
+	g_assert_cmpstr (nm_setting_wireless_security_get_pairwise (s_wsec, 0), ==, "ccmp");
 
 	g_assert_cmpint (nm_setting_wireless_security_get_num_groups (s_wsec), ==, 1);
 	g_assert_cmpstr (nm_setting_wireless_security_get_group (s_wsec, 0), ==, "ccmp");
 
 	g_assert_cmpint (nm_setting_wireless_security_get_num_protos (s_wsec), ==, 1);
-	g_assert_cmpstr (nm_setting_wireless_security_get_proto (s_wsec, 0), ==, "wpa");
+	g_assert_cmpstr (nm_setting_wireless_security_get_proto (s_wsec, 0), ==, "rsn");
 
 	/* ===== IPv4 SETTING ===== */
 
@@ -4464,9 +4470,11 @@ test_write_wired_dhcp (void)
 	g_object_set (s_ip4,
 	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
 	              NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33",
-	              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "awesome-hostname",
+	              NM_SETTING_IP4_CONFIG_DHCP_FQDN, "awesome.hostname",
+	              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_ENCODED,
 	              NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE,
 	              NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE,
+	              NM_SETTING_IP_CONFIG_DHCP_IAID, "2864434397",
 	              NULL);
 
 	nmtst_assert_connection_verifies (connection);
@@ -4476,8 +4484,10 @@ test_write_wired_dhcp (void)
 	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
 
 	g_object_set (s_ip6,
-	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_DHCP,
 	              NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
+	              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "awesome.hostname",
+	              NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, (guint) NM_DHCP_HOSTNAME_FLAG_FQDN_NO_UPDATE,
 	              NULL);
 
 	_writer_new_connection (connection,
@@ -6455,12 +6465,13 @@ test_write_wifi_wpa_psk_adhoc (void)
 	nm_connection_add_setting (connection, NM_SETTING (s_wsec));
 
 	g_object_set (s_wsec,
-	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none",
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
 	              NM_SETTING_WIRELESS_SECURITY_PSK, "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0",
 	              NULL);
 
-	nm_setting_wireless_security_add_proto (s_wsec, "wpa");
-	nm_setting_wireless_security_add_group (s_wsec, "tkip");
+	nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+	nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+	nm_setting_wireless_security_add_group (s_wsec, "ccmp");
 
 	/* IP4 setting */
 	s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
diff --git a/src/settings/plugins/ifupdown/meson.build b/src/settings/plugins/ifupdown/meson.build
index 365ae1a9..0cabe771 100644
--- a/src/settings/plugins/ifupdown/meson.build
+++ b/src/settings/plugins/ifupdown/meson.build
@@ -3,25 +3,18 @@ sources = files(
   'nms-ifupdown-parser.c',
 )
 
-deps = [
-  libudev_dep,
-  nm_dep,
-]
-
 libnms_ifupdown_core = static_library(
   'nms-ifupdown-core',
   sources: sources,
-  dependencies: deps,
-)
-
-sources = files(
-  'nms-ifupdown-plugin.c',
+  dependencies: daemon_nm_default_dep,
+  c_args: daemon_c_flags,
 )
 
 libnm_settings_plugin_ifupdown = shared_module(
   'nm-settings-plugin-ifupdown',
-  sources: sources,
-  dependencies: deps,
+  sources: 'nms-ifupdown-plugin.c',
+  dependencies: daemon_nm_default_dep,
+  c_args: daemon_c_flags,
   link_with: libnms_ifupdown_core,
   link_args: ldflags_linker_script_settings,
   link_depends: linker_script_settings,
@@ -31,18 +24,6 @@ libnm_settings_plugin_ifupdown = shared_module(
 
 core_plugins += libnm_settings_plugin_ifupdown
 
-# FIXME: check_so_symbols replacement
-'''
-run_target(
-  'check-local-symbols-settings-ifupdown',
-  command: [check_so_symbols, libnm_settings_plugin_ifupdown.full_path()],
-  depends: libnm_settings_plugin_ifupdown,
-)
-
-check-local-symbols-settings-ifupdown: src/settings/plugins/ifupdown/libnm-settings-plugin-ifupdown.la
-  $(call check_so_symbols,$(builddir)/src/settings/plugins/ifupdown/.libs/libnm-settings-plugin-ifupdown.so)
-'''
-
 if enable_tests
   subdir('tests')
 endif
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c
index 75f29878..a146ae60 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c
@@ -1,22 +1,7 @@
-/* NetworkManager -- Network link manager
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Tom Parker <palfrey@tevp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2004 Tom Parker
+ * Copyright (C) 2004 Tom Parker
  */
 
 #include "nm-default.h"
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h
index 308228a4..af02c7f6 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h
@@ -1,22 +1,7 @@
-/* NetworkManager -- Network link manager
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Tom Parker <palfrey@tevp.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2004 Tom Parker
+ * Copyright (C) 2004 Tom Parker
  */
 
 #ifndef _INTERFACE_PARSER_H
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c
index 41b20850..1db9ef15 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c
@@ -1,22 +1,7 @@
-/* NetworkManager system settings service (ifupdown)
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Alexander Sack <asac@ubuntu.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Canonical Ltd.
+ * Copyright (C) 2008 Canonical Ltd.
  */
 
 #include "nm-default.h"
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-parser.h
index 7569648f..b8761fc3 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.h
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.h
@@ -1,22 +1,7 @@
-/* NetworkManager system settings service (ifupdown)
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Alexander Sack <asac@ubuntu.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Canonical Ltd.
+ * Copyright (C) 2008 Canonical Ltd.
  */
 
 #ifndef __NMS_IFUPDOWN_PARSER_H__
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
index e663ab8a..d19db0fd 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c
@@ -1,23 +1,8 @@
-/* NetworkManager system settings service (ifupdown)
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Alexander Sack <asac@ubuntu.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2007,2008 Canonical Ltd.
- * (C) Copyright 2009 - 2011 Red Hat, Inc.
+ * Copyright (C) 2007, 2008 Canonical Ltd.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
  */
 
 #include "nm-default.h"
diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h
index 10ea2be4..91e3e43a 100644
--- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h
+++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.h
@@ -1,22 +1,7 @@
-/* NetworkManager system settings service (ifupdown)
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Alexander Sack <asac@ubuntu.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Canonical Ltd.
+ * Copyright (C) 2008 Canonical Ltd.
  */
 
 #ifndef __NMS_IFUPDOWN_PLUGIN_H__
diff --git a/src/settings/plugins/ifupdown/tests/meson.build b/src/settings/plugins/ifupdown/tests/meson.build
index 9b844c75..1ca094b5 100644
--- a/src/settings/plugins/ifupdown/tests/meson.build
+++ b/src/settings/plugins/ifupdown/tests/meson.build
@@ -3,7 +3,8 @@ test_unit = 'test-ifupdown'
 exe = executable(
   test_unit,
   test_unit + '.c',
-  dependencies: test_nm_dep,
+  dependencies: libnetwork_manager_test_dep,
+  c_args: test_c_flags,
   link_with: libnms_ifupdown_core,
 )
 
diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
index 4adcf085..6a7b5ecc 100644
--- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c
+++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
@@ -1,20 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
  * Copyright (C) 2010 Red Hat, Inc.
- *
  */
 
 #include "nm-default.h"
@@ -149,6 +135,9 @@ expected_free (Expected *e)
 	g_free (e);
 }
 
+NM_AUTO_DEFINE_FCN_VOID0 (Expected *, _nm_auto_free_expected, expected_free)
+#define nm_auto_free_expected nm_auto(_nm_auto_free_expected)
+
 static void
 compare_expected_to_ifparser (if_parser *parser, Expected *e)
 {
@@ -226,7 +215,7 @@ init_ifparser_with_file (const char *file)
 static void
 test1_ignore_line_before_first_block (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test1");
 
@@ -238,14 +227,12 @@ test1_ignore_line_before_first_block (void)
 	expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test2_wrapped_line (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test2");
 
@@ -254,14 +241,12 @@ test2_wrapped_line (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test3_wrapped_multiline_multiarg (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test3");
 
@@ -274,14 +259,12 @@ test3_wrapped_multiline_multiarg (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test4_allow_auto_is_auto (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test4");
 
@@ -290,14 +273,12 @@ test4_allow_auto_is_auto (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test5_allow_auto_multiarg (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test5");
 
@@ -308,14 +289,12 @@ test5_allow_auto_multiarg (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test6_mixed_whitespace (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test6");
 
@@ -325,8 +304,6 @@ test6_mixed_whitespace (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
@@ -348,7 +325,7 @@ test8_long_line_wrapped (void)
 static void
 test9_wrapped_lines_in_block (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test9");
 
@@ -362,14 +339,12 @@ test9_wrapped_lines_in_block (void)
 	expected_block_add_key (b, expected_key_new ("gateway", "10.250.2.50"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test11_complex_wrap (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test11");
 
@@ -380,14 +355,12 @@ test11_complex_wrap (void)
 	expected_block_add_key (b, expected_key_new ("pre-up", "/sbin/ifconfig eth0 up"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test12_complex_wrap_split_word (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test12");
 
@@ -398,14 +371,12 @@ test12_complex_wrap_split_word (void)
 	expected_block_add_key (b, expected_key_new ("up", "ifup ppp0=dsl"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test13_more_mixed_whitespace (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test13");
 
@@ -415,14 +386,12 @@ test13_more_mixed_whitespace (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test14_mixed_whitespace_block_start (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test14");
 
@@ -438,14 +407,12 @@ test14_mixed_whitespace_block_start (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test15_trailing_space (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test15");
 
@@ -455,23 +422,20 @@ test15_trailing_space (void)
 	expected_add_block (e, b);
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test16_missing_newline (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test16");
 
 	e = expected_new ();
 	expected_add_block (e, expected_block_new ("mapping", "eth0"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
+
 static void
 test17_read_static_ipv4 (void)
 {
@@ -578,7 +542,7 @@ test19_read_static_ipv4_plen (void)
 static void
 test20_source_stanza (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test20-source-stanza");
 
@@ -597,14 +561,12 @@ test20_source_stanza (void)
 	expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
 
 	compare_expected_to_ifparser (parser, e);
-
-	expected_free (e);
 }
 
 static void
 test21_source_dir_stanza (void)
 {
-	Expected *e;
+	nm_auto_free_expected Expected *e = NULL;
 	ExpectedBlock *b;
 	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test21-source-dir-stanza");
 
@@ -617,10 +579,34 @@ test21_source_dir_stanza (void)
 	expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
 
 	compare_expected_to_ifparser (parser, e);
+}
+
+static void
+test22_duplicate_stanzas (void)
+{
+	nm_auto_free_expected Expected *e = NULL;
+	ExpectedBlock *b;
+	nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test22-duplicate-stanzas");
+
+	e = expected_new ();
 
-	expected_free (e);
+	b = expected_block_new ("iface", "br10");
+	expected_add_block (e, b);
+	expected_block_add_key (b, expected_key_new ("inet", "manual"));
+	expected_block_add_key (b, expected_key_new ("bridge-ports", "enp6s0.15"));
+	expected_block_add_key (b, expected_key_new ("bridge-stp", "off"));
+	expected_block_add_key (b, expected_key_new ("bridge-maxwait", "0"));
+	expected_block_add_key (b, expected_key_new ("bridge-fd", "0"));
+	b = expected_block_new ("iface", "br10");
+	expected_add_block (e, b);
+	expected_block_add_key (b, expected_key_new ("inet", "auto"));
+	expected_block_add_key (b, expected_key_new ("bridge-ports", "enp6s0.15"));
+
+	compare_expected_to_ifparser (parser, e);
 }
 
+/*****************************************************************************/
+
 NMTST_DEFINE ();
 
 int
@@ -650,6 +636,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/ifupdate/read_static_ipv4_plen",          test19_read_static_ipv4_plen);
 	g_test_add_func ("/ifupdate/source_stanza",                  test20_source_stanza);
 	g_test_add_func ("/ifupdate/source_dir_stanza",              test21_source_dir_stanza);
+	g_test_add_func ("/ifupdate/test22-duplicate-stanzas",       test22_duplicate_stanzas);
 
 	return g_test_run ();
 }
diff --git a/src/settings/plugins/ifupdown/tests/test22-duplicate-stanzas b/src/settings/plugins/ifupdown/tests/test22-duplicate-stanzas
new file mode 100644
index 00000000..c13c2e7e
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test22-duplicate-stanzas
@@ -0,0 +1,8 @@
+iface br10 inet manual
+    bridge_ports    enp6s0.15
+    bridge_stp      off
+    bridge_maxwait  0
+    bridge_fd       0
+
+iface br10 inet auto
+    bridge_ports enp6s0.15
diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
index fbe70ef4..fdb88d2a 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2008 - 2018 Red Hat, Inc.
  */
@@ -369,7 +355,7 @@ _load_file (NMSKeyfilePlugin *self,
 	                              &local);
 	if (!connection) {
 		if (error)
-			g_propagate_error (error, local);
+			g_propagate_error (error, g_steal_pointer (&local));
 		else
 			_LOGW ("load: \"%s\": failed to load connection: %s", full_filename, local->message);
 		return NULL;
@@ -1090,7 +1076,7 @@ nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self,
 	gboolean hard_failure = FALSE;
 	NMSKeyfileStorage *storage;
 	gs_unref_object NMSKeyfileStorage *storage_result = NULL;
-	gboolean nmmeta_success = FALSE;
+	gboolean nmmeta_errno;
 	gs_free char *nmmeta_filename = NULL;
 	NMSKeyfileStorageType storage_type;
 	const char *loaded_path;
@@ -1116,6 +1102,7 @@ nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self,
 			       simulate ? "simulate " : "",
 			       loaded_path ? "write" : "delete",
 			       uuid);
+			nmmeta_errno = 0;
 			hard_failure = TRUE;
 			goto out;
 		}
@@ -1124,29 +1111,30 @@ nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self,
 	}
 
 	if (simulate) {
-		nmmeta_success = TRUE;
+		nmmeta_errno = 0;
 		nmmeta_filename = nms_keyfile_nmmeta_filename (dirname, uuid, FALSE);
 	} else {
-		nmmeta_success = nms_keyfile_nmmeta_write (dirname,
-		                                           uuid,
-		                                           loaded_path,
-		                                           FALSE,
-		                                           shadowed_storage,
-		                                           &nmmeta_filename);
+		nmmeta_errno = nms_keyfile_nmmeta_write (dirname,
+		                                         uuid,
+		                                         loaded_path,
+		                                         FALSE,
+		                                         shadowed_storage,
+		                                         &nmmeta_filename);
 	}
 
-	_LOGT ("commit: %s nmmeta file \"%s\"%s%s%s%s%s%s %s",
+	_LOGT ("commit: %s nmmeta file \"%s\"%s%s%s%s%s%s %s%s%s%s",
 	       loaded_path ? "writing" : "deleting",
 	       nmmeta_filename,
 	       NM_PRINT_FMT_QUOTED (loaded_path, " (pointing to \"", loaded_path, "\")", ""),
 	       NM_PRINT_FMT_QUOTED (shadowed_storage, " (shadows \"", shadowed_storage, "\")", ""),
 	       simulate
 	       ? "simulated"
-	       : (  nmmeta_success
-	          ? "succeeded"
-	          : "failed"));
+	       : (  nmmeta_errno < 0
+	          ? "failed"
+	          : "succeeded"),
+	       NM_PRINT_FMT_QUOTED (nmmeta_errno < 0, " (", nm_strerror_native (nm_errno_native (nmmeta_errno)), ")", ""));
 
-	if (!nmmeta_success)
+	if (nmmeta_errno < 0)
 		goto out;
 
 	storage = nm_sett_util_storages_lookup_by_filename (&priv->storages, nmmeta_filename);
@@ -1177,12 +1165,13 @@ nms_keyfile_plugin_set_nmmeta_tombstone (NMSKeyfilePlugin *self,
 	}
 
 out:
-	nm_assert (!nmmeta_success || !hard_failure);
-	nm_assert (nmmeta_success  || !storage_result);
+	nm_assert (nmmeta_errno <= 0);
+	nm_assert (nmmeta_errno < 0  || !hard_failure);
+	nm_assert (nmmeta_errno == 0 || !storage_result);
 
 	NM_SET_OUT (out_hard_failure, hard_failure);
 	NM_SET_OUT (out_storage, (NMSettingsStorage *) g_steal_pointer (&storage_result));
-	return nmmeta_success;
+	return nmmeta_errno >= 0;
 }
 
 /*****************************************************************************/
diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.h b/src/settings/plugins/keyfile/nms-keyfile-plugin.h
index 48440964..e885f16c 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-plugin.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c
index 8d1f5599..af9e6726 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-reader.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2015 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.h b/src/settings/plugins/keyfile/nms-keyfile-reader.h
index f20e6d93..307d6ffe 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-reader.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-reader.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2008 Red Hat, Inc.
  */
diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.c b/src/settings/plugins/keyfile/nms-keyfile-storage.c
index d68d60c8..bcc06795 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-storage.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-storage.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2018 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.h b/src/settings/plugins/keyfile/nms-keyfile-storage.h
index 2252b47b..00a034d4 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-storage.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-storage.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2018 Red Hat, Inc.
  */
 
diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.c b/src/settings/plugins/keyfile/nms-keyfile-utils.c
index ea03e1b6..f03c601a 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-utils.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-utils.c
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2010 - 2018 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010 - 2018 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -206,7 +192,7 @@ nms_keyfile_nmmeta_read_from_file (const char *full_filename,
 	return TRUE;
 }
 
-gboolean
+int
 nms_keyfile_nmmeta_write (const char *dirname,
                           const char *uuid,
                           const char *loaded_path,
@@ -216,6 +202,7 @@ nms_keyfile_nmmeta_write (const char *dirname,
 {
 	gs_free char *full_filename_tmp = NULL;
 	gs_free char *full_filename = NULL;
+	int errsv;
 
 	nm_assert (dirname && dirname[0] == '/');
 	nm_assert (   nm_utils_is_uuid (uuid)
@@ -231,13 +218,15 @@ nms_keyfile_nmmeta_write (const char *dirname,
 	(void) unlink (full_filename_tmp);
 
 	if (!loaded_path) {
-		gboolean success = TRUE;
-
 		full_filename_tmp[strlen (full_filename_tmp) - 1] = '\0';
-		if (unlink (full_filename_tmp) != 0)
-			success = NM_IN_SET (errno, ENOENT);
+		errsv = 0;
+		if (unlink (full_filename_tmp) != 0) {
+			errsv = -NM_ERRNO_NATIVE (errno);
+			if (errsv == -ENOENT)
+				errsv = 0;
+		}
 		NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp));
-		return success;
+		return errsv;
 	}
 
 	if (loaded_path_allow_relative) {
@@ -266,29 +255,36 @@ nms_keyfile_nmmeta_write (const char *dirname,
 
 		contents = g_key_file_to_data (kf, &length, NULL);
 
-		if (!nm_utils_file_set_contents (full_filename, contents, length, 0600, NULL)) {
+		if (!nm_utils_file_set_contents (full_filename,
+		                                 contents,
+		                                 length,
+		                                 0600,
+		                                 &errsv,
+		                                 NULL)) {
 			NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp));
-			return FALSE;
+			return -NM_ERRNO_NATIVE (errsv);
 		}
 	} else {
 		/* we only have the "loaded_path" to store. That is commonly used for the tombstones to
 		 * link to /dev/null. A symlink is sufficient to store that ammount of information.
 		 * No need to bother with a keyfile. */
 		if (symlink (loaded_path, full_filename_tmp) != 0) {
+			errsv = -NM_ERRNO_NATIVE (errno);
 			full_filename_tmp[strlen (full_filename_tmp) - 1] = '\0';
 			NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename_tmp));
-			return FALSE;
+			return errsv;
 		}
 
 		if (rename (full_filename_tmp, full_filename) != 0) {
+			errsv = -NM_ERRNO_NATIVE (errno);
 			(void) unlink (full_filename_tmp);
 			NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename));
-			return FALSE;
+			return errsv;
 		}
 	}
 
 	NM_SET_OUT (out_full_filename, g_steal_pointer (&full_filename));
-	return TRUE;
+	return 0;
 }
 
 /*****************************************************************************/
diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.h b/src/settings/plugins/keyfile/nms-keyfile-utils.h
index 723c4436..f943d65c 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-utils.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-utils.h
@@ -1,20 +1,6 @@
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2010 - 2018 Red Hat, Inc.
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2010 - 2018 Red Hat, Inc.
  */
 
 #ifndef __NMS_KEYFILE_UTILS_H__
@@ -66,12 +52,12 @@ gboolean nms_keyfile_nmmeta_read_from_file (const char *full_filename,
                                             char **out_loaded_path,
                                             char **out_shadowed_storage);
 
-gboolean nms_keyfile_nmmeta_write (const char *dirname,
-                                   const char *uuid,
-                                   const char *loaded_path,
-                                   gboolean loaded_path_allow_relative,
-                                   const char *shadowed_storage,
-                                   char **out_full_filename);
+int nms_keyfile_nmmeta_write (const char *dirname,
+                              const char *uuid,
+                              const char *loaded_path,
+                              gboolean loaded_path_allow_relative,
+                              const char *shadowed_storage,
+                              char **out_full_filename);
 
 /*****************************************************************************/
 
diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c
index abd3f1f4..fa95198c 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-writer.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-writer.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2008 - 2015 Red Hat, Inc.
  */
@@ -130,8 +116,12 @@ cert_writer (NMConnection *connection,
 		 * being sure that the entire profile can be written and all circumstances are good to
 		 * proceed. That means, while writing we must only collect the blogs in-memory, and write
 		 * them all in the end together (or not at all). */
-		success = nm_utils_file_set_contents (new_path, (const char *) blob_data,
-		                                      blob_len, 0600, &local);
+		success = nm_utils_file_set_contents (new_path,
+		                                      (const char *) blob_data,
+		                                      blob_len,
+		                                      0600,
+		                                      NULL,
+		                                      &local);
 		if (success) {
 			/* Write the path value to the keyfile.
 			 * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64,"  */
@@ -344,7 +334,12 @@ _internal_write_connection (NMConnection *connection,
 		}
 	}
 
-	nm_utils_file_set_contents (path, kf_content_buf, kf_content_len, 0600, &local_err);
+	nm_utils_file_set_contents (path,
+	                            kf_content_buf,
+	                            kf_content_len,
+	                            0600,
+	                            NULL,
+	                            &local_err);
 	if (local_err) {
 		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
 		             "error writing to file '%s': %s",
diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.h b/src/settings/plugins/keyfile/nms-keyfile-writer.h
index 99e86025..98ec8a6b 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-writer.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-writer.h
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 Novell, Inc.
  * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
diff --git a/src/settings/plugins/keyfile/tests/meson.build b/src/settings/plugins/keyfile/tests/meson.build
index f1e96bdf..7bf9fda0 100644
--- a/src/settings/plugins/keyfile/tests/meson.build
+++ b/src/settings/plugins/keyfile/tests/meson.build
@@ -3,7 +3,8 @@ test_unit = 'test-keyfile-settings'
 exe = executable(
   test_unit,
   test_unit + '.c',
-  dependencies: test_nm_dep,
+  dependencies: libnetwork_manager_test_dep,
+  c_args: test_c_flags,
 )
 
 test(
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
index f96111a2..d2da09da 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
@@ -1,19 +1,5 @@
-/* NetworkManager system settings service - keyfile plugin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+// SPDX-License-Identifier: GPL-2.0+
+/*
  * Copyright (C) 2008 - 2017 Red Hat, Inc.
  */
 
@@ -2543,7 +2529,7 @@ _assert_keyfile_nmmeta (const char *dirname,
 	nm_clear_g_free (&full_filename);
 
 
-	g_assert (nms_keyfile_nmmeta_write (dirname, uuid, loaded_path, allow_relative, NULL, &full_filename));
+	g_assert_cmpint (nms_keyfile_nmmeta_write (dirname, uuid, loaded_path, allow_relative, NULL, &full_filename), ==, 0);
 	g_assert_cmpstr (full_filename, ==, exp_full_filename);
 	nm_clear_g_free (&full_filename);