]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IpSecDriver.c
Update the relevant drivers to use the correct GUID for EFI_IPSEC2_PROTOCOL.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecDriver.c
index b38f2a94523f982a83900294e6ba9474594cf64e..bd12aa2e07a29b695af34002a76b2eca1776f77a 100644 (file)
 \r
 **/\r
 \r
-#include <Library/UdpIoLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
 #include "IpSecConfigImpl.h"\r
+#include "IkeService.h"\r
 #include "IpSecDebug.h"\r
 \r
 /**\r
@@ -38,9 +40,34 @@ IpSecDriverBindingSupported (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL\r
   )\r
 {\r
+  EFI_STATUS  Udp4Status;\r
+  EFI_STATUS  Udp6Status;\r
+\r
+  Udp4Status = gBS->OpenProtocol (\r
+                      ControllerHandle,\r
+                      &gEfiUdp4ServiceBindingProtocolGuid,\r
+                      NULL,\r
+                      This->DriverBindingHandle,\r
+                      ControllerHandle,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+\r
+  Udp6Status = gBS->OpenProtocol (\r
+                      ControllerHandle,\r
+                      &gEfiUdp6ServiceBindingProtocolGuid,\r
+                      NULL,\r
+                      This->DriverBindingHandle,\r
+                      ControllerHandle,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+\r
   //\r
-  //TODO: Add Udp4Protocol and Udp6Protocol testing.\r
+  // The controller with either Udp4Sb or Udp6Sb is supported.\r
   //\r
+  if (!EFI_ERROR (Udp4Status) || !EFI_ERROR (Udp6Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
@@ -54,7 +81,7 @@ IpSecDriverBindingSupported (
 \r
   @retval EFI_SUCCES           This driver is added to ControllerHandle\r
   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
-  @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.\r
+  @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.  \r
                                Currently not implemented.\r
   @retval other                This driver does not support this device\r
 \r
@@ -67,10 +94,59 @@ IpSecDriverBindingStart (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
+  EFI_IPSEC2_PROTOCOL *IpSec;\r
+  EFI_STATUS          Status;\r
+  EFI_STATUS          Udp4Status;\r
+  EFI_STATUS          Udp6Status;\r
+  IPSEC_PRIVATE_DATA  *Private;\r
+\r
   //\r
-  //TODO: Add Udp4Io and Udp6Io creation for the IKE.\r
+  // Ipsec protocol should be installed when load image.\r
   //\r
-  return EFI_SUCCESS;\r
+  Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);\r
+\r
+  //\r
+  // If udp4 sb is on the controller, try to open a udp4 io for input.\r
+  //\r
+  Udp4Status = gBS->OpenProtocol (\r
+                      ControllerHandle,\r
+                      &gEfiUdp4ServiceBindingProtocolGuid,\r
+                      NULL,\r
+                      This->DriverBindingHandle,\r
+                      ControllerHandle,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+\r
+  if (!EFI_ERROR (Udp4Status)) {\r
+    Udp4Status = IkeOpenInputUdp4 (Private, ControllerHandle);\r
+  }\r
+  //\r
+  // If udp6 sb is on the controller, try to open a udp6 io for input.\r
+  //\r
+  Udp6Status = gBS->OpenProtocol (\r
+                      ControllerHandle,\r
+                      &gEfiUdp6ServiceBindingProtocolGuid,\r
+                      NULL,\r
+                      This->DriverBindingHandle,\r
+                      ControllerHandle,\r
+                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                      );\r
+\r
+  if (!EFI_ERROR (Udp6Status)) {\r
+    Udp6Status = IkeOpenInputUdp6 (Private, ControllerHandle);\r
+  }\r
+\r
+  if (!EFI_ERROR (Udp4Status) || !EFI_ERROR (Udp6Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return EFI_DEVICE_ERROR;\r
 }\r
 \r
 /**\r
@@ -95,10 +171,78 @@ IpSecDriverBindingStop (
   IN EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
+  EFI_IPSEC2_PROTOCOL *IpSec;\r
+  EFI_STATUS          Status;\r
+  IPSEC_PRIVATE_DATA  *Private;\r
+  IKE_UDP_SERVICE     *UdpSrv;\r
+  LIST_ENTRY          *Entry;\r
+  LIST_ENTRY          *Next;\r
+\r
   //\r
-  //TODO: Add UdpIo4 and UdpIo6 destruction when the Udp driver unload or stop.\r
+  // Locate ipsec protocol to get private data.\r
   //\r
-  return EFI_UNSUPPORTED;\r
+  Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);\r
+\r
+  //\r
+  // If has udp4 io opened on the controller, close and free it.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp4List) {\r
+\r
+    UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
+    //\r
+    // Find the right udp service which installed on the appointed nic handle.\r
+    //\r
+    if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {\r
+      UdpIoFreeIo (UdpSrv->Input);\r
+      UdpSrv->Input = NULL;\r
+    }\r
+\r
+    if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {\r
+      UdpIoFreeIo (UdpSrv->Output);\r
+      UdpSrv->Output = NULL;\r
+    }\r
+\r
+    if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {\r
+      RemoveEntryList (&UdpSrv->List);\r
+      FreePool (UdpSrv);\r
+      ASSERT (Private->Udp4Num > 0);\r
+      Private->Udp4Num--;\r
+    }\r
+  }\r
+  //\r
+  // If has udp6 io opened on the controller, close and free it.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp6List) {\r
+\r
+    UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
+    //\r
+    // Find the right udp service which installed on the appointed nic handle.\r
+    //\r
+    if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {\r
+      UdpIoFreeIo (UdpSrv->Input);\r
+      UdpSrv->Input = NULL;\r
+    }\r
+\r
+    if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {\r
+      UdpIoFreeIo (UdpSrv->Output);\r
+      UdpSrv->Output = NULL;\r
+    }\r
+\r
+    if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {\r
+      RemoveEntryList (&UdpSrv->List);\r
+      FreePool (UdpSrv);\r
+      ASSERT (Private->Udp6Num > 0);\r
+      Private->Udp6Num--;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {\r
@@ -112,9 +256,9 @@ EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {
 \r
 /**\r
   This is a callback function when the mIpSecInstance.DisabledEvent is signaled.\r
-\r
+    \r
   @param[in]  Event        Event whose notification function is being invoked.\r
-  @param[in]  Context      Pointer to the notification function's context.\r
+  @param[in]  Context      Pointer to the notification function's context. \r
 \r
 **/\r
 VOID\r
