]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: unify dhcp6_option_append_{ia,pd}()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 6 Feb 2022 05:56:59 +0000 (14:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Feb 2022 05:43:45 +0000 (14:43 +0900)
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-client.c

index ad77a9c44c5405f99f0ef51d41a79a79783a12c8..23738d3197266772a809bba9ca34f6a12efc8d0c 100644 (file)
@@ -81,7 +81,6 @@ bool dhcp6_option_can_request(uint16_t option);
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
-int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd);
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
 int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char * const *user_class);
 int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char * const *user_class);
index f570e78875dae5767f49654c1973fa3849f29d93..5099fa152c3332f07d15b28cab98853353c494d6 100644 (file)
@@ -282,75 +282,33 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
         return 0;
 }
 
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
-        size_t ia_buflen, ia_addrlen = 0;
-        struct ia_header header;
-        DHCP6Address *addr;
-        uint8_t *ia_hdr;
-        uint16_t len;
+static int option_append_ia_address(uint8_t **buf, size_t *buflen, const struct iaaddr *address) {
+        struct iaaddr a;
         int r;
 
-        assert_return(buf, -EINVAL);
-        assert_return(*buf, -EINVAL);
-        assert_return(buflen, -EINVAL);
-        assert_return(ia, -EINVAL);
-
-        /* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
-
-        switch (ia->type) {
-        case SD_DHCP6_OPTION_IA_NA:
-                len = sizeof(struct ia_header);
-                header = (struct ia_header) {
-                        .id = ia->header.id,
-                };
-                break;
-
-        case SD_DHCP6_OPTION_IA_TA:
-                len = sizeof(be32_t); /* IA_TA does not have lifetime. */
-                header = (struct ia_header) {
-                        .id = ia->header.id,
-                };
-                break;
-
-        default:
-                assert_not_reached();
-        }
-
-        if (*buflen < offsetof(DHCP6Option, data) + len)
-                return -ENOBUFS;
-
-        ia_hdr = *buf;
-        ia_buflen = *buflen;
-
-        *buf += offsetof(DHCP6Option, data);
-        *buflen -= offsetof(DHCP6Option, data);
-
-        memcpy(*buf, &header, len);
-
-        *buf += len;
-        *buflen -= len;
-
-        LIST_FOREACH(addresses, addr, ia->addresses) {
-                struct iaaddr a = {
-                        .address = addr->iaaddr.address,
-                };
+        assert(buf);
+        assert(*buf);
+        assert(buflen);
+        assert(address);
 
-                r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
-                if (r < 0)
-                        return r;
+        /* Do not append T1 and T2. */
+        a = (struct iaaddr) {
+                .address = address->address,
+        };
 
-                memcpy(*buf, &a, sizeof(struct iaaddr));
+        r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
+        if (r < 0)
+                return r;
 
-                *buf += sizeof(struct iaaddr);
-                *buflen -= sizeof(struct iaaddr);
+        memcpy(*buf, &a, sizeof(struct iaaddr));
 
-                ia_addrlen += offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
-        }
+        *buf += sizeof(struct iaaddr);
+        *buflen -= sizeof(struct iaaddr);
 
-        return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
+        return offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
 }
 
-static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const DHCP6Address *prefix) {
+static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const struct iapdprefix *prefix) {
         struct iapdprefix p;
         int r;
 
@@ -359,14 +317,13 @@ static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const DHCP6Add
         assert(buflen);
         assert(prefix);
 
-        if (prefix->iapdprefix.prefixlen == 0)
+        if (prefix->prefixlen == 0)
                 return -EINVAL;
 
         /* Do not append T1 and T2. */
-
         p = (struct iapdprefix) {
-                .prefixlen = prefix->iapdprefix.prefixlen,
-                .address = prefix->iapdprefix.address,
+                .prefixlen = prefix->prefixlen,
+                .address = prefix->address,
         };
 
         r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IA_PD_PREFIX, sizeof(struct iapdprefix));
@@ -381,29 +338,46 @@ static int option_append_pd_prefix(uint8_t **buf, size_t *buflen, const DHCP6Add
         return offsetof(DHCP6Option, data) + sizeof(struct iapdprefix);
 }
 
-int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd) {
+int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
         struct ia_header header;
-        size_t len, pd_buflen;
-        uint8_t *pd_hdr;
+        const DHCP6Address *addr;
+        size_t ia_buflen;
+        uint8_t *ia_hdr;
+        uint16_t len;
         int r;
 
         assert_return(buf, -EINVAL);
         assert_return(*buf, -EINVAL);
         assert_return(buflen, -EINVAL);
-        assert_return(pd, -EINVAL);
-        assert_return(pd->type == SD_DHCP6_OPTION_IA_PD, -EINVAL);
+        assert_return(ia, -EINVAL);
 
-        /* Do not set T1 and T2. */
-        len = sizeof(struct ia_header);
-        header = (struct ia_header) {
-                .id = pd->header.id,
-        };
+        /* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
+
+        switch (ia->type) {
+        case SD_DHCP6_OPTION_IA_NA:
+        case SD_DHCP6_OPTION_IA_PD:
+                len = sizeof(struct ia_header);
+                header = (struct ia_header) {
+                        .id = ia->header.id,
+                };
+                break;
+
+        case SD_DHCP6_OPTION_IA_TA:
+                len = sizeof(be32_t); /* IA_TA does not have lifetime. */
+                header = (struct ia_header) {
+                        .id = ia->header.id,
+                };
+                break;
+
+        default:
+                assert_not_reached();
+        }
 
         if (*buflen < offsetof(DHCP6Option, data) + len)
                 return -ENOBUFS;
 
-        pd_hdr = *buf;
-        pd_buflen = *buflen;
+        ia_hdr = *buf;
+        ia_buflen = *buflen;
 
         /* The header will be written at the end of this function. */
         *buf += offsetof(DHCP6Option, data);
@@ -413,16 +387,18 @@ int dhcp6_option_append_pd(uint8_t **buf, size_t *buflen, const DHCP6IA *pd) {
         *buf += len;
         *buflen -= len;
 
-        DHCP6Address *prefix;
-        LIST_FOREACH(addresses, prefix, pd->addresses) {
-                r = option_append_pd_prefix(buf, buflen, prefix);
+        LIST_FOREACH(addresses, addr, ia->addresses) {
+                if (ia->type == SD_DHCP6_OPTION_IA_PD)
+                        r = option_append_pd_prefix(buf, buflen, &addr->iapdprefix);
+                else
+                        r = option_append_ia_address(buf, buflen, &addr->iaaddr);
                 if (r < 0)
                         return r;
 
                 len += r;
         }
 
-        return option_append_hdr(&pd_hdr, &pd_buflen, pd->type, len);
+        return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len);
 }
 
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
index b60950740af109ae19128f392ce10cd409a2382e..89d91f928915ba80247bf4897b22ec418325ba28 100644 (file)
@@ -702,7 +702,7 @@ static int client_append_common_options_in_managed_mode(
         }
 
         if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD) && ia_pd) {
-                r = dhcp6_option_append_pd(opt, optlen, ia_pd);
+                r = dhcp6_option_append_ia(opt, optlen, ia_pd);
                 if (r < 0)
                         return r;
         }