/** @file
  The implementation of policy entry operation function in IpSecConfig application.

  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IpSecConfig.h"
#include "Indexer.h"
#include "Match.h"
#include "Helper.h"
#include "ForEach.h"
#include "PolicyEntryOperation.h"

/**
  Fill in EFI_IPSEC_SPD_SELECTOR through ParamPackage list.

  @param[out]     Selector        The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[in]      ParamPackage    The pointer to the ParamPackage list.
  @param[in, out] Mask            The pointer to the Mask.

  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SPD_SELECTOR successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CreateSpdSelector (
     OUT EFI_IPSEC_SPD_SELECTOR    *Selector,
  IN     LIST_ENTRY                *ParamPackage,
  IN OUT UINT32                    *Mask
  )
{
  EFI_STATUS      Status;
  EFI_STATUS      ReturnStatus;
  CONST CHAR16    *ValueStr;

  Status       = EFI_SUCCESS;
  ReturnStatus = EFI_SUCCESS;

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local");
  if (ValueStr != NULL) {
    Selector->LocalAddressCount = 1;
    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->LocalAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--local",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= LOCAL;
    }
  }

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote");
  if (ValueStr != NULL) {
    Selector->RemoteAddressCount = 1;
    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->RemoteAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--remote",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= REMOTE;
    }
  }

  Selector->NextLayerProtocol = EFI_IPSEC_ANY_PROTOCOL;

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  Status = GetNumber (
             L"--proto",
             (UINT16) -1,
             &Selector->NextLayerProtocol,
             sizeof (UINT16),
             mMapIpProtocol,
             ParamPackage,
             FORMAT_NUMBER | FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= PROTO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Selector->LocalPort  = EFI_IPSEC_ANY_PORT;
  Selector->RemotePort = EFI_IPSEC_ANY_PORT;

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local-port");
  if (ValueStr != NULL) {
    Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->LocalPort, &Selector->LocalPortRange);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--local-port",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= LOCAL_PORT;
    }
  }

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote-port");
  if (ValueStr != NULL) {
    Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->RemotePort, &Selector->RemotePortRange);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--remote-port",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= REMOTE_PORT;
    }
  }

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  Status = GetNumber (
             L"--icmp-type",
             (UINT8) -1,
             &Selector->LocalPort,
             sizeof (UINT16),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= ICMP_TYPE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
  //
  Status = GetNumber (
             L"--icmp-code",
             (UINT8) -1,
             &Selector->RemotePort,
             sizeof (UINT16),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= ICMP_CODE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  return ReturnStatus;
}

/**
  Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA through ParamPackage list.

  @param[out] Selector        The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[out] Data            The pointer to the EFI_IPSEC_SPD_DATA structure.
  @param[in]  ParamPackage    The pointer to the ParamPackage list.
  @param[out] Mask            The pointer to the Mask.
  @param[in]  CreateNew       The switch to create new.

  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CreateSpdEntry (
  OUT EFI_IPSEC_SPD_SELECTOR    **Selector,
  OUT EFI_IPSEC_SPD_DATA        **Data,
  IN  LIST_ENTRY                *ParamPackage,
  OUT UINT32                    *Mask,
  IN  BOOLEAN                   CreateNew
  )
{
  EFI_STATUS      Status;
  EFI_STATUS      ReturnStatus;
  CONST CHAR16    *ValueStr;
  UINTN           DataSize;

  Status    = EFI_SUCCESS;
  *Mask     = 0;

  *Selector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR) + 2 * sizeof (EFI_IP_ADDRESS_INFO));
  ASSERT (*Selector != NULL);

  (*Selector)->LocalAddress  = (EFI_IP_ADDRESS_INFO *) (*Selector + 1);
  (*Selector)->RemoteAddress = (*Selector)->LocalAddress + 1;

  ReturnStatus = CreateSpdSelector (*Selector, ParamPackage, Mask);

  //
  // SPD DATA
  // NOTE: Allocate enough memory and add padding for different arch.
  //
  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SPD_DATA));
  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_PROCESS_POLICY));
  DataSize += sizeof (EFI_IPSEC_TUNNEL_OPTION);

  *Data = AllocateZeroPool (DataSize);
  ASSERT (*Data != NULL);

  (*Data)->ProcessingPolicy               = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (
                                                                           (*Data + 1),
                                                                           sizeof (UINTN)
                                                                           );
  (*Data)->ProcessingPolicy->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER (
                                                                          ((*Data)->ProcessingPolicy + 1),
                                                                          sizeof (UINTN)
                                                                          );


  //
  // Convert user imput from string to integer, and fill in the Name in EFI_IPSEC_SPD_DATA.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--name");
  if (ValueStr != NULL) {
    UnicodeStrToAsciiStrS (ValueStr, (CHAR8 *) (*Data)->Name, sizeof ((*Data)->Name));
    *Mask |= NAME;
  }

  //
  // Convert user imput from string to integer, and fill in the PackageFlag in EFI_IPSEC_SPD_DATA.
  //
  Status = GetNumber (
             L"--packet-flag",
             (UINT8) -1,
             &(*Data)->PackageFlag,
             sizeof (UINT32),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= PACKET_FLAG;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in the Action in EFI_IPSEC_SPD_DATA.
  //
  Status = GetNumber (
             L"--action",
             (UINT8) -1,
             &(*Data)->Action,
             sizeof (UINT32),
             mMapIpSecAction,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= ACTION;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in the ExtSeqNum in EFI_IPSEC_SPD_DATA.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence")) {
    (*Data)->ProcessingPolicy->ExtSeqNum   = TRUE;
    *Mask |= EXT_SEQUENCE;
  } else if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence-")) {
    (*Data)->ProcessingPolicy->ExtSeqNum   = FALSE;
    *Mask |= EXT_SEQUENCE;
  }

  //
  // Convert user imput from string to integer, and fill in the SeqOverflow in EFI_IPSEC_SPD_DATA.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow")) {
    (*Data)->ProcessingPolicy->SeqOverflow = TRUE;
    *Mask |= SEQUENCE_OVERFLOW;
  } else if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow-")) {
    (*Data)->ProcessingPolicy->SeqOverflow = FALSE;
    *Mask |= SEQUENCE_OVERFLOW;
  }

  //
  // Convert user imput from string to integer, and fill in the FragCheck in EFI_IPSEC_SPD_DATA.
  //
  if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check")) {
    (*Data)->ProcessingPolicy->FragCheck   = TRUE;
    *Mask |= FRAGMENT_CHECK;
  } else if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check-")) {
    (*Data)->ProcessingPolicy->FragCheck   = FALSE;
    *Mask |= FRAGMENT_CHECK;
  }

  //
  // Convert user imput from string to integer, and fill in the ProcessingPolicy in EFI_IPSEC_SPD_DATA.
  //
  Status = GetNumber (
             L"--lifebyte",
             (UINT64) -1,
             &(*Data)->ProcessingPolicy->SaLifetime.ByteCount,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFEBYTE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--lifetime",
             (UINT64) -1,
             &(*Data)->ProcessingPolicy->SaLifetime.HardLifetime,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFETIME;
  }
  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--lifetime-soft",
             (UINT64) -1,
             &(*Data)->ProcessingPolicy->SaLifetime.SoftLifetime,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFETIME_SOFT;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  (*Data)->ProcessingPolicy->Mode = EfiIPsecTransport;
  Status = GetNumber (
             L"--mode",
             0,
             &(*Data)->ProcessingPolicy->Mode,
             sizeof (UINT32),
             mMapIpSecMode,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= MODE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-local");
  if (ValueStr != NULL) {
    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->LocalTunnelAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--tunnel-local",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= TUNNEL_LOCAL;
    }
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-remote");
  if (ValueStr != NULL) {
    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--tunnel-remote",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= TUNNEL_REMOTE;
    }
  }

  (*Data)->ProcessingPolicy->TunnelOption->DF = EfiIPsecTunnelCopyDf;
  Status = GetNumber (
             L"--dont-fragment",
             0,
             &(*Data)->ProcessingPolicy->TunnelOption->DF,
             sizeof (UINT32),
             mMapDfOption,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= DONT_FRAGMENT;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  (*Data)->ProcessingPolicy->Proto = EfiIPsecESP;
  Status = GetNumber (
             L"--ipsec-proto",
             0,
             &(*Data)->ProcessingPolicy->Proto,
             sizeof (UINT32),
             mMapIpSecProtocol,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= IPSEC_PROTO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--encrypt-algo",
             0,
             &(*Data)->ProcessingPolicy->EncAlgoId,
             sizeof (UINT8),
             mMapEncAlgo,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= ENCRYPT_ALGO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--auth-algo",
             0,
             &(*Data)->ProcessingPolicy->AuthAlgoId,
             sizeof (UINT8),
             mMapAuthAlgo,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= AUTH_ALGO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Cannot check Mode against EfiIPsecTunnel, because user may want to change tunnel_remote only so the Mode is not set.
  //
  if ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE | DONT_FRAGMENT)) == 0) {
    (*Data)->ProcessingPolicy->TunnelOption = NULL;
  }

  if ((*Mask & (EXT_SEQUENCE | SEQUENCE_OVERFLOW | FRAGMENT_CHECK | LIFEBYTE |
                LIFETIME_SOFT | LIFETIME | MODE | TUNNEL_LOCAL | TUNNEL_REMOTE |
                DONT_FRAGMENT | IPSEC_PROTO | AUTH_ALGO | ENCRYPT_ALGO)) == 0) {
    if ((*Data)->Action != EfiIPsecActionProtect) {
      //
      // User may not provide additional parameter for Protect action, so we cannot simply set ProcessingPolicy to NULL.
      //
      (*Data)->ProcessingPolicy = NULL;
    }
  }

  if (CreateNew) {
    if ((*Mask & (LOCAL | REMOTE | PROTO | ACTION)) != (LOCAL | REMOTE | PROTO | ACTION)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--local --remote --proto --action"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else if (((*Data)->Action == EfiIPsecActionProtect) &&
               ((*Data)->ProcessingPolicy->Mode == EfiIPsecTunnel) &&
               ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE))) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--tunnel-local --tunnel-remote"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    }
  }

  return ReturnStatus;
}

/**
  Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 through ParamPackage list.

  @param[out] SaId            The pointer to the EFI_IPSEC_SA_ID structure.
  @param[out] Data            The pointer to the EFI_IPSEC_SA_DATA2 structure.
  @param[in]  ParamPackage    The pointer to the ParamPackage list.
  @param[out] Mask            The pointer to the Mask.
  @param[in]  CreateNew       The switch to create new.

  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CreateSadEntry (
  OUT EFI_IPSEC_SA_ID      **SaId,
  OUT EFI_IPSEC_SA_DATA2   **Data,
  IN  LIST_ENTRY           *ParamPackage,
  OUT UINT32               *Mask,
  IN  BOOLEAN              CreateNew
  )
{
  EFI_STATUS      Status;
  EFI_STATUS      ReturnStatus;
  UINTN           AuthKeyLength;
  UINTN           EncKeyLength;
  CONST CHAR16    *ValueStr;
  CHAR8           *AsciiStr;
  UINTN           DataSize;

  Status        = EFI_SUCCESS;
  ReturnStatus  = EFI_SUCCESS;
  *Mask         = 0;
  AuthKeyLength = 0;
  EncKeyLength  = 0;

  *SaId = AllocateZeroPool (sizeof (EFI_IPSEC_SA_ID));
  ASSERT (*SaId != NULL);

  //
  // Convert user imput from string to integer, and fill in the Spi in EFI_IPSEC_SA_ID.
  //
  Status = GetNumber (L"--spi", (UINT32) -1, &(*SaId)->Spi, sizeof (UINT32), NULL, ParamPackage, FORMAT_NUMBER);
  if (!EFI_ERROR (Status)) {
    *Mask |= SPI;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in the Proto in EFI_IPSEC_SA_ID.
  //
  Status = GetNumber (
             L"--ipsec-proto",
             0,
             &(*SaId)->Proto,
             sizeof (EFI_IPSEC_PROTOCOL_TYPE),
             mMapIpSecProtocol,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= IPSEC_PROTO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in EFI_IPSEC_SA_DATA2.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
  if (ValueStr != NULL) {
    AuthKeyLength = StrLen (ValueStr);
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
  if (ValueStr != NULL) {
    EncKeyLength = StrLen (ValueStr);
  }

  //
  // EFI_IPSEC_SA_DATA2:
  //   +------------
  //   | EFI_IPSEC_SA_DATA2
  //   +-----------------------
  //   | AuthKey
  //   +-------------------------
  //   | EncKey
  //   +-------------------------
  //   | SpdSelector
  //
  // Notes: To make sure the address alignment add padding after each data if needed.
  //
  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2));
  DataSize  = ALIGN_VARIABLE (DataSize + AuthKeyLength);
  DataSize  = ALIGN_VARIABLE (DataSize + EncKeyLength);
  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_SPD_SELECTOR));
  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IP_ADDRESS_INFO));
  DataSize += sizeof (EFI_IP_ADDRESS_INFO);



  *Data = AllocateZeroPool (DataSize);
  ASSERT (*Data != NULL);

  (*Data)->ManualSet                    = TRUE;
  (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER (((*Data) + 1), sizeof (UINTN));
  (*Data)->AlgoInfo.EspAlgoInfo.EncKey  = (VOID *) ALIGN_POINTER (
                                                     ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.AuthKey + AuthKeyLength),
                                                     sizeof (UINTN)
                                                     );
  (*Data)->SpdSelector                  = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER (
                                                                       ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.EncKey + EncKeyLength),
                                                                       sizeof (UINTN)
                                                                       );
  (*Data)->SpdSelector->LocalAddress    = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
                                                                    ((UINT8 *) (*Data)->SpdSelector + sizeof (EFI_IPSEC_SPD_SELECTOR)),
                                                                    sizeof (UINTN));
  (*Data)->SpdSelector->RemoteAddress   = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
                                                                    (*Data)->SpdSelector->LocalAddress + 1,
                                                                    sizeof (UINTN)
                                                                    );

  (*Data)->Mode = EfiIPsecTransport;
  Status = GetNumber (
             L"--mode",
             0,
             &(*Data)->Mode,
             sizeof (EFI_IPSEC_MODE),
             mMapIpSecMode,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= MODE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // According to RFC 4303-3.3.3. The first packet sent using a given SA
  // will contain a sequence number of 1.
  //
  (*Data)->SNCount = 1;
  Status = GetNumber (
             L"--sequence-number",
             (UINT64) -1,
             &(*Data)->SNCount,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= SEQUENCE_NUMBER;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  (*Data)->AntiReplayWindows = 0;
  Status = GetNumber (
             L"--antireplay-window",
             (UINT8) -1,
             &(*Data)->AntiReplayWindows,
             sizeof (UINT8),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= SEQUENCE_NUMBER;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--encrypt-algo",
             0,
             &(*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId,
             sizeof (UINT8),
             mMapEncAlgo,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= ENCRYPT_ALGO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
  if (ValueStr != NULL ) {
    (*Data)->AlgoInfo.EspAlgoInfo.EncKeyLength = EncKeyLength;
    AsciiStr = AllocateZeroPool (EncKeyLength + 1);
    ASSERT (AsciiStr != NULL);
    UnicodeStrToAsciiStrS (ValueStr, AsciiStr, EncKeyLength + 1);
    CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.EncKey,  AsciiStr, EncKeyLength);
    FreePool (AsciiStr);
    *Mask |= ENCRYPT_KEY;
  } else {
    (*Data)->AlgoInfo.EspAlgoInfo.EncKey = NULL;
  }

  Status = GetNumber (
             L"--auth-algo",
             0,
             &(*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId,
             sizeof (UINT8),
             mMapAuthAlgo,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= AUTH_ALGO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
  if (ValueStr != NULL) {
    (*Data)->AlgoInfo.EspAlgoInfo.AuthKeyLength = AuthKeyLength;
    AsciiStr = AllocateZeroPool (AuthKeyLength + 1);
    ASSERT (AsciiStr != NULL);
    UnicodeStrToAsciiStrS (ValueStr, AsciiStr, AuthKeyLength + 1);
    CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.AuthKey, AsciiStr, AuthKeyLength);
    FreePool (AsciiStr);
    *Mask |= AUTH_KEY;
  } else {
    (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = NULL;
  }

  Status = GetNumber (
             L"--lifebyte",
             (UINT64) -1,
             &(*Data)->SaLifetime.ByteCount,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFEBYTE;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--lifetime",
             (UINT64) -1,
             &(*Data)->SaLifetime.HardLifetime,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFETIME;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--lifetime-soft",
             (UINT64) -1,
             &(*Data)->SaLifetime.SoftLifetime,
             sizeof (UINT64),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= LIFETIME_SOFT;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--path-mtu",
             (UINT32) -1,
             &(*Data)->PathMTU,
             sizeof (UINT32),
             NULL,
             ParamPackage,
             FORMAT_NUMBER
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= PATH_MTU;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  //
  // Convert user imput from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-dest");
  if (ValueStr != NULL) {
    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelDestinationAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--tunnel-dest",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= DEST;
    }
  }

  //
  // Convert user input from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-source");
  if (ValueStr != NULL) {
    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelSourceAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--tunnel-source",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= SOURCE;
    }
  }

  //
  // If it is TunnelMode, then check if the tunnel-source and --tunnel-dest are set
  //
  if ((*Data)->Mode == EfiIPsecTunnel) {
    if ((*Mask & (DEST|SOURCE)) != (DEST|SOURCE)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--tunnel-source --tunnel-dest"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    }
  }
  ReturnStatus = CreateSpdSelector ((*Data)->SpdSelector, ParamPackage, Mask);

  if (CreateNew) {
    if ((*Mask & (SPI|IPSEC_PROTO|LOCAL|REMOTE)) != (SPI|IPSEC_PROTO|LOCAL|REMOTE)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--spi --ipsec-proto --local --remote"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      if ((*SaId)->Proto == EfiIPsecAH) {
        if ((*Mask & AUTH_ALGO) == 0) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
            mHiiHandle,
            mAppName,
            L"--auth-algo"
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
            mHiiHandle,
            mAppName,
            L"--auth-key"
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        }
      } else {
        if ((*Mask & (ENCRYPT_ALGO|AUTH_ALGO)) != (ENCRYPT_ALGO|AUTH_ALGO) ) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
            mHiiHandle,
            mAppName,
            L"--encrypt-algo --auth-algo"
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        } else if ((*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (*Mask & ENCRYPT_KEY) == 0) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
            mHiiHandle,
            mAppName,
            L"--encrypt-key"
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
            mHiiHandle,
            mAppName,
            L"--auth-key"
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        }
      }
    }
  }

  return ReturnStatus;
}

/**
  Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA through ParamPackage list.

  @param[out] PadId           The pointer to the EFI_IPSEC_PAD_ID structure.
  @param[out] Data            The pointer to the EFI_IPSEC_PAD_DATA structure.
  @param[in]  ParamPackage    The pointer to the ParamPackage list.
  @param[out] Mask            The pointer to the Mask.
  @param[in]  CreateNew       The switch to create new.

  @retval EFI_SUCCESS              Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CreatePadEntry (
  OUT EFI_IPSEC_PAD_ID      **PadId,
  OUT EFI_IPSEC_PAD_DATA    **Data,
  IN  LIST_ENTRY            *ParamPackage,
  OUT UINT32                *Mask,
  IN  BOOLEAN               CreateNew
  )
{
  EFI_STATUS         Status;
  EFI_STATUS         ReturnStatus;
  SHELL_FILE_HANDLE  FileHandle;
  UINT64             FileSize;
  UINTN              AuthDataLength;
  UINTN              RevocationDataLength;
  UINTN              DataLength;
  UINTN              Index;
  CONST CHAR16       *ValueStr;
  UINTN              DataSize;

  Status               = EFI_SUCCESS;
  ReturnStatus         = EFI_SUCCESS;
  *Mask                = 0;
  AuthDataLength       = 0;
  RevocationDataLength = 0;

  *PadId = AllocateZeroPool (sizeof (EFI_IPSEC_PAD_ID));
  ASSERT (*PadId != NULL);

  //
  // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_ID.
  //
  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-address");
  if (ValueStr != NULL) {
    (*PadId)->PeerIdValid = FALSE;
    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &(*PadId)->Id.IpAddress);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
        mHiiHandle,
        mAppName,
        L"--peer-address",
        ValueStr
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else {
      *Mask |= PEER_ADDRESS;
    }
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-id");
  if (ValueStr != NULL) {
    (*PadId)->PeerIdValid = TRUE;
    StrnCpyS ((CHAR16 *) (*PadId)->Id.PeerId, MAX_PEERID_LEN / sizeof (CHAR16), ValueStr, MAX_PEERID_LEN / sizeof (CHAR16) - 1);
    *Mask |= PEER_ID;
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
  if (ValueStr != NULL) {
    if (ValueStr[0] == L'@') {
      //
      // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
      //
      Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
          mHiiHandle,
          mAppName,
          &ValueStr[1]
          );
        ReturnStatus = EFI_INVALID_PARAMETER;
      } else {
        Status = ShellGetFileSize (FileHandle, &FileSize);
        ShellCloseFile (&FileHandle);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
            mHiiHandle,
            mAppName,
            &ValueStr[1]
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
        } else {
          AuthDataLength = (UINTN) FileSize;
        }
      }
    } else {
      AuthDataLength = StrLen (ValueStr);
    }
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
  if (ValueStr != NULL) {
    RevocationDataLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);
  }

  //
  // Allocate Buffer for Data. Add padding after each struct to make sure the alignment
  // in different Arch.
  //
  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));
  DataSize  = ALIGN_VARIABLE (DataSize + AuthDataLength);
  DataSize += RevocationDataLength;

  *Data = AllocateZeroPool (DataSize);
  ASSERT (*Data != NULL);

  (*Data)->AuthData       = (VOID *) ALIGN_POINTER ((*Data + 1), sizeof (UINTN));
  (*Data)->RevocationData = (VOID *) ALIGN_POINTER (((UINT8 *) (*Data + 1) + AuthDataLength), sizeof (UINTN));
  (*Data)->AuthProtocol   = EfiIPsecAuthProtocolIKEv1;

  //
  // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_DATA.
  //
  Status = GetNumber (
             L"--auth-proto",
             0,
             &(*Data)->AuthProtocol,
             sizeof (EFI_IPSEC_AUTH_PROTOCOL_TYPE),
             mMapAuthProto,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= AUTH_PROTO;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  Status = GetNumber (
             L"--auth-method",
             0,
             &(*Data)->AuthMethod,
             sizeof (EFI_IPSEC_AUTH_METHOD),
             mMapAuthMethod,
             ParamPackage,
             FORMAT_STRING
             );
  if (!EFI_ERROR (Status)) {
    *Mask |= AUTH_METHOD;
  }

  if (Status == EFI_INVALID_PARAMETER) {
    ReturnStatus = EFI_INVALID_PARAMETER;
  }

  if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id")) {
    (*Data)->IkeIdFlag = TRUE;
    *Mask |= IKE_ID;
  }

  if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id-")) {
    (*Data)->IkeIdFlag = FALSE;
    *Mask |= IKE_ID;
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
  if (ValueStr != NULL) {
    if (ValueStr[0] == L'@') {
      //
      // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
      //

      Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
          mHiiHandle,
          mAppName,
          &ValueStr[1]
          );
        ReturnStatus = EFI_INVALID_PARAMETER;
        (*Data)->AuthData = NULL;
      } else {
        DataLength = AuthDataLength;
        Status     = ShellReadFile (FileHandle, &DataLength, (*Data)->AuthData);
        ShellCloseFile (&FileHandle);
        if (EFI_ERROR (Status)) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
            mHiiHandle,
            mAppName,
            &ValueStr[1]
            );
          ReturnStatus = EFI_INVALID_PARAMETER;
          (*Data)->AuthData = NULL;
        } else {
          ASSERT (DataLength == AuthDataLength);
          *Mask |= AUTH_DATA;
        }
      }
    } else {
      for (Index = 0; Index < AuthDataLength; Index++) {
        ((CHAR8 *) (*Data)->AuthData)[Index] = (CHAR8) ValueStr[Index];
      }
      (*Data)->AuthDataSize = AuthDataLength;
      *Mask |= AUTH_DATA;
    }
  }

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
  if (ValueStr != NULL) {
    CopyMem ((*Data)->RevocationData, ValueStr, RevocationDataLength);
    (*Data)->RevocationDataSize = RevocationDataLength;
    *Mask |= REVOCATION_DATA;
  } else {
    (*Data)->RevocationData = NULL;
  }

  if (CreateNew) {
    if ((*Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--peer-id --peer-address"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    } else if ((*Mask & (AUTH_METHOD | AUTH_DATA)) != (AUTH_METHOD | AUTH_DATA)) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
        mHiiHandle,
        mAppName,
        L"--auth-method --auth-data"
        );
      ReturnStatus = EFI_INVALID_PARAMETER;
    }
  }

  return ReturnStatus;
}

CREATE_POLICY_ENTRY mCreatePolicyEntry[] = {
  (CREATE_POLICY_ENTRY) CreateSpdEntry,
  (CREATE_POLICY_ENTRY) CreateSadEntry,
  (CREATE_POLICY_ENTRY) CreatePadEntry
};

/**
  Combine old SPD entry with new SPD entry.

  @param[in, out] OldSelector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[in, out] OldData        The pointer to the EFI_IPSEC_SPD_DATA structure.
  @param[in]      NewSelector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[in]      NewData        The pointer to the EFI_IPSEC_SPD_DATA structure.
  @param[in]      Mask           The pointer to the Mask.
  @param[out]     CreateNew      The switch to create new.

  @retval EFI_SUCCESS              Combined successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CombineSpdEntry (
  IN OUT EFI_IPSEC_SPD_SELECTOR    *OldSelector,
  IN OUT EFI_IPSEC_SPD_DATA        *OldData,
  IN     EFI_IPSEC_SPD_SELECTOR    *NewSelector,
  IN     EFI_IPSEC_SPD_DATA        *NewData,
  IN     UINT32                    Mask,
     OUT BOOLEAN                   *CreateNew
  )
{

  //
  // Process Selector
  //
  *CreateNew = FALSE;
  if ((Mask & LOCAL) == 0) {
    NewSelector->LocalAddressCount = OldSelector->LocalAddressCount;
    NewSelector->LocalAddress      = OldSelector->LocalAddress;
  } else if ((NewSelector->LocalAddressCount != OldSelector->LocalAddressCount) ||
             (CompareMem (NewSelector->LocalAddress, OldSelector->LocalAddress, NewSelector->LocalAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
    *CreateNew = TRUE;
  }

  if ((Mask & REMOTE) == 0) {
    NewSelector->RemoteAddressCount = OldSelector->RemoteAddressCount;
    NewSelector->RemoteAddress      = OldSelector->RemoteAddress;
  } else if ((NewSelector->RemoteAddressCount != OldSelector->RemoteAddressCount) ||
             (CompareMem (NewSelector->RemoteAddress, OldSelector->RemoteAddress, NewSelector->RemoteAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
    *CreateNew = TRUE;
  }

  if ((Mask & PROTO) == 0) {
    NewSelector->NextLayerProtocol = OldSelector->NextLayerProtocol;
  } else if (NewSelector->NextLayerProtocol != OldSelector->NextLayerProtocol) {
    *CreateNew = TRUE;
  }

  switch (NewSelector->NextLayerProtocol) {
    case EFI_IP4_PROTO_TCP:
    case EFI_IP4_PROTO_UDP:
      if ((Mask & LOCAL_PORT) == 0) {
        NewSelector->LocalPort      = OldSelector->LocalPort;
        NewSelector->LocalPortRange = OldSelector->LocalPortRange;
      } else if ((NewSelector->LocalPort != OldSelector->LocalPort) ||
        (NewSelector->LocalPortRange != OldSelector->LocalPortRange)) {
        *CreateNew = TRUE;
      }

      if ((Mask & REMOTE_PORT) == 0) {
        NewSelector->RemotePort      = OldSelector->RemotePort;
        NewSelector->RemotePortRange = OldSelector->RemotePortRange;
      } else if ((NewSelector->RemotePort != OldSelector->RemotePort) ||
        (NewSelector->RemotePortRange != OldSelector->RemotePortRange)) {
        *CreateNew = TRUE;
      }
      break;

    case EFI_IP4_PROTO_ICMP:
      if ((Mask & ICMP_TYPE) == 0) {
        NewSelector->LocalPort = OldSelector->LocalPort;
      } else if (NewSelector->LocalPort != OldSelector->LocalPort) {
        *CreateNew = TRUE;
      }

      if ((Mask & ICMP_CODE) == 0) {
        NewSelector->RemotePort = OldSelector->RemotePort;
      } else if (NewSelector->RemotePort != OldSelector->RemotePort) {
        *CreateNew = TRUE;
      }
      break;
  }
  //
  // Process Data
  //
  OldData->SaIdCount = 0;

  if ((Mask & NAME) != 0) {
    AsciiStrCpyS ((CHAR8 *) OldData->Name, MAX_PEERID_LEN, (CHAR8 *) NewData->Name);
  }

  if ((Mask & PACKET_FLAG) != 0) {
    OldData->PackageFlag = NewData->PackageFlag;
  }

  if ((Mask & ACTION) != 0) {
    OldData->Action = NewData->Action;
  }

  if (OldData->Action != EfiIPsecActionProtect) {
    OldData->ProcessingPolicy = NULL;
  } else {
    //
    // Protect
    //
    if (OldData->ProcessingPolicy == NULL) {
      //
      // Just point to new data if originally NULL.
      //
      OldData->ProcessingPolicy = NewData->ProcessingPolicy;
      if (OldData->ProcessingPolicy->Mode == EfiIPsecTunnel &&
          (Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)
        ) {
        //
        // Change to Protect action and Tunnel mode, but without providing local/remote tunnel address.
        //
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
          mHiiHandle,
          mAppName,
          L"--tunnel-local --tunnel-remote"
          );
        return EFI_INVALID_PARAMETER;
      }
    } else {
      //
      // Modify some of the data.
      //
      if ((Mask & EXT_SEQUENCE) != 0) {
        OldData->ProcessingPolicy->ExtSeqNum = NewData->ProcessingPolicy->ExtSeqNum;
      }

      if ((Mask & SEQUENCE_OVERFLOW) != 0) {
        OldData->ProcessingPolicy->SeqOverflow = NewData->ProcessingPolicy->SeqOverflow;
      }

      if ((Mask & FRAGMENT_CHECK) != 0) {
        OldData->ProcessingPolicy->FragCheck = NewData->ProcessingPolicy->FragCheck;
      }

      if ((Mask & LIFEBYTE) != 0) {
        OldData->ProcessingPolicy->SaLifetime.ByteCount = NewData->ProcessingPolicy->SaLifetime.ByteCount;
      }

      if ((Mask & LIFETIME_SOFT) != 0) {
        OldData->ProcessingPolicy->SaLifetime.SoftLifetime = NewData->ProcessingPolicy->SaLifetime.SoftLifetime;
      }

      if ((Mask & LIFETIME) != 0) {
        OldData->ProcessingPolicy->SaLifetime.HardLifetime = NewData->ProcessingPolicy->SaLifetime.HardLifetime;
      }

      if ((Mask & MODE) != 0) {
        OldData->ProcessingPolicy->Mode = NewData->ProcessingPolicy->Mode;
      }

      if ((Mask & IPSEC_PROTO) != 0) {
        OldData->ProcessingPolicy->Proto = NewData->ProcessingPolicy->Proto;
      }

      if ((Mask & AUTH_ALGO) != 0) {
        OldData->ProcessingPolicy->AuthAlgoId = NewData->ProcessingPolicy->AuthAlgoId;
      }

      if ((Mask & ENCRYPT_ALGO) != 0) {
        OldData->ProcessingPolicy->EncAlgoId = NewData->ProcessingPolicy->EncAlgoId;
      }

      if (OldData->ProcessingPolicy->Mode != EfiIPsecTunnel) {
        OldData->ProcessingPolicy->TunnelOption = NULL;
      } else {
        if (OldData->ProcessingPolicy->TunnelOption == NULL) {
          //
          // Set from Transport mode to Tunnel mode, should ensure TUNNEL_LOCAL & TUNNEL_REMOTE both exists.
          //
          if ((Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)) {
            ShellPrintHiiEx (
              -1,
              -1,
              NULL,
              STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
              mHiiHandle,
              mAppName,
              L"--tunnel-local --tunnel-remote"
              );
            return EFI_INVALID_PARAMETER;
          }

          OldData->ProcessingPolicy->TunnelOption = NewData->ProcessingPolicy->TunnelOption;
        } else {
          if ((Mask & TUNNEL_LOCAL) != 0) {
            CopyMem (
              &OldData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
              &NewData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
              sizeof (EFI_IP_ADDRESS)
              );
          }

          if ((Mask & TUNNEL_REMOTE) != 0) {
            CopyMem (
              &OldData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
              &NewData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
              sizeof (EFI_IP_ADDRESS)
              );
          }

          if ((Mask & DONT_FRAGMENT) != 0) {
            OldData->ProcessingPolicy->TunnelOption->DF = NewData->ProcessingPolicy->TunnelOption->DF;
          }
        }
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Combine old SAD entry with new SAD entry.

  @param[in, out] OldSaId      The pointer to the EFI_IPSEC_SA_ID structure.
  @param[in, out] OldData      The pointer to the EFI_IPSEC_SA_DATA2 structure.
  @param[in]      NewSaId      The pointer to the EFI_IPSEC_SA_ID structure.
  @param[in]      NewData      The pointer to the EFI_IPSEC_SA_DATA2 structure.
  @param[in]      Mask         The pointer to the Mask.
  @param[out]     CreateNew    The switch to create new.

  @retval EFI_SUCCESS              Combined successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CombineSadEntry (
  IN OUT EFI_IPSEC_SA_ID      *OldSaId,
  IN OUT EFI_IPSEC_SA_DATA2   *OldData,
  IN     EFI_IPSEC_SA_ID      *NewSaId,
  IN     EFI_IPSEC_SA_DATA2   *NewData,
  IN     UINT32               Mask,
     OUT BOOLEAN              *CreateNew
  )
{

  *CreateNew = FALSE;

  if ((Mask & SPI) == 0) {
    NewSaId->Spi = OldSaId->Spi;
  } else if (NewSaId->Spi != OldSaId->Spi) {
    *CreateNew = TRUE;
  }

  if ((Mask & IPSEC_PROTO) == 0) {
    NewSaId->Proto = OldSaId->Proto;
  } else if (NewSaId->Proto != OldSaId->Proto) {
    *CreateNew = TRUE;
  }

  if ((Mask & DEST) == 0) {
    CopyMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS));
  } else if (CompareMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS)) != 0) {
    *CreateNew = TRUE;
  }

  if ((Mask & SOURCE) == 0) {
    CopyMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS));
  } else if (CompareMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS)) != 0) {
    *CreateNew = TRUE;
  }
  //
  // Process SA_DATA.
  //
  if ((Mask & MODE) != 0) {
    OldData->Mode = NewData->Mode;
  }

  if ((Mask & SEQUENCE_NUMBER) != 0) {
    OldData->SNCount = NewData->SNCount;
  }

  if ((Mask & ANTIREPLAY_WINDOW) != 0) {
    OldData->AntiReplayWindows = NewData->AntiReplayWindows;
  }

  if ((Mask & AUTH_ALGO) != 0) {
    OldData->AlgoInfo.EspAlgoInfo.AuthAlgoId    = NewData->AlgoInfo.EspAlgoInfo.AuthAlgoId;
  }

  if ((Mask & AUTH_KEY) != 0) {
    OldData->AlgoInfo.EspAlgoInfo.AuthKey       = NewData->AlgoInfo.EspAlgoInfo.AuthKey;
    OldData->AlgoInfo.EspAlgoInfo.AuthKeyLength = NewData->AlgoInfo.EspAlgoInfo.AuthKeyLength;
  }

  if ((Mask & ENCRYPT_ALGO) != 0) {
    OldData->AlgoInfo.EspAlgoInfo.EncAlgoId     = NewData->AlgoInfo.EspAlgoInfo.EncAlgoId;
  }

  if ((Mask & ENCRYPT_KEY) != 0) {
    OldData->AlgoInfo.EspAlgoInfo.EncKey        = NewData->AlgoInfo.EspAlgoInfo.EncKey;
    OldData->AlgoInfo.EspAlgoInfo.EncKeyLength  = NewData->AlgoInfo.EspAlgoInfo.EncKeyLength;
  }

  if (NewSaId->Proto == EfiIPsecAH) {
    if ((Mask & (ENCRYPT_ALGO | ENCRYPT_KEY)) != 0) {
      //
      // Should not provide encrypt_* if AH.
      //
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_UNWANTED_PARAMETER),
        mHiiHandle,
        mAppName,
        L"--encrypt-algo --encrypt-key"
        );
      return EFI_INVALID_PARAMETER;
    }
  }

  if (NewSaId->Proto == EfiIPsecESP && OldSaId->Proto == EfiIPsecAH) {
    //
    // AH -> ESP
    // Should provide encrypt_algo at least.
    //
    if ((Mask & ENCRYPT_ALGO) == 0) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
        mHiiHandle,
        mAppName,
        L"--encrypt-algo"
        );
      return EFI_INVALID_PARAMETER;
    }

    //
    // Encrypt_key should be provided if algorithm is not NONE.
    //
    if (NewData->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (Mask & ENCRYPT_KEY) == 0) {
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
        mHiiHandle,
        mAppName,
        L"--encrypt-algo"
        );
      return EFI_INVALID_PARAMETER;
    }
  }

  if ((Mask & LIFEBYTE) != 0) {
    OldData->SaLifetime.ByteCount    = NewData->SaLifetime.ByteCount;
  }

  if ((Mask & LIFETIME_SOFT) != 0) {
    OldData->SaLifetime.SoftLifetime = NewData->SaLifetime.SoftLifetime;
  }

  if ((Mask & LIFETIME) != 0) {
    OldData->SaLifetime.HardLifetime = NewData->SaLifetime.HardLifetime;
  }

  if ((Mask & PATH_MTU) != 0) {
    OldData->PathMTU                 = NewData->PathMTU;
  }
  //
  // Process SpdSelector.
  //
  if (OldData->SpdSelector == NULL) {
    if ((Mask & (LOCAL | REMOTE | PROTO | LOCAL_PORT | REMOTE_PORT | ICMP_TYPE | ICMP_CODE)) != 0) {
      if ((Mask & (LOCAL | REMOTE | PROTO)) != (LOCAL | REMOTE | PROTO)) {
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
          mHiiHandle,
          mAppName,
          L"--local --remote --proto"
          );
        return EFI_INVALID_PARAMETER;
      }

      OldData->SpdSelector = NewData->SpdSelector;
    }
  } else {
    if ((Mask & LOCAL) != 0) {
      OldData->SpdSelector->LocalAddressCount  = NewData->SpdSelector->LocalAddressCount;
      OldData->SpdSelector->LocalAddress       = NewData->SpdSelector->LocalAddress;
    }

    if ((Mask & REMOTE) != 0) {
      OldData->SpdSelector->RemoteAddressCount = NewData->SpdSelector->RemoteAddressCount;
      OldData->SpdSelector->RemoteAddress      = NewData->SpdSelector->RemoteAddress;
    }

    if ((Mask & PROTO) != 0) {
      OldData->SpdSelector->NextLayerProtocol  = NewData->SpdSelector->NextLayerProtocol;
    }

    if (OldData->SpdSelector != NULL) {
      switch (OldData->SpdSelector->NextLayerProtocol) {
        case EFI_IP4_PROTO_TCP:
        case EFI_IP4_PROTO_UDP:
          if ((Mask & LOCAL_PORT) != 0) {
            OldData->SpdSelector->LocalPort  = NewData->SpdSelector->LocalPort;
          }

          if ((Mask & REMOTE_PORT) != 0) {
            OldData->SpdSelector->RemotePort = NewData->SpdSelector->RemotePort;
          }
          break;

        case EFI_IP4_PROTO_ICMP:
          if ((Mask & ICMP_TYPE) != 0) {
            OldData->SpdSelector->LocalPort  = (UINT8) NewData->SpdSelector->LocalPort;
          }

          if ((Mask & ICMP_CODE) != 0) {
            OldData->SpdSelector->RemotePort = (UINT8) NewData->SpdSelector->RemotePort;
          }
          break;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Combine old PAD entry with new PAD entry.

  @param[in, out] OldPadId     The pointer to the EFI_IPSEC_PAD_ID structure.
  @param[in, out] OldData      The pointer to the EFI_IPSEC_PAD_DATA structure.
  @param[in]      NewPadId     The pointer to the EFI_IPSEC_PAD_ID structure.
  @param[in]      NewData      The pointer to the EFI_IPSEC_PAD_DATA structure.
  @param[in]      Mask         The pointer to the Mask.
  @param[out]     CreateNew    The switch to create new.

  @retval EFI_SUCCESS              Combined successfully.
  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.

**/
EFI_STATUS
CombinePadEntry (
  IN OUT EFI_IPSEC_PAD_ID      *OldPadId,
  IN OUT EFI_IPSEC_PAD_DATA    *OldData,
  IN     EFI_IPSEC_PAD_ID      *NewPadId,
  IN     EFI_IPSEC_PAD_DATA    *NewData,
  IN     UINT32                Mask,
     OUT BOOLEAN               *CreateNew
  )
{

  *CreateNew = FALSE;

  if ((Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
    CopyMem (NewPadId, OldPadId, sizeof (EFI_IPSEC_PAD_ID));
  } else {
    if ((Mask & PEER_ID) != 0) {
      if (OldPadId->PeerIdValid) {
        if (StrCmp ((CONST CHAR16 *) OldPadId->Id.PeerId, (CONST CHAR16 *) NewPadId->Id.PeerId) != 0) {
          *CreateNew = TRUE;
        }
      } else {
        *CreateNew = TRUE;
      }
    } else {
      //
      // MASK & PEER_ADDRESS
      //
      if (OldPadId->PeerIdValid) {
        *CreateNew = TRUE;
      } else {
        if ((CompareMem (&OldPadId->Id.IpAddress.Address, &NewPadId->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0) ||
            (OldPadId->Id.IpAddress.PrefixLength != NewPadId->Id.IpAddress.PrefixLength)) {
          *CreateNew = TRUE;
        }
      }
    }
  }

  if ((Mask & AUTH_PROTO) != 0) {
    OldData->AuthProtocol = NewData->AuthProtocol;
  }

  if ((Mask & AUTH_METHOD) != 0) {
    OldData->AuthMethod = NewData->AuthMethod;
  }

  if ((Mask & IKE_ID) != 0) {
    OldData->IkeIdFlag = NewData->IkeIdFlag;
  }

  if ((Mask & AUTH_DATA) != 0) {
    OldData->AuthDataSize = NewData->AuthDataSize;
    OldData->AuthData     = NewData->AuthData;
  }

  if ((Mask & REVOCATION_DATA) != 0) {
    OldData->RevocationDataSize = NewData->RevocationDataSize;
    OldData->RevocationData     = NewData->RevocationData;
  }

  return EFI_SUCCESS;
}

COMBINE_POLICY_ENTRY mCombinePolicyEntry[] = {
  (COMBINE_POLICY_ENTRY) CombineSpdEntry,
  (COMBINE_POLICY_ENTRY) CombineSadEntry,
  (COMBINE_POLICY_ENTRY) CombinePadEntry
};

/**
  Edit entry information in the database.

  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
  @param[in] Data        The pointer to the data.
  @param[in] Context     The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.

  @retval EFI_SUCCESS    Continue the iteration.
  @retval EFI_ABORTED    Abort the iteration.
**/
EFI_STATUS
EditOperatePolicyEntry (
  IN EFI_IPSEC_CONFIG_SELECTOR    *Selector,
  IN VOID                         *Data,
  IN EDIT_POLICY_ENTRY_CONTEXT    *Context
  )
{
  EFI_STATUS    Status;
  BOOLEAN       CreateNew;

  if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
    ASSERT (Context->DataType < 3);

    Status = mCombinePolicyEntry[Context->DataType] (
               Selector,
               Data,
               Context->Selector,
               Context->Data,
               Context->Mask,
               &CreateNew
               );
    if (!EFI_ERROR (Status)) {
      //
      // If the Selector already existed, this Entry will be updated by set data.
      //
      Status = mIpSecConfig->SetData (
                               mIpSecConfig,
                               Context->DataType,
                               Context->Selector, /// New created selector.
                               Data, /// Old date which has been modified, need to be set data.
                               Selector
                               );
      ASSERT_EFI_ERROR (Status);
      
      if (CreateNew) {
        //
        // Edit the entry to a new one. So, we need delete the old entry.
        //
        Status = mIpSecConfig->SetData (
                                 mIpSecConfig,
                                 Context->DataType,
                                 Selector, /// Old selector.
                                 NULL, /// NULL means to delete this Entry specified by Selector.
                                 NULL
                                 );
        ASSERT_EFI_ERROR (Status);
      }
    }

    Context->Status = Status;
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Edit entry information in database according to datatype.

  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.
  @param[in] ParamPackage    The pointer to the ParamPackage list.

  @retval EFI_SUCCESS             Edit entry information successfully.
  @retval EFI_NOT_FOUND           Can't find the specified entry.
  @retval Others                  Some mistaken case.
**/
EFI_STATUS
EditPolicyEntry (
  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,
  IN LIST_ENTRY                    *ParamPackage
  )
{
  EFI_STATUS                   Status;
  EDIT_POLICY_ENTRY_CONTEXT    Context;
  CONST CHAR16                 *ValueStr;

  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
  if (ValueStr == NULL) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
    return EFI_NOT_FOUND;
  }

  Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
  if (!EFI_ERROR (Status)) {
    Context.DataType = DataType;
    Context.Status   = EFI_NOT_FOUND;
    Status = mCreatePolicyEntry[DataType] (&Context.Selector, &Context.Data, ParamPackage, &Context.Mask, FALSE);
    if (!EFI_ERROR (Status)) {
      ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) EditOperatePolicyEntry, &Context);
      Status = Context.Status;
    }

    if (Context.Selector != NULL) {
      gBS->FreePool (Context.Selector);
    }

    if (Context.Data != NULL) {
      gBS->FreePool (Context.Data);
    }
  }

  if (Status == EFI_NOT_FOUND) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
  } else if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_EDIT_FAILED), mHiiHandle, mAppName);
  }

  return Status;

}

