summaryrefslogtreecommitdiffstats
path: root/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
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/Dhcp6Dxe/Dhcp6Impl.c
parent7fb60a98ca3a78cf318703b99e64add9f4262fa5 (diff)
downloadedk2-cc65822475b10d8eb9c01dab251ef1f647efe180.tar.gz
edk2-cc65822475b10d8eb9c01dab251ef1f647efe180.tar.bz2
edk2-cc65822475b10d8eb9c01dab251ef1f647efe180.zip
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/Dhcp6Dxe/Dhcp6Impl.c')
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c101
1 files changed, 50 insertions, 51 deletions
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;
}