/** @file
  The implementation for Shell application IfConfig6.

  Copyright (c) 2009 - 2016, 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 <Library/ShellLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiHiiServicesLib.h>
#include <Library/HiiLib.h>
#include <Library/NetLib.h>

#include <Protocol/Ip6.h>
#include <Protocol/Ip6Config.h>

#include "IfConfig6.h"

//
// String token ID of ifconfig6 command help message text.
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringIfconfig6HelpTokenId = STRING_TOKEN (STR_IFCONFIG6_HELP);

EFI_HII_HANDLE      mHiiHandle;

SHELL_PARAM_ITEM    mIfConfig6CheckList[] = {
  {
    L"-b",
    TypeFlag
  },
  {
    L"-s",
    TypeMaxValue
  },
  {
    L"-l",
    TypeValue
  },
  {
    L"-r",
    TypeValue
  },
  {
    NULL,
    TypeMax
  },
};

VAR_CHECK_ITEM  mSetCheckList[] = {
  {
   L"auto",
    0x00000001,
    0x00000001,
    FlagTypeSingle
  },
  {
    L"man",
    0x00000002,
    0x00000001,
    FlagTypeSingle
  },
  {
    L"host",
    0x00000004,
    0x00000002,
    FlagTypeSingle
  },
  {
    L"dad",
    0x00000008,
    0x00000004,
    FlagTypeSingle
  },
  {
    L"gw",
    0x00000010,
    0x00000008,
    FlagTypeSingle
  },
  {
    L"dns",
    0x00000020,
    0x00000010,
    FlagTypeSingle
  },
  {
    L"id",
    0x00000040,
    0x00000020,
    FlagTypeSingle
  },
  {
    NULL,
    0x0,
    0x0,
    FlagTypeSkipUnknown
  },
};

/**
  Split a string with specified separator and save the substring to a list.

  @param[in]    String       The pointer of the input string.
  @param[in]    Separator    The specified separator.

  @return The pointer of headnode of ARG_LIST.

**/
ARG_LIST *
SplitStrToList (
  IN CONST CHAR16    *String,
  IN CHAR16          Separator
  )
{
  CHAR16      *Str;
  CHAR16      *ArgStr;
  ARG_LIST    *ArgList;
  ARG_LIST    *ArgNode;

  if (String == NULL || *String == L'\0') {
    return NULL;
  }

  //
  // Copy the CONST string to a local copy.
  //
  Str     = AllocateCopyPool (StrSize (String), String);
  ASSERT (Str != NULL);
  ArgStr  = Str;

  //
  // init a node for the list head.
  //
  ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
  ASSERT (ArgNode != NULL);
  ArgList = ArgNode;

  //
  // Split the local copy and save in the list node.
  //
  while (*Str != L'\0') {
    if (*Str == Separator) {
      *Str          = L'\0';
      ArgNode->Arg  = ArgStr;
      ArgStr        = Str + 1;
      ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
      ASSERT (ArgNode->Next != NULL);
      ArgNode = ArgNode->Next;
    }

    Str++;
  }

  ArgNode->Arg  = ArgStr;
  ArgNode->Next = NULL;

  return ArgList;
}

/**
  Check the correctness of input Args with '-s' option.

  @param[in]    CheckList    The pointer of VAR_CHECK_ITEM array.
  @param[in]    Name         The pointer of input arg.
  @param[in]    Init         The switch to execute the check.

  @return The value of VAR_CHECK_CODE.

**/
VAR_CHECK_CODE
IfConfig6RetriveCheckListByName(
  IN VAR_CHECK_ITEM    *CheckList,
  IN CHAR16            *Name,
  IN BOOLEAN           Init
)
{
  STATIC UINT32     CheckDuplicate;
  STATIC UINT32     CheckConflict;
  VAR_CHECK_CODE    RtCode;
  UINT32            Index;
  VAR_CHECK_ITEM    Arg;

  if (Init) {
    CheckDuplicate = 0;
    CheckConflict  = 0;
    return VarCheckOk;
  }

  RtCode  = VarCheckOk;
  Index   = 0;
  Arg     = CheckList[Index];

  //
  // Check the Duplicated/Conflicted/Unknown input Args.
  //
  while (Arg.FlagStr != NULL) {
    if (StrCmp (Arg.FlagStr, Name) == 0) {

      if (CheckDuplicate & Arg.FlagID) {
        RtCode = VarCheckDuplicate;
        break;
      }

      if (CheckConflict & Arg.ConflictMask) {
        RtCode = VarCheckConflict;
        break;
      }

      CheckDuplicate |= Arg.FlagID;
      CheckConflict  |= Arg.ConflictMask;
      break;
    }

    Arg = CheckList[++Index];
  }

  if (Arg.FlagStr == NULL) {
    RtCode = VarCheckUnknown;
  }

  return RtCode;
}

