link_check_ready(link);
}
-int dhcp6_request_address(Link *link) {
+int dhcp6_request_address(Link *link, int ir) {
int r, inf_req;
bool running;
assert(link);
assert(link->dhcp6_client);
-
- r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
- if (r < 0)
- return r;
-
- if (!inf_req)
- return 0;
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
r = sd_dhcp6_client_is_running(link->dhcp6_client);
if (r < 0)
running = !!r;
if (running) {
+ r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
+ if (r < 0)
+ return r;
+
+ if (inf_req == ir)
+ return 0;
+
r = sd_dhcp6_client_stop(link->dhcp6_client);
if (r < 0)
return r;
+ } else {
+ r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
+ if (r < 0)
+ return r;
}
- r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
+ r = sd_dhcp6_client_set_information_request(link->dhcp6_client, ir);
+ if (r < 0)
+ return r;
+
+ r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0)
return r;
if (r < 0)
goto error;
- r = sd_dhcp6_client_set_information_request(client, true);
- if (r < 0)
- goto error;
-
r = sd_dhcp6_client_set_mac(client,
(const uint8_t *) &link->mac,
sizeof (link->mac), ARPHRD_ETHER);
assert(link->dhcp6_client);
assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
- log_link_debug(link, "Acquiring DHCPv6 lease");
-
- r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
- if (r < 0 && r != -EBUSY)
- return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
- r = sd_dhcp6_client_start(link->dhcp6_client);
+ /* start DHCPv6 client in stateless mode */
+ r = dhcp6_request_address(link, true);
if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
+ else
+ log_link_debug(link, "Acquiring DHCPv6 lease");
}
if (link_ipv6_accept_ra_enabled(link)) {
assert(link);
assert(link->network);
assert(link->manager);
+ assert(link->dhcp6_client);
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) {
- if (flags & ND_RA_FLAG_MANAGED)
- dhcp6_request_address(link);
-
- r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
- if (r < 0 && r != -EBUSY)
- log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
- r = sd_dhcp6_client_start(link->dhcp6_client);
+ /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
+ r = dhcp6_request_address(link, flags & ND_RA_FLAG_MANAGED ? false : true);
if (r < 0 && r != -EBUSY)
- log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
+ log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
+ else
+ log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
}
if (!gateway)
int r;
assert(link);
+ assert(link->dhcp6_client);
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
switch (event) {
case SD_NDISC_EVENT_TIMEOUT:
- dhcp6_request_address(link);
-
- r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
- if (r < 0 && r != -EBUSY)
- log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
-
- r = sd_dhcp6_client_start(link->dhcp6_client);
+ /* (re)start DHCPv6 client in stateful mode */
+ r = dhcp6_request_address(link, false);
if (r < 0 && r != -EBUSY)
- log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
+ log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease after NDisc timeout: %m");
+ else
+ log_link_debug(link, "Acquiring DHCPv6 lease after NDisc timeout");
link->ndisc_configured = true;
link_check_ready(link);