summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-02-11 14:59:53 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-04-04 01:22:02 +0900
commit822883b3e7d4c66023052ce13f60dcfd9f4c97e7 (patch)
tree7e2a6db3ff58511e39c921fc4b48102132ad745c /src/libsystemd-network
parent612caa2626ba898708f4b8a2bdbb6c1014e84d63 (diff)
downloadsystemd-822883b3e7d4c66023052ce13f60dcfd9f4c97e7.tar.gz
sd-dhcp6-client: request several options
Even though these options are not currently used by sd-dhcp6-client, RFC 8415 states these options MUST be requested.
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/dhcp6-option.c6
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c49
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c7
3 files changed, 55 insertions, 7 deletions
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 2f4862fd5a..63d3f60513 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -62,7 +62,9 @@ bool dhcp6_option_can_request(uint16_t option) {
case SD_DHCP6_OPTION_NIS_DOMAIN_NAME:
case SD_DHCP6_OPTION_NISP_DOMAIN_NAME:
case SD_DHCP6_OPTION_SNTP_SERVER:
+ return true;
case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+ return false; /* This is automatically set when sending INFORMATION_REQUEST message. */
case SD_DHCP6_OPTION_BCMCS_SERVER_D:
case SD_DHCP6_OPTION_BCMCS_SERVER_A:
case SD_DHCP6_OPTION_GEOCONF_CIVIC:
@@ -124,9 +126,9 @@ bool dhcp6_option_can_request(uint16_t option) {
case SD_DHCP6_OPTION_CLIENT_LINKLAYER_ADDR:
case SD_DHCP6_OPTION_LINK_ADDRESS:
case SD_DHCP6_OPTION_RADIUS:
+ case SD_DHCP6_OPTION_SOL_MAX_RT: /* Automatically set when sending SOLICIT message. */
+ case SD_DHCP6_OPTION_INF_MAX_RT: /* Automatically set when sending INFORMATION_REQUEST message. */
return false;
- case SD_DHCP6_OPTION_SOL_MAX_RT:
- case SD_DHCP6_OPTION_INF_MAX_RT:
case SD_DHCP6_OPTION_ADDRSEL:
case SD_DHCP6_OPTION_ADDRSEL_TABLE:
case SD_DHCP6_OPTION_V6_PCP_SERVER:
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 3903318be5..a2725c99c6 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -635,6 +635,51 @@ static DHCP6MessageType client_message_type_from_state(sd_dhcp6_client *client)
}
}
+static int client_append_oro(sd_dhcp6_client *client, uint8_t **opt, size_t *optlen) {
+ _cleanup_free_ be16_t *buf = NULL;
+ be16_t *req_opts;
+ size_t n;
+
+ assert(client);
+ assert(opt);
+ assert(optlen);
+
+ switch (client->state) {
+ case DHCP6_STATE_INFORMATION_REQUEST:
+ n = client->n_req_opts;
+ buf = new(be16_t, n + 2);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy_safe(buf, client->req_opts, n * sizeof(be16_t));
+ buf[n++] = htobe16(SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME); /* RFC 8415 section 21.23 */
+ buf[n++] = htobe16(SD_DHCP6_OPTION_INF_MAX_RT); /* RFC 8415 section 21.25 */
+
+ typesafe_qsort(buf, n, be16_compare_func);
+ req_opts = buf;
+ break;
+
+ case DHCP6_STATE_SOLICITATION:
+ n = client->n_req_opts;
+ buf = new(be16_t, n + 1);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy_safe(buf, client->req_opts, n * sizeof(be16_t));
+ buf[n++] = htobe16(SD_DHCP6_OPTION_SOL_MAX_RT); /* RFC 8415 section 21.24 */
+
+ typesafe_qsort(buf, n, be16_compare_func);
+ req_opts = buf;
+ break;
+
+ default:
+ n = client->n_req_opts;
+ req_opts = client->req_opts;
+ }
+
+ return dhcp6_option_append(opt, optlen, SD_DHCP6_OPTION_ORO, n * sizeof(be16_t), req_opts);
+}
+
int dhcp6_client_send_message(sd_dhcp6_client *client) {
_cleanup_free_ DHCP6Message *message = NULL;
struct in6_addr all_servers =
@@ -712,9 +757,7 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) {
return r;
}
- r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ORO,
- client->n_req_opts * sizeof(be16_t),
- client->req_opts);
+ r = client_append_oro(client, &opt, &optlen);
if (r < 0)
return r;
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index f32f5a202c..95a6c514c6 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -450,11 +450,13 @@ static const uint8_t msg_information_request[] = {
0x0f, 0xb4, 0xe5,
/* MUD URL */
/* ORO */
- 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
+ 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x0c,
0x00, SD_DHCP6_OPTION_DNS_SERVER,
0x00, SD_DHCP6_OPTION_DOMAIN,
0x00, SD_DHCP6_OPTION_SNTP_SERVER,
+ 0x00, SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME,
0x00, SD_DHCP6_OPTION_NTP_SERVER,
+ 0x00, SD_DHCP6_OPTION_INF_MAX_RT,
/* Client ID */
0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
CLIENT_ID_BYTES,
@@ -490,11 +492,12 @@ static const uint8_t msg_solicit[] = {
/* Vendor Options */
/* MUD URL */
/* ORO */
- 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
+ 0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x0a,
0x00, SD_DHCP6_OPTION_DNS_SERVER,
0x00, SD_DHCP6_OPTION_DOMAIN,
0x00, SD_DHCP6_OPTION_SNTP_SERVER,
0x00, SD_DHCP6_OPTION_NTP_SERVER,
+ 0x00, SD_DHCP6_OPTION_SOL_MAX_RT,
/* Client ID */
0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
CLIENT_ID_BYTES,