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