libsystemd-network: ipv4ll probe conflict counter (#5361)
authorJason Reeder <jasonreeder@gmail.com>
Thu, 16 Feb 2017 10:14:38 +0000 (04:14 -0600)
committerLennart Poettering <lennart@poettering.net>
Thu, 16 Feb 2017 10:14:38 +0000 (11:14 +0100)
A bug exists where the conflict counter is cleared
regardless of whether or not the next probe attempt leads to
a successful address acquisition. This causes 'bursts' of
MAX_CONFLICTS probes followed by a delay of
RATE_LIMIT_INTERVAL instead of a single probe each
RATE_LIMIT_INTERVAL when beyond MAX_CONFLICTS.

The conflict counter should only be cleared after an
address is successfully acquired. This commit achieves that
goal.

From RFC3927:
A host should maintain a counter of the number of address
conflicts it has experienced in the process of trying to
acquire an address, and if the number of conflicts exceeds
MAX_CONFLICTS then the host MUST limit the rate at which it
probes for new addresses to no more than one new address per
RATE_LIMIT_INTERVAL.  This is to prevent catastrophic ARP
storms in pathological failure cases, such as a rogue host
that answers all ARP probes, causing legitimate hosts to go
into an infinite loop attempting to select a usable address.

Signed-off-by: Jason Reeder <jasonreeder@gmail.com>
src/libsystemd-network/sd-ipv4acd.c

index 4dd343c..2ebc00f 100644 (file)
@@ -242,8 +242,6 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
                         r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
                         if (r < 0)
                                 goto fail;
-
-                        acd->n_conflict = 0;
                 } else {
                         r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
                         if (r < 0)