summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/networkd-dhcp6.c95
-rw-r--r--src/network/networkd-link.h3
-rw-r--r--src/network/networkd-ndisc.c20
3 files changed, 64 insertions, 54 deletions
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index c3332bb1ac..3ec9b84a93 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -165,83 +165,82 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
link_check_ready(link);
}
-int dhcp6_configure(Link *link, bool inf_req) {
- int r, information_request;
+int dhcp6_request_address(Link *link) {
+ int r, inf_req;
+ bool running;
- assert_return(link, -EINVAL);
+ assert(link);
+ assert(link->dhcp6_client);
- link->dhcp6_configured = false;
+ r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req);
+ if (r < 0)
+ return r;
- if (link->dhcp6_client) {
- r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &information_request);
- if (r < 0) {
- log_link_warning_errno(link, r, "Could not get DHCPv6 Information request setting: %m");
- goto error;
- }
+ if (!inf_req)
+ return 0;
- if (information_request && !inf_req) {
- r = sd_dhcp6_client_stop(link->dhcp6_client);
- if (r < 0) {
- log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m");
- goto error;
- }
+ r = sd_dhcp6_client_is_running(link->dhcp6_client);
+ if (r < 0)
+ return r;
+ else
+ running = !!r;
- r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
- if (r < 0) {
- log_link_warning_errno(link, r, "Could not unset DHCPv6 Information request: %m");
- goto error;
- }
+ if (running) {
+ r = sd_dhcp6_client_stop(link->dhcp6_client);
+ if (r < 0)
+ return r;
+ }
- }
+ r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false);
+ if (r < 0)
+ return r;
+ if (running) {
r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0 && r != -EALREADY) {
- log_link_warning_errno(link, r, "Could not restart DHCPv6: %m");
- goto error;
- }
+ if (r < 0)
+ return r;
+ }
- if (r == -EALREADY)
- link->dhcp6_configured = true;
+ return 0;
+}
+int dhcp6_configure(Link *link) {
+ sd_dhcp6_client *client = NULL;
+ int r;
+
+ assert(link);
+
+ r = sd_dhcp6_client_new(&client);
+ if (r < 0)
return r;
- }
- r = sd_dhcp6_client_new(&link->dhcp6_client);
+ r = sd_dhcp6_client_attach_event(client, NULL, 0);
if (r < 0)
goto error;
- r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
+ r = sd_dhcp6_client_set_information_request(client, true);
if (r < 0)
- goto error;
+ return r;
- r = sd_dhcp6_client_set_mac(link->dhcp6_client,
+ r = sd_dhcp6_client_set_mac(client,
(const uint8_t *) &link->mac,
sizeof (link->mac), ARPHRD_ETHER);
if (r < 0)
goto error;
- r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
+ r = sd_dhcp6_client_set_index(client, link->ifindex);
if (r < 0)
goto error;
- r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
- link);
+ r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link);
if (r < 0)
goto error;
- if (inf_req) {
- r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true);
- if (r < 0)
- goto error;
- }
-
- r = sd_dhcp6_client_start(link->dhcp6_client);
- if (r < 0)
- goto error;
+ link->dhcp6_client = client;
- return r;
+ return 0;
- error:
- link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+error:
+ sd_dhcp6_client_unref(client);
return r;
}
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index a22041870e..d915e7c9c0 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -147,7 +147,8 @@ int link_set_timezone(Link *link, const char *timezone);
int ipv4ll_configure(Link *link);
int dhcp4_configure(Link *link);
-int dhcp6_configure(Link *link, bool information_request);
+int dhcp6_configure(Link *link);
+int dhcp6_request_address(Link *link);
int ndisc_configure(Link *link);
bool link_lldp_enabled(Link *link);
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index dfbc5a866e..bd5a5d675c 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -29,6 +29,7 @@
static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_addr *gateway, unsigned lifetime, int pref, void *userdata) {
Link *link = userdata;
+ int r;
assert(link);
assert(link->network);
@@ -36,14 +37,19 @@ static void ndisc_router_handler(sd_ndisc *nd, uint8_t flags, const struct in6_a
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return;
- if (flags & ND_RA_FLAG_MANAGED)
- dhcp6_configure(link, false);
- else if (flags & ND_RA_FLAG_OTHER)
- dhcp6_configure(link, true);
+ if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)) {
+ if (flags & ND_RA_FLAG_MANAGED)
+ dhcp6_request_address(link);
+
+ r = sd_dhcp6_client_start(link->dhcp6_client);
+ if (r < 0 && r != -EBUSY)
+ log_link_warning_errno(link, r, "Starting DHCPv6 client on NDisc request failed: %m");
+ }
}
static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
Link *link = userdata;
+ int r;
assert(link);
@@ -52,7 +58,11 @@ static void ndisc_handler(sd_ndisc *nd, int event, void *userdata) {
switch (event) {
case SD_NDISC_EVENT_TIMEOUT:
- dhcp6_configure(link, false);
+ dhcp6_request_address(link);
+
+ 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");
break;
case SD_NDISC_EVENT_STOP:
break;