]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Config2Impl.c
index 88ead9d26949cd2ec8d835680e8afff489621237..9dca48ddd6458044b089ed6b492ee29b8a365a0d 100644 (file)
@@ -1,16 +1,10 @@
 /** @file\r
   The implementation of EFI IPv4 Configuration II Protocol.\r
 \r
-  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
   (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<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
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -82,7 +76,7 @@ Ip4Config2DestroyDhcp4 (
 \r
   Instance->Dhcp4Handle = NULL;\r
 \r
-  return Status;  \r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -112,7 +106,7 @@ Ip4Config2OnPolicyChanged (
   if (IpSb->DefaultInterface != NULL) {\r
     if (IpSb->DefaultRouteTable != NULL) {\r
       Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
-      IpSb->DefaultRouteTable = NULL;    \r
+      IpSb->DefaultRouteTable = NULL;\r
     }\r
 \r
     Ip4CancelReceive (IpSb->DefaultInterface);\r
@@ -125,7 +119,7 @@ Ip4Config2OnPolicyChanged (
 \r
   //\r
   // Create new default interface and route table.\r
-  //    \r
+  //\r
   IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
   if (IpIf == NULL) {\r
     return ;\r
@@ -136,7 +130,7 @@ Ip4Config2OnPolicyChanged (
     Ip4FreeInterface (IpIf, NULL);\r
     return ;\r
   }\r
-  \r
+\r
   IpSb->DefaultInterface  = IpIf;\r
   InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
   IpSb->DefaultRouteTable = RouteTable;\r
@@ -255,7 +249,7 @@ Ip4Config2ReadConfigData (
       return EFI_NOT_FOUND;\r
     }\r
 \r
\r
+\r
     for (Index = 0; Index < Variable->DataRecordCount; Index++) {\r
 \r
       CopyMem (&DataRecord, &Variable->DataRecord[Index], sizeof (DataRecord));\r
@@ -375,8 +369,8 @@ Ip4Config2WriteConfigData (
 \r
 \r
 /**\r
-  Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData. \r
-  The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the \r
+  Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData.\r
+  The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the\r
   IP4 driver.\r
 \r
   @param[in]   IpSb        The IP4 service binding instance.\r
@@ -392,7 +386,7 @@ Ip4Config2BuildDefaultRouteTable (
   OUT EFI_IP4_ROUTE_TABLE       *Table\r
   )\r
 {\r
-  LIST_ENTRY                *Entry; \r
+  LIST_ENTRY                *Entry;\r
   IP4_ROUTE_ENTRY           *RtEntry;\r
   UINT32                    Count;\r
   INT32                     Index;\r
@@ -468,8 +462,8 @@ Ip4Config2OnDhcp4SbInstalled (
   @param[in]  StationAddress     Ip address to be set.\r
   @param[in]  SubnetMask         Subnet to be set.\r
 \r
-  @retval EFI_SUCCESS   Set default address successful.     \r
-  @retval Others        Some errors occur in setting.     \r
+  @retval EFI_SUCCESS   Set default address successful.\r
+  @retval Others        Some errors occur in setting.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -501,7 +495,7 @@ Ip4Config2SetDefaultAddr (
     //\r
     if (IpSb->DefaultRouteTable != NULL) {\r
       Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
-      IpSb->DefaultRouteTable = NULL;    \r
+      IpSb->DefaultRouteTable = NULL;\r
     }\r
 \r
     Ip4CancelReceive (IpSb->DefaultInterface);\r
@@ -509,7 +503,7 @@ Ip4Config2SetDefaultAddr (
     IpSb->DefaultInterface = NULL;\r
     //\r
     // Create new default interface and route table.\r
-    //    \r
+    //\r
     IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
     if (IpIf == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -520,7 +514,7 @@ Ip4Config2SetDefaultAddr (
       Ip4FreeInterface (IpIf, NULL);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    \r
+\r
     IpSb->DefaultInterface  = IpIf;\r
     InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
     IpSb->DefaultRouteTable = RouteTable;\r
@@ -537,8 +531,8 @@ Ip4Config2SetDefaultAddr (
   }\r
 \r
   if (IpIf->Arp != NULL) {\r
-    //   \r
-    // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address, \r
+    //\r
+    // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address,\r
     // but some IP children may have referenced the default interface before it is configured,\r
     // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.\r
     //\r
@@ -559,13 +553,6 @@ Ip4Config2SetDefaultAddr (
     }\r
   }\r
 \r
-  Ip4AddRoute (\r
-    IpSb->DefaultRouteTable,\r
-    StationAddress,\r
-    SubnetMask,\r
-    IP4_ALLZERO_ADDRESS\r
-    );\r
-\r
   //\r
   // Add a route for the connected network.\r
   //\r
@@ -580,20 +567,20 @@ Ip4Config2SetDefaultAddr (
 \r
   IpSb->State = IP4_SERVICE_CONFIGED;\r
   IpSb->Reconfig = FALSE;\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Set the station address, subnetmask and gateway address for the default interface.\r
 \r
-  @param[in]  Instance         The pointer to the IP4 config2 instance data.  \r
+  @param[in]  Instance         The pointer to the IP4 config2 instance data.\r
   @param[in]  StationAddress   Ip address to be set.\r
   @param[in]  SubnetMask       Subnet to be set.\r
   @param[in]  GatewayAddress   Gateway to be set.\r
 \r
-  @retval EFI_SUCCESS     Set default If successful.    \r
-  @retval Others          Errors occur as indicated.  \r
+  @retval EFI_SUCCESS     Set default If successful.\r
+  @retval Others          Errors occur as indicated.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -609,6 +596,13 @@ Ip4Config2SetDefaultIf (
 \r
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
 \r
+  //\r
+  // Check whether the StationAddress/SubnetMask pair is valid.\r
+  //\r
+  if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -623,7 +617,7 @@ Ip4Config2SetDefaultIf (
       IP4_ALLZERO_ADDRESS,\r
       IP4_ALLZERO_ADDRESS,\r
       GatewayAddress\r
-      );        \r
+      );\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -680,7 +674,7 @@ Ip4Config2CleanDhcp4 (
 /**\r
   This worker function sets the DNS server list for the EFI IPv4 network\r
   stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL\r
-  manages. The DNS server addresses must be unicast IPv4 addresses. \r
+  manages. The DNS server addresses must be unicast IPv4 addresses.\r
 \r
   @param[in]     Instance        The pointer to the IP4 config2 instance data.\r
   @param[in]     DataSize        The size of the buffer pointed to by Data in bytes.\r
@@ -705,7 +699,6 @@ Ip4Config2SetDnsServerWorker (
 {\r
   UINTN                 OldIndex;\r
   UINTN                 NewIndex;\r
-  UINTN                 Index1;\r
   EFI_IPv4_ADDRESS      *OldDns;\r
   EFI_IPv4_ADDRESS      *NewDns;\r
   UINTN                 OldDnsCount;\r
@@ -722,7 +715,7 @@ Ip4Config2SetDnsServerWorker (
   Item        = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
   NewDns      = (EFI_IPv4_ADDRESS *) Data;\r
   OldDns      = Item->Data.DnsServers;\r
-  NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);  \r
+  NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
   OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
   OneAdded    = FALSE;\r
 \r
@@ -741,15 +734,10 @@ Ip4Config2SetDnsServerWorker (
       //\r
       // The dns server address must be unicast.\r
       //\r
-      FreePool (Tmp);\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {\r
-      if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {\r
+      if (Tmp != NULL) {\r
         FreePool (Tmp);\r
-        return EFI_INVALID_PARAMETER;\r
       }\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
 \r
     if (OneAdded) {\r
@@ -784,7 +772,7 @@ Ip4Config2SetDnsServerWorker (
     if (Tmp != NULL) {\r
       if (Item->Data.Ptr != NULL) {\r
         FreePool (Item->Data.Ptr);\r
-      }      \r
+      }\r
       Item->Data.Ptr = Tmp;\r
     }\r
 \r
@@ -845,7 +833,7 @@ Ip4Config2OnDhcp4Complete (
     if (EFI_ERROR (Status)) {\r
       goto Exit;\r
     }\r
-  \r
+\r
     //\r
     // Parse the ACK to get required DNS server information.\r
     //\r
@@ -915,7 +903,6 @@ Ip4StartAutoConfig (
   EFI_DHCP4_PACKET_OPTION        *OptionList[1];\r
   IP4_CONFIG2_DHCP4_OPTION       ParaList;\r
   EFI_STATUS                     Status;\r
\r
 \r
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
 \r
@@ -969,8 +956,18 @@ Ip4StartAutoConfig (
                   IpSb->Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    NetLibDestroyServiceChild (\r
+      IpSb->Controller,\r
+      IpSb->Image,\r
+      &gEfiDhcp4ServiceBindingProtocolGuid,\r
+      Instance->Dhcp4Handle\r
+      );\r
 \r
+    Instance->Dhcp4Handle = NULL;\r
+\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Check the current DHCP status, if the DHCP process has\r
@@ -978,11 +975,10 @@ Ip4StartAutoConfig (
   //\r
   Dhcp4  = Instance->Dhcp4;\r
   Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
-\r
   if (Dhcp4Mode.State == Dhcp4Bound) {\r
     Ip4Config2OnDhcp4Complete (NULL, Instance);\r
-    return EFI_SUCCESS;\r
 \r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -1000,11 +996,28 @@ Ip4StartAutoConfig (
   Dhcp4Mode.ConfigData.OptionList  = OptionList;\r
 \r
   Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
-\r
   if (EFI_ERROR (Status)) {\r
+    gBS->CloseProtocol (\r
+           Instance->Dhcp4Handle,\r
+           &gEfiDhcp4ProtocolGuid,\r
+           IpSb->Image,\r
+           IpSb->Controller\r
+           );\r
+\r
+    NetLibDestroyServiceChild (\r
+      IpSb->Controller,\r
+      IpSb->Image,\r
+      &gEfiDhcp4ServiceBindingProtocolGuid,\r
+      Instance->Dhcp4Handle\r
+      );\r
+\r
+    Instance->Dhcp4 = NULL;\r
+\r
+    Instance->Dhcp4Handle = NULL;\r
+\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Start the DHCP process\r
   //\r
@@ -1015,27 +1028,30 @@ Ip4StartAutoConfig (
                   Instance,\r
                   &Instance->Dhcp4Event\r
                   );\r
-\r
   if (EFI_ERROR (Status)) {\r
+    Ip4Config2DestroyDhcp4 (Instance);\r
     return Status;\r
   }\r
 \r
   Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
-\r
   if (EFI_ERROR (Status)) {\r
+    Ip4Config2DestroyDhcp4 (Instance);\r
+    gBS->CloseEvent (Instance->Dhcp4Event);\r
+    Instance->Dhcp4Event = NULL;\r
+\r
     return Status;\r
   }\r
\r
-  IpSb->State     = IP4_SERVICE_STARTED;\r
+\r
+  IpSb->State = IP4_SERVICE_STARTED;\r
   DispatchDpc ();\r
-  return EFI_SUCCESS;\r
 \r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 \r
 /**\r
-  The work function is to get the interface information of the communication \r
+  The work function is to get the interface information of the communication\r
   device this IP4_CONFIG2_INSTANCE manages.\r
 \r
   @param[in]      Instance Pointer to the IP4 config2 instance data.\r
@@ -1070,7 +1086,7 @@ Ip4Config2GetIfInfo (
   if (IpSb->DefaultRouteTable != NULL) {\r
     Length += IpSb->DefaultRouteTable->TotalNum * sizeof (EFI_IP4_ROUTE_TABLE);\r
   }\r
-  \r
+\r
   if (*DataSize < Length) {\r
     *DataSize = Length;\r
     return EFI_BUFFER_TOO_SMALL;\r
@@ -1097,14 +1113,14 @@ Ip4Config2GetIfInfo (
     IfInfo->RouteTableSize = IpSb->DefaultRouteTable->TotalNum;\r
     IfInfo->RouteTable   = (EFI_IP4_ROUTE_TABLE *) ((UINT8 *) Data + sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));\r
 \r
-    Ip4Config2BuildDefaultRouteTable (IpSb, IfInfo->RouteTable);  \r
+    Ip4Config2BuildDefaultRouteTable (IpSb, IfInfo->RouteTable);\r
   }\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  The work function is to set the general configuration policy for the EFI IPv4 network \r
+  The work function is to set the general configuration policy for the EFI IPv4 network\r
   stack that is running on the communication device managed by this IP4_CONFIG2_INSTANCE.\r
   The policy will affect other configuration settings.\r
 \r
@@ -1146,7 +1162,7 @@ Ip4Config2SetPolicy (
     }\r
   } else {\r
     //\r
-    // The policy is changed. Clean the ManualAddress, Gateway and DnsServers, \r
+    // The policy is changed. Clean the ManualAddress, Gateway and DnsServers,\r
     // shrink the variable data size, and fire up all the related events.\r
     //\r
     DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
@@ -1175,7 +1191,7 @@ Ip4Config2SetPolicy (
     DataItem->DataSize = 0;\r
     DataItem->Status   = EFI_NOT_FOUND;\r
     NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);\r
-    \r
+\r
     if (NewPolicy == Ip4Config2PolicyDhcp) {\r
       SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_VOLATILE);\r
     } else {\r
@@ -1186,7 +1202,7 @@ Ip4Config2SetPolicy (
       if (Instance->Dhcp4Handle != NULL) {\r
         Ip4Config2DestroyDhcp4 (Instance);\r
       }\r
-      \r
+\r
       //\r
       // Close the event.\r
       //\r
@@ -1206,7 +1222,7 @@ Ip4Config2SetPolicy (
 }\r
 \r
 /**\r
-  The work function is to set the station addresses manually for the EFI IPv4 \r
+  The work function is to set the station addresses manually for the EFI IPv4\r
   network stack. It is only configurable when the policy is Ip4Config2PolicyStatic.\r
 \r
   @param[in]     Instance Pointer to the IP4 config2 instance data.\r
@@ -1227,7 +1243,7 @@ Ip4Config2SetPolicy (
 \r
 **/\r
 EFI_STATUS\r
