---
 src/connman.h  |    4 ++-
 src/ipconfig.c |   16 +++++++++++++-
 src/ipv4.c     |    5 ++++
 src/service.c  |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index a8ef170..3d416ca 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -251,7 +251,8 @@ void __connman_ipconfig_append_ipv6(struct connman_ipconfig 
*ipconfig,
 void __connman_ipconfig_append_ipv6config(struct connman_ipconfig *ipconfig,
                                                        DBusMessageIter *iter);
 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
-                                                       DBusMessageIter *array);
+                                       DBusMessageIter *array,
+                                       connman_bool_t *six2four);
 void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
                                                        DBusMessageIter *iter);
 enum connman_ipconfig_method __connman_ipconfig_get_method(
@@ -481,6 +482,7 @@ struct connman_ipconfig *__connman_service_get_ip4config(
                                struct connman_service *service);
 struct connman_ipconfig *__connman_service_get_ip6config(
                                struct connman_service *service);
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service);
 const char *__connman_service_get_ident(struct connman_service *service);
 const char *__connman_service_get_path(struct connman_service *service);
 unsigned int __connman_service_get_order(struct connman_service *service);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 58ee4d0..9e7f170 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1713,7 +1713,8 @@ void __connman_ipconfig_append_ipv4config(struct 
connman_ipconfig *ipconfig,
 }
 
 int __connman_ipconfig_set_config(struct connman_ipconfig *ipconfig,
-                                                       DBusMessageIter *array)
+                               DBusMessageIter *array,
+                               connman_bool_t *six2four)
 {
        enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
        const char *address = NULL, *netmask = NULL, *gateway = NULL,
@@ -1777,6 +1778,19 @@ int __connman_ipconfig_set_config(struct 
connman_ipconfig *ipconfig,
                                return -EINVAL;
 
                        dbus_message_iter_get_basic(&entry, &gateway);
+               } else if (g_str_equal(key, "6to4") == TRUE) {
+                       const char *str;
+                       if (type != DBUS_TYPE_STRING)
+                               return -EINVAL;
+
+                       dbus_message_iter_get_basic(&entry, &str);
+                       if (six2four != NULL) {
+                               if (g_ascii_strcasecmp(str, "true") == 0 ||
+                                               g_strcmp0(str, "1") == 0)
+                                       *six2four = TRUE;
+                               else
+                                       *six2four = FALSE;
+                       }
                }
                dbus_message_iter_next(&dict);
        }
diff --git a/src/ipv4.c b/src/ipv4.c
index e77b8ee..1ab0338 100644
--- a/src/ipv4.c
+++ b/src/ipv4.c
@@ -103,6 +103,9 @@ static int ipv4_probe(struct connman_element *element)
        if (err < 0)
                return err;
 
+       if (__connman_service_6to4_enabled(service) == TRUE)
+               __connman_6to4_probe(address);
+
        return 0;
 }
 
@@ -152,6 +155,8 @@ static void ipv4_remove(struct connman_element *element)
                        AF_INET, address, peer, prefixlen, broadcast) < 0))
                DBG("address removal failed");
 
+       __connman_6to4_remove();
+
        connman_element_unref(element);
 }
 
diff --git a/src/service.c b/src/service.c
index 1696e5a..68082c5 100644
--- a/src/service.c
+++ b/src/service.c
@@ -103,6 +103,7 @@ struct connman_service {
        char **excludes;
        char *pac;
        connman_bool_t wps;
+       connman_bool_t enabled_6to4;
 };
 
 static void append_path(gpointer value, gpointer user_data)
@@ -975,6 +976,9 @@ static void append_ipv4(DBusMessageIter *iter, void 
*user_data)
 
        if (service->ipconfig_ipv4 != NULL)
                __connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter);
+
+       connman_dbus_dict_append_basic(iter, "6to4",
+                               DBUS_TYPE_BOOLEAN, &service->enabled_6to4);
 }
 
 static void append_ipv6(DBusMessageIter *iter, void *user_data)
@@ -998,6 +1002,8 @@ static void append_ipv4config(DBusMessageIter *iter, void 
*user_data)
        if (service->ipconfig_ipv4 != NULL)
                __connman_ipconfig_append_ipv4config(service->ipconfig_ipv4,
                                                        iter);
+       connman_dbus_dict_append_basic(iter, "6to4",
+                               DBUS_TYPE_BOOLEAN, &service->enabled_6to4);
 }
 
 static void append_ipv6config(DBusMessageIter *iter, void *user_data)
