summary refs log tree commit diff
path: root/src/vpn-manager
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
committerMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
commit2c032d8f1c6292c1338a615e6ec40252889ba85c (patch)
tree1f77182220b2b0264288ba4a476ab47e5bc48716 /src/vpn-manager
parent33491bc4279481db8ae47213e34a6d695a0e8830 (diff)
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/vpn-manager')
-rw-r--r--src/vpn-manager/nm-vpn-connection.c550
-rw-r--r--src/vpn-manager/nm-vpn-connection.h77
-rw-r--r--src/vpn-manager/nm-vpn-manager.c79
-rw-r--r--src/vpn-manager/nm-vpn-manager.h42
-rw-r--r--src/vpn-manager/nm-vpn-service.c92
-rw-r--r--src/vpn-manager/nm-vpn-service.h28
6 files changed, 509 insertions, 359 deletions
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index d66dcfdb..cb07c7f9 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -19,6 +19,8 @@
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include <string.h>
 #include <sys/socket.h>
@@ -27,16 +29,12 @@
 #include <errno.h>
 #include <stdlib.h>
 
-#include "NetworkManager.h"
-#include "NetworkManagerVPN.h"
 #include "nm-vpn-connection.h"
-#include "nm-setting-connection.h"
-#include "nm-setting-vpn.h"
-#include "nm-setting-ip4-config.h"
+#include "nm-ip4-config.h"
+#include "nm-ip6-config.h"
 #include "nm-dbus-manager.h"
 #include "nm-platform.h"
 #include "nm-logging.h"
-#include "nm-utils.h"
 #include "nm-active-connection.h"
 #include "nm-dbus-glib-types.h"
 #include "NetworkManagerUtils.h"
@@ -44,10 +42,12 @@
 #include "settings/nm-settings-connection.h"
 #include "nm-dispatcher.h"
 #include "nm-agent-manager.h"
+#include "nm-core-internal.h"
+#include "nm-default-route-manager.h"
 
 #include "nm-vpn-connection-glue.h"
 
