diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1238,7 +1238,7 @@ { DADQ_WLOCK_ASSERT(); - callout_reset(&dp->dad_timer_ch, ticks, nd6_dad_timer, dp); + callout_reset(&dp->dad_timer_ch, ticks, nd6_dad_timer, (void *)dp->dad_ifa); } static void @@ -1370,17 +1370,30 @@ static void nd6_dad_timer(void *arg) { - struct dadq *dp = arg; - struct ifaddr *ifa = dp->dad_ifa; - struct ifnet *ifp = dp->dad_ifa->ifa_ifp; - struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; + struct ifaddr *ifa = (struct ifaddr *)arg; + struct dadq *dp; + struct ifnet *ifp; + struct in6_ifaddr *ia; char ip6buf[INET6_ADDRSTRLEN]; struct epoch_tracker et; + if (!ifa) + return; + dp = nd6_dad_find(ifa, NULL); + if (!dp) { + log(LOG_ERR, "Entry has been removed from DAD queue\n"); + return; + } + CURVNET_SET(dp->dad_vnet); - KASSERT(ia != NULL, ("DAD entry %p with no address", dp)); + ifp = ifa->ifa_ifp; + ia = (struct in6_ifaddr *)ifa; NET_EPOCH_ENTER(et); + if (!ia) { + log(LOG_ERR, "DAD entry %p with no address", dp); + goto done; + } if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) { /* Do not need DAD for ifdisabled interface. */ log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of "