about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-05-04 21:35:57 +0200
committerMichael Biebl <biebl@debian.org>2011-05-04 21:35:57 +0200
commit3241555aff5c969104e492501097f4cb8837bcca (patch)
tree6d15a02d02a9f1bfcda6075ae2b8c71537d8038d /src
parente1b66c145e71e7bc6a06845dd17788fb7b8e158e (diff)
parent9f806e97a24bba61417ae312fcc0da40914266fb (diff)
Merge commit 'upstream/0.8.999' into experimental
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in7
-rw-r--r--src/NetworkManagerUtils.c149
-rw-r--r--src/NetworkManagerUtils.h10
-rw-r--r--src/backends/Makefile.in7
-rw-r--r--src/bluez-manager/Makefile.am3
-rw-r--r--src/bluez-manager/Makefile.in10
-rw-r--r--src/dhcp-manager/Makefile.in7
-rw-r--r--src/dhcp-manager/tests/Makefile.in7
-rw-r--r--src/dns-manager/Makefile.in7
-rw-r--r--src/dns-manager/nm-dns-manager.c49
-rw-r--r--src/dns-manager/nm-dns-manager.h2
-rw-r--r--src/dnsmasq-manager/Makefile.in7
-rw-r--r--src/ip6-manager/Makefile.in7
-rw-r--r--src/ip6-manager/nm-ip6-manager.c19
-rw-r--r--src/logging/Makefile.in7
-rw-r--r--src/main.c133
-rw-r--r--src/modem-manager/Makefile.in7
-rw-r--r--src/modem-manager/nm-modem.c17
-rw-r--r--src/modem-manager/nm-modem.h1
-rw-r--r--src/nm-activation-request.c5
-rw-r--r--src/nm-active-connection.c8
-rw-r--r--src/nm-active-connection.h2
-rw-r--r--src/nm-device-wifi.c18
-rw-r--r--src/nm-device.c152
-rw-r--r--src/nm-manager.c263
-rw-r--r--src/nm-policy.c97
-rw-r--r--src/nm-session-monitor.c32
-rw-r--r--src/nm-system.c4
-rw-r--r--src/nm-udev-manager.c135
-rw-r--r--src/nm-wifi-ap-utils.c12
-rw-r--r--src/nm-wifi-ap.c96
-rw-r--r--src/nm-wifi-ap.h12
-rw-r--r--src/ppp-manager/Makefile.in7
-rw-r--r--src/ppp-manager/nm-ppp-manager.c33
-rw-r--r--src/ppp-manager/nm-ppp-manager.h2
-rw-r--r--src/ppp-manager/nm-pppd-plugin.c4
-rw-r--r--src/settings/Makefile.in7
-rw-r--r--src/settings/nm-default-wired-connection.c10
-rw-r--r--src/settings/nm-settings.c51
-rw-r--r--src/settings/plugins/Makefile.in7
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.in7
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c2
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c82
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.in7
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in12
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ctc-static12
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-112
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-214
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-311
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-411
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c11
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c855
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c86
-rw-r--r--src/settings/plugins/ifcfg-suse/Makefile.in7
-rw-r--r--src/settings/plugins/ifnet/Makefile.in7
-rw-r--r--src/settings/plugins/ifnet/tests/Makefile.in7
-rw-r--r--src/settings/plugins/ifupdown/Makefile.in7
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.in7
-rw-r--r--src/settings/plugins/keyfile/Makefile.in7
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.in7
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.in7
-rw-r--r--src/settings/tests/Makefile.in7
-rw-r--r--src/supplicant-manager/Makefile.in7
-rw-r--r--src/supplicant-manager/nm-supplicant-config.c8
-rw-r--r--src/supplicant-manager/nm-supplicant-settings-verify.c1
-rw-r--r--src/supplicant-manager/tests/Makefile.in7
-rw-r--r--src/tests/Makefile.in7
-rw-r--r--src/tests/test-wifi-ap-utils.c8
-rw-r--r--src/vpn-manager/Makefile.in7
-rw-r--r--src/vpn-manager/nm-vpn-connection-base.c5
-rw-r--r--src/vpn-manager/nm-vpn-connection.c15
-rw-r--r--src/vpn-manager/nm-vpn-connection.h2
-rw-r--r--src/vpn-manager/nm-vpn-manager.c4
-rw-r--r--src/vpn-manager/nm-vpn-manager.h2
-rw-r--r--src/vpn-manager/nm-vpn-service.c4
-rw-r--r--src/vpn-manager/nm-vpn-service.h2
-rw-r--r--src/wimax/Makefile.in7
79 files changed, 2235 insertions, 458 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 8e0bb40b..5d9567ed 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -262,6 +262,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -379,6 +383,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -400,6 +406,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 3981a1db..d069eca7 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.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) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
  */
 
@@ -374,6 +374,72 @@ nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting)
 }
 
 static void
+dump_object_to_props (GObject *object, GHashTable *hash)
+{
+	GParamSpec **pspecs;
+	guint len = 0, i;
+
+	pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &len);
+	for (i = 0; i < len; i++) {
+		value_hash_add_object_property (hash,
+		                                pspecs[i]->name,
+		                                object,
+		                                pspecs[i]->name,
+		                                pspecs[i]->value_type);
+	}
+	g_free (pspecs);
+}
+
+static void
+fill_device_props (NMDevice *device,
+                   GHashTable *dev_hash,
+                   GHashTable *ip4_hash,
+                   GHashTable *ip6_hash,
+                   GHashTable *dhcp4_hash,
+                   GHashTable *dhcp6_hash)
+{
+	NMIP4Config *ip4_config;
+	NMIP6Config *ip6_config;
+	NMDHCP4Config *dhcp4_config;
+	NMDHCP6Config *dhcp6_config;
+
+	/* If the action is for a VPN, send the VPN's IP interface instead of the device's */
+	value_hash_add_str (dev_hash, NMD_DEVICE_PROPS_IP_INTERFACE, nm_device_get_ip_iface (device));
+	value_hash_add_str (dev_hash, NMD_DEVICE_PROPS_INTERFACE, nm_device_get_iface (device));
+	value_hash_add_uint (dev_hash, NMD_DEVICE_PROPS_TYPE, nm_device_get_device_type (device));
+	value_hash_add_uint (dev_hash, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device));
+	value_hash_add_object_path (dev_hash, NMD_DEVICE_PROPS_PATH, nm_device_get_path (device));
+
+	ip4_config = nm_device_get_ip4_config (device);
+	if (ip4_config)
+		dump_object_to_props (G_OBJECT (ip4_config), ip4_hash);
+
+	ip6_config = nm_device_get_ip6_config (device);
+	if (ip6_config)
+		dump_object_to_props (G_OBJECT (ip6_config), ip6_hash);
+
+	dhcp4_config = nm_device_get_dhcp4_config (device);
+	if (dhcp4_config)
+		dump_object_to_props (G_OBJECT (dhcp4_config), dhcp4_hash);
+
+	dhcp6_config = nm_device_get_dhcp6_config (device);
+	if (dhcp6_config)
+		dump_object_to_props (G_OBJECT (dhcp6_config), dhcp6_hash);
+}
+
+static void
+fill_vpn_props (NMIP4Config *ip4_config,
+                NMIP6Config *ip6_config,
+                GHashTable *ip4_hash,
+                GHashTable *ip6_hash)
+{
+	if (ip4_config)
+		dump_object_to_props (G_OBJECT (ip4_config), ip4_hash);
+	if (ip6_config)
+		dump_object_to_props (G_OBJECT (ip6_config), ip6_hash);
+}
+
+static void
 dispatcher_done_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
 {
 	dbus_g_proxy_end_call (proxy, call, NULL, G_TYPE_INVALID);
@@ -384,7 +450,9 @@ void
 nm_utils_call_dispatcher (const char *action,
                           NMConnection *connection,
                           NMDevice *device,
-                          const char *vpn_iface)
+                          const char *vpn_iface,
+                          NMIP4Config *vpn_ip4_config,
+                          NMIP6Config *vpn_ip6_config)
 {
 	NMDBusManager *dbus_mgr;
 	DBusGProxy *proxy;
@@ -392,12 +460,21 @@ nm_utils_call_dispatcher (const char *action,
 	GHashTable *connection_hash;
 	GHashTable *connection_props;
 	GHashTable *device_props;
+	GHashTable *device_ip4_props;
+	GHashTable *device_ip6_props;
+	GHashTable *device_dhcp4_props;
+	GHashTable *device_dhcp6_props;
+	GHashTable *vpn_ip4_props;
+	GHashTable *vpn_ip6_props;
 
 	g_return_if_fail (action != NULL);
 
 	/* All actions except 'hostname' require a device */
-	if (strcmp (action, "hostname"))
+	if (strcmp (action, "hostname") != 0)
 		g_return_if_fail (NM_IS_DEVICE (device));
+	/* VPN actions require at least an IPv4 config (for now) */
+	if (strcmp (action, "vpn-up") == 0)
+		g_return_if_fail (vpn_ip4_config != NULL);
 
 	dbus_mgr = nm_dbus_manager_get ();
 	g_connection = nm_dbus_manager_get_connection (dbus_mgr);
@@ -426,25 +503,23 @@ nm_utils_call_dispatcher (const char *action,
 	}
 
 	device_props = value_hash_create ();
-
-	/* Hostname actions do not require a device */
-	if (strcmp (action, "hostname")) {
-		/* interface */
-		value_hash_add_str (device_props, NMD_DEVICE_PROPS_INTERFACE, nm_device_get_iface (device));
-
-		/* IP interface */
-		if (vpn_iface) {
-			value_hash_add_str (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, vpn_iface);
-		} else if (nm_device_get_ip_iface (device)) {
-			value_hash_add_str (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, nm_device_get_ip_iface (device));
-		}
-
-		/* type */
-		value_hash_add_uint (device_props, NMD_DEVICE_PROPS_TYPE, nm_device_get_device_type (device));
-
-		/* state */
-		value_hash_add_uint (device_props, NMD_DEVICE_PROPS_STATE, nm_device_get_state (device));
-		value_hash_add_object_path (device_props, NMD_DEVICE_PROPS_PATH, nm_device_get_path (device));
+	device_ip4_props = value_hash_create ();
+	device_ip6_props = value_hash_create ();
+	device_dhcp4_props = value_hash_create ();
+	device_dhcp6_props = value_hash_create ();
+	vpn_ip4_props = value_hash_create ();
+	vpn_ip6_props = value_hash_create ();
+
+	/* hostname actions only send the hostname */
+	if (strcmp (action, "hostname") != 0) {
+		fill_device_props (device,
+			               device_props,
+			               device_ip4_props,
+			               device_ip6_props,
+			               device_dhcp4_props,
+			               device_dhcp6_props);
+		if (vpn_iface)
+			fill_vpn_props (vpn_ip4_config, NULL, vpn_ip4_props, vpn_ip6_props);
 	}
 
 	/* Do a non-blocking call, but wait for the reply, because dbus-glib
@@ -455,17 +530,30 @@ nm_utils_call_dispatcher (const char *action,
 	 */
 	dbus_g_proxy_begin_call_with_timeout (proxy, "Action",
 	                                      dispatcher_done_cb,
-	                                      dbus_mgr,
+	                                      dbus_mgr,       /* automatically unref the dbus mgr when call is done */
 	                                      g_object_unref,
 	                                      5000,
 	                                      G_TYPE_STRING, action,
 	                                      DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, connection_hash,
 	                                      DBUS_TYPE_G_MAP_OF_VARIANT, connection_props,
 	                                      DBUS_TYPE_G_MAP_OF_VARIANT, device_props,
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, device_ip4_props,
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, device_ip6_props,
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp4_props,
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, device_dhcp6_props,
+	                                      G_TYPE_STRING, vpn_iface ? vpn_iface : "",
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip4_props,
+	                                      DBUS_TYPE_G_MAP_OF_VARIANT, vpn_ip6_props,
 	                                      G_TYPE_INVALID);
 	g_hash_table_destroy (connection_hash);
 	g_hash_table_destroy (connection_props);
 	g_hash_table_destroy (device_props);
+	g_hash_table_destroy (device_ip4_props);
+	g_hash_table_destroy (device_ip6_props);
+	g_hash_table_destroy (device_dhcp4_props);
+	g_hash_table_destroy (device_dhcp6_props);
+	g_hash_table_destroy (vpn_ip4_props);
+	g_hash_table_destroy (vpn_ip6_props);
 }
 
 gboolean
@@ -670,6 +758,21 @@ value_hash_add_bool (GHashTable *hash,
 	value_hash_add (hash, key, value);
 }
 
+void
+value_hash_add_object_property (GHashTable *hash,
+                                const char *key,
+                                GObject *object,
+                                const char *prop,
+                                GType val_type)
+{
+	GValue *value;
+
+	value = g_slice_new0 (GValue);
+	g_value_init (value, val_type);
+	g_object_get_property (object, prop, value);
+	value_hash_add (hash, key, value);
+}
+
 gboolean
 nm_utils_do_sysctl (const char *path, const char *value)
 {
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h
index 6f48a788..aaa267fb 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -45,7 +45,9 @@ void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *set
 void nm_utils_call_dispatcher (const char *action,
                                NMConnection *connection,
                                NMDevice *device,
-                               const char *vpn_iface);
+                               const char *vpn_iface,
+                               NMIP4Config *vpn_ip4_config,
+                               NMIP6Config *vpn_ip6_config);
 
 gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr);
 gboolean nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels);
@@ -72,6 +74,12 @@ void        value_hash_add_bool        (GHashTable *hash,
 					                    const char *key,
 					                    gboolean val);
 
+void        value_hash_add_object_property (GHashTable *hash,
+                                            const char *key,
+                                            GObject *object,
+                                            const char *prop,
+                                            GType val_type);
+
 gboolean nm_utils_do_sysctl (const char *path, const char *value);
 
 gboolean nm_utils_get_proc_sys_net_value (const char *path,
diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in
index db2b3753..a9ea3e80 100644
--- a/src/backends/Makefile.in
+++ b/src/backends/Makefile.in
@@ -155,6 +155,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -272,6 +276,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -293,6 +299,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/bluez-manager/Makefile.am b/src/bluez-manager/Makefile.am
index 6c199e8c..623c1060 100644
--- a/src/bluez-manager/Makefile.am
+++ b/src/bluez-manager/Makefile.am
@@ -4,8 +4,7 @@ INCLUDES = \
 	-I${top_srcdir}/libnm-util \
 	-I${top_srcdir}/src \
 	-I${top_srcdir}/src/logging \
-	-I${top_builddir}/marshallers \
-	-I$(top_srcdir)/src/nm-bluez-manager
+	-I${top_builddir}/marshallers
 
 noinst_LTLIBRARIES = libbluez-manager.la
 
diff --git a/src/bluez-manager/Makefile.in b/src/bluez-manager/Makefile.in
index 25aef190..1336b7ec 100644
--- a/src/bluez-manager/Makefile.in
+++ b/src/bluez-manager/Makefile.in
@@ -113,6 +113,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -230,6 +234,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -251,6 +257,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
@@ -304,8 +311,7 @@ INCLUDES = \
 	-I${top_srcdir}/libnm-util \
 	-I${top_srcdir}/src \
 	-I${top_srcdir}/src/logging \
-	-I${top_builddir}/marshallers \
-	-I$(top_srcdir)/src/nm-bluez-manager
+	-I${top_builddir}/marshallers
 
 noinst_LTLIBRARIES = libbluez-manager.la
 libbluez_manager_la_SOURCES = \
diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in
index 98589db0..dd557056 100644
--- a/src/dhcp-manager/Makefile.in
+++ b/src/dhcp-manager/Makefile.in
@@ -161,6 +161,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -278,6 +282,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -299,6 +305,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in
index ee6312a7..7e875055 100644
--- a/src/dhcp-manager/tests/Makefile.in
+++ b/src/dhcp-manager/tests/Makefile.in
@@ -111,6 +111,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -228,6 +232,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -249,6 +255,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in
index c8bf5100..4937a601 100644
--- a/src/dns-manager/Makefile.in
+++ b/src/dns-manager/Makefile.in
@@ -113,6 +113,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -230,6 +234,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -251,6 +257,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 32800d0b..fc582327 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -61,7 +61,9 @@ G_DEFINE_TYPE(NMDnsManager, nm_dns_manager, G_TYPE_OBJECT)
                                        NM_TYPE_DNS_MANAGER, \
                                        NMDnsManagerPrivate))
 
