]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IkeService.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeService.c
CommitLineData
9166f840 1/** @file\r
2 Provide IPsec Key Exchange (IKE) service general interfaces.\r
6cf9230f 3\r
6879581d 4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
9166f840 5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "IkeService.h"\r
17#include "IpSecConfigImpl.h"\r
18#include "Ikev2/Utility.h"\r
19\r
20IKE_EXCHANGE_INTERFACE *mIkeExchange[] = {\r
21 &mIkev1Exchange,\r
22 &mIkev2Exchange\r
23};\r
24\r
25EFI_UDP4_CONFIG_DATA mUdp4Conf = {\r
26 FALSE,\r
27 FALSE,\r
28 FALSE,\r
29 TRUE,\r
30 //\r
31 // IO parameters\r
32 //\r
33 0,\r
34 64,\r
35 FALSE,\r
36 0,\r
37 1000000,\r
38 FALSE,\r
ce68d3bc
SZ
39 {{0,0,0,0}},\r
40 {{0,0,0,0}},\r
9166f840 41 IKE_DEFAULT_PORT,\r
ce68d3bc 42 {{0,0,0,0}},\r
9166f840 43 0\r
44};\r
45\r
46EFI_UDP6_CONFIG_DATA mUdp6Conf = {\r
47 FALSE,\r
48 FALSE,\r
49 TRUE,\r
50 //\r
51 // IO parameters\r
52 //\r
53 0,\r
54 128,\r
55 0,\r
56 1000000,\r
57 //Access Point\r
ce68d3bc 58 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},\r
9166f840 59 IKE_DEFAULT_PORT,\r
ce68d3bc 60 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},\r
9166f840 61 0\r
62};\r
63\r
64/**\r
65 Check if the NIC handle is binded to a Udp service.\r
66\r
67 @param[in] Private Pointer of IPSEC_PRIVATE_DATA.\r
76389e18 68 @param[in] Handle The Handle of the NIC card.\r
9166f840 69 @param[in] IpVersion The version of the IP stack.\r
70\r
71 @return a pointer of IKE_UDP_SERVICE.\r
72\r
73**/\r
74IKE_UDP_SERVICE *\r
75IkeLookupUdp (\r
76 IN IPSEC_PRIVATE_DATA *Private,\r
77 IN EFI_HANDLE Handle,\r
78 IN UINT8 IpVersion\r
79 )\r
80{\r
81 LIST_ENTRY *Head;\r
82 LIST_ENTRY *Entry;\r
83 LIST_ENTRY *Next;\r
84 IKE_UDP_SERVICE *Udp;\r
85\r
86 Udp = NULL;\r
87 Head = (IpVersion == IP_VERSION_4) ? &Private->Udp4List : &Private->Udp6List;\r
88\r
89 NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {\r
90\r
91 Udp = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
92 //\r
93 // Find the right udp service which installed on the appointed NIC handle.\r
94 //\r
95 if (Handle == Udp->NicHandle) {\r
96 break;\r
97 } else {\r
98 Udp = NULL;\r
99 }\r
100 }\r
101\r
102 return Udp;\r
103}\r
104\r
105/**\r
106 Configure a UDPIO's UDP4 instance.\r
6cf9230f 107\r
108 This fuction is called by the UdpIoCreateIo() to configures a\r
9166f840 109 UDP4 instance.\r
6cf9230f 110\r
9166f840 111 @param[in] UdpIo The UDP_IO to be configured.\r
112 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
6cf9230f 113\r
9166f840 114 @retval EFI_SUCCESS The configuration succeeded.\r
115 @retval Others The UDP4 instance fails to configure.\r
116\r
117**/\r
118EFI_STATUS\r
1d8fa5e9 119EFIAPI\r
9166f840 120IkeConfigUdp4 (\r
121 IN UDP_IO *UdpIo,\r
122 IN VOID *Context\r
123 )\r
124{\r
125 EFI_UDP4_CONFIG_DATA Udp4Cfg;\r
126 EFI_UDP4_PROTOCOL *Udp4;\r
127\r
128 ZeroMem (&Udp4Cfg, sizeof (EFI_UDP4_CONFIG_DATA));\r
129\r
130 Udp4 = UdpIo->Protocol.Udp4;\r
131 CopyMem (\r
132 &Udp4Cfg,\r
133 &mUdp4Conf,\r
134 sizeof (EFI_UDP4_CONFIG_DATA)\r
135 );\r
136\r
137 if (Context != NULL) {\r
138 //\r
139 // Configure udp4 io with local default address.\r
140 //\r
141 Udp4Cfg.UseDefaultAddress = TRUE;\r
142 }\r
143\r
144 return Udp4->Configure (Udp4, &Udp4Cfg);\r
145}\r
146\r
147/**\r
148 Configure a UDPIO's UDP6 instance.\r
6cf9230f 149\r
150 This fuction is called by the UdpIoCreateIo()to configure a\r
9166f840 151 UDP6 instance.\r
6cf9230f 152\r
9166f840 153 @param[in] UdpIo The UDP_IO to be configured.\r
154 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
6cf9230f 155\r
9166f840 156 @retval EFI_SUCCESS The configuration succeeded.\r
157 @retval Others The configuration fails.\r
158\r
159**/\r
160EFI_STATUS\r
1d8fa5e9 161EFIAPI\r
9166f840 162IkeConfigUdp6 (\r
163 IN UDP_IO *UdpIo,\r
164 IN VOID *Context\r
165 )\r
166{\r
167 EFI_UDP6_PROTOCOL *Udp6;\r
168 EFI_UDP6_CONFIG_DATA Udp6Cfg;\r
169\r
170 ZeroMem (&Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));\r
171\r
172 Udp6 = UdpIo->Protocol.Udp6;\r
173 CopyMem (\r
174 &Udp6Cfg,\r
175 &mUdp6Conf,\r
176 sizeof (EFI_UDP6_CONFIG_DATA)\r
177 );\r
178\r
179 if (Context != NULL) {\r
180 //\r
181 // Configure instance with a destination address to start source address\r
182 // selection, and then get the configure data from the mode data to store\r
183 // the source address.\r
184 //\r
185 CopyMem (\r
186 &Udp6Cfg.RemoteAddress,\r
187 Context,\r
188 sizeof (EFI_IPv6_ADDRESS)\r
189 );\r
190 }\r
191\r
192 return Udp6->Configure (Udp6, &Udp6Cfg);\r
193}\r
194\r
195/**\r
196 Open and configure the related output UDPIO for IKE packet sending.\r
6cf9230f 197\r
198 If the UdpService is not configured, this fuction calls UdpIoCreatIo() to\r
9166f840 199 create UDPIO to bind this UdpService for IKE packet sending. If the UdpService\r
200 has already been configured, then return.\r
6cf9230f 201\r
9166f840 202 @param[in] UdpService The UDP_IO to be configured.\r
203 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().\r
6cf9230f 204\r
9166f840 205 @retval EFI_SUCCESS The configuration is successful.\r
206 @retval Others The configuration fails.\r
207\r
208**/\r
209EFI_STATUS\r
210IkeOpenOutputUdp (\r
211 IN IKE_UDP_SERVICE *UdpService,\r
212 IN EFI_IP_ADDRESS *RemoteIp\r
213 )\r
214{\r
215 EFI_STATUS Status;\r
216 EFI_IP4_CONFIG_PROTOCOL *Ip4Cfg;\r
217 EFI_IP4_IPCONFIG_DATA *Ip4CfgData;\r
218 UINTN BufSize;\r
219 EFI_IP6_MODE_DATA Ip6ModeData;\r
220 EFI_UDP6_PROTOCOL *Udp6;\r
221\r
222 Status = EFI_SUCCESS;\r
223 Ip4CfgData = NULL;\r
224 BufSize = 0;\r
225\r
226 //\r
227 // Check whether the input and output udp io are both configured.\r
228 //\r
229 if (UdpService->IsConfigured) {\r
230 goto ON_EXIT;\r
231 }\r
232\r
233 if (UdpService->IpVersion == UDP_IO_UDP4_VERSION) {\r
234 //\r
235 // Handle ip4config protocol to get local default address.\r
236 //\r
237 Status = gBS->HandleProtocol (\r
238 UdpService->NicHandle,\r
239 &gEfiIp4ConfigProtocolGuid,\r
240 (VOID **) &Ip4Cfg\r
241 );\r
242\r
243 if (EFI_ERROR (Status)) {\r
244 goto ON_EXIT;\r
245 }\r
246\r
247 Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, NULL);\r
248\r
249 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
250 goto ON_EXIT;\r
251 }\r
252\r
253 Ip4CfgData = AllocateZeroPool (BufSize);\r
254\r
255 if (Ip4CfgData == NULL) {\r
256 Status = EFI_OUT_OF_RESOURCES;\r
257 goto ON_EXIT;\r
258 }\r
259\r
260 Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, Ip4CfgData);\r
261 if (EFI_ERROR (Status)) {\r
262 goto ON_EXIT;\r
263 }\r
264\r
265 CopyMem (\r
266 &UdpService->DefaultAddress.v4,\r
267 &Ip4CfgData->StationAddress,\r
268 sizeof (EFI_IPv4_ADDRESS)\r
269 );\r
270\r
271 //\r
272 // Create udp4 io for output with local default address.\r
273 //\r
274 UdpService->Output = UdpIoCreateIo (\r
275 UdpService->NicHandle,\r
276 UdpService->ImageHandle,\r
277 IkeConfigUdp4,\r
278 UDP_IO_UDP4_VERSION,\r
279 &UdpService->DefaultAddress\r
280 );\r
281\r
282 if (UdpService->Output == NULL) {\r
283 Status = EFI_OUT_OF_RESOURCES;\r
284 goto ON_EXIT;\r
285 }\r
286\r
287 } else {\r
288 //\r
289 // Create udp6 io for output with remote address.\r
290 //\r
291 UdpService->Output = UdpIoCreateIo (\r
292 UdpService->NicHandle,\r
293 UdpService->ImageHandle,\r
294 IkeConfigUdp6,\r
295 UDP_IO_UDP6_VERSION,\r
296 RemoteIp\r
297 );\r
298\r
299 if (UdpService->Output == NULL) {\r
300 Status = EFI_OUT_OF_RESOURCES;\r
301 goto ON_EXIT;\r
302 }\r
303 //\r
304 // Get ip6 mode data to get the result of source address selection.\r
305 //\r
306 ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));\r
307\r
308 Udp6 = UdpService->Output->Protocol.Udp6;\r
309 Status = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);\r
310\r
311 if (EFI_ERROR (Status)) {\r
312 UdpIoFreeIo (UdpService->Output);\r
313 goto ON_EXIT;\r
314 }\r
315 //\r
316 // Reconfigure udp6 io without remote address.\r
317 //\r
318 Udp6->Configure (Udp6, NULL);\r
319 Status = IkeConfigUdp6 (UdpService->Output, NULL);\r
320\r
321 //\r
322 // Record the selected source address for ipsec process later.\r
323 //\r
324 CopyMem (\r
325 &UdpService->DefaultAddress.v6,\r
326 &Ip6ModeData.ConfigData.StationAddress,\r
327 sizeof (EFI_IPv6_ADDRESS)\r
328 );\r
329 }\r
330\r
331 UdpService->IsConfigured = TRUE;\r
332\r
333ON_EXIT:\r
334 if (Ip4CfgData != NULL) {\r
335 FreePool (Ip4CfgData);\r
336 }\r
337\r
338 return Status;\r
339}\r
340\r
341/**\r
342 Open and configure a UDPIO of Udp4 for IKE packet receiving.\r
6cf9230f 343\r
344 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and\r
9166f840 345 UDP4 IO for each NIC handle.\r
6cf9230f 346\r
9166f840 347 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
348 @param[in] Controller Handler for NIC card.\r
6879581d 349 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.\r
6cf9230f 350\r
9166f840 351 @retval EFI_SUCCESS The Operation is successful.\r
352 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
6cf9230f 353\r
9166f840 354**/\r
355EFI_STATUS\r
356IkeOpenInputUdp4 (\r
357 IN IPSEC_PRIVATE_DATA *Private,\r
6879581d 358 IN EFI_HANDLE Controller,\r
359 IN EFI_HANDLE ImageHandle\r
9166f840 360 )\r
361{\r
362 IKE_UDP_SERVICE *Udp4Srv;\r
363\r
364 //\r
365 // Check whether udp4 io of the controller has already been opened.\r
366 //\r
367 Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);\r
368\r
369 if (Udp4Srv != NULL) {\r
370 return EFI_ALREADY_STARTED;\r
371 }\r
372\r
373 Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
374\r
375 if (Udp4Srv == NULL) {\r
376 return EFI_OUT_OF_RESOURCES;\r
377 }\r
378 //\r
379 // Create udp4 io for iutput.\r
380 //\r
381 Udp4Srv->Input = UdpIoCreateIo (\r
382 Controller,\r
6879581d 383 ImageHandle,\r
9166f840 384 IkeConfigUdp4,\r
385 UDP_IO_UDP4_VERSION,\r
386 NULL\r
387 );\r
388\r
389 if (Udp4Srv->Input == NULL) {\r
390 FreePool (Udp4Srv);\r
391 return EFI_OUT_OF_RESOURCES;\r
392 }\r
393\r
394 Udp4Srv->NicHandle = Controller;\r
6879581d 395 Udp4Srv->ImageHandle = ImageHandle;\r
9166f840 396 Udp4Srv->ListHead = &(Private->Udp4List);\r
397 Udp4Srv->IpVersion = UDP_IO_UDP4_VERSION;\r
398 Udp4Srv->IsConfigured = FALSE;\r
399\r
400 ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
401\r
402 //\r
403 // Insert the udp4 io into the list and increase the count.\r
404 //\r
405 InsertTailList (&Private->Udp4List, &Udp4Srv->List);\r
406\r
407 Private->Udp4Num++;\r
408\r
409 UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);\r
410\r
411 return EFI_SUCCESS;\r
412}\r
413\r
414/**\r
415 Open and configure a UDPIO of Udp6 for IKE packet receiving.\r
6cf9230f 416\r
9166f840 417 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6\r
418 IO for each NIC handle.\r
6cf9230f 419\r
9166f840 420 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
421 @param[in] Controller Handler for NIC card.\r
6879581d 422 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.\r
6cf9230f 423\r
9166f840 424 @retval EFI_SUCCESS The Operation is successful.\r
425 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
6cf9230f 426\r
9166f840 427**/\r
428EFI_STATUS\r
429IkeOpenInputUdp6 (\r
430 IN IPSEC_PRIVATE_DATA *Private,\r
6879581d 431 IN EFI_HANDLE Controller,\r
432 IN EFI_HANDLE ImageHandle\r
9166f840 433 )\r
434{\r
435 IKE_UDP_SERVICE *Udp6Srv;\r
436\r
437 Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);\r
438\r
439 if (Udp6Srv != NULL) {\r
440 return EFI_ALREADY_STARTED;\r
441 }\r
442\r
443 Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
444\r
445 if (Udp6Srv == NULL) {\r
446 return EFI_OUT_OF_RESOURCES;\r
447 }\r
448 //\r
449 // Create udp6 io for input.\r
450 //\r
451 Udp6Srv->Input = UdpIoCreateIo (\r
452 Controller,\r
6879581d 453 ImageHandle,\r
9166f840 454 IkeConfigUdp6,\r
455 UDP_IO_UDP6_VERSION,\r
456 NULL\r
457 );\r
458\r
459 if (Udp6Srv->Input == NULL) {\r
460 FreePool (Udp6Srv);\r
461 return EFI_OUT_OF_RESOURCES;\r
462 }\r
463\r
464 Udp6Srv->NicHandle = Controller;\r
6879581d 465 Udp6Srv->ImageHandle = ImageHandle;\r
9166f840 466 Udp6Srv->ListHead = &(Private->Udp6List);\r
467 Udp6Srv->IpVersion = UDP_IO_UDP6_VERSION;\r
468 Udp6Srv->IsConfigured = FALSE;\r
469\r
470 ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
471\r
472 //\r
473 // Insert the udp6 io into the list and increase the count.\r
474 //\r
475 InsertTailList (&Private->Udp6List, &Udp6Srv->List);\r
476\r
477 Private->Udp6Num++;\r
478\r
479 UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);\r
480\r
481 return EFI_SUCCESS;\r
482}\r
483\r
484/**\r
485 The general interface of starting IPsec Key Exchange.\r
6cf9230f 486\r
9166f840 487 This function is called when a IKE negotiation to start getting a Key.\r
6cf9230f 488\r
489 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for\r
9166f840 490 IKE packet sending.\r
491 @param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.\r
492 @param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.\r
6cf9230f 493\r
9166f840 494 @retval EFI_SUCCESS The Operation is successful.\r
495 @retval EFI_ACCESS_DENIED No related PAD entry was found.\r
496 @retval EFI_INVALID_PARAMETER The IKE version is not supported.\r
6cf9230f 497\r
9166f840 498**/\r
499EFI_STATUS\r
500IkeNegotiate (\r
501 IN IKE_UDP_SERVICE *UdpService,\r
502 IN IPSEC_SPD_ENTRY *SpdEntry,\r
503 IN EFI_IP_ADDRESS *RemoteIp\r
504 )\r
505{\r
506 EFI_STATUS Status;\r
507 UINT8 *IkeSaSession;\r
508 IKE_EXCHANGE_INTERFACE *Exchange;\r
509 IPSEC_PRIVATE_DATA *Private;\r
510 IPSEC_PAD_ENTRY *PadEntry;\r
511 UINT8 IkeVersion;\r
512\r
513 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
514 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
515 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
516\r
517 //\r
518 // Try to open udp io for output if it hasn't.\r
519 //\r
520 Status = IkeOpenOutputUdp (UdpService, RemoteIp);\r
521 if (EFI_ERROR (Status)) {\r
522 return Status;\r
523 }\r
524 //\r
525 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.\r
6cf9230f 526 //\r
527 IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp);\r
9166f840 528\r
529\r
530 if (IkeSaSession == NULL) {\r
531 //\r
532 // Find the pad entry by the remote ip address.\r
533 //\r
534 PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);\r
535 if (PadEntry == NULL) {\r
536 return EFI_ACCESS_DENIED;\r
537 }\r
538 //\r
539 // Determine the IKE exchange instance by the auth protocol in pad entry.\r
540 //\r
541 ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);\r
542 if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {\r
543 return EFI_INVALID_PARAMETER;\r
544 }\r
545 Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];\r
546 //\r
547 // Start the main mode stage to negotiate IKE SA.\r
548 //\r
549 Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);\r
550 } else {\r
551 //\r
552 // Determine the IKE exchange instance by the IKE version in IKE SA session.\r
553 //\r
554 IkeVersion = IkeGetVersionFromSession (IkeSaSession);\r
555 if (IkeVersion != 2) {\r
556 return EFI_INVALID_PARAMETER;\r
557 }\r
6cf9230f 558\r
9166f840 559 Exchange = mIkeExchange[IkeVersion - 1];\r
560 //\r
561 // Start the quick mode stage to negotiate child SA.\r
562 //\r
563 Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);\r
564 }\r
565\r
566 return Status;\r
567}\r
568\r
569/**\r
570 The generic interface when receive a IKE packet.\r
6cf9230f 571\r
9166f840 572 This function is called when UDP IO receives a IKE packet.\r
6cf9230f 573\r
9166f840 574 @param[in] Packet Point to received IKE packet.\r
6cf9230f 575 @param[in] EndPoint Point to UDP_END_POINT which contains the information of\r
9166f840 576 Remote IP and Port.\r
577 @param[in] IoStatus The Status of Recieve Token.\r
578 @param[in] Context Point to data passed from the caller.\r
6cf9230f 579\r
9166f840 580**/\r
581VOID\r
1d8fa5e9 582EFIAPI\r
9166f840 583IkeDispatch (\r
584 IN NET_BUF *Packet,\r
585 IN UDP_END_POINT *EndPoint,\r
586 IN EFI_STATUS IoStatus,\r
587 IN VOID *Context\r
588 )\r
589{\r
590 IPSEC_PRIVATE_DATA *Private;\r
591 IKE_PACKET *IkePacket;\r
592 IKE_HEADER *IkeHdr;\r
593 IKE_UDP_SERVICE *UdpService;\r
594 IKE_EXCHANGE_INTERFACE *Exchange;\r
595 EFI_STATUS Status;\r
596\r
597 UdpService = (IKE_UDP_SERVICE *) Context;\r
598 IkePacket = NULL;\r
599 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
600 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
601 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
602\r
603 if (EFI_ERROR (IoStatus)) {\r
604 goto ON_EXIT;\r
605 }\r
606 //\r
607 // Check whether the ipsec is enabled or not.\r
608 //\r
609 if (Private->IpSec.DisabledFlag == TRUE) {\r
610 goto ON_EXIT;\r
611 }\r
612\r
613 if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {\r
614 goto ON_EXIT;\r
615 }\r
616\r
617 //\r
618 // Build IKE packet from the received netbuf.\r
619 //\r
620 IkePacket = IkePacketFromNetbuf (Packet);\r
621\r
622 if (IkePacket == NULL) {\r
623 goto ON_EXIT;\r
624 }\r
625 //\r
626 // Get the remote address from the IKE packet.\r
627 //\r
628 if (UdpService->IpVersion == IP_VERSION_4) {\r
629 *(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));\r
630 } else {\r
631 CopyMem (\r
632 &IkePacket->RemotePeerIp,\r
633 NTOHLLL (&EndPoint->RemoteAddr.v6),\r
634 sizeof (EFI_IPv6_ADDRESS)\r
635 );\r
636 }\r
637 //\r
638 // Try to open udp io for output if hasn't.\r
639 //\r
640 Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);\r
641\r
642 if (EFI_ERROR (Status)) {\r
643 goto ON_EXIT;\r
644 }\r
645\r
646 IkeHdr = IkePacket->Header;\r
647\r
648 //\r
649 // Determine the IKE exchange instance by the IKE version in IKE header.\r
650 //\r
651 if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {\r
652 Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];\r
653 } else {\r
654 goto ON_EXIT;\r
655 }\r
656\r
657 switch (IkeHdr->ExchangeType) {\r
658 case IKE_XCG_TYPE_IDENTITY_PROTECT:\r
659 case IKE_XCG_TYPE_SA_INIT:\r
660 case IKE_XCG_TYPE_AUTH:\r
661 Exchange->HandleSa (UdpService, IkePacket);\r
662 break;\r
663\r
664 case IKE_XCG_TYPE_QM:\r
665 case IKE_XCG_TYPE_CREATE_CHILD_SA:\r
666 Exchange->HandleChildSa (UdpService, IkePacket);\r
667 break;\r
668\r
669 case IKE_XCG_TYPE_INFO:\r
670 case IKE_XCG_TYPE_INFO2:\r
671 Exchange->HandleInfo (UdpService, IkePacket);\r
672 break;\r
673\r
674 default:\r
675 break;\r
676 }\r
677\r
678ON_EXIT:\r
679 if (IkePacket != NULL) {\r
680 IkePacketFree (IkePacket);\r
681 }\r
682\r
683 if (Packet != NULL) {\r
684 NetbufFree (Packet);\r
685 }\r
686\r
687 UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);\r
688\r
689 return ;\r
690}\r
691\r
692/**\r
693 Delete all established IKE SAs and related Child SAs.\r
6cf9230f 694\r
695 This function is the subfunction of the IpSecCleanupAllSa(). It first calls\r
696 IkeDeleteChildSa() to delete all Child SAs then send out the related\r
9166f840 697 Information packet.\r
698\r
6cf9230f 699 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA\r
4b0f5775 700 @param[in] IsDisableIpsec Indicate whether needs to disable IPsec.\r
9166f840 701\r
702**/\r
703VOID\r
704IkeDeleteAllSas (\r
6cf9230f 705 IN IPSEC_PRIVATE_DATA *Private,\r
706 IN BOOLEAN IsDisableIpsec\r
9166f840 707 )\r
708{\r
709 LIST_ENTRY *Entry;\r
710 LIST_ENTRY *NextEntry;\r
711 IKEV2_SA_SESSION *Ikev2SaSession;\r
712 UINT8 Value;\r
713 EFI_STATUS Status;\r
714 IKE_EXCHANGE_INTERFACE *Exchange;\r
715 UINT8 IkeVersion;\r
716\r
717 Exchange = NULL;\r
718\r
719 //\r
720 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.\r
721 //\r
722\r
723 //\r
724 // If IKEv2 SAs are under establishing, delete it directly.\r
725 //\r
726 if (!IsListEmpty (&Private->Ikev2SessionList)) {\r
727 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->Ikev2SessionList) {\r
6cf9230f 728 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
9166f840 729 RemoveEntryList (Entry);\r
730 Ikev2SaSessionFree (Ikev2SaSession);\r
731 }\r
732 }\r
6cf9230f 733\r
9166f840 734 //\r
735 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE\r
736 // and turn off the IsIPsecDisabling flag.\r
737 //\r
6cf9230f 738 if (IsListEmpty (&Private->Ikev2EstablishedList) && IsDisableIpsec) {\r
9166f840 739 Value = IPSEC_STATUS_DISABLED;\r
740 Status = gRT->SetVariable (\r
741 IPSECCONFIG_STATUS_NAME,\r
742 &gEfiIpSecConfigProtocolGuid,\r
743 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
744 sizeof (Value),\r
745 &Value\r
746 );\r
747 if (!EFI_ERROR (Status)) {\r
748 Private->IpSec.DisabledFlag = TRUE;\r
749 Private->IsIPsecDisabling = FALSE;\r
750 return ;\r
751 }\r
752 }\r
753\r
754 //\r
755 // Delete established IKEv2 SAs.\r
756 //\r
757 if (!IsListEmpty (&Private->Ikev2EstablishedList)) {\r
758 for (Entry = Private->Ikev2EstablishedList.ForwardLink; Entry != &Private->Ikev2EstablishedList;) {\r
759 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
760 Entry = Entry->ForwardLink;\r
6cf9230f 761\r
9166f840 762 Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;\r
763\r
764 //\r
765 // Call for Information Exchange.\r
766 //\r
767 IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);\r
768 if (IkeVersion == 2) {\r
769 Exchange = mIkeExchange[IkeVersion - 1];\r
770 Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);\r
6cf9230f 771 }\r
9166f840 772 }\r
773 }\r
6cf9230f 774\r
9166f840 775}\r
776\r
777\r
778\r