about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bluez-manager/Makefile.am3
-rw-r--r--src/bluez-manager/Makefile.in3
-rw-r--r--src/dns-manager/nm-dns-manager.c49
-rw-r--r--src/dns-manager/nm-dns-manager.h2
-rw-r--r--src/ip6-manager/nm-ip6-manager.c19
-rw-r--r--src/main.c110
-rw-r--r--src/modem-manager/nm-modem.c17
-rw-r--r--src/modem-manager/nm-modem.h1
-rw-r--r--src/nm-device.c2
-rw-r--r--src/nm-manager.c162
-rw-r--r--src/nm-system.c4
-rw-r--r--src/nm-udev-manager.c46
-rw-r--r--src/ppp-manager/nm-ppp-manager.c33
-rw-r--r--src/ppp-manager/nm-ppp-manager.h2
-rw-r--r--src/vpn-manager/nm-vpn-connection.c11
-rw-r--r--src/vpn-manager/nm-vpn-connection.h5
-rw-r--r--src/vpn-manager/nm-vpn-manager.c4
-rw-r--r--src/vpn-manager/nm-vpn-manager.h3
-rw-r--r--src/vpn-manager/nm-vpn-service.c4
-rw-r--r--src/vpn-manager/nm-vpn-service.h2
20 files changed, 289 insertions, 193 deletions
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 fad2ec6e..369028c7 100644
--- a/src/bluez-manager/Makefile.in
+++ b/src/bluez-manager/Makefile.in
@@ -286,8 +286,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/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 eb1c73a7..a48130b2 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -55,8 +55,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/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/main.c b/src/main.c
index b22c769d..da63930b 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,62 +146,62 @@ 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
@@ -208,6 +209,17 @@ 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;
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index b3f7eaa1..9471ef87 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -85,14 +85,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)
 {
@@ -651,12 +643,13 @@ real_deactivate_quickly (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 a2aed57e..6e47c903 100644
--- a/src/modem-manager/nm-modem.h
+++ b/src/modem-manager/nm-modem.h
@@ -97,7 +97,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-device.c b/src/nm-device.c
index 9c771c2a..8675bf62 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -1617,7 +1617,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 ());
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 8b24aa51..e34e9014 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -188,6 +188,7 @@ struct PendingActivation {
 
 typedef struct {
 	gboolean user_enabled;
+	gboolean daemon_enabled;
 	gboolean sw_enabled;
 	gboolean hw_enabled;
 	RfKillType rtype;
@@ -196,6 +197,7 @@ typedef struct {
 	const char *prop;
 	const char *hw_prop;
 	RfKillState (*other_enabled_func) (NMManager *);
+	RfKillState (*daemon_enabled_func) (NMManager *);
 } RadioState;
 
 typedef struct {
@@ -917,7 +919,6 @@ static GPtrArray *
 get_active_connections (NMManager *manager, NMConnection *filter)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-	NMVPNManager *vpn_manager;
 	GPtrArray *active;
 	GSList *iter;
 
@@ -939,9 +940,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;
 }
@@ -1651,21 +1650,28 @@ write_value_to_state_file (const char *filename,
 }
 
 static gboolean
-radio_enabled_for_rstate (RadioState *rstate)
+radio_enabled_for_rstate (RadioState *rstate, gboolean check_daemon_enabled)
 {
-	return rstate->user_enabled && rstate->sw_enabled && rstate->hw_enabled;
+	gboolean enabled;
+
+	enabled = rstate->user_enabled && rstate->sw_enabled && rstate->hw_enabled;
+	if (rstate->daemon_enabled_func && check_daemon_enabled)
+		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_daemon_enabled)
 {
 	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_daemon_enabled);
 }
 
 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;
@@ -1683,7 +1689,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) {
@@ -1830,9 +1835,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;
 
@@ -1851,9 +1856,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 */
@@ -1870,10 +1892,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
@@ -1882,14 +1908,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
@@ -2084,6 +2109,7 @@ add_device (NMManager *self, NMDevice *device)
 	GHashTableIter iter;
 	gpointer value;
 	gboolean managed = FALSE, enabled = FALSE;
+	RfKillType rtype = RFKILL_TYPE_UNKNOWN;
 
 	iface = nm_device_get_ip_iface (device);
 	g_assert (iface);
@@ -2117,26 +2143,21 @@ 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);
+		rtype = RFKILL_TYPE_WWAN;
+	}
 
