/** @file
  Provide IPsec Key Exchange (IKE) service general interfaces.

  Copyright (c) 2010 - 2018, 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 "IkeService.h"
#include "IpSecConfigImpl.h"

IKE_EXCHANGE_INTERFACE  *mIkeExchange[] = {
  &mIkev1Exchange,
  &mIkev2Exchange
};

EFI_UDP4_CONFIG_DATA    mUdp4Conf = {
  FALSE,
  FALSE,
  FALSE,
  TRUE,
  //
  // IO parameters
  //
  0,
  64,
  FALSE,
  0,
  1000000,
  FALSE,
  {{0,0,0,0}},
  {{0,0,0,0}},
  IKE_DEFAULT_PORT,
  {{0,0,0,0}},
  0
};

EFI_UDP6_CONFIG_DATA    mUdp6Conf = {
  FALSE,
  FALSE,
  TRUE,
  //
  // IO parameters
  //
  0,
  128,
  0,
  1000000,
  //Access Point
  {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
  IKE_DEFAULT_PORT,
  {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
  0
};

/**
  Check if the NIC handle is binded to a Udp service.

  @param[in]  Private    Pointer of IPSEC_PRIVATE_DATA.
  @param[in]  Handle     The Handle of the NIC card.
  @param[in]  IpVersion  The version of the IP stack.

  @return a pointer of IKE_UDP_SERVICE.

**/
IKE_UDP_SERVICE *
IkeLookupUdp (
  IN IPSEC_PRIVATE_DATA     *Private,
  IN EFI_HANDLE             Handle,
  IN UINT8                  IpVersion
  )
{
  LIST_ENTRY      *Head;
  LIST_ENTRY      *Entry;
  LIST_ENTRY      *Next;
  IKE_UDP_SERVICE *Udp;

  Udp   = NULL;
  Head  = (IpVersion == IP_VERSION_4) ? &Private->Udp4List : &Private->Udp6List;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {

    Udp = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
    //
    // Find the right udp service which installed on the appointed NIC handle.
    //
    if (Handle == Udp->NicHandle) {
      break;
    } else {
      Udp = NULL;
    }
  }

  return Udp;
}

/**
  Configure a UDPIO's UDP4 instance.

  This fuction is called by the UdpIoCreateIo() to configures a
  UDP4 instance.

  @param[in] UdpIo         The UDP_IO to be configured.
  @param[in] Context       User-defined data when calling UdpIoCreateIo().

  @retval EFI_SUCCESS      The configuration succeeded.
  @retval Others           The UDP4 instance fails to configure.

**/
EFI_STATUS
EFIAPI
IkeConfigUdp4 (
  IN UDP_IO                 *UdpIo,
  IN VOID                   *Context
  )
{
  EFI_UDP4_CONFIG_DATA  Udp4Cfg;
  EFI_UDP4_PROTOCOL     *Udp4;

  ZeroMem (&Udp4Cfg, sizeof (EFI_UDP4_CONFIG_DATA));

  Udp4 = UdpIo->Protocol.Udp4;
  CopyMem (
    &Udp4Cfg,
    &mUdp4Conf,
    sizeof (EFI_UDP4_CONFIG_DATA)
    );

  if (Context != NULL) {
    //
    // Configure udp4 io with local default address.
    //
    Udp4Cfg.UseDefaultAddress = TRUE;
  }

  return Udp4->Configure (Udp4, &Udp4Cfg);
}

/**
  Configure a UDPIO's UDP6 instance.

  This fuction is called by the UdpIoCreateIo()to configure a
  UDP6 instance.

  @param[in] UdpIo         The UDP_IO to be configured.
  @param[in] Context       User-defined data when calling UdpIoCreateIo().

  @retval EFI_SUCCESS      The configuration succeeded.
  @retval Others           The configuration fails.

**/
EFI_STATUS
EFIAPI
IkeConfigUdp6 (
  IN UDP_IO                 *UdpIo,
  IN VOID                   *Context
  )
{
  EFI_UDP6_PROTOCOL     *Udp6;
  EFI_UDP6_CONFIG_DATA  Udp6Cfg;

  ZeroMem (&Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));

  Udp6 = UdpIo->Protocol.Udp6;
  CopyMem (
    &Udp6Cfg,
    &mUdp6Conf,
    sizeof (EFI_UDP6_CONFIG_DATA)
    );

  if (Context != NULL) {
    //
    // Configure instance with a destination address to start source address
    // selection, and then get the configure data from the mode data to store
    // the source address.
    //
    CopyMem (
      &Udp6Cfg.RemoteAddress,
      Context,
      sizeof (EFI_IPv6_ADDRESS)
      );
  }

  return Udp6->Configure (Udp6, &Udp6Cfg);
}