-struct NMDnsManagerPrivate {
+typedef struct {
+	gboolean disposed;
+
 	NMIP4Config *ip4_vpn_config;
 	NMIP4Config *ip4_device_config;
 	NMIP6Config *ip6_vpn_config;
@@ -84,7 +86,7 @@ struct NMDnsManagerPrivate {
 	 * associated with a network interface (like hostnames).
 	 */
 	char *last_iface;
-};
+} NMDnsManagerPrivate;
 
 
 typedef struct {
@@ -1074,18 +1076,46 @@ nm_dns_manager_init (NMDnsManager *mgr)
 }
 
 static void
-nm_dns_manager_finalize (GObject *object)
+dispose (GObject *object)
+{
+	NMDnsManager *self = NM_DNS_MANAGER (object);
+	NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
+	GError *error = NULL;
+
+	if (priv->disposed == FALSE) {
+		priv->disposed = TRUE;
+
+		g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
+		g_slist_free (priv->plugins);
+		priv->plugins = NULL;
+
+		/* If we're quitting leave a valid resolv.conf in place, not one
+		 * pointing to 127.0.0.1 if any plugins were active.  Thus update
+		 * DNS after disposing of all plugins.
+		 */
+		if (!update_dns (self, priv->last_iface, TRUE, &error)) {
+			nm_log_warn (LOGD_DNS, "could not commit DNS changes on shutdown: (%d) %s",
+					     error ? error->code : -1,
+					     error && error->message ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+
+		g_slist_foreach (priv->configs, (GFunc) g_object_unref, NULL);
+		g_slist_free (priv->configs);
+		priv->configs = NULL;
+	}
+
+	G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
 {
 	NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
 
-	g_slist_foreach (priv->configs, (GFunc) g_object_unref, NULL);
-	g_slist_free (priv->configs);
 	g_free (priv->hostname);
 	g_free (priv->last_iface);
 
-	g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
-	g_slist_free (priv->plugins);
-
 	G_OBJECT_CLASS (nm_dns_manager_parent_class)->finalize (object);
 }
 
@@ -1094,7 +1124,8 @@ nm_dns_manager_class_init (NMDnsManagerClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-	object_class->finalize = nm_dns_manager_finalize;
+	object_class->dispose = dispose;
+	object_class->finalize = finalize;
 
 	g_type_class_add_private (object_class, sizeof (NMDnsManagerPrivate));
 }
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index 66ee5940..25d2a981 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -54,8 +54,6 @@ G_BEGIN_DECLS
 #define NM_IS_DNS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DNS_MANAGER))
 #define NM_DNS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DNS_MANAGER, NMDnsManagerClass)) 
 
-typedef struct NMDnsManagerPrivate NMDnsManagerPrivate;
-
 typedef struct {
 	GObject parent;
 } NMDnsManager;
diff --git a/src/dnsmasq-manager/Makefile.in b/src/dnsmasq-manager/Makefile.in
index 7ef4efe7..89f55e5e 100644
--- a/src/dnsmasq-manager/Makefile.in
+++ b/src/dnsmasq-manager/Makefile.in
@@ -110,6 +110,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -227,6 +231,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -248,6 +254,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in
index 7d001ce5..344ca0ea 100644
--- a/src/ip6-manager/Makefile.in
+++ b/src/ip6-manager/Makefile.in
@@ -110,6 +110,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -227,6 +231,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -248,6 +254,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c
index 0eb40302..4a5dee58 100644
--- a/src/ip6-manager/nm-ip6-manager.c
+++ b/src/ip6-manager/nm-ip6-manager.c
@@ -30,7 +30,6 @@
 #include "NetworkManagerUtils.h"
 #include "nm-marshal.h"
 #include "nm-logging.h"
-#include "nm-system.h"
 
 /* Pre-DHCP addrconf timeout, in seconds */
 #define NM_IP6_TIMEOUT 20
@@ -261,7 +260,7 @@ static gboolean
 rdnss_expired (gpointer user_data)
 {
 	NMIP6Device *device = user_data;
-	CallbackInfo info = { device, IP6_DHCP_OPT_NONE };
+	CallbackInfo info = { device, IP6_DHCP_OPT_NONE, FALSE };
 
 	nm_log_dbg (LOGD_IP6, "(%s): IPv6 RDNSS information expired", device->iface);
 
@@ -308,9 +307,9 @@ set_rdnss_timeout (NMIP6Device *device)
 	}
 
 	if (expires) {
-		device->rdnss_timeout_id = g_timeout_add_seconds (expires - now,
-														  rdnss_expired,
-														  device);
+		device->rdnss_timeout_id = g_timeout_add_seconds (MIN (expires - now, G_MAXUINT32 - 1),
+		                                                  rdnss_expired,
+		                                                  device);
 	}
 }
 
@@ -363,7 +362,7 @@ set_dnssl_timeout (NMIP6Device *device)
 	}
 
 	if (expires) {
-		device->dnssl_timeout_id = g_timeout_add_seconds (expires - now,
+		device->dnssl_timeout_id = g_timeout_add_seconds (MIN (expires - now, G_MAXUINT32 - 1),
 		                                                  dnssl_expired,
 		                                                  device);
 	}
@@ -689,9 +688,12 @@ process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt)
 	for (addr = (struct in6_addr *) (rdnss_opt + 1); opt_len >= 2; addr++, opt_len -= 2) {
 		char buf[INET6_ADDRSTRLEN + 1];
 
-		if (!inet_ntop (AF_INET6, addr, buf, sizeof (buf)))
-			strcpy(buf, "[invalid]");
+		if (!inet_ntop (AF_INET6, addr, buf, sizeof (buf))) {
+			nm_log_warn (LOGD_IP6, "(%s): received invalid RA-provided nameserver", device->iface);
+			continue;
+		}
 
+		/* Update the cached timeout if we already saw this server */
 		for (i = 0; i < device->rdnss_servers->len; i++) {
 			cur_server = &(g_array_index (device->rdnss_servers, NMIP6RDNSS, i));
 
@@ -834,6 +836,7 @@ process_nduseropt_dnssl (NMIP6Device *device, struct nd_opt_hdr *opt)
 		if (domain_str[0] == '\0')
 			continue;
 
+		/* Update cached domain information if we've seen this domain before */
 		for (i = 0; i < device->dnssl_domains->len; i++) {
 			cur_domain = &(g_array_index (device->dnssl_domains, NMIP6DNSSL, i));
 
diff --git a/src/logging/Makefile.in b/src/logging/Makefile.in
index 0809dc71..a85578d9 100644
--- a/src/logging/Makefile.in
+++ b/src/logging/Makefile.in
@@ -107,6 +107,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -224,6 +228,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -245,6 +251,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/main.c b/src/main.c
index 39e03de2..328c253d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -65,6 +65,7 @@
  */
 static NMManager *manager = NULL;
 static GMainLoop *main_loop = NULL;
+static int quit_pipe[2] = { -1, -1 };
 
 typedef struct {
 	time_t time;
@@ -145,69 +146,80 @@ static gboolean quit_early = FALSE;
 static void
 nm_signal_handler (int signo)
 {
-	static int in_fatal = 0;
+	static int in_fatal = 0, x;
 
 	/* avoid loops */
 	if (in_fatal > 0)
 		return;
 	++in_fatal;
 
-	switch (signo)
-	{
-		case SIGSEGV:
-		case SIGBUS:
-		case SIGILL:
-		case SIGABRT:
-			nm_log_warn (LOGD_CORE, "caught signal %d. Generating backtrace...", signo);
-			nm_logging_backtrace ();
-			exit (1);
-			break;
-
-		case SIGFPE:
-		case SIGPIPE:
-			/* let the fatal signals interrupt us */
-			--in_fatal;
-
-			nm_log_warn (LOGD_CORE, "caught signal %d, shutting down abnormally. Generating backtrace...", signo);
-			nm_logging_backtrace ();
-			g_main_loop_quit (main_loop);
-			break;
-
-		case SIGINT:
-		case SIGTERM:
-			/* let the fatal signals interrupt us */
-			--in_fatal;
-
-			nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo);
-			quit_early = TRUE;
-			g_main_loop_quit (main_loop);
-			break;
-
-		case SIGHUP:
-			--in_fatal;
-			/* FIXME:
-			 * Reread config stuff like system config files, VPN service files, etc
-			 */
-			break;
-
-		case SIGUSR1:
-			--in_fatal;
-			/* FIXME:
-			 * Play with log levels or something
-			 */
-			break;
-
-		default:
-			signal (signo, nm_signal_handler);
-			break;
+	switch (signo) {
+	case SIGSEGV:
+	case SIGBUS:
+	case SIGILL:
+	case SIGABRT:
+		nm_log_warn (LOGD_CORE, "caught signal %d. Generating backtrace...", signo);
+		nm_logging_backtrace ();
+		exit (1);
+		break;
+	case SIGFPE:
+	case SIGPIPE:
+		/* let the fatal signals interrupt us */
+		--in_fatal;
+		nm_log_warn (LOGD_CORE, "caught signal %d, shutting down abnormally. Generating backtrace...", signo);
+		nm_logging_backtrace ();
+		x = write (quit_pipe[1], "X", 1);
+		break;
+	case SIGINT:
+	case SIGTERM:
+		/* let the fatal signals interrupt us */
+		--in_fatal;
+		nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo);
+		quit_early = TRUE;
+		x = write (quit_pipe[1], "X", 1);
+		break;
+	case SIGHUP:
+		--in_fatal;
+		/* Reread config stuff like system config files, VPN service files, etc */
+		break;
+	case SIGUSR1:
+		--in_fatal;
+		/* Play with log levels or something */
+		break;
+	default:
+		signal (signo, nm_signal_handler);
+		break;
 	}
 }
 
+static gboolean
+quit_watch (GIOChannel *src, GIOCondition condition, gpointer user_data)
+{
+
+	if (condition & G_IO_IN) {
+		nm_log_warn (LOGD_CORE, "quit request received, terminating...");
+		g_main_loop_quit (main_loop);
+	}
+
+	return FALSE;
+}
+
 static void
 setup_signals (void)
 {
 	struct sigaction action;
 	sigset_t mask;
+	GIOChannel *quit_channel;
+
+	/* Set up our quit pipe */
+	if (pipe (quit_pipe) < 0) {
+		fprintf (stderr, "Failed to initialze SIGTERM pipe: %d", errno);
+		exit (1);
+	}
+	fcntl (quit_pipe[1], F_SETFL, O_NONBLOCK | fcntl (quit_pipe[1], F_GETFL));
+
+	quit_channel = g_io_channel_unix_new (quit_pipe[0]);
+	g_io_add_watch_full (quit_channel, G_PRIORITY_HIGH, G_IO_IN | G_IO_ERR, quit_watch, NULL, NULL);
 
 	sigemptyset (&mask);
 	action.sa_handler = nm_signal_handler;
@@ -462,7 +474,7 @@ main (int argc, char *argv[])
 	char *log_level = NULL, *log_domains = NULL;
 	char **dns = NULL;
 	gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
-	gboolean success;
+	gboolean success, show_version = FALSE;
 	NMPolicy *policy = NULL;
 	NMVPNManager *vpn_manager = NULL;
 	NMDnsManager *dns_mgr = NULL;
@@ -475,6 +487,7 @@ main (int argc, char *argv[])
 	char *cfg_log_level = NULL, *cfg_log_domains = NULL;
 
 	GOptionEntry options[] = {
+		{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version, "Print NetworkManager version and exit", NULL },
 		{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL },
 		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
 		{ "pid-file", 0, 0, G_OPTION_ARG_FILENAME, &pidfile, "Specify the location of a PID file", "filename" },
@@ -483,16 +496,14 @@ main (int argc, char *argv[])
 		{ "plugins", 0, 0, G_OPTION_ARG_STRING, &plugins, "List of plugins separated by ','", "plugin1,plugin2" },
 		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &log_level, "Log level: one of [ERR, WARN, INFO, DEBUG]", "INFO" },
 		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &log_domains,
-		        "Log domains separated by ',': any combination of [NONE,HW,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,USER_SET,SYS_SET,SUSPEND,CORE,DEVICE,OLPC]",
+		        "Log domains separated by ',': any combination of\n"
+		        "                                          [NONE,HW,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,\n"
+		        "                                           WIFI_SCAN,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,\n"
+		        "                                           AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,WIMAX]",
 		        "HW,RFKILL,WIFI" },
 		{NULL}
 	};
 
-	if (getuid () != 0) {
-		fprintf (stderr, "You must be root to run NetworkManager!\n");
-		exit (1);
-	}
-
 	if (!g_module_supported ()) {
 		fprintf (stderr, "GModules are not supported on your platform!\n");
 		exit (1);
@@ -520,6 +531,16 @@ main (int argc, char *argv[])
 		exit (1);
 	}
 
+	if (show_version) {
+		fprintf (stdout, NM_DIST_VERSION "\n");
+		exit (0);
+	}
+
+	if (getuid () != 0) {
+		fprintf (stderr, "You must be root to run NetworkManager!\n");
+		exit (1);
+	}
+
 	/* Make GIO ignore the remote VFS service; otherwise it tries to use the
 	 * session bus to contact the remote service, and NM shouldn't ever be
 	 * talking on the session bus.  See rh #588745
diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in
index ffe360bf..66f7c1bc 100644
--- a/src/modem-manager/Makefile.in
+++ b/src/modem-manager/Makefile.in
@@ -113,6 +113,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -230,6 +234,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -251,6 +257,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 449370eb..33f10789 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -86,14 +86,6 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-NMPPPManager *
-nm_modem_get_ppp_manager (NMModem *self)
-{
-	g_return_val_if_fail (NM_IS_MODEM (self), NULL);
-
-	return NM_MODEM_GET_PRIVATE (self)->ppp_manager;
-}
-
 gboolean
 nm_modem_get_mm_enabled (NMModem *self)
 {
@@ -666,12 +658,13 @@ real_deactivate (NMModem *self, NMDevice *device)
 
 	priv->in_bytes = priv->out_bytes = 0;
 
+	if (priv->ppp_manager) {
+		g_object_unref (priv->ppp_manager);
+		priv->ppp_manager = NULL;
+	}
+
 	switch (priv->ip_method) {
 	case MM_MODEM_IP_METHOD_PPP:
-		if (priv->ppp_manager) {
-			g_object_unref (priv->ppp_manager);
-			priv->ppp_manager = NULL;
-		}
 		break;
 	case MM_MODEM_IP_METHOD_STATIC:
 	case MM_MODEM_IP_METHOD_DHCP:
diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h
index a46a198c..bad19b04 100644
--- a/src/modem-manager/nm-modem.h
+++ b/src/modem-manager/nm-modem.h
@@ -99,7 +99,6 @@ GType nm_modem_get_type (void);
 
 /* Protected */
 
-NMPPPManager *nm_modem_get_ppp_manager (NMModem *modem);
 DBusGProxy *  nm_modem_get_proxy       (NMModem *modem, const char *interface);
 const char *  nm_modem_get_iface       (NMModem *modem);
 const char *  nm_modem_get_path        (NMModem *modem);
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c
index fb42de68..d3eb920d 100644
--- a/src/nm-activation-request.c
+++ b/src/nm-activation-request.c
@@ -84,6 +84,7 @@ typedef struct {
 enum {
 	PROP_0,
 	PROP_CONNECTION,
+	PROP_UUID,
 	PROP_SPECIFIC_OBJECT,
 	PROP_DEVICES,
 	PROP_STATE,
@@ -531,6 +532,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CONNECTION:
 		g_value_set_boxed (value, nm_connection_get_path (priv->connection));
 		break;
+	case PROP_UUID:
+		g_value_set_string (value, nm_connection_get_uuid (priv->connection));
+		break;
 	case PROP_SPECIFIC_OBJECT:
 		if (priv->specific_object)
 			g_value_set_boxed (value, priv->specific_object);
@@ -622,6 +626,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
 	/* properties */
     nm_active_connection_install_properties (object_class,
                                              PROP_CONNECTION,
+                                             PROP_UUID,
                                              PROP_SPECIFIC_OBJECT,
                                              PROP_DEVICES,
                                              PROP_STATE,
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 2f9a8f97..ae2afb07 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -35,6 +35,7 @@ nm_active_connection_get_next_object_path (void)
 void
 nm_active_connection_install_properties (GObjectClass *object_class,
                                          guint prop_connection,
+                                         guint prop_uuid,
                                          guint prop_specific_object,
                                          guint prop_devices,
                                          guint prop_state,
@@ -49,6 +50,13 @@ nm_active_connection_install_properties (GObjectClass *object_class,
 		                    DBUS_TYPE_G_OBJECT_PATH,
 		                    G_PARAM_READABLE));
 
+	g_object_class_install_property (object_class, prop_uuid,
+		g_param_spec_string (NM_ACTIVE_CONNECTION_UUID,
+		                     "Connection UUID",
+		                     "Connection UUID",
+		                     NULL,
+		                     G_PARAM_READABLE));
+
 	g_object_class_install_property (object_class, prop_specific_object,
 		g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT,
 		                    "Specific object",
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index d39fcbd7..4bd8c78e 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -25,6 +25,7 @@
 #include "nm-connection.h"
 
 #define NM_ACTIVE_CONNECTION_CONNECTION "connection"
+#define NM_ACTIVE_CONNECTION_UUID "uuid"
 #define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object"
 #define NM_ACTIVE_CONNECTION_DEVICES "devices"
 #define NM_ACTIVE_CONNECTION_STATE "state"
@@ -36,6 +37,7 @@ char *nm_active_connection_get_next_object_path (void);
 
 void nm_active_connection_install_properties (GObjectClass *object_class,
                                               guint prop_connection,
+                                              guint prop_uuid,
                                               guint prop_specific_object,
                                               guint prop_devices,
                                               guint prop_state,
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 626c2c0d..9258f77c 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -1390,9 +1390,9 @@ real_complete_connection (NMDevice *device,
 	const GByteArray *ssid = NULL;
 	GSList *iter;
 
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_wifi = nm_connection_get_setting_wireless (connection);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 
 	if (!specific_object) {
 		/* If not given a specific object, we need at minimum an SSID */
@@ -1430,8 +1430,10 @@ real_complete_connection (NMDevice *device,
 			gboolean valid;
 
 			settings = g_slist_prepend (settings, s_wifi);
-			settings = g_slist_prepend (settings, s_wsec);
-			settings = g_slist_prepend (settings, s_8021x);
+			if (s_wsec)
+				settings = g_slist_prepend (settings, s_wsec);
+			if (s_8021x)
+				settings = g_slist_prepend (settings, s_8021x);
 			valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error);
 			g_slist_free (settings);
 			if (!valid)
@@ -1449,6 +1451,12 @@ real_complete_connection (NMDevice *device,
 		}
 	}
 
+	/* Add a wifi setting if one doesn't exist yet */
+	if (!s_wifi) {
+		s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+		nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+	}
+
 	if (ap) {
 		ssid = nm_ap_get_ssid (ap);
 
diff --git a/src/nm-device.c b/src/nm-device.c
index 9b182c4d..ebd8cdb9 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -1384,7 +1384,7 @@ handle_dhcp_lease_change (NMDevice *device, gboolean ipv6)
 			nm_dhcp_client_foreach_option (priv->dhcp6_client,
 			                               dhcp6_add_option_cb,
 			                               priv->dhcp6_config);
-			nm_utils_call_dispatcher ("dhcp6-change", connection, device, NULL);
+			nm_utils_call_dispatcher ("dhcp6-change", connection, device, NULL, NULL, NULL);
 		} else {
 			nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.",
 			             nm_device_get_ip_iface (device));
@@ -1409,7 +1409,7 @@ handle_dhcp_lease_change (NMDevice *device, gboolean ipv6)
 			nm_dhcp_client_foreach_option (priv->dhcp4_client,
 			                               dhcp4_add_option_cb,
 			                               priv->dhcp4_config);
-			nm_utils_call_dispatcher ("dhcp4-change", connection, device, NULL);
+			nm_utils_call_dispatcher ("dhcp4-change", connection, device, NULL, NULL, NULL);
 		} else {
 			nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv4 config in response to DHCP event.",
 			             nm_device_get_ip_iface (device));
@@ -1680,7 +1680,7 @@ dhcp6_start (NMDevice *self,
 	 */
 	err = nm_system_set_ip6_route (priv->ip_iface ? priv->ip_ifindex : priv->ifindex,
 	                               &dest, 8, NULL, 256, 0, RTPROT_BOOT, RT_TABLE_LOCAL, NULL);
-	if (err) {
+	if (err && (nl_get_errno () != EEXIST)) {
 		nm_log_err (LOGD_DEVICE | LOGD_IP6,
 		            "(%s): failed to add IPv6 multicast route: %s",
 		            priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror ());
@@ -3692,6 +3692,138 @@ nm_device_get_firmware_missing (NMDevice *self)
 	return NM_DEVICE_GET_PRIVATE (self)->firmware_missing;
 }
 
+static const char *
+state_to_string (NMDeviceState state)
+{
+	switch (state) {
+	case NM_DEVICE_STATE_UNMANAGED:
+		return "unmanaged";
+	case NM_DEVICE_STATE_UNAVAILABLE:
+		return "unavailable";
+	case NM_DEVICE_STATE_DISCONNECTED:
+		return "disconnected";
+	case NM_DEVICE_STATE_PREPARE:
+		return "prepare";
+	case NM_DEVICE_STATE_CONFIG:
+		return "config";
+	case NM_DEVICE_STATE_NEED_AUTH:
+		return "need-auth";
+	case NM_DEVICE_STATE_IP_CONFIG:
+		return "ip-config";
+	case NM_DEVICE_STATE_IP_CHECK:
+		return "ip-check";
+	case NM_DEVICE_STATE_SECONDARIES:
+		return "secondaries";
+	case NM_DEVICE_STATE_ACTIVATED:
+		return "activated";
+	case NM_DEVICE_STATE_DEACTIVATING:
+		return "deactivating";
+	case NM_DEVICE_STATE_FAILED:
+		return "failed";
+	default:
+		break;
+	}
+	return "unknown";
+}
+
+static const char *
+reason_to_string (NMDeviceStateReason reason)
+{
+	switch (reason) {
+	case NM_DEVICE_STATE_REASON_NONE:
+		return "none";
+	case NM_DEVICE_STATE_REASON_NOW_MANAGED:
+		return "managed";
+	case NM_DEVICE_STATE_REASON_NOW_UNMANAGED:
+		return "unmanaged";
+	case NM_DEVICE_STATE_REASON_CONFIG_FAILED:
+		return "config-failed";
+	case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE:
+		return "ip-config-unavailable";
+	case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED:
+		return "ip-config-expired";
+	case NM_DEVICE_STATE_REASON_NO_SECRETS:
+		return "no-secrets";
+	case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT:
+		return "supplicant-disconnect";
+	case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED:
+		return "supplicant-config-failed";
+	case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED:
+		return "supplicant-failed";
+	case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT:
+		return "supplicant-timeout";
+	case NM_DEVICE_STATE_REASON_PPP_START_FAILED:
+		return "ppp-start-failed";
+	case NM_DEVICE_STATE_REASON_PPP_DISCONNECT:
+		return "ppp-disconnect";
+	case NM_DEVICE_STATE_REASON_PPP_FAILED:
+		return "ppp-failed";
+	case NM_DEVICE_STATE_REASON_DHCP_START_FAILED:
+		return "dhcp-start-failed";
+	case NM_DEVICE_STATE_REASON_DHCP_ERROR:
+		return "dhcp-error";
+	case NM_DEVICE_STATE_REASON_DHCP_FAILED:
+		return "dhcp-failed";
+	case NM_DEVICE_STATE_REASON_SHARED_START_FAILED:
+		return "sharing-start-failed";
+	case NM_DEVICE_STATE_REASON_SHARED_FAILED:
+		return "sharing-failed";
+	case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED:
+		return "autoip-start-failed";
+	case NM_DEVICE_STATE_REASON_AUTOIP_ERROR:
+		return "autoip-error";
+	case NM_DEVICE_STATE_REASON_AUTOIP_FAILED:
+		return "autoip-failed";
+	case NM_DEVICE_STATE_REASON_MODEM_BUSY:
+		return "modem-busy";
+	case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE:
+		return "modem-no-dialtone";
+	case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER:
+		return "modem-no-carrier";
+	case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT:
+		return "modem-dial-timeout";
+	case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED:
+		return "modem-dial-failed";
+	case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED:
+		return "modem-init-failed";
+	case NM_DEVICE_STATE_REASON_GSM_APN_FAILED:
+		return "gsm-apn-failed";
+	case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING:
+		return "gsm-registration-idle";
+	case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED:
+		return "gsm-registration-denied";
+	case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT:
+		return "gsm-registration-timeout";
+	case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED:
+		return "gsm-registration-failed";
+	case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED:
+		return "gsm-pin-check-failed";
+	case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING:
+		return "firmware-missing";
+	case NM_DEVICE_STATE_REASON_REMOVED:
+		return "removed";
+	case NM_DEVICE_STATE_REASON_SLEEPING:
+		return "sleeping";
+	case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED:
+		return "connection-removed";
+	case NM_DEVICE_STATE_REASON_USER_REQUESTED:
+		return "user-requested";
+	case NM_DEVICE_STATE_REASON_CARRIER:
+		return "carrier-chagned";
+	case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED:
+		return "connection-assumed";
+	case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE:
+		return "supplicant-available";
+	case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND:
+		return "modem-not-found";
+	case NM_DEVICE_STATE_REASON_BT_FAILED:
+		return "bluetooth-failed";
+	default:
+		break;
+	}
+	return "unknown";
+}
+
 void
 nm_device_state_changed (NMDevice *device,
                          NMDeviceState state,
@@ -3715,8 +3847,14 @@ nm_device_state_changed (NMDevice *device,
 	old_state = priv->state;
 	priv->state = state;
 
-	nm_log_info (LOGD_DEVICE, "(%s): device state change: %d -> %d (reason %d)",
-	             nm_device_get_iface (device), old_state, state, reason);
+	nm_log_info (LOGD_DEVICE, "(%s): device state change: %s -> %s (reason '%s') [%d %d %d]",
+	             nm_device_get_iface (device),
+	             state_to_string (old_state),
+	             state_to_string (state),
+	             reason_to_string (reason),
+	             old_state,
+	             state,
+	             reason);
 
 	/* Clear any delayed transitions */
 	delayed_transitions_clear (device);
@@ -3781,7 +3919,7 @@ nm_device_state_changed (NMDevice *device,
 	case NM_DEVICE_STATE_ACTIVATED:
 		nm_log_info (LOGD_DEVICE, "Activation (%s) successful, device activated.",
 		             nm_device_get_iface (device));
-		nm_utils_call_dispatcher ("up", nm_act_request_get_connection (req), device, NULL);
+		nm_utils_call_dispatcher ("up", nm_act_request_get_connection (req), device, NULL, NULL, NULL);
 		break;
 	case NM_DEVICE_STATE_FAILED:
 		nm_log_warn (LOGD_DEVICE, "Activation (%s) failed.", nm_device_get_iface (device));
@@ -3796,7 +3934,7 @@ nm_device_state_changed (NMDevice *device,
 	}
 
 	if (old_state == NM_DEVICE_STATE_ACTIVATED)
-		nm_utils_call_dispatcher ("down", nm_act_request_get_connection (req), device, NULL);
+		nm_utils_call_dispatcher ("down", nm_act_request_get_connection (req), device, NULL, NULL, NULL);
 
 	/* Dispose of the cached activation request */
 	if (req)
diff --git a/src/nm-manager.c b/src/nm-manager.c
index aad65088..568ff2ae 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -22,6 +22,9 @@
 #include <config.h>
 
 #include <netinet/ether.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
 #include <string.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
@@ -65,7 +68,15 @@
 
 #define UPOWER_DBUS_SERVICE "org.freedesktop.UPower"
 
-static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err);
+static gboolean impl_manager_get_devices (NMManager *manager,
+                                          GPtrArray **devices,
+                                          GError **err);
+
+static gboolean impl_manager_get_device_by_ip_iface (NMManager *self,
+                                                     const char *iface,
+                                                     char **out_object_path,
+                                                     GError **error);
+
 static void impl_manager_activate_connection (NMManager *manager,
                                               const char *connection_path,
                                               const char *device_path,
@@ -140,7 +151,7 @@ static const char *internal_activate_device (NMManager *manager,
                                              gboolean assumed,
                                              GError **error);
 
-static NMDevice *find_device_by_iface (NMManager *self, const gchar *iface);
+static NMDevice *find_device_by_ip_iface (NMManager *self, const gchar *iface);
 
 static GSList * remove_one_device (NMManager *manager,
                                    GSList *list,
@@ -186,6 +197,7 @@ struct PendingActivation {
 
 typedef struct {
 	gboolean user_enabled;
+	gboolean daemon_enabled;
 	gboolean sw_enabled;
 	gboolean hw_enabled;
 	RfKillType rtype;
@@ -194,6 +206,7 @@ typedef struct {
 	const char *prop;
 	const char *hw_prop;
 	RfKillState (*other_enabled_func) (NMManager *);
+	RfKillState (*daemon_enabled_func) (NMManager *);
 } RadioState;
 
 typedef struct {
@@ -403,7 +416,7 @@ modem_added (NMModemManager *modem_manager,
 
 	ip_iface = nm_modem_get_iface (modem);
 
-	replace_device = find_device_by_iface (NM_MANAGER (user_data), ip_iface);
+	replace_device = find_device_by_ip_iface (NM_MANAGER (user_data), ip_iface);
 	if (replace_device) {
 		priv->devices = remove_one_device (NM_MANAGER (user_data),
 		                                   priv->devices,
@@ -860,7 +873,6 @@ static GPtrArray *
 get_active_connections (NMManager *manager, NMConnection *filter)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-	NMVPNManager *vpn_manager;
 	GPtrArray *active;
 	GSList *iter;
 
@@ -882,9 +894,7 @@ get_active_connections (NMManager *manager, NMConnection *filter)
 	}
 
 	/* Add active VPN connections */
-	vpn_manager = nm_vpn_manager_get ();
-	nm_vpn_manager_add_active_connections (vpn_manager, filter, active);
-	g_object_unref (vpn_manager);
+	nm_vpn_manager_add_active_connections (priv->vpn_manager, filter, active);
 
 	return active;
 }
@@ -1000,21 +1010,31 @@ write_value_to_state_file (const char *filename,
 }
 
 static gboolean
-radio_enabled_for_rstate (RadioState *rstate)
+radio_enabled_for_rstate (RadioState *rstate, gboolean check_changeable)
 {
-	return rstate->user_enabled && rstate->sw_enabled && rstate->hw_enabled;
+	gboolean enabled;
+
+	enabled = rstate->user_enabled && rstate->hw_enabled;
+	if (check_changeable) {
+		enabled &= rstate->sw_enabled;
+		if (rstate->daemon_enabled_func)
+			enabled &= rstate->daemon_enabled;
+	}
+	return enabled;
 }
 
 static gboolean
-radio_enabled_for_type (NMManager *self, RfKillType rtype)
+radio_enabled_for_type (NMManager *self, RfKillType rtype, gboolean check_changeable)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 
-	return radio_enabled_for_rstate (&priv->radio_states[rtype]);
+	return radio_enabled_for_rstate (&priv->radio_states[rtype], check_changeable);
 }
 
 static void
-manager_update_radio_enabled (NMManager *self, RadioState *rstate)
+manager_update_radio_enabled (NMManager *self,
+                              RadioState *rstate,
+                              gboolean enabled)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	GSList *iter;
@@ -1032,7 +1052,6 @@ manager_update_radio_enabled (NMManager *self, RadioState *rstate)
 	/* enable/disable wireless devices as required */
 	for (iter = priv->devices; iter; iter = iter->next) {
 		RfKillType devtype = RFKILL_TYPE_UNKNOWN;
-		gboolean enabled = radio_enabled_for_rstate (rstate);
 
 		g_object_get (G_OBJECT (iter->data), NM_DEVICE_INTERFACE_RFKILL_TYPE, &devtype, NULL);
 		if (devtype == rstate->rtype) {
@@ -1174,9 +1193,9 @@ manager_rfkill_update_one_type (NMManager *self,
 	RfKillState other_state = RFKILL_UNBLOCKED;
 	RfKillState composite;
 	gboolean old_enabled, new_enabled, old_rfkilled, new_rfkilled;
-	gboolean old_hwe;
+	gboolean old_hwe, old_daemon_enabled = FALSE;
 
-	old_enabled = radio_enabled_for_rstate (rstate);
+	old_enabled = radio_enabled_for_rstate (rstate, TRUE);
 	old_rfkilled = rstate->hw_enabled && rstate->sw_enabled;
 	old_hwe = rstate->hw_enabled;
 
@@ -1195,9 +1214,26 @@ manager_rfkill_update_one_type (NMManager *self,
 
 	update_rstate_from_rfkill (rstate, composite);
 
+	/* If the device has a management daemon that can affect enabled state, check that now */
+	if (rstate->daemon_enabled_func) {
+		old_daemon_enabled = rstate->daemon_enabled;
+		rstate->daemon_enabled = (rstate->daemon_enabled_func (self) == RFKILL_UNBLOCKED);
+		if (old_daemon_enabled != rstate->daemon_enabled) {
+			nm_log_info (LOGD_RFKILL, "%s now %s by management service",
+				         rstate->desc,
+				         rstate->daemon_enabled ? "enabled" : "disabled");
+		}
+	}
+
+	/* Print out all states affecting device enablement */
 	if (rstate->desc) {
-		nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
-		            rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
+		if (rstate->daemon_enabled_func) {
+			nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d daemon-enabled %d",
+			            rstate->desc, rstate->hw_enabled, rstate->sw_enabled, rstate->daemon_enabled);
+		} else {
+			nm_log_dbg (LOGD_RFKILL, "%s hw-enabled %d sw-enabled %d",
+			            rstate->desc, rstate->hw_enabled, rstate->sw_enabled);
+		}
 	}
 
 	/* Log new killswitch state */
@@ -1214,10 +1250,14 @@ manager_rfkill_update_one_type (NMManager *self,
 			g_object_notify (G_OBJECT (self), rstate->hw_prop);
 	}
 
-	/* And finally update the actual device radio state itself */
-	new_enabled = radio_enabled_for_rstate (rstate);
+	/* And finally update the actual device radio state itself; respect the
+	 * daemon state here because this is never called from user-triggered
+	 * radio changes and we only want to ignore the daemon enabled state when
+	 * handling user radio change requests.
+	 */
+	new_enabled = radio_enabled_for_rstate (rstate, TRUE);
 	if (new_enabled != old_enabled)
-		manager_update_radio_enabled (self, rstate);
+		manager_update_radio_enabled (self, rstate, new_enabled);
 }
 
 static void
@@ -1226,14 +1266,13 @@ nm_manager_rfkill_update (NMManager *self, RfKillType rtype)
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	guint i;
 
-	if (rtype != RFKILL_TYPE_UNKNOWN) {
+	if (rtype != RFKILL_TYPE_UNKNOWN)
 		manager_rfkill_update_one_type (self, &priv->radio_states[rtype], rtype);
-		return;
+	else {
+		/* Otherwise sync all radio types */
+		for (i = 0; i < RFKILL_TYPE_MAX; i++)
+			manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
 	}
-
-	/* Otherwise sync all radio types */
-	for (i = 0; i < RFKILL_TYPE_MAX; i++)
-		manager_rfkill_update_one_type (self, &priv->radio_states[i], i);
 }
 
 static void
@@ -1368,11 +1407,12 @@ add_device (NMManager *self, NMDevice *device)
 	const GSList *unmanaged_specs;
 	NMConnection *existing = NULL;
 	gboolean managed = FALSE, enabled = FALSE;
+	RfKillType rtype = RFKILL_TYPE_UNKNOWN;
 
 	iface = nm_device_get_ip_iface (device);
 	g_assert (iface);
 
-	if (!NM_IS_DEVICE_MODEM (device) && find_device_by_iface (self, iface)) {
+	if (!NM_IS_DEVICE_MODEM (device) && find_device_by_ip_iface (self, iface)) {
 		g_object_unref (device);
 		return;
 	}
@@ -1401,34 +1441,27 @@ add_device (NMManager *self, NMDevice *device)
 		g_signal_connect (device, "notify::" NM_DEVICE_WIFI_IPW_RFKILL_STATE,
 		                  G_CALLBACK (manager_ipw_rfkill_state_changed),
 		                  self);
-
-		/* Update global rfkill state with this device's rfkill state, and
-		 * then set this device's rfkill state based on the global state.
-		 */
-		nm_manager_rfkill_update (self, RFKILL_TYPE_WLAN);
-		enabled = radio_enabled_for_type (self, RFKILL_TYPE_WLAN);
-		nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled);
+		rtype = RFKILL_TYPE_WLAN;
 	} else if (NM_IS_DEVICE_MODEM (device)) {
 		g_signal_connect (device, NM_DEVICE_MODEM_ENABLE_CHANGED,
 		                  G_CALLBACK (manager_modem_enabled_changed),
 		                  self);
-
-		nm_manager_rfkill_update (self, RFKILL_TYPE_WWAN);
-		enabled = radio_enabled_for_type (self, RFKILL_TYPE_WWAN);
-		/* Until we start respecting WWAN rfkill switches the modem itself
-		 * is the source of the enabled/disabled state, so the manager shouldn't
-		 * touch it here.
-		nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device),
-		                                 priv->radio_states[RFKILL_TYPE_WWAN].enabled);
-		*/
+		rtype = RFKILL_TYPE_WWAN;
 #if WITH_WIMAX
 	} else if (NM_IS_DEVICE_WIMAX (device)) {
-		nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX);
-		enabled = radio_enabled_for_type (self, RFKILL_TYPE_WIMAX);
-		nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled);
+		rtype = RFKILL_TYPE_WIMAX;
 #endif
 	}
 
+	if (rtype != RFKILL_TYPE_UNKNOWN) {
+		/* Update global rfkill state with this device's rfkill state, and
+		 * then set this device's rfkill state based on the global state.
+		 */
+		nm_manager_rfkill_update (self, rtype);
+		enabled = radio_enabled_for_type (self, rtype, TRUE);
+		nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled);
+	}
+
 	type_desc = nm_device_get_type_desc (device);
 	g_assert (type_desc);
 	driver = nm_device_get_driver (device);
@@ -1677,18 +1710,17 @@ bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
 }
 
 static NMDevice *
-find_device_by_iface (NMManager *self, const gchar *iface)
+find_device_by_ip_iface (NMManager *self, const gchar *iface)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
 	GSList *iter;
 
 	for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
-		NMDevice *device = NM_DEVICE (iter->data);
-		const gchar *d_iface = nm_device_get_ip_iface (device);
-		if (!strcmp (d_iface, iface))
-			return device;
-	}
+		NMDevice *candidate = iter->data;
 
+		if (g_strcmp0 (nm_device_get_ip_iface (candidate), iface) == 0)
+			return candidate;
+	}
 	return NULL;
 }
 
@@ -1743,7 +1775,7 @@ udev_device_removed_cb (NMUdevManager *manager,
 		 * they may have already been removed from sysfs.  Instead, we just
 		 * have to fall back to the device's interface name.
 		 */
-		device = find_device_by_iface (self, g_udev_device_get_name (udev_device));
+		device = find_device_by_ip_iface (self, g_udev_device_get_name (udev_device));
 	}
 
 	if (device)
@@ -1781,6 +1813,32 @@ impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err)
 	return TRUE;
 }
 
+static gboolean
+impl_manager_get_device_by_ip_iface (NMManager *self,
+                                     const char *iface,
+                                     char **out_object_path,
+                                     GError **error)
+{
+	NMDevice *device;
+	const char *path = NULL;
+
+	device = find_device_by_ip_iface (self, iface);
+	if (device) {
+		path = nm_device_get_path (device);
+		if (path)
+			*out_object_path = g_strdup (path);
+	}
+
+	if (path == NULL) {
+		g_set_error_literal (error,
+		                     NM_MANAGER_ERROR,
+		                     NM_MANAGER_ERROR_UNKNOWN_DEVICE,
+		                     "No device found for the requested iface.");
+	}
+
+	return path ? TRUE : FALSE;
+}
+
 static NMActRequest *
 nm_manager_get_act_request_by_path (NMManager *manager,
                                     const char *path,
@@ -1898,7 +1956,6 @@ nm_manager_activate_connection (NMManager *manager,
 
 	if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
 		NMActRequest *parent_req = NULL;
-		NMVPNManager *vpn_manager;
 
 		/* VPN connection */
 
@@ -1935,17 +1992,14 @@ nm_manager_activate_connection (NMManager *manager,
 			return NULL;
 		}
 
-		vpn_manager = nm_vpn_manager_get ();
-		vpn_connection = nm_vpn_manager_activate_connection (vpn_manager,
+		vpn_connection = nm_vpn_manager_activate_connection (priv->vpn_manager,
 		                                                     connection,
-		                                                     parent_req,
 		                                                     device,
 		                                                     TRUE,
 		                                                     sender_uid,
 		                                                     error);
 		if (vpn_connection)
 			path = nm_vpn_connection_get_active_connection_path (vpn_connection);
-		g_object_unref (vpn_manager);
 	} else {
 		NMDeviceState state;
 
@@ -2142,7 +2196,6 @@ nm_manager_deactivate_connection (NMManager *manager,
                                   GError **error)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-	NMVPNManager *vpn_manager;
 	GSList *iter;
 	gboolean success = FALSE;
 	NMVPNConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED;
@@ -2166,17 +2219,15 @@ nm_manager_deactivate_connection (NMManager *manager,
 	}
 
 	/* Check for VPN connections next */
-	vpn_manager = nm_vpn_manager_get ();
 	if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED)
 		vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED;
-	if (nm_vpn_manager_deactivate_connection (vpn_manager, connection_path, vpn_reason)) {
+	if (nm_vpn_manager_deactivate_connection (priv->vpn_manager, connection_path, vpn_reason)) {
 		success = TRUE;
 	} else {
 		g_set_error (error,
 		             NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
 		             "%s", "The connection was not active.");
 	}
-	g_object_unref (vpn_manager);
 
 done:
 	g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
@@ -2336,7 +2387,7 @@ do_sleep_wake (NMManager *self)
 			 */
 			for (i = 0; i < RFKILL_TYPE_MAX; i++) {
 				RadioState *rstate = &priv->radio_states[i];
-				gboolean enabled = radio_enabled_for_rstate (rstate);
+				gboolean enabled = radio_enabled_for_rstate (rstate, TRUE);
 				RfKillType devtype = RFKILL_TYPE_UNKNOWN;
 
 				if (rstate->desc) {
@@ -2784,6 +2835,7 @@ nm_manager_start (NMManager *self)
 	for (i = 0; i < RFKILL_TYPE_MAX; i++) {
 		RadioState *rstate = &priv->radio_states[i];
 		RfKillState udev_state;
+		gboolean enabled;
 
 		if (!rstate->desc)
 			continue;
@@ -2797,7 +2849,8 @@ nm_manager_start (NMManager *self)
 				         (rstate->hw_enabled && rstate->sw_enabled) ? "enabled" : "disabled",
 				         rstate->user_enabled ? "enabled" : "disabled");
 		}
-		manager_update_radio_enabled (self, rstate);
+		enabled = radio_enabled_for_rstate (rstate, TRUE);
+		manager_update_radio_enabled (self, rstate, enabled);
 	}
 
 	/* Log overall networking status - enabled/disabled */
@@ -3203,6 +3256,58 @@ dispose (GObject *object)
 	G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
 }
 
+#define KERN_RFKILL_OP_CHANGE_ALL 3
+#define KERN_RFKILL_TYPE_WLAN     1
+struct rfkill_event {
+	__u32 idx;
+	__u8  type;
+	__u8  op;
+	__u8  soft, hard;
+} __attribute__((packed));
+
+static void
+rfkill_change_wifi (const char *desc, gboolean enabled)
+{
+	int fd;
+	struct rfkill_event event;
+	ssize_t len;
+
+	errno = 0;
+	fd = open ("/dev/rfkill", O_RDWR);
+	if (fd < 0) {
+		if (errno == EACCES)
+			nm_log_warn (LOGD_RFKILL, "(%s): failed to open killswitch device "
+			             "for WiFi radio control", desc);
+		return;
+	}
+
+	if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) {
+		nm_log_warn (LOGD_RFKILL, "(%s): failed to set killswitch device for "
+		             "non-blocking operation", desc);
+		close (fd);
+		return;
+	}
+
+	memset (&event, 0, sizeof (event));
+	event.op = KERN_RFKILL_OP_CHANGE_ALL;
+	event.type = KERN_RFKILL_TYPE_WLAN;
+	event.soft = enabled ? 0 : 1;
+
+	len = write (fd, &event, sizeof (event));
+	if (len < 0) {
+		nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state: (%d) %s",
+		             desc, errno, g_strerror (errno));
+	} else if (len == sizeof (event)) {
+		nm_log_info (LOGD_RFKILL, "%s hardware radio set %s",
+		             desc, enabled ? "enabled" : "disabled");
+	} else {
+		/* Failed to write full structure */
+		nm_log_warn (LOGD_RFKILL, "(%s): failed to change WiFi killswitch state", desc);
+	}
+
+	close (fd);
+}
+
 static void
 manager_radio_user_toggled (NMManager *self,
                             RadioState *rstate,
@@ -3232,11 +3337,25 @@ manager_radio_user_toggled (NMManager *self,
 		}
 	}
 
-	old_enabled = radio_enabled_for_rstate (rstate);
+	/* When the user toggles the radio, their request should override any
+	 * daemon (like ModemManager) enabled state that can be changed.  For WWAN
+	 * for example, we want the WwanEnabled property to reflect the daemon state
+	 * too so that users can toggle the modem powered, but we don't want that
+	 * daemon state to affect whether or not the user *can* turn it on, which is
+	 * what the kernel rfkill state does.  So we ignore daemon enabled state
+	 * when determining what the new state should be since it shouldn't block
+	 * the user's request.
+	 */
+	old_enabled = radio_enabled_for_rstate (rstate, TRUE);
 	rstate->user_enabled = enabled;
-	new_enabled = radio_enabled_for_rstate (rstate);
-	if (new_enabled != old_enabled)
-		manager_update_radio_enabled (self, rstate);
+	new_enabled = radio_enabled_for_rstate (rstate, FALSE);
+	if (new_enabled != old_enabled) {
+		manager_update_radio_enabled (self, rstate, new_enabled);
+
+		/* For WiFi only (for now) set the actual kernel rfkill state */
+		if (rstate->rtype == RFKILL_TYPE_WLAN)
+			rfkill_change_wifi (rstate->desc, new_enabled);
+	}
 }
 
 static void
@@ -3291,19 +3410,19 @@ get_property (GObject *object, guint prop_id,
 		g_value_set_boolean (value, priv->net_enabled);
 		break;
 	case PROP_WIRELESS_ENABLED:
-		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN));
+		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WLAN, TRUE));
 		break;
 	case PROP_WIRELESS_HARDWARE_ENABLED:
 		g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WLAN].hw_enabled);
 		break;
 	case PROP_WWAN_ENABLED:
-		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN));
+		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WWAN, TRUE));
 		break;
 	case PROP_WWAN_HARDWARE_ENABLED:
 		g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
 		break;
 	case PROP_WIMAX_ENABLED:
