From: Daniel Wagner <[email protected]>
We should add the routing entries pushed by the OpenVPN server.
---
include/inet.h | 3 ++-
include/provider.h | 4 ++++
src/connection.c | 5 +++--
src/inet.c | 13 ++++++++++---
src/provider.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
src/service.c | 6 ++++--
6 files changed, 70 insertions(+), 8 deletions(-)
diff --git a/include/inet.h b/include/inet.h
index 7b34900..cdcd87b 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -46,7 +46,8 @@ connman_bool_t connman_inet_is_cfg80211(int index);
int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress);
int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress);
-int connman_inet_add_host_route(int index, const char *host, const char
*gateway);
+int connman_inet_add_host_route(int index, const char *host, const char
*gateway,
+ const char *netmask);
int connman_inet_del_host_route(int index, const char *host);
int connman_inet_set_gateway_address(int index, const char *gateway);
int connman_inet_clear_gateway_address(int index, const char *gateway);
diff --git a/include/provider.h b/include/provider.h
index dde37fb..569d47f 100644
--- a/include/provider.h
+++ b/include/provider.h
@@ -83,6 +83,10 @@ void connman_provider_set_dns(struct connman_provider
*provider,
void connman_provider_set_domain(struct connman_provider *provider,
const char *domain);
+int connman_provider_append_route(struct connman_provider *provider,
+ const char *host, const char *netmask,
+ const char *gateway);
+
const char *connman_provider_get_driver_name(struct connman_provider
*provider);
struct connman_provider_driver {
diff --git a/src/connection.c b/src/connection.c
index bac700f..0a6d90e 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -323,7 +323,7 @@ static int connection_probe(struct connman_element *element)
connman_inet_add_ipv6_host_route(element->index,
new_gateway->ipv6_gateway, NULL);
connman_inet_add_host_route(element->index,
- new_gateway->ipv4_gateway, NULL);
+ new_gateway->ipv4_gateway, NULL, NULL);
__connman_service_nameserver_add_routes(service,
new_gateway->ipv4_gateway);
__connman_service_set_domainname(service, domainname);
@@ -348,7 +348,8 @@ static int connection_probe(struct connman_element *element)
if (new_gateway->vpn == TRUE) {
connman_inet_add_host_route(active_gateway->index,
new_gateway->ipv4_gateway,
- active_gateway->ipv4_gateway);
+ active_gateway->ipv4_gateway,
+ NULL);
}
if (new_gateway->order >= active_gateway->order) {
diff --git a/src/inet.c b/src/inet.c
index 419126b..1834d94 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -616,7 +616,9 @@ int connman_inet_clear_address(int index, struct
connman_ipaddress *ipaddress)
return 0;
}
-int connman_inet_add_host_route(int index, const char *host, const char
*gateway)
+int connman_inet_add_host_route(int index, const char *host,
+ const char *gateway,
+ const char *netmask)
{
struct ifreq ifr;
struct rtentry rt;
@@ -638,9 +640,11 @@ int connman_inet_add_host_route(int index, const char
*host, const char *gateway
DBG("ifname %s", ifr.ifr_name);
memset(&rt, 0, sizeof(rt));
- rt.rt_flags = RTF_UP | RTF_HOST;
+ rt.rt_flags = RTF_UP;
if (gateway != NULL)
rt.rt_flags |= RTF_GATEWAY;
+ if (netmask == NULL)
+ rt.rt_flags |= RTF_HOST;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
@@ -657,7 +661,10 @@ int connman_inet_add_host_route(int index, const char
*host, const char *gateway
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
+ if (netmask != NULL)
+ addr.sin_addr.s_addr = inet_addr(netmask);
+ else
+ addr.sin_addr.s_addr = INADDR_ANY;
memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
rt.rt_dev = ifr.ifr_name;
diff --git a/src/provider.c b/src/provider.c
index ea7d37b..0a9cfa8 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -35,6 +35,12 @@ static GHashTable *provider_hash = NULL;
static GSList *driver_list = NULL;
+struct connman_route {
+ char *host;
+ char *netmask;
+ char *gateway;
+};
+
struct connman_provider {
struct connman_element element;
struct connman_service *vpn_service;
@@ -44,6 +50,7 @@ struct connman_provider {
char *host;
char *dns;
char *domain;
+ GSList *route_list;
struct connman_provider_driver *driver;
void *driver_data;
};
@@ -261,6 +268,7 @@ static int set_connected(struct connman_provider *provider,
char *nameservers = NULL, *name = NULL;
const char *value;
char *second_ns;
+ GSList *list;
int err;
__connman_service_indicate_state(provider->vpn_service,
@@ -312,6 +320,15 @@ static int set_connected(struct connman_provider *provider,
g_free(nameservers);
g_free(name);
+ for (list = provider->route_list; list; list = list->next) {
+ struct connman_route *route = list->data;
+
+ connman_inet_add_host_route(provider->element.index,
+ route->host,
+ route->gateway,
+ route->netmask);
+ /* XXX How to handle IPv6? */
+ }
} else {
connman_element_unregister_children(&provider->element);
__connman_service_indicate_state(service,
@@ -365,6 +382,7 @@ static void unregister_provider(gpointer data)
static void provider_destruct(struct connman_element *element)
{
struct connman_provider *provider = element->private;
+ GSList *list;
DBG("provider %p", provider);
@@ -373,6 +391,15 @@ static void provider_destruct(struct connman_element
*element)
g_free(provider->domain);
g_free(provider->identifier);
g_free(provider->dns);
+
+ for (list = provider->route_list; list; list = list->next) {
+ struct connman_route *route = list->data;
+
+ g_free(route->host);
+ g_free(route->netmask);
+ g_free(route->gateway);
+ }
+ g_slist_free(provider->route_list);
}
static void provider_initialize(struct connman_provider *provider)
@@ -395,6 +422,7 @@ static void provider_initialize(struct connman_provider
*provider)
provider->dns = NULL;
provider->domain = NULL;
provider->identifier = NULL;
+ provider->route_list = NULL;
}
static struct connman_provider *connman_provider_new(void)
@@ -694,6 +722,25 @@ int connman_provider_get_index(struct connman_provider
*provider)
return provider->element.index;
}
+int connman_provider_append_route(struct connman_provider *provider,
+ const char *host, const char *netmask,
+ const char *gateway)
+{
+ struct connman_route *route;
+
+ route = g_try_new0(struct connman_route, 1);
+ if (route == NULL)
+ return -ENOMEM;
+
+ route->host = g_strdup(host);
+ route->netmask = g_strdup(netmask);
+ route->gateway = g_strdup(gateway);
+
+ provider->route_list = g_slist_append(provider->route_list, route);
+
+ return TRUE;
+}
+
const char *connman_provider_get_driver_name(struct connman_provider *provider)
{
return provider->driver->name;
diff --git a/src/service.c b/src/service.c
index 626cd31..28ac88a 100644
--- a/src/service.c
+++ b/src/service.c
@@ -436,13 +436,15 @@ void __connman_service_nameserver_add_routes(struct
connman_service *service,
continue;
connman_inet_add_host_route(index,
- service->nameservers[i], gw);
+ service->nameservers[i],
+ gw, NULL);
}
} else if (service->nameserver != NULL) {
if (connman_inet_compare_subnet(index, service->nameserver))
return;
- connman_inet_add_host_route(index, service->nameserver, gw);
+ connman_inet_add_host_route(index, service->nameserver,
+ gw, NULL);
}
}
--
1.7.3.2
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman