From: Daniel Wagner <[email protected]>
---
src/connection.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++---
src/connman.h | 6 +++
2 files changed, 113 insertions(+), 6 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index 789a242..c25308c 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -103,11 +103,11 @@ static void find_element(struct connman_element *element,
gpointer user_data)
data->element = element;
}
-static struct gateway_data *add_gateway(int index, const char *gateway,
+static struct gateway_data *add_gateway(struct connman_service *service,
+ int index, const char *gateway,
const char *ipv6_gateway)
{
struct gateway_data *data;
- struct connman_service *service;
DBG("index %d ipv4 gateway %s ipv6 gateway %s", index, gateway,
ipv6_gateway);
@@ -128,10 +128,12 @@ static struct gateway_data *add_gateway(int index, const
char *gateway,
data->vpn = FALSE;
data->vpn_phy_index = -1;
- __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
- find_element, data);
+ if (service == NULL) {
+ __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
+ find_element, data);
- service = __connman_element_get_service(data->element);
+ service = __connman_element_get_service(data->element);
+ }
data->order = __connman_service_get_order(service);
gateway_list = g_slist_append(gateway_list, data);
@@ -315,7 +317,7 @@ static int connection_probe(struct connman_element *element)
connman_element_set_enabled(element, TRUE);
active_gateway = find_active_gateway();
- new_gateway = add_gateway(element->index, gateway, ipv6_gateway);
+ new_gateway = add_gateway(NULL, element->index, gateway, ipv6_gateway);
if (new_gateway == NULL)
return 0;
@@ -473,6 +475,105 @@ static void update_order(void)
}
}
+int __connman_connection_gateway_add(struct connman_service *service,
+ const char *ipv4_gateway, const char
*ipv6_gateway,
+ const char *vpn_ip, const char
*domainname)
+{
+ struct gateway_data *active_gateway = NULL;
+ struct gateway_data *new_gateway = NULL;
+ int index;
+
+ DBG("service %p ipv4 gateway %s ipv6 gateway %s vpn ip %s domainname
%s",
+ service, ipv4_gateway, ipv6_gateway, vpn_ip, domainname);
+
+ index = __connman_service_get_index(service);
+
+ /*
+ * If gateway is NULL, it's a point to point link and the default
+ * gateway is 0.0.0.0, meaning the interface.
+ */
+ if (ipv4_gateway == NULL)
+ ipv4_gateway = "0.0.0.0";
+
+ active_gateway = find_active_gateway();
+ new_gateway = add_gateway(service, index, ipv4_gateway, ipv6_gateway);
+ if (new_gateway == NULL)
+ return 0;
+
+ if (new_gateway->ipv6_gateway)
+ connman_inet_add_ipv6_host_route(index,
+ new_gateway->ipv6_gateway, NULL);
+
+ if (g_strcmp0(new_gateway->ipv4_gateway, "0.0.0.0"))
+ connman_inet_add_host_route(index,
+ new_gateway->ipv4_gateway, NULL);
+ if (service == NULL) {
+ new_gateway->vpn = TRUE;
+ new_gateway->vpn_ip = g_strdup(vpn_ip);
+ /* make sure vpn gateway are at higher priority */
+ new_gateway->order = 10;
+ if (active_gateway)
+ new_gateway->vpn_phy_index = active_gateway->index;
+ } else
+ new_gateway->vpn = FALSE;
+
+ if (active_gateway == NULL) {
+ set_default_gateway(new_gateway);
+ return 0;
+ }
+
+ if (new_gateway->vpn == TRUE) {
+ connman_inet_add_host_route(active_gateway->index,
+ new_gateway->ipv4_gateway,
+ active_gateway->ipv4_gateway);
+ }
+
+ if (new_gateway->order >= active_gateway->order) {
+ del_routes(active_gateway);
+ return 0;
+ }
+
+ return 0;
+}
+
+void __connman_connection_gateway_remove(struct connman_service *service,
+ const char *gateway)
+{
+ struct gateway_data *data = NULL;
+ gboolean set_default = FALSE;
+ int err;
+ int index;
+
+ DBG("service %p gateway %s", service, gateway);
+
+ if (gateway == NULL)
+ return;
+
+ index = __connman_service_get_index(service);
+
+ data = find_gateway(index, gateway);
+ if (data == NULL)
+ return;
+
+ set_default = data->vpn;
+
+ if (data->vpn == TRUE && data->vpn_phy_index >= 0)
+ connman_inet_del_host_route(data->vpn_phy_index,
+ data->ipv4_gateway);
+ err = remove_gateway(data);
+
+ /* with vpn this will be called after the network was deleted,
+ * we need to call set_default here because we will not recieve any
+ * gateway delete notification.
+ * We hit the same issue if remove_gateway() fails.
+ */
+ if (set_default || err < 0) {
+ data = find_default_gateway();
+ if (data != NULL)
+ set_default_gateway(data);
+ }
+}
+
gboolean __connman_connection_update_gateway(void)
{
struct gateway_data *active_gateway, *default_gateway;
diff --git a/src/connman.h b/src/connman.h
index 7524494..3fb095e 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -304,6 +304,12 @@ void __connman_ipv4_cleanup(void);
int __connman_connection_init(void);
void __connman_connection_cleanup(void);
+int __connman_connection_gateway_add(struct connman_service *service,
+ const char *ipv4_gateway, const char
*ipv6_gateway,
+ const char *vpn_ip, const char
*domainname);
+void __connman_connection_gateway_remove(struct connman_service *service,
+ const char *gateway);
+
gboolean __connman_connection_update_gateway(void);
int __connman_wpad_init(void);
--
1.7.4
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman