about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/Makefile.in56
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c74
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient.c17
-rw-r--r--src/dns-manager/nm-dns-manager.c27
-rw-r--r--src/dns-manager/nm-dns-manager.h5
-rw-r--r--src/gdb-cmd3
-rw-r--r--src/generated/nm-enum-types.c219
-rw-r--r--src/generated/nm-enum-types.h28
-rw-r--r--src/main.c5
-rw-r--r--src/modem-manager/nm-modem.c17
-rw-r--r--src/nm-activation-request.c8
-rw-r--r--src/nm-active-connection.c10
-rw-r--r--src/nm-device-bt.c9
-rw-r--r--src/nm-device-wifi.c22
-rw-r--r--src/nm-device-wifi.h1
-rw-r--r--src/nm-device.c2
-rw-r--r--src/nm-netlink-monitor.c5
-rw-r--r--src/nm-policy.c110
-rw-r--r--src/nm-system.c2
-rw-r--r--src/settings/nm-settings-connection.c5
-rw-r--r--src/settings/nm-settings.c12
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile.c12
-rw-r--r--src/wifi/wifi-utils-nl80211.c29
-rw-r--r--src/wifi/wifi-utils-wext.c6
25 files changed, 414 insertions, 273 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index cd124f6b..9d306a7e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -355,9 +355,6 @@ endif
 
 NetworkManager_LDFLAGS = -rdynamic
 
-NetworkManagerdir = $(datadir)/NetworkManager
-NetworkManager_DATA = gdb-cmd
-
 dbusservicedir = $(DBUS_SYS_DIR)
 dbusservice_DATA = org.freedesktop.NetworkManager.conf
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 0a7e87f9..c577cccd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -113,8 +113,7 @@ am_libtest_wifi_ap_utils_la_OBJECTS =  \
 	libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo
 libtest_wifi_ap_utils_la_OBJECTS =  \
 	$(am_libtest_wifi_ap_utils_la_OBJECTS)
-am__installdirs = "$(DESTDIR)$(sbindir)" \
-	"$(DESTDIR)$(NetworkManagerdir)" "$(DESTDIR)$(dbusservicedir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(dbusservicedir)"
 PROGRAMS = $(sbin_PROGRAMS)
 am__NetworkManager_SOURCES_DIST = nm-types.h nm-call-store.c \
 	nm-call-store.h nm-device.c nm-device.h nm-device-private.h \
@@ -294,7 +293,7 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-DATA = $(NetworkManager_DATA) $(dbusservice_DATA)
+DATA = $(dbusservice_DATA)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
 AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
