2 Driver Binding Protocol for IPsec Driver.
4 Copyright (c) 2009 - 2010, 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 // If has udp4 io opened on the controller, close and free it.
195 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp4List
) {
197 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
199 // Find the right udp service which installed on the appointed nic handle.
201 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
202 UdpIoFreeIo (UdpSrv
->Input
);
203 UdpSrv
->Input
= NULL
;
206 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
207 UdpIoFreeIo (UdpSrv
->Output
);
208 UdpSrv
->Output
= NULL
;
211 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
212 RemoveEntryList (&UdpSrv
->List
);
214 ASSERT (Private
->Udp4Num
> 0);
219 // If has udp6 io opened on the controller, close and free it.
221 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp6List
) {
223 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
225 // Find the right udp service which installed on the appointed nic handle.
227 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
228 UdpIoFreeIo (UdpSrv
->Input
);
229 UdpSrv
->Input
= NULL
;
232 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
233 UdpIoFreeIo (UdpSrv
->Output
);
234 UdpSrv
->Output
= NULL
;
237 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
238 RemoveEntryList (&UdpSrv
->List
);
240 ASSERT (Private
->Udp6Num
> 0);
248 EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding
= {
249 IpSecDriverBindingSupported
,
250 IpSecDriverBindingStart
,
251 IpSecDriverBindingStop
,
258 This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
260 @param[in] Event Event whose notification function is being invoked.
261 @param[in] Context Pointer to the notification function's context.
271 IPSEC_PRIVATE_DATA
*Private
;
272 Private
= (IPSEC_PRIVATE_DATA
*) Context
;
273 Private
->IsIPsecDisabling
= TRUE
;
274 IkeDeleteAllSas (Private
);
278 This is the declaration of an EFI image entry point. This entry point is
279 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
280 both device drivers and bus drivers.
282 The entry point for IPsec driver which installs the driver binding,
283 component name protocol, IPsec Config protcolon, and IPsec protocol in
286 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
287 @param[in] SystemTable A pointer to the EFI System Table.
289 @retval EFI_SUCCESS The operation completed successfully.
290 @retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
291 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
292 @retval Others The operation is failed.
297 IpSecDriverEntryPoint (
298 IN EFI_HANDLE ImageHandle
,
299 IN EFI_SYSTEM_TABLE
*SystemTable
303 IPSEC_PRIVATE_DATA
*Private
;
304 EFI_IPSEC2_PROTOCOL
*IpSec
;
307 // Check whether ipsec protocol has already been installed.
309 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
311 if (!EFI_ERROR (Status
)) {
312 DEBUG ((DEBUG_WARN
, "_ModuleEntryPoint: IpSec has been already loaded\n"));
313 Status
= EFI_ALREADY_STARTED
;
317 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
319 if (EFI_ERROR (Status
)) {
320 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
324 Private
= AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA
));
326 if (Private
== NULL
) {
327 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to allocate private data\n"));
328 Status
= EFI_OUT_OF_RESOURCES
;
332 // Create disable event to cleanup all SA when ipsec disabled by user.
334 Status
= gBS
->CreateEvent (
339 &mIpSecInstance
.DisabledEvent
341 if (EFI_ERROR (Status
)) {
342 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to create disable event\n"));
343 goto ON_FREE_PRIVATE
;
346 Private
->Signature
= IPSEC_PRIVATE_DATA_SIGNATURE
;
347 Private
->ImageHandle
= ImageHandle
;
348 CopyMem (&Private
->IpSec
, &mIpSecInstance
, sizeof (EFI_IPSEC2_PROTOCOL
));
351 // Initilize Private's members. Thess members is used for IKE.
353 InitializeListHead (&Private
->Udp4List
);
354 InitializeListHead (&Private
->Udp6List
);
355 InitializeListHead (&Private
->Ikev1SessionList
);
356 InitializeListHead (&Private
->Ikev1EstablishedList
);
357 InitializeListHead (&Private
->Ikev2SessionList
);
358 InitializeListHead (&Private
->Ikev2EstablishedList
);
360 RandomSeed (NULL
, 0);
362 // Initialize the ipsec config data and restore it from variable.
364 Status
= IpSecConfigInitialize (Private
);
365 if (EFI_ERROR (Status
)) {
366 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
370 // Install ipsec protocol which is used by ip driver to process ipsec header.
372 Status
= gBS
->InstallMultipleProtocolInterfaces (
374 &gEfiIpSec2ProtocolGuid
,
378 if (EFI_ERROR (Status
)) {
379 goto ON_UNINSTALL_CONFIG
;
382 Status
= EfiLibInstallDriverBindingComponentName2 (
385 &gIpSecDriverBinding
,
387 &gIpSecComponentName
,
388 &gIpSecComponentName2
390 if (EFI_ERROR (Status
)) {
391 goto ON_UNINSTALL_IPSEC
;
397 gBS
->UninstallProtocolInterface (
399 &gEfiIpSec2ProtocolGuid
,
403 gBS
->UninstallProtocolInterface (
405 &gEfiIpSecConfigProtocolGuid
,
406 &Private
->IpSecConfig
409 gBS
->CloseEvent (mIpSecInstance
.DisabledEvent
);
410 mIpSecInstance
.DisabledEvent
= NULL
;