diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-01-05 13:38:09 +0200 |
---|---|---|
committer | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-01-05 13:17:26 +0100 |
commit | 195007a210055b96f42f29348cbce02915dea242 (patch) | |
tree | de2dc353c33f9f8999d0df16a87fe15da379ad1b /src/network.c | |
parent | 60bc9d2cdd88171bf10a545b46f49b5e7c6415ab (diff) | |
download | connman-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.c | 65 |
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; |