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
This commit is contained in:
@@ -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,58 +638,64 @@ 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;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
goto ON_ERROR;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// 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);
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user