/** @file
  The implementation of EFI IPv6 Configuration Protocol.

  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<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 "Ip6Impl.h"

LIST_ENTRY  mIp6ConfigInstanceList = {&mIp6ConfigInstanceList, &mIp6ConfigInstanceList};

/**
  The event process routine when the DHCPv6 service binding protocol is installed
  in the system.

  @param[in]     Event         Not used.
  @param[in]     Context       Pointer to the IP6 config instance data.

**/
VOID
EFIAPI
Ip6ConfigOnDhcp6SbInstalled (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Update the current policy to NewPolicy. During the transition
  period, the default router list, on-link prefix list, autonomous prefix list
  and address list in all interfaces will be released.

  @param[in]  IpSb               The IP6 service binding instance.
  @param[in]  NewPolicy          The new policy to be updated to.

**/
VOID
Ip6ConfigOnPolicyChanged (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_CONFIG_POLICY  NewPolicy
  )
{
  LIST_ENTRY      *Entry;
  LIST_ENTRY      *Entry2;
  LIST_ENTRY      *Next;
  IP6_INTERFACE   *IpIf;
  IP6_DAD_ENTRY   *DadEntry;
  IP6_DELAY_JOIN_LIST       *DelayNode;
  
  //
  // Currently there are only two policies: Manual and Automatic. Regardless of
  // what transition is going on, i.e., Manual -> Automatic and Automatic ->
  // Manual, we have to free default router list, on-link prefix list, autonomous
  // prefix list, address list in all the interfaces and destroy any IPv6 child
  // instance whose local IP is neither 0 nor the link-local address.
  //
  Ip6CleanDefaultRouterList (IpSb);
  Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix);
  Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix);

  //
  // It's tricky... If the LinkLocal address is O.K., add back the link-local
  // prefix to the on-link prefix table.
  //
  if (IpSb->LinkLocalOk) {
    Ip6CreatePrefixListEntry (
      IpSb,
      TRUE,
      (UINT32) IP6_INFINIT_LIFETIME,
      (UINT32) IP6_INFINIT_LIFETIME,
      IP6_LINK_LOCAL_PREFIX_LENGTH,
      &IpSb->LinkLocalAddr
      );
  }

  //
  // All IPv6 children that use global unicast address as it's source address
  // should be destryoed now. The survivers are those use the link-local address
  // or the unspecified address as the source address.
  // TODO: Conduct a check here.
  Ip6RemoveAddr (
    IpSb,
    &IpSb->DefaultInterface->AddressList,
    &IpSb->DefaultInterface->AddressCount,
    NULL,
    0
    );

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    //
    // remove all pending delay node and DAD entries for the global addresses.
    //
    IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);

    NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) {
      DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link);
      if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) {
        RemoveEntryList (&DelayNode->Link);
        FreePool (DelayNode);
      }
    }

    NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) {
      DadEntry = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE);

      if (!NetIp6IsLinkLocalAddr (&DadEntry->AddressInfo->Address)) {
        //
        // Fail this DAD entry if the address is not link-local.
        //
        Ip6OnDADFinished (FALSE, IpIf, DadEntry);
      }
    }
  }

  if (NewPolicy == Ip6ConfigPolicyAutomatic) {
    //
    // Set parameters to trigger router solicitation sending in timer handler.
    //
    IpSb->RouterAdvertiseReceived = FALSE;
    IpSb->SolicitTimer            = IP6_MAX_RTR_SOLICITATIONS;
    //
    // delay 1 second
    //
    IpSb->Ticks                   = (UINT32) IP6_GET_TICKS (IP6_ONE_SECOND_IN_MS);
  }

}

/**
  The work function to trigger the DHCPv6 process to perform a stateful autoconfiguration.

  @param[in]     Instance      Pointer to the IP6 config instance data.
  @param[in]     OtherInfoOnly If FALSE, get stateful address and other information
                               via DHCPv6. Otherwise, only get the other information.

  @retval    EFI_SUCCESS       The operation finished successfully.
  @retval    EFI_UNSUPPORTED   The DHCP6 driver is not available.

**/
EFI_STATUS
Ip6ConfigStartStatefulAutoConfig (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN BOOLEAN              OtherInfoOnly
  )
{
  EFI_STATUS                Status;
  IP6_SERVICE               *IpSb;
  EFI_DHCP6_CONFIG_DATA     Dhcp6CfgData;
  EFI_DHCP6_PROTOCOL        *Dhcp6;
  EFI_DHCP6_PACKET_OPTION   *OptList[1];
  UINT16                    OptBuf[4];
  EFI_DHCP6_PACKET_OPTION   *Oro;
  EFI_DHCP6_RETRANSMISSION  InfoReqReXmit;

  //
  // A host must not invoke stateful address configuration if it is already
  // participating in the statuful protocol as a result of an earlier advertisement.
  //
  if (Instance->Dhcp6Handle != NULL) {
    return EFI_SUCCESS;
  }

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);

  Instance->OtherInfoOnly = OtherInfoOnly;

  Status = NetLibCreateServiceChild (
             IpSb->Controller,
             IpSb->Image,
             &gEfiDhcp6ServiceBindingProtocolGuid,
             &Instance->Dhcp6Handle
             );

  if (Status == EFI_UNSUPPORTED) {
    //
    // No DHCPv6 Service Binding protocol, register a notify.
    //
    if (Instance->Dhcp6SbNotifyEvent == NULL) {
      Instance->Dhcp6SbNotifyEvent = EfiCreateProtocolNotifyEvent (
                                       &gEfiDhcp6ServiceBindingProtocolGuid,
                                       TPL_CALLBACK,
                                       Ip6ConfigOnDhcp6SbInstalled,
                                       (VOID *) Instance,
                                       &Instance->Registration
                                       );
    }
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Instance->Dhcp6SbNotifyEvent != NULL) {
    gBS->CloseEvent (Instance->Dhcp6SbNotifyEvent);
  }

  Status = gBS->OpenProtocol (
                  Instance->Dhcp6Handle,
                  &gEfiDhcp6ProtocolGuid,
                  (VOID **) &Instance->Dhcp6,
                  IpSb->Image,
                  IpSb->Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  ASSERT_EFI_ERROR (Status);

  Dhcp6 = Instance->Dhcp6;
  Dhcp6->Configure (Dhcp6, NULL);

  //
  // Set the exta options to send. Here we only want the option request option
  // with DNS SERVERS.
  //
  Oro                         = (EFI_DHCP6_PACKET_OPTION *) OptBuf;
  Oro->OpCode                 = HTONS (DHCP6_OPT_ORO);
  Oro->OpLen                  = HTONS (2);
  *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS);
  OptList[0]                  = Oro;

  Status                      = EFI_SUCCESS;

  if (!OtherInfoOnly) {
    //
    // Get stateful address and other information via DHCPv6.
    //
    Dhcp6CfgData.Dhcp6Callback         = NULL;
    Dhcp6CfgData.CallbackContext       = NULL;
    Dhcp6CfgData.OptionCount           = 1;
    Dhcp6CfgData.OptionList            = &OptList[0];
    Dhcp6CfgData.IaDescriptor.Type     = EFI_DHCP6_IA_TYPE_NA;
    Dhcp6CfgData.IaDescriptor.IaId     = Instance->IaId;
    Dhcp6CfgData.IaInfoEvent           = Instance->Dhcp6Event;
    Dhcp6CfgData.ReconfigureAccept     = FALSE;
    Dhcp6CfgData.RapidCommit           = FALSE;
    Dhcp6CfgData.SolicitRetransmission = NULL;

    Status = Dhcp6->Configure (Dhcp6, &Dhcp6CfgData);

    if (!EFI_ERROR (Status)) {

      if (IpSb->LinkLocalOk) {
        Status = Dhcp6->Start (Dhcp6);
      } else {
        IpSb->Dhcp6NeedStart = TRUE;
      }

    }
  } else {
    //
    // Only get other information via DHCPv6, this doesn't require a config
    // action.
    //
    InfoReqReXmit.Irt = 4;
    InfoReqReXmit.Mrc = 64;
    InfoReqReXmit.Mrt = 60;
    InfoReqReXmit.Mrd = 0;

    if (IpSb->LinkLocalOk) {
      Status = Dhcp6->InfoRequest (
                        Dhcp6,
                        TRUE,
                        Oro,
                        0,
                        NULL,
                        &InfoReqReXmit,
                        Instance->Dhcp6Event,
                        Ip6ConfigOnDhcp6Reply,
                        Instance
                        );
    } else {
      IpSb->Dhcp6NeedInfoRequest = TRUE;
    }

  }

  return Status;
}

