diff options
-rw-r--r-- | src/network/networkd-dhcp6.c | 95 | ||||
-rw-r--r-- | src/network/networkd-link.h | 3 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 20 |
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; |