]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: request several options 22943/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 11 Feb 2022 05:59:53 +0000 (14:59 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 3 Apr 2022 16:22:02 +0000 (01:22 +0900)
Even though these options are not currently used by sd-dhcp6-client,
RFC 8415 states these options MUST be requested.

src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp6-client.c

index 2f4862fd5aae89203c6ba64872801e17fd135ce4..63d3f60513afff6a45d189297e6c713903eda8c1 100644 (file)
@@ -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:
index 3903318be5e2a24c6e35cdb36efee47e53a62cf2..a2725c99c62f07938d4df20434c65fff9578dbe0 100644 (file)
@@ -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;
 
index f32f5a202c4cc231dec979f2bcfeccb71263f0e1..95a6c514c6df0299fc4cff4a5d6ab3800e33243c 100644 (file)
@@ -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,