/**
  The notify function of create event when performing a manual config.

  @param[in]    Event        The event this notify function registered to.
  @param[in]    Context      Pointer to the context data registered to the event.

**/
VOID
EFIAPI
IfConfig6ManualAddressNotify (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  )
{
  *((BOOLEAN *) Context) = TRUE;
}

/**
  Print MAC address.

  @param[in]    Node    The pointer of MAC address buffer.
  @param[in]    Size    The size of MAC address buffer.

**/
VOID
IfConfig6PrintMacAddr (
  IN UINT8     *Node,
  IN UINT32    Size
  )
{
  UINTN    Index;

  ASSERT (Size <= MACADDRMAXSIZE);

  for (Index = 0; Index < Size; Index++) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY), mHiiHandle, Node[Index]);
    if (Index + 1 < Size) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
    }
  }

  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
}

/**
  Print IPv6 address.

  @param[in]    Ip           The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
  @param[in]    PrefixLen    The pointer of PrefixLen that describes the size Prefix.

**/
VOID
IfConfig6PrintIpAddr (
  IN EFI_IPv6_ADDRESS    *Ip,
  IN UINT8               *PrefixLen
  )
{
  UINTN      Index;
  BOOLEAN    Short;

  Short = FALSE;

  for (Index = 0; Index < PREFIXMAXLEN; Index = Index + 2) {

    if (!Short && (Index + 1 < PREFIXMAXLEN) && (Index % 2 == 0) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
      //
      // Deal with the case of ::.
      //
      if (Index == 0) {
        //
        // :: is at the beginning of the address.
        //
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
      }
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);

      while ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < PREFIXMAXLEN)) {
        Index = Index + 2;
        if (Index > PREFIXMAXLEN - 2) {
          break;
        }
      }

      Short = TRUE;

      if (Index == PREFIXMAXLEN) {
        //
        // :: is at the end of the address.
        //
        break;
      }
    }

    if (Index < PREFIXMAXLEN - 1) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index]);
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index + 1]);
    }

    if (Index + 2 < PREFIXMAXLEN) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
    }
  }

  if (PrefixLen != NULL) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), mHiiHandle, *PrefixLen);
  }
}

/**
  Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.

  @param[in, out]    Arg        The pointer of the address of ARG_LIST which save Args with the "-s" option.
  @param[out]        Buf        The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
  @param[out]        BufSize    The pointer of BufSize that describes the size of Buf in bytes.

  @retval EFI_SUCCESS    The convertion is successful.
  @retval Others         Does't find the host address, or it is an invalid IPv6 address in string format.

**/
EFI_STATUS
IfConfig6ParseManualAddressList (
  IN OUT ARG_LIST                         **Arg,
     OUT EFI_IP6_CONFIG_MANUAL_ADDRESS    **Buf,
     OUT UINTN                            *BufSize
  )
{
  EFI_STATUS                       Status;
  EFI_IP6_CONFIG_MANUAL_ADDRESS    *AddrBuf;
  ARG_LIST                         *VarArg;
  EFI_IPv6_ADDRESS                 Address;
  UINT8                            Prefix;
  UINT8                            AddrCnt;

  Prefix   = 0;
  AddrCnt  = 0;
  *BufSize = 0;
  *Buf     = NULL;
  VarArg   = *Arg;
  Status   = EFI_SUCCESS;

  //
  // Go through the list to check the correctness of input host ip6 address.
  //
  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {

    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);

    if (EFI_ERROR (Status)) {
      //
      // host ip ip ... gw
      //
      break;
    }

    VarArg = VarArg->Next;
    AddrCnt++;
  }

  if (AddrCnt == 0) {
    return EFI_INVALID_PARAMETER;
  }

  AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));
  ASSERT (AddrBuf != NULL);

  AddrCnt = 0;
  VarArg  = *Arg;
  Status  = EFI_SUCCESS;

  //
  // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
  //
  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {

    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);

    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
    // Zero prefix, length will be transfered to default prefix length.
    //
    if (Prefix == 0xFF) {
      Prefix = 0;
    }
    AddrBuf[AddrCnt].IsAnycast    = FALSE;
    AddrBuf[AddrCnt].PrefixLength = Prefix;
    IP6_COPY_ADDRESS (&AddrBuf[AddrCnt].Address, &Address);
    VarArg = VarArg->Next;
    AddrCnt++;
  }

  *Arg = VarArg;

  if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
    goto ON_ERROR;
  }

  *Buf     = AddrBuf;
  *BufSize = AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);

  return EFI_SUCCESS;

ON_ERROR:

  FreePool (AddrBuf);
  return Status;
}