-		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);
-		*/
+	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);
@@ -2597,6 +2618,7 @@ user_get_secrets_cb (DBusGProxy *proxy,
                      gpointer user_data)
 {
 	GetSecretsInfo *info = (GetSecretsInfo *) user_data;
+	NMManagerPrivate *priv;
 	GHashTable *settings = NULL;
 	GError *error = NULL;
 	GObject *provider;
@@ -2605,6 +2627,15 @@ user_get_secrets_cb (DBusGProxy *proxy,
 	g_return_if_fail (info->provider);
 	g_return_if_fail (info->setting_name);
 
+	/* Remove the GetSecretsInfo from our internal list just in case
+	 * calling the secrets provider's get_secrets_result() function tries
+	 * to cancel the secrets request, which would cause us to double-free
+	 * the GetSecretsInfo.  We know we're going to free it at the end here,
+	 * so there's no need to track it anymore.
+	 */
+	priv = NM_MANAGER_GET_PRIVATE (info->manager);
+	priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
+
 	provider = g_object_ref (info->provider);
 
 	if (dbus_g_proxy_end_call (proxy, call, &error,
@@ -2905,10 +2936,8 @@ nm_manager_activate_connection (NMManager *manager,
 
 	if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
 		NMActRequest *req = NULL;
-		NMVPNManager *vpn_manager;
 
 		/* VPN connection */
-
 		if (specific_object) {
 			/* Find the specifc connection the client requested we use */
 			req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
@@ -2942,10 +2971,8 @@ 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,
-		                                                     req,
 		                                                     device,
 		                                                     error);
 		if (vpn_connection) {
@@ -2955,7 +2982,6 @@ nm_manager_activate_connection (NMManager *manager,
 			                  G_CALLBACK (provider_cancel_secrets), manager);
 			path = nm_vpn_connection_get_active_connection_path (vpn_connection);
 		}
-		g_object_unref (vpn_manager);
 	} else {
 		NMDeviceState state;
 
@@ -3136,7 +3162,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;
@@ -3160,17 +3185,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);
@@ -3383,7 +3406,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) {
@@ -3997,6 +4020,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;
@@ -4010,7 +4034,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 */
@@ -4344,7 +4369,7 @@ dispose (GObject *object)
 {
 	NMManager *manager = NM_MANAGER (object);
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-	GSList *iter;
+	GSList *iter, *list;
 	DBusGConnection *bus;
 	DBusConnection *dbus_connection;
 
@@ -4390,6 +4415,20 @@ dispose (GObject *object)
 		priv->sys_settings = NULL;
 	}
 
+	/* Make sure we disconnect signal handlers from VPN connections that
+	 * might still be alive when the manager dies.
+	 */
+	list = nm_vpn_manager_get_active_connections (priv->vpn_manager);
+	for (iter = list; iter; iter = g_slist_next (iter)) {
+		g_signal_handlers_disconnect_by_func (G_OBJECT (iter->data),
+						      G_CALLBACK (provider_get_secrets),
+						      manager);
+		g_signal_handlers_disconnect_by_func (G_OBJECT (iter->data),
+						      G_CALLBACK (provider_cancel_secrets),
+						      manager);
+		/* unref to balance returned objects from the VPN manager */
+		g_object_unref (iter->data);
+	}
 	if (priv->vpn_manager_id) {
 		g_source_remove (priv->vpn_manager_id);
 		priv->vpn_manager_id = 0;
@@ -4472,11 +4511,20 @@ 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);
+	new_enabled = radio_enabled_for_rstate (rstate, FALSE);
 	if (new_enabled != old_enabled)
-		manager_update_radio_enabled (self, rstate);
+		manager_update_radio_enabled (self, rstate, new_enabled);
 }
 
 static void
@@ -4526,13 +4574,13 @@ 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);
@@ -4599,7 +4647,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-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 ff0ef68c..3ec8e7c9 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -88,7 +88,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";
@@ -373,8 +373,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");
@@ -403,14 +407,24 @@ net_add (NMUdevManager *self, GUdevDevice *device)
 {
 	gint etype;
 	const char *iface;
-	const char *devtype;
+	const char *tmp;
 
 	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;
+	}
+
+	/* 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.
+	 */
 	etype = g_udev_device_get_sysfs_attr_as_int (device, "type");
-	if (etype != 1) {
+	if ((etype != 1) && (!strncmp (iface, "ctc", 3) && (etype != 256))) {
 		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
@@ -420,16 +434,22 @@ net_add (NMUdevManager *self, GUdevDevice *device)
 	 * subclass.  ModemManager will pick it up though and so we'll handle it
 	 * through the mobile broadband stuff.
 	 */
-	devtype = g_udev_device_get_property (device, "DEVTYPE");
-	if (devtype && !strcmp (devtype, "wwan")) {
-		nm_log_dbg (LOGD_HW, "ignoring interface with devtype '%s'", devtype);
+	tmp = g_udev_device_get_property (device, "DEVTYPE");
+	if (g_strcmp0 (tmp, "wwan") == 0) {
+		nm_log_dbg (LOGD_HW, "ignoring interface with devtype '%s'", tmp);
 		return;
 	}
 
-	iface = g_udev_device_get_name (device);
-	if (!iface) {
-		nm_log_dbg (LOGD_HW, "failed to get device's interface");
-		return;
+	/* Ignore Nokia cdc-ether interfaces in PC-Suite mode since we need to
+	 * talk phonet to use them, which ModemManager doesn't do yet.
+	 */
+	tmp = g_udev_device_get_property (device, "ID_VENDOR_ID");
+	if (g_strcmp0 (tmp, "0421") == 0) { /* Nokia vendor ID */
+		tmp = g_udev_device_get_property (device, "ID_MODEL");
+		if (tmp && (strstr (tmp, "PC-Suite") || strstr (tmp, "PC Suite"))) {
+			nm_log_dbg (LOGD_HW, "ignoring Nokia PC-Suite ethernet interface");
+			return;
+		}
 	}
 
 	g_signal_emit (self, signals[DEVICE_ADDED], 0, device, device_creator);
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 31a5e57a..1258b8f6 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;
@@ -163,11 +167,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;
 
-	if (priv->act_req)
-		g_object_unref (priv->act_req);
-	g_object_unref (priv->dbus_manager);
+		_ppp_cleanup (NM_PPP_MANAGER (object));
+
+		if (priv->act_req) {
+			g_object_unref (priv->act_req);
+			priv->act_req = NULL;
+		}
+
+		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));
 }
 
@@ -706,7 +721,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);
 
@@ -1023,8 +1038,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 a0200973..51684157 100644
--- a/src/ppp-manager/nm-ppp-manager.h
+++ b/src/ppp-manager/nm-ppp-manager.h
@@ -69,8 +69,6 @@ void     nm_ppp_manager_update_secrets (NMPPPManager *manager,
                                         const char *password,
                                         const char *error_message);
 
-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/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 03e213ff..823b6149 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -61,8 +61,6 @@ typedef struct {
 
 	NMConnection *connection;
 
-	NMActRequest *act_request;
-
 	NMDevice *parent_dev;
 	gulong device_monitor;
 	gulong device_ip4;
@@ -199,15 +197,12 @@ device_ip4_config_changed (NMDevice *device,
 }
 
 NMVPNConnection *
-nm_vpn_connection_new (NMConnection *connection,
-                       NMActRequest *act_request,
-                       NMDevice *parent_device)
+nm_vpn_connection_new (NMConnection *connection, NMDevice *parent_device)
 {
 	NMVPNConnection *self;
 	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);
@@ -218,7 +213,6 @@ nm_vpn_connection_new (NMConnection *connection,
 
 	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),
@@ -925,7 +919,7 @@ connection_state_changed (NMVPNConnection *connection,
 {
 	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-	nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request));
+	nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (connection));
 
 	switch (state) {
 	case NM_VPN_CONNECTION_STATE_NEED_AUTH:
@@ -989,7 +983,6 @@ dispose (GObject *object)
 	if (priv->proxy)
 		g_object_unref (priv->proxy);
 
-	g_object_unref (priv->act_request);
 	g_object_unref (priv->connection);
 
 	G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index ab880b17..8da7d512 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-secrets-provider-interface.h"
 #include "nm-vpn-connection-base.h"
 
@@ -57,9 +56,7 @@ typedef struct {
 
 GType nm_vpn_connection_get_type (void);
 
-NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
-                                         NMActRequest *act_request,
-                                         NMDevice *parent_device);
+NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, NMDevice *parent_device);
 
 void                 nm_vpn_connection_activate        (NMVPNConnection *connection);
 NMConnection *       nm_vpn_connection_get_connection  (NMVPNConnection *connection);
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c
index d3cd10a8..38b06b19 100644
--- a/src/vpn-manager/nm-vpn-manager.c
+++ b/src/vpn-manager/nm-vpn-manager.c
@@ -157,7 +157,6 @@ connection_vpn_state_changed (NMVPNConnection *connection,
 NMVPNConnection *
 nm_vpn_manager_activate_connection (NMVPNManager *manager,
                                     NMConnection *connection,
-                                    NMActRequest *act_request,
                                     NMDevice *device,
                                     GError **error)
 {
@@ -168,7 +167,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);
@@ -205,7 +203,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 		return NULL;
 	}
 
-	vpn = nm_vpn_service_activate (service, connection, act_request, device, error);
+	vpn = nm_vpn_service_activate (service, connection, device, 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 f14844a9..b9cf7daf 100644
--- a/src/vpn-manager/nm-vpn-manager.h
+++ b/src/vpn-manager/nm-vpn-manager.h
@@ -25,8 +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))
 #define NM_VPN_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
@@ -69,7 +67,6 @@ NMVPNManager *nm_vpn_manager_get (void);
 
 NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager,
                                                      NMConnection *connection,
-                                                     NMActRequest *act_request,
                                                      NMDevice *device,
                                                      GError **error);
 
diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c
index 3d44d900..68cfadb7 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,
                          GError **error)
 {
@@ -332,7 +331,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);
@@ -341,7 +339,7 @@ nm_vpn_service_activate (NMVPNService *service,
 
 	clear_quit_timeout (service);
 
-	vpn = nm_vpn_connection_new (connection, act_request, device);
+	vpn = nm_vpn_connection_new (connection, device);
 	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 c7c1b036..0c7030e4 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,
                                            GError **error);