@@ -125,34 +269,17 @@ IpSecCleanupAllSa (
   )\r
 {\r
   IPSEC_PRIVATE_DATA  *Private;\r
-  UINT8               Value;\r
-  EFI_STATUS          Status;\r
-\r
-  Private = (IPSEC_PRIVATE_DATA *) Context;\r
-\r
-  //\r
-  // Set the Status Variable\r
-  //\r
-  Value  = IPSEC_STATUS_DISABLED;\r
-  Status = gRT->SetVariable (\r
-                  IPSECCONFIG_STATUS_NAME,\r
-                  &gEfiIpSecConfigProtocolGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                  sizeof (Value),\r
-                  &Value\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    Private->IpSec.DisabledFlag = TRUE;\r
-  }\r
-\r
+  Private                   = (IPSEC_PRIVATE_DATA *) Context;\r
+  Private->IsIPsecDisabling = TRUE;\r
+  IkeDeleteAllSas (Private);\r
 }\r
 \r
 /**\r
   This is the declaration of an EFI image entry point. This entry point is\r
   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including\r
   both device drivers and bus drivers.\r
-\r
-  The entry point for IPsec driver which installs the driver binding,\r
+  \r
+  The entry point for IPsec driver which installs the driver binding, \r
   component name protocol, IPsec Config protcolon, and IPsec protocol in\r
   its ImageHandle.\r
 \r
@@ -162,7 +289,7 @@ IpSecCleanupAllSa (
   @retval EFI_SUCCESS           The operation completed successfully.\r
   @retval EFI_ALREADY_STARTED   The IPsec driver has been already loaded.\r
   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
-  @retval Others                The operation is failed.\r
+  @retval Others                The operation is failed. \r
 \r
 **/\r
 EFI_STATUS\r
@@ -174,12 +301,12 @@ IpSecDriverEntryPoint (
 {\r
   EFI_STATUS          Status;\r
   IPSEC_PRIVATE_DATA  *Private;\r
-  EFI_IPSEC_PROTOCOL  *IpSec;\r
+  EFI_IPSEC2_PROTOCOL *IpSec;\r
 \r
   //\r
   // Check whether ipsec protocol has already been installed.\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &IpSec);\r
+  Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
 \r
   if (!EFI_ERROR (Status)) {\r
     DEBUG ((DEBUG_WARN, "_ModuleEntryPoint: IpSec has been already loaded\n"));\r
@@ -202,7 +329,7 @@ IpSecDriverEntryPoint (
     goto ON_EXIT;\r
   }\r
   //\r
-  // Create disable event to cleanup all sa when ipsec disabled by user.\r
+  // Create disable event to cleanup all SA when ipsec disabled by user.\r
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -218,8 +345,8 @@ IpSecDriverEntryPoint (
 \r
   Private->Signature    = IPSEC_PRIVATE_DATA_SIGNATURE;\r
   Private->ImageHandle  = ImageHandle;\r
-  CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC_PROTOCOL));\r
-\r
+  CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));\r
+  \r
   //\r
   // Initilize Private's members. Thess members is used for IKE.\r
   //\r
@@ -229,7 +356,8 @@ IpSecDriverEntryPoint (
   InitializeListHead (&Private->Ikev1EstablishedList);\r
   InitializeListHead (&Private->Ikev2SessionList);\r
   InitializeListHead (&Private->Ikev2EstablishedList);\r
-\r
+  \r
+  RandomSeed (NULL, 0);\r
   //\r
   // Initialize the ipsec config data and restore it from variable.\r
   //\r
@@ -243,7 +371,7 @@ IpSecDriverEntryPoint (
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Private->Handle,\r
-                  &gEfiIpSecProtocolGuid,\r
+                  &gEfiIpSec2ProtocolGuid,\r
                   &Private->IpSec,\r
                   NULL\r
                   );\r
@@ -260,11 +388,17 @@ IpSecDriverEntryPoint (
              &gIpSecComponentName2\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    goto ON_UNINSTALL_CONFIG;\r
+    goto ON_UNINSTALL_IPSEC;\r
   }\r
-\r
+  \r
   return Status;\r
 \r
+ON_UNINSTALL_IPSEC:\r
+  gBS->UninstallProtocolInterface (\r
+         Private->Handle,\r
+         &gEfiIpSec2ProtocolGuid,\r
+         &Private->IpSec\r
+         );\r
 ON_UNINSTALL_CONFIG:\r
   gBS->UninstallProtocolInterface (\r
         Private->Handle,\r