/**
  Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.

  @param[in, out]    Arg        The pointer of the address of ARG_LIST that save Args with the "-s" option.
  @param[out]        Buf        The pointer of the address of EFI_IPv6_ADDRESS.
  @param[out]        BufSize    The pointer of BufSize that describes the size of Buf in bytes.

  @retval EFI_SUCCESS    The conversion is successful.
  @retval Others         Doesn't find the host address, or it is an invalid IPv6 address in string format.

**/
EFI_STATUS
IfConfig6ParseGwDnsAddressList (
  IN OUT ARG_LIST            **Arg,
     OUT EFI_IPv6_ADDRESS    **Buf,
     OUT UINTN               *BufSize
  )
{
  EFI_STATUS          Status;
  EFI_IPv6_ADDRESS    *AddrBuf;
  ARG_LIST            *VarArg;
  EFI_IPv6_ADDRESS    Address;
  UINT8               Prefix;
  UINT8               AddrCnt;

  AddrCnt  = 0;
  *BufSize = 0;
  *Buf     = NULL;
  VarArg   = *Arg;
  Status   = EFI_SUCCESS;

  //
  // Go through the list to check the correctness of input gw/dns address.
  //
  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {

    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);

    if (EFI_ERROR (Status)) {
      //
      // gw ip ip ... host
      //
      break;
    }

    VarArg = VarArg->Next;
    AddrCnt++;
  }

  if (AddrCnt == 0) {
    return EFI_INVALID_PARAMETER;
  }

  AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IPv6_ADDRESS));
  ASSERT (AddrBuf != NULL);

  AddrCnt = 0;
  VarArg  = *Arg;
  Status  = EFI_SUCCESS;

  //
  // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
  //
  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {

    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);

    if (EFI_ERROR (Status)) {
      break;
    }

    IP6_COPY_ADDRESS (&AddrBuf[AddrCnt], &Address);

    VarArg = VarArg->Next;
    AddrCnt++;
  }

  *Arg = VarArg;

  if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
   goto ON_ERROR;
  }

  *Buf     = AddrBuf;
  *BufSize = AddrCnt * sizeof (EFI_IPv6_ADDRESS);

  return EFI_SUCCESS;

ON_ERROR:

  FreePool (AddrBuf);
  return Status;
}

/**
  Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.

  @param[in, out]   Arg     The pointer of the address of ARG_LIST that saves Args with the "-s" option.
  @param[out]       IfId    The pointer of EFI_IP6_CONFIG_INTERFACE_ID.

  @retval EFI_SUCCESS              The get status processed successfullly.
  @retval EFI_INVALID_PARAMETER    The get status process failed.

**/
EFI_STATUS
IfConfig6ParseInterfaceId (
  IN OUT ARG_LIST                       **Arg,
     OUT EFI_IP6_CONFIG_INTERFACE_ID    **IfId
  )
{
  UINT8     Index;
  UINT8     NodeVal;
  CHAR16    *IdStr;

  if (*Arg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Index = 0;
  IdStr = (*Arg)->Arg;
  ASSERT (IfId != NULL);
  *IfId = AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID));
  ASSERT (*IfId != NULL);

  while ((*IdStr != L'\0') && (Index < 8)) {

    NodeVal = 0;
    while ((*IdStr != L':') && (*IdStr != L'\0')) {

      if ((*IdStr <= L'F') && (*IdStr >= L'A')) {
        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'A' + 10);
      } else if ((*IdStr <= L'f') && (*IdStr >= L'a')) {
        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'a' + 10);
      } else if ((*IdStr <= L'9') && (*IdStr >= L'0')) {
        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'0');
      } else {
        FreePool (*IfId);
        return EFI_INVALID_PARAMETER;
      }

      IdStr++;
    }

    (*IfId)->Id[Index++] = NodeVal;

    if (*IdStr == L':') {
      IdStr++;
    }
  }

  *Arg = (*Arg)->Next;
  return EFI_SUCCESS;
}

