2 Driver Binding Protocol for IPsec Driver.
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
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.
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.
16 #include <Library/BaseCryptLib.h>
18 #include "IpSecConfigImpl.h"
19 #include "IkeService.h"
20 #include "IpSecDebug.h"
23 Test to see if this driver supports ControllerHandle.
25 @param[in] This Protocol instance pointer.
26 @param[in] ControllerHandle Handle of device to test.
27 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
30 @retval EFI_SUCCES This driver supports this device.
31 @retval EFI_ALREADY_STARTED This driver is already running on this device.
32 @retval other This driver does not support this device.
37 IpSecDriverBindingSupported (
38 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
39 IN EFI_HANDLE ControllerHandle
,
40 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
43 EFI_STATUS Udp4Status
;
44 EFI_STATUS Udp6Status
;
46 Udp4Status
= gBS
->OpenProtocol (
48 &gEfiUdp4ServiceBindingProtocolGuid
,
50 This
->DriverBindingHandle
,
52 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
55 Udp6Status
= gBS
->OpenProtocol (
57 &gEfiUdp6ServiceBindingProtocolGuid
,
59 This
->DriverBindingHandle
,
61 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
65 // The controller with either Udp4Sb or Udp6Sb is supported.
67 if (!EFI_ERROR (Udp4Status
) || !EFI_ERROR (Udp6Status
)) {
71 return EFI_UNSUPPORTED
;
75 Start this driver on ControllerHandle.
77 @param[in] This Protocol instance pointer.
78 @param[in] ControllerHandle Handle of device to bind driver to.
79 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
82 @retval EFI_SUCCES This driver is added to ControllerHandle
83 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
84 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
85 Currently not implemented.
86 @retval other This driver does not support this device
91 IpSecDriverBindingStart (
92 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
93 IN EFI_HANDLE ControllerHandle
,
94 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
97 EFI_IPSEC2_PROTOCOL
*IpSec
;
99 EFI_STATUS Udp4Status
;
100 EFI_STATUS Udp6Status
;
101 IPSEC_PRIVATE_DATA
*Private
;
104 // Ipsec protocol should be installed when load image.
106 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
108 if (EFI_ERROR (Status
)) {
112 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
115 // If udp4 sb is on the controller, try to open a udp4 io for input.
117 Udp4Status
= gBS
->OpenProtocol (
119 &gEfiUdp4ServiceBindingProtocolGuid
,
121 This
->DriverBindingHandle
,
123 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
126 if (!EFI_ERROR (Udp4Status
)) {
127 Udp4Status
= IkeOpenInputUdp4 (Private
, ControllerHandle
);
130 // If udp6 sb is on the controller, try to open a udp6 io for input.
132 Udp6Status
= gBS
->OpenProtocol (
134 &gEfiUdp6ServiceBindingProtocolGuid
,
136 This
->DriverBindingHandle
,
138 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
141 if (!EFI_ERROR (Udp6Status
)) {
142 Udp6Status
= IkeOpenInputUdp6 (Private
, ControllerHandle
);
145 if (!EFI_ERROR (Udp4Status
) || !EFI_ERROR (Udp6Status
)) {
149 return EFI_DEVICE_ERROR
;
153 Stop this driver on ControllerHandle.
155 @param[in] This Protocol instance pointer.
156 @param[in] ControllerHandle Handle of a device to stop the driver on.
157 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
158 children is zero, stop the entire bus driver.
159 @param[in] ChildHandleBuffer List of Child Handles to Stop.
161 @retval EFI_SUCCES This driver removed ControllerHandle.
162 @retval other This driver was not removed from this device.
167 IpSecDriverBindingStop (
168 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
169 IN EFI_HANDLE ControllerHandle
,
170 IN UINTN NumberOfChildren
,
171 IN EFI_HANDLE
*ChildHandleBuffer
174 EFI_IPSEC2_PROTOCOL
*IpSec
;
176 IPSEC_PRIVATE_DATA
*Private
;
177 IKE_UDP_SERVICE
*UdpSrv
;
182 // Locate ipsec protocol to get private data.
184 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
186 if (EFI_ERROR (Status
)) {
190 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
193 // Delete all SAs before stop Ipsec.
195 IkeDeleteAllSas (Private
, FALSE
);
197 // If has udp4 io opened on the controller, close and free it.
199 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp4List
) {
201 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
203 // Find the right udp service which installed on the appointed nic handle.
205 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
206 UdpIoFreeIo (UdpSrv
->Input
);
207 UdpSrv
->Input
= NULL
;
210 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
211 UdpIoFreeIo (UdpSrv
->Output
);
212 UdpSrv
->Output
= NULL
;
215 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
216 RemoveEntryList (&UdpSrv
->List
);
218 ASSERT (Private
->Udp4Num
> 0);
223 // If has udp6 io opened on the controller, close and free it.
225 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp6List
) {
227 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
229 // Find the right udp service which installed on the appointed nic handle.
231 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
232 UdpIoFreeIo (UdpSrv
->Input
);
233 UdpSrv
->Input
= NULL
;
236 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
237 UdpIoFreeIo (UdpSrv
->Output
);
238 UdpSrv
->Output
= NULL
;
241 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
242 RemoveEntryList (&UdpSrv
->List
);
244 ASSERT (Private
->Udp6Num
> 0);
252 EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding
= {
253 IpSecDriverBindingSupported
,
254 IpSecDriverBindingStart
,
255 IpSecDriverBindingStop
,
262 This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
264 @param[in] Event Event whose notification function is being invoked.
265 @param[in] Context Pointer to the notification function's context.
275 IPSEC_PRIVATE_DATA
*Private
;
276 Private
= (IPSEC_PRIVATE_DATA
*) Context
;
277 Private
->IsIPsecDisabling
= TRUE
;
278 IkeDeleteAllSas (Private
, TRUE
);
282 This is the declaration of an EFI image entry point. This entry point is
283 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
284 both device drivers and bus drivers.
286 The entry point for IPsec driver which installs the driver binding,
287 component name protocol, IPsec Config protcolon, and IPsec protocol in
290 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
291 @param[in] SystemTable A pointer to the EFI System Table.
293 @retval EFI_SUCCESS The operation completed successfully.
294 @retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
295 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
296 @retval Others The operation is failed.
301 IpSecDriverEntryPoint (
302 IN EFI_HANDLE ImageHandle
,
303 IN EFI_SYSTEM_TABLE
*SystemTable
307 IPSEC_PRIVATE_DATA
*Private
;
308 EFI_IPSEC2_PROTOCOL
*IpSec
;
311 // Check whether ipsec protocol has already been installed.
313 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
315 if (!EFI_ERROR (Status
)) {
316 DEBUG ((DEBUG_WARN
, "_ModuleEntryPoint: IpSec has been already loaded\n"));
317 Status
= EFI_ALREADY_STARTED
;
321 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
323 if (EFI_ERROR (Status
)) {
324 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
328 Private
= AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA
));
330 if (Private
== NULL
) {
331 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to allocate private data\n"));
332 Status
= EFI_OUT_OF_RESOURCES
;
336 // Create disable event to cleanup all SA when ipsec disabled by user.
338 Status
= gBS
->CreateEvent (
343 &mIpSecInstance
.DisabledEvent
345 if (EFI_ERROR (Status
)) {
346 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to create disable event\n"));
347 goto ON_FREE_PRIVATE
;
350 Private
->Signature
= IPSEC_PRIVATE_DATA_SIGNATURE
;
351 Private
->ImageHandle
= ImageHandle
;
352 CopyMem (&Private
->IpSec
, &mIpSecInstance
, sizeof (EFI_IPSEC2_PROTOCOL
));
355 // Initilize Private's members. Thess members is used for IKE.
357 InitializeListHead (&Private
->Udp4List
);
358 InitializeListHead (&Private
->Udp6List
);
359 InitializeListHead (&Private
->Ikev1SessionList
);
360 InitializeListHead (&Private
->Ikev1EstablishedList
);
361 InitializeListHead (&Private
->Ikev2SessionList
);
362 InitializeListHead (&Private
->Ikev2EstablishedList
);
364 RandomSeed (NULL
, 0);
366 // Initialize the ipsec config data and restore it from variable.
368 Status
= IpSecConfigInitialize (Private
);
369 if (EFI_ERROR (Status
)) {
370 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
374 // Install ipsec protocol which is used by ip driver to process ipsec header.
376 Status
= gBS
->InstallMultipleProtocolInterfaces (
378 &gEfiIpSec2ProtocolGuid
,
382 if (EFI_ERROR (Status
)) {
383 goto ON_UNINSTALL_CONFIG
;
386 Status
= EfiLibInstallDriverBindingComponentName2 (
389 &gIpSecDriverBinding
,
391 &gIpSecComponentName
,
392 &gIpSecComponentName2
394 if (EFI_ERROR (Status
)) {
395 goto ON_UNINSTALL_IPSEC
;
401 gBS
->UninstallProtocolInterface (
403 &gEfiIpSec2ProtocolGuid
,
407 gBS
->UninstallProtocolInterface (
409 &gEfiIpSecConfigProtocolGuid
,
410 &Private
->IpSecConfig
413 gBS
->CloseEvent (mIpSecInstance
.DisabledEvent
);
414 mIpSecInstance
.DisabledEvent
= NULL
;