/**
  Open and configure the related output UDPIO for IKE packet sending.

  If the UdpService is not configured, this fuction calls UdpIoCreatIo() to
  create UDPIO to bind this UdpService for IKE packet sending. If the UdpService
  has already been configured, then return.

  @param[in] UdpService     The UDP_IO to be configured.
  @param[in] RemoteIp       User-defined data when calling UdpIoCreateIo().

  @retval EFI_SUCCESS      The configuration is successful.
  @retval Others           The configuration fails.

**/
EFI_STATUS
IkeOpenOutputUdp (
  IN IKE_UDP_SERVICE           *UdpService,
  IN EFI_IP_ADDRESS            *RemoteIp
  )
{
  EFI_STATUS                       Status;
  EFI_IP4_CONFIG2_PROTOCOL         *Ip4Cfg2;
  EFI_IP4_CONFIG2_INTERFACE_INFO   *IfInfo;
  UINTN                            BufSize;
  EFI_IP6_MODE_DATA                Ip6ModeData;
  EFI_UDP6_PROTOCOL                *Udp6;

  Status      = EFI_SUCCESS;
  IfInfo      = NULL;
  BufSize     = 0;

  //
  // Check whether the input and output udp io are both configured.
  //
  if (UdpService->IsConfigured) {
    goto ON_EXIT;
  }

  if (UdpService->IpVersion == UDP_IO_UDP4_VERSION) {
    //
    // Handle ip4config protocol to get local default address.
    //
    Status = gBS->HandleProtocol (
                    UdpService->NicHandle,
                    &gEfiIp4Config2ProtocolGuid,
                    (VOID **) &Ip4Cfg2
                    );

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    //
    // Get the interface information size.
    //
    Status = Ip4Cfg2->GetData (
                       Ip4Cfg2,
                       Ip4Config2DataTypeInterfaceInfo,
                       &BufSize,
                       NULL
                       );

    if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
      goto ON_EXIT;
    }

    IfInfo = AllocateZeroPool (BufSize);

    if (IfInfo == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    //
    // Get the interface info.
    //
    Status = Ip4Cfg2->GetData (
                       Ip4Cfg2,
                       Ip4Config2DataTypeInterfaceInfo,
                       &BufSize,
                       IfInfo
                       );

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    CopyMem (
      &UdpService->DefaultAddress.v4,
      &IfInfo->StationAddress,
      sizeof (EFI_IPv4_ADDRESS)
      );

    //
    // Create udp4 io for output with local default address.
    //
    UdpService->Output = UdpIoCreateIo (
                           UdpService->NicHandle,
                           UdpService->ImageHandle,
                           IkeConfigUdp4,
                           UDP_IO_UDP4_VERSION,
                           &UdpService->DefaultAddress
                           );

    if (UdpService->Output == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

  } else {
    //
    // Create udp6 io for output with remote address.
    //
    UdpService->Output = UdpIoCreateIo (
                           UdpService->NicHandle,
                           UdpService->ImageHandle,
                           IkeConfigUdp6,
                           UDP_IO_UDP6_VERSION,
                           RemoteIp
                           );

    if (UdpService->Output == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    //
    // Get ip6 mode data to get the result of source address selection.
    //
    ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));

    Udp6    = UdpService->Output->Protocol.Udp6;
    Status  = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);

    if (EFI_ERROR (Status)) {
      UdpIoFreeIo (UdpService->Output);
      goto ON_EXIT;
    }

    if (Ip6ModeData.AddressList != NULL) {
      FreePool (Ip6ModeData.AddressList);
    }

    if (Ip6ModeData.GroupTable != NULL) {
      FreePool (Ip6ModeData.GroupTable);
    }

    if (Ip6ModeData.RouteTable != NULL) {
      FreePool (Ip6ModeData.RouteTable);
    }

    if (Ip6ModeData.NeighborCache != NULL) {
      FreePool (Ip6ModeData.NeighborCache);
    }

    if (Ip6ModeData.PrefixTable != NULL) {
      FreePool (Ip6ModeData.PrefixTable);
    }

    if (Ip6ModeData.IcmpTypeList != NULL) {
      FreePool (Ip6ModeData.IcmpTypeList);
    }

    //
    // Reconfigure udp6 io without remote address.
    //
    Udp6->Configure (Udp6, NULL);
    Status = IkeConfigUdp6 (UdpService->Output, NULL);

    //
    // Record the selected source address for ipsec process later.
    //
    CopyMem (
      &UdpService->DefaultAddress.v6,
      &Ip6ModeData.ConfigData.StationAddress,
      sizeof (EFI_IPv6_ADDRESS)
      );
  }

  UdpService->IsConfigured = TRUE;

