summaryrefslogtreecommitdiff
path: root/src/connection.c
diff options
context:
space:
mode:
authorYu A Wang <yu.a.wang@intel.com>2011-08-17 04:04:18 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-08-17 10:45:08 +0200
commitd48d264504adee79da711698cd6eb81096b5c8d7 (patch)
tree23e627bf2df9471e523525e736748089c0634130 /src/connection.c
parent9e83f367842b77a6e0475668f18a89a0740c7cde (diff)
downloadconnman-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.
Diffstat (limited to 'src/connection.c')
-rw-r--r--src/connection.c35
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 &&