/** @file
  The implementation of EFI IPv4 Configuration II Protocol.

  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Ip4Impl.h"

LIST_ENTRY  mIp4Config2InstanceList = {&mIp4Config2InstanceList, &mIp4Config2InstanceList};

/**
  The event process routine when the DHCPv4 service binding protocol is installed
  in the system.

  @param[in]     Event         Not used.
  @param[in]     Context       Pointer to the IP4 config2 instance data.

**/
VOID
EFIAPI
Ip4Config2OnDhcp4SbInstalled (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.

  @param[in, out] Instance    The buffer of IP4 config2 instance to be freed.

  @retval EFI_SUCCESS         The child was successfully destroyed.
  @retval Others              Failed to destroy the child.

**/
EFI_STATUS
Ip4Config2DestroyDhcp4 (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  IP4_SERVICE                 *IpSb;
  EFI_STATUS                  Status;
  EFI_DHCP4_PROTOCOL          *Dhcp4;

  Dhcp4 = Instance->Dhcp4;
  ASSERT (Dhcp4 != NULL);

  Dhcp4->Stop (Dhcp4);
  Dhcp4->Configure (Dhcp4, NULL);
  Instance->Dhcp4 = NULL;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  //
  // Close DHCPv4 protocol and destroy the child.
  //
  Status = gBS->CloseProtocol (
                  Instance->Dhcp4Handle,
                  &gEfiDhcp4ProtocolGuid,
                  IpSb->Image,
                  IpSb->Controller
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = NetLibDestroyServiceChild (
             IpSb->Controller,
             IpSb->Image,
             &gEfiDhcp4ServiceBindingProtocolGuid,
             Instance->Dhcp4Handle
             );

  Instance->Dhcp4Handle = NULL;

  return Status;  
}

/**
  Update the current policy to NewPolicy. During the transition
  period, the default router list
  and address list in all interfaces will be released.

  @param[in]  IpSb               The IP4 service binding instance.
  @param[in]  NewPolicy          The new policy to be updated to.

**/
VOID
Ip4Config2OnPolicyChanged (
  IN IP4_SERVICE            *IpSb,
  IN EFI_IP4_CONFIG2_POLICY NewPolicy
  )
{
  IP4_INTERFACE   *IpIf;
  IP4_ROUTE_TABLE *RouteTable;

  //
  // Currently there are only two policies: static and dhcp. Regardless of
  // what transition is going on, i.e., static -> dhcp and dhcp ->
  // static, we have to free default router table and all addresses.
  //

  if (IpSb->DefaultInterface != NULL) {
    if (IpSb->DefaultRouteTable != NULL) {
      Ip4FreeRouteTable (IpSb->DefaultRouteTable);
      IpSb->DefaultRouteTable = NULL;    
    }

    Ip4CancelReceive (IpSb->DefaultInterface);

    Ip4FreeInterface (IpSb->DefaultInterface, NULL);
    IpSb->DefaultInterface = NULL;
  }

  Ip4CleanAssembleTable (&IpSb->Assemble);

  //
  // Create new default interface and route table.
  //    
  IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
  if (IpIf == NULL) {
    return ;
  }

  RouteTable = Ip4CreateRouteTable ();
  if (RouteTable == NULL) {
    Ip4FreeInterface (IpIf, NULL);
    return ;
  }
  
  IpSb->DefaultInterface  = IpIf;
  InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
  IpSb->DefaultRouteTable = RouteTable;
  Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);

  if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) {
    IpSb->State = IP4_SERVICE_UNSTARTED;
  }

  //
  // Start the dhcp configuration.
  //
  if (NewPolicy == Ip4Config2PolicyDhcp) {
    Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
  }

}

/**
  Signal the registered event. It is the callback routine for NetMapIterate.

  @param[in]  Map    Points to the list of registered event.
  @param[in]  Item   The registered event.
  @param[in]  Arg    Not used.

  @retval EFI_SUCCESS           The event was signaled successfully.
**/
EFI_STATUS
EFIAPI
Ip4Config2SignalEvent (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item,
  IN VOID                   *Arg
  )
{
  gBS->SignalEvent ((EFI_EVENT) Item->Key);

  return EFI_SUCCESS;
}

/**
  Read the configuration data from variable storage according to the VarName and
  gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the
  data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the
  configuration data to IP4_CONFIG2_INSTANCE.

  @param[in]      VarName       The pointer to the variable name
  @param[in, out] Instance      The pointer to the IP4 config2 instance data.

  @retval EFI_NOT_FOUND         The variable can not be found or already corrupted.
  @retval EFI_OUT_OF_RESOURCES  Fail to allocate resource to complete the operation.
  @retval EFI_SUCCESS           The configuration data was retrieved successfully.

**/
EFI_STATUS
Ip4Config2ReadConfigData (
  IN     CHAR16               *VarName,
  IN OUT IP4_CONFIG2_INSTANCE *Instance
  )
{
  EFI_STATUS              Status;
  UINTN                   VarSize;
  IP4_CONFIG2_VARIABLE    *Variable;
  IP4_CONFIG2_DATA_ITEM   *DataItem;
  UINTN                   Index;
  IP4_CONFIG2_DATA_RECORD DataRecord;
  CHAR8                   *Data;

  //
  // Try to read the configuration variable.
  //
  VarSize = 0;
  Status  = gRT->GetVariable (
                   VarName,
                   &gEfiIp4Config2ProtocolGuid,
                   NULL,
                   &VarSize,
                   NULL
                   );

  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate buffer and read the config variable.
    //
    Variable = AllocatePool (VarSize);
    if (Variable == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gRT->GetVariable (
                    VarName,
                    &gEfiIp4Config2ProtocolGuid,
                    NULL,
                    &VarSize,
                    Variable
                    );
    if (EFI_ERROR (Status) || (UINT16) (~NetblockChecksum ((UINT8 *) Variable, (UINT32) VarSize)) != 0) {
      //
      // GetVariable still error or the variable is corrupted.
      // Fall back to the default value.
      //
      FreePool (Variable);

      //
      // Remove the problematic variable and return EFI_NOT_FOUND, a new
      // variable will be set again.
      //
      gRT->SetVariable (
             VarName,
             &gEfiIp4Config2ProtocolGuid,
             IP4_CONFIG2_VARIABLE_ATTRIBUTE,
             0,
             NULL
             );

      return EFI_NOT_FOUND;
    }

 
    for (Index = 0; Index < Variable->DataRecordCount; Index++) {

      CopyMem (&DataRecord, &Variable->DataRecord[Index], sizeof (DataRecord));

      DataItem = &Instance->DataItem[DataRecord.DataType];
      if (DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED) &&
          (DataItem->DataSize != DataRecord.DataSize)
          ) {
        //
        // Perhaps a corrupted data record...
        //
        continue;
      }

      if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {
        //
        // This data item has variable length data.
        //
        DataItem->Data.Ptr = AllocatePool (DataRecord.DataSize);
        if (DataItem->Data.Ptr == NULL) {
          //
          // no memory resource
          //
          continue;
        }
      }

      Data = (CHAR8 *) Variable + DataRecord.Offset;
      CopyMem (DataItem->Data.Ptr, Data, DataRecord.DataSize);

      DataItem->DataSize = DataRecord.DataSize;
      DataItem->Status   = EFI_SUCCESS;
    }

    FreePool (Variable);
    return EFI_SUCCESS;
  }

  return Status;
}