/**
  Insert entry information in database.

  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
  @param[in] Data        The pointer to the data.
  @param[in] Context     The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.

  @retval EFI_SUCCESS    Continue the iteration.
  @retval EFI_ABORTED    Abort the iteration.
**/
EFI_STATUS
InsertPolicyEntry (
  IN EFI_IPSEC_CONFIG_SELECTOR      *Selector,
  IN VOID                           *Data,
  IN INSERT_POLICY_ENTRY_CONTEXT    *Context
  )
{
  //
  // Found the entry which we want to insert before.
  //
  if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {

    Context->Status = mIpSecConfig->SetData (
                                      mIpSecConfig,
                                      Context->DataType,
                                      Context->Selector,
                                      Context->Data,
                                      Selector
                                      );
    //
    // Abort the iteration after the insertion.
    //
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Insert or add entry information in database according to datatype.

  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.
  @param[in] ParamPackage    The pointer to the ParamPackage list.

  @retval EFI_SUCCESS             Insert or add entry information successfully.
  @retval EFI_NOT_FOUND           Can't find the specified entry.
  @retval EFI_BUFFER_TOO_SMALL    The entry already existed.
  @retval EFI_UNSUPPORTED         The operation is not supported.
  @retval Others                  Some mistaken case.
**/
EFI_STATUS
AddOrInsertPolicyEntry (
  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,
  IN LIST_ENTRY                    *ParamPackage
  )
{
  EFI_STATUS                     Status;
  EFI_IPSEC_CONFIG_SELECTOR      *Selector;
  VOID                           *Data;
  INSERT_POLICY_ENTRY_CONTEXT    Context;
  UINT32                         Mask;
  UINTN                          DataSize;
  CONST CHAR16                   *ValueStr;

  Status = mCreatePolicyEntry[DataType] (&Selector, &Data, ParamPackage, &Mask, TRUE);
  if (!EFI_ERROR (Status)) {
    //
    // Find if the Selector to be inserted already exists.
    //
    DataSize = 0;
    Status = mIpSecConfig->GetData (
                             mIpSecConfig,
                             DataType,
                             Selector,
                             &DataSize,
                             NULL
                             );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_EXISTS), mHiiHandle, mAppName);
    } else if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {
      Status = mIpSecConfig->SetData (
                               mIpSecConfig,
                               DataType,
                               Selector,
                               Data,
                               NULL
                               );
    } else {
      ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
      if (ValueStr == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
        return EFI_NOT_FOUND;
      }

      Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
      if (!EFI_ERROR (Status)) {
        Context.DataType  = DataType;
        Context.Status    = EFI_NOT_FOUND;
        Context.Selector  = Selector;
        Context.Data      = Data;

        ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) InsertPolicyEntry, &Context);
        Status = Context.Status;
        if (Status == EFI_NOT_FOUND) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
        }
      }
    }

    gBS->FreePool (Selector);
    gBS->FreePool (Data);
  }

  if (Status == EFI_UNSUPPORTED) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_UNSUPPORT), mHiiHandle, mAppName);
  } else if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_FAILED), mHiiHandle, mAppName);
  }

  return Status;
}