-Ip4Config2SetMaunualAddress (\r
+Ip4Config2SetManualAddress (\r
   IN IP4_CONFIG2_INSTANCE *Instance,\r
   IN UINTN                DataSize,\r
   IN VOID                 *Data\r
@@ -1240,12 +1256,20 @@ Ip4Config2SetMaunualAddress (
   IP4_ADDR                       SubnetMask;\r
   VOID                           *Ptr;\r
   IP4_SERVICE                    *IpSb;\r
+  IP4_INTERFACE                  *IpIf;\r
+  IP4_ROUTE_TABLE                *RouteTable;\r
+\r
+  DataItem   = NULL;\r
+  Status     = EFI_SUCCESS;\r
+  Ptr        = NULL;\r
+  IpIf       = NULL;\r
+  RouteTable = NULL;\r
 \r
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
 \r
   ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);\r
 \r
-  if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {\r
+  if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0)) {\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
@@ -1253,51 +1277,110 @@ Ip4Config2SetMaunualAddress (
     return EFI_WRITE_PROTECTED;\r
   }\r
 \r
-  NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);\r
+  DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
 \r
-  StationAddress = EFI_NTOHL (NewAddress.Address);\r
-  SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
+  if (Data != NULL && DataSize != 0) {\r
+    NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);\r
 \r
-  if (NetGetMaskLength (SubnetMask) == IP4_MASK_NUM) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
+    StationAddress = EFI_NTOHL (NewAddress.Address);\r
+    SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
 \r
-  //\r
-  // Store the new data, and init the DataItem status to EFI_NOT_READY because\r
-  // we may have an asynchronous configuration process.\r
-  //\r
-  Ptr = AllocateCopyPool (DataSize, Data);\r
-  if (Ptr == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
+    //\r
+    // Check whether the StationAddress/SubnetMask pair is valid.\r
+    //\r
+    if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
 \r
-  DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
-  if (DataItem->Data.Ptr != NULL) {\r
-    FreePool (DataItem->Data.Ptr);\r
-  }\r
-  \r
-  DataItem->Data.Ptr = Ptr;\r
-  DataItem->DataSize = DataSize;\r
-  DataItem->Status   = EFI_NOT_READY;\r
+    //\r
+    // Store the new data, and init the DataItem status to EFI_NOT_READY because\r
+    // we may have an asynchronous configuration process.\r
+    //\r
+    Ptr = AllocateCopyPool (DataSize, Data);\r
+    if (Ptr == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
-  IpSb->Reconfig = TRUE;\r
-  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
+    if (DataItem->Data.Ptr != NULL) {\r
+      FreePool (DataItem->Data.Ptr);\r
+    }\r
+\r
+    DataItem->Data.Ptr = Ptr;\r
+    DataItem->DataSize = DataSize;\r
+    DataItem->Status   = EFI_NOT_READY;\r
+\r
+    IpSb->Reconfig = TRUE;\r
+    Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
+\r
+    DataItem->Status = Status;\r
+\r
+    if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {\r
+      if (Ptr != NULL) {\r
+        FreePool (Ptr);\r
+      }\r
+      DataItem->Data.Ptr = NULL;\r
+    }\r
+  } else {\r
+    //\r
+    // DataSize is 0 and Data is NULL, clean up the manual address.\r
+    //\r
+    if (DataItem->Data.Ptr != NULL) {\r
+      FreePool (DataItem->Data.Ptr);\r
+    }\r
+    DataItem->Data.Ptr = NULL;\r
+    DataItem->DataSize = 0;\r
+    DataItem->Status   = EFI_NOT_FOUND;\r
+\r
+    //\r
+    // Free the default router table and Interface, clean up the assemble table.\r
+    //\r
+    if (IpSb->DefaultInterface != NULL) {\r
+      if (IpSb->DefaultRouteTable != NULL) {\r
+        Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
+        IpSb->DefaultRouteTable = NULL;\r
+      }\r
+\r
+      Ip4CancelReceive (IpSb->DefaultInterface);\r
+\r
+      Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
+      IpSb->DefaultInterface = NULL;\r
+    }\r
+\r
+    Ip4CleanAssembleTable (&IpSb->Assemble);\r
+\r
+    //\r
+    // Create new default interface and route table.\r
+    //\r
+    IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
+    if (IpIf == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
-  DataItem->Status = Status; \r
+    RouteTable = Ip4CreateRouteTable ();\r
+    if (RouteTable == NULL) {\r
+      Ip4FreeInterface (IpIf, NULL);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
-  if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {\r
-    if (Ptr != NULL) {\r
-      FreePool (Ptr);\r
+    IpSb->DefaultInterface  = IpIf;\r
+    InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
+    IpSb->DefaultRouteTable = RouteTable;\r
+    Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
+\r
+    //\r
+    // Reset the State to unstarted.\r
+    //\r
+    if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) {\r
+      IpSb->State = IP4_SERVICE_UNSTARTED;\r
     }\r
-    DataItem->Data.Ptr = NULL; \r
   }\r
 \r
   return Status;\r
 }\r
 \r
 /**\r
-  The work function is to set the gateway addresses manually for the EFI IPv4 \r
-  network stack that is running on the communication device that this EFI IPv4 \r
+  The work function is to set the gateway addresses manually for the EFI IPv4\r
+  network stack that is running on the communication device that this EFI IPv4\r
   Configuration Protocol manages. It is not configurable when the policy is\r
   Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.\r
 \r
@@ -1338,7 +1421,13 @@ Ip4Config2SetGateway (
   BOOLEAN               OneAdded;\r
   VOID                  *Tmp;\r
 \r
-  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
+  OldGateway      = NULL;\r
+  NewGateway      = NULL;\r
+  OneRemoved      = FALSE;\r
+  OneAdded        = FALSE;\r
+  Tmp             = NULL;\r
+\r
+  if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv4_ADDRESS) != 0)) {\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
@@ -1348,41 +1437,13 @@ Ip4Config2SetGateway (
 \r
   IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
 \r
-  NewGateway      = (EFI_IPv4_ADDRESS *) Data;\r
-  NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
-    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
-\r
-    if ((IpSb->DefaultInterface->SubnetMask != 0) && \r
-        !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {\r
-      if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
\r
-  DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
+  DataItem        = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
   OldGateway      = DataItem->Data.Gateway;\r
   OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
-  OneRemoved      = FALSE;\r
-  OneAdded        = FALSE;\r
-\r
-  if (NewGatewayCount != OldGatewayCount) {\r
-    Tmp = AllocatePool (DataSize);\r
-    if (Tmp == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  } else {\r
-    Tmp = NULL;\r
-  }\r
 \r
   for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {\r
     //\r
-    // Remove this route entry.\r
+    // Remove the old route entry.\r
     //\r
     CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));\r
     Ip4DelRoute (\r
@@ -1392,46 +1453,84 @@ Ip4Config2SetGateway (
       NTOHL (Gateway)\r
       );\r
     OneRemoved = TRUE;\r
-\r
   }\r
 \r
-  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
-    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
-    Ip4AddRoute (\r
-      IpSb->DefaultRouteTable,\r
-      IP4_ALLZERO_ADDRESS,\r
-      IP4_ALLZERO_ADDRESS,\r
-      NTOHL (Gateway)\r
-      );    \r
-\r
-    OneAdded = TRUE;\r
-  }\r
+  if (Data != NULL && DataSize != 0) {\r
+    NewGateway      = (EFI_IPv4_ADDRESS *) Data;\r
+    NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
+      CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
 \r
+      if ((IpSb->DefaultInterface->SubnetMask != 0) &&\r
+          !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
 \r
-  if (!OneRemoved && !OneAdded) {\r
-    DataItem->Status = EFI_SUCCESS;\r
-    return EFI_ABORTED;\r
-  } else {\r
+      for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {\r
+        if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+      }\r
+    }\r
 \r
-    if (Tmp != NULL) {\r
-      if (DataItem->Data.Ptr != NULL) {\r
-        FreePool (DataItem->Data.Ptr);\r
+    if (NewGatewayCount != OldGatewayCount) {\r
+      Tmp = AllocatePool (DataSize);\r
+      if (Tmp == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
       }\r
-      DataItem->Data.Ptr = Tmp;\r
+    } else {\r
+      Tmp = NULL;\r
     }\r
 \r
-    CopyMem (DataItem->Data.Ptr, Data, DataSize);\r
-    DataItem->DataSize = DataSize;\r
-    DataItem->Status   = EFI_SUCCESS;\r
-    return EFI_SUCCESS;\r
+    for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
+      //\r
+      // Add the new route entry.\r
+      //\r
+      CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
+      Ip4AddRoute (\r
+        IpSb->DefaultRouteTable,\r
+        IP4_ALLZERO_ADDRESS,\r
+        IP4_ALLZERO_ADDRESS,\r
+        NTOHL (Gateway)\r
+        );\r
+\r
+      OneAdded = TRUE;\r
+    }\r
+\r
+    if (!OneRemoved && !OneAdded) {\r
+      DataItem->Status = EFI_SUCCESS;\r
+      return EFI_ABORTED;\r
+    } else {\r
+      if (Tmp != NULL) {\r
+        if (DataItem->Data.Ptr != NULL) {\r
+          FreePool (DataItem->Data.Ptr);\r
+        }\r
+        DataItem->Data.Ptr = Tmp;\r
+      }\r
+\r
+      CopyMem (DataItem->Data.Ptr, Data, DataSize);\r
+      DataItem->DataSize = DataSize;\r
+      DataItem->Status   = EFI_SUCCESS;\r
+    }\r
+  } else {\r
+    //\r
+    // DataSize is 0 and Data is NULL, clean up the Gateway address.\r
+    //\r
+    if (DataItem->Data.Ptr != NULL) {\r
+      FreePool (DataItem->Data.Ptr);\r
+    }\r
+    DataItem->Data.Ptr = NULL;\r
+    DataItem->DataSize = 0;\r
+    DataItem->Status   = EFI_NOT_FOUND;\r
   }\r
 \r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  The work function is to set the DNS server list for the EFI IPv4 network \r
-  stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL \r
-  manages. It is not configurable when the policy is Ip4Config2PolicyDhcp. \r
+  The work function is to set the DNS server list for the EFI IPv4 network\r
+  stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL\r
+  manages. It is not configurable when the policy is Ip4Config2PolicyDhcp.\r
   The DNS server addresses must be unicast IPv4 addresses.\r
 \r
   @param[in]     Instance The pointer to the IP4 config2 instance data.\r
@@ -1457,9 +1556,11 @@ Ip4Config2SetDnsServer (
   IN VOID                 *Data\r
   )\r
 {\r
-  IP4_CONFIG2_DATA_ITEM *Item;\r
+  EFI_STATUS                     Status;\r
+  IP4_CONFIG2_DATA_ITEM          *Item;\r
 \r
-  Item = NULL;\r
+  Status = EFI_SUCCESS;\r
+  Item   = NULL;\r
 \r
   if (Instance->Policy != Ip4Config2PolicyStatic) {\r
     return EFI_WRITE_PROTECTED;\r
@@ -1471,7 +1572,21 @@ Ip4Config2SetDnsServer (
     REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);\r
   }\r
 \r
-  return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
+  if (Data != NULL && DataSize != 0) {\r
+    Status = Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
+  } else {\r
+    //\r
+    // DataSize is 0 and Data is NULL, clean up the DnsServer address.\r
+    //\r
+    if (Item->Data.Ptr != NULL) {\r
+      FreePool (Item->Data.Ptr);\r
+    }\r
+    Item->Data.Ptr = NULL;\r
+    Item->DataSize = 0;\r
+    Item->Status   = EFI_NOT_FOUND;\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -1488,33 +1603,18 @@ Ip4Config2InitIfInfo (
   OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo\r
   )\r
 {\r
-  IfInfo->Name[0] = L'e';\r
-  IfInfo->Name[1] = L't';\r
-  IfInfo->Name[2] = L'h';\r
-  IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip4Config2Instance.IfIndex);\r
-  IfInfo->Name[4] = 0;\r
+  UnicodeSPrint (\r
+    IfInfo->Name,\r
+    EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE,\r
+    L"eth%d",\r
+    IpSb->Ip4Config2Instance.IfIndex\r
+  );\r
 \r
   IfInfo->IfType        = IpSb->SnpMode.IfType;\r
   IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;\r
   CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress, IfInfo->HwAddressSize);\r
 }\r
 \r
-/**\r
-  The event handle routine when DHCPv4 process is finished or is updated.\r
-\r
-  @param[in]     Event         Not used.\r
-  @param[in]     Context       The pointer to the IP4 configuration instance data.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Ip4Config2OnDhcp4Event (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  )\r
-{\r
-  return ;\r
-}\r
 \r
 \r
 /**\r
@@ -1549,9 +1649,8 @@ Ip4Config2OnDhcp4Event (
                                 network stack was set successfully.\r
   @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:\r
                                 - This is NULL.\r
-                                - Data is NULL.\r
-                                - One or more fields in Data do not match the requirement of the\r
-                                  data type indicated by DataType.\r
+                                - One or more fields in Data and DataSize do not match the\r
+                                  requirement of the data type indicated by DataType.\r
   @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified\r
                                 configuration data cannot be set under the current policy.\r
   @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration\r
@@ -1579,7 +1678,7 @@ EfiIp4Config2SetData (
   IP4_CONFIG2_INSTANCE *Instance;\r
   IP4_SERVICE          *IpSb;\r
 \r
-  if ((This == NULL) || (Data == NULL)) {\r
+  if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1903,7 +2002,7 @@ Ip4Config2InitInstance (
     NetMapInit (&Instance->DataItem[Index].EventMap);\r
   }\r
 \r
-  \r
+\r
   //\r
   // Initialize each data type: associate storage and set data size for the\r
   // fixed size data types, hook the SetData function, set the data attribute.\r
@@ -1923,7 +2022,7 @@ Ip4Config2InitInstance (
   SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);\r
 \r
   DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
-  DataItem->SetData  = Ip4Config2SetMaunualAddress;\r
+  DataItem->SetData  = Ip4Config2SetManualAddress;\r
   DataItem->Status   = EFI_NOT_FOUND;\r
 \r
   DataItem           = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
@@ -1934,23 +2033,11 @@ Ip4Config2InitInstance (
   DataItem->SetData  = Ip4Config2SetDnsServer;\r
   DataItem->Status   = EFI_NOT_FOUND;\r
 \r
-  //\r
-  // Create the event used for DHCP.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  Ip4Config2OnDhcp4Event,\r
-                  Instance,\r
-                  &Instance->Dhcp4Event\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
   Instance->Configured  = TRUE;\r
 \r
   //\r
   // Try to read the config data from NV variable.\r
-  // If not found, write initialized config data into NV variable \r
+  // If not found, write initialized config data into NV variable\r
   // as a default config data.\r
   //\r
   Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);\r
@@ -1961,7 +2048,7 @@ Ip4Config2InitInstance (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   Instance->Ip4Config2.SetData              = EfiIp4Config2SetData;\r
   Instance->Ip4Config2.GetData              = EfiIp4Config2GetData;\r
   Instance->Ip4Config2.RegisterDataNotify   = EfiIp4Config2RegisterDataNotify;\r
@@ -2050,7 +2137,7 @@ Ip4AutoReconfigCallBackDpc (
   if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
     IpSb->State = IP4_SERVICE_UNSTARTED;\r
   }\r
-  \r
+\r
   IpSb->Reconfig = TRUE;\r
 \r
   Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r