-		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WIMAX));
+		g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WIMAX, TRUE));
 		break;
 	case PROP_WIMAX_HARDWARE_ENABLED:
 		g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled);
@@ -3371,7 +3490,7 @@ nm_manager_init (NMManager *manager)
 	priv->radio_states[RFKILL_TYPE_WWAN].prop = NM_MANAGER_WWAN_ENABLED;
 	priv->radio_states[RFKILL_TYPE_WWAN].hw_prop = NM_MANAGER_WWAN_HARDWARE_ENABLED;
 	priv->radio_states[RFKILL_TYPE_WWAN].desc = "WWAN";
-	priv->radio_states[RFKILL_TYPE_WWAN].other_enabled_func = nm_manager_get_modem_enabled_state;
+	priv->radio_states[RFKILL_TYPE_WWAN].daemon_enabled_func = nm_manager_get_modem_enabled_state;
 	priv->radio_states[RFKILL_TYPE_WWAN].rtype = RFKILL_TYPE_WWAN;
 
 	priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE;
diff --git a/src/nm-policy.c b/src/nm-policy.c
index fcada545..5c30828b 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -238,7 +238,7 @@ _set_hostname (NMPolicy *policy,
 	}
 
 	if (nm_policy_set_system_hostname (policy->cur_hostname, msg))
