From: Yu Watanabe Date: Mon, 4 Sep 2023 18:12:46 +0000 (+0900) Subject: sd-dhcp6-client: rework IA_NA or IA_PD getters X-Git-Tag: v255-rc1~470^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8ec95c7ff0029b56492008ce3268542ff02a977;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h index 470fc798709..c1eb23eba1a 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 9d1c69ed3f0..2be084d45cd 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; + a = &lease->addr_iter->iaaddr; + if (ret_lifetime_preferred) - *ret_lifetime_preferred = be32toh(lease->addr_iter->iaaddr.lifetime_preferred); + *ret_lifetime_preferred = be32_sec_to_usec(a->lifetime_preferred, /* max_as_infinity = */ true); if (ret_lifetime_valid) - *ret_lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid); - - lease->addr_iter = lease->addr_iter->addresses_next; + *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; + a = &lease->prefix_iter->iapdprefix; + if (ret_prefix) - *ret_prefix = lease->prefix_iter->iapdprefix.address; + *ret_prefix = a->address; if (ret_prefix_len) - *ret_prefix_len = lease->prefix_iter->iapdprefix.prefixlen; + *ret_prefix_len = a->prefixlen; + return 0; +} + +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 = be32toh(lease->prefix_iter->iapdprefix.lifetime_preferred); + *ret_lifetime_preferred = be32_sec_to_usec(a->lifetime_preferred, /* max_as_infinity = */ true); if (ret_lifetime_valid) - *ret_lifetime_valid = be32toh(lease->prefix_iter->iapdprefix.lifetime_valid); - - lease->prefix_iter = lease->prefix_iter->addresses_next; + *ret_lifetime_valid = be32_sec_to_usec(a->lifetime_valid, /* max_as_infinity = */ true); 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_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 a954bfb6668..7c253b5e5f7 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); - - 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); + 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)); + + 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 0051a7ee44b..56bbc4acc54 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 e30344fb4fe..5c5dff9413d 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 e4db7ef75d7..0b2f6e68b81 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 dc226ebc997..607f85428d4 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);