/**
  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.

**/
EFI_STATUS
EFIAPI
Ip6ConfigSignalEvent (
  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
  gEfiIp6ConfigProtocolGuid. 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 IP6_CONFIG_INSTANCE.

  @param[in]      VarName  The pointer to the variable name
  @param[in, out] Instance The pointer to the IP6 config 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
Ip6ConfigReadConfigData (
  IN     CHAR16               *VarName,
  IN OUT IP6_CONFIG_INSTANCE  *Instance
  )
{
  EFI_STATUS              Status;
  UINTN                   VarSize;
  IP6_CONFIG_VARIABLE     *Variable;
  IP6_CONFIG_DATA_ITEM    *DataItem;
  UINTN                   Index;
  IP6_CONFIG_DATA_RECORD  DataRecord;
  CHAR8                   *Data;

  //
  // Try to read the configuration variable.
  //
  VarSize = 0;
  Status  = gRT->GetVariable (
                   VarName,
                   &gEfiIp6ConfigProtocolGuid,
                   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,
                    &gEfiIp6ConfigProtocolGuid,
                    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,
             &gEfiIp6ConfigProtocolGuid,
             IP6_CONFIG_VARIABLE_ATTRIBUTE,
             0,
             NULL
             );

      return EFI_NOT_FOUND;
    }

    //
    // Get the IAID we use.
    //
    Instance->IaId = Variable->IaId;

    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 IP6_CONFIG_INSTANCE to variable storage.

  @param[in]      VarName  The pointer to the variable name.
  @param[in]      Instance The pointer to the IP6 configuration 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
Ip6ConfigWriteConfigData (
  IN CHAR16               *VarName,
  IN IP6_CONFIG_INSTANCE  *Instance
  )
{
  UINTN                   Index;
  UINTN                   VarSize;
  IP6_CONFIG_DATA_ITEM    *DataItem;
  IP6_CONFIG_VARIABLE     *Variable;
  IP6_CONFIG_DATA_RECORD  *DataRecord;
  CHAR8                   *Heap;
  EFI_STATUS              Status;

  VarSize = sizeof (IP6_CONFIG_VARIABLE) - sizeof (IP6_CONFIG_DATA_RECORD);

  for (Index = 0; Index < Ip6ConfigDataTypeMaximum; Index++) {

    DataItem = &Instance->DataItem[Index];
    if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) {

      VarSize += sizeof (IP6_CONFIG_DATA_RECORD) + DataItem->DataSize;
    }
  }

  Variable = AllocatePool (VarSize);
  if (Variable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Variable->IaId            = Instance->IaId;
  Heap                      = (CHAR8 *) Variable + VarSize;
  Variable->DataRecordCount = 0;

  for (Index = 0; Index < Ip6ConfigDataTypeMaximum; 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_IP6_CONFIG_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,
                  &gEfiIp6ConfigProtocolGuid,
                  IP6_CONFIG_VARIABLE_ATTRIBUTE,
                  VarSize,
                  Variable
                  );

  FreePool (Variable);

  return Status;
}

/**
  The work function for EfiIp6ConfigGetData() to get the interface information
  of the communication device this IP6Config instance manages.

  @param[in]      Instance Pointer to the IP6 config 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
Ip6ConfigGetIfInfo (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN OUT UINTN            *DataSize,
  IN VOID                 *Data      OPTIONAL
  )
{
  IP6_SERVICE                    *IpSb;
  UINTN                          Length;
  IP6_CONFIG_DATA_ITEM           *Item;
  EFI_IP6_CONFIG_INTERFACE_INFO  *IfInfo;
  UINT32                         AddressCount;
  UINT32                         RouteCount;

  IpSb   = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  Length = sizeof (EFI_IP6_CONFIG_INTERFACE_INFO);

  //
  // Calculate the required length, add the buffer size for AddressInfo and
  // RouteTable
  //
  Ip6BuildEfiAddressList (IpSb, &AddressCount, NULL);
  Ip6BuildEfiRouteTable (IpSb->RouteTable, &RouteCount, NULL);

  Length += AddressCount * sizeof (EFI_IP6_ADDRESS_INFO) + RouteCount * sizeof (EFI_IP6_ROUTE_TABLE);

  if (*DataSize < Length) {
    *DataSize = Length;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Copy the fixed size part of the interface info.
  //
  Item = &Instance->DataItem[Ip6ConfigDataTypeInterfaceInfo];
  IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;
  CopyMem (IfInfo, Item->Data.Ptr, sizeof (EFI_IP6_CONFIG_INTERFACE_INFO));

  //
  // AddressInfo
  //
  IfInfo->AddressInfo = (EFI_IP6_ADDRESS_INFO *) (IfInfo + 1);
  Ip6BuildEfiAddressList (IpSb, &IfInfo->AddressInfoCount, &IfInfo->AddressInfo);

  //
  // RouteTable
  //
  IfInfo->RouteTable = (EFI_IP6_ROUTE_TABLE *) (IfInfo->AddressInfo + IfInfo->AddressInfoCount);
  Ip6BuildEfiRouteTable (IpSb->RouteTable, &IfInfo->RouteCount, &IfInfo->RouteTable);

  if (IfInfo->AddressInfoCount == 0) {
    IfInfo->AddressInfo = NULL;
  }

  if (IfInfo->RouteCount == 0) {
    IfInfo->RouteTable = NULL;
  }

  return EFI_SUCCESS;
}

/**
  The work function for EfiIp6ConfigSetData() to set the alternative inteface ID
  for the communication device managed by this IP6Config instance, if the link local
  IPv6 addresses generated from the interface ID based on the default source the
  EFI IPv6 Protocol uses is a duplicate address.

  @param[in]     Instance Pointer to the IP6 configuration 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,
                               8 bytes.
  @retval EFI_SUCCESS          The specified configuration data for the EFI IPv6
                               network stack was set.

**/
EFI_STATUS
Ip6ConfigSetAltIfId (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP6_CONFIG_INTERFACE_ID  *OldIfId;
  EFI_IP6_CONFIG_INTERFACE_ID  *NewIfId;
  IP6_CONFIG_DATA_ITEM         *DataItem;

  if (DataSize != sizeof (EFI_IP6_CONFIG_INTERFACE_ID)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  DataItem = &Instance->DataItem[Ip6ConfigDataTypeAltInterfaceId];
  OldIfId  = DataItem->Data.AltIfId;
  NewIfId  = (EFI_IP6_CONFIG_INTERFACE_ID *) Data;

  CopyMem (OldIfId, NewIfId, DataSize);
  DataItem->Status = EFI_SUCCESS;

  return EFI_SUCCESS;
}

/**
  The work function for EfiIp6ConfigSetData() to set the general configuration
  policy for the EFI IPv6 network stack that is running on the communication device
  managed by this IP6Config instance. The policy will affect other configuration settings.

  @param[in]     Instance Pointer to the IP6 config 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
Ip6ConfigSetPolicy (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP6_CONFIG_POLICY  NewPolicy;
  IP6_CONFIG_DATA_ITEM   *DataItem;
  IP6_SERVICE            *IpSb;

  if (DataSize != sizeof (EFI_IP6_CONFIG_POLICY)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  NewPolicy = *((EFI_IP6_CONFIG_POLICY *) Data);

  if (NewPolicy > Ip6ConfigPolicyAutomatic) {
    return EFI_INVALID_PARAMETER;
  }

  if (NewPolicy == Instance->Policy) {

    return EFI_ABORTED;
  } else {
    //
    // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
    // data size, and fire up all the related events.
    //
    DataItem           = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL);

    DataItem           = &Instance->DataItem[Ip6ConfigDataTypeGateway];
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL);

    DataItem           = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;
    NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL);
    
    if (NewPolicy == Ip6ConfigPolicyManual) {
      //
      // The policy is changed from automatic to manual. Stop the DHCPv6 process
      // and destroy the DHCPv6 child.
      //
      if (Instance->Dhcp6Handle != NULL) {
        Ip6ConfigDestroyDhcp6 (Instance);
      }
    }

    IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
    Ip6ConfigOnPolicyChanged (IpSb, NewPolicy);

    Instance->Policy = NewPolicy;

    return EFI_SUCCESS;
  }
}

/**
  The work function for EfiIp6ConfigSetData() to set the number of consecutive
  Neighbor Solicitation messages sent while performing Duplicate Address Detection
  on a tentative address. A value of ZERO indicates that Duplicate Address Detection
  will not be performed on a tentative address.

  @param[in]     Instance The Instance Pointer to the IP6 config 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_ABORTED          The new transmit count equals the current configuration.
  @retval EFI_SUCCESS          The specified configuration data for the EFI IPv6
                               network stack was set.

**/
EFI_STATUS
Ip6ConfigSetDadXmits (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS  *OldDadXmits;

  if (DataSize != sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  OldDadXmits = Instance->DataItem[Ip6ConfigDataTypeDupAddrDetectTransmits].Data.DadXmits;

  if ((*(UINT32 *) Data) == OldDadXmits->DupAddrDetectTransmits) {

    return EFI_ABORTED;
  } else {

    OldDadXmits->DupAddrDetectTransmits = *((UINT32 *) Data);
    return EFI_SUCCESS;
  }
}

/**
  The callback function for Ip6SetAddr. The prototype is defined
  as IP6_DAD_CALLBACK. It is called after Duplicate Address Detection is performed
  for the manual address set by Ip6ConfigSetMaunualAddress.

  @param[in]     IsDadPassed   If TRUE, Duplicate Address Detection passed.
  @param[in]     TargetAddress The tentative IPv6 address to be checked.
  @param[in]     Context       Pointer to the IP6 configuration instance data.

**/
VOID
Ip6ManualAddrDadCallback (
  IN BOOLEAN           IsDadPassed,
  IN EFI_IPv6_ADDRESS  *TargetAddress,
  IN VOID              *Context
  )
{
  IP6_CONFIG_INSTANCE            *Instance;
  UINTN                          Index;
  IP6_CONFIG_DATA_ITEM           *Item;
  EFI_IP6_CONFIG_MANUAL_ADDRESS  *ManualAddr;
  EFI_IP6_CONFIG_MANUAL_ADDRESS  *PassedAddr;
  UINTN                          DadPassCount;
  UINTN                          DadFailCount;
  IP6_SERVICE                    *IpSb;

  Instance   = (IP6_CONFIG_INSTANCE *) Context;
  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
  Item       = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
  ManualAddr = NULL;

  if (Item->DataSize == 0) {
    return;
  }

  for (Index = 0; Index < Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); Index++) {
    //
    // Find the original tag used to place into the NET_MAP.
    //
    ManualAddr = Item->Data.ManualAddress + Index;
    if (EFI_IP6_EQUAL (TargetAddress, &ManualAddr->Address)) {
      break;
    }
  }

  ASSERT (Index != Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));

  if (IsDadPassed) {
    NetMapInsertTail (&Instance->DadPassedMap, ManualAddr, NULL);
  } else {
    NetMapInsertTail (&Instance->DadFailedMap, ManualAddr, NULL);
  }

  DadPassCount = NetMapGetCount (&Instance->DadPassedMap);
  DadFailCount = NetMapGetCount (&Instance->DadFailedMap);

  if ((DadPassCount + DadFailCount) == (Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS))) {
    //
    // All addresses have finished the configuration process.
    //
    if (DadFailCount != 0) {
      //
      // There is at least one duplicate address.
      //
      FreePool (Item->Data.Ptr);

      Item->DataSize = DadPassCount * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
      if (Item->DataSize == 0) {
        //
        // All failed, bad luck.
        //
        Item->Data.Ptr = NULL;
        Item->Status   = EFI_NOT_FOUND;
      } else {
        //
        // Part of addresses are detected to be duplicates, so update the
        // data with those passed.
        //
        PassedAddr = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AllocatePool (Item->DataSize);
        ASSERT (PassedAddr != NULL);

        Item->Data.Ptr = PassedAddr;
        Item->Status   = EFI_SUCCESS;

        while (!NetMapIsEmpty (&Instance->DadPassedMap)) {
          ManualAddr = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) NetMapRemoveHead (&Instance->DadPassedMap, NULL);
          CopyMem (PassedAddr, ManualAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));

          PassedAddr++;
        }

        ASSERT ((UINTN) PassedAddr - (UINTN) Item->Data.Ptr == Item->DataSize);
      }
    } else {
      //
      // All addresses are valid.
      //
      Item->Status = EFI_SUCCESS;
    }

    //
    // Remove the tags we put in the NET_MAPs.
    //
    while (!NetMapIsEmpty (&Instance->DadFailedMap)) {
      NetMapRemoveHead (&Instance->DadFailedMap, NULL);
    }

    while (!NetMapIsEmpty (&Instance->DadPassedMap)) {
      NetMapRemoveHead (&Instance->DadPassedMap, NULL);
    }

    //
    // Signal the waiting events.
    //
    NetMapIterate (&Item->EventMap, Ip6ConfigSignalEvent, NULL);
    IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
    Ip6ConfigWriteConfigData (IpSb->MacString, Instance);
  }
}