/**
  Write the configuration data from IP4_CONFIG2_INSTANCE to variable storage.

  @param[in]      VarName       The pointer to the variable name.
  @param[in]      Instance      The pointer to the IP4 config2 instance data.

  @retval EFI_OUT_OF_RESOURCES  Fail to allocate resource to complete the operation.
  @retval EFI_SUCCESS           The configuration data is written successfully.

**/
EFI_STATUS
Ip4Config2WriteConfigData (
  IN CHAR16               *VarName,
  IN IP4_CONFIG2_INSTANCE *Instance
  )
{
  UINTN                   Index;
  UINTN                   VarSize;
  IP4_CONFIG2_DATA_ITEM   *DataItem;
  IP4_CONFIG2_VARIABLE    *Variable;
  IP4_CONFIG2_DATA_RECORD *DataRecord;
  CHAR8                   *Heap;
  EFI_STATUS              Status;

  VarSize = sizeof (IP4_CONFIG2_VARIABLE) - sizeof (IP4_CONFIG2_DATA_RECORD);

  for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {

    DataItem = &Instance->DataItem[Index];
    if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) {

      VarSize += sizeof (IP4_CONFIG2_DATA_RECORD) + DataItem->DataSize;
    }
  }

  Variable = AllocatePool (VarSize);
  if (Variable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Heap                      = (CHAR8 *) Variable + VarSize;
  Variable->DataRecordCount = 0;

  for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {

    DataItem = &Instance->DataItem[Index];
    if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) {

      Heap -= DataItem->DataSize;
      CopyMem (Heap, DataItem->Data.Ptr, DataItem->DataSize);

      DataRecord           = &Variable->DataRecord[Variable->DataRecordCount];
      DataRecord->DataType = (EFI_IP4_CONFIG2_DATA_TYPE) Index;
      DataRecord->DataSize = (UINT32) DataItem->DataSize;
      DataRecord->Offset   = (UINT16) (Heap - (CHAR8 *) Variable);

      Variable->DataRecordCount++;
    }
  }

  Variable->Checksum = 0;
  Variable->Checksum = (UINT16) ~NetblockChecksum ((UINT8 *) Variable, (UINT32) VarSize);

  Status = gRT->SetVariable (
                  VarName,
                  &gEfiIp4Config2ProtocolGuid,
                  IP4_CONFIG2_VARIABLE_ATTRIBUTE,
                  VarSize,
                  Variable
                  );

  FreePool (Variable);

  return Status;
}


/**
  Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData. 
  The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the 
  IP4 driver.

  @param[in]   IpSb        The IP4 service binding instance.
  @param[out]  Table       The built IP4 route table.

  @retval EFI_SUCCESS           The route table is successfully build
  @retval EFI_NOT_FOUND         Failed to allocate the memory for the rotue table.

**/
EFI_STATUS
Ip4Config2BuildDefaultRouteTable (
  IN  IP4_SERVICE               *IpSb,
  OUT EFI_IP4_ROUTE_TABLE       *Table
  )
{
  LIST_ENTRY                *Entry; 
  IP4_ROUTE_ENTRY           *RtEntry;
  UINT32                    Count;
  INT32                     Index;

  if (IpSb->DefaultRouteTable == NULL) {
    return EFI_NOT_FOUND;
  }

  Count = IpSb->DefaultRouteTable->TotalNum;

  if (Count == 0) {
    return EFI_NOT_FOUND;
  }

  //
  // Copy the route entry to EFI route table. Keep the order of
  // route entry copied from most specific to default route. That
  // is, interlevel the route entry from the instance's route area
  // and those from the default route table's route area.
  //
  Count = 0;

  for (Index = IP4_MASK_MAX; Index >= 0; Index--) {

    NET_LIST_FOR_EACH (Entry, &(IpSb->DefaultRouteTable->RouteArea[Index])) {
      RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);

      EFI_IP4 (Table[Count].SubnetAddress)  = HTONL (RtEntry->Dest & RtEntry->Netmask);
      EFI_IP4 (Table[Count].SubnetMask)     = HTONL (RtEntry->Netmask);
      EFI_IP4 (Table[Count].GatewayAddress) = HTONL (RtEntry->NextHop);

      Count++;
    }

  }

  return EFI_SUCCESS;
}

/**
  The event process routine when the DHCPv4 service binding protocol is installed
  in the system.

  @param[in]     Event         Not used.
  @param[in]     Context       The pointer to the IP4 config2 instance data.

**/
VOID
EFIAPI
Ip4Config2OnDhcp4SbInstalled (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  IP4_CONFIG2_INSTANCE  *Instance;

  Instance = (IP4_CONFIG2_INSTANCE *) Context;

  if ((Instance->Dhcp4Handle != NULL) || (Instance->Policy != Ip4Config2PolicyDhcp)) {
    //
    // The DHCP4 child is already created or the policy is no longer DHCP.
    //
    return ;
  }

  Ip4StartAutoConfig (Instance);
}

