]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
Add additional delay in DHCP6 InfoRequest interface to wait for link local address...
[mirror_edk2.git] / NetworkPkg / Dhcp6Dxe / Dhcp6Impl.c
index 4bed614d2baeb47bf05711a9de5e40eabcb07093..2c2b9f9f0e7b5219050c1b43fa983c6990497ff2 100644 (file)
@@ -608,11 +608,12 @@ EfiDhcp6InfoRequest (
   )\r
 {\r
   EFI_STATUS                   Status;\r
-  EFI_TPL                      OldTpl;\r
   DHCP6_INSTANCE               *Instance;\r
   DHCP6_SERVICE                *Service;\r
-  DHCP6_INF_CB                 *InfCb;\r
   UINTN                        Index;\r
+  EFI_EVENT                    Timer;\r
+  EFI_STATUS                   TimerStatus;\r
+  UINTN                        GetMappingTimeOut;\r
 \r
   if (This == NULL || OptionRequest == NULL || Retransmission == NULL || ReplyCallback == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -637,57 +638,63 @@ EfiDhcp6InfoRequest (
   Instance = DHCP6_INSTANCE_FROM_THIS (This);\r
   Service  = Instance->Service;\r
 \r
-  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);\r
-  Instance->UdpSts = EFI_ALREADY_STARTED;\r
-\r
-  //\r
-  // Create and initialize the control block for the info-request.\r
-  //\r
-  InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));\r
-\r
-  if (InfCb == NULL) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  InfCb->ReplyCallback   = ReplyCallback;\r
-  InfCb->CallbackContext = CallbackContext;\r
-  InfCb->TimeoutEvent    = TimeoutEvent;\r
-\r
-  InsertTailList (&Instance->InfList, &InfCb->Link);\r
-\r
-  //\r
-  // Send the info-request message to start exchange process.\r
-  //\r
-  Status = Dhcp6SendInfoRequestMsg (\r
+  Status = Dhcp6StartInfoRequest (\r
              Instance,\r
-             InfCb,\r
              SendClientId,\r
              OptionRequest,\r
              OptionCount,\r
              OptionList,\r
-             Retransmission\r
+             Retransmission,\r
+             TimeoutEvent,\r
+             ReplyCallback,\r
+             CallbackContext\r
              );\r
+  if (Status == EFI_NO_MAPPING) {\r
+    //\r
+    // The link local address is not ready, wait for some time and restart\r
+    // the DHCP6 information request process.\r
+    //\r
+    Status = Dhcp6GetMappingTimeOut(Service->Ip6Cfg, &GetMappingTimeOut);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
+    Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-  //\r
-  // Register receive callback for the stateless exchange process.\r
-  //\r
-  Status = UdpIoRecvDatagram(\r
-             Service->UdpIo,\r
-             Dhcp6ReceivePacket,\r
-             Service,\r
-             0\r
-             );\r
+    //\r
+    // Start the timer, wait for link local address DAD to finish.\r
+    //\r
+    Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut);\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->CloseEvent (Timer);\r
+      return Status;\r
+    }\r
 \r
-  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
-    goto ON_ERROR;\r
+    do {  \r
+      TimerStatus = gBS->CheckEvent (Timer);\r
+      if (!EFI_ERROR (TimerStatus)) {\r
+        Status = Dhcp6StartInfoRequest (\r
+                   Instance,\r
+                   SendClientId,\r
+                   OptionRequest,\r
+                   OptionCount,\r
+                   OptionList,\r
+                   Retransmission,\r
+                   TimeoutEvent,\r
+                   ReplyCallback,\r
+                   CallbackContext\r
+                   );\r
+      }\r
+    } while (TimerStatus == EFI_NOT_READY);\r
+    \r
+    gBS->CloseEvent (Timer);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
 \r
   //\r
   // Poll udp out of the net tpl if synchoronus call.\r
@@ -701,14 +708,6 @@ EfiDhcp6InfoRequest (
   }\r
 \r
   return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-\r
-  RemoveEntryList (&InfCb->Link);\r
-  FreePool (InfCb);\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
 }\r
 \r
 \r