summary refs log tree commit diff
path: root/src/settings
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings')
-rw-r--r--src/settings/Makefile.am9
-rw-r--r--src/settings/Makefile.in20
-rw-r--r--src/settings/nm-agent-manager.c45
-rw-r--r--src/settings/nm-agent-manager.h10
-rw-r--r--src/settings/nm-settings-connection.c20
-rw-r--r--src/settings/nm-settings-connection.h4
-rw-r--r--src/settings/nm-settings-error.c50
-rw-r--r--src/settings/nm-settings-error.h36
-rw-r--r--src/settings/nm-settings.c229
-rw-r--r--src/settings/nm-settings.h3
-rw-r--r--src/settings/nm-system-config-interface.h2
-rw-r--r--src/settings/plugins/Makefile.in9
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.am7
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.in22
-rw-r--r--src/settings/plugins/ifcfg-rh/common.h11
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c834
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.h2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.am3
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.in15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am9
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in18
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband8
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface11
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid6
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-219
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-22
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c1245
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c99
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.h9
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c276
-rw-r--r--src/settings/plugins/ifcfg-suse/Makefile.in9
-rw-r--r--src/settings/plugins/ifcfg-suse/plugin.c4
-rw-r--r--src/settings/plugins/ifnet/Makefile.am16
-rw-r--r--src/settings/plugins/ifnet/Makefile.in25
-rw-r--r--src/settings/plugins/ifnet/connection_parser.c89
-rw-r--r--src/settings/plugins/ifnet/net_parser.c169
-rw-r--r--src/settings/plugins/ifnet/net_parser.h4
-rw-r--r--src/settings/plugins/ifnet/net_utils.c169
-rw-r--r--src/settings/plugins/ifnet/net_utils.h1
-rw-r--r--src/settings/plugins/ifnet/plugin.c85
-rw-r--r--src/settings/plugins/ifnet/plugin.h2
-rw-r--r--src/settings/plugins/ifnet/tests/Makefile.in9
-rw-r--r--src/settings/plugins/ifnet/tests/net11
-rw-r--r--src/settings/plugins/ifnet/tests/test_all.c43
-rw-r--r--src/settings/plugins/ifnet/tests/wpa_supplicant.conf7
-rw-r--r--src/settings/plugins/ifnet/wpa_parser.c19
-rw-r--r--src/settings/plugins/ifnet/wpa_parser.h5
-rw-r--r--src/settings/plugins/ifupdown/Makefile.in9
-rw-r--r--src/settings/plugins/ifupdown/interface_parser.c13
-rw-r--r--src/settings/plugins/ifupdown/interface_parser.h3
-rw-r--r--src/settings/plugins/ifupdown/parser.c315
-rw-r--r--src/settings/plugins/ifupdown/plugin.c49
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.am2
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.in11
-rw-r--r--src/settings/plugins/ifupdown/tests/test-ifupdown.c391
-rw-r--r--src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip45
-rw-r--r--src/settings/plugins/keyfile/Makefile.am4
-rw-r--r--src/settings/plugins/keyfile/Makefile.in13
-rw-r--r--src/settings/plugins/keyfile/plugin.c54
-rw-r--r--src/settings/plugins/keyfile/plugin.h4
-rw-r--r--src/settings/plugins/keyfile/reader.c89
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.am2
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.in11
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.am3
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.in12
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection13
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile.c207
-rw-r--r--src/settings/plugins/keyfile/writer.c40
-rw-r--r--src/settings/tests/Makefile.am1
-rw-r--r--src/settings/tests/Makefile.in10
74 files changed, 4048 insertions, 930 deletions
diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am
index 21dc5bb0..8024d541 100644
--- a/src/settings/Makefile.am
+++ b/src/settings/Makefile.am
@@ -2,10 +2,13 @@ SUBDIRS=plugins . tests
 
 INCLUDES = -I${top_srcdir} \
            -I${top_srcdir}/include \
+           -I${top_builddir}/include \
            -I${top_srcdir}/libnm-util \
+           -I${top_builddir}/libnm-util \
+           -I${top_srcdir}/src/generated \
+           -I${top_builddir}/src/generated \
            -I${top_srcdir}/src/logging \
-           -I${top_srcdir}/src \
-           -I${top_builddir}/marshallers
+           -I${top_srcdir}/src
 
 noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la
 
@@ -64,7 +67,7 @@ libsettings_la_CPPFLAGS = \
 
 libsettings_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/src/generated/libnm-generated.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
 	$(DBUS_LIBS) \
diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in
index b4f4508f..d1278206 100644
--- a/src/settings/Makefile.in
+++ b/src/settings/Makefile.in
@@ -58,7 +58,7 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libsettings_la_DEPENDENCIES =  \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/src/generated/libnm-generated.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
@@ -203,6 +203,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -257,11 +259,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -272,6 +278,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -311,6 +318,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -377,10 +386,13 @@ top_srcdir = @top_srcdir@
 SUBDIRS = plugins . tests
 INCLUDES = -I${top_srcdir} \
            -I${top_srcdir}/include \
+           -I${top_builddir}/include \
            -I${top_srcdir}/libnm-util \
+           -I${top_builddir}/libnm-util \
+           -I${top_srcdir}/src/generated \
+           -I${top_builddir}/src/generated \
            -I${top_srcdir}/src/logging \
-           -I${top_srcdir}/src \
-           -I${top_builddir}/marshallers
+           -I${top_srcdir}/src
 
 noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la
 libtest_settings_utils_la_SOURCES = \
@@ -438,7 +450,7 @@ libsettings_la_CPPFLAGS = \
 
 libsettings_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
+	$(top_builddir)/src/generated/libnm-generated.la \
 	$(top_builddir)/src/logging/libnm-logging.la \
 	$(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
 	$(DBUS_LIBS) \
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
index 5ccbdc67..b7057400 100644
--- a/src/settings/nm-agent-manager.c
+++ b/src/settings/nm-agent-manager.c
@@ -36,6 +36,7 @@
 #include "nm-manager-auth.h"
 #include "nm-setting-vpn.h"
 #include "nm-setting-connection.h"
+#include "nm-enum-types.h"
 
 G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT)
 
@@ -88,17 +89,6 @@ static void impl_agent_manager_unregister (NMAgentManager *self,
 /********************************************************************/
 
 #define NM_AGENT_MANAGER_ERROR         (nm_agent_manager_error_quark ())
-#define NM_TYPE_AGENT_MANAGER_ERROR    (nm_agent_manager_error_get_type ())
-
-typedef enum {
-	NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0,
-	NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
-	NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND,
-	NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
-	NM_AGENT_MANAGER_ERROR_NOT_REGISTERED,
-	NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR,
-	NM_AGENT_MANAGER_ERROR_NO_SECRETS
-} NMAgentManagerError;
 
 static GQuark
 nm_agent_manager_error_quark (void)
@@ -110,37 +100,6 @@ nm_agent_manager_error_quark (void)
 	return ret;
 }
 
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
-
-static GType
-nm_agent_manager_error_get_type (void)
-{
-	static GType etype = 0;
-
-	if (etype == 0) {
-		static const GEnumValue values[] = {
-			/* Unable to determine caller's sender or UID */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "SenderUnknown"),
-			/* Permission for some operation was denied */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"),
-			/* The caller's session could not be determined */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "SessionNotFound"),
-			/* The identifier was invalid */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "InvalidIdentifier"),
-			/* Request was not from a registered agent */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"),
-			/* Some internal error occurred */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"),
-			/* No secrets were available */
-			ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NoSecrets"),
-			{ 0, 0, 0 }
-		};
-
-		etype = g_enum_register_static ("NMAgentManagerError", values);
-	}
-	return etype;
-}
-
 /*************************************************************/
 
 static gboolean
@@ -962,7 +921,7 @@ get_next_cb (Request *req)
 		 * we use the 'modify.own' permission instead of 'modify.system'.  If the
 		 * request affects more than just the caller, require 'modify.system'.
 		 */
-		s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION);
+		s_con = nm_connection_get_setting_connection (req->connection);
 		g_assert (s_con);
 		if (nm_setting_connection_get_num_permissions (s_con) == 1)
 			perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h
index e49f579d..9e8de44b 100644
--- a/src/settings/nm-agent-manager.h
+++ b/src/settings/nm-agent-manager.h
@@ -34,6 +34,16 @@
 #define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_AGENT_MANAGER))
 #define NM_AGENT_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass))
 
+typedef enum {
+	NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, /*< nick=SenderUnknown >*/
+	NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,  /*< nick=PermissionDenied >*/
+	NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND,  /*< nick=SessionNotFound >*/
+	NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, /*< nick=InvalidIdentifier >*/
+	NM_AGENT_MANAGER_ERROR_NOT_REGISTERED,     /*< nick=NotRegistered >*/
+	NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR,     /*< nick=InternalError >*/
+	NM_AGENT_MANAGER_ERROR_NO_SECRETS          /*< nick=NoSecrets >*/
+} NMAgentManagerError;
+
 typedef struct {
 	GObject parent;
 } NMAgentManager;
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index cdad8325..5d240c77 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -221,7 +221,7 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self)
 
 	priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (NM_CONNECTION (self));
 	g_assert (s_con);
 
 	/* Check every user in the ACL for a session */
@@ -1024,7 +1024,7 @@ check_writable (NMConnection *connection, GError **error)
 	g_return_val_if_fail (connection != NULL, FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	if (!s_con) {
 		g_set_error_literal (error,
 		                     NM_SETTINGS_ERROR,
@@ -1175,11 +1175,11 @@ get_modify_permission_update (NMConnection *old, NMConnection *new)
 	NMSettingConnection *s_con;
 	guint32 orig_num = 0, new_num = 0;
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (old, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (old);
 	g_assert (s_con);
 	orig_num = nm_setting_connection_get_num_permissions (s_con);
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (new, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (new);
 	g_assert (s_con);
 	new_num = nm_setting_connection_get_num_permissions (s_con);
 
@@ -1283,7 +1283,7 @@ get_modify_permission_basic (NMSettingsConnection *connection)
 	 * we use the 'modify.own' permission instead of 'modify.system'.  If the
 	 * request affects more than just the caller, require 'modify.system'.
 	 */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
 	g_assert (s_con);
 	if (nm_setting_connection_get_num_permissions (s_con) == 1)
 		return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
@@ -1422,11 +1422,14 @@ nm_settings_connection_get_timestamp (NMSettingsConnection *connection)
  * @connection: the #NMSettingsConnection
  * @timestamp: timestamp to set into the connection and to store into
  * the timestamps database
+ * @flush_to_disk: if %TRUE, commit timestamp update to persistent storage
  *
  * Updates the connection and timestamps database with the provided timestamp.
  **/
 void
-nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp)
+nm_settings_connection_update_timestamp (NMSettingsConnection *connection,
+                                         guint64 timestamp,
+                                         gboolean flush_to_disk)
 {
 	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
 	const char *connection_uuid;
@@ -1438,6 +1441,9 @@ nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint
 	/* Update timestamp in private storage */
 	priv->timestamp = timestamp;
 
+	if (flush_to_disk == FALSE)
+		return;
+
 	/* Save timestamp to timestamps database file */
 	timestamps_file = g_key_file_new ();
 	if (!g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, &error)) {
@@ -1576,7 +1582,7 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection,
 		return;  /* Already in the list */
 
 	/* Add the new BSSID; let the hash take ownership of the allocated BSSID string */
-	bssid_str = nm_ether_ntop (seen_bssid);
+	bssid_str = nm_utils_hwaddr_ntoa (seen_bssid, ARPHRD_ETHER);
 	g_return_if_fail (bssid_str != NULL);
 	g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str);
 
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
index bc9e3c47..077a145d 100644
--- a/src/settings/nm-settings-connection.h
+++ b/src/settings/nm-settings-connection.h
@@ -124,7 +124,9 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self);
 
 guint64 nm_settings_connection_get_timestamp (NMSettingsConnection *connection);
 
-void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp);
+void nm_settings_connection_update_timestamp (NMSettingsConnection *connection,
+                                              guint64 timestamp,
+                                              gboolean flush_to_disk);
 
 void nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection);
 
diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c
index 7e24fb71..fd4eca36 100644
--- a/src/settings/nm-settings-error.c
+++ b/src/settings/nm-settings-error.c
@@ -31,53 +31,3 @@ nm_settings_error_quark (void)
 
 	return ret;
 }
-
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
-
-GType
-nm_settings_error_get_type (void)
-{
-	static GType etype = 0;
-
-	if (etype == 0) {
-		static const GEnumValue values[] = {
-			ENUM_ENTRY (NM_SETTINGS_ERROR_GENERAL, "GeneralError"),
-
-			/* The connection was invalid. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"),
-			/* The connection is read-only; modifications are not allowed. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"),
-			/* A bug in the settings service caused the error. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"),
-			/* Retrieval or request of secrets failed. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"),
-			/* The request for secrets was canceled. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"),
-			/* The request could not be completed because permission was denied. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"),
-			/* The requested setting does not existing in this connection. */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"),
-			/* The caller does not have permission to perform this operation */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
-			/* No plugin supports adding new connections */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"),
-			/* The plugin providing this connection does not support updating it */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"),
-			/* The plugin providing this connection does not support deleting it */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"),
-			/* Failed to add the connection */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"),
-			/* No plugin supports modifying the system hostname */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"),
-			/* Saving the system hostname failed */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"),
-			/* A connection with this UUID already exists */
-			ENUM_ENTRY (NM_SETTINGS_ERROR_UUID_EXISTS, "UuidExists"),
-			{ 0, 0, 0 }
-		};
-
-		etype = g_enum_register_static ("NMSettingsError", values);
-	}
-
-	return etype;
-}
diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h
index b782a779..82132c6f 100644
--- a/src/settings/nm-settings-error.h
+++ b/src/settings/nm-settings-error.h
@@ -25,24 +25,24 @@
 #include <glib.h>
 #include <glib-object.h>
 
-enum {
-	NM_SETTINGS_ERROR_GENERAL = 0,
-	NM_SETTINGS_ERROR_INVALID_CONNECTION,
-	NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
-	NM_SETTINGS_ERROR_INTERNAL_ERROR,
-	NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
-	NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED,
-	NM_SETTINGS_ERROR_PERMISSION_DENIED,
-	NM_SETTINGS_ERROR_INVALID_SETTING,
-	NM_SETTINGS_ERROR_NOT_PRIVILEGED,
-	NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
-	NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED,
-	NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED,
-	NM_SETTINGS_ERROR_ADD_FAILED,
-	NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
-	NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
-	NM_SETTINGS_ERROR_UUID_EXISTS,
-};
+typedef enum {
+	NM_SETTINGS_ERROR_GENERAL = 0,                 /*< nick=GeneralError >*/
+	NM_SETTINGS_ERROR_INVALID_CONNECTION,          /*< nick=InvalidConnection >*/
+	NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,        /*< nick=ReadOnlyConnection >*/
+	NM_SETTINGS_ERROR_INTERNAL_ERROR,              /*< nick=InternalError >*/
+	NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,         /*< nick=SecretsUnavailable >*/
+	NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED,    /*< nick=SecretsRequestCanceled >*/
+	NM_SETTINGS_ERROR_PERMISSION_DENIED,           /*< nick=PermissionDenied >*/
+	NM_SETTINGS_ERROR_INVALID_SETTING,             /*< nick=InvalidSetting >*/
+	NM_SETTINGS_ERROR_NOT_PRIVILEGED,              /*< nick=NotPrivileged >*/
+	NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,           /*< nick=AddNotSupported >*/
+	NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED,        /*< nick=UpdateNotSupported >*/
+	NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED,        /*< nick=DeleteNotSupported >*/
+	NM_SETTINGS_ERROR_ADD_FAILED,                  /*< nick=AddFailed >*/
+	NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, /*< nick=SaveHostnameNotSupported >*/
+	NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,        /*< nick=SaveHostnameFailed >*/
+	NM_SETTINGS_ERROR_UUID_EXISTS,                 /*< nick=UuidExists >*/
+} NMSettingsError;
 
 #define NM_SETTINGS_ERROR (nm_settings_error_quark ())
 GQuark nm_settings_error_quark (void);
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index f0bfc162..1ead4f8b 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -29,8 +29,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <gmodule.h>
-#include <net/ethernet.h>
-#include <netinet/ether.h>
+#include <net/if_arp.h>
 #include <pwd.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
@@ -52,8 +51,11 @@
 #include <nm-setting-wired.h>
 #include <nm-setting-wireless.h>
 #include <nm-setting-wireless-security.h>
+#include <nm-setting-bond.h>
+#include <nm-utils.h>
 
 #include "../nm-device-ethernet.h"
+#include "../nm-device-wired.h"
 #include "nm-dbus-glib-types.h"
 #include "nm-settings.h"
 #include "nm-settings-connection.h"
@@ -226,36 +228,49 @@ impl_settings_list_connections (NMSettings *self,
 	return TRUE;
 }
 
-static gboolean
-impl_settings_get_connection_by_uuid (NMSettings *self,
-                                      const char *uuid,
-                                      char **out_object_path,
-                                      GError **error)
+NMSettingsConnection *
+nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid)
 {
-	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+	NMSettingsPrivate *priv;
+	NMSettingsConnection *candidate;
 	GHashTableIter iter;
-	NMConnection *candidate = NULL;
-	gboolean found = FALSE;
+
+	g_return_val_if_fail (self != NULL, NULL);
+	g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
+	g_return_val_if_fail (uuid != NULL, NULL);
+
+	priv = NM_SETTINGS_GET_PRIVATE (self);
 
 	load_connections (self);
 
 	g_hash_table_iter_init (&iter, priv->connections);
 	while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
-		if (g_strcmp0 (uuid, nm_connection_get_uuid (candidate)) == 0) {
-			*out_object_path = g_strdup (nm_connection_get_path (candidate));
-			found = TRUE;
-			break;
-		}
+		if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
+			return candidate;
 	}
 
-	if (!found) {
+	return NULL;
+}
+
+static gboolean
+impl_settings_get_connection_by_uuid (NMSettings *self,
+                                      const char *uuid,
+                                      char **out_object_path,
+                                      GError **error)
+{
+	NMSettingsConnection *connection = NULL;
+
+	connection = nm_settings_get_connection_by_uuid (self, uuid);
+	if (connection)
+		*out_object_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
+	else {
 		g_set_error_literal (error,
 		                     NM_SETTINGS_ERROR,
 		                     NM_SETTINGS_ERROR_INVALID_CONNECTION,
 		                     "No connection with the UUID was found.");
 	}
 
-	return found;
+	return !!connection;
 }
 
 static int
@@ -267,9 +282,9 @@ connection_sort (gconstpointer pa, gconstpointer pb)
 	NMSettingConnection *con_b;
 	guint64 ts_a, ts_b;
 
-	con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION);
+	con_a = nm_connection_get_setting_connection (a);
 	g_assert (con_a);
-	con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
+	con_b = nm_connection_get_setting_connection (b);
 	g_assert (con_b);
 
 	if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) {
@@ -549,6 +564,7 @@ find_plugin (GSList *list, const char *pname)
 static gboolean
 load_plugins (NMSettings *self, const char **plugins, GError **error)
 {
+	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	GSList *list = NULL;
 	const char **iter;
 	gboolean success = TRUE;
@@ -558,7 +574,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
 		char *full_name, *path;
 		const char *pname = *iter;
 		GObject *obj;
-		GObject * (*factory_func) (void);
+		GObject * (*factory_func) (const char *);
 
 		/* strip leading spaces */
 		while (isblank (*pname))
@@ -601,7 +617,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
 			break;
 		}
 
-		obj = (*factory_func) ();
+		obj = (*factory_func) (priv->config_file);
 		if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
 			g_set_error (error, 0, 0,
 			             "Plugin '%s' returned invalid system config object.",
@@ -901,6 +917,45 @@ add_new_connection (NMSettings *self,
 	return NULL;
 }
 
+static gboolean
+secrets_filter_cb (NMSetting *setting,
+                   const char *secret,
+                   NMSettingSecretFlags flags,
+                   gpointer user_data)
+{
+	NMSettingSecretFlags filter_flags = GPOINTER_TO_UINT (user_data);
+
+	/* Returns TRUE to remove the secret */
+
+	/* Can't use bitops with SECRET_FLAG_NONE so handle that specifically */
+	if (   (flags == NM_SETTING_SECRET_FLAG_NONE)
+	    && (filter_flags == NM_SETTING_SECRET_FLAG_NONE))
+		return FALSE;
+
+	/* Otherwise if the secret has at least one of the desired flags keep it */
+	return (flags & filter_flags) ? FALSE : TRUE;
+}
+
+static void
+send_agent_owned_secrets (NMSettings *self,
+                          NMSettingsConnection *connection,
+                          gulong caller_uid)
+{
+	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+	NMConnection *for_agent;
+
+	/* Dupe the connection so we can clear out non-agent-owned secrets,
+	 * as agent-owned secrets are the only ones we send back to be saved.
+	 * Only send secrets to agents of the same UID that called update too.
+	 */
+	for_agent = nm_connection_duplicate (NM_CONNECTION (connection));
+	nm_connection_clear_secrets_with_flags (for_agent,
+	                                        secrets_filter_cb,
+	                                        GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED));
+	nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, caller_uid);
+	g_object_unref (for_agent);
+}
+
 static void
 pk_add_cb (NMAuthChain *chain,
            GError *chain_error,
@@ -915,6 +970,7 @@ pk_add_cb (NMAuthChain *chain,
 	NMSettingsConnection *added = NULL;
 	NMSettingsAddCallback callback;
 	gpointer callback_data;
+	gulong caller_uid;
 	const char *perm;
 
 	priv->auths = g_slist_remove (priv->auths, chain);
@@ -954,9 +1010,14 @@ pk_add_cb (NMAuthChain *chain,
 done:
 	callback = nm_auth_chain_get_data (chain, "callback");
 	callback_data = nm_auth_chain_get_data (chain, "callback-data");
+	caller_uid = nm_auth_chain_get_data_ulong (chain, "caller-uid");
 
 	callback (self, added, error, context, callback_data);
 
+	/* Send agent-owned secrets to the agents */
+	if (!error && added)
+		send_agent_owned_secrets (self, added, caller_uid);
+
 	g_clear_error (&error);
 	nm_auth_chain_unref (chain);
 }
@@ -974,6 +1035,38 @@ add_cb (NMSettings *self,
 		dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
 }
 
+/* FIXME: remove if/when kernel supports adhoc wpa */
+static gboolean
+is_adhoc_wpa (NMConnection *connection)
+{
+	NMSettingWireless *s_wifi;
+	NMSettingWirelessSecurity *s_wsec;
+	const char *mode, *key_mgmt;
+
+	/* The kernel doesn't support Ad-Hoc WPA connections well at this time,
+	 * and turns them into open networks.  It's been this way since at least
+	 * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks.
+	 */
+
+	s_wifi = nm_connection_get_setting_wireless (connection);
+	if (!s_wifi)
+		return FALSE;
+
+	mode = nm_setting_wireless_get_mode (s_wifi);
+	if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) != 0)
+		return FALSE;
+
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	if (!s_wsec)
+		return FALSE;
+
+	key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+	if (g_strcmp0 (key_mgmt, "wpa-none") != 0)
+		return FALSE;
+
+	return TRUE;
+}
+
 void
 nm_settings_add_connection (NMSettings *self,
                             NMConnection *connection,
@@ -1001,6 +1094,19 @@ nm_settings_add_connection (NMSettings *self,
 		return;
 	}
 
+	/* The kernel doesn't support Ad-Hoc WPA connections well at this time,
+	 * and turns them into open networks.  It's been this way since at least
+	 * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks.
+	 */
+	if (is_adhoc_wpa (connection)) {
+		error = g_error_new_literal (NM_SETTINGS_ERROR,
+		                             NM_SETTINGS_ERROR_INVALID_CONNECTION,
+		                             "WPA Ad-Hoc disabled due to kernel bugs");
+		callback (self, NULL, error, context, user_data);
+		g_error_free (error);
+		return;
+	}
+
 	/* Do any of the plugins support adding? */
 	if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
 		error = g_error_new_literal (NM_SETTINGS_ERROR,
@@ -1044,7 +1150,7 @@ nm_settings_add_connection (NMSettings *self,
 	 * we use the 'modify.own' permission instead of 'modify.system'.  If the
 	 * request affects more than just the caller, require 'modify.system'.
 	 */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
 	if (nm_setting_connection_get_num_permissions (s_con) == 1)
 		perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
@@ -1060,6 +1166,7 @@ nm_settings_add_connection (NMSettings *self,
 	nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref);
 	nm_auth_chain_set_data (chain, "callback", callback, NULL);
 	nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
+	nm_auth_chain_set_data_ulong (chain, "caller-uid", caller_uid);
 }
 
 static void
@@ -1172,13 +1279,14 @@ impl_settings_save_hostname (NMSettings *self,
 }
 
 static gboolean
-have_connection_for_device (NMSettings *self, GByteArray *mac)
+have_connection_for_device (NMSettings *self, GByteArray *mac, NMDevice *device)
 {
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	GHashTableIter iter;
 	gpointer data;
 	NMSettingConnection *s_con;
 	NMSettingWired *s_wired;
+	NMSettingInfiniband *s_infiniband;
 	const GByteArray *setting_mac;
 	gboolean ret = FALSE;
 
@@ -1189,16 +1297,27 @@ have_connection_for_device (NMSettings *self, GByteArray *mac)
 	g_hash_table_iter_init (&iter, priv->connections);
 	while (g_hash_table_iter_next (&iter, NULL, &data)) {
 		NMConnection *connection = NM_CONNECTION (data);
-		const char *ctype;
+		const char *ctype, *iface;
 
 		s_con = nm_connection_get_setting_connection (connection);
 		ctype = nm_setting_connection_get_connection_type (s_con);
 
+		iface = nm_connection_get_virtual_iface_name (connection);
+		if (iface) {
+			if (!strcmp (iface, nm_device_get_iface (device))) {
+				ret = TRUE;
+				break;
+			} else
+				continue;
+		}
+
 		if (   strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)
+		    && strcmp (ctype, NM_SETTING_INFINIBAND_SETTING_NAME)
 		    && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME))
 			continue;
 
 		s_wired = nm_connection_get_setting_wired (connection);
+		s_infiniband = nm_connection_get_setting_infiniband (connection);
 
 		/* No wired setting; therefore the PPPoE connection applies to any device */
 		if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) {
@@ -1206,10 +1325,15 @@ have_connection_for_device (NMSettings *self, GByteArray *mac)
 			break;
 		}
 
-		setting_mac = nm_setting_wired_get_mac_address (s_wired);
+		g_assert (s_wired != NULL || s_infiniband != NULL);
+
+		setting_mac = s_wired ?
+			nm_setting_wired_get_mac_address (s_wired) :
+			nm_setting_infiniband_get_mac_address (s_infiniband);
 		if (setting_mac) {
 			/* A connection mac-locked to this device */
-			if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) {
+			if (mac->len == setting_mac->len &&
+				!memcmp (setting_mac->data, mac->data, mac->len)) {
 				ret = TRUE;
 				break;
 			}
@@ -1225,7 +1349,7 @@ have_connection_for_device (NMSettings *self, GByteArray *mac)
 
 /* Search through the list of blacklisted MAC addresses in the config file. */
 static gboolean
-is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac)
+is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac, int hwaddr_type)
 {
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	GKeyFile *config;
@@ -1249,15 +1373,15 @@ is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac)
 
 	list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL);
 	for (iter = list; iter && *iter; iter++) {
-		struct ether_addr *candidate;
+		guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX];
 
-		if (strcmp(g_strstrip(*iter), "*") == 0) {
+		if (strcmp (g_strstrip (*iter), "*") == 0) {
 			found = TRUE;
 			break;
 		}
 
-		candidate = ether_aton (*iter);
-		if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
+		candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer);
+		if (candidate && !memcmp (mac->data, candidate, mac->len)) {
 			found = TRUE;
 			break;
 		}
@@ -1280,6 +1404,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
 {
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	NMSettingConnection *s_con;
+	int hwaddr_type;
 	char *tmp;
 	GKeyFile *config;
 	char **list, **iter, **updated;
@@ -1297,8 +1422,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
 	 * connection for that device again.
 	 */
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
-	                                                           NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (NM_CONNECTION (wired));
 	g_assert (s_con);
 
 	/* Ignore removals of read-only connections, since they couldn't have
@@ -1311,20 +1435,27 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
 	if (!config)
 		goto cleanup;
 
+	if (nm_connection_get_setting_wired (NM_CONNECTION (wired)))
+		hwaddr_type = ARPHRD_ETHER;
+	else if (nm_connection_get_setting_infiniband (NM_CONNECTION (wired)))
+		hwaddr_type = ARPHRD_INFINIBAND;
+	else
+		goto cleanup;
+
 	g_key_file_set_list_separator (config, ',');
 	g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL);
 
 	list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL);
 	for (iter = list; iter && *iter; iter++) {
-		struct ether_addr *candidate;
+		guint8 *candidate, buffer[NM_UTILS_HWADDR_LEN_MAX];
 
-		if (strcmp(g_strstrip(*iter), "*") == 0) {
+		if (strcmp (g_strstrip (*iter), "*") == 0) {
 			found = TRUE;
 			break;
 		}
 
-		candidate = ether_aton (*iter);
-		if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
+		candidate = nm_utils_hwaddr_aton (*iter, hwaddr_type, buffer);
+		if (candidate && !memcmp (mac->data, candidate, mac->len)) {
 			found = TRUE;
 			break;
 		}
@@ -1332,9 +1463,7 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
 
 	/* Add this device's MAC to the list */
 	if (!found) {
-		tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
-		                       mac->data[0], mac->data[1], mac->data[2],
-		                       mac->data[3], mac->data[4], mac->data[5]);
+		tmp = nm_utils_hwaddr_ntoa (mac->data, hwaddr_type);
 
 		/* New list; size + 1 for the new element, + 1 again for ending NULL */
 		updated = g_malloc0 (sizeof (char*) * (len + 2));
@@ -1424,13 +1553,14 @@ nm_settings_device_added (NMSettings *self, NMDevice *device)
 {
 	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
 	GByteArray *mac = NULL;
-	struct ether_addr tmp;
+	const guint8 *hwaddr;
+	int hwaddr_type;
 	NMDefaultWiredConnection *wired;
 	gboolean read_only = TRUE;
 	const char *id;
 	char *defname;
 
-	if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
+	if (!NM_IS_DEVICE_WIRED (device))
 		return;
 
 	/* If the device isn't managed or it already has a default wired connection,
@@ -1440,13 +1570,14 @@ nm_settings_device_added (NMSettings *self, NMDevice *device)
 	    || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG))
 		return;
 
-	nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp);
+	hwaddr = nm_device_wired_get_hwaddr (NM_DEVICE_WIRED (device));
+	hwaddr_type = nm_device_wired_get_hwaddr_type (NM_DEVICE_WIRED (device));
 
-	mac = g_byte_array_sized_new (ETH_ALEN);
-	g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN);
+	mac = g_byte_array_new ();
+	g_byte_array_append (mac, hwaddr, nm_utils_hwaddr_len (hwaddr_type));
 
-	if (   have_connection_for_device (self, mac)
-	    || is_mac_auto_wired_blacklisted (self, mac))
+	if (   have_connection_for_device (self, mac, device)
+		|| is_mac_auto_wired_blacklisted (self, mac, hwaddr_type))
 		goto ignore;
 
 	if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
@@ -1480,7 +1611,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device)
 {
 	NMDefaultWiredConnection *connection;
 
-	if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
+	if (!NM_IS_DEVICE_WIRED (device))
 		return;
 
 	connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
@@ -1518,7 +1649,7 @@ nm_settings_new (const char *config_file,
 	}
 
 	/* Add the keyfile plugin last */
-	keyfile_plugin = nm_settings_keyfile_plugin_new ();
+	keyfile_plugin = nm_settings_keyfile_plugin_new (config_file);
 	g_assert (keyfile_plugin);
 	add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin));
 
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 77485e19..9a02f8fe 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -108,6 +108,9 @@ GSList *nm_settings_get_connections (NMSettings *settings);
 NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings,
                                                           const char *path);
 