/**
  Set the station address and subnetmask for the default interface.

  @param[in]  IpSb               The pointer to the IP4 service binding instance.
  @param[in]  StationAddress     Ip address to be set.
  @param[in]  SubnetMask         Subnet to be set.

  @retval EFI_SUCCESS   Set default address successful.     
  @retval Others        Some errors occur in setting.     

**/
EFI_STATUS
Ip4Config2SetDefaultAddr (
  IN IP4_SERVICE            *IpSb,
  IN IP4_ADDR               StationAddress,
  IN IP4_ADDR               SubnetMask
  )
{
  EFI_STATUS                Status;
  IP4_INTERFACE             *IpIf;
  IP4_PROTOCOL              *Ip4Instance;
  EFI_ARP_PROTOCOL          *Arp;
  LIST_ENTRY                *Entry;
  IP4_ADDR                  Subnet;
  IP4_ROUTE_TABLE           *RouteTable;

  IpIf = IpSb->DefaultInterface;
  ASSERT (IpIf != NULL);

  if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {
    IpSb->State = IP4_SERVICE_CONFIGED;
    return EFI_SUCCESS;
  }

  if (IpSb->Reconfig) {
    //
    // The default address is changed, free the previous interface first.
    //
    if (IpSb->DefaultRouteTable != NULL) {
      Ip4FreeRouteTable (IpSb->DefaultRouteTable);
      IpSb->DefaultRouteTable = NULL;    
    }

    Ip4CancelReceive (IpSb->DefaultInterface);
    Ip4FreeInterface (IpSb->DefaultInterface, NULL);
    IpSb->DefaultInterface = NULL;
    //
    // Create new default interface and route table.
    //    
    IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
    if (IpIf == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    RouteTable = Ip4CreateRouteTable ();
    if (RouteTable == NULL) {
      Ip4FreeInterface (IpIf, NULL);
      return EFI_OUT_OF_RESOURCES;
    }
    
    IpSb->DefaultInterface  = IpIf;
    InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
    IpSb->DefaultRouteTable = RouteTable;
    Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
  }

  if (IpSb->State == IP4_SERVICE_CONFIGED) {
    IpSb->State = IP4_SERVICE_UNSTARTED;
  }

  Status = Ip4SetAddress (IpIf, StationAddress, SubnetMask);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (IpIf->Arp != NULL) {
    //   
    // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address, 
    // but some IP children may have referenced the default interface before it is configured,
    // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.
    //
    Arp = NULL;
    NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
      Ip4Instance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, AddrLink, IP4_PROTOCOL_SIGNATURE);
      Status = gBS->OpenProtocol (
                      IpIf->ArpHandle,
                      &gEfiArpProtocolGuid,
                      (VOID **) &Arp,
                      gIp4DriverBinding.DriverBindingHandle,
                      Ip4Instance->Handle,
                      EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                      );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }
  }

  Ip4AddRoute (
    IpSb->DefaultRouteTable,
    StationAddress,
    SubnetMask,
    IP4_ALLZERO_ADDRESS
    );

  //
  // Add a route for the connected network.
  //
  Subnet = StationAddress & SubnetMask;

  Ip4AddRoute (
    IpSb->DefaultRouteTable,
    Subnet,
    SubnetMask,
    IP4_ALLZERO_ADDRESS
    );

  IpSb->State = IP4_SERVICE_CONFIGED;
  IpSb->Reconfig = FALSE;
  
  return EFI_SUCCESS;
}

/**
  Set the station address, subnetmask and gateway address for the default interface.

  @param[in]  Instance         The pointer to the IP4 config2 instance data.  
  @param[in]  StationAddress   Ip address to be set.
  @param[in]  SubnetMask       Subnet to be set.
  @param[in]  GatewayAddress   Gateway to be set.

  @retval EFI_SUCCESS     Set default If successful.    
  @retval Others          Errors occur as indicated.  

**/
EFI_STATUS
Ip4Config2SetDefaultIf (
  IN IP4_CONFIG2_INSTANCE   *Instance,
  IN IP4_ADDR               StationAddress,
  IN IP4_ADDR               SubnetMask,
  IN IP4_ADDR               GatewayAddress
  )
{
  EFI_STATUS                Status;
  IP4_SERVICE               *IpSb;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create a route if there is a default router.
  //
  if (GatewayAddress != IP4_ALLZERO_ADDRESS) {
    Ip4AddRoute (
      IpSb->DefaultRouteTable,
      IP4_ALLZERO_ADDRESS,
      IP4_ALLZERO_ADDRESS,
      GatewayAddress
      );        
  }

  return EFI_SUCCESS;
}


/**
  Release all the DHCP related resources.

  @param  Instance              The IP4 config2 instance.

  @return None

**/
VOID
Ip4Config2CleanDhcp4 (
  IN IP4_CONFIG2_INSTANCE   *Instance
  )
{
  IP4_SERVICE               *IpSb;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  if (Instance->Dhcp4 != NULL) {
    Instance->Dhcp4->Stop (Instance->Dhcp4);

    gBS->CloseProtocol (
          Instance->Dhcp4Handle,
          &gEfiDhcp4ProtocolGuid,
          IpSb->Image,
          IpSb->Controller
          );

    Instance->Dhcp4 = NULL;
  }

  if (Instance->Dhcp4Handle != NULL) {
    NetLibDestroyServiceChild (
      IpSb->Controller,
      IpSb->Image,
      &gEfiDhcp4ServiceBindingProtocolGuid,
      Instance->Dhcp4Handle
      );

    Instance->Dhcp4Handle = NULL;
  }

  if (Instance->Dhcp4Event != NULL) {
    gBS->CloseEvent (Instance->Dhcp4Event);
    Instance->Dhcp4Event = NULL;
  }
}

/**
  This worker function sets the DNS server list for the EFI IPv4 network
  stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL
  manages. The DNS server addresses must be unicast IPv4 addresses. 

  @param[in]     Instance        The pointer to the IP4 config2 instance data.
  @param[in]     DataSize        The size of the buffer pointed to by Data in bytes.
  @param[in]     Data            The data buffer to set, points to an array of
                                 EFI_IPv4_ADDRESS instances.

  @retval EFI_BAD_BUFFER_SIZE    The DataSize does not match the size of the type.
  @retval EFI_INVALID_PARAMETER  One or more fields in Data is invalid.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to complete the operation.
  @retval EFI_ABORTED            The DNS server addresses to be set equal the current
                                 configuration.
  @retval EFI_SUCCESS            The specified configuration data for the EFI IPv4
                                 network stack was set.

**/
EFI_STATUS
Ip4Config2SetDnsServerWorker (
  IN IP4_CONFIG2_INSTANCE    *Instance,
  IN UINTN                   DataSize,
  IN VOID                    *Data
  )
{
  UINTN                 OldIndex;
  UINTN                 NewIndex;
  UINTN                 Index1;
  EFI_IPv4_ADDRESS      *OldDns;
  EFI_IPv4_ADDRESS      *NewDns;
  UINTN                 OldDnsCount;
  UINTN                 NewDnsCount;
  IP4_CONFIG2_DATA_ITEM *Item;
  BOOLEAN               OneAdded;
  VOID                  *Tmp;
  IP4_ADDR              DnsAddress;

  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  Item        = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
  NewDns      = (EFI_IPv4_ADDRESS *) Data;
  OldDns      = Item->Data.DnsServers;
  NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);  
  OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);
  OneAdded    = FALSE;

  if (NewDnsCount != OldDnsCount) {
    Tmp = AllocatePool (DataSize);
    if (Tmp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    Tmp = NULL;
  }

  for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
    CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));

    if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {
      //
      // The dns server address must be unicast.
      //
      FreePool (Tmp);
      return EFI_INVALID_PARAMETER;
    }

    for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {
      if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {
        FreePool (Tmp);
        return EFI_INVALID_PARAMETER;
      }
    }

    if (OneAdded) {
      //
      // If any address in the new setting is not in the old settings, skip the
      // comparision below.
      //
      continue;
    }

    for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
      if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
        //
        // If found break out.
        //
        break;
      }
    }

    if (OldIndex == OldDnsCount) {
      OneAdded = TRUE;
    }
  }

  if (!OneAdded && (DataSize == Item->DataSize)) {
    //
    // No new item is added and the size is the same.
    //
    Item->Status = EFI_SUCCESS;
    return EFI_ABORTED;
  } else {
    if (Tmp != NULL) {
      if (Item->Data.Ptr != NULL) {
        FreePool (Item->Data.Ptr);
      }      
      Item->Data.Ptr = Tmp;
    }

    CopyMem (Item->Data.Ptr, Data, DataSize);
    Item->DataSize = DataSize;
    Item->Status   = EFI_SUCCESS;
    return EFI_SUCCESS;
  }
}



