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))
#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)
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;
}
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;
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);
}
#include <linux/ipv6_route.h>
-#include "sd-dhcp6-client.h"
-
+#include "dhcp6-lease-internal.h"
#include "hashmap.h"
#include "in-addr-prefix-util.h"
#include "networkd-address-generation.h"
}
static int dhcp6_pd_assign_subnet_prefixes(Link *link, Link *uplink) {
- usec_t timestamp_usec;
int r;
assert(link);
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;
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;
int dhcp6_pd_prefix_acquired(Link *uplink) {
union in_addr_union server_address;
- usec_t timestamp_usec;
Link *link;
int r;
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);
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;
}
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"
static int dhcp6_address_acquired(Link *link) {
struct in6_addr server_address;
- usec_t timestamp_usec;
int r;
assert(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;
}
#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"
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);
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)
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);
!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;
}
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);