+NMSettingsConnection *nm_settings_get_connection_by_uuid (NMSettings *settings,
+                                                          const char *uuid);
+
 const GSList *nm_settings_get_unmanaged_specs (NMSettings *self);
 
 char *nm_settings_get_hostname (NMSettings *self);
diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h
index 96a64061..bbe74d49 100644
--- a/src/settings/nm-system-config-interface.h
+++ b/src/settings/nm-system-config-interface.h
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 /* Plugin's factory function that returns a GObject that implements
  * NMSystemConfigInterface.
  */
-GObject * nm_system_config_factory (void);
+GObject * nm_system_config_factory (const char *config_file);
 
 #define NM_TYPE_SYSTEM_CONFIG_INTERFACE      (nm_system_config_interface_get_type ())
 #define NM_SYSTEM_CONFIG_INTERFACE(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface))
diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in
index 7c9c8784..0997f445 100644
--- a/src/settings/plugins/Makefile.in
+++ b/src/settings/plugins/Makefile.in
@@ -152,6 +152,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -206,11 +208,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -221,6 +227,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -260,6 +267,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.am b/src/settings/plugins/ifcfg-rh/Makefile.am
index 9874d352..8b5b0f24 100644
--- a/src/settings/plugins/ifcfg-rh/Makefile.am
+++ b/src/settings/plugins/ifcfg-rh/Makefile.am
@@ -23,11 +23,12 @@ libifcfg_rh_io_la_SOURCES = \
 	utils.h
 
 INCLUDES = \
+	-I$(top_srcdir)/src/wifi \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-glib \
-	-I$(top_srcdir)/libnm-util \
-	-I$(top_builddir)/marshallers
+	-I$(top_srcdir)/libnm-util
 
 libifcfg_rh_io_la_CPPFLAGS = \
 	$(GLIB_CFLAGS) \
@@ -38,6 +39,7 @@ libifcfg_rh_io_la_CPPFLAGS = \
 	-DSBINDIR=\"$(sbindir)\"
 
 libifcfg_rh_io_la_LIBADD = \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(GLIB_LIBS) \
 	$(NSS_LIBS)
@@ -59,7 +61,6 @@ libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version
 libnm_settings_plugin_ifcfg_rh_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(top_builddir)/libnm-glib/libnm-glib.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
 	libifcfg-rh-io.la \
 	$(GLIB_LIBS) \
 	$(GMODULE_LIBS) \
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in
index 79b66b2d..3325c7e8 100644
--- a/src/settings/plugins/ifcfg-rh/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/Makefile.in
@@ -81,6 +81,7 @@ am__installdirs = "$(DESTDIR)$(pkglibdir)" \
 LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libifcfg_rh_io_la_DEPENDENCIES =  \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
 am_libifcfg_rh_io_la_OBJECTS = libifcfg_rh_io_la-shvar.lo \
@@ -92,9 +93,8 @@ am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
 am__v_lt_0 = --silent
 libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES =  \
 	$(top_builddir)/libnm-util/libnm-util.la \
-	$(top_builddir)/libnm-glib/libnm-glib.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
-	libifcfg-rh-io.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(top_builddir)/libnm-glib/libnm-glib.la libifcfg-rh-io.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
 am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS =  \
 	libnm_settings_plugin_ifcfg_rh_la-plugin.lo \
@@ -222,6 +222,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -276,11 +278,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -291,6 +297,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -330,6 +337,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -412,11 +421,12 @@ libifcfg_rh_io_la_SOURCES = \
 	utils.h
 
 INCLUDES = \
+	-I$(top_srcdir)/src/wifi \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-glib \
-	-I$(top_srcdir)/libnm-util \
-	-I$(top_builddir)/marshallers
+	-I$(top_srcdir)/libnm-util
 
 libifcfg_rh_io_la_CPPFLAGS = \
 	$(GLIB_CFLAGS) \
@@ -427,6 +437,7 @@ libifcfg_rh_io_la_CPPFLAGS = \
 	-DSBINDIR=\"$(sbindir)\"
 
 libifcfg_rh_io_la_LIBADD = \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(GLIB_LIBS) \
 	$(NSS_LIBS)
@@ -448,7 +459,6 @@ libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version
 libnm_settings_plugin_ifcfg_rh_la_LIBADD = \
 	$(top_builddir)/libnm-util/libnm-util.la \
 	$(top_builddir)/libnm-glib/libnm-glib.la \
-	$(top_builddir)/marshallers/libmarshallers.la \
 	libifcfg-rh-io.la \
 	$(GLIB_LIBS) \
 	$(GMODULE_LIBS) \
diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h
index 74a77c4c..fc8ce22a 100644
--- a/src/settings/plugins/ifcfg-rh/common.h
+++ b/src/settings/plugins/ifcfg-rh/common.h
@@ -15,7 +15,7 @@
  * 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 - 2010 Red Hat, Inc.
+ * (C) Copyright 2008 - 2011 Red Hat, Inc.
  */
 
 #ifndef __COMMON_H__
@@ -41,9 +41,12 @@
 #define IFCFG_PLUGIN_NAME "ifcfg-rh"
 #define IFCFG_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc.  To report bugs please use the NetworkManager mailing list."
 
-#define TYPE_ETHERNET "Ethernet"
-#define TYPE_WIRELESS "Wireless"
-#define TYPE_BRIDGE   "Bridge"
+#define TYPE_ETHERNET   "Ethernet"
+#define TYPE_WIRELESS   "Wireless"
+#define TYPE_INFINIBAND "InfiniBand"
+#define TYPE_BRIDGE     "Bridge"
+#define TYPE_BOND       "Bond"
+#define TYPE_VLAN       "Vlan"
 
 #define SECRET_FLAG_AGENT "user"
 #define SECRET_FLAG_NOT_SAVED "ask"
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index b4be4cba..04d5463c 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -569,7 +569,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
 		return FALSE;
 	}
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
 	if (!s_con) {
 		g_set_error (error,
 		             NM_SETTINGS_ERROR,
@@ -790,7 +790,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
 }
 
 G_MODULE_EXPORT GObject *
-nm_system_config_factory (void)
+nm_system_config_factory (const char *config_file)
 {
 	static SCPluginIfcfg *singleton = NULL;
 	SCPluginIfcfgPrivate *priv;
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 910cca35..01d83c1b 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ * Copyright (C) 2008 - 2012 Red Hat, Inc.
  */
 
 #include <config.h>
@@ -33,25 +33,22 @@
 #include <netinet/ether.h>
 #include <linux/if.h>
 
-#ifndef __user
-#define __user
-#endif
-#include <linux/types.h>
-#include <wireless.h>
-#undef __user
-
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <nm-connection.h>
 #include <NetworkManager.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-ip4-config.h>
+#include <nm-setting-vlan.h>
 #include <nm-setting-ip6-config.h>
 #include <nm-setting-wired.h>
 #include <nm-setting-wireless.h>
 #include <nm-setting-8021x.h>
+#include <nm-setting-bond.h>
 #include <nm-utils.h>
 
+#include "wifi-utils.h"
+
 #include "common.h"
 #include "shvar.h"
 #include "utils.h"
@@ -77,16 +74,46 @@ get_int (const char *str, int *value)
 	return TRUE;
 }
 
+static char *
+make_connection_name (shvarFile *ifcfg,
+                      const char *ifcfg_name,
+                      const char *suggested,
+                      const char *prefix)
+{
+	char *full_name = NULL, *name;
+
+	/* If the ifcfg file already has a NAME, always use that */
+	name = svGetValue (ifcfg, "NAME", FALSE);
+	if (name && strlen (name))
+		return name;
+
+	/* Otherwise construct a new NAME */
+	g_free (name);
+	if (!prefix)
+		prefix = _("System");
+
+	/* For cosmetic reasons, if the suggested name is the same as
+	 * the ifcfg files name, don't use it.  Mainly for wifi so that
+	 * the SSID is shown in the connection ID instead of just "wlan0".
+	 */
+	if (suggested && strcmp (ifcfg_name, suggested))
+		full_name = g_strdup_printf ("%s %s (%s)", prefix, suggested, ifcfg_name);
+	else
+		full_name = g_strdup_printf ("%s %s", prefix, ifcfg_name);
+
+	return full_name;
+}
+
 static NMSetting *
 make_connection_setting (const char *file,
                          shvarFile *ifcfg,
                          const char *type,
-                         const char *suggested)
+                         const char *suggested,
+                         const char *prefix)
 {
 	NMSettingConnection *s_con;
 	const char *ifcfg_name = NULL;
-	char *new_id = NULL, *uuid = NULL, *value;
-	char *ifcfg_id;
+	char *new_id, *uuid = NULL, *zone = NULL, *value;
 
 	ifcfg_name = utils_get_ifcfg_name (file, TRUE);
 	if (!ifcfg_name)
@@ -94,32 +121,9 @@ make_connection_setting (const char *file,
 
 	s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
 
-	/* Try the ifcfg file's internally defined name if available */
-	ifcfg_id = svGetValue (ifcfg, "NAME", FALSE);
-	if (ifcfg_id && strlen (ifcfg_id))
-		g_object_set (s_con, NM_SETTING_CONNECTION_ID, ifcfg_id, NULL);
-
-	if (!nm_setting_connection_get_id (s_con)) {
-		if (suggested) {
-			/* For cosmetic reasons, if the suggested name is the same as
-			 * the ifcfg files name, don't use it.  Mainly for wifi so that
-			 * the SSID is shown in the connection ID instead of just "wlan0".
-			 */
-			if (strcmp (ifcfg_name, suggested)) {
-				new_id = g_strdup_printf ("%s %s (%s)", reader_get_prefix (), suggested, ifcfg_name);
-				g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
-			}
-		}
-
-		/* Use the ifcfg file's name as a last resort */
-		if (!nm_setting_connection_get_id (s_con)) {
-			new_id = g_strdup_printf ("%s %s", reader_get_prefix (), ifcfg_name);
-			g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
-		}
-	}
-
+	new_id = make_connection_name (ifcfg, ifcfg_name, suggested, prefix);
+	g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
 	g_free (new_id);
-	g_free (ifcfg_id);
 
 	/* Try for a UUID key before falling back to hashing the file name */
 	uuid = svGetValue (ifcfg, "UUID", FALSE);
@@ -127,6 +131,7 @@ make_connection_setting (const char *file,
 		g_free (uuid);
 		uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName);
 	}
+
 	g_object_set (s_con,
 	              NM_SETTING_CONNECTION_TYPE, type,
 	              NM_SETTING_CONNECTION_UUID, uuid,
@@ -153,14 +158,23 @@ make_connection_setting (const char *file,
 		g_strfreev (items);
 	}
 
+
+	zone = svGetValue(ifcfg, "ZONE", FALSE);
+	if (!zone || !strlen (zone)) {
+		g_free (zone);
+		zone = NULL;
+	}
+	g_object_set (s_con, NM_SETTING_CONNECTION_ZONE, zone, NULL);
+	g_free (zone);
+
 	return NM_SETTING (s_con);
 }
 
 static gboolean
-read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error)
+read_mac_address (shvarFile *ifcfg, const char *key, int type,
+                  GByteArray **array, GError **error)
 {
 	char *value = NULL;
-	struct ether_addr *mac;
 
 	g_return_val_if_fail (ifcfg != NULL, FALSE);
 	g_return_val_if_fail (array != NULL, FALSE);
@@ -174,8 +188,8 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError
 		return TRUE;
 	}
 
-	mac = ether_aton (value);
-	if (!mac) {
+	*array = nm_utils_hwaddr_atoba (value, type);
+	if (!*array) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "%s: the MAC address '%s' was invalid.", key, value);
 		g_free (value);
@@ -183,8 +197,6 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError
 	}
 
 	g_free (value);
-	*array = g_byte_array_sized_new (ETH_ALEN);
-	g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN);
 	return TRUE;
 }
 
@@ -266,7 +278,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg,
 		goto done;
 	}
 
-	if (!read_mac_address (ifcfg, "HWADDR", &ifcfg_mac, error))
+	if (!read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &ifcfg_mac, error))
 		goto done;
 	/* Ensure we got a MAC */
 	if (!ifcfg_mac) {
@@ -627,7 +639,6 @@ read_one_ip4_route (shvarFile *ifcfg,
 
 	g_return_val_if_fail (ifcfg != NULL, NULL);
 	g_return_val_if_fail (network_file != NULL, NULL);
-	g_return_val_if_fail (which >= 0, NULL);
 
 	route = nm_ip4_route_new ();
 
@@ -1115,7 +1126,7 @@ static NMSetting *
 make_ip4_setting (shvarFile *ifcfg,
                   const char *network_file,
                   const char *iscsiadm_path,
-                  gboolean valid_ip6_config,
+                  gboolean can_disable_ip4,
                   GError **error)
 {
 	NMSettingIP4Config *s_ip4 = NULL;
@@ -1230,7 +1241,7 @@ make_ip4_setting (shvarFile *ifcfg,
 		    && !tmp_ip4_0 && !tmp_prefix_0 && !tmp_netmask_0
 		    && !tmp_ip4_1 && !tmp_prefix_1 && !tmp_netmask_1
 		    && !tmp_ip4_2 && !tmp_prefix_2 && !tmp_netmask_2) {
-			if (valid_ip6_config)
+			if (can_disable_ip4)
 				/* Nope, no IPv4 */
 				method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
 			else
@@ -1255,7 +1266,7 @@ make_ip4_setting (shvarFile *ifcfg,
 	              NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE),
 	              NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE),
 	              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
-	              NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", TRUE),
+	              NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE),
 	              NULL);
 
 	if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
@@ -1424,6 +1435,9 @@ make_ip6_setting (shvarFile *ifcfg,
 	guint32 i;
 	shvarFile *network_ifcfg;
 	gboolean never_default = FALSE, tmp_success;
+	gboolean ip6_privacy, ip6_privacy_prefer_public_ip;
+	char *ip6_privacy_str;
+	NMSettingIP6ConfigPrivacy ip6_privacy_val;
 
 	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
 	if (!s_ip6) {
@@ -1510,12 +1524,29 @@ make_ip6_setting (shvarFile *ifcfg,
 	}
 	/* TODO - handle other methods */
 
+	/* Read IPv6 Privacy Extensions configuration */
+	ip6_privacy_str = svGetValue (ifcfg, "IPV6_PRIVACY", FALSE);
+	if (ip6_privacy_str) {
+		ip6_privacy = svTrueValue (ifcfg, "IPV6_PRIVACY", FALSE);
+		if (!ip6_privacy)
+			ip6_privacy = g_strcmp0 (ip6_privacy_str, "rfc4941") == 0 ||
+			              g_strcmp0 (ip6_privacy_str, "rfc3041") == 0;
+	}
+	ip6_privacy_prefer_public_ip = svTrueValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE);
+	ip6_privacy_val = ip6_privacy_str ?
+	                      (ip6_privacy ?
+	                          (ip6_privacy_prefer_public_ip ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) :
+	                          NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) :
+	                      NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN;
+	g_free (ip6_privacy_str);
+
 	g_object_set (s_ip6,
 	              NM_SETTING_IP6_CONFIG_METHOD, method,
 	              NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE),
 	              NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE),
 	              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
 	              NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
+	              NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val,
 	              NULL);
 
 	/* Don't bother to read IP, DNS and routes when IPv6 is disabled */
@@ -1926,6 +1957,7 @@ parse_wpa_psk (shvarFile *ifcfg,
 {
 	shvarFile *keys_ifcfg;
 	char *psk = NULL, *p, *hashed = NULL;
+	size_t plen;
 	gboolean quoted = FALSE;
 
 	/* Passphrase must be between 10 and 66 characters in length because WPA
@@ -1949,8 +1981,10 @@ parse_wpa_psk (shvarFile *ifcfg,
 		return NULL;
 
 	p = psk;
+	plen = strlen (p);
 
-	if (p[0] == '"' && psk[strlen (psk) - 1] == '"')
+	if (   (plen >= 2 && (p[0] == '"' || p[0] == '\'') && p[0] == p[plen - 1])
+	    || (plen >= 3 && p[0] == '$' && p[1] == '\'' && p[1] == p[plen - 1]))
 		quoted = TRUE;
 
 	if (!quoted && (strlen (psk) == 64)) {
@@ -1970,21 +2004,18 @@ parse_wpa_psk (shvarFile *ifcfg,
 		 * and between 8 and 63 characters as a passphrase.
 		 */
 
-		if (quoted) {
-			/* Get rid of the quotes */
-			p++;
-			p[strlen (p) - 1] = '\0';
-		}
+		/* Get rid of the quotes */
+		hashed = utils_single_unquote_string (p);
 
 		/* Length check */
-		if (strlen (p) < 8 || strlen (p) > 63) {
+		if (strlen (hashed) < 8 || strlen (hashed) > 63) {
 			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 			             "Invalid WPA_PSK (passphrases must be between "
 			             "8 and 63 characters long (inclusive))");
+			g_free (hashed);
+			hashed = NULL;
 			goto out;
 		}
-
-		hashed = g_strdup (p);
 	}
 
 	if (!hashed) {
@@ -2045,18 +2076,18 @@ eap_simple_reader (const char *eap_method,
 }
 
 static char *
-get_cert_file (const char *ifcfg_path, const char *cert_path)
+get_full_file_path (const char *ifcfg_path, const char *file_path)
 {
-	const char *base = cert_path;
+	const char *base = file_path;
 	char *p, *ret, *dirname;
 
 	g_return_val_if_fail (ifcfg_path != NULL, NULL);
-	g_return_val_if_fail (cert_path != NULL, NULL);
+	g_return_val_if_fail (file_path != NULL, NULL);
 
-	if (cert_path[0] == '/')
-		return g_strdup (cert_path);
+	if (file_path[0] == '/')
+		return g_strdup (file_path);
 
-	p = strrchr (cert_path, '/');
+	p = strrchr (file_path, '/');
 	if (p)
 		base = p + 1;
 
@@ -2102,7 +2133,7 @@ eap_tls_reader (const char *eap_method,
 
 	ca_cert = svGetValue (ifcfg, ca_cert_key, FALSE);
 	if (ca_cert) {
-		real_path = get_cert_file (ifcfg->fileName, ca_cert);
+		real_path = get_full_file_path (ifcfg->fileName, ca_cert);
 		if (phase2) {
 			if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
 			                                           real_path,
@@ -2159,7 +2190,7 @@ eap_tls_reader (const char *eap_method,
 		goto done;
 	}
 
-	real_path = get_cert_file (ifcfg->fileName, privkey);
+	real_path = get_full_file_path (ifcfg->fileName, privkey);
 	if (phase2) {
 		if (!nm_setting_802_1x_set_phase2_private_key (s_8021x,
 		                                               real_path,
@@ -2196,7 +2227,7 @@ eap_tls_reader (const char *eap_method,
 			goto done;
 		}
 
-		real_path = get_cert_file (ifcfg->fileName, client_cert);
+		real_path = get_full_file_path (ifcfg->fileName, client_cert);
 		if (phase2) {
 			if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x,
 			                                               real_path,
@@ -2246,7 +2277,7 @@ eap_peap_reader (const char *eap_method,
 
 	ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
 	if (ca_cert) {
-		real_cert_path = get_cert_file (ifcfg->fileName, ca_cert);
+		real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert);
 		if (!nm_setting_802_1x_set_ca_cert (s_8021x,
 		                                    real_cert_path,
 		                                    NM_SETTING_802_1X_CK_SCHEME_PATH,
@@ -2352,7 +2383,7 @@ eap_ttls_reader (const char *eap_method,
 
 	ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
 	if (ca_cert) {
-		real_cert_path = get_cert_file (ifcfg->fileName, ca_cert);
+		real_cert_path = get_full_file_path (ifcfg->fileName, ca_cert);
 		if (!nm_setting_802_1x_set_ca_cert (s_8021x,
 		                                    real_cert_path,
 		                                    NM_SETTING_802_1X_CK_SCHEME_PATH,
@@ -2422,6 +2453,111 @@ done:
 	return success;
 }
 
+static gboolean
+eap_fast_reader (const char *eap_method,
+                 shvarFile *ifcfg,
+                 shvarFile *keys,
+                 NMSetting8021x *s_8021x,
+                 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;
+	char **list = NULL, **iter;
+	const char* pac_prov_str;
+	gboolean allow_unauth = FALSE, allow_auth = FALSE;
+	gboolean success = FALSE;
+
+	pac_file = svGetValue (ifcfg, "IEEE_8021X_PAC_FILE", FALSE);
+	if (pac_file) {
+		real_pac_path = get_full_file_path (ifcfg->fileName, pac_file);
+		g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, real_pac_path, NULL);
+	}
+
+	fast_provisioning = svGetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", FALSE);
+	if (fast_provisioning) {
+		list = g_strsplit_set (fast_provisioning, " \t", 0);
+		for (iter = list; iter && *iter; iter++) {
+			if (**iter == '\0')
+				continue;
+			if (strcmp (*iter, "allow-unauth") == 0)
+				allow_unauth = TRUE;
+			else if (strcmp (*iter, "allow-auth") == 0)
+				allow_auth = TRUE;
+			else {
+				PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: invalid IEEE_8021X_FAST_PROVISIONING '%s' "
+				             "(space-separated list of these values [allow-auth, allow-unauth] expected)",
+				             *iter);
+			}
+		}
+		g_strfreev (list);
+		list = NULL;
+	}
+	pac_prov_str = allow_unauth ? (allow_auth ? "3" : "1") : (allow_auth ? "2" : "0");
+	g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL);
+
+	if (!pac_file && !(allow_unauth || allow_auth)) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled.");
+		goto done;
+	}
+
+	anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE);
+	if (anon_ident && strlen (anon_ident))
+		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
+
+	inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
+	if (!inner_auth) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+		goto done;
+	}
+
+	/* Handle options for the inner auth method */
+	list = g_strsplit (inner_auth, " ", 0);
+	for (iter = list; iter && *iter; iter++) {
+		if (!strlen (*iter))
+			continue;
+
+		if (   !strcmp (*iter, "MSCHAPV2")
+		    || !strcmp (*iter, "GTC")) {
+			if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+				goto done;
+		} else {
+			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+			             "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);
+		break;
+	}
+
+	if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "No valid IEEE_8021X_INNER_AUTH_METHODS found.");
+		goto done;
+	}
+
+	success = TRUE;
+
+done:
+	g_strfreev (list);
+	g_free (inner_auth);
+	g_free (fast_provisioning);
+	g_free (real_pac_path);
+	g_free (pac_file);
+	g_free (anon_ident);
+	return success;
+}
+
 typedef struct {
 	const char *method;
 	gboolean (*reader)(const char *eap_method,
@@ -2443,6 +2579,7 @@ static EAPReader eap_readers[] = {
 	{ "tls", eap_tls_reader, FALSE },
 	{ "peap", eap_peap_reader, FALSE },
 	{ "ttls", eap_ttls_reader, FALSE },
+	{ "fast", eap_fast_reader, FALSE },
 	{ NULL, NULL }
 };
 
@@ -2749,7 +2886,7 @@ make_wireless_setting (shvarFile *ifcfg,
 
 	s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
 
-	if (read_mac_address (ifcfg, "HWADDR", &array, error)) {
+	if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &array, error)) {
 		if (array) {
 			g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL);
 
@@ -2773,7 +2910,7 @@ make_wireless_setting (shvarFile *ifcfg,
 	}
 
 	array = NULL;
-	if (read_mac_address (ifcfg, "MACADDR", &array, error)) {
+	if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &array, error)) {
 		if (array) {
 			g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL);
 			g_byte_array_free (array, TRUE);
@@ -2901,19 +3038,16 @@ make_wireless_setting (shvarFile *ifcfg,
 
 	value = svGetValue (ifcfg, "BSSID", FALSE);
 	if (value) {
-		struct ether_addr *eth;
 		GByteArray *bssid;
 
-		eth = ether_aton (value);
-		if (!eth) {
+		bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
+		if (!bssid) {
 			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 			             "Invalid BSSID '%s'", value);
 			g_free (value);
 			goto error;
 		}
 
-		bssid = g_byte_array_sized_new (ETH_ALEN);
-		g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN);
 		g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL);
 		g_byte_array_free (bssid, TRUE);
 		g_free (value);
@@ -3032,7 +3166,7 @@ wireless_connection_from_ifcfg (const char *file,
 	/* Connection */
 	con_setting = make_connection_setting (file, ifcfg,
 	                                       NM_SETTING_WIRELESS_SETTING_NAME,
-	                                       printable_ssid);
+	                                       printable_ssid, NULL);
 	g_free (printable_ssid);
 	if (!con_setting) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
@@ -3082,7 +3216,7 @@ make_wired_setting (shvarFile *ifcfg,
 		g_free (value);
 	}
 
-	if (read_mac_address (ifcfg, "HWADDR", &mac, error)) {
+	if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &mac, error)) {
 		if (mac) {
 			g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
 
@@ -3193,7 +3327,7 @@ make_wired_setting (shvarFile *ifcfg,
 	}
 
 	mac = NULL;
-	if (read_mac_address (ifcfg, "MACADDR", &mac, error)) {
+	if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &mac, error)) {
 		if (mac) {
 			g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL);
 			g_byte_array_free (mac, TRUE);
@@ -3260,6 +3394,7 @@ wired_connection_from_ifcfg (const char *file,
 	NMSetting *con_setting = NULL;
 	NMSetting *wired_setting = NULL;
 	NMSetting8021x *s_8021x = NULL;
+	char *value;
 
 	g_return_val_if_fail (file != NULL, NULL);
 	g_return_val_if_fail (ifcfg != NULL, NULL);
@@ -3271,7 +3406,7 @@ wired_connection_from_ifcfg (const char *file,
 		return NULL;
 	}
 
-	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL);
+	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL);
 	if (!con_setting) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Failed to create connection setting.");
@@ -3280,6 +3415,238 @@ wired_connection_from_ifcfg (const char *file,
 	}
 	nm_connection_add_setting (connection, con_setting);
 
+	/* Might be a bond slave; handle master device or connection */
+	value = svGetValue (ifcfg, "MASTER", FALSE);
+	if (value) {
+		g_object_set (con_setting, NM_SETTING_CONNECTION_MASTER, value, NULL);
+		g_object_set (con_setting,
+		              NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME,
+		              NULL);
+		g_free (value);
+	}
+
+	wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error);
+	if (!wired_setting) {
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, wired_setting);
+
+	if (s_8021x)
+		nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+	if (!nm_connection_verify (connection, error)) {
+		g_object_unref (connection);
+		return NULL;
+	}
+
+	return connection;
+}
+
+static NMSetting *
+make_infiniband_setting (shvarFile *ifcfg,
+                         const char *file,
+                         gboolean nm_controlled,
+                         char **unmanaged,
+                         GError **error)
+{
+	NMSettingInfiniband *s_infiniband;
+	char *value = NULL;
+	GByteArray *mac = NULL;
+	int mtu;
+
+	s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ());
+
+	value = svGetValue (ifcfg, "MTU", FALSE);
+	if (value) {
+		if (get_int (value, &mtu)) {
+			if (mtu >= 0 && mtu < 65536)
+				g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu, NULL);
+		} else {
+			/* Shouldn't be fatal... */
+			PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: invalid MTU '%s'", value);
+		}
+		g_free (value);
+	}
+
+	if (read_mac_address (ifcfg, "HWADDR", ARPHRD_INFINIBAND, &mac, error)) {
+		if (mac) {
+			g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL);
+
+			/* A connection can only be unmanaged if we know the MAC address */
+			if (!nm_controlled) {
+				char *mac_str = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND);
+				*unmanaged = g_strdup_printf ("mac:%s", mac_str);
+				g_free (mac_str);
+			}
+
+			g_byte_array_free (mac, TRUE);
+		}
+	} else {
+		g_object_unref (s_infiniband);
+		return NULL;
+	}
+
+	if (svTrueValue (ifcfg, "CONNECTED_MODE", FALSE))
+		g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL);
+	else
+		g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL);
+
+	if (!nm_controlled && !*unmanaged) {
+		/* If NM_CONTROLLED=no but there wasn't a MAC address, notify
+		   the user that the device cannot be unmanaged.
+		 */
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed");
+	}
+
+	return (NMSetting *) s_infiniband;
+}
+
+static NMConnection *
+infiniband_connection_from_ifcfg (const char *file,
+                                  shvarFile *ifcfg,
+                                  gboolean nm_controlled,
+                                  char **unmanaged,
+                                  GError **error)
+{
+	NMConnection *connection = NULL;
+	NMSetting *con_setting = NULL;
+	NMSetting *infiniband_setting = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	g_return_val_if_fail (ifcfg != NULL, NULL);
+
+	connection = nm_connection_new ();
+	if (!connection) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Failed to allocate new connection for %s.", file);
+		return NULL;
+	}
+
+	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL);
+	if (!con_setting) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Failed to create connection setting.");
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, con_setting);
+
+	infiniband_setting = make_infiniband_setting (ifcfg, file, nm_controlled, unmanaged, error);
+	if (!infiniband_setting) {
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, infiniband_setting);
+
+	if (!nm_connection_verify (connection, error)) {
+		g_object_unref (connection);
+		return NULL;
+	}
+
+	return connection;
+}
+
+static void
+handle_bond_option (NMSettingBond *s_bond,
+                    const char *key,
+                    const char *value)
+{
+	if (!nm_setting_bond_add_option (s_bond, key, value))
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: invalid bonding option '%s'", key);
+}
+
+static NMSetting *
+make_bond_setting (shvarFile *ifcfg,
+                   const char *file,
+                   gboolean nm_controlled,
+                   char **unmanaged,
+                   GError **error)
+{
+	NMSettingBond *s_bond;
+	char *value;
+
+	s_bond = NM_SETTING_BOND (nm_setting_bond_new ());
+
+	value = svGetValue (ifcfg, "DEVICE", FALSE);
+	if (!value || !strlen (value)) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "mandatory DEVICE keyword missing");
+		goto error;
+	}
+
+	g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, value, NULL);
+	g_free (value);
+
+	value = svGetValue (ifcfg, "BONDING_OPTS", FALSE);
+	if (value) {
+		char **items, **iter;
+
+		items = g_strsplit_set (value, " ", -1);
+		for (iter = items; iter && *iter; iter++) {
+			if (strlen (*iter)) {
+				char **keys, *key, *val;
+
+				keys = g_strsplit_set (*iter, "=", 2);
+				if (keys && *keys) {
+					key = *keys;
+					val = *(keys + 1);
+					if (val && strlen(key) && strlen(val))
+						handle_bond_option (s_bond, key, val);
+				}
+
+				g_strfreev (keys);
+			}
+		}
+		g_free (value);
+		g_strfreev (items);
+	}
+
+	return (NMSetting *) s_bond;
+
+error:
+	g_object_unref (s_bond);
+	return NULL;
+}
+
+static NMConnection *
+bond_connection_from_ifcfg (const char *file,
+                            shvarFile *ifcfg,
+                            gboolean nm_controlled,
+                            char **unmanaged,
+                            GError **error)
+{
+	NMConnection *connection = NULL;
+	NMSetting *con_setting = NULL;
+	NMSetting *bond_setting = NULL;
+	NMSetting *wired_setting = NULL;
+	NMSetting8021x *s_8021x = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	g_return_val_if_fail (ifcfg != NULL, NULL);
+
+	connection = nm_connection_new ();
+	if (!connection) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Failed to allocate new connection for %s.", file);
+		return NULL;
+	}
+
+	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond"));
+	if (!con_setting) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Failed to create connection setting.");
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, con_setting);
+
+	bond_setting = make_bond_setting (ifcfg, file, nm_controlled, unmanaged, error);
+	if (!bond_setting) {
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, bond_setting);
+
 	wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error);
 	if (!wired_setting) {
 		g_object_unref (connection);
@@ -3299,50 +3666,245 @@ wired_connection_from_ifcfg (const char *file,
 }
 
 static gboolean
-is_wireless_device (const char *iface)
+is_bond_device (const char *name, shvarFile *parsed)
 {
-	int fd;
-	struct iw_range range;
-	struct iwreq wrq;
-	gboolean is_wireless = FALSE;
+	g_return_val_if_fail (name != NULL, FALSE);
+	g_return_val_if_fail (parsed != NULL, FALSE);
+
+	if (svTrueValue (parsed, "BONDING_MASTER", FALSE))
+		return TRUE;
+	
+	/* XXX: Check for "bond[\d]+"? */
 
-	g_return_val_if_fail (iface != NULL, FALSE);
+	return FALSE;
+}
 
-	fd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (fd == -1)
-		return FALSE;
+static gboolean
+is_vlan_device (const char *name, shvarFile *parsed)
+{
+	g_return_val_if_fail (name != NULL, FALSE);
+	g_return_val_if_fail (parsed != NULL, FALSE);
 
-	memset (&wrq, 0, sizeof (struct iwreq));
-	memset (&range, 0, sizeof (struct iw_range));
-	strncpy (wrq.ifr_name, iface, IFNAMSIZ);
-	wrq.u.data.pointer = (caddr_t) &range;
-	wrq.u.data.length = sizeof (struct iw_range);
+	if (svTrueValue (parsed, "VLAN", FALSE))
+		return TRUE;
 
-	if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0)
-		is_wireless = TRUE;
-	else {
-		if (errno == EOPNOTSUPP)
-			is_wireless = FALSE;
-		else {
-			/* Sigh... some wired devices (kvm/qemu) return EINVAL when the
-			 * device is down even though it's not a wireless device.  So try
-			 * IWNAME as a fallback.
-			 */
-			memset (&wrq, 0, sizeof (struct iwreq));
-			strncpy (wrq.ifr_name, iface, IFNAMSIZ);
-			if (ioctl (fd, SIOCGIWNAME, &wrq) == 0)
-				is_wireless = TRUE;
+	return FALSE;
+}
+
+static void
+parse_prio_map_list (NMSettingVlan *s_vlan,
+                     shvarFile *ifcfg,
+                     const char *key,
+                     NMVlanPriorityMap map)
+{
+	char *value;
+	gchar **list = NULL, **iter;
+
+	value = svGetValue (ifcfg, key, FALSE);
+	if (!value)
+		return;
+
+	list = g_strsplit_set (value, ",", -1);
+	g_free (value);
+
+	for (iter = list; iter && *iter; iter++) {
+		if (!*iter || !strchr (*iter, ':'))
+			continue;
+
+		if (!nm_setting_vlan_add_priority_str (s_vlan, map, *iter)) {
+			PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: invalid %s priority map item '%s'",
+			             key, *iter);
+		}
+	}
+	g_strfreev (list);
+}
+
+static NMSetting *
+make_vlan_setting (shvarFile *ifcfg,
+                   const char *file,
+                   gboolean nm_controlled,
+                   char **out_master,
+                   char **unmanaged,
+                   NMSetting8021x **s_8021x,
+                   GError **error)
+{
+	NMSettingVlan *s_vlan = NULL;
+	char *value = NULL;
+	char *iface_name = NULL;
+	char *parent = NULL;
+	const char *p = NULL, *w;
+	gboolean has_numbers = FALSE;
+	gint vlan_id = -1;
+	guint32 vlan_flags = 0;
+
+	value = svGetValue (ifcfg, "VLAN_ID", FALSE);
+	if (value) {
+		errno = 0;
+		vlan_id = (gint) g_ascii_strtoll (value, NULL, 10);
+		if (vlan_id < 0 || vlan_id > 4096 || errno) {
+			g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid VLAN_ID '%s'", value);
+			g_free (value);
+			return NULL;
+		}
+		g_free (value);
+	}
+
+	/* Need DEVICE if we don't have a separate VLAN_ID property */
+	iface_name = svGetValue (ifcfg, "DEVICE", FALSE);
+	if (!iface_name && vlan_id < 0) {
+		g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0,
+		                     "Missing DEVICE property; cannot determine VLAN ID.");
+		return NULL;
+	}
+
+	s_vlan = NM_SETTING_VLAN (nm_setting_vlan_new ());
+
+	if (iface_name) {
+		g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, iface_name, NULL);
+
+		p = strchr (iface_name, '.');
+		if (p) {
+			/* eth0.43; PHYSDEV is assumed from it */
+			parent = g_strndup (iface_name, p - iface_name);
+			p++;
+		} else {
+			/* format like vlan43; PHYSDEV or MASTER must be set */
+			if (g_str_has_prefix (iface_name, "vlan"))
+				p = iface_name + 4;
 		}
+
+		w = p;
+		while (*w && !has_numbers)
+			has_numbers = g_ascii_isdigit (*w);
+
+		/* Grab VLAN ID from interface name; this takes precedence over the
+		 * separate VLAN_ID property for backwards compat.
+		 */
+		if (has_numbers) {
+			errno = 0;
+			vlan_id = (gint) g_ascii_strtoll (p, NULL, 10);
+			if (vlan_id < 0 || vlan_id > 4095 || errno) {
+				g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+				             "Failed to determine VLAN ID from DEVICE '%s'",
+				             iface_name);
+				goto error;
+			}
+		}
+	}
+
+	if (vlan_id < 0) {
+		g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0,
+		                     "Failed to determine VLAN ID from DEVICE or VLAN_ID.");
+		goto error;
 	}