/**
  Callback function when DHCP process finished. It will save the
  retrieved IP configure parameter from DHCP to the NVRam.

  @param  Event                  The callback event
  @param  Context                Opaque context to the callback

  @return None

**/
VOID
EFIAPI
Ip4Config2OnDhcp4Complete (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  IP4_CONFIG2_INSTANCE      *Instance;
  EFI_DHCP4_MODE_DATA       Dhcp4Mode;
  EFI_STATUS                Status;
  IP4_ADDR                  StationAddress;
  IP4_ADDR                  SubnetMask;
  IP4_ADDR                  GatewayAddress;
  UINT32                    Index;
  UINT32                    OptionCount;
  EFI_DHCP4_PACKET_OPTION   **OptionList;

  Instance = (IP4_CONFIG2_INSTANCE *) Context;
  ASSERT (Instance->Dhcp4 != NULL);

  //
  // Get the DHCP retrieved parameters
  //
  Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (Dhcp4Mode.State == Dhcp4Bound) {
    StationAddress = EFI_NTOHL (Dhcp4Mode.ClientAddress);
    SubnetMask = EFI_NTOHL (Dhcp4Mode.SubnetMask);
    GatewayAddress = EFI_NTOHL (Dhcp4Mode.RouterAddress);

    Status = Ip4Config2SetDefaultIf (Instance, StationAddress, SubnetMask, GatewayAddress);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  
    //
    // Parse the ACK to get required DNS server information.
    //
    OptionCount = 0;
    OptionList  = NULL;

    Status      = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);
    if (Status != EFI_BUFFER_TOO_SMALL) {
      goto Exit;
    }

    OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
    if (OptionList == NULL) {
      goto Exit;
    }

    Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);
    if (EFI_ERROR (Status)) {
      FreePool (OptionList);
      goto Exit;
    }

    for (Index = 0; Index < OptionCount; Index++) {
      //
      // Look for DNS Server opcode (6).
      //
      if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) {
        if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {
          break;
        }

        Ip4Config2SetDnsServerWorker (Instance, OptionList[Index]->Length, &OptionList[Index]->Data[0]);
        break;
      }
    }

    FreePool (OptionList);

    Instance->DhcpSuccess = TRUE;
  }

Exit:
  Ip4Config2CleanDhcp4 (Instance);
  DispatchDpc ();
}


/**
  Start the DHCP configuration for this IP service instance.
  It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
  DHCP configuration.

  @param[in]  Instance           The IP4 config2 instance to configure

  @retval EFI_SUCCESS            The auto configuration is successfull started
  @retval Others                 Failed to start auto configuration.

**/
EFI_STATUS
Ip4StartAutoConfig (
  IN IP4_CONFIG2_INSTANCE   *Instance
  )
{
  IP4_SERVICE                    *IpSb;
  EFI_DHCP4_PROTOCOL             *Dhcp4;
  EFI_DHCP4_MODE_DATA            Dhcp4Mode;
  EFI_DHCP4_PACKET_OPTION        *OptionList[1];
  IP4_CONFIG2_DHCP4_OPTION       ParaList;
  EFI_STATUS                     Status;
 

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  if (IpSb->State > IP4_SERVICE_UNSTARTED) {
    return EFI_SUCCESS;
  }

  //
  // A host must not invoke DHCP configuration if it is already
  // participating in the DHCP configuraiton process.
  //
  if (Instance->Dhcp4Handle != NULL) {
    return EFI_SUCCESS;
  }

  Status = NetLibCreateServiceChild (
             IpSb->Controller,
             IpSb->Image,
             &gEfiDhcp4ServiceBindingProtocolGuid,
             &Instance->Dhcp4Handle
             );

  if (Status == EFI_UNSUPPORTED) {
    //
    // No DHCPv4 Service Binding protocol, register a notify.
    //
    if (Instance->Dhcp4SbNotifyEvent == NULL) {
      Instance->Dhcp4SbNotifyEvent = EfiCreateProtocolNotifyEvent (
                                       &gEfiDhcp4ServiceBindingProtocolGuid,
                                       TPL_CALLBACK,
                                       Ip4Config2OnDhcp4SbInstalled,
                                       (VOID *) Instance,
                                       &Instance->Registration
                                       );
    }
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Instance->Dhcp4SbNotifyEvent != NULL) {
    gBS->CloseEvent (Instance->Dhcp4SbNotifyEvent);
  }

  Status = gBS->OpenProtocol (
                  Instance->Dhcp4Handle,
                  &gEfiDhcp4ProtocolGuid,
                  (VOID **) &Instance->Dhcp4,
                  IpSb->Image,
                  IpSb->Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  ASSERT_EFI_ERROR (Status);


  //
  // Check the current DHCP status, if the DHCP process has
  // already finished, return now.
  //
  Dhcp4  = Instance->Dhcp4;
  Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);

  if (Dhcp4Mode.State == Dhcp4Bound) {
    Ip4Config2OnDhcp4Complete (NULL, Instance);
    return EFI_SUCCESS;

  }

  //
  // Try to start the DHCP process. Use most of the current
  // DHCP configuration to avoid problems if some DHCP client
  // yields the control of this DHCP service to us.
  //
  ParaList.Head.OpCode             = DHCP4_TAG_PARA_LIST;
  ParaList.Head.Length             = 3;
  ParaList.Head.Data[0]            = DHCP4_TAG_NETMASK;
  ParaList.Route                   = DHCP4_TAG_ROUTER;
  ParaList.Dns                     = DHCP4_TAG_DNS_SERVER;
  OptionList[0]                    = &ParaList.Head;
  Dhcp4Mode.ConfigData.OptionCount = 1;
  Dhcp4Mode.ConfigData.OptionList  = OptionList;

  Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);

  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Start the DHCP process
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  Ip4Config2OnDhcp4Complete,
                  Instance,
                  &Instance->Dhcp4Event
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);

  if (EFI_ERROR (Status)) {
    return Status;
  }
 
  IpSb->State     = IP4_SERVICE_STARTED;
  DispatchDpc ();
  return EFI_SUCCESS;

}



