From fcb51238e0523d64a698b8738a15bbc1aea9febe Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 7 Sep 2019 03:29:46 +0900 Subject: [PATCH] dhcp6: read OPTION_INFORMATION_REFRESH_TIME option Fixes #13460. --- src/libsystemd-network/sd-dhcp6-client.c | 21 ++++++++++++++++++++- src/systemd/sd-dhcp6-client.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index d7a5349c701..7dab776b729 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -29,6 +29,9 @@ #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN +#define IRT_DEFAULT 1 * USEC_PER_DAY +#define IRT_MINIMUM 600 * USEC_PER_SEC + /* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */ enum { DHCP6_REQUEST_IA_NA = 1, @@ -71,6 +74,8 @@ struct sd_dhcp6_client { void *userdata; struct duid duid; size_t duid_len; + usec_t information_request_time_usec; + usec_t information_refresh_time_usec; }; static const uint16_t default_req_opts[] = { @@ -820,6 +825,7 @@ static int client_parse_message( uint32_t lt_t1 = ~0, lt_t2 = ~0; bool clientid = false; size_t pos = 0; + usec_t irt = IRT_DEFAULT; int r; assert(client); @@ -994,6 +1000,10 @@ static int client_parse_message( return r; break; + + case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME: + irt = be32toh(*(be32_t *) optval) * USEC_PER_SEC; + break; } pos += offsetof(DHCP6Option, data) + optlen; @@ -1025,6 +1035,8 @@ static int client_parse_message( } } + client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM); + return 0; } @@ -1425,8 +1437,15 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { client->fd = r; } - if (client->information_request) + if (client->information_request) { + usec_t t = now(CLOCK_MONOTONIC); + + if (t < usec_add(client->information_request_time_usec, client->information_refresh_time_usec)) + return 0; + + client->information_request_time_usec = t; state = DHCP6_STATE_INFORMATION_REQUEST; + } log_dhcp6_client(client, "Started in %s mode", client->information_request? "Information request": diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index 43d38f5c7da..3aac3f14fe3 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -66,6 +66,7 @@ enum { SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */ SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */ + SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME = 32, /* RFC 8415, sec. 21.23 */ /* option code 35 is unassigned */