connection: Remove connection element
authorDaniel Wagner <daniel.wagner@bmw-carit.de>
Tue, 15 Feb 2011 15:45:23 +0000 (16:45 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 15 Feb 2011 17:05:33 +0000 (18:05 +0100)
include/element.h
src/connection.c
src/connman.h
src/element.c
src/ipconfig.c
src/ipv4.c
src/main.c
src/network.c
src/service.c

index 3723df8..f38ecfa 100644 (file)
@@ -51,7 +51,6 @@ enum connman_element_type {
        CONNMAN_ELEMENT_TYPE_DHCP       = 9,
        CONNMAN_ELEMENT_TYPE_BOOTP      = 10,
        CONNMAN_ELEMENT_TYPE_ZEROCONF   = 11,
-       CONNMAN_ELEMENT_TYPE_CONNECTION = 42,
        CONNMAN_ELEMENT_TYPE_VENDOR     = 10000,
 };
 
index 7e517fa..6b2dd2b 100644 (file)
@@ -3,6 +3,7 @@
  *  Connection Manager
  *
  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2011  BMW Car IT GmbH. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -32,9 +33,9 @@
 
 struct gateway_data {
        int index;
+       struct connman_service *service;
        char *ipv4_gateway;
        char *ipv6_gateway;
-       struct connman_element *element;
        unsigned int order;
        gboolean active;
        /* VPN extra data */
@@ -43,17 +44,20 @@ struct gateway_data {
        int vpn_phy_index;
 };
 
-static GSList *gateway_list = NULL;
+static GHashTable *gateway_hash = NULL;
 
 static struct gateway_data *find_gateway(int index, const char *gateway)
 {
-       GSList *list;
+       GHashTableIter iter;
+       gpointer value, key;
 
        if (gateway == NULL)
                return NULL;
 
-       for (list = gateway_list; list; list = list->next) {
-               struct gateway_data *data = list->data;
+       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)
                        continue;
@@ -88,31 +92,13 @@ static int del_routes(struct gateway_data *data)
        }
 }
 
-static void find_element(struct connman_element *element, gpointer user_data)
-{
-       struct gateway_data *data = user_data;
-
-       DBG("element %p name %s", element, element->name);
-
-       if (data->element != NULL)
-               return;
-
-       if (element->index != data->index)
-               return;
-
-       data->element = element;
-}
-
-static struct gateway_data *add_gateway(int index, const char *gateway,
-                                               const char *ipv6_gateway)
+static struct gateway_data *add_gateway(struct connman_service *service,
+                                       int index, const char *ipv4_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);
 
-       if (strlen(gateway) == 0)
+       if (strlen(ipv4_gateway) == 0)
                return NULL;
 
        data = g_try_new0(struct gateway_data, 1);
@@ -120,21 +106,17 @@ static struct gateway_data *add_gateway(int index, const char *gateway,
                return NULL;
 
        data->index = index;
-       data->ipv4_gateway = g_strdup(gateway);
+       data->ipv4_gateway = g_strdup(ipv4_gateway);
        data->ipv6_gateway = g_strdup(ipv6_gateway);
        data->active = FALSE;
-       data->element = NULL;
        data->vpn_ip = NULL;
        data->vpn = FALSE;
        data->vpn_phy_index = -1;
+       data->service = service;
 
-       __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
-                                                       find_element, data);
-
-       service = __connman_element_get_service(data->element);
        data->order = __connman_service_get_order(service);
 
-       gateway_list = g_slist_append(gateway_list, data);
+       g_hash_table_replace(gateway_hash, service, data);
 
        return data;
 }