-		nm_utils_call_dispatcher ("hostname", NULL, NULL, NULL);
+		nm_utils_call_dispatcher ("hostname", NULL, NULL, NULL, NULL, NULL);
 }
 
 static void
@@ -539,7 +539,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	NMActRequest *best_req = NULL;
 	NMDnsManager *dns_mgr;
 	GSList *devices = NULL, *iter;
-#if NOT_YET
+#if 0
 	GSList *vpns;
 #endif
 	NMIP6Config *ip6_config = NULL;
@@ -555,7 +555,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
 	if (!force_update && (best == policy->default_device6))
 		goto out;
 
-#if NOT_YET
+#if 0
 	/* If a VPN connection is active, it is preferred */
 	vpns = nm_vpn_manager_get_active_connections (policy->vpn_manager);
 	for (iter = vpns; iter; iter = g_slist_next (iter)) {
@@ -686,6 +686,16 @@ typedef struct {
 	guint id;
 } ActivateData;
 
+static void
+activate_data_free (ActivateData *data)
+{
+	if (data->id)
+		g_source_remove (data->id);
+	g_object_unref (data->device);
+	memset (data, 0, sizeof (*data));
+	g_free (data);
+}
+
 static gboolean
 auto_activate_device (gpointer user_data)
 {
@@ -698,6 +708,9 @@ auto_activate_device (gpointer user_data)
 	g_assert (data);
 	policy = data->policy;
 
+	data->id = 0;
+	policy->pending_activation_checks = g_slist_remove (policy->pending_activation_checks, data);
+
 	// FIXME: if a device is already activating (or activated) with a connection
 	// but another connection now overrides the current one for that device,
 	// deactivate the device and activate the new connection instead of just
@@ -741,14 +754,37 @@ auto_activate_device (gpointer user_data)
 	g_slist_free (connections);
 
  out:
-	/* Remove this call's handler ID */
-	policy->pending_activation_checks = g_slist_remove (policy->pending_activation_checks, data);
-	g_object_unref (data->device);
-	g_free (data);
-
+	activate_data_free (data);
 	return FALSE;
 }
 
+static ActivateData *
+activate_data_new (NMPolicy *policy, NMDevice *device, guint delay_seconds)
+{
+	ActivateData *data;
+
+	data = g_malloc0 (sizeof (ActivateData));
+	data->policy = policy;
+	data->device = g_object_ref (device);
+	if (delay_seconds > 0)
+		data->id = g_timeout_add_seconds (delay_seconds, auto_activate_device, data);
+	else
+		data->id = g_idle_add (auto_activate_device, data);
+	return data;
+}
+
+static ActivateData *
+find_pending_activation (GSList *list, NMDevice *device)
+{
+	GSList *iter;
+
+	for (iter = list; iter; iter = g_slist_next (iter)) {
+		if (((ActivateData *) iter->data)->device == device)
+			return iter->data;
+	}
+	return NULL;
+}
+
 /*****************************************************************************/
 
 static void
@@ -803,7 +839,6 @@ static void
 schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds)
 {
 	ActivateData *data;
-	GSList *iter;
 	NMDeviceState state;
 
 	if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
@@ -816,19 +851,11 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds
 	if (!nm_device_autoconnect_allowed (device))
 		return;
 
-	for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) {
-		/* Only one pending activation check at a time */
-		if (((ActivateData *) iter->data)->device == device)
-			return;
+	/* Schedule an auto-activation if there isn't one already for this device */
+	if (find_pending_activation (policy->pending_activation_checks, device) == NULL) {
+		data = activate_data_new (policy, device, delay_seconds);
+		policy->pending_activation_checks = g_slist_append (policy->pending_activation_checks, data);
 	}
-
-	data = g_malloc0 (sizeof (ActivateData));
-	g_return_if_fail (data != NULL);
-
-	data->policy = policy;
-	data->device = g_object_ref (device);
-	data->id = delay_seconds ? g_timeout_add_seconds (delay_seconds, auto_activate_device, data) : g_idle_add (auto_activate_device, data);
-	policy->pending_activation_checks = g_slist_append (policy->pending_activation_checks, data);
 }
 
 static NMConnection *
@@ -896,7 +923,10 @@ device_state_changed (NMDevice *device,
 		break;
 	case NM_DEVICE_STATE_UNMANAGED:
 	case NM_DEVICE_STATE_UNAVAILABLE:
+		update_routing_and_dns (policy, FALSE);
+		break;
 	case NM_DEVICE_STATE_DISCONNECTED:
+		/* Device is now available for auto-activation */
 		update_routing_and_dns (policy, FALSE);
 		schedule_activate_check (policy, device, 0);
 		break;
@@ -968,21 +998,14 @@ static void
 device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
 {
 	NMPolicy *policy = (NMPolicy *) user_data;
+	ActivateData *tmp;
 	GSList *iter;
 
 	/* Clear any idle callbacks for this device */
-	iter = policy->pending_activation_checks;
-	while (iter) {
-		ActivateData *data = (ActivateData *) iter->data;
-		GSList *next = g_slist_next (iter);
-
-		if (data->device == device) {
-			g_source_remove (data->id);
-			g_object_unref (data->device);
-			g_free (data);
-			policy->pending_activation_checks = g_slist_delete_link (policy->pending_activation_checks, iter);
-		}
-		iter = next;
+	tmp = find_pending_activation (policy->pending_activation_checks, device);
+	if (tmp) {
+		policy->pending_activation_checks = g_slist_remove (policy->pending_activation_checks, tmp);
+		activate_data_free (tmp);
 	}
 
 	/* Clear any signal handlers for this device */
@@ -1171,13 +1194,7 @@ nm_policy_destroy (NMPolicy *policy)
 		policy->lookup = NULL;
 	}
 
-	for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) {
-		ActivateData *data = (ActivateData *) iter->data;
-
-		g_source_remove (data->id);
-		g_object_unref (data->device);
-		g_free (data);
-	}
+	g_slist_foreach (policy->pending_activation_checks, (GFunc) activate_data_free, NULL);
 	g_slist_free (policy->pending_activation_checks);
 
 	g_signal_handler_disconnect (policy->vpn_manager, policy->vpn_activated_id);
diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c
index 4877b770..c163ee6a 100644
--- a/src/nm-session-monitor.c
+++ b/src/nm-session-monitor.c
@@ -189,6 +189,19 @@ error:
 	return NULL;
 }
 
+static void
+session_merge (Session *src, Session *dest)
+{
+	g_return_if_fail (src != NULL);
+	g_return_if_fail (dest != NULL);
+
+	g_warn_if_fail (g_strcmp0 (src->user, dest->user) == 0);
+	g_warn_if_fail (src->uid == dest->uid);
+
+	dest->local = (dest->local || src->local);
+	dest->active = (dest->active || src->active);
+}
+
 /********************************************************************/
 
 static void
@@ -237,14 +250,24 @@ reload_database (NMSessionMonitor *self, GError **error)
 	}
 
 	for (i = 0; i < len; i++) {
+		Session *found;
+
 		if (!g_str_has_prefix (groups[i], "Session "))
 			continue;
 
 		s = session_new (self->database, groups[i], error);
 		if (!s)
 			goto error;
-		g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s);
-		g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s);
+
+		found = g_hash_table_lookup (self->sessions_by_user, (gpointer) s->user);
+		if (found) {
+			session_merge (s, found);
+			session_free (s);
+		} else {
+			/* Entirely new user */
+			g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s);
+			g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s);
+		}
 	}
 
 	g_strfreev (groups);
@@ -387,9 +410,10 @@ nm_session_monitor_get (void)
 	static NMSessionMonitor *singleton = NULL;
 
 	if (singleton)
-		return NM_SESSION_MONITOR (g_object_ref (singleton));
+		return g_object_ref (singleton);
 
-	return NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
+	singleton = NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
+	return singleton;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/nm-system.c b/src/nm-system.c
index e8b8fec1..88db6596 100644
--- a/src/nm-system.c
+++ b/src/nm-system.c
@@ -312,10 +312,10 @@ sync_addresses (const char *iface, int ifindex, int family,
 		}
 
 		err = rtnl_addr_add (nlh, addrs[i], 0);
-		if (err < 0) {
+		if (err < 0 && (nl_get_errno () != EEXIST)) {
 			nm_log_err (log_domain,
 			            "(%s): error %d returned from rtnl_addr_add():\n%s",
-						iface, err, nl_geterror ());
+			            iface, err, nl_geterror ());
 		}
 
 		rtnl_addr_put (addrs[i]);
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index 3563a574..41a4e15b 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -74,6 +74,7 @@ typedef struct {
 	char *driver;
 	RfKillType rtype;
 	gint state;
+	gboolean platform;
 } Killswitch;
 
 RfKillState
@@ -91,7 +92,7 @@ rfkill_type_to_desc (RfKillType rtype)
 	if (rtype == 0)
 		return "WiFi";
 	else if (rtype == 1)
-		return "WWan";
+		return "WWAN";
 	else if (rtype == 2)
 		return "WiMAX";
 	return "unknown";
@@ -113,8 +114,8 @@ static Killswitch *
 killswitch_new (GUdevDevice *device, RfKillType rtype)
 {
 	Killswitch *ks;
-	GUdevDevice *parent = NULL;
-	const char *driver;
+	GUdevDevice *parent = NULL, *grandparent = NULL;
+	const char *driver, *subsys, *parent_subsys = NULL;
 
 	ks = g_malloc0 (sizeof (Killswitch));
 	ks->name = g_strdup (g_udev_device_get_name (device));
@@ -123,17 +124,33 @@ killswitch_new (GUdevDevice *device, RfKillType rtype)
 	ks->rtype = rtype;
 
 	driver = g_udev_device_get_property (device, "DRIVER");
-	if (!driver) {
-		parent = g_udev_device_get_parent (device);
-		if (parent)
+	subsys = g_udev_device_get_subsystem (device);
+
+	/* Check parent for various attributes */
+	parent = g_udev_device_get_parent (device);
+	if (parent) {
+		parent_subsys = g_udev_device_get_subsystem (parent);
+		if (!driver)
 			driver = g_udev_device_get_property (parent, "DRIVER");
+		if (!driver) {
+			/* Sigh; try the grandparent */
+			grandparent = g_udev_device_get_parent (parent);
+			if (grandparent)
+				driver = g_udev_device_get_property (parent, "DRIVER");
+		}
 	}
-	if (driver)
-		ks->driver = g_strdup (driver);
 
+	if (!driver)
+		driver = "(unknown)";
+	ks->driver = g_strdup (driver);
+
+	if (g_strcmp0 (subsys, "platform") == 0 || g_strcmp0 (parent_subsys, "platform") == 0)
+		ks->platform = TRUE;
+
+	if (grandparent)
+		g_object_unref (grandparent);
 	if (parent)
 		g_object_unref (parent);
-
 	return ks;
 }
 
@@ -178,28 +195,77 @@ recheck_killswitches (NMUdevManager *self)
 	NMUdevManagerPrivate *priv = NM_UDEV_MANAGER_GET_PRIVATE (self);
 	GSList *iter;
 	RfKillState poll_states[RFKILL_TYPE_MAX];
+	gboolean platform_checked[RFKILL_TYPE_MAX];
 	int i;
 
 	/* Default state is unblocked */
-	for (i = 0; i < RFKILL_TYPE_MAX; i++)
+	for (i = 0; i < RFKILL_TYPE_MAX; i++) {
 		poll_states[i] = RFKILL_UNBLOCKED;
+		platform_checked[i] = FALSE;
+	}
+
+	/* Perform two passes here; the first pass is for non-platform switches,
+	 * which typically if hardkilled cannot be changed except by a physical
+	 * hardware switch.  The second pass checks platform killswitches, which
+	 * take precedence over device killswitches, because typically platform
+	 * killswitches control device killswitches.  That is, a hardblocked device
+	 * switch can often be unblocked by a platform switch.  Thus if we have
+	 * a hardblocked device switch and a softblocked platform switch, the
+	 * combined state should be softblocked since the platform switch can be
+	 * unblocked to change the device switch.
+	 */
 
+	/* Device switches first */
 	for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
 		Killswitch *ks = iter->data;
 		GUdevDevice *device;
 		RfKillState dev_state;
+		int sysfs_state;
+
+		if (ks->platform == FALSE) {
+			device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
+			if (device) {
+				sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
+				dev_state = sysfs_state_to_nm_state (sysfs_state);
+				if (dev_state > poll_states[ks->rtype])
+					poll_states[ks->rtype] = dev_state;
+				g_object_unref (device);
+			}
+		}
+	}
 
-		device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
-		if (!device)
-			continue;
-
-		dev_state = sysfs_state_to_nm_state (g_udev_device_get_property_as_int (device, "RFKILL_STATE"));
-		if (dev_state > poll_states[ks->rtype])
-			poll_states[ks->rtype] = dev_state;
-
-		g_object_unref (device);
+	/* Platform switches next; their state overwrites device state */
+	for (iter = priv->killswitches; iter; iter = g_slist_next (iter)) {
+		Killswitch *ks = iter->data;
+		GUdevDevice *device;
+		RfKillState dev_state;
+		int sysfs_state;
+
+		if (ks->platform == TRUE) {
+			device = g_udev_client_query_by_subsystem_and_name (priv->client, "rfkill", ks->name);
+			if (device) {
+				sysfs_state = g_udev_device_get_property_as_int (device, "RFKILL_STATE");
+				dev_state = sysfs_state_to_nm_state (sysfs_state);
+
+				if (platform_checked[ks->rtype] == FALSE) {
+					/* Overwrite device state with platform state for first
+					 * platform switch found.
+					 */
+					poll_states[ks->rtype] = dev_state;
+					platform_checked[ks->rtype] = TRUE;
+				} else {
+					/* If there are multiple platform switches of the same type,
+					 * take the "worst" state for all of that type.
+					 */
+					if (dev_state > poll_states[ks->rtype])
+						poll_states[ks->rtype] = dev_state;
+				}
+				g_object_unref (device);
+			}
+		}
 	}
 
+	/* Log and emit change signal for final rfkill states */
 	for (i = 0; i < RFKILL_TYPE_MAX; i++) {
 		if (poll_states[i] != priv->rfkill_states[i]) {
 			nm_log_dbg (LOGD_RFKILL, "%s rfkill state now '%s'",
@@ -385,8 +451,12 @@ device_creator (NMUdevManager *manager,
 	}
 
 	if (!driver) {
-		nm_log_warn (LOGD_HW, "%s: couldn't determine device driver; ignoring...", path);
-		goto out;
+		if (g_str_has_prefix (ifname, "easytether")) {
+			driver = "easytether";
+		} else {
+			nm_log_warn (LOGD_HW, "%s: couldn't determine device driver; ignoring...", path);
+			goto out;
+		}
 	}
 
 	ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex");
@@ -420,13 +490,26 @@ net_add (NMUdevManager *self, GUdevDevice *device)
 	gint etype;
 	const char *iface;
 	const char *tmp;
+	gboolean is_ctc;
 
 	g_return_if_fail (device != NULL);
 
+	iface = g_udev_device_get_name (device);
+	if (!iface) {
+		nm_log_dbg (LOGD_HW, "failed to get device's interface");
+		return;
+	}
+
 	etype = g_udev_device_get_sysfs_attr_as_int (device, "type");
-	if (etype != 1) {
+	is_ctc = (strncmp (iface, "ctc", 3) == 0) && (etype == 256);
+
+	/* Ignore devices that don't report Ethernet encapsulation, except for
+	 * s390 CTC-type devices that report 256 for some reason.
+	 * FIXME: use something other than interface name to detect CTC here.
+	 */
+	if ((etype != 1) && (is_ctc == FALSE)) {
 		nm_log_dbg (LOGD_HW, "ignoring interface with type %d", etype);
-		return; /* Not using ethernet encapsulation, don't care */
+		return;
 	}
 
 	/* Not all ethernet devices are immediately usable; newer mobile broadband
@@ -454,12 +537,6 @@ net_add (NMUdevManager *self, GUdevDevice *device)
 		}
 	}
 
-	iface = g_udev_device_get_name (device);
-	if (!iface) {
-		nm_log_dbg (LOGD_HW, "failed to get device's interface");
-		return;
-	}
-
 	g_signal_emit (self, signals[DEVICE_ADDED], 0, device, device_creator);
 }
 
diff --git a/src/nm-wifi-ap-utils.c b/src/nm-wifi-ap-utils.c
index 1efcc9d8..215c4935 100644
--- a/src/nm-wifi-ap-utils.c
+++ b/src/nm-wifi-ap-utils.c
@@ -481,14 +481,10 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid,
 	const char *mode, *key_mgmt, *auth_alg, *leap_username;
 	gboolean adhoc = FALSE;
 
-	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
-	s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
-
-	if (!s_wifi) {
-		s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
-		nm_connection_add_setting (connection, NM_SETTING (s_wifi));
-	}
+	s_wifi = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wifi);
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 
 	/* Fill in missing SSID */
 	ssid = nm_setting_wireless_get_ssid (s_wifi);
diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c
index 5fbdcea6..6eab9581 100644
--- a/src/nm-wifi-ap.c
+++ b/src/nm-wifi-ap.c
@@ -51,9 +51,9 @@ typedef struct
 	guint32			freq;		/* Frequency in MHz; ie 2412 (== 2.412 GHz) */
 	guint32			max_bitrate;/* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */
 
-	guint32			flags;		/* General flags */
-	guint32			wpa_flags;	/* WPA-related flags */
-	guint32			rsn_flags;	/* RSN (WPA2) -related flags */
+	NM80211ApFlags         flags;      /* General flags */
+	NM80211ApSecurityFlags wpa_flags;  /* WPA-related flags */
+	NM80211ApSecurityFlags rsn_flags;  /* RSN (WPA2) -related flags */
 
 	/* Non-scanned attributes */
 	gboolean			fake;	/* Whether or not the AP is from a scan */
@@ -215,7 +215,17 @@ static void
 nm_ap_class_init (NMAccessPointClass *ap_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (ap_class);
-	guint32 all_sec_flags;
+	const NM80211ApSecurityFlags all_sec_flags =   NM_802_11_AP_SEC_NONE
+	                                             | NM_802_11_AP_SEC_PAIR_WEP40
+	                                             | NM_802_11_AP_SEC_PAIR_WEP104
+	                                             | NM_802_11_AP_SEC_PAIR_TKIP
+	                                             | NM_802_11_AP_SEC_PAIR_CCMP
+	                                             | NM_802_11_AP_SEC_GROUP_WEP40
+	                                             | NM_802_11_AP_SEC_GROUP_WEP104
+	                                             | NM_802_11_AP_SEC_GROUP_TKIP
+	                                             | NM_802_11_AP_SEC_GROUP_CCMP
+	                                             | NM_802_11_AP_SEC_KEY_MGMT_PSK
+	                                             | NM_802_11_AP_SEC_KEY_MGMT_802_1X;
 
 	g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate));
 
@@ -225,19 +235,6 @@ nm_ap_class_init (NMAccessPointClass *ap_class)
 	object_class->finalize = finalize;
 
 	/* properties */
-
-	all_sec_flags =   NM_802_11_AP_SEC_NONE
-	                | NM_802_11_AP_SEC_PAIR_WEP40
-	                | NM_802_11_AP_SEC_PAIR_WEP104
-	                | NM_802_11_AP_SEC_PAIR_TKIP
-	                | NM_802_11_AP_SEC_PAIR_CCMP
-	                | NM_802_11_AP_SEC_GROUP_WEP40
-	                | NM_802_11_AP_SEC_GROUP_WEP104
-	                | NM_802_11_AP_SEC_GROUP_TKIP
-	                | NM_802_11_AP_SEC_GROUP_CCMP
-	                | NM_802_11_AP_SEC_KEY_MGMT_PSK
-	                | NM_802_11_AP_SEC_KEY_MGMT_802_1X;
-
 	g_object_class_install_property
 		(object_class, PROP_FLAGS,
 		 g_param_spec_uint (NM_AP_FLAGS,
@@ -371,7 +368,7 @@ NMAccessPoint *nm_ap_new (void)
 	return (NMAccessPoint *) object;
 }
 
-static guint32
+static NM80211ApSecurityFlags
 pair_to_flags (const char *str)
 {
 	g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
@@ -387,7 +384,7 @@ pair_to_flags (const char *str)
 	return NM_802_11_AP_SEC_NONE;
 }
 
-static guint32
+static NM80211ApSecurityFlags
 group_to_flags (const char *str)
 {
 	g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
@@ -403,11 +400,11 @@ group_to_flags (const char *str)
 	return NM_802_11_AP_SEC_NONE;
 }
 
-static guint32
+static NM80211ApSecurityFlags
 security_from_dict (GHashTable *security)
 {
 	GValue *value;
-	guint32 flags = NM_802_11_AP_SEC_NONE;
+	NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
 	const char **items, **iter;
 
 	value = g_hash_table_lookup (security, "KeyMgmt");
@@ -482,12 +479,12 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
 				}
 			}
 		} else if (!strcmp (key, "WPA")) {
-			guint32 flags = nm_ap_get_wpa_flags (ap);
+			NM80211ApSecurityFlags flags = nm_ap_get_wpa_flags (ap);
 
 			flags |= security_from_dict (g_value_get_boxed (variant));
 			nm_ap_set_wpa_flags (ap, flags);
 		} else if (!strcmp (key, "RSN")) {
-			guint32 flags = nm_ap_get_rsn_flags (ap);
+			NM80211ApSecurityFlags flags = nm_ap_get_rsn_flags (ap);
 
 			flags |= security_from_dict (g_value_get_boxed (variant));
 			nm_ap_set_rsn_flags (ap, flags);
@@ -516,7 +513,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
 
 		if (strcmp (key, "Privacy") == 0) {
 			if (val) {
-				guint32 flags = nm_ap_get_flags (ap);
+				NM80211ApFlags flags = nm_ap_get_flags (ap);
 				nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
 			}
 		}
@@ -581,7 +578,7 @@ static void
 add_pair_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec)
 {
 	guint32 num = nm_setting_wireless_security_get_num_pairwise (sec);
-	guint32 flags = NM_802_11_AP_SEC_NONE;
+	NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
 	guint32 i;
 
 	/* If no ciphers are specified, that means "all" WPA ciphers */
@@ -608,7 +605,7 @@ static void
 add_group_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec)
 {
 	guint32 num = nm_setting_wireless_security_get_num_groups (sec);
-	guint32 flags = NM_802_11_AP_SEC_NONE;
+	NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
 	guint32 i;
 
 	/* If no ciphers are specified, that means "all" WPA ciphers */
@@ -643,7 +640,8 @@ nm_ap_new_fake_from_connection (NMConnection *connection)
 	NMSettingWirelessSecurity *s_wireless_sec;
 	const GByteArray *ssid;
 	const char *mode, *band, *key_mgmt;
-	guint32 channel, flags;
+	guint32 channel;
+	NM80211ApSecurityFlags flags;
 	gboolean psk = FALSE, eap = FALSE;
 
 	g_return_val_if_fail (connection != NULL, NULL);
@@ -874,21 +872,17 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid)
 }
 
 
-guint32
+NM80211ApFlags
 nm_ap_get_flags (NMAccessPoint *ap)
 {
-	guint32 flags;
-
-	g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_FLAGS_NONE);
-
-	g_object_get (ap, NM_AP_FLAGS, &flags, NULL);
+	g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_SEC_NONE);
 
