Let ifconfig wait for IPv6-address to not be tentative

After asking a NetBSD-developer, and verifying that the same applies to FreeBSD, I found out the solution (which applies on both these OSes):

The Duplicate Address Detection (DAD) will use some time detecting if the address is already in use. The amount of time it will use for this is defined in seconds in the sysctl(3) value net.inet6.ip6.dad_count. In NetBSD's /etc/rc.d/network, function network_start_ipv6_autoconf, the script waits for this amount plus one second.

When DAD finds out that the address is already in use on the network, ifconfig(8) will show the address as duplicated. In this state it is not possible to bind to the address, similar to when the address is tentative.

A more complete and correcter solution would thus be:

ifconfig igb0 inet6 2001:db8::10/64 add
dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null)
sleep $dadcount
sleep 1
ifconfig igb0 | grep 2001:db8::10/64 | egrep '(duplicated|tentative)$' >&2 && exit 1
service my_service start

I have observed that FreeBSD and NetBSD behave differently when adding an address that is currently in duplicated state:

  • FreeBSD 11 will immediatly remove the duplicated state, allowing the address to be used, abeit possibly causing conflicts.
  • NetBSD 7 will mark the address as tentative, and it won't change the state from there, at least not for a couple minutes. The address must be removed and added again in order to be useable.

An address can be in several states, tentative is one of them. Having ifconfig wait for an address to leave the state tentative is simply not in accord with the design.

You may configure to use optimistic DAD as defined in RFC 4429. The purpose is to make an address available to applications even if the DAD is not yet completed. You may need to reconfigure the kernel to utilize this feature.

Once the kernel is built to provide optimistic DAD, then you may certain sysctl-settings to enable it. From ip-sysctl.txt:

/proc/sys/net/ipv6/* Variables:
...

conf/interface/*:
        Change special settings per interface.

        The functional behaviour for certain settings is different
        depending on whether local forwarding is enabled or not.

...

optimistic_dad - BOOLEAN
        Whether to perform Optimistic Duplicate Address Detection (RFC 4429).
                0: disabled (default)
                1: enabled

use_optimistic - BOOLEAN
        If enabled, do not classify optimistic addresses as deprecated during
        source address selection.  Preferred addresses will still be chosen
        before optimistic addresses, subject to other ranking in the source
        address selection algorithm.
                0: disabled (default)
                1: enabled

That is, do something like

sysctl -w net.ipv6.conf.enp2s6.optimistic_dad=1
sysctl -w net.ipv6.conf.enp2s6.use_optimistic=1

at boot time.