NetworkPkg: Fix DHCP TransmitReceive EFI_NO_MAPPING return in DnsDxe
v2: * Add Timeout check, if time out, return EFI_DEVICE_ERROR. If the default station address is not available, TransmitReceive function will return EFI_NO_MAPPING. DNS driver should handle this case. This issue is caused by the r18201 fix. Cc: Ye Ting <ting.ye@intel.com> Cc: Zhang Lubo <lubo.zhang@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Lubo Zhang <lubo.zhang@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18248 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
		| @@ -14,6 +14,152 @@ Intel Corporation. | ||||
|  | ||||
| #include "DnsImpl.h" | ||||
|  | ||||
| /** | ||||
|   The callback function for the timer event used to get map. | ||||
|  | ||||
|   @param[in] Event    The event this function is registered to. | ||||
|   @param[in] Context  The context registered to the event. | ||||
| **/ | ||||
| VOID | ||||
| EFIAPI | ||||
| TimeoutToGetMap ( | ||||
|   IN EFI_EVENT      Event, | ||||
|   IN VOID           *Context | ||||
|   ) | ||||
| { | ||||
|   *((BOOLEAN *) Context) = TRUE; | ||||
|   return ; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   Create an IP child, use it to start the auto configuration, then destroy it. | ||||
|  | ||||
|   @param[in] Controller       The controller which has the service installed. | ||||
|   @param[in] Image            The image handle used to open service. | ||||
|  | ||||
|   @retval EFI_SUCCESS         The configuration is done. | ||||
|   @retval Others              Other errors as indicated. | ||||
| **/ | ||||
| EFI_STATUS | ||||
| EFIAPI | ||||
| DnsStartIp4( | ||||
|   IN  EFI_HANDLE            Controller, | ||||
|   IN  EFI_HANDLE            Image | ||||
|   ) | ||||
| { | ||||
|   EFI_IP4_PROTOCOL              *Ip4; | ||||
|   EFI_HANDLE                    Ip4Handle; | ||||
|   EFI_EVENT                     TimerToGetMap; | ||||
|   EFI_IP4_CONFIG_DATA           Ip4ConfigData; | ||||
|   EFI_IP4_MODE_DATA             Ip4Mode; | ||||
|   EFI_STATUS                    Status; | ||||
|  | ||||
|   BOOLEAN                       Timeout; | ||||
|  | ||||
|   // | ||||
|   // Get the Ip4ServiceBinding Protocol | ||||
|   // | ||||
|   Ip4Handle     = NULL; | ||||
|   Ip4           = NULL; | ||||
|   TimerToGetMap = NULL; | ||||
|    | ||||
|   Timeout      = FALSE; | ||||
|  | ||||
|   Status = NetLibCreateServiceChild ( | ||||
|              Controller, | ||||
|              Image, | ||||
|              &gEfiIp4ServiceBindingProtocolGuid, | ||||
|              &Ip4Handle | ||||
|              ); | ||||
|  | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     return Status; | ||||
|   } | ||||
|  | ||||
|   Status = gBS->OpenProtocol ( | ||||
|                  Ip4Handle, | ||||
|                  &gEfiIp4ProtocolGuid, | ||||
|                  (VOID **) &Ip4, | ||||
|                  Controller, | ||||
|                  Image, | ||||
|                  EFI_OPEN_PROTOCOL_GET_PROTOCOL | ||||
|                  ); | ||||
|  | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto ON_EXIT; | ||||
|   } | ||||
|  | ||||
|   Ip4ConfigData.DefaultProtocol          = EFI_IP_PROTO_ICMP; | ||||
|   Ip4ConfigData.AcceptAnyProtocol        = FALSE; | ||||
|   Ip4ConfigData.AcceptIcmpErrors         = FALSE; | ||||
|   Ip4ConfigData.AcceptBroadcast          = FALSE; | ||||
|   Ip4ConfigData.AcceptPromiscuous        = FALSE; | ||||
|   Ip4ConfigData.UseDefaultAddress        = TRUE; | ||||
|   ZeroMem (&Ip4ConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS)); | ||||
|   ZeroMem (&Ip4ConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); | ||||
|   Ip4ConfigData.TypeOfService            = 0; | ||||
|   Ip4ConfigData.TimeToLive               = 1; | ||||
|   Ip4ConfigData.DoNotFragment            = FALSE; | ||||
|   Ip4ConfigData.RawData                  = FALSE; | ||||
|   Ip4ConfigData.ReceiveTimeout           = 0; | ||||
|   Ip4ConfigData.TransmitTimeout          = 0; | ||||
|  | ||||
|   Status = Ip4->Configure (Ip4, &Ip4ConfigData); | ||||
|  | ||||
|   if (Status == EFI_NO_MAPPING) { | ||||
|     Status  = gBS->CreateEvent ( | ||||
|                     EVT_NOTIFY_SIGNAL | EVT_TIMER, | ||||
|                     TPL_CALLBACK, | ||||
|                     TimeoutToGetMap, | ||||
|                     &Timeout, | ||||
|                     &TimerToGetMap | ||||
|                     ); | ||||
|      | ||||
|     if (EFI_ERROR (Status)) { | ||||
|       goto ON_EXIT; | ||||
|     } | ||||
|      | ||||
|     Status = gBS->SetTimer ( | ||||
|                    TimerToGetMap, | ||||
|                    TimerRelative, | ||||
|                    MultU64x32 (10000000, 5) | ||||
|                    ); | ||||
|      | ||||
|     if (EFI_ERROR (Status)) { | ||||
|       goto ON_EXIT; | ||||
|     } | ||||
|      | ||||
|     while (!Timeout) { | ||||
|       Ip4->Poll (Ip4); | ||||
|    | ||||
|       if (!EFI_ERROR (Ip4->GetModeData (Ip4, &Ip4Mode, NULL, NULL)) &&  | ||||
|           Ip4Mode.IsConfigured) {        | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (Timeout) { | ||||
|       Status = EFI_DEVICE_ERROR; | ||||
|     } | ||||
|   } | ||||
|    | ||||
| ON_EXIT:  | ||||
|  | ||||
|   if (TimerToGetMap != NULL) { | ||||
|     gBS->SetTimer (TimerToGetMap, TimerCancel, 0); | ||||
|     gBS->CloseEvent (TimerToGetMap); | ||||
|   } | ||||
|  | ||||
|   NetLibDestroyServiceChild ( | ||||
|     Controller, | ||||
|     Image, | ||||
|     &gEfiIp4ServiceBindingProtocolGuid, | ||||
|     Ip4Handle | ||||
|     ); | ||||
|    | ||||
|   return Status; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   This function initialize the DHCP4 message instance. | ||||
|  | ||||
| @@ -322,6 +468,16 @@ GetDns4ServerFromDhcp4 ( | ||||
|     return EFI_NO_MEDIA; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Start the auto configuration if UseDefaultSetting. | ||||
|   // | ||||
|   if (Instance->Dns4CfgData.UseDefaultSetting) { | ||||
|     Status = DnsStartIp4 (Controller, Image); | ||||
|     if (EFI_ERROR(Status)) { | ||||
|       return Status; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   // | ||||
|   // Create a Mnp child instance, get the protocol and config for it. | ||||
|   // | ||||
|   | ||||
		Reference in New Issue
	
	Block a user