[PATCH v2 13/15] vpn-provider: Add route support in vpn config file

Jukka Rissanen jukka.rissanen at linux.intel.com
Tue Nov 27 06:10:23 PST 2012


---
 vpn/vpn-provider.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++------
 vpn/vpn.h          |  3 +-
 2 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index b6fb132..d2cc335 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -307,7 +307,7 @@ static void set_user_networks(struct vpn_provider *provider, GSList *networks)
 
 		if (__vpn_provider_append_user_route(provider,
 					route->family, route->network,
-					route->netmask) != 0)
+					route->netmask, route->gateway) != 0)
 			break;
 	}
 }
@@ -544,12 +544,15 @@ void __vpn_provider_append_properties(struct vpn_provider *provider,
 }
 
 int __vpn_provider_append_user_route(struct vpn_provider *provider,
-			int family, const char *network, const char *netmask)
+				int family, const char *network,
+				const char *netmask, const char *gateway)
 {
 	struct vpn_route *route;
-	char *key = g_strdup_printf("%d/%s/%s", family, network, netmask);
+	char *key = g_strdup_printf("%d/%s/%s/%s", family, network,
+				netmask, gateway != NULL ? gateway : "");
 
-	DBG("family %d network %s netmask %s", family, network, netmask);
+	DBG("family %d network %s netmask %s gw %s", family, network,
+							netmask, gateway);
 
 	route = g_hash_table_lookup(provider->user_routes, key);
 	if (route == NULL) {
@@ -562,6 +565,7 @@ int __vpn_provider_append_user_route(struct vpn_provider *provider,
 		route->family = family;
 		route->network = g_strdup(network);
 		route->netmask = g_strdup(netmask);
+		route->gateway = g_strdup(gateway);
 
 		g_hash_table_replace(provider->user_routes, key, route);
 	} else
@@ -1766,7 +1770,70 @@ static const char *get_string(GHashTable *settings, const char *key)
 
 static GSList *parse_user_networks(const char *network_str)
 {
-	return NULL;
+	GSList *networks = NULL;
+	char **elems = g_strsplit(network_str, ",", 0);
+	int i = 0;
+
+	if (elems == NULL)
+		return NULL;
+
+	while (elems[i] != NULL) {
+		struct vpn_route *vpn_route;
+		char *network, *netmask, *gateway;
+		int family;
+		char **route;
+
+		route = g_strsplit(elems[i], "/", 0);
+		if (route == NULL)
+			goto next;
+
+		network = route[0];
+		if (network == NULL || network[0] == '\0')
+			goto next;
+
+		family = connman_inet_check_ipaddress(network);
+		if (family < 0) {
+			DBG("Cannot get address family of %s (%d/%s)", network,
+				family, gai_strerror(family));
+			if (strstr(network, ":") != NULL) {
+				DBG("Guessing it is IPv6");
+				family = AF_INET6;
+			} else {
+				DBG("Guessing it is IPv4");
+				family = AF_INET;
+			}
+		}
+
+		netmask = route[1];
+		if (netmask == NULL || netmask[0] == '\0')
+			goto next;
+
+		gateway = route[2];
+
+		vpn_route = g_try_new0(struct vpn_route, 1);
+		if (vpn_route == NULL) {
+			g_strfreev(route);
+			break;
+		}
+
+		vpn_route->family = family;
+		vpn_route->network = g_strdup(network);
+		vpn_route->netmask = g_strdup(netmask);
+		vpn_route->gateway = g_strdup(gateway);
+
+		DBG("route %s/%s%s%s", network, netmask,
+			gateway ? " via " : "", gateway ? gateway : "");
+
+		networks = g_slist_prepend(networks, vpn_route);
+
+	next:
+		g_strfreev(route);
+		i++;
+	}
+
+	g_strfreev(elems);
+
+	return g_slist_reverse(networks);
 }
 
 int __vpn_provider_create_from_config(GHashTable *settings,
@@ -1850,12 +1917,13 @@ int __vpn_provider_create_from_config(GHashTable *settings,
 
 	connection_added_signal(provider);
 
-	err = 0;
+	g_free(ident);
+
+	return 0;
 
 fail:
 	g_free(ident);
-	if (networks != NULL)
-		g_slist_free_full(networks, free_route);
+	g_slist_free_full(networks, free_route);
 
 	return err;
 }
diff --git a/vpn/vpn.h b/vpn/vpn.h
index 3cdba2e..8adfcf2 100644
--- a/vpn/vpn.h
+++ b/vpn/vpn.h
@@ -74,7 +74,8 @@ void __vpn_ipconfig_cleanup(void);
 char *__vpn_provider_create_identifier(const char *host, const char *domain);
 connman_bool_t __vpn_provider_check_routes(struct vpn_provider *provider);
 int __vpn_provider_append_user_route(struct vpn_provider *provider,
-			int family, const char *network, const char *netmask);
+				int family, const char *network,
+				const char *netmask, const char *gateway);
 void __vpn_provider_append_properties(struct vpn_provider *provider, DBusMessageIter *iter);
 void __vpn_provider_list(DBusMessageIter *iter, void *user_data);
 int __vpn_provider_create(DBusMessage *msg);
-- 
1.7.11.4




More information about the connman mailing list