/**
  Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.

  @param[in, out]   Arg      The pointer of the address of ARG_LIST that saves Args with the "-s" option.
  @param[out]       Xmits    The pointer of Xmits.

  @retval EFI_SUCCESS    The get status processed successfully.
  @retval others         The get status process failed.

**/
EFI_STATUS
IfConfig6ParseDadXmits (
  IN OUT ARG_LIST    **Arg,
     OUT UINT32      *Xmits
  )
{
  CHAR16    *ValStr;

  if (*Arg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ValStr = (*Arg)->Arg;
  *Xmits = 0;

  while (*ValStr != L'\0') {

    if ((*ValStr <= L'9') && (*ValStr >= L'0')) {

      *Xmits = (*Xmits * 10) + (*ValStr - L'0');

    } else {

      return EFI_INVALID_PARAMETER;
    }

    ValStr++;
  }

  *Arg = (*Arg)->Next;
  return EFI_SUCCESS;
}

/**
  The get current status of all handles.

  @param[in]   ImageHandle    The handle of  ImageHandle.
  @param[in]   IfName         The pointer of  IfName(interface name).
  @param[in]   IfList         The pointer of  IfList(interface list).

  @retval EFI_SUCCESS    The get status processed successfully.
  @retval others         The get status process failed.

**/
EFI_STATUS
IfConfig6GetInterfaceInfo (
  IN EFI_HANDLE    ImageHandle,
  IN CHAR16        *IfName,
  IN LIST_ENTRY    *IfList
  )
{
  EFI_STATUS                       Status;
  UINTN                            HandleIndex;
  UINTN                            HandleNum;
  EFI_HANDLE                       *HandleBuffer;
  EFI_IP6_CONFIG_PROTOCOL          *Ip6Cfg;
  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;
  IFCONFIG6_INTERFACE_CB           *IfCb;
  UINTN                            DataSize;

  HandleBuffer = NULL;
  HandleNum    = 0;

  IfInfo       = NULL;
  IfCb         = NULL;

  //
  // Locate all the handles with ip6 service binding protocol.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiIp6ServiceBindingProtocolGuid,
                  NULL,
                  &HandleNum,
                  &HandleBuffer
                 );
  if (EFI_ERROR (Status) || (HandleNum == 0)) {
    return EFI_ABORTED;
  }

  //
  // Enumerate all handles that installed with ip6 service binding protocol.
  //
  for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
    IfCb      = NULL;
    IfInfo    = NULL;
    DataSize  = 0;

    //
    // Ip6config protocol and ip6 service binding protocol are installed
    // on the same handle.
    //
    ASSERT (HandleBuffer != NULL);
    Status = gBS->HandleProtocol (
                    HandleBuffer[HandleIndex],
                    &gEfiIp6ConfigProtocolGuid,
                    (VOID **) &Ip6Cfg
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
    //
    // Get the interface information size.
    //
    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeInterfaceInfo,
                       &DataSize,
                       NULL
                       );

    if (Status != EFI_BUFFER_TOO_SMALL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }

    IfInfo = AllocateZeroPool (DataSize);

    if (IfInfo == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }
    //
    // Get the interface info.
    //
    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeInterfaceInfo,
                       &DataSize,
                       IfInfo
                       );

    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }
    //
    // Check the interface name if required.
    //
    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {
      FreePool (IfInfo);
      continue;
    }

    DataSize = 0;
    //
    // Get the size of dns server list.
    //
    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeDnsServer,
                       &DataSize,
                       NULL
                       );

    if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }

    IfCb = AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB) + DataSize);

    if (IfCb == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }

    IfCb->NicHandle = HandleBuffer[HandleIndex];
    IfCb->IfInfo    = IfInfo;
    IfCb->IfCfg     = Ip6Cfg;
    IfCb->DnsCnt    = (UINT32) (DataSize / sizeof (EFI_IPv6_ADDRESS));

    //
    // Get the dns server list if has.
    //
    if (DataSize > 0) {

      Status = Ip6Cfg->GetData (
                         Ip6Cfg,
                         Ip6ConfigDataTypeDnsServer,
                         &DataSize,
                         IfCb->DnsAddr
                         );

      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
        goto ON_ERROR;
      }
    }
    //
    // Get the interface id if has.
    //
    DataSize   = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
    IfCb->IfId = AllocateZeroPool (DataSize);

    if (IfCb->IfId == NULL) {
      goto ON_ERROR;
    }

    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeAltInterfaceId,
                       &DataSize,
                       IfCb->IfId
                       );

    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }

    if (Status == EFI_NOT_FOUND) {
      FreePool (IfCb->IfId);
      IfCb->IfId = NULL;
    }
    //
    // Get the config policy.
    //
    DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
    Status   = Ip6Cfg->GetData (
                         Ip6Cfg,
                         Ip6ConfigDataTypePolicy,
                         &DataSize,
                         &IfCb->Policy
                         );

    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }
    //
    // Get the dad transmits.
    //
    DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
    Status   = Ip6Cfg->GetData (
                         Ip6Cfg,
                         Ip6ConfigDataTypeDupAddrDetectTransmits,
                         &DataSize,
                         &IfCb->Xmits
                         );

    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
      goto ON_ERROR;
    }

    InsertTailList (IfList, &IfCb->Link);

    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {
      //
      // Only need the appointed interface, keep the allocated buffer.
      //
      IfCb   = NULL;
      IfInfo = NULL;
      break;
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (IfInfo != NULL) {
    FreePool (IfInfo);
  }

  if (IfCb != NULL) {
    if (IfCb->IfId != NULL) {
      FreePool (IfCb->IfId);
    }

    FreePool (IfCb);
  }

  return Status;
}

