summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/networkd-dhcp6.c31
-rw-r--r--src/network/networkd-link.c11
-rw-r--r--src/network/networkd-link.h2
-rw-r--r--src/network/networkd-ndisc.c26
4 files changed, 30 insertions, 40 deletions
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index a44c9ea71d..50721b1c74 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -164,19 +164,13 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
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)
@@ -185,12 +179,27 @@ int dhcp6_request_address(Link *link) {
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;
@@ -215,10 +224,6 @@ int dhcp6_configure(Link *link) {
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);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 9ac0b47d77..ba4147f875 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1444,15 +1444,12 @@ static int link_acquire_ipv6_conf(Link *link) {
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)) {
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 14c4a02c7e..5efefd27d6 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -160,7 +160,7 @@ int link_set_timezone(Link *link, const char *timezone);
int ipv4ll_configure(Link *link);
int dhcp4_configure(Link *link);
int dhcp6_configure(Link *link);
-int dhcp6_request_address(Link *link);
+int dhcp6_request_address(Link *link, int ir);
int ndisc_configure(Link *link);
const char* link_state_to_string(LinkState s) _const_;
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 3baca2e63c..7359cc2b67 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -149,21 +149,19 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
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)
@@ -205,16 +203,6 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
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);
- if (r < 0 && r != -EBUSY)
- log_link_warning_errno(link, r, "Starting DHCPv6 client after NDisc timeout failed: %m");
-
link->ndisc_configured = true;
link_check_ready(link);