You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
2.6 KiB
Diff
56 lines
2.6 KiB
Diff
commit b09851c2be354e592802fe9209b4cd6150bd818d
|
|
Author: Felix Stupp <felix.stupp@banananet.work>
|
|
Date: Tue Sep 3 20:33:03 2024 +0000
|
|
|
|
network/radv: fade out announced prefixes rather than just deleting them
|
|
|
|
Fixes https://github.com/systemd/systemd/issues/29651
|
|
|
|
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c
|
|
index c384d4e627..537203c13b 100644
|
|
--- a/src/libsystemd-network/sd-radv.c
|
|
+++ b/src/libsystemd-network/sd-radv.c
|
|
@@ -679,6 +679,8 @@ void sd_radv_remove_prefix(
|
|
if (!prefix)
|
|
return;
|
|
|
|
+ const char *addr_p = IN6_ADDR_PREFIX_TO_STRING(prefix, prefixlen);
|
|
+
|
|
LIST_FOREACH(prefix, cur, ra->prefixes) {
|
|
if (prefixlen != cur->opt.prefixlen)
|
|
continue;
|
|
@@ -686,9 +688,32 @@ void sd_radv_remove_prefix(
|
|
if (!in6_addr_equal(prefix, &cur->opt.in6_addr))
|
|
continue;
|
|
|
|
+ /* "Fade out" IPv6 prefix, i.e. informing clients about its sudden invalidity.
|
|
+ * Realized by announcing the prefix with preferred=0 & valid=2h.
|
|
+ * This makes clients rotating to a newer prefix if some is already defined.
|
|
+ */
|
|
+
|
|
+ // TODO is copying required here? (& does it do anything at all?)
|
|
+ sd_radv_prefix *p = cur;
|
|
+
|
|
+ // TODO replace hacky way to get current time
|
|
+ uint64_t current_time = cur->valid_until - cur->lifetime_valid_usec;
|
|
+ // TODO replace constant with setting (valid lifetime) ?
|
|
+ uint64_t two_hours_usec = (uint64_t) 2 * 60 * 60 * 1000000;
|
|
+ sd_radv_prefix_set_preferred_lifetime(p, 0, current_time);
|
|
+ sd_radv_prefix_set_valid_lifetime(p, two_hours_usec, current_time + two_hours_usec);
|
|
+
|
|
+ // TODO is full replacement procedure required or can we just edit the stored prefix without this?
|
|
+ // procedure cloned from sd_radv_add_prefix, if found. I do not call this here because of the duplicated search in the list & because of the different logging message
|
|
+ sd_radv_prefix_ref(p);
|
|
LIST_REMOVE(prefix, ra->prefixes, cur);
|
|
- ra->n_prefixes--;
|
|
sd_radv_prefix_unref(cur);
|
|
+ LIST_APPEND(prefix, ra->prefixes, p);
|
|
+
|
|
+ log_radv(ra, "Fade out IPv6 prefix %s (preferred: %s, valid: %s)",
|
|
+ addr_p,
|
|
+ FORMAT_TIMESPAN(p->lifetime_preferred_usec, USEC_PER_SEC),
|
|
+ FORMAT_TIMESPAN(p->lifetime_valid_usec, USEC_PER_SEC));
|
|
return;
|
|
}
|
|
}
|