/**
  The work function for EfiIp6ConfigSetData() to set the station addresses manually
  for the EFI IPv6 network stack. It is only configurable when the policy is
  Ip6ConfigPolicyManual.

  @param[in]     Instance Pointer to the IP6 configuration 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
Ip6ConfigSetMaunualAddress (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  EFI_IP6_CONFIG_MANUAL_ADDRESS  *NewAddress;
  EFI_IP6_CONFIG_MANUAL_ADDRESS  *TmpAddress;
  IP6_CONFIG_DATA_ITEM           *DataItem;
  UINTN                          NewAddressCount;
  UINTN                          Index1;
  UINTN                          Index2;
  IP6_SERVICE                    *IpSb;
  IP6_ADDRESS_INFO               *CurrentAddrInfo;
  IP6_ADDRESS_INFO               *Copy;
  LIST_ENTRY                     CurrentSourceList;
  UINT32                         CurrentSourceCount;
  LIST_ENTRY                     *Entry;
  LIST_ENTRY                     *Entry2;
  IP6_INTERFACE                  *IpIf;
  IP6_PREFIX_LIST_ENTRY          *PrefixEntry;
  EFI_STATUS                     Status;
  BOOLEAN                        IsUpdated;

  ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status != EFI_NOT_READY);

  if (((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
  NewAddress      = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data;

  for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {

    if (NetIp6IsLinkLocalAddr (&NewAddress->Address)    ||
        !NetIp6IsValidUnicast (&NewAddress->Address)    ||
        (NewAddress->PrefixLength > 128)
        ) {
      //
      // make sure the IPv6 address is unicast and not link-local address &&
      // the prefix length is valid.
      //
      return EFI_INVALID_PARAMETER;
    }

    TmpAddress = NewAddress + 1;
    for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) {
      //
      // Any two addresses in the array can't be equal.
      //
      if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) {

        return EFI_INVALID_PARAMETER;
      }
    }
  }

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);

  //
  // Build the current source address list.
  //
  InitializeListHead (&CurrentSourceList);
  CurrentSourceCount = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);

    NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
      CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

      Copy            = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo);
      if (Copy == NULL) {
        break;
      }

      InsertTailList (&CurrentSourceList, &Copy->Link);
      CurrentSourceCount++;
    }
  }

  //
  // Update the value... a long journey starts
  //
  NewAddress = AllocateCopyPool (DataSize, Data);
  if (NewAddress == NULL) {
    Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0);

    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Store the new data, and init the DataItem status to EFI_NOT_READY because
  // we may have an asynchronous configuration process.
  //
  DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
  if (DataItem->Data.Ptr != NULL) {
    FreePool (DataItem->Data.Ptr);
  }
  DataItem->Data.Ptr = NewAddress;
  DataItem->DataSize = DataSize;
  DataItem->Status   = EFI_NOT_READY;

  //
  // Trigger DAD, it's an asynchronous process.
  //
  IsUpdated  = FALSE;

  for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
    if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) {
      ASSERT (CurrentAddrInfo != NULL);
      //
      // Remove this already existing source address from the CurrentSourceList
      // built before.
      //
      Ip6RemoveAddr (
        NULL,
        &CurrentSourceList,
        &CurrentSourceCount,
        &CurrentAddrInfo->Address,
        128
        );

      //
      // If the new address's prefix length is not specified, just use the previous configured
      // prefix length for this address.
      //
      if (NewAddress->PrefixLength == 0) {
        NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength;
      }

      //
      // This manual address is already in use, see whether prefix length is changed.
      //
      if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) {
        //
        // Remove the on-link prefix table, the route entry will be removed
        // implicitly.
        //
        PrefixEntry = Ip6FindPrefixListEntry (
                        IpSb,
                        TRUE,
                        CurrentAddrInfo->PrefixLength,
                        &CurrentAddrInfo->Address
                        );
        if (PrefixEntry != NULL) {
          Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
        }

        //
        // Save the prefix length.
        //
        CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength;
        IsUpdated = TRUE;
      }

      //
      // create a new on-link prefix entry.
      //
      PrefixEntry = Ip6FindPrefixListEntry (
                      IpSb,
                      TRUE,
                      NewAddress->PrefixLength,
                      &NewAddress->Address
                      );
      if (PrefixEntry == NULL) {
        Ip6CreatePrefixListEntry (
          IpSb,
          TRUE,
          (UINT32) IP6_INFINIT_LIFETIME,
          (UINT32) IP6_INFINIT_LIFETIME,
          NewAddress->PrefixLength,
          &NewAddress->Address
          );
      }

      CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast;
      //
      // Artificially mark this address passed DAD be'coz it is already in use.
      //
      Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance);
    } else {
      //
      // A new address.
      //
      IsUpdated = TRUE;

      //
      // Set the new address, this will trigger DAD and activate the address if
      // DAD succeeds.
      //
      Ip6SetAddress (
        IpSb->DefaultInterface,
        &NewAddress->Address,
        NewAddress->IsAnycast,
        NewAddress->PrefixLength,
        (UINT32) IP6_INFINIT_LIFETIME,
        (UINT32) IP6_INFINIT_LIFETIME,
        Ip6ManualAddrDadCallback,
        Instance
        );
    }
  }

  //
  // Check the CurrentSourceList, it now contains those addresses currently in
  // use and will be removed.
  //
  IpIf = IpSb->DefaultInterface;

  while (!IsListEmpty (&CurrentSourceList)) {
    IsUpdated = TRUE;

    CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link);

    //
    // This local address is going to be removed, the IP instances that are
    // currently using it will be destroyed.
    //
    Ip6RemoveAddr (
      IpSb,
      &IpIf->AddressList,
      &IpIf->AddressCount,
      &CurrentAddrInfo->Address,
      128
      );

    //
    // Remove the on-link prefix table, the route entry will be removed
    // implicitly.
    //
    PrefixEntry = Ip6FindPrefixListEntry (
                    IpSb,
                    TRUE,
                    CurrentAddrInfo->PrefixLength,
                    &CurrentAddrInfo->Address
                    );
    if (PrefixEntry != NULL) {
      Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
    }

    RemoveEntryList (&CurrentAddrInfo->Link);
    FreePool (CurrentAddrInfo);
  }

  if (IsUpdated) {
    if (DataItem->Status == EFI_NOT_READY) {
      //
      // If DAD is disabled on this interface, the configuration process is
      // actually synchronous, and the data item's status will be changed to
      // the final status before we reach here, just check it.
      //
      Status = EFI_NOT_READY;
    } else {
      Status = EFI_SUCCESS;
    }
  } else {
    //
    // No update is taken, reset the status to success and return EFI_ABORTED.
    //
    DataItem->Status = EFI_SUCCESS;
    Status           = EFI_ABORTED;
  }

  return Status;
}

/**
  The work function for EfiIp6ConfigSetData() to set the gateway addresses manually
  for the EFI IPv6 network stack that is running on the communication device that
  this EFI IPv6 Configuration Protocol manages. It is not configurable when the policy is
  Ip6ConfigPolicyAutomatic. The gateway addresses must be unicast IPv6 addresses.

  @param[in]     Instance The pointer to the IP6 config 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
Ip6ConfigSetGateway (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  UINTN                 Index1;
  UINTN                 Index2;
  EFI_IPv6_ADDRESS      *OldGateway;
  EFI_IPv6_ADDRESS      *NewGateway;
  UINTN                 OldGatewayCount;
  UINTN                 NewGatewayCount;
  IP6_CONFIG_DATA_ITEM  *Item;
  BOOLEAN               OneRemoved;
  BOOLEAN               OneAdded;
  IP6_SERVICE           *IpSb;
  IP6_DEFAULT_ROUTER    *DefaultRouter;
  VOID                  *Tmp;

  if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  NewGateway      = (EFI_IPv6_ADDRESS *) Data;
  NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {

    if (!NetIp6IsValidUnicast (NewGateway + Index1)) {

      return EFI_INVALID_PARAMETER;
    }

    for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
      if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  IpSb            = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  Item            = &Instance->DataItem[Ip6ConfigDataTypeGateway];
  OldGateway      = Item->Data.Gateway;
  OldGatewayCount = Item->DataSize / sizeof (EFI_IPv6_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++) {
    //
    // Find the gateways that are no long in the new setting and remove them.
    //
    for (Index2 = 0; Index2 < NewGatewayCount; Index2++) {
      if (EFI_IP6_EQUAL (OldGateway + Index1, NewGateway + Index2)) {
        OneRemoved = TRUE;
        break;
      }
    }

    if (Index2 == NewGatewayCount) {
      //
      // Remove this default router.
      //
      DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
      if (DefaultRouter != NULL) {
        Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
      }
    }
  }

  for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {

    DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1);
    if (DefaultRouter == NULL) {
      Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME);
      OneAdded = TRUE;
    }
  }

  if (!OneRemoved && !OneAdded) {
    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;
  }
}

/**
  The work function for EfiIp6ConfigSetData() to set the DNS server list for the
  EFI IPv6 network stack running on the communication device that this EFI IPv6
  Configuration Protocol manages. It is not configurable when the policy is
  Ip6ConfigPolicyAutomatic. The DNS server addresses must be unicast IPv6 addresses.

  @param[in]     Instance The pointer to the IP6 config 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_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 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 IPv6
                                network stack was set.

**/
EFI_STATUS
Ip6ConfigSetDnsServer (
  IN IP6_CONFIG_INSTANCE  *Instance,
  IN UINTN                DataSize,
  IN VOID                 *Data
  )
{
  UINTN                 OldIndex;
  UINTN                 NewIndex;
  EFI_IPv6_ADDRESS      *OldDns;
  EFI_IPv6_ADDRESS      *NewDns;
  UINTN                 OldDnsCount;
  UINTN                 NewDnsCount;
  IP6_CONFIG_DATA_ITEM  *Item;
  BOOLEAN               OneAdded;
  VOID                  *Tmp;

  if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  Item        = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
  NewDns      = (EFI_IPv6_ADDRESS *) Data;
  OldDns      = Item->Data.DnsServers;
  NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
  OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_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++) {

    if (!NetIp6IsValidUnicast (NewDns + NewIndex)) {
      //
      // The dns server address must be unicast.
      //
      if (Tmp != NULL) {
        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_IP6_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;
  }
}

/**
  Generate the operational state of the interface this IP6 config instance manages
  and output in EFI_IP6_CONFIG_INTERFACE_INFO.

  @param[in]      IpSb     The pointer to the IP6 service binding instance.
  @param[out]     IfInfo   The pointer to the IP6 configuration interface information structure.

**/
VOID
Ip6ConfigInitIfInfo (
  IN  IP6_SERVICE                    *IpSb,
  OUT EFI_IP6_CONFIG_INTERFACE_INFO  *IfInfo
  )
{
  UnicodeSPrint (
    IfInfo->Name,
    sizeof (IfInfo->Name),
    L"eth%d",
    IpSb->Ip6ConfigInstance.IfIndex
  );

  IfInfo->IfType        = IpSb->SnpMode.IfType;
  IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;
  CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress, IfInfo->HwAddressSize);
}

