diff options
author | Yu A Wang <yu.a.wang@intel.com> | 2011-08-17 04:04:18 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-08-17 10:45:08 +0200 |
commit | d48d264504adee79da711698cd6eb81096b5c8d7 (patch) | |
tree | 23e627bf2df9471e523525e736748089c0634130 | |
parent | 9e83f367842b77a6e0475668f18a89a0740c7cde (diff) | |
download | connman-d48d264504adee79da711698cd6eb81096b5c8d7.tar.gz connman-d48d264504adee79da711698cd6eb81096b5c8d7.tar.bz2 connman-d48d264504adee79da711698cd6eb81096b5c8d7.zip |
connection: Fix vpn on networks without gateway
VPN establishment fails on gateway less networks, like for example ppp
based cellular ones. To fix that, a host route to the VPN server is
established.
-rw-r--r-- | src/connection.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/connection.c b/src/connection.c index bd0a21ed..f92c4cfa 100644 --- a/src/connection.c +++ b/src/connection.c @@ -40,6 +40,7 @@ struct gateway_config { gboolean vpn; char *vpn_ip; int vpn_phy_index; + char *vpn_phy_ip; }; struct gateway_data { @@ -188,6 +189,7 @@ static struct gateway_data *add_gateway(struct connman_service *service, config->gateway = g_strdup(gateway); config->vpn_ip = NULL; + config->vpn_phy_ip = NULL; config->vpn = FALSE; config->vpn_phy_index = -1; config->active = FALSE; @@ -266,6 +268,9 @@ static void set_default_gateway(struct gateway_data *data, data->ipv4_gateway->vpn == TRUE) { connman_inet_set_gateway_address(data->index, data->ipv4_gateway->vpn_ip); + connman_inet_add_host_route(data->ipv4_gateway->vpn_phy_index, + data->ipv4_gateway->vpn_ip, + data->ipv4_gateway->vpn_phy_ip); data->ipv4_gateway->active = TRUE; __connman_service_indicate_default(data->service); @@ -277,6 +282,9 @@ static void set_default_gateway(struct gateway_data *data, data->ipv6_gateway->vpn == TRUE) { connman_inet_set_ipv6_gateway_address(data->index, data->ipv6_gateway->vpn_ip); + connman_inet_add_host_route(data->ipv6_gateway->vpn_phy_index, + data->ipv6_gateway->vpn_ip, + data->ipv6_gateway->vpn_phy_ip); data->ipv6_gateway->active = TRUE; __connman_service_indicate_default(data->service); @@ -347,12 +355,14 @@ static void remove_gateway(gpointer user_data) if (data->ipv4_gateway != NULL) { g_free(data->ipv4_gateway->gateway); g_free(data->ipv4_gateway->vpn_ip); + g_free(data->ipv4_gateway->vpn_phy_ip); g_free(data->ipv4_gateway); } if (data->ipv6_gateway != NULL) { g_free(data->ipv6_gateway->gateway); g_free(data->ipv6_gateway->vpn_ip); + g_free(data->ipv6_gateway->vpn_phy_ip); g_free(data->ipv6_gateway); } @@ -513,9 +523,20 @@ int __connman_connection_gateway_add(struct connman_service *service, else if (gateway != NULL) new_gateway->ipv4_gateway->vpn_ip = g_strdup(gateway); - if (active_gateway) + if (active_gateway) { + const char *new_ipv4_gateway; + + new_ipv4_gateway = + active_gateway->ipv4_gateway->gateway; + if (new_ipv4_gateway != NULL && + g_strcmp0(new_ipv4_gateway, + "0.0.0.0") != 0) + new_gateway->ipv4_gateway->vpn_phy_ip = + g_strdup(new_ipv4_gateway); + new_gateway->ipv4_gateway->vpn_phy_index = active_gateway->index; + } } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6 && new_gateway->ipv6_gateway != NULL) { @@ -526,9 +547,19 @@ int __connman_connection_gateway_add(struct connman_service *service, else if (gateway != NULL) new_gateway->ipv6_gateway->vpn_ip = g_strdup(gateway); - if (active_gateway) + if (active_gateway) { + const char *new_ipv6_gateway; + + new_ipv6_gateway = + active_gateway->ipv6_gateway->gateway; + if (new_ipv6_gateway != NULL && + g_strcmp0(new_ipv6_gateway, "::") != 0) + new_gateway->ipv6_gateway->vpn_phy_ip = + g_strdup(new_ipv6_gateway); + new_gateway->ipv6_gateway->vpn_phy_index = active_gateway->index; + } } } else { if (type == CONNMAN_IPCONFIG_TYPE_IPV4 && |