Merge pull request #1356 from pfl/dhcp6_suspend

DHCPv6 suspend fixes
This commit is contained in:
Tom Gundersen 2015-09-24 00:55:49 +02:00
commit 5fecc33e32
5 changed files with 70 additions and 47 deletions

View file

@ -125,6 +125,8 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
assert_return(client, -EINVAL);
assert_return(interface_index >= -1, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
client->index = interface_index;
return 0;
@ -140,6 +142,8 @@ int sd_dhcp6_client_set_mac(
assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
assert_return(arp_type > 0, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
if (arp_type == ARPHRD_ETHER)
assert_return(addr_len == ETH_ALEN, -EINVAL);
else if (arp_type == ARPHRD_INFINIBAND)
@ -173,6 +177,8 @@ int sd_dhcp6_client_set_duid(
assert_return(duid, -EINVAL);
assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
switch (type) {
case DHCP6_DUID_LLT:
if (duid_len <= sizeof(client->duid.llt))
@ -205,6 +211,8 @@ int sd_dhcp6_client_set_duid(
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, bool enabled) {
assert_return(client, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
client->information_request = enabled;
return 0;
@ -1126,6 +1134,9 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
assert_return(client->event, -EINVAL);
assert_return(client->index > 0, -EINVAL);
if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
return -EALREADY;
r = client_reset(client);
if (r < 0)
return r;

View file

@ -581,7 +581,11 @@ static void test_client_information_cb(sd_dhcp6_client *client, int event,
if (verbose)
printf(" got DHCPv6 event %d\n", event);
assert_se(sd_dhcp6_client_set_information_request(client, false) == -EBUSY);
assert_se(sd_dhcp6_client_set_callback(client, NULL, e) >= 0);
assert_se(sd_dhcp6_client_stop(client) >= 0);
assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
assert_se(sd_dhcp6_client_set_callback(client,
test_client_solicit_cb, e) >= 0);

View file

@ -147,7 +147,9 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
case SD_DHCP6_CLIENT_EVENT_STOP:
case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE:
case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX:
log_link_debug(link, "DHCPv6 event %d", event);
log_link_warning(link, "DHCPv6 lease lost");
link->dhcp6_configured = false;
break;
case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
@ -165,6 +167,7 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
return;
}
link->dhcp6_configured = true;
break;
default:
@ -176,6 +179,8 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
event);
return;
}
link_client_handler(link);
}
static int dhcp6_configure(Link *link, int event) {
@ -183,92 +188,91 @@ static int dhcp6_configure(Link *link, int event) {
bool information_request;
assert_return(link, -EINVAL);
assert_return(IN_SET(event, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT,
SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER,
SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED), -EINVAL);
link->dhcp6_configured = false;
if (link->dhcp6_client) {
if (event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED)
return 0;
r = sd_dhcp6_client_get_information_request(link->dhcp6_client,
&information_request);
if (r < 0) {
log_link_warning(link, "Could not get DHCPv6 Information request setting: %s",
strerror(-r));
link->dhcp6_client =
sd_dhcp6_client_unref(link->dhcp6_client);
return r;
strerror(-r));
goto error;
}
if (!information_request)
return r;
if (information_request && event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) {
r = sd_dhcp6_client_stop(link->dhcp6_client);
if (r < 0) {
log_link_warning(link, "Could not stop DHCPv6 while setting Managed mode %s",
strerror(-r));
goto error;
}
r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
false);
if (r < 0) {
log_link_warning(link, "Could not unset DHCPv6 Information request: %s",
strerror(-r));
goto error;
}
r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
false);
if (r < 0) {
log_link_warning(link, "Could not unset DHCPv6 Information request: %s",
strerror(-r));
link->dhcp6_client =
sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0) {
log_link_warning(link, "Could not restart DHCPv6 after enabling Information request: %s",
strerror(-r));
link->dhcp6_client =
sd_dhcp6_client_unref(link->dhcp6_client);
return r;
if (r < 0 && r != -EALREADY) {
log_link_warning(link, "Could not restart DHCPv6: %s",
strerror(-r));
goto error;
}
if (r == -EALREADY)
link->dhcp6_configured = true;
return r;
}
r = sd_dhcp6_client_new(&link->dhcp6_client);
if (r < 0)
return r;
goto error;
r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
if (r < 0) {
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
if (r < 0)
goto error;
r = sd_dhcp6_client_set_mac(link->dhcp6_client,
(const uint8_t *) &link->mac,
sizeof (link->mac), ARPHRD_ETHER);
if (r < 0) {
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
if (r < 0)
goto error;
r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
if (r < 0) {
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
if (r < 0)
goto error;
r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
link);
if (r < 0) {
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
if (r < 0)
goto error;
if (event == SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) {
r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
true);
if (r < 0) {
link->dhcp6_client =
sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
if (r < 0)
goto error;
}
r = sd_dhcp6_client_start(link->dhcp6_client);
if (r < 0)
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
goto error;
return r;
error:
link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
return r;
}
static int dhcp6_prefix_expired(Link *link) {

View file

@ -504,6 +504,9 @@ void link_client_handler(Link *link) {
if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
return;
if (link_dhcp6_enabled(link) && !link->dhcp6_configured)
return;
if (link->state != LINK_STATE_CONFIGURED)
link_enter_configured(link);

View file

@ -91,6 +91,7 @@ struct Link {
uint16_t original_mtu;
unsigned dhcp4_messages;
bool dhcp4_configured;
bool dhcp6_configured;
sd_ipv4ll *ipv4ll;
bool ipv4ll_address;