/**
  Parse DHCPv6 reply packet to get the DNS server list.
  It is the work function for Ip6ConfigOnDhcp6Reply and Ip6ConfigOnDhcp6Event.

  @param[in]      Dhcp6    The pointer to the EFI_DHCP6_PROTOCOL instance.
  @param[in, out] Instance The pointer to the IP6 configuration instance data.
  @param[in]      Reply    The pointer to the DHCPv6 reply packet.

  @retval EFI_SUCCESS      The DNS server address was retrieved from the reply packet.
  @retval EFI_NOT_READY    The reply packet does not contain the DNS server option, or
                           the DNS server address is not valid.

**/
EFI_STATUS
Ip6ConfigParseDhcpReply (
  IN     EFI_DHCP6_PROTOCOL  *Dhcp6,
  IN OUT IP6_CONFIG_INSTANCE *Instance,
  IN     EFI_DHCP6_PACKET    *Reply
  )
{
  EFI_STATUS               Status;
  UINT32                   OptCount;
  EFI_DHCP6_PACKET_OPTION  **OptList;
  UINT16                   OpCode;
  UINT16                   Length;
  UINTN                    Index;
  UINTN                    Index2;
  EFI_IPv6_ADDRESS         *DnsServer;
  IP6_CONFIG_DATA_ITEM     *Item;

  //
  // A DHCPv6 reply packet is received as the response to our InfoRequest
  // packet.
  //
  OptCount = 0;
  Status   = Dhcp6->Parse (Dhcp6, Reply, &OptCount, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return EFI_NOT_READY;
  }

  OptList = AllocatePool (OptCount * sizeof (EFI_DHCP6_PACKET_OPTION *));
  if (OptList == NULL) {
    return EFI_NOT_READY;
  }

  Status = Dhcp6->Parse (Dhcp6, Reply, &OptCount, OptList);
  if (EFI_ERROR (Status)) {
    Status = EFI_NOT_READY;
    goto ON_EXIT;
  }

  Status = EFI_SUCCESS;

  for (Index = 0; Index < OptCount; Index++) {
    //
    // Go through all the options to check the ones we are interested in.
    // The OpCode and Length are in network byte-order and may not be naturally
    // aligned.
    //
    CopyMem (&OpCode, &OptList[Index]->OpCode, sizeof (OpCode));
    OpCode = NTOHS (OpCode);

    if (OpCode == DHCP6_OPT_DNS_SERVERS) {
      CopyMem (&Length, &OptList[Index]->OpLen, sizeof (Length));
      Length = NTOHS (Length);

      if ((Length == 0) || ((Length % sizeof (EFI_IPv6_ADDRESS)) != 0)) {
        //
        // The length should be a multiple of 16 bytes.
        //
        Status = EFI_NOT_READY;
        break;
      }

      //
      // Validate the DnsServers: whether they are unicast addresses.
      //
      DnsServer = (EFI_IPv6_ADDRESS *) OptList[Index]->Data;
      for (Index2 = 0; Index2 < Length / sizeof (EFI_IPv6_ADDRESS); Index2++) {
        if (!NetIp6IsValidUnicast (DnsServer)) {
          Status = EFI_NOT_READY;
          goto ON_EXIT;
        }

        DnsServer++;
      }

      Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];

      if (Item->DataSize != Length) {
        if (Item->Data.Ptr != NULL) {
          FreePool (Item->Data.Ptr);
        }

        Item->Data.Ptr = AllocatePool (Length);
        ASSERT (Item->Data.Ptr != NULL);
      }

      CopyMem (Item->Data.Ptr, OptList[Index]->Data, Length);
      Item->DataSize = Length;
      Item->Status   = EFI_SUCCESS;

      //
      // Signal the waiting events.
      //
      NetMapIterate (&Item->EventMap, Ip6ConfigSignalEvent, NULL);

      break;
    }
  }

