ipconfig: Default method is auto for IPv6
[platform/upstream/connman.git] / src / ipconfig.c
index a2a7bf2..7a14c42 100644 (file)
@@ -76,12 +76,6 @@ struct connman_ipdevice {
 
        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_ipv6;
-       struct connman_ipconfig *driver_config_ipv6;
 };
 
 static GHashTable *ipdevice_hash = NULL;
@@ -324,132 +318,10 @@ static void free_ipdevice(gpointer data)
        g_free(ipdevice);
 }
 
-static GSList *driver_list = NULL;
-
-static gint compare_priority(gconstpointer a, gconstpointer b)
-{
-       const struct connman_ipconfig_driver *driver1 = a;
-       const struct connman_ipconfig_driver *driver2 = b;
-
-       return driver2->priority - driver1->priority;
-}
-
-/**
- * connman_ipconfig_driver_register:
- * @driver: IP configuration driver
- *
- * Register a new IP configuration driver
- *
- * Returns: %0 on success
- */
-int connman_ipconfig_driver_register(struct connman_ipconfig_driver *driver)
-{
-       DBG("driver %p name %s", driver, driver->name);
-
-       driver_list = g_slist_insert_sorted(driver_list, driver,
-                                                       compare_priority);
-
-       return 0;
-}
-
-/**
- * connman_ipconfig_driver_unregister:
- * @driver: IP configuration driver
- *
- * Remove a previously registered IP configuration driver.
- */
-void connman_ipconfig_driver_unregister(struct connman_ipconfig_driver *driver)
-{
-       DBG("driver %p name %s", driver, driver->name);
-
-       driver_list = g_slist_remove(driver_list, 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 ipv4 %p ipv6 %p", ipdevice->config_ipv4,
                                        ipdevice->config_ipv6);
-
-       if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
-               return;
-
-       if (ipdevice->driver_ipv4 != NULL && ipdevice->driver_ipv6 != NULL)
-               return;
-
-       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->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;
-               }
-       }
-
-       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 (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_ipv6 == NULL) {
-               connman_ipconfig_unref(ipdevice->driver_config_ipv6);
-               ipdevice->driver_config_ipv6 = NULL;
-       }
 }
 
 static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
@@ -457,32 +329,6 @@ static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
        DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
                                        ipdevice->config_ipv6);
 
-       if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
-               return;
-
-       if (ipdevice->driver_ipv4 == NULL && ipdevice->driver_ipv6 == NULL)
-               return;
-
-       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;
-       }
-
-       if (ipdevice->driver_config_ipv6) {
-               connman_ipconfig_unref(ipdevice->driver_config_ipv6);
-               ipdevice->driver_config_ipv6 = NULL;
-       }
-
        if (ipdevice->config_ipv4)
                connman_inet_clear_address(ipdevice->index,
                                        ipdevice->config_ipv4->address);
@@ -1002,9 +848,11 @@ static struct connman_ipconfig *create_ipv6config(int index)
        if (ipv6config == NULL)
                return NULL;
 
+       ipv6config->refcount = 1;
+
        ipv6config->index = index;
        ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