-G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION)
+G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION)
 
 typedef enum {
 	/* Only system secrets */
@@ -62,7 +62,7 @@ typedef enum {
 	SECRETS_REQ_LAST
 } SecretsReq;
 
-/* Internal VPN states, private to NMVPNConnection */
+/* Internal VPN states, private to NMVpnConnection */
 typedef enum {
 	STATE_UNKNOWN = 0,
 	STATE_WAITING,
@@ -79,6 +79,8 @@ typedef enum {
 
 typedef struct {
 	NMConnection *connection;
+	gboolean service_can_persist;
+	gboolean connection_can_persist;
 
 	guint32 secrets_id;
 	SecretsReq secrets_idx;
@@ -86,7 +88,9 @@ typedef struct {
 
 	VpnState vpn_state;
 	guint dispatcher_id;
-	NMVPNConnectionStateReason failure_reason;
+	NMVpnConnectionStateReason failure_reason;
+
+	NMVpnServiceState service_state;
 
 	DBusGProxy *proxy;
 	GHashTable *connect_hash;
@@ -103,13 +107,14 @@ typedef struct {
 	int ip_ifindex;
 	char *banner;
 	guint32 mtu;
-} NMVPNConnectionPrivate;
+} NMVpnConnectionPrivate;
 
-#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
+#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVpnConnectionPrivate))
 
 enum {
 	VPN_STATE_CHANGED,
 	INTERNAL_STATE_CHANGED,
+	INTERNAL_RETRY_AFTER_FAILURE,
 
 	LAST_SIGNAL
 };
@@ -127,7 +132,7 @@ enum {
 	LAST_PROP
 };
 
-static void get_secrets (NMVPNConnection *self,
+static void get_secrets (NMVpnConnection *self,
                          SecretsReq secrets_idx,
                          const char **hints);
 
@@ -136,14 +141,14 @@ static void plugin_interactive_secrets_required (DBusGProxy *proxy,
                                                  const char **secrets,
                                                  gpointer user_data);
 
-static void _set_vpn_state (NMVPNConnection *connection,
+static void _set_vpn_state (NMVpnConnection *connection,
                             VpnState vpn_state,
-                            NMVPNConnectionStateReason reason,
+                            NMVpnConnectionStateReason reason,
                             gboolean quitting);
 
 /*********************************************************************/
 
-static NMVPNConnectionState
+static NMVpnConnectionState
 _state_to_nm_vpn_state (VpnState state)
 {
 	switch (state) {
@@ -173,7 +178,7 @@ _state_to_nm_vpn_state (VpnState state)
 	case STATE_FAILED:
 		return NM_VPN_CONNECTION_STATE_FAILED;
 	default:
-		return STATE_UNKNOWN;
+		return NM_VPN_CONNECTION_STATE_UNKNOWN;
 	}
 }
 
@@ -203,9 +208,9 @@ _state_to_ac_state (VpnState vpn_state)
 }
 
 static void
-call_plugin_disconnect (NMVPNConnection *self)
+call_plugin_disconnect (NMVpnConnection *self)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GError *error = NULL;
 
 	if (priv->proxy) {
@@ -222,9 +227,9 @@ call_plugin_disconnect (NMVPNConnection *self)
 }
 
 static void
-vpn_cleanup (NMVPNConnection *connection, NMDevice *parent_dev)
+vpn_cleanup (NMVpnConnection *connection, NMDevice *parent_dev)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
 	if (priv->ip_ifindex) {
 		nm_platform_link_set_down (priv->ip_ifindex);
@@ -252,8 +257,8 @@ vpn_cleanup (NMVPNConnection *connection, NMDevice *parent_dev)
 static void
 dispatcher_pre_down_done (guint call_id, gpointer user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 
 	priv->dispatcher_id = 0;
 	_set_vpn_state (self, STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
@@ -262,17 +267,17 @@ dispatcher_pre_down_done (guint call_id, gpointer user_data)
 static void
 dispatcher_pre_up_done (guint call_id, gpointer user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 
 	priv->dispatcher_id = 0;
 	_set_vpn_state (self, STATE_ACTIVATED, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
 }
 
 static void
-dispatcher_cleanup (NMVPNConnection *self)
+dispatcher_cleanup (NMVpnConnection *self)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 
 	if (priv->dispatcher_id) {
 		nm_dispatcher_call_cancel (priv->dispatcher_id);
@@ -281,14 +286,14 @@ dispatcher_cleanup (NMVPNConnection *self)
 }
 
 static void
-_set_vpn_state (NMVPNConnection *connection,
+_set_vpn_state (NMVpnConnection *connection,
                 VpnState vpn_state,
-                NMVPNConnectionStateReason reason,
+                NMVpnConnectionStateReason reason,
                 gboolean quitting)
 {
-	NMVPNConnectionPrivate *priv;
+	NMVpnConnectionPrivate *priv;
 	VpnState old_vpn_state;
-	NMVPNConnectionState new_external_state, old_external_state;
+	NMVpnConnectionState new_external_state, old_external_state;
 	NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection));
 
 	g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
@@ -319,6 +324,9 @@ _set_vpn_state (NMVPNConnection *connection,
 
 	dispatcher_cleanup (connection);
 
+	nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), connection);
+	nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), connection);
+
 	/* The connection gets destroyed by the VPN manager when it enters the
 	 * disconnected/failed state, but we need to keep it around for a bit
 	 * to send out signals and handle the dispatcher.  So ref it.
@@ -434,12 +442,34 @@ _set_vpn_state (NMVPNConnection *connection,
 		g_object_unref (parent_dev);
 }
 
+static gboolean
+_service_and_connection_can_persist (NMVpnConnection *self)
+{
+	return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist &&
+	       NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist;
+}
+
+static gboolean
+_connection_only_can_persist (NMVpnConnection *self)
+{
+	return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist &&
+	       !NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist;
+}
+
 static void
 device_state_changed (NMActiveConnection *active,
                       NMDevice *device,
                       NMDeviceState new_state,
                       NMDeviceState old_state)
 {
+	if (_service_and_connection_can_persist (NM_VPN_CONNECTION (active))) {
+		if (new_state <= NM_DEVICE_STATE_DISCONNECTED ||
+		    new_state == NM_DEVICE_STATE_FAILED) {
+			nm_active_connection_set_device (active, NULL);
+		}
+		return;
+	}
+
 	if (new_state <= NM_DEVICE_STATE_DISCONNECTED) {
 		_set_vpn_state (NM_VPN_CONNECTION (active),
 		                STATE_DISCONNECTED,
@@ -463,6 +493,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
 	NMIP4Config *parent_config;
 	guint32 parent_gw;
 	NMPlatformIP4Route route;
+	guint32 route_metric;
 
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
 	g_return_if_fail (NM_IS_DEVICE (parent_device));
@@ -478,6 +509,8 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
 	if (!parent_gw)
 		return;
 
+	route_metric = nm_device_get_ip4_route_metric (parent_device);
+
 	memset (&route, 0, sizeof (route));
 	route.network = vpn_gw;
 	route.plen = 32;
@@ -490,8 +523,8 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
 	if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
 		route.gateway = 0;
 
-	route.source = NM_PLATFORM_SOURCE_VPN;
-	route.metric = nm_device_get_priority (parent_device);
+	route.source = NM_IP_CONFIG_SOURCE_VPN;
+	route.metric = route_metric;
 	nm_ip4_config_add_route (config, &route);
 
 	/* Ensure there's a route to the parent device's gateway through the
@@ -502,8 +535,8 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
 	memset (&route, 0, sizeof (route));
 	route.network = parent_gw;
 	route.plen = 32;
-	route.source = NM_PLATFORM_SOURCE_VPN;
-	route.metric = nm_device_get_priority (parent_device);
+	route.source = NM_IP_CONFIG_SOURCE_VPN;
+	route.metric = route_metric;
 
 	nm_ip4_config_add_route (config, &route);
 }
@@ -516,6 +549,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
 	NMIP6Config *parent_config;
 	const struct in6_addr *parent_gw;
 	NMPlatformIP6Route route;
+	guint32 route_metric;
 
 	g_return_if_fail (NM_IS_IP6_CONFIG (config));
 	g_return_if_fail (NM_IS_DEVICE (parent_device));
@@ -527,6 +561,8 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
 	if (!parent_gw)
 		return;
 
+	route_metric = nm_device_get_ip6_route_metric (parent_device);
+
 	memset (&route, 0, sizeof (route));
 	route.network = *vpn_gw;
 	route.plen = 128;
@@ -539,8 +575,8 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
 	if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
 		route.gateway = in6addr_any;
 
-	route.source = NM_PLATFORM_SOURCE_VPN;
-	route.metric = nm_device_get_priority (parent_device);
+	route.source = NM_IP_CONFIG_SOURCE_VPN;
+	route.metric = route_metric;
 	nm_ip6_config_add_route (config, &route);
 
 	/* Ensure there's a route to the parent device's gateway through the
@@ -551,13 +587,13 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
 	memset (&route, 0, sizeof (route));
 	route.network = *parent_gw;
 	route.plen = 128;
-	route.source = NM_PLATFORM_SOURCE_VPN;
-	route.metric = nm_device_get_priority (parent_device);
+	route.source = NM_IP_CONFIG_SOURCE_VPN;
+	route.metric = route_metric;
 
 	nm_ip6_config_add_route (config, &route);
 }
 
-NMVPNConnection *
+NMVpnConnection *
 nm_vpn_connection_new (NMConnection *connection,
                        NMDevice *parent_device,
                        const char *specific_object,
@@ -566,7 +602,7 @@ nm_vpn_connection_new (NMConnection *connection,
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
 	g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
 
-	return (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
+	return (NMVpnConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
 	                                         NM_ACTIVE_CONNECTION_INT_CONNECTION, connection,
 	                                         NM_ACTIVE_CONNECTION_INT_DEVICE, parent_device,
 	                                         NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object,
@@ -576,17 +612,17 @@ nm_vpn_connection_new (NMConnection *connection,
 }
 
 static const char *
-nm_vpn_connection_get_service (NMVPNConnection *connection)
+nm_vpn_connection_get_service (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-	NMSettingVPN *s_vpn;
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMSettingVpn *s_vpn;
 
 	s_vpn = nm_connection_get_setting_vpn (priv->connection);
 	return nm_setting_vpn_get_service_type (s_vpn);
 }
 
 static const char *
-vpn_plugin_failure_to_string (NMVPNPluginFailure failure)
+vpn_plugin_failure_to_string (NMVpnPluginFailure failure)
 {
 	switch (failure) {
 	case NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED:
@@ -603,10 +639,10 @@ vpn_plugin_failure_to_string (NMVPNPluginFailure failure)
 
 static void
 plugin_failed (DBusGProxy *proxy,
-               NMVPNPluginFailure plugin_failure,
+               NMVpnPluginFailure plugin_failure,
                gpointer user_data)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (user_data);
 
 	nm_log_warn (LOGD_VPN, "VPN plugin failed: %s (%d)",
 	             vpn_plugin_failure_to_string (plugin_failure), plugin_failure);
@@ -620,11 +656,12 @@ plugin_failed (DBusGProxy *proxy,
 		break;
 	default:
 		priv->failure_reason = NM_VPN_CONNECTION_STATE_REASON_UNKNOWN;
+		break;
 	}
 }
 
 static const char *
-vpn_service_state_to_string (NMVPNServiceState state)
+vpn_service_state_to_string (NMVpnServiceState state)
 {
 	switch (state) {
 	case NM_VPN_SERVICE_STATE_INIT:
@@ -662,13 +699,13 @@ static const char *state_table[] = {
 static const char *
 vpn_state_to_string (VpnState state)
 {
-	if (state >= 0 && state < G_N_ELEMENTS (state_table))
+	if ((gsize) state < G_N_ELEMENTS (state_table))
 		return state_table[state];
 	return "unknown";
 }
 
 static const char *
-vpn_reason_to_string (NMVPNConnectionStateReason reason)
+vpn_reason_to_string (NMVpnConnectionStateReason reason)
 {
 	switch (reason) {
 	case NM_VPN_CONNECTION_STATE_REASON_NONE:
@@ -701,36 +738,52 @@ vpn_reason_to_string (NMVPNConnectionStateReason reason)
 
 static void
 plugin_state_changed (DBusGProxy *proxy,
-                      NMVPNServiceState state,
+                      NMVpnServiceState new_service_state,
                       gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnServiceState old_service_state = priv->service_state;
 
 	nm_log_info (LOGD_VPN, "VPN plugin state changed: %s (%d)",
-	             vpn_service_state_to_string (state), state);
+	             vpn_service_state_to_string (new_service_state), new_service_state);
+	priv->service_state = new_service_state;
 
-	if (state == NM_VPN_SERVICE_STATE_STOPPED) {
+	if (new_service_state == NM_VPN_SERVICE_STATE_STOPPED) {
 		/* Clear connection secrets to ensure secrets get requested each time the
 		 * connection is activated.
 		 */
 		nm_connection_clear_secrets (priv->connection);
 
 		if ((priv->vpn_state >= STATE_WAITING) && (priv->vpn_state <= STATE_ACTIVATED)) {
+			VpnState old_state = priv->vpn_state;
+
 			nm_log_info (LOGD_VPN, "VPN plugin state change reason: %s (%d)",
 			             vpn_reason_to_string (priv->failure_reason), priv->failure_reason);
 			_set_vpn_state (connection, STATE_FAILED, priv->failure_reason, FALSE);
 
 			/* Reset the failure reason */
 			priv->failure_reason = NM_VPN_CONNECTION_STATE_REASON_UNKNOWN;
+
+			/* If the connection failed, the service cannot persist, but the
+			 * connection can persist, ask listeners to re-activate the connection.
+			 */
+			if (   old_state == STATE_ACTIVATED
+			    && priv->vpn_state == STATE_FAILED
+			    && _connection_only_can_persist (connection))
+				g_signal_emit (connection, signals[INTERNAL_RETRY_AFTER_FAILURE], 0);
 		}
+	} else if (new_service_state == NM_VPN_SERVICE_STATE_STARTING &&
+	           old_service_state == NM_VPN_SERVICE_STATE_STARTED) {
+		/* The VPN service got disconnected and is attempting to reconnect */
+		_set_vpn_state (connection, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, FALSE);
 	}
 }
 
 static void
-print_vpn_config (NMVPNConnection *connection)
+print_vpn_config (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	const NMPlatformIP4Address *address4;
 	const NMPlatformIP6Address *address6;
 	char *dns_domain = NULL;
@@ -831,41 +884,29 @@ print_vpn_config (NMVPNConnection *connection)
 	}
 }
 
-static gboolean
-nm_vpn_connection_apply_config (NMVPNConnection *connection)
+static void
+apply_parent_device_config (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection));
 	NMIP4Config *vpn4_parent_config = NULL;
 	NMIP6Config *vpn6_parent_config = NULL;
 
-	if (priv->ip_ifindex > 0) {
-		nm_platform_link_set_up (priv->ip_ifindex);
+	if (priv->ip4_config)
+		vpn4_parent_config = nm_ip4_config_new ();
+	if (priv->ip6_config)
+		vpn6_parent_config = nm_ip6_config_new ();
 
-		if (priv->ip4_config) {
-			if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex))
-				return FALSE;
-		}
-
-		if (priv->ip6_config) {
-			if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex))
-				return FALSE;
-		}
-
-		if (priv->ip4_config)
-			vpn4_parent_config = nm_ip4_config_new ();
-		if (priv->ip6_config)
-			vpn6_parent_config = nm_ip6_config_new ();
-	} else {
+	if (priv->ip_ifindex <= 0) {
 		/* If the VPN didn't return a network interface, it is a route-based
 		 * VPN (like kernel IPSec) and all IP addressing and routing should
 		 * be done on the parent interface instead.
 		 */
 
-		if (priv->ip4_config)
-			vpn4_parent_config = g_object_ref (priv->ip4_config);
-		if (priv->ip6_config)
-			vpn6_parent_config = g_object_ref (priv->ip6_config);
+		if (vpn4_parent_config)
+			nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config);
+		if (vpn6_parent_config)
+			nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config);
 	}
 
 	if (vpn4_parent_config) {
@@ -884,6 +925,32 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
 		nm_device_set_vpn6_config (parent_dev, vpn6_parent_config);
 		g_object_unref (vpn6_parent_config);
 	}
