mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 20:43:59 +00:00 
			
		
		
		
	 5dd08a463d
			
		
	
	
		5dd08a463d
		
	
	
	
	
		
			
			IpSecStop() is incompetent to send out the delete information since the underlying IP child has been destroyed. Delete all established IKE SAs and related Child SAs directly. Cc: Ye Ting <ting.ye@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18223 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			666 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			666 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Driver Binding Protocol for IPsec Driver.
 | |
| 
 | |
|   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
 | |
| 
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php.
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Library/BaseCryptLib.h>
 | |
| 
 | |
| #include "IpSecConfigImpl.h"
 | |
| #include "IkeService.h"
 | |
| #include "IpSecDebug.h"
 | |
| 
 | |
| /**
 | |
|   Test to see if this driver supports ControllerHandle. This is the worker function
 | |
|   for IpSec4(6)DriverbindingSupported.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to test.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
|   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
 | |
|   
 | |
|   @retval EFI_SUCCES           This driver supports this device.
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
 | |
|   @retval other                This driver does not support this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSecSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL,
 | |
|   IN UINT8                        IpVersion
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   EFI_GUID    *UdpServiceBindingGuid;
 | |
|   
 | |
|   if (IpVersion == IP_VERSION_4) {
 | |
|     UdpServiceBindingGuid  = &gEfiUdp4ServiceBindingProtocolGuid;
 | |
|   } else {
 | |
|     UdpServiceBindingGuid  = &gEfiUdp6ServiceBindingProtocolGuid;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (
 | |
|                   ControllerHandle,
 | |
|                   UdpServiceBindingGuid,
 | |
|                   NULL,
 | |
|                   This->DriverBindingHandle,
 | |
|                   ControllerHandle,
 | |
|                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Start this driver on ControllerHandle. This is the worker function
 | |
|   for IpSec4(6)DriverbindingStart.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to bind driver to.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
|   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver is added to ControllerHandle
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
 | |
|   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
 | |
|                                Currently not implemented.
 | |
|   @retval other                This driver does not support this device
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSecStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,
 | |
|   IN UINT8                        IpVersion
 | |
|   )
 | |
| {
 | |
|   EFI_IPSEC2_PROTOCOL *IpSec;
 | |
|   EFI_STATUS          Status;
 | |
|   IPSEC_PRIVATE_DATA  *Private;
 | |
| 
 | |
|   //
 | |
|   // Ipsec protocol should be installed when load image.
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
 | |
| 
 | |
|   if (IpVersion == IP_VERSION_4) {
 | |
|     //
 | |
|     // Try to open a udp4 io for input.
 | |
|     //
 | |
|     Status = gBS->OpenProtocol (
 | |
|                         ControllerHandle,
 | |
|                         &gEfiUdp4ServiceBindingProtocolGuid,
 | |
|                         NULL,
 | |
|                         This->DriverBindingHandle,
 | |
|                         ControllerHandle,
 | |
|                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                         );
 | |
| 
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       Status = IkeOpenInputUdp4 (Private, ControllerHandle, This->DriverBindingHandle);
 | |
|     }
 | |
|   } else {
 | |
|     //
 | |
|     // Try to open a udp6 io for input.
 | |
|     //
 | |
|     Status = gBS->OpenProtocol (
 | |
|                         ControllerHandle,
 | |
|                         &gEfiUdp6ServiceBindingProtocolGuid,
 | |
|                         NULL,
 | |
|                         This->DriverBindingHandle,
 | |
|                         ControllerHandle,
 | |
|                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL
 | |
|                         );
 | |
| 
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       Status = IkeOpenInputUdp6 (Private, ControllerHandle, This->DriverBindingHandle);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_DEVICE_ERROR;
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle. This is the worker function
 | |
|   for IpSec4(6)DriverbindingStop.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
 | |
|   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
 | |
|                                    children is zero, stop the entire bus driver.
 | |
|   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
 | |
|   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver removed ControllerHandle.
 | |
|   @retval other                This driver was not removed from this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSecStop (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN UINTN                        NumberOfChildren,
 | |
|   IN EFI_HANDLE                   *ChildHandleBuffer,
 | |
|   IN UINT8                        IpVersion
 | |
|   )
 | |
| {
 | |
|   EFI_IPSEC2_PROTOCOL *IpSec;
 | |
|   EFI_STATUS          Status;
 | |
|   IPSEC_PRIVATE_DATA  *Private;
 | |
|   IKE_UDP_SERVICE     *UdpSrv;
 | |
|   LIST_ENTRY          *Entry;
 | |
|   LIST_ENTRY          *Next;
 | |
|   IKEV2_SA_SESSION    *Ikev2SaSession;
 | |
| 
 | |
|   //
 | |
|   // Locate ipsec protocol to get private data.
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
 | |
| 
 | |
|   //
 | |
|   // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup
 | |
|   // and leave the SAs unchanged if the other IP stack is still running.
 | |
|   //
 | |
|   if ((IpVersion == IP_VERSION_4 && Private->Udp6Num ==0) ||
 | |
|       (IpVersion == IP_VERSION_6 && Private->Udp4Num ==0)) {
 | |
|     //
 | |
|     // If IKEv2 SAs are under establishing, delete it directly.
 | |
|     //
 | |
|     if (!IsListEmpty (&Private->Ikev2SessionList)) {
 | |
|       NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2SessionList) {
 | |
|         Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
 | |
|         RemoveEntryList (&Ikev2SaSession->BySessionTable);
 | |
|         Ikev2SaSessionFree (Ikev2SaSession);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Delete established IKEv2 SAs.
 | |
|     //
 | |
|     if (!IsListEmpty (&Private->Ikev2EstablishedList)) {
 | |
|       NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2EstablishedList) {
 | |
|         Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry); 
 | |
|         RemoveEntryList (&Ikev2SaSession->BySessionTable);
 | |
|         Ikev2SaSessionFree (Ikev2SaSession);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (IpVersion == IP_VERSION_4) {
 | |
|     //
 | |
|     // If has udp4 io opened on the controller, close and free it.
 | |
|     //
 | |
|     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp4List) {
 | |
| 
 | |
|       UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
 | |
|       //
 | |
|       // Find the right udp service which installed on the appointed nic handle.
 | |
|       //
 | |
|       if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
 | |
|         UdpIoFreeIo (UdpSrv->Input);
 | |
|         UdpSrv->Input = NULL;
 | |
|       }
 | |
| 
 | |
|       if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
 | |
|         UdpIoFreeIo (UdpSrv->Output);
 | |
|         UdpSrv->Output = NULL;
 | |
|       }
 | |
| 
 | |
|       if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
 | |
|         RemoveEntryList (&UdpSrv->List);
 | |
|         FreePool (UdpSrv);
 | |
|         ASSERT (Private->Udp4Num > 0);
 | |
|         Private->Udp4Num--;
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     //
 | |
|     // If has udp6 io opened on the controller, close and free it.
 | |
|     //
 | |
|     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp6List) {
 | |
| 
 | |
|       UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
 | |
|       //
 | |
|       // Find the right udp service which installed on the appointed nic handle.
 | |
|       //
 | |
|       if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
 | |
|         UdpIoFreeIo (UdpSrv->Input);
 | |
|         UdpSrv->Input = NULL;
 | |
|       }
 | |
| 
 | |
|       if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
 | |
|         UdpIoFreeIo (UdpSrv->Output);
 | |
|         UdpSrv->Output = NULL;
 | |
|       }
 | |
| 
 | |
|       if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
 | |
|         RemoveEntryList (&UdpSrv->List);
 | |
|         FreePool (UdpSrv);
 | |
|         ASSERT (Private->Udp6Num > 0);
 | |
|         Private->Udp6Num--;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Test to see if this driver supports ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to test.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver supports this device.
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
 | |
|   @retval other                This driver does not support this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec4DriverBindingSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return IpSecSupported (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            RemainingDevicePath,
 | |
|            IP_VERSION_4
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Start this driver on ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to bind driver to.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver is added to ControllerHandle
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
 | |
|   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
 | |
|                                Currently not implemented.
 | |
|   @retval other                This driver does not support this device
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec4DriverBindingStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return IpSecStart (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            RemainingDevicePath,
 | |
|            IP_VERSION_4
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
 | |
|   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
 | |
|                                    children is zero, stop the entire bus driver.
 | |
|   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver removed ControllerHandle.
 | |
|   @retval other                This driver was not removed from this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec4DriverBindingStop (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN UINTN                        NumberOfChildren,
 | |
|   IN EFI_HANDLE                   *ChildHandleBuffer
 | |
|   )
 | |
| {
 | |
|   return IpSecStop (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            NumberOfChildren,
 | |
|            ChildHandleBuffer,
 | |
|            IP_VERSION_4
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Test to see if this driver supports ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to test.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver supports this device.
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
 | |
|   @retval other                This driver does not support this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec6DriverBindingSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return IpSecSupported (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            RemainingDevicePath,
 | |
|            IP_VERSION_6
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Start this driver on ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of device to bind driver to.
 | |
|   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
 | |
|                                    device to start.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver is added to ControllerHandle
 | |
|   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
 | |
|   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
 | |
|                                Currently not implemented.
 | |
|   @retval other                This driver does not support this device
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec6DriverBindingStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
 | |
|   )
 | |
| {
 | |
|   return IpSecStart (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            RemainingDevicePath,
 | |
|            IP_VERSION_6
 | |
|            );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle.
 | |
| 
 | |
|   @param[in]  This                 Protocol instance pointer.
 | |
|   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
 | |
|   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
 | |
|                                    children is zero, stop the entire bus driver.
 | |
|   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
 | |
| 
 | |
|   @retval EFI_SUCCES           This driver removed ControllerHandle.
 | |
|   @retval other                This driver was not removed from this device.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSec6DriverBindingStop (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | |
|   IN EFI_HANDLE                   ControllerHandle,
 | |
|   IN UINTN                        NumberOfChildren,
 | |
|   IN EFI_HANDLE                   *ChildHandleBuffer
 | |
|   )
 | |
| {
 | |
|   return IpSecStop (
 | |
|            This,
 | |
|            ControllerHandle,
 | |
|            NumberOfChildren,
 | |
|            ChildHandleBuffer,
 | |
|            IP_VERSION_6
 | |
|            );
 | |
| }
 | |
| 
 | |
| EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding = {
 | |
|   IpSec4DriverBindingSupported,
 | |
|   IpSec4DriverBindingStart,
 | |
|   IpSec4DriverBindingStop,
 | |
|   0xa,
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding = {
 | |
|   IpSec6DriverBindingSupported,
 | |
|   IpSec6DriverBindingStart,
 | |
|   IpSec6DriverBindingStop,
 | |
|   0xa,
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
 | |
| 
 | |
|   @param[in]  Event        Event whose notification function is being invoked.
 | |
|   @param[in]  Context      Pointer to the notification function's context.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| IpSecCleanupAllSa (
 | |
|   IN  EFI_EVENT     Event,
 | |
|   IN  VOID          *Context
 | |
|   )
 | |
| {
 | |
|   IPSEC_PRIVATE_DATA  *Private;
 | |
|   Private                   = (IPSEC_PRIVATE_DATA *) Context;
 | |
|   Private->IsIPsecDisabling = TRUE;
 | |
|   IkeDeleteAllSas (Private, TRUE);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This is the declaration of an EFI image entry point. This entry point is
 | |
|   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
 | |
|   both device drivers and bus drivers.
 | |
| 
 | |
|   The entry point for IPsec driver which installs the driver binding,
 | |
|   component name protocol, IPsec Config protcolon, and IPsec protocol in
 | |
|   its ImageHandle.
 | |
| 
 | |
|   @param[in] ImageHandle        The firmware allocated handle for the UEFI image.
 | |
|   @param[in] SystemTable        A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation completed successfully.
 | |
|   @retval EFI_ALREADY_STARTED   The IPsec driver has been already loaded.
 | |
|   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
 | |
|   @retval Others                The operation is failed.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| IpSecDriverEntryPoint (
 | |
|   IN EFI_HANDLE              ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE        *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
|   IPSEC_PRIVATE_DATA  *Private;
 | |
|   EFI_IPSEC2_PROTOCOL *IpSec;
 | |
| 
 | |
|   //
 | |
|   // Check whether ipsec protocol has already been installed.
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_WARN, "_ModuleEntryPoint: IpSec has been already loaded\n"));
 | |
|     Status = EFI_ALREADY_STARTED;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID **) &mDpc);
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
| 
 | |
|   Private = AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA));
 | |
| 
 | |
|   if (Private == NULL) {
 | |
|     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to allocate private data\n"));
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     goto ON_EXIT;
 | |
|   }
 | |
|   //
 | |
|   // Create disable event to cleanup all SA when ipsec disabled by user.
 | |
|   //
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_SIGNAL,
 | |
|                   TPL_CALLBACK,
 | |
|                   IpSecCleanupAllSa,
 | |
|                   Private,
 | |
|                   &mIpSecInstance.DisabledEvent
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to create disable event\n"));
 | |
|     goto ON_FREE_PRIVATE;
 | |
|   }
 | |
| 
 | |
|   Private->Signature    = IPSEC_PRIVATE_DATA_SIGNATURE;
 | |
|   Private->ImageHandle  = ImageHandle;
 | |
|   CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));
 | |
| 
 | |
|   //
 | |
|   // Initilize Private's members. Thess members is used for IKE.
 | |
|   //
 | |
|   InitializeListHead (&Private->Udp4List);
 | |
|   InitializeListHead (&Private->Udp6List);
 | |
|   InitializeListHead (&Private->Ikev1SessionList);
 | |
|   InitializeListHead (&Private->Ikev1EstablishedList);
 | |
|   InitializeListHead (&Private->Ikev2SessionList);
 | |
|   InitializeListHead (&Private->Ikev2EstablishedList);
 | |
| 
 | |
|   RandomSeed (NULL, 0);
 | |
|   //
 | |
|   // Initialize the ipsec config data and restore it from variable.
 | |
|   //
 | |
|   Status = IpSecConfigInitialize (Private);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
 | |
|     goto ON_CLOSE_EVENT;
 | |
|   }
 | |
|   //
 | |
|   // Install ipsec protocol which is used by ip driver to process ipsec header.
 | |
|   //
 | |
|   Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                   &Private->Handle,
 | |
|                   &gEfiIpSec2ProtocolGuid,
 | |
|                   &Private->IpSec,
 | |
|                   NULL
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_UNINSTALL_CONFIG;
 | |
|   }
 | |
| 
 | |
|   Status = EfiLibInstallDriverBindingComponentName2 (
 | |
|              ImageHandle,
 | |
|              SystemTable,
 | |
|              &gIpSec4DriverBinding,
 | |
|              ImageHandle,
 | |
|              &gIpSecComponentName,
 | |
|              &gIpSecComponentName2
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_UNINSTALL_IPSEC;
 | |
|   }
 | |
| 
 | |
|   Status = EfiLibInstallDriverBindingComponentName2 (
 | |
|              ImageHandle,
 | |
|              SystemTable,
 | |
|              &gIpSec6DriverBinding,
 | |
|              NULL,
 | |
|              &gIpSecComponentName,
 | |
|              &gIpSecComponentName2
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto ON_UNINSTALL_IPSEC4_DB;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| 
 | |
| ON_UNINSTALL_IPSEC4_DB:
 | |
|   gBS->UninstallMultipleProtocolInterfaces (
 | |
|          ImageHandle,
 | |
|          &gEfiDriverBindingProtocolGuid,
 | |
|          &gIpSec4DriverBinding,
 | |
|          &gEfiComponentName2ProtocolGuid,
 | |
|          &gIpSecComponentName2,
 | |
|          &gEfiComponentNameProtocolGuid,
 | |
|          &gIpSecComponentName,
 | |
|          NULL
 | |
|          );
 | |
| 
 | |
| ON_UNINSTALL_IPSEC:
 | |
|   gBS->UninstallProtocolInterface (
 | |
|          Private->Handle,
 | |
|          &gEfiIpSec2ProtocolGuid,
 | |
|          &Private->IpSec
 | |
|          );
 | |
| ON_UNINSTALL_CONFIG:
 | |
|   gBS->UninstallProtocolInterface (
 | |
|         Private->Handle,
 | |
|         &gEfiIpSecConfigProtocolGuid,
 | |
|         &Private->IpSecConfig
 | |
|         );
 | |
| ON_CLOSE_EVENT:
 | |
|   gBS->CloseEvent (mIpSecInstance.DisabledEvent);
 | |
|   mIpSecInstance.DisabledEvent = NULL;
 | |
| ON_FREE_PRIVATE:
 | |
|   FreePool (Private);
 | |
| ON_EXIT:
 | |
|   return Status;
 | |
| }
 | |
| 
 |