-	return flags;
+	return NM_AP_GET_PRIVATE (ap)->flags;
 }
 
 
 void
-nm_ap_set_flags (NMAccessPoint *ap, guint32 flags)
+nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags)
 {
 	NMAccessPointPrivate *priv;
 
@@ -902,56 +896,46 @@ nm_ap_set_flags (NMAccessPoint *ap, guint32 flags)
 	}
 }
 
-guint32
+NM80211ApSecurityFlags
 nm_ap_get_wpa_flags (NMAccessPoint *ap)
 {
-	guint32 flags;
-
 	g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_SEC_NONE);
 
-	g_object_get (ap, NM_AP_WPA_FLAGS, &flags, NULL);
-
-	return flags;
+	return NM_AP_GET_PRIVATE (ap)->wpa_flags;
 }
 
 
 void
-nm_ap_set_wpa_flags (NMAccessPoint *ap, guint32 flags)
+nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags)
 {
 	NMAccessPointPrivate *priv;
 
 	g_return_if_fail (NM_IS_AP (ap));
 
 	priv = NM_AP_GET_PRIVATE (ap);
-
 	if (priv->wpa_flags != flags) {
 		priv->wpa_flags = flags;
 		g_object_notify (G_OBJECT (ap), NM_AP_WPA_FLAGS);
 	}
 }
 
-guint32
+NM80211ApSecurityFlags
 nm_ap_get_rsn_flags (NMAccessPoint *ap)
 {
-	guint32 flags;
-
 	g_return_val_if_fail (NM_IS_AP (ap), NM_802_11_AP_SEC_NONE);
 
-	g_object_get (ap, NM_AP_RSN_FLAGS, &flags, NULL);
-
-	return flags;
+	return NM_AP_GET_PRIVATE (ap)->rsn_flags;
 }
 
 
 void
-nm_ap_set_rsn_flags (NMAccessPoint *ap, guint32 flags)
+nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags)
 {
 	NMAccessPointPrivate *priv;
 
 	g_return_if_fail (NM_IS_AP (ap));
 
 	priv = NM_AP_GET_PRIVATE (ap);
-
 	if (priv->rsn_flags != flags) {
 		priv->rsn_flags = flags;
 		g_object_notify (G_OBJECT (ap), NM_AP_RSN_FLAGS);
@@ -1329,7 +1313,7 @@ nm_ap_complete_connection (NMAccessPoint *self,
 }
 
 static gboolean
-capabilities_compatible (guint32 a_flags, guint32 b_flags)
+capabilities_compatible (NM80211ApSecurityFlags a_flags, NM80211ApSecurityFlags b_flags)
 {
 	if (a_flags == b_flags)
 		return TRUE;
@@ -1402,10 +1386,10 @@ nm_ap_match_in_list (NMAccessPoint *find_ap,
 			if (nm_ap_get_rsn_flags (list_ap) != nm_ap_get_rsn_flags (find_ap))
 				continue;
 		} else {
-			guint32 list_wpa_flags = nm_ap_get_wpa_flags (list_ap);
-			guint32 find_wpa_flags = nm_ap_get_wpa_flags (find_ap);
-			guint32 list_rsn_flags = nm_ap_get_rsn_flags (list_ap);
-			guint32 find_rsn_flags = nm_ap_get_rsn_flags (find_ap);
+			NM80211ApSecurityFlags list_wpa_flags = nm_ap_get_wpa_flags (list_ap);
+			NM80211ApSecurityFlags find_wpa_flags = nm_ap_get_wpa_flags (find_ap);
+			NM80211ApSecurityFlags list_rsn_flags = nm_ap_get_rsn_flags (list_ap);
+			NM80211ApSecurityFlags find_rsn_flags = nm_ap_get_rsn_flags (find_ap);
 
 			/* Just ensure that there is overlap in the capabilities */
 			if (   !capabilities_compatible (list_wpa_flags, find_wpa_flags)
diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h
index 2a10d350..4c98f248 100644
--- a/src/nm-wifi-ap.h
+++ b/src/nm-wifi-ap.h
@@ -71,14 +71,14 @@ void				nm_ap_set_timestamp_via_timestamp	(NMAccessPoint *ap, const GTimeVal *ti
 const GByteArray *	nm_ap_get_ssid (const NMAccessPoint * ap);
 void				nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid);
 
-guint32			nm_ap_get_flags	(NMAccessPoint *ap);
-void				nm_ap_set_flags	(NMAccessPoint *ap, guint32 flags);
+NM80211ApFlags         nm_ap_get_flags     (NMAccessPoint *ap);
+void                   nm_ap_set_flags     (NMAccessPoint *ap, NM80211ApFlags flags);
 
-guint32			nm_ap_get_wpa_flags	(NMAccessPoint *ap);
-void				nm_ap_set_wpa_flags	(NMAccessPoint *ap, guint32 flags);
+NM80211ApSecurityFlags nm_ap_get_wpa_flags (NMAccessPoint *ap);
+void                   nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags);
 
-guint32			nm_ap_get_rsn_flags	(NMAccessPoint *ap);
-void				nm_ap_set_rsn_flags	(NMAccessPoint *ap, guint32 flags);
+NM80211ApSecurityFlags nm_ap_get_rsn_flags	(NMAccessPoint *ap);
+void                   nm_ap_set_rsn_flags  (NMAccessPoint *ap, NM80211ApSecurityFlags flags);
 
 const struct ether_addr * nm_ap_get_address	(const NMAccessPoint *ap);
 void				nm_ap_set_address		(NMAccessPoint *ap, const struct ether_addr *addr);
diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in
index 897a5033..13c60b41 100644
--- a/src/ppp-manager/Makefile.in
+++ b/src/ppp-manager/Makefile.in
@@ -146,6 +146,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -263,6 +267,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -284,6 +290,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 41b5ef1a..767b9315 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -66,10 +66,14 @@ static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
 
 #include "nm-ppp-manager-glue.h"
 
+static void _ppp_cleanup  (NMPPPManager *manager);
+
 #define NM_PPPD_PLUGIN PLUGINDIR "/nm-pppd-plugin.so"
 #define PPP_MANAGER_SECRET_TRIES "ppp-manager-secret-tries"
 
 typedef struct {
+	gboolean disposed;
+
 	GPid pid;
 	NMDBusManager *dbus_manager;
 	char *dbus_path;
@@ -164,11 +168,19 @@ dispose (GObject *object)
 {
 	NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object);
 
-	nm_ppp_manager_stop (NM_PPP_MANAGER (object));
+	if (priv->disposed == FALSE) {
+		priv->disposed = TRUE;
+
+		_ppp_cleanup (NM_PPP_MANAGER (object));
+
+		if (priv->act_req) {
+			g_object_unref (priv->act_req);
+			priv->act_req = NULL;
+		}
 
-	if (priv->act_req)
-		g_object_unref (priv->act_req);
-	g_object_unref (priv->dbus_manager);
+		g_object_unref (priv->dbus_manager);
+		priv->dbus_manager = NULL;
+	}
 
 	G_OBJECT_CLASS (nm_ppp_manager_parent_class)->dispose (object);
 }
@@ -315,9 +327,12 @@ monitor_stats (NMPPPManager *manager)
 	NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
 
 	priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0);
-	if (priv->monitor_fd > 0)
+	if (priv->monitor_fd > 0) {
+		g_warn_if_fail (priv->monitor_id == 0);
+		if (priv->monitor_id)
+			g_source_remove (priv->monitor_id);
 		priv->monitor_id = g_timeout_add_seconds (5, monitor_cb, manager);
-	else
+	} else
 		nm_log_warn (LOGD_PPP, "could not monitor PPP stats: %s", strerror (errno));
 }
 
@@ -766,7 +781,7 @@ pppd_timed_out (gpointer data)
 	NMPPPManager *manager = NM_PPP_MANAGER (data);
 
 	nm_log_warn (LOGD_PPP, "pppd timed out or didn't initialize our dbus module");
-	nm_ppp_manager_stop (manager);
+	_ppp_cleanup (manager);
 
 	g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_PPP_STATUS_DEAD);
 
@@ -1043,8 +1058,8 @@ ensure_killed (gpointer data)
 	return FALSE;
 }
 
-void
-nm_ppp_manager_stop (NMPPPManager *manager)
+static void
+_ppp_cleanup (NMPPPManager *manager)
 {
 	NMPPPManagerPrivate *priv;
 
diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h
index 5a8c73e4..c38602fc 100644
--- a/src/ppp-manager/nm-ppp-manager.h
+++ b/src/ppp-manager/nm-ppp-manager.h
@@ -63,8 +63,6 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager,
                                guint32 timeout_secs,
                                GError **err);
 
-void     nm_ppp_manager_stop  (NMPPPManager *manager);
-
 
 #define NM_PPP_MANAGER_ERROR nm_ppp_manager_error_quark()
 #define NM_TYPE_PPP_MANAGER_ERROR (nm_ppp_manager_error_get_type ()) 
diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c
index c64bb87f..e2e5c709 100644
--- a/src/ppp-manager/nm-pppd-plugin.c
+++ b/src/ppp-manager/nm-pppd-plugin.c
@@ -240,13 +240,13 @@ nm_ip_up (void *data, int arg)
 }
 
 static int
-get_chap_check()
+get_chap_check (void)
 {
 	return 1;
 }
 
 static int
-get_pap_check()
+get_pap_check (void)
 {
 	return 1;
 }
diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in
index 81970334..123132b7 100644
--- a/src/settings/Makefile.in
+++ b/src/settings/Makefile.in
@@ -172,6 +172,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -289,6 +293,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -310,6 +316,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c
index 035d851c..9cbfc760 100644
--- a/src/settings/nm-default-wired-connection.c
+++ b/src/settings/nm-default-wired-connection.c
@@ -43,14 +43,6 @@ typedef struct {
 } NMDefaultWiredConnectionPrivate;
 
 enum {
-	PROP_0,
-	PROP_MAC,
-	PROP_DEVICE,
-	PROP_READ_ONLY,
-	LAST_PROP
-};
-
-enum {
 	TRY_UPDATE,
 	DELETED,
 	LAST_SIGNAL
@@ -120,7 +112,7 @@ nm_default_wired_connection_new (const GByteArray *mac,
 	self = (NMDefaultWiredConnection *) g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, NULL);
 	if (self) {
 		priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (self);
-		priv->device = device;
+		priv->device = g_object_ref (device);
 		priv->mac = g_byte_array_sized_new (ETH_ALEN);
 		g_byte_array_append (priv->mac, mac->data, mac->len);
 
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index f6dbf5e3..87fa4b6c 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -91,6 +91,11 @@ static gboolean impl_settings_list_connections (NMSettings *self,
                                                 GPtrArray **connections,
                                                 GError **error);
 
+static gboolean impl_settings_get_connection_by_uuid (NMSettings *self,
+                                                      const char *uuid,
+                                                      char **out_object_path,
+                                                      GError **error);
+
 static void impl_settings_add_connection (NMSettings *self,
                                           GHashTable *settings,
                                           DBusGMethodInvocation *context);
@@ -222,6 +227,38 @@ 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)
+{
+	NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+	GHashTableIter iter;
+	NMConnection *candidate = NULL;
+	gboolean found = FALSE;
+
+	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 (!found) {
+		g_set_error_literal (error,
+		                     NM_SETTINGS_ERROR,
+		                     NM_SETTINGS_ERROR_INVALID_CONNECTION,
+		                     "No connection with the UUID was found.");
+	}
+
+	return found;
+}
+
 static int
 connection_sort (gconstpointer pa, gconstpointer pb)
 {
@@ -1099,19 +1136,19 @@ 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 *connection_type;
+		const char *ctype;
 
-		s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
-		connection_type = nm_setting_connection_get_connection_type (s_con);
+		s_con = nm_connection_get_setting_connection (connection);
+		ctype = nm_setting_connection_get_connection_type (s_con);
 
-		if (   strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
-		    && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
+		if (   strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME)
+		    && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME))
 			continue;
 
-		s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+		s_wired = nm_connection_get_setting_wired (connection);
 
 		/* No wired setting; therefore the PPPoE connection applies to any device */
-		if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
+		if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) {
 			ret = TRUE;
 			break;
 		}
diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in
index d0ade2a1..148e9620 100644
--- a/src/settings/plugins/Makefile.in
+++ b/src/settings/plugins/Makefile.in
@@ -121,6 +121,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -238,6 +242,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -259,6 +265,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in
index dac8fc9e..f02b6431 100644
--- a/src/settings/plugins/ifcfg-rh/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/Makefile.in
@@ -191,6 +191,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -308,6 +312,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -329,6 +335,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index ae40b90a..7915c467 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -213,7 +213,7 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
 	g_return_if_fail (self != NULL);
 	g_return_if_fail (connection != NULL);
 
-	managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection);
+	managed = !nm_ifcfg_connection_get_unmanaged_spec (connection);
 	path = nm_ifcfg_connection_get_path (connection);
 
 	g_object_ref (connection);
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index c366dd40..a6f9ca85 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -150,6 +150,7 @@ make_connection_setting (const char *file,
 			}
 		}
 		g_free (value);
+		g_strfreev (items);
 	}
 
 	return NM_SETTING (s_con);
@@ -294,7 +295,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg,
 				/* Record is good; fill IP4 config with its info */
 				if (!method) {
 					g_warning ("%s: malformed iscsiadm record: missing BOOTPROTO.", __func__);
-					return FALSE;
+					goto done;
 				}
 
 				g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL);
@@ -305,7 +306,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg,
 				    if (!ipaddr.s_addr || !prefix) {
 						g_warning ("%s: malformed iscsiadm record: BOOTPROTO=static "
 						           "but missing IP address or prefix.", __func__);
-						return FALSE;
+						goto done;
 					}
 
 					addr = nm_ip4_address_new ();
@@ -322,7 +323,8 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg,
 
 					// FIXME: DNS search domains?
 				}
-				return TRUE;
+				success = TRUE;
+				goto done;
 			}
 			skip = FALSE;
 			hwaddr_matched = FALSE;