/**
  The work function is to get the interface information of the communication 
  device this IP4_CONFIG2_INSTANCE manages.

  @param[in]      Instance Pointer to the IP4 config2 instance data.
  @param[in, out] DataSize On input, in bytes, the size of Data. On output, in
                           bytes, the size of buffer required to store the specified
                           configuration data.
  @param[in]      Data     The data buffer in which the configuration data is returned.
                           Ignored if DataSize is ZERO.

  @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified
                               configuration data, and the required size is
                               returned in DataSize.
  @retval EFI_SUCCESS          The specified configuration data was obtained.

**/
EFI_STATUS
Ip4Config2GetIfInfo (
  IN IP4_CONFIG2_INSTANCE *Instance,
  IN OUT UINTN            *DataSize,
  IN VOID                 *Data      OPTIONAL
  )
{
  IP4_SERVICE                    *IpSb;
  UINTN                          Length;
  IP4_CONFIG2_DATA_ITEM          *Item;
  EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;
  IP4_ADDR                       Address;

  IpSb   = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  Length = sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO);

  if (IpSb->DefaultRouteTable != NULL) {
    Length += IpSb->DefaultRouteTable->TotalNum * sizeof (EFI_IP4_ROUTE_TABLE);
  }
  
  if (*DataSize < Length) {
    *DataSize = Length;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Copy the fixed size part of the interface info.
  //
  Item = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];
  IfInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *) Data;
  CopyMem (IfInfo, Item->Data.Ptr, sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));

  //
  // Update the address info.
  //
  if (IpSb->DefaultInterface != NULL) {
    Address = HTONL (IpSb->DefaultInterface->Ip);
    CopyMem (&IfInfo->StationAddress, &Address, sizeof (EFI_IPv4_ADDRESS));
    Address = HTONL (IpSb->DefaultInterface->SubnetMask);
    CopyMem (&IfInfo->SubnetMask, &Address, sizeof (EFI_IPv4_ADDRESS));
  }

  if (IpSb->DefaultRouteTable != NULL) {
    IfInfo->RouteTableSize = IpSb->DefaultRouteTable->TotalNum;
    IfInfo->RouteTable   = (EFI_IP4_ROUTE_TABLE *) ((UINT8 *) Data + sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));

    Ip4Config2BuildDefaultRouteTable (IpSb, IfInfo->RouteTable);  
  }
  
  return EFI_SUCCESS;
}

/**
  The work function is to set the general configuration policy for the EFI IPv4 network 
  stack that is running on the communication device managed by this IP4_CONFIG2_INSTANCE.
  The policy will affect other configuration settings.

  @param[in]     Instance Pointer to the IP4 config2 instance data.
  @param[in]     DataSize Size of the buffer pointed to by Data in bytes.
  @param[in]     Data     The data buffer to set.

  @retval EFI_INVALID_PARAMETER The to be set policy is invalid.
  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type.
  @retval EFI_ABORTED           The new policy equals the current policy.
  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                network stack was set.

**/
EFI_STATUS
Ip4Config2SetPolicy (
  IN IP4_CONFIG2_INSTANCE *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP4_CONFIG2_POLICY NewPolicy;
  IP4_CONFIG2_DATA_ITEM  *DataItem;
  IP4_SERVICE            *IpSb;

  if (DataSize != sizeof (EFI_IP4_CONFIG2_POLICY)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  NewPolicy = *((EFI_IP4_CONFIG2_POLICY *) Data);

  if (NewPolicy >= Ip4Config2PolicyMax) {
    return EFI_INVALID_PARAMETER;
  }

  if (NewPolicy == Instance->Policy) {
    if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) {
      return EFI_ABORTED;
    }
  } else {
    //
    // The policy is changed. Clean the ManualAddress, Gateway and DnsServers, 
    // shrink the variable data size, and fire up all the related events.
    //
    DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);

    DataItem           = &Instance->DataItem[Ip4Config2DataTypeGateway];
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);

    DataItem           = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
    
    if (NewPolicy == Ip4Config2PolicyDhcp) {
      SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_VOLATILE);
    } else {
      //
      // The policy is changed from dhcp to static. Stop the DHCPv4 process
      // and destroy the DHCPv4 child.
      //
      if (Instance->Dhcp4Handle != NULL) {
        Ip4Config2DestroyDhcp4 (Instance);
      }
      
      //
      // Close the event.
      //
      if (Instance->Dhcp4Event != NULL) {
        gBS->CloseEvent (Instance->Dhcp4Event);
        Instance->Dhcp4Event = NULL;
      }
    }
  }

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  Ip4Config2OnPolicyChanged (IpSb, NewPolicy);

  Instance->Policy = NewPolicy;

  return EFI_SUCCESS;
}

/**
  The work function is to set the station addresses manually for the EFI IPv4 
  network stack. It is only configurable when the policy is Ip4Config2PolicyStatic.

  @param[in]     Instance Pointer to the IP4 config2 instance data.
  @param[in]     DataSize Size of the buffer pointed to by Data in bytes.
  @param[in]     Data     The data buffer to set.

  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type.
  @retval EFI_WRITE_PROTECTED   The specified configuration data cannot be set
                                under the current policy.
  @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
  @retval EFI_OUT_OF_RESOURCES  Fail to allocate resource to complete the operation.
  @retval EFI_NOT_READY         An asynchrous process is invoked to set the specified
                                configuration data, and the process is not finished.
  @retval EFI_ABORTED           The manual addresses to be set equal current
                                configuration.
  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                network stack was set.

**/
EFI_STATUS
Ip4Config2SetMaunualAddress (
  IN IP4_CONFIG2_INSTANCE *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP4_CONFIG2_MANUAL_ADDRESS NewAddress;
  IP4_CONFIG2_DATA_ITEM          *DataItem;
  EFI_STATUS                     Status;
  IP4_ADDR                       StationAddress;
  IP4_ADDR                       SubnetMask;
  VOID                           *Ptr;
  IP4_SERVICE                    *IpSb;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);

  if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip4Config2PolicyStatic) {
    return EFI_WRITE_PROTECTED;
  }

  NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);

  //
  // Store the new data, and init the DataItem status to EFI_NOT_READY because
  // we may have an asynchronous configuration process.
  //
  Ptr = AllocateCopyPool (DataSize, Data);
  if (Ptr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
  if (DataItem->Data.Ptr != NULL) {
    FreePool (DataItem->Data.Ptr);
  }
  
  DataItem->Data.Ptr = Ptr;
  DataItem->DataSize = DataSize;
  DataItem->Status   = EFI_NOT_READY;

  StationAddress = EFI_NTOHL (NewAddress.Address);
  SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);

  IpSb->Reconfig = TRUE;
  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }  

  DataItem->Status = EFI_SUCCESS;   

ON_EXIT:
  if (EFI_ERROR (DataItem->Status)) {
    if (Ptr != NULL) {
      FreePool (Ptr);
    }
    DataItem->Data.Ptr = NULL; 
  }

  return EFI_SUCCESS;
}