+}
+
+static gboolean
+nm_vpn_connection_apply_config (NMVpnConnection *connection)
+{
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+	if (priv->ip_ifindex > 0) {
+		nm_platform_link_set_up (priv->ip_ifindex);
+
+		if (priv->ip4_config) {
+			if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex,
+			                           nm_vpn_connection_get_ip4_route_metric (connection)))
+				return FALSE;
+		}
+
+		if (priv->ip6_config) {
+			if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex))
+				return FALSE;
+		}
+	}
+
+	apply_parent_device_config (connection);
+
+	nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), connection);
+	nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), connection);
 
 	nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) complete.",
 	             nm_connection_get_id (priv->connection));
@@ -892,17 +959,13 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
 }
 
 static void
-nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection,
+nm_vpn_connection_config_maybe_complete (NMVpnConnection *connection,
                                          gboolean         success)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-	if (priv->connect_timeout == 0) {
-		/* config_complete() was already called with an error;
-		 * ignore further calls.
-		 */
+	if (priv->vpn_state < STATE_IP_CONFIG_GET || priv->vpn_state > STATE_ACTIVATED)
 		return;
-	}
 
 	if (success) {
 		if (   (priv->has_ip4 && !priv->ip4_config)
@@ -912,8 +975,10 @@ nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection,
 		}
 	}
 
-	g_source_remove (priv->connect_timeout);
-	priv->connect_timeout = 0;
+	if (priv->connect_timeout) {
+		g_source_remove (priv->connect_timeout);
+		priv->connect_timeout = 0;
+	}
 
 	if (success) {
 		print_vpn_config (connection);
@@ -935,12 +1000,18 @@ nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection,
                           nm_connection_get_id (priv->connection), property)
 
 static gboolean
-process_generic_config (NMVPNConnection *connection,
+process_generic_config (NMVpnConnection *connection,
                         GHashTable *config_hash)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	GValue *val;
 
+	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CAN_PERSIST);
+	if (val && G_VALUE_HOLDS_BOOLEAN (val) && g_value_get_boolean (val)) {
+		/* Defaults to FALSE, so only let service indicate TRUE */
+		priv->service_can_persist = TRUE;
+	}
+
 	g_clear_pointer (&priv->ip_iface, g_free);
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CONFIG_TUNDEV);
 	if (val) {
@@ -1014,8 +1085,8 @@ nm_vpn_connection_config_get (DBusGProxy *proxy,
                               GHashTable *config_hash,
                               gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	GValue *val;
 
 	nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) reply received.",
@@ -1049,18 +1120,34 @@ nm_vpn_connection_config_get (DBusGProxy *proxy,
 	g_clear_object (&priv->ip6_config);
 }
 
-static guint
-vpn_routing_metric (NMVPNConnection *connection)
+guint32
+nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
-	if (priv->ip_ifindex)
-		return NM_PLATFORM_ROUTE_METRIC_DEFAULT;
-	else {
-		NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection));
+	if (priv->connection) {
+		gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (priv->connection));
 
-		return nm_device_get_priority (parent_dev);
+		if (route_metric >= 0)
+			return route_metric;
 	}
+
+	return NM_VPN_ROUTE_METRIC_DEFAULT;
+}
+
+guint32
+nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *connection)
+{
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+	if (priv->connection) {
+		gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (priv->connection));
+
+		if (route_metric >= 0)
+			return route_metric;
+	}
+
+	return NM_VPN_ROUTE_METRIC_DEFAULT;
 }
 
 static void
@@ -1068,12 +1155,13 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
                                   GHashTable *config_hash,
                                   gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	NMPlatformIP4Address address;
 	NMIP4Config *config;
 	GValue *val;
 	int i;
+	guint32 route_metric;
 
 	if (priv->vpn_state == STATE_CONNECT)
 		_set_vpn_state (connection, STATE_IP_CONFIG_GET, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
@@ -1126,7 +1214,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 		address.plen = g_value_get_uint (val);
 
 	if (address.address && address.plen) {
-		address.source = NM_PLATFORM_SOURCE_VPN;
+		address.source = NM_IP_CONFIG_SOURCE_VPN;
 		nm_ip4_config_add_address (config, &address);
 	} else {
 		nm_log_err (LOGD_VPN, "invalid IP4 config received!");
@@ -1156,7 +1244,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 		nm_ip4_config_set_mss (config, g_value_get_uint (val));
 
 	if (priv->mtu)
-		nm_ip4_config_set_mtu (config, priv->mtu);
+		nm_ip4_config_set_mtu (config, priv->mtu, NM_IP_CONFIG_SOURCE_VPN);
 
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN);
 	if (val)
@@ -1171,6 +1259,8 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 			nm_ip4_config_add_domain (config, *domain);
 	}
 
+	route_metric = nm_vpn_connection_get_ip4_route_metric (connection);
+
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES);
 	if (val) {
 		GSList *routes;
@@ -1178,15 +1268,15 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 
 		routes = nm_utils_ip4_routes_from_gvalue (val);
 		for (iter = routes; iter; iter = iter->next) {
-			NMIP4Route *item = iter->data;
+			NMIPRoute *item = iter->data;
 			NMPlatformIP4Route route;
 
 			memset (&route, 0, sizeof (route));
-			route.network = nm_ip4_route_get_dest (item);
-			route.plen = nm_ip4_route_get_prefix (item);
-			route.gateway = nm_ip4_route_get_next_hop (item);
-			route.source = NM_PLATFORM_SOURCE_VPN;
-			route.metric = vpn_routing_metric (connection);
+			nm_ip_route_get_dest_binary (item, &route.network);
+			route.plen = nm_ip_route_get_prefix (item);
+			nm_ip_route_get_next_hop_binary (item, &route.gateway);
+			route.source = NM_IP_CONFIG_SOURCE_VPN;
+			route.metric = route_metric;
 
 			/* Ignore host routes to the VPN gateway since NM adds one itself
 			 * below.  Since NM knows more about the routing situation than
@@ -1200,7 +1290,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 			nm_ip4_config_add_route (config, &route);
 		}
 
-		g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref);
+		g_slist_free_full (routes, (GDestroyNotify) nm_ip_route_unref);
 	}
 
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT);
@@ -1210,8 +1300,9 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 	/* Merge in user overrides from the NMConnection's IPv4 setting */
 	nm_ip4_config_merge_setting (config,
 	                             nm_connection_get_setting_ip4_config (priv->connection),
-	                             vpn_routing_metric (connection));
+	                             route_metric);
 
+	g_clear_object (&priv->ip4_config);
 	priv->ip4_config = config;
 	nm_ip4_config_export (config);
 	g_object_notify (G_OBJECT (connection), NM_ACTIVE_CONNECTION_IP4_CONFIG);
@@ -1223,12 +1314,13 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
                                   GHashTable *config_hash,
                                   gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	NMPlatformIP6Address address;
 	NMIP6Config *config;
 	GValue *val;
 	int i;
+	guint32 route_metric;
 
 	nm_log_info (LOGD_VPN, "VPN connection '%s' (IP6 Config Get) reply received.",
 	             nm_connection_get_id (priv->connection));
@@ -1280,7 +1372,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 		address.plen = g_value_get_uint (val);
 
 	if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen) {
-		address.source = NM_PLATFORM_SOURCE_VPN;
+		address.source = NM_IP_CONFIG_SOURCE_VPN;
 		nm_ip6_config_add_address (config, &address);
 	} else {
 		nm_log_err (LOGD_VPN, "invalid IP6 config received!");
@@ -1317,6 +1409,8 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 			nm_ip6_config_add_domain (config, *domain);
 	}
 