ON_EXIT:
  if (IfInfo != NULL) {
    FreePool (IfInfo);
  }

  return Status;
}

/**
  Open and configure a UDPIO of Udp4 for IKE packet receiving.

  This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
  UDP4 IO for each NIC handle.

  @param[in] Private        Point to IPSEC_PRIVATE_DATA
  @param[in] Controller     Handler for NIC card.
  @param[in] ImageHandle    The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.

  @retval EFI_SUCCESS             The Operation is successful.
  @retval EFI_OUT_OF_RESOURCE     The required system resource can't be allocated.

**/
EFI_STATUS
IkeOpenInputUdp4 (
  IN IPSEC_PRIVATE_DATA           *Private,
  IN EFI_HANDLE                   Controller,
  IN EFI_HANDLE                   ImageHandle
  )
{
  IKE_UDP_SERVICE *Udp4Srv;

  //
  // Check whether udp4 io of the controller has already been opened.
  //
  Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);

  if (Udp4Srv != NULL) {
    return EFI_ALREADY_STARTED;
  }

  Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));

  if (Udp4Srv == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Create udp4 io for iutput.
  //
  Udp4Srv->Input = UdpIoCreateIo (
                     Controller,
                     ImageHandle,
                     IkeConfigUdp4,
                     UDP_IO_UDP4_VERSION,
                     NULL
                     );

  if (Udp4Srv->Input == NULL) {
    FreePool (Udp4Srv);
    return EFI_OUT_OF_RESOURCES;
  }

  Udp4Srv->NicHandle    = Controller;
  Udp4Srv->ImageHandle  = ImageHandle;
  Udp4Srv->ListHead     = &(Private->Udp4List);
  Udp4Srv->IpVersion    = UDP_IO_UDP4_VERSION;
  Udp4Srv->IsConfigured = FALSE;

  ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));

  //
  // Insert the udp4 io into the list and increase the count.
  //
  InsertTailList (&Private->Udp4List, &Udp4Srv->List);

  Private->Udp4Num++;

  UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);

  return EFI_SUCCESS;
}

/**
  Open and configure a UDPIO of Udp6 for IKE packet receiving.

  This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
  IO for each NIC handle.

  @param[in] Private        Point to IPSEC_PRIVATE_DATA
  @param[in] Controller     Handler for NIC card.
  @param[in] ImageHandle    The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.

  @retval EFI_SUCCESS             The Operation is successful.
  @retval EFI_OUT_OF_RESOURCE     The required system resource can't be allocated.

**/
EFI_STATUS
IkeOpenInputUdp6 (
  IN IPSEC_PRIVATE_DATA           *Private,
  IN EFI_HANDLE                   Controller,
  IN EFI_HANDLE                   ImageHandle
  )
{
  IKE_UDP_SERVICE *Udp6Srv;

  Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);

  if (Udp6Srv != NULL) {
    return EFI_ALREADY_STARTED;
  }

  Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));

  if (Udp6Srv == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Create udp6 io for input.
  //
  Udp6Srv->Input = UdpIoCreateIo (
                     Controller,
                     ImageHandle,
                     IkeConfigUdp6,
                     UDP_IO_UDP6_VERSION,
                     NULL
                     );

  if (Udp6Srv->Input == NULL) {
    FreePool (Udp6Srv);
    return EFI_OUT_OF_RESOURCES;
  }

  Udp6Srv->NicHandle    = Controller;
  Udp6Srv->ImageHandle  = ImageHandle;
  Udp6Srv->ListHead     = &(Private->Udp6List);
  Udp6Srv->IpVersion    = UDP_IO_UDP6_VERSION;
  Udp6Srv->IsConfigured = FALSE;

  ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));

  //
  // Insert the udp6 io into the list and increase the count.
  //
  InsertTailList (&Private->Udp6List, &Udp6Srv->List);

  Private->Udp6Num++;

  UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);

  return EFI_SUCCESS;
}

