/** @file
  The implementation of EFI IPv6 Configuration Protocol.

  Copyright (c) 2009 - 2012, 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;

  //
  // 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 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->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 paramters 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 (IP6_CONFIG_DHCP6_OPTION_ORO);
  Oro->OpLen                  = HTONS (2);
  *((UINT16 *) &Oro->Data[0]) = HTONS (IP6_CONFIG_DHCP6_OPTION_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 = 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 {

    if (NewPolicy == Ip6ConfigPolicyAutomatic) {
      //
      // 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);
    } else {
      //
      // 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;

  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
        );

      //
      // 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;
  UINTN                 Index1;
  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.
      //
      FreePool (Tmp);
      return EFI_INVALID_PARAMETER;
    }

    for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {
      if (EFI_IP6_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_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
  )
{
  IfInfo->Name[0] = L'e';
  IfInfo->Name[1] = L't';
  IfInfo->Name[2] = L'h';
  IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip6ConfigInstance.IfIndex);
  IfInfo->Name[4] = 0;

  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 == IP6_CONFIG_DHCP6_OPTION_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.
      //
      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   = Ip6ConfigPolicyAutomatic;
  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;
}

