1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-08-22 01:50:10 +03:00

networkd: dhcp6 - split up configure() method

Enabling address acquisition, configuring the client and starting the client are now
split out. This to better handle the client being repeatedly enabled due to router
advertisements.
This commit is contained in:
Tom Gundersen
2015-11-10 15:43:52 +01:00
parent 9d96e6c3ef
commit 7a695d8e1f
3 changed files with 71 additions and 61 deletions

View File

@ -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);
link->dhcp6_configured = false;
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 (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_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;
}
}
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 == -EALREADY)
link->dhcp6_configured = true;
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;
r = sd_dhcp6_client_is_running(link->dhcp6_client);
if (r < 0)
return r;
else
running = !!r;
if (running) {
r = sd_dhcp6_client_stop(link->dhcp6_client);
if (r < 0)
return r;
}
r = sd_dhcp6_client_new(&link->dhcp6_client);
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)
return r;
}
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_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;
}
link->dhcp6_client = client;
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0)
goto error;
return 0;
return r;
error:
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
error:
sd_dhcp6_client_unref(client);
return r;
}

View File

@ -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);

View File

@ -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;