@@ -154,49 +136,47 @@ static void connection_newgateway(int index, const char *gateway)
 
 static void set_default_gateway(struct gateway_data *data)
 {
-       struct connman_element *element = data->element;
-       struct connman_service *service = NULL;
+       int index;
 
        DBG("gateway %s", data->ipv4_gateway);
 
        if (data->vpn == TRUE) {
-               connman_inet_set_gateway_address(data->index, data->vpn_ip);
+               connman_inet_set_gateway_address(data->index,
+                                                       data->vpn_ip);
                data->active = TRUE;
 
-               service = __connman_service_lookup_from_index(data->index);
-               if (service == NULL)
-                       return;
-
-               __connman_service_indicate_default(service);
+               __connman_service_indicate_default(data->service);
 
                return;
        }
 
+       index = __connman_service_get_index(data->service);
+
        if (g_strcmp0(data->ipv4_gateway, "0.0.0.0") == 0) {
-               if (connman_inet_set_gateway_interface(element->index) < 0)
+               if (connman_inet_set_gateway_interface(index) < 0)
                        return;
                goto done;
        }
 
-       connman_inet_set_ipv6_gateway_address(element->index,
-                                               data->ipv6_gateway);
-       if (connman_inet_set_gateway_address(element->index,
-                                       data->ipv4_gateway) < 0)
+       connman_inet_set_ipv6_gateway_address(index, data->ipv6_gateway);
+       if (connman_inet_set_gateway_address(index, data->ipv4_gateway) < 0)
                return;
 
 done:
-       service = __connman_element_get_service(element);
-       __connman_service_indicate_default(service);
+       __connman_service_indicate_default(data->service);
 }
 
 static struct gateway_data *find_default_gateway(void)
 {
        struct gateway_data *found = NULL;
        unsigned int order = 0;
-       GSList *list;
+       GHashTableIter iter;
+       gpointer value, key;
+
+       g_hash_table_iter_init(&iter, gateway_hash);
 
-       for (list = gateway_list; list; list = list->next) {
-               struct gateway_data *data = list->data;
+       while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+               struct gateway_data *data = value;
 
                if (found == NULL || data->order > order) {
                        found = data;
@@ -207,25 +187,24 @@ static struct gateway_data *find_default_gateway(void)
        return found;
 }
 
-static int remove_gateway(struct gateway_data *data)
+static int disable_gateway(struct gateway_data *data)
 {
-       int err;
+       if (data->active == TRUE)
+               return del_routes(data);
 
-       DBG("gateway %s", data->ipv4_gateway);
+       return 0;
+}
 
-       gateway_list = g_slist_remove(gateway_list, data);
+static void remove_gateway(gpointer user_data)
+{
+       struct gateway_data *data = user_data;
 
-       if (data->active == TRUE)
-               err = del_routes(data);
-       else
-               err = 0;
+       DBG("gateway %s", data->ipv4_gateway);
 
        g_free(data->ipv4_gateway);
        g_free(data->ipv6_gateway);
        g_free(data->vpn_ip);
        g_free(data);
-
-       return err;
 }
 
 static void connection_delgateway(int index, const char *gateway)
@@ -251,12 +230,15 @@ static struct connman_rtnl connection_rtnl = {
 
 static struct gateway_data *find_active_gateway(void)
 {
-       GSList *list;
+       GHashTableIter iter;
+       gpointer value, key;
 
        DBG("");
 
-       for (list = gateway_list; list; list = list->next) {
-               struct gateway_data *data = list->data;
+       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->active == TRUE)
                        return data;
@@ -265,85 +247,80 @@ static struct gateway_data *find_active_gateway(void)
        return NULL;
 }
 
-static int connection_probe(struct connman_element *element)
+static void update_order(void)
 {
-       struct connman_service *service = NULL;
-       const char *gateway = NULL, *ipv6_gateway = NULL;
-       const char *vpn_ip = NULL;
-       const char *domainname = NULL;
-       struct gateway_data *active_gateway = NULL;
-       struct gateway_data *new_gateway = NULL;
+       GHashTableIter iter;
+       gpointer value, key;
 
-       DBG("element %p name %s", element, element->name);
-
-       if (element->parent == NULL)
-               return -ENODEV;
-
-       /* FIXME: Remove temporarily for the static gateway support */
-       /* if (element->parent->type != CONNMAN_ELEMENT_TYPE_IPV4)
-               return -ENODEV; */
+       DBG("");
 
-       connman_element_get_value(element,
-                               CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
-       connman_element_get_value(element,
-                       CONNMAN_PROPERTY_ID_IPV6_GATEWAY, &ipv6_gateway);
+       g_hash_table_iter_init(&iter, gateway_hash);
 
-       connman_element_get_value(element,
-                       CONNMAN_PROPERTY_ID_IPV4_PEER, &vpn_ip);
+       while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+               struct gateway_data *data = value;
 
-       if (vpn_ip == NULL)
-               connman_element_get_value(element,
-                               CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &vpn_ip);
+               data->order = __connman_service_get_order(data->service);
+       }
+}
 
-       DBG("vpn_ip %s", vpn_ip);
+int __connman_connection_gateway_add(struct connman_service *service,
+                                       const char *ipv4_gateway,
+                                       const char *ipv6_gateway,
+                                       const char *peer)
+{
+       struct gateway_data *active_gateway = NULL;
+       struct gateway_data *new_gateway = NULL;
+       int index;
 
-       connman_element_get_value(element,
-                       CONNMAN_PROPERTY_ID_DOMAINNAME, &domainname);
+       index = __connman_service_get_index(service);
 
-       DBG("ipv4 gateway %s ipv6 gateway %s domainname %s",
-                               gateway, ipv6_gateway, domainname);
+       DBG("service %p index %d ipv4 gateway %s ipv6 gateway %s vpn ip %s",
+               service, index, ipv4_gateway, ipv6_gateway, peer);
 
        /*
         * If gateway is NULL, it's a point to point link and the default
         * gateway is 0.0.0.0, meaning the interface.
         */
-       if (gateway == NULL) {
-               gateway = "0.0.0.0";
-               element->ipv4.gateway = g_strdup(gateway);
-       }
-
-       connman_element_set_enabled(element, TRUE);
+       if (ipv4_gateway == NULL)
+               ipv4_gateway = "0.0.0.0";
 
        active_gateway = find_active_gateway();
-       new_gateway = add_gateway(element->index, gateway, ipv6_gateway);
+       new_gateway = add_gateway(service, index, ipv4_gateway, ipv6_gateway);
        if (new_gateway == NULL)
                return 0;
 
-       service = __connman_element_get_service(element);
+       if (new_gateway->ipv6_gateway) {
+               connman_inet_add_ipv6_host_route(index,
+                                               new_gateway->ipv6_gateway,
+                                               NULL);
+       }
 
-       if (new_gateway->ipv6_gateway)
-               connman_inet_add_ipv6_host_route(element->index,
-                                       new_gateway->ipv6_gateway, NULL);
+       if (g_strcmp0(new_gateway->ipv4_gateway, "0.0.0.0") != 0) {
+               connman_inet_add_host_route(index,
+                                               new_gateway->ipv4_gateway,
+                                               NULL);
+       }
 
-       if (g_strcmp0(new_gateway->ipv4_gateway, "0.0.0.0"))
-               connman_inet_add_host_route(element->index,
-                                       new_gateway->ipv4_gateway, NULL);
        __connman_service_nameserver_add_routes(service,
                                                new_gateway->ipv4_gateway);
-       __connman_service_set_domainname(service, domainname);
 
        __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY,
                                                CONNMAN_IPCONFIG_TYPE_IPV4);
 
-       if (service == NULL) {
+       if (connman_service_get_type(service) == CONNMAN_SERVICE_TYPE_VPN) {
                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 (peer != NULL)
+                       new_gateway->vpn_ip = g_strdup(peer);
+               else if (ipv4_gateway != NULL)
+                       new_gateway->vpn_ip = g_strdup(ipv4_gateway);
+               else
+                       new_gateway->vpn_ip = g_strdup(ipv6_gateway);
+
                if (active_gateway)
                        new_gateway->vpn_phy_index = active_gateway->index;
-       } else
+       } else {
                new_gateway->vpn = FALSE;
+       }
 
        if (active_gateway == NULL) {
                set_default_gateway(new_gateway);
@@ -354,52 +331,42 @@ static int connection_probe(struct connman_element *element)
                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;
+               connman_inet_clear_gateway_address(active_gateway->index,
+                                               active_gateway->ipv4_gateway);
        }
 
        return 0;
 }
 
-static void connection_remove(struct connman_element *element)
+void __connman_connection_gateway_remove(struct connman_service *service)
 {
-       struct connman_service *service;
-       const char *gateway = NULL;
        struct gateway_data *data = NULL;
        gboolean set_default = FALSE;
        int err;
 
-       DBG("element %p name %s", element, element->name);
+       DBG("service %p", service);
 
-       service = __connman_element_get_service(element);
        __connman_service_nameserver_del_routes(service);
+
        __connman_service_indicate_state(service,
                                        CONNMAN_SERVICE_STATE_DISCONNECT,
                                        CONNMAN_IPCONFIG_TYPE_IPV4);
 
-       connman_element_set_enabled(element, FALSE);
-
-       connman_element_get_value(element,
-                               CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
-
-       DBG("gateway %s", gateway);
-
-       if (gateway == NULL)
-               return;
-
-       data = find_gateway(element->index, gateway);
+       data = g_hash_table_lookup(gateway_hash, service);
        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,
+       if (data->vpn == TRUE && data->index >= 0) {
+               connman_inet_del_host_route(data->index,
                                                data->ipv4_gateway);
-       err = remove_gateway(data);
+       }
+
+       __connman_service_nameserver_del_routes(service);
+
+       err = disable_gateway(data);
+       g_hash_table_remove(gateway_hash, service);
 
        /* with vpn this will be called after the network was deleted,
         * we need to call set_default here because we will not recieve any
@@ -411,84 +378,57 @@ static void connection_remove(struct connman_element *element)
                if (data != NULL)
                        set_default_gateway(data);
        }
-
-       connman_element_unref(element);
 }
 
-static struct connman_driver connection_driver = {
-       .name           = "connection",
-       .type           = CONNMAN_ELEMENT_TYPE_CONNECTION,
-       .priority       = CONNMAN_DRIVER_PRIORITY_LOW,
-       .probe          = connection_probe,
-       .remove         = connection_remove,
-};
-
-int __connman_connection_init(void)
+gboolean __connman_connection_update_gateway(void)
 {
-       DBG("");
+       struct gateway_data *active_gateway, *default_gateway;
+       gboolean updated = FALSE;
 
-       if (connman_rtnl_register(&connection_rtnl) < 0)
-               connman_error("Failed to setup RTNL gateway driver");
+       update_order();
+
+       active_gateway = find_active_gateway();
+       default_gateway = find_default_gateway();
+
+       if (active_gateway && active_gateway != default_gateway)
+               updated = TRUE;
 
-       return connman_driver_register(&connection_driver);
+       return updated;
 }
 
-void __connman_connection_cleanup(void)
+int __connman_connection_init(void)
 {
-       GSList *list;
+       int err;
 
        DBG("");
 
-       connman_driver_unregister(&connection_driver);
-
-       connman_rtnl_unregister(&connection_rtnl);
-
-       for (list = gateway_list; list; list = list->next) {
-               struct gateway_data *data = list->data;
-
-               DBG("index %d gateway %s", data->index, data->ipv4_gateway);
+       gateway_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+                                                       NULL, remove_gateway);
 
-               g_free(data->ipv4_gateway);
-               g_free(data);
-               list->data = NULL;
-       }
+       err = connman_rtnl_register(&connection_rtnl);
+       if (err < 0)
+               connman_error("Failed to setup RTNL gateway driver");
 
-       g_slist_free(gateway_list);
-       gateway_list = NULL;
+       return err;
 }
 
-static void update_order(void)
+void __connman_connection_cleanup(void)
 {
-       GSList *list = NULL;
-
-       for (list = gateway_list; list; list = list->next) {
-               struct gateway_data *data = list->data;
-               struct connman_service *service;
-               int index = data->index;
+       GHashTableIter iter;
+       gpointer value, key;
 
-               if (data->vpn)
-                       service = __connman_service_lookup_from_index(index);
-               else
-                       service = __connman_element_get_service(data->element);
-
-               data->order = __connman_service_get_order(service);
-       }
-}
+       DBG("");
 
-gboolean __connman_connection_update_gateway(void)
-{
-       struct gateway_data *active_gateway, *default_gateway;
-       gboolean updated = FALSE;
+       connman_rtnl_unregister(&connection_rtnl);
 
-       update_order();
+       g_hash_table_iter_init(&iter, gateway_hash);
 
-       active_gateway = find_active_gateway();
-       default_gateway = find_default_gateway();
+       while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+               struct gateway_data *data = value;
 
-       if (active_gateway && active_gateway != default_gateway) {
-               del_routes(active_gateway);
-               updated = TRUE;
+               disable_gateway(data);
        }
 
-       return updated;
+       g_hash_table_destroy(gateway_hash);
+       gateway_hash = NULL;
 }
index 0bcf63e..b2e87a6 100644 (file)
@@ -261,8 +261,6 @@ void __connman_ipconfig_set_element_ipv6_gateway(
                        struct connman_ipconfig *ipconfig,
                                struct connman_element *element);
 
-int __connman_ipconfig_set_gateway_to_element(struct connman_ipconfig *ipconfig,
-                                       struct connman_element *parent);
 int __connman_ipconfig_set_address(struct connman_ipconfig *ipconfig);
 int __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig);
 unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask);
@@ -295,6 +293,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 *peer);
+void __connman_connection_gateway_remove(struct connman_service *service);
+
 gboolean __connman_connection_update_gateway(void);
 
 int __connman_wpad_init(void);
index 78120ce..e3ec3b7 100644 (file)
@@ -66,8 +66,6 @@ static const char *type2string(enum connman_element_type type)
                return "bootp";
        case CONNMAN_ELEMENT_TYPE_ZEROCONF:
                return "zeroconf";
-       case CONNMAN_ELEMENT_TYPE_CONNECTION:
-               return "connection";
        case CONNMAN_ELEMENT_TYPE_VENDOR:
                return "vendor";
        }
@@ -196,8 +194,11 @@ struct connman_service *__connman_element_get_service(struct connman_element *el
        enum connman_device_type type;
 
        device = __connman_element_get_device(element);
-       if (device == NULL)
-               return NULL;
+       if (device == NULL) {
+               /* Workaround for the connection removal. */
+               service = __connman_service_lookup_from_index(element->index);
+               return service;
+       }
 
        type = connman_device_get_type(device);
 
@@ -1397,7 +1398,6 @@ void __connman_element_start(void)
 
        __connman_rtnl_start();
 
-       __connman_connection_init();
        __connman_ipv4_init();
        __connman_dhcp_init();
        __connman_wpad_init();
@@ -1417,7 +1417,6 @@ void __connman_element_stop(void)
        __connman_dhcp_cleanup();
        __connman_ipv4_cleanup();
        __connman_provider_cleanup();
-       __connman_connection_cleanup();
 }
 
 static gboolean free_driver(GNode *node, gpointer data)
index 49eda33..14edb3d 100644 (file)
@@ -972,11 +972,31 @@ const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
 
 void __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, const char *gateway)
 {
+       struct connman_service *service;
+
        if (ipconfig->address == NULL)
                return;
 
+       service = __connman_service_lookup_from_index(ipconfig->index);
+       if (service != NULL)
+               __connman_connection_gateway_remove(service);
+
        g_free(ipconfig->address->gateway);
        ipconfig->address->gateway = g_strdup(gateway);
+
+       if (service != NULL && ipconfig->address->gateway != NULL) {
+               if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+                       __connman_connection_gateway_add(service,
+                                               NULL,
+                                               ipconfig->address->gateway,
+                                               ipconfig->address->peer);
+               } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+                       __connman_connection_gateway_add(service,
+                                               ipconfig->address->gateway,
+                                               NULL,
+                                               ipconfig->address->peer);
+               }
+       }
 }
 
 unsigned char __connman_ipconfig_get_prefixlen(struct connman_ipconfig *ipconfig)
