summaryrefslogtreecommitdiff
path: root/src/vpn-manager/nm-vpn-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn-manager/nm-vpn-connection.c')
-rw-r--r--src/vpn-manager/nm-vpn-connection.c113
1 files changed, 87 insertions, 26 deletions
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index a348ab7182..c581874880 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -41,6 +41,7 @@
#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"
@@ -234,6 +235,9 @@ vpn_cleanup (NMVpnConnection *connection, NMDevice *parent_dev)
nm_platform_address_flush (priv->ip_ifindex);
}
+ nm_default_route_manager_ip4_remove_default_route (nm_default_route_manager_get (), connection);
+ nm_default_route_manager_ip6_remove_default_route (nm_default_route_manager_get (), connection);
+
nm_device_set_vpn4_config (parent_dev, NULL);
nm_device_set_vpn6_config (parent_dev, NULL);
@@ -321,6 +325,11 @@ _set_vpn_state (NMVpnConnection *connection,
dispatcher_cleanup (connection);
+ if (vpn_state >= STATE_DISCONNECTED && vpn_state <= STATE_FAILED) {
+ nm_default_route_manager_ip4_remove_default_route (nm_default_route_manager_get (), connection);
+ nm_default_route_manager_ip6_remove_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.
@@ -487,6 +496,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));
@@ -502,6 +512,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;
@@ -515,7 +527,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
route.gateway = 0;
route.source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = nm_device_get_priority (parent_device);
+ route.metric = route_metric;
nm_ip4_config_add_route (config, &route);
/* Ensure there's a route to the parent device's gateway through the
@@ -527,7 +539,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32
route.network = parent_gw;
route.plen = 32;
route.source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = nm_device_get_priority (parent_device);
+ route.metric = route_metric;
nm_ip4_config_add_route (config, &route);
}
@@ -540,6 +552,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));
@@ -551,6 +564,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;
@@ -564,7 +579,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
route.gateway = in6addr_any;
route.source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = nm_device_get_priority (parent_device);
+ route.metric = route_metric;
nm_ip6_config_add_route (config, &route);
/* Ensure there's a route to the parent device's gateway through the
@@ -576,7 +591,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
route.network = *parent_gw;
route.plen = 128;
route.source = NM_IP_CONFIG_SOURCE_VPN;
- route.metric = nm_device_get_priority (parent_device);
+ route.metric = route_metric;
nm_ip6_config_add_route (config, &route);
}
@@ -936,6 +951,9 @@ nm_vpn_connection_apply_config (NMVpnConnection *connection)
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));
_set_vpn_state (connection, STATE_PRE_UP, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
@@ -959,7 +977,7 @@ nm_vpn_connection_config_maybe_complete (NMVpnConnection *connection,
}
}
- if (priv->connect_timeout == 0) {
+ if (priv->connect_timeout) {
g_source_remove (priv->connect_timeout);
priv->connect_timeout = 0;
}
@@ -1104,18 +1122,44 @@ 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)
+{
+ NMDevice *parent_dev;
+ 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_ip4_config (priv->connection));
+
+ if (route_metric >= 0)
+ return route_metric;
+ }
+
+ if ( priv->ip_ifindex
+ || !(parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection))))
+ return NM_VPN_ROUTE_METRIC_DEFAULT;
+
+ return nm_device_get_ip4_route_metric (parent_dev);
+}
+
+guint32
+nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *connection)
{
+ NMDevice *parent_dev;
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_ip6_config (priv->connection));
- return nm_device_get_priority (parent_dev);
+ if (route_metric >= 0)
+ return route_metric;
}
+
+ if ( priv->ip_ifindex
+ || !(parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection))))
+ return NM_VPN_ROUTE_METRIC_DEFAULT;
+
+ return nm_device_get_ip6_route_metric (parent_dev);
}
static void
@@ -1129,6 +1173,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
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);
@@ -1226,6 +1271,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;
@@ -1233,15 +1280,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);
+ 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 = vpn_routing_metric (connection);
+ 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
@@ -1255,7 +1302,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);
@@ -1265,7 +1312,7 @@ 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;
@@ -1285,6 +1332,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
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));
@@ -1373,6 +1421,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;
@@ -1380,15 +1430,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);
+ 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 = vpn_routing_metric (connection);
+ 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
@@ -1402,7 +1452,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);
@@ -1412,7 +1462,7 @@ 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;
@@ -1665,6 +1715,17 @@ nm_vpn_connection_get_connection (NMVpnConnection *connection)
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->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)
{