From fb70992d3973cf09f421260780c4ac96b99467e7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 5 Sep 2023 03:11:53 +0900 Subject: [PATCH 1/4] sd-dhcp6-client: introduce sd_dhcp6_lease_has_pd_prefix() and friend No functional change, just refactoring. --- src/libsystemd-network/sd-dhcp6-lease.c | 8 ++++++++ src/libsystemd-network/test-dhcp6-client.c | 3 +++ src/network/networkd-dhcp-prefix-delegation.c | 18 +----------------- src/network/networkd-dhcp-prefix-delegation.h | 1 - src/network/networkd-dhcp6.c | 6 +++--- src/network/networkd-json.c | 3 ++- src/network/networkd-link.c | 2 +- src/systemd/sd-dhcp6-lease.h | 2 ++ 8 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 6dcc25888d..9d1c69ed3f 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -243,6 +243,10 @@ void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) { lease->addr_iter = lease->ia_na ? lease->ia_na->addresses : NULL; } +int sd_dhcp6_lease_has_address(sd_dhcp6_lease *lease) { + return lease && lease->ia_na; +} + int sd_dhcp6_lease_get_pd( sd_dhcp6_lease *lease, struct in6_addr *ret_prefix, @@ -273,6 +277,10 @@ void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) { lease->prefix_iter = lease->ia_pd ? lease->ia_pd->addresses : NULL; } +int sd_dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) { + return lease && lease->ia_pd; +} + int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) { assert(lease); assert(optval || optlen == 0); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index ccf9208d43..a954bfb666 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -902,6 +902,9 @@ static void test_lease_managed(sd_dhcp6_client *client) { assert_se(dhcp6_lease_get_serverid(lease, &id, &len) >= 0); assert_se(memcmp_nn(id, len, server_id, sizeof(server_id)) == 0); + assert_se(sd_dhcp6_lease_has_address(lease)); + assert_se(sd_dhcp6_lease_has_pd_prefix(lease)); + sd_dhcp6_lease_reset_address_iter(lease); assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) >= 0); assert_se(in6_addr_equal(&addr, &ia_na_address1)); diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index c6e6857aa4..0051a7ee44 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -51,19 +51,6 @@ bool dhcp_pd_is_uplink(Link *link, Link *target, bool accept_auto) { return accept_auto; } -bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) { - uint32_t lifetime_preferred_sec, lifetime_valid_sec; - struct in6_addr pd_prefix; - uint8_t pd_prefix_len; - - if (!lease) - return false; - - sd_dhcp6_lease_reset_pd_prefix_iter(lease); - - return sd_dhcp6_lease_get_pd(lease, &pd_prefix, &pd_prefix_len, &lifetime_preferred_sec, &lifetime_valid_sec) >= 0; -} - static void link_remove_dhcp_pd_subnet_prefix(Link *link, const struct in6_addr *prefix) { void *key; @@ -1154,10 +1141,7 @@ static bool dhcp6_pd_uplink_is_ready(Link *link) { if (sd_dhcp6_client_is_running(link->dhcp6_client) <= 0) return false; - if (!link->dhcp6_lease) - return false; - - return dhcp6_lease_has_pd_prefix(link->dhcp6_lease); + return sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease); } int dhcp_pd_find_uplink(Link *link, Link **ret) { diff --git a/src/network/networkd-dhcp-prefix-delegation.h b/src/network/networkd-dhcp-prefix-delegation.h index b12e985bec..e591b8ae2e 100644 --- a/src/network/networkd-dhcp-prefix-delegation.h +++ b/src/network/networkd-dhcp-prefix-delegation.h @@ -13,7 +13,6 @@ typedef struct Link Link; bool link_dhcp_pd_is_enabled(Link *link); bool dhcp_pd_is_uplink(Link *link, Link *target, bool accept_auto); int dhcp_pd_find_uplink(Link *link, Link **ret); -bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease); int dhcp_pd_remove(Link *link, bool only_marked); int dhcp_request_prefix_delegation(Link *link); int dhcp4_pd_prefix_acquired(Link *uplink); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 57e1087211..e30344fb4f 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -317,11 +317,11 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) { if (r < 0) return r; - if (dhcp6_lease_has_pd_prefix(lease)) { + if (sd_dhcp6_lease_has_pd_prefix(lease)) { r = dhcp6_pd_prefix_acquired(link); if (r < 0) return r; - } else if (dhcp6_lease_has_pd_prefix(lease_old)) + } else if (sd_dhcp6_lease_has_pd_prefix(lease_old)) /* When we had PD prefixes but not now, we need to remove them. */ dhcp_pd_prefix_lost(link); @@ -353,7 +353,7 @@ static int dhcp6_lease_lost(Link *link) { log_link_info(link, "DHCPv6 lease lost"); - if (dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) + if (sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) dhcp_pd_prefix_lost(link); link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease); diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 1e425fcb29..e4db7ef75d 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -1084,7 +1084,8 @@ static int dhcp6_client_pd_append_json(Link *link, JsonVariant **v) { assert(link->network); assert(v); - if (!link->network->dhcp6_use_pd_prefix || !link->dhcp6_lease || !dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) + if (!link->network->dhcp6_use_pd_prefix || + !sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) return 0; sd_dhcp6_lease_reset_pd_prefix_iter(link->dhcp6_lease); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index eea47f6c8c..a3b6762dc4 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -485,7 +485,7 @@ void link_check_ready(Link *link) { } if (link_dhcp6_enabled(link) && link->network->dhcp6_use_pd_prefix && - link->dhcp6_lease && dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) { + sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) { if (!dhcp6_ready) return (void) log_link_debug(link, "%s(): DHCPv6 IA_PD prefix is assigned, but DHCPv6 protocol is not finished yet.", __func__); if (!dhcp_pd_ready) diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h index 9f52496985..dc226ebc99 100644 --- a/src/systemd/sd-dhcp6-lease.h +++ b/src/systemd/sd-dhcp6-lease.h @@ -37,11 +37,13 @@ int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr, uint32_t *lifetime_preferred, uint32_t *lifetime_valid); +int sd_dhcp6_lease_has_address(sd_dhcp6_lease *lease); void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease); int sd_dhcp6_lease_get_pd(sd_dhcp6_lease *lease, struct in6_addr *prefix, uint8_t *prefix_len, uint32_t *lifetime_preferred, uint32_t *lifetime_valid); +int sd_dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease); int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret); int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret); From d8ec95c7ff0029b56492008ce3268542ff02a977 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 5 Sep 2023 03:12:46 +0900 Subject: [PATCH 2/4] sd-dhcp6-client: rework IA_NA or IA_PD getters This splits sd_dhcp6_lease_get_address() into small pieces, and introduce FOREACH_DHCP6_ADDRESS() macro. Also, the lifetimes provided by _get_address_lifetime() are now in usec, and _get_address_lifetime_timestamp() provides timestamp. The same change is also applied for IA_PD. --- src/libsystemd-network/dhcp6-lease-internal.h | 14 ++ src/libsystemd-network/sd-dhcp6-lease.c | 143 ++++++++++++++---- src/libsystemd-network/test-dhcp6-client.c | 78 ++++------ src/network/networkd-dhcp-prefix-delegation.c | 47 +++--- src/network/networkd-dhcp6.c | 25 ++- src/network/networkd-json.c | 34 ++--- src/systemd/sd-dhcp6-lease.h | 40 +++-- 7 files changed, 238 insertions(+), 143 deletions(-) diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index 470fc79870..c1eb23eba1 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -72,3 +72,17 @@ int dhcp6_lease_new_from_message( const triple_timestamp *timestamp, const struct in6_addr *server_address, sd_dhcp6_lease **ret); + +#define _FOREACH_DHCP6_ADDRESS(lease, it) \ + for (int it = sd_dhcp6_lease_address_iterator_reset(lease); \ + it > 0; \ + it = sd_dhcp6_lease_address_iterator_next(lease)) +#define FOREACH_DHCP6_ADDRESS(lease) \ + _FOREACH_DHCP6_ADDRESS(lease, UNIQ_T(i, UNIQ)) + +#define _FOREACH_DHCP6_PD_PREFIX(lease, it) \ + for (int it = sd_dhcp6_lease_pd_iterator_reset(lease); \ + it > 0; \ + it = sd_dhcp6_lease_pd_iterator_next(lease)) +#define FOREACH_DHCP6_PD_PREFIX(lease) \ + _FOREACH_DHCP6_PD_PREFIX(lease, UNIQ_T(i, UNIQ)) diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 9d1c69ed3f..2be084d45c 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -8,6 +8,7 @@ #include "alloc-util.h" #include "dhcp6-internal.h" #include "dhcp6-lease-internal.h" +#include "network-common.h" #include "strv.h" #define IRT_DEFAULT (1 * USEC_PER_DAY) @@ -216,67 +217,149 @@ int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *ret) { return 0; } -int sd_dhcp6_lease_get_address( +int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *ret) { + assert_return(lease, -EINVAL); + + if (!lease->addr_iter) + return -ENODATA; + + if (ret) + *ret = lease->addr_iter->iaaddr.address; + return 0; +} + +int sd_dhcp6_lease_get_address_lifetime( sd_dhcp6_lease *lease, - struct in6_addr *ret_addr, - uint32_t *ret_lifetime_preferred, - uint32_t *ret_lifetime_valid) { + usec_t *ret_lifetime_preferred, + usec_t *ret_lifetime_valid) { + + const struct iaaddr *a; assert_return(lease, -EINVAL); if (!lease->addr_iter) return -ENODATA; - if (ret_addr) - *ret_addr = lease->addr_iter->iaaddr.address; - if (ret_lifetime_preferred) - *ret_lifetime_preferred = be32toh(lease->addr_iter->iaaddr.lifetime_preferred); - if (ret_lifetime_valid) - *ret_lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid); + a = &lease->addr_iter->iaaddr; - lease->addr_iter = lease->addr_iter->addresses_next; + if (ret_lifetime_preferred) + *ret_lifetime_preferred = be32_sec_to_usec(a->lifetime_preferred, /* max_as_infinity = */ true); + if (ret_lifetime_valid) + *ret_lifetime_valid = be32_sec_to_usec(a->lifetime_valid, /* max_as_infinity = */ true); return 0; } -void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) { - if (lease) - lease->addr_iter = lease->ia_na ? lease->ia_na->addresses : NULL; +int sd_dhcp6_lease_address_iterator_reset(sd_dhcp6_lease *lease) { + if (!lease) + return false; + + lease->addr_iter = lease->ia_na ? lease->ia_na->addresses : NULL; + return !!lease->addr_iter; +} + +int sd_dhcp6_lease_address_iterator_next(sd_dhcp6_lease *lease) { + if (!lease || !lease->addr_iter) + return false; + + lease->addr_iter = lease->addr_iter->addresses_next; + return !!lease->addr_iter; } int sd_dhcp6_lease_has_address(sd_dhcp6_lease *lease) { return lease && lease->ia_na; } -int sd_dhcp6_lease_get_pd( +int sd_dhcp6_lease_get_pd_prefix( sd_dhcp6_lease *lease, struct in6_addr *ret_prefix, - uint8_t *ret_prefix_len, - uint32_t *ret_lifetime_preferred, - uint32_t *ret_lifetime_valid) { + uint8_t *ret_prefix_len) { + + const struct iapdprefix *a; assert_return(lease, -EINVAL); if (!lease->prefix_iter) return -ENODATA; - if (ret_prefix) - *ret_prefix = lease->prefix_iter->iapdprefix.address; - if (ret_prefix_len) - *ret_prefix_len = lease->prefix_iter->iapdprefix.prefixlen; - if (ret_lifetime_preferred) - *ret_lifetime_preferred = be32toh(lease->prefix_iter->iapdprefix.lifetime_preferred); - if (ret_lifetime_valid) - *ret_lifetime_valid = be32toh(lease->prefix_iter->iapdprefix.lifetime_valid); + a = &lease->prefix_iter->iapdprefix; - lease->prefix_iter = lease->prefix_iter->addresses_next; + if (ret_prefix) + *ret_prefix = a->address; + if (ret_prefix_len) + *ret_prefix_len = a->prefixlen; return 0; } -void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease) { - if (lease) - lease->prefix_iter = lease->ia_pd ? lease->ia_pd->addresses : NULL; +int sd_dhcp6_lease_get_pd_lifetime( + sd_dhcp6_lease *lease, + uint64_t *ret_lifetime_preferred, + uint64_t *ret_lifetime_valid) { + + const struct iapdprefix *a; + + assert_return(lease, -EINVAL); + + if (!lease->prefix_iter) + return -ENODATA; + + a = &lease->prefix_iter->iapdprefix; + + if (ret_lifetime_preferred) + *ret_lifetime_preferred = be32_sec_to_usec(a->lifetime_preferred, /* max_as_infinity = */ true); + if (ret_lifetime_valid) + *ret_lifetime_valid = be32_sec_to_usec(a->lifetime_valid, /* max_as_infinity = */ true); + return 0; } +int sd_dhcp6_lease_pd_iterator_reset(sd_dhcp6_lease *lease) { + if (!lease) + return false; + + lease->prefix_iter = lease->ia_pd ? lease->ia_pd->addresses : NULL; + return !!lease->prefix_iter; +} + +int sd_dhcp6_lease_pd_iterator_next(sd_dhcp6_lease *lease) { + if (!lease || !lease->prefix_iter) + return false; + + lease->prefix_iter = lease->prefix_iter->addresses_next; + return !!lease->prefix_iter; +} + +#define DEFINE_GET_TIMESTAMP2(name) \ + int sd_dhcp6_lease_get_##name##_lifetime_timestamp( \ + sd_dhcp6_lease *lease, \ + clockid_t clock, \ + uint64_t *ret_lifetime_preferred, \ + uint64_t *ret_lifetime_valid) { \ + \ + usec_t t, p, v; \ + int r; \ + \ + assert_return(lease, -EINVAL); \ + \ + r = sd_dhcp6_lease_get_##name##_lifetime( \ + lease, \ + ret_lifetime_preferred ? &p : NULL, \ + ret_lifetime_valid ? &v : NULL); \ + if (r < 0) \ + return r; \ + \ + r = sd_dhcp6_lease_get_timestamp(lease, clock, &t); \ + if (r < 0) \ + return r; \ + \ + if (ret_lifetime_preferred) \ + *ret_lifetime_preferred = time_span_to_stamp(p, t); \ + if (ret_lifetime_valid) \ + *ret_lifetime_valid = time_span_to_stamp(v, t); \ + return 0; \ + } + +DEFINE_GET_TIMESTAMP2(address); +DEFINE_GET_TIMESTAMP2(pd); + int sd_dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) { return lease && lease->ia_pd; } diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index a954bfb666..7c253b5e5f 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -893,7 +893,7 @@ static void test_lease_common(sd_dhcp6_client *client) { static void test_lease_managed(sd_dhcp6_client *client) { sd_dhcp6_lease *lease; struct in6_addr addr; - uint32_t lt_pref, lt_valid; + usec_t lt_pref, lt_valid; uint8_t *id, prefixlen; size_t len; @@ -905,53 +905,37 @@ static void test_lease_managed(sd_dhcp6_client *client) { assert_se(sd_dhcp6_lease_has_address(lease)); assert_se(sd_dhcp6_lease_has_pd_prefix(lease)); - sd_dhcp6_lease_reset_address_iter(lease); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_na_address1)); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_na_address2)); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENODATA); + for (unsigned i = 0; i < 2; i++) { + assert_se(sd_dhcp6_lease_address_iterator_reset(lease)); + assert_se(sd_dhcp6_lease_get_address(lease, &addr) >= 0); + assert_se(sd_dhcp6_lease_get_address_lifetime(lease, <_pref, <_valid) >= 0); + assert_se(in6_addr_equal(&addr, &ia_na_address1)); + assert_se(lt_pref == 150 * USEC_PER_SEC); + assert_se(lt_valid == 180 * USEC_PER_SEC); + assert_se(sd_dhcp6_lease_address_iterator_next(lease)); + assert_se(sd_dhcp6_lease_get_address(lease, &addr) >= 0); + assert_se(sd_dhcp6_lease_get_address_lifetime(lease, <_pref, <_valid) >= 0); + assert_se(in6_addr_equal(&addr, &ia_na_address2)); + assert_se(lt_pref == 150 * USEC_PER_SEC); + assert_se(lt_valid == 180 * USEC_PER_SEC); + assert_se(!sd_dhcp6_lease_address_iterator_next(lease)); - sd_dhcp6_lease_reset_address_iter(lease); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_na_address1)); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_na_address2)); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENODATA); - - sd_dhcp6_lease_reset_pd_prefix_iter(lease); - assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_pd_prefix1)); - assert_se(prefixlen == 64); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_pd_prefix2)); - assert_se(prefixlen == 64); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENODATA); - - sd_dhcp6_lease_reset_pd_prefix_iter(lease); - assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_pd_prefix1)); - assert_se(prefixlen == 64); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_pd(lease, &addr, &prefixlen, <_pref, <_valid) >= 0); - assert_se(in6_addr_equal(&addr, &ia_pd_prefix2)); - assert_se(prefixlen == 64); - assert_se(lt_pref == 150); - assert_se(lt_valid == 180); - assert_se(sd_dhcp6_lease_get_address(lease, &addr, <_pref, <_valid) == -ENODATA); + assert_se(sd_dhcp6_lease_pd_iterator_reset(lease)); + assert_se(sd_dhcp6_lease_get_pd_prefix(lease, &addr, &prefixlen) >= 0); + assert_se(sd_dhcp6_lease_get_pd_lifetime(lease, <_pref, <_valid) >= 0); + assert_se(in6_addr_equal(&addr, &ia_pd_prefix1)); + assert_se(prefixlen == 64); + assert_se(lt_pref == 150 * USEC_PER_SEC); + assert_se(lt_valid == 180 * USEC_PER_SEC); + assert_se(sd_dhcp6_lease_pd_iterator_next(lease)); + assert_se(sd_dhcp6_lease_get_pd_prefix(lease, &addr, &prefixlen) >= 0); + assert_se(sd_dhcp6_lease_get_pd_lifetime(lease, <_pref, <_valid) >= 0); + assert_se(in6_addr_equal(&addr, &ia_pd_prefix2)); + assert_se(prefixlen == 64); + assert_se(lt_pref == 150 * USEC_PER_SEC); + assert_se(lt_valid == 180 * USEC_PER_SEC); + assert_se(!sd_dhcp6_lease_pd_iterator_next(lease)); + } test_lease_common(client); } diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index 0051a7ee44..56bbc4acc5 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -2,8 +2,7 @@ #include -#include "sd-dhcp6-client.h" - +#include "dhcp6-lease-internal.h" #include "hashmap.h" #include "in-addr-prefix-util.h" #include "networkd-address-generation.h" @@ -993,7 +992,6 @@ int dhcp4_pd_prefix_acquired(Link *uplink) { } static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) { - usec_t timestamp_usec; int r; assert(link); @@ -1004,19 +1002,14 @@ static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) { if (r <= 0) return r; - r = sd_dhcp6_lease_get_timestamp(uplink->dhcp6_lease, CLOCK_BOOTTIME, ×tamp_usec); - if (r < 0) - return r; - - for (sd_dhcp6_lease_reset_pd_prefix_iter(uplink->dhcp6_lease);;) { - uint32_t lifetime_preferred_sec, lifetime_valid_sec; + FOREACH_DHCP6_PD_PREFIX(uplink->dhcp6_lease) { + usec_t lifetime_preferred_usec, lifetime_valid_usec; struct in6_addr pd_prefix; uint8_t pd_prefix_len; - r = sd_dhcp6_lease_get_pd(uplink->dhcp6_lease, &pd_prefix, &pd_prefix_len, - &lifetime_preferred_sec, &lifetime_valid_sec); + r = sd_dhcp6_lease_get_pd_prefix(uplink->dhcp6_lease, &pd_prefix, &pd_prefix_len); if (r < 0) - break; + return r; if (pd_prefix_len > 64) continue; @@ -1026,9 +1019,13 @@ static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) { if (r < 0) return r; + r = sd_dhcp6_lease_get_pd_lifetime_timestamp(uplink->dhcp6_lease, CLOCK_BOOTTIME, + &lifetime_preferred_usec, &lifetime_valid_usec); + if (r < 0) + return r; + r = dhcp_pd_assign_subnet_prefix(link, &pd_prefix, pd_prefix_len, - sec_to_usec(lifetime_preferred_sec, timestamp_usec), - sec_to_usec(lifetime_valid_sec, timestamp_usec), + lifetime_preferred_usec, lifetime_valid_usec, /* is_uplink = */ link == uplink); if (r < 0) return r; @@ -1039,7 +1036,6 @@ static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) { int dhcp6_pd_prefix_acquired(Link *uplink) { union in_addr_union server_address; - usec_t timestamp_usec; Link *link; int r; @@ -1050,20 +1046,15 @@ int dhcp6_pd_prefix_acquired(Link *uplink) { if (r < 0) return log_link_warning_errno(uplink, r, "Failed to get server address of DHCPv6 lease: %m"); - r = sd_dhcp6_lease_get_timestamp(uplink->dhcp6_lease, CLOCK_BOOTTIME, ×tamp_usec); - if (r < 0) - return log_link_warning_errno(uplink, r, "Failed to get timestamp of DHCPv6 lease: %m"); - /* First, logs acquired prefixes and request unreachable routes. */ - for (sd_dhcp6_lease_reset_pd_prefix_iter(uplink->dhcp6_lease);;) { - uint32_t lifetime_preferred_sec, lifetime_valid_sec; + FOREACH_DHCP6_PD_PREFIX(uplink->dhcp6_lease) { + usec_t lifetime_valid_usec; struct in6_addr pd_prefix; uint8_t pd_prefix_len; - r = sd_dhcp6_lease_get_pd(uplink->dhcp6_lease, &pd_prefix, &pd_prefix_len, - &lifetime_preferred_sec, &lifetime_valid_sec); + r = sd_dhcp6_lease_get_pd_prefix(uplink->dhcp6_lease, &pd_prefix, &pd_prefix_len); if (r < 0) - break; + return r; /* Mask prefix for safety. */ r = in6_addr_mask(&pd_prefix, pd_prefix_len); @@ -1074,9 +1065,13 @@ int dhcp6_pd_prefix_acquired(Link *uplink) { if (r < 0) return r; + r = sd_dhcp6_lease_get_pd_lifetime_timestamp(uplink->dhcp6_lease, CLOCK_BOOTTIME, + NULL, &lifetime_valid_usec); + if (r < 0) + return r; + r = dhcp6_request_unreachable_route(uplink, &pd_prefix, pd_prefix_len, - sec_to_usec(lifetime_valid_sec, timestamp_usec), - &server_address); + lifetime_valid_usec, &server_address); if (r < 0) return r; } diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index e30344fb4f..5c5dff9413 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -3,9 +3,8 @@ Copyright © 2014 Intel Corporation. All rights reserved. ***/ -#include "sd-dhcp6-client.h" - #include "dhcp6-client-internal.h" +#include "dhcp6-lease-internal.h" #include "hashmap.h" #include "hostname-setup.h" #include "hostname-util.h" @@ -242,7 +241,6 @@ static int dhcp6_request_address( static int dhcp6_address_acquired(Link *link) { struct in6_addr server_address; - usec_t timestamp_usec; int r; assert(link); @@ -256,21 +254,22 @@ static int dhcp6_address_acquired(Link *link) { if (r < 0) return log_link_warning_errno(link, r, "Failed to get server address of DHCPv6 lease: %m"); - r = sd_dhcp6_lease_get_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, ×tamp_usec); - if (r < 0) - return log_link_warning_errno(link, r, "Failed to get timestamp of DHCPv6 lease: %m"); - - for (sd_dhcp6_lease_reset_address_iter(link->dhcp6_lease);;) { - uint32_t lifetime_preferred_sec, lifetime_valid_sec; + FOREACH_DHCP6_ADDRESS(link->dhcp6_lease) { + usec_t lifetime_preferred_usec, lifetime_valid_usec; struct in6_addr ip6_addr; - r = sd_dhcp6_lease_get_address(link->dhcp6_lease, &ip6_addr, &lifetime_preferred_sec, &lifetime_valid_sec); + r = sd_dhcp6_lease_get_address(link->dhcp6_lease, &ip6_addr); if (r < 0) - break; + return r; + + r = sd_dhcp6_lease_get_address_lifetime_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, + &lifetime_preferred_usec, &lifetime_valid_usec); + if (r < 0) + return r; r = dhcp6_request_address(link, &server_address, &ip6_addr, - sec_to_usec(lifetime_preferred_sec, timestamp_usec), - sec_to_usec(lifetime_valid_sec, timestamp_usec)); + lifetime_preferred_usec, + lifetime_valid_usec); if (r < 0) return r; } diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index e4db7ef75d..0b2f6e68b8 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -9,7 +9,6 @@ #include "netif-util.h" #include "networkd-address.h" #include "networkd-dhcp-common.h" -#include "networkd-dhcp-prefix-delegation.h" #include "networkd-json.h" #include "networkd-link.h" #include "networkd-manager.h" @@ -1046,7 +1045,7 @@ static int dhcp_server_append_json(Link *link, JsonVariant **v) { static int dhcp6_client_lease_append_json(Link *link, JsonVariant **v) { _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; - uint64_t lease_timestamp_usec; + usec_t lease_timestamp_usec; int r; assert(link); @@ -1061,9 +1060,9 @@ static int dhcp6_client_lease_append_json(Link *link, JsonVariant **v) { r = json_build(&w, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_FINITE_USEC("Timeout1USec", - link->dhcp6_lease->lifetime_t1 + lease_timestamp_usec), + usec_add(link->dhcp6_lease->lifetime_t1, lease_timestamp_usec)), JSON_BUILD_PAIR_FINITE_USEC("Timeout2USec", - link->dhcp6_lease->lifetime_t2 + lease_timestamp_usec), + usec_add(link->dhcp6_lease->lifetime_t2, lease_timestamp_usec)), JSON_BUILD_PAIR_FINITE_USEC("LeaseTimestampUSec", lease_timestamp_usec))); if (r < 0) @@ -1074,10 +1073,6 @@ static int dhcp6_client_lease_append_json(Link *link, JsonVariant **v) { static int dhcp6_client_pd_append_json(Link *link, JsonVariant **v) { _cleanup_(json_variant_unrefp) JsonVariant *array = NULL; - struct in6_addr prefix; - uint32_t lifetime_preferred, lifetime_valid; - uint8_t prefix_len; - uint64_t lease_timestamp_usec; int r; assert(link); @@ -1088,20 +1083,25 @@ static int dhcp6_client_pd_append_json(Link *link, JsonVariant **v) { !sd_dhcp6_lease_has_pd_prefix(link->dhcp6_lease)) return 0; - sd_dhcp6_lease_reset_pd_prefix_iter(link->dhcp6_lease); + FOREACH_DHCP6_PD_PREFIX(link->dhcp6_lease) { + usec_t lifetime_preferred_usec, lifetime_valid_usec; + struct in6_addr prefix; + uint8_t prefix_len; - r = sd_dhcp6_lease_get_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, &lease_timestamp_usec); - if (r < 0) - return 0; + r = sd_dhcp6_lease_get_pd_prefix(link->dhcp6_lease, &prefix, &prefix_len); + if (r < 0) + return r; + + r = sd_dhcp6_lease_get_pd_lifetime_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, + &lifetime_preferred_usec, &lifetime_valid_usec); + if (r < 0) + return r; - while (sd_dhcp6_lease_get_pd(link->dhcp6_lease, &prefix, &prefix_len, &lifetime_preferred, &lifetime_valid) >= 0) { r = json_variant_append_arrayb(&array, JSON_BUILD_OBJECT( JSON_BUILD_PAIR_IN6_ADDR("Prefix", &prefix), JSON_BUILD_PAIR_UNSIGNED("PrefixLength", prefix_len), - JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUSec", - sec_to_usec(lifetime_preferred, lease_timestamp_usec)), - JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUSec", - sec_to_usec(lifetime_valid, lease_timestamp_usec)))); + JSON_BUILD_PAIR_FINITE_USEC("PreferredLifetimeUSec", lifetime_preferred_usec), + JSON_BUILD_PAIR_FINITE_USEC("ValidLifetimeUSec", lifetime_valid_usec))); if (r < 0) return r; } diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h index dc226ebc99..607f85428d 100644 --- a/src/systemd/sd-dhcp6-lease.h +++ b/src/systemd/sd-dhcp6-lease.h @@ -32,17 +32,37 @@ typedef struct sd_dhcp6_lease sd_dhcp6_lease; int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *ret); -void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease); -int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, - struct in6_addr *addr, - uint32_t *lifetime_preferred, - uint32_t *lifetime_valid); +int sd_dhcp6_lease_address_iterator_reset(sd_dhcp6_lease *lease); +int sd_dhcp6_lease_address_iterator_next(sd_dhcp6_lease *lease); +int sd_dhcp6_lease_get_address( + sd_dhcp6_lease *lease, + struct in6_addr *ret); +int sd_dhcp6_lease_get_address_lifetime( + sd_dhcp6_lease *lease, + uint64_t *ret_lifetime_preferred, + uint64_t *ret_lifetime_valid); +int sd_dhcp6_lease_get_address_lifetime_timestamp( + sd_dhcp6_lease *lease, + clockid_t clock, + uint64_t *ret_lifetime_preferred, + uint64_t *ret_lifetime_valid); int sd_dhcp6_lease_has_address(sd_dhcp6_lease *lease); -void sd_dhcp6_lease_reset_pd_prefix_iter(sd_dhcp6_lease *lease); -int sd_dhcp6_lease_get_pd(sd_dhcp6_lease *lease, struct in6_addr *prefix, - uint8_t *prefix_len, - uint32_t *lifetime_preferred, - uint32_t *lifetime_valid); + +int sd_dhcp6_lease_pd_iterator_reset(sd_dhcp6_lease *lease); +int sd_dhcp6_lease_pd_iterator_next(sd_dhcp6_lease *lease); +int sd_dhcp6_lease_get_pd_prefix( + sd_dhcp6_lease *lease, + struct in6_addr *ret_prefix, + uint8_t *ret_prefix_length); +int sd_dhcp6_lease_get_pd_lifetime( + sd_dhcp6_lease *lease, + uint64_t *ret_lifetime_preferred, + uint64_t *ret_lifetime_valid); +int sd_dhcp6_lease_get_pd_lifetime_timestamp( + sd_dhcp6_lease *lease, + clockid_t clock, + uint64_t *ret_lifetime_preferred, + uint64_t *ret_lifetime_valid); int sd_dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease); int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret); From 9132cbd5adeae45817fb253a45f7b2b09358d6db Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 5 Sep 2023 15:50:23 +0900 Subject: [PATCH 3/4] sd-dhcp6-client: use be32_sec_to_usec() at more places --- src/libsystemd-network/dhcp6-option.c | 42 ++++++++++++++----------- src/libsystemd-network/sd-dhcp6-lease.c | 26 +++++++-------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c index 76db8717b2..83f40f3f02 100644 --- a/src/libsystemd-network/dhcp6-option.c +++ b/src/libsystemd-network/dhcp6-option.c @@ -15,6 +15,7 @@ #include "dns-domain.h" #include "escape.h" #include "memory-util.h" +#include "network-common.h" #include "strv.h" #include "unaligned.h" @@ -585,7 +586,7 @@ static int dhcp6_option_parse_ia_options(sd_dhcp6_client *client, const uint8_t static int dhcp6_option_parse_ia_address(sd_dhcp6_client *client, DHCP6IA *ia, const uint8_t *data, size_t len) { _cleanup_free_ DHCP6Address *a = NULL; - uint32_t lt_valid, lt_pref; + usec_t lt_valid, lt_pref; int r; assert(ia); @@ -604,17 +605,18 @@ static int dhcp6_option_parse_ia_address(sd_dhcp6_client *client, DHCP6IA *ia, c memcpy(&a->iaaddr, data, sizeof(struct iaaddr)); - lt_valid = be32toh(a->iaaddr.lifetime_valid); - lt_pref = be32toh(a->iaaddr.lifetime_preferred); + lt_valid = be32_sec_to_usec(a->iaaddr.lifetime_valid, /* max_as_infinity = */ true); + lt_pref = be32_sec_to_usec(a->iaaddr.lifetime_preferred, /* max_as_infinity = */ true); if (lt_valid == 0) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Received an IA address with zero valid lifetime, ignoring."); if (lt_pref > lt_valid) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), - "Received an IA address with preferred lifetime %"PRIu32 - " larger than valid lifetime %"PRIu32", ignoring.", - lt_pref, lt_valid); + "Received an IA address with preferred lifetime %s " + "larger than valid lifetime %s, ignoring.", + FORMAT_TIMESPAN(lt_pref, USEC_PER_SEC), + FORMAT_TIMESPAN(lt_valid, USEC_PER_SEC)); if (len > sizeof(struct iaaddr)) { r = dhcp6_option_parse_ia_options(client, data + sizeof(struct iaaddr), len - sizeof(struct iaaddr)); @@ -628,7 +630,7 @@ static int dhcp6_option_parse_ia_address(sd_dhcp6_client *client, DHCP6IA *ia, c static int dhcp6_option_parse_ia_pdprefix(sd_dhcp6_client *client, DHCP6IA *ia, const uint8_t *data, size_t len) { _cleanup_free_ DHCP6Address *a = NULL; - uint32_t lt_valid, lt_pref; + usec_t lt_valid, lt_pref; int r; assert(ia); @@ -647,17 +649,18 @@ static int dhcp6_option_parse_ia_pdprefix(sd_dhcp6_client *client, DHCP6IA *ia, memcpy(&a->iapdprefix, data, sizeof(struct iapdprefix)); - lt_valid = be32toh(a->iapdprefix.lifetime_valid); - lt_pref = be32toh(a->iapdprefix.lifetime_preferred); + lt_valid = be32_sec_to_usec(a->iapdprefix.lifetime_valid, /* max_as_infinity = */ true); + lt_pref = be32_sec_to_usec(a->iapdprefix.lifetime_preferred, /* max_as_infinity = */ true); if (lt_valid == 0) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Received a PD prefix with zero valid lifetime, ignoring."); if (lt_pref > lt_valid) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), - "Received a PD prefix with preferred lifetime %"PRIu32 - " larger than valid lifetime %"PRIu32", ignoring.", - lt_pref, lt_valid); + "Received a PD prefix with preferred lifetime %s " + "larger than valid lifetime %s, ignoring.", + FORMAT_TIMESPAN(lt_pref, USEC_PER_SEC), + FORMAT_TIMESPAN(lt_valid, USEC_PER_SEC)); if (len > sizeof(struct iapdprefix)) { r = dhcp6_option_parse_ia_options(client, data + sizeof(struct iapdprefix), len - sizeof(struct iapdprefix)); @@ -678,7 +681,7 @@ int dhcp6_option_parse_ia( DHCP6IA **ret) { _cleanup_(dhcp6_ia_freep) DHCP6IA *ia = NULL; - uint32_t lt_t1, lt_t2; + usec_t lt_t1, lt_t2; size_t header_len; int r; @@ -728,17 +731,18 @@ int dhcp6_option_parse_ia( "from the one chosen by the client, ignoring."); /* It is not necessary to check if the lifetime_t2 is zero here, as in that case it will be updated later. */ - lt_t1 = be32toh(ia->header.lifetime_t1); - lt_t2 = be32toh(ia->header.lifetime_t2); + lt_t1 = be32_sec_to_usec(ia->header.lifetime_t1, /* max_as_infinity = */ true); + lt_t2 = be32_sec_to_usec(ia->header.lifetime_t2, /* max_as_infinity = */ true); if (lt_t1 > lt_t2) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), - "Received an IA option with T1 %"PRIu32"sec > T2 %"PRIu32"sec, ignoring.", - lt_t1, lt_t2); + "Received an IA option with T1 %s > T2 %s, ignoring.", + FORMAT_TIMESPAN(lt_t1, USEC_PER_SEC), + FORMAT_TIMESPAN(lt_t2, USEC_PER_SEC)); if (lt_t1 == 0 && lt_t2 > 0) return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), - "Received an IA option with zero T1 and non-zero T2 (%"PRIu32"sec), ignoring.", - lt_t2); + "Received an IA option with zero T1 and non-zero T2 (%s), ignoring.", + FORMAT_TIMESPAN(lt_t2, USEC_PER_SEC)); for (size_t offset = header_len; offset < option_data_len;) { const uint8_t *subdata; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 2be084d45c..db9b471961 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -36,30 +36,26 @@ int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_ return 0; } -static usec_t sec2usec(uint32_t sec) { - return sec == UINT32_MAX ? USEC_INFINITY : sec * USEC_PER_SEC; -} - static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) { - uint32_t t1 = UINT32_MAX, t2 = UINT32_MAX, min_valid_lt = UINT32_MAX; + usec_t t1 = USEC_INFINITY, t2 = USEC_INFINITY, min_valid_lt = USEC_INFINITY; assert(lease); assert(lease->ia_na || lease->ia_pd); if (lease->ia_na) { - t1 = MIN(t1, be32toh(lease->ia_na->header.lifetime_t1)); - t2 = MIN(t2, be32toh(lease->ia_na->header.lifetime_t2)); + t1 = MIN(t1, be32_sec_to_usec(lease->ia_na->header.lifetime_t1, /* max_as_infinity = */ true)); + t2 = MIN(t2, be32_sec_to_usec(lease->ia_na->header.lifetime_t2, /* max_as_infinity = */ true)); LIST_FOREACH(addresses, a, lease->ia_na->addresses) - min_valid_lt = MIN(min_valid_lt, be32toh(a->iaaddr.lifetime_valid)); + min_valid_lt = MIN(min_valid_lt, be32_sec_to_usec(a->iaaddr.lifetime_valid, /* max_as_infinity = */ true)); } if (lease->ia_pd) { - t1 = MIN(t1, be32toh(lease->ia_pd->header.lifetime_t1)); - t2 = MIN(t2, be32toh(lease->ia_pd->header.lifetime_t2)); + t1 = MIN(t1, be32_sec_to_usec(lease->ia_pd->header.lifetime_t1, /* max_as_infinity = */ true)); + t2 = MIN(t2, be32_sec_to_usec(lease->ia_pd->header.lifetime_t2, /* max_as_infinity = */ true)); LIST_FOREACH(addresses, a, lease->ia_pd->addresses) - min_valid_lt = MIN(min_valid_lt, be32toh(a->iapdprefix.lifetime_valid)); + min_valid_lt = MIN(min_valid_lt, be32_sec_to_usec(a->iapdprefix.lifetime_valid, /* max_as_infinity = */ true)); } if (t2 == 0 || t2 > min_valid_lt) { @@ -69,9 +65,9 @@ static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) { t2 = min_valid_lt / 10 * 8; } - lease->lifetime_valid = sec2usec(min_valid_lt); - lease->lifetime_t1 = sec2usec(t1); - lease->lifetime_t2 = sec2usec(t2); + lease->lifetime_valid = min_valid_lt; + lease->lifetime_t1 = t1; + lease->lifetime_t2 = t2; } int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid) { @@ -747,7 +743,7 @@ static int dhcp6_lease_parse_message( return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "Received information refresh time option with an invalid length (%zu).", optlen); - irt = unaligned_read_be32(optval) * USEC_PER_SEC; + irt = unaligned_be32_sec_to_usec(optval, /* max_as_infinity = */ false); break; } } From 394fac52d0e79f9cc5b66e85d14a760da425c323 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 5 Sep 2023 15:50:50 +0900 Subject: [PATCH 4/4] sd-dhcp6-client: introduce sd_dhcp6_lease_get_t1() and friends --- src/libsystemd-network/dhcp6-lease-internal.h | 1 - src/libsystemd-network/sd-dhcp6-client.c | 10 +++- src/libsystemd-network/sd-dhcp6-lease.c | 53 ++++++++++++++----- src/network/networkd-json.c | 23 ++++---- src/systemd/sd-dhcp6-lease.h | 6 +++ 5 files changed, 69 insertions(+), 24 deletions(-) diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index c1eb23eba1..0a2434b5ab 100644 --- a/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libsystemd-network/dhcp6-lease-internal.h @@ -47,7 +47,6 @@ struct sd_dhcp6_lease { char *captive_portal; }; -int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid); int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len); int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 120384b3da..4c500fc4a9 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1069,7 +1069,15 @@ static int client_enter_bound_state(sd_dhcp6_client *client) { (void) event_source_disable(client->receive_message); (void) event_source_disable(client->timeout_resend); - r = dhcp6_lease_get_lifetime(client->lease, &lifetime_t1, &lifetime_t2, &lifetime_valid); + r = sd_dhcp6_lease_get_t1(client->lease, &lifetime_t1); + if (r < 0) + goto error; + + r = sd_dhcp6_lease_get_t2(client->lease, &lifetime_t2); + if (r < 0) + goto error; + + r = sd_dhcp6_lease_get_valid_lifetime(client->lease, &lifetime_valid); if (r < 0) goto error; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index db9b471961..3608586e5d 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -70,20 +70,47 @@ static void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) { lease->lifetime_t2 = t2; } -int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2, usec_t *ret_valid) { - assert(lease); +#define DEFINE_GET_TIME_FUNCTIONS(name, val) \ + int sd_dhcp6_lease_get_##name( \ + sd_dhcp6_lease *lease, \ + uint64_t *ret) { \ + \ + assert_return(lease, -EINVAL); \ + \ + if (!lease->ia_na && !lease->ia_pd) \ + return -ENODATA; \ + \ + if (ret) \ + *ret = lease->val; \ + return 0; \ + } \ + \ + int sd_dhcp6_lease_get_##name##_timestamp( \ + sd_dhcp6_lease *lease, \ + clockid_t clock, \ + uint64_t *ret) { \ + \ + usec_t s, t; \ + int r; \ + \ + assert_return(lease, -EINVAL); \ + \ + r = sd_dhcp6_lease_get_##name(lease, &s); \ + if (r < 0) \ + return r; \ + \ + r = sd_dhcp6_lease_get_timestamp(lease, clock, &t); \ + if (r < 0) \ + return r; \ + \ + if (ret) \ + *ret = time_span_to_stamp(s, t); \ + return 0; \ + } - if (!lease->ia_na && !lease->ia_pd) - return -ENODATA; - - if (ret_t1) - *ret_t1 = lease->lifetime_t1; - if (ret_t2) - *ret_t2 = lease->lifetime_t2; - if (ret_valid) - *ret_valid = lease->lifetime_valid; - return 0; -} +DEFINE_GET_TIME_FUNCTIONS(t1, lifetime_t1); +DEFINE_GET_TIME_FUNCTIONS(t2, lifetime_t1); +DEFINE_GET_TIME_FUNCTIONS(valid_lifetime, lifetime_valid); static void dhcp6_lease_set_server_address(sd_dhcp6_lease *lease, const struct in6_addr *server_address) { assert(lease); diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c index 0b2f6e68b8..fc033d0258 100644 --- a/src/network/networkd-json.c +++ b/src/network/networkd-json.c @@ -1045,7 +1045,7 @@ static int dhcp_server_append_json(Link *link, JsonVariant **v) { static int dhcp6_client_lease_append_json(Link *link, JsonVariant **v) { _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; - usec_t lease_timestamp_usec; + usec_t ts, t1, t2; int r; assert(link); @@ -1054,17 +1054,22 @@ static int dhcp6_client_lease_append_json(Link *link, JsonVariant **v) { if (!link->dhcp6_lease) return 0; - r = sd_dhcp6_lease_get_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, &lease_timestamp_usec); + r = sd_dhcp6_lease_get_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, &ts); if (r < 0) - return 0; + return r; + + r = sd_dhcp6_lease_get_t1_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, &t1); + if (r < 0) + return r; + + r = sd_dhcp6_lease_get_t2_timestamp(link->dhcp6_lease, CLOCK_BOOTTIME, &t2); + if (r < 0) + return r; r = json_build(&w, JSON_BUILD_OBJECT( - JSON_BUILD_PAIR_FINITE_USEC("Timeout1USec", - usec_add(link->dhcp6_lease->lifetime_t1, lease_timestamp_usec)), - JSON_BUILD_PAIR_FINITE_USEC("Timeout2USec", - usec_add(link->dhcp6_lease->lifetime_t2, lease_timestamp_usec)), - JSON_BUILD_PAIR_FINITE_USEC("LeaseTimestampUSec", - lease_timestamp_usec))); + JSON_BUILD_PAIR_FINITE_USEC("Timeout1USec", t1), + JSON_BUILD_PAIR_FINITE_USEC("Timeout2USec", t2), + JSON_BUILD_PAIR_FINITE_USEC("LeaseTimestampUSec", ts))); if (r < 0) return r; diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h index 607f85428d..543dc94025 100644 --- a/src/systemd/sd-dhcp6-lease.h +++ b/src/systemd/sd-dhcp6-lease.h @@ -30,6 +30,12 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_dhcp6_lease sd_dhcp6_lease; int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); +int sd_dhcp6_lease_get_t1(sd_dhcp6_lease *lease, uint64_t *ret); +int sd_dhcp6_lease_get_t1_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); +int sd_dhcp6_lease_get_t2(sd_dhcp6_lease *lease, uint64_t *ret); +int sd_dhcp6_lease_get_t2_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); +int sd_dhcp6_lease_get_valid_lifetime(sd_dhcp6_lease *lease, uint64_t *ret); +int sd_dhcp6_lease_get_valid_lifetime_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *ret); int sd_dhcp6_lease_address_iterator_reset(sd_dhcp6_lease *lease);