]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IpSecMain.c
Update the relevant drivers to use the correct GUID for EFI_IPSEC2_PROTOCOL.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecMain.c
CommitLineData
9166f840 1/** @file\r
2 The mian interface of IPsec Protocol.\r
3\r
4 Copyright (c) 2009 - 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 "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
73 Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (This);\r
74 IpPayload = (*FragmentTable)[0].FragmentBuffer;\r
75 IsOutbound = (BOOLEAN) ((TrafficDirection == EfiIPsecOutBound) ? TRUE : FALSE);\r
76 OldLastHead = *LastHead;\r
77 *RecycleSignal = NULL;\r
78 SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
79 \r
80 if (!IsOutbound) {\r
81 //\r
82 // For inbound traffic, process the ipsec header of the packet.\r
83 //\r
84 Status = IpSecProtectInboundPacket (\r
85 IpVersion,\r
86 IpHead,\r
87 LastHead,\r
88 OptionsBuffer,\r
89 OptionsLength,\r
90 FragmentTable,\r
91 FragmentCount,\r
92 &SpdSelector,\r
93 RecycleSignal\r
94 );\r
95\r
96 if (Status == EFI_ACCESS_DENIED || Status == EFI_OUT_OF_RESOURCES) {\r
97 //\r
98 // The packet is denied to access.\r
99 //\r
100 goto ON_EXIT;\r
101 }\r
102\r
103 if (Status == EFI_SUCCESS) {\r
104 \r
105 //\r
106 // Check the spd entry if the packet is accessible.\r
107 //\r
108 if (SpdSelector == NULL) {\r
109 Status = EFI_ACCESS_DENIED;\r
110 goto ON_EXIT;\r
111 }\r
112\r
113 Status = EFI_ACCESS_DENIED;\r
114 NET_LIST_FOR_EACH (Entry, SpdList) {\r
115 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
116 if (IsSubSpdSelector ( \r
117 (EFI_IPSEC_CONFIG_SELECTOR *) SpdSelector,\r
118 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
119 )) {\r
120 Status = EFI_SUCCESS;\r
121 }\r
122 } \r
123 goto ON_EXIT;\r
124 } \r
125 }\r
126\r
127 Status = EFI_ACCESS_DENIED; \r
128\r
129 NET_LIST_FOR_EACH (Entry, SpdList) {\r
130 //\r
131 // For outbound and non-ipsec Inbound traffic: check the spd entry.\r
132 //\r
133 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
134\r
135 if (EFI_ERROR (IpSecLookupSpdEntry (\r
136 SpdEntry,\r
137 IpVersion,\r
138 IpHead,\r
139 IpPayload,\r
140 OldLastHead,\r
141 IsOutbound, \r
142 &Action\r
143 ))) {\r
144 //\r
145 // If the related SPD not find\r
146 //\r
147 continue;\r
148 }\r
149\r
150 switch (Action) {\r
151\r
152 case EfiIPsecActionProtect:\r
153\r
154 if (IsOutbound) {\r
155 //\r
156 // For outbound traffic, lookup the sad entry.\r
157 //\r
158 Status = IpSecLookupSadEntry (\r
159 Private,\r
160 NicHandle,\r
161 IpVersion,\r
162 IpHead,\r
163 IpPayload,\r
164 OldLastHead,\r
165 SpdEntry,\r
166 &SadEntry\r
167 );\r
168\r
169 if (SadEntry != NULL) {\r
170 //\r
171 // Process the packet by the found sad entry.\r
172 //\r
173 Status = IpSecProtectOutboundPacket (\r
174 IpVersion,\r
175 IpHead,\r
176 LastHead,\r
177 OptionsBuffer,\r
178 OptionsLength,\r
179 FragmentTable,\r
180 FragmentCount,\r
181 SadEntry,\r
182 RecycleSignal\r
183 );\r
184\r
185 } else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {\r
186 //\r
187 // TODO: if no need return not ready to upper layer, change here.\r
188 //\r
189 Status = EFI_SUCCESS;\r
190 }\r
191 } else if (OldLastHead == IP6_ICMP && *IpPayload != ICMP_V6_ECHO_REQUEST) {\r
192 //\r
193 // For inbound icmpv6 traffic except ping request, accept the packet\r
194 // although no sad entry associated with protect spd entry.\r
195 //\r
196 Status = IpSecLookupSadEntry (\r
197 Private,\r
198 NicHandle,\r
199 IpVersion,\r
200 IpHead,\r
201 IpPayload,\r
202 OldLastHead,\r
203 SpdEntry,\r
204 &SadEntry\r
205 );\r
206 if (SadEntry == NULL) {\r
207 Status = EFI_SUCCESS;\r
208 }\r
209 }\r
210\r
211 goto ON_EXIT;\r
212\r
213 case EfiIPsecActionBypass:\r
214 Status = EFI_SUCCESS;\r
215 goto ON_EXIT;\r
216\r
217 case EfiIPsecActionDiscard:\r
218 goto ON_EXIT; \r
219 }\r
220 }\r
221 \r
222 //\r
223 // If don't find the related SPD entry, return the EFI_ACCESS_DENIED and discard it.\r
224 // But it the packet is NS/NA, it should be by passed even not find the related SPD entry.\r
225 //\r
226 if (OldLastHead == IP6_ICMP && \r
227 (*IpPayload == ICMP_V6_NEIGHBOR_SOLICIT || *IpPayload == ICMP_V6_NEIGHBOR_ADVERTISE)\r
228 ){\r
229 Status = EFI_SUCCESS;\r
230 }\r
231 \r
232ON_EXIT:\r
233 return Status;\r
234}\r
235\r