summaryrefslogtreecommitdiff
path: root/NetworkPkg
diff options
context:
space:
mode:
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-08-22 08:01:19 +0000
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-08-22 08:01:19 +0000
commitcc65822475b10d8eb9c01dab251ef1f647efe180 (patch)
tree5fd077a770ed9058a83141626820d7e0dd286d51 /NetworkPkg
parent7fb60a98ca3a78cf318703b99e64add9f4262fa5 (diff)
downloadedk2-platforms-cc65822475b10d8eb9c01dab251ef1f647efe180.tar.xz
Add additional delay in DHCP6 InfoRequest interface to wait for link local address DAD to finish.
Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: qianouyang <qian.ouyang@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13664 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'NetworkPkg')
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c16
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf4
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c101
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h4
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Io.c102
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Io.h36
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c39
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h19
8 files changed, 262 insertions, 59 deletions
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
index 54ef2e2783..b789f2a478 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
@@ -2,7 +2,7 @@
Driver Binding functions and Service Binding functions
implementationfor for Dhcp6 Driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -132,6 +132,7 @@ Dhcp6CreateService (
)
{
DHCP6_SERVICE *Dhcp6Srv;
+ EFI_STATUS Status;
*Service = NULL;
Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));
@@ -166,6 +167,19 @@ Dhcp6CreateService (
);
//
+ // Locate Ip6->Ip6Config and store it for get IP6 Duplicate Address Detection transmits.
+ //
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiIp6ConfigProtocolGuid,
+ (VOID **) &Dhcp6Srv->Ip6Cfg
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (Dhcp6Srv);
+ return Status;
+ }
+
+ //
// Generate client Duid: If SMBIOS system UUID is located, generate DUID in DUID-UUID format.
// Otherwise, in DUID-LLT format.
//
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf b/NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
index f10b07ac3c..7c84397431 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
@@ -1,7 +1,7 @@
## @file
# Component description file for Dhcp6 module.
#
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -66,4 +66,4 @@
gEfiUdp6ProtocolGuid
gEfiDhcp6ServiceBindingProtocolGuid
gEfiDhcp6ProtocolGuid
-
+ gEfiIp6ConfigProtocolGuid
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
index 4bed614d2b..2c2b9f9f0e 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
@@ -608,11 +608,12 @@ EfiDhcp6InfoRequest (
)
{
EFI_STATUS Status;
- EFI_TPL OldTpl;
DHCP6_INSTANCE *Instance;
DHCP6_SERVICE *Service;
- DHCP6_INF_CB *InfCb;
UINTN Index;
+ EFI_EVENT Timer;
+ EFI_STATUS TimerStatus;
+ UINTN GetMappingTimeOut;
if (This == NULL || OptionRequest == NULL || Retransmission == NULL || ReplyCallback == NULL) {
return EFI_INVALID_PARAMETER;
@@ -637,57 +638,63 @@ EfiDhcp6InfoRequest (
Instance = DHCP6_INSTANCE_FROM_THIS (This);
Service = Instance->Service;
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Instance->UdpSts = EFI_ALREADY_STARTED;
-
- //
- // Create and initialize the control block for the info-request.
- //
- InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));
-
- if (InfCb == NULL) {
- gBS->RestoreTPL (OldTpl);
- return EFI_OUT_OF_RESOURCES;
- }
-
- InfCb->ReplyCallback = ReplyCallback;
- InfCb->CallbackContext = CallbackContext;
- InfCb->TimeoutEvent = TimeoutEvent;
-
- InsertTailList (&Instance->InfList, &InfCb->Link);
-
- //
- // Send the info-request message to start exchange process.
- //
- Status = Dhcp6SendInfoRequestMsg (
+ Status = Dhcp6StartInfoRequest (
Instance,
- InfCb,
SendClientId,
OptionRequest,
OptionCount,
OptionList,
- Retransmission
+ Retransmission,
+ TimeoutEvent,
+ ReplyCallback,
+ CallbackContext
);
+ if (Status == EFI_NO_MAPPING) {
+ //
+ // The link local address is not ready, wait for some time and restart
+ // the DHCP6 information request process.
+ //
+ Status = Dhcp6GetMappingTimeOut(Service->Ip6Cfg, &GetMappingTimeOut);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
+ Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- //
- // Register receive callback for the stateless exchange process.
- //
- Status = UdpIoRecvDatagram(
- Service->UdpIo,
- Dhcp6ReceivePacket,
- Service,
- 0
- );
+ //
+ // Start the timer, wait for link local address DAD to finish.
+ //
+ Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut);
+ if (EFI_ERROR (Status)) {
+ gBS->CloseEvent (Timer);
+ return Status;
+ }
- if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
- goto ON_ERROR;
+ do {
+ TimerStatus = gBS->CheckEvent (Timer);
+ if (!EFI_ERROR (TimerStatus)) {
+ Status = Dhcp6StartInfoRequest (
+ Instance,
+ SendClientId,
+ OptionRequest,
+ OptionCount,
+ OptionList,
+ Retransmission,
+ TimeoutEvent,
+ ReplyCallback,
+ CallbackContext
+ );
+ }
+ } while (TimerStatus == EFI_NOT_READY);
+
+ gBS->CloseEvent (Timer);
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
}
-
- gBS->RestoreTPL (OldTpl);
//
// Poll udp out of the net tpl if synchoronus call.
@@ -701,14 +708,6 @@ EfiDhcp6InfoRequest (
}
return EFI_SUCCESS;
-
-ON_ERROR:
-
- RemoveEntryList (&InfCb->Link);
- FreePool (InfCb);
- gBS->RestoreTPL (OldTpl);
-
- return Status;
}
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
index dda0cf37d5..0e206cd504 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
@@ -1,7 +1,7 @@
/** @file
Dhcp6 internal data structure and definition declaration.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -21,6 +21,7 @@
#include <Protocol/Dhcp6.h>
#include <Protocol/Udp6.h>
+#include <Protocol/Ip6Config.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/DriverBinding.h>
@@ -259,6 +260,7 @@ struct _DHCP6_SERVICE {
EFI_HANDLE Image;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
EFI_DHCP6_DUID *ClientId;
UDP_IO *UdpIo;
UINT32 Xid;
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index 7320642edd..656fd83908 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -1,7 +1,7 @@
/** @file
Dhcp6 internal functions implementation.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -1626,6 +1626,106 @@ Dhcp6SendRenewRebindMsg (
return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}
+/**
+ Start the information request process.
+
+ @param[in] Instance The pointer to the Dhcp6 instance.
+ @param[in] SendClientId If TRUE, the client identifier option will be included in
+ information request message. Otherwise, the client identifier
+ option will not be included.
+ @param[in] OptionRequest The pointer to the option request option.
+ @param[in] OptionCount The number options in the OptionList.
+ @param[in] OptionList The array pointers to the appended options.
+ @param[in] Retransmission The pointer to the retransmission control.
+ @param[in] TimeoutEvent The event of timeout.
+ @param[in] ReplyCallback The callback function when the reply was received.
+ @param[in] CallbackContext The pointer to the parameter passed to the callback.
+
+ @retval EFI_SUCCESS Start the info-request process successfully.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+ @retval EFI_NO_MAPPING No source address is available for use.
+ @retval Others Failed to start the info-request process.
+
+**/
+EFI_STATUS
+Dhcp6StartInfoRequest (
+ IN DHCP6_INSTANCE *Instance,
+ IN BOOLEAN SendClientId,
+ IN EFI_DHCP6_PACKET_OPTION *OptionRequest,
+ IN UINT32 OptionCount,
+ IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL,
+ IN EFI_DHCP6_RETRANSMISSION *Retransmission,
+ IN EFI_EVENT TimeoutEvent OPTIONAL,
+ IN EFI_DHCP6_INFO_CALLBACK ReplyCallback,
+ IN VOID *CallbackContext OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ DHCP6_INF_CB *InfCb;
+ DHCP6_SERVICE *Service;
+ EFI_TPL OldTpl;
+
+ Service = Instance->Service;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ Instance->UdpSts = EFI_ALREADY_STARTED;
+ //
+ // Create and initialize the control block for the info-request.
+ //
+ InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));
+
+ if (InfCb == NULL) {
+ gBS->RestoreTPL (OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InfCb->ReplyCallback = ReplyCallback;
+ InfCb->CallbackContext = CallbackContext;
+ InfCb->TimeoutEvent = TimeoutEvent;
+
+ InsertTailList (&Instance->InfList, &InfCb->Link);
+
+ //
+ // Send the info-request message to start exchange process.
+ //
+ Status = Dhcp6SendInfoRequestMsg (
+ Instance,
+ InfCb,
+ SendClientId,
+ OptionRequest,
+ OptionCount,
+ OptionList,
+ Retransmission
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Register receive callback for the stateless exchange process.
+ //
+ Status = UdpIoRecvDatagram(
+ Service->UdpIo,
+ Dhcp6ReceivePacket,
+ Service,
+ 0
+ );
+
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ goto ON_ERROR;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ gBS->RestoreTPL (OldTpl);
+ RemoveEntryList (&InfCb->Link);
+ FreePool (InfCb);
+
+ return Status;
+}
/**
Create the information request message and send it.
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
index 31459c96d3..b0b12a79fe 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
@@ -1,7 +1,7 @@
/** @file
Dhcp6 internal functions declaration.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -130,6 +130,40 @@ Dhcp6SendReleaseMsg (
);
/**
+ Start the information request process.
+
+ @param[in] Instance The pointer to the Dhcp6 instance.
+ @param[in] SendClientId If TRUE, the client identifier option will be included in
+ information request message. Otherwise, the client identifier
+ option will not be included.
+ @param[in] OptionRequest The pointer to the option request option.
+ @param[in] OptionCount The number options in the OptionList.
+ @param[in] OptionList The array pointers to the appended options.
+ @param[in] Retransmission The pointer to the retransmission control.
+ @param[in] TimeoutEvent The event of timeout.
+ @param[in] ReplyCallback The callback function when the reply was received.
+ @param[in] CallbackContext The pointer to the parameter passed to the callback.
+
+ @retval EFI_SUCCESS Start the info-request process successfully.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+ @retval EFI_NO_MAPPING No source address is available for use.
+ @retval Others Failed to start the info-request process.
+
+**/
+EFI_STATUS
+Dhcp6StartInfoRequest (
+ IN DHCP6_INSTANCE *Instance,
+ IN BOOLEAN SendClientId,
+ IN EFI_DHCP6_PACKET_OPTION *OptionRequest,
+ IN UINT32 OptionCount,
+ IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL,
+ IN EFI_DHCP6_RETRANSMISSION *Retransmission,
+ IN EFI_EVENT TimeoutEvent OPTIONAL,
+ IN EFI_DHCP6_INFO_CALLBACK ReplyCallback,
+ IN VOID *CallbackContext OPTIONAL
+ );
+
+/**
Create the information request message and send it.
@param[in] Instance The pointer to the Dhcp6 instance.
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
index 6bf96a1996..4c32028680 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
@@ -1189,3 +1189,42 @@ Dhcp6AppendCacheIa (
Instance->IaCb.Ia = NewIa;
}
}
+
+/**
+ Calculate the Dhcp6 get mapping timeout by adding additinal delay to the IP6 DAD transmits count.
+
+ @param[in] Ip6Cfg The pointer to Ip6 config protocol.
+ @param[out] TimeOut The time out value in 100ns units.
+
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_SUCCESS Calculate the time out value successfully.
+**/
+EFI_STATUS
+Dhcp6GetMappingTimeOut (
+ IN EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg,
+ OUT UINTN *TimeOut
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;
+
+ if (Ip6Cfg == NULL || TimeOut == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
+ &DataSize,
+ &DadXmits
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *TimeOut = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + DHCP6_DAD_ADDITIONAL_DELAY;
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
index 61bb9f324e..2a44d0068f 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
@@ -1,7 +1,7 @@
/** @file
Dhcp6 support functions declaration.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -17,7 +17,8 @@
#define __EFI_DHCP6_UTILITY_H__
-#define DHCP6_10_BIT_MASK 0x3ff
+#define DHCP6_10_BIT_MASK 0x3ff
+#define DHCP6_DAD_ADDITIONAL_DELAY 30000000 // 3 seconds
/**
Generate client Duid in the format of Duid-llt.
@@ -337,4 +338,18 @@ Dhcp6AppendCacheIa (
IN DHCP6_INSTANCE *Instance
);
+/**
+ Calculate the Dhcp6 get mapping timeout by adding additinal delay to the IP6 DAD transmits count.
+
+ @param[in] Ip6Cfg The pointer to Ip6 config protocol.
+ @param[out] TimeOut The time out value in 100ns units.
+
+ @retval EFI_INVALID_PARAMETER Input parameters are invalid.
+ @retval EFI_SUCCESS Calculate the time out value successfully.
+**/
+EFI_STATUS
+Dhcp6GetMappingTimeOut (
+ IN EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg,
+ OUT UINTN *TimeOut
+ );
#endif