@@ -1240,33 +1260,6 @@ void __connman_ipconfig_set_element_ipv6_gateway(
                element->ipv6.gateway = ipconfig->address->gateway;
 }
 
-/*
- * FIXME: The element soulution should be removed in the future
- * Set IPv4 and IPv6 gateway
- */
-int __connman_ipconfig_set_gateway_to_element(struct connman_ipconfig *ipconfig,
-                                               struct connman_element *parent)
-{
-       struct connman_element *connection;
-
-       connection = connman_element_create(NULL);
-
-       DBG("ipconfig %p", ipconfig);
-
-       connection->type  = CONNMAN_ELEMENT_TYPE_CONNECTION;
-       connection->index = ipconfig->index;
-
-       if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
-               connection->ipv4.gateway = ipconfig->address->gateway;
-       else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
-               connection->ipv6.gateway = ipconfig->address->gateway;
-
-       if (connman_element_register(connection, parent) < 0)
-               connman_element_unref(connection);
-
-       return 0;
-}
-
 int __connman_ipconfig_set_address(struct connman_ipconfig *ipconfig)
 {
        DBG("");
index f7b664b..57efdaf 100644 (file)
 static int ipv4_probe(struct connman_element *element)
 {
        struct connman_service *service;
-       struct connman_ipconfig *ipconfig;
-       struct connman_element *connection;
        const char *address = NULL, *netmask = NULL, *broadcast = NULL;
        const char *peer = NULL, *nameserver = NULL, *pac = NULL;
+       const char *domainname = NULL, *ipv4_gw = NULL, *ipv6_gw = NULL;
        char *timeserver = NULL;
        unsigned char prefixlen;
+       int err;
 
        DBG("element %p name %s", element, element->name);
        connman_element_get_value(element,
@@ -63,6 +63,14 @@ static int ipv4_probe(struct connman_element *element)
        connman_element_get_value(element,
                        CONNMAN_PROPERTY_ID_IPV4_PAC, &pac);
 
+       connman_element_get_value(element,
+                       CONNMAN_PROPERTY_ID_DOMAINNAME, &domainname);
+
+       connman_element_get_value(element,
+                       CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &ipv4_gw);
+       connman_element_get_value(element,
+                       CONNMAN_PROPERTY_ID_IPV6_GATEWAY, &ipv6_gw);
+
        DBG("address %s", address);
        DBG("peer %s", peer);
        DBG("netmask %s", netmask);
@@ -88,25 +96,18 @@ static int ipv4_probe(struct connman_element *element)
 
        connman_timeserver_append(timeserver);
 
-       connection = connman_element_create(NULL);
-
-       connection->type    = CONNMAN_ELEMENT_TYPE_CONNECTION;
-       connection->index   = element->index;
-       connection->devname = connman_inet_ifname(element->index);
+       err = __connman_connection_gateway_add(service, ipv4_gw, ipv6_gw, peer);
+       if (err < 0)
+               return err;
 
-       ipconfig = __connman_service_get_ip6config(service);
-       if (ipconfig != NULL)
-               __connman_ipconfig_set_element_ipv6_gateway(
-                                               ipconfig, connection);
-
-       if (connman_element_register(connection, element) < 0)
-               connman_element_unref(connection);
+       __connman_service_set_domainname(service, domainname);
 
        return 0;
 }
 
 static void ipv4_remove(struct connman_element *element)
 {
+       struct connman_service *service;
        const char *address = NULL, *netmask = NULL, *broadcast = NULL;
        const char *peer = NULL, *nameserver = NULL;
        char *timeserver = NULL;
@@ -135,12 +136,14 @@ static void ipv4_remove(struct connman_element *element)
        DBG("netmask %s", netmask);
        DBG("broadcast %s", broadcast);
 
-       if (nameserver != NULL) {
-               struct connman_service *service;
+       service = __connman_element_get_service(element);
+
+       __connman_service_set_domainname(service, NULL);
+
+       __connman_connection_gateway_remove(service);
 
-               service = __connman_element_get_service(element);
+       if (nameserver != NULL)
                __connman_service_nameserver_remove(service, nameserver);
-       }
 
        prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
 
index b64e435..ac90b5e 100644 (file)
@@ -228,6 +228,7 @@ int main(int argc, char *argv[])
        __connman_detect_init();
        __connman_session_init();
        __connman_timeserver_init();
+       __connman_connection_init();
 
        __connman_plugin_init(option_plugin, option_noplugin);
 
@@ -249,6 +250,7 @@ int main(int argc, char *argv[])
 
        __connman_plugin_cleanup();
 
+       __connman_connection_cleanup();
        __connman_timeserver_cleanup();
        __connman_session_cleanup();
        __connman_detect_cleanup();
index 64d81db..a8ebb47 100644 (file)
@@ -686,6 +686,7 @@ static void set_connected_manual(struct connman_network *network)
        struct connman_service *service;
        struct connman_ipconfig *ipconfig;
        const char *nameserver = NULL;
+       const char *gateway;
        int err;
 
        DBG("network %p", network);
@@ -708,7 +709,10 @@ static void set_connected_manual(struct connman_network *network)
        if (nameserver != NULL)
                __connman_service_nameserver_append(service, nameserver);
 
-       __connman_ipconfig_set_gateway_to_element(ipconfig, &network->element);
+       connman_element_get_value(&network->element,
+                               CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
+       if (gateway != NULL)
+               __connman_ipconfig_set_gateway(ipconfig, gateway);
 
        network->connecting = FALSE;
 
@@ -1062,8 +1066,6 @@ static int dhcp_start(struct connman_network *network)
 static int dhcp_stop(struct connman_network *network)
 {
        connman_element_unregister_children_type(&network->element,
-                                       CONNMAN_ELEMENT_TYPE_CONNECTION);
-       connman_element_unregister_children_type(&network->element,
                                                CONNMAN_ELEMENT_TYPE_IPV4);
        connman_element_unregister_children_type(&network->element,
                                                CONNMAN_ELEMENT_TYPE_DHCP);
@@ -1075,6 +1077,7 @@ static int manual_ipv4_set(struct connman_network *network,
                                struct connman_ipconfig *ipconfig)
 {
        struct connman_service *service;
+       const char *gateway;
        int err;
 
        service = __connman_service_lookup_from_network(network);
@@ -1088,7 +1091,10 @@ static int manual_ipv4_set(struct connman_network *network,
                return err;
        }
 
-       __connman_ipconfig_set_gateway_to_element(ipconfig, &network->element);
+       connman_element_get_value(&network->element,
+                               CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
+       if (gateway != NULL)
+               __connman_ipconfig_set_gateway(ipconfig, gateway);
 
        __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY,
                                        CONNMAN_IPCONFIG_TYPE_IPV4);
@@ -1117,8 +1123,6 @@ int __connman_network_clear_ipconfig(struct connman_network *network,
        case CONNMAN_IPCONFIG_METHOD_AUTO:
                return -EINVAL;
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
-               connman_element_unregister_children_type(&network->element,
-                                       CONNMAN_ELEMENT_TYPE_CONNECTION);
                __connman_ipconfig_clear_address(ipconfig);
                break;
        case CONNMAN_IPCONFIG_METHOD_DHCP:
index 41f5086..5bbc76c 100644 (file)
@@ -641,12 +641,15 @@ static void nameserver_del_routes(int index, char **nameservers)
 void __connman_service_nameserver_add_routes(struct connman_service *service,
                                                const char *gw)
 {
-       int index;
+       int index = -1;
 
        if (service == NULL)
                return;
 
-       index = connman_network_get_index(service->network);
+       if (service->network != NULL)
+               index = connman_network_get_index(service->network);
+       else if (service->provider != NULL)
+               index = connman_provider_get_index(service->provider);
 
        if (service->nameservers_config != NULL) {
                /*
@@ -668,12 +671,15 @@ void __connman_service_nameserver_add_routes(struct connman_service *service,
 
 void __connman_service_nameserver_del_routes(struct connman_service *service)
 {
-       int index;
+       int index = -1;
 
        if (service == NULL)
                return;
 
-       index = connman_network_get_index(service->network);
+       if (service->network != NULL)
+               index = connman_network_get_index(service->network);
+       else if (service->provider != NULL)
+               index = connman_provider_get_index(service->provider);
 
        if (service->nameservers_config != NULL)
                nameserver_del_routes(index, service->nameservers_config);
@@ -1743,10 +1749,12 @@ int __connman_service_get_index(struct connman_service *service)
        if (service == NULL)
                return -1;
 
-       if (service->network == NULL)
-               return -1;
+       if (service->network != NULL)
+               return connman_network_get_index(service->network);
+       else if (service->provider != NULL)
+               return connman_provider_get_index(service->provider);
 
-       return connman_network_get_index(service->network);
+       return -1;
 }
 
 void __connman_service_set_domainname(struct connman_service *service,