/**
  The list process of the IfConfig6 application.

  @param[in]   IfList    The pointer of IfList(interface list).

  @retval EFI_SUCCESS    The IfConfig6 list processed successfully.
  @retval others         The IfConfig6 list process failed.

**/
EFI_STATUS
IfConfig6ShowInterfaceInfo (
  IN LIST_ENTRY    *IfList
  )
{
  EFI_STATUS                Status;
  LIST_ENTRY                *Entry;
  IFCONFIG6_INTERFACE_CB    *IfCb;
  UINTN                     Index;

  Entry  = IfList->ForwardLink;
  Status = EFI_SUCCESS;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
  }

  //
  // Go through the interface list.
  //
  while (Entry != IfList) {

    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);

    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), mHiiHandle);

    //
    // Print interface name.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), mHiiHandle, IfCb->IfInfo->Name);

    //
    // Print interface config policy.
    //
    if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), mHiiHandle);
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), mHiiHandle);
    }

    //
    // Print dad transmit.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), mHiiHandle, IfCb->Xmits);

    //
    // Print interface id if has.
    //
    if (IfCb->IfId != NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), mHiiHandle);

      IfConfig6PrintMacAddr (
        IfCb->IfId->Id,
        8
        );
    }
    //
    // Print mac address of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), mHiiHandle);

    IfConfig6PrintMacAddr (
      IfCb->IfInfo->HwAddress.Addr,
      IfCb->IfInfo->HwAddressSize
      );

    //
    // Print ip addresses list of the interface.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD), mHiiHandle);

    for (Index = 0; Index < IfCb->IfInfo->AddressInfoCount; Index++) {
      IfConfig6PrintIpAddr (
        &IfCb->IfInfo->AddressInfo[Index].Address,
        &IfCb->IfInfo->AddressInfo[Index].PrefixLength
        );
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
    }

    //
    // Print dns server addresses list of the interface if has.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), mHiiHandle);

    for (Index = 0; Index < IfCb->DnsCnt; Index++) {
      IfConfig6PrintIpAddr (
        &IfCb->DnsAddr[Index],
        NULL
        );
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
    }

    //
    // Print route table of the interface if has.
    //
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), mHiiHandle);

    for (Index = 0; Index < IfCb->IfInfo->RouteCount; Index++) {
      IfConfig6PrintIpAddr (
        &IfCb->IfInfo->RouteTable[Index].Destination,
        &IfCb->IfInfo->RouteTable[Index].PrefixLength
        );
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT), mHiiHandle);

      IfConfig6PrintIpAddr (
        &IfCb->IfInfo->RouteTable[Index].Gateway,
        NULL
        );
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
    }

    Entry = Entry->ForwardLink;
  }

  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), mHiiHandle);

  return Status;
}

/**
  The clean process of the IfConfig6 application.

  @param[in]   IfList    The pointer of IfList(interface list).

  @retval EFI_SUCCESS    The IfConfig6 clean processed successfully.
  @retval others         The IfConfig6 clean process failed.

**/
EFI_STATUS
IfConfig6ClearInterfaceInfo (
  IN LIST_ENTRY    *IfList
  )
{
  EFI_STATUS                Status;
  LIST_ENTRY                *Entry;
  IFCONFIG6_INTERFACE_CB    *IfCb;
  EFI_IP6_CONFIG_POLICY     Policy;

  Policy = Ip6ConfigPolicyAutomatic;
  Entry  = IfList->ForwardLink;
  Status = EFI_SUCCESS;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
  }

  //
  // Go through the interface list.
  //
  while (Entry != IfList) {

    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);

    Status = IfCb->IfCfg->SetData (
                            IfCb->IfCfg,
                            Ip6ConfigDataTypePolicy,
                            sizeof (EFI_IP6_CONFIG_POLICY),
                            &Policy
                            );

    if (EFI_ERROR (Status)) {
      break;
    }

    Entry  = Entry->ForwardLink;
  }

  return Status;
}