/**
  The general interface of starting IPsec Key Exchange.

  This function is called when a IKE negotiation to start getting a Key.

  @param[in] UdpService   Point to IKE_UDP_SERVICE which will be used for
                          IKE packet sending.
  @param[in] SpdEntry     Point to the SPD entry related to the IKE negotiation.
  @param[in] RemoteIp     Point to EFI_IP_ADDRESS related to the IKE negotiation.

  @retval EFI_SUCCESS            The Operation is successful.
  @retval EFI_ACCESS_DENIED      No related PAD entry was found.
  @retval EFI_INVALID_PARAMETER  The IKE version is not supported.

**/
EFI_STATUS
IkeNegotiate (
  IN IKE_UDP_SERVICE       *UdpService,
  IN IPSEC_SPD_ENTRY       *SpdEntry,
  IN EFI_IP_ADDRESS        *RemoteIp
  )
{
  EFI_STATUS               Status;
  UINT8                    *IkeSaSession;
  IKE_EXCHANGE_INTERFACE   *Exchange;
  IPSEC_PRIVATE_DATA       *Private;
  IPSEC_PAD_ENTRY          *PadEntry;
  UINT8                    IkeVersion;

  Private = (UdpService->IpVersion == IP_VERSION_4) ?
             IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
             IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);

  //
  // Try to open udp io for output if it hasn't.
  //
  Status = IkeOpenOutputUdp (UdpService, RemoteIp);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.
  //
  IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp);


  if (IkeSaSession == NULL) {
    //
    // Find the pad entry by the remote ip address.
    //
    PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);
    if (PadEntry == NULL) {
      return EFI_ACCESS_DENIED;
    }
    //
    // Determine the IKE exchange instance by the auth protocol in pad entry.
    //
    ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);
    if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {
      return EFI_INVALID_PARAMETER;
    }
    Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];
    //
    // Start the main mode stage to negotiate IKE SA.
    //
    Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);
  } else {
    //
    // Determine the IKE exchange instance by the IKE version in IKE SA session.
    //
    IkeVersion = IkeGetVersionFromSession (IkeSaSession);
    if (IkeVersion != 2) {
      return EFI_INVALID_PARAMETER;
    }

    Exchange = mIkeExchange[IkeVersion - 1];
    //
    // Start the quick mode stage to negotiate child SA.
    //
    Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);
  }

  return Status;
}