+	g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL);
 
-	close (fd);
-	return is_wireless;
+	if (!parent)
+		parent = svGetValue (ifcfg, "PHYSDEV", FALSE);
+	if (parent == NULL) {
+		g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0,
+		                     "Failed to determine VLAN parent from DEVICE or PHYSDEV");
+		goto error;
+	}
+	g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL);
+
+	if (svTrueValue (ifcfg, "REORDER_HDR", FALSE))
+		vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS;
+
+	value = svGetValue (ifcfg, "VLAN_FLAGS", FALSE);
+	if (value) {
+		if (g_strstr_len (value, -1, "GVRP"))
+			vlan_flags |= NM_VLAN_FLAG_GVRP;
+		if (g_strstr_len (value, -1, "LOOSE_BINDING"))
+			vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING;
+	}
+
+	g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL);
+	g_free (value);
+
+	parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP);
+	parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP);
+
+	if (out_master)
+		*out_master = svGetValue (ifcfg, "MASTER", FALSE);
+	return (NMSetting *) s_vlan;
+
+error:
+	g_free (parent);
+	g_free (iface_name);
+	g_object_unref (s_vlan);
+	return NULL;
+}
+
+static NMConnection *
+vlan_connection_from_ifcfg (const char *file,
+                            shvarFile *ifcfg,
+                            gboolean nm_controlled,
+                            char **unmanaged,
+                            GError **error)
+{
+	NMConnection *connection = NULL;
+	NMSetting *con_setting = NULL;
+	NMSetting *wired_setting = NULL;
+	NMSetting *vlan_setting = NULL;
+	NMSetting8021x *s_8021x = NULL;
+	char *master = NULL;
+
+	g_return_val_if_fail (file != NULL, NULL);
+	g_return_val_if_fail (ifcfg != NULL, NULL);
+
+	connection = nm_connection_new ();
+	if (!connection) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+			     "Failed to allocate new connection for %s.", file);
+		return NULL;
+	}
+
+	con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan");
+	if (!con_setting) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+			     "Failed to create connection setting.");
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, con_setting);
+
+	vlan_setting = make_vlan_setting (ifcfg, file, nm_controlled, &master, unmanaged, &s_8021x, error);
+	if (!vlan_setting) {
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, vlan_setting);
+
+	/* Handle master interface or connection */
+	if (master) {
+		g_object_set (con_setting, NM_SETTING_CONNECTION_MASTER, master, NULL);
+		g_object_set (con_setting,
+		              NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_VLAN_SETTING_NAME,
+		              NULL);
+		g_free (master);
+	}
+
+	wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error);
+	if (!wired_setting) {
+		g_object_unref (connection);
+		return NULL;
+	}
+	nm_connection_add_setting (connection, wired_setting);
+
+	if (s_8021x)
+		nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+	if (!nm_connection_verify (connection, error)) {
+		g_object_unref (connection);
+		return NULL;
+	}
+
+	return connection;
 }
 
 enum {
 	IGNORE_REASON_NONE = 0x00,
 	IGNORE_REASON_BRIDGE = 0x01,
-	IGNORE_REASON_VLAN = 0x02,
 };
 
 NMConnection *