ON_EXIT:

  FreePool (OptList);
  return Status;
}

/**
  The callback function for Ip6SetAddr. The prototype is defined
  as IP6_DAD_CALLBACK. It is called after Duplicate Address Detection is performed
  on the tentative address by DHCPv6 in Ip6ConfigOnDhcp6Event().

  @param[in]     IsDadPassed   If TRUE, Duplicate Address Detection passes.
  @param[in]     TargetAddress The tentative IPv6 address to be checked.
  @param[in]     Context       Pointer to the IP6 configuration instance data.

**/
VOID
Ip6ConfigSetStatefulAddrCallback (
  IN BOOLEAN           IsDadPassed,
  IN EFI_IPv6_ADDRESS  *TargetAddress,
  IN VOID              *Context
  )
{
  IP6_CONFIG_INSTANCE  *Instance;

  Instance = (IP6_CONFIG_INSTANCE *) Context;
  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);

  //
  // We should record the addresses that fail the DAD, and DECLINE them.
  //
  if (IsDadPassed) {
    //
    // Decrease the count, no interests in those passed DAD.
    //
    if (Instance->FailedIaAddressCount > 0 ) {
      Instance->FailedIaAddressCount--;
    }
  } else {
    //
    // Record it.
    //
    IP6_COPY_ADDRESS (Instance->DeclineAddress + Instance->DeclineAddressCount, TargetAddress);
    Instance->DeclineAddressCount++;
  }

  if (Instance->FailedIaAddressCount == Instance->DeclineAddressCount) {
    //
    // The checking on all addresses are finished.
    //
    if (Instance->DeclineAddressCount != 0) {
      //
      // Decline those duplicates.
      //
      if (Instance->Dhcp6 != NULL) {
        Instance->Dhcp6->Decline (
                           Instance->Dhcp6,
                           Instance->DeclineAddressCount,
                           Instance->DeclineAddress
                           );
      }
    }

    if (Instance->DeclineAddress != NULL) {
      FreePool (Instance->DeclineAddress);
    }
    Instance->DeclineAddress      = NULL;
    Instance->DeclineAddressCount = 0;
  }
}

