/** @file | |
Provide IPsec Key Exchange (IKE) service general interfaces. | |
Copyright (c) 2010 - 2013, 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" | |
#include "Ikev2/Utility.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_CONFIG_PROTOCOL *Ip4Cfg; | |
EFI_IP4_IPCONFIG_DATA *Ip4CfgData; | |
UINTN BufSize; | |
EFI_IP6_MODE_DATA Ip6ModeData; | |
EFI_UDP6_PROTOCOL *Udp6; | |
Status = EFI_SUCCESS; | |
Ip4CfgData = 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, | |
&gEfiIp4ConfigProtocolGuid, | |
(VOID **) &Ip4Cfg | |
); | |
if (EFI_ERROR (Status)) { | |
goto ON_EXIT; | |
} | |
Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, NULL); | |
if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { | |
goto ON_EXIT; | |
} | |
Ip4CfgData = AllocateZeroPool (BufSize); | |
if (Ip4CfgData == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto ON_EXIT; | |
} | |
Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, Ip4CfgData); | |
if (EFI_ERROR (Status)) { | |
goto ON_EXIT; | |
} | |
CopyMem ( | |
&UdpService->DefaultAddress.v4, | |
&Ip4CfgData->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; | |
} | |
// | |
// 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 (Ip4CfgData != NULL) { | |
FreePool (Ip4CfgData); | |
} | |
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); | |
} | |
} | |
} | |
} | |