@@ -1851,6 +1857,21 @@ void __connman_service_set_passphrase(struct 
connman_service *service,
        __connman_storage_save_service(service);
 }
 
+connman_bool_t __connman_service_6to4_enabled(struct connman_service *service)
+{
+       enum connman_ipconfig_method method;
+
+       if (service == NULL)
+               return FALSE;
+
+       method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
+       if (method == CONNMAN_IPCONFIG_METHOD_UNKNOWN ||
+                               method == CONNMAN_IPCONFIG_METHOD_OFF)
+               return FALSE;
+
+       return service->enabled_6to4;
+}
+
 static DBusMessage *get_properties(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
 {
@@ -2050,7 +2071,8 @@ static int set_ipconfig(struct connman_service *service,
                        struct connman_ipconfig *ipconfig,
                        DBusMessageIter *array,
                        enum connman_service_state state,
-                       enum connman_service_state *new_state)
+                       enum connman_service_state *new_state,
+                       connman_bool_t *six2four)
 {
        enum connman_ipconfig_method old_method;
        enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
@@ -2063,7 +2085,7 @@ static int set_ipconfig(struct connman_service *service,
                                        is_connected_state(service, state))
                __connman_network_clear_ipconfig(service->network, ipconfig);
 
-       err = __connman_ipconfig_set_config(ipconfig, array);
+       err = __connman_ipconfig_set_config(ipconfig, array, six2four);
        method = __connman_ipconfig_get_method(ipconfig);
        type = __connman_ipconfig_get_config_type(ipconfig);
 
@@ -2253,14 +2275,31 @@ static DBusMessage *set_property(DBusConnection *conn,
                        return __connman_error_invalid_property(msg);
 
                if (g_str_equal(name, "IPv4.Configuration") == TRUE) {
+                       connman_bool_t six2four;
                        ipv4 = service->ipconfig_ipv4;
                        err = set_ipconfig(service, ipv4, &value,
-                                       service->state_ipv4, &state);
+                                       service->state_ipv4, &state,
+                                       &six2four);
+                       if (err == 0 && service->enabled_6to4 != six2four) {
+                               struct connman_ipaddress *addr;
+                               addr = __connman_ipconfig_get_system_address(
+                                               service->ipconfig_ipv4);
+                               service->enabled_6to4 = six2four;
+                               if (service->enabled_6to4 == TRUE) {
+                                       if (__connman_service_6to4_enabled(
+                                                       service) == TRUE &&
+                                                       addr != NULL) {
+                                               __connman_6to4_probe(
+                                                       addr->local);
+                                       }
+                               } else
+                                       __connman_6to4_remove();
+                       }
 
                } else if (g_str_equal(name, "IPv6.Configuration") == TRUE) {
                        ipv6 = service->ipconfig_ipv6;
                        err = set_ipconfig(service, ipv6, &value,
-                                       service->state_ipv6, &state);
+                                       service->state_ipv6, &state, NULL);
                }
 
                if (err < 0) {
@@ -4763,6 +4802,9 @@ static int service_load(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_UNKNOWN:
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_ETHERNET:
+               service->enabled_6to4 = g_key_file_get_boolean(keyfile,
+                                                       service->identifier,
+                                                       "IPv4.6to4", NULL);
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
        case CONNMAN_SERVICE_TYPE_GADGET:
@@ -4837,6 +4879,11 @@ static int service_load(struct connman_service *service)
                                        CONNMAN_SERVICE_STATE_FAILURE;
                        service->error = string2error(str);
                }
+
+               service->enabled_6to4 = g_key_file_get_boolean(keyfile,
+                                                       service->identifier,
+                                                       "IPv4.6to4", NULL);
+
                break;
        }
 
@@ -4951,6 +4998,8 @@ update:
        case CONNMAN_SERVICE_TYPE_UNKNOWN:
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_ETHERNET:
+               g_key_file_set_boolean(keyfile, service->identifier,
+                                       "IPv4.6to4", service->enabled_6to4);
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
        case CONNMAN_SERVICE_TYPE_GADGET:
@@ -5007,6 +5056,10 @@ update:
                        g_key_file_remove_key(keyfile, service->identifier,
                                                        "Failure", NULL);
                }
+
+               g_key_file_set_boolean(keyfile, service->identifier,
+                                       "IPv4.6to4", service->enabled_6to4);
+
                break;
        }
 
-- 
1.7.0.4

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to