/**
  The event handle routine when DHCPv6 process is finished or is updated.

  @param[in]     Event         Not used.
  @param[in]     Context       The pointer to the IP6 configuration instance data.

**/
VOID
EFIAPI
Ip6ConfigOnDhcp6Event (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  IP6_CONFIG_INSTANCE      *Instance;
  EFI_DHCP6_PROTOCOL       *Dhcp6;
  EFI_STATUS               Status;
  EFI_DHCP6_MODE_DATA      Dhcp6ModeData;
  EFI_DHCP6_IA             *Ia;
  EFI_DHCP6_IA_ADDRESS     *IaAddr;
  UINT32                   Index;
  IP6_SERVICE              *IpSb;
  IP6_ADDRESS_INFO         *AddrInfo;
  IP6_INTERFACE            *IpIf;

  Instance = (IP6_CONFIG_INSTANCE *) Context;

  if ((Instance->Policy != Ip6ConfigPolicyAutomatic) || Instance->OtherInfoOnly) {
    //
    // IPv6 is not operating in the automatic policy now or
    // the DHCPv6 information request message exchange is aborted.
    //
    return ;
  }

  //
  // The stateful address autoconfiguration is done or updated.
  //
  Dhcp6 = Instance->Dhcp6;

  Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
  if (EFI_ERROR (Status)) {
    return ;
  }

  IpSb   = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  IpIf   = IpSb->DefaultInterface;
  Ia     = Dhcp6ModeData.Ia;
  IaAddr = Ia->IaAddress;

  if (Instance->DeclineAddress != NULL) {
    FreePool (Instance->DeclineAddress);
  }

  Instance->DeclineAddress = (EFI_IPv6_ADDRESS *) AllocatePool (Ia->IaAddressCount * sizeof (EFI_IPv6_ADDRESS));
  if (Instance->DeclineAddress == NULL) {
    goto ON_EXIT;
  }

  Instance->FailedIaAddressCount = Ia->IaAddressCount;
  Instance->DeclineAddressCount   = 0;

  for (Index = 0; Index < Ia->IaAddressCount; Index++, IaAddr++) {
    if (Ia->IaAddress[Index].ValidLifetime != 0 && Ia->State == Dhcp6Bound) {
      //
      // Set this address, either it's a new address or with updated lifetimes.
      // An appropriate prefix length will be set.
      //
      Ip6SetAddress (
        IpIf,
        &IaAddr->IpAddress,
        FALSE,
        0,
        IaAddr->ValidLifetime,
        IaAddr->PreferredLifetime,
        Ip6ConfigSetStatefulAddrCallback,
        Instance
        );
    } else {
      //
      // discard this address, artificially decrease the count as if this address
      // passed DAD.
      //
      if (Ip6IsOneOfSetAddress (IpSb, &IaAddr->IpAddress, NULL, &AddrInfo)) {
        ASSERT (AddrInfo != NULL);
        Ip6RemoveAddr (
          IpSb,
          &IpIf->AddressList,
          &IpIf->AddressCount,
          &AddrInfo->Address,
          AddrInfo->PrefixLength
          );
      }

      if (Instance->FailedIaAddressCount > 0) {
        Instance->FailedIaAddressCount--;
      }
    }
  }

  //
  // Parse the Reply packet to get the options we need.
  //
  if (Dhcp6ModeData.Ia->ReplyPacket != NULL) {
    Ip6ConfigParseDhcpReply (Dhcp6, Instance, Dhcp6ModeData.Ia->ReplyPacket);
  }

ON_EXIT:

  FreePool (Dhcp6ModeData.ClientId);
  FreePool (Dhcp6ModeData.Ia);
}

/**
  The event process routine when the DHCPv6 server is answered with a reply packet
  for an information request.

  @param[in]     This          Points to the EFI_DHCP6_PROTOCOL.
  @param[in]     Context       The pointer to the IP6 configuration instance data.
  @param[in]     Packet        The DHCPv6 reply packet.

  @retval EFI_SUCCESS      The DNS server address was retrieved from the reply packet.
  @retval EFI_NOT_READY    The reply packet does not contain the DNS server option, or
                           the DNS server address is not valid.

**/
EFI_STATUS
EFIAPI
Ip6ConfigOnDhcp6Reply (
  IN EFI_DHCP6_PROTOCOL  *This,
  IN VOID                *Context,
  IN EFI_DHCP6_PACKET    *Packet
  )
{
  return Ip6ConfigParseDhcpReply (This, (IP6_CONFIG_INSTANCE *) Context, Packet);
}

/**
  The event process routine when the DHCPv6 service binding protocol is installed
  in the system.

  @param[in]     Event         Not used.
  @param[in]     Context       The pointer to the IP6 config instance data.

**/
VOID
EFIAPI
Ip6ConfigOnDhcp6SbInstalled (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  IP6_CONFIG_INSTANCE  *Instance;

  Instance = (IP6_CONFIG_INSTANCE *) Context;

  if ((Instance->Dhcp6Handle != NULL) || (Instance->Policy != Ip6ConfigPolicyAutomatic)) {
    //
    // The DHCP6 child is already created or the policy is no longer AUTOMATIC.
    //
    return ;
  }

  Ip6ConfigStartStatefulAutoConfig (Instance, Instance->OtherInfoOnly);
}