/**
  The set process of the IfConfig6 application.

  @param[in]   IfList    The pointer of IfList(interface list).
  @param[in]   VarArg    The pointer of ARG_LIST(Args with "-s" option).

  @retval EFI_SUCCESS    The IfConfig6 set processed successfully.
  @retval others         The IfConfig6 set process failed.

**/
EFI_STATUS
IfConfig6SetInterfaceInfo (
  IN LIST_ENTRY    *IfList,
  IN ARG_LIST      *VarArg
  )
{
  EFI_STATUS                       Status;
  IFCONFIG6_INTERFACE_CB           *IfCb;
  EFI_IP6_CONFIG_MANUAL_ADDRESS    *CfgManAddr;
  EFI_IPv6_ADDRESS                 *CfgAddr;
  UINTN                            AddrSize;
  EFI_IP6_CONFIG_INTERFACE_ID      *InterfaceId;
  UINT32                           DadXmits;
  UINT32                           CurDadXmits;
  UINTN                            CurDadXmitsLen;
  EFI_IP6_CONFIG_POLICY            Policy;

  VAR_CHECK_CODE                   CheckCode;
  EFI_EVENT                        TimeOutEvt;
  EFI_EVENT                        MappedEvt;
  BOOLEAN                          IsAddressOk;

  UINTN                            DataSize;
  UINT32                           Index;
  UINT32                           Index2;
  BOOLEAN                          IsAddressSet;
  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;

  CfgManAddr  = NULL;
  CfgAddr     = NULL;
  TimeOutEvt  = NULL;
  MappedEvt   = NULL;
  IfInfo      = NULL;
  InterfaceId = NULL;
  CurDadXmits = 0;

  if (IsListEmpty (IfList)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
    return EFI_INVALID_PARAMETER;
  }
  //
  // Make sure to set only one interface each time.
  //
  IfCb   = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
  Status = EFI_SUCCESS;

  //
  // Initialize check list mechanism.
  //
  CheckCode = IfConfig6RetriveCheckListByName(
                NULL,
                NULL,
                TRUE
                );

  //
  // Create events & timers for asynchronous settings.
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &TimeOutEvt
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  IfConfig6ManualAddressNotify,
                  &IsAddressOk,
                  &MappedEvt
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  //
  // Parse the setting variables.
  //
  while (VarArg != NULL) {
     //
     // Check invalid parameters (duplication & unknown & conflict).
     //
    CheckCode = IfConfig6RetriveCheckListByName(
                  mSetCheckList,
                  VarArg->Arg,
                  FALSE
                  );

    if (VarCheckOk != CheckCode) {
      switch (CheckCode) {
        case VarCheckDuplicate:
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), mHiiHandle, VarArg->Arg);
          break;

        case VarCheckConflict:
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), mHiiHandle, VarArg->Arg);
          break;

        case VarCheckUnknown:
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), mHiiHandle, VarArg->Arg);
          break;

        default:
          break;
      }

      VarArg = VarArg->Next;
      continue;
    }
    //
    // Process valid variables.
    //
    if (StrCmp(VarArg->Arg, L"auto") == 0) {
      //
      // Set automaic config policy
      //
      Policy = Ip6ConfigPolicyAutomatic;
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypePolicy,
                              sizeof (EFI_IP6_CONFIG_POLICY),
                              &Policy
                              );

      if (EFI_ERROR(Status)) {
        goto ON_EXIT;
      }

      VarArg= VarArg->Next;

    } else if (StrCmp (VarArg->Arg, L"man") == 0) {
      //
      // Set manual config policy.
      //
      Policy = Ip6ConfigPolicyManual;
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypePolicy,
                              sizeof (EFI_IP6_CONFIG_POLICY),
                              &Policy
                              );

      if (EFI_ERROR(Status)) {
        goto ON_EXIT;
      }

      VarArg= VarArg->Next;

    } else if (StrCmp (VarArg->Arg, L"host") == 0) {
      //
      // Parse till the next tag or the end of command line.
      //
      VarArg = VarArg->Next;
      Status = IfConfig6ParseManualAddressList (
                 &VarArg,
                 &CfgManAddr,
                 &AddrSize
                 );

      if (EFI_ERROR (Status)) {
        if (Status == EFI_INVALID_PARAMETER) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"host");
          continue;
        } else {
          goto ON_EXIT;
        }
      }
      //
      // Set static host ip6 address list.
      //   This is a asynchronous process.
      //
      IsAddressOk = FALSE;

      Status = IfCb->IfCfg->RegisterDataNotify (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeManualAddress,
                              MappedEvt
                              );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeManualAddress,
                              AddrSize,
                              CfgManAddr
                              );

      if (Status == EFI_NOT_READY) {
        //
        // Get current dad transmits count.
        //
        CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
        IfCb->IfCfg->GetData (
                       IfCb->IfCfg,
                       Ip6ConfigDataTypeDupAddrDetectTransmits,
                       &CurDadXmitsLen,
                       &CurDadXmits
                       );

        gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits);

        while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
          if (IsAddressOk) {
            Status = EFI_SUCCESS;
            break;
          }
        }
      }

      IfCb->IfCfg->UnregisterDataNotify (
                     IfCb->IfCfg,
                     Ip6ConfigDataTypeManualAddress,
                     MappedEvt
                     );

      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST), mHiiHandle, Status);
        goto ON_EXIT;
      }

      //
      // Check whether the address is set successfully.
      //
      DataSize = 0;

      Status = IfCb->IfCfg->GetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeInterfaceInfo,
                              &DataSize,
                              NULL
                              );

      if (Status != EFI_BUFFER_TOO_SMALL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
        goto ON_EXIT;
      }

      IfInfo = AllocateZeroPool (DataSize);

      if (IfInfo == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Status = IfCb->IfCfg->GetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeInterfaceInfo,
                              &DataSize,
                              IfInfo
                              );

      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
        goto ON_EXIT;
      }

      for ( Index = 0; Index < (UINTN) (AddrSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); Index++) {
        IsAddressSet = FALSE;
        //
        // By default, the prefix length 0 is regarded as 64.
        //
        if (CfgManAddr[Index].PrefixLength == 0) {
          CfgManAddr[Index].PrefixLength = 64;
        }

        for (Index2 = 0; Index2 < IfInfo->AddressInfoCount; Index2++) {
          if (EFI_IP6_EQUAL (&IfInfo->AddressInfo[Index2].Address, &CfgManAddr[Index].Address) &&
              (IfInfo->AddressInfo[Index2].PrefixLength == CfgManAddr[Index].PrefixLength)) {
            IsAddressSet = TRUE;
            break;
          }
        }

        if (!IsAddressSet) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED), mHiiHandle);
          IfConfig6PrintIpAddr (
            &CfgManAddr[Index].Address,
            &CfgManAddr[Index].PrefixLength
            );
        }
      }

    } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
      //
      // Parse till the next tag or the end of command line.
      //
      VarArg = VarArg->Next;
      Status = IfConfig6ParseGwDnsAddressList (
                 &VarArg,
                 &CfgAddr,
                 &AddrSize
                 );

      if (EFI_ERROR (Status)) {
        if (Status == EFI_INVALID_PARAMETER) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"gw");
          continue;
        } else {
          goto ON_EXIT;
        }
      }
      //
      // Set static gateway ip6 address list.
      //
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeGateway,
                              AddrSize,
                              CfgAddr
                              );

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

    } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
      //
      // Parse till the next tag or the end of command line.
      //
      VarArg = VarArg->Next;
      Status = IfConfig6ParseGwDnsAddressList (
                 &VarArg,
                 &CfgAddr,
                 &AddrSize
                 );

      if (EFI_ERROR (Status)) {
        if (Status == EFI_INVALID_PARAMETER) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"dns");
          continue;
        } else {
          goto ON_EXIT;
        }
      }
      //
      // Set static dhs server ip6 address list.
      //
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeDnsServer,
                              AddrSize,
                              CfgAddr
                              );

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

    } else if (StrCmp (VarArg->Arg, L"id") == 0) {
      //
      // Parse till the next tag or the end of command line.
      //
      VarArg = VarArg->Next;
      Status = IfConfig6ParseInterfaceId (&VarArg, &InterfaceId);

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }
      //
      // Set alternative interface id.
      //
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeAltInterfaceId,
                              sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
                              InterfaceId
                              );

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

    } else if (StrCmp (VarArg->Arg, L"dad") == 0) {
      //
      // Parse till the next tag or the end of command line.
      //
      VarArg = VarArg->Next;
      Status = IfConfig6ParseDadXmits (&VarArg, &DadXmits);

      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }
      //
      // Set dad transmits count.
      //
      Status = IfCb->IfCfg->SetData (
                              IfCb->IfCfg,
                              Ip6ConfigDataTypeDupAddrDetectTransmits,
                              sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
                              &DadXmits
                              );

      if (EFI_ERROR(Status)) {
        goto ON_EXIT;
      }
    }
  }

