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