summaryrefslogtreecommitdiff
path: root/src/connection.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-03-14 17:28:56 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-03-19 13:09:04 +0200
commit55152eb4345f483ff43a5dbb030dd86a66debaa2 (patch)
treed870afa29fed04cbddeb1b0d274ce91d21988b3d /src/connection.c
parent4ceb840875188a407afb79f957cbe1db57bead44 (diff)
downloadconnman-55152eb4345f483ff43a5dbb030dd86a66debaa2.tar.gz
connman-55152eb4345f483ff43a5dbb030dd86a66debaa2.tar.bz2
connman-55152eb4345f483ff43a5dbb030dd86a66debaa2.zip
connection: Get correct VPN phy link data
VPN could be using wrong phy link data if there are multiple active links.
Diffstat (limited to 'src/connection.c')
-rw-r--r--src/connection.c149
1 files changed, 93 insertions, 56 deletions
diff --git a/src/connection.c b/src/connection.c
index 888ab062..4e7b0ab6 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -80,6 +80,90 @@ static struct gateway_config *find_gateway(int index, const char *gateway)
return NULL;
}
+/*
+ * Find the gateway that is serving the VPN link
+ */
+static struct gateway_data *find_phy_gateway(int index, const char *gateway)
+{
+ GHashTableIter iter;
+ gpointer value, key;
+
+ if (gateway == NULL)
+ return NULL;
+
+ g_hash_table_iter_init(&iter, gateway_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct gateway_data *data = value;
+
+ if (data->ipv4_gateway != NULL && data->index != index &&
+ g_str_equal(data->ipv4_gateway->gateway,
+ gateway) == TRUE)
+ return data;
+
+ if (data->ipv6_gateway != NULL && data->index != index &&
+ g_str_equal(data->ipv6_gateway->gateway,
+ gateway) == TRUE)
+ return data;
+ }
+
+ return NULL;
+}
+
+static void set_vpn_routes(struct gateway_config *config,
+ struct connman_service *service,
+ const char *gateway,
+ enum connman_ipconfig_type type,
+ const char *peer)
+{
+ struct gateway_data *data;
+ struct connman_ipconfig *ipconfig;
+ int index;
+
+ config->vpn = TRUE;
+ if (peer != NULL)
+ config->vpn_ip = g_strdup(peer);
+ else if (gateway != NULL)
+ config->vpn_ip = g_strdup(gateway);
+
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ ipconfig = __connman_service_get_ip4config(service);
+ else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ ipconfig = __connman_service_get_ip6config(service);
+ else
+ return;
+
+ index = __connman_ipconfig_get_index(ipconfig);
+ data = find_phy_gateway(index, gateway);
+
+ if (data != NULL) {
+ /*
+ * data->service points now to original
+ * service that is serving the VPN link
+ */
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+ ipconfig =
+ __connman_service_get_ip4config(data->service);
+ else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+ ipconfig =
+ __connman_service_get_ip6config(data->service);
+ else
+ return;
+
+ if (ipconfig != NULL) {
+ const char *address;
+
+ address = __connman_ipconfig_get_local(ipconfig);
+ config->vpn_phy_ip = g_strdup(address);
+ }
+
+ config->vpn_phy_index = data->index;
+ }
+
+ DBG("vpn %s phy %s index %d", config->vpn_ip,
+ config->vpn_phy_ip, config->vpn_phy_index);
+}
+
static int del_routes(struct gateway_data *data,
enum connman_ipconfig_type type)
{
@@ -591,62 +675,15 @@ int __connman_connection_gateway_add(struct connman_service *service,
if (connman_service_get_type(service) == CONNMAN_SERVICE_TYPE_VPN) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
- new_gateway->ipv4_gateway != NULL) {
- new_gateway->ipv4_gateway->vpn = TRUE;
- if (peer != NULL)
- new_gateway->ipv4_gateway->vpn_ip =
- g_strdup(peer);
- else if (gateway != NULL)
- new_gateway->ipv4_gateway->vpn_ip =
- g_strdup(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;
- }
-
- DBG("vpn %s phy %s index %d",
- new_gateway->ipv4_gateway->vpn_ip,
- new_gateway->ipv4_gateway->vpn_phy_ip,
- new_gateway->ipv4_gateway->vpn_phy_index);
-
- } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
- new_gateway->ipv6_gateway != NULL) {
- new_gateway->ipv6_gateway->vpn = TRUE;
- if (peer != NULL)
- new_gateway->ipv6_gateway->vpn_ip =
- g_strdup(peer);
- else if (gateway != NULL)
- new_gateway->ipv6_gateway->vpn_ip =
- g_strdup(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;
- }
-
- DBG("vpn %s phy %s index %d",
- new_gateway->ipv6_gateway->vpn_ip,
- new_gateway->ipv6_gateway->vpn_phy_ip,
- new_gateway->ipv6_gateway->vpn_phy_index);
- }
+ new_gateway->ipv4_gateway != NULL)
+ set_vpn_routes(new_gateway->ipv4_gateway,
+ service, gateway, type, peer);
+
+ else if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
+ new_gateway->ipv6_gateway != NULL)
+ set_vpn_routes(new_gateway->ipv6_gateway,
+ service, gateway, type, peer);
+
} else {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
new_gateway->ipv4_gateway != NULL)