2 The mian interface of IPsec Protocol.
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "IpSecConfigImpl.h"
17 #include "IpSecImpl.h"
19 EFI_IPSEC2_PROTOCOL mIpSecInstance
= { IpSecProcess
, NULL
, TRUE
};
22 Handles IPsec packet processing for inbound and outbound IP packets.
24 The EFI_IPSEC_PROCESS process routine handles each inbound or outbound packet.
25 The behavior is that it can perform one of the following actions:
26 bypass the packet, discard the packet, or protect the packet.
28 @param[in] This Pointer to the EFI_IPSEC2_PROTOCOL instance.
29 @param[in] NicHandle Instance of the network interface.
30 @param[in] IpVersion IPV4 or IPV6.
31 @param[in, out] IpHead Pointer to the IP Header.
32 @param[in, out] LastHead The protocol of the next layer to be processed by IPsec.
33 @param[in, out] OptionsBuffer Pointer to the options buffer.
34 @param[in, out] OptionsLength Length of the options buffer.
35 @param[in, out] FragmentTable Pointer to a list of fragments.
36 @param[in, out] FragmentCount Number of fragments.
37 @param[in] TrafficDirection Traffic direction.
38 @param[out] RecycleSignal Event for recycling of resources.
40 @retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.
41 @retval EFI_SUCCESS The packet was protected.
42 @retval EFI_ACCESS_DENIED The packet was discarded.
48 IN EFI_IPSEC2_PROTOCOL
*This
,
49 IN EFI_HANDLE NicHandle
,
52 IN OUT UINT8
*LastHead
,
53 IN OUT VOID
**OptionsBuffer
,
54 IN OUT UINT32
*OptionsLength
,
55 IN OUT EFI_IPSEC_FRAGMENT_DATA
**FragmentTable
,
56 IN OUT UINT32
*FragmentCount
,
57 IN EFI_IPSEC_TRAFFIC_DIR TrafficDirection
,
58 OUT EFI_EVENT
*RecycleSignal
61 IPSEC_PRIVATE_DATA
*Private
;
62 IPSEC_SPD_ENTRY
*SpdEntry
;
63 EFI_IPSEC_SPD_SELECTOR
*SpdSelector
;
64 IPSEC_SAD_ENTRY
*SadEntry
;
67 EFI_IPSEC_ACTION Action
;
73 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (This
);
74 IpPayload
= (*FragmentTable
)[0].FragmentBuffer
;
75 IsOutbound
= (BOOLEAN
) ((TrafficDirection
== EfiIPsecOutBound
) ? TRUE
: FALSE
);
76 OldLastHead
= *LastHead
;
77 *RecycleSignal
= NULL
;
78 SpdList
= &mConfigData
[IPsecConfigDataTypeSpd
];
82 // For inbound traffic, process the ipsec header of the packet.
84 Status
= IpSecProtectInboundPacket (
96 if (Status
== EFI_ACCESS_DENIED
|| Status
== EFI_OUT_OF_RESOURCES
) {
98 // The packet is denied to access.
103 if (Status
== EFI_SUCCESS
) {
106 // Check the spd entry if the packet is accessible.
108 if (SpdSelector
== NULL
) {
109 Status
= EFI_ACCESS_DENIED
;
113 Status
= EFI_ACCESS_DENIED
;
114 NET_LIST_FOR_EACH (Entry
, SpdList
) {
115 SpdEntry
= IPSEC_SPD_ENTRY_FROM_LIST (Entry
);
116 if (IsSubSpdSelector (
117 (EFI_IPSEC_CONFIG_SELECTOR
*) SpdSelector
,
118 (EFI_IPSEC_CONFIG_SELECTOR
*) SpdEntry
->Selector
120 Status
= EFI_SUCCESS
;
127 Status
= EFI_ACCESS_DENIED
;
129 NET_LIST_FOR_EACH (Entry
, SpdList
) {
131 // For outbound and non-ipsec Inbound traffic: check the spd entry.
133 SpdEntry
= IPSEC_SPD_ENTRY_FROM_LIST (Entry
);
135 if (EFI_ERROR (IpSecLookupSpdEntry (
145 // If the related SPD not find
152 case EfiIPsecActionProtect
:
156 // For outbound traffic, lookup the sad entry.
158 Status
= IpSecLookupSadEntry (
169 if (SadEntry
!= NULL
) {
171 // Process the packet by the found sad entry.
173 Status
= IpSecProtectOutboundPacket (
185 } else if (OldLastHead
== IP6_ICMP
&& *IpPayload
!= ICMP_V6_ECHO_REQUEST
) {
187 // TODO: if no need return not ready to upper layer, change here.
189 Status
= EFI_SUCCESS
;
191 } else if (OldLastHead
== IP6_ICMP
&& *IpPayload
!= ICMP_V6_ECHO_REQUEST
) {
193 // For inbound icmpv6 traffic except ping request, accept the packet
194 // although no sad entry associated with protect spd entry.
196 Status
= IpSecLookupSadEntry (
206 if (SadEntry
== NULL
) {
207 Status
= EFI_SUCCESS
;
213 case EfiIPsecActionBypass
:
214 Status
= EFI_SUCCESS
;
217 case EfiIPsecActionDiscard
:
223 // If don't find the related SPD entry, return the EFI_ACCESS_DENIED and discard it.
224 // But it the packet is NS/NA, it should be by passed even not find the related SPD entry.
226 if (OldLastHead
== IP6_ICMP
&&
227 (*IpPayload
== ICMP_V6_NEIGHBOR_SOLICIT
|| *IpPayload
== ICMP_V6_NEIGHBOR_ADVERTISE
)
229 Status
= EFI_SUCCESS
;