]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-radv: if lifetime < SD_RADV_DEFAULT_MAX_TIMEOUT_USEC, adjust timeout (#13491)
authorGeorg Müller <georgmueller@gmx.net>
Fri, 20 Sep 2019 08:23:45 +0000 (10:23 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Fri, 20 Sep 2019 13:52:29 +0000 (13:52 +0000)
The RFC states that lifetime (AdvDefaultLifetime) must be at least
MaxRtrAdvInterval (which more or less corresponds to SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
in systemd).

To fulfill this limit, virtually lower MaxRtrAdvInterval and MinRtrAdvInterval
accordingly.

Also check that min is not lower than 3s and max is not lower than 4s.

src/libsystemd-network/sd-radv.c

index d531f52326d3f054d1ff615fc41b5e6d708cc540..5c7f727faa69bff79965c05e49b74e275788bc37 100644 (file)
@@ -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",