@@ -494,7 +496,7 @@ parse_ip6_address (const char *value,
 static NMIP4Address *
 read_full_ip4_address (shvarFile *ifcfg,
                        const char *network_file,
-                       guint32 which,
+                       gint32 which,
                        GError **error)
 {
 	NMIP4Address *addr;
@@ -504,12 +506,12 @@ read_full_ip4_address (shvarFile *ifcfg,
 	shvarFile *network_ifcfg;
 	char *value;
 
-	g_return_val_if_fail (which > 0, NULL);
+	g_return_val_if_fail (which >= -1, NULL);
 	g_return_val_if_fail (ifcfg != NULL, NULL);
 	g_return_val_if_fail (network_file != NULL, NULL);
 
 	addr = nm_ip4_address_new ();
-	if (which == 1) {
+	if (which == -1) {
 		ip_tag = g_strdup ("IPADDR");
 		prefix_tag = g_strdup ("PREFIX");
 		netmask_tag = g_strdup ("NETMASK");
@@ -768,7 +770,6 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError
 			}
 		}
 		dest = g_match_info_fetch (match_info, 1);
-		g_match_info_free (match_info);
 		if (!strcmp (dest, "default"))
 			strcpy (dest, "0.0.0.0");
 		if (inet_pton (AF_INET, dest, &ip4_addr) != 1) {
@@ -782,6 +783,7 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError
 
 		/* Prefix - is optional; 32 if missing */
 		prefix = g_match_info_fetch (match_info, 2);
+		g_match_info_free (match_info);
 		prefix_int = 32;
 		if (prefix) {
 			errno = 0;
@@ -793,7 +795,6 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError
 				goto error;
 			}
 		}
-
 		nm_ip4_route_set_prefix (route, (guint32) prefix_int);
 		g_free (prefix);
 
@@ -1022,7 +1023,6 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro
 			}
 		}
 		dest = g_match_info_fetch (match_info, 1);
-		g_match_info_free (match_info);
 		if (!strcmp (dest, "default"))
 			strcpy (dest, "::");
 		if (inet_pton (AF_INET6, dest, &ip6_addr) != 1) {
@@ -1036,6 +1036,7 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro
 
 		/* Prefix - is optional; 128 if missing */
 		prefix = g_match_info_fetch (match_info, 2);
+		g_match_info_free (match_info);
 		prefix_int = 128;
 		if (prefix) {
 			errno = 0;
@@ -1047,7 +1048,6 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro
 				goto error;
 			}
 		}
-
 		nm_ip6_route_set_prefix (route, (guint32) prefix_int);
 		g_free (prefix);
 
@@ -1120,7 +1120,7 @@ make_ip4_setting (shvarFile *ifcfg,
 	char *value = NULL;
 	char *route_path = NULL;
 	char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
-	guint32 i;
+	gint32 i;
 	shvarFile *network_ifcfg;
 	shvarFile *route_ifcfg;
 	gboolean never_default = FALSE, tmp_success;
@@ -1164,6 +1164,7 @@ make_ip4_setting (shvarFile *ifcfg,
 		if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp"))
 			method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
 		else if (!g_ascii_strcasecmp (value, "ibft")) {
+			g_free (value);
 			g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL);
 			/* iSCSI Boot Firmware Table: need to read values from the iSCSI 
 			 * firmware for this device and create the IP4 setting using those.
@@ -1197,6 +1198,9 @@ make_ip4_setting (shvarFile *ifcfg,
 		g_free (value);
 	} else {
 		char *tmp_ip4, *tmp_prefix, *tmp_netmask;
+		char *tmp_ip4_0, *tmp_prefix_0, *tmp_netmask_0;
+		char *tmp_ip4_1, *tmp_prefix_1, *tmp_netmask_1;
+		char *tmp_ip4_2, *tmp_prefix_2, *tmp_netmask_2;
 
 		/* If there is no BOOTPROTO, no IPADDR, no PREFIX, no NETMASK, but
 		 * valid IPv6 configuration, assume that IPv4 is disabled.  Otherwise,
@@ -1211,7 +1215,19 @@ make_ip4_setting (shvarFile *ifcfg,
 		tmp_ip4 = svGetValue (ifcfg, "IPADDR", FALSE);
 		tmp_prefix = svGetValue (ifcfg, "PREFIX", FALSE);
 		tmp_netmask = svGetValue (ifcfg, "NETMASK", FALSE);
-		if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) {
+		tmp_ip4_0 = svGetValue (ifcfg, "IPADDR0", FALSE);
+		tmp_prefix_0 = svGetValue (ifcfg, "PREFIX0", FALSE);
+		tmp_netmask_0 = svGetValue (ifcfg, "NETMASK0", FALSE);
+		tmp_ip4_1 = svGetValue (ifcfg, "IPADDR1", FALSE);
+		tmp_prefix_1 = svGetValue (ifcfg, "PREFIX1", FALSE);
+		tmp_netmask_1 = svGetValue (ifcfg, "NETMASK1", FALSE);
+		tmp_ip4_2 = svGetValue (ifcfg, "IPADDR2", FALSE);
+		tmp_prefix_2 = svGetValue (ifcfg, "PREFIX2", FALSE);
+		tmp_netmask_2 = svGetValue (ifcfg, "NETMASK2", FALSE);
+		if (   !tmp_ip4   && !tmp_prefix   && !tmp_netmask
+		    && !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) {
 				/* Nope, no IPv4 */
 				g_object_set (s_ip4,
@@ -1225,6 +1241,15 @@ make_ip4_setting (shvarFile *ifcfg,
 		g_free (tmp_ip4);
 		g_free (tmp_prefix);
 		g_free (tmp_netmask);
+		g_free (tmp_ip4_0);
+		g_free (tmp_prefix_0);
+		g_free (tmp_netmask_0);
+		g_free (tmp_ip4_1);
+		g_free (tmp_prefix_1);
+		g_free (tmp_netmask_1);
+		g_free (tmp_ip4_2);
+		g_free (tmp_prefix_2);
+		g_free (tmp_netmask_2);
 	}
 
 	g_object_set (s_ip4,
@@ -1239,12 +1264,17 @@ make_ip4_setting (shvarFile *ifcfg,
 	if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
 		NMIP4Address *addr;
 
-		for (i = 1; i < 256; i++) {
+		for (i = -1; i < 256; i++) {
 			addr = read_full_ip4_address (ifcfg, network_file, i, error);
 			if (error && *error)
 				goto done;
-			if (!addr)
-				break;
+			if (!addr) {
+				/* The first mandatory variable is 2-indexed (IPADDR2)
+				 * Variables IPADDR, IPADDR0 and IPADDR1 are optional */
+				if (i > 1)
+					break;
+				continue;
+			}
 
 			if (!nm_setting_ip4_config_add_address (s_ip4, addr))
 				PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: duplicate IP4 address");
@@ -1650,6 +1680,7 @@ add_one_wep_key (shvarFile *ifcfg,
 
 	if (key) {
 		nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key);
+		g_free (key);
 		success = TRUE;
 	} else
 		g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid WEP key length.");
@@ -2782,6 +2813,7 @@ make_wireless_setting (shvarFile *ifcfg,
 			ssid_len  = (value_len - 2) / 2;
 			memcpy (buf, tmp, ssid_len);
 			p = &buf[0];
+			g_free (tmp);
 		}
 
 		if (ssid_len > 32 || ssid_len == 0) {
@@ -2841,6 +2873,7 @@ make_wireless_setting (shvarFile *ifcfg,
 		if (!eth) {
 			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
 			             "Invalid BSSID '%s'", value);
+			g_free (value);
 			goto error;
 		}
 
@@ -2848,6 +2881,7 @@ make_wireless_setting (shvarFile *ifcfg,
 		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);
 	}
 
 	value = svGetValue (ifcfg, "CHANNEL", FALSE);
@@ -2867,6 +2901,7 @@ make_wireless_setting (shvarFile *ifcfg,
 			g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL);
 		else
 			g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL);
+		g_free (value);
 	}
 
 	value = svGetValue (ifcfg, "MTU", FALSE);
@@ -2882,6 +2917,7 @@ make_wireless_setting (shvarFile *ifcfg,
 			goto error;
 		}
 		g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL);
+		g_free (value);
 	}
 
 done:
@@ -2944,6 +2980,7 @@ wireless_connection_from_ifcfg (const char *file,
 		/* Wireless security */
 		security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, error);
 		if (*error) {
+			g_free (printable_ssid);
 			g_object_unref (connection);
 			return NULL;
 		}
@@ -3077,6 +3114,11 @@ make_wired_setting (shvarFile *ifcfg,
 	}
 	g_free (value);
 
+	value = svGetValue (ifcfg, "CTCPROT", FALSE);
+	if (value && strlen (value))
+		nm_setting_wired_add_s390_option (s_wired, "ctcprot", value);
+	g_free (value);
+
 	nettype = svGetValue (ifcfg, "NETTYPE", FALSE);
 	if (nettype && strlen (nettype)) {
 		if (!strcmp (nettype, "qeth") || !strcmp (nettype, "lcs") || !strcmp (nettype, "ctc"))
@@ -3084,6 +3126,7 @@ make_wired_setting (shvarFile *ifcfg,
 		else
 			PLUGIN_WARN (IFCFG_PLUGIN_NAME, "    warning: unknown s390 NETTYPE '%s'", nettype);
 	}
+	g_free (nettype);
 
 	value = svGetValue (ifcfg, "OPTIONS", FALSE);
 	if (value && strlen (value)) {
@@ -3106,8 +3149,6 @@ make_wired_setting (shvarFile *ifcfg,
 	}
 	g_free (value);
 
-	g_free (nettype);
-
 	if (!nm_controlled && !*unmanaged) {
 		/* If NM_CONTROLLED=no but there wasn't a MAC address or z/VM
 		 * subchannels, notify the user that the device cannot be unmanaged.
@@ -3332,6 +3373,12 @@ connection_from_file (const char *filename,
 		}
 
 		g_free (device);
+	} else {
+		/* Check for IBM s390 CTC devices and call them Ethernet */
+		if (g_strcmp0 (type, "CTC") == 0) {
+			g_free (type);
+			type = g_strdup (TYPE_ETHERNET);
+		}
 	}
 
 	nmc = svGetValue (parsed, "NM_CONTROLLED", FALSE);
@@ -3439,6 +3486,7 @@ connection_from_file (const char *filename,
 
 		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL);
 	}
+	g_free (bootproto);
 
 	if (!nm_connection_verify (connection, &error)) {
 		g_object_unref (connection);
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
index 0481e1f6..db084969 100644
--- a/src/settings/plugins/ifcfg-rh/shvar.c
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -296,14 +296,14 @@ svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim)
 	    if (s->current) s->current->data = keyValue;
 	    else s->lineList = g_list_append(s->lineList, keyValue);
 	    s->modified = 1;
+	    goto end;
 	} else if (val1) {
 	    /* delete line */
 	    s->lineList = g_list_remove_link(s->lineList, s->current);
 	    g_list_free_1(s->current);
 	    s->modified = 1;
-	    goto bail; /* do not need keyValue */
 	}
-	goto end;
+	goto bail; /* do not need keyValue */
     }
 
     if (!val1) {
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
index 171cd5e5..cd37d0a7 100644
--- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
@@ -152,6 +152,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -269,6 +273,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -290,6 +296,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
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 22d1b4a7..935d0ec4 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
@@ -58,6 +58,10 @@ EXTRA_DIST = \
 	route-test-wired-static-routes \
 	ifcfg-test-wired-static-routes-legacy \
 	route-test-wired-static-routes-legacy \
+	ifcfg-test-wired-ipv4-manual-1 \
+	ifcfg-test-wired-ipv4-manual-2 \
+	ifcfg-test-wired-ipv4-manual-3 \
+	ifcfg-test-wired-ipv4-manual-4 \
 	ifcfg-test-wired-ipv6-manual \
 	route6-test-wired-ipv6-manual \
 	ifcfg-test-wired-static-no-prefix-8 \
@@ -71,6 +75,7 @@ EXTRA_DIST = \
 	ifcfg-test-wifi-wep-104-ascii \
 	keys-test-wifi-wep-104-ascii \
 	ifcfg-test-wired-qeth-static \
+	ifcfg-test-wired-ctc-static \
 	ifcfg-test-bridge-main \
 	ifcfg-test-bridge-component \
 	ifcfg-test-vlan-interface \
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 4f95948f..a10cbb86 100644
--- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
@@ -76,6 +76,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -193,6 +197,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -214,6 +220,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
@@ -321,6 +328,10 @@ EXTRA_DIST = \
 	route-test-wired-static-routes \
 	ifcfg-test-wired-static-routes-legacy \
 	route-test-wired-static-routes-legacy \
+	ifcfg-test-wired-ipv4-manual-1 \
+	ifcfg-test-wired-ipv4-manual-2 \
+	ifcfg-test-wired-ipv4-manual-3 \
+	ifcfg-test-wired-ipv4-manual-4 \
 	ifcfg-test-wired-ipv6-manual \
 	route6-test-wired-ipv6-manual \
 	ifcfg-test-wired-static-no-prefix-8 \
@@ -334,6 +345,7 @@ EXTRA_DIST = \
 	ifcfg-test-wifi-wep-104-ascii \
 	keys-test-wifi-wep-104-ascii \
 	ifcfg-test-wired-qeth-static \
+	ifcfg-test-wired-ctc-static \
 	ifcfg-test-bridge-main \
 	ifcfg-test-bridge-component \
 	ifcfg-test-vlan-interface \
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ctc-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ctc-static
new file mode 100644
index 00000000..61f8f423
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ctc-static
@@ -0,0 +1,12 @@
+# IBM CTC
+DEVICE=ctc0
+TYPE=CTC
+BOOTPROTO=static
+IPADDR=192.168.70.87
+GATEWAY=192.168.70.136
+NETMASK=255.255.255.0
+ONBOOT=yes
+SUBCHANNELS=0.0.1b00,0.0.1b01
+NETTYPE=ctc
+CTCPROT=0
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1
new file mode 100644
index 00000000..cad0f6cf
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-1
@@ -0,0 +1,12 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+IPADDR0=1.2.3.4
+PREFIX0=24
+GATEWAY0=1.1.1.1
+IPADDR1=9.8.7.6
+PREFIX1=16
+IPADDR2=3.3.3.3
+PREFIX2=8
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2
new file mode 100644
index 00000000..ad9290a4
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-2
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+IPADDR=1.2.3.4
+PREFIX=24
+GATEWAY=1.1.1.1
+IPADDR2=9.8.7.6
+PREFIX2=16
+GATEWAY2=5.5.5.5
+IPADDR3=3.3.3.3
+PREFIX3=8
+GATEWAY3=7.7.7.7
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3
new file mode 100644
index 00000000..f2457bd2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-3
@@ -0,0 +1,11 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+IPADDR2=1.2.3.4
+PREFIX2=24
+IPADDR3=9.8.7.6
+PREFIX3=16
+IPADDR4=3.3.3.3
+PREFIX4=8
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4
new file mode 100644
index 00000000..e6b77141
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv4-manual-4
@@ -0,0 +1,11 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+IPADDR=1.2.3.4
+PREFIX=24
+IPADDR1=9.8.7.6
+PREFIX1=16
+IPADDR2=3.3.3.3
+PREFIX2=8
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
index a6c54fd3..e32ad789 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-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.
  *
- * Copyright (C) 2008 - 2009 Red Hat, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
 #include <stdio.h>
@@ -53,7 +53,7 @@ test_get_ifcfg_path (const char *desc,
                      const char *path,
                      const char *expected)
 {
-	const char *result;
+	char *result;
 
 	result = utils_get_ifcfg_path (path);
 	if (expected == NULL) {
@@ -64,6 +64,7 @@ test_get_ifcfg_path (const char *desc,
 		ASSERT (strcmp (result, expected) == 0,
 		        desc, "unexpected ifcfg name '%s' created for '%s'", result, path);
 	}
+	g_free (result);
 }
 
 static void
@@ -71,7 +72,7 @@ test_get_keys_path (const char *desc,
                     const char *path,
                     const char *expected)
 {
-	const char *result;
+	char *result;
 
 	result = utils_get_keys_path (path);
 	if (expected == NULL) {
@@ -82,6 +83,7 @@ test_get_keys_path (const char *desc,
 		ASSERT (strcmp (result, expected) == 0,
 		        desc, "unexpected extra path '%s' created for '%s'", result, path);
 	}
+	g_free (result);
 }
 
 static void
@@ -89,7 +91,7 @@ test_get_route_path (const char *desc,
                      const char *path,
                      const char *expected)
 {
-	const char *result;
+	char *result;
 
 	result = utils_get_route_path (path);
 	if (expected == NULL) {
@@ -100,6 +102,7 @@ test_get_route_path (const char *desc,
 		ASSERT (strcmp (result, expected) == 0,
 		        desc, "unexpected extra path '%s' created for '%s'", result, path);
 	}
+	g_free (result);
 }
 
 static void
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 ebe9e47f..e6013f8d 100644
--- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -327,6 +327,10 @@ test_read_minimal (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -445,6 +449,7 @@ test_read_unmanaged (void)
 	        TEST_IFCFG_UNMANAGED,
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME);
 
+	g_free (unmanaged);
 	g_object_unref (connection);
 }
 
@@ -456,7 +461,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 	NMSettingWired *s_wired;
 	NMSettingIP4Config *s_ip4;
 	NMSettingIP6Config *s_ip6;
-	char *unmanaged = FALSE;
+	char *unmanaged = NULL;
 	char *keyfile = NULL;
 	char *routefile = NULL;
 	char *route6file = NULL;
@@ -494,7 +499,7 @@ test_read_wired_static (const char *file, const char *expected_id)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-static-verify", "failed to verify %s: %s", file, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-static-verify", "failed to verify %s: unexpected unmanaged value", file);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -748,6 +753,10 @@ test_read_wired_static (const char *file, const char *expected_id)
 			file);
 	}
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -759,7 +768,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix)
 	NMConnection *connection;
 	NMSettingConnection *s_con;
 	NMSettingIP4Config *s_ip4;
-	char *unmanaged = FALSE;
+	char *unmanaged = NULL;
 	char *keyfile = NULL;
 	char *routefile = NULL;
 	char *route6file = NULL;
@@ -793,7 +802,7 @@ test_read_wired_static_no_prefix (guint32 expected_prefix)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-static-no-prefix-verify", "failed to verify %s: %s", file, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-static-no-prefix-verify", "failed to verify %s: unexpected unmanaged value", file);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -855,6 +864,10 @@ test_read_wired_static_no_prefix (guint32 expected_prefix)
 	        NM_SETTING_IP4_CONFIG_ADDRESSES);
 
 	g_free (file);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -898,7 +911,7 @@ test_read_wired_dhcp (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-dhcp-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -1025,7 +1038,10 @@ test_read_wired_dhcp (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_DNS);
 
-
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -1068,7 +1084,7 @@ test_read_wired_global_gateway (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-global-gateway-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-global-gateway-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_GLOBAL_GATEWAY);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -1152,6 +1168,10 @@ test_read_wired_global_gateway (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_ADDRESSES);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -1191,7 +1211,7 @@ test_read_wired_never_default (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-never-default-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-never-default-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_NEVER_DEFAULT);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -1274,6 +1294,10 @@ test_read_wired_never_default (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -1312,7 +1336,7 @@ test_read_wired_defroute_no (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-defroute-no-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-defroute-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DEFROUTE_NO);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -1388,6 +1412,10 @@ test_read_wired_defroute_no (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -1433,7 +1461,7 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
 	        error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-defroute-no-gatewaydev-yes-verify",
 	        "failed to verify %s: unexpected unmanaged value",
 	        TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES);
@@ -1511,6 +1539,10 @@ test_read_wired_defroute_no_gatewaydev_yes (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -1672,6 +1704,7 @@ test_read_wired_static_routes (void)
 	        "wired-static-routes-verify-ip4", "failed to verify %s: unexpected route metric #2",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES);
 
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -1877,6 +1910,159 @@ test_read_wired_static_routes_legacy (void)
 	        "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 metric",
 	        TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+}
+
+static void
+test_read_wired_ipv4_manual (const char *file, const char *expected_id)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingWired *s_wired;
+	NMSettingIP4Config *s_ip4;
+	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_address1 = "1.2.3.4";
+	const char *expected_address2 = "9.8.7.6";
+	const char *expected_address3 = "3.3.3.3";
+	guint32 expected_prefix1 = 24;
+	guint32 expected_prefix2 = 16;
+	guint32 expected_prefix3 = 8;
+	NMIP4Address *ip4_addr;
+	struct in_addr addr;
+
+	connection = connection_from_file (file,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	ASSERT (connection != NULL,
+	        "wired-ipv4-manual-read", "failed to read %s: %s", file, error->message);
+
+	ASSERT (nm_connection_verify (connection, &error),
+	        "wired-ipv4-manual-verify", "failed to verify %s: %s", file, error->message);
+
+	ASSERT (unmanaged == NULL,
+	        "wired-ipv4-manual-verify", "failed to verify %s: unexpected unmanaged value", file);
+
+	/* ===== CONNECTION SETTING ===== */
+
+	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	ASSERT (s_con != NULL,
+	        "wired-ipv4-manual-verify-connection", "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,
+	        "wired-ipv4-manual-verify-connection", "failed to verify %s: missing %s / %s key",
+	        file,
+	        NM_SETTING_CONNECTION_SETTING_NAME,
+	        NM_SETTING_CONNECTION_ID);
+	ASSERT (strcmp (tmp, expected_id) == 0,
+	        "wired-ipv4-manual-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+	        file,
+	        NM_SETTING_CONNECTION_SETTING_NAME,
+	        NM_SETTING_CONNECTION_ID);
+
+	/* ===== WIRED SETTING ===== */
+
+	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	ASSERT (s_wired != NULL,
+	        "wired-ipv4-manual-verify-wired", "failed to verify %s: missing %s setting",
+	        file,
+	        NM_SETTING_WIRED_SETTING_NAME);
+
+	/* ===== IPv4 SETTING ===== */
+
+	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	ASSERT (s_ip4 != NULL,
+	        "wired-ipv4-manual-verify-ip4", "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,
+	        "wired-ipv4-manual-verify-ip4", "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) == 3,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+		file,
+		NM_SETTING_IP4_CONFIG_SETTING_NAME,
+		NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+	/* Address #1 */
+	ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+	ASSERT (ip4_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #1",
+		file);
+
+	ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix1,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
+		file);
+
+	ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
+		file);
+	ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
+		file);
+
+	/* Address #2 */
+	ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 1);
+	ASSERT (ip4_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #2",
+		file);
+
+	ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix2,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #2 prefix",
+		file);
+
+	ASSERT (inet_pton (AF_INET, expected_address2, &addr) > 0,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #2",
+		file);
+	ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #2",
+		file);
+
+	/* Address #3 */
+	ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 2);
+	ASSERT (ip4_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #3",
+		file);
+
+	ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix3,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #3 prefix",
+		file);
+
+	ASSERT (inet_pton (AF_INET, expected_address3, &addr) > 0,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #3",
+		file);
+	ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+		"wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #3",
+		file);
+
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -1933,7 +2119,7 @@ test_read_wired_ipv6_manual (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-ipv6-manual-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_MANUAL, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-ipv6-manual-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -2176,6 +2362,7 @@ test_read_wired_ipv6_manual (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_DNS);
 
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -2223,7 +2410,7 @@ test_read_wired_ipv6_only (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-ipv6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-ipv6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -2333,6 +2520,7 @@ test_read_wired_ipv6_only (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_DNS);
 
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -2375,7 +2563,7 @@ test_read_wired_dhcp6_only (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-dhcp6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-dhcp6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP6_ONLY);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -2438,6 +2626,7 @@ test_read_wired_dhcp6_only (void)
 	        NM_SETTING_IP6_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP6_CONFIG_METHOD);
 
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -2474,7 +2663,7 @@ test_read_onboot_no (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "onboot-no-verify", "failed to verify %s: %s", TEST_IFCFG_ONBOOT_NO, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "onboot-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_ONBOOT_NO);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -2492,6 +2681,10 @@ test_read_onboot_no (void)
 	        NM_SETTING_CONNECTION_SETTING_NAME,
 	        NM_SETTING_CONNECTION_AUTOCONNECT);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -2535,7 +2728,7 @@ test_read_wired_8021x_peap_mschapv2 (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-8021x-peap-mschapv2-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-8021x-peap-mschapv2-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2);
 
 	/* ===== WIRED SETTING ===== */
@@ -2678,6 +2871,10 @@ test_read_wired_8021x_peap_mschapv2 (void)
 
 	g_object_unref (tmp_8021x);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -2741,6 +2938,10 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags
 
 	g_free (dirname);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -2919,6 +3120,10 @@ test_read_wifi_open (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -2997,6 +3202,10 @@ test_read_wifi_open_auto (void)
 	        NM_SETTING_WIRELESS_SETTING_NAME,
 	        NM_SETTING_WIRELESS_MODE);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3081,7 +3290,11 @@ test_read_wifi_open_ssid_hex (void)
 	        TEST_IFCFG_WIFI_OPEN_SSID_HEX,
 	        NM_SETTING_WIRELESS_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SSID);
