/** @file\r
Implementation of Neighbor Discovery support routines.\r
\r
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
}\r
\r
/**\r
- Destory a IP6 prefix list entry.\r
+ Destroy a IP6 prefix list entry.\r
\r
@param[in] IpSb The pointer to IP6_SERVICE instance.\r
@param[in] PrefixEntry The to be destroyed prefix list entry.\r
Clean an IP6 default router list.\r
\r
@param[in] IpSb The pointer to the IP6_SERVICE instance.\r
- @param[in] DefaultRouter The to be destroyed IP6_DEFAULT_ROUTER.\r
\r
**/\r
VOID\r
UINT16 OptBuf[4];\r
EFI_DHCP6_PACKET_OPTION *Oro;\r
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;\r
-\r
+ EFI_IPv6_ADDRESS AllNodes;\r
+ \r
IpSb = IpIf->Service;\r
AddrInfo = DadEntry->AddressInfo;\r
\r
RemoveEntryList (&DadEntry->Link);\r
FreePool (DadEntry);\r
//\r
+ // Leave link-scope all-nodes multicast address (FF02::1)\r
+ //\r
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);\r
+ Ip6LeaveGroup (IpSb, &AllNodes);\r
+ //\r
// Disable IP operation since link-local address is a duplicate address.\r
//\r
IpSb->LinkLocalDadFail = TRUE;\r
NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE);\r
ASSERT (AddressInfo != NULL);\r
\r
+ //\r
+ // Do nothing if we have already started DAD on the address.\r
+ //\r
+ if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
Status = EFI_SUCCESS;\r
IpSb = IpIf->Service;\r
DadXmits = &IpSb->Ip6ConfigInstance.DadXmits;\r
goto Exit;\r
} else {\r
OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH);\r
- Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);\r
+ if (OptionLen != 0) {\r
+ Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);\r
+ ASSERT (Option != NULL);\r
\r
- //\r
- // All included options should have a length that is greater than zero.\r
- //\r
- if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
- goto Exit;\r
+ //\r
+ // All included options should have a length that is greater than zero.\r
+ //\r
+ if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
+ goto Exit;\r
+ }\r
}\r
}\r
\r
if (IsDAD && !IsMaintained) {\r
DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf);\r
if (DupAddrDetect != NULL) {\r
- if (DupAddrDetect->Transmit == 0) {\r
- //\r
- // The NS is from another node to performing DAD on the same address since\r
- // we haven't send out any NS yet. Fail DAD for the tentative address.\r
- //\r
- Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect);\r
- Status = EFI_ICMP_ERROR;\r
- goto Exit;\r
- }\r
-\r
//\r
// Check the MAC address of the incoming packet.\r
//\r
goto Exit;\r
} else {\r
OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH);\r
- Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);\r
+ if (OptionLen != 0) {\r
+ Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);\r
+ ASSERT (Option != NULL);\r
\r
- //\r
- // All included options should have a length that is greater than zero.\r
- //\r
- if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
- goto Exit;\r
+ //\r
+ // All included options should have a length that is greater than zero.\r
+ //\r
+ if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
+ goto Exit;\r
+ }\r
}\r
}\r
\r
// All included options have a length that is greater than zero.\r
//\r
OptionLen = (UINT16) (Head->PayloadLength - IP6_RA_LENGTH);\r
- Option = NetbufGetByte (Packet, IP6_RA_LENGTH, NULL);\r
+ if (OptionLen != 0) {\r
+ Option = NetbufGetByte (Packet, IP6_RA_LENGTH, NULL);\r
+ ASSERT (Option != NULL);\r
\r
- if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
- goto Exit;\r
+ if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
+ goto Exit;\r
+ }\r
}\r
\r
//\r
// All included options have a length that is greater than zero.\r
//\r
OptionLen = (UINT16) (Head->PayloadLength - IP6_REDITECT_LENGTH);\r
- Option = NetbufGetByte (Packet, IP6_REDITECT_LENGTH, NULL);\r
+ if (OptionLen != 0) {\r
+ Option = NetbufGetByte (Packet, IP6_REDITECT_LENGTH, NULL);\r
+ ASSERT (Option != NULL);\r
\r
- if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
- goto Exit;\r
+ if (!Ip6IsNDOptionValid (Option, OptionLen)) {\r
+ goto Exit;\r
+ }\r
}\r
\r
Target = (EFI_IPv6_ADDRESS *) (Icmp + 1);\r
//\r
Flag = FALSE;\r
if ((DupAddrDetect->Receive == 0) ||\r
- (DupAddrDetect->Transmit == DupAddrDetect->Receive)) {\r
+ (DupAddrDetect->Transmit <= DupAddrDetect->Receive)) {\r
Flag = TRUE;\r
}\r
\r