Page MenuHomeFreeBSD

Do not perform DAD on stf(4) interfaces.
ClosedPublic

Authored by markj on Mar 29 2019, 2:11 PM.
Tags
None
Referenced Files
F131634192: D19751.diff
Thu, Oct 9, 10:18 PM
Unknown Object (File)
Fri, Oct 3, 3:46 AM
Unknown Object (File)
Tue, Sep 23, 10:11 PM
Unknown Object (File)
Sat, Sep 13, 9:29 PM
Unknown Object (File)
Aug 26 2025, 8:01 PM
Unknown Object (File)
Aug 8 2025, 3:39 PM
Unknown Object (File)
Jul 31 2025, 2:12 AM
Unknown Object (File)
Jul 29 2025, 5:55 PM
Subscribers

Details

Summary

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.
Test Plan

The problem could be reproduced simply by assigning an address to an stf(4) interface.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable