The copyright change to ShellLibHiiGuid.h needs to be corrected.  It should be 
updated to 2011 - 2016, not replace 2011 with 2016.

If you fix that, then:
Reviewed-By: Jaben Carsey <jaben.car...@intel.com>

SideNote and I am not sure if this is reason enough to reject a patch.

This would be much cleaner to review/understand as a series of patches. My 
thought is this would be a clean order.
Patch 1 - add the GUID to the ShellLibHiiGuid.h and ShellPkg.DEC
Patch 2 - add the new NULL library instance
Patch 3 - update DSC file.

-Jaben

> -----Original Message-----
> From: Zhang, Lubo
> Sent: Tuesday, March 01, 2016 6:14 PM
> To: edk2-devel@lists.01.org
> Cc: Carsey, Jaben <jaben.car...@intel.com>; Wu, Jiaxin
> <jiaxin...@intel.com>; Ye, Ting <ting...@intel.com>; Fu, Siyuan
> <siyuan...@intel.com>
> Subject: [patch] ShellPkg: Merge Ping6 and Ifconfig6 tools to Shell command.
> Importance: High
> 
> According to the new Shell spec, we add Network2 profile and
> merge Ping6 and Ifconfig6 tools to Shell command.
> 
> Cc: Carsey Jaben <jaben.car...@intel.com>
> Cc: Wu Jiaxin <jiaxin...@intel.com>
> Cc: Ye Ting <ting...@intel.com>
> Cc: Fu Siyuan <siyuan...@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Zhang Lubo <lubo.zh...@intel.com>
> ---
>  ShellPkg/Include/Guid/ShellLibHiiGuid.h            |    9 +-
>  .../UefiShellNetwork2CommandsLib/Ifconfig6.c       | 1839
> ++++++++++++++++++++
>  .../Library/UefiShellNetwork2CommandsLib/Ping6.c   | 1247 +++++++++++++
>  .../UefiShellNetwork2CommandsLib.c                 |   91 +
>  .../UefiShellNetwork2CommandsLib.h                 |   72 +
>  .../UefiShellNetwork2CommandsLib.inf               |   63 +
>  .../UefiShellNetwork2CommandsLib.uni               |  151 ++
>  ShellPkg/ShellPkg.dec                              |    4 +-
>  ShellPkg/ShellPkg.dsc                              |    8 +-
>  9 files changed, 3479 insertions(+), 5 deletions(-)
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma
> ndsLib.c
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma
> ndsLib.h
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma
> ndsLib.inf
>  create mode 100644
> ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma
> ndsLib.uni
> 
> diff --git a/ShellPkg/Include/Guid/ShellLibHiiGuid.h
> b/ShellPkg/Include/Guid/ShellLibHiiGuid.h
> index 62c2e72..edbfd7c 100644
> --- a/ShellPkg/Include/Guid/ShellLibHiiGuid.h
> +++ b/ShellPkg/Include/Guid/ShellLibHiiGuid.h
> @@ -1,9 +1,9 @@
>  /** @file
>    GUIDs for HII package list installed by Shell libraries.
> 
> -  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 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
> 
> @@ -52,10 +52,16 @@
> 
>  #define SHELL_NETWORK1_HII_GUID \
>    { \
>      0xf3d301bb, 0xf4a5, 0x45a8, { 0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37,
> 0xae } \
>    }
> +
> +#define SHELL_NETWORK2_HII_GUID \
> +  { \
> +    0x174b2b5, 0xf505, 0x4b12, { 0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea,
> 0x37 } \
> +  }
> +
>  #define SHELL_TFTP_HII_GUID \
>    { \
>      0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e,
> 0xd4 } \
>    }
> 
> @@ -71,9 +77,10 @@ extern EFI_GUID gShellDriver1HiiGuid;
>  extern EFI_GUID gShellInstall1HiiGuid;
>  extern EFI_GUID gShellLevel1HiiGuid;
>  extern EFI_GUID gShellLevel2HiiGuid;
>  extern EFI_GUID gShellLevel3HiiGuid;
>  extern EFI_GUID gShellNetwork1HiiGuid;
> +extern EFI_GUID gShellNetwork2HiiGuid;
>  extern EFI_GUID gShellTftpHiiGuid;
>  extern EFI_GUID gShellBcfgHiiGuid;
> 
>  #endif
> diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
> new file mode 100644
> index 0000000..b1592e6
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
> @@ -0,0 +1,1839 @@
> +/** @file
> +  The implementation for Shell command IfConfig6.
> +
> +  Copyright (c) 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 "UefiShellNetwork2CommandsLib.h"
> +
> +typedef enum {
> +  IfConfig6OpList     = 1,
> +  IfConfig6OpSet      = 2,
> +  IfConfig6OpClear    = 3
> +};
> +
> +typedef enum {
> +  VarCheckReserved      = -1,
> +  VarCheckOk            = 0,
> +  VarCheckDuplicate,
> +  VarCheckConflict,
> +  VarCheckUnknown,
> +  VarCheckLackValue,
> +  VarCheckOutOfMem
> +} VAR_CHECK_CODE;
> +
> +typedef enum {
> +  FlagTypeSingle         = 0,
> +  FlagTypeNeedVar,
> +  FlagTypeNeedSet,
> +  FlagTypeSkipUnknown
> +} VAR_CHECK_FLAG_TYPE;
> +
> +#define MACADDRMAXSIZE    32
> +#define PREFIXMAXLEN      16
> +
> +typedef struct _IFCONFIG6_INTERFACE_CB {
> +  EFI_HANDLE                                  NicHandle;
> +  LIST_ENTRY                                  Link;
> +  EFI_IP6_CONFIG_PROTOCOL                     *IfCfg;
> +  EFI_IP6_CONFIG_INTERFACE_INFO               *IfInfo;
> +  EFI_IP6_CONFIG_INTERFACE_ID                 *IfId;
> +  EFI_IP6_CONFIG_POLICY                       Policy;
> +  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS    Xmits;
> +  UINT32                                      DnsCnt;
> +  EFI_IPv6_ADDRESS                            DnsAddr[1];
> +} IFCONFIG6_INTERFACE_CB;
> +
> +typedef struct _ARG_LIST ARG_LIST;
> +
> +struct _ARG_LIST {
> +  ARG_LIST    *Next;
> +  CHAR16      *Arg;
> +};
> +
> +typedef struct _IFCONFIG6_PRIVATE_DATA {
> +  EFI_HANDLE  ImageHandle;
> +  LIST_ENTRY  IfList;
> +
> +  UINT32      OpCode;
> +  CHAR16      *IfName;
> +  ARG_LIST    *VarArg;
> +} IFCONFIG6_PRIVATE_DATA;
> +
> +typedef struct _VAR_CHECK_ITEM{
> +  CHAR16                 *FlagStr;
> +  UINT32                 FlagID;
> +  UINT32                 ConflictMask;
> +  VAR_CHECK_FLAG_TYPE    FlagType;
> +} VAR_CHECK_ITEM;
> +
> +
> +SHELL_PARAM_ITEM    mIfConfig6CheckList[] = {
> +  {
> +    L"-b",
> +    TypeFlag
> +  },
> +  {
> +    L"-s",
> +    TypeMaxValue
> +  },
> +  {
> +    L"-l",
> +    TypeValue
> +  },
> +  {
> +    L"-r",
> +    TypeValue
> +  },
> +  {
> +    L"-?",
> +    TypeFlag
> +  },
> +  {
> +    NULL,
> +    TypeMax
> +  },
> +};
> +
> +VAR_CHECK_ITEM  mIfConfig6SetCheckList[] = {
> +  {
> +   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 *
> +IfConfig6SplitStrToList (
> +  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), gShellNetwork2HiiHandle,
> Node[Index]);
> +    if (Index + 1 < Size) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
> +    }
> +  }
> +
> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
> +}
> +
> +/**
> +  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), gShellNetwork2HiiHandle);
> +      }
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
> +
> +      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), gShellNetwork2HiiHandle, Ip-
> >Addr[Index]);
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip-
> >Addr[Index + 1]);
> +    }
> +
> +    if (Index + 2 < PREFIXMAXLEN) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
> +    }
> +  }
> +
> +  if (PrefixLen != NULL) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_PREFIX_LEN), gShellNetwork2HiiHandle, *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 Status;
> +  }
> +
> +  //
> +  // 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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 SHELL_SUCCESS  The IfConfig6 list processed successfully.
> +  @retval others         The IfConfig6 list process failed.
> +
> +**/
> +SHELL_STATUS
> +IfConfig6ShowInterfaceInfo (
> +  IN LIST_ENTRY    *IfList
> +  )
> +{
> +  LIST_ENTRY                *Entry;
> +  IFCONFIG6_INTERFACE_CB    *IfCb;
> +  UINTN                     Index;
> +
> +  Entry  = IfList->ForwardLink;
> +
> +  if (IsListEmpty (IfList)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
> +  }
> +
> +  //
> +  // 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), gShellNetwork2HiiHandle);
> +
> +    //
> +    // Print interface name.
> +    //
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_IF_NAME), gShellNetwork2HiiHandle, IfCb->IfInfo-
> >Name);
> +
> +    //
> +    // Print interface config policy.
> +    //
> +    if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_POLICY_AUTO), gShellNetwork2HiiHandle);
> +    } else {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_POLICY_MAN), gShellNetwork2HiiHandle);
> +    }
> +
> +    //
> +    // Print dad transmit.
> +    //
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_DAD_TRANSMITS), gShellNetwork2HiiHandle, IfCb-
> >Xmits);
> +
> +    //
> +    // Print interface id if has.
> +    //
> +    if (IfCb->IfId != NULL) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), gShellNetwork2HiiHandle);
> +
> +      IfConfig6PrintMacAddr (
> +        IfCb->IfId->Id,
> +        8
> +        );
> +    }
> +    //
> +    // Print mac address of the interface.
> +    //
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), gShellNetwork2HiiHandle);
> +
> +    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), gShellNetwork2HiiHandle);
> +
> +    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), gShellNetwork2HiiHandle);
> +    }
> +
> +    //
> +    // Print dns server addresses list of the interface if has.
> +    //
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), gShellNetwork2HiiHandle);
> +
> +    for (Index = 0; Index < IfCb->DnsCnt; Index++) {
> +      IfConfig6PrintIpAddr (
> +        &IfCb->DnsAddr[Index],
> +        NULL
> +        );
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
> +    }
> +
> +    //
> +    // Print route table of the interface if has.
> +    //
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_ROUTE_HEAD), gShellNetwork2HiiHandle);
> +
> +    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), gShellNetwork2HiiHandle);
> +
> +      IfConfig6PrintIpAddr (
> +        &IfCb->IfInfo->RouteTable[Index].Gateway,
> +        NULL
> +        );
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
> +    }
> +
> +    Entry = Entry->ForwardLink;
> +  }
> +
> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK),
> gShellNetwork2HiiHandle);
> +
> +  return SHELL_SUCCESS;
> +}
> +
> +/**
> +  The clean process of the IfConfig6 application.
> +
> +  @param[in]   IfList    The pointer of IfList(interface list).
> +
> +  @retval SHELL_SUCCESS  The IfConfig6 clean processed successfully.
> +  @retval others         The IfConfig6 clean process failed.
> +
> +**/
> +SHELL_STATUS
> +IfConfig6ClearInterfaceInfo (
> +  IN LIST_ENTRY    *IfList
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SHELL_STATUS              ShellStatus;
> +  LIST_ENTRY                *Entry;
> +  IFCONFIG6_INTERFACE_CB    *IfCb;
> +  EFI_IP6_CONFIG_POLICY     Policy;
> +
> +  Policy = Ip6ConfigPolicyAutomatic;
> +  Entry  = IfList->ForwardLink;
> +  Status = EFI_SUCCESS;
> +  ShellStatus = SHELL_SUCCESS;
> +
> +  if (IsListEmpty (IfList)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
> +  }
> +
> +  //
> +  // 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)) {
> +      ShellStatus = SHELL_ACCESS_DENIED;
> +      break;
> +    }
> +
> +    Entry  = Entry->ForwardLink;
> +  }
> +
> +  return ShellStatus;
> +}
> +
> +/**
> +  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 SHELL_SUCCESS  The IfConfig6 set processed successfully.
> +  @retval others         The IfConfig6 set process failed.
> +
> +**/
> +SHELL_STATUS
> +IfConfig6SetInterfaceInfo (
> +  IN LIST_ENTRY    *IfList,
> +  IN ARG_LIST      *VarArg
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  SHELL_STATUS                     ShellStatus;
> +  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), gShellNetwork2HiiHandle);
> +    return SHELL_INVALID_PARAMETER;
> +  }
> +  //
> +  // Make sure to set only one interface each time.
> +  //
> +  IfCb   = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
> +  Status = EFI_SUCCESS;
> +  ShellStatus = SHELL_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)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  IfConfig6ManualAddressNotify,
> +                  &IsAddressOk,
> +                  &MappedEvt
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Parse the setting variables.
> +  //
> +  while (VarArg != NULL) {
> +     //
> +     // Check invalid parameters (duplication & unknown & conflict).
> +     //
> +    CheckCode = IfConfig6RetriveCheckListByName(
> +                  mIfConfig6SetCheckList,
> +                  VarArg->Arg,
> +                  FALSE
> +                  );
> +
> +    if (VarCheckOk != CheckCode) {
> +      switch (CheckCode) {
> +        case VarCheckDuplicate:
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), gShellNetwork2HiiHandle,
> VarArg->Arg);
> +          break;
> +
> +        case VarCheckConflict:
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), gShellNetwork2HiiHandle,
> VarArg->Arg);
> +          break;
> +
> +        case VarCheckUnknown:
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), gShellNetwork2HiiHandle,
> 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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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) {
> +          ShellStatus = SHELL_INVALID_PARAMETER;
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle,
> L"host");
> +          continue;
> +        } else {
> +          ShellStatus = SHELL_ACCESS_DENIED;
> +          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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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), gShellNetwork2HiiHandle, Status);
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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), gShellNetwork2HiiHandle, Status);
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        goto ON_EXIT;
> +      }
> +
> +      IfInfo = AllocateZeroPool (DataSize);
> +
> +      if (IfInfo == NULL) {
> +        ShellStatus = SHELL_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), gShellNetwork2HiiHandle, Status);
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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), gShellNetwork2HiiHandle);
> +          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) {
> +          ShellStatus = SHELL_INVALID_PARAMETER;
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"gw");
> +          continue;
> +        } else {
> +          ShellStatus = SHELL_ACCESS_DENIED;
> +          goto ON_EXIT;
> +        }
> +      }
> +      //
> +      // Set static gateway ip6 address list.
> +      //
> +      Status = IfCb->IfCfg->SetData (
> +                              IfCb->IfCfg,
> +                              Ip6ConfigDataTypeGateway,
> +                              AddrSize,
> +                              CfgAddr
> +                              );
> +
> +      if (EFI_ERROR (Status)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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) {
> +          ShellStatus = SHELL_INVALID_PARAMETER;
> +          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"dns");
> +          continue;
> +        } else {
> +          ShellStatus = SHELL_ACCESS_DENIED;
> +          goto ON_EXIT;
> +        }
> +      }
> +      //
> +      // Set static DNS server ip6 address list.
> +      //
> +      Status = IfCb->IfCfg->SetData (
> +                              IfCb->IfCfg,
> +                              Ip6ConfigDataTypeDnsServer,
> +                              AddrSize,
> +                              CfgAddr
> +                              );
> +
> +      if (EFI_ERROR (Status)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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)) {
> +        ShellStatus = SHELL_INVALID_PARAMETER;
> +        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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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)) {
> +        ShellStatus = SHELL_ACCESS_DENIED;
> +        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 ShellStatus;
> +
> +}
> +
> +/**
> +  The IfConfig6 main process.
> +
> +  @param[in]   Private    The pointer of IFCONFIG6_PRIVATE_DATA.
> +
> +  @retval SHELL_SUCCESS   IfConfig6 processed successfully.
> +  @retval others          The IfConfig6 process failed.
> +
> +**/
> +SHELL_STATUS
> +IfConfig6 (
> +  IN IFCONFIG6_PRIVATE_DATA    *Private
> +  )
> +{
> +  EFI_STATUS    Status;
> +  SHELL_STATUS  ShellStatus;
> +
> +  ShellStatus = SHELL_SUCCESS;
> +
> +  //
> +  // Get configure information of all interfaces.
> +  //
> +  Status = IfConfig6GetInterfaceInfo (
> +             Private->ImageHandle,
> +             Private->IfName,
> +             &Private->IfList
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_NOT_FOUND;
> +    goto ON_EXIT;
> +  }
> +
> +  switch (Private->OpCode) {
> +  case IfConfig6OpList:
> +    ShellStatus = IfConfig6ShowInterfaceInfo (&Private->IfList);
> +    break;
> +
> +  case IfConfig6OpClear:
> +    ShellStatus = IfConfig6ClearInterfaceInfo (&Private->IfList);
> +    break;
> +
> +  case IfConfig6OpSet:
> +    ShellStatus = IfConfig6SetInterfaceInfo (&Private->IfList, 
> Private->VarArg);
> +    break;
> +
> +  default:
> +    ShellStatus = SHELL_UNSUPPORTED;
> +  }
> +
> +ON_EXIT:
> +
> +  return ShellStatus;
> +}
> +
> +/**
> +  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);
> +}
> +
> +/**
> +  Function for 'ifconfig6' command.
> +
> +  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
> +  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
> +
> +  @retval SHELL_SUCCESS   ifconfig6 command processed successfully.
> +  @retval others          The ifconfig6 command process failed.
> +
> +**/
> +SHELL_STATUS
> +EFIAPI
> +ShellCommandRunIfconfig6 (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                Status;
> +  SHELL_STATUS              ShellStatus;
> +  IFCONFIG6_PRIVATE_DATA    *Private;
> +  LIST_ENTRY                *ParamPackage;
> +  CONST CHAR16              *ValueStr;
> +  ARG_LIST                  *ArgList;
> +  CHAR16                    *ProblemParam;
> +  CHAR16                    *Str;
> +
> +  Private = NULL;
> +  Status = EFI_INVALID_PARAMETER;
> +  ShellStatus = SHELL_SUCCESS;
> +
> +  Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage,
> &ProblemParam, TRUE, FALSE);
> +  if (EFI_ERROR (Status)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_ERR_INVALID_COMMAND), gShellNetwork2HiiHandle,
> L"ifconfig6", ProblemParam);
> +    ShellStatus = SHELL_INVALID_PARAMETER;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // To handle no option.
> +  //
> +  if (!ShellCommandLineGetFlag (ParamPackage, L"-r") &&
> !ShellCommandLineGetFlag (ParamPackage, L"-s") &&
> +      !ShellCommandLineGetFlag (ParamPackage, L"-?") &&
> !ShellCommandLineGetFlag (ParamPackage, L"-l")) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_LACK_OPTION), gShellNetwork2HiiHandle);
> +    ShellStatus = SHELL_INVALID_PARAMETER;
> +    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"-r")) &&
> (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
> +      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) &&
> (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
> +      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) &&
> (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
> +      ((ShellCommandLineGetFlag (ParamPackage, L"-l")) &&
> (ShellCommandLineGetFlag (ParamPackage, L"-?")))) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_IFCONFIG6_CONFLICT_OPTIONS), gShellNetwork2HiiHandle);
> +    ShellStatus = SHELL_INVALID_PARAMETER;
> +    goto ON_EXIT;
> +  }
> +
> +  Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));
> +
> +  if (Private == NULL) {
> +    ShellStatus = SHELL_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), gShellNetwork2HiiHandle);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +    //
> +    // To split the configuration into multi-section.
> +    //
> +    ArgList         = IfConfig6SplitStrToList (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), gShellNetwork2HiiHandle);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +  }
> +  //
> +  // Main process of ifconfig6.
> +  //
> +  ShellStatus = IfConfig6 (Private);
> +
> +ON_EXIT:
> +
> +  ShellCommandLineFreeVarList (ParamPackage);
> +  if (Private != NULL) {
> +    IfConfig6Cleanup (Private);
> +  }
> +  return ShellStatus;
> +
> +}
> +
> diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
> new file mode 100644
> index 0000000..af7d08f
> --- /dev/null
> +++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
> @@ -0,0 +1,1247 @@
> +/** @file
> +  The implementation for Ping6 application.
> +
> +  Copyright (c) 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 "UefiShellNetwork2CommandsLib.h"
> +
> +#define PING6_DEFAULT_TIMEOUT      5000
> +#define PING6_MAX_SEND_NUMBER      10000
> +#define PING6_MAX_BUFFER_SIZE      32768
> +#define PING6_ONE_SECOND           10000000
> +
> +//
> +// A similar amount of time that passes in femtoseconds
> +// for each increment of TimerValue. It is for NT32 only.
> +//
> +#define NTTIMERPERIOD    358049
> +
> +#pragma pack(1)
> +
> +typedef struct _ICMP6_ECHO_REQUEST_REPLY {
> +  UINT8                       Type;
> +  UINT8                       Code;
> +  UINT16                      Checksum;
> +  UINT16                      Identifier;
> +  UINT16                      SequenceNum;
> +  UINT64                      TimeStamp;
> +  UINT8                       Data[1];
> +} ICMP6_ECHO_REQUEST_REPLY;
> +
> +#pragma pack()
> +
> +typedef struct _PING6_ICMP6_TX_INFO {
> +  LIST_ENTRY                  Link;
> +  UINT16                      SequenceNum;
> +  UINT64                      TimeStamp;
> +  EFI_IP6_COMPLETION_TOKEN    *Token;
> +} PING6_ICMP6_TX_INFO;
> +
> +typedef struct _PING6_PRIVATE_DATA {
> +  EFI_HANDLE                  ImageHandle;
> +  EFI_HANDLE                  NicHandle;
> +  EFI_HANDLE                  Ip6ChildHandle;
> +  EFI_IP6_PROTOCOL            *Ip6;
> +  EFI_EVENT                   Timer;
> +
> +  EFI_STATUS                  Status;
> +  LIST_ENTRY                  TxList;
> +  EFI_IP6_COMPLETION_TOKEN    RxToken;
> +  UINT16                      RxCount;
> +  UINT16                      TxCount;
> +  UINT64                      RttSum;
> +  UINT64                      RttMin;
> +  UINT64                      RttMax;
> +  UINT32                      SequenceNum;
> +
> +  EFI_IPv6_ADDRESS            SrcAddress;
> +  EFI_IPv6_ADDRESS            DstAddress;
> +  UINT32                      SendNum;
> +  UINT32                      BufferSize;
> +} PING6_PRIVATE_DATA;
> +
> +
> +SHELL_PARAM_ITEM    Ping6ParamList[] = {
> +  {
> +    L"-l",
> +    TypeValue
> +  },
> +  {
> +    L"-n",
> +    TypeValue
> +  },
> +  {
> +    L"-s",
> +    TypeValue
> +  },
> +  {
> +    L"-?",
> +    TypeFlag
> +  },
> +  {
> +    NULL,
> +    TypeMax
> +  },
> +};
> +
> +//
> +// Global Variables in Ping6 application.
> +//
> +CONST CHAR16            *mIp6DstString;
> +CONST CHAR16            *mIp6SrcString;
> +UINT64                  mFrequency = 0;
> +UINT64                  mIp6CurrentTick = 0;
> +EFI_CPU_ARCH_PROTOCOL   *Cpu = NULL;
> +
> +
> +
> +/**
> +  Reads and returns the current value of the Time.
> +
> +  @return The current tick value.
> +
> +**/
> +UINT64
> +Ping6ReadTime ()
> +{
> +  UINT64                 TimerPeriod;
> +  EFI_STATUS             Status;
> +
> +  ASSERT (Cpu != NULL);
> +
> +  Status = Cpu->GetTimerValue (Cpu, 0, &mIp6CurrentTick, &TimerPeriod);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // The WinntGetTimerValue will return EFI_UNSUPPORTED. Set the
> +    // TimerPeriod by ourselves.
> +    //
> +    mIp6CurrentTick += 1000000;
> +  }
> +
> +  return mIp6CurrentTick;
> +}
> +
> +/**
> +  Get and calculate the frequency in tick/ms.
> +  The result is saved in the globle variable mFrequency
> +
> +  @retval EFI_SUCCESS    Calculated the frequency successfully.
> +  @retval Others         Failed to calculate the frequency.
> +
> +**/
> +EFI_STATUS
> +Ping6GetFrequency (
> +  VOID
> +  )
> +{
> +  EFI_STATUS               Status;
> +  UINT64                   CurrentTick;
> +  UINT64                   TimerPeriod;
> +
> +  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)
> &Cpu);
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTick, &TimerPeriod);
> +
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // For NT32 Simulator only. 358049 is a similar value to keep timer
> granularity.
> +    // Set the timer period by ourselves.
> +    //
> +    TimerPeriod = (UINT64) NTTIMERPERIOD;
> +  }
> +  //
> +  // The timer period is in femtosecond (1 femtosecond is 1e-15 second).
> +  // So 1e+12 is divided by timer period to produce the freq in tick/ms.
> +  //
> +  mFrequency = DivU64x64Remainder (1000000000000ULL, TimerPeriod,
> NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get and calculate the duration in ms.
> +
> +  @param[in]  Begin    The start point of time.
> +  @param[in]  End      The end point of time.
> +
> +  @return The duration in ms.
> +
> +**/
> +UINT64
> +Ping6CalculateTick (
> +  IN UINT64    Begin,
> +  IN UINT64    End
> +  )
> +{
> +  ASSERT (End > Begin);
> +  return DivU64x64Remainder (End - Begin, mFrequency, NULL);
> +}
> +
> +/**
> +  Destroy IPING6_ICMP6_TX_INFO, and recollect the memory.
> +
> +  @param[in]    TxInfo    The pointer to PING6_ICMP6_TX_INFO.
> +
> +**/
> +VOID
> +Ping6DestroyTxInfo (
> +  IN PING6_ICMP6_TX_INFO    *TxInfo
> +  )
> +{
> +  EFI_IP6_TRANSMIT_DATA    *TxData;
> +  EFI_IP6_FRAGMENT_DATA    *FragData;
> +  UINTN                    Index;
> +
> +  ASSERT (TxInfo != NULL);
> +
> +  if (TxInfo->Token != NULL) {
> +
> +    if (TxInfo->Token->Event != NULL) {
> +      gBS->CloseEvent (TxInfo->Token->Event);
> +    }
> +
> +    TxData = TxInfo->Token->Packet.TxData;
> +    if (TxData != NULL) {
> +
> +      if (TxData->OverrideData != NULL) {
> +        FreePool (TxData->OverrideData);
> +      }
> +
> +      if (TxData->ExtHdrs != NULL) {
> +        FreePool (TxData->ExtHdrs);
> +      }
> +
> +      for (Index = 0; Index < TxData->FragmentCount; Index++) {
> +        FragData = TxData->FragmentTable[Index].FragmentBuffer;
> +        if (FragData != NULL) {
> +          FreePool (FragData);
> +        }
> +      }
> +    }
> +
> +    FreePool (TxInfo->Token);
> +  }
> +
> +  FreePool (TxInfo);
> +}
> +
> +/**
> +  Match the request, and reply with SequenceNum/TimeStamp.
> +
> +  @param[in]    Private    The pointer to PING6_PRIVATE_DATA.
> +  @param[in]    Packet     The pointer to ICMP6_ECHO_REQUEST_REPLY.
> +
> +  @retval EFI_SUCCESS      The match is successful.
> +  @retval EFI_NOT_FOUND    The reply can't be matched with any request.
> +
> +**/
> +EFI_STATUS
> +Ping6OnMatchEchoReply (
> +  IN PING6_PRIVATE_DATA          *Private,
> +  IN ICMP6_ECHO_REQUEST_REPLY    *Packet
> +  )
> +{
> +  PING6_ICMP6_TX_INFO    *TxInfo;
> +  LIST_ENTRY             *Entry;
> +  LIST_ENTRY             *NextEntry;
> +
> +  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
> +    TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
> +
> +    if ((TxInfo->SequenceNum == Packet->SequenceNum) && (TxInfo-
> >TimeStamp == Packet->TimeStamp)) {
> +      Private->RxCount++;
> +      RemoveEntryList (&TxInfo->Link);
> +      Ping6DestroyTxInfo (TxInfo);
> +      return EFI_SUCCESS;
> +    }
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  The original intention is to send a request.
> +  Currently, the application retransmits an icmp6 echo request packet
> +  per second in sendnumber times that is specified by the user.
> +  Because nothing can be done here, all things move to the timer rountine.
> +
> +  @param[in]    Event      A EFI_EVENT type event.
> +  @param[in]    Context    The pointer to Context.
> +
> +**/
> +VOID
> +EFIAPI
> +Ping6OnEchoRequestSent6 (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +}
> +
> +/**
> +  receive reply, match and print reply infomation.
> +
> +  @param[in]    Event      A EFI_EVENT type event.
> +  @param[in]    Context    The pointer to context.
> +
> +**/
> +VOID
> +EFIAPI
> +Ping6OnEchoReplyReceived6 (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  PING6_PRIVATE_DATA          *Private;
> +  EFI_IP6_COMPLETION_TOKEN    *RxToken;
> +  EFI_IP6_RECEIVE_DATA        *RxData;
> +  ICMP6_ECHO_REQUEST_REPLY    *Reply;
> +  UINT32                      PayLoad;
> +  UINT64                      Rtt;
> +  CHAR8                       Near;
> +
> +  Private = (PING6_PRIVATE_DATA *) Context;
> +
> +  if (Private->Status == EFI_ABORTED) {
> +    return;
> +  }
> +
> +  RxToken = &Private->RxToken;
> +  RxData  = RxToken->Packet.RxData;
> +  Reply   = RxData->FragmentTable[0].FragmentBuffer;
> +  PayLoad = RxData->DataLength;
> +
> +  if (RxData->Header->NextHeader != IP6_ICMP) {
> +    goto ON_EXIT;
> +  }
> +
> +  if (!IP6_IS_MULTICAST (&Private->DstAddress) &&
> +      !EFI_IP6_EQUAL (&RxData->Header->SourceAddress, &Private-
> >DstAddress)) {
> +    goto ON_EXIT;
> +  }
> +
> +  if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) {
> +    goto ON_EXIT;
> +  }
> +
> +  if (PayLoad != Private->BufferSize) {
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Check whether the reply matches the sent request before.
> +  //
> +  Status = Ping6OnMatchEchoReply (Private, Reply);
> +  if (EFI_ERROR(Status)) {
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Display statistics on this icmp6 echo reply packet.
> +  //
> +  Rtt  = Ping6CalculateTick (Reply->TimeStamp, Ping6ReadTime ());
> +  if (Rtt != 0) {
> +    Near = (CHAR8) '=';
> +  } else {
> +    Near = (CHAR8) '<';
> +  }
> +
> +  Private->RttSum += Rtt;
> +  Private->RttMin  = Private->RttMin > Rtt ? Rtt : Private->RttMin;
> +  Private->RttMax  = Private->RttMax < Rtt ? Rtt : Private->RttMax;
> +
> +  ShellPrintHiiEx (
> +    -1,
> +    -1,
> +    NULL,
> +    STRING_TOKEN (STR_PING6_REPLY_INFO),
> +    gShellNetwork2HiiHandle,
> +    PayLoad,
> +    mIp6DstString,
> +    Reply->SequenceNum,
> +    RxData->Header->HopLimit,
> +    Near,
> +    Rtt
> +    );
> +
> +ON_EXIT:
> +
> +  if (Private->RxCount < Private->SendNum) {
> +    //
> +    // Continue to receive icmp6 echo reply packets.
> +    //
> +    RxToken->Status = EFI_ABORTED;
> +
> +    Status = Private->Ip6->Receive (Private->Ip6, RxToken);
> +
> +    if (EFI_ERROR (Status)) {
> +      Private->Status = EFI_ABORTED;
> +    }
> +  } else {
> +    //
> +    // All reply have already been received from the dest host.
> +    //
> +    Private->Status = EFI_SUCCESS;
> +  }
> +  //
> +  // Singal to recycle the each rxdata here, not at the end of process.
> +  //
> +  gBS->SignalEvent (RxData->RecycleSignal);
> +}
> +
> +/**
> +  Initial EFI_IP6_COMPLETION_TOKEN.
> +
> +  @param[in]    Private        The pointer of PING6_PRIVATE_DATA.
> +  @param[in]    TimeStamp      The TimeStamp of request.
> +  @param[in]    SequenceNum    The SequenceNum of request.
> +
> +  @return The pointer of EFI_IP6_COMPLETION_TOKEN.
> +
> +**/
> +EFI_IP6_COMPLETION_TOKEN *
> +Ping6GenerateToken (
> +  IN PING6_PRIVATE_DATA    *Private,
> +  IN UINT64                TimeStamp,
> +  IN UINT16                SequenceNum
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_IP6_COMPLETION_TOKEN    *Token;
> +  EFI_IP6_TRANSMIT_DATA       *TxData;
> +  ICMP6_ECHO_REQUEST_REPLY    *Request;
> +
> +  Request = AllocateZeroPool (Private->BufferSize);
> +
> +  if (Request == NULL) {
> +    return NULL;
> +  }
> +  //
> +  // Assembly icmp6 echo request packet.
> +  //
> +  Request->Type        = ICMP_V6_ECHO_REQUEST;
> +  Request->Code        = 0;
> +  Request->SequenceNum = SequenceNum;
> +  Request->TimeStamp   = TimeStamp;
> +  Request->Identifier  = 0;
> +  //
> +  // Leave check sum to ip6 layer, since it has no idea of source address
> +  // selection.
> +  //
> +  Request->Checksum    = 0;
> +
> +  TxData = AllocateZeroPool (sizeof (EFI_IP6_TRANSMIT_DATA));
> +
> +  if (TxData == NULL) {
> +    FreePool (Request);
> +    return NULL;
> +  }
> +  //
> +  // Assembly ipv6 token for transmit.
> +  //
> +  TxData->OverrideData       = 0;
> +  TxData->ExtHdrsLength      = 0;
> +  TxData->ExtHdrs            = NULL;
> +  TxData->DataLength         = Private->BufferSize;
> +  TxData->FragmentCount      = 1;
> +  TxData->FragmentTable[0].FragmentBuffer = (VOID *) Request;
> +  TxData->FragmentTable[0].FragmentLength = Private->BufferSize;
> +
> +  Token = AllocateZeroPool (sizeof (EFI_IP6_COMPLETION_TOKEN));
> +
> +  if (Token == NULL) {
> +    FreePool (Request);
> +    FreePool (TxData);
> +    return NULL;
> +  }
> +
> +  Token->Status         = EFI_ABORTED;
> +  Token->Packet.TxData  = TxData;
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  Ping6OnEchoRequestSent6,
> +                  Private,
> +                  &Token->Event
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    FreePool (Request);
> +    FreePool (TxData);
> +    FreePool (Token);
> +    return NULL;
> +  }
> +
> +  return Token;
> +}
> +
> +/**
> +  Transmit the EFI_IP6_COMPLETION_TOKEN.
> +
> +  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.
> +
> +  @retval EFI_SUCCESS             Transmitted successfully.
> +  @retval EFI_OUT_OF_RESOURCES    No memory is available on the platform.
> +  @retval others                  Transmitted unsuccessfully.
> +
> +**/
> +EFI_STATUS
> +Ping6SendEchoRequest (
> +  IN PING6_PRIVATE_DATA    *Private
> +  )
> +{
> +  EFI_STATUS             Status;
> +  PING6_ICMP6_TX_INFO    *TxInfo;
> +
> +  TxInfo = AllocateZeroPool (sizeof (PING6_ICMP6_TX_INFO));
> +
> +  if (TxInfo == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  TxInfo->TimeStamp   = Ping6ReadTime ();
> +  TxInfo->SequenceNum = (UINT16) (Private->TxCount + 1);
> +
> +  TxInfo->Token       = Ping6GenerateToken (
> +                          Private,
> +                          TxInfo->TimeStamp,
> +                          TxInfo->SequenceNum
> +                          );
> +
> +  if (TxInfo->Token == NULL) {
> +    Ping6DestroyTxInfo (TxInfo);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = Private->Ip6->Transmit (Private->Ip6, TxInfo->Token);
> +
> +  if (EFI_ERROR (Status)) {
> +    Ping6DestroyTxInfo (TxInfo);
> +    return Status;
> +  }
> +
> +  InsertTailList (&Private->TxList, &TxInfo->Link);
> +  Private->TxCount++;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Place a completion token into the receive packet queue to receive the
> echo reply.
> +
> +  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.
> +
> +  @retval EFI_SUCCESS      Put the token into the receive packet queue
> successfully.
> +  @retval others           Put the token into the receive packet queue
> unsuccessfully.
> +
> +**/
> +EFI_STATUS
> +Ping6OnReceiveEchoReply (
> +  IN PING6_PRIVATE_DATA    *Private
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN));
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  Ping6OnEchoReplyReceived6,
> +                  Private,
> +                  &Private->RxToken.Event
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Private->RxToken.Status = EFI_NOT_READY;
> +
> +  return Private->Ip6->Receive (Private->Ip6, &Private->RxToken);
> +}
> +
> +/**
> +  Remove the timeout request from the list.
> +
> +  @param[in]    Event    A EFI_EVENT type event.
> +  @param[in]    Context  The pointer to Context.
> +
> +**/
> +VOID
> +EFIAPI
> +Ping6OnTimerRoutine6 (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS             Status;
> +  PING6_PRIVATE_DATA     *Private;
> +  PING6_ICMP6_TX_INFO    *TxInfo;
> +  LIST_ENTRY             *Entry;
> +  LIST_ENTRY             *NextEntry;
> +  UINT64                 Time;
> +
> +  Private = (PING6_PRIVATE_DATA *) Context;
> +
> +  //
> +  // Retransmit icmp6 echo request packets per second in sendnumber
> times.
> +  //
> +  if (Private->TxCount < Private->SendNum) {
> +
> +    Status = Ping6SendEchoRequest (Private);
> +    if (Private->TxCount != 0){
> +      if (EFI_ERROR (Status)) {
> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_SEND_REQUEST), gShellNetwork2HiiHandle, Private->TxCount +
> 1);
> +      }
> +    }
> +  }
> +  //
> +  // Check whether any icmp6 echo request in the list timeout.
> +  //
> +  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
> +    TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
> +    Time   = Ping6CalculateTick (TxInfo->TimeStamp, Ping6ReadTime ());
> +
> +    //
> +    // Remove the timeout echo request from txlist.
> +    //
> +    if (Time > PING6_DEFAULT_TIMEOUT) {
> +
> +      if (EFI_ERROR (TxInfo->Token->Status)) {
> +        Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
> +      }
> +      //
> +      // Remove the timeout icmp6 echo request from list.
> +      //
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_TIMEOUT),
> gShellNetwork2HiiHandle, TxInfo->SequenceNum);
> +
> +      RemoveEntryList (&TxInfo->Link);
> +      Ping6DestroyTxInfo (TxInfo);
> +
> +      if (IsListEmpty (&Private->TxList) && (Private->TxCount == Private-
> >SendNum)) {
> +        //
> +        // All the left icmp6 echo request in the list timeout.
> +        //
> +        Private->Status = EFI_TIMEOUT;
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  Create a valid IP6 instance.
> +
> +  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.
> +
> +  @retval EFI_SUCCESS              Create a valid IP6 instance successfully.
> +  @retval EFI_ABORTED              Locate handle with ip6 service binding
> protocol unsuccessfully.
> +  @retval EFI_INVALID_PARAMETER    The source address is unspecified
> when the destination address is a link -ocal address.
> +  @retval EFI_OUT_OF_RESOURCES     No memory is available on the
> platform.
> +  @retval EFI_NOT_FOUND            The source address is not found.
> +**/
> +EFI_STATUS
> +Ping6CreateIpInstance (
> +  IN  PING6_PRIVATE_DATA    *Private
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  UINTN                            HandleIndex;
> +  UINTN                            HandleNum;
> +  EFI_HANDLE                       *HandleBuffer;
> +  EFI_SERVICE_BINDING_PROTOCOL     *Ip6Sb;
> +  EFI_IP6_CONFIG_PROTOCOL          *Ip6Cfg;
> +  EFI_IP6_CONFIG_DATA              Ip6Config;
> +  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;
> +  UINTN                            IfInfoSize;
> +  EFI_IPv6_ADDRESS                 *Addr;
> +  UINTN                            AddrIndex;
> +
> +  HandleBuffer = NULL;
> +  Ip6Sb        = NULL;
> +  IfInfo       = NULL;
> +  IfInfoSize   = 0;
> +
> +  //
> +  // 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;
> +  }
> +  //
> +  // Source address is required when pinging a link-local address on multi-
> +  // interfaces host.
> +  //
> +  if (NetIp6IsLinkLocalAddr (&Private->DstAddress) &&
> +      NetIp6IsUnspecifiedAddr (&Private->SrcAddress) &&
> +      (HandleNum > 1)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_INVALID_SOURCE), gShellNetwork2HiiHandle);
> +    Status = EFI_INVALID_PARAMETER;
> +    goto ON_ERROR;
> +  }
> +  //
> +  // For each ip6 protocol, check interface addresses list.
> +  //
> +  for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
> +
> +    Ip6Sb      = NULL;
> +    IfInfo     = NULL;
> +    IfInfoSize = 0;
> +
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[HandleIndex],
> +                    &gEfiIp6ServiceBindingProtocolGuid,
> +                    (VOID **) &Ip6Sb
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      goto ON_ERROR;
> +    }
> +
> +    if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) {
> +      //
> +      // No need to match interface address.
> +      //
> +      break;
> +    } else {
> +      //
> +      // Ip6config protocol and ip6 service binding protocol are installed
> +      // on the same handle.
> +      //
> +      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,
> +                         &IfInfoSize,
> +                         NULL
> +                         );
> +
> +      if (Status != EFI_BUFFER_TOO_SMALL) {
> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
> +        goto ON_ERROR;
> +      }
> +
> +      IfInfo = AllocateZeroPool (IfInfoSize);
> +
> +      if (IfInfo == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto ON_ERROR;
> +      }
> +      //
> +      // Get the interface info.
> +      //
> +      Status = Ip6Cfg->GetData (
> +                         Ip6Cfg,
> +                         Ip6ConfigDataTypeInterfaceInfo,
> +                         &IfInfoSize,
> +                         IfInfo
> +                         );
> +
> +      if (EFI_ERROR (Status)) {
> +        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
> +        goto ON_ERROR;
> +      }
> +      //
> +      // Check whether the source address is one of the interface addresses.
> +      //
> +      for (AddrIndex = 0; AddrIndex < IfInfo->AddressInfoCount; AddrIndex++)
> {
> +
> +        Addr = &(IfInfo->AddressInfo[AddrIndex].Address);
> +        if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) {
> +          //
> +          // Match a certain interface address.
> +          //
> +          break;
> +        }
> +      }
> +
> +      if (AddrIndex < IfInfo->AddressInfoCount) {
> +        //
> +        // Found a nic handle with right interface address.
> +        //
> +        break;
> +      }
> +    }
> +
> +    FreePool (IfInfo);
> +    IfInfo = NULL;
> +  }
> +  //
> +  // No exact interface address matched.
> +  //
> +
> +  if (HandleIndex == HandleNum) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_SOURCE_NOT_FOUND), gShellNetwork2HiiHandle,
> mIp6SrcString);
> +    Status = EFI_NOT_FOUND;
> +    goto ON_ERROR;
> +  }
> +
> +  Private->NicHandle = HandleBuffer[HandleIndex];
> +
> +  ASSERT (Ip6Sb != NULL);
> +  Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle);
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ON_ERROR;
> +  }
> +
> +  Status = gBS->OpenProtocol (
> +                  Private->Ip6ChildHandle,
> +                  &gEfiIp6ProtocolGuid,
> +                  (VOID **) &Private->Ip6,
> +                  Private->ImageHandle,
> +                  Private->Ip6ChildHandle,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ON_ERROR;
> +  }
> +
> +  ZeroMem (&Ip6Config, sizeof (EFI_IP6_CONFIG_DATA));
> +
> +  //
> +  // Configure the ip6 instance for icmp6 packet exchange.
> +  //
> +  Ip6Config.DefaultProtocol   = 58;
> +  Ip6Config.AcceptAnyProtocol = FALSE;
> +  Ip6Config.AcceptIcmpErrors  = TRUE;
> +  Ip6Config.AcceptPromiscuous = FALSE;
> +  Ip6Config.TrafficClass      = 0;
> +  Ip6Config.HopLimit          = 128;
> +  Ip6Config.FlowLabel         = 0;
> +  Ip6Config.ReceiveTimeout    = 0;
> +  Ip6Config.TransmitTimeout   = 0;
> +
> +  IP6_COPY_ADDRESS (&Ip6Config.StationAddress, &Private->SrcAddress);
> +
> +  IP6_COPY_ADDRESS (&Ip6Config.DestinationAddress, &Private-
> >DstAddress);
> +
> +  Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config);
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_CONFIG),
> gShellNetwork2HiiHandle, Status);
> +    goto ON_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +ON_ERROR:
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +
> +  if (IfInfo != NULL) {
> +    FreePool (IfInfo);
> +  }
> +
> +  if ((Ip6Sb != NULL) && (Private->Ip6ChildHandle != NULL)) {
> +    Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Destroy the IP6 instance.
> +
> +  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.
> +
> +**/
> +VOID
> +Ping6DestroyIpInstance (
> +  IN PING6_PRIVATE_DATA    *Private
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_SERVICE_BINDING_PROTOCOL    *Ip6Sb;
> +
> +  gBS->CloseProtocol (
> +         Private->Ip6ChildHandle,
> +         &gEfiIp6ProtocolGuid,
> +         Private->ImageHandle,
> +         Private->Ip6ChildHandle
> +         );
> +
> +  Status = gBS->HandleProtocol (
> +                  Private->NicHandle,
> +                  &gEfiIp6ServiceBindingProtocolGuid,
> +                  (VOID **) &Ip6Sb
> +                  );
> +
> +  if (!EFI_ERROR(Status)) {
> +    Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
> +  }
> +}
> +
> +/**
> +  The Ping6 Process.
> +
> +  @param[in]   ImageHandle    The firmware allocated handle for the UEFI
> image.
> +  @param[in]   SendNumber     The send request count.
> +  @param[in]   BufferSize     The send buffer size.
> +  @param[in]   SrcAddress     The source IPv6 address.
> +  @param[in]   DstAddress     The destination IPv6 address.
> +
> +  @retval SHELL_SUCCESS    The ping6 processed successfullly.
> +  @retval others           The ping6 processed unsuccessfully.
> +
> +**/
> +SHELL_STATUS
> +ShellPing6 (
> +  IN EFI_HANDLE          ImageHandle,
> +  IN UINT32              SendNumber,
> +  IN UINT32              BufferSize,
> +  IN EFI_IPv6_ADDRESS    *SrcAddress,
> +  IN EFI_IPv6_ADDRESS    *DstAddress
> +  )
> +{
> +  EFI_STATUS             Status;
> +  EFI_INPUT_KEY          Key;
> +  PING6_PRIVATE_DATA     *Private;
> +  PING6_ICMP6_TX_INFO    *TxInfo;
> +  LIST_ENTRY             *Entry;
> +  LIST_ENTRY             *NextEntry;
> +  SHELL_STATUS           ShellStatus;
> +
> +  ShellStatus = SHELL_SUCCESS;
> +  Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA));
> +
> +  ASSERT (Private != NULL);
> +
> +  Private->ImageHandle = ImageHandle;
> +  Private->SendNum     = SendNumber;
> +  Private->BufferSize  = BufferSize;
> +  Private->RttMin      = ~((UINT64 )(0x0));
> +  Private->Status      = EFI_NOT_READY;
> +
> +  InitializeListHead (&Private->TxList);
> +
> +  IP6_COPY_ADDRESS (&Private->SrcAddress, SrcAddress);
> +  IP6_COPY_ADDRESS (&Private->DstAddress, DstAddress);
> +
> +  //
> +  // Open and configure a ip6 instance for ping6.
> +  //
> +  Status = Ping6CreateIpInstance (Private);
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Print the command line itself.
> +  //
> +  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START),
> gShellNetwork2HiiHandle, mIp6DstString, Private->BufferSize);
> +  //
> +  // Create a ipv6 token to receive the first icmp6 echo reply packet.
> +  //
> +  Status = Ping6OnReceiveEchoReply (Private);
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Create and start timer to send icmp6 echo request packet per second.
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  Ping6OnTimerRoutine6,
> +                  Private,
> +                  &Private->Timer
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Create a ipv6 token to send the first icmp6 echo request packet.
> +  //
> +  Status = Ping6SendEchoRequest (Private);
> +  //
> +  // EFI_NOT_READY for IPsec is enable and IKE is not established.
> +  //
> +  if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    if(Status == EFI_NOT_FOUND) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_NOSOURCE_INDOMAIN), gShellNetwork2HiiHandle,
> mIp6DstString);
> +    }
> +
> +    goto ON_EXIT;
> +  }
> +
> +  Status = gBS->SetTimer (
> +                  Private->Timer,
> +                  TimerPeriodic,
> +                  PING6_ONE_SECOND
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Control the ping6 process by two factors:
> +  // 1. Hot key
> +  // 2. Private->Status
> +  //   2.1. success means all icmp6 echo request packets get reply packets.
> +  //   2.2. timeout means the last icmp6 echo reply request timeout to get
> reply.
> +  //   2.3. noready means ping6 process is on-the-go.
> +  //
> +  while (Private->Status == EFI_NOT_READY) {
> +    Private->Ip6->Poll (Private->Ip6);
> +
> +    //
> +    // Terminate the ping6 process by 'esc' or 'ctl-c'.
> +    //
> +    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
> +
> +    if (!EFI_ERROR(Status)) {
> +      if ((Key.UnicodeChar == 0x1b) || (Key.UnicodeChar == 0x03) ||
> +         ((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC))) {
> +        goto ON_STAT;
> +      }
> +    }
> +  }
> +
> +ON_STAT:
> +  //
> +  // Display the statistics in all.
> +  //
> +  gBS->SetTimer (Private->Timer, TimerCancel, 0);
> +
> +  if (Private->TxCount != 0) {
> +    ShellPrintHiiEx (
> +      -1,
> +      -1,
> +      NULL,
> +      STRING_TOKEN (STR_PING6_STAT),
> +      gShellNetwork2HiiHandle,
> +      Private->TxCount,
> +      Private->RxCount,
> +      (100 * (Private->TxCount - Private->RxCount)) / Private->TxCount,
> +      Private->RttSum
> +      );
> +  }
> +
> +  if (Private->RxCount != 0) {
> +    ShellPrintHiiEx (
> +      -1,
> +      -1,
> +      NULL,
> +      STRING_TOKEN (STR_PING6_RTT),
> +      gShellNetwork2HiiHandle,
> +      Private->RttMin,
> +      Private->RttMax,
> +      DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL)
> +      );
> +  }
> +
> +ON_EXIT:
> +
> +  if (Private != NULL) {
> +    Private->Status = EFI_ABORTED;
> +
> +    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
> +      TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
> +
> +      Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
> +
> +      RemoveEntryList (&TxInfo->Link);
> +      Ping6DestroyTxInfo (TxInfo);
> +    }
> +
> +    if (Private->Timer != NULL) {
> +      gBS->CloseEvent (Private->Timer);
> +    }
> +
> +    if (Private->Ip6 != NULL) {
> +      Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken);
> +    }
> +
> +    if (Private->RxToken.Event != NULL) {
> +      gBS->CloseEvent (Private->RxToken.Event);
> +    }
> +
> +    if (Private->Ip6ChildHandle != NULL) {
> +      Ping6DestroyIpInstance (Private);
> +    }
> +
> +    FreePool (Private);
> +  }
> +
> +  return ShellStatus;
> +}
> +
> +/**
> +  Function for 'ping6' command.
> +
> +  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
> +  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
> +
> +  @retval SHELL_SUCCESS  The ping6 processed successfullly.
> +  @retval others         The ping6 processed unsuccessfully.
> +
> +**/
> +SHELL_STATUS
> +EFIAPI
> +ShellCommandRunPing6 (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS          Status;
> +  SHELL_STATUS        ShellStatus;
> +  EFI_IPv6_ADDRESS    DstAddress;
> +  EFI_IPv6_ADDRESS    SrcAddress;
> +  UINT64              BufferSize;
> +  UINTN               SendNumber;
> +  LIST_ENTRY          *ParamPackage;
> +  CONST CHAR16        *ValueStr;
> +  CONST CHAR16        *ValueStrPtr;
> +  UINTN               NonOptionCount;
> +  CHAR16              *ProblemParam;
> +
> +  ProblemParam = NULL;
> +  ShellStatus = SHELL_SUCCESS;
> +
> +  Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage,
> &ProblemParam, TRUE, FALSE);
> +  if (EFI_ERROR(Status)) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT),
> gShellNetwork2HiiHandle);
> +    ShellStatus = SHELL_INVALID_PARAMETER;
> +    goto ON_EXIT;
> +  }
> +
> +  SendNumber = 10;
> +  BufferSize = 16;
> +
> +  //
> +  // Parse the paramter of count number.
> +  //
> +  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-n");
> +  ValueStrPtr = ValueStr;
> +  if (ValueStr != NULL) {
> +    SendNumber = ShellStrToUintn (ValueStrPtr);
> +
> +    //
> +    // ShellStrToUintn will return 0 when input is 0 or an invalid input 
> string.
> +    //
> +    if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_INVALID_SEND_NUMBER), gShellNetwork2HiiHandle, ValueStr);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +  }
> +  //
> +  // Parse the paramter of buffer size.
> +  //
> +  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");
> +  ValueStrPtr = ValueStr;
> +  if (ValueStr != NULL) {
> +    BufferSize = ShellStrToUintn (ValueStrPtr);
> +
> +    //
> +    // ShellStrToUintn will return 0 when input is 0 or an invalid input 
> string.
> +    //
> +    if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN
> (STR_PING6_INVALID_BUFFER_SIZE), gShellNetwork2HiiHandle, ValueStr);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +  }
> +
> +  ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS));
> +  ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS));
> +
> +  //
> +  // Parse the paramter of source ip address.
> +  //
> +  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
> +  ValueStrPtr = ValueStr;
> +  if (ValueStr != NULL) {
> +    mIp6SrcString = ValueStr;
> +    Status = NetLibStrToIp6 (ValueStrPtr, &SrcAddress);
> +    if (EFI_ERROR (Status)) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP),
> gShellNetwork2HiiHandle, ValueStr);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +  }
> +  //
> +  // Parse the paramter of destination ip address.
> +  //
> +  NonOptionCount = ShellCommandLineGetCount(ParamPackage);
> +  ValueStr = ShellCommandLineGetRawValue (ParamPackage,
> (UINT32)(NonOptionCount-1));
> +  if (NonOptionCount != 2) {
> +    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT),
> gShellNetwork2HiiHandle);
> +    ShellStatus = SHELL_INVALID_PARAMETER;
> +    goto ON_EXIT;
> +  }
> +  ValueStrPtr = ValueStr;
> +  if (ValueStr != NULL) {
> +    mIp6DstString = ValueStr;
> +    Status = NetLibStrToIp6 (ValueStrPtr, &DstAddress);
> +    if (EFI_ERROR (Status)) {
> +      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP),
> gShellNetwork2HiiHandle, ValueStr);
> +      ShellStatus = SHELL_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +  }
> +  //
> +  // Get frequency to calculate the time from ticks.
> +  //
> +  Status = Ping6GetFrequency ();
> +
> +  if (EFI_ERROR(Status)) {
> +    ShellStatus = SHELL_ACCESS_DENIED;
> +    goto ON_EXIT;
> +  }
> +  //
> +  // Enter into ping6 process.
> +  //
> +  ShellStatus = ShellPing6 (
> +              ImageHandle,
> +              (UINT32)SendNumber,
> +              (UINT32)BufferSize,
> +              &SrcAddress,
> +              &DstAddress
> +              );
> +
> +ON_EXIT:
> +  ShellCommandLineFreeVarList (ParamPackage);
> +  return ShellStatus;
> +}
> +
> diff --git
> a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.c
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.c
> new file mode 100644
> index 0000000..6837b3a
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.c
> @@ -0,0 +1,91 @@
> +/** @file
> +  Main file for NULL named library for network2 shell command functions.
> +
> +  Copyright (c) 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 "UefiShellNetwork2CommandsLib.h"
> +
> +CONST CHAR16 gShellNetwork2FileName[] = L"ShellCommands";
> +EFI_HANDLE gShellNetwork2HiiHandle = NULL;
> +
> +/**
> +  return the file name of the help text file if not using HII.
> +
> +  @return The string pointer to the file name.
> +**/
> +CONST CHAR16*
> +EFIAPI
> +ShellCommandGetManFileNameNetwork2 (
> +  VOID
> +  )
> +{
> +  return (gShellNetwork2FileName);
> +}
> +
> +/**
> +  Constructor for the Shell Network2 Commands library.
> +
> +  Install the handlers for Network2 UEFI Shell 2.0 profile commands.
> +
> +  @param ImageHandle            The image handle of the process.
> +  @param SystemTable            The EFI System Table pointer.
> +
> +  @retval EFI_SUCCESS           The shell command handlers were installed
> sucessfully.
> +  @retval EFI_UNSUPPORTED       The shell level required was not found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +ShellNetwork2CommandsLibConstructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  gShellNetwork2HiiHandle = NULL;
> +
> +  //
> +  // check our bit of the profiles mask
> +  //
> +  if ((PcdGet8(PcdShellProfileMask) & BIT4) == 0) {
> +    return (EFI_SUCCESS);
> +  }
> +
> +  gShellNetwork2HiiHandle = HiiAddPackages (&gShellNetwork2HiiGuid,
> gImageHandle, UefiShellNetwork2CommandsLibStrings, NULL);
> +  if (gShellNetwork2HiiHandle == NULL) {
> +    return (EFI_DEVICE_ERROR);
> +  }
> +  //
> +  // install our shell command handlers
> +  //
> +  ShellCommandRegisterCommandName(L"ping6",    ShellCommandRunPing6
> , ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE ,
> gShellNetwork2HiiHandle, STRING_TOKEN(STR_GET_HELP_PING6));
> +
> ShellCommandRegisterCommandName(L"ifconfig6",ShellCommandRunIfconfig
> 6 , ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE ,
> gShellNetwork2HiiHandle, STRING_TOKEN(STR_GET_HELP_IFCONFIG6));
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +/**
> +  Destructor for the library.  free any resources.
> +
> +  @param ImageHandle            The image handle of the process.
> +  @param SystemTable            The EFI System Table pointer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +ShellNetwork2CommandsLibDestructor (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  if (gShellNetwork2HiiHandle != NULL) {
> +    HiiRemovePackages(gShellNetwork2HiiHandle);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.h
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.h
> new file mode 100644
> index 0000000..138cc8c
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.h
> @@ -0,0 +1,72 @@
> +/** @file
> +  Main file for NULL named library for network2 shell command functions.
> +
> +  Copyright (c) 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.
> +
> +**/
> +
> +#ifndef _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
> +#define _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/ServiceBinding.h>
> +#include <Protocol/Ip6.h>
> +#include <Protocol/Ip6Config.h>
> +
> +#include <Guid/ShellLibHiiGuid.h>
> +
> +#include <Library/ShellLib.h>
> +#include <Library/ShellCommandLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/NetLib.h>
> +
> +extern EFI_HANDLE gShellNetwork2HiiHandle;
> +
> +/**
> +  Function for 'ping6' command.
> +
> +  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
> +  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
> +
> +  @retval SHELL_SUCCESS  The ping6 processed successfullly.
> +  @retval others         The ping6 processed unsuccessfully.
> +
> +**/
> +SHELL_STATUS
> +EFIAPI
> +ShellCommandRunPing6 (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  );
> +
> +/**
> +  Function for 'ifconfig6' command.
> +
> +  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
> +  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
> +
> +  @retval SHELL_SUCCESS   The ifconfig6 command processed successfully.
> +  @retval others          The ifconfig6 command process failed.
> +
> +**/
> +SHELL_STATUS
> +EFIAPI
> +ShellCommandRunIfconfig6 (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  );
> +
> +#endif
> +
> diff --git
> a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.inf
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.inf
> new file mode 100644
> index 0000000..426efcc
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.inf
> @@ -0,0 +1,63 @@
> +##  @file
> +# Provides shell network2 functions
> +#
> +# Copyright (c) 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.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010006
> +  BASE_NAME                      = UefiShellNetwork2CommandsLib
> +  FILE_GUID                      = D94E3B82-908E-46bf-A7B9-C7B7F17B1B7D
> +  MODULE_TYPE                    = UEFI_APPLICATION
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL|UEFI_APPLICATION UEFI_DRIVER
> +  CONSTRUCTOR                    = ShellNetwork2CommandsLibConstructor
> +  DESTRUCTOR                     = ShellNetwork2CommandsLibDestructor
> +
> +[Sources.common]
> +  UefiShellNetwork2CommandsLib.uni
> +  UefiShellNetwork2CommandsLib.c
> +  UefiShellNetwork2CommandsLib.h
> +  Ping6.c
> +  Ifconfig6.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  ShellPkg/ShellPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> +  MemoryAllocationLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  ShellCommandLib
> +  ShellLib
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  PcdLib
> +  HiiLib
> +  FileHandleLib
> +  NetLib
> +
> +[Pcd]
> +  gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid                       ## CONSUMES
> +  gEfiIp6ProtocolGuid                           ## SOMETIMES_CONSUMES
> +  gEfiIp6ServiceBindingProtocolGuid             ## SOMETIMES_CONSUMES
> +  gEfiIp6ConfigProtocolGuid                     ## SOMETIMES_CONSUMES
> +
> +[Guids]
> +  gShellNetwork2HiiGuid                         ## SOMETIMES_CONSUMES ## HII
> diff --git
> a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.uni
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.uni
> new file mode 100644
> index 0000000..fb2bfab
> --- /dev/null
> +++
> b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm
> andsLib.uni
> @@ -0,0 +1,151 @@
> +/** @file
> +
> +  String definitions for UEFI Shell network 2 commands
> +  Copyright (c) 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<BR>
> +  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.
> +
> +  Module Name:
> +
> +   UefiShellNetwork2CommandsLib.uni
> +
> +  Abstract:
> +
> +   String definitions for UEFI Shell 2.0 network 2 commands
> +**/
> +
> +#langdef   en-US "english"
> +
> +#string STR_PING6_INVALID_IP               #language en-US  "%Ping6: Invalid 
> IP6
> address, %s\r\n"
> +#string STR_PING6_INVALID_INPUT            #language en-US  "%Ping6: Invalid
> input, please type 'Ping6 -?'for help\r\n"
> +#string STR_PING6_INVALID_SEND_NUMBER      #language en-US  "%Ping6:
> Invalid send number, %s\r\n"
> +#string STR_PING6_INVALID_BUFFER_SIZE      #language en-US  "%Ping6:
> Invalid buffer size, %s\r\n"
> +#string STR_PING6_INVALID_SOURCE           #language en-US  "%Ping6:
> Require source interface option\r\n"
> +#string STR_PING6_IP6_CONFIG               #language en-US  "%Ping6: The
> process of Ip6 Configure %r\r\n"
> +#string STR_PING6_IP6CFG_GETDATA           #language en-US  "%Ping6: Get
> data of the interface information %r\r\n"
> +#string STR_PING6_SEND_REQUEST             #language en-US  "Echo request
> sequence %d fails.\r\n"
> +#string STR_PING6_SOURCE_NOT_FOUND         #language en-US  "Source %s
> not found.\r\n"
> +#string STR_PING6_NOSOURCE_INDOMAIN        #language en-US  "No
> sources in %s's multicast domain.\r\n"
> +#string STR_PING6_START                    #language en-US  "Ping %s %d data
> bytes\r\n"
> +#string STR_PING6_TIMEOUT                  #language en-US  "Echo request
> sequence %d timeout.\r\n"
> +#string STR_PING6_REPLY_INFO               #language en-US  "%d bytes from %s
> : icmp_seq=%d ttl=%d time%c%dms\r\n"
> +#string STR_PING6_STAT                     #language en-US  "\n%d packets
> transmitted, %d received, %d%% packet loss, time %dms\r\n"
> +#string STR_PING6_RTT                      #language en-US  "\nRtt(round 
> trip time)
> min=%dms max=%dms avg=%dms\r\n"
> +
> +#string STR_IFCONFIG6_ERR_IP6CFG_GETDATA       #language en-US    "Get
> data of the interface information %hr\r\n"
> +#string STR_IFCONFIG6_INFO_BREAK               #language en-US    
> "----------------
> -------------------------------------------------"
> +#string STR_IFCONFIG6_INFO_COLON               #language en-US    ":"
> +#string STR_IFCONFIG6_INFO_JOINT               #language en-US    " >> "
> +#string STR_IFCONFIG6_INFO_NEWLINE             #language en-US    "\r\n"
> +#string STR_IFCONFIG6_INFO_IF_NAME             #language en-US
> "\n%Hname         : %s%N\r\n"
> +#string STR_IFCONFIG6_INFO_POLICY_AUTO         #language en-US
> "%Hpolicy       : automatic%N\r\n"
> +#string STR_IFCONFIG6_INFO_POLICY_MAN          #language en-US
> "%Hpolicy       : manual%N\r\n"
> +#string STR_IFCONFIG6_INFO_DAD_TRANSMITS       #language en-US
> "%Hdad xmits    : %d%N\r\n"
> +#string STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD   #language en-US
> "%Hinterface id : %N"
> +#string STR_IFCONFIG6_INFO_MAC_ADDR_HEAD       #language en-US
> "%Hmac addr     : %N"
> +#string STR_IFCONFIG6_INFO_MAC_ADDR_BODY       #language en-US
> "%02x"
> +#string STR_IFCONFIG6_INFO_IP_ADDR_HEAD        #language en-US
> "\n%Hhost addr    : %N\r\n"
> +#string STR_IFCONFIG6_INFO_DNS_ADDR_HEAD       #language en-US
> "\n%Hdns server   : %N\r\n"
> +#string STR_IFCONFIG6_INFO_IP_ADDR_BODY        #language en-US    "%02x"
> +#string STR_IFCONFIG6_INFO_IP_ADDR_BODY4BIT    #language en-US    "%x"
> +#string STR_IFCONFIG6_INFO_ROUTE_HEAD          #language en-US
> "\n%Hroute table  : %N\r\n"
> +#string STR_IFCONFIG6_INFO_PREFIX_LEN          #language en-US    "/%d"
> +#string STR_IFCONFIG6_LINE_HELP                #language en-US    "Displays 
> or
> modifies the IPv6 configuration"
> +#string STR_IFCONFIG6_ERR_LACK_INTERFACE       #language en-US    "Lack
> interface name.\r\n"
> +                                                                  "Usage: 
> IfConfig6 -s <Name> \r\n"
> +                                                                  "Example: 
> IfConfig6 -s eth0 auto\r\n"
> +#string STR_IFCONFIG6_LACK_OPTION              #language en-US    "Flags 
> lack.
> Please type 'IfConfig6 -?' for help info.\r\n"
> +#string STR_IFCONFIG6_CONFLICT_OPTIONS         #language en-US    "Flags
> conflict. Please type 'IfConfig6 -?' for help info.\r\n"
> +#string STR_IFCONFIG6_ERR_LACK_COMMAND         #language en-US    "Lack
> interface config option.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_INVALID_INTERFACE    #language en-US
> "Invalid interface name.\r\n"
> +                                                                  "Hint: Use 
> {IfConfig6 -l} to check existing
> interface names.\r\n"
> +#string STR_IFCONFIG6_ERR_INVALID_COMMAND      #language en-US
> "Invalid command. Bad command %H%s%N is skipped.\r\n"
> +                                                                  "Hint: 
> Incorrect option or arguments.
> Please type 'IfConfig6 -?' for help info.\r\n"
> +#string STR_IFCONFIG6_ERR_LACK_ARGUMENTS       #language en-US    "Lack
> arguments. Bad command %H%s%N is skipped.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_LACK_OPTION          #language en-US    "Lack
> options.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_MAN_HOST             #language en-US    "Manual
> address configuration failed. Please retry.\r\n"
> +#string STR_IFCONFIG6_ERR_DUPLICATE_COMMAND    #language en-US
> "Duplicate commands. Bad command %H%s%N is skipped.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_CONFLICT_COMMAND     #language en-US
> "Conflict commands. Bad command %H%s%N is skipped.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_UNKNOWN_COMMAND      #language en-US
> "Unknown commands. Bad command %H%s%N is skipped.\r\n"
> +                                                                  "Hint: 
> Please type 'IfConfig6 -?' for help
> info.\r\n"
> +#string STR_IFCONFIG6_ERR_ADDRESS_FAILED       #language en-US    "It
> failed to set .\r\n"
> +
> +
> +#string STR_GET_HELP_PING6                     #language en-US ""
> +".TH ping6 0 "Ping a target machine with UEFI IPv6 network stack."\r\n"
> +".SH NAME\r\n"
> +"Ping a target machine with UEFI IPv6 network stack.\r\n"
> +".SH SYNOPSIS\r\n"
> +" \r\n"
> +"Ping6 [-l size] [-n count] [-s SourceIp] TargetIp\r\n"
> +".SH OPTIONS\r\n"
> +" \r\n"
> +"  -l size     Send buffer size, in bytes(default=16, min=16, 
> max=32768).\r\n"
> +"  -n count    Send request count, (default=10, min=1, max=10000).\r\n"
> +"  -s SourceIp Source IPv6 address.\r\n"
> +"  TargetIp    Target IPv6 address.\r\n"
> +".SH EXAMPLES\r\n"
> +" \r\n"
> +"Examples:\r\n"
> +"  * To ping the target host by sending 5 request with 1000 bytes from
> 2002::1\r\n"
> +"    Shell:\> Ping6 -s 2002::1 2002::2 -l 1000 -n 5\r\n"
> +" \r\n"
> +"  * To ping the target host with 1000 bytes\r\n"
> +"    Shell:\> Ping6 2002::2 -l 1000\r\n"
> +
> +#string STR_GET_HELP_IFCONFIG6                 #language en-US    ""
> +".TH ifconfig6 0 "Displays or modifies IPv6 configuration for network
> interface."\r\n"
> +".SH NAME\r\n"
> +"Displays or modifies IPv6 configuration for network interface.\r\n"
> +".SH SYNOPSIS\r\n"
> +" \r\n"
> +"IfConfig6 -r [Name] | -l [Name] \r\n"
> +"IfConfig6 -s <Name> [dad <Num>] [auto | [man [id <mac>] [host <IPv6> gw
> <IPv6>]\r\n"
> +"             [dns <IPv6>]]]\r\n"
> +".SH OPTIONS\r\n"
> +" \r\n"
> +"  Name                     Adapter name, i.e., eth0\r\n"
> +"  -r [Name]                Reconfigure all or specified interface, and 
> set\r\n"
> +"                           automatic policy. If specified interface is 
> already\r\n"
> +"                           set to automatic,then refresh the IPv6 
> configuration.\r\n"
> +"  -l [Name]                List the configuration of the specified 
> interface.\r\n"
> +"  -s <Name> dad <Num>      Set dad transmits count of the specified
> interface.\r\n"
> +"  -s <Name> auto           Set automatic policy of the specified 
> interface.\r\n"
> +"  -s <Name> man id <Mac>   Set alternative interface id of the specified
> \r\n"
> +"                           interface. Must under manual policy.\r\n"
> +"  -s <Name> man host <IPv6> gw <IPv6>\r\n"
> +"                           Set static host IP and gateway address of 
> the\r\n"
> +"                           specified interface. Must under manual 
> policy.\r\n"
> +"  -s <Name> man dns <IPv6> Set DNS server IP addresses of the
> specified\r\n"
> +"                           interface.Must under manual policy.\r\n"
> +".SH EXAMPLES\r\n"
> +" \r\n"
> +"EXAMPLES:\r\n"
> +"  * To list the configuration for the interface eth0:\r\n"
> +"    Shell:\> ifConfig6 -l eth0\r\n"
> +" \r\n"
> +"  * To use automatic configuration to request the IPv6 address
> configuration\r\n"
> +"    dynamically for the interface eth0:\r\n"
> +"    Shell:\> ifconfig6 -s eth0 auto\r\n"
> +" \r\n"
> +"  * To set the dad transmits count for eth0 under automatic policy:\r\n"
> +"    Shell:\> ifconfig6 -s eth0 auto dad 10\r\n"
> +" \r\n"
> +"  * To set the alternative interface id of eth0 under manual policy:\r\n"
> +"    Shell:\> ifconfig6 -s eth0 man id ff:dd:aa:88:66:cc\r\n"
> +" \r\n"
> +"  * To use the static IP6 addresses configuration for the interface 
> eth0,\r\n"
> +"    and this configuration survives the network reload:\r\n"
> +"    Shell:\> ifconfig6 -s eth0 man host 2002::1/64 2002::2/64 gw
> 2002::3/64\r\n"
> diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec
> index 76a2b7d..39f8012 100644
> --- a/ShellPkg/ShellPkg.dec
> +++ b/ShellPkg/ShellPkg.dec
> @@ -1,10 +1,10 @@
>  ## @file ShellPkg.dec
>  # This Package provides all definitions for EFI and UEFI Shell
>  #
>  # (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>
> -# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
> +# 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
> @@ -51,10 +51,11 @@
>    gShellInstall1HiiGuid           = {0x7d574d54, 0xd364, 0x4d4a, {0x95, 0xe3,
> 0x49, 0x45, 0xdb, 0x7a, 0xd3, 0xee}}
>    gShellLevel1HiiGuid             = {0xdec5daa4, 0x6781, 0x4820, {0x9c, 0x63,
> 0xa7, 0xb0, 0xe4, 0xf1, 0xdb, 0x31}}
>    gShellLevel2HiiGuid             = {0xf95a7ccc, 0x4c55, 0x4426, {0xa7, 0xb4,
> 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae}}
>    gShellLevel3HiiGuid             = {0x4344558d, 0x4ef9, 0x4725, {0xb1, 0xe4,
> 0x33, 0x76, 0xe8, 0xd6, 0x97, 0x4f}}
>    gShellNetwork1HiiGuid           = {0xf3d301bb, 0xf4a5, 0x45a8, {0xb0, 0xb7,
> 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}}
> +  gShellNetwork2HiiGuid           = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60,
> 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}}
>    gShellTftpHiiGuid               = {0x738a9314, 0x82c1, 0x4592, {0x8f, 
> 0xf7, 0xc1,
> 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}}
>    gShellBcfgHiiGuid               = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2,
> 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}}
> 
>  [Protocols]
>    gEfiShellProtocolGuid               = {0x6302d008, 0x7f9b, 0x4f30, {0x87, 
> 0xac,
> 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}}
> @@ -92,10 +93,11 @@
>    #  don't forget to update the text file if you change this.
>    #  bit 0 = Drivers1
>    #  bit 1 = Debug1
>    #  bit 2 = Install1
>    #  bit 3 = Network1
> +  #  bit 4 = Network2
>    gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0xFF|UINT8|0x0000000D
> 
>    ## This is the character count for allocation for consistent mappings
> 
> gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength|50|UINT8|0x0000000
> 9
> 
> diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc
> index 7e07cfb..31fe499 100644
> --- a/ShellPkg/ShellPkg.dsc
> +++ b/ShellPkg/ShellPkg.dsc
> @@ -1,9 +1,9 @@
>  ##  @file
>  # Shell Package
>  #
> -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2007 - 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
> @@ -26,11 +26,11 @@
>  [LibraryClasses.common]
> 
> UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiAp
> plicationEntryPoint.inf
> 
> UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo
> tServicesTableLib.inf
> 
> DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptiona
> lDevicePathProtocol.inf
>    DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
> -
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Base
> DebugPrintErrorLevelLib.inf
> +
> DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Base
> DebugPrintErrorLevelLib.inf
>    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> 
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemor
> yAllocationLib.inf
>    UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
>    BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
>    BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> @@ -44,11 +44,11 @@
> 
>    ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> 
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommand
> Lib.inf
>    ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
> 
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLi
> b.inf
> -
> +
> 
> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePe
> CoffGetEntryPointLib.inf
> 
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgC
> ommandLib.inf
>    IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> 
>  [LibraryClasses.ARM]
> @@ -86,10 +86,11 @@
> 
> ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.
> inf
> 
> ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLi
> b.inf
> 
> ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib
> .inf
> 
> ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLi
> b.inf
> 
> ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Comma
> ndsLib.inf
> +
> ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma
> ndsLib.inf
>    ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
> 
>    ShellPkg/Library/UefiDpLib/UefiDpLib.inf {
>      <LibraryClasses>
> 
> TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTempl
> ate.inf
> @@ -105,10 +106,11 @@
>  !ifndef $(NO_SHELL_PROFILES)
> 
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comm
> andsLib.inf
> 
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comma
> ndsLib.inf
> 
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comm
> andsLib.inf
> 
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1C
> ommandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2C
> ommandsLib.inf
>  !ifdef $(INCLUDE_DP)
>        NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf
>  !endif #$(INCLUDE_DP)
>  !ifdef $(INCLUDE_TFTP_COMMAND)
> 
> NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.i
> nf
> --
> 1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to