• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Driver Binding Protocol for IPsec Driver.
3 
4   Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
5 
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php.
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include <Library/BaseCryptLib.h>
17 
18 #include "IpSecConfigImpl.h"
19 #include "IkeService.h"
20 #include "IpSecDebug.h"
21 
22 /**
23   Test to see if this driver supports ControllerHandle. This is the worker function
24   for IpSec4(6)DriverbindingSupported.
25 
26   @param[in]  This                 Protocol instance pointer.
27   @param[in]  ControllerHandle     Handle of device to test.
28   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
29                                    device to start.
30   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
31 
32   @retval EFI_SUCCES           This driver supports this device.
33   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
34   @retval other                This driver does not support this device.
35 
36 **/
37 EFI_STATUS
38 EFIAPI
IpSecSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,IN UINT8 IpVersion)39 IpSecSupported (
40   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
41   IN EFI_HANDLE                   ControllerHandle,
42   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL,
43   IN UINT8                        IpVersion
44   )
45 {
46   EFI_STATUS  Status;
47   EFI_GUID    *UdpServiceBindingGuid;
48 
49   if (IpVersion == IP_VERSION_4) {
50     UdpServiceBindingGuid  = &gEfiUdp4ServiceBindingProtocolGuid;
51   } else {
52     UdpServiceBindingGuid  = &gEfiUdp6ServiceBindingProtocolGuid;
53   }
54 
55   Status = gBS->OpenProtocol (
56                   ControllerHandle,
57                   UdpServiceBindingGuid,
58                   NULL,
59                   This->DriverBindingHandle,
60                   ControllerHandle,
61                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
62                   );
63   if (EFI_ERROR (Status)) {
64     return EFI_UNSUPPORTED;
65   }
66   return EFI_SUCCESS;
67 }
68 
69 /**
70   Start this driver on ControllerHandle. This is the worker function
71   for IpSec4(6)DriverbindingStart.
72 
73   @param[in]  This                 Protocol instance pointer.
74   @param[in]  ControllerHandle     Handle of device to bind driver to.
75   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
76                                    device to start.
77   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
78 
79   @retval EFI_SUCCES           This driver is added to ControllerHandle
80   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
81   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
82                                Currently not implemented.
83   @retval other                This driver does not support this device
84 
85 **/
86 EFI_STATUS
87 EFIAPI
IpSecStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL,IN UINT8 IpVersion)88 IpSecStart (
89   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
90   IN EFI_HANDLE                   ControllerHandle,
91   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,
92   IN UINT8                        IpVersion
93   )
94 {
95   EFI_IPSEC2_PROTOCOL *IpSec;
96   EFI_STATUS          Status;
97   IPSEC_PRIVATE_DATA  *Private;
98 
99   //
100   // Ipsec protocol should be installed when load image.
101   //
102   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
103 
104   if (EFI_ERROR (Status)) {
105     return Status;
106   }
107 
108   Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
109 
110   if (IpVersion == IP_VERSION_4) {
111     //
112     // Try to open a udp4 io for input.
113     //
114     Status = gBS->OpenProtocol (
115                         ControllerHandle,
116                         &gEfiUdp4ServiceBindingProtocolGuid,
117                         NULL,
118                         This->DriverBindingHandle,
119                         ControllerHandle,
120                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL
121                         );
122 
123     if (!EFI_ERROR (Status)) {
124       Status = IkeOpenInputUdp4 (Private, ControllerHandle, This->DriverBindingHandle);
125     }
126   } else {
127     //
128     // Try to open a udp6 io for input.
129     //
130     Status = gBS->OpenProtocol (
131                         ControllerHandle,
132                         &gEfiUdp6ServiceBindingProtocolGuid,
133                         NULL,
134                         This->DriverBindingHandle,
135                         ControllerHandle,
136                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL
137                         );
138 
139     if (!EFI_ERROR (Status)) {
140       Status = IkeOpenInputUdp6 (Private, ControllerHandle, This->DriverBindingHandle);
141     }
142   }
143 
144   if (EFI_ERROR (Status)) {
145     return EFI_DEVICE_ERROR;
146   }
147   return EFI_SUCCESS;
148 }
149 
150 /**
151   Stop this driver on ControllerHandle. This is the worker function
152   for IpSec4(6)DriverbindingStop.
153 
154   @param[in]  This                 Protocol instance pointer.
155   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
156   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
157                                    children is zero, stop the entire bus driver.
158   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
159   @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
160 
161   @retval EFI_SUCCES           This driver removed ControllerHandle.
162   @retval other                This driver was not removed from this device.
163 
164 **/
165 EFI_STATUS
166 EFIAPI
IpSecStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer,IN UINT8 IpVersion)167 IpSecStop (
168   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
169   IN EFI_HANDLE                   ControllerHandle,
170   IN UINTN                        NumberOfChildren,
171   IN EFI_HANDLE                   *ChildHandleBuffer,
172   IN UINT8                        IpVersion
173   )
174 {
175   EFI_IPSEC2_PROTOCOL *IpSec;
176   EFI_STATUS          Status;
177   IPSEC_PRIVATE_DATA  *Private;
178   IKE_UDP_SERVICE     *UdpSrv;
179   LIST_ENTRY          *Entry;
180   LIST_ENTRY          *Next;
181   IKEV2_SA_SESSION    *Ikev2SaSession;
182 
183   //
184   // Locate ipsec protocol to get private data.
185   //
186   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
187 
188   if (EFI_ERROR (Status)) {
189     return Status;
190   }
191 
192   Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);
193 
194   //
195   // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup
196   // and leave the SAs unchanged if the other IP stack is still running.
197   //
198   if ((IpVersion == IP_VERSION_4 && Private->Udp6Num ==0) ||
199       (IpVersion == IP_VERSION_6 && Private->Udp4Num ==0)) {
200     //
201     // If IKEv2 SAs are under establishing, delete it directly.
202     //
203     if (!IsListEmpty (&Private->Ikev2SessionList)) {
204       NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2SessionList) {
205         Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
206         RemoveEntryList (&Ikev2SaSession->BySessionTable);
207         Ikev2SaSessionFree (Ikev2SaSession);
208       }
209     }
210 
211     //
212     // Delete established IKEv2 SAs.
213     //
214     if (!IsListEmpty (&Private->Ikev2EstablishedList)) {
215       NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Ikev2EstablishedList) {
216         Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);
217         RemoveEntryList (&Ikev2SaSession->BySessionTable);
218         Ikev2SaSessionFree (Ikev2SaSession);
219       }
220     }
221   }
222 
223   if (IpVersion == IP_VERSION_4) {
224     //
225     // If has udp4 io opened on the controller, close and free it.
226     //
227     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp4List) {
228 
229       UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
230       //
231       // Find the right udp service which installed on the appointed nic handle.
232       //
233       if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
234         UdpIoFreeIo (UdpSrv->Input);
235         UdpSrv->Input = NULL;
236       }
237 
238       if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
239         UdpIoFreeIo (UdpSrv->Output);
240         UdpSrv->Output = NULL;
241       }
242 
243       if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
244         RemoveEntryList (&UdpSrv->List);
245         FreePool (UdpSrv);
246         ASSERT (Private->Udp4Num > 0);
247         Private->Udp4Num--;
248       }
249     }
250   } else {
251     //
252     // If has udp6 io opened on the controller, close and free it.
253     //
254     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp6List) {
255 
256       UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
257       //
258       // Find the right udp service which installed on the appointed nic handle.
259       //
260       if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {
261         UdpIoFreeIo (UdpSrv->Input);
262         UdpSrv->Input = NULL;
263       }
264 
265       if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {
266         UdpIoFreeIo (UdpSrv->Output);
267         UdpSrv->Output = NULL;
268       }
269 
270       if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {
271         RemoveEntryList (&UdpSrv->List);
272         FreePool (UdpSrv);
273         ASSERT (Private->Udp6Num > 0);
274         Private->Udp6Num--;
275       }
276     }
277   }
278 
279   return EFI_SUCCESS;
280 }
281 
282 /**
283   Test to see if this driver supports ControllerHandle.
284 
285   @param[in]  This                 Protocol instance pointer.
286   @param[in]  ControllerHandle     Handle of device to test.
287   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
288                                    device to start.
289 
290   @retval EFI_SUCCES           This driver supports this device.
291   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
292   @retval other                This driver does not support this device.
293 
294 **/
295 EFI_STATUS
296 EFIAPI
IpSec4DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)297 IpSec4DriverBindingSupported (
298   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
299   IN EFI_HANDLE                   ControllerHandle,
300   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
301   )
302 {
303   return IpSecSupported (
304            This,
305            ControllerHandle,
306            RemainingDevicePath,
307            IP_VERSION_4
308            );
309 }
310 
311 /**
312   Start this driver on ControllerHandle.
313 
314   @param[in]  This                 Protocol instance pointer.
315   @param[in]  ControllerHandle     Handle of device to bind driver to.
316   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
317                                    device to start.
318 
319   @retval EFI_SUCCES           This driver is added to ControllerHandle
320   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
321   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
322                                Currently not implemented.
323   @retval other                This driver does not support this device
324 
325 **/
326 EFI_STATUS
327 EFIAPI
IpSec4DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)328 IpSec4DriverBindingStart (
329   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
330   IN EFI_HANDLE                   ControllerHandle,
331   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
332   )
333 {
334   return IpSecStart (
335            This,
336            ControllerHandle,
337            RemainingDevicePath,
338            IP_VERSION_4
339            );
340 }
341 
342 /**
343   Stop this driver on ControllerHandle.
344 
345   @param[in]  This                 Protocol instance pointer.
346   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
347   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
348                                    children is zero, stop the entire bus driver.
349   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
350 
351   @retval EFI_SUCCES           This driver removed ControllerHandle.
352   @retval other                This driver was not removed from this device.
353 
354 **/
355 EFI_STATUS
356 EFIAPI
IpSec4DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)357 IpSec4DriverBindingStop (
358   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
359   IN EFI_HANDLE                   ControllerHandle,
360   IN UINTN                        NumberOfChildren,
361   IN EFI_HANDLE                   *ChildHandleBuffer
362   )
363 {
364   return IpSecStop (
365            This,
366            ControllerHandle,
367            NumberOfChildren,
368            ChildHandleBuffer,
369            IP_VERSION_4
370            );
371 }
372 
373 /**
374   Test to see if this driver supports ControllerHandle.
375 
376   @param[in]  This                 Protocol instance pointer.
377   @param[in]  ControllerHandle     Handle of device to test.
378   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
379                                    device to start.
380 
381   @retval EFI_SUCCES           This driver supports this device.
382   @retval EFI_ALREADY_STARTED  This driver is already running on this device.
383   @retval other                This driver does not support this device.
384 
385 **/
386 EFI_STATUS
387 EFIAPI
IpSec6DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)388 IpSec6DriverBindingSupported (
389   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
390   IN EFI_HANDLE                   ControllerHandle,
391   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
392   )
393 {
394   return IpSecSupported (
395            This,
396            ControllerHandle,
397            RemainingDevicePath,
398            IP_VERSION_6
399            );
400 }
401 
402 /**
403   Start this driver on ControllerHandle.
404 
405   @param[in]  This                 Protocol instance pointer.
406   @param[in]  ControllerHandle     Handle of device to bind driver to.
407   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
408                                    device to start.
409 
410   @retval EFI_SUCCES           This driver is added to ControllerHandle
411   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
412   @retval EFI_DEVICE_ERROR     The device could not be started due to a device error.
413                                Currently not implemented.
414   @retval other                This driver does not support this device
415 
416 **/
417 EFI_STATUS
418 EFIAPI
IpSec6DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)419 IpSec6DriverBindingStart (
420   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
421   IN EFI_HANDLE                   ControllerHandle,
422   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
423   )
424 {
425   return IpSecStart (
426            This,
427            ControllerHandle,
428            RemainingDevicePath,
429            IP_VERSION_6
430            );
431 }
432 
433 /**
434   Stop this driver on ControllerHandle.
435 
436   @param[in]  This                 Protocol instance pointer.
437   @param[in]  ControllerHandle     Handle of a device to stop the driver on.
438   @param[in]  NumberOfChildren     Number of Handles in ChildHandleBuffer. If the number of
439                                    children is zero, stop the entire bus driver.
440   @param[in]  ChildHandleBuffer    List of Child Handles to Stop.
441 
442   @retval EFI_SUCCES           This driver removed ControllerHandle.
443   @retval other                This driver was not removed from this device.
444 
445 **/
446 EFI_STATUS
447 EFIAPI
IpSec6DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)448 IpSec6DriverBindingStop (
449   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
450   IN EFI_HANDLE                   ControllerHandle,
451   IN UINTN                        NumberOfChildren,
452   IN EFI_HANDLE                   *ChildHandleBuffer
453   )
454 {
455   return IpSecStop (
456            This,
457            ControllerHandle,
458            NumberOfChildren,
459            ChildHandleBuffer,
460            IP_VERSION_6
461            );
462 }
463 
464 EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding = {
465   IpSec4DriverBindingSupported,
466   IpSec4DriverBindingStart,
467   IpSec4DriverBindingStop,
468   0xa,
469   NULL,
470   NULL
471 };
472 
473 EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding = {
474   IpSec6DriverBindingSupported,
475   IpSec6DriverBindingStart,
476   IpSec6DriverBindingStop,
477   0xa,
478   NULL,
479   NULL
480 };
481 
482 /**
483   This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
484 
485   @param[in]  Event        Event whose notification function is being invoked.
486   @param[in]  Context      Pointer to the notification function's context.
487 
488 **/
489 VOID
490 EFIAPI
IpSecCleanupAllSa(IN EFI_EVENT Event,IN VOID * Context)491 IpSecCleanupAllSa (
492   IN  EFI_EVENT     Event,
493   IN  VOID          *Context
494   )
495 {
496   IPSEC_PRIVATE_DATA  *Private;
497   Private                   = (IPSEC_PRIVATE_DATA *) Context;
498   Private->IsIPsecDisabling = TRUE;
499   IkeDeleteAllSas (Private, TRUE);
500 }
501 
502 /**
503   This is the declaration of an EFI image entry point. This entry point is
504   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
505   both device drivers and bus drivers.
506 
507   The entry point for IPsec driver which installs the driver binding,
508   component name protocol, IPsec Config protcolon, and IPsec protocol in
509   its ImageHandle.
510 
511   @param[in] ImageHandle        The firmware allocated handle for the UEFI image.
512   @param[in] SystemTable        A pointer to the EFI System Table.
513 
514   @retval EFI_SUCCESS           The operation completed successfully.
515   @retval EFI_ALREADY_STARTED   The IPsec driver has been already loaded.
516   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
517   @retval Others                The operation is failed.
518 
519 **/
520 EFI_STATUS
521 EFIAPI
IpSecDriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)522 IpSecDriverEntryPoint (
523   IN EFI_HANDLE              ImageHandle,
524   IN EFI_SYSTEM_TABLE        *SystemTable
525   )
526 {
527   EFI_STATUS          Status;
528   IPSEC_PRIVATE_DATA  *Private;
529   EFI_IPSEC2_PROTOCOL *IpSec;
530 
531   //
532   // Check whether ipsec protocol has already been installed.
533   //
534   Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);
535 
536   if (!EFI_ERROR (Status)) {
537     DEBUG ((DEBUG_WARN, "_ModuleEntryPoint: IpSec has been already loaded\n"));
538     Status = EFI_ALREADY_STARTED;
539     goto ON_EXIT;
540   }
541 
542   Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID **) &mDpc);
543 
544   if (EFI_ERROR (Status)) {
545     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
546     goto ON_EXIT;
547   }
548 
549   Private = AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA));
550 
551   if (Private == NULL) {
552     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to allocate private data\n"));
553     Status = EFI_OUT_OF_RESOURCES;
554     goto ON_EXIT;
555   }
556   //
557   // Create disable event to cleanup all SA when ipsec disabled by user.
558   //
559   Status = gBS->CreateEvent (
560                   EVT_NOTIFY_SIGNAL,
561                   TPL_CALLBACK,
562                   IpSecCleanupAllSa,
563                   Private,
564                   &mIpSecInstance.DisabledEvent
565                   );
566   if (EFI_ERROR (Status)) {
567     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to create disable event\n"));
568     goto ON_FREE_PRIVATE;
569   }
570 
571   Private->Signature    = IPSEC_PRIVATE_DATA_SIGNATURE;
572   Private->ImageHandle  = ImageHandle;
573   CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));
574 
575   //
576   // Initilize Private's members. Thess members is used for IKE.
577   //
578   InitializeListHead (&Private->Udp4List);
579   InitializeListHead (&Private->Udp6List);
580   InitializeListHead (&Private->Ikev1SessionList);
581   InitializeListHead (&Private->Ikev1EstablishedList);
582   InitializeListHead (&Private->Ikev2SessionList);
583   InitializeListHead (&Private->Ikev2EstablishedList);
584 
585   RandomSeed (NULL, 0);
586   //
587   // Initialize the ipsec config data and restore it from variable.
588   //
589   Status = IpSecConfigInitialize (Private);
590   if (EFI_ERROR (Status)) {
591     DEBUG ((DEBUG_ERROR, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
592     goto ON_CLOSE_EVENT;
593   }
594   //
595   // Install ipsec protocol which is used by ip driver to process ipsec header.
596   //
597   Status = gBS->InstallMultipleProtocolInterfaces (
598                   &Private->Handle,
599                   &gEfiIpSec2ProtocolGuid,
600                   &Private->IpSec,
601                   NULL
602                   );
603   if (EFI_ERROR (Status)) {
604     goto ON_UNINSTALL_CONFIG;
605   }
606 
607   Status = EfiLibInstallDriverBindingComponentName2 (
608              ImageHandle,
609              SystemTable,
610              &gIpSec4DriverBinding,
611              ImageHandle,
612              &gIpSecComponentName,
613              &gIpSecComponentName2
614              );
615   if (EFI_ERROR (Status)) {
616     goto ON_UNINSTALL_IPSEC;
617   }
618 
619   Status = EfiLibInstallDriverBindingComponentName2 (
620              ImageHandle,
621              SystemTable,
622              &gIpSec6DriverBinding,
623              NULL,
624              &gIpSecComponentName,
625              &gIpSecComponentName2
626              );
627   if (EFI_ERROR (Status)) {
628     goto ON_UNINSTALL_IPSEC4_DB;
629   }
630 
631   return Status;
632 
633 ON_UNINSTALL_IPSEC4_DB:
634   gBS->UninstallMultipleProtocolInterfaces (
635          ImageHandle,
636          &gEfiDriverBindingProtocolGuid,
637          &gIpSec4DriverBinding,
638          &gEfiComponentName2ProtocolGuid,
639          &gIpSecComponentName2,
640          &gEfiComponentNameProtocolGuid,
641          &gIpSecComponentName,
642          NULL
643          );
644 
645 ON_UNINSTALL_IPSEC:
646   gBS->UninstallProtocolInterface (
647          Private->Handle,
648          &gEfiIpSec2ProtocolGuid,
649          &Private->IpSec
650          );
651 ON_UNINSTALL_CONFIG:
652   gBS->UninstallProtocolInterface (
653         Private->Handle,
654         &gEfiIpSecConfigProtocolGuid,
655         &Private->IpSecConfig
656         );
657 ON_CLOSE_EVENT:
658   gBS->CloseEvent (mIpSecInstance.DisabledEvent);
659   mIpSecInstance.DisabledEvent = NULL;
660 ON_FREE_PRIVATE:
661   FreePool (Private);
662 ON_EXIT:
663   return Status;
664 }
665 
666