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

Reply via email to