stf(4) does not support multicast, which is a requirement for ND6 DAD.
It also does not set IFF_DRV_RUNNING. As a result, the last case in
nd6_timer() gets triggered by an address assigned to stf0, and it marks
the address as tentative. The next time nd6_timer() fires, it sees
IN6_IFF_TENTATIVE and starts DAD. nd6_dad_start(), however, simply
returns because IFF_DRV_RUNNING is not set. So, the interface address
stays stuck in the tentative state.
To fix this, the minimal change needed is to set IFF_DRV_RUNNING in
stf(4). I think that change is reasonable; once an address is assigned
and the interface is UP, the driver is running. This diff makes some
additional changes:
- In in6if_do_dad(), remove a redundant check for !UP || !RUNNING. There is only one caller in the tree, and it only looks at whether the return value is non-zero.
- Have in6if_do_dad() return false if the interface is not multicast-capable.
- Set ND6_IFF_NO_DAD when an address is assigned to an stf(4) interface and the interface goes UP as a result. Note that this is not sufficient to fix the problem because the new address is marked as tentative and DAD is started before in6_ifattach() is called. However, setting no_dad is formally correct.
- Change nd6_timer() to not flag addresses as tentative if no_dad is set.