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
Unknown Object (File)
Jan 26 2024, 8:31 PM
Unknown Object (File)
Dec 23 2023, 12:31 AM
Unknown Object (File)
Dec 21 2023, 8:27 AM
Unknown Object (File)
Oct 29 2023, 6:12 PM
Unknown Object (File)
Aug 28 2023, 6:54 PM
Unknown Object (File)
Jul 25 2023, 1:20 AM
Unknown Object (File)
Jul 8 2023, 2:57 PM
Unknown Object (File)
Jun 28 2023, 1:35 AM
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