-	
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3108,6 +3321,11 @@ test_read_wifi_open_ssid_bad (const char *file, const char *test)
 	                                   &ignore_error);
 	ASSERT (connection == NULL, test, "unexpected success reading %s", file);
 	g_clear_error (&error);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 }
 
 #define TEST_IFCFG_WIFI_OPEN_SSID_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-quoted"
@@ -3191,7 +3409,11 @@ test_read_wifi_open_ssid_quoted (void)
 	        TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
 	        NM_SETTING_WIRELESS_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SSID);
-	
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3465,6 +3687,10 @@ test_read_wifi_wep (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3729,6 +3955,10 @@ test_read_wifi_wep_adhoc (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_DNS);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3865,6 +4095,10 @@ test_read_wifi_wep_passphrase (void)
 	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -3998,6 +4232,10 @@ test_read_wifi_wep_40_ascii (void)
 	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -4131,6 +4369,10 @@ test_read_wifi_wep_104_ascii (void)
 	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -4267,6 +4509,10 @@ test_read_wifi_leap (void)
 	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -4322,6 +4568,10 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte
 	g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == expected_flags);
 	g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -4637,6 +4887,10 @@ test_read_wifi_wpa_psk (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -4738,6 +4992,10 @@ test_read_wifi_wpa_psk_unquoted (void)
 	        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);
 }
 
@@ -4771,6 +5029,11 @@ test_read_wifi_wpa_psk_unquoted2 (void)
 	ASSERT (connection == NULL,
 	        "wifi-wpa-psk-unquoted-read", "unexpected success reading %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2);
 	g_clear_error (&error);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 }
 
 #define TEST_IFCFG_WIFI_WPA_PSK_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc"
@@ -4958,6 +5221,10 @@ test_read_wifi_wpa_psk_adhoc (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5110,6 +5377,10 @@ test_read_wifi_wpa_psk_hex (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5151,7 +5422,7 @@ test_read_wifi_wpa_eap_tls (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wifi-wpa-eap-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wifi-wpa-eap-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TLS);
 
 	/* ===== WIRELESS SETTING ===== */
@@ -5257,6 +5528,10 @@ test_read_wifi_wpa_eap_tls (void)
 	                    "wifi-wpa-eap-tls-verify-8021x",
 	                    NM_SETTING_802_1X_PRIVATE_KEY);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5297,7 +5572,7 @@ test_read_wifi_wpa_eap_ttls_tls (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS);
 
 	/* ===== WIRELESS SETTING ===== */
@@ -5425,6 +5700,10 @@ test_read_wifi_wpa_eap_ttls_tls (void)
 	        NM_SETTING_802_1X_SETTING_NAME,
 	        NM_SETTING_802_1X_IDENTITY);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5496,6 +5775,10 @@ test_read_wifi_dynamic_wep_leap (void)
 	g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "bill smith");
 	g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz");
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5537,7 +5820,7 @@ test_read_wifi_wep_eap_ttls_chap (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP);
 
 	/* ===== WIRELESS SETTING ===== */
@@ -5657,6 +5940,10 @@ test_read_wifi_wep_eap_ttls_chap (void)
 	        NM_SETTING_802_1X_SETTING_NAME,
 	        NM_SETTING_802_1X_PASSWORD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5699,7 +5986,7 @@ test_read_wired_qeth_static (void)
 	ASSERT (nm_connection_verify (connection, &error),
 	        "wired-qeth-static-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message);
 
-	ASSERT (unmanaged == FALSE,
+	ASSERT (unmanaged == NULL,
 	        "wired-qeth-static-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_QETH_STATIC);
 
 	/* ===== CONNECTION SETTING ===== */
@@ -5829,6 +6116,83 @@ test_read_wired_qeth_static (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_CTC_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ctc-static"
+
+static void
+test_read_wired_ctc_static (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingWired *s_wired;
+	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 test-wired-ctc-static";
+	const char *expected_channel0 = "0.0.1b00";
+	const char *expected_channel1 = "0.0.1b01";
+	const GPtrArray *subchannels;
+	gboolean success;
+
+	connection = connection_from_file (TEST_IFCFG_WIRED_CTC_STATIC,
+	                                   NULL,
+	                                   TYPE_ETHERNET,
+	                                   NULL,
+	                                   &unmanaged,
+	                                   &keyfile,
+	                                   &routefile,
+	                                   &route6file,
+	                                   &error,
+	                                   &ignore_error);
+	g_assert_no_error (error);
+	g_assert (connection);
+	
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (unmanaged == NULL);
+
+	/* ===== CONNECTION SETTING ===== */
+	s_con = nm_connection_get_setting_connection (connection);
+	g_assert (s_con != NULL);
+	g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
+
+	/* ===== WIRED SETTING ===== */
+	s_wired = nm_connection_get_setting_wired (connection);
+	g_assert (s_wired != NULL);
+
+	g_assert (nm_setting_wired_get_mac_address (s_wired) == NULL);
+
+	/* Subchannels */
+	subchannels = nm_setting_wired_get_s390_subchannels (s_wired);
+	g_assert (subchannels != NULL);
+	g_assert_cmpint (subchannels->len, ==, 2);
+
+	g_assert_cmpstr (g_ptr_array_index (subchannels, 0), ==, expected_channel0);
+	g_assert_cmpstr (g_ptr_array_index (subchannels, 1), ==, expected_channel1);
+
+	/* Nettype */
+	g_assert_cmpstr (nm_setting_wired_get_s390_nettype (s_wired), ==, "ctc");
+
+	/* port name */
+	tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot");
+	g_assert (tmp != NULL);
+	g_assert_cmpstr (tmp, ==, "0");
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -5952,6 +6316,10 @@ test_read_wifi_wep_no_keys (void)
 	        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 	        NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -6022,6 +6390,10 @@ test_read_permissions (void)
 	ASSERT (strcmp (tmp, "johnny5") == 0,
 	        "permissions-verify-permissions", "unexpected permission #3");
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -6086,6 +6458,10 @@ test_read_wifi_wep_agent_keys (void)
 	flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec);
 	g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -6316,6 +6692,7 @@ test_write_wired_static (void)
 		unlink (route6file);
 
 	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -6434,6 +6811,10 @@ test_write_wired_dhcp (void)
 	        "wired-dhcp-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);
 }
@@ -6571,6 +6952,7 @@ test_write_wired_static_ip6_only (void)
 		unlink (route6file);
 
 	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -6715,6 +7097,7 @@ test_read_write_static_routes_legacy (void)
 	        "read-write-static-routes-legacy-write", "written and re-read connection weren't the same.");
 
 	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (keyfile2);
 	g_free (routefile);
@@ -6896,6 +7279,7 @@ test_write_wired_static_routes (void)
 	        "wired-static-routes-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);
@@ -7037,6 +7421,10 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void)
 	        "wired-dhcp-8021x-peap-mschapv2write", "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);
 }
@@ -7265,6 +7653,10 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme,
 	g_free (tmp);
 
 	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 	g_object_unref (reread);
 }
@@ -7403,6 +7795,7 @@ test_write_wifi_open (void)
 	ASSERT (strncmp (tmp, "\"\"", 2) != 0,
 	        "wifi-open-write-reread", "unexpected ESSID double-quote in %s", testfile);
 
+	g_free (tmp);
 	svCloseFile (ifcfg);
 
 	unlink (testfile);
@@ -7417,6 +7810,10 @@ test_write_wifi_open (void)
 	        "wifi-open-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);
 }
@@ -7536,6 +7933,10 @@ test_write_wifi_open_hex_ssid (void)
 	        "wifi-open-hex-ssid-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);
 }
@@ -7687,6 +8088,10 @@ test_write_wifi_wep (void)
 	        "wifi-wep-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);
 }
@@ -7846,6 +8251,10 @@ test_write_wifi_wep_adhoc (void)
 	        "wifi-wep-adhoc-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);
 }
@@ -7995,6 +8404,10 @@ test_write_wifi_wep_passphrase (void)
 	        "wifi-wep-passphrase-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);
 }
@@ -8146,6 +8559,10 @@ test_write_wifi_wep_40_ascii (void)
 	        "wifi-wep-40-ascii-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);
 }
@@ -8297,6 +8714,10 @@ test_write_wifi_wep_104_ascii (void)
 	        "wifi-wep-104-ascii-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);
 }
@@ -8445,6 +8866,10 @@ test_write_wifi_leap (void)
 	        "wifi-leap-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);
 }
@@ -8571,6 +8996,10 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags)
 	g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
 
 	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 	g_object_unref (reread);
 }
@@ -8732,6 +9161,10 @@ test_write_wifi_wpa_psk (const char *name,
 	        test_name, "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);
 }
@@ -8889,6 +9322,10 @@ test_write_wifi_wpa_psk_adhoc (void)
 	        "wifi-wpa-psk-adhoc-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);
 }
@@ -9066,6 +9503,10 @@ test_write_wifi_wpa_eap_tls (void)
 	        "wifi-wpa-eap-tls-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);
 }
@@ -9261,6 +9702,10 @@ test_write_wifi_wpa_eap_ttls_tls (void)
 	        "wifi-wpa-eap-ttls-tls-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);
 }
@@ -9428,11 +9873,203 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void)
 	        "wifi-wpa-eap-ttls-mschapv2-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);
 }
 
 static void
+test_write_wifi_wpa_then_open (void)
+{
+	NMConnection *connection;
+	NMConnection *reread;
+	NMSettingConnection *s_con;
+	NMSettingWireless *s_wifi;
+	NMSettingWirelessSecurity *s_wsec;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	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;
+	GByteArray *ssid;
+	const unsigned char ssid_data[] = "blahblah";
+
+	/* Test that writing out a WPA config then changing that to an open
+	 * config doesn't leave various WPA-related keys lying around in the ifcfg.
+	 */
+
+	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, "random wifi connection",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* Wifi setting */
+	s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+	g_assert (s_wifi);
+	nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+	ssid = g_byte_array_sized_new (sizeof (ssid_data));
+	g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+	g_object_set (s_wifi,
+	              NM_SETTING_WIRELESS_SSID, ssid,
+	              NM_SETTING_WIRELESS_MODE, "infrastructure",
+	              NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+	              NULL);
+
+	g_byte_array_free (ssid, TRUE);
+
+	/* Wireless security setting */
+	s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	g_assert (s_wsec);
+	nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+	g_object_set (s_wsec,
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
+	              NM_SETTING_WIRELESS_SECURITY_PSK, "some cool PSK",
+	              NULL);
+
+	nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+	nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
+	nm_setting_wireless_security_add_group (s_wsec, "tkip");
+
+	nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+	nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+	nm_setting_wireless_security_add_group (s_wsec, "ccmp");
+
+	/* IP4 setting */
+	s_ip4 = (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_IGNORE, NULL);
+
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	/* Save the ifcfg */
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &testfile,
+	                                 &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (testfile);
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_WIRELESS,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	g_assert_no_error (error);
+	g_assert (reread);
+
+	success = nm_connection_verify (reread, &error);
+	g_assert_no_error (error);
+
+	success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (success);
+
+	g_free (unmanaged);
+	unmanaged = NULL;
+	g_free (routefile);
+	routefile = NULL;
+	g_free (route6file);
+	route6file = NULL;
+	g_object_unref (reread);
+
+	/* Now change the connection to open and recheck */
+	s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	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);
+
+	/* Write it back out */
+	success = writer_update_connection (connection,
+	                                    TEST_SCRATCH_DIR "/network-scripts/",
+	                                    testfile,
+	                                    keyfile,
+	                                    &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	unlink (keyfile);
+	g_free (keyfile);
+	keyfile = NULL;
+
+	/* re-read it for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_WIRELESS,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (testfile);
+	g_assert_no_error (error);
+
+	g_assert (reread);
+
+	/* No keyfile since it's an open connection this time */
+	g_assert (keyfile);
+	g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE);
+
+	success = nm_connection_verify (reread, &error);
+	g_assert_no_error (error);
+
+	success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (success);
+
+	unlink (testfile);
+	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (reread);
+
+	g_object_unref (connection);
+}
+
+static void
 test_write_wifi_dynamic_wep_leap (void)
 {
 	NMConnection *connection;
@@ -9568,11 +10205,16 @@ test_write_wifi_dynamic_wep_leap (void)
 
 	tmp = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE);
 	g_assert_cmpstr (tmp, ==, "LEAP");
+	g_free (tmp);
 
 	svCloseFile (ifcfg);
 	unlink (testfile);
 
 	g_free (testfile);
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 	g_object_unref (reread);
 }
@@ -9709,6 +10351,10 @@ test_read_ibft_dhcp (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_METHOD);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -9921,6 +10567,10 @@ test_read_ibft_static (void)
 	        NM_SETTING_IP4_CONFIG_SETTING_NAME,
 	        NM_SETTING_IP4_CONFIG_ADDRESSES);
 
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 	g_object_unref (connection);
 }
 
@@ -9949,6 +10599,11 @@ test_read_ibft_malformed (const char *name, const char *iscsiadm_path)
 	                                   &ignore_error);
 	ASSERT (connection == NULL,
 	        name, "unexpectedly able to read %s", TEST_IFCFG_IBFT_STATIC);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 }
 
 static void
@@ -10078,6 +10733,135 @@ test_write_wired_qeth_dhcp (void)
 		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);
+}
+
+static void
+test_write_wired_ctc_dhcp (void)
+{
+	NMConnection *connection;
+	NMConnection *reread;
+	NMSettingConnection *s_con;
+	NMSettingWired *s_wired;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	char *uuid;
+	GPtrArray *subchans;
+	gboolean success;
+	GError *error = NULL;
+	char *testfile = NULL;
+	char *unmanaged = NULL;
+	char *keyfile = NULL;
+	char *routefile = NULL;
+	char *route6file = NULL;
+	gboolean ignore_error = FALSE;
+	shvarFile *ifcfg;
+	char *tmp;
+
+	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, "Test Write Wired ctc Static",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* Wired setting */
+	s_wired = (NMSettingWired *) nm_setting_wired_new ();
+	g_assert (s_wired);
+	nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+	subchans = g_ptr_array_sized_new (2);
+	g_ptr_array_add (subchans, "0.0.600");
+	g_ptr_array_add (subchans, "0.0.601");
+	g_object_set (s_wired,
+	              NM_SETTING_WIRED_S390_SUBCHANNELS, subchans,
+	              NM_SETTING_WIRED_S390_NETTYPE, "ctc",
+	              NULL);
+	g_ptr_array_free (subchans, TRUE);
+	nm_setting_wired_add_s390_option (s_wired, "ctcprot", "0");
+
+	/* 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_IGNORE, NULL);
+
+	/* Verify */
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	/* Save the ifcfg */
+	success = writer_new_connection (connection,
+	                                 TEST_SCRATCH_DIR "/network-scripts/",
+	                                 &testfile,
+	                                 &error);
+	g_assert_no_error (error);
+	g_assert (success);
+	g_assert (testfile != NULL);
+
+	/* Ensure the CTCPROT item gets written out as it's own option */
+	ifcfg = svNewFile (testfile);
+	g_assert (ifcfg);
+
+	tmp = svGetValue (ifcfg, "CTCPROT", TRUE);
+	g_assert (tmp);
+	g_assert_cmpstr (tmp, ==, "0");
+	g_free (tmp);
+
+	/* And that it's not in the generic OPTIONS string */
+	tmp = svGetValue (ifcfg, "OPTIONS", TRUE);
+	g_assert (tmp == NULL);
+	g_free (tmp);
+
+	svCloseFile (ifcfg);
+
+	/* re-read the connection for comparison */
+	reread = connection_from_file (testfile,
+	                               NULL,
+	                               TYPE_ETHERNET,
+	                               NULL,
+	                               &unmanaged,
+	                               &keyfile,
+	                               &routefile,
+	                               &route6file,
+	                               &error,
+	                               &ignore_error);
+	unlink (testfile);
+
+	g_assert (reread);
+	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);
+
+	if (route6file)
+		unlink (route6file);
+
+	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -10200,6 +10984,7 @@ test_write_permissions (void)
 		unlink (route6file);
 
 	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -10330,6 +11115,7 @@ test_write_wifi_wep_agent_keys (void)
 		unlink (route6file);
 
 	g_free (testfile);
+	g_free (unmanaged);
 	g_free (keyfile);
 	g_free (routefile);
 	g_free (route6file);
@@ -10624,6 +11410,11 @@ test_read_bridge_main (void)
 	                                   &ignore_error);
 	ASSERT (connection == NULL,
 	        "bridge-main-read", "unexpected success reading %s", TEST_IFCFG_BRIDGE_MAIN);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 }
 
 #define TEST_IFCFG_BRIDGE_COMPONENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-component"
@@ -10658,8 +11449,11 @@ test_read_bridge_component (void)
 	ASSERT (g_strcmp0 (unmanaged, "mac:00:22:15:59:62:97") == 0,
 	        "bridge-component-read", "unexpected unmanaged spec from %s", TEST_IFCFG_BRIDGE_COMPONENT);
 
-	g_object_unref (connection);
 	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
+	g_object_unref (connection);
 }
 
 #define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-interface"
@@ -10687,6 +11481,11 @@ test_read_vlan_interface (void)
 	                                   &ignore_error);
 	ASSERT (connection == NULL,
 	        "vlan-interface-read", "unexpected success reading %s", TEST_IFCFG_VLAN_INTERFACE);
+
+	g_free (unmanaged);
+	g_free (keyfile);
+	g_free (routefile);
+	g_free (route6file);
 }
 
 #define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex"
@@ -10697,6 +11496,11 @@ test_read_vlan_interface (void)
 #define TEST_IFCFG_WIRED_STATIC           TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static"
 #define TEST_IFCFG_WIRED_STATIC_BOOTPROTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-bootproto"
 
+#define TEST_IFCFG_WIRED_IPV4_MANUAL_1 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv4-manual-1"
+#define TEST_IFCFG_WIRED_IPV4_MANUAL_2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv4-manual-2"
+#define TEST_IFCFG_WIRED_IPV4_MANUAL_3 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv4-manual-3"
+#define TEST_IFCFG_WIRED_IPV4_MANUAL_4 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv4-manual-4"
+
 #define DEFAULT_HEX_PSK "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0"
 
 int main (int argc, char **argv)
@@ -10724,6 +11528,10 @@ int main (int argc, char **argv)
 	test_read_wired_defroute_no_gatewaydev_yes ();
 	test_read_wired_static_routes ();
 	test_read_wired_static_routes_legacy ();
+	test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_1, "System test-wired-ipv4-manual-1");
+	test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_2, "System test-wired-ipv4-manual-2");
+	test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_3, "System test-wired-ipv4-manual-3");
+	test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_4, "System test-wired-ipv4-manual-4");
 	test_read_wired_ipv6_manual ();
 	test_read_wired_ipv6_only ();
 	test_read_wired_dhcp6_only ();
@@ -10758,6 +11566,7 @@ int main (int argc, char **argv)
 	test_read_wifi_wpa_eap_ttls_tls ();
 	test_read_wifi_wep_eap_ttls_chap ();
 	test_read_wired_qeth_static ();
+	test_read_wired_ctc_static ();
 	test_read_wifi_wep_no_keys ();
 	test_read_permissions ();
 	test_read_wifi_wep_agent_keys ();
@@ -10818,7 +11627,9 @@ int main (int argc, char **argv)
 	test_write_wifi_wpa_eap_ttls_tls ();
 	test_write_wifi_wpa_eap_ttls_mschapv2 ();
 	test_write_wifi_dynamic_wep_leap ();