@@ -735,8 +734,6 @@ NetworkManager_LDADD = ./generated/libnm-generated.la \
 	$(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(POLKIT_LIBS) \
 	$(SYSTEMD_LOGIN_LIBS) $(LIBM) $(LIBDL) $(am__append_10)
 NetworkManager_LDFLAGS = -rdynamic
-NetworkManagerdir = $(datadir)/NetworkManager
-NetworkManager_DATA = gdb-cmd
 dbusservicedir = $(DBUS_SYS_DIR)
 dbusservice_DATA = org.freedesktop.NetworkManager.conf
 EXTRA_DIST = \
@@ -1617,27 +1614,6 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-NetworkManagerDATA: $(NetworkManager_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(NetworkManager_DATA)'; test -n "$(NetworkManagerdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(NetworkManagerdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(NetworkManagerdir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(NetworkManagerdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(NetworkManagerdir)" || exit $$?; \
-	done
-
-uninstall-NetworkManagerDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(NetworkManager_DATA)'; test -n "$(NetworkManagerdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(NetworkManagerdir)'; $(am__uninstall_files_from_dir)
 install-dbusserviceDATA: $(dbusservice_DATA)
 	@$(NORMAL_INSTALL)
 	@list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \
@@ -1856,7 +1832,7 @@ check: $(BUILT_SOURCES)
 all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
 installdirs: installdirs-recursive
 installdirs-am:
-	for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(NetworkManagerdir)" "$(DESTDIR)$(dbusservicedir)"; do \
+	for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(dbusservicedir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: $(BUILT_SOURCES)
@@ -1915,7 +1891,7 @@ info: info-recursive
 
 info-am:
 
-install-data-am: install-NetworkManagerDATA install-dbusserviceDATA
+install-data-am: install-dbusserviceDATA
 	@$(NORMAL_INSTALL)
 	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 install-dvi: install-dvi-recursive
@@ -1962,8 +1938,7 @@ ps: ps-recursive
 
 ps-am:
 
-uninstall-am: uninstall-NetworkManagerDATA uninstall-dbusserviceDATA \
-	uninstall-sbinPROGRAMS
+uninstall-am: uninstall-dbusserviceDATA uninstall-sbinPROGRAMS
 
 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
 	ctags-recursive install install-am install-data-am \
@@ -1974,17 +1949,16 @@ uninstall-am: uninstall-NetworkManagerDATA uninstall-dbusserviceDATA \
 	clean-noinstLTLIBRARIES clean-sbinPROGRAMS ctags \
 	ctags-recursive distclean distclean-compile distclean-generic \
 	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-NetworkManagerDATA \
-	install-am install-data install-data-am install-data-hook \
-	install-dbusserviceDATA install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
-	uninstall uninstall-NetworkManagerDATA uninstall-am \
+	html-am info info-am install install-am install-data \
+	install-data-am install-data-hook install-dbusserviceDATA \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-sbinPROGRAMS install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am \
 	uninstall-dbusserviceDATA uninstall-sbinPROGRAMS
 
 
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index 2cdd304d..7bcf935b 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -323,6 +323,32 @@ nm_dhcp_client_start_ip4 (NMDHCPClient *self,
 	return priv->pid ? TRUE : FALSE;
 }
 
+/* uuid_parse does not work for machine-id, so we use our own converter */
+static gboolean
+machine_id_parse (const char *in, uuid_t uu)
+{
+	const char *cp;
+	int i;
+	char buf[3];
+
+	g_return_val_if_fail (in != NULL, FALSE);
+	g_return_val_if_fail (strlen (in) == 32, FALSE);
+
+	for (i = 0; i < 32; i++, cp++) {
+		if (!g_ascii_isxdigit (in[i]))
+			return FALSE;
+	}
+
+	buf[2] = 0;
+	cp = in;
+	for (i = 0; i < 16; i++) {
+		buf[0] = *cp++;
+		buf[1] = *cp++;
+		uu[i] = ((unsigned char) strtoul (buf, NULL, 16)) & 0xFF;
+	}
+	return TRUE;
+}
+
 static GByteArray *
 generate_duid_from_machine_id (void)
 {
@@ -334,7 +360,7 @@ generate_duid_from_machine_id (void)
 	gsize sumlen = sizeof (buffer);
 	const guint16 duid_type = g_htons (4);
 	uuid_t uuid;
-	int ret;
+	gboolean success;
 
 	/* Get the machine ID from /etc/machine-id; it's always in /etc no matter
 	 * where our configured SYSCONFDIR is.
@@ -348,10 +374,10 @@ generate_duid_from_machine_id (void)
 	}
 
 	contents = g_strstrip (contents);
-	ret = uuid_parse (contents, uuid);
+	success = machine_id_parse (contents, uuid);
 	g_free (contents);
 
-	if (ret != 0) {
+	if (!success) {
 		nm_log_warn (LOGD_DHCP6, "Failed to parse " SYSCONFDIR "/machine-id to generate DHCPv6 DUID.");
 		return NULL;
 	}
@@ -379,23 +405,6 @@ generate_duid_from_machine_id (void)
 	return duid;
 }
 
-static GByteArray *
-get_duid (NMDHCPClient *self)
-{
-	static GByteArray *duid = NULL;
-	GByteArray *copy = NULL;
-
-	if (G_UNLIKELY (duid == NULL))
-		duid = generate_duid_from_machine_id ();
-
-	if (G_LIKELY (duid)) {
-		copy = g_byte_array_sized_new (duid->len);
-		g_byte_array_append (copy, duid->data, duid->len);
-	}
-
-	return copy;
-}
-
 static char *
 escape_duid (const GByteArray *duid)
 {
@@ -413,6 +422,31 @@ escape_duid (const GByteArray *duid)
 	return g_string_free (s, FALSE);
 }
 
+static GByteArray *
+get_duid (NMDHCPClient *self)
+{
+	static GByteArray *duid = NULL;
+	GByteArray *copy = NULL;
+	char *escaped;
+
+	if (G_UNLIKELY (duid == NULL)) {
+		duid = generate_duid_from_machine_id ();
+
+		if (nm_logging_level_enabled (LOGL_DEBUG)) {
+			escaped = escape_duid (duid);
+			nm_log_dbg (LOGD_DHCP6, "Generated DUID from machine-id: %s", escaped);
+			g_free (escaped);
+		}
+	}
+
+	if (G_LIKELY (duid)) {
+		copy = g_byte_array_sized_new (duid->len);
+		g_byte_array_append (copy, duid->data, duid->len);
+	}
+
+	return copy;
+}
+
 gboolean
 nm_dhcp_client_start_ip6 (NMDHCPClient *self,
                           NMSettingIP6Config *s_ip6,
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
index d9f51352..c43ecf50 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient.c
@@ -455,8 +455,9 @@ dhclient_start (NMDHCPClient *client,
 	GError *error = NULL;
 	const char *iface, *uuid, *system_bus_address;
 	char *binary_name, *cmd_str, *pid_file = NULL, *system_bus_address_env = NULL;
-	gboolean ipv6;
+	gboolean ipv6, success;
 	guint log_domain;
+	char *escaped;
 
 	g_return_val_if_fail (priv->pid_file == NULL, -1);
 
@@ -497,6 +498,20 @@ dhclient_start (NMDHCPClient *client,
 		return -1;
 	}
 
+	/* Save the DUID to the leasefile dhclient will actually use */
+	if (ipv6) {
+		escaped = nm_dhcp_dhclient_escape_duid (duid);
+		success = nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &error);
+		g_free (escaped);
+		if (!success) {
+			nm_log_warn (log_domain, "(%s): failed to save DUID to %s: (%d) %s.",
+			             iface, priv->lease_file,
+			             error ? error->code : -1,
+			             error && error->message ? error->message : "(unknown)");
+			return -1;
+		}
+	}
+
 	argv = g_ptr_array_new ();
 	g_ptr_array_add (argv, (gpointer) priv->path);
 
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index b838e9f0..707cbbbb 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -16,7 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Copyright (C) 2004 - 2005 Colin Walters <walters@redhat.com>
- * Copyright (C) 2004 - 2012 Red Hat, Inc.
+ * Copyright (C) 2004 - 2013 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
  *   and others
  */
@@ -77,6 +77,14 @@ typedef struct {
 	gboolean dns_touched;
 } NMDnsManagerPrivate;
 
+enum {
+	CONFIG_CHANGED,
+
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
 
 typedef struct {
 	GPtrArray *nameservers;
@@ -746,6 +754,10 @@ update_dns (NMDnsManager *self,
 	if (success == FALSE)
 		success = update_resolv_conf (domain, searches, nameservers, error);
 
+	/* signal that resolv.conf was changed */
+	if (success)
+		g_signal_emit (self, signals[CONFIG_CHANGED], 0);
+
 	if (searches)
 		g_strfreev (searches);
 	if (nameservers)
@@ -1145,9 +1157,20 @@ nm_dns_manager_class_init (NMDnsManagerClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+	g_type_class_add_private (object_class, sizeof (NMDnsManagerPrivate));
+
+	/* virtual methods */
 	object_class->dispose = dispose;
 	object_class->finalize = finalize;
 
-	g_type_class_add_private (object_class, sizeof (NMDnsManagerPrivate));
+	/* signals */
+	signals[CONFIG_CHANGED] =
+		g_signal_new ("config-changed",
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              G_STRUCT_OFFSET (NMDnsManagerClass, config_changed),
+		              NULL, NULL,
+		              g_cclosure_marshal_VOID__VOID,
+		              G_TYPE_NONE, 0);
 }
 
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index 23492012..0fd4c198 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -16,7 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Copyright (C) 2004 - 2005 Colin Walters <walters@redhat.com>
- * Copyright (C) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2013 Red Hat, Inc.
  * Copyright (C) 2005 - 2008 Novell, Inc.
  *   and others
  */
@@ -60,6 +60,9 @@ typedef struct {
 
 typedef struct {
 	GObjectClass parent;
+
+	/* Signals */
+	void (*config_changed) (NMDnsManager *mgr);
 } NMDnsManagerClass;
 
 GType nm_dns_manager_get_type (void);
diff --git a/src/gdb-cmd b/src/gdb-cmd
deleted file mode 100644
index aea32eb0..00000000
--- a/src/gdb-cmd
+++ /dev/null
@@ -1,3 +0,0 @@
-bt
-thread apply all bt full
-q
diff --git a/src/generated/nm-enum-types.c b/src/generated/nm-enum-types.c
index c1eac45e..4fe5792c 100644
--- a/src/generated/nm-enum-types.c
+++ b/src/generated/nm-enum-types.c
@@ -5,52 +5,52 @@
 
 #include "nm-enum-types.h"
 
-#include "nm-sleep-monitor.h" 
-#include "nm-device.h" 
 #include "nm-rfkill.h" 
 #include "NetworkManagerUtils.h" 
-#include "nm-device-vlan.h" 
 #include "nm-device-factory.h" 
 #include "nm-active-connection.h" 
 #include "nm-wifi-ap.h" 
+#include "nm-device-ethernet.h" 
 #include "nm-device-bt.h" 
 #include "nm-call-store.h" 
+#include "nm-device-infiniband.h" 
 #include "nm-device-wifi.h" 
 #include "nm-dbus-manager.h" 
-#include "nm-device-olpc-mesh.h" 
 #include "nm-device-bridge.h" 
-#include "nm-dhcp4-config.h" 
+#include "nm-device-private.h" 
 #include "nm-dhcp6-config.h" 
+#include "nm-session-utils.h" 
 #include "nm-netlink-compat.h" 
 #include "nm-session-monitor.h" 
-#include "nm-connection-provider.h" 
+#include "nm-ip4-config.h" 
 #include "nm-device-bond.h" 
 #include "nm-wifi-ap-utils.h" 
-#include "nm-hostname-provider.h" 
 #include "nm-device-adsl.h" 
 #include "nm-policy-hosts.h" 
 #include "nm-dispatcher.h" 
+#include "nm-connection-provider.h" 
 #include "nm-manager.h" 
 #include "nm-device-modem.h" 
-#include "nm-device-wired.h" 
 #include "nm-activation-request.h" 
-#include "nm-session-utils.h" 
 #include "nm-policy-hostname.h" 
-#include "nm-device-infiniband.h" 
 #include "nm-properties-changed-signal.h" 
 #include "nm-types.h" 
 #include "nm-ip6-config.h" 
-#include "nm-device-private.h" 
 #include "nm-policy.h" 
 #include "nm-manager-auth.h" 
 #include "nm-config.h" 
 #include "nm-netlink-utils.h" 
+#include "nm-dhcp4-config.h" 
 #include "nm-netlink-monitor.h" 
 #include "nm-udev-manager.h" 
 #include "nm-system.h" 
 #include "nm-connectivity.h" 
-#include "nm-device-ethernet.h" 
-#include "nm-ip4-config.h" 
+#include "nm-device-vlan.h" 
+#include "nm-device-wired.h" 
+#include "nm-device-olpc-mesh.h" 
+#include "nm-hostname-provider.h" 
+#include "nm-sleep-monitor.h" 
+#include "nm-device.h" 
 #include "nm-logging.h" 
 #include "nm-dns-utils.h" 
 #include "nm-dns-plugin.h" 
@@ -101,26 +101,6 @@
 #include "nm-wimax-nsp.h"
 
 GType
-nm_device_error_get_type (void)
-{
-  static volatile gsize g_define_type_id__volatile = 0;
-
-  if (g_once_init_enter (&g_define_type_id__volatile))
-    {
-      static const GEnumValue values[] = {
-        { NM_DEVICE_ERROR_CONNECTION_ACTIVATING, "NM_DEVICE_ERROR_CONNECTION_ACTIVATING", "ConnectionActivating" },
-        { NM_DEVICE_ERROR_CONNECTION_INVALID, "NM_DEVICE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_DEVICE_ERROR_NOT_ACTIVE, "NM_DEVICE_ERROR_NOT_ACTIVE", "NotActive" },
-        { 0, NULL, NULL }
-      };
-      GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMDeviceError"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
-    }
-
-  return g_define_type_id__volatile;
-}
-GType
 nm_rf_kill_state_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
@@ -163,20 +143,20 @@ nm_rf_kill_type_get_type (void)
   return g_define_type_id__volatile;
 }
 GType
-nm_vlan_error_get_type (void)
+nm_ethernet_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile))
     {
       static const GEnumValue values[] = {
-        { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" },
-        { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED", "ConnectionNotWired" },
+        { NM_ETHERNET_ERROR_CONNECTION_INVALID, "NM_ETHERNET_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMVlanError"), values);
+        g_enum_register_static (g_intern_static_string ("NMEthernetError"), values);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
@@ -203,6 +183,26 @@ nm_bt_error_get_type (void)
   return g_define_type_id__volatile;
 }
 GType
+nm_infiniband_error_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+
+  if (g_once_init_enter (&g_define_type_id__volatile))
+    {
+      static const GEnumValue values[] = {
+        { NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND, "NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND", "ConnectionNotInfiniband" },
+        { NM_INFINIBAND_ERROR_CONNECTION_INVALID, "NM_INFINIBAND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, "NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { 0, NULL, NULL }
+      };
+      GType g_define_type_id =
+        g_enum_register_static (g_intern_static_string ("NMInfinibandError"), values);
+      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+    }
+
+  return g_define_type_id__volatile;
+}
+GType
 nm_wifi_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
@@ -216,6 +216,7 @@ nm_wifi_error_get_type (void)
         { NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND", "AccessPointNotFound" },
         { NM_WIFI_ERROR_SCAN_NOT_ALLOWED, "NM_WIFI_ERROR_SCAN_NOT_ALLOWED", "ScanNotAllowed" },
         { NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, "NM_WIFI_ERROR_AP_MODE_UNSUPPORTED", "ApModeUnsupported" },
+        { NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, "NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED", "AdhocModeUnsupported" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
@@ -226,40 +227,71 @@ nm_wifi_error_get_type (void)
   return g_define_type_id__volatile;
 }
 GType
-nm_olpc_mesh_error_get_type (void)
+nm_bridge_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile))
     {
       static const GEnumValue values[] = {
-        { NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH", "ConnectionNotMesh" },
-        { NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "NM_OLPC_MESH_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE, "NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE", "ConnectionNotBridge" },
+        { NM_BRIDGE_ERROR_CONNECTION_INVALID, "NM_BRIDGE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, "NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMOlpcMeshError"), values);
+        g_enum_register_static (g_intern_static_string ("NMBridgeError"), values);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
   return g_define_type_id__volatile;
 }
 GType
-nm_bridge_error_get_type (void)
+nm_session_monitor_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile))
     {
       static const GEnumValue values[] = {
-        { NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE, "NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE", "ConnectionNotBridge" },
-        { NM_BRIDGE_ERROR_CONNECTION_INVALID, "NM_BRIDGE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, "NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { NM_SESSION_MONITOR_ERROR_IO_ERROR, "NM_SESSION_MONITOR_ERROR_IO_ERROR", "IOError" },
+        { NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE", "MalformedDatabase" },
+        { NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "NM_SESSION_MONITOR_ERROR_UNKNOWN_USER", "UnknownUser" },
+        { NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NM_SESSION_MONITOR_ERROR_NO_DATABASE", "NoDatabase" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMBridgeError"), values);
+        g_enum_register_static (g_intern_static_string ("NMSessionMonitorError"), values);
+      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+    }
+
+  return g_define_type_id__volatile;
+}
+GType
+nm_ip4_config_compare_flags_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+
+  if (g_once_init_enter (&g_define_type_id__volatile))
+    {
+      static const GEnumValue values[] = {
+        { NM_IP4_COMPARE_FLAG_NONE, "NM_IP4_COMPARE_FLAG_NONE", "none" },
+        { NM_IP4_COMPARE_FLAG_ADDRESSES, "NM_IP4_COMPARE_FLAG_ADDRESSES", "addresses" },
+        { NM_IP4_COMPARE_FLAG_PTP_ADDRESS, "NM_IP4_COMPARE_FLAG_PTP_ADDRESS", "ptp-address" },
+        { NM_IP4_COMPARE_FLAG_NAMESERVERS, "NM_IP4_COMPARE_FLAG_NAMESERVERS", "nameservers" },
+        { NM_IP4_COMPARE_FLAG_ROUTES, "NM_IP4_COMPARE_FLAG_ROUTES", "routes" },
+        { NM_IP4_COMPARE_FLAG_DOMAINS, "NM_IP4_COMPARE_FLAG_DOMAINS", "domains" },
+        { NM_IP4_COMPARE_FLAG_SEARCHES, "NM_IP4_COMPARE_FLAG_SEARCHES", "searches" },
+        { NM_IP4_COMPARE_FLAG_MTU, "NM_IP4_COMPARE_FLAG_MTU", "mtu" },
+        { NM_IP4_COMPARE_FLAG_MSS, "NM_IP4_COMPARE_FLAG_MSS", "mss" },
+        { NM_IP4_COMPARE_FLAG_WINS_SERVERS, "NM_IP4_COMPARE_FLAG_WINS_SERVERS", "wins-servers" },
+        { NM_IP4_COMPARE_FLAG_NIS_SERVERS, "NM_IP4_COMPARE_FLAG_NIS_SERVERS", "nis-servers" },
+        { NM_IP4_COMPARE_FLAG_NIS_DOMAIN, "NM_IP4_COMPARE_FLAG_NIS_DOMAIN", "nis-domain" },
+        { NM_IP4_COMPARE_FLAG_ALL, "NM_IP4_COMPARE_FLAG_ALL", "all" },
+        { 0, NULL, NULL }
+      };
+      GType g_define_type_id =
+        g_enum_register_static (g_intern_static_string ("NMIP4ConfigCompareFlags"), values);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
@@ -360,47 +392,6 @@ nm_manager_error_get_type (void)
   return g_define_type_id__volatile;
 }
 GType
-nm_session_monitor_error_get_type (void)
-{
-  static volatile gsize g_define_type_id__volatile = 0;
-
-  if (g_once_init_enter (&g_define_type_id__volatile))
-    {
-      static const GEnumValue values[] = {
-        { NM_SESSION_MONITOR_ERROR_IO_ERROR, "NM_SESSION_MONITOR_ERROR_IO_ERROR", "IOError" },
-        { NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE", "MalformedDatabase" },
-        { NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "NM_SESSION_MONITOR_ERROR_UNKNOWN_USER", "UnknownUser" },
-        { NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NM_SESSION_MONITOR_ERROR_NO_DATABASE", "NoDatabase" },
-        { 0, NULL, NULL }
-      };
-      GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMSessionMonitorError"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
-    }
-
-  return g_define_type_id__volatile;
-}
-GType
-nm_infiniband_error_get_type (void)
-{
-  static volatile gsize g_define_type_id__volatile = 0;
-
-  if (g_once_init_enter (&g_define_type_id__volatile))
-    {
-      static const GEnumValue values[] = {
-        { NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND, "NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND", "ConnectionNotInfiniband" },
-        { NM_INFINIBAND_ERROR_CONNECTION_INVALID, "NM_INFINIBAND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, "NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
-        { 0, NULL, NULL }
-      };
-      GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMInfinibandError"), values);
-      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
-    }
-
-  return g_define_type_id__volatile;
-}
-GType
 nm_ip6_config_compare_flags_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
@@ -514,50 +505,60 @@ nm_netlink_monitor_error_get_type (void)
   return g_define_type_id__volatile;
 }
 GType
-nm_ethernet_error_get_type (void)
+nm_vlan_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile))
     {
       static const GEnumValue values[] = {
-        { NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED", "ConnectionNotWired" },
-        { NM_ETHERNET_ERROR_CONNECTION_INVALID, "NM_ETHERNET_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
-        { NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" },
+        { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMEthernetError"), values);
+        g_enum_register_static (g_intern_static_string ("NMVlanError"), values);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
   return g_define_type_id__volatile;
 }
 GType
-nm_ip4_config_compare_flags_get_type (void)
+nm_olpc_mesh_error_get_type (void)
 {
   static volatile gsize g_define_type_id__volatile = 0;
 
   if (g_once_init_enter (&g_define_type_id__volatile))
     {
       static const GEnumValue values[] = {
-        { NM_IP4_COMPARE_FLAG_NONE, "NM_IP4_COMPARE_FLAG_NONE", "none" },
-        { NM_IP4_COMPARE_FLAG_ADDRESSES, "NM_IP4_COMPARE_FLAG_ADDRESSES", "addresses" },
-        { NM_IP4_COMPARE_FLAG_PTP_ADDRESS, "NM_IP4_COMPARE_FLAG_PTP_ADDRESS", "ptp-address" },
-        { NM_IP4_COMPARE_FLAG_NAMESERVERS, "NM_IP4_COMPARE_FLAG_NAMESERVERS", "nameservers" },
-        { NM_IP4_COMPARE_FLAG_ROUTES, "NM_IP4_COMPARE_FLAG_ROUTES", "routes" },
-        { NM_IP4_COMPARE_FLAG_DOMAINS, "NM_IP4_COMPARE_FLAG_DOMAINS", "domains" },
-        { NM_IP4_COMPARE_FLAG_SEARCHES, "NM_IP4_COMPARE_FLAG_SEARCHES", "searches" },
-        { NM_IP4_COMPARE_FLAG_MTU, "NM_IP4_COMPARE_FLAG_MTU", "mtu" },
-        { NM_IP4_COMPARE_FLAG_MSS, "NM_IP4_COMPARE_FLAG_MSS", "mss" },
-        { NM_IP4_COMPARE_FLAG_WINS_SERVERS, "NM_IP4_COMPARE_FLAG_WINS_SERVERS", "wins-servers" },
-        { NM_IP4_COMPARE_FLAG_NIS_SERVERS, "NM_IP4_COMPARE_FLAG_NIS_SERVERS", "nis-servers" },
-        { NM_IP4_COMPARE_FLAG_NIS_DOMAIN, "NM_IP4_COMPARE_FLAG_NIS_DOMAIN", "nis-domain" },
-        { NM_IP4_COMPARE_FLAG_ALL, "NM_IP4_COMPARE_FLAG_ALL", "all" },
+        { NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH", "ConnectionNotMesh" },
+        { NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "NM_OLPC_MESH_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
-        g_enum_register_static (g_intern_static_string ("NMIP4ConfigCompareFlags"), values);
+        g_enum_register_static (g_intern_static_string ("NMOlpcMeshError"), values);
+      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+    }
+
+  return g_define_type_id__volatile;
+}
+GType
+nm_device_error_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+
+  if (g_once_init_enter (&g_define_type_id__volatile))
+    {
+      static const GEnumValue values[] = {
+        { NM_DEVICE_ERROR_CONNECTION_ACTIVATING, "NM_DEVICE_ERROR_CONNECTION_ACTIVATING", "ConnectionActivating" },
+        { NM_DEVICE_ERROR_CONNECTION_INVALID, "NM_DEVICE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
+        { NM_DEVICE_ERROR_NOT_ACTIVE, "NM_DEVICE_ERROR_NOT_ACTIVE", "NotActive" },
+        { 0, NULL, NULL }
+      };
+      GType g_define_type_id =
+        g_enum_register_static (g_intern_static_string ("NMDeviceError"), values);
       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
     }
 
diff --git a/src/generated/nm-enum-types.h b/src/generated/nm-enum-types.h
index 36de65cc..6dd250bb 100644
--- a/src/generated/nm-enum-types.h
+++ b/src/generated/nm-enum-types.h
@@ -9,22 +9,24 @@
 #include <glib-object.h>
 
 G_BEGIN_DECLS
-GType nm_device_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ())
 GType nm_rf_kill_state_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_RF_KILL_STATE (nm_rf_kill_state_get_type ())
 GType nm_rf_kill_type_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_RF_KILL_TYPE (nm_rf_kill_type_get_type ())
-GType nm_vlan_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_VLAN_ERROR (nm_vlan_error_get_type ())
+GType nm_ethernet_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
 GType nm_bt_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_BT_ERROR (nm_bt_error_get_type ())
+GType nm_infiniband_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_INFINIBAND_ERROR (nm_infiniband_error_get_type ())
 GType nm_wifi_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
-GType nm_olpc_mesh_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ())
 GType nm_bridge_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_BRIDGE_ERROR (nm_bridge_error_get_type ())
+GType nm_session_monitor_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_SESSION_MONITOR_ERROR (nm_session_monitor_error_get_type ())
+GType nm_ip4_config_compare_flags_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_IP4_CONFIG_COMPARE_FLAGS (nm_ip4_config_compare_flags_get_type ())
 GType nm_bond_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_BOND_ERROR (nm_bond_error_get_type ())
 GType nm_adsl_error_get_type (void) G_GNUC_CONST;
@@ -33,10 +35,6 @@ GType nm_dispatcher_action_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_DISPATCHER_ACTION (nm_dispatcher_action_get_type ())
 GType nm_manager_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_MANAGER_ERROR (nm_manager_error_get_type ())
-GType nm_session_monitor_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_SESSION_MONITOR_ERROR (nm_session_monitor_error_get_type ())
-GType nm_infiniband_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_INFINIBAND_ERROR (nm_infiniband_error_get_type ())
 GType nm_ip6_config_compare_flags_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_IP6_CONFIG_COMPARE_FLAGS (nm_ip6_config_compare_flags_get_type ())
 GType nm_auth_call_result_get_type (void) G_GNUC_CONST;
@@ -47,10 +45,12 @@ GType nm_nm_nl_prop_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_NM_NL_PROP (nm_nm_nl_prop_get_type ())
 GType nm_netlink_monitor_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_get_type ())
-GType nm_ethernet_error_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
-GType nm_ip4_config_compare_flags_get_type (void) G_GNUC_CONST;
-#define NM_TYPE_IP4_CONFIG_COMPARE_FLAGS (nm_ip4_config_compare_flags_get_type ())
+GType nm_vlan_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_VLAN_ERROR (nm_vlan_error_get_type ())
+GType nm_olpc_mesh_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ())
+GType nm_device_error_get_type (void) G_GNUC_CONST;
+#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ())
 GType nm_logging_error_get_type (void) G_GNUC_CONST;
 #define NM_TYPE_LOGGING_ERROR (nm_logging_error_get_type ())
 GType nm_dns_manager_error_get_type (void) G_GNUC_CONST;
diff --git a/src/main.c b/src/main.c
index 85bfc272..feb8fa3f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -98,10 +98,6 @@ signal_handling_thread (void *arg)
 			/* Reread config stuff like system config files, VPN service files, etc */
 			nm_log_info (LOGD_CORE, "caught signal %d, not supported yet.", signo);
 			break;
-		case SIGUSR1:
-			/* Play with log levels or something */
-			nm_log_info (LOGD_CORE, "caught signal %d, not supported yet.", signo);
-			break;
 		default:
 			nm_log_err (LOGD_CORE, "caught unexpected signal %d", signo);
 			break;
@@ -127,7 +123,6 @@ setup_signals (void)
 	sigaddset (&signal_set, SIGHUP);
 	sigaddset (&signal_set, SIGINT);
 	sigaddset (&signal_set, SIGTERM);
-	sigaddset (&signal_set, SIGUSR1);
 
 	/* Block all signals of interest. */
 	status = pthread_sigmask (SIG_BLOCK, &signal_set, &old_sig_mask);
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 2d24a3ea..34aeccf4 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -55,6 +55,7 @@ typedef struct {
 	char *path;
 	char *control_port;
 	char *data_port;
+	char *ppp_iface;
 	guint32 ip_method;
 
 	NMPPPManager *ppp_manager;
@@ -146,8 +147,8 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
 	gboolean dns_workaround = FALSE;
 
 	/* Notify about the new data port to use */
-	g_free (priv->data_port);
-	priv->data_port = g_strdup (iface);
+	g_free (priv->ppp_iface);
+	priv->ppp_iface = g_strdup (iface);
 	g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT);
 
 	/* Work around a PPP bug (#1732) which causes many mobile broadband
@@ -561,6 +562,9 @@ deactivate (NMModem *self, NMDevice *device)
 		nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method);
 		break;
 	}
+
+	g_free (priv->ppp_iface);
+	priv->ppp_iface = NULL;
 }
 
 /*****************************************************************************/
@@ -655,7 +659,12 @@ nm_modem_get_data_port (NMModem *self)
 	g_return_val_if_fail (self != NULL, NULL);
 	g_return_val_if_fail (NM_IS_MODEM (self), NULL);
 
-	return NM_MODEM_GET_PRIVATE (self)->data_port;
+	/* The ppp_iface takes precedence over the data interface when PPP is used,
+	 * since data_iface is the TTY over which PPP is run, and that TTY can't
+	 * do IP.  The caller really wants the thing that's doing IP.
+	 */
+	return NM_MODEM_GET_PRIVATE (self)->ppp_iface ?
+		NM_MODEM_GET_PRIVATE (self)->ppp_iface : NM_MODEM_GET_PRIVATE (self)->data_port;
 }
 
 /*****************************************************************************/
@@ -712,7 +721,7 @@ get_property (GObject *object, guint prop_id,
 		g_value_set_string (value, priv->control_port);
 		break;
 	case PROP_DATA_PORT:
-		g_value_set_string (value, priv->data_port);
+		g_value_set_string (value, nm_modem_get_data_port (NM_MODEM (object)));
 		break;
 	case PROP_UID:
 		g_value_set_string (value, priv->uid);
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c
index 88504ce0..76949cf2 100644
--- a/src/nm-activation-request.c
+++ b/src/nm-activation-request.c
@@ -297,6 +297,7 @@ nm_act_request_add_share_rule (NMActRequest *req,
 static void
 device_state_changed (NMDevice *device, GParamSpec *pspec, NMActRequest *self)
 {
+	NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
 	NMActiveConnectionState ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
 
 	/* Set NMActiveConnection state based on the device's state */
@@ -318,6 +319,13 @@ device_state_changed (NMDevice *device, GParamSpec *pspec, NMActRequest *self)
 	case NM_DEVICE_STATE_FAILED:
 	case NM_DEVICE_STATE_DISCONNECTED:
 		ac_state = NM_ACTIVE_CONNECTION_STATE_DEACTIVATED;
+
+		/* No longer need to pay attention to device state */
+		if (priv->device && priv->device_state_id) {
+			g_signal_handler_disconnect (priv->device, priv->device_state_id);
+			priv->device_state_id = 0;
+		}
+		g_clear_object (&priv->device);
 		break;
 	default:
 		break;
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 15b4b485..6e3a5da6 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -101,6 +101,10 @@ nm_active_connection_set_state (NMActiveConnection *self,
 	if (priv->state == new_state)
 		return;
 
+	/* DEACTIVATED is a terminal state */
+	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
+		g_return_if_fail (new_state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+
 	old_state = priv->state;
 	priv->state = new_state;
 	g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
@@ -110,6 +114,12 @@ nm_active_connection_set_state (NMActiveConnection *self,
 		nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection),
 		                                         (guint64) time (NULL), TRUE);
 	}
+
+	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
+		/* Device is no longer relevant when deactivated */
+		g_clear_object (&priv->device);
+		g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES);
+	}
 }
 
 const char *
diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c
index 366e2683..5766ab8e 100644
--- a/src/nm-device-bt.c
+++ b/src/nm-device-bt.c
@@ -1150,13 +1150,12 @@ mm_name_owner_changed (NMDBusManager *dbus_mgr,
 	gboolean new_owner_good;
 
 	/* Can't handle the signal if its not from the modem service */
-	if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0)
-		return;
-
+	if (   strcmp (MM_OLD_DBUS_SERVICE, name) != 0
 #if WITH_MODEM_MANAGER_1
-	if (strcmp (MM_NEW_DBUS_SERVICE, name) != 0)
-		return;
+	    && strcmp (MM_NEW_DBUS_SERVICE, name) != 0
 #endif
+	    )
+		return;
 
 	old_owner_good = (old_owner && strlen (old_owner));
 	new_owner_good = (new_owner && strlen (new_owner));
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 67a10d43..abbf7c44 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -1016,6 +1016,7 @@ check_connection_compatible (NMDevice *device,
 	NMSettingWireless *s_wireless;
 	const GByteArray *mac;
 	const GSList *mac_blacklist, *mac_blacklist_iter;
+	const char *mode;
 
 	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
@@ -1071,8 +1072,17 @@ check_connection_compatible (NMDevice *device,
 		return FALSE;
 	}
 
-	/* Early exit if supplicant or device don't support AP mode */
-	if (g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0) {
+	/* Early exit if supplicant or device doesn't support requested mode */
+	mode = nm_setting_wireless_get_mode (s_wireless);
+	if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) {
+		if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) {
+			g_set_error_literal (error,
+			                     NM_WIFI_ERROR,
+			                     NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED,
+			                     "Ad-Hoc mode is not supported by this device.");
+			return FALSE;
+		}
+	} else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) {
 		if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) {
 			g_set_error_literal (error,
 			                     NM_WIFI_ERROR,
@@ -2448,7 +2458,15 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
 		break;
 	case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
 		cleanup_association_attempt (self, FALSE);
+
+		/* If the device is already in UNAVAILABLE state then the state change
+		 * is a NOP and the interface won't be re-acquired in the device state
+		 * change handler.  So ensure we have a new one here so that we're
+		 * ready if the supplicant comes back.
+		 */
 		supplicant_interface_release (self);
+		supplicant_interface_acquire (self);
+
 		nm_device_state_changed (device,
 		                         NM_DEVICE_STATE_UNAVAILABLE,
 		                         NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
diff --git a/src/nm-device-wifi.h b/src/nm-device-wifi.h
index 425b8525..368d0b80 100644
--- a/src/nm-device-wifi.h
+++ b/src/nm-device-wifi.h
@@ -48,6 +48,7 @@ typedef enum {
 	NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND,      /*< nick=AccessPointNotFound >*/
 	NM_WIFI_ERROR_SCAN_NOT_ALLOWED,            /*< nick=ScanNotAllowed >*/
 	NM_WIFI_ERROR_AP_MODE_UNSUPPORTED,         /*< nick=ApModeUnsupported >*/
+	NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED,      /*< nick=AdhocModeUnsupported >*/
 } NMWifiError;
 
 #define NM_DEVICE_WIFI_HW_ADDRESS          "hw-address"
diff --git a/src/nm-device.c b/src/nm-device.c
index b0810680..9fe914f0 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -339,7 +339,7 @@ update_accept_ra_save (NMDevice *self)
 	if (!nm_utils_get_proc_sys_net_value_with_bounds (priv->ip6_accept_ra_path,
 	                                                  ip_iface,
 	                                                  &priv->ip6_accept_ra_save,
-	                                                  0, 1)) {
+	                                                  0, 2)) {
 		g_free (priv->ip6_accept_ra_path);
 		priv->ip6_accept_ra_path = NULL;
 	}
diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c
index 111dffaa..ba8053e9 100644
--- a/src/nm-netlink-monitor.c
+++ b/src/nm-netlink-monitor.c
@@ -38,10 +38,7 @@
 #include <linux/if.h>
 #include <linux/unistd.h>
 #include <unistd.h>
-#include <netlink/version.h>
-#if LIBNL_VER_NUM == LIBNL_VER (3, 2) && LIBNL_VER_MIC < 20
-#include <netlink/object-api.h>
-#endif
+#include <netlink/netlink.h>
 #include <netlink/object.h>
 #include <netlink/route/addr.h>
 #include <netlink/route/rtnl.h>
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 752cf44e..38a03613 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.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 - 2012 Red Hat, Inc.
+ * Copyright (C) 2004 - 2013 Red Hat, Inc.
  * Copyright (C) 2007 - 2008 Novell, Inc.
  */
 
@@ -62,6 +62,10 @@ struct NMPolicy {
 	NMDevice *default_device6;
 
 	HostnameThread *lookup;
+	guint32 lookup_ipv4_addr;          /* IPv4 for reverse lookup */
+	struct in6_addr *lookup_ipv6_addr; /* IPv6 for reverse lookup */
+	NMDnsManager *dns_manager;
+	gulong config_changed_id;
 
 	gint reset_retries_id;  /* idle handler for resetting the retries count */
 
@@ -229,14 +233,21 @@ _set_hostname (NMPolicy *policy,
                const char *new_hostname,
                const char *msg)
 {
-	NMDnsManager *dns_mgr;
-
 	/* The incoming hostname *can* be NULL, which will get translated to
 	 * 'localhost.localdomain' or such in the hostname policy code, but we
 	 * keep cur_hostname = NULL in the case because we need to know that
 	 * there was no valid hostname to start with.
 	 */
 
+	/* Clear lookup adresses if we have a hostname, so that we didn't
+	 * restart reverse lookup thread later.
+	 */
+	if (new_hostname) {
+		policy->lookup_ipv4_addr = 0;
+		g_free (policy->lookup_ipv6_addr);
+		policy->lookup_ipv6_addr = NULL;
+	}
+
 	/* Don't change the hostname or update DNS this is the first time we're
 	 * trying to change the hostname, and it's not actually changing.
 	 */
@@ -255,9 +266,7 @@ _set_hostname (NMPolicy *policy,
 	policy->cur_hostname = g_strdup (new_hostname);
 	policy->hostname_changed = TRUE;
 
-	dns_mgr = nm_dns_manager_get (NULL);
-	nm_dns_manager_set_hostname (dns_mgr, policy->cur_hostname);
-	g_object_unref (dns_mgr);
+	nm_dns_manager_set_hostname (policy->dns_manager, policy->cur_hostname);
 
 	if (nm_policy_set_system_hostname (policy->cur_hostname, msg))
 		nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL);
@@ -398,7 +407,8 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
 		g_assert (addr4); /* checked for > 1 address above */
 
 		/* Start the hostname lookup thread */
-		policy->lookup = hostname4_thread_new (nm_ip4_address_get_address (addr4), lookup_callback, policy);
+		policy->lookup_ipv4_addr = nm_ip4_address_get_address (addr4);
+		policy->lookup = hostname4_thread_new (policy->lookup_ipv4_addr, lookup_callback, policy);
 	} else if (best6) {
 		NMIP6Config *ip6_config;
 		NMIP6Address *addr6;
@@ -416,7 +426,9 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
 		g_assert (addr6); /* checked for > 1 address above */
 
 		/* Start the hostname lookup thread */
-		policy->lookup = hostname6_thread_new (nm_ip6_address_get_address (addr6), lookup_callback, policy);
+		policy->lookup_ipv6_addr = g_malloc0 (sizeof (struct in6_addr));
+		memcpy (policy->lookup_ipv6_addr, nm_ip6_address_get_address (addr6), sizeof (struct in6_addr));
+		policy->lookup = hostname6_thread_new (policy->lookup_ipv6_addr, lookup_callback, policy);
 	}
 
 	if (!policy->lookup) {
@@ -1264,7 +1276,6 @@ device_state_changed (NMDevice *device,
 	NMIP4Config *ip4_config;
 	NMIP6Config *ip6_config;
 	NMSettingConnection *s_con;
-	NMDnsManager *dns_mgr;
 
 	if (connection)
 		g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (0));
@@ -1322,20 +1333,18 @@ device_state_changed (NMDevice *device,
 
 		/* Add device's new IPv4 and IPv6 configs to DNS */
 
-		dns_mgr = nm_dns_manager_get (NULL);
-		nm_dns_manager_begin_updates (dns_mgr, __func__);
+		nm_dns_manager_begin_updates (policy->dns_manager, __func__);
 
 		ip4_config = nm_device_get_ip4_config (device);
 		if (ip4_config)
-			nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
+			nm_dns_manager_add_ip4_config (policy->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
 		ip6_config = nm_device_get_ip6_config (device);
 		if (ip6_config)
-			nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
+			nm_dns_manager_add_ip6_config (policy->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
 
 		update_routing_and_dns (policy, FALSE);
 
-		nm_dns_manager_end_updates (dns_mgr, __func__);
-		g_object_unref (dns_mgr);
+		nm_dns_manager_end_updates (policy->dns_manager, __func__);
 		break;
 	case NM_DEVICE_STATE_UNMANAGED:
 	case NM_DEVICE_STATE_UNAVAILABLE:
@@ -1387,16 +1396,14 @@ device_ip4_config_changed (NMDevice *device,
                            gpointer user_data)
 {
 	NMPolicy *policy = user_data;
-	NMDnsManager *dns_mgr;
 	const char *ip_iface = nm_device_get_ip_iface (device);
 	NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL;
 
-	dns_mgr = nm_dns_manager_get (NULL);
-	nm_dns_manager_begin_updates (dns_mgr, __func__);
+	nm_dns_manager_begin_updates (policy->dns_manager, __func__);
 
 	/* Old configs get removed immediately */
 	if (old_config)
-		nm_dns_manager_remove_ip4_config (dns_mgr, old_config);
+		nm_dns_manager_remove_ip4_config (policy->dns_manager, old_config);
 
 	/* Ignore IP config changes while the device is activating, because we'll
 	 * catch all the changes when the device moves to ACTIVATED state.
@@ -1404,8 +1411,8 @@ device_ip4_config_changed (NMDevice *device,
 	 */
 	if (!nm_device_is_activating (device)) {
 		if (new_config)
-			nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
-		update_ip4_dns (policy, dns_mgr);
+			nm_dns_manager_add_ip4_config (policy->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
+		update_ip4_dns (policy, policy->dns_manager);
 
 		/* Only change routing if something actually changed */
 		diff = nm_ip4_config_diff (new_config, old_config);
@@ -1413,8 +1420,7 @@ device_ip4_config_changed (NMDevice *device,
 			update_ip4_routing (policy, TRUE);
 	}
 
-	nm_dns_manager_end_updates (dns_mgr, __func__);
-	g_object_unref (dns_mgr);
+	nm_dns_manager_end_updates (policy->dns_manager, __func__);
 }
 
 static void
@@ -1424,16 +1430,14 @@ device_ip6_config_changed (NMDevice *device,
                            gpointer user_data)
 {
 	NMPolicy *policy = user_data;
-	NMDnsManager *dns_mgr;
 	const char *ip_iface = nm_device_get_ip_iface (device);
 	NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL;
 
-	dns_mgr = nm_dns_manager_get (NULL);
-	nm_dns_manager_begin_updates (dns_mgr, __func__);
+	nm_dns_manager_begin_updates (policy->dns_manager, __func__);
 
 	/* Old configs get removed immediately */
 	if (old_config)
-		nm_dns_manager_remove_ip6_config (dns_mgr, old_config);
+		nm_dns_manager_remove_ip6_config (policy->dns_manager, old_config);
 
 	/* Ignore IP config changes while the device is activating, because we'll
 	 * catch all the changes when the device moves to ACTIVATED state.
@@ -1441,8 +1445,8 @@ device_ip6_config_changed (NMDevice *device,
 	 */
 	if (!nm_device_is_activating (device)) {
 		if (new_config)
-			nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
-		update_ip6_dns (policy, dns_mgr);
+			nm_dns_manager_add_ip6_config (policy->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
+		update_ip6_dns (policy, policy->dns_manager);
 
 		/* Only change routing if something actually changed */
 		diff = nm_ip6_config_diff (new_config, old_config);
@@ -1450,8 +1454,7 @@ device_ip6_config_changed (NMDevice *device,
 			update_ip6_routing (policy, TRUE);
 	}
 
-	nm_dns_manager_end_updates (dns_mgr, __func__);
-	g_object_unref (dns_mgr);
+	nm_dns_manager_end_updates (policy->dns_manager, __func__);
 }
 
 static void
@@ -1792,6 +1795,43 @@ firewall_started (NMFirewallManager *manager,
 }
 
 static void
+dns_config_changed (NMDnsManager *dns_manager, gpointer user_data)
+{
+	NMPolicy *policy = (NMPolicy *) user_data;
+
+	/* Restart a thread for reverse-DNS lookup after we are signalled that
+	 * DNS changed. Because the result from a previous run may not be right
+	 * (race in updating DNS and doing the reverse lookup).
+	 */
+
+	/* Stop a lookup thread if any. */
+	if (policy->lookup) {
+		hostname_thread_kill (policy->lookup);
+		policy->lookup = NULL;
+	}
+
+	/* Re-start the hostname lookup thread if we don't have hostname yet. */
+	if (policy->lookup_ipv4_addr) {
+		char buf[INET_ADDRSTRLEN];
+		struct in_addr addr = { .s_addr = policy->lookup_ipv4_addr };
+		
+		if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf)))
+			strcpy (buf, "(unknown)");
+		nm_log_dbg (LOGD_DNS, "restarting IPv4 reverse-lookup thread for address %s'", buf);
+
+		policy->lookup = hostname4_thread_new (policy->lookup_ipv4_addr, lookup_callback, policy);
+	} else if (policy->lookup_ipv6_addr) {
+		char buf[INET6_ADDRSTRLEN];
+
+		if (!inet_ntop (AF_INET6, policy->lookup_ipv6_addr, buf, sizeof (buf)))
+			strcpy (buf, "(unknown)");
+		nm_log_dbg (LOGD_DNS, "restarting IPv6 reverse-lookup thread for address %s'", buf);
+
+		policy->lookup = hostname6_thread_new (policy->lookup_ipv6_addr, lookup_callback, policy);
+	}
+}
+
+static void
 connection_updated (NMSettings *settings,
                     NMConnection *connection,
                     gpointer user_data)
@@ -1917,6 +1957,10 @@ nm_policy_new (NMManager *manager, NMSettings *settings)
 	                       G_CALLBACK (firewall_started), policy);
 	policy->fw_started_id = id;
 
+	policy->dns_manager = nm_dns_manager_get (NULL);
+	policy->config_changed_id = g_signal_connect (policy->dns_manager, "config-changed",
+	                                              G_CALLBACK (dns_config_changed), policy);
+
 	_connect_manager_signal (policy, "state-changed", global_state_changed);
 	_connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed);
 	_connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed);
@@ -1955,6 +1999,7 @@ nm_policy_destroy (NMPolicy *policy)
 		hostname_thread_kill (policy->lookup);
 		policy->lookup = NULL;
 	}
+	g_free (policy->lookup_ipv6_addr);
 
 	g_slist_foreach (policy->pending_activation_checks, (GFunc) activate_data_free, NULL);
 	g_slist_free (policy->pending_activation_checks);
@@ -1965,6 +2010,9 @@ nm_policy_destroy (NMPolicy *policy)
 	g_signal_handler_disconnect (policy->fw_manager, policy->fw_started_id);
 	g_object_unref (policy->fw_manager);
 
+	g_signal_handler_disconnect (policy->dns_manager, policy->config_changed_id);
+	g_object_unref (policy->dns_manager);
+
 	for (iter = policy->manager_ids; iter; iter = g_slist_next (iter))
 		g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data));
 	g_slist_free (policy->manager_ids);
diff --git a/src/nm-system.c b/src/nm-system.c
index 031daf8a..1a2f9382 100644
--- a/src/nm-system.c
+++ b/src/nm-system.c
@@ -1167,7 +1167,7 @@ add_default_ip6_route (int ifindex, const struct in6_addr *gw, int mss)
 	g_return_val_if_fail (route != NULL, -ENOMEM);
 
 	/* Add the new default route */
-	err = nm_netlink_route6_add (route, &in6addr_any, 0, gw, NLM_F_CREATE);
+	err = nm_netlink_route6_add (route, &in6addr_any, 0, gw, NLM_F_CREATE | NLM_F_REPLACE);
 	if (err == -NLE_EXIST)
 		err = 0;
 
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index f0cfc3fc..d3415862 100644
--- a/src/settings/nm-settings-connection.c
+++ b/src/settings/nm-settings-connection.c
@@ -1734,14 +1734,9 @@ static void
 nm_settings_connection_init (NMSettingsConnection *self)
 {
 	NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
-	static guint32 dbus_counter = 0;
-	char *dbus_path;
 
 	priv->dbus_mgr = nm_dbus_manager_get ();
 
-	dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++);
-	nm_connection_set_path (NM_CONNECTION (self), dbus_path);
-	g_free (dbus_path);
 	priv->visible = FALSE;
 
 	priv->session_monitor = nm_session_monitor_get ();
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index fa474e09..2cfda091 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -587,7 +587,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
 	gboolean keyfile_added = FALSE;
 	gboolean success = TRUE;
 
-	for (iter = plugins; *iter; iter++) {
+	for (iter = plugins; iter && *iter; iter++) {
 		GModule *plugin;
 		char *full_name, *path;
 		const char *pname = *iter;
@@ -1768,12 +1768,10 @@ nm_settings_new (const char *config_file,
 	priv->dbus_mgr = nm_dbus_manager_get ();
 	priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
 
-	if (plugins) {
-		/* Load the plugins; fail if a plugin is not found. */
-		if (!load_plugins (self, plugins, error)) {
-			g_object_unref (self);
-			return NULL;
-		}
+	/* Load the plugins; fail if a plugin is not found. */
+	if (!load_plugins (self, plugins, error)) {
+		g_object_unref (self);
+		return NULL;
 	}
 
 	unmanaged_specs_changed (NULL, self);
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c
index 8a646e1c..f14e5cf7 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile.c
@@ -603,7 +603,7 @@ test_write_wired_connection (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
@@ -821,7 +821,7 @@ test_write_ip6_wired_connection (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
@@ -1139,7 +1139,7 @@ test_write_wireless_connection (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
@@ -1269,7 +1269,7 @@ test_write_string_ssid (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
@@ -1916,7 +1916,7 @@ test_write_bt_dun_connection (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
@@ -2162,7 +2162,7 @@ test_write_gsm_connection (void)
 	owner_grp = getegid ();
 	success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
 	ASSERT (success == TRUE,
-			"connection-write", "failed to allocate write keyfile: %s",
+			"connection-write", "failed to write keyfile: %s",
 			error ? error->message : "(none)");
 
 	ASSERT (testfile != NULL,
diff --git a/src/wifi/wifi-utils-nl80211.c b/src/wifi/wifi-utils-nl80211.c
index 5a7103ee..4a2dd937 100644
--- a/src/wifi/wifi-utils-nl80211.c
+++ b/src/wifi/wifi-utils-nl80211.c
@@ -564,6 +564,15 @@ struct nl80211_device_info {
 	gboolean success;
 };
 
+#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00
+#define WLAN_CIPHER_SUITE_WEP40     0x000FAC01
+#define WLAN_CIPHER_SUITE_TKIP      0x000FAC02
+#define WLAN_CIPHER_SUITE_CCMP      0x000FAC04
+#define WLAN_CIPHER_SUITE_WEP104    0x000FAC05
+#define WLAN_CIPHER_SUITE_AES_CMAC  0x000FAC06
+#define WLAN_CIPHER_SUITE_GCMP      0x000FAC08
+#define WLAN_CIPHER_SUITE_SMS4      0x00147201
+
 static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 {
 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -674,22 +683,26 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 		num = nla_len (tb[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32);
 		for (i = 0; i < num; i++) {
 			switch (ciphers[i]) {
-			case 0x000fac01:
+			case WLAN_CIPHER_SUITE_WEP40:
 				info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40;
 				break;
-			case 0x000fac05:
+			case WLAN_CIPHER_SUITE_WEP104:
 				info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP104;
 				break;
-			case 0x000fac02:
+			case WLAN_CIPHER_SUITE_TKIP:
 				info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP |
 					      NM_WIFI_DEVICE_CAP_WPA;
 				break;
-			case 0x000fac04:
+			case WLAN_CIPHER_SUITE_CCMP:
 				info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP |
 					      NM_WIFI_DEVICE_CAP_RSN;
 				break;
+			case WLAN_CIPHER_SUITE_AES_CMAC:
+			case WLAN_CIPHER_SUITE_GCMP:
+			case WLAN_CIPHER_SUITE_SMS4:
+				break;
 			default:
-				nm_log_err (LOGD_HW | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITES %#8.8x.", ciphers[i]);
+				nm_log_dbg (LOGD_HW | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", ciphers[i]);
 				break;
 			}
 		}
@@ -700,10 +713,10 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 		int i;
 
 		nla_for_each_nested (nl_mode, tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
-			if (nla_type (nl_mode) == NL80211_IFTYPE_AP) {
+			if (nla_type (nl_mode) == NL80211_IFTYPE_AP)
 				info->caps |= NM_WIFI_DEVICE_CAP_AP;
-				break;
-			}
+			else if (nla_type (nl_mode) == NL80211_IFTYPE_ADHOC)
+				info->caps |= NM_WIFI_DEVICE_CAP_ADHOC;
 		}
 	}
 
diff --git a/src/wifi/wifi-utils-wext.c b/src/wifi/wifi-utils-wext.c
index 37cd94e9..6e990aed 100644
--- a/src/wifi/wifi-utils-wext.c
+++ b/src/wifi/wifi-utils-wext.c
@@ -556,6 +556,12 @@ wext_get_caps (WifiDataWext *wext, struct iw_range *range)
 		caps &= ~WPA_CAPS;
 	}
 
+	/* There's no way to detect Ad-Hoc/AP mode support with WEXT
+	 * (other than actually trying to do it), so just assume that
+	 * Ad-Hoc is supported and AP isn't.
+	 */
+	caps |= NM_WIFI_DEVICE_CAP_ADHOC;
+
 	return caps;
 }