From: Jiri Bohac <jbo...@suse.cz> Date: Thu, 13 Oct 2016 18:52:15 +0200
> The IPv6 temporary address generation uses a variable called DESYNC_FACTOR > to prevent hosts updating the addresses at the same time. Quoting RFC 4941: > > ... The value DESYNC_FACTOR is a random value (different for each > client) that ensures that clients don't synchronize with each other and > generate new addresses at exactly the same time ... > > DESYNC_FACTOR is defined as: > > DESYNC_FACTOR -- A random value within the range 0 - MAX_DESYNC_FACTOR. > It is computed once at system start (rather than each time it is used) > and must never be greater than (TEMP_VALID_LIFETIME - REGEN_ADVANCE). > > First, I believe the RFC has a typo in it and meant to say: "and must > never be greater than (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE)" > > The reason is that at various places in the RFC, DESYNC_FACTOR is used in > a calculation like (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR) or > (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE - DESYNC_FACTOR). It needs to be > smaller than (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE) for the result of > these calculations to be larger than zero. It's never used in a > calculation together with TEMP_VALID_LIFETIME. > > I already submitted an errata to the rfc-editor: > https://www.rfc-editor.org/errata_search.php?rfc=4941 > > The Linux implementation of DESYNC_FACTOR is very wrong: > max_desync_factor is used in places DESYNC_FACTOR should be used. > max_desync_factor is initialized to the RFC-recommended value for > MAX_DESYNC_FACTOR (600) but the whole point is to get a _random_ value. > > And nothing ensures that the value used is not greater than > (TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE), which leads to underflows. The > effect can easily be observed when setting the temp_prefered_lft sysctl > e.g. to 60. The preferred lifetime of the temporary addresses will be > bogus. > > TEMP_PREFERRED_LIFETIME and REGEN_ADVANCE are not constants and can be > influenced by these three sysctls: regen_max_retry, dad_transmits and > temp_prefered_lft. Thus, the upper bound for desync_factor needs to be > re-calculated each time a new address is generated and if desync_factor is > larger than the new upper bound, a new random value needs to be > re-generated. > > And since we already have max_desync_factor configurable per interface, we > also need to calculate and store desync_factor per interface. > > Signed-off-by: Jiri Bohac <jbo...@suse.cz> Applied.