/**
  The work function is to set the gateway addresses manually for the EFI IPv4 
  network stack that is running on the communication device that this EFI IPv4 
  Configuration Protocol manages. It is not configurable when the policy is
  Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.

  @param[in]     Instance The pointer to the IP4 config2 instance data.
  @param[in]     DataSize The size of the buffer pointed to by Data in bytes.
  @param[in]     Data     The data buffer to set. This points to an array of
                          EFI_IPv6_ADDRESS instances.

  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type.
  @retval EFI_WRITE_PROTECTED   The specified configuration data cannot be set
                                under the current policy.
  @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource to complete the operation.
  @retval EFI_ABORTED           The manual gateway addresses to be set equal the
                                current configuration.
  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                network stack was set.

**/
EFI_STATUS
Ip4Config2SetGateway (
  IN IP4_CONFIG2_INSTANCE *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  IP4_SERVICE                    *IpSb;
  IP4_CONFIG2_DATA_ITEM          *DataItem;
  IP4_ADDR                       Gateway;

  UINTN                 Index1;
  UINTN                 Index2;
  EFI_IPv4_ADDRESS      *OldGateway;
  EFI_IPv4_ADDRESS      *NewGateway;
  UINTN                 OldGatewayCount;
  UINTN                 NewGatewayCount;
  BOOLEAN               OneRemoved;
  BOOLEAN               OneAdded;
  VOID                  *Tmp;

  if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip4Config2PolicyStatic) {
    return EFI_WRITE_PROTECTED;
  }


  NewGateway      = (EFI_IPv4_ADDRESS *) Data;
  NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
    
    if (!NetIp4IsUnicast (NTOHL (Gateway), 0)) {

      return EFI_INVALID_PARAMETER;
    }

    for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
      if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
        return EFI_INVALID_PARAMETER;
      }
    }
  }
 
  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
  OldGateway      = DataItem->Data.Gateway;
  OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);
  OneRemoved      = FALSE;
  OneAdded        = FALSE;

  if (NewGatewayCount != OldGatewayCount) {
    Tmp = AllocatePool (DataSize);
    if (Tmp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    Tmp = NULL;
  }

  for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
    //
    // Remove this route entry.
    //
    CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));
    Ip4DelRoute (
      IpSb->DefaultRouteTable,
      IP4_ALLZERO_ADDRESS,
      IP4_ALLZERO_ADDRESS,
      NTOHL (Gateway)
      );
    OneRemoved = TRUE;

  }

  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
    CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
    Ip4AddRoute (
      IpSb->DefaultRouteTable,
      IP4_ALLZERO_ADDRESS,
      IP4_ALLZERO_ADDRESS,
      NTOHL (Gateway)
      );    

    OneAdded = TRUE;
  }


  if (!OneRemoved && !OneAdded) {
    DataItem->Status = EFI_SUCCESS;
    return EFI_ABORTED;
  } else {

    if (Tmp != NULL) {
      if (DataItem->Data.Ptr != NULL) {
        FreePool (DataItem->Data.Ptr);
      }
      DataItem->Data.Ptr = Tmp;
    }

    CopyMem (DataItem->Data.Ptr, Data, DataSize);
    DataItem->DataSize = DataSize;
    DataItem->Status   = EFI_SUCCESS;
    return EFI_SUCCESS;
  }

}

/**
  The work function is to set the DNS server list for the EFI IPv4 network 
  stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL 
  manages. It is not configurable when the policy is Ip4Config2PolicyDhcp. 
  The DNS server addresses must be unicast IPv4 addresses.

  @param[in]     Instance The pointer to the IP4 config2 instance data.
  @param[in]     DataSize The size of the buffer pointed to by Data in bytes.
  @param[in]     Data     The data buffer to set, points to an array of
                          EFI_IPv4_ADDRESS instances.

  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type.
  @retval EFI_WRITE_PROTECTED   The specified configuration data cannot be set
                                under the current policy.
  @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources to complete the operation.
  @retval EFI_ABORTED           The DNS server addresses to be set equal the current
                                configuration.
  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv4
                                network stack was set.

**/
EFI_STATUS
Ip4Config2SetDnsServer (
  IN IP4_CONFIG2_INSTANCE *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  IP4_CONFIG2_DATA_ITEM *Item;

  Item = NULL;

  if (Instance->Policy != Ip4Config2PolicyStatic) {
    return EFI_WRITE_PROTECTED;
  }

  Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];

  if (DATA_ATTRIB_SET (Item->Attribute, DATA_ATTRIB_VOLATILE)) {
    REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);
  }

  return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);
}

/**
  Generate the operational state of the interface this IP4 config2 instance manages
  and output in EFI_IP4_CONFIG2_INTERFACE_INFO.

  @param[in]      IpSb     The pointer to the IP4 service binding instance.
  @param[out]     IfInfo   The pointer to the IP4 config2 interface information structure.

**/
VOID
Ip4Config2InitIfInfo (
  IN  IP4_SERVICE                    *IpSb,
  OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo
  )
{
  IfInfo->Name[0] = L'e';
  IfInfo->Name[1] = L't';
  IfInfo->Name[2] = L'h';
  IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip4Config2Instance.IfIndex);
  IfInfo->Name[4] = 0;

  IfInfo->IfType        = IpSb->SnpMode.IfType;
  IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;
  CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress, IfInfo->HwAddressSize);
}

/**
  The event handle routine when DHCPv4 process is finished or is updated.

  @param[in]     Event         Not used.
  @param[in]     Context       The pointer to the IP4 configuration instance data.

**/
VOID
EFIAPI
Ip4Config2OnDhcp4Event (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  return ;
}


