diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c index 9a1e3d076f..75d4f23fb0 100644 --- a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c +++ b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c @@ -52,7 +52,8 @@ Ip6ConfigOnPolicyChanged ( LIST_ENTRY *Next; IP6_INTERFACE *IpIf; IP6_DAD_ENTRY *DadEntry; - + IP6_DELAY_JOIN_LIST *DelayNode; + // // Currently there are only two policies: Manual and Automatic. Regardless of // what transition is going on, i.e., Manual -> Automatic and Automatic -> @@ -94,10 +95,18 @@ Ip6ConfigOnPolicyChanged ( NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { // - // remove all pending DAD entries for the global addresses. + // remove all pending delay node and DAD entries for the global addresses. // IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE); + NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) { + DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link); + if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) { + RemoveEntryList (&DelayNode->Link); + FreePool (DelayNode); + } + } + NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) { DadEntry = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE); diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c index 9f30f9b20e..2c8be42f09 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.c +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c @@ -982,6 +982,13 @@ Ip6InitDADProcess ( NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE); ASSERT (AddressInfo != NULL); + // + // Do nothing if we have already started DAD on the address. + // + if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) { + return EFI_SUCCESS; + } + Status = EFI_SUCCESS; IpSb = IpIf->Service; DadXmits = &IpSb->Ip6ConfigInstance.DadXmits; @@ -1577,16 +1584,6 @@ Ip6ProcessNeighborSolicit ( if (IsDAD && !IsMaintained) { DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf); if (DupAddrDetect != NULL) { - if (DupAddrDetect->Transmit == 0) { - // - // The NS is from another node to performing DAD on the same address since - // we haven't send out any NS yet. Fail DAD for the tentative address. - // - Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect); - Status = EFI_ICMP_ERROR; - goto Exit; - } - // // Check the MAC address of the incoming packet. // @@ -2863,7 +2860,7 @@ Ip6NdFasterTimerTicking ( // Flag = FALSE; if ((DupAddrDetect->Receive == 0) || - (DupAddrDetect->Transmit == DupAddrDetect->Receive)) { + (DupAddrDetect->Transmit <= DupAddrDetect->Receive)) { Flag = TRUE; }