networkd: Allow DHCP4 client to set the number to attempt to reconfigure.
Otherwise current value is 6 and after 6 it will give up.
This commit is contained in:
parent
11793fcd63
commit
715cedfbf0
|
@ -1396,6 +1396,16 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>MaxAttempts=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specifies how many times the DHCPv4 client configuration should be attempted. Takes a
|
||||||
|
number or <literal>infinity</literal>. Defaults to <literal>infinity</literal>.
|
||||||
|
Note that the time between retries is increased exponentially, so the network will not be
|
||||||
|
overloaded even if this number is high.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>DUIDType=</varname></term>
|
<term><varname>DUIDType=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
|
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
|
||||||
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
|
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
|
||||||
|
|
||||||
#define MAX_CLIENT_ATTEMPT 6
|
|
||||||
|
|
||||||
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
|
||||||
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
|
||||||
|
|
||||||
|
@ -90,7 +88,8 @@ struct sd_dhcp_client {
|
||||||
uint32_t mtu;
|
uint32_t mtu;
|
||||||
uint32_t xid;
|
uint32_t xid;
|
||||||
usec_t start_time;
|
usec_t start_time;
|
||||||
unsigned attempt;
|
uint64_t attempt;
|
||||||
|
uint64_t max_attempts;
|
||||||
usec_t request_sent;
|
usec_t request_sent;
|
||||||
sd_event_source *timeout_t1;
|
sd_event_source *timeout_t1;
|
||||||
sd_event_source *timeout_t2;
|
sd_event_source *timeout_t2;
|
||||||
|
@ -522,6 +521,14 @@ int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempts) {
|
||||||
|
assert_return(client, -EINVAL);
|
||||||
|
|
||||||
|
client->max_attempts = max_attempts;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
|
|
||||||
|
@ -1052,12 +1059,12 @@ static int client_timeout_resend(
|
||||||
case DHCP_STATE_REQUESTING:
|
case DHCP_STATE_REQUESTING:
|
||||||
case DHCP_STATE_BOUND:
|
case DHCP_STATE_BOUND:
|
||||||
|
|
||||||
if (client->attempt < MAX_CLIENT_ATTEMPT)
|
if (client->attempt < client->max_attempts)
|
||||||
client->attempt++;
|
client->attempt++;
|
||||||
else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
next_timeout = time_now + ((UINT64_C(1) << client->attempt) - 1) * USEC_PER_SEC;
|
next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1082,16 +1089,14 @@ static int client_timeout_resend(
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
client->state = DHCP_STATE_SELECTING;
|
client->state = DHCP_STATE_SELECTING;
|
||||||
client->attempt = 0;
|
client->attempt = 0;
|
||||||
} else {
|
} else if (client->attempt >= client->max_attempts)
|
||||||
if (client->attempt >= MAX_CLIENT_ATTEMPT)
|
goto error;
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCP_STATE_SELECTING:
|
case DHCP_STATE_SELECTING:
|
||||||
r = client_send_discover(client);
|
r = client_send_discover(client);
|
||||||
if (r < 0 && client->attempt >= MAX_CLIENT_ATTEMPT)
|
if (r < 0 && client->attempt >= client->max_attempts)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1101,7 +1106,7 @@ static int client_timeout_resend(
|
||||||
case DHCP_STATE_RENEWING:
|
case DHCP_STATE_RENEWING:
|
||||||
case DHCP_STATE_REBINDING:
|
case DHCP_STATE_REBINDING:
|
||||||
r = client_send_request(client);
|
r = client_send_request(client);
|
||||||
if (r < 0 && client->attempt >= MAX_CLIENT_ATTEMPT)
|
if (r < 0 && client->attempt >= client->max_attempts)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (client->state == DHCP_STATE_INIT_REBOOT)
|
if (client->state == DHCP_STATE_INIT_REBOOT)
|
||||||
|
@ -1934,6 +1939,7 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
|
||||||
.mtu = DHCP_DEFAULT_MIN_SIZE,
|
.mtu = DHCP_DEFAULT_MIN_SIZE,
|
||||||
.port = DHCP_PORT_CLIENT,
|
.port = DHCP_PORT_CLIENT,
|
||||||
.anonymize = !!anonymize,
|
.anonymize = !!anonymize,
|
||||||
|
.max_attempts = (uint64_t) -1,
|
||||||
};
|
};
|
||||||
/* NOTE: this could be moved to a function. */
|
/* NOTE: this could be moved to a function. */
|
||||||
if (anonymize) {
|
if (anonymize) {
|
||||||
|
|
|
@ -833,5 +833,11 @@ int dhcp4_configure(Link *link) {
|
||||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m");
|
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set listen port: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link->network->dhcp_max_attempts > 0) {
|
||||||
|
r = sd_dhcp_client_set_max_attempts(link->dhcp_client, link->network->dhcp_max_attempts);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
|
||||||
|
}
|
||||||
|
|
||||||
return dhcp4_set_client_identifier(link);
|
return dhcp4_set_client_identifier(link);
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ DHCP.Hostname, config_parse_hostname,
|
||||||
DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
|
DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
|
||||||
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical)
|
||||||
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
|
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
|
||||||
|
DHCP.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
|
||||||
DHCP.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
|
DHCP.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
|
||||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
|
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)
|
||||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
|
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid)
|
||||||
|
|
|
@ -1575,6 +1575,54 @@ int config_parse_section_route_table(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_dhcp_max_attempts(
|
||||||
|
const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
Network *network = data;
|
||||||
|
uint64_t a;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(network);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
network->dhcp_max_attempts = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(rvalue, "infinity")) {
|
||||||
|
network->dhcp_max_attempts = (uint64_t) -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = safe_atou64(rvalue, &a);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to parse DHCP maximum attempts, ignoring: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a == 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"%s= must be positive integer or 'infinity', ignoring: %s", lvalue, rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
network->dhcp_max_attempts = a;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
||||||
"Failed to parse DHCP use domains setting");
|
"Failed to parse DHCP use domains setting");
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct Network {
|
||||||
char *dhcp_vendor_class_identifier;
|
char *dhcp_vendor_class_identifier;
|
||||||
char **dhcp_user_class;
|
char **dhcp_user_class;
|
||||||
char *dhcp_hostname;
|
char *dhcp_hostname;
|
||||||
|
uint64_t dhcp_max_attempts;
|
||||||
unsigned dhcp_route_metric;
|
unsigned dhcp_route_metric;
|
||||||
uint32_t dhcp_route_table;
|
uint32_t dhcp_route_table;
|
||||||
uint16_t dhcp_client_port;
|
uint16_t dhcp_client_port;
|
||||||
|
@ -315,6 +316,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
|
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
|
||||||
/* Legacy IPv4LL support */
|
/* Legacy IPv4LL support */
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,9 @@ int sd_dhcp_client_get_client_id(
|
||||||
int sd_dhcp_client_set_mtu(
|
int sd_dhcp_client_set_mtu(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
uint32_t mtu);
|
uint32_t mtu);
|
||||||
|
int sd_dhcp_client_set_max_attempts(
|
||||||
|
sd_dhcp_client *client,
|
||||||
|
uint64_t attempt);
|
||||||
int sd_dhcp_client_set_client_port(
|
int sd_dhcp_client_set_client_port(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
uint16_t port);
|
uint16_t port);
|
||||||
|
|
|
@ -199,6 +199,7 @@ MaxLeaseTimeSec=
|
||||||
DefaultLeaseTimeSec=
|
DefaultLeaseTimeSec=
|
||||||
EmitTimezone=
|
EmitTimezone=
|
||||||
DNS=
|
DNS=
|
||||||
|
MaxAttempts=
|
||||||
[DHCPv4]
|
[DHCPv4]
|
||||||
UseHostname=
|
UseHostname=
|
||||||
UseMTU=
|
UseMTU=
|
||||||
|
|
Loading…
Reference in New Issue