diff options
author | Patrik Flykt <patrik.flykt@linux.intel.com> | 2014-12-10 16:17:35 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-12-10 18:31:21 +0100 |
commit | 85bd849f09aceb7f972a0697494ea22b2247a5d7 (patch) | |
tree | 4be6e0c54309245882c3a95ee47c87d1fa3adc1e /src | |
parent | 5c79bd79839f1e50bd3c34a0670037f7965ca5a4 (diff) |
networkd-dhcp6: Support ICMPv6 Other information
When ICMPv6 Other information is received, enable Information request
in DHCPv6. If the DHCPv6 client already exists, only update the client
if there is a transition from Other to Managed state.
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-dhcp6.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index bf8d78b6d0..c31bd4ec30 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -43,6 +43,7 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { case DHCP6_EVENT_RESEND_EXPIRE: case DHCP6_EVENT_RETRANS_MAX: case DHCP6_EVENT_IP_ACQUIRE: + case DHCP6_EVENT_INFORMATION_REQUEST: log_link_debug(link, "DHCPv6 event %d", event); break; @@ -58,13 +59,47 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { } } -static int dhcp6_configure(Link *link) { +static int dhcp6_configure(Link *link, int event) { int r; + bool information_request; assert_return(link, -EINVAL); - if (link->dhcp6_client) - return 0; + if (link->dhcp6_client) { + if (event != ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED) + return 0; + + r = sd_dhcp6_client_get_information_request(link->dhcp6_client, + &information_request); + if (r < 0) { + log_link_warning(link, "Could not get DHCPv6 Information request setting"); + link->dhcp6_client = + sd_dhcp6_client_unref(link->dhcp6_client); + return r; + } + + if (!information_request) + return r; + + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, + false); + if (r < 0) { + log_link_warning(link, "Could not unset DHCPv6 Information request"); + link->dhcp6_client = + sd_dhcp6_client_unref(link->dhcp6_client); + return r; + } + + r = sd_dhcp6_client_start(link->dhcp6_client); + if (r < 0) { + log_link_warning(link, "Could not restart DHCPv6 after enabling Information request"); + link->dhcp6_client = + sd_dhcp6_client_unref(link->dhcp6_client); + return r; + } + + return r; + } r = sd_dhcp6_client_new(&link->dhcp6_client); if (r < 0) @@ -97,6 +132,16 @@ static int dhcp6_configure(Link *link) { return r; } + if (event == ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER) { + r = sd_dhcp6_client_set_information_request(link->dhcp6_client, + true); + if (r < 0) { + link->dhcp6_client = + sd_dhcp6_client_unref(link->dhcp6_client); + return r; + } + } + r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); @@ -116,10 +161,10 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) { switch(event) { case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE: - case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER: return; case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT: + case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER: case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED: break; @@ -134,7 +179,7 @@ static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) { return; } - dhcp6_configure(link); + dhcp6_configure(link, event); } int icmp6_configure(Link *link) { |