Page MenuHomeFreeBSD

Enhanced IPv6 DAD algorithm
ClosedPublic

Authored by hrs on Feb 14 2015, 10:29 AM.

Details

Summary

This patch implements Enhanced DAD algorithm described in
draft-ietf-6man-enhanced-dad-13.

Problem description:

hiren@ reported that an aggregation of multiple interfaces could
cause a looped back NS message which prevented DAD from working. The
following command lines simulate the situation:

  1. ifconfig epair0 create
  2. ifconfig epair0a up
  3. ifconfig epair0b up
  4. ifconfig lagg0 create laggproto loadbalance laggport epair0a laggport epair0b up
  5. ifconfig lagg0 inet6 2001:db8::1/64

    DAD always fails. This looks unrealistic but can happen in a practical configuration, too.

    Disabling DAD by setting net.inet6.ip6.dad_count to 0 is a workaround. However, it is a vnet-wide knob and disables DAD on all of the interfaces unintentionally.

    Setting V_dad_ignore_ns variable (not a sysctl, though) makes it unconditionally ignore NS messages during a DAD period. While this may be another workaround for the looped back NS message issue, it has another fundamental problem with DAD functionality that DAD never fails when two nodes attempt a DAD at almost the same time because no NA message is sent in that case. This patch removes this variable because it had not been enabled for a long time and not useful.

Enhanced DAD algorithm:

draft-ietf-6man-enhanced-dad-13 uses a Nonce option (RFC 3971), which
was originally introduced for SeND, to detect a looped backed NS
message. It simply adds a nonce for an outgoing DAD probe NS message
and check if a received NS message has the same nonce. If it matches
each other, the probe message is recognized as a looped back one and
discarded. In the old behavior, this looped back probe is recognized
as a probe from another node and results in a DAD failure.

Implementation:

ns6_ns_output() has an integer argument for whether it is called for
DAD or not. The patch changes it to accept a pointer to a buffer
which contains a random nonce. If a nonce is supplied, DAD will be
performed and ND_OPT_NONCE (type=14) is always added to a probe NS
message.

A nonce is calculated by arc4random(). RFC 3971 says length of a
nonce must be longer than 6 bytes. An NS message will be in 8 bytes
long when a nonce with the shortest length is used (NS message must be in
units of 8 bytes). The patch uses 14 bytes for a nonce (i.e. total
length of a probe message is 16 bytes). There is a room for
discussion. 6 bytes may be enough because collision probability is
still low and it does not change length of a probe message from the
current implementation.

Test Plan
  1. ifconfig epair0 create
  2. ifconfig epair0a up
  3. ifconfig epair0b up
  4. ifconfig lagg0 create laggproto loadbalance laggport epair0a laggport epair0b up
  5. ifconfig lagg0 inet6 2001:db8::1/64

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

hrs retitled this revision from to Enhanced IPv6 DAD algorithm.
hrs updated this object.
hrs edited the test plan for this revision. (Show Details)
hrs added reviewers: bz, ae, hiren, ume, glebius.
ae edited edge metadata.

Looks good for me.

sys/netinet6/nd6_nbr.c
1228 ↗(On Diff #3761)

Maybe it will be better hide this log message under nd6_debug?

1554 ↗(On Diff #3761)

DAD does retransmits with 1s delay, it seems impossible to receive looped back message with such delay :)

This revision is now accepted and ready to land.Feb 16 2015, 8:39 AM
hiren edited edge metadata.

My quick test shows that it works and I do not see the problem anymore.

@hrs:
When do you plan to commit/mfc this?

hrs updated this revision to Diff 4072.

Closed by commit rS279531 (authored by @hrs).

sys/netinet6/nd6_nbr.c
1228 ↗(On Diff #3761)

This is because Sec. 4.2 in draft-ietf-6man-enhanced-dad-13 specifies that receivers SHOULD log a system management message when an NS message which includes a nonce is received regardless if it matches or not. This log message may be annoying, though.