]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
MdeModulePkg: Fix IPv4 double free
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Config2Impl.c
index fcb2bdd56270287a414d5805147926333d8f0ba8..17e0247832200cbf3fe7504ab762544cff18b5d4 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   The implementation of EFI IPv4 Configuration II Protocol.\r
 \r
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2015 - 2016, 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
@@ -149,6 +150,7 @@ Ip4Config2OnPolicyChanged (
   // Start the dhcp configuration.\r
   //\r
   if (NewPolicy == Ip4Config2PolicyDhcp) {\r
+    IpSb->Reconfig = TRUE;\r
     Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
   }\r
 \r
@@ -463,7 +465,7 @@ Ip4Config2OnDhcp4SbInstalled (
 /**\r
   Set the station address and subnetmask for the default interface.\r
 \r
-  @param[in]  Instance           The pointer to the IP4 config2 instance data.\r
+  @param[in]  IpSb               The pointer to the IP4 service binding instance.\r
   @param[in]  StationAddress     Ip address to be set.\r
   @param[in]  SubnetMask         Subnet to be set.\r
 \r
@@ -473,13 +475,12 @@ Ip4Config2OnDhcp4SbInstalled (
 **/\r
 EFI_STATUS\r
 Ip4Config2SetDefaultAddr (\r
-  IN IP4_CONFIG2_INSTANCE   *Instance,\r
+  IN IP4_SERVICE            *IpSb,\r
   IN IP4_ADDR               StationAddress,\r
   IN IP4_ADDR               SubnetMask\r
   )\r
 {\r
   EFI_STATUS                Status;\r
-  IP4_SERVICE               *IpSb;\r
   IP4_INTERFACE             *IpIf;\r
   IP4_PROTOCOL              *Ip4Instance;\r
   EFI_ARP_PROTOCOL          *Arp;\r
@@ -487,43 +488,45 @@ Ip4Config2SetDefaultAddr (
   IP4_ADDR                  Subnet;\r
   IP4_ROUTE_TABLE           *RouteTable;\r
 \r
-  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
   IpIf = IpSb->DefaultInterface;\r
   ASSERT (IpIf != NULL);\r
 \r
   if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {\r
+    IpSb->State = IP4_SERVICE_CONFIGED;\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  //\r
-  // The default address is changed, free the previous interface first.\r
-  //\r
-  if (IpSb->DefaultRouteTable != NULL) {\r
-    Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
-    IpSb->DefaultRouteTable = NULL;    \r
-  }\r
+  if (IpSb->Reconfig) {\r
+    //\r
+    // The default address is changed, free the previous interface first.\r
+    //\r
+    if (IpSb->DefaultRouteTable != NULL) {\r
+      Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
+      IpSb->DefaultRouteTable = NULL;    \r
+    }\r
 \r
-  Ip4CancelReceive (IpSb->DefaultInterface);\r
-  Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
-  IpSb->DefaultInterface = NULL;\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
+    Ip4CancelReceive (IpSb->DefaultInterface);\r
+    Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
+    IpSb->DefaultInterface = NULL;\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
-  RouteTable = Ip4CreateRouteTable ();\r
-  if (RouteTable == NULL) {\r
-    Ip4FreeInterface (IpIf, NULL);\r
-    return EFI_OUT_OF_RESOURCES;\r
+    RouteTable = Ip4CreateRouteTable ();\r
+    if (RouteTable == NULL) {\r
+      Ip4FreeInterface (IpIf, NULL);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    \r
+    IpSb->DefaultInterface  = IpIf;\r
+    InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
+    IpSb->DefaultRouteTable = RouteTable;\r
+    Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
   }\r
-  \r
-  IpSb->DefaultInterface  = IpIf;\r
-  InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
-  IpSb->DefaultRouteTable = RouteTable;\r
-  Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
 \r
   if (IpSb->State == IP4_SERVICE_CONFIGED) {\r
     IpSb->State = IP4_SERVICE_UNSTARTED;\r
@@ -577,6 +580,8 @@ Ip4Config2SetDefaultAddr (
     );\r
 \r
   IpSb->State = IP4_SERVICE_CONFIGED;\r
+  IpSb->Reconfig = FALSE;\r
+  \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -603,7 +608,9 @@ Ip4Config2SetDefaultIf (
   EFI_STATUS                Status;\r
   IP4_SERVICE               *IpSb;\r
 \r
-  Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);\r
+  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
+\r
+  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -611,7 +618,6 @@ Ip4Config2SetDefaultIf (
   //\r
   // Create a route if there is a default router.\r
   //\r
-  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
   if (GatewayAddress != IP4_ALLZERO_ADDRESS) {\r
     Ip4AddRoute (\r
       IpSb->DefaultRouteTable,\r
@@ -672,6 +678,126 @@ Ip4Config2CleanDhcp4 (
   }\r
 }\r
 \r
+/**\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
+\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
+  @param[in]     Data            The data buffer to set, points to an array of\r
+                                 EFI_IPv4_ADDRESS instances.\r
+\r
+  @retval EFI_BAD_BUFFER_SIZE    The DataSize does not match the size of the type.\r
+  @retval EFI_INVALID_PARAMETER  One or more fields in Data is invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to complete the operation.\r
+  @retval EFI_ABORTED            The DNS server addresses to be set equal the current\r
+                                 configuration.\r
+  @retval EFI_SUCCESS            The specified configuration data for the EFI IPv4\r
+                                 network stack was set.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip4Config2SetDnsServerWorker (\r
+  IN IP4_CONFIG2_INSTANCE    *Instance,\r
+  IN UINTN                   DataSize,\r
+  IN VOID                    *Data\r
+  )\r
+{\r
+  UINTN                 OldIndex;\r
+  UINTN                 NewIndex;\r
+  UINTN                 Index1;\r
+  EFI_IPv4_ADDRESS      *OldDns;\r
+  EFI_IPv4_ADDRESS      *NewDns;\r
+  UINTN                 OldDnsCount;\r
+  UINTN                 NewDnsCount;\r
+  IP4_CONFIG2_DATA_ITEM *Item;\r
+  BOOLEAN               OneAdded;\r
+  VOID                  *Tmp;\r
+  IP4_ADDR              DnsAddress;\r
+\r
+  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  Item        = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
+  NewDns      = (EFI_IPv4_ADDRESS *) Data;\r
+  OldDns      = Item->Data.DnsServers;\r
+  NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);  \r
+  OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
+  OneAdded    = FALSE;\r
+\r
+  if (NewDnsCount != OldDnsCount) {\r
+    Tmp = AllocatePool (DataSize);\r
+    if (Tmp == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  } else {\r
+    Tmp = NULL;\r
+  }\r
+\r
+  for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
+    CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
+\r
+    if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {\r
+      //\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
+        FreePool (Tmp);\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
+    if (OneAdded) {\r
+      //\r
+      // If any address in the new setting is not in the old settings, skip the\r
+      // comparision below.\r
+      //\r
+      continue;\r
+    }\r
+\r
+    for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {\r
+      if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {\r
+        //\r
+        // If found break out.\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (OldIndex == OldDnsCount) {\r
+      OneAdded = TRUE;\r
+    }\r
+  }\r
+\r
+  if (!OneAdded && (DataSize == Item->DataSize)) {\r
+    //\r
+    // No new item is added and the size is the same.\r
+    //\r
+    Item->Status = EFI_SUCCESS;\r
+    return EFI_ABORTED;\r
+  } else {\r
+    if (Tmp != NULL) {\r
+      if (Item->Data.Ptr != NULL) {\r
+        FreePool (Item->Data.Ptr);\r
+      }      \r
+      Item->Data.Ptr = Tmp;\r
+    }\r
+\r
+    CopyMem (Item->Data.Ptr, Data, DataSize);\r
+    Item->DataSize = DataSize;\r
+    Item->Status   = EFI_SUCCESS;\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+\r
 \r
 /**\r
   Callback function when DHCP process finished. It will save the\r
@@ -696,6 +822,9 @@ Ip4Config2OnDhcp4Complete (
   IP4_ADDR                  StationAddress;\r
   IP4_ADDR                  SubnetMask;\r
   IP4_ADDR                  GatewayAddress;\r
+  UINT32                    Index;\r
+  UINT32                    OptionCount;\r
+  EFI_DHCP4_PACKET_OPTION   **OptionList;\r
 \r
   Instance = (IP4_CONFIG2_INSTANCE *) Context;\r
   ASSERT (Instance->Dhcp4 != NULL);\r
@@ -719,6 +848,44 @@ Ip4Config2OnDhcp4Complete (
       goto Exit;\r
     }\r
   \r
+    //\r
+    // Parse the ACK to get required DNS server information.\r
+    //\r
+    OptionCount = 0;\r
+    OptionList  = NULL;\r
+\r
+    Status      = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
+    if (Status != EFI_BUFFER_TOO_SMALL) {\r
+      goto Exit;\r
+    }\r
+\r
+    OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));\r
+    if (OptionList == NULL) {\r
+      goto Exit;\r
+    }\r
+\r
+    Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (OptionList);\r
+      goto Exit;\r
+    }\r
+\r
+    for (Index = 0; Index < OptionCount; Index++) {\r
+      //\r
+      // Look for DNS Server opcode (6).\r
+      //\r
+      if (OptionList[Index]->OpCode == DHCP_TAG_DNS_SERVER) {\r
+        if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {\r
+          break;\r
+        }\r
+\r
+        Ip4Config2SetDnsServerWorker (Instance, OptionList[Index]->Length, &OptionList[Index]->Data[0]);\r
+        break;\r
+      }\r
+    }\r
+\r
+    FreePool (OptionList);\r
+\r
     Instance->DhcpSuccess = TRUE;\r
   }\r
 \r
@@ -826,9 +993,10 @@ Ip4StartAutoConfig (
   // yields the control of this DHCP service to us.\r
   //\r
   ParaList.Head.OpCode             = DHCP_TAG_PARA_LIST;\r
-  ParaList.Head.Length             = 2;\r
+  ParaList.Head.Length             = 3;\r
   ParaList.Head.Data[0]            = DHCP_TAG_NETMASK;\r
   ParaList.Route                   = DHCP_TAG_ROUTER;\r
+  ParaList.Dns                     = DHCP_TAG_DNS_SERVER;\r
   OptionList[0]                    = &ParaList.Head;\r
   Dhcp4Mode.ConfigData.OptionCount = 1;\r
   Dhcp4Mode.ConfigData.OptionList  = OptionList;\r
@@ -976,7 +1144,9 @@ Ip4Config2SetPolicy (
   }\r
 \r
   if (NewPolicy == Instance->Policy) {\r
-     return EFI_ABORTED;\r
+    if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) {\r
+      return EFI_ABORTED;\r
+    }\r
   } else {\r
     if (NewPolicy == Ip4Config2PolicyDhcp) {\r
       //\r
@@ -1024,6 +1194,7 @@ Ip4Config2SetPolicy (
       //\r
       if (Instance->Dhcp4Event != NULL) {\r
         gBS->CloseEvent (Instance->Dhcp4Event);\r
+        Instance->Dhcp4Event = NULL;\r
       }\r
     }\r
   }\r
@@ -1070,6 +1241,9 @@ Ip4Config2SetMaunualAddress (
   IP4_ADDR                       StationAddress;\r
   IP4_ADDR                       SubnetMask;\r
   VOID                           *Ptr;\r
+  IP4_SERVICE                    *IpSb;\r
+\r
+  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
 \r
   ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);\r
 \r
@@ -1104,7 +1278,8 @@ Ip4Config2SetMaunualAddress (
   StationAddress = EFI_NTOHL (NewAddress.Address);\r
   SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
 \r
-  Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);\r
+  IpSb->Reconfig = TRUE;\r
+  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
   }  \r
@@ -1284,102 +1459,11 @@ Ip4Config2SetDnsServer (
   IN VOID                 *Data\r
   )\r
 {\r
-  UINTN                 OldIndex;\r
-  UINTN                 NewIndex;\r
-  UINTN                 Index1;\r
-  EFI_IPv4_ADDRESS      *OldDns;\r
-  EFI_IPv4_ADDRESS      *NewDns;\r
-  UINTN                 OldDnsCount;\r
-  UINTN                 NewDnsCount;\r
-  IP4_CONFIG2_DATA_ITEM *Item;\r
-  BOOLEAN               OneAdded;\r
-  VOID                  *Tmp;\r
-  IP4_ADDR              DnsAddress;\r
-\r
-  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
-    return EFI_BAD_BUFFER_SIZE;\r
-  }\r
-\r
   if (Instance->Policy != Ip4Config2PolicyStatic) {\r
     return EFI_WRITE_PROTECTED;\r
   }\r
 \r
-  Item        = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
-  NewDns      = (EFI_IPv4_ADDRESS *) Data;\r
-  OldDns      = Item->Data.DnsServers;\r
-  NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
-  OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
-  OneAdded    = FALSE;\r
-\r
-  if (NewDnsCount != OldDnsCount) {\r
-    Tmp = AllocatePool (DataSize);\r
-    if (Tmp == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-  } else {\r
-    Tmp = NULL;\r
-  }\r
-\r
-  for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
-    CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
-\r
-    if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {\r
-      //\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
-        FreePool (Tmp);\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-\r
-    if (OneAdded) {\r
-      //\r
-      // If any address in the new setting is not in the old settings, skip the\r
-      // comparision below.\r
-      //\r
-      continue;\r
-    }\r
-\r
-    for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {\r
-      if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {\r
-        //\r
-        // If found break out.\r
-        //\r
-        break;\r
-      }\r
-    }\r
-\r
-    if (OldIndex == OldDnsCount) {\r
-      OneAdded = TRUE;\r
-    }\r
-  }\r
-\r
-  if (!OneAdded && (DataSize == Item->DataSize)) {\r
-    //\r
-    // No new item is added and the size is the same.\r
-    //\r
-    Item->Status = EFI_SUCCESS;\r
-    return EFI_ABORTED;\r
-  } else {\r
-    if (Tmp != NULL) {\r
-      if (Item->Data.Ptr != NULL) {\r
-        FreePool (Item->Data.Ptr);\r
-      }      \r
-      Item->Data.Ptr = Tmp;\r
-    }\r
-\r
-    CopyMem (Item->Data.Ptr, Data, DataSize);\r
-    Item->DataSize = DataSize;\r
-    Item->Status   = EFI_SUCCESS;\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
+  return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
 }\r
 \r
 /**\r
@@ -1827,7 +1911,7 @@ Ip4Config2InitInstance (
   DataItem->SetData  = Ip4Config2SetPolicy;\r
   DataItem->Data.Ptr = &Instance->Policy;\r
   DataItem->DataSize = sizeof (Instance->Policy);\r
-  Instance->Policy   = Ip4Config2PolicyDhcp;\r
+  Instance->Policy   = Ip4Config2PolicyStatic;\r
   SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);\r
 \r
   DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
@@ -1858,6 +1942,8 @@ Ip4Config2InitInstance (
 \r
   //\r
   // Try to read the config data from 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
   if (Status == EFI_NOT_FOUND) {\r
@@ -1867,21 +1953,7 @@ Ip4Config2InitInstance (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-\r
-  //\r
-  // Try to set the configured parameter.\r
-  //\r
-  for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; Index++) {\r
-    DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];\r
-    if (DataItem->Data.Ptr != NULL) {\r
-      DataItem->SetData (\r
-                  &IpSb->Ip4Config2Instance,\r
-                  DataItem->DataSize,\r
-                  DataItem->Data.Ptr\r
-                  );\r
-    }\r
-  }\r
-\r
+  \r
   Instance->Ip4Config2.SetData              = EfiIp4Config2SetData;\r
   Instance->Ip4Config2.GetData              = EfiIp4Config2GetData;\r
   Instance->Ip4Config2.RegisterDataNotify   = EfiIp4Config2RegisterDataNotify;\r
@@ -1926,6 +1998,7 @@ Ip4Config2CleanInstance (
   //\r
   if (Instance->Dhcp4Event != NULL) {\r
     gBS->CloseEvent (Instance->Dhcp4Event);\r
+    Instance->Dhcp4Event = NULL;\r
   }\r
 \r
   for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {\r
@@ -1948,3 +2021,53 @@ Ip4Config2CleanInstance (
   RemoveEntryList (&Instance->Link);\r
 }\r
 \r
+/**\r
+  The event handle for IP4 auto reconfiguration. The original default\r
+  interface and route table will be removed as the default.\r
+\r
+  @param[in]  Context                The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBackDpc (\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  IP4_SERVICE               *IpSb;\r
+\r
+  IpSb      = (IP4_SERVICE *) Context;\r
+  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
+\r
+  if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
+    IpSb->State = IP4_SERVICE_UNSTARTED;\r
+  }\r
+  \r
+  IpSb->Reconfig = TRUE;\r
+\r
+  Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
+\r
+  return ;\r
+}\r
+\r
+\r
+/**\r
+  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.\r
+\r
+  @param Event     The event that is signalled.\r
+  @param Context   The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBack (\r
+  IN EFI_EVENT              Event,\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  //\r
+  // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK\r
+  //\r
+  QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);\r
+}\r
+\r