]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IpSecDriver.c
NetworkPkg: Fix hang issue after system reconnected when IPSec has set up
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecDriver.c
index b38f2a94523f982a83900294e6ba9474594cf64e..d8282b5e2fdab6c8d1732c238d31bfbe5bb735d8 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Driver Binding Protocol for IPsec Driver.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \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
+  Test to see if this driver supports ControllerHandle. This is the worker function\r
+  for IpSec4(6)DriverbindingSupported.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of device to test.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to start.\r
+  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.\r
+  \r
+  @retval EFI_SUCCES           This driver supports this device.\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on this device.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL,\r
+  IN UINT8                        IpVersion\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_GUID    *UdpServiceBindingGuid;\r
+  \r
+  if (IpVersion == IP_VERSION_4) {\r
+    UdpServiceBindingGuid  = &gEfiUdp4ServiceBindingProtocolGuid;\r
+  } else {\r
+    UdpServiceBindingGuid  = &gEfiUdp6ServiceBindingProtocolGuid;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  UdpServiceBindingGuid,\r
+                  NULL,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle. This is the worker function\r
+  for IpSec4(6)DriverbindingStart.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of device to bind driver to.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to start.\r
+  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.\r
+\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
+                               Currently not implemented.\r
+  @retval other                This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,\r
+  IN UINT8                        IpVersion\r
+  )\r
+{\r
+  EFI_IPSEC2_PROTOCOL *IpSec;\r
+  EFI_STATUS          Status;\r
+  IPSEC_PRIVATE_DATA  *Private;\r
+\r
+  //\r
+  // Ipsec protocol should be installed when load image.\r
+  //\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
+  if (IpVersion == IP_VERSION_4) {\r
+    //\r
+    // Try to open a udp4 io for input.\r
+    //\r
+    Status = 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 (Status)) {\r
+      Status = IkeOpenInputUdp4 (Private, ControllerHandle, This->DriverBindingHandle);\r
+    }\r
+  } else {\r
+    //\r
+    // Try to open a udp6 io for input.\r
+    //\r
+    Status = 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 (Status)) {\r
+      Status = IkeOpenInputUdp6 (Private, ControllerHandle, This->DriverBindingHandle);\r
+    }\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle. This is the worker function\r
+  for IpSec4(6)DriverbindingStop.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of a device to stop the driver on.\r
+  @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of\r
+                                   children is zero, stop the entire bus driver.\r
+  @param[in]  ChildHandleBuffer    List of Child Handles to Stop.\r
+  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.\r
+\r
+  @retval EFI_SUCCES           This driver removed ControllerHandle.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer,\r
+  IN UINT8                        IpVersion\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
+  IKEV2_SA_SESSION    *Ikev2SaSession;\r
+\r
+  //\r
+  // Locate ipsec protocol to get private data.\r
+  //\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
+  // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup\r
+  // and leave the SAs unchanged if the other IP stack is still running.\r
+  //\r
+  if ((IpVersion == IP_VERSION_4 && Private->Udp6Num ==0) ||\r
+      (IpVersion == IP_VERSION_6 && Private->Udp4Num ==0)) {\r
+    //\r
+    // If IKEv2 SAs are under establishing, delete it directly.\r
+    //\r
+    if (!IsListEmpty (&Private->Ikev2SessionList)) {\r
+      NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2SessionList) {\r
+        Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
+        RemoveEntryList (&Ikev2SaSession->BySessionTable);\r
+        Ikev2SaSessionFree (Ikev2SaSession);\r
+      }\r
+    }\r
+\r
+    //\r
+    // Delete established IKEv2 SAs.\r
+    //\r
+    if (!IsListEmpty (&Private->Ikev2EstablishedList)) {\r
+      NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2EstablishedList) {\r
+        Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry); \r
+        RemoveEntryList (&Ikev2SaSession->BySessionTable);\r
+        Ikev2SaSessionFree (Ikev2SaSession);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (IpVersion == IP_VERSION_4) {\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
+  } else {\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
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Test to see if this driver supports ControllerHandle.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-IpSecDriverBindingSupported (\r
+IpSec4DriverBindingSupported (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL\r
   )\r
 {\r
-  //\r
-  //TODO: Add Udp4Protocol and Udp6Protocol testing.\r
-  //\r
-  return EFI_UNSUPPORTED;\r
+  return IpSecSupported (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_4\r
+           );\r
 }\r
 \r
 /**\r
@@ -61,16 +325,18 @@ IpSecDriverBindingSupported (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-IpSecDriverBindingStart (\r
+IpSec4DriverBindingStart (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
-  //\r
-  //TODO: Add Udp4Io and Udp6Io creation for the IKE.\r
-  //\r
-  return EFI_SUCCESS;\r
+  return IpSecStart (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_4\r
+           );\r
 }\r
 \r
 /**\r
@@ -88,23 +354,126 @@ IpSecDriverBindingStart (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-IpSecDriverBindingStop (\r
+IpSec4DriverBindingStop (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN UINTN                        NumberOfChildren,\r
   IN EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  //\r
-  //TODO: Add UdpIo4 and UdpIo6 destruction when the Udp driver unload or stop.\r
-  //\r
-  return EFI_UNSUPPORTED;\r
+  return IpSecStop (\r
+           This,\r
+           ControllerHandle,\r
+           NumberOfChildren,\r
+           ChildHandleBuffer,\r
+           IP_VERSION_4\r
+           );\r
+}\r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of device to test.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to start.\r
+\r
+  @retval EFI_SUCCES           This driver supports this device.\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on this device.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL\r
+  )\r
+{\r
+  return IpSecSupported (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_6\r
+           );\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of device to bind driver to.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to start.\r
+\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
+                               Currently not implemented.\r
+  @retval other                This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return IpSecStart (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_6\r
+           );\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle.\r
+\r
+  @param[in]  This                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of a device to stop the driver on.\r
+  @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of\r
+                                   children is zero, stop the entire bus driver.\r
+  @param[in]  ChildHandleBuffer    List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCES           This driver removed ControllerHandle.\r
+  @retval other                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+{\r
+  return IpSecStop (\r
+           This,\r
+           ControllerHandle,\r
+           NumberOfChildren,\r
+           ChildHandleBuffer,\r
+           IP_VERSION_6\r
+           );\r
 }\r
 \r
-EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {\r
-  IpSecDriverBindingSupported,\r
-  IpSecDriverBindingStart,\r
-  IpSecDriverBindingStop,\r
+EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding = {\r
+  IpSec4DriverBindingSupported,\r
+  IpSec4DriverBindingStart,\r
+  IpSec4DriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding = {\r
+  IpSec6DriverBindingSupported,\r
+  IpSec6DriverBindingStart,\r
+  IpSec6DriverBindingStop,\r
   0xa,\r
   NULL,\r
   NULL\r
@@ -125,26 +494,9 @@ 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, TRUE);\r
 }\r
 \r
 /**\r
@@ -174,12 +526,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 +554,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,7 +570,7 @@ IpSecDriverEntryPoint (
 \r
   Private->Signature    = IPSEC_PRIVATE_DATA_SIGNATURE;\r
   Private->ImageHandle  = ImageHandle;\r
-  CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC_PROTOCOL));\r
+  CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));\r
 \r
   //\r
   // Initilize Private's members. Thess members is used for IKE.\r
@@ -230,6 +582,7 @@ IpSecDriverEntryPoint (
   InitializeListHead (&Private->Ikev2SessionList);\r
   InitializeListHead (&Private->Ikev2EstablishedList);\r
 \r
+  RandomSeed (NULL, 0);\r
   //\r
   // Initialize the ipsec config data and restore it from variable.\r
   //\r
@@ -243,7 +596,7 @@ IpSecDriverEntryPoint (
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Private->Handle,\r
-                  &gEfiIpSecProtocolGuid,\r
+                  &gEfiIpSec2ProtocolGuid,\r
                   &Private->IpSec,\r
                   NULL\r
                   );\r
@@ -254,17 +607,47 @@ IpSecDriverEntryPoint (
   Status = EfiLibInstallDriverBindingComponentName2 (\r
              ImageHandle,\r
              SystemTable,\r
-             &gIpSecDriverBinding,\r
+             &gIpSec4DriverBinding,\r
              ImageHandle,\r
              &gIpSecComponentName,\r
              &gIpSecComponentName2\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    goto ON_UNINSTALL_CONFIG;\r
+    goto ON_UNINSTALL_IPSEC;\r
+  }\r
+\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gIpSec6DriverBinding,\r
+             NULL,\r
+             &gIpSecComponentName,\r
+             &gIpSecComponentName2\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_UNINSTALL_IPSEC4_DB;\r
   }\r
 \r
   return Status;\r
 \r
+ON_UNINSTALL_IPSEC4_DB:\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+         ImageHandle,\r
+         &gEfiDriverBindingProtocolGuid,\r
+         &gIpSec4DriverBinding,\r
+         &gEfiComponentName2ProtocolGuid,\r
+         &gIpSecComponentName2,\r
+         &gEfiComponentNameProtocolGuid,\r
+         &gIpSecComponentName,\r
+         NULL\r
+         );\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