+	route_metric = nm_vpn_connection_get_ip6_route_metric (connection);
+
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES);
 	if (val) {
 		GSList *routes;
@@ -1324,15 +1418,15 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 
 		routes = nm_utils_ip6_routes_from_gvalue (val);
 		for (iter = routes; iter; iter = iter->next) {
-			NMIP6Route *item = iter->data;
+			NMIPRoute *item = iter->data;
 			NMPlatformIP6Route route;
 
 			memset (&route, 0, sizeof (route));
-			route.network = *nm_ip6_route_get_dest (item);
-			route.plen = nm_ip6_route_get_prefix (item);
-			route.gateway = *nm_ip6_route_get_next_hop (item);
-			route.source = NM_PLATFORM_SOURCE_VPN;
-			route.metric = vpn_routing_metric (connection);
+			nm_ip_route_get_dest_binary (item, &route.network);
+			route.plen = nm_ip_route_get_prefix (item);
+			nm_ip_route_get_next_hop_binary (item, &route.gateway);
+			route.source = NM_IP_CONFIG_SOURCE_VPN;
+			route.metric = route_metric;
 
 			/* Ignore host routes to the VPN gateway since NM adds one itself
 			 * below.  Since NM knows more about the routing situation than
@@ -1346,7 +1440,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 			nm_ip6_config_add_route (config, &route);
 		}
 
-		g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref);
+		g_slist_free_full (routes, (GDestroyNotify) nm_ip_route_unref);
 	}
 
 	val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT);
@@ -1356,8 +1450,9 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 	/* Merge in user overrides from the NMConnection's IPv6 setting */
 	nm_ip6_config_merge_setting (config,
 	                             nm_connection_get_setting_ip6_config (priv->connection),
-	                             vpn_routing_metric (connection));
+	                             route_metric);
 
+	g_clear_object (&priv->ip6_config);
 	priv->ip6_config = config;
 	nm_ip6_config_export (config);
 	g_object_notify (G_OBJECT (connection), NM_ACTIVE_CONNECTION_IP6_CONFIG);
@@ -1367,8 +1462,8 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
 static gboolean
 connect_timeout_cb (gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
 	priv->connect_timeout = 0;
 
@@ -1384,9 +1479,9 @@ connect_timeout_cb (gpointer user_data)
 }
 
 static void
-connect_success (NMVPNConnection *connection)
+connect_success (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
 	/* 40 second timeout waiting for IP config signal from VPN service */
 	priv->connect_timeout = g_timeout_add_seconds (40, connect_timeout_cb, connection);
@@ -1398,8 +1493,8 @@ connect_success (NMVPNConnection *connection)
 static void
 connect_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GError *err = NULL;
 
 	nm_log_info (LOGD_VPN, "VPN connection '%s' (Connect) reply received.",
@@ -1420,8 +1515,8 @@ connect_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 static void
 connect_interactive_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GError *err = NULL;
 
 	nm_log_info (LOGD_VPN, "VPN connection '%s' (ConnectInteractive) reply received.",
@@ -1452,8 +1547,9 @@ static GHashTable *
 _hash_with_username (NMConnection *connection, const char *username)
 {
 	NMConnection *dup;
-	NMSettingVPN *s_vpn;
+	NMSettingVpn *s_vpn;
 	GHashTable *hash;
+	GVariant *dict;
 	const char *existing;
 
 	/* Shortcut if we weren't given a username or if there already was one in
@@ -1462,23 +1558,30 @@ _hash_with_username (NMConnection *connection, const char *username)
 	s_vpn = nm_connection_get_setting_vpn (connection);
 	g_assert (s_vpn);
 	existing = nm_setting_vpn_get_user_name (s_vpn);
-	if (username == NULL || existing)
-		return nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+	if (username == NULL || existing) {
+		dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
+		hash = nm_utils_connection_dict_to_hash (dict);
+		g_variant_unref (dict);
+		return hash;
+	}
 
-	dup = nm_connection_duplicate (connection);
+	dup = nm_simple_connection_new_clone (connection);
 	g_assert (dup);
 	s_vpn = nm_connection_get_setting_vpn (dup);
 	g_assert (s_vpn);
 	g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL);
-	hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ALL);
+	dict = nm_connection_to_dbus (dup, NM_CONNECTION_SERIALIZE_ALL);
 	g_object_unref (dup);
+
+	hash = nm_utils_connection_dict_to_hash (dict);
+	g_variant_unref (dict);
 	return hash;
 }
 
 static void
-really_activate (NMVPNConnection *connection, const char *username)
+really_activate (NMVpnConnection *connection, const char *username)
 {
-	NMVPNConnectionPrivate *priv;
+	NMVpnConnectionPrivate *priv;
 	NMAgentManager *agent_mgr;
 	GHashTable *details;
 
@@ -1542,15 +1645,20 @@ really_activate (NMVPNConnection *connection, const char *username)
 }
 
 void
-nm_vpn_connection_activate (NMVPNConnection *connection)
+nm_vpn_connection_activate (NMVpnConnection *connection)
 {
-	NMVPNConnectionPrivate *priv;
+	NMVpnConnectionPrivate *priv;
+	NMSettingVpn *s_vpn;
 	DBusGConnection *bus;
 
 	g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
 
 	priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 
+	s_vpn = nm_connection_get_setting_vpn (priv->connection);
+	g_assert (s_vpn);
+	priv->connection_can_persist = nm_setting_vpn_get_persistent (s_vpn);
+
 	_set_vpn_state (connection, STATE_PREPARE, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
 
 	bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
@@ -1588,15 +1696,26 @@ nm_vpn_connection_activate (NMVPNConnection *connection)
 }
 
 NMConnection *
-nm_vpn_connection_get_connection (NMVPNConnection *connection)
+nm_vpn_connection_get_connection (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
 	return NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection;
 }
 
-NMVPNConnectionState
-nm_vpn_connection_get_vpn_state (NMVPNConnection *connection)
+const char*
+nm_vpn_connection_get_connection_id (NMVpnConnection *connection)
+{
+	NMConnection *c;
+
+	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
+
+	c = NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection;
+	return c ? nm_connection_get_id (c) : NULL;
+}
+
+NMVpnConnectionState
+nm_vpn_connection_get_vpn_state (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NM_VPN_CONNECTION_STATE_UNKNOWN);
 
@@ -1604,7 +1723,7 @@ nm_vpn_connection_get_vpn_state (NMVPNConnection *connection)
 }
 
 const char *
-nm_vpn_connection_get_banner (NMVPNConnection *connection)
+nm_vpn_connection_get_banner (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
@@ -1612,7 +1731,7 @@ nm_vpn_connection_get_banner (NMVPNConnection *connection)
 }
 
 NMIP4Config *
-nm_vpn_connection_get_ip4_config (NMVPNConnection *connection)
+nm_vpn_connection_get_ip4_config (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
@@ -1620,7 +1739,7 @@ nm_vpn_connection_get_ip4_config (NMVPNConnection *connection)
 }
 
 NMIP6Config *
-nm_vpn_connection_get_ip6_config (NMVPNConnection *connection)
+nm_vpn_connection_get_ip6_config (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
@@ -1628,7 +1747,7 @@ nm_vpn_connection_get_ip6_config (NMVPNConnection *connection)
 }
 
 const char *
-nm_vpn_connection_get_ip_iface (NMVPNConnection *connection)
+nm_vpn_connection_get_ip_iface (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
 
@@ -1636,7 +1755,7 @@ nm_vpn_connection_get_ip_iface (NMVPNConnection *connection)
 }
 
 int
-nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection)
+nm_vpn_connection_get_ip_ifindex (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), -1);
 
@@ -1644,7 +1763,7 @@ nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection)
 }
 
 guint32
-nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection)
+nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), 0);
 
@@ -1652,7 +1771,7 @@ nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection)
 }
 
 struct in6_addr *
-nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection)
+nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *connection)
 {
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), 0);
 
@@ -1660,8 +1779,8 @@ nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection)
 }
 
 void
-nm_vpn_connection_disconnect (NMVPNConnection *connection,
-                              NMVPNConnectionStateReason reason,
+nm_vpn_connection_disconnect (NMVpnConnection *connection,
+                              NMVpnConnectionStateReason reason,
                               gboolean quitting)
 {
 	g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
@@ -1670,11 +1789,11 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
 }
 
 gboolean
-nm_vpn_connection_deactivate (NMVPNConnection *connection,
-                              NMVPNConnectionStateReason reason,
+nm_vpn_connection_deactivate (NMVpnConnection *connection,
+                              NMVpnConnectionStateReason reason,
                               gboolean quitting)
 {
-	NMVPNConnectionPrivate *priv;
+	NMVpnConnectionPrivate *priv;
 	gboolean success = FALSE;
 
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), FALSE);
@@ -1692,8 +1811,8 @@ nm_vpn_connection_deactivate (NMVPNConnection *connection,
 static void
 plugin_need_secrets_cb  (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GError *error = NULL;
 	char *setting_name;
 
@@ -1741,11 +1860,13 @@ plugin_need_secrets_cb  (DBusGProxy *proxy, DBusGProxyCall *call, void *user_dat
 static void
 plugin_new_secrets_cb  (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GError *error = NULL;
 
-	if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+	if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+		_set_vpn_state (self, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
+	} else {
 		nm_log_err (LOGD_VPN, "(%s/%s) sending new secrets to the plugin failed: %s %s",
 		            nm_connection_get_uuid (priv->connection),
 		            nm_connection_get_id (priv->connection),
@@ -1764,8 +1885,8 @@ get_secrets_cb (NMSettingsConnection *connection,
                 GError *error,
                 gpointer user_data)
 {
-	NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnection *self = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 	GHashTable *hash;
 
 	g_return_if_fail (NM_CONNECTION (connection) == priv->connection);
@@ -1813,12 +1934,12 @@ get_secrets_cb (NMSettingsConnection *connection,
 }
 
 static void
-get_secrets (NMVPNConnection *self,
+get_secrets (NMVpnConnection *self,
              SecretsReq secrets_idx,
              const char **hints)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
-	NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_NONE;
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE;
 	GError *error = NULL;
 
 	g_return_if_fail (secrets_idx < SECRETS_REQ_LAST);
@@ -1831,21 +1952,21 @@ get_secrets (NMVPNConnection *self,
 
 	switch (priv->secrets_idx) {
 	case SECRETS_REQ_SYSTEM:
-		flags = NM_SETTINGS_GET_SECRETS_FLAG_ONLY_SYSTEM;
+		flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM;
 		break;
 	case SECRETS_REQ_EXISTING:
-		flags = NM_SETTINGS_GET_SECRETS_FLAG_NONE;
+		flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE;
 		break;
 	case SECRETS_REQ_NEW:
 	case SECRETS_REQ_INTERACTIVE:
-		flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+		flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
 		break;
 	default:
 		g_assert_not_reached ();
 	}
 
 	if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self)))
-		flags |= NM_SETTINGS_GET_SECRETS_FLAG_USER_REQUESTED;
+		flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED;
 
 	priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
 	                                                       nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
@@ -1871,8 +1992,8 @@ plugin_interactive_secrets_required (DBusGProxy *proxy,
                                      const char **secrets,
                                      gpointer user_data)
 {
-	NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+	NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
 	guint32 secrets_len = secrets ? g_strv_length ((char **) secrets) : 0;
 	char **hints;
 	guint32 i;
@@ -1900,9 +2021,42 @@ plugin_interactive_secrets_required (DBusGProxy *proxy,
 /******************************************************************************/
 
 static void
-nm_vpn_connection_init (NMVPNConnection *self)
+device_changed (NMActiveConnection *active,
+                NMDevice *new_device,
+                NMDevice *old_device)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (active);
+
+	if (!_service_and_connection_can_persist (NM_VPN_CONNECTION (active)))
+		return;
+	if (priv->vpn_state < STATE_CONNECT || priv->vpn_state > STATE_ACTIVATED)
+		return;
+
+	/* Route-based VPNs must update their routing and send a new IP config
+	 * since all their routes need to be adjusted for new_device.
+	 */
+	if (priv->ip_ifindex <= 0)
+		return;
+
+	/* Device changed underneath the VPN connection.  Let the plugin figure
+	 * out that connectivity is down and start its reconnect attempt if it
+	 * needs to.
+	 */
+	if (old_device) {
+		nm_device_set_vpn4_config (old_device, NULL);
+		nm_device_set_vpn6_config (old_device, NULL);
+	}
+
+	if (new_device)
+		apply_parent_device_config (NM_VPN_CONNECTION (active));
+}
+
+/******************************************************************************/
+
+static void
+nm_vpn_connection_init (NMVpnConnection *self)
+{
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
 
 	priv->vpn_state = STATE_WAITING;
 	priv->secrets_idx = SECRETS_REQ_SYSTEM;
@@ -1922,7 +2076,7 @@ constructed (GObject *object)
 static void
 dispose (GObject *object)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
 
 	if (priv->connect_hash) {
 		g_hash_table_destroy (priv->connect_hash);
@@ -1953,7 +2107,7 @@ dispose (GObject *object)
 static void
 finalize (GObject *object)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
 
 	g_free (priv->banner);
 	g_free (priv->ip_iface);
@@ -1974,7 +2128,7 @@ static void
 get_property (GObject *object, guint prop_id,
 		    GValue *value, GParamSpec *pspec)
 {
-	NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
+	NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
 	NMDevice *parent_dev;
 
 	switch (prop_id) {
@@ -2007,12 +2161,12 @@ get_property (GObject *object, guint prop_id,
 }
 
 static void
-nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
+nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
 	NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class);
 
-	g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
+	g_type_class_add_private (connection_class, sizeof (NMVpnConnectionPrivate));
 
 	/* virtual methods */
 	object_class->get_property = get_property;
@@ -2020,25 +2174,26 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
 	object_class->dispose = dispose;
 	object_class->finalize = finalize;
 	active_class->device_state_changed = device_state_changed;
+	active_class->device_changed = device_changed;
 
 	g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER);
 
 	/* properties */
-	g_object_class_install_property (object_class, PROP_VPN_STATE,
-		g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE,
-		                   "VpnState",
-		                   "Current VPN state",
-		                   NM_VPN_CONNECTION_STATE_UNKNOWN,
-		                   NM_VPN_CONNECTION_STATE_DISCONNECTED,
-		                   NM_VPN_CONNECTION_STATE_UNKNOWN,
-		                   G_PARAM_READABLE));
-
-	g_object_class_install_property (object_class, PROP_BANNER,
-		g_param_spec_string (NM_VPN_CONNECTION_BANNER,
-		                     "Banner",
-		                     "Login Banner",
-		                     NULL,
-		                     G_PARAM_READABLE));
+	g_object_class_install_property
+		(object_class, PROP_VPN_STATE,
+		 g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "",
+		                    NM_VPN_CONNECTION_STATE_UNKNOWN,
+		                    NM_VPN_CONNECTION_STATE_DISCONNECTED,
+		                    NM_VPN_CONNECTION_STATE_UNKNOWN,
+		                    G_PARAM_READABLE |
+		                    G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property
+		(object_class, PROP_BANNER,
+		 g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "",
+		                      NULL,
+		                      G_PARAM_READABLE |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_override_property (object_class, PROP_IP4_CONFIG,
 	                                  NM_ACTIVE_CONNECTION_IP4_CONFIG);
@@ -2060,6 +2215,13 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
 		              0, NULL, NULL, NULL,
 		              G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
 
+	signals[INTERNAL_RETRY_AFTER_FAILURE] =
+		g_signal_new (NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE,
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_FIRST,
+		              0, NULL, NULL, NULL,
+		              G_TYPE_NONE, 0);
+
 	nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
 	                                        G_TYPE_FROM_CLASS (object_class),
 	                                        &dbus_glib_nm_vpn_connection_object_info);
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index c9c88cda..0e63caac 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -19,21 +19,22 @@
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
-#ifndef NM_VPN_CONNECTION_H
-#define NM_VPN_CONNECTION_H
+#ifndef __NETWORKMANAGER_VPN_CONNECTION_H__
+#define __NETWORKMANAGER_VPN_CONNECTION_H__
 
 #include <glib.h>
 #include <glib-object.h>
-#include "NetworkManagerVPN.h"
+#include "nm-vpn-dbus-interface.h"
 #include "nm-device.h"
 #include "nm-auth-subject.h"
+#include "nm-active-connection.h"
 
 #define NM_TYPE_VPN_CONNECTION            (nm_vpn_connection_get_type ())
-#define NM_VPN_CONNECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection))
-#define NM_VPN_CONNECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
+#define NM_VPN_CONNECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnection))
+#define NM_VPN_CONNECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass))
 #define NM_IS_VPN_CONNECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION))
 #define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_CONNECTION))
-#define NM_VPN_CONNECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
+#define NM_VPN_CONNECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass))
 
 /* Properties */
 #define NM_VPN_CONNECTION_VPN_STATE "vpn-state"
@@ -41,52 +42,62 @@
 
 /* Signals */
 /* not exported: includes old reason code */
-#define NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED "internal-state-changed"
+#define NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED       "internal-state-changed"
+#define NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE "internal-retry-after-failure"
 
 
-typedef struct {
+#define NM_VPN_ROUTE_METRIC_DEFAULT     50
+
+
+struct _NMVpnConnection {
 	NMActiveConnection parent;
-} NMVPNConnection;
+};
 
 typedef struct {
 	NMActiveConnectionClass parent;
 
 	/* Signals */
-	void (*vpn_state_changed) (NMVPNConnection *connection,
-	                           NMVPNConnectionState new_state,
-	                           NMVPNConnectionStateReason reason);
+	void (*vpn_state_changed) (NMVpnConnection *connection,
+	                           NMVpnConnectionState new_state,
+	                           NMVpnConnectionStateReason reason);
 
 	/* not exported over D-Bus */
-	void (*internal_state_changed) (NMVPNConnection *connection,
-	                                NMVPNConnectionState new_state,
-	                                NMVPNConnectionState old_state,
-	                                NMVPNConnectionStateReason reason);
-} NMVPNConnectionClass;
+	void (*internal_state_changed) (NMVpnConnection *connection,
+	                                NMVpnConnectionState new_state,
+	                                NMVpnConnectionState old_state,
+	                                NMVpnConnectionStateReason reason);
+
+	void (*internal_failed_retry)  (NMVpnConnection *connection);
+} NMVpnConnectionClass;
 
 GType nm_vpn_connection_get_type (void);
 
-NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
+NMVpnConnection * nm_vpn_connection_new (NMConnection *connection,
                                          NMDevice *parent_device,
                                          const char *specific_object,
                                          NMAuthSubject *subject);
 
-void                 nm_vpn_connection_activate        (NMVPNConnection *connection);
-NMConnection *       nm_vpn_connection_get_connection  (NMVPNConnection *connection);
-NMVPNConnectionState nm_vpn_connection_get_vpn_state   (NMVPNConnection *connection);
-const char *         nm_vpn_connection_get_banner      (NMVPNConnection *connection);
+void                 nm_vpn_connection_activate        (NMVpnConnection *connection);
+NMConnection *       nm_vpn_connection_get_connection  (NMVpnConnection *connection);
+const char*          nm_vpn_connection_get_connection_id (NMVpnConnection *connection);
+NMVpnConnectionState nm_vpn_connection_get_vpn_state   (NMVpnConnection *connection);
+const char *         nm_vpn_connection_get_banner      (NMVpnConnection *connection);
 
-gboolean             nm_vpn_connection_deactivate      (NMVPNConnection *connection,
-                                                        NMVPNConnectionStateReason reason,
+gboolean             nm_vpn_connection_deactivate      (NMVpnConnection *connection,
+                                                        NMVpnConnectionStateReason reason,
                                                         gboolean quitting);
-void                 nm_vpn_connection_disconnect      (NMVPNConnection *connection,
-                                                        NMVPNConnectionStateReason reason,
+void                 nm_vpn_connection_disconnect      (NMVpnConnection *connection,
+                                                        NMVpnConnectionStateReason reason,
                                                         gboolean quitting);
 
-NMIP4Config *        nm_vpn_connection_get_ip4_config  (NMVPNConnection *connection);
-NMIP6Config *        nm_vpn_connection_get_ip6_config  (NMVPNConnection *connection);
-const char *         nm_vpn_connection_get_ip_iface    (NMVPNConnection *connection);
-int                  nm_vpn_connection_get_ip_ifindex  (NMVPNConnection *connection);
-guint32              nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection);
-struct in6_addr *    nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection);
+NMIP4Config *        nm_vpn_connection_get_ip4_config  (NMVpnConnection *connection);
+NMIP6Config *        nm_vpn_connection_get_ip6_config  (NMVpnConnection *connection);
+const char *         nm_vpn_connection_get_ip_iface    (NMVpnConnection *connection);
+int                  nm_vpn_connection_get_ip_ifindex  (NMVpnConnection *connection);
+guint32              nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *connection);
+struct in6_addr *    nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *connection);
+
+guint32              nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *connection);
+guint32              nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *connection);
 
-#endif /* NM_VPN_CONNECTION_H */
+#endif /* __NETWORKMANAGER_VPN_CONNECTION_H__ */
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c
index 5550d4d6..1f3798c7 100644
--- a/src/vpn-manager/nm-vpn-manager.c
+++ b/src/vpn-manager/nm-vpn-manager.c
@@ -19,6 +19,8 @@
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
+#include "config.h"
+
 #include <string.h>
 #include <gio/gio.h>
 
@@ -27,36 +29,27 @@
 #include "nm-vpn-connection.h"
 #include "nm-setting-vpn.h"
 #include "nm-dbus-manager.h"
-#include "NetworkManagerVPN.h"
+#include "nm-vpn-dbus-interface.h"
 #include "nm-enum-types.h"
 #include "nm-logging.h"
 
 #define VPN_NAME_FILES_DIR NMCONFDIR "/VPN"
 
-G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
+G_DEFINE_TYPE (NMVpnManager, nm_vpn_manager, G_TYPE_OBJECT)
 
-#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
+#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVpnManagerPrivate))
 
 typedef struct {
 	GHashTable *services;
 	GFileMonitor *monitor;
 	guint monitor_id;
-} NMVPNManagerPrivate;
+} NMVpnManagerPrivate;
 
