diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index a27d67a315d..93aadd1e4fa 100644 --- a/src/libsystemd-network/dhcp-identifier.c +++ b/src/libsystemd-network/dhcp-identifier.c @@ -23,43 +23,7 @@ static const char * const duid_type_table[_DUID_TYPE_MAX] = { DEFINE_STRING_TABLE_LOOKUP_TO_STRING(duid_type, DUIDType); -int dhcp_validate_duid_len(DUIDType duid_type, size_t duid_len, bool strict) { - struct duid d; - - assert_cc(sizeof(d.raw) >= MAX_DUID_LEN); - if (duid_len > MAX_DUID_LEN) - return -EINVAL; - - if (!strict) - /* Strict validation is not requested. We only ensure that the - * DUID is not too long. */ - return 0; - - switch (duid_type) { - case DUID_TYPE_LLT: - if (duid_len <= sizeof(d.llt)) - return -EINVAL; - break; - case DUID_TYPE_EN: - if (duid_len != sizeof(d.en)) - return -EINVAL; - break; - case DUID_TYPE_LL: - if (duid_len <= sizeof(d.ll)) - return -EINVAL; - break; - case DUID_TYPE_UUID: - if (duid_len != sizeof(d.uuid)) - return -EINVAL; - break; - default: - /* accept unknown type in order to be forward compatible */ - break; - } - return 0; -} - -static int dhcp_identifier_set_duid_llt( +int dhcp_identifier_set_duid_llt( const struct hw_addr_data *hw_addr, uint16_t arp_type, usec_t t, @@ -97,7 +61,7 @@ static int dhcp_identifier_set_duid_llt( return 0; } -static int dhcp_identifier_set_duid_ll( +int dhcp_identifier_set_duid_ll( const struct hw_addr_data *hw_addr, uint16_t arp_type, struct duid *ret_duid, @@ -160,7 +124,7 @@ int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *r return 0; } -static int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len) { +int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len) { sd_id128_t machine_id; int r; @@ -179,27 +143,28 @@ static int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len) return 0; } -int dhcp_identifier_set_duid( +int dhcp_identifier_set_duid_raw( DUIDType duid_type, - const struct hw_addr_data *hw_addr, - uint16_t arp_type, - usec_t llt_time, - bool test_mode, + const uint8_t *buf, + size_t buf_len, struct duid *ret_duid, size_t *ret_len) { - switch (duid_type) { - case DUID_TYPE_LLT: - return dhcp_identifier_set_duid_llt(hw_addr, arp_type, llt_time, ret_duid, ret_len); - case DUID_TYPE_EN: - return dhcp_identifier_set_duid_en(test_mode, ret_duid, ret_len); - case DUID_TYPE_LL: - return dhcp_identifier_set_duid_ll(hw_addr, arp_type, ret_duid, ret_len); - case DUID_TYPE_UUID: - return dhcp_identifier_set_duid_uuid(ret_duid, ret_len); - default: + assert(buf || buf_len == 0); + assert(ret_duid); + assert(ret_len); + + if (duid_type < 0 || duid_type > UINT16_MAX) return -EINVAL; - } + + if (buf_len > MAX_DUID_LEN) + return -EINVAL; + + unaligned_write_be16(&ret_duid->type, duid_type); + memcpy_safe(ret_duid->raw.data, buf, buf_len); + + *ret_len = offsetof(struct duid, raw.data) + buf_len; + return 0; } int dhcp_identifier_set_iaid( diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h index 523dfc4a71b..3830b5952cf 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -57,13 +57,23 @@ struct duid { } _packed_; int dhcp_validate_duid_len(DUIDType duid_type, size_t duid_len, bool strict); -int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len); -int dhcp_identifier_set_duid( - DUIDType duid_type, +int dhcp_identifier_set_duid_llt( const struct hw_addr_data *hw_addr, uint16_t arp_type, - usec_t llt_time, - bool test_mode, + usec_t t, + struct duid *ret_duid, + size_t *ret_len); +int dhcp_identifier_set_duid_ll( + const struct hw_addr_data *hw_addr, + uint16_t arp_type, + struct duid *ret_duid, + size_t *ret_len); +int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len); +int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len); +int dhcp_identifier_set_duid_raw( + DUIDType duid_type, + const uint8_t *buf, + size_t buf_len, struct duid *ret_duid, size_t *ret_len); int dhcp_identifier_set_iaid( diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 272201abfdc..8f330c8f145 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -402,27 +402,15 @@ int sd_dhcp_client_set_client_id( * without further modification. Otherwise, if duid_type is supported, DUID * is set based on that type. Otherwise, an error is returned. */ -static int dhcp_client_set_iaid_duid_internal( +static int dhcp_client_set_iaid( sd_dhcp_client *client, bool iaid_set, - uint32_t iaid, - DUIDType duid_type, - const void *duid, - size_t duid_len, - usec_t llt_time) { + uint32_t iaid) { - size_t len; int r; assert_return(client, -EINVAL); assert_return(!sd_dhcp_client_is_running(client), -EBUSY); - assert_return(duid_len == 0 || duid, -EINVAL); - - if (duid) { - r = dhcp_validate_duid_len(duid_type, duid_len, true); - if (r < 0) - return log_dhcp_client_errno(client, r, "Failed to validate length of DUID: %m"); - } zero(client->client_id); client->client_id.type = 255; @@ -437,46 +425,132 @@ static int dhcp_client_set_iaid_duid_internal( return log_dhcp_client_errno(client, r, "Failed to set IAID: %m"); } - if (duid) { - client->client_id.ns.duid.type = htobe16(duid_type); - memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len); - len = sizeof(client->client_id.ns.duid.type) + duid_len; - - } else { - r = dhcp_identifier_set_duid(duid_type, &client->hw_addr, - client->arp_type, llt_time, client->test_mode, - &client->client_id.ns.duid, &len); - if (r == -EOPNOTSUPP) - return log_dhcp_client_errno(client, r, - "Failed to set %s. MAC address is not set or " - "interface type is not supported.", - duid_type_to_string(duid_type)); - if (r < 0) - return log_dhcp_client_errno(client, r, "Failed to set %s: %m", - duid_type_to_string(duid_type)); - } - - client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; - return 0; } -int sd_dhcp_client_set_iaid_duid( - sd_dhcp_client *client, - bool iaid_set, - uint32_t iaid, - uint16_t duid_type, - const void *duid, - size_t duid_len) { - return dhcp_client_set_iaid_duid_internal(client, iaid_set, iaid, duid_type, duid, duid_len, 0); -} - int sd_dhcp_client_set_iaid_duid_llt( sd_dhcp_client *client, bool iaid_set, uint32_t iaid, usec_t llt_time) { - return dhcp_client_set_iaid_duid_internal(client, iaid_set, iaid, DUID_TYPE_LLT, NULL, 0, llt_time); + + size_t len; + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + + r = dhcp_client_set_iaid(client, iaid_set, iaid); + if (r < 0) + return r; + + r = dhcp_identifier_set_duid_llt(&client->hw_addr, client->arp_type, llt_time, &client->client_id.ns.duid, &len); + if (r < 0) + return log_dhcp_client_errno(client, r, "Failed to set DUID-LLT: %m"); + + client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; + + return 0; +} + +int sd_dhcp_client_set_iaid_duid_ll( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid) { + + size_t len; + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + + r = dhcp_client_set_iaid(client, iaid_set, iaid); + if (r < 0) + return r; + + r = dhcp_identifier_set_duid_ll(&client->hw_addr, client->arp_type, &client->client_id.ns.duid, &len); + if (r < 0) + return log_dhcp_client_errno(client, r, "Failed to set DUID-LL: %m"); + + client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; + + return 0; +} + +int sd_dhcp_client_set_iaid_duid_en( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid) { + + size_t len; + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + + r = dhcp_client_set_iaid(client, iaid_set, iaid); + if (r < 0) + return r; + + r = dhcp_identifier_set_duid_en(client->test_mode, &client->client_id.ns.duid, &len); + if (r < 0) + return log_dhcp_client_errno(client, r, "Failed to set DUID-EN: %m"); + + client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; + + return 0; +} + +int sd_dhcp_client_set_iaid_duid_uuid( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid) { + + size_t len; + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + + r = dhcp_client_set_iaid(client, iaid_set, iaid); + if (r < 0) + return r; + + r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len); + if (r < 0) + return log_dhcp_client_errno(client, r, "Failed to set DUID-UUID: %m"); + + client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; + + return 0; +} + +int sd_dhcp_client_set_iaid_duid_raw( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid, + uint16_t duid_type, + const uint8_t *duid, + size_t duid_len) { + + size_t len; + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp_client_is_running(client), -EBUSY); + assert_return(duid || duid_len == 0, -EINVAL); + + r = dhcp_client_set_iaid(client, iaid_set, iaid); + if (r < 0) + return r; + + r = dhcp_identifier_set_duid_raw(duid_type, duid, duid_len, &client->client_id.ns.duid, &len); + if (r < 0) + return log_dhcp_client_errno(client, r, "Failed to set DUID: %m"); + + client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + len; + + return 0; } void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode) { @@ -798,21 +872,9 @@ static int client_message_init( /* If no client identifier exists, construct an RFC 4361-compliant one */ if (client->client_id_len == 0) { - size_t duid_len; - - client->client_id.type = 255; - - r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr, - /* legacy_unstable_byteorder = */ true, - &client->client_id.ns.iaid); + r = sd_dhcp_client_set_iaid_duid_en(client, /* iaid_set = */ false, /* iaid = */ 0); if (r < 0) return r; - - r = dhcp_identifier_set_duid_en(client->test_mode, &client->client_id.ns.duid, &duid_len); - if (r < 0) - return r; - - client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len; } /* Some DHCP servers will refuse to issue an DHCP lease if the Client diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 2f4053caad0..8957e1cf4bf 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -190,60 +190,70 @@ static int client_ensure_duid(sd_dhcp6_client *client) { * without further modification. Otherwise, if duid_type is supported, DUID * is set based on that type. Otherwise, an error is returned. */ -static int dhcp6_client_set_duid_internal( - sd_dhcp6_client *client, - DUIDType duid_type, - const void *duid, - size_t duid_len, - usec_t llt_time) { +int sd_dhcp6_client_set_duid_llt(sd_dhcp6_client *client, uint64_t llt_time) { int r; assert_return(client, -EINVAL); assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); - assert_return(duid_len == 0 || duid, -EINVAL); - if (duid) { - r = dhcp_validate_duid_len(duid_type, duid_len, true); - if (r < 0) { - r = dhcp_validate_duid_len(duid_type, duid_len, false); - if (r < 0) - return log_dhcp6_client_errno(client, r, "Failed to validate length of DUID: %m"); - - log_dhcp6_client(client, "Using DUID of type %i of incorrect length, proceeding.", duid_type); - } - - client->duid.type = htobe16(duid_type); - memcpy(&client->duid.raw.data, duid, duid_len); - client->duid_len = sizeof(client->duid.type) + duid_len; - - } else { - r = dhcp_identifier_set_duid(duid_type, &client->hw_addr, client->arp_type, llt_time, - client->test_mode, &client->duid, &client->duid_len); - if (r == -EOPNOTSUPP) - return log_dhcp6_client_errno(client, r, - "Failed to set %s. MAC address is not set or " - "interface type is not supported.", - duid_type_to_string(duid_type)); - if (r < 0) - return log_dhcp6_client_errno(client, r, "Failed to set %s: %m", - duid_type_to_string(duid_type)); - } + r = dhcp_identifier_set_duid_llt(&client->hw_addr, client->arp_type, llt_time, &client->duid, &client->duid_len); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to set DUID-LLT: %m"); return 0; } -int sd_dhcp6_client_set_duid( - sd_dhcp6_client *client, - uint16_t duid_type, - const void *duid, - size_t duid_len) { - return dhcp6_client_set_duid_internal(client, duid_type, duid, duid_len, 0); +int sd_dhcp6_client_set_duid_ll(sd_dhcp6_client *client) { + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); + + r = dhcp_identifier_set_duid_ll(&client->hw_addr, client->arp_type, &client->duid, &client->duid_len); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to set DUID-LL: %m"); + + return 0; } -int sd_dhcp6_client_set_duid_llt( - sd_dhcp6_client *client, - usec_t llt_time) { - return dhcp6_client_set_duid_internal(client, DUID_TYPE_LLT, NULL, 0, llt_time); +int sd_dhcp6_client_set_duid_en(sd_dhcp6_client *client) { + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); + + r = dhcp_identifier_set_duid_en(client->test_mode, &client->duid, &client->duid_len); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to set DUID-EN: %m"); + + return 0; +} + +int sd_dhcp6_client_set_duid_uuid(sd_dhcp6_client *client) { + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); + + r = dhcp_identifier_set_duid_uuid(&client->duid, &client->duid_len); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to set DUID-UUID: %m"); + + return 0; +} + +int sd_dhcp6_client_set_duid_raw(sd_dhcp6_client *client, uint16_t duid_type, const uint8_t *duid, size_t duid_len) { + int r; + + assert_return(client, -EINVAL); + assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); + assert_return(duid || duid_len == 0, -EINVAL); + + r = dhcp_identifier_set_duid_raw(duid_type, duid, duid_len, &client->duid, &client->duid_len); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to set DUID: %m"); + + return 0; } int sd_dhcp6_client_duid_as_string( diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 6b1842f1f89..ccf9208d433 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -428,7 +428,7 @@ TEST(client_parse_message_issue_22099) { assert_se(sd_dhcp6_client_new(&client) >= 0); assert_se(sd_dhcp6_client_set_iaid(client, 0xcc59117b) >= 0); - assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0); + assert_se(sd_dhcp6_client_set_duid_raw(client, 2, duid, sizeof(duid)) >= 0); assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0); } @@ -472,7 +472,7 @@ TEST(client_parse_message_issue_24002) { assert_se(sd_dhcp6_client_new(&client) >= 0); assert_se(sd_dhcp6_client_set_iaid(client, 0xaabbccdd) >= 0); - assert_se(sd_dhcp6_client_set_duid(client, 2, duid, sizeof(duid)) >= 0); + assert_se(sd_dhcp6_client_set_duid_raw(client, 2, duid, sizeof(duid)) >= 0); assert_se(dhcp6_lease_new_from_message(client, (const DHCP6Message*) msg, sizeof(msg), NULL, NULL, &lease) >= 0); } diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index eeb3585f293..9dcd37e11c6 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -1326,20 +1326,42 @@ static int dhcp4_set_client_identifier(Link *link) { /* If configured, apply user specified DUID and IAID */ const DUID *duid = link_get_dhcp4_duid(link); - if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) - r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client, + if (duid->raw_data_len == 0) + switch (duid->type) { + case DUID_TYPE_LLT: + r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client, + link->network->dhcp_iaid_set, + link->network->dhcp_iaid, + duid->llt_time); + break; + case DUID_TYPE_LL: + r = sd_dhcp_client_set_iaid_duid_ll(link->dhcp_client, + link->network->dhcp_iaid_set, + link->network->dhcp_iaid); + break; + case DUID_TYPE_EN: + r = sd_dhcp_client_set_iaid_duid_en(link->dhcp_client, + link->network->dhcp_iaid_set, + link->network->dhcp_iaid); + break; + case DUID_TYPE_UUID: + r = sd_dhcp_client_set_iaid_duid_uuid(link->dhcp_client, + link->network->dhcp_iaid_set, + link->network->dhcp_iaid); + break; + default: + r = sd_dhcp_client_set_iaid_duid_raw(link->dhcp_client, + link->network->dhcp_iaid_set, + link->network->dhcp_iaid, + duid->type, NULL, 0); + } + else + r = sd_dhcp_client_set_iaid_duid_raw(link->dhcp_client, link->network->dhcp_iaid_set, link->network->dhcp_iaid, - duid->llt_time); - else - r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, - link->network->dhcp_iaid_set, - link->network->dhcp_iaid, - duid->type, - duid->raw_data_len > 0 ? duid->raw_data : NULL, - duid->raw_data_len); + duid->type, duid->raw_data, duid->raw_data_len); if (r < 0) - return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IAID+DUID: %m"); + return r; break; } case DHCP_CLIENT_ID_MAC: { diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 00c767e1fb8..95b13ca93c6 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -555,13 +555,26 @@ static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) { } duid = link_get_dhcp6_duid(link); - if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) - r = sd_dhcp6_client_set_duid_llt(client, duid->llt_time); + + if (duid->raw_data_len == 0) + switch (duid->type) { + case DUID_TYPE_LLT: + r = sd_dhcp6_client_set_duid_llt(client, duid->llt_time); + break; + case DUID_TYPE_LL: + r = sd_dhcp6_client_set_duid_ll(client); + break; + case DUID_TYPE_EN: + r = sd_dhcp6_client_set_duid_en(client); + break; + case DUID_TYPE_UUID: + r = sd_dhcp6_client_set_duid_uuid(client); + break; + default: + r = sd_dhcp6_client_set_duid_raw(client, duid->type, NULL, 0); + } else - r = sd_dhcp6_client_set_duid(client, - duid->type, - duid->raw_data_len > 0 ? duid->raw_data : NULL, - duid->raw_data_len); + r = sd_dhcp6_client_set_duid_raw(client, duid->type, duid->raw_data, duid->raw_data_len); if (r < 0) return r; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 7339bb68724..ddd445c9f05 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -257,18 +257,30 @@ int sd_dhcp_client_set_client_id( uint8_t type, const uint8_t *data, size_t data_len); -__extension__ int sd_dhcp_client_set_iaid_duid( - sd_dhcp_client *client, - bool iaid_set, - uint32_t iaid, - uint16_t duid_type, - const void *duid, - size_t duid_len); __extension__ int sd_dhcp_client_set_iaid_duid_llt( sd_dhcp_client *client, bool iaid_set, uint32_t iaid, uint64_t llt_time); +__extension__ int sd_dhcp_client_set_iaid_duid_ll( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid); +__extension__ int sd_dhcp_client_set_iaid_duid_en( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid); +__extension__ int sd_dhcp_client_set_iaid_duid_uuid( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid); +__extension__ int sd_dhcp_client_set_iaid_duid_raw( + sd_dhcp_client *client, + bool iaid_set, + uint32_t iaid, + uint16_t duid_type, + const uint8_t *duid, + size_t duid_len); int sd_dhcp_client_get_client_id( sd_dhcp_client *client, uint8_t *ret_type, diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index a9fa78569d2..c85c5652c48 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -211,14 +211,11 @@ int sd_dhcp6_client_set_mac( const uint8_t *addr, size_t addr_len, uint16_t arp_type); -int sd_dhcp6_client_set_duid( - sd_dhcp6_client *client, - uint16_t duid_type, - const void *duid, - size_t duid_len); -int sd_dhcp6_client_set_duid_llt( - sd_dhcp6_client *client, - uint64_t llt_time); +int sd_dhcp6_client_set_duid_llt(sd_dhcp6_client *client, uint64_t llt_time); +int sd_dhcp6_client_set_duid_ll(sd_dhcp6_client *client); +int sd_dhcp6_client_set_duid_en(sd_dhcp6_client *client); +int sd_dhcp6_client_set_duid_uuid(sd_dhcp6_client *client); +int sd_dhcp6_client_set_duid_raw(sd_dhcp6_client *client, uint16_t duid_type, const uint8_t *duid, size_t duid_len); int sd_dhcp6_client_set_iaid( sd_dhcp6_client *client, uint32_t iaid);