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