/**
  Set the configuration for the EFI IPv4 network stack running on the communication
  device this EFI_IP4_CONFIG2_PROTOCOL instance manages.

  This function is used to set the configuration data of type DataType for the EFI
  IPv4 network stack that is running on the communication device that this EFI IPv4
  Configuration Protocol instance manages.

  DataSize is used to calculate the count of structure instances in the Data for
  a DataType in which multiple structure instances are allowed.

  This function is always non-blocking. When setting some type of configuration data,
  an asynchronous process is invoked to check the correctness of the data, such as
  performing Duplicate Address Detection on the manually set local IPv4 addresses.
  EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
  is invoked, and the process is not finished yet. The caller wanting to get the result
  of the asynchronous process is required to call RegisterDataNotify() to register an
  event on the specified configuration data. Once the event is signaled, the caller
  can call GetData() to obtain the configuration data and know the result.
  For other types of configuration data that do not require an asynchronous configuration
  process, the result of the operation is immediately returned.

  @param[in]     This           The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
  @param[in]     DataType       The type of data to set.
  @param[in]     DataSize       Size of the buffer pointed to by Data in bytes.
  @param[in]     Data           The data buffer to set. The type of the data buffer is
                                associated with the DataType.

  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
                                network stack was set successfully.
  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                - This is NULL.
                                - Data is NULL.
                                - One or more fields in Data do not match the requirement of the
                                  data type indicated by DataType.
  @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified
                                configuration data cannot be set under the current policy.
  @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration
                                data is already in process.
  @retval EFI_NOT_READY         An asynchronous process was invoked to set the specified
                                configuration data, and the process is not finished yet.
  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type
                                indicated by DataType.
  @retval EFI_UNSUPPORTED       This DataType is not supported.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected system error or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiIp4Config2SetData (
  IN EFI_IP4_CONFIG2_PROTOCOL   *This,
  IN EFI_IP4_CONFIG2_DATA_TYPE  DataType,
  IN UINTN                      DataSize,
  IN VOID                       *Data
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP4_CONFIG2_INSTANCE *Instance;
  IP4_SERVICE          *IpSb;

  if ((This == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip4Config2DataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
  IpSb     = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);


  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Status = Instance->DataItem[DataType].Status;
  if (Status != EFI_NOT_READY) {

    if (Instance->DataItem[DataType].SetData == NULL) {
      //
      // This type of data is readonly.
      //
      Status = EFI_WRITE_PROTECTED;
    } else {

      Status = Instance->DataItem[DataType].SetData (Instance, DataSize, Data);
      if (!EFI_ERROR (Status)) {
        //
        // Fire up the events registered with this type of data.
        //
        NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip4Config2SignalEvent, NULL);
        Ip4Config2WriteConfigData (IpSb->MacString, Instance);
      } else if (Status == EFI_ABORTED) {
        //
        // The SetData is aborted because the data to set is the same with
        // the one maintained.
        //
        Status = EFI_SUCCESS;
        NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip4Config2SignalEvent, NULL);
      }
    }
  } else {
    //
    // Another asynchornous process is on the way.
    //
    Status = EFI_ACCESS_DENIED;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Get the configuration data for the EFI IPv4 network stack running on the communication
  device that this EFI_IP4_CONFIG2_PROTOCOL instance manages.

  This function returns the configuration data of type DataType for the EFI IPv4 network
  stack running on the communication device that this EFI IPv4 Configuration Protocol instance
  manages.

  The caller is responsible for allocating the buffer used to return the specified
  configuration data. The required size will be returned to the caller if the size of
  the buffer is too small.

  EFI_NOT_READY is returned if the specified configuration data is not ready due to an
  asynchronous configuration process already in progress. The caller can call RegisterDataNotify()
  to register an event on the specified configuration data. Once the asynchronous configuration
  process is finished, the event will be signaled, and a subsequent GetData() call will return
  the specified configuration data.

  @param[in]      This           Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
  @param[in]      DataType       The type of data to get.
  @param[in, out] DataSize       On input, in bytes, the size of Data. On output, in bytes, the
                                 size of buffer required to store the specified configuration data.
  @param[in]     Data            The data buffer in which the configuration data is returned. The
                                 type of the data buffer is associated with the DataType.
                                 This is an optional parameter that may be NULL.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - This is NULL.
                                - DataSize is NULL.
                                - Data is NULL if *DataSize is not zero.
  @retval EFI_BUFFER_TOO_SMALL  The size of Data is too small for the specified configuration data,
                                and the required size is returned in DataSize.
  @retval EFI_NOT_READY         The specified configuration data is not ready due to an
                                asynchronous configuration process already in progress.
  @retval EFI_NOT_FOUND         The specified configuration data is not found.

**/
EFI_STATUS
EFIAPI
EfiIp4Config2GetData (
  IN EFI_IP4_CONFIG2_PROTOCOL   *This,
  IN EFI_IP4_CONFIG2_DATA_TYPE  DataType,
  IN OUT UINTN                  *DataSize,
  IN VOID                       *Data   OPTIONAL
  )
{
  EFI_TPL               OldTpl;
  EFI_STATUS            Status;
  IP4_CONFIG2_INSTANCE  *Instance;
  IP4_CONFIG2_DATA_ITEM *DataItem;

  if ((This == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip4Config2DataTypeMaximum) {
    return EFI_NOT_FOUND;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
  DataItem = &Instance->DataItem[DataType];

  Status   = Instance->DataItem[DataType].Status;
  if (!EFI_ERROR (Status)) {

    if (DataItem->GetData != NULL) {

      Status = DataItem->GetData (Instance, DataSize, Data);
    } else if (*DataSize < Instance->DataItem[DataType].DataSize) {
      //
      // Update the buffer length.
      //
      *DataSize = Instance->DataItem[DataType].DataSize;
      Status    = EFI_BUFFER_TOO_SMALL;
    } else {

      *DataSize = Instance->DataItem[DataType].DataSize;
      CopyMem (Data, Instance->DataItem[DataType].Data.Ptr, *DataSize);
    }
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Register an event that is signaled whenever a configuration process on the specified
  configuration data is done.

  This function registers an event that is to be signaled whenever a configuration
  process on the specified configuration data is performed. An event can be registered
  for a different DataType simultaneously. The caller is responsible for determining
  which type of configuration data causes the signaling of the event in such an event.

  @param[in]     This           Pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
  @param[in]     DataType       The type of data to unregister the event for.
  @param[in]     Event          The event to register.

  @retval EFI_SUCCESS           The notification event for the specified configuration data is
                                registered.
  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
  @retval EFI_UNSUPPORTED       The configuration data type specified by DataType is not
                                supported.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_ACCESS_DENIED     The Event is already registered for the DataType.

**/
EFI_STATUS
EFIAPI
EfiIp4Config2RegisterDataNotify (
  IN EFI_IP4_CONFIG2_PROTOCOL   *This,
  IN EFI_IP4_CONFIG2_DATA_TYPE  DataType,
  IN EFI_EVENT                  Event
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP4_CONFIG2_INSTANCE *Instance;
  NET_MAP              *EventMap;
  NET_MAP_ITEM         *Item;

  if ((This == NULL) || (Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip4Config2DataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  OldTpl    = gBS->RaiseTPL (TPL_CALLBACK);

  Instance  = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
  EventMap  = &Instance->DataItem[DataType].EventMap;

  //
  // Check whether this event is already registered for this DataType.
  //
  Item = NetMapFindKey (EventMap, Event);
  if (Item == NULL) {

    Status = NetMapInsertTail (EventMap, Event, NULL);

    if (EFI_ERROR (Status)) {

      Status = EFI_OUT_OF_RESOURCES;
    }

  } else {

    Status = EFI_ACCESS_DENIED;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Remove a previously registered event for the specified configuration data.

  @param  This                   The pointer to the EFI_IP4_CONFIG2_PROTOCOL instance.
  @param  DataType               The type of data to remove from the previously
                                 registered event.
  @param  Event                  The event to be unregistered.

  @retval EFI_SUCCESS            The event registered for the specified
                                 configuration data was removed.
  @retval EFI_INVALID_PARAMETER  This is NULL or Event is NULL.
  @retval EFI_NOT_FOUND          The Event has not been registered for the
                                 specified DataType.

**/
EFI_STATUS
EFIAPI
EfiIp4Config2UnregisterDataNotify (
  IN EFI_IP4_CONFIG2_PROTOCOL   *This,
  IN EFI_IP4_CONFIG2_DATA_TYPE  DataType,
  IN EFI_EVENT                  Event
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP4_CONFIG2_INSTANCE *Instance;
  NET_MAP_ITEM         *Item;

  if ((This == NULL) || (Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip4Config2DataTypeMaximum) {
    return EFI_NOT_FOUND;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);

  Item = NetMapFindKey (&Instance->DataItem[DataType].EventMap, Event);
  if (Item != NULL) {

    NetMapRemoveItem (&Instance->DataItem[DataType].EventMap, Item, NULL);
    Status = EFI_SUCCESS;
  } else {

    Status = EFI_NOT_FOUND;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Initialize an IP4_CONFIG2_INSTANCE.

  @param[out]    Instance       The buffer of IP4_CONFIG2_INSTANCE to be initialized.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources to complete the operation.
  @retval EFI_SUCCESS           The IP4_CONFIG2_INSTANCE initialized successfully.

**/
EFI_STATUS
Ip4Config2InitInstance (
  OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  IP4_SERVICE           *IpSb;
  IP4_CONFIG2_INSTANCE  *TmpInstance;
  LIST_ENTRY            *Entry;
  EFI_STATUS            Status;
  UINTN                 Index;
  UINT16                IfIndex;
  IP4_CONFIG2_DATA_ITEM *DataItem;


  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  Instance->Signature = IP4_CONFIG2_INSTANCE_SIGNATURE;


  //
  // Determine the index of this interface.
  //
  IfIndex = 0;
  NET_LIST_FOR_EACH (Entry, &mIp4Config2InstanceList) {
    TmpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_CONFIG2_INSTANCE, Link, IP4_CONFIG2_INSTANCE_SIGNATURE);

    if (TmpInstance->IfIndex > IfIndex) {
      //
      // There is a sequence hole because some interface is down.
      //
      break;
    }

    IfIndex++;
  }

  Instance->IfIndex = IfIndex;
  NetListInsertBefore (Entry, &Instance->Link);

  for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
    //
    // Initialize the event map for each data item.
    //
    NetMapInit (&Instance->DataItem[Index].EventMap);
  }

  
  //
  // Initialize each data type: associate storage and set data size for the
  // fixed size data types, hook the SetData function, set the data attribute.
  //
  DataItem           = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];
  DataItem->GetData  = Ip4Config2GetIfInfo;
  DataItem->Data.Ptr = &Instance->InterfaceInfo;
  DataItem->DataSize = sizeof (Instance->InterfaceInfo);
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED | DATA_ATTRIB_VOLATILE);
  Ip4Config2InitIfInfo (IpSb, &Instance->InterfaceInfo);

  DataItem           = &Instance->DataItem[Ip4Config2DataTypePolicy];
  DataItem->SetData  = Ip4Config2SetPolicy;
  DataItem->Data.Ptr = &Instance->Policy;
  DataItem->DataSize = sizeof (Instance->Policy);
  Instance->Policy   = Ip4Config2PolicyStatic;
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);

  DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
  DataItem->SetData  = Ip4Config2SetMaunualAddress;
  DataItem->Status   = EFI_NOT_FOUND;

  DataItem           = &Instance->DataItem[Ip4Config2DataTypeGateway];
  DataItem->SetData  = Ip4Config2SetGateway;
  DataItem->Status   = EFI_NOT_FOUND;

  DataItem           = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
  DataItem->SetData  = Ip4Config2SetDnsServer;
  DataItem->Status   = EFI_NOT_FOUND;

  //
  // Create the event used for DHCP.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  Ip4Config2OnDhcp4Event,
                  Instance,
                  &Instance->Dhcp4Event
                  );
  ASSERT_EFI_ERROR (Status);

  Instance->Configured  = TRUE;

  //
  // Try to read the config data from NV variable.
  // If not found, write initialized config data into NV variable 
  // as a default config data.
  //
  Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);
  if (Status == EFI_NOT_FOUND) {
    Status = Ip4Config2WriteConfigData (IpSb->MacString, Instance);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  Instance->Ip4Config2.SetData              = EfiIp4Config2SetData;
  Instance->Ip4Config2.GetData              = EfiIp4Config2GetData;
  Instance->Ip4Config2.RegisterDataNotify   = EfiIp4Config2RegisterDataNotify;
  Instance->Ip4Config2.UnregisterDataNotify = EfiIp4Config2UnregisterDataNotify;

  //
  // Publish the IP4 configuration form
  //
  return Ip4Config2FormInit (Instance);
}


/**
  Release an IP4_CONFIG2_INSTANCE.

  @param[in, out] Instance    The buffer of IP4_CONFIG2_INSTANCE to be freed.

**/
VOID
Ip4Config2CleanInstance (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  UINTN                 Index;
  IP4_CONFIG2_DATA_ITEM *DataItem;

  if (Instance->DeclineAddress != NULL) {
    FreePool (Instance->DeclineAddress);
  }

  if (!Instance->Configured) {
    return ;
  }

  if (Instance->Dhcp4Handle != NULL) {

    Ip4Config2DestroyDhcp4 (Instance);
  }

  //
  // Close the event.
  //
  if (Instance->Dhcp4Event != NULL) {
    gBS->CloseEvent (Instance->Dhcp4Event);
    Instance->Dhcp4Event = NULL;
  }

  for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {

    DataItem = &Instance->DataItem[Index];

    if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {
      if (DataItem->Data.Ptr != NULL) {
        FreePool (DataItem->Data.Ptr);
      }
      DataItem->Data.Ptr = NULL;
      DataItem->DataSize = 0;
    }

    NetMapClean (&Instance->DataItem[Index].EventMap);
  }

  Ip4Config2FormUnload (Instance);

  RemoveEntryList (&Instance->Link);
}

/**
  The event handle for IP4 auto reconfiguration. The original default
  interface and route table will be removed as the default.

  @param[in]  Context                The IP4 service binding instance.

**/
VOID
EFIAPI
Ip4AutoReconfigCallBackDpc (
  IN VOID                   *Context
  )
{
  IP4_SERVICE               *IpSb;

  IpSb      = (IP4_SERVICE *) Context;
  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);

  if (IpSb->State > IP4_SERVICE_UNSTARTED) {
    IpSb->State = IP4_SERVICE_UNSTARTED;
  }
  
  IpSb->Reconfig = TRUE;

  Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);

  return ;
}


/**
  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.

  @param Event     The event that is signalled.
  @param Context   The IP4 service binding instance.

**/
VOID
EFIAPI
Ip4AutoReconfigCallBack (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  //
  // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);
}