/**
  Set the configuration for the EFI IPv6 network stack running on the communication
  device this EFI IPv6 Configuration Protocol instance manages.

  This function is used to set the configuration data of type DataType for the EFI
  IPv6 network stack that is running on the communication device that this EFI IPv6
  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 IPv6 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_IP6_CONFIG_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
EfiIp6ConfigSetData (
  IN EFI_IP6_CONFIG_PROTOCOL    *This,
  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
  IN UINTN                      DataSize,
  IN VOID                       *Data
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP6_CONFIG_INSTANCE  *Instance;
  IP6_SERVICE          *IpSb;

  if ((This == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip6ConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  Instance = IP6_CONFIG_INSTANCE_FROM_PROTOCOL (This);
  IpSb     = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  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, Ip6ConfigSignalEvent, NULL);
        Ip6ConfigWriteConfigData (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, Ip6ConfigSignalEvent, 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 IPv6 network stack running on the communication
  device that this EFI IPv6 Configuration Protocol instance manages.

  This function returns the configuration data of type DataType for the EFI IPv6 network
  stack running on the communication device that this EFI IPv6 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_IP6_CONFIG_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
EfiIp6ConfigGetData (
  IN EFI_IP6_CONFIG_PROTOCOL    *This,
  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
  IN OUT UINTN                  *DataSize,
  IN VOID                       *Data   OPTIONAL
  )
{
  EFI_TPL               OldTpl;
  EFI_STATUS            Status;
  IP6_CONFIG_INSTANCE   *Instance;
  IP6_CONFIG_DATA_ITEM  *DataItem;

  if ((This == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip6ConfigDataTypeMaximum) {
    return EFI_NOT_FOUND;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = IP6_CONFIG_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_IP6_CONFIG_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
EfiIp6ConfigRegisterDataNotify (
  IN EFI_IP6_CONFIG_PROTOCOL    *This,
  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
  IN EFI_EVENT                  Event
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP6_CONFIG_INSTANCE  *Instance;
  NET_MAP              *EventMap;
  NET_MAP_ITEM         *Item;

  if ((This == NULL) || (Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip6ConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  OldTpl    = gBS->RaiseTPL (TPL_CALLBACK);

  Instance  = IP6_CONFIG_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_IP6_CONFIG_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
EfiIp6ConfigUnregisterDataNotify (
  IN EFI_IP6_CONFIG_PROTOCOL    *This,
  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
  IN EFI_EVENT                  Event
  )
{
  EFI_TPL              OldTpl;
  EFI_STATUS           Status;
  IP6_CONFIG_INSTANCE  *Instance;
  NET_MAP_ITEM         *Item;

  if ((This == NULL) || (Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= Ip6ConfigDataTypeMaximum) {
    return EFI_NOT_FOUND;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = IP6_CONFIG_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 IP6_CONFIG_INSTANCE.

  @param[out]    Instance       The buffer of IP6_CONFIG_INSTANCE to be initialized.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources to complete the operation.
  @retval EFI_SUCCESS           The IP6_CONFIG_INSTANCE initialized successfully.

**/
EFI_STATUS
Ip6ConfigInitInstance (
  OUT IP6_CONFIG_INSTANCE  *Instance
  )
{
  IP6_SERVICE           *IpSb;
  IP6_CONFIG_INSTANCE   *TmpInstance;
  LIST_ENTRY            *Entry;
  EFI_STATUS            Status;
  UINTN                 Index;
  UINT16                IfIndex;
  IP6_CONFIG_DATA_ITEM  *DataItem;

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);

  Instance->Signature = IP6_CONFIG_INSTANCE_SIGNATURE;

  //
  // Determine the index of this interface.
  //
  IfIndex = 0;
  NET_LIST_FOR_EACH (Entry, &mIp6ConfigInstanceList) {
    TmpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_CONFIG_INSTANCE, Link, IP6_CONFIG_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 < Ip6ConfigDataTypeMaximum; Index++) {
    //
    // Initialize the event map for each data item.
    //
    NetMapInit (&Instance->DataItem[Index].EventMap);
  }

  //
  // Initialize the NET_MAPs used for DAD on manually configured source addresses.
  //
  NetMapInit (&Instance->DadFailedMap);
  NetMapInit (&Instance->DadPassedMap);

  //
  // 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[Ip6ConfigDataTypeInterfaceInfo];
  DataItem->GetData  = Ip6ConfigGetIfInfo;
  DataItem->Data.Ptr = &Instance->InterfaceInfo;
  DataItem->DataSize = sizeof (Instance->InterfaceInfo);
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED | DATA_ATTRIB_VOLATILE);
  Ip6ConfigInitIfInfo (IpSb, &Instance->InterfaceInfo);

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypeAltInterfaceId];
  DataItem->SetData  = Ip6ConfigSetAltIfId;
  DataItem->Data.Ptr = &Instance->AltIfId;
  DataItem->DataSize = sizeof (Instance->AltIfId);
  DataItem->Status   = EFI_NOT_FOUND;
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypePolicy];
  DataItem->SetData  = Ip6ConfigSetPolicy;
  DataItem->Data.Ptr = &Instance->Policy;
  DataItem->DataSize = sizeof (Instance->Policy);
  Instance->Policy   = Ip6ConfigPolicyManual;
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypeDupAddrDetectTransmits];
  DataItem->SetData  = Ip6ConfigSetDadXmits;
  DataItem->Data.Ptr = &Instance->DadXmits;
  DataItem->DataSize = sizeof (Instance->DadXmits);
  Instance->DadXmits.DupAddrDetectTransmits = IP6_CONFIG_DEFAULT_DAD_XMITS;
  SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
  DataItem->SetData  = Ip6ConfigSetMaunualAddress;
  DataItem->Status   = EFI_NOT_FOUND;

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypeGateway];
  DataItem->SetData  = Ip6ConfigSetGateway;
  DataItem->Status   = EFI_NOT_FOUND;

  DataItem           = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
  DataItem->SetData  = Ip6ConfigSetDnsServer;
  DataItem->Status   = EFI_NOT_FOUND;

  //
  // Create the event used for DHCP.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  Ip6ConfigOnDhcp6Event,
                  Instance,
                  &Instance->Dhcp6Event
                  );
  ASSERT_EFI_ERROR (Status);

  Instance->Configured  = TRUE;

  //
  // Try to read the config data from NV variable.
  //
  Status = Ip6ConfigReadConfigData (IpSb->MacString, Instance);
  if (Status == EFI_NOT_FOUND) {
    //
    // The NV variable is not set, so generate a random IAID, and write down the
    // fresh new configuration as the NV variable now.
    //
    Instance->IaId = NET_RANDOM (NetRandomInitSeed ());

    for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) {
      Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31));
    }

    Ip6ConfigWriteConfigData (IpSb->MacString, Instance);
  } else if (EFI_ERROR (Status)) {
    return Status;
  }

  Instance->Ip6Config.SetData              = EfiIp6ConfigSetData;
  Instance->Ip6Config.GetData              = EfiIp6ConfigGetData;
  Instance->Ip6Config.RegisterDataNotify   = EfiIp6ConfigRegisterDataNotify;
  Instance->Ip6Config.UnregisterDataNotify = EfiIp6ConfigUnregisterDataNotify;


  //
  // Publish the IP6 configuration form
  //
  return Ip6ConfigFormInit (Instance);
}

/**
  Release an IP6_CONFIG_INSTANCE.

  @param[in, out] Instance    The buffer of IP6_CONFIG_INSTANCE to be freed.

**/
VOID
Ip6ConfigCleanInstance (
  IN OUT IP6_CONFIG_INSTANCE  *Instance
  )
{
  UINTN                 Index;
  IP6_CONFIG_DATA_ITEM  *DataItem;

  if (Instance->DeclineAddress != NULL) {
    FreePool (Instance->DeclineAddress);
  }

  if (!Instance->Configured) {
    return ;
  }

  if (Instance->Dhcp6Handle != NULL) {

    Ip6ConfigDestroyDhcp6 (Instance);
  }

  //
  // Close the event.
  //
  if (Instance->Dhcp6Event != NULL) {
    gBS->CloseEvent (Instance->Dhcp6Event);
  }

  NetMapClean (&Instance->DadPassedMap);
  NetMapClean (&Instance->DadFailedMap);

  for (Index = 0; Index < Ip6ConfigDataTypeMaximum; 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);
  }

  Ip6ConfigFormUnload (Instance);

  RemoveEntryList (&Instance->Link);
}

/**
  Destroy the Dhcp6 child in IP6_CONFIG_INSTANCE and release the resources.

  @param[in, out] Instance    The buffer of IP6_CONFIG_INSTANCE to be freed.

  @retval EFI_SUCCESS         The child was successfully destroyed.
  @retval Others              Failed to destroy the child.

**/
EFI_STATUS
Ip6ConfigDestroyDhcp6 (
  IN OUT IP6_CONFIG_INSTANCE  *Instance
  )
{
  IP6_SERVICE                 *IpSb;
  EFI_STATUS                  Status;
  EFI_DHCP6_PROTOCOL          *Dhcp6;

  Dhcp6 = Instance->Dhcp6;
  ASSERT (Dhcp6 != NULL);

  Dhcp6->Stop (Dhcp6);
  Dhcp6->Configure (Dhcp6, NULL);
  Instance->Dhcp6 = NULL;

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);

  //
  // Close DHCPv6 protocol and destroy the child.
  //
  Status = gBS->CloseProtocol (
                  Instance->Dhcp6Handle,
                  &gEfiDhcp6ProtocolGuid,
                  IpSb->Image,
                  IpSb->Controller
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = NetLibDestroyServiceChild (
             IpSb->Controller,
             IpSb->Image,
             &gEfiDhcp6ServiceBindingProtocolGuid,
             Instance->Dhcp6Handle
             );

  Instance->Dhcp6Handle = NULL;

  return Status;
}

