mirror of
https://github.com/systemd/systemd.git
synced 2024-10-30 06:25:37 +03:00
sd-radv: update how to calculate interval of sending advertisements
This commit is contained in:
parent
0945767012
commit
804775577d
@ -17,6 +17,8 @@
|
|||||||
* The maximum time allowed between sending unsolicited multicast Router Advertisements from the
|
* The maximum time allowed between sending unsolicited multicast Router Advertisements from the
|
||||||
* interface, in seconds. MUST be no less than 4 seconds and no greater than 1800 seconds.
|
* interface, in seconds. MUST be no less than 4 seconds and no greater than 1800 seconds.
|
||||||
* Default: 600 seconds */
|
* Default: 600 seconds */
|
||||||
|
#define RADV_MIN_MAX_TIMEOUT_USEC (4 * USEC_PER_SEC)
|
||||||
|
#define RADV_MAX_MAX_TIMEOUT_USEC (1800 * USEC_PER_SEC)
|
||||||
#define RADV_DEFAULT_MAX_TIMEOUT_USEC (600 * USEC_PER_SEC)
|
#define RADV_DEFAULT_MAX_TIMEOUT_USEC (600 * USEC_PER_SEC)
|
||||||
/* RFC 4861 section 6.2.1.
|
/* RFC 4861 section 6.2.1.
|
||||||
* MinRtrAdvInterval
|
* MinRtrAdvInterval
|
||||||
@ -24,7 +26,7 @@
|
|||||||
* interface, in seconds. MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval.
|
* interface, in seconds. MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval.
|
||||||
* Default: 0.33 * MaxRtrAdvInterval If MaxRtrAdvInterval >= 9 seconds; otherwise, the Default is
|
* Default: 0.33 * MaxRtrAdvInterval If MaxRtrAdvInterval >= 9 seconds; otherwise, the Default is
|
||||||
* MaxRtrAdvInterval (Note, this should be a typo. We use 0.75 * MaxRtrAdvInterval). */
|
* MaxRtrAdvInterval (Note, this should be a typo. We use 0.75 * MaxRtrAdvInterval). */
|
||||||
#define RADV_DEFAULT_MIN_TIMEOUT_USEC (RADV_DEFAULT_MAX_TIMEOUT_USEC / 3)
|
#define RADV_MIN_MIN_TIMEOUT_USEC (3 * USEC_PER_SEC)
|
||||||
/* RFC 4861 section 6.2.4.
|
/* RFC 4861 section 6.2.4.
|
||||||
* AdvDefaultLifetime
|
* AdvDefaultLifetime
|
||||||
* The value to be placed in the Router Lifetime field of Router Advertisements sent from the interface,
|
* The value to be placed in the Router Lifetime field of Router Advertisements sent from the interface,
|
||||||
@ -34,7 +36,7 @@
|
|||||||
* point-to-point link the peers may have enough information about the number and status of devices at
|
* point-to-point link the peers may have enough information about the number and status of devices at
|
||||||
* the other end so that advertisements are needed less frequently.
|
* the other end so that advertisements are needed less frequently.
|
||||||
* Default: 3 * MaxRtrAdvInterval */
|
* Default: 3 * MaxRtrAdvInterval */
|
||||||
#define RADV_MIN_ROUTER_LIFETIME_USEC (4 * USEC_PER_SEC)
|
#define RADV_MIN_ROUTER_LIFETIME_USEC RADV_MIN_MAX_TIMEOUT_USEC
|
||||||
#define RADV_MAX_ROUTER_LIFETIME_USEC (9000 * USEC_PER_SEC)
|
#define RADV_MAX_ROUTER_LIFETIME_USEC (9000 * USEC_PER_SEC)
|
||||||
#define RADV_DEFAULT_ROUTER_LIFETIME_USEC (3 * RADV_DEFAULT_MAX_TIMEOUT_USEC)
|
#define RADV_DEFAULT_ROUTER_LIFETIME_USEC (3 * RADV_DEFAULT_MAX_TIMEOUT_USEC)
|
||||||
/* RFC 4861 section 10.
|
/* RFC 4861 section 10.
|
||||||
|
@ -292,16 +292,6 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static usec_t radv_compute_timeout(usec_t min, usec_t max) {
|
|
||||||
assert_return(min <= max, 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
|
static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||||
usec_t min_timeout, max_timeout, time_now, timeout;
|
usec_t min_timeout, max_timeout, time_now, timeout;
|
||||||
sd_radv *ra = userdata;
|
sd_radv *ra = userdata;
|
||||||
@ -310,6 +300,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
|
|||||||
assert(s);
|
assert(s);
|
||||||
assert(ra);
|
assert(ra);
|
||||||
assert(ra->event);
|
assert(ra->event);
|
||||||
|
assert(router_lifetime_is_valid(ra->lifetime_usec));
|
||||||
|
|
||||||
r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
|
r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -320,27 +311,35 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
|
|||||||
log_radv_errno(ra, r, "Unable to send Router Advertisement: %m");
|
log_radv_errno(ra, r, "Unable to send Router Advertisement: %m");
|
||||||
|
|
||||||
/* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
|
/* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
|
||||||
if (ra->ra_sent < RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
|
if (ra->ra_sent < RADV_MAX_INITIAL_RTR_ADVERTISEMENTS)
|
||||||
max_timeout = RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
|
max_timeout = RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
|
||||||
min_timeout = RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
|
else
|
||||||
} else {
|
|
||||||
max_timeout = RADV_DEFAULT_MAX_TIMEOUT_USEC;
|
max_timeout = RADV_DEFAULT_MAX_TIMEOUT_USEC;
|
||||||
min_timeout = RADV_DEFAULT_MIN_TIMEOUT_USEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
|
/* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
|
||||||
so lower the interval here */
|
* so lower the interval here */
|
||||||
if (ra->lifetime_usec > 0 && ra->lifetime_usec < max_timeout) {
|
if (ra->lifetime_usec > 0)
|
||||||
max_timeout = ra->lifetime_usec;
|
max_timeout = MIN(max_timeout, ra->lifetime_usec);
|
||||||
min_timeout = max_timeout / 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout = radv_compute_timeout(min_timeout, max_timeout);
|
if (max_timeout >= 9 * USEC_PER_SEC)
|
||||||
|
min_timeout = max_timeout / 3;
|
||||||
|
else
|
||||||
|
min_timeout = max_timeout * 3 / 4;
|
||||||
|
|
||||||
|
/* RFC 4861, Section 6.2.1.
|
||||||
|
* MaxRtrAdvInterval MUST be no less than 4 seconds and no greater than 1800 seconds.
|
||||||
|
* MinRtrAdvInterval MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. */
|
||||||
|
assert(max_timeout >= RADV_MIN_MAX_TIMEOUT_USEC);
|
||||||
|
assert(max_timeout <= RADV_MAX_MAX_TIMEOUT_USEC);
|
||||||
|
assert(min_timeout >= RADV_MIN_MIN_TIMEOUT_USEC);
|
||||||
|
assert(min_timeout <= max_timeout * 3 / 4);
|
||||||
|
|
||||||
|
timeout = min_timeout + random_u64_range(max_timeout - min_timeout);
|
||||||
log_radv(ra, "Next Router Advertisement in %s", FORMAT_TIMESPAN(timeout, USEC_PER_SEC));
|
log_radv(ra, "Next Router Advertisement in %s", FORMAT_TIMESPAN(timeout, USEC_PER_SEC));
|
||||||
|
|
||||||
r = event_reset_time(ra->event, &ra->timeout_event_source,
|
r = event_reset_time(ra->event, &ra->timeout_event_source,
|
||||||
clock_boottime_or_monotonic(),
|
clock_boottime_or_monotonic(),
|
||||||
time_now + timeout, MSEC_PER_SEC,
|
usec_add(time_now, timeout), MSEC_PER_SEC,
|
||||||
radv_timeout, ra,
|
radv_timeout, ra,
|
||||||
ra->event_priority, "radv-timeout", true);
|
ra->event_priority, "radv-timeout", true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user