@@ -3363,7 +3925,7 @@ connection_from_file (const char *filename,
 	NMSetting *s_ip4, *s_ip6;
 	const char *ifcfg_name = NULL;
 	gboolean nm_controlled = TRUE;
-	gboolean ip6_used = FALSE;
+	gboolean can_disable_ip4 = FALSE;
 	GError *error = NULL;
 	guint32 ignore_reason = IGNORE_REASON_NONE;
 
@@ -3402,9 +3964,6 @@ connection_from_file (const char *filename,
 	if (!type) {
 		char *device;
 
-		/* If no type, if the device has wireless extensions, it's wifi,
-		 * otherwise it's ethernet.
-		 */
 		device = svGetValue (parsed, "DEVICE", FALSE);
 		if (!device) {
 			g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
@@ -3422,8 +3981,12 @@ connection_from_file (const char *filename,
 		}
 
 		if (!test_type) {
+			if (is_bond_device (device, parsed))
+				type = g_strdup (TYPE_BOND);
+			else if (is_vlan_device (device, parsed))
+				type = g_strdup (TYPE_VLAN);
 			/* Test wireless extensions */
-			if (is_wireless_device (device))
+			else if (wifi_utils_is_wifi (device, NULL))
 				type = g_strdup (TYPE_WIRELESS);
 			else
 				type = g_strdup (TYPE_ETHERNET);
@@ -3456,7 +4019,14 @@ connection_from_file (const char *filename,
 		g_free (lower);
 	}
 
-	/* Ignore BRIDGE= and VLAN= connections for now too (rh #619863) */
+	if (svTrueValue (parsed, "BONDING_MASTER", FALSE) &&
+	    strcasecmp (type, TYPE_BOND)) {
+		g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+		             "BONDING_MASTER=yes key only allowed in TYPE=bond connections");
+		goto done;
+	}
+
+	/* Ignore BRIDGE= connections for now too (rh #619863) */
 	tmp = svGetValue (parsed, "BRIDGE", FALSE);
 	if (tmp) {
 		g_free (tmp);
@@ -3464,24 +4034,21 @@ connection_from_file (const char *filename,
 		ignore_reason = IGNORE_REASON_BRIDGE;
 	}
 
-	if (nm_controlled) {
-		tmp = svGetValue (parsed, "VLAN", FALSE);
-		if (tmp) {
-			g_free (tmp);
-			nm_controlled = FALSE;
-			ignore_reason = IGNORE_REASON_VLAN;
-		}
-	}
-
 	/* Construct the connection */
 	if (!strcasecmp (type, TYPE_ETHERNET))
 		connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
 	else if (!strcasecmp (type, TYPE_WIRELESS))
 		connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
-	else if (!strcasecmp (type, TYPE_BRIDGE)) {
+	else if (!strcasecmp (type, TYPE_INFINIBAND))
+		connection = infiniband_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
+	else if (!strcasecmp (type, TYPE_BOND))
+		connection = bond_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
+	else if (!strcasecmp (type, TYPE_VLAN))
+		connection = vlan_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
+	else if (!strcasecmp (type, TYPE_BRIDGE))
 		g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
 		             "Bridge connections are not yet supported");
-	} else {
+	else {
 		g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
 		             "Unknown connection type '%s'", type);
 	}
@@ -3524,10 +4091,13 @@ connection_from_file (const char *filename,
 		nm_connection_add_setting (connection, s_ip6);
 		method = nm_setting_ip6_config_get_method (NM_SETTING_IP6_CONFIG (s_ip6));
 		if (method && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
-			ip6_used = TRUE;
+			can_disable_ip4 = TRUE;
 	}
 
-	s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, ip6_used, &error);
+	if (utils_disabling_ip4_config_allowed (connection))
+		can_disable_ip4 = TRUE;
+
+	s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, can_disable_ip4, &error);
 	if (error) {
 		g_object_unref (connection);
 		connection = NULL;
@@ -3544,7 +4114,7 @@ connection_from_file (const char *filename,
 	    && !g_ascii_strcasecmp (bootproto, "ibft")) {
 		NMSettingConnection *s_con;
 
-		s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+		s_con = nm_connection_get_setting_connection (connection);
 		g_assert (s_con);
 
 		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL);
@@ -3569,9 +4139,3 @@ done:
 	return connection;
 }
 
-const char *
-reader_get_prefix (void)
-{
-	return _("System");
-}
-
diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h
index 2a031977..97c727cc 100644
--- a/src/settings/plugins/ifcfg-rh/reader.h
+++ b/src/settings/plugins/ifcfg-rh/reader.h
@@ -37,6 +37,4 @@ NMConnection *connection_from_file (const char *filename,
                                     GError **error,
                                     gboolean *ignore_error);
 
-const char *reader_get_prefix (void);
-
 #endif  /* __READER_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am
index 1b76a474..5b34ffe3 100644
--- a/src/settings/plugins/ifcfg-rh/tests/Makefile.am
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am
@@ -2,6 +2,7 @@ SUBDIRS=network-scripts
 
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
@@ -20,7 +21,9 @@ test_ifcfg_rh_CPPFLAGS = \
 test_ifcfg_rh_LDADD = \
 	$(top_builddir)/libnm-glib/libnm-glib.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(builddir)/../libifcfg-rh-io.la \
+	$(LIBM)
 	$(DBUS_LIBS)
 
 test_ifcfg_rh_utils_SOURCES = \
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
index 71c5d60b..5e8abf83 100644
--- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
@@ -61,6 +61,7 @@ test_ifcfg_rh_OBJECTS = $(am_test_ifcfg_rh_OBJECTS)
 am__DEPENDENCIES_1 =
 test_ifcfg_rh_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(builddir)/../libifcfg-rh-io.la $(am__DEPENDENCIES_1)
 AM_V_lt = $(am__v_lt_$(V))
 am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -183,6 +184,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -237,11 +240,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -252,6 +259,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -291,6 +299,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -357,6 +367,7 @@ top_srcdir = @top_srcdir@
 SUBDIRS = network-scripts
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
@@ -373,8 +384,9 @@ test_ifcfg_rh_CPPFLAGS = \
 test_ifcfg_rh_LDADD = \
 	$(top_builddir)/libnm-glib/libnm-glib.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/src/wifi/libwifi-utils.la \
 	$(builddir)/../libifcfg-rh-io.la \
-	$(DBUS_LIBS)
+	$(LIBM)
 
 test_ifcfg_rh_utils_SOURCES = \
 	test-ifcfg-rh-utils.c
@@ -833,6 +845,7 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-recursive uninstall uninstall-am
 
+	$(DBUS_LIBS)
 
 @WITH_TESTS_TRUE@check-local: test-ifcfg-rh
 @WITH_TESTS_TRUE@	$(abs_builddir)/test-ifcfg-rh-utils
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
index 935d0ec4..776962f0 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
@@ -36,6 +36,8 @@ EXTRA_DIST = \
 	ifcfg-test-wifi-leap-always-ask \
 	ifcfg-test-wifi-wpa-psk \
 	keys-test-wifi-wpa-psk \
+	ifcfg-test-wifi-wpa-psk-2 \
+	keys-test-wifi-wpa-psk-2 \
 	ifcfg-test-wifi-wpa-psk-unquoted \
 	keys-test-wifi-wpa-psk-unquoted \
 	ifcfg-test-wifi-wpa-psk-unquoted2 \
@@ -79,11 +81,16 @@ EXTRA_DIST = \
 	ifcfg-test-bridge-main \
 	ifcfg-test-bridge-component \
 	ifcfg-test-vlan-interface \
+	ifcfg-test-vlan-only-vlanid \
+	ifcfg-test-vlan-only-device \
 	ifcfg-test-wifi-wep-no-keys \
 	ifcfg-test-permissions \
 	ifcfg-test-wifi-wep-agent-keys \
 	ifcfg-test-wifi-dynamic-wep-leap \
-	keys-test-wifi-dynamic-wep-leap
+	keys-test-wifi-dynamic-wep-leap \
+	ifcfg-test-infiniband \
+	ifcfg-test-bond-main \
+	ifcfg-test-bond-slave
 
 check-local:
 	@for f in $(EXTRA_DIST); do \
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
index 6292f12c..4f34cfc3 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
@@ -107,6 +107,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -161,11 +163,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -176,6 +182,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -215,6 +222,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -316,6 +325,8 @@ EXTRA_DIST = \
 	ifcfg-test-wifi-leap-always-ask \
 	ifcfg-test-wifi-wpa-psk \
 	keys-test-wifi-wpa-psk \
+	ifcfg-test-wifi-wpa-psk-2 \
+	keys-test-wifi-wpa-psk-2 \
 	ifcfg-test-wifi-wpa-psk-unquoted \
 	keys-test-wifi-wpa-psk-unquoted \
 	ifcfg-test-wifi-wpa-psk-unquoted2 \
@@ -359,11 +370,16 @@ EXTRA_DIST = \
 	ifcfg-test-bridge-main \
 	ifcfg-test-bridge-component \
 	ifcfg-test-vlan-interface \
+	ifcfg-test-vlan-only-vlanid \
+	ifcfg-test-vlan-only-device \
 	ifcfg-test-wifi-wep-no-keys \
 	ifcfg-test-permissions \
 	ifcfg-test-wifi-wep-agent-keys \
 	ifcfg-test-wifi-dynamic-wep-leap \
-	keys-test-wifi-dynamic-wep-leap
+	keys-test-wifi-dynamic-wep-leap \
+	ifcfg-test-infiniband \
+	ifcfg-test-bond-main \
+	ifcfg-test-bond-slave
 
 all: all-am
 
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main
new file mode 100644
index 00000000..4c4834d5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-main
@@ -0,0 +1,5 @@
+DEVICE=bond0
+ONBOOT=no
+TYPE=Bond
+BOOTPROTO=dhcp
+BONDING_OPTS="miimon=100"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave
new file mode 100644
index 00000000..cfef2b16
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bond-slave
@@ -0,0 +1,4 @@
+DEVICE=eth0
+HWADDR=00:22:15:59:62:97
+ONBOOT=no
+MASTER=bond0
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband
new file mode 100644
index 00000000..6c36f1de
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-infiniband
@@ -0,0 +1,8 @@
+TYPE=InfiniBand
+DEVICE=ib0
+HWADDR=80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22
+CONNECTED_MODE=yes
+MTU=65520
+IPADDR=192.168.2.2
+NETMASK=255.255.255.0
+GATEWAY=192.168.2.1
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
index 6c841855..ccd75d7f 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
@@ -1,7 +1,12 @@
-DEVICE=eth1.43
 VLAN=yes
+TYPE=Vlan
+DEVICE=vlan43
+PHYSDEV=eth9
+REORDER_HDR=0
+VLAN_FLAGS=GVRP,LOOSE_BINDING
+VLAN_INGRESS_PRIORITY_MAP=0:1,2:5
+VLAN_EGRESS_PRIORITY_MAP=12:3,14:7,3:1
 ONBOOT=yes
-BOOTPROTO=none
+BOOTPROTO=static
 IPADDR=192.168.43.149
 NETMASK=255.255.255.0
-
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device
new file mode 100644
index 00000000..4ba06f28
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-device
@@ -0,0 +1,4 @@
+VLAN=yes
+TYPE=Vlan
+DEVICE=eth0.9
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid
new file mode 100644
index 00000000..622d41ec
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-only-vlanid
@@ -0,0 +1,6 @@
+VLAN=yes
+TYPE=Vlan
+PHYSDEV=eth9
+VLAN_ID=43
+ONBOOT=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2
new file mode 100644
index 00000000..038b656d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-2
@@ -0,0 +1,19 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=ipsum
+CHANNEL=6
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-PSK
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2
new file mode 100644
index 00000000..bf98da5a
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-2
@@ -0,0 +1,2 @@
+WPA_PSK=$'They\'re really saying I love you. >>`<<'
+
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 e32266cb..62882a76 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <netinet/ether.h>
+#include <linux/if_infiniband.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
@@ -43,6 +44,7 @@
 #include <nm-setting-gsm.h>
 #include <nm-setting-cdma.h>
 #include <nm-setting-serial.h>
+#include <nm-setting-vlan.h>
 
 #include "nm-test-helpers.h"
 
@@ -235,7 +237,7 @@ test_read_minimal (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "minimal-wired-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_MINIMAL,
@@ -275,7 +277,7 @@ test_read_minimal (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "minimal-wired-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_MINIMAL,
@@ -307,7 +309,7 @@ test_read_minimal (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "minimal-wired-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_MINIMAL,
@@ -379,7 +381,7 @@ test_read_unmanaged (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "unmanaged-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_UNMANAGED,
@@ -417,7 +419,7 @@ test_read_unmanaged (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "unmanaged-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_UNMANAGED,
@@ -443,7 +445,7 @@ test_read_unmanaged (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 == NULL,
 	        "unmanaged-verify-ip4", "failed to verify %s: unexpected %s setting",
 	        TEST_IFCFG_UNMANAGED,
@@ -504,7 +506,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-static-verify-connection", "failed to verify %s: missing %s setting",
 	        file,
@@ -539,7 +541,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-static-verify-wired", "failed to verify %s: missing %s setting",
 	        file,
@@ -571,7 +573,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-static-verify-ip4", "failed to verify %s: missing %s setting",
 	        file,
@@ -586,7 +588,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
 	/* Implicit may-fail */
-	ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == FALSE,
+	ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == TRUE,
 	        "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
 	        file,
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
@@ -666,7 +668,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 	if (!strcmp (expected_id, "System test-wired-static")) {
 		/* ===== IPv6 SETTING ===== */
 
-		s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+		s_ip6 = nm_connection_get_setting_ip6_config (connection);
 		ASSERT (s_ip6 != NULL,
 			"wired-static-verify-ip6", "failed to verify %s: missing %s setting",
 			file,
@@ -807,7 +809,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s setting",
 	        file,
@@ -829,7 +831,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing %s setting",
 	        file,
@@ -916,7 +918,7 @@ test_read_wired_dhcp (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-dhcp-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP,
@@ -951,7 +953,7 @@ test_read_wired_dhcp (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-dhcp-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP,
@@ -977,7 +979,7 @@ test_read_wired_dhcp (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-dhcp-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP,
@@ -1089,7 +1091,7 @@ test_read_wired_global_gateway (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
@@ -1110,7 +1112,7 @@ test_read_wired_global_gateway (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
@@ -1118,7 +1120,7 @@ test_read_wired_global_gateway (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
@@ -1216,7 +1218,7 @@ test_read_wired_never_default (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-never-default-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_NEVER_DEFAULT,
@@ -1237,7 +1239,7 @@ test_read_wired_never_default (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-never-default-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_NEVER_DEFAULT,
@@ -1245,7 +1247,7 @@ test_read_wired_never_default (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-never-default-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_NEVER_DEFAULT,
@@ -1274,7 +1276,7 @@ test_read_wired_never_default (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-never-default-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_NEVER_DEFAULT,
@@ -1341,7 +1343,7 @@ test_read_wired_defroute_no (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-defroute-no-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO,
@@ -1362,7 +1364,7 @@ test_read_wired_defroute_no (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-defroute-no-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO,
@@ -1370,7 +1372,7 @@ test_read_wired_defroute_no (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-defroute-no-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO,
@@ -1392,7 +1394,7 @@ test_read_wired_defroute_no (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-defroute-no-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO,
@@ -1468,7 +1470,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
@@ -1489,7 +1491,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-defroute-no-gatewaydev-yes-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
@@ -1497,7 +1499,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
@@ -1519,7 +1521,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
@@ -1597,7 +1599,7 @@ test_read_wired_static_routes (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-static-routes-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES,
@@ -1618,7 +1620,7 @@ test_read_wired_static_routes (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-static-routes-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES,
@@ -1626,7 +1628,7 @@ test_read_wired_static_routes (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-static-routes-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES,
@@ -1764,7 +1766,7 @@ test_read_wired_static_routes_legacy (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
@@ -1785,7 +1787,7 @@ test_read_wired_static_routes_legacy (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
@@ -1793,7 +1795,7 @@ test_read_wired_static_routes_legacy (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
@@ -1961,7 +1963,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-ipv4-manual-verify-connection", "failed to verify %s: missing %s setting",
 	        file,
@@ -1982,7 +1984,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-ipv4-manual-verify-wired", "failed to verify %s: missing %s setting",
 	        file,
@@ -1990,7 +1992,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-ipv4-manual-verify-ip4", "failed to verify %s: missing %s setting",
 	        file,
@@ -2124,7 +2126,7 @@ test_read_wired_ipv6_manual (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2145,7 +2147,7 @@ test_read_wired_ipv6_manual (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-ipv6-manual-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2153,7 +2155,7 @@ test_read_wired_ipv6_manual (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2211,7 +2213,7 @@ test_read_wired_ipv6_manual (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2415,7 +2417,7 @@ test_read_wired_ipv6_only (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2436,7 +2438,7 @@ test_read_wired_ipv6_only (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-ipv6-only-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2444,7 +2446,7 @@ test_read_wired_ipv6_only (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2459,7 +2461,7 @@ test_read_wired_ipv6_only (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-ipv6-only-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_IPV6_MANUAL,
@@ -2568,7 +2570,7 @@ test_read_wired_dhcp6_only (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP6_ONLY,
@@ -2589,7 +2591,7 @@ test_read_wired_dhcp6_only (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-dhcp6-only-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP6_ONLY,
@@ -2597,7 +2599,7 @@ test_read_wired_dhcp6_only (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-dhcp6-only-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP6_ONLY,
@@ -2612,7 +2614,7 @@ test_read_wired_dhcp6_only (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "wired-dhcp6-only-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_DHCP6_ONLY,
@@ -2668,7 +2670,7 @@ test_read_onboot_no (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "onboot-no-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_ONBOOT_NO,
@@ -2734,7 +2736,7 @@ test_read_wired_8021x_peap_mschapv2 (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-8021x-peap-mschapv2-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
@@ -2742,7 +2744,7 @@ test_read_wired_8021x_peap_mschapv2 (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
@@ -2757,7 +2759,7 @@ test_read_wired_8021x_peap_mschapv2 (void)
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	ASSERT (s_8021x != NULL,
 	        "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
@@ -2929,11 +2931,11 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags
 	g_assert (success);
 
 	/* ===== WIRED SETTING ===== */
-	s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x);
 	g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1);
 	g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls");
@@ -3001,7 +3003,7 @@ test_read_wifi_open (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-open-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN,
@@ -3041,7 +3043,7 @@ test_read_wifi_open (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-open-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN,
@@ -3120,7 +3122,7 @@ test_read_wifi_open (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-open-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN,
@@ -3177,7 +3179,7 @@ test_read_wifi_open_auto (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-open-auto-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_AUTO,
@@ -3198,7 +3200,7 @@ test_read_wifi_open_auto (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_AUTO,
@@ -3260,7 +3262,7 @@ test_read_wifi_open_ssid_hex (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_SSID_HEX,
@@ -3281,7 +3283,7 @@ test_read_wifi_open_ssid_hex (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_SSID_HEX,
@@ -3379,7 +3381,7 @@ test_read_wifi_open_ssid_quoted (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
@@ -3400,7 +3402,7 @@ test_read_wifi_open_ssid_quoted (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
@@ -3476,7 +3478,7 @@ test_read_wifi_wep (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP,
@@ -3516,7 +3518,7 @@ test_read_wifi_wep (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP,
@@ -3608,7 +3610,7 @@ test_read_wifi_wep (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP,
@@ -3687,7 +3689,7 @@ test_read_wifi_wep (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wep-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP,
@@ -3752,7 +3754,7 @@ test_read_wifi_wep_adhoc (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_ADHOC,
@@ -3785,7 +3787,7 @@ test_read_wifi_wep_adhoc (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_ADHOC,
@@ -3852,7 +3854,7 @@ test_read_wifi_wep_adhoc (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_ADHOC,
@@ -3919,7 +3921,7 @@ test_read_wifi_wep_adhoc (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wep-adhoc-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_ADHOC,
@@ -4015,7 +4017,7 @@ test_read_wifi_wep_passphrase (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-passphrase-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_PASSPHRASE,
@@ -4023,7 +4025,7 @@ test_read_wifi_wep_passphrase (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_PASSPHRASE,
@@ -4045,7 +4047,7 @@ test_read_wifi_wep_passphrase (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_PASSPHRASE,
@@ -4153,7 +4155,7 @@ test_read_wifi_wep_40_ascii (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-40-ascii-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_40_ASCII,
@@ -4161,7 +4163,7 @@ test_read_wifi_wep_40_ascii (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_40_ASCII,
@@ -4182,7 +4184,7 @@ test_read_wifi_wep_40_ascii (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_40_ASCII,
@@ -4290,7 +4292,7 @@ test_read_wifi_wep_104_ascii (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-104-ascii-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_104_ASCII,
@@ -4298,7 +4300,7 @@ test_read_wifi_wep_104_ascii (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_104_ASCII,
@@ -4319,7 +4321,7 @@ test_read_wifi_wep_104_ascii (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_104_ASCII,
@@ -4428,7 +4430,7 @@ test_read_wifi_leap (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-leap-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_LEAP,
@@ -4449,7 +4451,7 @@ test_read_wifi_leap (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_LEAP,
@@ -4471,7 +4473,7 @@ test_read_wifi_leap (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_LEAP,
@@ -4566,13 +4568,13 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte
 	g_assert (success);
 
 	/* ===== WIRELESS SETTING ===== */
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wifi = nm_connection_get_setting_wireless (connection);
 	g_assert (s_wifi);
 
 	g_assert (g_strcmp0 (nm_setting_wireless_get_security (s_wifi), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0);
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec);
 
 	g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0);
@@ -4643,7 +4645,7 @@ test_read_wifi_wpa_psk (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK,
@@ -4683,7 +4685,7 @@ test_read_wifi_wpa_psk (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK,
@@ -4774,7 +4776,7 @@ test_read_wifi_wpa_psk (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK,
@@ -4887,7 +4889,7 @@ test_read_wifi_wpa_psk (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wpa-psk-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK,
@@ -4908,6 +4910,111 @@ test_read_wifi_wpa_psk (void)
 	g_object_unref (connection);
 }
 
+#define TEST_IFCFG_WIFI_WPA_PSK_2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-2"
+
+static void
+test_read_wifi_wpa_psk_2 (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wsec;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	const char *tmp;
+	const char *expected_id = "System ipsum (test-wifi-wpa-psk-2)";
+	const char *expected_psk = "They're really saying I love you. >>`<<";
+
+	connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_2,
+                                     NULL,
+                                     TYPE_WIRELESS,
+                                     NULL,
+                                     &unmanaged,
+                                     &keyfile,
+                                     &routefile,
+                                     &route6file,
+                                     &error,
+                                     &ignore_error);
+	ASSERT (connection != NULL,
+	        "wifi-wpa-psk-2-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_2, error->message);
+
+	ASSERT (nm_connection_verify (connection, &error),
+	        "wifi-wpa-psk-2-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_2, error->message);
+
+	/* ===== CONNECTION SETTING ===== */
+
+	s_con = nm_connection_get_setting_connection (connection);
+	ASSERT (s_con != NULL,
+	        "wifi-wpa-psk-2-verify-connection", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_CONNECTION_SETTING_NAME);
+
+	/* ID */
+	tmp = nm_setting_connection_get_id (s_con);
+	ASSERT (tmp != NULL,
+	        "wifi-wpa-psk-2-verify-connection", "failed to verify %s: missing %s / %s key",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_CONNECTION_SETTING_NAME,
+	        NM_SETTING_CONNECTION_ID);
+	ASSERT (strcmp (tmp, expected_id) == 0,
+	        "wifi-wpa-psk-2-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_CONNECTION_SETTING_NAME,
+	        NM_SETTING_CONNECTION_ID);
+
+	/* ===== WIRELESS SETTING ===== */
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	ASSERT (s_wireless != NULL,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SETTING_NAME);
+
+	/* Security */
+	tmp = nm_setting_wireless_get_security (s_wireless);
+	ASSERT (tmp != NULL,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s / %s key",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SETTING_NAME,
+	        NM_SETTING_WIRELESS_SEC);
+	ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SETTING_NAME,
+	        NM_SETTING_WIRELESS_SEC);
+
+	/* ===== WIRELESS SECURITY SETTING ===== */
+
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	ASSERT (s_wsec != NULL,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+	/* PSK */
+	tmp = nm_setting_wireless_security_get_psk (s_wsec);
+	ASSERT (tmp != NULL,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: missing %s / %s key",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+	        NM_SETTING_WIRELESS_SECURITY_PSK);
+	ASSERT (strcmp (tmp, expected_psk) == 0,
+	        "wifi-wpa-psk-2-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+	        TEST_IFCFG_WIFI_WPA_PSK_2,
+	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+	        NM_SETTING_WIRELESS_SECURITY_PSK);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+}
+
 #define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted"
 
 static void
@@ -4945,7 +5052,7 @@ test_read_wifi_wpa_psk_unquoted (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
@@ -4966,7 +5073,7 @@ test_read_wifi_wpa_psk_unquoted (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
@@ -4987,7 +5094,7 @@ test_read_wifi_wpa_psk_unquoted (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
@@ -5092,7 +5199,7 @@ test_read_wifi_wpa_psk_adhoc (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
@@ -5113,7 +5220,7 @@ test_read_wifi_wpa_psk_adhoc (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
@@ -5147,7 +5254,7 @@ test_read_wifi_wpa_psk_adhoc (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
@@ -5221,7 +5328,7 @@ test_read_wifi_wpa_psk_adhoc (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
@@ -5283,7 +5390,7 @@ test_read_wifi_wpa_psk_hex (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_HEX,
@@ -5304,7 +5411,7 @@ test_read_wifi_wpa_psk_hex (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_HEX,
@@ -5343,7 +5450,7 @@ test_read_wifi_wpa_psk_hex (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_HEX,
@@ -5377,7 +5484,7 @@ test_read_wifi_wpa_psk_hex (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_PSK_HEX,
@@ -5441,7 +5548,7 @@ test_read_wifi_wpa_eap_tls (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-eap-tls-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TLS,
@@ -5449,7 +5556,7 @@ test_read_wifi_wpa_eap_tls (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TLS,
@@ -5464,7 +5571,7 @@ test_read_wifi_wpa_eap_tls (void)
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	ASSERT (s_8021x != NULL,
 	        "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TLS,
@@ -5591,7 +5698,7 @@ test_read_wifi_wpa_eap_ttls_tls (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wpa-eap-ttls-tls-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
@@ -5599,7 +5706,7 @@ test_read_wifi_wpa_eap_ttls_tls (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
@@ -5614,7 +5721,7 @@ test_read_wifi_wpa_eap_ttls_tls (void)
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	ASSERT (s_8021x != NULL,
 	        "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
@@ -5756,13 +5863,13 @@ test_read_wifi_dynamic_wep_leap (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wifi = nm_connection_get_setting_wireless (connection);
 	g_assert (s_wifi);
 
 	g_assert_cmpstr (nm_setting_wireless_get_security (s_wifi), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
 
 	/* ===== WiFi SECURITY SETTING ===== */
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec);
 
 	/* Key management */
@@ -5778,7 +5885,7 @@ test_read_wifi_dynamic_wep_leap (void)
 	g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, NULL);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x);
 
 	/* EAP method should be "leap" */
@@ -5839,7 +5946,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-eap-ttls-chap-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
@@ -5847,7 +5954,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
@@ -5862,7 +5969,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
 	/* ===== 802.1x SETTING ===== */
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
@@ -5882,7 +5989,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
 	        NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
 
 	/* ===== 802.1x SETTING ===== */
-	s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	ASSERT (s_8021x != NULL,
 	        "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
@@ -6005,7 +6112,7 @@ test_read_wired_qeth_static (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wired-qeth-static-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_QETH_STATIC,
@@ -6026,7 +6133,7 @@ test_read_wired_qeth_static (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "wired-qeth-static-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_QETH_STATIC,
@@ -6116,7 +6223,7 @@ test_read_wired_qeth_static (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "wired-qeth-static-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIRED_QETH_STATIC,
@@ -6247,7 +6354,7 @@ test_read_wifi_wep_no_keys (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_NO_KEYS,
@@ -6273,7 +6380,7 @@ test_read_wifi_wep_no_keys (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_NO_KEYS,
@@ -6295,7 +6402,7 @@ test_read_wifi_wep_no_keys (void)
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
 
-	s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	ASSERT (s_wsec != NULL,
 	        "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_WIFI_WEP_NO_KEYS,
@@ -6371,7 +6478,7 @@ test_read_permissions (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "permissions-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_PERMISSIONS,
@@ -6451,13 +6558,13 @@ test_read_wifi_wep_agent_keys (void)
 	 */
 
 	/* ===== WIRELESS SETTING ===== */
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wifi = nm_connection_get_setting_wireless (connection);
 	g_assert (s_wifi);
 	tmp = nm_setting_wireless_get_security (s_wifi);
 	g_assert (g_strcmp0 (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0);
 
 	/* ===== WIRELESS SECURITY SETTING ===== */
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	g_assert (s_wsec);
 
 	g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0);
@@ -6692,8 +6799,8 @@ test_write_wired_static (void)
 	 * However after re-reading they are dropped into IPv4 setting.
 	 * So, in order to comparison succeeded, move DNS domains back to IPv6 setting.
 	 */
-	reread_s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG));
-	reread_s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP6_CONFIG));
+	reread_s_ip4 = nm_connection_get_setting_ip4_config (reread);
+	reread_s_ip6 = nm_connection_get_setting_ip6_config (reread);
 	nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 2));
 	nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 3));
 	nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 3);
@@ -7018,7 +7125,7 @@ test_read_write_static_routes_legacy (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
@@ -7041,7 +7148,7 @@ test_read_write_static_routes_legacy (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "read-write-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
@@ -7049,7 +7156,7 @@ test_read_write_static_routes_legacy (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
@@ -7628,7 +7735,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme,
 	 * matter what scheme was used in the original connection they will be read
 	 * back in as paths.
 	 */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (reread);
 	g_assert (s_8021x);
 	g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH);
 	g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH);
@@ -7657,7 +7764,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme,
 			 * say it's not system-owned, and therefore it should not show up
 			 * in the re-read connection.
 			 */
-			s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+			s_8021x = nm_connection_get_setting_802_1x (connection);
 			g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL);
 		}
 
@@ -10085,7 +10192,7 @@ test_write_wifi_wpa_then_open (void)
 	g_object_unref (reread);
 
 	/* Now change the connection to open and recheck */
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wifi = nm_connection_get_setting_wireless (connection);
 	g_assert (s_wifi);
 	g_object_set (s_wifi, NM_SETTING_WIRELESS_SEC, NULL, NULL);
 	nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
@@ -10534,7 +10641,7 @@ test_read_ibft_dhcp (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "ibft-dhcp-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_DHCP,
@@ -10581,7 +10688,7 @@ test_read_ibft_dhcp (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "ibft-dhcp-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_DHCP,
@@ -10613,7 +10720,7 @@ test_read_ibft_dhcp (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "ibft-dhcp-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_DHCP,
@@ -10679,7 +10786,7 @@ test_read_ibft_static (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "ibft-static-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_STATIC,
@@ -10726,7 +10833,7 @@ test_read_ibft_static (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "ibft-static-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_STATIC,
@@ -10758,7 +10865,7 @@ test_read_ibft_static (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "ibft-static-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_IFCFG_IBFT_STATIC,
@@ -11754,6 +11861,8 @@ test_read_vlan_interface (void)
 	char *route6file = NULL;
 	gboolean ignore_error = FALSE;
 	GError *error = NULL;
+	NMSettingVlan *s_vlan;
+	guint32 from = 0, to = 0;
 
 	connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE,
 	                                   NULL,
@@ -11765,13 +11874,844 @@ test_read_vlan_interface (void)
 	                                   &route6file,
 	                                   &error,
 	                                   &ignore_error);
-	ASSERT (connection == NULL,
-	        "vlan-interface-read", "unexpected success reading %s", TEST_IFCFG_VLAN_INTERFACE);
+	g_assert_no_error (error);
+	g_assert (connection != NULL);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+
+	s_vlan = nm_connection_get_setting_vlan (connection);
+	g_assert (s_vlan);
+
+	g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "vlan43");
+	g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9");
+	g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43);
+	g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==,
+	                 NM_VLAN_FLAG_GVRP | NM_VLAN_FLAG_LOOSE_BINDING);
+
+	/* Ingress map */
+	g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP), ==, 2);
+
+	g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0, &from, &to));
+	g_assert_cmpint (from, ==, 0);
+	g_assert_cmpint (to, ==, 1);
+
+	g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, &from, &to));
+	g_assert_cmpint (from, ==, 2);
+	g_assert_cmpint (to, ==, 5);
+
+	/* Egress map */
+	g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP), ==, 3);
+
+	g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0, &from, &to));
+	g_assert_cmpint (from, ==, 12);
+	g_assert_cmpint (to, ==, 3);
+
+	g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to));
+	g_assert_cmpint (from, ==, 14);
+	g_assert_cmpint (to, ==, 7);
+
+	g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to));
+	g_assert_cmpint (from, ==, 3);
+	g_assert_cmpint (to, ==, 1);
+
+	g_object_unref (connection);
+}
+
+#define TEST_IFCFG_VLAN_ONLY_VLANID TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-only-vlanid"
+
+static void
+test_read_vlan_only_vlan_id (void)
+{
+	NMConnection *connection;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	NMSettingVlan *s_vlan;
+
+	connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	g_assert_no_error (error);
+	g_assert (connection != NULL);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+
+	s_vlan = nm_connection_get_setting_vlan (connection);
+	g_assert (s_vlan);
+
+	g_assert (nm_setting_vlan_get_interface_name (s_vlan) == NULL);
+	g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9");
+	g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43);
+
+	g_object_unref (connection);
+}
+
+#define TEST_IFCFG_VLAN_ONLY_DEVICE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-only-device"
+
+static void
+test_read_vlan_only_device (void)
+{
+	NMConnection *connection;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	NMSettingVlan *s_vlan;
+
+	connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_DEVICE,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	g_assert_no_error (error);
+	g_assert (connection != NULL);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+
+	s_vlan = nm_connection_get_setting_vlan (connection);
+	g_assert (s_vlan);
+
+	g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "eth0.9");
+	g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0");
+	g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 9);
+
+	g_object_unref (connection);
+}
+
+static void
+test_write_vlan (void)
+{
+	NMConnection *connection;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	char *written = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	gboolean success = FALSE;
+
+	connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE,
+	                                   NULL,
+	                                   TYPE_VLAN,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	g_assert (connection != NULL);
+
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &written,
+	                                 &error);
+	g_assert (success);
+
+	unlink (written);
+	g_free (written);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+}
+
+static void
+test_write_vlan_only_vlanid (void)
+{
+	NMConnection *connection, *reread;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	char *written = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	gboolean success = FALSE;
+
+	connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID,
+	                                   NULL,
+	                                   TYPE_VLAN,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	g_assert_no_error (error);
+	g_assert (connection != NULL);
+
+	g_free (unmanaged);
+	unmanaged = NULL;
+	g_free (keyfile);
+	keyfile = NULL;
+	g_free (routefile);
+	routefile = NULL;
+	g_free (route6file);
+	route6file = NULL;
+
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &written,
+	                                 &error);
+	g_assert (success);
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (written,
+	                               NULL,
+	                               TYPE_ETHERNET,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (written);
+	g_free (written);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+
+	g_assert_no_error (error);
+	g_assert (reread != NULL);
+
+	success = nm_connection_verify (reread, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (success);
+
+	g_object_unref (connection);
+	g_object_unref (reread);
+}
+
+#define TEST_IFCFG_BOND_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-main"
+
+static void
+test_read_bond_main (void)
+{
+	NMConnection *connection;
+	NMSettingBond *s_bond;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+
+	connection = connection_from_file (TEST_IFCFG_BOND_MAIN,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	ASSERT (connection != NULL,
+	        "bond-main-read", "unexpected failure reading %s", TEST_IFCFG_BOND_MAIN);
+
+	ASSERT (nm_connection_verify (connection, &error),
+	        "bond-main-read", "failed to verify %s: %s", TEST_IFCFG_BOND_MAIN, error->message);
+
+	/* ===== Bonding SETTING ===== */
+
+	s_bond = nm_connection_get_setting_bond (connection);
+	ASSERT (s_bond != NULL,
+	        "bond-main", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_BOND_MAIN,
+	        NM_SETTING_BOND_SETTING_NAME);
+
+	ASSERT (g_strcmp0 (nm_setting_bond_get_interface_name (s_bond), "bond0") == 0,
+	        "bond-main", "failed to verify %s: DEVICE=%s does not match bond0",
+	        TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_interface_name (s_bond));
+
+	ASSERT (g_strcmp0 (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), "100") == 0,
+	        "bond-main", "failed to verify %s: miimon=%s does not match 100",
+	        TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON));
 
 	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
+	g_object_unref (connection);
+}
+
+static void
+test_write_bond_main (void)
+{
+	NMConnection *connection;
+	NMConnection *reread;
+	NMSettingConnection *s_con;
+	NMSettingBond *s_bond;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	NMSettingWired *s_wired;
+	char *uuid;
+	const guint32 ip1 = htonl (0x01010103);
+	const guint32 gw = htonl (0x01010101);
+	const guint32 prefix = 24;
+	NMIP4Address *addr;
+	gboolean success;
+	GError *error = NULL;
+	char *testfile = NULL;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+
+	connection = nm_connection_new ();
+	ASSERT (connection != NULL,
+	        "bond-main-write", "failed to allocate new connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_setting_connection_new ();
+	ASSERT (s_con != NULL,
+	        "bond-main-write", "failed to allocate new %s setting",
+	        NM_SETTING_CONNECTION_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+	uuid = nm_utils_uuid_generate ();
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "Test Write Bond Main",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* Wired setting */
+	s_wired = (NMSettingWired *) nm_setting_wired_new ();
+	ASSERT (s_wired != NULL,
+	        "bond-main-write", "failed to allocate new %s setting",
+	        NM_SETTING_WIRED_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+	/* bond setting */
+	s_bond = (NMSettingBond *) nm_setting_bond_new ();
+	ASSERT (s_bond != NULL,
+	        "bond-main-write", "failed to allocate new %s setting",
+	        NM_SETTING_BOND_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_bond));
+
+	g_object_set (s_bond,
+	              NM_SETTING_BOND_INTERFACE_NAME, "bond0",
+	              NULL);
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+	ASSERT (s_ip4 != NULL,
+			"bond-main-write", "failed to allocate new %s setting",
+			NM_SETTING_IP4_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+	g_object_set (s_ip4,
+	              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+	              NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE,
+	              NULL);
+
+	addr = nm_ip4_address_new ();
+	nm_ip4_address_set_address (addr, ip1);
+	nm_ip4_address_set_prefix (addr, prefix);
+	nm_ip4_address_set_gateway (addr, gw);
+	nm_setting_ip4_config_add_address (s_ip4, addr);
+	nm_ip4_address_unref (addr);
+
+	/* IP6 setting */
+	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+	ASSERT (s_ip6 != NULL,
+	        "bond-main-write", "failed to allocate new %s setting",
+	        NM_SETTING_IP6_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+	g_object_set (s_ip6,
+	              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+	              NULL);
+
+	ASSERT (nm_connection_verify (connection, &error) == TRUE,
+	        "bond-main-write", "failed to verify connection: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	/* Save the ifcfg */
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &testfile,
+	                                 &error);
+	ASSERT (success == TRUE,
+	        "bond-main-write", "failed to write connection to disk: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	ASSERT (testfile != NULL,
+	        "bond-main-write", "didn't get ifcfg file path back after writing connection");
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_BOND,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (testfile);
+
+	ASSERT (reread != NULL,
+	        "bond-main-write-reread", "failed to read %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_verify (reread, &error),
+	        "bond-main-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+	        "bond-main-write", "written and re-read connection weren't the same.");
+
+	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+	g_object_unref (reread);
+}
+
+#define TEST_IFCFG_BOND_SLAVE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-slave"
+
+static void
+test_read_bond_slave (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+
+	connection = connection_from_file (TEST_IFCFG_BOND_SLAVE,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	ASSERT (connection != NULL,
+	        "bond-slave-read", "unexpected failure reading %s", TEST_IFCFG_BOND_MAIN);
+
+	ASSERT (nm_connection_verify (connection, &error),
+	        "bond-slave-read", "failed to verify %s: %s", TEST_IFCFG_BOND_MAIN, error->message);
+
+	s_con = nm_connection_get_setting_connection (connection);
+	ASSERT (s_con != NULL,
+	        "bond-slave-read", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_BOND_SLAVE, NM_SETTING_CONNECTION_SETTING_NAME);
+
+	ASSERT (g_strcmp0 (nm_setting_connection_get_master (s_con), "bond0") == 0,
+	        "bond-slave-read", "failed to verify %s: master is not bond0",
+	        TEST_IFCFG_BOND_SLAVE);
+
+	ASSERT (g_strcmp0 (nm_setting_connection_get_slave_type (s_con), NM_SETTING_BOND_SETTING_NAME) == 0,
+	        "bond-slave-read", "failed to verify %s: slave-type is not bond",
+	        TEST_IFCFG_BOND_SLAVE);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+}
+
+static void
+test_write_bond_slave (void)
+{
+	NMConnection *connection;
+	NMConnection *reread;
+	NMSettingConnection *s_con;
+	NMSettingWired *s_wired;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
+	GByteArray *mac;
+	guint32 mtu = 1492;
+	char *uuid;
+	gboolean success;
+	GError *error = NULL;
+	char *testfile = NULL;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+
+	connection = nm_connection_new ();
+	ASSERT (connection != NULL,
+	        "bond-slave-write", "failed to allocate new connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_setting_connection_new ();
+	ASSERT (s_con != NULL,
+	        "bond-slave-write", "failed to allocate new %s setting",
+	        NM_SETTING_CONNECTION_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+	uuid = nm_utils_uuid_generate ();
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "Test Write Bond Slave",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+				  NM_SETTING_CONNECTION_MASTER, "bond0",
+				  NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* Wired setting */
+	s_wired = (NMSettingWired *) nm_setting_wired_new ();
+	ASSERT (s_wired != NULL,
+	        "bond-main-write", "failed to allocate new %s setting",
+	        NM_SETTING_WIRED_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+	mac = g_byte_array_sized_new (sizeof (tmpmac));
+	g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+
+	g_object_set (s_wired,
+	              NM_SETTING_WIRED_MAC_ADDRESS, mac,
+	              NM_SETTING_WIRED_MTU, mtu,
+	              NULL);
+	g_byte_array_free (mac, TRUE);
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+	ASSERT (s_ip4 != NULL,
+			"bond-slave-write", "failed to allocate new %s setting",
+			NM_SETTING_IP4_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+	g_object_set (s_ip4,
+	              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
+	              NULL);
+
+	/* IP6 setting */
+	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+	ASSERT (s_ip6 != NULL,
+	        "bond-slave-write", "failed to allocate new %s setting",
+	        NM_SETTING_IP6_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+	g_object_set (s_ip6,
+	              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+	              NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
+	              NULL);
+
+	ASSERT (nm_connection_verify (connection, &error) == TRUE,
+	        "bond-slave-write", "failed to verify connection: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	/* Save the ifcfg */
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &testfile,
+	                                 &error);
+	ASSERT (success == TRUE,
+	        "bond-slave-write", "failed to write connection to disk: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	ASSERT (testfile != NULL,
+	        "bond-slave-write", "didn't get ifcfg file path back after writing connection");
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_ETHERNET,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (testfile);
+
+	ASSERT (reread != NULL,
+	        "bond-slave-write-reread", "failed to read %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_verify (reread, &error),
+	        "bond-slave-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+	        "bond-slave-write", "written and re-read connection weren't the same.");
+
+	if (route6file)
+		unlink (route6file);
+
+	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+	g_object_unref (reread);
+}
+
+#define TEST_IFCFG_INFINIBAND TEST_IFCFG_DIR"/network-scripts/ifcfg-test-infiniband"
+
+static void
+test_read_infiniband (void)
+{
+	NMConnection *connection;
+	NMSettingInfiniband *s_infiniband;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	GError *error = NULL;
+	const GByteArray *array;
+	char expected_mac_address[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 };
+	const char *transport_mode;
+
+	connection = connection_from_file (TEST_IFCFG_INFINIBAND,
+	                                   NULL,
+	                                   TYPE_INFINIBAND,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	ASSERT (connection != NULL,
+	        "infiniband-read", "failed to read %s: %s", TEST_IFCFG_INFINIBAND, error->message);
+
+	ASSERT (nm_connection_verify (connection, &error),
+	        "infiniband-verify", "failed to verify %s: %s", TEST_IFCFG_INFINIBAND, error->message);
+
+	ASSERT (unmanaged == NULL,
+	        "infiniband-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_INFINIBAND);
+
+	/* ===== INFINIBAND SETTING ===== */
+
+	s_infiniband = nm_connection_get_setting_infiniband (connection);
+	ASSERT (s_infiniband != NULL,
+	        "infiniband-verify-wired", "failed to verify %s: missing %s setting",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME);
+
+	/* MAC address */
+	array = nm_setting_infiniband_get_mac_address (s_infiniband);
+	ASSERT (array != NULL,
+	        "infiniband-verify-infiniband", "failed to verify %s: missing %s / %s key",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME,
+	        NM_SETTING_INFINIBAND_MAC_ADDRESS);
+	ASSERT (array->len == INFINIBAND_ALEN,
+	        "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value length",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME,
+	        NM_SETTING_INFINIBAND_MAC_ADDRESS);
+	ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+	        "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME,
+	        NM_SETTING_INFINIBAND_MAC_ADDRESS);
+
+	/* Transport mode */
+	transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband);
+	ASSERT (transport_mode != NULL,
+	        "infiniband-verify-infiniband", "failed to verify %s: missing %s / %s key",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME,
+	        NM_SETTING_INFINIBAND_TRANSPORT_MODE);
+	ASSERT (strcmp (transport_mode, "connected") == 0,
+	        "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value",
+	        TEST_IFCFG_INFINIBAND,
+	        NM_SETTING_INFINIBAND_SETTING_NAME,
+	        NM_SETTING_INFINIBAND_TRANSPORT_MODE);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+}
+
+static void
+test_write_infiniband (void)
+{
+	NMConnection *connection;
+	NMConnection *reread;
+	NMSettingConnection *s_con;
+	NMSettingInfiniband *s_infiniband;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	unsigned char tmpmac[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 };
+	GByteArray *mac;
+	guint32 mtu = 65520;
+	char *uuid;
+	const guint32 ip1 = htonl (0x01010103);
+	const guint32 gw = htonl (0x01010101);
+	const guint32 prefix = 24;
+	NMIP4Address *addr;
+	gboolean success;
+	GError *error = NULL;
+	char *testfile = NULL;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+
+	connection = nm_connection_new ();
+	ASSERT (connection != NULL,
+	        "infiniband-write", "failed to allocate new connection");
+
+	/* Connection setting */
+	s_con = (NMSettingConnection *) nm_setting_connection_new ();
+	ASSERT (s_con != NULL,
+	        "infiniband-write", "failed to allocate new %s setting",
+	        NM_SETTING_CONNECTION_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+	uuid = nm_utils_uuid_generate ();
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "Test Write InfiniBand",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* InfiniBand setting */
+	s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new ();
+	ASSERT (s_infiniband != NULL,
+	        "infiniband-write", "failed to allocate new %s setting",
+	        NM_SETTING_INFINIBAND_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_infiniband));
+
+	mac = g_byte_array_sized_new (sizeof (tmpmac));
+	g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+
+	g_object_set (s_infiniband,
+	              NM_SETTING_INFINIBAND_MAC_ADDRESS, mac,
+	              NM_SETTING_INFINIBAND_MTU, mtu,
+	              NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected",
+	              NULL);
+	g_byte_array_free (mac, TRUE);
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+	ASSERT (s_ip4 != NULL,
+			"infiniband-write", "failed to allocate new %s setting",
+			NM_SETTING_IP4_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+	g_object_set (s_ip4,
+	              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+	              NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE,
+	              NULL);
+
+	addr = nm_ip4_address_new ();
+	nm_ip4_address_set_address (addr, ip1);
+	nm_ip4_address_set_prefix (addr, prefix);
+	nm_ip4_address_set_gateway (addr, gw);
+	nm_setting_ip4_config_add_address (s_ip4, addr);
+	nm_ip4_address_unref (addr);
+
+	/* IP6 setting */
+	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+	ASSERT (s_ip6 != NULL,
+	        "wired-static-write", "failed to allocate new %s setting",
+	        NM_SETTING_IP6_CONFIG_SETTING_NAME);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+	g_object_set (s_ip6,
+	              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+	              NULL);
+
+	ASSERT (nm_connection_verify (connection, &error) == TRUE,
+	        "infiniband-write", "failed to verify connection: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	/* Save the ifcfg */
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &testfile,
+	                                 &error);
+	ASSERT (success == TRUE,
+	        "infiniband-write", "failed to write connection to disk: %s",
+	        (error && error->message) ? error->message : "(unknown)");
+
+	ASSERT (testfile != NULL,
+	        "infiniband-write", "didn't get ifcfg file path back after writing connection");
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_INFINIBAND,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (testfile);
+
+	ASSERT (reread != NULL,
+	        "infiniband-write-reread", "failed to read %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_verify (reread, &error),
+	        "infiniband-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+	ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+	        "infiniband-write", "written and re-read connection weren't the same.");
+
+	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+	g_object_unref (reread);
 }
 
 #define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex"
@@ -11843,6 +12783,7 @@ int main (int argc, char **argv)
 	test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_ALWAYS,
 	                                  NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
 	test_read_wifi_wpa_psk ();
+	test_read_wifi_wpa_psk_2 ();
 	test_read_wifi_wpa_psk_unquoted ();
 	test_read_wifi_wpa_psk_unquoted2 ();
 	test_read_wifi_wpa_psk_adhoc ();
@@ -11856,6 +12797,10 @@ int main (int argc, char **argv)
 	test_read_wifi_wep_no_keys ();
 	test_read_permissions ();
 	test_read_wifi_wep_agent_keys ();
+	test_read_infiniband ();
+	test_read_vlan_interface ();
+	test_read_vlan_only_vlan_id ();
+	test_read_vlan_only_device ();
 
 	test_write_wired_static ();
 	test_write_wired_static_ip6_only ();
@@ -11908,6 +12853,12 @@ int main (int argc, char **argv)
 	                         TRUE,
 	                         TRUE,
 	                         "really insecure passphrase04!");
+	test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK Passphrase Special Chars",
+	                         "wifi-wpa-wpa2-psk-passphrase-write-spec-chars",
+	                         FALSE,
+	                         TRUE,
+	                         TRUE,
+	                         "blah`oops\"grr'$*@~!%");
 	test_write_wifi_wpa_psk_adhoc ();
 	test_write_wifi_wpa_eap_tls ();
 	test_write_wifi_wpa_eap_ttls_tls ();
@@ -11919,6 +12870,9 @@ int main (int argc, char **argv)
 	test_write_wired_ctc_dhcp ();
 	test_write_permissions ();
 	test_write_wifi_wep_agent_keys ();
+	test_write_infiniband ();
+	test_write_vlan ();
+	test_write_vlan_only_vlanid ();
 
 	/* iSCSI / ibft */
 	test_read_ibft_dhcp ();
@@ -11930,6 +12884,12 @@ int main (int argc, char **argv)
 	test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1");
 	test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2");
 
+	/* bonding */
+	test_read_bond_main ();
+	test_read_bond_slave ();
+	test_write_bond_main ();
+	test_write_bond_slave ();
+
 	/* Stuff we expect to fail for now */
 	test_write_wired_pppoe ();
 	test_write_vpn ();
@@ -11937,7 +12897,6 @@ int main (int argc, char **argv)
 	test_write_mobile_broadband (FALSE);
 	test_read_bridge_main ();
 	test_read_bridge_component ();
-	test_read_vlan_interface ();
 
 	base = g_path_get_basename (argv[0]);
 	fprintf (stdout, "%s: SUCCESS\n", base);
diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c
index 92a0b802..0b7ddf36 100644
--- a/src/settings/plugins/ifcfg-rh/utils.c
+++ b/src/settings/plugins/ifcfg-rh/utils.c
@@ -15,7 +15,7 @@
  * 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 - 2010 Red Hat, Inc.
+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
  */
 
 #include <glib.h>
@@ -116,6 +116,89 @@ utils_hexstr2bin (const char *hex, size_t len)
 /* End from hostap */
 
 /*
+ * utils_single_quote_string
+ *
+ * Put string inside single quotes and remove CR, LF characters. If single quote
+ * is present, escape it with a backslash and prepend the whole string with $
+ * in order to have $'string'. That allows us to use single quote inside
+ * single quotes without breaking bash syntax. (man bash, section QUOTING).
+ *
+ * Caller is responsible for freeing the returned string.
+ */
+char *
+utils_single_quote_string (const char *str)
+{
+	static const char const drop_chars[] = "\r\n"; /* drop CR and LF */
+	static const char escape_char = '\\'; /* escape char is backslash */
+	static const char quote_char = '\'';  /* quote char is single quote */
+	size_t i, slen, j = 0;
+	size_t drop = 0, extra = 0;
+	char *new_str;
+
+	slen = strlen (str);
+	for (i = 0; i < slen; i++) {
+		if (str[i] == quote_char)
+			extra++;
+		if (strchr (drop_chars, str[i]))
+			drop++;
+	}
+	new_str = g_malloc0 (slen + extra - drop + 4); /* 4 is for $''\0*/
+	if (!new_str) return NULL;
+
+	if (extra > 0)
+		new_str[j++] = '$';
+	new_str[j++] = quote_char;
+	for (i = 0; i < slen; i++) {
+		if (strchr (drop_chars, str[i]))
+			continue;
+		if (str[i] == quote_char)
+			new_str[j++] = escape_char;
+		new_str[j++] = str[i];
+	}
+	new_str[j] = quote_char;
+
+	return new_str;
+}
+
+/*
+ * utils_single_unquote_string
+ *
+ * Remove string from single (or double) quotes, and remove escaping of '.
+ * Also remove first $ if the string is in the form of $'string'.
+ *
+ * Caller is responsible for freeing the returned string.
+ */
+char *
+utils_single_unquote_string (const char *str)
+{
+	static const char escape_char = '\\'; /* escape char is backslash */
+	static const char q_char = '\''; /* quote char is single quote */
+	static const char dq_char = '"'; /* double quote char */
+	size_t i, slen, j = 0, quote = 0, dollar = 0;
+	char *new_str;
+
+	slen = strlen (str);
+	new_str = g_malloc0 (slen + 1);
+	if (!new_str) return NULL;
+
+	if (   (slen >= 2 && (str[0] == dq_char || str[0] == q_char) && str[0] == str[slen-1])
+	    || (slen >= 3 && str[0] == '$' && str[1] == q_char && str[1] == str[slen-1])) {
+		quote = 1;
+		if (str[0] == '$') dollar = 1;
+	}
+
+	i = quote + dollar;
+	while (i < slen - quote) {
+		if (str[i] == escape_char && str[i+1] == q_char)
+			i++;
+		new_str[j++] = str[i++];
+	}
+	new_str[j] = '\0';
+
+	return new_str;
+}
+
+/*
  * Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when
  * installing packages.
  *
@@ -360,3 +443,17 @@ gone:
 	return ret;
 }
 
+gboolean
+utils_disabling_ip4_config_allowed (NMConnection *connection)
+{
+	NMSettingConnection *s_con;
+
+	s_con = nm_connection_get_setting_connection (connection);
+	g_assert (s_con);
+
+	/* bonding slaves are allowed to have no ip configuration */
+	if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME))
+		return TRUE;
+
+	return FALSE;
+}
diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h
index d5e3a133..4fe7303b 100644
--- a/src/settings/plugins/ifcfg-rh/utils.h
+++ b/src/settings/plugins/ifcfg-rh/utils.h
@@ -15,13 +15,14 @@
  * 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 - 2009 Red Hat, Inc.
+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
  */
 
 #ifndef _UTILS_H_
 #define _UTILS_H_
 
 #include <glib.h>
+#include <nm-connection.h>
 #include "shvar.h"
 #include "common.h"
 
@@ -29,6 +30,10 @@ char *utils_bin2hexstr (const char *bytes, int len, int final_len);
 
 char *utils_hexstr2bin (const char *hex, size_t len);
 
+char *utils_single_quote_string (const char *str);
+
+char *utils_single_unquote_string (const char *str);
+
 char *utils_cert_path (const char *parent, const char *suffix);
 
 const char *utils_get_ifcfg_name (const char *file, gboolean only_ifcfg);
@@ -47,5 +52,7 @@ shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create);
 
 gboolean utils_has_route_file_new_syntax (const char *filename);
 
+gboolean utils_disabling_ip4_config_allowed (NMConnection *connection);
+
 #endif  /* _UTILS_H_ */
 
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index 068bcda2..e2aa57dd 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2009 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 - 2012 Red Hat, Inc.
  */
 
 #include <ctype.h>
@@ -28,6 +28,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <netinet/ether.h>
 
 #include <nm-setting-connection.h>
 #include <nm-setting-wired.h>
@@ -36,6 +37,7 @@
 #include <nm-setting-ip4-config.h>
 #include <nm-setting-ip6-config.h>
 #include <nm-setting-pppoe.h>
+#include <nm-setting-vlan.h>
 #include <nm-utils.h>
 
 #include "common.h"
@@ -456,7 +458,7 @@ write_8021x_setting (NMConnection *connection,
 	gboolean success = FALSE;
 	GString *phase2_auth;
 
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	if (!s_8021x) {
 		/* If wired, clear KEY_MGMT */
 		if (wired)
@@ -504,6 +506,24 @@ write_8021x_setting (NMConnection *connection,
 	if (value && !strcmp (value, "1"))
 		svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", "yes", FALSE);
 
+	/* PAC file */
+	value = nm_setting_802_1x_get_pac_file (s_8021x);
+	svSetValue (ifcfg, "IEEE_8021X_PAC_FILE", NULL, FALSE);
+	if (value)
+		svSetValue (ifcfg, "IEEE_8021X_PAC_FILE", value, FALSE);
+
+	/* FAST PAC provisioning */
+	value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x);
+	svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", NULL, FALSE);
+	if (value) {
+		if (strcmp (value, "1") == 0)
+			svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-unauth", FALSE);
+		else if (strcmp (value, "2") == 0)
+			svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-auth", FALSE);
+		else if (strcmp (value, "3") == 0)
+			svSetValue (ifcfg, "IEEE_8021X_FAST_PROVISIONING", "allow-unauth allow-auth", FALSE);
+	}
+
 	/* Phase2 auth methods */
 	svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", NULL, FALSE);
 	phase2_auth = g_string_new (NULL);
@@ -554,7 +574,7 @@ write_wireless_security_setting (NMConnection *connection,
 	guint32 i, num;
 	GString *str;
 
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	if (!s_wsec) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
@@ -716,24 +736,20 @@ write_wireless_security_setting (NMConnection *connection,
 
 	/* WPA Passphrase */
 	if (wpa) {
-		GString *quoted = NULL;
+		char *quoted = NULL;
 
 		psk = nm_setting_wireless_security_get_psk (s_wsec);
 		if (psk && (strlen (psk) != 64)) {
 			/* Quote the PSK since it's a passphrase */
-			quoted = g_string_sized_new (strlen (psk) + 2); /* 2 for quotes */
-			g_string_append_c (quoted, '"');
-			g_string_append (quoted, psk);
-			g_string_append_c (quoted, '"');
+			quoted = utils_single_quote_string (psk);
 		}
 		set_secret (ifcfg,
 		            "WPA_PSK",
-		            quoted ? quoted->str : psk,
+		            quoted ? quoted : psk,
 		            "WPA_PSK_FLAGS",
 		            nm_setting_wireless_security_get_psk_flags (s_wsec),
 		            TRUE);
-		if (quoted)
-			g_string_free (quoted, TRUE);
+		g_free (quoted);
 	} else {
 		set_secret (ifcfg,
 		            "WPA_PSK",
@@ -761,7 +777,7 @@ write_wireless_setting (NMConnection *connection,
 	gboolean adhoc = FALSE, hex_ssid = FALSE;
 	const GSList *macaddr_blacklist;
 
-	s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	if (!s_wireless) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME);
@@ -944,6 +960,48 @@ write_wireless_setting (NMConnection *connection,
 }
 
 static gboolean
+write_infiniband_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+	NMSettingInfiniband *s_infiniband;
+	const GByteArray *mac;
+	char *tmp;
+	const char *transport_mode;
+	guint32 mtu;
+
+	s_infiniband = nm_connection_get_setting_infiniband (connection);
+	if (!s_infiniband) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Missing '%s' setting", NM_SETTING_INFINIBAND_SETTING_NAME);
+		return FALSE;
+	}
+
+	svSetValue (ifcfg, "HWADDR", NULL, FALSE);
+	mac = nm_setting_infiniband_get_mac_address (s_infiniband);
+	if (mac) {
+		tmp = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND);
+		svSetValue (ifcfg, "HWADDR", tmp, FALSE);
+		g_free (tmp);
+	}
+
+	svSetValue (ifcfg, "MTU", NULL, FALSE);
+	mtu = nm_setting_infiniband_get_mtu (s_infiniband);
+	if (mtu) {
+		tmp = g_strdup_printf ("%u", mtu);
+		svSetValue (ifcfg, "MTU", tmp, FALSE);
+		g_free (tmp);
+	}
+
+	transport_mode = nm_setting_infiniband_get_transport_mode (s_infiniband);
+	svSetValue (ifcfg, "CONNECTED_MODE",
+	            strcmp (transport_mode, "connected") == 0 ? "yes" : "no",
+	            FALSE);
+
+	svSetValue (ifcfg, "TYPE", TYPE_INFINIBAND, FALSE);
+
+	return TRUE;
+}
+
+static gboolean
 write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 {
 	NMSettingWired *s_wired;
@@ -955,7 +1013,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	GString *str;
 	const GSList *macaddr_blacklist;
 
-	s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	if (!s_wired) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME);
@@ -1064,11 +1122,143 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	return TRUE;
 }
 
+static GString *vlan_priority_maplist_to_stringlist (NMSettingVlan *s_vlan, NMVlanPriorityMap map)
+{
+	GSList *strlist = NULL, *iter;
+	GString *value = NULL;
+
+	if (map == NM_VLAN_INGRESS_MAP)
+		g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, &strlist, NULL);
+	else if (map == NM_VLAN_EGRESS_MAP)
+		g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, &strlist, NULL);
+	else
+		return NULL;
+
+	value = g_string_new ("");
+	for (iter = strlist; iter; iter = g_slist_next (iter))
+		g_string_append_printf (value, "%s%s", value->len ? "," : "", (const char *) iter->data);
+
+	nm_utils_slist_free (strlist, g_free);
+
+	return value;
+}
+
+static gboolean
+write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+	NMSettingVlan *s_vlan;
+	NMSettingConnection *s_con;
+	char *tmp;
+	guint32 vlan_flags = 0;
+	GString *text = NULL;
+
+	s_con = nm_connection_get_setting_connection (connection);
+	if (!s_con) {
+		g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing connection setting");
+		return FALSE;
+	}
+
+	s_vlan = nm_connection_get_setting_vlan (connection);
+	if (!s_vlan) {
+		g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing VLAN setting");
+		return FALSE;
+	}
+
+	svSetValue (ifcfg, "VLAN", "yes", FALSE);
+	svSetValue (ifcfg, "TYPE", TYPE_VLAN, FALSE);
+	svSetValue (ifcfg, "DEVICE", nm_setting_vlan_get_interface_name (s_vlan), FALSE);
+	svSetValue (ifcfg, "PHYSDEV", nm_setting_vlan_get_parent (s_vlan), FALSE);
+	svSetValue (ifcfg, "MASTER", nm_setting_connection_get_master (s_con), FALSE);
+
+	tmp = g_strdup_printf ("%d", nm_setting_vlan_get_id (s_vlan));
+	svSetValue (ifcfg, "VLAN_ID", tmp, FALSE);
+	g_free (tmp);
+
+	vlan_flags = nm_setting_vlan_get_flags (s_vlan);
+	if (vlan_flags & NM_VLAN_FLAG_REORDER_HEADERS)
+		svSetValue (ifcfg, "REORDER_HDR", "1", FALSE);
+	else
+		svSetValue (ifcfg, "REORDER_HDR", "0", FALSE);
+
+	svSetValue (ifcfg, "VLAN_FLAGS", NULL, FALSE);
+	if (vlan_flags & NM_VLAN_FLAG_GVRP) {
+		if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING)
+			svSetValue (ifcfg, "VLAN_FLAGS", "GVRP,LOOSE_BINDING", FALSE);
+		else
+			svSetValue (ifcfg, "VLAN_FLAGS", "GVRP", FALSE);
+	} else if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING)
+		svSetValue (ifcfg, "VLAN_FLAGS", "LOOSE_BINDING", FALSE);
+
+	text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP);
+	svSetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE);
+	if (text)
+		g_string_free (text, TRUE);
+
+	text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_EGRESS_MAP);
+	svSetValue (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE);
+	if (text)
+		g_string_free (text, TRUE);
+
+	return TRUE;
+}
+
+static gboolean
+write_bonding_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+	NMSettingBond *s_bond;
+	const char *iface;
+	guint32 i, num_opts;
+
+	s_bond = nm_connection_get_setting_bond (connection);
+	if (!s_bond) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+		             "Missing '%s' setting", NM_SETTING_BOND_SETTING_NAME);
+		return FALSE;
+	}
+
+	iface = nm_setting_bond_get_interface_name (s_bond);
+	if (!iface) {
+		g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing interface name");
+		return FALSE;
+	}
+
+	svSetValue (ifcfg, "DEVICE", iface, FALSE);
+	svSetValue (ifcfg, "BONDING_OPTS", NULL, FALSE);
+
+	num_opts = nm_setting_bond_get_num_options (s_bond);
+	if (num_opts > 0) {
+		GString *str = g_string_sized_new (64);
+
+		for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) {
+			const char *key, *value;
+
+			if (!nm_setting_bond_get_option (s_bond, i, &key, &value))
+				continue;
+
+			if (str->len)
+				g_string_append_c (str, ' ');
+
+			g_string_append_printf (str, "%s=%s", key, value);
+		}
+
+		if (str->len)
+			svSetValue (ifcfg, "BONDING_OPTS", str->str, FALSE);
+
+		g_string_free (str, TRUE);
+	}
+
+	svSetValue (ifcfg, "TYPE", TYPE_BOND, FALSE);
+	svSetValue (ifcfg, "BONDING_MASTER", "yes", FALSE);
+
+	return TRUE;
+}
+
 static void
 write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
 {
 	guint32 n, i;
 	GString *str;
+	const char *master;
 
 	svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE);
 	svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE);
@@ -1097,6 +1287,14 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
 		svSetValue (ifcfg, "USERS", str->str, FALSE);
 		g_string_free (str, TRUE);
 	}
+
+	svSetValue (ifcfg, "ZONE", nm_setting_connection_get_zone(s_con), FALSE);
+
+	master = nm_setting_connection_get_master (s_con);
+	if (master) {
+		if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME))
+			svSetValue (ifcfg, "MASTER", master, FALSE);
+	}
 }
 
 static gboolean
@@ -1172,7 +1370,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	gboolean fake_ip4 = FALSE;
 	const char *method = NULL;
 
-	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	if (s_ip4)
 		method = nm_setting_ip4_config_get_method (s_ip4);
 
@@ -1509,7 +1707,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	GString *ip_str1, *ip_str2, *ip_ptr;
 	char *route6_path;
 
-	s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	if (!s_ip6) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME);
@@ -1587,7 +1785,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	}
 
 	/* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */
-	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */
 	num = nm_setting_ip6_config_get_num_dns (s_ip6);
 	for (i = 0; i < 254; i++) {
@@ -1644,6 +1842,24 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	            nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes",
 	            FALSE);
 
+	/* IPv6 Privacy Extensions */
+	svSetValue (ifcfg, "IPV6_PRIVACY", NULL, FALSE);
+	svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", NULL, FALSE);
+	switch (nm_setting_ip6_config_get_ip6_privacy (s_ip6)){
+	case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
+		svSetValue (ifcfg, "IPV6_PRIVACY", "no", FALSE);
+	break;
+	case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR:
+		svSetValue (ifcfg, "IPV6_PRIVACY", "rfc3041", FALSE);
+		svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", "yes", FALSE);
+	break;
+	case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR:
+		svSetValue (ifcfg, "IPV6_PRIVACY", "rfc3041", FALSE);
+	break;
+	default:
+	break;
+	}
+
 	/* Static routes go to route6-<dev> file */
 	route6_path = utils_get_route6_path (ifcfg->fileName);
 	if (!route6_path) {
@@ -1665,6 +1881,7 @@ error:
 static char *
 escape_id (const char *id)
 {
+	static const char const as_dash[] = "\\][|/=()!";
 	char *escaped = g_strdup (id);
 	char *p = escaped;
 
@@ -1672,9 +1889,7 @@ escape_id (const char *id)
 	while (*p) {
 		if (*p == ' ')
 			*p = '_';
-		else if (*p == '/')
-			*p = '-';
-		else if (*p == '\\')
+		else if (strchr (as_dash, *p))
 			*p = '-';
 		p++;
 	}
@@ -1691,6 +1906,7 @@ write_connection (NMConnection *connection,
                   GError **error)
 {
 	NMSettingConnection *s_con;
+	NMSettingIP4Config *s_ip4;
 	NMSettingIP6Config *s_ip6;
 	gboolean success = FALSE;
 	shvarFile *ifcfg = NULL;
@@ -1699,7 +1915,7 @@ write_connection (NMConnection *connection,
 	gboolean no_8021x = FALSE;
 	gboolean wired = FALSE;
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	if (!s_con) {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Missing '%s' setting", NM_SETTING_CONNECTION_SETTING_NAME);
@@ -1759,7 +1975,7 @@ write_connection (NMConnection *connection,
 
 	if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
 		// FIXME: can't write PPPoE at this time
-		if (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)) {
+		if (nm_connection_get_setting_pppoe (connection)) {
 			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 			             "Can't write connection type '%s'",
 			             NM_SETTING_PPPOE_SETTING_NAME);
@@ -1769,9 +1985,18 @@ write_connection (NMConnection *connection,
 		if (!write_wired_setting (connection, ifcfg, error))
 			goto out;
 		wired = TRUE;
+	} else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) {
+		if (!write_vlan_setting (connection, ifcfg, error))
+			goto out;
 	} else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) {
 		if (!write_wireless_setting (connection, ifcfg, &no_8021x, error))
 			goto out;
+	} else if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
+		if (!write_infiniband_setting (connection, ifcfg, error))
+			goto out;
+	} else if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME)) {
+		if (!write_bonding_setting (connection, ifcfg, error))
+			goto out;
 	} else {
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 		             "Can't write connection type '%s'", type);
@@ -1783,10 +2008,13 @@ write_connection (NMConnection *connection,
 			goto out;
 	}
 
-	if (!write_ip4_setting (connection, ifcfg, error))
-		goto out;
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
+	if (s_ip4 || !utils_disabling_ip4_config_allowed (connection)) {
+		if (!write_ip4_setting (connection, ifcfg, error))
+			goto out;
+	}
 
-	s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	if (s_ip6) {
 		if (!write_ip6_setting (connection, ifcfg, error))
 			goto out;
diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in
index dfa84086..ac528342 100644
--- a/src/settings/plugins/ifcfg-suse/Makefile.in
+++ b/src/settings/plugins/ifcfg-suse/Makefile.in
@@ -170,6 +170,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -224,11 +226,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -239,6 +245,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -278,6 +285,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
diff --git a/src/settings/plugins/ifcfg-suse/plugin.c b/src/settings/plugins/ifcfg-suse/plugin.c
index 78db56e5..2ec90d81 100644
--- a/src/settings/plugins/ifcfg-suse/plugin.c
+++ b/src/settings/plugins/ifcfg-suse/plugin.c
@@ -18,7 +18,7 @@
  * 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 - 2009 Red Hat, Inc.
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -309,7 +309,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
 }
 
 G_MODULE_EXPORT GObject *
-nm_system_config_factory (void)
+nm_system_config_factory (const char *config_file)
 {
 	static SCPluginIfcfg *singleton = NULL;
 
diff --git a/src/settings/plugins/ifnet/Makefile.am b/src/settings/plugins/ifnet/Makefile.am
index 9bf8a79a..84deda5b 100644
--- a/src/settings/plugins/ifnet/Makefile.am
+++ b/src/settings/plugins/ifnet/Makefile.am
@@ -45,13 +45,13 @@ lib_ifnet_io_la_SOURCES = \
 	wpa_parser.c
 
 lib_ifnet_io_la_CPPFLAGS = \
-			   $(GLIB_CFLAGS) \
-		           $(DBUS_CFLAGS) \
-		           -DG_DISABLE_DEPRECATED \
-		           -DSYSCONFDIR=\"$(sysconfdir)\" \
-		           -DSBINDIR=\"$(sbindir)\"
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	-DG_DISABLE_DEPRECATED \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DSBINDIR=\"$(sbindir)\"
 
 lib_ifnet_io_la_LIBADD = \
-			 $(top_builddir)/libnm-util/libnm-util.la \
-			 $(GLIB_LIBS)\
-			 $(GIO_LIBS)
+	 $(top_builddir)/libnm-util/libnm-util.la \
+	 $(GLIB_LIBS)\
+	 $(GIO_LIBS)
diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in
index 8218b85a..322adbf8 100644
--- a/src/settings/plugins/ifnet/Makefile.in
+++ b/src/settings/plugins/ifnet/Makefile.in
@@ -218,6 +218,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -272,11 +274,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -287,6 +293,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -326,6 +333,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -433,16 +442,16 @@ lib_ifnet_io_la_SOURCES = \
 	wpa_parser.c
 
 lib_ifnet_io_la_CPPFLAGS = \
-			   $(GLIB_CFLAGS) \
-		           $(DBUS_CFLAGS) \
-		           -DG_DISABLE_DEPRECATED \
-		           -DSYSCONFDIR=\"$(sysconfdir)\" \
-		           -DSBINDIR=\"$(sbindir)\"
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	-DG_DISABLE_DEPRECATED \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DSBINDIR=\"$(sbindir)\"
 
 lib_ifnet_io_la_LIBADD = \
-			 $(top_builddir)/libnm-util/libnm-util.la \
-			 $(GLIB_LIBS)\
-			 $(GIO_LIBS)
+	 $(top_builddir)/libnm-util/libnm-util.la \
+	 $(GLIB_LIBS)\
+	 $(GIO_LIBS)
 
 all: all-recursive
 
diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c
index b4aaa8d2..78812f97 100644
--- a/src/settings/plugins/ifnet/connection_parser.c
+++ b/src/settings/plugins/ifnet/connection_parser.c
@@ -45,12 +45,6 @@
 #include "connection_parser.h"
 #include "nm-ifnet-connection.h"
 
-static const char *
-get_prefix (void)
-{
-	return _("System");
-}
-
 static void
 update_connection_id (NMConnection *connection, const char *conn_name)
 {
@@ -62,16 +56,12 @@ update_connection_id (NMConnection *connection, const char *conn_name)
 
 	name_len = strlen (conn_name);
 	if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) {
-		gchar * conn_name_printable = utils_hexstr2bin (conn_name + 2, name_len - 2);
-		idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name_printable);
-		g_free (conn_name_printable);
+		idstr = utils_hexstr2bin (conn_name + 2, name_len - 2);
 	} else
-		idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name);
+		idstr = g_strdup_printf ("%s", conn_name);
 	uuid_base = idstr;
 	uuid = nm_utils_uuid_generate_from_string (uuid_base);
-	setting =
-	    (NMSettingConnection *) nm_connection_get_setting (connection,
-							       NM_TYPE_SETTING_CONNECTION);
+	setting = nm_connection_get_setting_connection (connection);
 	g_object_set (setting, NM_SETTING_CONNECTION_ID, idstr,
 		      NM_SETTING_CONNECTION_UUID, uuid, NULL);
 	PLUGIN_PRINT (IFNET_PLUGIN_NAME,
@@ -509,20 +499,17 @@ static gboolean
 read_mac_address (const char *conn_name, GByteArray **array, GError **error)
 {
 	const char *value = ifnet_get_data (conn_name, "mac");
-	struct ether_addr *mac;
 
 	if (!value || !strlen (value))
 		return TRUE;
 
-	mac = ether_aton (value);
-	if (!mac) {
+	*array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
+	if (!*array) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
-			     "The MAC address '%s' was invalid.", value);
+					 "The MAC address '%s' was invalid.", value);
 		return FALSE;
 	}
 
-	*array = g_byte_array_sized_new (ETH_ALEN);
-	g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN);
 	return TRUE;
 }
 
@@ -567,7 +554,7 @@ make_wired_connection_setting (NMConnection *connection,
 		nm_connection_add_setting (connection, NM_SETTING (s_wired));
 }
 
-/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, 
+/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
  * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/
 static void
 make_ip4_setting (NMConnection *connection,
@@ -596,19 +583,19 @@ make_ip4_setting (NMConnection *connection,
 			g_object_unref (ip4_setting);
 			return;
 		}
-		if (!strcmp (method, "dhcp"))
+		if (strstr (method, "dhcp"))
 			g_object_set (ip4_setting,
 						  NM_SETTING_IP4_CONFIG_METHOD,
 						  NM_SETTING_IP4_CONFIG_METHOD_AUTO,
 						  NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
-		else if (!strcmp (method, "autoip")){
+		else if (strstr (method, "autoip")) {
 			g_object_set (ip4_setting,
 						  NM_SETTING_IP4_CONFIG_METHOD,
 						  NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
 						  NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
 			nm_connection_add_setting (connection, NM_SETTING (ip4_setting));
 			return;
-		} else if (!strcmp (method, "shared")){
+		} else if (strstr (method, "shared")) {
 			g_object_set (ip4_setting,
 						  NM_SETTING_IP4_CONFIG_METHOD,
 						  NM_SETTING_IP4_CONFIG_METHOD_SHARED,
@@ -663,7 +650,7 @@ make_ip4_setting (NMConnection *connection,
 	}
 
 	/* add dhcp hostname and client id */
-	if (!is_static_block && !strcmp (method, "dhcp")) {
+	if (!is_static_block && strstr (method, "dhcp")) {
 		gchar *dhcp_hostname, *client_id;
 
 		get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id);
@@ -868,7 +855,7 @@ make_ip6_setting (NMConnection *connection,
 		nm_ip6_route_set_dest (route, iblock->ip);
 		nm_ip6_route_set_next_hop (route, iblock->next_hop);
 		nm_ip6_route_set_prefix (route, iblock->prefix);
-		/* metric is not per routes configuration right now 
+		/* metric is not per routes configuration right now
 		 * global metric is also supported (metric="x") */
 		if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
 			metric = strtol (metric_str, NULL, 10);
@@ -995,7 +982,7 @@ make_wireless_connection_setting (const char *conn_name,
 		goto error;
 	}
 
-	/* mode=0: infrastructure 
+	/* mode=0: infrastructure
 	 * mode=1: adhoc */
 	value = wpa_get_value (conn_name, "mode");
 	if (value)
@@ -1012,18 +999,15 @@ make_wireless_connection_setting (const char *conn_name,
 	/* BSSID setting */
 	value = wpa_get_value (conn_name, "bssid");
 	if (value) {
-		struct ether_addr *eth;
 		GByteArray *bssid;
 
-		eth = ether_aton (value);
-		if (!eth) {
+		bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
+		if (!bssid) {
 			g_set_error (error, ifnet_plugin_error_quark (), 0,
-				     "Invalid BSSID '%s'", value);
+						 "Invalid BSSID '%s'", value);
 			goto error;
 		}
 
-		bssid = g_byte_array_sized_new (ETH_ALEN);
-		g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN);
 		g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID,
 			      bssid, NULL);
 		g_byte_array_free (bssid, TRUE);
@@ -1666,9 +1650,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, GError **error
 	connection = nm_connection_new ();
 	if (!connection)
 		return NULL;
-	setting =
-	    (NMSettingConnection *) nm_connection_get_setting (connection,
-							       NM_TYPE_SETTING_CONNECTION);
+	setting = nm_connection_get_setting_connection (connection);
 	if (!setting) {
 		setting = NM_SETTING_CONNECTION (nm_setting_connection_new ());
 		g_assert (setting);
@@ -2021,10 +2003,7 @@ write_8021x_setting (NMConnection *connection,
 	GString *phase2_auth;
 	GString *phase1;
 
-	s_8021x =
-	    (NMSetting8021x *) nm_connection_get_setting (connection,
-							  NM_TYPE_SETTING_802_1X);
-
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	if (!s_8021x) {
 		return TRUE;
 	}
@@ -2119,9 +2098,7 @@ write_wireless_security_setting (NMConnection * connection,
 	guint32 i, num;
 	GString *str;
 
-	s_wsec =
-	    (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
-								     NM_TYPE_SETTING_WIRELESS_SECURITY);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
 	if (!s_wsec) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
 			     "Missing '%s' setting",
@@ -2171,7 +2148,6 @@ write_wireless_security_setting (NMConnection * connection,
 		wpa_set_data (conn_name, "auth_alg", NULL);
 
 	/* Default WEP TX key index */
-	wpa_set_data (conn_name, "wep_tx_keyidx", NULL);
 	if (wep) {
 		tmp =
 		    g_strdup_printf ("%d",
@@ -2179,7 +2155,8 @@ write_wireless_security_setting (NMConnection * connection,
 				     (s_wsec));
 		wpa_set_data (conn_name, "wep_tx_keyidx", tmp);
 		g_free (tmp);
-	}
+	} else
+		wpa_set_data (conn_name, "wep_tx_keyidx", NULL);
 
 	/* WEP keys */
 	for (i = 0; i < 4; i++) {
@@ -2287,7 +2264,7 @@ write_wireless_setting (NMConnection *connection,
 	gboolean adhoc = FALSE, hex_ssid = FALSE;
 	gchar *ssid_str, *tmp;
 
-	s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	if (!s_wireless) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
 			     "Missing '%s' setting",
@@ -2406,9 +2383,7 @@ write_wired_setting (NMConnection *connection,
 	char *tmp;
 	guint32 mtu;
 
-	s_wired =
-	    (NMSettingWired *) nm_connection_get_setting (connection,
-							  NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	if (!s_wired) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
 			     "Missing '%s' setting",
@@ -2462,9 +2437,7 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err
 	gboolean has_def_route = FALSE;
 	gboolean success = FALSE;
 
-	s_ip4 =
-	    (NMSettingIP4Config *) nm_connection_get_setting (connection,
-							      NM_TYPE_SETTING_IP4_CONFIG);
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	if (!s_ip4) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
 			     "Missing '%s' setting",
@@ -2668,9 +2641,7 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err
 	NMIP6Address *addr;
 	const struct in6_addr *ip;
 
-	s_ip6 =
-	    (NMSettingIP6Config *) nm_connection_get_setting (connection,
-							      NM_TYPE_SETTING_IP6_CONFIG);
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	if (!s_ip6) {
 		g_set_error (error, ifnet_plugin_error_quark (), 0,
 			     "Missing '%s' setting",
@@ -2856,7 +2827,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection,
 		NMSettingPPPOE *s_pppoe;
 
 		/* Writing pppoe setting */
-		s_pppoe = NM_SETTING_PPPOE (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE));
+		s_pppoe = nm_connection_get_setting_pppoe (connection);
 		if (!write_pppoe_setting (conn_name, s_pppoe))
 			goto out;
 		pppoe = TRUE;
@@ -2884,7 +2855,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection,
 	if (!write_ip4_setting (connection, conn_name, error))
 		goto out;
 
-	s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	if (s_ip6) {
 		/* IPv6 Setting */
 		if (!write_ip6_setting (connection, conn_name, error))
@@ -2972,9 +2943,7 @@ get_wireless_name (NMConnection * connection)
 	char buf[33];
 	int i = 0;
 
-	s_wireless =
-	    (NMSettingWireless *) nm_connection_get_setting (connection,
-							     NM_TYPE_SETTING_WIRELESS);
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	if (!s_wireless)
 		return NULL;
 
@@ -3020,7 +2989,7 @@ ifnet_add_new_connection (NMConnection *connection,
 	const char *type;
 	gchar *new_type, *new_name = NULL;
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
 	type = nm_setting_connection_get_connection_type (s_con);
 	g_assert (type);
diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c
index a48103db..38765f5f 100644
--- a/src/settings/plugins/ifnet/net_parser.c
+++ b/src/settings/plugins/ifnet/net_parser.c
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <nm-system-config-interface.h>
 #include <stdio.h>
+#include "plugin.h"
 #include "net_parser.h"
 #include "net_utils.h"
 
@@ -106,7 +107,6 @@ ignore_connection_name (const char *name)
 	if (strlen (name) == 12 && is_hex (name))
 		result = TRUE;
 	return result;
-
 }
 
 static gboolean
@@ -169,12 +169,10 @@ init_block_by_line (gchar * buf)
 			conn = add_new_connection_config ("wireless", pos);
 	}
 	data = g_strdup (key_value[1]);
-	tmp = strip_string (data, '(');
-	tmp = strip_string (tmp, ')');
-	strip_string (tmp, '"');
+	tmp = strip_string (data, '"');
 	strip_string (tmp, '\'');
 	if (conn)
-		g_hash_table_insert (conn, g_strdup (key_value[0]),
+		g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '),
 				     g_strdup (tmp));
 	g_free (data);
 	g_strfreev (key_value);
@@ -195,26 +193,31 @@ destroy_connection_config (GHashTable * conn)
 	g_hash_table_destroy (conn);
 }
 
-// read settings from /etc/NetworkManager/nm-system-settings.conf
+/* Read settings from NetworkManager's config file */
 const char *
 ifnet_get_global_setting (const char *group, const char *key)
 {
 	GError *error = NULL;
 	GKeyFile *keyfile = g_key_file_new ();
 	gchar *result = NULL;
+	const char *conf_file;
+
+	/* Get confing file name from plugin. */
+	conf_file = ifnet_plugin_get_conf_file ();
 
 	if (!g_key_file_load_from_file (keyfile,
-					IFNET_SYSTEM_SETTINGS_KEY_FILE,
+					conf_file,
 					G_KEY_FILE_NONE, &error)) {
 		PLUGIN_WARN (IFNET_PLUGIN_NAME,
 			     "loading system config file (%s) caused error: (%d) %s",
-			     IFNET_SYSTEM_SETTINGS_KEY_FILE,
+			     conf_file,
 			     error ? error->code : -1, error
 			     && error->message ? error->message : "(unknown)");
 	} else {
 		result = g_key_file_get_string (keyfile, group, key, &error);
 	}
 	g_key_file_free (keyfile);
+
 	return result;
 }
 
@@ -283,6 +286,20 @@ is_function (gchar * line)
 	return FALSE;
 }
 
+static void
+append_line (GString *buf, gchar* line)
+{
+	gchar *pos = NULL;
+
+	if ((pos = strchr (line, '#')) != NULL)
+		*pos = '\0';
+	g_strstrip (line);
+
+	if (line[0] != '\0')
+		g_string_append_printf (buf, " %s", line);
+	g_free (line);
+}
+
 gboolean
 ifnet_init (gchar * config_file)
 {
@@ -292,6 +309,8 @@ ifnet_init (gchar * config_file)
 	/* Handle multiple lines with brackets */
 	gboolean complete = TRUE;
 
+	gboolean openrc_style = TRUE;
+
 	/* line buffer */
 	GString *buf;
 
@@ -319,36 +338,60 @@ ifnet_init (gchar * config_file)
 			strip_function (channel, line);
 			continue;
 		}
-		if (line[0] != '#' && line[0] != '\0') {
-			gchar *pos = NULL;
 
+		// New openrc style, bash arrays are not allowed. We only care about '"'
+		if (openrc_style && line[0] != '#' && line[0] != '\0'
+				&& !strchr (line, '(') && !strchr (line, ')')) {
+			gchar *tmp = line;
+
+			while ((tmp = strchr (tmp, '"')) != NULL) {
+				complete = !complete;
+				++tmp;
+			}
+
+			append_line (buf, line);
+			// Add "(separator) for routes. It will be easier for later parsing
+			if (strstr (buf->str, "via"))
+				g_string_append_printf (buf, "\"");
+
+			if (!complete)
+				continue;
+
+			strip_string (buf->str, '"');
+
+			init_block_by_line (buf->str);
+			g_string_free (buf, TRUE);
+			buf = g_string_new (NULL);
+		}
+		// Old bash arrays for baselayout-1, to be deleted
+		else if (line[0] != '#' && line[0] != '\0') {
 			if (!complete) {
 				complete =
 				    g_strrstr (line,
 					       ")") == NULL ? FALSE : TRUE;
-				if ((pos = strchr (line, '#')) != NULL)
-					*pos = '\0';
-				g_strstrip (line);
-				if (line[0] != '\0') {
-					g_string_append_printf (buf,
-								" %s", line);
-				}
-				g_free (line);
-				if (!complete)
+
+				append_line (buf, line);
+				if (!complete) {
+					openrc_style = FALSE;
 					continue;
+				}
+				else {
+					openrc_style = TRUE;
+				}
 			} else {
 				complete =
 				    (g_strrstr (line, "(") != NULL
 				     && g_strrstr (line, ")") != NULL)
 				    || g_strrstr (line, "(") == NULL;
-				if ((pos = strchr (line, '#')) != NULL)
-					*pos = '\0';
-				g_strstrip (line);
-				if (line[0] != '\0')
-					g_string_append (buf, line);
-				g_free (line);
+
+				append_line (buf, line);
 				if (!complete)
+				{
+					openrc_style = FALSE;
 					continue;
+				} else {
+					openrc_style = TRUE;
+				}
 			}
 			init_block_by_line (buf->str);
 			g_string_free (buf, TRUE);
@@ -374,6 +417,34 @@ ifnet_get_data (const char *conn_name, const char *key)
 	return NULL;
 }
 
+/* format ip values for comparison */
+static gchar*
+format_ip_for_comparison (const gchar * value)
+{
+	gchar **ipset;
+	guint length, i;
+	GString *formated_string = g_string_new (NULL);
+	gchar *formatted = NULL;
+
+	ipset = g_strsplit (value, "\"", 0);
+	length = g_strv_length (ipset);
+
+	for (i = 0; i < length; i++)
+	{
+		strip_string (ipset[i], ' ');
+		if (ipset[i][0] != '\0')
+			g_string_append_printf (formated_string,
+						"%s ", ipset[i]);
+	}
+	formatted = g_strdup (formated_string->str);
+	formatted[formated_string->len - 1] = '\0';
+
+	g_string_free (formated_string, TRUE);
+	g_strfreev (ipset);
+
+	return formatted;
+}
+
 void
 ifnet_set_data (const char *conn_name, const char *key, const char *value)
 {
@@ -391,7 +462,31 @@ ifnet_set_data (const char *conn_name, const char *key, const char *value)
 	}
 	/* Remove existing key value pair */
 	if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) {
-		if (stripped && !strcmp(old_value, stripped)){
+
+		/* This ugly hack is due to baselayout compatibility. We have to
+		 * deal with different ip format. So sometimes we have the same ips
+		 * but different strings.
+		 */
+		if (stripped &&
+			(!strcmp (key, "config")
+			|| !strcmp (key, "routes")
+			|| !strcmp (key, "pppd")
+			|| !strcmp (key, "chat")))
+		{
+			gchar *old_ips = format_ip_for_comparison (old_value);
+			gchar *new_ips = format_ip_for_comparison (value);
+			if(!strcmp (old_ips, new_ips))
+			{
+				g_free (stripped);
+				g_free (old_ips);
+				g_free (new_ips);
+				return;
+			}
+			g_free (old_ips);
+			g_free (new_ips);
+		}
+
+		if (stripped && !strcmp (old_value, stripped)) {
 			g_free (stripped);
 			return;
 		}
@@ -436,22 +531,28 @@ format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name)
 	guint length, i;
 	GString *formated_string = g_string_new (NULL);
 
+	strip_string (value, '(');
+	strip_string (value, ')');
 	strip_string (value, '"');
-	ipset = g_strsplit (value, "\" \"", 0);
+	ipset = g_strsplit (value, "\"", 0);
 	length = g_strv_length (ipset);
 
 	//only one line
 	if (length < 2) {
 		*out_line =
-		    g_strdup_printf ("%s_%s=( \"%s\" )\n", key, name, value);
+		    g_strdup_printf ("%s_%s=\"%s\"\n", key, name, value);
 		goto done;
 	}
 	// Multiple lines
-	g_string_append_printf (formated_string, "%s_%s=(\n", key, name);
+	g_string_append_printf (formated_string, "%s_%s=\"\n", key, name);
 	for (i = 0; i < length; i++)
-		g_string_append_printf (formated_string,
-					"\t\"%s\"\n", ipset[i]);
-	g_string_append (formated_string, ")\n");
+	{
+		strip_string (ipset[i], ' ');
+		if (ipset[i][0] != '\0')
+			g_string_append_printf (formated_string,
+						"%s\n", ipset[i]);
+	}
+	g_string_append (formated_string, "\"\n");
 	*out_line = g_strdup (formated_string->str);
 done:
 	g_string_free (formated_string, TRUE);
@@ -466,7 +567,7 @@ ifnet_flush_to_file (const char *config_file)
 	gpointer key, value, name, network;
 	GHashTableIter iter, iter_network;
 	GList *list_iter;
-	gchar *out_line;
+	gchar *out_line = NULL;
 	gsize bytes_written;
 	gboolean result = FALSE;
 
@@ -475,6 +576,8 @@ ifnet_flush_to_file (const char *config_file)
 	if (!conn_table || !global_settings_table)
 		return FALSE;
 
+	backup_file (config_file);
+
 	channel = g_io_channel_new_file (config_file, "w", NULL);
 	if (!channel) {
 		PLUGIN_WARN (IFNET_PLUGIN_NAME,
diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h
index 0411e939..5dcc7e25 100644
--- a/src/settings/plugins/ifnet/net_parser.h
+++ b/src/settings/plugins/ifnet/net_parser.h
@@ -24,8 +24,8 @@
 
 #include <glib.h>
 
-#define CONF_NET_FILE "/etc/conf.d/net"
-#define IFNET_SYSTEM_SETTINGS_KEY_FILE "/etc/NetworkManager/nm-system-settings.conf"
+#define CONF_NET_FILE SYSCONFDIR "/conf.d/net"
+#define IFNET_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
 #define IFNET_KEY_FILE_GROUP "ifnet"
 
 gboolean ifnet_init (gchar * config_file);
diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c
index b533ae3f..f1687479 100644
--- a/src/settings/plugins/ifnet/net_utils.c
+++ b/src/settings/plugins/ifnet/net_utils.c
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <nm-utils.h>
 #include <nm-system-config-interface.h>
+#include <gio/gio.h>
 #include "net_utils.h"
 #include "wpa_parser.h"
 #include "net_parser.h"
@@ -242,8 +243,7 @@ read_hostname (const char *path)
 		if (g_str_has_prefix (all_lines[i], "hostname")) {
 			tmp = strstr (all_lines[i], "=");
 			tmp++;
-			tmp = strip_string (tmp, '"');
-			result = g_strdup (tmp);
+			result = g_shell_unquote (tmp, NULL);
 			break;
 		}
 
@@ -352,6 +352,49 @@ is_ip6_address (const char *in_address)
 
 }
 
+// 'c' is only used for openrc style
+static gchar **
+split_addresses_by_char (const gchar *addresses, const gchar *c)
+{
+	gchar **ipset;
+
+	if (addresses == NULL)
+		return NULL;
+
+	if (strchr (addresses, '(') != NULL) { // old baselayout style
+		gchar *tmp = g_strdup (addresses);
+		strip_string (tmp, '(');
+		strip_string (tmp, ')');
+		strip_string (tmp, '"');
+		strip_string (tmp, '\'');
+		ipset = g_strsplit (tmp, "\" \"", 0);
+		g_free(tmp);
+	} else { // openrc style
+		if (strstr (addresses, "netmask"))
+			// There is only one ip address if "netmask" is specified.
+			// '\n' is not used in config so there will be only one split.
+			ipset = g_strsplit (addresses, "\n", 0);
+		else
+			ipset = g_strsplit (addresses, c, 0);
+	}
+
+	return ipset;
+}
+
+static gchar **
+split_addresses (const gchar* addresses)
+{
+	// " " is only used by openrc style
+	return split_addresses_by_char (addresses, " ");
+}
+
+static gchar **
+split_routes (const gchar* routes)
+{
+	// "\"" is only used by openrc style
+	return split_addresses_by_char (routes, "\"");
+}
+
 gboolean
 has_ip6_address (const char *conn_name)
 {
@@ -360,7 +403,7 @@ has_ip6_address (const char *conn_name)
 	guint i;
 
 	g_return_val_if_fail (conn_name != NULL, FALSE);
-	ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+	ipset = split_addresses (ifnet_get_data (conn_name, "config"));
 	length = g_strv_length (ipset);
 	for (i = 0; i < length; i++) {
 		if (!is_ip6_address (ipset[i]))
@@ -512,8 +555,11 @@ get_ip4_gateway (gchar * gateway)
 	tmp = g_strdup (tmp);
 	strip_string (tmp, ' ');
 	strip_string (tmp, '"');
+
+	// Only one gateway is selected
 	if ((split = strstr (tmp, "\"")) != NULL)
 		*split = '\0';
+
 	if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr))
 		goto error;
 	g_free (tmp);
@@ -567,14 +613,11 @@ convert_ip4_config_block (const char *conn_name)
 	gchar *ip;
 	guint32 def_gateway = 0;
 	const char *routes;
-	gchar *pos;
 	ip_block *start = NULL, *current = NULL, *iblock = NULL;
-	const char *pattern =
-	    "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))";
 
 	g_return_val_if_fail (conn_name != NULL, NULL);
 
-	ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+	ipset = split_addresses (ifnet_get_data (conn_name, "config"));
 	length = g_strv_length (ipset);
 
 	routes = ifnet_get_data (conn_name, "routes");
@@ -584,73 +627,16 @@ convert_ip4_config_block (const char *conn_name)
 	for (i = 0; i < length; i++) {
 		ip = ipset[i];
 		ip = strip_string (ip, '"');
-		//Handle ip like 192.168.4.{1..3}
-		if ((pos = strchr (ip, '{')) != NULL) {
-			gchar *ip_start, *ip_prefix;
-			gchar *begin_str, *end_str;
-			int begin, end, j;
-			GRegex *regex;
-			GMatchInfo *match_info;
-
-			regex = g_regex_new (pattern, 0, 0, NULL);
-			g_regex_match (regex, ip, 0, &match_info);
-			g_regex_unref (regex);
-
-			if (!g_match_info_matches (match_info)) {
-				g_match_info_free (match_info);
-				continue;
-			}
-			begin_str = g_match_info_fetch (match_info, 3);
-			end_str = g_match_info_fetch (match_info, 4);
-			begin = atoi (begin_str);
-			end = atoi (end_str);
-			ip_start = g_match_info_fetch (match_info, 2);
-			ip_prefix = g_match_info_fetch (match_info, 5);
-			if (end < begin || begin < 1 || end > 254) {
-				g_match_info_free (match_info);
-				continue;
-			}
-
-			for (j = begin; j <= end; j++) {
-				char suf[4];
-				gchar *newip;
-
-				sprintf (suf, "%d", j);
-				newip =
-				    g_strconcat (ip_start, suf, ip_prefix,
-						 NULL);
-				iblock = create_ip4_block (newip);
-				if (iblock == NULL) {
-					g_free (newip);
-					continue;
-				}
-				if (!iblock->gateway && def_gateway != 0)
-					iblock->gateway = def_gateway;
-				if (start == NULL)
-					start = current = iblock;
-				else {
-					current->next = iblock;
-					current = iblock;
-				}
-				g_free (newip);
-			}
-			g_free (begin_str);
-			g_free (end_str);
-			g_free (ip_start);
-			g_free (ip_prefix);
-			g_match_info_free (match_info);
-		} else {
-			iblock = create_ip4_block (ip);
-			if (iblock == NULL)
-				continue;
-			if (!iblock->gateway && def_gateway != 0)
-				iblock->gateway = def_gateway;
-			if (start == NULL)
-				start = current = iblock;
-			else {
-				current->next = iblock;
-				current = iblock;
-			}
+		iblock = create_ip4_block (ip);
+		if (iblock == NULL)
+			continue;
+		if (!iblock->gateway && def_gateway != 0)
+			iblock->gateway = def_gateway;
+		if (start == NULL)
+			start = current = iblock;
+		else {
+			current->next = iblock;
+			current = iblock;
 		}
 	}
 	g_strfreev (ipset);
@@ -667,7 +653,7 @@ convert_ip6_config_block (const char *conn_name)
 	ip6_block *start = NULL, *current = NULL, *iblock = NULL;
 
 	g_return_val_if_fail (conn_name != NULL, NULL);
-	ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+	ipset = split_addresses (ifnet_get_data (conn_name, "config"));
 	length = g_strv_length (ipset);
 	for (i = 0; i < length; i++) {
 		ip = ipset[i];
@@ -693,15 +679,11 @@ convert_ip4_routes_block (const char *conn_name)
 	guint length;
 	guint i;
 	gchar *ip;
-	const char *routes;
 	ip_block *start = NULL, *current = NULL, *iblock = NULL;
 
 	g_return_val_if_fail (conn_name != NULL, NULL);
 
-	routes = ifnet_get_data (conn_name, "routes");
-	if (!routes)
-		return NULL;
-	ipset = g_strsplit (routes, "\" \"", 0);
+	ipset = split_routes (ifnet_get_data (conn_name, "routes"));
 	length = g_strv_length (ipset);
 	for (i = 0; i < length; i++) {
 		ip = ipset[i];
@@ -731,15 +713,11 @@ convert_ip6_routes_block (const char *conn_name)
 	guint length;
 	guint i;
 	gchar *ip, *tmp_addr;
-	const char *routes;
 	ip6_block *start = NULL, *current = NULL, *iblock = NULL;
 	struct in6_addr *tmp_ip6_addr;
 
 	g_return_val_if_fail (conn_name != NULL, NULL);
-	routes = ifnet_get_data (conn_name, "routes");
-	if (!routes)
-		return NULL;
-	ipset = g_strsplit (routes, "\" \"", 0);
+	ipset = split_routes (ifnet_get_data (conn_name, "routes"));
 	length = g_strv_length (ipset);
 	for (i = 0; i < length; i++) {
 		ip = ipset[i];
@@ -897,8 +875,8 @@ void
 get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
 {
 	const char *dhcp_client;
-	const gchar *dhcpcd_conf = "/etc/dhcpcd.conf";
-	const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf";
+	const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf";
+	const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf";
 	gchar *line = NULL, *tmp = NULL, *contents = NULL;
 	gchar **all_lines;
 	guint line_num, i;
@@ -972,3 +950,20 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
 	g_strfreev (all_lines);
 	g_free (contents);
 }
+
+void backup_file (const gchar* target)
+{
+	GFile *source, *backup;
+	gchar* backup_path;
+	GError **error = NULL;
+
+	source = g_file_new_for_path (target);
+	backup_path = g_strdup_printf ("%s.bak", target);
+	backup = g_file_new_for_path (backup_path);
+
+	g_file_copy (source, backup, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error);
+	if (error && *error)
+		PLUGIN_WARN (IFNET_PLUGIN_NAME, "Backup failed: %s", (*error)->message);
+
+	g_free (backup_path);
+}
diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h
index 42f8d672..dee49143 100644
--- a/src/settings/plugins/ifnet/net_utils.h
+++ b/src/settings/plugins/ifnet/net_utils.h
@@ -77,4 +77,5 @@ gboolean is_true (const char *str);
 
 void get_dhcp_hostname_and_client_id (char **hostname, char **client_id);
 
+void backup_file (const gchar* target);
 #endif
diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c
index 59083688..fff83805 100644
--- a/src/settings/plugins/ifnet/plugin.c
+++ b/src/settings/plugins/ifnet/plugin.c
@@ -48,6 +48,7 @@
 typedef struct {
 	GHashTable *config_connections;
 	gchar *hostname;
+	char *conf_file;
 	gboolean unmanaged_well_known;
 
 	GFileMonitor *hostname_monitor;
@@ -180,7 +181,7 @@ monitor_file_changes (const char *filename,
 /* Callback for nm_settings_connection_replace_and_commit. Report any errors
  * encountered when commiting connection settings updates. */
 static void
-commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) 
+commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused)
 {
 	if (error) {
 		PLUGIN_WARN (IFNET_PLUGIN_NAME, "    error updating: %s",
@@ -188,8 +189,7 @@ commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused)
 	} else {
 		NMSettingConnection *s_con;
 
-		s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection),
-		                                                           NM_TYPE_SETTING_CONNECTION);
+		s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
 		g_assert (s_con);
 		PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated",
 		              nm_setting_connection_get_id (s_con));
@@ -317,6 +317,26 @@ reload_connections (gpointer config)
 	g_list_free (conn_names);
 }
 
+static void
+check_flagged_secrets (NMSetting  *setting,
+                       const char *key,
+                       const GValue *value,
+                       GParamFlags flags,
+                       gpointer user_data)
+{
+	gboolean *is_system_secret = user_data;
+
+	if (flags & NM_SETTING_PARAM_SECRET) {
+		NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
+
+		if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) {
+			*is_system_secret = TRUE;
+		}
+	}
+}
+
 static NMSettingsConnection *
 add_connection (NMSystemConfigInterface *config,
                 NMConnection *source,
@@ -324,11 +344,28 @@ add_connection (NMSystemConfigInterface *config,
 {
 	NMIfnetConnection *connection = NULL;
 	char *conn_name;
+	gboolean has_flagged_secrets = FALSE;
+	NMSettingConnection *s_con;
+
+	s_con = nm_connection_get_setting_connection (source);
+	g_assert (s_con);
+
+	/* If the connection is not available for all users, ignore
+	 * it as this plugin only deals with System Connections */
+	if (nm_setting_connection_get_num_permissions (s_con))
+		return NULL;
+
+	/* If the connection has flagged secrets, ignore
+	 * it as this plugin does not deal with user agent service */
+	nm_connection_for_each_setting_value (source, check_flagged_secrets, &has_flagged_secrets);
+
+	if (!has_flagged_secrets) {
+		conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error);
+		if (conn_name)
+			connection = nm_ifnet_connection_new (conn_name, source);
+		reload_connections (config);
+	}
 
-	conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error);
-	if (conn_name)
-		connection = nm_ifnet_connection_new (conn_name, source);
-	reload_connections (config);
 	return connection ? NM_SETTINGS_CONNECTION (connection) : NULL;
 }
 
@@ -494,6 +531,7 @@ dispose (GObject * object)
 	}
 
 	g_free (priv->hostname);
+	g_free (priv->conf_file);
 	ifnet_destroy ();
 	wpa_parser_destroy ();
 	G_OBJECT_CLASS (sc_plugin_ifnet_parent_class)->dispose (object);
@@ -527,16 +565,37 @@ sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class)
 					  NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
 }
 
+const char *
+ifnet_plugin_get_conf_file (void)
+{
+	SCPluginIfnet *ifnet_plugin;
+	SCPluginIfnetPrivate *priv;
+
+	/* Get config file name. Plugin's singleton has already been created
+	 * with correct config file path, so the string passed here has no efect
+	 * and we get the valid file name.
+	 */
+	ifnet_plugin = SC_PLUGIN_IFNET (nm_system_config_factory ("fake string"));
+	priv = SC_PLUGIN_IFNET_GET_PRIVATE (ifnet_plugin);
+	g_object_unref (ifnet_plugin);
+
+	return priv->conf_file;
+}
+
 G_MODULE_EXPORT GObject *
-nm_system_config_factory (void)
+nm_system_config_factory (const char *config_file)
 {
 	static SCPluginIfnet *singleton = NULL;
+	SCPluginIfnetPrivate *priv;
 
-	if (!singleton)
-		singleton
-		    =
-		    SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL));
-	else
+	if (!singleton) {
+		singleton = SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL));
+		if (singleton) {
+			priv = SC_PLUGIN_IFNET_GET_PRIVATE (singleton);
+			priv->conf_file = strdup (config_file);
+		}
+	} else
 		g_object_ref (singleton);
+
 	return G_OBJECT (singleton);
 }
diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h
index 83099b63..eecab159 100644
--- a/src/settings/plugins/ifnet/plugin.h
+++ b/src/settings/plugins/ifnet/plugin.h
@@ -43,5 +43,7 @@ struct _SCPluginIfnetClass {
 	GObjectClass parent;
 };
 
+const char * ifnet_plugin_get_conf_file (void);
+
 GType sc_plugin_ifnet_get_type (void);
 #endif
diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in
index fe7f40e2..02ee121f 100644
--- a/src/settings/plugins/ifnet/tests/Makefile.in
+++ b/src/settings/plugins/ifnet/tests/Makefile.in
@@ -141,6 +141,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -195,11 +197,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -210,6 +216,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -249,6 +256,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net
index 0eef399a..27d39f44 100644
--- a/src/settings/plugins/ifnet/tests/net
+++ b/src/settings/plugins/ifnet/tests/net
@@ -27,10 +27,9 @@ config_eth2=(
 routes_eth2=("default via  4321:0:1:2:3:4:567:89ab")
 enable_ipv6_eth2="true"
 config_eth3=("nufjlsjlll")
-managed_eth4=("false")
+managed_eth4="false"
 routes_eth4=("default via 4321:0:1:2:3:4:567:89ab")
 config_eth5=("dhcp")
-config_eth6=("192.168.4.{1..101}/24")
 
 config_eth7=( "dhcp" )
 auto_eth7="true"
@@ -38,6 +37,14 @@ auto_eth7="true"
 # missing config_eth8
 auto_eth8="true"
 
+#new openrc style
+config_eth9="202.117.16.10/24 202.117.17.10/24"
+routes_eth9="default via 202.117.16.1
+10.0.0.0/8 via 192.168.0.1
+"
+config_eth10="202.117.16.2 netmask 255.255.255.0"
+routes_eth10="10.0.0.0/8 via 192.168.0.1"
+
 config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255")
 routes_myxjtu2=("default via 202.117.16.1")
 dns_servers_myxjtu2="202.117.0.20 202.117.0.21"
diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c
index 52d9ce2a..50441d4e 100644
--- a/src/settings/plugins/ifnet/tests/test_all.c
+++ b/src/settings/plugins/ifnet/tests/test_all.c
@@ -33,11 +33,21 @@
 #include "wpa_parser.h"
 #include "connection_parser.h"
 
+/* Fake config file function to make the linker happy */
+const char *ifnet_plugin_get_conf_file (void);
+
+const char *
+ifnet_plugin_get_conf_file (void)
+{
+	return "/etc/foo/barasdfasdfasdfasdf";
+}
+
+
 static void
 test_getdata ()
 {
 	ASSERT (ifnet_get_data ("eth1", "config")
-		&& strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0,
+		&& strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0,
 		"get data", "config_eth1 is not correct");
 	ASSERT (ifnet_get_data ("ppp0", "username")
 		&& strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0,
@@ -84,7 +94,7 @@ test_is_static ()
 	ASSERT (is_static_ip4 ("eth0") == TRUE, "is static",
 		"a static interface is recognized as dhcp");
 	ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static",
-		"a static interface is recognized as dhcp");
+		"a dhcp interface is recognized as static");
 }
 
 static void
@@ -182,10 +192,6 @@ test_convert_ipv4_config_block ()
 	ASSERT (iblock == NULL, "convert config_block",
 		"convert error configuration");
 	destroy_ip_block (iblock);
-	iblock = convert_ip4_config_block ("eth6");
-	ASSERT (iblock != NULL, "convert config_block",
-		"convert error configuration");
-	destroy_ip_block (iblock);
 }
 
 static void
@@ -200,6 +206,16 @@ test_convert_ipv4_routes_block ()
 	destroy_ip_block (tmp);
 	ASSERT (iblock == NULL, "convert ip4 routes",
 		"should only get one route");
+
+	iblock = convert_ip4_routes_block ("eth9");
+	tmp = iblock;
+
+	ASSERT (iblock != NULL, "convert ip4 routes", "should get one route");
+	check_ip_block (iblock, "10.0.0.0", "255.0.0.0", "192.168.0.1");
+	iblock = iblock->next;
+	destroy_ip_block (tmp);
+	ASSERT (iblock == NULL, "convert ip4 routes",
+		"should only get one route");
 }
 
 static void
@@ -222,6 +238,9 @@ test_wpa_parser ()
 		"wep_key0 of static-wep-test should be abcde, find %s", value);
 	ASSERT (exist_ssid ("leap-example"), "get wsec",
 		"ssid leap-example is not found");
+
+	value = wpa_get_value ("test-with-hash-in-psk", "psk");
+	g_assert_cmpstr (value, ==, "\"xjtudlc3731###asdfasdfasdf\"");
 }
 
 static void
@@ -272,6 +291,18 @@ test_new_connection ()
 		"new connection failed: %s",
 		error ? error->message : "NONE");
 	g_object_unref (connection);
+
+	connection = ifnet_update_connection_from_config_block ("eth9", &error);
+	ASSERT (connection != NULL, "new connection",
+		"new connection(eth9) failed: %s",
+		error ? error->message : "NONE");
+	g_object_unref (connection);
+
+	connection = ifnet_update_connection_from_config_block ("eth10", &error);
+	ASSERT (connection != NULL, "new connection",
+		"new connection(eth10) failed: %s",
+		error ? error->message : "NONE");
+	g_object_unref (connection);
 }
 
 #define NET_GEN_NAME "net.generate"
diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
index 4f5f68cf..609ee0e1 100644
--- a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
+++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
@@ -863,3 +863,10 @@ network={
 	phase2="auth=CHAP"
 	priority=20
 }
+
+network={
+  ssid="test-with-hash-in-psk"
+  key_mgmt=WPA-PSK
+  psk="xjtudlc3731###asdfasdfasdf"
+}
+
diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c
index da2bc3bb..0fd7d16b 100644
--- a/src/settings/plugins/ifnet/wpa_parser.c
+++ b/src/settings/plugins/ifnet/wpa_parser.c
@@ -124,7 +124,7 @@ add_key_value (GHashTable * network, gchar * line)
 	g_strstrip (key_value[0]);
 	g_strstrip (key_value[1]);
 
-	/* Reserve quotes for psk, wep_key, ssid 
+	/* Reserve quotes for psk, wep_key, ssid
 	 * Quotes will determine whether they are hex format */
 	if (strcmp (key_value[0], "psk") != 0
 	    && !g_str_has_prefix (key_value[0], "wep_key")
@@ -162,7 +162,7 @@ add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key)
 	}
 }
 
-/* Reading wep security information from /etc/conf.d/net. 
+/* Reading wep security information from /etc/conf.d/net.
  * This should not be used in futre, use wpa_supplicant instead. */
 static void
 add_keys_from_net ()
@@ -279,16 +279,21 @@ wpa_parser_init (const char *wpa_supplicant_conf)
 			} else {
 				GHashTable *network =
 				    g_hash_table_new (g_str_hash, g_str_equal);
-				gchar *tmp;
 
 				do {
+					gchar *quote_start, *quote_end = NULL, *comment;
+
 					if (line[0] == '#' || line[0] == '\0') {
 						g_free (line);
 						continue;
 					}
-					/* ignore inline comments */
-					if ((tmp = strchr (line, '#')) != NULL)
-						*tmp = '\0';
+					/* ignore inline comments unless inside
+					   a double-quoted string */
+					if ((quote_start = strchr (line, '"')) != NULL)
+						quote_end = strrchr (quote_start + 1, '"');
+					if ((comment = strchr ((quote_end != NULL) ?
+					                       quote_end : line, '#')) != NULL)
+						*comment = '\0';
 					if (strstr (line, "}") != NULL)
 						complete = TRUE;
 					add_key_value (network, line);
@@ -371,6 +376,8 @@ wpa_flush_to_file (const char *config_file)
 	if (!wsec_table || !wsec_global_table)
 		return FALSE;
 
+	backup_file (config_file);
+
 	channel = g_io_channel_new_file (config_file, "w", NULL);
 	if (!channel) {
 		PLUGIN_WARN (IFNET_PLUGIN_NAME,
diff --git a/src/settings/plugins/ifnet/wpa_parser.h b/src/settings/plugins/ifnet/wpa_parser.h
index 7fd77a05..3a0d377e 100644
--- a/src/settings/plugins/ifnet/wpa_parser.h
+++ b/src/settings/plugins/ifnet/wpa_parser.h
@@ -21,8 +21,11 @@
 
 #ifndef _WPA_PARSER_H
 #define _WPA_PARSER_H
-#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant/wpa_supplicant.conf"
+
 #include <glib.h>
+
+#define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf"
+
 void wpa_parser_init (const char *wpa_supplicant_conf);
 void wpa_parser_destroy (void);
 
diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in
index 98dded68..f5087648 100644
--- a/src/settings/plugins/ifupdown/Makefile.in
+++ b/src/settings/plugins/ifupdown/Makefile.in
@@ -217,6 +217,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -271,11 +273,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -286,6 +292,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -325,6 +332,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c
index b7c64242..38ed1479 100644
--- a/src/settings/plugins/ifupdown/interface_parser.c
+++ b/src/settings/plugins/ifupdown/interface_parser.c
@@ -294,6 +294,19 @@ const char *ifparser_getkey(if_block* iface, const char *key)
 	return NULL;
 }
 
+gboolean
+ifparser_haskey(if_block* iface, const char *key)
+{
+	if_data *curr = iface->info;
+
+	while (curr != NULL) {
+		if (strcmp (curr->key, key) == 0)
+			return TRUE;
+		curr = curr->next;
+	}
+	return FALSE;
+}
+
 int ifparser_get_num_info(if_block* iface)
 {
 	int i = 0;
diff --git a/src/settings/plugins/ifupdown/interface_parser.h b/src/settings/plugins/ifupdown/interface_parser.h
index 0c1de23a..e68abcf6 100644
--- a/src/settings/plugins/ifupdown/interface_parser.h
+++ b/src/settings/plugins/ifupdown/interface_parser.h
@@ -24,6 +24,8 @@
 #ifndef _INTERFACE_PARSER_H
 #define _INTERFACE_PARSER_H
 
+#include <glib.h>
+
 typedef struct _if_data
 {
 	char *key;
@@ -45,6 +47,7 @@ void ifparser_destroy(void);
 if_block *ifparser_getif(const char* iface);
 if_block *ifparser_getfirst(void);
 const char *ifparser_getkey(if_block* iface, const char *key);
+gboolean ifparser_haskey(if_block* iface, const char *key);
 int ifparser_get_num_blocks(void);
 int ifparser_get_num_info(if_block* iface);
 
diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c
index dc2f8abf..6927f43f 100644
--- a/src/settings/plugins/ifupdown/parser.c
+++ b/src/settings/plugins/ifupdown/parser.c
@@ -25,6 +25,7 @@
 #include <arpa/inet.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include <nm-connection.h>
 #include <NetworkManager.h>
@@ -311,8 +312,7 @@ update_wireless_security_setting_from_if_block(NMConnection *connection,
 		return;
 	}
 
-	s_wireless = NM_SETTING_WIRELESS(nm_connection_get_setting(connection,
-												    NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless(connection);
 	g_return_if_fail(s_wireless);
 
 	PLUGIN_PRINT ("SCPlugin-Ifupdown","update wireless security settings (%s).", block->name);
@@ -433,96 +433,263 @@ eni_plugin_error_quark() {
 
 	return error_quark;
 }
-	
 
 static void
+ifupdown_ip4_add_dns (NMSettingIP4Config *s_ip4, const char *dns)
+{
+	struct in_addr addr;
+	char **list, **iter;
+
+	if (dns == NULL)
+		return;
+
+	list = g_strsplit_set (dns, " \t", -1);
+	for (iter = list; iter && *iter; iter++) {
+		g_strstrip (*iter);
+		if (isblank (*iter[0]))
+			continue;
+		if (!inet_pton (AF_INET, *iter, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: ignoring invalid nameserver '%s'", *iter);
+			continue;
+		}
+
+		if (!nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: duplicate DNS domain '%s'", *iter);
+		}
+	}
+	g_strfreev (list);
+}
+
+static gboolean
 update_ip4_setting_from_if_block(NMConnection *connection,
-						   if_block *block)
+						   if_block *block,
+						   GError **error)
 {
 
-	NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new());
+	NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new());
 	const char *type = ifparser_getkey(block, "inet");
 	gboolean is_static = type && !strcmp("static", type);
 
-	if(!is_static) {
-		g_object_set(ip4_setting,
-				   NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
-				   NULL);
+	if (!is_static) {
+		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
 	} else {
- 		struct in_addr tmp_ip4_addr;
-		NMIP4Address *ip4_addr = nm_ip4_address_new ();
-
-		const char *address_v = ifparser_getkey(block, "address");
-		const char *netmask_v = ifparser_getkey(block, "netmask");
-		const char *gateway_v = ifparser_getkey(block, "gateway");
-		const char *nameserver_v = ifparser_getkey(block, "dns-nameserver");
-		const char *nameservers_v = ifparser_getkey(block, "dns-nameservers");
-		GSList* nameservers_list = NULL;
-		GSList* nameservers_list_i = NULL;
-		GError *error = NULL;
-
-		if(nameservers_v)
-			nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v);
-		if(nameserver_v)
-			nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v));
-
-		if (!address_v)
-			address_v = g_strdup ("0.0.0.0");
-
-		if (inet_pton (AF_INET, address_v, &tmp_ip4_addr))
-			nm_ip4_address_set_address (ip4_addr, tmp_ip4_addr.s_addr);
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "address", address_v);
-		if (!netmask_v)
-			netmask_v = g_strdup( "255.255.255.255");
-
-		if (inet_pton (AF_INET, netmask_v, &tmp_ip4_addr))
-			nm_ip4_address_set_prefix (ip4_addr, nm_utils_ip4_netmask_to_prefix(tmp_ip4_addr.s_addr));
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "netmask", netmask_v);
+		struct in_addr tmp_addr, tmp_mask, tmp_gw;
+		NMIP4Address *addr;
+		const char *address_v;
+		const char *netmask_v;
+		const char *gateway_v;
+		const char *nameserver_v;
+		const char *nameservers_v;
+		const char *search_v;
+		char **list, **iter;
+		guint32 netmask_int = 32;
+
+		/* Address */
+		address_v = ifparser_getkey (block, "address");
+		if (!address_v || !inet_pton (AF_INET, address_v, &tmp_addr)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+			             "Missing IPv4 address '%s'",
+			             address_v ? address_v : "(none)");
+			goto error;
+		}
 
+		/* mask/prefix */
+		netmask_v = ifparser_getkey (block, "netmask");
+		if (netmask_v) {
+			if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) {
+				g_set_error (error, eni_plugin_error_quark (), 0,
+						   "Invalid IPv4 netmask '%s'", netmask_v);
+				goto error;
+			}
+			netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask.s_addr);
+		}
+
+		/* gateway */
+		gateway_v = ifparser_getkey (block, "gateway");
 		if (!gateway_v)
-			gateway_v = g_strdup (address_v);
+			gateway_v = address_v;  /* dcbw: whaaa?? */
+		if (!inet_pton (AF_INET, gateway_v, &tmp_gw)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+					   "Invalid IPv4 gateway '%s'", gateway_v);
+			goto error;
+		}
 
-		if (inet_pton (AF_INET, gateway_v, &tmp_ip4_addr))
-			nm_ip4_address_set_gateway (ip4_addr, tmp_ip4_addr.s_addr);
-		else
-			g_set_error (&error, eni_plugin_error_quark (), 0,
-					   "Invalid %s IP4 address '%s'", "gateway", gateway_v);
+		/* Add the new address to the setting */
+		addr = nm_ip4_address_new ();
+		nm_ip4_address_set_address (addr, tmp_addr.s_addr);
+		nm_ip4_address_set_prefix (addr, netmask_int);
+		nm_ip4_address_set_gateway (addr, tmp_gw.s_addr);
 
-		if (nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) {
+		if (nm_setting_ip4_config_add_address (s_ip4, addr)) {
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
-			             nm_setting_ip4_config_get_num_addresses (ip4_setting));
+			             nm_setting_ip4_config_get_num_addresses (s_ip4));
 		} else {
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP4 address");
 		}
 
-		while(nameservers_list_i) {
-			gchar *dns = nameservers_list_i->data;
-			nameservers_list_i = nameservers_list_i -> next;
-			if(!dns)
-				continue;
-			if (inet_pton (AF_INET, dns, &tmp_ip4_addr)) {
-				if (!nm_setting_ip4_config_add_dns (ip4_setting, tmp_ip4_addr.s_addr))
-					PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns);
-			} else
-				g_set_error (&error, eni_plugin_error_quark (), 0,
-						   "Invalid %s IP4 address nameserver '%s'", "nameserver", dns);
+		nameserver_v = ifparser_getkey (block, "dns-nameserver");
+		ifupdown_ip4_add_dns (s_ip4, nameserver_v);
+
+		nameservers_v = ifparser_getkey (block, "dns-nameservers");
+		ifupdown_ip4_add_dns (s_ip4, nameservers_v);
+
+		if (!nm_setting_ip4_config_get_num_dns (s_ip4))
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
+
+		/* DNS searches */
+		search_v = ifparser_getkey (block, "dns-search");
+		if (search_v) {
+			list = g_strsplit_set (search_v, " \t", -1);
+			for (iter = list; iter && *iter; iter++) {
+				g_strstrip (*iter);
+				if (isblank (*iter[0]))
+					continue;
+				if (!nm_setting_ip4_config_add_dns_search (s_ip4, *iter)) {
+					PLUGIN_WARN ("SCPlugin-Ifupdown",
+							   "    warning: duplicate DNS domain '%s'", *iter);
+				}
+			}
+			g_strfreev (list);
 		}
-		if (!nm_setting_ip4_config_get_num_dns (ip4_setting))
+
+		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
+	}
+
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+	return TRUE;
+
+error:
+	g_object_unref (s_ip4);
+	return FALSE;
+}
+
+static void
+ifupdown_ip6_add_dns (NMSettingIP6Config *s_ip6, const char *dns)
+{
+	struct in6_addr addr;
+	char **list, **iter;
+
+	if (dns == NULL)
+		return;
+
+	list = g_strsplit_set (dns, " \t", -1);
+	for (iter = list; iter && *iter; iter++) {
+		g_strstrip (*iter);
+		if (isblank (*iter[0]))
+			continue;
+		if (!inet_pton (AF_INET6, *iter, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: ignoring invalid nameserver '%s'", *iter);
+			continue;
+		}
+
+		if (!nm_setting_ip6_config_add_dns (s_ip6, &addr)) {
+			PLUGIN_WARN ("SCPlugin-Ifupdown",
+					   "    warning: duplicate DNS domain '%s'", *iter);
+		}
+	}
+	g_strfreev (list);
+}
+
+static gboolean
+update_ip6_setting_from_if_block(NMConnection *connection,
+						   if_block *block,
+						   GError **error)
+{
+	NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new());
+	const char *type = ifparser_getkey(block, "inet6");
+	gboolean is_static = type && (!strcmp("static", type) ||
+							!strcmp("v4tunnel", type));
+
+	if (!is_static) {
+		g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+	} else {
+		struct in6_addr tmp_addr, tmp_gw;
+		NMIP6Address *addr;
+		const char *address_v;
+		const char *prefix_v;
+		const char *gateway_v;
+		const char *nameserver_v;
+		const char *nameservers_v;
+		const char *search_v;
+		int prefix_int = 128;
+		char **list, **iter;
+
+		/* Address */
+		address_v = ifparser_getkey(block, "address");
+		if (!address_v || !inet_pton (AF_INET6, address_v, &tmp_addr)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+			             "Missing IPv6 address '%s'",
+			             address_v ? address_v : "(none)");
+			goto error;
+		}
+
+		/* Prefix */
+		prefix_v = ifparser_getkey(block, "netmask");
+		if (prefix_v)
+			prefix_int = g_ascii_strtoll (prefix_v, NULL, 10);
+
+		/* Gateway */
+		gateway_v = ifparser_getkey (block, "gateway");
+		if (!gateway_v)
+			gateway_v = address_v;  /* dcbw: whaaa?? */
+		if (!inet_pton (AF_INET6, gateway_v, &tmp_gw)) {
+			g_set_error (error, eni_plugin_error_quark (), 0,
+					   "Invalid IPv6 gateway '%s'", gateway_v);
+			goto error;
+		}
+
+		/* Add the new address to the setting */
+		addr = nm_ip6_address_new ();
+		nm_ip6_address_set_address (addr, &tmp_addr);
+		nm_ip6_address_set_prefix (addr, prefix_int);
+		nm_ip6_address_set_gateway (addr, &tmp_gw);
+
+		if (nm_setting_ip6_config_add_address (s_ip6, addr)) {
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
+					   nm_setting_ip6_config_get_num_addresses (s_ip6));
+		} else {
+			PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP6 address");
+		}
+
+		nameserver_v = ifparser_getkey(block, "dns-nameserver");
+		ifupdown_ip6_add_dns (s_ip6, nameserver_v);
+
+		nameservers_v = ifparser_getkey(block, "dns-nameservers");
+		ifupdown_ip6_add_dns (s_ip6, nameservers_v);
+
+		if (!nm_setting_ip6_config_get_num_dns (s_ip6))
 			PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
 
-		g_object_set(ip4_setting,
-				   NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
-				   NULL);
+		/* DNS searches */
+		search_v = ifparser_getkey (block, "dns-search");
+		if (search_v) {
+			list = g_strsplit_set (search_v, " \t", -1);
+			for (iter = list; iter && *iter; iter++) {
+				g_strstrip (*iter);
+				if (isblank (*iter[0]))
+					continue;
+				if (!nm_setting_ip6_config_add_dns_search (s_ip6, *iter)) {
+					PLUGIN_WARN ("SCPlugin-Ifupdown",
+							   "    warning: duplicate DNS domain '%s'", *iter);
+				}
+			}
+			g_strfreev (list);
+		}
 
-		g_slist_foreach (nameservers_list, (GFunc) g_free, NULL);
-		g_slist_free (nameservers_list);
+		g_object_set (s_ip6,
+		              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+		              NULL);
 	}
 
-	nm_connection_add_setting(connection, NM_SETTING(ip4_setting));
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+	return TRUE;
+
+error:
+	g_object_unref (s_ip6);
+	return FALSE;
 }
 
 gboolean
@@ -537,7 +704,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
 	NMSettingConnection *s_con;
 	gboolean success = FALSE;
 
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	if(!s_con) {
 		s_con = NM_SETTING_CONNECTION (nm_setting_connection_new());
 		g_assert (s_con);
@@ -562,15 +729,19 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
 			   block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
 
 	if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type))
-		update_wired_setting_from_if_block (connection, block);	
+		update_wired_setting_from_if_block (connection, block);
 	else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
 		update_wireless_setting_from_if_block (connection, block);
 		update_wireless_security_setting_from_if_block (connection, block);
 	}
 
-	update_ip4_setting_from_if_block (connection, block);
+	if (ifparser_haskey(block, "inet6"))
+		success = update_ip6_setting_from_if_block (connection, block, error);
+	else
+		success = update_ip4_setting_from_if_block (connection, block, error);
 
-	success = nm_connection_verify (connection, error);
+	if (success == TRUE)
+		success = nm_connection_verify (connection, error);
 
 	g_free (idstr);
 	return success;
diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c
index 9679edea..4dbb0aa2 100644
--- a/src/settings/plugins/ifupdown/plugin.c
+++ b/src/settings/plugins/ifupdown/plugin.c
@@ -19,7 +19,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * (C) Copyright 2007,2008 Canonical Ltd.
- * (C) Copyright 2009 Red Hat, Inc.
+ * (C) Copyright 2009 - 2011 Red Hat, Inc.
  */
 
 #include <string.h>
@@ -42,6 +42,7 @@
 #include "nm-setting-wireless.h"
 #include "nm-setting-wired.h"
 #include "nm-setting-ppp.h"
+#include "nm-utils.h"
 
 #include "nm-ifupdown-connection.h"
 #include "plugin.h"
@@ -60,9 +61,6 @@
 #define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd.  To report bugs please use the NetworkManager mailing list."
 #define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname"
 
-#define IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
-#define IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
-
 #define IFUPDOWN_KEY_FILE_GROUP "ifupdown"
 #define IFUPDOWN_KEY_FILE_KEY_MANAGED "managed"
 #define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE
@@ -81,7 +79,7 @@ typedef struct {
 	GHashTable *well_known_interfaces;
 	GHashTable *well_known_ifaces;
 	gboolean unmanage_well_known;
-	const char *conf_file;
+	char *conf_file;
 
 	gulong inotify_event_id;
 	int inotify_system_hostname_wd;
@@ -190,10 +188,9 @@ bind_device_to_connection (SCPluginIfupdown *self,
                            NMIfupdownConnection *exported)
 {
 	GByteArray *mac_address;
-	NMSetting *s_wired = NULL;
-	NMSetting *s_wifi = NULL;
+	NMSettingWired *s_wired;
+	NMSettingWireless *s_wifi;
 	const char *iface, *address;
-	struct ether_addr *tmp_mac;
 
 	iface = g_udev_device_get_name (device);
 	if (!iface) {
@@ -207,18 +204,15 @@ bind_device_to_connection (SCPluginIfupdown *self,
 		return;
 	}
 
-	tmp_mac = ether_aton (address);
-	if (!tmp_mac) {
+	mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER);
+	if (!mac_address) {
 		PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s",
 		             address, iface);
 		return;
 	}
 
-	mac_address = g_byte_array_sized_new (ETH_ALEN);
-	g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN);
-
-	s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED);
-	s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS);
+	s_wired = nm_connection_get_setting_wired (NM_CONNECTION (exported));
+	s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (exported));
 	if (s_wired) {
 		PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting");
 		g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL);
@@ -432,13 +426,13 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config)
 	keys = g_hash_table_get_keys (priv->iface_connections);
 	for (iter = keys; iter; iter = g_list_next (iter)) {
 		NMIfupdownConnection *exported;
-		NMSetting *setting;
+		NMSettingConnection *setting;
 
 		if (!g_hash_table_lookup (auto_ifaces, iter->data))
 			continue;
 
 		exported = g_hash_table_lookup (priv->iface_connections, iter->data);
-		setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION));
+		setting = nm_connection_get_setting_connection (NM_CONNECTION (exported));
 		g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
 
 		nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL);
@@ -448,12 +442,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config)
 	g_list_free (keys);
 	g_hash_table_destroy (auto_ifaces);
 
-	/* Find the config file */
-	if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS))
-		priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE;
-	else
-		priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE;
-
+	/* Read the config file to find out whether to manage interfaces */
 	keyfile = g_key_file_new ();
 	if (!g_key_file_load_from_file (keyfile,
 	                                priv->conf_file,
@@ -706,20 +695,28 @@ GObject__dispose (GObject *object)
 	if (priv->well_known_interfaces)
 		g_hash_table_destroy(priv->well_known_interfaces);
 
+	g_free (priv->conf_file);
+
 	if (priv->client)
 		g_object_unref (priv->client);
 
+
 	G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object);
 }
 
 G_MODULE_EXPORT GObject *
-nm_system_config_factory (void)
+nm_system_config_factory (const char *config_file)
 {
 	static SCPluginIfupdown *singleton = NULL;
+	SCPluginIfupdownPrivate *priv;
 
-	if (!singleton)
+	if (!singleton) {
 		singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL));
-	else
+		if (singleton) {
+			priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (singleton);
+			priv->conf_file = strdup (config_file);
+		}
+	} else
 		g_object_ref (singleton);
 
 	return G_OBJECT (singleton);
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am
index aed86197..ff219d5d 100644
--- a/src/settings/plugins/ifupdown/tests/Makefile.am
+++ b/src/settings/plugins/ifupdown/tests/Makefile.am
@@ -29,4 +29,4 @@ endif
 
 EXTRA_DIST = \
 	test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \
-	test13 test14 test15 test16
+	test13 test14 test15 test16 test17-wired-static-verify-ip4
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in
index aca48837..a03be1bd 100644
--- a/src/settings/plugins/ifupdown/tests/Makefile.in
+++ b/src/settings/plugins/ifupdown/tests/Makefile.in
@@ -141,6 +141,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -195,11 +197,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -210,6 +216,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -249,6 +256,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -334,7 +343,7 @@ test_ifupdown_LDADD = \
 
 EXTRA_DIST = \
 	test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \
-	test13 test14 test15 test16
+	test13 test14 test15 test16 test17-wired-static-verify-ip4
 
 all: all-am
 
diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
index 16465364..01020bdf 100644
--- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c
+++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
@@ -21,6 +21,9 @@
 #include <glib.h>
 #include <string.h>
 
+#include <nm-utils.h>
+
+#include "nm-test-helpers.h"
 #include "interface_parser.h"
 #include "parser.h"
 
@@ -455,6 +458,386 @@ test16_missing_newline (const char *path)
 	ifparser_destroy ();
 	expected_free (e);
 }
+static void
+test17_read_static_ipv4 (const char *path)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingIP4Config *s_ip4;
+	NMSettingWired *s_wired;
+	char *unmanaged = NULL;
+	GError *error = NULL;
+	const char* tmp;
+	const char *expected_address = "10.0.0.3";
+	const char *expected_id = "Ifupdown (eth0)";
+	const char *expected_dns1 = "10.0.0.1";
+	const char *expected_dns2 = "10.0.0.2";
+	const char *expected_search1 = "example.com";
+	const char *expected_search2 = "foo.example.com";
+	guint32 expected_prefix = 8;
+	NMIP4Address *ip4_addr;
+	struct in_addr addr;
+#define TEST17_NAME "wired-static-verify-ip4"
+	if_block *block = NULL;
+
+	const char* file = "test17-" TEST17_NAME;
+
+	init_ifparser_with_file (path, file);
+	block = ifparser_getfirst ();
+	connection = nm_connection_new();
+	ifupdown_update_connection_from_if_block(connection, block, &error);
+
+	ASSERT (connection != NULL,
+			TEST17_NAME, "failed to read %s: %s", file, error->message);
+
+	ASSERT (nm_connection_verify (connection, &error),
+			TEST17_NAME, "failed to verify %s: %s", file, error->message);
+
+	ASSERT (unmanaged == NULL,
+			TEST17_NAME, "failed to verify %s: unexpected unmanaged value", file);
+
+	/* ===== CONNECTION SETTING ===== */
+
+	s_con = nm_connection_get_setting_connection (connection);
+	ASSERT (s_con != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME);
+
+	/* ID */
+	tmp = nm_setting_connection_get_id (s_con);
+	ASSERT (tmp != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s / %s key",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME,
+			NM_SETTING_CONNECTION_ID);
+	ASSERT (strcmp (tmp, expected_id) == 0,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value: %s",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME,
+			NM_SETTING_CONNECTION_ID, tmp);
+
+	/* ===== WIRED SETTING ===== */
+
+	s_wired = nm_connection_get_setting_wired (connection);
+	ASSERT (s_wired != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_WIRED_SETTING_NAME);
+
+	/* ===== IPv4 SETTING ===== */
+
+	ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0,
+			TEST17_NAME, "failed to verify %s: couldn't convert IP address #1",
+			file);
+
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
+	ASSERT (s_ip4 != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+	/* Method */
+	tmp = nm_setting_ip4_config_get_method (s_ip4);
+	ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_METHOD);
+
+	/* IP addresses */
+	ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+	ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+	ASSERT (ip4_addr,
+			TEST17_NAME, "failed to verify %s: missing IP4 address #1",
+			file);
+
+	ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix,
+			TEST17_NAME, "failed to verify %s: unexpected IP4 address prefix",
+			file);
+
+	ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+			TEST17_NAME, "failed to verify %s: unexpected IP4 address: %s",
+			file, addr.s_addr);
+
+	/* DNS Addresses */
+	ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+			TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #1",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #1",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+			TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #2",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #2",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	/* DNS search domains */
+	ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 2,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS);
+
+	tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0);
+	ASSERT (tmp != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s / %s key",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+	ASSERT (strcmp (tmp, expected_search1) == 0,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+	tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1);
+	ASSERT (tmp != NULL,
+			TEST17_NAME, "failed to verify %s: missing %s / %s key",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+	ASSERT (strcmp (tmp, expected_search2) == 0,
+			TEST17_NAME, "failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP4_CONFIG_SETTING_NAME,
+			NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+	g_object_unref (connection);
+}
+
+static void
+test18_read_static_ipv6 (const char *path)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingIP6Config *s_ip6;
+	NMSettingWired *s_wired;
+	char *unmanaged = NULL;
+	GError *error = NULL;
+	const char* tmp;
+	const char *expected_address = "fc00::1";
+	const char *expected_id = "Ifupdown (myip6tunnel)";
+	const char *expected_dns1 = "fc00::2";
+	const char *expected_dns2 = "fc00::3";
+	const char *expected_search1 = "example.com";
+	const char *expected_search2 = "foo.example.com";
+	guint32 expected_prefix = 64;
+	NMIP6Address *ip6_addr;
+	struct in6_addr addr;
+	if_block *block = NULL;
+#define TEST18_NAME "wired-static-verify-ip6"
+	const char* file = "test18-" TEST18_NAME;
+
+	init_ifparser_with_file (path, file);
+	block = ifparser_getfirst ();
+	connection = nm_connection_new();
+	ifupdown_update_connection_from_if_block(connection, block, &error);
+
+	ASSERT (connection != NULL,
+			TEST18_NAME
+			"failed to read %s: %s", file, error->message);
+
+	ASSERT (nm_connection_verify (connection, &error),
+			TEST18_NAME,
+			"failed to verify %s: %s", file, error->message);
+
+	ASSERT (unmanaged == NULL,
+			TEST18_NAME,
+			"failed to verify %s: unexpected unmanaged value", file);
+
+	/* ===== CONNECTION SETTING ===== */
+
+	s_con = nm_connection_get_setting_connection (connection);
+	ASSERT (s_con != NULL,
+			TEST18_NAME, "failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME);
+
+	/* ID */
+	tmp = nm_setting_connection_get_id (s_con);
+	ASSERT (tmp != NULL,
+			TEST18_NAME,
+			"failed to verify %s: missing %s / %s key",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME,
+			NM_SETTING_CONNECTION_ID);
+
+	ASSERT (strcmp (tmp, expected_id) == 0,
+			TEST18_NAME,
+			"failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_CONNECTION_SETTING_NAME,
+			NM_SETTING_CONNECTION_ID);
+
+	/* ===== WIRED SETTING ===== */
+
+	s_wired = nm_connection_get_setting_wired (connection);
+	ASSERT (s_wired != NULL,
+			TEST18_NAME, "failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_WIRED_SETTING_NAME);
+
+	/* ===== IPv6 SETTING ===== */
+
+	ASSERT (inet_pton (AF_INET6, expected_address, &addr) > 0,
+			TEST18_NAME,
+			"failed to verify %s: couldn't convert IP address #1",
+			file);
+
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
+	ASSERT (s_ip6 != NULL,
+			TEST18_NAME,
+			"failed to verify %s: missing %s setting",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+	/* Method */
+	tmp = nm_setting_ip6_config_get_method (s_ip6);
+	ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+			TEST18_NAME,
+			"failed to verify %s: unexpected %s / %s key value",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_METHOD);
+
+	/* IP addresses */
+	ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
+			TEST18_NAME,
+			"failed to verify %s: unexpected number of %s / %s",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+	ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+	ASSERT (ip6_addr,
+			TEST18_NAME,
+			"failed to verify %s: missing %s / %s #1",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+	ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix,
+			TEST18_NAME
+			"failed to verify %s: unexpected %s / %s prefix",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+	ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr),
+								&addr),
+			TEST18_NAME,
+			"failed to verify %s: unexpected %s / %s",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+	/* DNS Addresses */
+	ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
+			TEST18_NAME,
+			"failed to verify %s: unexpected number of %s / %s values",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS);
+
+	ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0,
+			TEST18_NAME,
+			"failed to verify %s: couldn't convert DNS IP address #1",
+			file);
+
+	ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0),
+								&addr),
+			TEST18_NAME,
+			"failed to verify %s: unexpected %s / %s #1",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS);
+
+	ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0,
+			TEST18_NAME,
+			"failed to verify %s: couldn't convert DNS IP address #2",
+			file);
+
+	ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1),
+								&addr),
+			TEST18_NAME, "failed to verify %s: unexpected %s / %s #2",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS);
+
+	/* DNS search domains */
+	ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 2,
+			TEST18_NAME,
+			"failed to verify %s: unexpected number of %s / %s values",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+	tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 0);
+	ASSERT (tmp != NULL,
+			"wired-ipv6-manual-verify-ip6",
+			"failed to verify %s: missing %s / %s #1",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+	ASSERT (strcmp (tmp, expected_search1) == 0,
+			"wired-ipv6-manual-verify-ip6",
+			"failed to verify %s: unexpected %s / %s #1",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+	tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 1);
+	ASSERT (tmp != NULL,
+			TEST18_NAME,
+			"failed to verify %s: missing %s / %s #2",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+	ASSERT (strcmp (tmp, expected_search2) == 0,
+			TEST18_NAME,
+			"failed to verify %s: unexpected %s / %s #2",
+			file,
+			NM_SETTING_IP6_CONFIG_SETTING_NAME,
+			NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+	g_free (unmanaged);
+	g_object_unref (connection);
+}
+
 
 #if GLIB_CHECK_VERSION(2,25,12)
 typedef GTestFixtureFunc TCFunc;
@@ -467,6 +850,12 @@ typedef void (*TCFunc)(void);
 int main (int argc, char **argv)
 {
 	GTestSuite *suite;
+	GError *error = NULL;
+
+	g_type_init ();
+
+	if (!nm_utils_init (&error))
+		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
 
 	g_test_init (&argc, &argv, NULL);
 
@@ -490,6 +879,8 @@ int main (int argc, char **argv)
 	g_test_suite_add (suite, TESTCASE (test14_mixed_whitespace_block_start, TEST_ENI_DIR));
 	g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR));
 	g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR));
+	g_test_suite_add (suite, TESTCASE (test17_read_static_ipv4, TEST_ENI_DIR));
+	g_test_suite_add (suite, TESTCASE (test18_read_static_ipv6, TEST_ENI_DIR));
 
 	return g_test_run ();
 }
diff --git a/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4 b/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4
new file mode 100644
index 00000000..9e5243a7
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test17-wired-static-verify-ip4
@@ -0,0 +1,5 @@
+iface eth0 inet static
+  address 10.0.0.3
+  netmask 255.0.0.0
+  dns-search example.com foo.example.com
+  dns-nameservers 10.0.0.1 10.0.0.2
diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am
index 3b242142..83031c24 100644
--- a/src/settings/plugins/keyfile/Makefile.am
+++ b/src/settings/plugins/keyfile/Makefile.am
@@ -3,7 +3,9 @@ SUBDIRS=. tests
 INCLUDES = \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
-	-I$(top_srcdir)/libnm-util
+	-I$(top_builddir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util
 
 noinst_LTLIBRARIES = \
 	libkeyfile-io.la \
diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in
index ae0c9f8e..c766e794 100644
--- a/src/settings/plugins/keyfile/Makefile.in
+++ b/src/settings/plugins/keyfile/Makefile.in
@@ -193,6 +193,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -247,11 +249,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -262,6 +268,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -301,6 +308,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -368,7 +377,9 @@ SUBDIRS = . tests
 INCLUDES = \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
-	-I$(top_srcdir)/libnm-util
+	-I$(top_builddir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util
 
 noinst_LTLIBRARIES = \
 	libkeyfile-io.la \
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
index af69c200..d53907a9 100644
--- a/src/settings/plugins/keyfile/plugin.c
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -42,9 +42,6 @@
 #include "common.h"
 #include "utils.h"
 
-#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
-#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
-
 static char *plugin_get_hostname (SCPluginKeyfile *plugin);
 static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
 
@@ -60,7 +57,7 @@ typedef struct {
 	GFileMonitor *monitor;
 	guint monitor_id;
 
-	const char *conf_file;
+	char *conf_file;
 	GFileMonitor *conf_file_monitor;
 	guint conf_file_monitor_id;
 
@@ -354,13 +351,15 @@ setup_monitoring (NMSystemConfigInterface *config)
 		priv->monitor = monitor;
 	}
 
-	file = g_file_new_for_path (priv->conf_file);
-	monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
-	g_object_unref (file);
+	if (priv->conf_file) {
+		file = g_file_new_for_path (priv->conf_file);
+		monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+		g_object_unref (file);
 
-	if (monitor) {
-		priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
-		priv->conf_file_monitor = monitor;
+		if (monitor) {
+			priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
+			priv->conf_file_monitor = monitor;
+		}
 	}
 }
 
@@ -410,6 +409,9 @@ get_unmanaged_specs (NMSystemConfigInterface *config)
 	GSList *specs = NULL;
 	GError *error = NULL;
 
+	if (!priv->conf_file)
+		return NULL;
+
 	key_file = g_key_file_new ();
 	if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) {
 		char *str;
@@ -460,6 +462,9 @@ plugin_get_hostname (SCPluginKeyfile *plugin)
 	char *hostname = NULL;
 	GError *error = NULL;
 
+	if (!priv->conf_file)
+		return NULL;
+
 	key_file = g_key_file_new ();
 	if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error))
 		hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL);
@@ -481,6 +486,11 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
 	GError *error = NULL;
 	gboolean result = FALSE;
 
+	if (!priv->conf_file) {
+		g_warning ("Error saving hostname: no config file");
+		return FALSE;
+	}
+
 	key_file = g_key_file_new ();
 	if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) {
 		char *data;
@@ -517,14 +527,6 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
 static void
 sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
-
-	if (g_file_test (CONF_FILE, G_FILE_TEST_EXISTS))
-		priv->conf_file = CONF_FILE;
-	else
-		priv->conf_file = OLD_CONF_FILE;
-
-	priv->hostname = plugin_get_hostname (plugin);
 }
 
 static void
@@ -597,6 +599,7 @@ dispose (GObject *object)
 	}
 
 	g_free (priv->hostname);
+	g_free (priv->conf_file);
 
 	if (priv->hash)
 		g_hash_table_destroy (priv->hash);
@@ -642,13 +645,22 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
 }
 
 GObject *
-nm_settings_keyfile_plugin_new (void)
+nm_settings_keyfile_plugin_new (const char *config_file)
 {
 	static SCPluginKeyfile *singleton = NULL;
+	SCPluginKeyfilePrivate *priv;
 
-	if (!singleton)
+	if (!singleton) {
 		singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
-	else
+		if (singleton) {
+			priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton);
+
+			priv->conf_file = g_strdup (config_file);
+
+			/* plugin_set_hostname() has to be called *after* priv->conf_file is set */
+			priv->hostname = plugin_get_hostname (singleton);
+		}
+	} else
 		g_object_ref (singleton);
 
 	return G_OBJECT (singleton);
diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h
index af5147ef..05d4e2b0 100644
--- a/src/settings/plugins/keyfile/plugin.h
+++ b/src/settings/plugins/keyfile/plugin.h
@@ -16,7 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
 #ifndef _PLUGIN_H_
@@ -43,6 +43,6 @@ GType sc_plugin_keyfile_get_type (void);
 
 GQuark keyfile_plugin_error_quark (void);
 
-GObject *nm_settings_keyfile_plugin_new (void);
+GObject *nm_settings_keyfile_plugin_new (const char *config_file);
 
 #endif	/* _PLUGIN_H_ */
diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c
index 4128b9f2..c7889cfc 100644
--- a/src/settings/plugins/keyfile/reader.c
+++ b/src/settings/plugins/keyfile/reader.c
@@ -34,8 +34,10 @@
 #include <nm-setting-wireless.h>
 #include <nm-setting-bluetooth.h>
 #include <nm-setting-8021x.h>
+#include <nm-utils.h>
 #include <arpa/inet.h>
 #include <netinet/ether.h>
+#include <linux/if_infiniband.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -650,12 +652,11 @@ static void
 mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
 {
 	const char *setting_name = nm_setting_get_name (setting);
-	struct ether_addr *eth;
 	char *tmp_string = NULL, *p;
 	gint *tmp_list;
 	GByteArray *array = NULL;
 	gsize length;
-	int i;
+	int i, type;
 
 	p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL);
 	if (tmp_string) {
@@ -666,43 +667,45 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons
 				i++;
 			p++;
 		}
-		if (i == 5) {
-			/* parse as a MAC address */
-			eth = ether_aton (tmp_string);
-			if (eth) {
-				g_free (tmp_string);
-				array = g_byte_array_sized_new (ETH_ALEN);
-				g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN);
-				goto done;
-			}
-		}
+
+		/* If we found enough it's probably a string-format MAC address */
+		type = nm_utils_hwaddr_type (i + 1);
+		if (type > 0)
+			array = nm_utils_hwaddr_atoba (tmp_string, type);
 	}
 	g_free (tmp_string);
 
-	/* Old format; list of ints */
-	tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL);
-	array = g_byte_array_sized_new (length);
-	for (i = 0; i < length; i++) {
-		int val = tmp_list[i];
-		unsigned char v = (unsigned char) (val & 0xFF);
-
-		if (val < 0 || val > 255) {
-			g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not "
-			           " between 0 and 255 inclusive)", __func__, setting_name,
-			           key, val);
-		} else
-			g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+	if (array == NULL) {
+		/* Old format; list of ints */
+		tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL);
+		type = nm_utils_hwaddr_type (length);
+		if (type < 0) {
+			array = g_byte_array_sized_new (length);
+			for (i = 0; i < length; i++) {
+				int val = tmp_list[i];
+				const guint8 v = (guint8) (val & 0xFF);
+
+				if (val < 0 || val > 255) {
+					g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not "
+							   " between 0 and 255 inclusive)", __func__, setting_name,
+							   key, val);
+					g_byte_array_free (array, TRUE);
+					array = NULL;
+					break;
+				}
+				g_byte_array_append (array, &v, 1);
+			}
+		}
+		g_free (tmp_list);
 	}
-	g_free (tmp_list);
 
-done:
-	if (array->len == ETH_ALEN) {
+	if (array) {
 		g_object_set (setting, key, array, NULL);
+		g_byte_array_free (array, TRUE);
 	} else {
 		g_warning ("%s: ignoring invalid MAC address for %s / %s",
 		           __func__, setting_name, key);
 	}
-	g_byte_array_free (array, TRUE);
 }
 
 static void
@@ -825,6 +828,22 @@ ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char
 	}
 }
 
+static void
+password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+	const char *setting_name = nm_setting_get_name (setting);
+	GByteArray *array;
+
+	array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE);
+	if (array) {
+		g_object_set (setting, key, array, NULL);
+		g_byte_array_free (array, TRUE);
+	} else {
+		g_warning ("%s: ignoring invalid raw password for %s / %s",
+		           __func__, setting_name, key);
+	}
+}
+
 static char *
 get_cert_path (const char *keyfile_path, GByteArray *cert_path)
 {
@@ -1019,11 +1038,19 @@ static KeyParser key_parsers[] = {
 	  NM_SETTING_BLUETOOTH_BDADDR,
 	  TRUE,
 	  mac_address_parser },
+	{ NM_SETTING_INFINIBAND_SETTING_NAME,
+	  NM_SETTING_INFINIBAND_MAC_ADDRESS,
+	  TRUE,
+	  mac_address_parser },
 	{ NM_SETTING_WIRELESS_SETTING_NAME,
 	  NM_SETTING_WIRELESS_SSID,
 	  TRUE,
 	  ssid_parser },
 	{ NM_SETTING_802_1X_SETTING_NAME,
+	  NM_SETTING_802_1X_PASSWORD_RAW,
+	  TRUE,
+	  password_raw_parser },
+	{ NM_SETTING_802_1X_SETTING_NAME,
 	  NM_SETTING_802_1X_CA_CERT,
 	  TRUE,
 	  cert_parser },
@@ -1300,7 +1327,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
 	 * the keyfile didn't include it, which can happen when the base
 	 * device type setting is all default values (like ethernet).
 	 */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	if (s_con) {
 		ctype = nm_setting_connection_get_connection_type (s_con);
 		setting = nm_connection_get_setting_by_name (connection, ctype);
@@ -1314,7 +1341,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
 	if (vpn_secrets) {
 		NMSettingVPN *s_vpn;
 
-		s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+		s_vpn = nm_connection_get_setting_vpn (connection);
 		if (s_vpn)
 			read_vpn_secrets (key_file, s_vpn);
 	}
diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am
index affe8dca..2adbf873 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.am
+++ b/src/settings/plugins/keyfile/tests/Makefile.am
@@ -2,7 +2,9 @@ SUBDIRS=keyfiles
 
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
 
diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in
index c1fc662d..ff08e529 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/Makefile.in
@@ -179,6 +179,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -233,11 +235,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -248,6 +254,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -287,6 +294,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -353,7 +362,9 @@ top_srcdir = @top_srcdir@
 SUBDIRS = keyfiles
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
 
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
index 55dda7ee..f163312e 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
@@ -13,7 +13,8 @@ KEYFILES = \
 	Test_Wired_TLS_Old \
 	Test_Wired_TLS_New \
 	Test_Wired_TLS_Blob \
-	Test_Wired_TLS_Path_Missing
+	Test_Wired_TLS_Path_Missing \
+	Test_InfiniBand_Connection
 
 CERTS = \
 	test-ca-cert.pem \
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
index 0ea23ebc..cf5b868f 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
@@ -107,6 +107,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -161,11 +163,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -176,6 +182,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -215,6 +222,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -293,7 +302,8 @@ KEYFILES = \
 	Test_Wired_TLS_Old \
 	Test_Wired_TLS_New \
 	Test_Wired_TLS_Blob \
-	Test_Wired_TLS_Path_Missing
+	Test_Wired_TLS_Path_Missing \
+	Test_InfiniBand_Connection
 
 CERTS = \
 	test-ca-cert.pem \
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
new file mode 100644
index 00000000..3a984b77
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
@@ -0,0 +1,13 @@
+[connection]
+id=Test InfiniBand Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=infiniband
+
+[infiniband]
+mac-address=00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90
+transport-mode=datagram
+mtu=1400
+
+[ipv4]
+method=auto
+
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c
index 2859cb3e..79fa2f9c 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile.c
@@ -26,6 +26,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
+#include <linux/if_infiniband.h>
 
 #include <nm-utils.h>
 #include <nm-setting-connection.h>
@@ -38,6 +39,7 @@
 #include <nm-setting-ppp.h>
 #include <nm-setting-gsm.h>
 #include <nm-setting-8021x.h>
+#include <nm-setting-infiniband.h>
 
 #include "nm-test-helpers.h"
 
@@ -93,7 +95,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -142,7 +144,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -174,7 +176,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -297,7 +299,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "connection-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -745,7 +747,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -779,7 +781,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -787,7 +789,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -809,7 +811,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "connection-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -1001,7 +1003,7 @@ test_read_wired_mac_case (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_MAC_CASE_FILE,
@@ -1035,7 +1037,7 @@ test_read_wired_mac_case (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_MAC_CASE_FILE,
@@ -1087,7 +1089,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1136,7 +1138,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "connection-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1162,7 +1164,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1315,7 +1317,7 @@ test_read_string_ssid (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "connection-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_STRING_SSID_FILE,
@@ -1832,7 +1834,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -1866,7 +1868,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== BLUETOOTH SETTING ===== */
 
-	s_bluetooth = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+	s_bluetooth = nm_connection_get_setting_bluetooth (connection);
 	ASSERT (s_bluetooth != NULL,
 	        "connection-verify-bt", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1905,7 +1907,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== GSM SETTING ===== */
 
-	s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+	s_gsm = nm_connection_get_setting_gsm (connection);
 	ASSERT (s_gsm != NULL,
 	        "connection-verify-gsm", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -1952,7 +1954,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== SERIAL SETTING ===== */
 
-	s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+	s_serial = nm_connection_get_setting_serial (connection);
 	ASSERT (s_serial != NULL,
 	        "connection-verify-serial", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -2081,7 +2083,7 @@ test_read_gsm_connection (void)
 	NMSettingConnection *s_con;
 	NMSettingSerial *s_serial;
 	NMSettingGsm *s_gsm;
-	NMSetting *s_bluetooth;
+	NMSettingBluetooth *s_bluetooth;
 	GError *error = NULL;
 	const char *tmp;
 	const char *expected_id = "AT&T Data Connect";
@@ -2100,7 +2102,7 @@ test_read_gsm_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2134,7 +2136,7 @@ test_read_gsm_connection (void)
 	/* ===== BLUETOOTH SETTING ===== */
 
 	/* Plain GSM, so no BT setting expected */
-	s_bluetooth = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+	s_bluetooth = nm_connection_get_setting_bluetooth (connection);
 	ASSERT (s_bluetooth == NULL,
 	        "connection-verify-bt", "unexpected %s setting",
 	        TEST_GSM_FILE,
@@ -2142,7 +2144,7 @@ test_read_gsm_connection (void)
 
 	/* ===== GSM SETTING ===== */
 
-	s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+	s_gsm = nm_connection_get_setting_gsm (connection);
 	ASSERT (s_gsm != NULL,
 	        "connection-verify-gsm", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2215,7 +2217,7 @@ test_read_gsm_connection (void)
 
 	/* ===== SERIAL SETTING ===== */
 
-	s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+	s_serial = nm_connection_get_setting_serial (connection);
 	ASSERT (s_serial != NULL,
 	        "connection-verify-serial", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2324,7 +2326,7 @@ static void
 test_read_wired_8021x_tls_blob_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2346,11 +2348,11 @@ test_read_wired_8021x_tls_blob_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2389,7 +2391,7 @@ static void
 test_read_wired_8021x_tls_bad_path_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2411,11 +2413,11 @@ test_read_wired_8021x_tls_bad_path_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2451,7 +2453,7 @@ static void
 test_read_wired_8021x_tls_old_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2472,11 +2474,11 @@ test_read_wired_8021x_tls_old_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2507,7 +2509,7 @@ static void
 test_read_wired_8021x_tls_new_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2529,11 +2531,11 @@ test_read_wired_8021x_tls_new_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2779,7 +2781,7 @@ test_write_wired_8021x_tls_connection_blob (void)
 	g_assert (testfile);
 
 	/* Check that the new certs got written out */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
 	uuid = nm_setting_connection_get_uuid (s_con);
 	g_assert (uuid);
@@ -2805,7 +2807,7 @@ test_write_wired_8021x_tls_connection_blob (void)
 	}
 
 	/* Ensure the re-read connection's certificates use the path scheme */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (reread);
 	g_assert (s_8021x);
 	g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
 	g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
@@ -2828,6 +2830,134 @@ test_write_wired_8021x_tls_connection_blob (void)
 	g_object_unref (connection);
 }
 
+#define TEST_INFINIBAND_FILE    TEST_KEYFILES_DIR"/Test_InfiniBand_Connection"
+
+static void
+test_read_infiniband_connection (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingInfiniband *s_ib;
+	GError *error = NULL;
+	const GByteArray *array;
+	guint8 expected_mac[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
+		0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89,
+		0x90 };
+	const char *expected_id = "Test InfiniBand Connection";
+	const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+	gboolean success;
+
+	connection = nm_keyfile_plugin_connection_from_file (TEST_INFINIBAND_FILE, &error);
+	g_assert_no_error (error);
+	g_assert (connection);
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	/* Connection setting */
+	s_con = nm_connection_get_setting_connection (connection);
+	g_assert (s_con);
+	g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
+	g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, expected_uuid);
+
+	/* InfiniBand setting */
+	s_ib = nm_connection_get_setting_infiniband (connection);
+	g_assert (s_ib);
+
+	array = nm_setting_infiniband_get_mac_address (s_ib);
+	g_assert (array);
+	g_assert_cmpint (array->len, ==, INFINIBAND_ALEN);
+	g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0);
+
+	g_object_unref (connection);
+}
+
+static void
+test_write_infiniband_connection (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingInfiniband *s_ib;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	char *uuid;
+	GByteArray *mac;
+	guint8 tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0xab, 0xbc,
+		0xcd, 0xde, 0xef, 0xf0, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f, 0x6f, 0xba
+	};
+	gboolean success;
+	NMConnection *reread;
+	char *testfile = NULL;
+	GError *error = NULL;
+	pid_t owner_grp;
+	uid_t owner_uid;
+
+	connection = nm_connection_new ();
+	g_assert (connection);
+
+	/* Connection setting */
+
+	s_con = (NMSettingConnection *) nm_setting_connection_new ();
+	g_assert (s_con);
+	nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+	uuid = nm_utils_uuid_generate ();
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "Work InfiniBand",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* InfiniBand setting */
+	s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new ();
+	g_assert (s_ib);
+	nm_connection_add_setting (connection, NM_SETTING (s_ib));
+
+	mac = g_byte_array_sized_new (sizeof (tmpmac));
+	g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+	g_object_set (s_ib,
+	              NM_SETTING_INFINIBAND_MAC_ADDRESS, mac,
+	              NM_SETTING_INFINIBAND_MTU, 900,
+	              NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram",
+	              NULL);
+	g_byte_array_free (mac, TRUE);
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+	g_assert (s_ip4);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+	g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+	/* IP6 setting */
+	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+	g_assert (s_ip6);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+	g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+
+	/* Write out the connection */
+	owner_uid = geteuid ();
+	owner_grp = getegid ();
+	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (testfile);
+
+	/* Read the connection back in and compare it to the one we just wrote out */
+	reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
+	g_assert_no_error (error);
+	g_assert (reread);
+
+	g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
+
+	unlink (testfile);
+	g_free (testfile);
+
+	g_object_unref (reread);
+	g_object_unref (connection);
+}
+
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
@@ -2876,6 +3006,9 @@ int main (int argc, char **argv)
 	test_write_wired_8021x_tls_connection_path ();
 	test_write_wired_8021x_tls_connection_blob ();
 
+	test_read_infiniband_connection ();
+	test_write_infiniband_connection ();
+
 	base = g_path_get_basename (argv[0]);
 	fprintf (stdout, "%s: SUCCESS\n", base);
 	g_free (base);
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index 2babe267..bbd6a7c3 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -416,7 +416,7 @@ mac_address_writer (GKeyFile *file,
 	GByteArray *array;
 	const char *setting_name = nm_setting_get_name (setting);
 	char *mac;
-	struct ether_addr tmp;
+	int type;
 
 	g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
 
@@ -424,15 +424,16 @@ mac_address_writer (GKeyFile *file,
 	if (!array)
 		return;
 
-	if (array->len != ETH_ALEN) {
+	type = nm_utils_hwaddr_type (array->len);
+	if (type < 0) {
 		g_warning ("%s: invalid %s / %s MAC address length %d",
 		           __func__, setting_name, key, array->len);
 		return;
 	}
 
-	memcpy (tmp.ether_addr_octet, array->data, ETH_ALEN);
-	mac = ether_ntoa (&tmp);
+	mac = nm_utils_hwaddr_ntoa (array->data, type);
 	g_key_file_set_string (file, setting_name, key, mac);
+	g_free (mac);
 }
 
 static void
@@ -532,6 +533,31 @@ ssid_writer (GKeyFile *file,
 	}
 }
 
+static void
+password_raw_writer (GKeyFile *file,
+                     const char *keyfile_dir,
+                     const char *uuid,
+                     NMSetting *setting,
+                     const char *key,
+                     const GValue *value)
+{
+	const char *setting_name = nm_setting_get_name (setting);
+	GByteArray *array;
+	int i, *tmp_array;
+
+	g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
+
+	array = (GByteArray *) g_value_get_boxed (value);
+	if (!array || !array->len)
+		return;
+
+	tmp_array = g_new (gint, array->len);
+	for (i = 0; i < array->len; i++)
+		tmp_array[i] = (int) array->data[i];
+	g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len);
+	g_free (tmp_array);
+}
+
 typedef struct ObjectType {
 	const char *key;
 	const char *suffix;
@@ -787,10 +813,16 @@ static KeyWriter key_writers[] = {
 	{ NM_SETTING_BLUETOOTH_SETTING_NAME,
 	  NM_SETTING_BLUETOOTH_BDADDR,
 	  mac_address_writer },
+	{ NM_SETTING_INFINIBAND_SETTING_NAME,
+	  NM_SETTING_INFINIBAND_MAC_ADDRESS,
+	  mac_address_writer },
 	{ NM_SETTING_WIRELESS_SETTING_NAME,
 	  NM_SETTING_WIRELESS_SSID,
 	  ssid_writer },
 	{ NM_SETTING_802_1X_SETTING_NAME,
+	  NM_SETTING_802_1X_PASSWORD_RAW,
+	  password_raw_writer },
+	{ NM_SETTING_802_1X_SETTING_NAME,
 	  NM_SETTING_802_1X_CA_CERT,
 	  cert_writer },
 	{ NM_SETTING_802_1X_SETTING_NAME,
diff --git a/src/settings/tests/Makefile.am b/src/settings/tests/Makefile.am
index 4a451398..57d56fc4 100644
--- a/src/settings/tests/Makefile.am
+++ b/src/settings/tests/Makefile.am
@@ -1,5 +1,6 @@
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_srcdir)/src/settings
 
diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in
index 7c966ba2..de5474d4 100644
--- a/src/settings/tests/Makefile.in
+++ b/src/settings/tests/Makefile.in
@@ -143,6 +143,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -197,11 +199,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -212,6 +218,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -251,6 +258,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -316,6 +325,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_srcdir)/src/settings