return 1;
}
-static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix) {
+static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, usec_t timestamp_usec, uint32_t lifetime_sec) {
_cleanup_(route_freep) Route *route = NULL;
Route *existing;
int r;
route->dst_prefixlen = 64;
route->protocol = RTPROT_DHCP;
route->priority = link->network->dhcp6_pd_route_metric;
+ route->lifetime = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
if (route_get(NULL, link, route, &existing) < 0)
link->dhcp6_pd_configured = false;
static int dhcp6_pd_assign_prefix(
Link *link,
const struct in6_addr *prefix,
+ usec_t timestamp_usec,
uint32_t lifetime_preferred,
uint32_t lifetime_valid) {
return r;
}
- r = dhcp6_pd_request_route(link, prefix);
+ r = dhcp6_pd_request_route(link, prefix, timestamp_usec, lifetime_valid);
if (r < 0)
return r;
Link *dhcp6_link,
const struct in6_addr *pd_prefix,
uint8_t pd_prefix_len,
+ usec_t timestamp_usec,
uint32_t lifetime_preferred,
uint32_t lifetime_valid,
bool assign_preferred_subnet_id) {
continue;
(void) in6_addr_prefix_to_string(&assigned_prefix, 64, &buf);
- r = dhcp6_pd_assign_prefix(link, &assigned_prefix, lifetime_preferred, lifetime_valid);
+ r = dhcp6_pd_assign_prefix(link, &assigned_prefix, timestamp_usec, lifetime_preferred, lifetime_valid);
if (r < 0) {
log_link_warning_errno(link, r, "Failed to assign/update prefix %s: %m", strna(buf));
if (link == dhcp6_link)
return 1;
}
-static int dhcp6_request_unreachable_route(Link *link, const struct in6_addr *addr, uint8_t prefixlen) {
+static int dhcp6_request_unreachable_route(Link *link, const struct in6_addr *addr, uint8_t prefixlen, usec_t timestamp_usec, uint32_t lifetime_sec) {
_cleanup_(route_freep) Route *route = NULL;
_cleanup_free_ char *buf = NULL;
Route *existing;
route->table = link_get_dhcp6_route_table(link);
route->type = RTN_UNREACHABLE;
route->protocol = RTPROT_DHCP;
+ route->lifetime = usec_add(timestamp_usec, lifetime_sec * USEC_PER_SEC);
if (route_get(link->manager, NULL, route, &existing) < 0)
link->dhcp6_configured = false;
}
static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
+ usec_t timestamp_usec;
Link *link;
int r;
assert(dhcp6_link);
assert(dhcp6_link->dhcp6_lease);
+ r = sd_dhcp6_lease_get_timestamp(dhcp6_link->dhcp6_lease, clock_boottime_or_monotonic(), ×tamp_usec);
+ if (r < 0)
+ return log_link_warning_errno(dhcp6_link, r, "Failed to get timestamp of DHCPv6 lease: %m");
+
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
if (link == dhcp6_link)
continue;
if (r == 0)
continue;
- r = dhcp6_request_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
+ r = dhcp6_request_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len, timestamp_usec, lifetime_valid);
if (r < 0)
return r;
r = dhcp6_pd_prefix_distribute(dhcp6_link,
&pd_prefix,
pd_prefix_len,
+ timestamp_usec,
lifetime_preferred,
lifetime_valid,
true);
r = dhcp6_pd_prefix_distribute(dhcp6_link,
&pd_prefix,
pd_prefix_len,
+ timestamp_usec,
lifetime_preferred,
lifetime_valid,
false);