]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update PXE driver to wait for IPv6 duplicate address detection to finish.
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2012 04:34:10 +0000 (04:34 +0000)
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 4 Jul 2012 04:34:10 +0000 (04:34 +0000)
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@13485 6f19259b-4bc3-4df7-8a09-765794883524

NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h

index 3e73976ddb6a1fda2a9ede6d09f389b3d2530b0d..4bed614d2baeb47bf05711a9de5e40eabcb07093 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This EFI_DHCP6_PROTOCOL interface implementation.\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
@@ -200,13 +200,13 @@ EfiDhcp6Stop (
   ASSERT (Instance->IaCb.Ia != NULL);\r
 \r
   //\r
-  // The instance has already been stopped.\r
+  // No valid REPLY message received yet, cleanup this instance directly.\r
   //\r
   if (Instance->IaCb.Ia->State == Dhcp6Init ||\r
       Instance->IaCb.Ia->State == Dhcp6Selecting ||\r
       Instance->IaCb.Ia->State == Dhcp6Requesting\r
       ) {\r
-    return Status;\r
+    goto ON_EXIT;\r
   }\r
 \r
   //\r
@@ -215,7 +215,10 @@ EfiDhcp6Stop (
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   Instance->UdpSts = EFI_ALREADY_STARTED;\r
-  Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
+  Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
@@ -229,7 +232,8 @@ EfiDhcp6Stop (
     }\r
     Status = Instance->UdpSts;\r
   }\r
-\r
+  \r
+ON_EXIT:\r
   //\r
   // Clean up the session data for the released Ia.\r
   //\r
index 0a2dd6d13ebc1eb6f20fd9491faa860056edcd6b..6ab2afa088af05fc5113a25d364211044590e3c9 100644 (file)
@@ -1260,6 +1260,8 @@ PxeBcRegisterIp6Address (
   EFI_EVENT                        TimeOutEvt;\r
   EFI_EVENT                        MappedEvt;\r
   EFI_STATUS                       Status;\r
+  UINT64                           DadTriggerTime;\r
+  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS    DadXmits;\r
 \r
   Status     = EFI_SUCCESS;\r
   TimeOutEvt = NULL;\r
@@ -1303,6 +1305,20 @@ PxeBcRegisterIp6Address (
     goto ON_EXIT;\r
   }\r
 \r
+  //\r
+  // Get Duplicate Address Detection Transmits count.\r
+  //\r
+  DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
+  Status = Ip6Cfg->GetData (\r
+                     Ip6Cfg,\r
+                     Ip6ConfigDataTypeDupAddrDetectTransmits,\r
+                     &DataSize,\r
+                     &DadXmits\r
+                     );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
   //\r
   // Create a timer as setting address timeout event since DAD in IP6 driver.\r
   //\r
@@ -1354,7 +1370,8 @@ PxeBcRegisterIp6Address (
   // Start the 5 secondes timer to wait for setting address.\r
   //\r
   Status = EFI_NO_MAPPING;\r
-  gBS->SetTimer (TimeOutEvt, TimerRelative, PXEBC_DHCP6_MAPPING_TIMEOUT);\r
+  DadTriggerTime = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + PXEBC_DAD_ADDITIONAL_DELAY;\r
+  gBS->SetTimer (TimeOutEvt, TimerRelative, DadTriggerTime);\r
 \r
   while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {\r
     Ip6->Poll (Ip6);\r
@@ -1698,9 +1715,17 @@ PxeBcDhcp6Sarr (
   UINT8                            Buffer[PXEBC_DHCP6_OPTION_MAX_SIZE];\r
   UINT32                           OptCount;\r
   EFI_STATUS                       Status;\r
+  EFI_IP6_CONFIG_PROTOCOL          *Ip6Cfg;\r
+  EFI_STATUS                       TimerStatus;\r
+  EFI_EVENT                        Timer;\r
+  UINT64                           GetMappingTimeOut;\r
+  UINTN                            DataSize;\r
+  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS    DadXmits;\r
 \r
   Status     = EFI_SUCCESS;\r
   PxeMode    = Private->PxeBc.Mode;\r
+  Ip6Cfg     = Private->Ip6Cfg;\r
+  Timer      = NULL;\r
 \r
   //\r
   // Build option list for the request packet.\r
@@ -1735,8 +1760,8 @@ PxeBcDhcp6Sarr (
   // Configure the DHCPv6 instance for PXE boot.\r
   //\r
   Status = Dhcp6->Configure (Dhcp6, &Config);\r
+  FreePool (Retransmit);\r
   if (EFI_ERROR (Status)) {\r
-    FreePool (Retransmit);\r
     return Status;\r
   }\r
 \r
@@ -1754,6 +1779,52 @@ PxeBcDhcp6Sarr (
   // Start DHCPv6 S.A.R.R. process to acquire IPv6 address.\r
   //\r
   Status = Dhcp6->Start (Dhcp6);\r
+  if (Status == EFI_NO_MAPPING) {\r
+    //\r
+    // IP6 Linklocal address is not available for use, so stop current Dhcp process\r
+    // and wait for duplicate address detection to finish.\r
+    //\r
+    Dhcp6->Stop (Dhcp6);\r
+\r
+    //\r
+    // Get Duplicate Address Detection Transmits count.\r
+    //\r
+    DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
+    Status = Ip6Cfg->GetData (\r
+                       Ip6Cfg,\r
+                       Ip6ConfigDataTypeDupAddrDetectTransmits,\r
+                       &DataSize,\r
+                       &DadXmits\r
+                       );\r
+    if (EFI_ERROR (Status)) {\r
+      Dhcp6->Configure (Dhcp6, NULL);\r
+      return Status;\r
+    }\r
+\r
+    Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);\r
+    if (EFI_ERROR (Status)) {\r
+      Dhcp6->Configure (Dhcp6, NULL);\r
+      return Status;\r
+    }\r
+\r
+    GetMappingTimeOut = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + PXEBC_DAD_ADDITIONAL_DELAY;\r
+    Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut);\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->CloseEvent (Timer);\r
+      Dhcp6->Configure (Dhcp6, NULL);\r
+      return Status;\r
+    }\r
+\r
+    do {\r
+      \r
+      TimerStatus = gBS->CheckEvent (Timer);\r
+      if (!EFI_ERROR (TimerStatus)) {\r
+        Status = Dhcp6->Start (Dhcp6);\r
+      }\r
+    } while (TimerStatus == EFI_NOT_READY);\r
+    \r
+    gBS->CloseEvent (Timer);\r
+  }\r
   if (EFI_ERROR (Status)) {\r
     if (Status == EFI_ICMP_ERROR) {\r
       PxeMode->IcmpErrorReceived = TRUE;\r
index bf4839c493b8c23a4460c9be0b0997447c9d48f5..bb8ad65b6300e2788dd11a789f515df1eee9b9a6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Functions declaration related with DHCPv6 for UefiPxeBc Driver.\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
@@ -19,7 +19,6 @@
 #define PXEBC_DHCP6_OPTION_MAX_NUM        16\r
 #define PXEBC_DHCP6_OPTION_MAX_SIZE       312\r
 #define PXEBC_DHCP6_PACKET_MAX_SIZE       1472\r
-#define PXEBC_DHCP6_MAPPING_TIMEOUT       50000000   // 5 seconds, unit is 10nanosecond.\r
 #define PXEBC_IP6_POLICY_MAX              0xff\r
 \r
 #define PXEBC_DHCP6_S_PORT                547\r
index 0b0ff1c06a416c0366c74e75d3be276add7c712f..bea4931efbc3ca55624a65167d06999fbae217fe 100644 (file)
@@ -2,7 +2,7 @@
   This EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.\r
   interfaces declaration.\r
 \r
-  Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 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
@@ -65,6 +65,7 @@ typedef struct _PXEBC_VIRTUAL_NIC   PXEBC_VIRTUAL_NIC;
 #define PXEBC_DEFAULT_HOPLIMIT        64\r
 #define PXEBC_DEFAULT_LIFETIME        50000    // 50 ms, unit is microsecond\r
 #define PXEBC_UDP_TIMEOUT             30000000 // 3 seconds, unit is 100nanosecond\r
+#define PXEBC_DAD_ADDITIONAL_DELAY    30000000 // 3 seconds\r
 #define PXEBC_MTFTP_TIMEOUT           4\r
 #define PXEBC_MTFTP_RETRIES           6\r
 #define PXEBC_DHCP_RETRIES            4        // refers to mPxeDhcpTimeout, also by PXE2.1 spec.\r