mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
Merge pull request #24299 from yuwata/dhcp6-no-binding
dhcp6: gracefully handle NoBinding error
This commit is contained in:
commit
4f4e9104f3
@ -82,3 +82,14 @@ static const char * const dhcp6_message_status_table[_DHCP6_STATUS_MAX] = {
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, DHCP6Status);
|
||||
|
||||
int dhcp6_message_status_to_errno(DHCP6Status s) {
|
||||
switch (s) {
|
||||
case DHCP6_STATUS_SUCCESS:
|
||||
return 0;
|
||||
case DHCP6_STATUS_NO_BINDING:
|
||||
return -EADDRNOTAVAIL;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -154,3 +154,4 @@ const char *dhcp6_message_type_to_string(DHCP6MessageType s) _const_;
|
||||
DHCP6MessageType dhcp6_message_type_from_string(const char *s) _pure_;
|
||||
const char *dhcp6_message_status_to_string(DHCP6Status s) _const_;
|
||||
DHCP6Status dhcp6_message_status_from_string(const char *s) _pure_;
|
||||
int dhcp6_message_status_to_errno(DHCP6Status s);
|
||||
|
@ -48,7 +48,7 @@ static void fuzz_client(sd_dhcp6_client *client, const uint8_t *data, size_t siz
|
||||
assert_se(IN_SET(client->state, DHCP6_STATE_REQUEST, DHCP6_STATE_BOUND));
|
||||
break;
|
||||
case DHCP6_STATE_REQUEST:
|
||||
assert_se(client->state == DHCP6_STATE_BOUND);
|
||||
assert_se(IN_SET(client->state, DHCP6_STATE_BOUND, DHCP6_STATE_SOLICITATION));
|
||||
break;
|
||||
default:
|
||||
assert_not_reached();
|
||||
|
@ -543,13 +543,9 @@ static void client_notify(sd_dhcp6_client *client, int event) {
|
||||
client->callback(client, event, client->userdata);
|
||||
}
|
||||
|
||||
static void client_stop(sd_dhcp6_client *client, int error) {
|
||||
DHCP6_CLIENT_DONT_DESTROY(client);
|
||||
|
||||
static void client_cleanup(sd_dhcp6_client *client) {
|
||||
assert(client);
|
||||
|
||||
client_notify(client, error);
|
||||
|
||||
client->lease = sd_dhcp6_lease_unref(client->lease);
|
||||
|
||||
/* Reset IRT here. Otherwise, we cannot restart the client in the information requesting mode,
|
||||
@ -566,6 +562,16 @@ static void client_stop(sd_dhcp6_client *client, int error) {
|
||||
client_set_state(client, DHCP6_STATE_STOPPED);
|
||||
}
|
||||
|
||||
static void client_stop(sd_dhcp6_client *client, int error) {
|
||||
DHCP6_CLIENT_DONT_DESTROY(client);
|
||||
|
||||
assert(client);
|
||||
|
||||
client_notify(client, error);
|
||||
|
||||
client_cleanup(client);
|
||||
}
|
||||
|
||||
static int client_append_common_options_in_managed_mode(
|
||||
sd_dhcp6_client *client,
|
||||
uint8_t **opt,
|
||||
@ -684,6 +690,9 @@ static int client_append_oro(sd_dhcp6_client *client, uint8_t **opt, size_t *opt
|
||||
req_opts = client->req_opts;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
return dhcp6_option_append(opt, optlen, SD_DHCP6_OPTION_ORO, n * sizeof(be16_t), req_opts);
|
||||
}
|
||||
|
||||
@ -1133,6 +1142,20 @@ static int client_process_reply(
|
||||
return log_invalid_message_type(client, message);
|
||||
|
||||
r = dhcp6_lease_new_from_message(client, message, len, timestamp, server_address, &lease);
|
||||
if (r == -EADDRNOTAVAIL) {
|
||||
|
||||
/* If NoBinding status code is received, we cannot request the address anymore.
|
||||
* Let's restart transaction from the beginning. */
|
||||
|
||||
if (client->state == DHCP6_STATE_REQUEST)
|
||||
/* The lease is not acquired yet, hence it is not necessary to notify the restart. */
|
||||
client_cleanup(client);
|
||||
else
|
||||
/* We need to notify the previous lease was expired. */
|
||||
client_stop(client, SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE);
|
||||
|
||||
return client_start_transaction(client, DHCP6_STATE_SOLICITATION);
|
||||
}
|
||||
if (r < 0)
|
||||
return log_dhcp6_client_errno(client, r, "Failed to process received reply message, ignoring: %m");
|
||||
|
||||
|
@ -512,7 +512,7 @@ static int dhcp6_lease_parse_message(
|
||||
return log_dhcp6_client_errno(client, r, "Failed to parse status code: %m");
|
||||
|
||||
if (r > 0)
|
||||
return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL),
|
||||
return log_dhcp6_client_errno(client, dhcp6_message_status_to_errno(r),
|
||||
"Received %s message with non-zero status: %s%s%s",
|
||||
dhcp6_message_type_to_string(message->type),
|
||||
strempty(msg), isempty(msg) ? "" : ": ",
|
||||
|
Loading…
Reference in New Issue
Block a user