-GQuark
-nm_vpn_manager_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("nm-vpn-manager-error");
-	return quark;
-}
 
-
-static NMVPNService *
-get_service_by_namefile (NMVPNManager *self, const char *namefile)
+static NMVpnService *
+get_service_by_namefile (NMVpnManager *self, const char *namefile)
 {
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
 	GHashTableIter iter;
 	gpointer data;
 
@@ -65,7 +58,7 @@ get_service_by_namefile (NMVPNManager *self, const char *namefile)
 
 	g_hash_table_iter_init (&iter, priv->services);
 	while (g_hash_table_iter_next (&iter, NULL, &data)) {
-		NMVPNService *candidate = NM_VPN_SERVICE (data);
+		NMVpnService *candidate = NM_VPN_SERVICE (data);
 		const char *service_namefile;
 
 		service_namefile = nm_vpn_service_get_name_file (candidate);
@@ -76,13 +69,13 @@ get_service_by_namefile (NMVPNManager *self, const char *namefile)
 }
 
 gboolean
-nm_vpn_manager_activate_connection (NMVPNManager *manager,
-                                    NMVPNConnection *vpn,
+nm_vpn_manager_activate_connection (NMVpnManager *manager,
+                                    NMVpnConnection *vpn,
                                     GError **error)
 {
 	NMConnection *connection;
-	NMSettingVPN *s_vpn;
-	NMVPNService *service;
+	NMSettingVpn *s_vpn;
+	NMVpnService *service;
 	const char *service_name;
 	NMDevice *device;
 
@@ -95,7 +88,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 	g_assert (device);
 	if (   nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED
 	    && nm_device_get_state (device) != NM_DEVICE_STATE_SECONDARIES) {
-		g_set_error_literal (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE,
+		g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED,
 		                     "The base device for the VPN connection was not active.");
 		return FALSE;
 	}
@@ -109,7 +102,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 	g_assert (service_name);
 	service = g_hash_table_lookup (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name);
 	if (!service) {
-		g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID,
+		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
 		             "The VPN service '%s' was not installed.",
 		             service_name);
 		return FALSE;
@@ -119,18 +112,18 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
 }
 
 gboolean
-nm_vpn_manager_deactivate_connection (NMVPNManager *self,
-                                      NMVPNConnection *connection,
-                                      NMVPNConnectionStateReason reason)
+nm_vpn_manager_deactivate_connection (NMVpnManager *self,
+                                      NMVpnConnection *connection,
+                                      NMVpnConnectionStateReason reason)
 {
 	return nm_vpn_connection_deactivate (connection, reason, FALSE);
 }
 
 static void
-try_add_service (NMVPNManager *self, const char *namefile)
+try_add_service (NMVpnManager *self, const char *namefile)
 {
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
-	NMVPNService *service = NULL;
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
+	NMVpnService *service = NULL;
 	GHashTableIter iter;
 	GError *error = NULL;
 	const char *service_name;
@@ -166,9 +159,9 @@ vpn_dir_changed (GFileMonitor *monitor,
                  GFileMonitorEvent event_type,
                  gpointer user_data)
 {
-	NMVPNManager *self = NM_VPN_MANAGER (user_data);
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
-	NMVPNService *service;
+	NMVpnManager *self = NM_VPN_MANAGER (user_data);
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
+	NMVpnService *service;
 	char *path;
 
 	path = g_file_get_path (file);
@@ -207,10 +200,10 @@ vpn_dir_changed (GFileMonitor *monitor,
 
 /******************************************************************************/
 
-NMVPNManager *
+NMVpnManager *
 nm_vpn_manager_get (void)
 {
-	static NMVPNManager *singleton = NULL;
+	static NMVpnManager *singleton = NULL;
 
 	if (!singleton)
 		singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL));
@@ -222,9 +215,9 @@ nm_vpn_manager_get (void)
 }
 
 static void
-nm_vpn_manager_init (NMVPNManager *self)
+nm_vpn_manager_init (NMVpnManager *self)
 {
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
 	GFile *file;
 	GDir *dir;
 	const char *fn;
@@ -258,11 +251,11 @@ nm_vpn_manager_init (NMVPNManager *self)
 }
 
 static void
-stop_all_services (NMVPNManager *self)
+stop_all_services (NMVpnManager *self)
 {
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
 	GHashTableIter iter;
-	NMVPNService *service;
+	NMVpnService *service;
 
 	g_hash_table_iter_init (&iter, priv->services);
 	while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) {
@@ -275,7 +268,7 @@ stop_all_services (NMVPNManager *self)
 static void
 dispose (GObject *object)
 {
-	NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
+	NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
 
 	if (priv->monitor) {
 		if (priv->monitor_id)
@@ -294,15 +287,13 @@ dispose (GObject *object)
 }
 
 static void
-nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
+nm_vpn_manager_class_init (NMVpnManagerClass *manager_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
 
-	g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
+	g_type_class_add_private (manager_class, sizeof (NMVpnManagerPrivate));
 
 	/* virtual methods */
 	object_class->dispose = dispose;
-
-	dbus_g_error_domain_register (NM_VPN_MANAGER_ERROR, NULL, NM_TYPE_VPN_MANAGER_ERROR);
 }
 
diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h
index 57f947b0..b75a6179 100644
--- a/src/vpn-manager/nm-vpn-manager.h
+++ b/src/vpn-manager/nm-vpn-manager.h
@@ -19,52 +19,38 @@
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
-#ifndef NM_VPN_MANAGER_H
-#define NM_VPN_MANAGER_H
+#ifndef __NETWORKMANAGER_VPN_MANAGER_H__
+#define __NETWORKMANAGER_VPN_MANAGER_H__
 
 #include <glib.h>
 #include <glib-object.h>
 #include "nm-vpn-connection.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))
+#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))
 #define NM_IS_VPN_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_MANAGER))
 #define NM_IS_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_MANAGER))
-#define NM_VPN_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVPNManagerClass))
-
-typedef enum
-{
-	NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0, /*< nick=BaseDeviceNotActive >*/
-	NM_VPN_MANAGER_ERROR_CONNECTION_INVALID,    /*< nick=ConnectionInvalid >*/
-	NM_VPN_MANAGER_ERROR_SERVICE_INVALID,       /*< nick=ServiceInvalid >*/
-	NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED,  /*< nick=ServiceStartFailed >*/
-} NMVPNManagerError;
-
-#define NM_VPN_MANAGER_ERROR (nm_vpn_manager_error_quark ())
-
-GQuark nm_vpn_manager_error_quark (void);
-GType nm_vpn_manager_error_get_type (void);
-
+#define NM_VPN_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVpnManagerClass))
 
 typedef struct {
 	GObject parent;
-} NMVPNManager;
+} NMVpnManager;
 
 typedef struct {
 	GObjectClass parent;
-} NMVPNManagerClass;
+} NMVpnManagerClass;
 
 GType nm_vpn_manager_get_type (void);
 
-NMVPNManager *nm_vpn_manager_get (void);
+NMVpnManager *nm_vpn_manager_get (void);
 
-gboolean nm_vpn_manager_activate_connection (NMVPNManager *manager,
-                                             NMVPNConnection *vpn,
+gboolean nm_vpn_manager_activate_connection (NMVpnManager *manager,
+                                             NMVpnConnection *vpn,
                                              GError **error);
 
-gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager,
-                                               NMVPNConnection *connection,
-                                               NMVPNConnectionStateReason reason);
+gboolean nm_vpn_manager_deactivate_connection (NMVpnManager *manager,
+                                               NMVpnConnection *connection,
+                                               NMVpnConnectionStateReason reason);
 
-#endif /* NM_VPN_MANAGER_H */
+#endif /* __NETWORKMANAGER_VPN_MANAGER_H__ */
diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c
index 824543fa..b46d13ec 100644
--- a/src/vpn-manager/nm-vpn-service.c
+++ b/src/vpn-manager/nm-vpn-service.c
@@ -19,10 +19,10 @@
  * Copyright (C) 2005 - 2008 Novell, Inc.
  */
 
-#include <config.h>
+#include "config.h"
+
 #include <glib.h>
 #include <string.h>
-#include <dbus/dbus.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <signal.h>
@@ -35,7 +35,7 @@
 #include "nm-vpn-manager.h"
 #include "nm-glib-compat.h"
 
-G_DEFINE_TYPE (NMVPNService, nm_vpn_service, G_TYPE_OBJECT)
+G_DEFINE_TYPE (NMVpnService, nm_vpn_service, G_TYPE_OBJECT)
 
 typedef struct {
 	char *name;
@@ -43,24 +43,24 @@ typedef struct {
 	char *program;
 	char *namefile;
 
-	NMVPNConnection *active;
+	NMVpnConnection *active;
 	GSList *pending;
 
 	guint start_timeout;
 	gboolean service_running;
-} NMVPNServicePrivate;
+} NMVpnServicePrivate;
 
-#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVPNServicePrivate))
+#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVpnServicePrivate))
 
 #define VPN_CONNECTION_GROUP "VPN Connection"
 
-static gboolean start_pending_vpn (NMVPNService *self);
+static gboolean start_pending_vpn (NMVpnService *self, GError **error);
 
-NMVPNService *
+NMVpnService *
 nm_vpn_service_new (const char *namefile, GError **error)
 {
-	NMVPNService *self;
-	NMVPNServicePrivate *priv;
+	NMVpnService *self;
+	NMVpnServicePrivate *priv;
 	GKeyFile *kf;
 
 	g_return_val_if_fail (namefile != NULL, NULL);
@@ -72,7 +72,7 @@ nm_vpn_service_new (const char *namefile, GError **error)
 		return NULL;
 	}
 
-	self = (NMVPNService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL);
+	self = (NMVpnService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL);
 	priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 	priv->namefile = g_strdup (namefile);
 
@@ -100,7 +100,7 @@ error:
 }
 
 const char *
-nm_vpn_service_get_dbus_service (NMVPNService *service)
+nm_vpn_service_get_dbus_service (NMVpnService *service)
 {
 	g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
 
@@ -108,7 +108,7 @@ nm_vpn_service_get_dbus_service (NMVPNService *service)
 }
 
 const char *
-nm_vpn_service_get_name_file (NMVPNService *service)
+nm_vpn_service_get_name_file (NMVpnService *service)
 {
 	g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
 
@@ -116,21 +116,21 @@ nm_vpn_service_get_name_file (NMVPNService *service)
 }
 
 static void
-connection_vpn_state_changed (NMVPNConnection *connection,
-                              NMVPNConnectionState new_state,
-                              NMVPNConnectionState old_state,
-                              NMVPNConnectionStateReason reason,
+connection_vpn_state_changed (NMVpnConnection *connection,
+                              NMVpnConnectionState new_state,
+                              NMVpnConnectionState old_state,
+                              NMVpnConnectionStateReason reason,
                               gpointer user_data)
 {
-	NMVPNService *self = NM_VPN_SERVICE (user_data);
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
+	NMVpnService *self = NM_VPN_SERVICE (user_data);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 
 	if (new_state == NM_VPN_CONNECTION_STATE_FAILED ||
 	    new_state == NM_VPN_CONNECTION_STATE_DISCONNECTED) {
 		g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_vpn_state_changed), self);
 		if (connection == priv->active) {
 			priv->active = NULL;
-			start_pending_vpn (self);
+			start_pending_vpn (self, NULL);
 		} else
 			priv->pending = g_slist_remove (priv->pending, connection);
 		g_object_unref (connection);
@@ -138,11 +138,11 @@ connection_vpn_state_changed (NMVPNConnection *connection,
 }
 
 void
-nm_vpn_service_stop_connections (NMVPNService *service,
+nm_vpn_service_stop_connections (NMVpnService *service,
                                  gboolean quitting,
-                                 NMVPNConnectionStateReason reason)
+                                 NMVpnConnectionStateReason reason)
 {
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 	GSList *iter;
 
 	/* Just add priv->active to the beginning of priv->pending,
@@ -154,7 +154,7 @@ nm_vpn_service_stop_connections (NMVPNService *service,
 	}
 
 	for (iter = priv->pending; iter; iter = iter->next) {
-		NMVPNConnection *vpn = NM_VPN_CONNECTION (iter->data);
+		NMVpnConnection *vpn = NM_VPN_CONNECTION (iter->data);
 
 		g_signal_handlers_disconnect_by_func (vpn, G_CALLBACK (connection_vpn_state_changed), service);
 		if (quitting) {
@@ -184,8 +184,8 @@ _daemon_setup (gpointer user_data G_GNUC_UNUSED)
 static gboolean
 _daemon_exec_timeout (gpointer data)
 {
-	NMVPNService *self = NM_VPN_SERVICE (data);
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
+	NMVpnService *self = NM_VPN_SERVICE (data);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 
 	nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", priv->name);
 	priv->start_timeout = 0;
@@ -194,9 +194,9 @@ _daemon_exec_timeout (gpointer data)
 }
 
 static gboolean
-nm_vpn_service_daemon_exec (NMVPNService *service, GError **error)
+nm_vpn_service_daemon_exec (NMVpnService *service, GError **error)
 {
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 	GPid pid;
 	char *vpn_argv[2];
 	gboolean success = FALSE;
@@ -219,7 +219,7 @@ nm_vpn_service_daemon_exec (NMVPNService *service, GError **error)
 		             spawn_error && spawn_error->message ? spawn_error->message : "(unknown)");
 
 		g_set_error (error,
-		             NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED,
+		             NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
 		             "%s", spawn_error ? spawn_error->message : "unknown g_spawn_async() error");
 
 		nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED);
@@ -231,9 +231,9 @@ nm_vpn_service_daemon_exec (NMVPNService *service, GError **error)
 }
 
 static gboolean
-start_active_vpn (NMVPNService *self, GError **error)
+start_active_vpn (NMVpnService *self, GError **error)
 {
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 
 	if (!priv->active)
 		return TRUE;
@@ -253,9 +253,9 @@ start_active_vpn (NMVPNService *self, GError **error)
 }
 
 static gboolean
-start_pending_vpn (NMVPNService *self)
+start_pending_vpn (NMVpnService *self, GError **error)
 {
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 
 	g_assert (priv->active == NULL);
 
@@ -266,15 +266,15 @@ start_pending_vpn (NMVPNService *self)
 	priv->active = g_slist_nth_data (priv->pending, 0);
 	priv->pending = g_slist_remove (priv->pending, priv->active);
 
-	return start_active_vpn (self, NULL);
+	return start_active_vpn (self, error);
 }
 
 gboolean
-nm_vpn_service_activate (NMVPNService *service,
-                         NMVPNConnection *vpn,
+nm_vpn_service_activate (NMVpnService *service,
+                         NMVpnConnection *vpn,
                          GError **error)
 {
-	NMVPNServicePrivate *priv;
+	NMVpnServicePrivate *priv;
 
 	g_return_val_if_fail (NM_IS_VPN_SERVICE (service), FALSE);
 	g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
@@ -300,7 +300,7 @@ nm_vpn_service_activate (NMVPNService *service,
 	}
 
 	/* Otherwise start the next VPN */
-	return start_pending_vpn (service);
+	return start_pending_vpn (service, error);
 }
 
 static void
@@ -310,8 +310,8 @@ _name_owner_changed (NMDBusManager *mgr,
                      const char *new,
                      gpointer user_data)
 {
-	NMVPNService *service = NM_VPN_SERVICE (user_data);
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+	NMVpnService *service = NM_VPN_SERVICE (user_data);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
 	gboolean old_owner_good, new_owner_good, success;
 
 	if (strcmp (name, priv->dbus_service))
@@ -344,7 +344,7 @@ _name_owner_changed (NMDBusManager *mgr,
 /******************************************************************************/
 
 static void
-nm_vpn_service_init (NMVPNService *self)
+nm_vpn_service_init (NMVpnService *self)
 {
 	g_signal_connect (nm_dbus_manager_get (),
 	                  NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
@@ -355,8 +355,8 @@ nm_vpn_service_init (NMVPNService *self)
 static void
 dispose (GObject *object)
 {
-	NMVPNService *self = NM_VPN_SERVICE (object);
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
+	NMVpnService *self = NM_VPN_SERVICE (object);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
 
 	if (priv->start_timeout) {
 		g_source_remove (priv->start_timeout);
@@ -377,7 +377,7 @@ dispose (GObject *object)
 static void
 finalize (GObject *object)
 {
-	NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object);
+	NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object);
 
 	g_free (priv->name);
 	g_free (priv->dbus_service);
@@ -388,11 +388,11 @@ finalize (GObject *object)
 }
 
 static void
-nm_vpn_service_class_init (NMVPNServiceClass *service_class)
+nm_vpn_service_class_init (NMVpnServiceClass *service_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (service_class);
 
-	g_type_class_add_private (service_class, sizeof (NMVPNServicePrivate));
+	g_type_class_add_private (service_class, sizeof (NMVpnServicePrivate));
 
 	/* virtual methods */
 	object_class->dispose = dispose;
diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h
index 4545d1f0..cafa6904 100644
--- a/src/vpn-manager/nm-vpn-service.h
+++ b/src/vpn-manager/nm-vpn-service.h
@@ -19,8 +19,8 @@
  * Copyright (C) 2005 - 2008 Novell, Inc.
  */
 
-#ifndef NM_VPN_SERVICE_H
-#define NM_VPN_SERVICE_H
+#ifndef __NETWORKMANAGER_VPN_SERVICE_H__
+#define __NETWORKMANAGER_VPN_SERVICE_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -28,36 +28,36 @@
 #include "nm-vpn-connection.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))
-#define NM_VPN_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
+#define NM_VPN_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVpnService))
+#define NM_VPN_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVpnServiceClass))
 #define NM_IS_VPN_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE))
 #define NM_IS_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_SERVICE))
-#define NM_VPN_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
+#define NM_VPN_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVpnServiceClass))
 
 typedef struct {
 	GObject parent;
-} NMVPNService;
+} NMVpnService;
 
 typedef struct {
 	GObjectClass parent;
-} NMVPNServiceClass;
+} NMVpnServiceClass;
 
 GType nm_vpn_service_get_type (void);
 
-NMVPNService * nm_vpn_service_new (const char *namefile, GError **error);
+NMVpnService * nm_vpn_service_new (const char *namefile, GError **error);
 
 /* Returns the VPN service's D-Bus service name */
-const char *nm_vpn_service_get_dbus_service (NMVPNService *service);
+const char *nm_vpn_service_get_dbus_service (NMVpnService *service);
 
 /* Returns the path of the VPN service's .name file */
-const char *nm_vpn_service_get_name_file (NMVPNService *service);
+const char *nm_vpn_service_get_name_file (NMVpnService *service);
 
-gboolean nm_vpn_service_activate (NMVPNService *service,
-                                  NMVPNConnection *vpn,
+gboolean nm_vpn_service_activate (NMVpnService *service,
+                                  NMVpnConnection *vpn,
                                   GError **error);
 
-void nm_vpn_service_stop_connections (NMVPNService *service,
+void nm_vpn_service_stop_connections (NMVpnService *service,
                                       gboolean quitting,
-                                      NMVPNConnectionStateReason reason);
+                                      NMVpnConnectionStateReason reason);
 
 #endif  /* NM_VPN_VPN_SERVICE_H */