Cancel DAD for an ifa when the ifp has ND6_IFF_IFDISABLED as early as
possible and do not clear IN6_IFF_TENTATIVE. If IFDISABLED was accidentally set after a DAD started, TENTATIVE could be cleared because no NA was received due to IFDISABLED, and as a result it could prevent DAD when manually clearing IFDISABLED after that.
This commit is contained in:
parent
4327a6c8c6
commit
705bef548a
@ -1312,6 +1312,7 @@ nd6_dad_timer(struct dadq *dp)
|
||||
{
|
||||
CURVNET_SET(dp->dad_vnet);
|
||||
struct ifaddr *ifa = dp->dad_ifa;
|
||||
struct ifnet *ifp = dp->dad_ifa->ifa_ifp;
|
||||
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
|
||||
char ip6buf[INET6_ADDRSTRLEN];
|
||||
|
||||
@ -1320,6 +1321,16 @@ nd6_dad_timer(struct dadq *dp)
|
||||
log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
|
||||
goto done;
|
||||
}
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
|
||||
/* Do not need DAD for ifdisabled interface. */
|
||||
TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list);
|
||||
log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of "
|
||||
"ND6_IFF_IFDISABLED.\n", ifp->if_xname);
|
||||
free(dp, M_IP6NDP);
|
||||
dp = NULL;
|
||||
ifa_free(ifa);
|
||||
goto done;
|
||||
}
|
||||
if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
|
||||
log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
|
||||
"%s(%s)\n",
|
||||
@ -1384,9 +1395,12 @@ nd6_dad_timer(struct dadq *dp)
|
||||
} else {
|
||||
/*
|
||||
* We are done with DAD. No NA came, no NS came.
|
||||
* No duplicate address found.
|
||||
* No duplicate address found. Check IFDISABLED flag
|
||||
* again in case that it is changed between the
|
||||
* beginning of this function and here.
|
||||
*/
|
||||
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
|
||||
if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0)
|
||||
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
|
||||
|
||||
nd6log((LOG_DEBUG,
|
||||
"%s: DAD complete for %s - no duplicates found\n",
|
||||
|
Loading…
Reference in New Issue
Block a user