-       ipv6config->method = CONNMAN_IPCONFIG_METHOD_OFF;
+       ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
 
        ipv6config->address = connman_ipaddress_alloc(AF_INET6);
        if (ipv6config->address == NULL) {
@@ -1058,31 +906,6 @@ struct connman_ipconfig *connman_ipconfig_create(int index,
        return ipconfig;
 }
 
-/**
- * connman_ipconfig_clone:
- *
- * Clone an ipconfig structure and create new reference.
- *
- * Returns: a newly-allocated #connman_ipconfig structure
- */
-struct connman_ipconfig *connman_ipconfig_clone(struct connman_ipconfig *ipconfig)
-{
-       struct connman_ipconfig *ipconfig_clone;
-
-       DBG("ipconfig %p", ipconfig);
-
-       ipconfig_clone = g_try_new0(struct connman_ipconfig, 1);
-       if (ipconfig_clone == NULL)
-               return NULL;
-
-       ipconfig_clone->refcount = 1;
-
-       ipconfig_clone->origin = connman_ipconfig_ref(ipconfig);
-
-       ipconfig_clone->index = -1;
-
-       return ipconfig_clone;
-}
 
 /**
  * connman_ipconfig_ref:
@@ -1092,6 +915,9 @@ struct connman_ipconfig *connman_ipconfig_clone(struct connman_ipconfig *ipconfi
  */
 struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
 {
+       DBG("ipconfig %p refcount %d", ipconfig,
+                               g_atomic_int_get(&ipconfig->refcount) + 1);
+
        g_atomic_int_inc(&ipconfig->refcount);
 
        return ipconfig;
@@ -1105,8 +931,13 @@ struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
  */
 void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
 {
-       if (ipconfig &&
-               g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
+       if (ipconfig == NULL)
+               return;
+
+       DBG("ipconfig %p refcount %d", ipconfig,
+                       g_atomic_int_get(&ipconfig->refcount) - 1);
+
+       if (g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
                __connman_ipconfig_disable(ipconfig);
 
                connman_ipconfig_set_ops(ipconfig, NULL);
@@ -1130,6 +961,9 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
  */
 void *connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
 {
+       if (ipconfig == NULL)
+               return NULL;
+
        return ipconfig->ops_data;
 }
 
@@ -1199,15 +1033,6 @@ void connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
        ipconfig->ops = ops;
 }
 
-struct connman_ipconfig *connman_ipconfig_get_ipv6config(
-                               struct connman_ipconfig *ipconfig)
-{
-       if (ipconfig == NULL)
-               return NULL;
-
-       return ipconfig;
-}
-
 /**
  * connman_ipconfig_set_method:
  * @ipconfig: ipconfig structure
@@ -1254,7 +1079,8 @@ void __connman_ipconfig_set_element_ipv6_gateway(
                        struct connman_ipconfig *ipconfig,
                                struct connman_element *element)
 {
-       element->ipv6.gateway = ipconfig->address->gateway;
+       if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV6)
+               element->ipv6.gateway = ipconfig->address->gateway;
 }
 
 /*
@@ -1293,6 +1119,7 @@ int __connman_ipconfig_set_address(struct connman_ipconfig *ipconfig)
        case CONNMAN_IPCONFIG_METHOD_OFF:
        case CONNMAN_IPCONFIG_METHOD_FIXED:
        case CONNMAN_IPCONFIG_METHOD_DHCP:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
                break;
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
                if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
@@ -1320,6 +1147,7 @@ int __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
        case CONNMAN_IPCONFIG_METHOD_OFF:
        case CONNMAN_IPCONFIG_METHOD_FIXED:
        case CONNMAN_IPCONFIG_METHOD_DHCP:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
                break;
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
                if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
@@ -1403,7 +1231,8 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
                                        ipdevice->config_ipv4 != NULL) {
-               ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+               ipconfig_list = g_list_remove(ipconfig_list,
+                                                       ipdevice->config_ipv4);
 
                connman_ipaddress_clear(ipdevice->config_ipv4->system);
 
@@ -1412,7 +1241,8 @@ int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig)
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
                                        ipdevice->config_ipv6 != NULL) {
-               ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
+               ipconfig_list = g_list_remove(ipconfig_list,
+                                                       ipdevice->config_ipv6);
 
                connman_ipaddress_clear(ipdevice->config_ipv6->system);
 
@@ -1501,6 +1331,8 @@ const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method
                return "manual";
        case CONNMAN_IPCONFIG_METHOD_DHCP:
                return "dhcp";
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
+               return "auto";
        }
 
        return NULL;
@@ -1516,6 +1348,8 @@ enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method
                return CONNMAN_IPCONFIG_METHOD_MANUAL;
        else if (g_strcmp0(method, "dhcp") == 0)
                return CONNMAN_IPCONFIG_METHOD_DHCP;
+       else if (g_strcmp0(method, "auto") == 0)
+               return CONNMAN_IPCONFIG_METHOD_AUTO;
        else
                return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
 }
@@ -1527,6 +1361,9 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
 
        DBG("");
 
+       if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV4)
+               return;
+
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (str == NULL)
                return;
@@ -1563,6 +1400,9 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
 
        DBG("");
 
+       if (ipconfig->type != CONNMAN_IPCONFIG_TYPE_IPV6)
+               return;
+
        str = __connman_ipconfig_method2string(ipconfig->method);
        if (str == NULL)
                return;
@@ -1605,6 +1445,7 @@ void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
                return;
        case CONNMAN_IPCONFIG_METHOD_FIXED:
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
                break;
        }
 
@@ -1642,6 +1483,7 @@ void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
        case CONNMAN_IPCONFIG_METHOD_OFF:
        case CONNMAN_IPCONFIG_METHOD_FIXED:
        case CONNMAN_IPCONFIG_METHOD_DHCP:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
                return;
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
                break;
@@ -1750,6 +1592,7 @@ int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
        case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
        case CONNMAN_IPCONFIG_METHOD_OFF:
        case CONNMAN_IPCONFIG_METHOD_FIXED:
+       case CONNMAN_IPCONFIG_METHOD_AUTO:
                return -EINVAL;
 
        case CONNMAN_IPCONFIG_METHOD_MANUAL:
@@ -1808,7 +1651,7 @@ void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
 int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
                GKeyFile *keyfile, const char *identifier, const char *prefix)
 {
-       const char *method;
+       char *method;
        char *key;
 
        DBG("ipconfig %p identifier %s", ipconfig, identifier);
@@ -1822,6 +1665,11 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig,
                        ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
        } else
                ipconfig->method = __connman_ipconfig_string2method(method);
+
+       if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
+               ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
+
+       g_free(method);
        g_free(key);
 
        key = g_strdup_printf("%snetmask_prefixlen", prefix);