ON_EXIT:

  if (CfgManAddr != NULL) {
    FreePool (CfgManAddr);
  }

  if (CfgAddr != NULL) {
    FreePool (CfgAddr);
  }

  if (MappedEvt != NULL) {
    gBS->CloseEvent (MappedEvt);
  }

  if (TimeOutEvt != NULL) {
    gBS->CloseEvent (TimeOutEvt);
  }

  if (IfInfo != NULL) {
    FreePool (IfInfo);
  }

  return Status;

}

/**
  The IfConfig6 main process.

  @param[in]   Private    The pointer of IFCONFIG6_PRIVATE_DATA.

  @retval EFI_SUCCESS    IfConfig6 processed successfully.
  @retval others         The IfConfig6 process failed.

**/
EFI_STATUS
IfConfig6 (
  IN IFCONFIG6_PRIVATE_DATA    *Private
  )
{
  EFI_STATUS    Status;

  //
  // Get configure information of all interfaces.
  //
  Status = IfConfig6GetInterfaceInfo (
             Private->ImageHandle,
             Private->IfName,
             &Private->IfList
             );

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  switch (Private->OpCode) {
  case IfConfig6OpList:
    Status = IfConfig6ShowInterfaceInfo (&Private->IfList);
    break;

  case IfConfig6OpClear:
    Status = IfConfig6ClearInterfaceInfo (&Private->IfList);
    break;

  case IfConfig6OpSet:
    Status = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);
    break;

  default:
    Status = EFI_ABORTED;
  }

ON_EXIT:

  return Status;
}