/**
  The generic interface when receive a IKE packet.

  This function is called when UDP IO receives a IKE packet.

  @param[in] Packet       Point to received IKE packet.
  @param[in] EndPoint     Point to UDP_END_POINT which contains the information of
                          Remote IP and Port.
  @param[in] IoStatus     The Status of Recieve Token.
  @param[in] Context      Point to data passed from the caller.

**/
VOID
EFIAPI
IkeDispatch (
  IN NET_BUF                        *Packet,
  IN UDP_END_POINT                  *EndPoint,
  IN EFI_STATUS                     IoStatus,
  IN VOID                           *Context
  )
{
  IPSEC_PRIVATE_DATA                *Private;
  IKE_PACKET                        *IkePacket;
  IKE_HEADER                        *IkeHdr;
  IKE_UDP_SERVICE                   *UdpService;
  IKE_EXCHANGE_INTERFACE            *Exchange;
  EFI_STATUS                        Status;

  UdpService = (IKE_UDP_SERVICE *) Context;
  IkePacket  = NULL;
  Private    = (UdpService->IpVersion == IP_VERSION_4) ?
               IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
               IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);

  if (EFI_ERROR (IoStatus)) {
    goto ON_EXIT;
  }
  //
  // Check whether the ipsec is enabled or not.
  //
  if (Private->IpSec.DisabledFlag == TRUE) {
    goto ON_EXIT;
  }

  if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {
    goto ON_EXIT;
  }

  //
  // Build IKE packet from the received netbuf.
  //
  IkePacket = IkePacketFromNetbuf (Packet);

  if (IkePacket == NULL) {
    goto ON_EXIT;
  }
  //
  // Get the remote address from the IKE packet.
  //
  if (UdpService->IpVersion == IP_VERSION_4) {
    *(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));
  } else {
    CopyMem (
      &IkePacket->RemotePeerIp,
      NTOHLLL (&EndPoint->RemoteAddr.v6),
      sizeof (EFI_IPv6_ADDRESS)
      );
  }
  //
  // Try to open udp io for output if hasn't.
  //
  Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  IkeHdr = IkePacket->Header;

  //
  // Determine the IKE exchange instance by the IKE version in IKE header.
  //
  if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {
    Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];
  } else {
    goto ON_EXIT;
  }

  switch (IkeHdr->ExchangeType) {
  case IKE_XCG_TYPE_IDENTITY_PROTECT:
  case IKE_XCG_TYPE_SA_INIT:
  case IKE_XCG_TYPE_AUTH:
    Exchange->HandleSa (UdpService, IkePacket);
    break;

  case IKE_XCG_TYPE_QM:
  case IKE_XCG_TYPE_CREATE_CHILD_SA:
    Exchange->HandleChildSa (UdpService, IkePacket);
    break;

  case IKE_XCG_TYPE_INFO:
  case IKE_XCG_TYPE_INFO2:
    Exchange->HandleInfo (UdpService, IkePacket);
    break;

  default:
    break;
  }

ON_EXIT:
  if (IkePacket != NULL) {
    IkePacketFree (IkePacket);
  }

  if (Packet != NULL) {
    NetbufFree (Packet);
  }

  UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);

  return ;
}

/**
  Delete all established IKE SAs and related Child SAs.

  This function is the subfunction of the IpSecCleanupAllSa(). It first calls
  IkeDeleteChildSa() to delete all Child SAs then send out the related
  Information packet.

  @param[in]  Private           Pointer of the IPSEC_PRIVATE_DATA
  @param[in]  IsDisableIpsec    Indicate whether needs to disable IPsec.

**/
VOID
IkeDeleteAllSas (
  IN IPSEC_PRIVATE_DATA  *Private,
  IN BOOLEAN             IsDisableIpsec
  )
{
  LIST_ENTRY             *Entry;
  LIST_ENTRY             *NextEntry;
  IKEV2_SA_SESSION       *Ikev2SaSession;
  UINT8                  Value;
  EFI_STATUS             Status;
  IKE_EXCHANGE_INTERFACE *Exchange;
  UINT8                  IkeVersion;

  Exchange = NULL;

  //
  // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.
  //

  //
  // If IKEv2 SAs are under establishing, delete it directly.
  //
  if (!IsListEmpty (&Private->Ikev2SessionList)) {
    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->Ikev2SessionList) {
      Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
      RemoveEntryList (Entry);
      Ikev2SaSessionFree (Ikev2SaSession);
    }
  }

  //
  // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE
  // and turn off the IsIPsecDisabling flag.
  //
  if (IsListEmpty (&Private->Ikev2EstablishedList) && IsDisableIpsec) {
    Value = IPSEC_STATUS_DISABLED;
    Status = gRT->SetVariable (
               IPSECCONFIG_STATUS_NAME,
               &gEfiIpSecConfigProtocolGuid,
               EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
               sizeof (Value),
               &Value
               );
    if (!EFI_ERROR (Status)) {
      Private->IpSec.DisabledFlag = TRUE;
      Private->IsIPsecDisabling   = FALSE;
      return ;
    }
  }

  //
  // Delete established IKEv2 SAs.
  //
  if (!IsListEmpty (&Private->Ikev2EstablishedList)) {
    for (Entry = Private->Ikev2EstablishedList.ForwardLink; Entry != &Private->Ikev2EstablishedList;) {
      Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
      Entry = Entry->ForwardLink;

      Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;

      //
      // Call for Information Exchange.
      //
      IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);
      if (IkeVersion == 2) {
        Exchange = mIkeExchange[IkeVersion - 1];
        Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);
      }
    }
  }

}



