From eb213f2f392dd36b5667f7cb76a98c4af0804c9c Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 20 Aug 2015 07:01:47 +0000 Subject: [PATCH] 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 Cc: Zhang Lubo Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu Reviewed-by: Ye Ting Reviewed-by: Lubo Zhang git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18248 6f19259b-4bc3-4df7-8a09-765794883524 --- NetworkPkg/DnsDxe/DnsDhcp.c | 156 +++++++++++++++++++++++++++++++++++ NetworkPkg/DnsDxe/DnsDxe.inf | 2 + 2 files changed, 158 insertions(+) diff --git a/NetworkPkg/DnsDxe/DnsDhcp.c b/NetworkPkg/DnsDxe/DnsDhcp.c index 1cc337f0cf..a9fdfb65b4 100644 --- a/NetworkPkg/DnsDxe/DnsDhcp.c +++ b/NetworkPkg/DnsDxe/DnsDhcp.c @@ -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. // diff --git a/NetworkPkg/DnsDxe/DnsDxe.inf b/NetworkPkg/DnsDxe/DnsDxe.inf index bed0bd399e..d63bbbebc4 100644 --- a/NetworkPkg/DnsDxe/DnsDxe.inf +++ b/NetworkPkg/DnsDxe/DnsDxe.inf @@ -61,6 +61,8 @@ gEfiDhcp4ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES gEfiDhcp4ProtocolGuid ## SOMETIMES_CONSUMES gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiIp4ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES + gEfiIp4ProtocolGuid ## SOMETIMES_CONSUMES gEfiManagedNetworkServiceBindingProtocolGuid ## SOMETIMES_CONSUMES gEfiManagedNetworkProtocolGuid ## SOMETIMES_CONSUMES