/**
  The IfConfig6 cleanup process, free the allocated memory.

  @param[in]   Private    The pointer of  IFCONFIG6_PRIVATE_DATA.

**/
VOID
IfConfig6Cleanup (
  IN IFCONFIG6_PRIVATE_DATA    *Private
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *NextEntry;
  IFCONFIG6_INTERFACE_CB    *IfCb;
  ARG_LIST                  *ArgNode;
  ARG_LIST                  *ArgHead;

  ASSERT (Private != NULL);

  //
  // Clean the list which save the set config Args.
  //
  if (Private->VarArg != NULL) {
    ArgHead = Private->VarArg;

    while (ArgHead->Next != NULL) {
      ArgNode = ArgHead->Next;
      FreePool (ArgHead);
      ArgHead = ArgNode;
    }

    FreePool (ArgHead);
  }

  if (Private->IfName != NULL)
    FreePool (Private->IfName);


  //
  // Clean the IFCONFIG6_INTERFACE_CB list.
  //
  Entry     = Private->IfList.ForwardLink;
  NextEntry = Entry->ForwardLink;

  while (Entry != &Private->IfList) {

    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);

    RemoveEntryList (&IfCb->Link);

    if (IfCb->IfId != NULL) {

      FreePool (IfCb->IfId);
    }

    if (IfCb->IfInfo != NULL) {

      FreePool (IfCb->IfInfo);
    }

    FreePool (IfCb);

    Entry     = NextEntry;
    NextEntry = Entry->ForwardLink;
  }

  FreePool (Private);
}

/**
  This is the declaration of an EFI image entry point. This entry point is
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
  both device drivers and bus drivers.

  The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.

  @param[in] ImageHandle    The image handle of this application.
  @param[in] SystemTable    The pointer to the EFI System Table.

  @retval EFI_SUCCESS    The operation completed successfully.
  @retval Others         Some errors occur.

**/
EFI_STATUS
EFIAPI
IfConfig6Initialize (
  IN  EFI_HANDLE         ImageHandle,
  IN  EFI_SYSTEM_TABLE    *SystemTable
  )
{
  EFI_STATUS                    Status;
  IFCONFIG6_PRIVATE_DATA        *Private;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageList;
  LIST_ENTRY                    *ParamPackage;
  CONST CHAR16                  *ValueStr;
  ARG_LIST                      *ArgList;
  CHAR16                        *ProblemParam;
  CHAR16                        *Str;

  Private = NULL;

  //
  // Retrieve HII package list from ImageHandle
  //
  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiHiiPackageListProtocolGuid,
                  (VOID **) &PackageList,
                  ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Publish HII package list to HII Database.
  //
  Status = gHiiDatabase->NewPackageList (
                          gHiiDatabase,
                          PackageList,
                          NULL,
                          &mHiiHandle
                          );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  ASSERT (mHiiHandle != NULL);

  Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), mHiiHandle, ProblemParam);
    goto ON_EXIT;
  }

  //
  // To handle no option.
  //
  if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&
      !ShellCommandLineGetFlag (ParamPackage, L"-l")) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION), mHiiHandle);
    goto ON_EXIT;
  }
  //
  // To handle conflict options.
  //
  if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||
      ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l")))) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS), mHiiHandle);
    goto ON_EXIT;
  }

  Status = EFI_INVALID_PARAMETER;

  Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));

  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  InitializeListHead (&Private->IfList);

  //
  // To get interface name for the list option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
    Private->OpCode = IfConfig6OpList;
    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");
    if (ValueStr != NULL) {
      Str             = AllocateCopyPool (StrSize (ValueStr), ValueStr);
      ASSERT (Str != NULL);
      Private->IfName = Str;
    }
  }
  //
  // To get interface name for the clear option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {
    Private->OpCode = IfConfig6OpClear;
    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");
    if (ValueStr != NULL) {
      Str             = AllocateCopyPool (StrSize (ValueStr), ValueStr);
      ASSERT (Str != NULL);
      Private->IfName = Str;
    }
  }
  //
  // To get interface name and corresponding Args for the set option.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {

    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
    if (ValueStr == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE), mHiiHandle);
      goto ON_EXIT;
    }
    //
    // To split the configuration into multi-section.
    //
    ArgList         = SplitStrToList (ValueStr, L' ');
    ASSERT (ArgList != NULL);

    Private->OpCode = IfConfig6OpSet;
    Private->IfName = ArgList->Arg;

    Private->VarArg = ArgList->Next;

    if (Private->IfName == NULL || Private->VarArg == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND), mHiiHandle);
      goto ON_EXIT;
    }
  }
  //
  // Main process of ifconfig6.
  //
  Status = IfConfig6 (Private);

ON_EXIT:

  ShellCommandLineFreeVarList (ParamPackage);
  HiiRemovePackages (mHiiHandle);
  if (Private != NULL)
    IfConfig6Cleanup (Private);

  return Status;
}