+	test_write_wifi_wpa_then_open ();
 	test_write_wired_qeth_dhcp ();
+	test_write_wired_ctc_dhcp ();
 	test_write_permissions ();
 	test_write_wifi_wep_agent_keys ();
 
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index 6924262f..6b66b232 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -354,6 +354,7 @@ write_object (NMSetting8021x *s_8021x,
 		success = write_secret_file (new_file, (const char *) blob->data, blob->len, &write_error);
 		if (success) {
 			svSetValue (ifcfg, objtype->ifcfg_key, new_file, FALSE);
+			g_free (new_file);
 			return TRUE;
 		} else {
 			g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
@@ -884,6 +885,38 @@ write_wireless_setting (NMConnection *connection,
 	if (nm_setting_wireless_get_security (s_wireless)) {
 		if (!write_wireless_security_setting (connection, ifcfg, adhoc, no_8021x, error))
 			return FALSE;
+	} else {
+		char *keys_path;
+
+		/* Clear out wifi security keys */
+		svSetValue (ifcfg, "KEY_MGMT", NULL, FALSE);
+		svSetValue (ifcfg, "IEEE_8021X_IDENTITY", NULL, FALSE);
+		set_secret (ifcfg, "IEEE_8021X_PASSWORD", NULL, "IEEE_8021X_PASSWORD_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+		svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE);
+
+		/* Clear existing keys */
+		set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+		for (i = 0; i < 4; i++) {
+			tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1);
+			set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+			g_free (tmp);
+	
+			tmp = g_strdup_printf ("KEY%d", i + 1);
+			set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+			g_free (tmp);
+		}
+
+		svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE);
+		svSetValue (ifcfg, "WPA_ALLOW_WPA", NULL, FALSE);
+		svSetValue (ifcfg, "WPA_ALLOW_WPA2", NULL, FALSE);
+		svSetValue (ifcfg, "CIPHER_PAIRWISE", NULL, FALSE);
+		svSetValue (ifcfg, "CIPHER_GROUP", NULL, FALSE);
+		set_secret (ifcfg, "WPA_PSK", NULL, "WPA_PSK_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+
+		/* Kill any old keys file */
+		keys_path = utils_get_keys_path (ifcfg->fileName);
+		(void) unlink (keys_path);
+		g_free (keys_path);
 	}
 
 	svSetValue (ifcfg, "TYPE", TYPE_WIRELESS, FALSE);
@@ -897,7 +930,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	NMSettingWired *s_wired;
 	const GByteArray *device_mac, *cloned_mac;
 	char *tmp;
-	const char *nettype, *portname, *s390_key, *s390_val;
+	const char *nettype, *portname, *ctcprot, *s390_key, *s390_val;
 	guint32 mtu, num_opts, i;
 	const GPtrArray *s390_subchannels;
 	GString *str;
@@ -964,6 +997,11 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	if (portname)
 		svSetValue (ifcfg, "PORTNAME", portname, FALSE);
 
+	svSetValue (ifcfg, "CTCPROT", NULL, FALSE);
+	ctcprot = nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot");
+	if (ctcprot)
+		svSetValue (ifcfg, "CTCPROT", ctcprot, FALSE);
+
 	svSetValue (ifcfg, "OPTIONS", NULL, FALSE);
 	num_opts = nm_setting_wired_get_num_s390_options (s_wired);
 	if (s390_subchannels && num_opts) {
@@ -972,7 +1010,7 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 			nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val);
 
 			/* portname is handled separately */
-			if (!strcmp (s390_key, "portname"))
+			if (!strcmp (s390_key, "portname") || !strcmp (s390_key, "ctcprot"))
 				continue;
 
 			if (str->len)
@@ -1090,6 +1128,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	const char *value;
 	char *addr_key, *prefix_key, *netmask_key, *gw_key, *metric_key, *tmp;
 	char *route_path = NULL;
+	gint32 j;
 	guint32 i, num;
 	GString *searches;
 	gboolean success = FALSE;
@@ -1109,20 +1148,28 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 
 		/* IPv4 disabled, clear IPv4 related parameters */
 		svSetValue (ifcfg, "BOOTPROTO", NULL, FALSE);
-		for (i = 0; i < 254; i++) {
-			if (i == 0) {
+		for (j = -1; j < 256; j++) {
+			if (j == -1) {
 				addr_key = g_strdup ("IPADDR");
 				prefix_key = g_strdup ("PREFIX");
+				netmask_key = g_strdup ("NETMASK");
 				gw_key = g_strdup ("GATEWAY");
 			} else {
-				addr_key = g_strdup_printf ("IPADDR%d", i + 1);
-				prefix_key = g_strdup_printf ("PREFIX%d", i + 1);
-				gw_key = g_strdup_printf ("GATEWAY%d", i + 1);
+				addr_key = g_strdup_printf ("IPADDR%d", j);
+				prefix_key = g_strdup_printf ("PREFIX%d", j);
+				netmask_key = g_strdup_printf ("NETMASK%d", j);
+				gw_key = g_strdup_printf ("GATEWAY%d", j);
 			}
 
 			svSetValue (ifcfg, addr_key, NULL, FALSE);
 			svSetValue (ifcfg, prefix_key, NULL, FALSE);
+			svSetValue (ifcfg, netmask_key, NULL, FALSE);
 			svSetValue (ifcfg, gw_key, NULL, FALSE);
+
+			g_free (addr_key);
+			g_free (prefix_key);
+			g_free (netmask_key);
+			g_free (gw_key);
 		}
 
 		route_path = utils_get_route_path (ifcfg->fileName);
@@ -1146,25 +1193,27 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 	else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
 		svSetValue (ifcfg, "BOOTPROTO", "shared", FALSE);
 
+	/* Write out IPADDR0 .. IPADDR255, PREFIX0 .. PREFIX255, GATEWAY0 .. GATEWAY255
+	 * Possible NETMASK<n> is removed only (it's obsolete) */
 	num = nm_setting_ip4_config_get_num_addresses (s_ip4);
-	for (i = 0; i < 254; i++) {
-		char buf[INET_ADDRSTRLEN + 1];
+	svSetValue (ifcfg, "IPADDR", NULL, FALSE);
+	svSetValue (ifcfg, "PREFIX", NULL, FALSE);
+	svSetValue (ifcfg, "NETMASK", NULL, FALSE);
+	svSetValue (ifcfg, "GATEWAY", NULL, FALSE);
+	for (i = 0; i < 256; i++) {
+		char buf[INET_ADDRSTRLEN];
 		NMIP4Address *addr;
 		guint32 ip;
 
-		if (i == 0) {
-			addr_key = g_strdup ("IPADDR");
-			prefix_key = g_strdup ("PREFIX");
-			gw_key = g_strdup ("GATEWAY");
-		} else {
-			addr_key = g_strdup_printf ("IPADDR%d", i + 1);
-			prefix_key = g_strdup_printf ("PREFIX%d", i + 1);
-			gw_key = g_strdup_printf ("GATEWAY%d", i + 1);
-		}
+		addr_key = g_strdup_printf ("IPADDR%d", i);
+		prefix_key = g_strdup_printf ("PREFIX%d", i);
+		netmask_key = g_strdup_printf ("NETMASK%d", i);
+		gw_key = g_strdup_printf ("GATEWAY%d", i);
 
 		if (i >= num) {
 			svSetValue (ifcfg, addr_key, NULL, FALSE);
 			svSetValue (ifcfg, prefix_key, NULL, FALSE);
+			svSetValue (ifcfg, netmask_key, NULL, FALSE);
 			svSetValue (ifcfg, gw_key, NULL, FALSE);
 		} else {
 			addr = nm_setting_ip4_config_get_address (s_ip4, i);
@@ -1189,6 +1238,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 
 		g_free (addr_key);
 		g_free (prefix_key);
+		g_free (netmask_key);
 		g_free (gw_key);
 	}
 
diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in
index 2a8a1639..02e2247a 100644
--- a/src/settings/plugins/ifcfg-suse/Makefile.in
+++ b/src/settings/plugins/ifcfg-suse/Makefile.in
@@ -139,6 +139,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -256,6 +260,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -277,6 +283,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in
index 793258f7..2bc7bc32 100644
--- a/src/settings/plugins/ifnet/Makefile.in
+++ b/src/settings/plugins/ifnet/Makefile.in
@@ -187,6 +187,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -304,6 +308,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -325,6 +331,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in
index adb1816c..17b80c36 100644
--- a/src/settings/plugins/ifnet/tests/Makefile.in
+++ b/src/settings/plugins/ifnet/tests/Makefile.in
@@ -110,6 +110,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -227,6 +231,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -248,6 +254,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in
index af545df7..5f5a456b 100644
--- a/src/settings/plugins/ifupdown/Makefile.in
+++ b/src/settings/plugins/ifupdown/Makefile.in
@@ -186,6 +186,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -303,6 +307,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -324,6 +330,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in
index 8bd83a15..7412e65d 100644
--- a/src/settings/plugins/ifupdown/tests/Makefile.in
+++ b/src/settings/plugins/ifupdown/tests/Makefile.in
@@ -110,6 +110,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -227,6 +231,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -248,6 +254,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in
index 409499d7..a2a7d231 100644
--- a/src/settings/plugins/keyfile/Makefile.in
+++ b/src/settings/plugins/keyfile/Makefile.in
@@ -162,6 +162,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -279,6 +283,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -300,6 +306,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in
index 733b4916..05ed3a61 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/Makefile.in
@@ -148,6 +148,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -265,6 +269,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -286,6 +292,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
index 0b0b3551..2c3c1630 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
@@ -76,6 +76,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -193,6 +197,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -214,6 +220,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in
index 70e6b17e..33c4bd38 100644
--- a/src/settings/tests/Makefile.in
+++ b/src/settings/tests/Makefile.in
@@ -112,6 +112,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -229,6 +233,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -250,6 +256,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in
index cfee4510..729917d3 100644
--- a/src/supplicant-manager/Makefile.in
+++ b/src/supplicant-manager/Makefile.in
@@ -153,6 +153,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -270,6 +274,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -291,6 +297,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index 6ee9c510..81d68bb3 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -695,6 +695,14 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
 			if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, connection_uid, FALSE))
 				return FALSE;
 		}
+
+		if (!strcmp (key_mgmt, "wpa-eap")) {
+			/* If using WPA Enterprise, enable optimized background scanning
+			 * to ensure roaming within an ESS works well.
+			 */
+			if (!nm_supplicant_config_add_option (self, "bgscan", "simple:30:-45:300", -1, FALSE))
+				nm_log_warn (LOGD_SUPPLICANT, "Error enabling background scanning for ESS roaming");
+		}
 	}
 
 	return TRUE;
diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.c b/src/supplicant-manager/nm-supplicant-settings-verify.c
index c65af4de..0372fd93 100644
--- a/src/supplicant-manager/nm-supplicant-settings-verify.c
+++ b/src/supplicant-manager/nm-supplicant-settings-verify.c
@@ -124,6 +124,7 @@ static const struct Opt opt_table[] = {
 	{ "key_id",             TYPE_BYTES,   0, 0, FALSE,  NULL },
 	{ "fragment_size",      TYPE_INT,     1, 2000, FALSE,  NULL },
 	{ "proactive_key_caching", TYPE_INT,  0, 1, FALSE,  NULL },
+	{ "bgscan",             TYPE_BYTES,   0, 0, FALSE,  NULL },
 };
 
 
diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in
index 58cb15f3..18288c6e 100644
--- a/src/supplicant-manager/tests/Makefile.in
+++ b/src/supplicant-manager/tests/Makefile.in
@@ -112,6 +112,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -229,6 +233,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -250,6 +256,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index f702ac86..0f19b712 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -129,6 +129,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -246,6 +250,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -267,6 +273,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c
index deb31f3f..93bd325a 100644
--- a/src/tests/test-wifi-ap-utils.c
+++ b/src/tests/test-wifi-ap-utils.c
@@ -77,6 +77,14 @@ complete_connection (const char *ssid,
 {
 	GByteArray *tmp;
 	gboolean success;
+	NMSettingWireless *s_wifi;
+
+	/* Add a wifi setting if one doesn't exist */
+	s_wifi = nm_connection_get_setting_wireless (src);
+	if (!s_wifi) {
+		s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+		nm_connection_add_setting (src, NM_SETTING (s_wifi));
+	}
 
 	tmp = g_byte_array_sized_new (strlen (ssid));
 	g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid));
diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in
index 8903d70e..a8fea32d 100644
--- a/src/vpn-manager/Makefile.in
+++ b/src/vpn-manager/Makefile.in
@@ -114,6 +114,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -231,6 +235,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -252,6 +258,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
diff --git a/src/vpn-manager/nm-vpn-connection-base.c b/src/vpn-manager/nm-vpn-connection-base.c
index 7fde5db0..c7373627 100644
--- a/src/vpn-manager/nm-vpn-connection-base.c
+++ b/src/vpn-manager/nm-vpn-connection-base.c
@@ -44,6 +44,7 @@ typedef struct {
 enum {
 	PROP_0,
 	PROP_CONNECTION,
+	PROP_UUID,
 	PROP_SPECIFIC_OBJECT,
 	PROP_DEVICES,
 	PROP_STATE,
@@ -143,6 +144,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CONNECTION:
 		g_value_set_boxed (value, nm_connection_get_path (priv->connection));
 		break;
+	case PROP_UUID:
+		g_value_set_boxed (value, nm_connection_get_uuid (priv->connection));
+		break;
 	case PROP_SPECIFIC_OBJECT:
 		g_value_set_boxed (value, priv->ac_path);
 		break;
@@ -181,6 +185,7 @@ nm_vpn_connection_base_class_init (NMVpnConnectionBaseClass *vpn_class)
 	/* properties */
     nm_active_connection_install_properties (object_class,
                                              PROP_CONNECTION,
+                                             PROP_UUID,
                                              PROP_SPECIFIC_OBJECT,
                                              PROP_DEVICES,
                                              PROP_STATE,
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 601d29bc..cf6135a6 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.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) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
@@ -60,7 +60,6 @@ typedef struct {
 
 	gboolean user_requested;
 	gulong user_uid;
-	NMActRequest *act_request;
 	guint32 secrets_id;
 	char *username;
 
@@ -141,7 +140,9 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
 		nm_utils_call_dispatcher ("vpn-up",
 		                          priv->connection,
 		                          priv->parent_dev,
-		                          ip_iface);
+		                          ip_iface,
+		                          priv->ip4_config,
+		                          NULL);
 		break;
 	case NM_VPN_CONNECTION_STATE_FAILED:
 	case NM_VPN_CONNECTION_STATE_DISCONNECTED:
@@ -149,7 +150,9 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
 			nm_utils_call_dispatcher ("vpn-down",
 			                          priv->connection,
 			                          priv->parent_dev,
-			                          ip_iface);
+			                          ip_iface,
+			                          NULL,
+			                          NULL);
 		}
 		break;
 	default:
@@ -201,7 +204,6 @@ device_ip4_config_changed (NMDevice *device,
 
 NMVPNConnection *
 nm_vpn_connection_new (NMConnection *connection,
-                       NMActRequest *act_request,
                        NMDevice *parent_device,
                        gboolean user_requested,
                        gulong user_uid)
@@ -210,7 +212,6 @@ nm_vpn_connection_new (NMConnection *connection,
 	NMVPNConnectionPrivate *priv;
 
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
 	g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
 
 	self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
@@ -223,7 +224,6 @@ nm_vpn_connection_new (NMConnection *connection,
 	priv->user_uid = user_uid;
 	priv->connection = g_object_ref (connection);
 	priv->parent_dev = g_object_ref (parent_device);
-	priv->act_request = g_object_ref (act_request);
 
 	priv->device_monitor = g_signal_connect (parent_device, "state-changed",
 									 G_CALLBACK (device_state_changed),
@@ -1074,7 +1074,6 @@ dispose (GObject *object)
 		                                       priv->secrets_id);
 	}
 
-	g_object_unref (priv->act_request);
 	g_object_unref (priv->connection);
 	g_free (priv->username);
 
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index fd5ee24e..ee8eb5b6 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -26,7 +26,6 @@
 #include <glib-object.h>
 #include "NetworkManagerVPN.h"
 #include "nm-device.h"
-#include "nm-activation-request.h"
 #include "nm-vpn-connection-base.h"
 
 #define NM_TYPE_VPN_CONNECTION            (nm_vpn_connection_get_type ())
@@ -57,7 +56,6 @@ typedef struct {
 GType nm_vpn_connection_get_type (void);
 
 NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
-                                         NMActRequest *act_request,
                                          NMDevice *parent_device,
                                          gboolean user_requested,
                                          gulong user_uid);
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c
index 2bd8f236..6772bb18 100644
--- a/src/vpn-manager/nm-vpn-manager.c
+++ b/src/vpn-manager/nm-vpn-manager.c
@@ -161,7 +161,6 @@ connection_vpn_state_changed (NMVPNConnection *connection,
 NMVPNConnection *
 nm_vpn_manager_activate_connection (NMVPNManager *manager,
                                     NMConnection *connection,
-                                    NMActRequest *act_request,
                                     NMDevice *device,
                                     gboolean user_requested,
                                     gulong user_uid,
@@ -174,7 +173,6 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 
 	g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 	g_return_val_if_fail (error != NULL, NULL);
 	g_return_val_if_fail (*error == NULL, NULL);
@@ -211,7 +209,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 		return NULL;
 	}
 
-	vpn = nm_vpn_service_activate (service, connection, act_request, device, user_requested, user_uid, error);
+	vpn = nm_vpn_service_activate (service, connection, device, user_requested, user_uid, error);
 	if (vpn) {
 		g_signal_connect (vpn, "vpn-state-changed",
 		                  G_CALLBACK (connection_vpn_state_changed),
diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h
index 6159bb86..a899122c 100644
--- a/src/vpn-manager/nm-vpn-manager.h
+++ b/src/vpn-manager/nm-vpn-manager.h
@@ -25,7 +25,6 @@
 #include <glib.h>
 #include <glib-object.h>
 #include "nm-vpn-connection.h"
-#include "nm-activation-request.h"
 
 #define NM_TYPE_VPN_MANAGER            (nm_vpn_manager_get_type ())
 #define NM_VPN_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager))
@@ -69,7 +68,6 @@ NMVPNManager *nm_vpn_manager_get (void);
 
 NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager,
                                                      NMConnection *connection,
-                                                     NMActRequest *act_request,
                                                      NMDevice *device,
                                                      gboolean user_requested,
                                                      gulong user_uid,
diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c
index 3b4e2b48..ed08a40a 100644
--- a/src/vpn-manager/nm-vpn-service.c
+++ b/src/vpn-manager/nm-vpn-service.c
@@ -323,7 +323,6 @@ connection_vpn_state_changed (NMVPNConnection *connection,
 NMVPNConnection *
 nm_vpn_service_activate (NMVPNService *service,
                          NMConnection *connection,
-                         NMActRequest *act_request,
                          NMDevice *device,
                          gboolean user_requested,
                          gulong user_uid,
@@ -334,7 +333,6 @@ nm_vpn_service_activate (NMVPNService *service,
 
 	g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-	g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 	g_return_val_if_fail (error != NULL, NULL);
 	g_return_val_if_fail (*error == NULL, NULL);
@@ -343,7 +341,7 @@ nm_vpn_service_activate (NMVPNService *service,
 
 	clear_quit_timeout (service);
 
-	vpn = nm_vpn_connection_new (connection, act_request, device, user_requested, user_uid);
+	vpn = nm_vpn_connection_new (connection, device, user_requested, user_uid);
 	g_signal_connect (vpn, "vpn-state-changed",
 				   G_CALLBACK (connection_vpn_state_changed),
 				   service);
diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h
index 0c2445e2..cbe394ca 100644
--- a/src/vpn-manager/nm-vpn-service.h
+++ b/src/vpn-manager/nm-vpn-service.h
@@ -26,7 +26,6 @@
 #include <glib-object.h>
 #include "nm-device.h"
 #include "nm-vpn-connection.h"
-#include "nm-activation-request.h"
 
 #define NM_TYPE_VPN_SERVICE            (nm_vpn_service_get_type ())
 #define NM_VPN_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVPNService))
@@ -57,7 +56,6 @@ const char *nm_vpn_service_get_name_file (NMVPNService *service);
 
 NMVPNConnection * nm_vpn_service_activate (NMVPNService *service,
                                            NMConnection *connection,
-                                           NMActRequest *act_request,
                                            NMDevice *device,
                                            gboolean user_requested,
                                            gulong user_uid,
diff --git a/src/wimax/Makefile.in b/src/wimax/Makefile.in
index b65d5ea9..e6064bc6 100644
--- a/src/wimax/Makefile.in
+++ b/src/wimax/Makefile.in
@@ -110,6 +110,10 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DATADIRNAME = @DATADIRNAME@
 DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -227,6 +231,8 @@ POLKIT_CFLAGS = @POLKIT_CFLAGS@
 POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
 RESOLVCONF_PATH = @RESOLVCONF_PATH@
 SED = @SED@
@@ -248,6 +254,7 @@ abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
 ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@