]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IpSecMain.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecMain.c
CommitLineData
9166f840 1/** @file\r
2 The mian interface of IPsec Protocol.\r
3\r
f75a7f56 4 Copyright (c) 2009 - 2018, 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 "IpSecConfigImpl.h"\r
17#include "IpSecImpl.h"\r
18\r
19EFI_IPSEC2_PROTOCOL mIpSecInstance = { IpSecProcess, NULL, TRUE };\r
20\r
21/**\r
22 Handles IPsec packet processing for inbound and outbound IP packets.\r
23\r
24 The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet.\r
25 The behavior is that it can perform one of the following actions:\r
26 bypass the packet, discard the packet, or protect the packet.\r
27\r
0a7294f7 28 @param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance.\r
9166f840 29 @param[in] NicHandle Instance of the network interface.\r
30 @param[in] IpVersion IPV4 or IPV6.\r
31 @param[in, out] IpHead Pointer to the IP Header.\r
32 @param[in, out] LastHead The protocol of the next layer to be processed by IPsec.\r
33 @param[in, out] OptionsBuffer Pointer to the options buffer.\r
34 @param[in, out] OptionsLength Length of the options buffer.\r
35 @param[in, out] FragmentTable Pointer to a list of fragments.\r
36 @param[in, out] FragmentCount Number of fragments.\r
37 @param[in] TrafficDirection Traffic direction.\r
38 @param[out] RecycleSignal Event for recycling of resources.\r
39\r
40 @retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.\r
41 @retval EFI_SUCCESS The packet was protected.\r
42 @retval EFI_ACCESS_DENIED The packet was discarded.\r
43\r
44**/\r
45EFI_STATUS\r
46EFIAPI\r
47IpSecProcess (\r
48 IN EFI_IPSEC2_PROTOCOL *This,\r
49 IN EFI_HANDLE NicHandle,\r
50 IN UINT8 IpVersion,\r
51 IN OUT VOID *IpHead,\r
52 IN OUT UINT8 *LastHead,\r
53 IN OUT VOID **OptionsBuffer,\r
54 IN OUT UINT32 *OptionsLength,\r
55 IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,\r
56 IN OUT UINT32 *FragmentCount,\r
57 IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection,\r
58 OUT EFI_EVENT *RecycleSignal\r
59 )\r
60{\r
61 IPSEC_PRIVATE_DATA *Private;\r
62 IPSEC_SPD_ENTRY *SpdEntry;\r
63 EFI_IPSEC_SPD_SELECTOR *SpdSelector;\r
64 IPSEC_SAD_ENTRY *SadEntry;\r
65 LIST_ENTRY *SpdList;\r
66 LIST_ENTRY *Entry;\r
67 EFI_IPSEC_ACTION Action;\r
68 EFI_STATUS Status;\r
69 UINT8 *IpPayload;\r
70 UINT8 OldLastHead;\r
71 BOOLEAN IsOutbound;\r
72\r
f75a7f56
LG
73 if (OptionsBuffer == NULL ||\r
74 OptionsLength == NULL ||\r
75 FragmentTable == NULL ||\r
47b27101 76 FragmentCount == NULL\r
77 ) {\r
78 return EFI_INVALID_PARAMETER;\r
79 }\r
9166f840 80 Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (This);\r
81 IpPayload = (*FragmentTable)[0].FragmentBuffer;\r
82 IsOutbound = (BOOLEAN) ((TrafficDirection == EfiIPsecOutBound) ? TRUE : FALSE);\r
83 OldLastHead = *LastHead;\r
84 *RecycleSignal = NULL;\r
85 SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
f75a7f56 86\r
9166f840 87 if (!IsOutbound) {\r
88 //\r
89 // For inbound traffic, process the ipsec header of the packet.\r
90 //\r
91 Status = IpSecProtectInboundPacket (\r
92 IpVersion,\r
93 IpHead,\r
94 LastHead,\r
95 OptionsBuffer,\r
96 OptionsLength,\r
97 FragmentTable,\r
98 FragmentCount,\r
99 &SpdSelector,\r
100 RecycleSignal\r
101 );\r
102\r
103 if (Status == EFI_ACCESS_DENIED || Status == EFI_OUT_OF_RESOURCES) {\r
104 //\r
105 // The packet is denied to access.\r
106 //\r
107 goto ON_EXIT;\r
108 }\r
109\r
110 if (Status == EFI_SUCCESS) {\r
f75a7f56 111\r
9166f840 112 //\r
113 // Check the spd entry if the packet is accessible.\r
114 //\r
115 if (SpdSelector == NULL) {\r
116 Status = EFI_ACCESS_DENIED;\r
117 goto ON_EXIT;\r
118 }\r
119\r
120 Status = EFI_ACCESS_DENIED;\r
121 NET_LIST_FOR_EACH (Entry, SpdList) {\r
122 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
f75a7f56 123 if (IsSubSpdSelector (\r
9166f840 124 (EFI_IPSEC_CONFIG_SELECTOR *) SpdSelector,\r
125 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
126 )) {\r
127 Status = EFI_SUCCESS;\r
128 }\r
f75a7f56 129 }\r
9166f840 130 goto ON_EXIT;\r
f75a7f56 131 }\r
9166f840 132 }\r
133\r
f75a7f56 134 Status = EFI_ACCESS_DENIED;\r
9166f840 135\r
136 NET_LIST_FOR_EACH (Entry, SpdList) {\r
137 //\r
138 // For outbound and non-ipsec Inbound traffic: check the spd entry.\r
139 //\r
140 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
141\r
142 if (EFI_ERROR (IpSecLookupSpdEntry (\r
143 SpdEntry,\r
144 IpVersion,\r
145 IpHead,\r
146 IpPayload,\r
147 OldLastHead,\r
f75a7f56 148 IsOutbound,\r
9166f840 149 &Action\r
150 ))) {\r
151 //\r
152 // If the related SPD not find\r
153 //\r
154 continue;\r
155 }\r
156\r
157 switch (Action) {\r
158\r
159 case EfiIPsecActionProtect:\r
160\r
161 if (IsOutbound) {\r
162 //\r
163 // For outbound traffic, lookup the sad entry.\r
164 //\r
165 Status = IpSecLookupSadEntry (\r
166 Private,\r
167 NicHandle,\r
168 IpVersion,\r
169 IpHead,\r
170 IpPayload,\r
171 OldLastHead,\r
172 SpdEntry,\r
173 &SadEntry\r
174 );\r
175\r
176 if (SadEntry != NULL) {\r
177 //\r
178 // Process the packet by the found sad entry.\r
179 //\r
180 Status = IpSecProtectOutboundPacket (\r
181 IpVersion,\r
182 IpHead,\r
183 LastHead,\r
184 OptionsBuffer,\r
185 OptionsLength,\r
186 FragmentTable,\r
187 FragmentCount,\r
188 SadEntry,\r
189 RecycleSignal\r
190 );\r
191\r
192 } else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {\r
193 //\r
194 // TODO: if no need return not ready to upper layer, change here.\r
195 //\r
196 Status = EFI_SUCCESS;\r
197 }\r
198 } else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {\r
199 //\r
200 // For inbound icmpv6 traffic except ping request, accept the packet\r
201 // although no sad entry associated with protect spd entry.\r
202 //\r
203 Status = IpSecLookupSadEntry (\r
204 Private,\r
205 NicHandle,\r
206 IpVersion,\r
207 IpHead,\r
208 IpPayload,\r
209 OldLastHead,\r
210 SpdEntry,\r
211 &SadEntry\r
212 );\r
213 if (SadEntry == NULL) {\r
214 Status = EFI_SUCCESS;\r
215 }\r
216 }\r
217\r
218 goto ON_EXIT;\r
219\r
220 case EfiIPsecActionBypass:\r
221 Status = EFI_SUCCESS;\r
222 goto ON_EXIT;\r
223\r
224 case EfiIPsecActionDiscard:\r
f75a7f56 225 goto ON_EXIT;\r
9166f840 226 }\r
227 }\r
f75a7f56 228\r
9166f840 229 //\r
230 // If don't find the related SPD entry, return the EFI_ACCESS_DENIED and discard it.\r
231 // But it the packet is NS/NA, it should be by passed even not find the related SPD entry.\r
232 //\r
f75a7f56 233 if (OldLastHead == IP6_ICMP &&\r
9166f840 234 (*IpPayload == ICMP_V6_NEIGHBOR_SOLICIT || *IpPayload == ICMP_V6_NEIGHBOR_ADVERTISE)\r
235 ){\r
236 Status = EFI_SUCCESS;\r
237 }\r
f75a7f56 238\r
9166f840 239ON_EXIT:\r
240 return Status;\r
241}\r
242\r