/** @file
  The implementation of EFI IPv6 Configuration Protocol.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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;
  IP6_ADDRESS_INFO     *AddrInfo;
  IP6_PROTOCOL         *Instance;
  BOOLEAN              Recovery;

  Recovery = FALSE;

  //
  // 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
      );
  }

  if (!IsListEmpty (&IpSb->DefaultInterface->AddressList) && (IpSb->DefaultInterface->AddressCount > 0)) {
    //
    // If any IPv6 children (Instance) in configured state and use global unicast address, it will be
    // destroyed in Ip6RemoveAddr() function later. Then, the upper layer driver's Stop() function will be
    // called, which may break the upper layer network stacks. So, the driver should take the responsibility
    // for the recovery by using ConnectController() after Ip6RemoveAddr().
    // Here, just check whether need to recover the upper layer network stacks later.
    //
    NET_LIST_FOR_EACH (Entry, &IpSb->DefaultInterface->AddressList) {
      AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
      if (!IsListEmpty (&IpSb->Children)) {
        NET_LIST_FOR_EACH (Entry2, &IpSb->Children) {
          Instance = NET_LIST_USER_STRUCT_S (Entry2, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
          if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, &AddrInfo->Address)) {
            Recovery = TRUE;
            break;
          }
        }
      }
    }

    //
    // All IPv6 children that use global unicast address as its source address
    // should be destroyed 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
      );

    if ((IpSb->Controller != NULL) && Recovery) {
      //
      // ConnectController() to recover the upper layer network stacks.
      //
      gBS->ConnectController (IpSb->Controller, NULL, NULL, TRUE);
    }
  }

  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. Otherwise, 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 error or the variable is corrupted.
      //
      goto Error;
    }

    //
    // 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.
        // Check that the length is contained within the variable before allocating.
        //
        if (DataRecord.DataSize > VarSize - DataRecord.Offset) {
          goto Error;
        }

        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;

Error:
  //
  // Fall back to the default value.
  //
  if (Variable != NULL) {
    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;
}

/**
  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 interface 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 Ip6ConfigSetManualAddress.

  @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 asynchronous 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
Ip6ConfigSetManualAddress (
  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;
  LIST_ENTRY                     *Next;
  IP6_DAD_ENTRY                  *DadEntry;
  IP6_DELAY_JOIN_LIST            *DelayNode;

  NewAddress      = NULL;
  TmpAddress      = NULL;
  CurrentAddrInfo = NULL;
  Copy            = NULL;
  Entry           = NULL;
  Entry2          = NULL;
  IpIf            = NULL;
  PrefixEntry     = NULL;
  Next            = NULL;
  DadEntry        = NULL;
  DelayNode       = NULL;
  Status          = EFI_SUCCESS;

  ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status != EFI_NOT_READY);

  if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);

  DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];

  if ((Data != NULL) && (DataSize != 0)) {
    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;
        }
      }
    }

    //
    // 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.
    //
    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;
    }
  } else {
    //
    // DataSize is 0 and Data is NULL, clean up the manual address.
    //
    if (DataItem->Data.Ptr != NULL) {
      FreePool (DataItem->Data.Ptr);
    }

    DataItem->Data.Ptr = NULL;
    DataItem->DataSize = 0;
    DataItem->Status   = EFI_NOT_FOUND;

    Ip6CleanDefaultRouterList (IpSb);
    Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix);
    Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix);
    Ip6CleanAssembleTable (&IpSb->Assemble);

    if (IpSb->LinkLocalOk) {
      Ip6CreatePrefixListEntry (
        IpSb,
        TRUE,
        (UINT32)IP6_INFINIT_LIFETIME,
        (UINT32)IP6_INFINIT_LIFETIME,
        IP6_LINK_LOCAL_PREFIX_LENGTH,
        &IpSb->LinkLocalAddr
        );
    }

    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);
        }
      }
    }
  }

  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;

  OldGateway    = NULL;
  NewGateway    = NULL;
  Item          = NULL;
  DefaultRouter = NULL;
  Tmp           = NULL;
  OneRemoved    = FALSE;
  OneAdded      = FALSE;

  if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  IpSb            = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  Item            = &Instance->DataItem[Ip6ConfigDataTypeGateway];
  OldGateway      = Item->Data.Gateway;
  OldGatewayCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);

  for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
    //
    // Remove this default router.
    //
    DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
    if (DefaultRouter != NULL) {
      Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
      OneRemoved = TRUE;
    }
  }

  if ((Data != NULL) && (DataSize != 0)) {
    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;
        }
      }
    }

    if (NewGatewayCount != OldGatewayCount) {
      Tmp = AllocatePool (DataSize);
      if (Tmp == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
    } else {
      Tmp = NULL;
    }

    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;
    }
  } else {
    //
    // DataSize is 0 and Data is NULL, clean up the Gateway address.
    //
    if (Item->Data.Ptr != NULL) {
      FreePool (Item->Data.Ptr);
    }

    Item->Data.Ptr = NULL;
    Item->DataSize = 0;
    Item->Status   = EFI_NOT_FOUND;
  }

  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;

  OldDns = NULL;
  NewDns = NULL;
  Item   = NULL;
  Tmp    = NULL;

  if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Instance->Policy != Ip6ConfigPolicyManual) {
    return EFI_WRITE_PROTECTED;
  }

  Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];

  if ((Data != NULL) && (DataSize != 0)) {
    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;
    }
  } else {
    //
    // DataSize is 0 and Data is NULL, clean up the DnsServer address.
    //
    if (Item->Data.Ptr != NULL) {
      FreePool (Item->Data.Ptr);
    }

    Item->Data.Ptr = NULL;
    Item->DataSize = 0;
    Item->Status   = EFI_NOT_FOUND;
  }

  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.
                                - One or more fields in Data and DataSizedo 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) && (DataSize != 0)) || ((Data != NULL) && (DataSize == 0))) {
    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 asynchronous 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 = Ip6ConfigSetManualAddress;
  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;
}
