Becase EFI_TIMEOUT and EFI_NO_MAPPING are not the returned code in 
Dns4Configure according UEFI spec. That is also the reason why DNS  driver 
should handle this case. We can use EFI_DEVICE_ERROR instead since it means an 
unexpected network error occurred.

For the DnsStartIp4(), I will add the error code description before checkin my 
code.

Thanks.
Jiaxin

-----Original Message-----
From: Ye, Ting 
Sent: Wednesday, August 19, 2015 2:38 PM
To: Wu, Jiaxin; edk2-devel@lists.01.org
Cc: Zhang, Lubo
Subject: RE: [PATCH v2] NetworkPkg: Fix DHCP TransmitReceive EFI_NO_MAPPING 
return in DnsDxe

When timeout, why don't use EFI_TIMEOUT as error code? Also, the error code is 
missed in function description of DnsStartIp4().
Other parts are good to me.

Reviewed-by: Ye Ting <ting...@intel.com> 

-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, August 19, 2015 1:49 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting; Zhang, Lubo
Subject: [PATCH v2] 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...@intel.com>
Cc: Zhang Lubo <lubo.zh...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin...@intel.com>
---
 NetworkPkg/DnsDxe/DnsDhcp.c  | 155 +++++++++++++++++++++++++++++++++++++++++++
 NetworkPkg/DnsDxe/DnsDxe.inf |   2 +
 2 files changed, 157 insertions(+)

diff --git a/NetworkPkg/DnsDxe/DnsDhcp.c b/NetworkPkg/DnsDxe/DnsDhcp.c index 
1cc337f..d0a0888 100644
--- a/NetworkPkg/DnsDxe/DnsDhcp.c
+++ b/NetworkPkg/DnsDxe/DnsDhcp.c
@@ -13,10 +13,155 @@ 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.
+**/
+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.
 
   This function will pad each item of dhcp4 message packet.
 
   @param  Seed             Pointer to the message instance of the DHCP4 packet.
@@ -321,10 +466,20 @@ GetDns4ServerFromDhcp4 (
   if (!MediaPresent) {
     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.
   //
   Status = NetLibCreateServiceChild (
              Controller,
              Image,
diff --git a/NetworkPkg/DnsDxe/DnsDxe.inf b/NetworkPkg/DnsDxe/DnsDxe.inf index 
bed0bd3..d63bbbe 100644
--- a/NetworkPkg/DnsDxe/DnsDxe.inf
+++ b/NetworkPkg/DnsDxe/DnsDxe.inf
@@ -59,10 +59,12 @@
   gEfiUdp4ServiceBindingProtocolGuid              ## TO_START
   gEfiUdp4ProtocolGuid                            ## BY_START
   gEfiDhcp4ServiceBindingProtocolGuid             ## SOMETIMES_CONSUMES
   gEfiDhcp4ProtocolGuid                           ## SOMETIMES_CONSUMES
   gEfiIp4Config2ProtocolGuid                      ## SOMETIMES_CONSUMES
+  gEfiIp4ServiceBindingProtocolGuid               ## SOMETIMES_CONSUMES
+  gEfiIp4ProtocolGuid                             ## SOMETIMES_CONSUMES
   gEfiManagedNetworkServiceBindingProtocolGuid    ## SOMETIMES_CONSUMES
   gEfiManagedNetworkProtocolGuid                  ## SOMETIMES_CONSUMES
   
   gEfiDns6ServiceBindingProtocolGuid              ## BY_START
   gEfiDns6ProtocolGuid                            ## BY_START
--
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to