summaryrefslogtreecommitdiff
path: root/src/network.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-01-05 13:38:09 +0200
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-05 13:17:26 +0100
commit195007a210055b96f42f29348cbce02915dea242 (patch)
treede2dc353c33f9f8999d0df16a87fe15da379ad1b /src/network.c
parent60bc9d2cdd88171bf10a545b46f49b5e7c6415ab (diff)
downloadconnman-195007a210055b96f42f29348cbce02915dea242.tar.gz
connman-195007a210055b96f42f29348cbce02915dea242.tar.bz2
connman-195007a210055b96f42f29348cbce02915dea242.zip
dhcpv6: Initial stateful DHCPv6 support.
This patch contains solicitation message support.
Diffstat (limited to 'src/network.c')
-rw-r--r--src/network.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/src/network.c b/src/network.c
index e2266d01..f9aed498 100644
--- a/src/network.c
+++ b/src/network.c
@@ -982,10 +982,60 @@ static void dhcpv6_info_callback(struct connman_network *network,
stop_dhcpv6(network);
}
+static gboolean dhcpv6_set_addresses(struct connman_network *network)
+{
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv6;
+ int err = -EINVAL;
+
+ service = __connman_service_lookup_from_network(network);
+ if (service == NULL)
+ goto err;
+
+ connman_network_set_associating(network, FALSE);
+
+ network->connecting = FALSE;
+
+ ipconfig_ipv6 = __connman_service_get_ip6config(service);
+ err = __connman_ipconfig_address_add(ipconfig_ipv6);
+ if (err < 0)
+ goto err;
+
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
+ if (err < 0)
+ goto err;
+
+ return 0;
+
+err:
+ connman_network_set_error(network,
+ CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
+ return err;
+}
+
+static void dhcpv6_callback(struct connman_network *network,
+ connman_bool_t success)
+{
+ DBG("success %d", success);
+
+ /* Start the renew process if necessary */
+ if (success == TRUE) {
+
+ if (dhcpv6_set_addresses(network) < 0) {
+ stop_dhcpv6(network);
+ return;
+ }
+
+ return;
+ } else
+ stop_dhcpv6(network);
+}
+
static void check_dhcpv6(struct nd_router_advert *reply,
unsigned int length, void *user_data)
{
struct connman_network *network = user_data;
+ GSList *prefixes;
DBG("reply %p", reply);
@@ -1008,8 +1058,14 @@ static void check_dhcpv6(struct nd_router_advert *reply,
network->router_solicit_count = 0;
- /* We do stateless DHCPv6 only if router advertisement says so */
- if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
+ prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
+
+ /*
+ * We do stateful/stateless DHCPv6 if router advertisement says so.
+ */
+ if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
+ __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
+ else if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
__connman_dhcpv6_start_info(network, dhcpv6_info_callback);
connman_network_unref(network);
@@ -1074,6 +1130,7 @@ static gboolean set_connected(gpointer user_data)
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_AUTO:
autoconf_ipv6_set(network);
break;
@@ -1086,8 +1143,6 @@ static gboolean set_connected(gpointer user_data)
return FALSE;
}
break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- break;
}
switch (ipv4_method) {
@@ -1129,8 +1184,8 @@ static gboolean set_connected(gpointer user_data)
case CONNMAN_IPCONFIG_METHOD_OFF:
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
- case CONNMAN_IPCONFIG_METHOD_DHCP:
break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_AUTO:
stop_dhcpv6(network);
break;