summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/sd-radv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network/sd-radv.c')
-rw-r--r--src/libsystemd-network/sd-radv.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c
index d531f52326..5c7f727faa 100644
--- a/src/libsystemd-network/sd-radv.c
+++ b/src/libsystemd-network/sd-radv.c
@@ -273,6 +273,10 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
static usec_t radv_compute_timeout(usec_t min, usec_t max) {
assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC);
+ /* RFC 4861: min must be no less than 3s, max must be no less than 4s */
+ min = MAX(min, 3*USEC_PER_SEC);
+ max = MAX(max, 4*USEC_PER_SEC);
+
return min + (random_u32() % (max - min));
}
@@ -302,6 +306,13 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
}
+ /* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
+ so lower the interval here */
+ if (ra->lifetime > 0 && (ra->lifetime * USEC_PER_SEC) < max_timeout) {
+ max_timeout = ra->lifetime * USEC_PER_SEC;
+ min_timeout = max_timeout / 3;
+ }
+
timeout = radv_compute_timeout(min_timeout, max_timeout);
log_radv("Next Router Advertisement in %s",