network,dhcp: restart client with 'networkctl renew' when delayed by IPv6 only mode
This is convenient when the server supports IPv6 only mode. Otherwise, we cannot request a new address during the client is waiting an IPv6 connectivity. Note, the minimal timespan is 5min, and a server may send a quite large value.
This commit is contained in:
@@ -2351,6 +2351,18 @@ int sd_dhcp_client_set_ipv6_connectivity(sd_dhcp_client *client, int have) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_client_interrupt_ipv6_only_mode(sd_dhcp_client *client) {
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(sd_dhcp_client_is_running(client), -ESTALE);
|
||||
assert_return(client->fd >= 0, -EINVAL);
|
||||
|
||||
if (sd_event_source_get_enabled(client->timeout_ipv6_only_mode, NULL) <= 0)
|
||||
return 0;
|
||||
|
||||
client_initialize(client);
|
||||
return client_start(client);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
|
||||
int r;
|
||||
|
||||
|
||||
@@ -1744,6 +1744,25 @@ int dhcp4_start_full(Link *link, bool set_ipv6_connectivity) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dhcp4_renew(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link->dhcp_client)
|
||||
return 0;
|
||||
|
||||
/* The DHCPv4 client may have been stopped by the IPv6 only mode. Let's unconditionally restart the
|
||||
* client if it is not running. */
|
||||
if (!sd_dhcp_client_is_running(link->dhcp_client))
|
||||
return dhcp4_start(link);
|
||||
|
||||
/* The client may be waiting for IPv6 connectivity. Let's restart the client in that case. */
|
||||
if (dhcp_client_get_state(link->dhcp_client) != DHCP_STATE_BOUND)
|
||||
return sd_dhcp_client_interrupt_ipv6_only_mode(link->dhcp_client);
|
||||
|
||||
/* Otherwise, send a RENEW command. */
|
||||
return sd_dhcp_client_send_renew(link->dhcp_client);
|
||||
}
|
||||
|
||||
static int dhcp4_configure_duid(Link *link) {
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
@@ -20,6 +20,7 @@ int dhcp4_start_full(Link *link, bool set_ipv6_connectivity);
|
||||
static inline int dhcp4_start(Link *link) {
|
||||
return dhcp4_start_full(link, true);
|
||||
}
|
||||
int dhcp4_renew(Link *link);
|
||||
int dhcp4_lease_lost(Link *link);
|
||||
int dhcp4_check_ready(Link *link);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "bus-message-util.h"
|
||||
#include "bus-polkit.h"
|
||||
#include "dns-domain.h"
|
||||
#include "networkd-dhcp4.h"
|
||||
#include "networkd-json.h"
|
||||
#include "networkd-link-bus.h"
|
||||
#include "networkd-link.h"
|
||||
@@ -626,13 +627,7 @@ int bus_link_method_renew(sd_bus_message *message, void *userdata, sd_bus_error
|
||||
if (r == 0)
|
||||
return 1; /* Polkit will call us back */
|
||||
|
||||
if (sd_dhcp_client_is_running(l->dhcp_client))
|
||||
r = sd_dhcp_client_send_renew(l->dhcp_client);
|
||||
else
|
||||
/* The DHCPv4 client may have been stopped by the IPv6 only mode. Let's unconditionally
|
||||
* restart the client here. Note, if the DHCPv4 client is disabled, then dhcp4_start() does
|
||||
* nothing and returns 0. */
|
||||
r = dhcp4_start(l);
|
||||
r = dhcp4_renew(l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ int sd_dhcp_client_send_release(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_send_decline(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_send_renew(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_set_ipv6_connectivity(sd_dhcp_client *client, int have);
|
||||
int sd_dhcp_client_interrupt_ipv6_only_mode(sd_dhcp_client *client);
|
||||
|
||||
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
|
||||
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
|
||||
|
||||
Reference in New Issue
Block a user