From b44e71853d9de3927b1e77e71fca3ffe0da82e49 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 9 Dec 2010 13:11:50 +0200 Subject: [PATCH] ipconfig: Define 2 separate pointers for IPv4 and IPv6 This patch does not yet enable IPv6 only network support but it is required for later work. --- include/ipconfig.h | 3 +- include/network.h | 4 +- plugins/ofono.c | 4 +- src/connman.h | 11 +- src/ipconfig.c | 321 ++++++++++++++++++++++++++++++++++++----------------- src/ipv4.c | 2 +- src/network.c | 146 +++++++++++++++--------- src/provider.c | 21 +++- src/service.c | 314 ++++++++++++++++++++++++++++++++++----------------- 9 files changed, 563 insertions(+), 263 deletions(-) diff --git a/include/ipconfig.h b/include/ipconfig.h index 28a3d6a..92110e0 100644 --- a/include/ipconfig.h +++ b/include/ipconfig.h @@ -74,7 +74,8 @@ struct connman_ipconfig_ops { void (*ip_release) (struct connman_ipconfig *ipconfig); }; -struct connman_ipconfig *connman_ipconfig_create(int index); +struct connman_ipconfig *connman_ipconfig_create(int index, + enum connman_ipconfig_type type); struct connman_ipconfig *connman_ipconfig_clone(struct connman_ipconfig *ipconfig); struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig); void connman_ipconfig_unref(struct connman_ipconfig *ipconfig); diff --git a/include/network.h b/include/network.h index f6ebc3a..0b538a4 100644 --- a/include/network.h +++ b/include/network.h @@ -89,7 +89,9 @@ connman_bool_t connman_network_get_connected(struct connman_network *network); connman_bool_t connman_network_get_associating(struct connman_network *network); -void connman_network_set_method(struct connman_network *network, +void connman_network_set_ipv4_method(struct connman_network *network, + enum connman_ipconfig_method method); +void connman_network_set_ipv6_method(struct connman_network *network, enum connman_ipconfig_method method); int connman_network_set_address(struct connman_network *network, diff --git a/plugins/ofono.c b/plugins/ofono.c index ee47406..1cb0961 100644 --- a/plugins/ofono.c +++ b/plugins/ofono.c @@ -1497,7 +1497,7 @@ static void set_connected(struct connman_network *network, return; case CONNMAN_IPCONFIG_METHOD_FIXED: - connman_network_set_method(network, method); + connman_network_set_ipv4_method(network, method); if (connected == FALSE) cleanup_ipconfig(network); @@ -1506,7 +1506,7 @@ static void set_connected(struct connman_network *network, break; case CONNMAN_IPCONFIG_METHOD_DHCP: - connman_network_set_method(network, method); + connman_network_set_ipv4_method(network, method); connman_network_set_connected(network, connected); break; diff --git a/src/connman.h b/src/connman.h index 9b8fcc7..03eda92 100644 --- a/src/connman.h +++ b/src/connman.h @@ -376,7 +376,8 @@ int __connman_network_disconnect(struct connman_network *network); int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig); int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig); + struct connman_ipconfig *ipconfig_ipv4, + struct connman_ipconfig *ipconfig_ipv6); connman_bool_t __connman_network_has_driver(struct connman_network *network); @@ -459,9 +460,13 @@ struct connman_service *__connman_service_create_from_provider(struct connman_pr void __connman_service_update_from_network(struct connman_network *network); void __connman_service_remove_from_network(struct connman_network *network); -void __connman_service_create_ipconfig(struct connman_service *service, +void __connman_service_create_ip4config(struct connman_service *service, + int index); +void __connman_service_create_ip6config(struct connman_service *service, int index); -struct connman_ipconfig *__connman_service_get_ipconfig( +struct connman_ipconfig *__connman_service_get_ip4config( + struct connman_service *service); +struct connman_ipconfig *__connman_service_get_ip6config( struct connman_service *service); const char *__connman_service_get_ident(struct connman_service *service); const char *__connman_service_get_path(struct connman_service *service); diff --git a/src/ipconfig.c b/src/ipconfig.c index c6e33ec..a2a7bf2 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -50,8 +50,6 @@ struct connman_ipconfig { enum connman_ipconfig_method method; struct connman_ipaddress *address; struct connman_ipaddress *system; - - struct connman_ipconfig *ipv6; }; struct connman_ipdevice { @@ -76,10 +74,14 @@ struct connman_ipdevice { char *pac; - struct connman_ipconfig *config; + struct connman_ipconfig *config_ipv4; + struct connman_ipconfig *config_ipv6; + + struct connman_ipconfig_driver *driver_ipv4; + struct connman_ipconfig *driver_config_ipv4; - struct connman_ipconfig_driver *driver; - struct connman_ipconfig *driver_config; + struct connman_ipconfig_driver *driver_ipv6; + struct connman_ipconfig *driver_config_ipv6; }; static GHashTable *ipdevice_hash = NULL; @@ -302,8 +304,15 @@ static void free_ipdevice(gpointer data) connman_info("%s {remove} index %d", ipdevice->ifname, ipdevice->index); - if (ipdevice->config != NULL) - connman_ipconfig_unref(ipdevice->config); + if (ipdevice->config_ipv4 != NULL) { + connman_ipconfig_unref(ipdevice->config_ipv4); + ipdevice->config_ipv4 = NULL; + } + + if (ipdevice->config_ipv6 != NULL) { + connman_ipconfig_unref(ipdevice->config_ipv6); + ipdevice->config_ipv6 = NULL; + } free_address_list(ipdevice); g_free(ipdevice->ipv4_gateway); @@ -359,65 +368,129 @@ void connman_ipconfig_driver_unregister(struct connman_ipconfig_driver *driver) static void __connman_ipconfig_lower_up(struct connman_ipdevice *ipdevice) { GSList *list; + int is_dhcpv4 = 0, is_dhcpv6 = 0; + int found = 0; - DBG("ipconfig %p", ipdevice->config); + DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4, + ipdevice->config_ipv6); - if (ipdevice->config == NULL) + if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL) return; - switch (ipdevice->config->method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: + if (ipdevice->driver_ipv4 != NULL && ipdevice->driver_ipv6 != NULL) return; - case CONNMAN_IPCONFIG_METHOD_DHCP: - break; + + if (ipdevice->config_ipv4) { + switch (ipdevice->config_ipv4->method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + is_dhcpv4 = 1; + break; + } } - if (ipdevice->driver != NULL) - return; + if (ipdevice->config_ipv6) { + switch (ipdevice->config_ipv6->method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + is_dhcpv6 = 1; + break; + } + } - ipdevice->driver_config = connman_ipconfig_clone(ipdevice->config); - if (ipdevice->driver_config == NULL) - return; + if (is_dhcpv4 && ipdevice->config_ipv4) { + ipdevice->driver_config_ipv4 = connman_ipconfig_clone( + ipdevice->config_ipv4); + if (ipdevice->driver_config_ipv4 == NULL) + return; + } + + if (is_dhcpv6 && ipdevice->config_ipv6) { + ipdevice->driver_config_ipv6 = connman_ipconfig_clone( + ipdevice->config_ipv6); + if (ipdevice->driver_config_ipv6 == NULL) + return; + } for (list = driver_list; list; list = list->next) { struct connman_ipconfig_driver *driver = list->data; - if (driver->request(ipdevice->driver_config) == 0) { - ipdevice->driver = driver; - break; + if (is_dhcpv4 && ipdevice->driver_ipv4 != NULL) { + if (!driver->request(ipdevice->driver_config_ipv4)) { + ipdevice->driver_ipv4 = driver; + found++; + } } + + if (is_dhcpv6 && ipdevice->driver_ipv6 != NULL) { + if (!driver->request(ipdevice->driver_config_ipv6)) { + ipdevice->driver_ipv6 = driver; + found++; + } + } + + if (found > 1) + break; + } + + if (ipdevice->driver_ipv4 == NULL) { + connman_ipconfig_unref(ipdevice->driver_config_ipv4); + ipdevice->driver_config_ipv4 = NULL; } - if (ipdevice->driver == NULL) { - connman_ipconfig_unref(ipdevice->driver_config); - ipdevice->driver_config = NULL; + if (ipdevice->driver_ipv6 == NULL) { + connman_ipconfig_unref(ipdevice->driver_config_ipv6); + ipdevice->driver_config_ipv6 = NULL; } } static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice) { - DBG("ipconfig %p", ipdevice->config); + DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4, + ipdevice->config_ipv6); - if (ipdevice->config == NULL) + if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL) return; - if (ipdevice->driver == NULL) + if (ipdevice->driver_ipv4 == NULL && ipdevice->driver_ipv6 == NULL) return; - ipdevice->driver->release(ipdevice->driver_config); + if (ipdevice->driver_ipv4) { + ipdevice->driver_ipv4->release(ipdevice->driver_config_ipv4); + ipdevice->driver_ipv4 = NULL; + } + + if (ipdevice->driver_ipv6) { + ipdevice->driver_ipv6->release(ipdevice->driver_config_ipv6); + ipdevice->driver_ipv6 = NULL; + } + + if (ipdevice->driver_config_ipv4) { + connman_ipconfig_unref(ipdevice->driver_config_ipv4); + ipdevice->driver_config_ipv4 = NULL; + } - ipdevice->driver = NULL; + if (ipdevice->driver_config_ipv6) { + connman_ipconfig_unref(ipdevice->driver_config_ipv6); + ipdevice->driver_config_ipv6 = NULL; + } - connman_ipconfig_unref(ipdevice->driver_config); - ipdevice->driver_config = NULL; + if (ipdevice->config_ipv4) + connman_inet_clear_address(ipdevice->index, + ipdevice->config_ipv4->address); - connman_inet_clear_address(ipdevice->index, ipdevice->config->address); - connman_inet_clear_ipv6_address(ipdevice->index, - ipdevice->driver_config->address->local, - ipdevice->driver_config->address->prefixlen); + if (ipdevice->config_ipv6) + connman_inet_clear_ipv6_address(ipdevice->index, + ipdevice->config_ipv6->address->local, + ipdevice->config_ipv6->address->prefixlen); } static void update_stats(struct connman_ipdevice *ipdevice, @@ -433,10 +506,16 @@ static void update_stats(struct connman_ipdevice *ipdevice, connman_info("%s {TX} %u packets %u bytes", ipdevice->ifname, stats->tx_packets, stats->tx_bytes); - if (ipdevice->config == NULL) + if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL) + return; + + if (ipdevice->config_ipv4) + service = connman_ipconfig_get_data(ipdevice->config_ipv4); + else if (ipdevice->config_ipv6) + service = connman_ipconfig_get_data(ipdevice->config_ipv6); + else return; - service = connman_ipconfig_get_data(ipdevice->config); if (service == NULL) return; @@ -640,17 +719,18 @@ void __connman_ipconfig_newaddr(int index, int family, const char *label, ipdevice->address_list = g_slist_append(ipdevice->address_list, ipaddress); - connman_info("%s {add} address %s/%u label %s", ipdevice->ifname, - address, prefixlen, label); + connman_info("%s {add} address %s/%u label %s family %d", + ipdevice->ifname, address, prefixlen, label, family); - if (ipdevice->config != NULL) { - if (family == AF_INET6 && ipdevice->config->ipv6 != NULL) - connman_ipaddress_copy(ipdevice->config->ipv6->system, - ipaddress); - else - connman_ipaddress_copy(ipdevice->config->system, - ipaddress); - } + if (ipdevice->config_ipv4 != NULL && family == AF_INET) + connman_ipaddress_copy(ipdevice->config_ipv4->system, + ipaddress); + + else if (ipdevice->config_ipv6 != NULL && family == AF_INET6) + connman_ipaddress_copy(ipdevice->config_ipv6->system, + ipaddress); + else + return; if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) != (IFF_RUNNING | IFF_LOWER_UP)) return; @@ -734,15 +814,23 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope, if (family == AF_INET6) { g_free(ipdevice->ipv6_gateway); ipdevice->ipv6_gateway = g_strdup(gateway); + + if (ipdevice->config_ipv6 != NULL && + ipdevice->config_ipv6->system != NULL) { + g_free(ipdevice->config_ipv6->system->gateway); + ipdevice->config_ipv6->system->gateway = + g_strdup(gateway); + } } else { g_free(ipdevice->ipv4_gateway); ipdevice->ipv4_gateway = g_strdup(gateway); - } - if (ipdevice->config != NULL && - ipdevice->config->system != NULL) { - g_free(ipdevice->config->system->gateway); - ipdevice->config->system->gateway = g_strdup(gateway); + if (ipdevice->config_ipv4 != NULL && + ipdevice->config_ipv4->system != NULL) { + g_free(ipdevice->config_ipv4->system->gateway); + ipdevice->config_ipv4->system->gateway = + g_strdup(gateway); + } } for (list = ipdevice->address_list; list; list = list->next) { @@ -790,15 +878,21 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope, if (family == AF_INET6) { g_free(ipdevice->ipv6_gateway); ipdevice->ipv6_gateway = NULL; + + if (ipdevice->config_ipv6 != NULL && + ipdevice->config_ipv6->system != NULL) { + g_free(ipdevice->config_ipv6->system->gateway); + ipdevice->config_ipv6->system->gateway = NULL; + } } else { g_free(ipdevice->ipv4_gateway); ipdevice->ipv4_gateway = NULL; - } - if (ipdevice->config != NULL && - ipdevice->config->system != NULL) { - g_free(ipdevice->config->system->gateway); - ipdevice->config->system->gateway = NULL; + if (ipdevice->config_ipv4 != NULL && + ipdevice->config_ipv4->system != NULL) { + g_free(ipdevice->config_ipv4->system->gateway); + ipdevice->config_ipv4->system->gateway = NULL; + } } for (list = ipdevice->address_list; list; list = list->next) { @@ -879,9 +973,16 @@ const char *__connman_ipconfig_get_gateway(int index) if (ipdevice->ipv4_gateway != NULL) return ipdevice->ipv4_gateway; - if (ipdevice->config != NULL && - ipdevice->config->address != NULL) - return ipdevice->config->address->gateway; + if (ipdevice->config_ipv4 != NULL && + ipdevice->config_ipv4->address != NULL) + return ipdevice->config_ipv4->address->gateway; + + if (ipdevice->ipv6_gateway != NULL) + return ipdevice->ipv6_gateway; + + if (ipdevice->config_ipv6 != NULL && + ipdevice->config_ipv6->address != NULL) + return ipdevice->config_ipv6->address->gateway; return NULL; } @@ -889,9 +990,6 @@ const char *__connman_ipconfig_get_gateway(int index) void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index) { ipconfig->index = index; - - if (ipconfig->ipv6 != NULL) - ipconfig->ipv6->index = index; } static struct connman_ipconfig *create_ipv6config(int index) @@ -916,8 +1014,6 @@ static struct connman_ipconfig *create_ipv6config(int index) ipv6config->system = connman_ipaddress_alloc(AF_INET6); - ipv6config->ipv6 = NULL; - DBG("ipconfig %p", ipv6config); return ipv6config; @@ -930,10 +1026,14 @@ static struct connman_ipconfig *create_ipv6config(int index) * * Returns: a newly-allocated #connman_ipconfig structure */ -struct connman_ipconfig *connman_ipconfig_create(int index) +struct connman_ipconfig *connman_ipconfig_create(int index, + enum connman_ipconfig_type type) { struct connman_ipconfig *ipconfig; + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + return create_ipv6config(index); + DBG("index %d", index); ipconfig = g_try_new0(struct connman_ipconfig, 1); @@ -953,8 +1053,6 @@ struct connman_ipconfig *connman_ipconfig_create(int index) ipconfig->system = connman_ipaddress_alloc(AF_INET); - ipconfig->ipv6 = create_ipv6config(index); - DBG("ipconfig %p", ipconfig); return ipconfig; @@ -999,17 +1097,6 @@ struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig) return ipconfig; } -static void free_ipv6config(struct connman_ipconfig *ipconfig) -{ - if (ipconfig == NULL) - return; - - connman_ipconfig_set_ops(ipconfig, NULL); - connman_ipaddress_free(ipconfig->system); - connman_ipaddress_free(ipconfig->address); - g_free(ipconfig->ipv6); -} - /** * connman_ipconfig_unref: * @ipconfig: ipconfig structure @@ -1031,7 +1118,6 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig) connman_ipaddress_free(ipconfig->system); connman_ipaddress_free(ipconfig->address); - free_ipv6config(ipconfig->ipv6); g_free(ipconfig); } } @@ -1119,7 +1205,7 @@ struct connman_ipconfig *connman_ipconfig_get_ipv6config( if (ipconfig == NULL) return NULL; - return ipconfig->ipv6; + return ipconfig; } /** @@ -1168,7 +1254,7 @@ void __connman_ipconfig_set_element_ipv6_gateway( struct connman_ipconfig *ipconfig, struct connman_element *element) { - element->ipv6.gateway = ipconfig->ipv6->address->gateway; + element->ipv6.gateway = ipconfig->address->gateway; } /* @@ -1186,8 +1272,11 @@ int __connman_ipconfig_set_gateway(struct connman_ipconfig *ipconfig, connection->type = CONNMAN_ELEMENT_TYPE_CONNECTION; connection->index = ipconfig->index; - connection->ipv4.gateway = ipconfig->address->gateway; - connection->ipv6.gateway = ipconfig->ipv6->address->gateway; + + 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); @@ -1289,6 +1378,7 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig) struct connman_ipdevice *ipdevice; gboolean up = FALSE, down = FALSE; gboolean lower_up = FALSE, lower_down = FALSE; + enum connman_ipconfig_type type; DBG("ipconfig %p", ipconfig); @@ -1300,18 +1390,39 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig) if (ipdevice == NULL) return -ENXIO; - if (ipdevice->config == ipconfig) - return -EALREADY; + if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4) { + if (ipdevice->config_ipv4 == ipconfig) + return -EALREADY; + type = CONNMAN_IPCONFIG_TYPE_IPV4; + } else if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6) { + if (ipdevice->config_ipv6 == ipconfig) + return -EALREADY; + type = CONNMAN_IPCONFIG_TYPE_IPV6; + } else + return -EINVAL; + + if (type == CONNMAN_IPCONFIG_TYPE_IPV4 && + ipdevice->config_ipv4 != NULL) { + ipconfig_list = g_list_remove(ipconfig_list, ipconfig); + + connman_ipaddress_clear(ipdevice->config_ipv4->system); - if (ipdevice->config != NULL) { + connman_ipconfig_unref(ipdevice->config_ipv4); + } + + if (type == CONNMAN_IPCONFIG_TYPE_IPV6 && + ipdevice->config_ipv6 != NULL) { ipconfig_list = g_list_remove(ipconfig_list, ipconfig); - connman_ipaddress_clear(ipdevice->config->system); + connman_ipaddress_clear(ipdevice->config_ipv6->system); - connman_ipconfig_unref(ipdevice->config); + connman_ipconfig_unref(ipdevice->config_ipv6); } - ipdevice->config = connman_ipconfig_ref(ipconfig); + if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + ipdevice->config_ipv4 = connman_ipconfig_ref(ipconfig); + else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + ipdevice->config_ipv6 = connman_ipconfig_ref(ipconfig); ipconfig_list = g_list_append(ipconfig_list, ipconfig); @@ -1353,18 +1464,28 @@ int __connman_ipconfig_disable(struct connman_ipconfig *ipconfig) if (ipdevice == NULL) return -ENXIO; - if (ipdevice->config == NULL || ipdevice->config != ipconfig) + if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL) return -EINVAL; - ipconfig_list = g_list_remove(ipconfig_list, ipconfig); + if (ipdevice->config_ipv4 == ipconfig) { + ipconfig_list = g_list_remove(ipconfig_list, ipconfig); + + connman_ipaddress_clear(ipdevice->config_ipv4->system); + connman_ipconfig_unref(ipdevice->config_ipv4); + ipdevice->config_ipv4 = NULL; + return 0; + } - connman_ipaddress_clear(ipdevice->config->system); - connman_ipaddress_clear(ipdevice->config->ipv6->system); + if (ipdevice->config_ipv6 == ipconfig) { + ipconfig_list = g_list_remove(ipconfig_list, ipconfig); - connman_ipconfig_unref(ipdevice->config); - ipdevice->config = NULL; + connman_ipaddress_clear(ipdevice->config_ipv6->system); + connman_ipconfig_unref(ipdevice->config_ipv6); + ipdevice->config_ipv6 = NULL; + return 0; + } - return 0; + return -EINVAL; } const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method) diff --git a/src/ipv4.c b/src/ipv4.c index 9124015..da115ed 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -94,7 +94,7 @@ static int ipv4_probe(struct connman_element *element) connection->index = element->index; connection->devname = connman_inet_ifname(element->index); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip6config(service); if (ipconfig != NULL) __connman_ipconfig_set_element_ipv6_gateway( ipconfig, connection); diff --git a/src/network.c b/src/network.c index 6e205ab..9902fdd 100644 --- a/src/network.c +++ b/src/network.c @@ -294,16 +294,25 @@ void connman_network_set_index(struct connman_network *network, int index) if (service == NULL) goto done; - ipconfig = __connman_service_get_ipconfig(service); - - if (network->element.index < 0 && ipconfig == NULL) - /* - * This is needed for plugins that havent set their ipconfig - * layer yet, due to not being able to get a network index - * prior to creating a service. - */ - __connman_service_create_ipconfig(service, index); - else { + ipconfig = __connman_service_get_ip4config(service); + + DBG("index %d service %p ip4config %p", network->element.index, + service, ipconfig); + + if (network->element.index < 0 && ipconfig == NULL) { + + ipconfig = __connman_service_get_ip4config(service); + if (ipconfig == NULL) + /* + * This is needed for plugins that havent set their + * ipconfig layer yet, due to not being able to get + * a network index prior to creating a service. + */ + __connman_service_create_ip4config(service, index); + else + __connman_ipconfig_set_index(ipconfig, index); + + } else { /* If index changed, the index of ipconfig must be reset. */ if (ipconfig == NULL) goto done; @@ -514,7 +523,7 @@ static void set_configure_error(struct connman_network *network) CONNMAN_SERVICE_STATE_FAILURE); } -void connman_network_set_method(struct connman_network *network, +void connman_network_set_ipv4_method(struct connman_network *network, enum connman_ipconfig_method method) { struct connman_service *service; @@ -526,7 +535,26 @@ void connman_network_set_method(struct connman_network *network, if (service == NULL) return; - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip4config(service); + if (ipconfig == NULL) + return; + + connman_ipconfig_set_method(ipconfig, method); +} + +void connman_network_set_ipv6_method(struct connman_network *network, + enum connman_ipconfig_method method) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig; + + network->element.ipv6.method = method; + + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return; + + ipconfig = __connman_service_get_ip6config(service); if (ipconfig == NULL) return; @@ -620,7 +648,7 @@ static void set_connected_manual(struct connman_network *network) service = __connman_service_lookup_from_network(network); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip4config(service); set_configuration(network); @@ -699,31 +727,39 @@ static gboolean set_connected(gpointer user_data) { struct connman_network *network = user_data; struct connman_service *service; - struct connman_ipconfig *ipconfig; - enum connman_ipconfig_method method; + struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; + enum connman_ipconfig_method ipv4_method, ipv6_method; service = __connman_service_lookup_from_network(network); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig_ipv4 = __connman_service_get_ip4config(service); + ipconfig_ipv6 = __connman_service_get_ip6config(service); - method = __connman_ipconfig_get_method(ipconfig); + DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4, + ipconfig_ipv6); + + if (ipconfig_ipv4) + ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); + else + ipv4_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; + + if (ipconfig_ipv6) + ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); + else + ipv6_method = CONNMAN_IPCONFIG_METHOD_UNKNOWN; - DBG("method %d", method); + DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method); + DBG("network connected %d", network->connected); if (network->connected == TRUE) { - enum connman_ipconfig_method ipv6_method; - struct connman_ipconfig *ipv6config; int ret; - ipv6config = connman_ipconfig_get_ipv6config(ipconfig); - ipv6_method = __connman_ipconfig_get_method(ipv6config); switch (ipv6_method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - break; case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipv6config); + ret = manual_ipv6_set(network, ipconfig_ipv6); if (ret != 0) { connman_network_set_error(network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); @@ -734,7 +770,7 @@ static gboolean set_connected(gpointer user_data) break; } - switch (method) { + switch (ipv4_method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: return FALSE; @@ -1007,42 +1043,46 @@ int __connman_network_clear_ipconfig(struct connman_network *network, } int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig) + struct connman_ipconfig *ipconfig_ipv4, + struct connman_ipconfig *ipconfig_ipv6) { - struct connman_ipconfig *ipv6config; enum connman_ipconfig_method method; int ret; - ipv6config = connman_ipconfig_get_ipv6config(ipconfig); - method = __connman_ipconfig_get_method(ipv6config); - switch (method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - break; - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipv6config); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return FALSE; + if (ipconfig_ipv6) { + method = __connman_ipconfig_get_method(ipconfig_ipv6); + + switch (method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + break; + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + ret = manual_ipv6_set(network, ipconfig_ipv6); + if (ret != 0) { + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + return FALSE; + } + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + break; } - break; - case CONNMAN_IPCONFIG_METHOD_DHCP: - break; } - method = __connman_ipconfig_get_method(ipconfig); + if (ipconfig_ipv4) { + method = __connman_ipconfig_get_method(ipconfig_ipv4); - switch (method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: - return -EINVAL; - case CONNMAN_IPCONFIG_METHOD_MANUAL: - return manual_ipv4_set(network, ipconfig); - case CONNMAN_IPCONFIG_METHOD_DHCP: - return dhcp_start(network); + switch (method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_FIXED: + return -EINVAL; + case CONNMAN_IPCONFIG_METHOD_MANUAL: + return manual_ipv4_set(network, ipconfig_ipv4); + case CONNMAN_IPCONFIG_METHOD_DHCP: + return dhcp_start(network); + } } return 0; diff --git a/src/provider.c b/src/provider.c index ea7d37b..efcf748 100644 --- a/src/provider.c +++ b/src/provider.c @@ -669,12 +669,12 @@ void connman_provider_set_index(struct connman_provider *provider, int index) if (service == NULL) return; - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip4config(service); if (ipconfig == NULL) { - __connman_service_create_ipconfig(service, index); + __connman_service_create_ip4config(service, index); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip4config(service); if (ipconfig == NULL) { DBG("Couldnt create ipconfig"); goto done; @@ -685,6 +685,21 @@ void connman_provider_set_index(struct connman_provider *provider, int index) __connman_ipconfig_set_index(ipconfig, index); + ipconfig = __connman_service_get_ip6config(service); + + if (ipconfig == NULL) { + __connman_service_create_ip6config(service, index); + + ipconfig = __connman_service_get_ip6config(service); + if (ipconfig == NULL) { + DBG("Couldnt create ipconfig for IPv6"); + goto done; + } + } + + connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_OFF); + __connman_ipconfig_set_index(ipconfig, index); + done: provider->element.index = index; } diff --git a/src/service.c b/src/service.c index ba5b288..aeaf170 100644 --- a/src/service.c +++ b/src/service.c @@ -79,7 +79,8 @@ struct connman_service { char *mnc; connman_bool_t roaming; connman_bool_t login_required; - struct connman_ipconfig *ipconfig; + struct connman_ipconfig *ipconfig_ipv4; + struct connman_ipconfig *ipconfig_ipv6; struct connman_network *network; struct connman_provider *provider; char **nameservers; @@ -339,7 +340,14 @@ static connman_bool_t is_connected(const struct connman_service *service) static void update_nameservers(struct connman_service *service) { - const char *ifname = connman_ipconfig_get_ifname(service->ipconfig); + const char *ifname; + + if (service->ipconfig_ipv4) + ifname = connman_ipconfig_get_ifname(service->ipconfig_ipv4); + else if (service->ipconfig_ipv6) + ifname = connman_ipconfig_get_ifname(service->ipconfig_ipv6); + else + ifname = NULL; if (ifname == NULL) return; @@ -748,8 +756,12 @@ static void append_ethernet(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - if (service->ipconfig != NULL) - __connman_ipconfig_append_ethernet(service->ipconfig, iter); + if (service->ipconfig_ipv4 != NULL) + __connman_ipconfig_append_ethernet(service->ipconfig_ipv4, + iter); + else if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_append_ethernet(service->ipconfig_ipv6, + iter); } static void append_ipv4(DBusMessageIter *iter, void *user_data) @@ -759,49 +771,37 @@ static void append_ipv4(DBusMessageIter *iter, void *user_data) if (is_connected(service) == FALSE) return; - if (service->ipconfig != NULL) - __connman_ipconfig_append_ipv4(service->ipconfig, iter); + if (service->ipconfig_ipv4 != NULL) + __connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter); } static void append_ipv6(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - struct connman_ipconfig *ipv6config; if (is_connected(service) == FALSE) return; - if (service->ipconfig == NULL) - return; - - ipv6config = connman_ipconfig_get_ipv6config(service->ipconfig); - if (ipv6config == NULL) - return; - - __connman_ipconfig_append_ipv6(ipv6config, iter); + if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_append_ipv6(service->ipconfig_ipv6, iter); } static void append_ipv4config(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - if (service->ipconfig != NULL) - __connman_ipconfig_append_ipv4config(service->ipconfig, iter); + if (service->ipconfig_ipv4 != NULL) + __connman_ipconfig_append_ipv4config(service->ipconfig_ipv4, + iter); } static void append_ipv6config(DBusMessageIter *iter, void *user_data) { struct connman_service *service = user_data; - struct connman_ipconfig *ipv6config; - - if (service->ipconfig == NULL) - return; - - ipv6config = connman_ipconfig_get_ipv6config(service->ipconfig); - if (ipv6config == NULL) - return; - __connman_ipconfig_append_ipv6config(ipv6config, iter); + if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_append_ipv6config(service->ipconfig_ipv6, + iter); } static void append_dns(DBusMessageIter *iter, void *user_data) @@ -923,9 +923,12 @@ static void append_proxy(DBusMessageIter *iter, void *user_data) break; case CONNMAN_SERVICE_PROXY_METHOD_AUTO: /* Maybe DHCP, or WPAD, has provided an url for a pac file */ - if (service->ipconfig != NULL) + if (service->ipconfig_ipv4 != NULL) pac = __connman_ipconfig_get_proxy_autoconfig( - service->ipconfig); + service->ipconfig_ipv4); + else if (service->ipconfig_ipv6 != NULL) + pac = __connman_ipconfig_get_proxy_autoconfig( + service->ipconfig_ipv6); if (service->pac == NULL && pac == NULL) goto done; @@ -1575,8 +1578,15 @@ void __connman_service_set_proxy_autoconfig(struct connman_service *service, if (service == NULL) return; - if (__connman_ipconfig_set_proxy_autoconfig(service->ipconfig, - url) < 0) + if (service->ipconfig_ipv4) { + if (__connman_ipconfig_set_proxy_autoconfig( + service->ipconfig_ipv4, url) < 0) + return; + } else if (service->ipconfig_ipv6) { + if (__connman_ipconfig_set_proxy_autoconfig( + service->ipconfig_ipv6, url) < 0) + return; + } else return; proxy_changed(service); @@ -1587,7 +1597,13 @@ const char *connman_service_get_proxy_autoconfig(struct connman_service *service if (service == NULL) return NULL; - return __connman_ipconfig_get_proxy_autoconfig(service->ipconfig); + if (service->ipconfig_ipv4) + return __connman_ipconfig_get_proxy_autoconfig( + service->ipconfig_ipv4); + else if (service->ipconfig_ipv6) + return __connman_ipconfig_get_proxy_autoconfig( + service->ipconfig_ipv6); + return NULL; } void __connman_service_set_passphrase(struct connman_service *service, @@ -2024,39 +2040,38 @@ static DBusMessage *set_property(DBusConnection *conn, enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN; int err = 0; - struct connman_ipconfig *ipv6config; DBG("%s", name); - ipv6config = connman_ipconfig_get_ipv6config( - service->ipconfig); - if (service->ipconfig == NULL) + if (service->ipconfig_ipv4 == NULL && + service->ipconfig_ipv6 == NULL) return __connman_error_invalid_property(msg); if (is_connecting(service) || is_connected(service)) { __connman_network_clear_ipconfig(service->network, - service->ipconfig); + service->ipconfig_ipv4); __connman_network_clear_ipconfig(service->network, - ipv6config); + service->ipconfig_ipv6); } if (g_str_equal(name, "IPv4.Configuration") == TRUE) { type = CONNMAN_IPCONFIG_TYPE_IPV4; err = __connman_ipconfig_set_config( - service->ipconfig, type, &value); + service->ipconfig_ipv4, type, &value); } else if (g_str_equal(name, "IPv6.Configuration") == TRUE) { type = CONNMAN_IPCONFIG_TYPE_IPV6; err = __connman_ipconfig_set_config( - ipv6config, type, &value); + service->ipconfig_ipv6, type, &value); } if (err < 0) { if (is_connected(service) || is_connecting(service)) __connman_network_set_ipconfig( - service->network, - service->ipconfig); + service->network, + service->ipconfig_ipv4, + service->ipconfig_ipv6); return __connman_error_failed(msg, -err); } @@ -2068,7 +2083,8 @@ static DBusMessage *set_property(DBusConnection *conn, if (is_connecting(service) || is_connected(service)) __connman_network_set_ipconfig(service->network, - service->ipconfig); + service->ipconfig_ipv4, + service->ipconfig_ipv6); __connman_storage_save_service(service); } else @@ -2213,7 +2229,14 @@ static gboolean connect_timeout(gpointer user_data) if (service->network != NULL) __connman_network_disconnect(service->network); - __connman_ipconfig_disable(service->ipconfig); + if (service->ipconfig_ipv4) + if (!__connman_ipconfig_disable(service->ipconfig_ipv4)) + service->ipconfig_ipv4 = NULL; + + if (service->ipconfig_ipv6) + if (!__connman_ipconfig_disable(service->ipconfig_ipv6)) + service->ipconfig_ipv6 = NULL; + __connman_stats_service_unregister(service); if (service->pending != NULL) { @@ -2576,9 +2599,14 @@ static void service_free(gpointer user_data) if (service->provider != NULL) connman_provider_unref(service->provider); - if (service->ipconfig != NULL) { - connman_ipconfig_unref(service->ipconfig); - service->ipconfig = NULL; + if (service->ipconfig_ipv4 != NULL) { + connman_ipconfig_unref(service->ipconfig_ipv4); + service->ipconfig_ipv4 = NULL; + } + + if (service->ipconfig_ipv6 != NULL) { + connman_ipconfig_unref(service->ipconfig_ipv6); + service->ipconfig_ipv6 = NULL; } if (service->location != NULL) @@ -2833,7 +2861,14 @@ char *connman_service_get_interface(struct connman_service *service) return NULL; if (service->type == CONNMAN_SERVICE_TYPE_VPN) { - index = connman_ipconfig_get_index(service->ipconfig); + if (service->ipconfig_ipv4) + index = connman_ipconfig_get_index( + service->ipconfig_ipv4); + else if (service->ipconfig_ipv6) + index = connman_ipconfig_get_index( + service->ipconfig_ipv6); + else + return NULL; return connman_inet_ifname(index); } @@ -2861,12 +2896,22 @@ __connman_service_get_network(struct connman_service *service) return service->network; } -struct connman_ipconfig *__connman_service_get_ipconfig(struct connman_service *service) +struct connman_ipconfig * +__connman_service_get_ip4config(struct connman_service *service) { if (service == NULL) return NULL; - return service->ipconfig; + return service->ipconfig_ipv4; +} + +struct connman_ipconfig * +__connman_service_get_ip6config(struct connman_service *service) +{ + if (service == NULL) + return NULL; + + return service->ipconfig_ipv6; } enum connman_service_security __connman_service_get_security(struct connman_service *service) @@ -3009,7 +3054,10 @@ int __connman_service_indicate_state(struct connman_service *service, &service->stats_roaming.data); } - __connman_ipconfig_enable(service->ipconfig); + if (service->ipconfig_ipv4) + __connman_ipconfig_enable(service->ipconfig_ipv4); + if (service->ipconfig_ipv6) + __connman_ipconfig_enable(service->ipconfig_ipv6); } service->state = state; @@ -3281,7 +3329,10 @@ int __connman_service_connect(struct connman_service *service) &service->stats_roaming.data); } - __connman_ipconfig_enable(service->ipconfig); + if (service->ipconfig_ipv4) + __connman_ipconfig_enable(service->ipconfig_ipv4); + if (service->ipconfig_ipv6) + __connman_ipconfig_enable(service->ipconfig_ipv6); err = __connman_network_connect(service->network); } else if (service->type == CONNMAN_SERVICE_TYPE_VPN && @@ -3292,7 +3343,16 @@ int __connman_service_connect(struct connman_service *service) if (err < 0) { if (err != -EINPROGRESS) { - __connman_ipconfig_disable(service->ipconfig); + if (service->ipconfig_ipv4) + if (!__connman_ipconfig_disable( + service->ipconfig_ipv4)) + service->ipconfig_ipv4 = NULL; + + if (service->ipconfig_ipv6) + if (!__connman_ipconfig_disable( + service->ipconfig_ipv6)) + service->ipconfig_ipv6 = NULL; + __connman_stats_service_unregister(service); if (service->userconnect == TRUE) return __connman_agent_report_error(service, @@ -3313,7 +3373,6 @@ int __connman_service_connect(struct connman_service *service) int __connman_service_disconnect(struct connman_service *service) { - struct connman_ipconfig *ipv6config; int err; DBG("service %p", service); @@ -3326,15 +3385,22 @@ int __connman_service_disconnect(struct connman_service *service) else return -EOPNOTSUPP; - __connman_ipconfig_set_proxy_autoconfig(service->ipconfig, NULL); + if (service->ipconfig_ipv4) + __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv4, + NULL); + else + __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6, + NULL); - __connman_ipconfig_clear_address(service->ipconfig); + __connman_ipconfig_clear_address(service->ipconfig_ipv4); + __connman_ipconfig_clear_address(service->ipconfig_ipv6); - ipv6config = connman_ipconfig_get_ipv6config(service->ipconfig); + if (!__connman_ipconfig_disable(service->ipconfig_ipv4)) + service->ipconfig_ipv4 = NULL; - __connman_ipconfig_clear_address(ipv6config); + if (!__connman_ipconfig_disable(service->ipconfig_ipv6)) + service->ipconfig_ipv6 = NULL; - __connman_ipconfig_disable(service->ipconfig); __connman_stats_service_unregister(service); if (err < 0) { @@ -3724,34 +3790,54 @@ static const struct connman_ipconfig_ops service_ops = { .ip_release = service_ip_release, }; -static void setup_ipconfig(struct connman_service *service, int index) +static void setup_ip4config(struct connman_service *service, int index) { if (index < 0) return; - service->ipconfig = connman_ipconfig_create(index); - if (service->ipconfig == NULL) + service->ipconfig_ipv4 = connman_ipconfig_create(index, + CONNMAN_IPCONFIG_TYPE_IPV4); + if (service->ipconfig_ipv4 == NULL) return; - connman_ipconfig_set_method(service->ipconfig, + connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP); - connman_ipconfig_set_data(service->ipconfig, service); + connman_ipconfig_set_data(service->ipconfig_ipv4, service); - connman_ipconfig_set_ops(service->ipconfig, &service_ops); + connman_ipconfig_set_ops(service->ipconfig_ipv4, &service_ops); } -void __connman_service_create_ipconfig(struct connman_service *service, +static void setup_ip6config(struct connman_service *service, int index) +{ + if (index < 0) + return; + + service->ipconfig_ipv6 = connman_ipconfig_create(index, + CONNMAN_IPCONFIG_TYPE_IPV6); + if (service->ipconfig_ipv6 == NULL) + return; + + connman_ipconfig_set_method(service->ipconfig_ipv6, + CONNMAN_IPCONFIG_METHOD_OFF); + + connman_ipconfig_set_data(service->ipconfig_ipv6, service); + + connman_ipconfig_set_ops(service->ipconfig_ipv6, &service_ops); +} + +void __connman_service_create_ip4config(struct connman_service *service, int index) { - struct connman_ipconfig *ipv6config; const char *ident = service->profile; GKeyFile *keyfile; - if (service->ipconfig != NULL) + DBG("ipv4 %p", service->ipconfig_ipv4); + + if (service->ipconfig_ipv4 != NULL) return; - setup_ipconfig(service, index); + setup_ip4config(service, index); if (ident == NULL) return; @@ -3760,14 +3846,36 @@ void __connman_service_create_ipconfig(struct connman_service *service, if (keyfile == NULL) return; + if (service->ipconfig_ipv4) + __connman_ipconfig_load(service->ipconfig_ipv4, keyfile, + service->identifier, "IPv4."); + g_key_file_free(keyfile); +} + +void __connman_service_create_ip6config(struct connman_service *service, + int index) +{ + const char *ident = service->profile; + GKeyFile *keyfile; + + DBG("ipv6 %p", service->ipconfig_ipv6); + + if (service->ipconfig_ipv6 != NULL) + return; + + setup_ip6config(service, index); + + if (ident == NULL) + return; + + keyfile = __connman_storage_open_profile(ident); + if (keyfile == NULL) + return; - ipv6config = connman_ipconfig_get_ipv6config(service->ipconfig); - if (ipv6config != NULL) - __connman_ipconfig_load(ipv6config, keyfile, + if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_load(service->ipconfig_ipv6, keyfile, service->identifier, "IPv6."); - __connman_ipconfig_load(service->ipconfig, keyfile, - service->identifier, "IPv4."); g_key_file_free(keyfile); } @@ -3811,7 +3919,12 @@ struct connman_service *__connman_service_lookup_from_index(int index) while (g_sequence_iter_is_end(iter) == FALSE) { service = g_sequence_get(iter); - if (connman_ipconfig_get_index(service->ipconfig) == index) + if (connman_ipconfig_get_index(service->ipconfig_ipv4) + == index) + return service; + + if (connman_ipconfig_get_index(service->ipconfig_ipv6) + == index) return service; iter = g_sequence_iter_next(iter); @@ -4014,6 +4127,7 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne struct connman_service *service; const char *ident, *group; char *name; + int index; DBG("network %p", network); @@ -4065,7 +4179,9 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne update_from_network(service, network); - setup_ipconfig(service, connman_network_get_index(network)); + index = connman_network_get_index(network); + setup_ip4config(service, index); + setup_ip6config(service, index); service_register(service); @@ -4205,16 +4321,25 @@ __connman_service_create_from_provider(struct connman_provider *provider) service->strength = 0; - service->ipconfig = connman_ipconfig_create(index); - if (service->ipconfig == NULL) + service->ipconfig_ipv4 = connman_ipconfig_create(index, + CONNMAN_IPCONFIG_TYPE_IPV4); + if (service->ipconfig_ipv4 == NULL) return service; - connman_ipconfig_set_method(service->ipconfig, + connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_MANUAL); + connman_ipconfig_set_data(service->ipconfig_ipv4, service); + connman_ipconfig_set_ops(service->ipconfig_ipv4, &service_ops); - connman_ipconfig_set_data(service->ipconfig, service); + service->ipconfig_ipv6 = connman_ipconfig_create(index, + CONNMAN_IPCONFIG_TYPE_IPV6); + if (service->ipconfig_ipv6 == NULL) + return service; - connman_ipconfig_set_ops(service->ipconfig, &service_ops); + connman_ipconfig_set_method(service->ipconfig_ipv6, + CONNMAN_IPCONFIG_METHOD_OFF); + connman_ipconfig_set_data(service->ipconfig_ipv6, service); + connman_ipconfig_set_ops(service->ipconfig_ipv6, &service_ops); service_register(service); @@ -4362,19 +4487,14 @@ static int service_load(struct connman_service *service) service->passphrase = str; } - if (service->ipconfig != NULL) { - struct connman_ipconfig *ipv6config; + if (service->ipconfig_ipv4 != NULL) + __connman_ipconfig_load(service->ipconfig_ipv4, keyfile, + service->identifier, "IPv4."); - ipv6config = connman_ipconfig_get_ipv6config( - service->ipconfig); - if (ipv6config != NULL) - __connman_ipconfig_load(ipv6config, keyfile, + if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_load(service->ipconfig_ipv6, keyfile, service->identifier, "IPv6."); - __connman_ipconfig_load(service->ipconfig, keyfile, - service->identifier, "IPv4."); - } - service->nameservers = g_key_file_get_string_list(keyfile, service->identifier, "Nameservers", &length, NULL); if (service->nameservers != NULL && length == 0) { @@ -4545,18 +4665,14 @@ update: g_key_file_remove_key(keyfile, service->identifier, "Passphrase", NULL); - if (service->ipconfig != NULL) { - struct connman_ipconfig *ipv6config; + if (service->ipconfig_ipv4 != NULL) + __connman_ipconfig_save(service->ipconfig_ipv4, keyfile, + service->identifier, "IPv4."); - ipv6config = connman_ipconfig_get_ipv6config(service->ipconfig); - if (ipv6config != NULL) - __connman_ipconfig_save(ipv6config, keyfile, + if (service->ipconfig_ipv6 != NULL) + __connman_ipconfig_save(service->ipconfig_ipv6, keyfile, service->identifier, "IPv6."); - __connman_ipconfig_save(service->ipconfig, keyfile, - service->identifier, "IPv4."); - } - if (service->nameservers != NULL) { guint len = g_strv_length(service->nameservers); -- 2.7.4