Skip to content

ipv6: the Duplicate Address Detection delay is added to the timeout instead of delaying the first probe #1179

Description

@adamgeorge309

Summary

RFC 4862 has a node delay the first Neighbor Solicitation (NS) of Duplicate
Address Detection (DAD) by a random time of up to MAX_RTR_SOLICITATION_DELAY.
INET keeps the random draw but applies it at the wrong end: the probe goes out
immediately and the random second is added to the timeout instead.

initiateDad(), src/inet/networklayer/icmpv6/Ipv6NeighbourDiscovery.cc:812:

    Ipv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
    // Send a NS
    createAndSendNsPacket(tentativeAddr, destAddr, Ipv6Address::UNSPECIFIED_ADDRESS, ie);
    dadEntry->numNSSent++;
    ...
    // added uniform(0, IPv6_MAX_RTR_SOLICITATION_DELAY) to account for joining the solicited-node multicast
    // group which is delay up to one 1 second (RFC 4862, 5.4.2)
    scheduleAfter(ie->getProtocolData<Ipv6InterfaceData>()->getRetransTimer()
            + uniform(0, IPv6_MAX_RTR_SOLICITATION_DELAY), msg);

The comment names the right section and the right reason; the code applies the
delay to the timer rather than to the send. IPv6_MAX_RTR_SOLICITATION_DELAY is
1 (src/inet/networklayer/ipv6/Ipv6InterfaceData.h:48).

What the standard says

RFC 4862 Section 5.4.2, Sending Neighbor Solicitation Messages:

Before sending a Neighbor Solicitation, an interface MUST join the all-nodes
multicast address and the solicited-node multicast address of the tentative
address.

To check an address, a node sends DupAddrDetectTransmits Neighbor
Solicitations, each separated by RetransTimer milliseconds.

If the Neighbor Solicitation is going to be the first message sent from an
interface after interface (re)initialization, the node SHOULD delay joining
the solicited-node multicast address by a random delay between 0 and
MAX_RTR_SOLICITATION_DELAY as specified in [RFC4861]. This serves to alleviate
congestion when many nodes start up on the link at the same time, such as
after a power failure, and may help to avoid race conditions when more than
one node is trying to solicit for the same address at the same time.

Even if the Neighbor Solicitation is not going to be the first message sent,
the node SHOULD delay joining the solicited-node multicast address by a random
delay between 0 and MAX_RTR_SOLICITATION_DELAY if the address being checked is
configured by a router advertisement message sent to a multicast address.

The join must precede the solicitation, so delaying the join delays the
solicitation with it. The second paragraph covers INET's other case: a global
address formed from a multicast Router Advertisement (RA).

Why it matters

Two things are wrong, and neither makes detection less safe — a node that probes
early and listens longer covers the same window. They are conformance and
timing defects.

  1. There is no delay before the first probe at all. Nodes brought up at the same
    instant probe at the same instant, which is exactly the congestion and the
    race the delay exists to avoid, and a capture taken from INET does not look
    like one from a real host during boot.
  2. The probes are unevenly spaced. The first two are RetransTimer plus the
    random draw apart while every later pair is RetransTimer apart, against
    "each separated by RetransTimer milliseconds".

Measured in examples/ipv6/nclients, config ETH, on origin/master at
8ac5675:

Event Time
cli[0] forms its tentative link-local address 0.922007 s
cli[0] transmits its first Neighbor Solicitation (NS) 0.922007 s — the same event
cli[0] completes Duplicate Address Detection (DAD) 2.866676 s

The check ran for 1.944669 s rather than the 1 s of RetransTimer, because the
draw went into the timeout.

Reproduce with:

cd examples/ipv6/nclients
opp_run -m -u Cmdenv -c ETH -f omnetpp.ini --sim-time-limit=30s \
    --cmdenv-express-mode=false --cmdenv-log-level=detail \
    --cmdenv-log-prefix="%t %M: " \
  | grep "cli\[0\].ipv6.neighbourDiscovery: ----------INITIATING\|cli\[0\].ipv6.neighbourDiscovery: DAD completed"

Every node in the run behaves the same way: the probes are spread only by the
nodes' own staggered bootup times, not by the per-node random delay the standard
asks for.

Found while surveying the limitations listed by showcases/ipv6/autoconfiguration.
Not a regression: the comment and the code have disagreed since the delay was
added.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions