summaryrefslogtreecommitdiff
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>2010-10-15 05:40:41 +0000
committerqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>2010-10-15 05:40:41 +0000
commit705f53a9b49e7ee3d1ca4bcc7133534ed64590dc (patch)
treed79da69796a730af23def17ffd0de865365d3355 /MdeModulePkg
parenta72526804846e44773174a7b4800168e889d831a (diff)
downloadedk2-platforms-705f53a9b49e7ee3d1ca4bcc7133534ed64590dc.tar.xz
Update IPsec.h file to follow approved ECR which will be collected into future UEFI 2.3 Specification after 2.3 errata B and future UEFI Specifications after 2.3. The changes mainly include:
1. Add EFI_IPSEC2_PROTOCOL 2. Remove IPsec Authentication Algorithm Definition and IPsec Encryption Algorithm Definition. 3. Add EFI_IPSEC_SA_DATA2 data structure. And also update IPv4 driver to call EFI_IPSEC2_PROTOCOL. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10941 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Include/Library/NetLib.h16
-rw-r--r--MdeModulePkg/Library/DxeNetLib/NetBuffer.c48
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c246
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h28
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c46
7 files changed, 274 insertions, 114 deletions
diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index 0a9d03c6e8..fe59cc3e44 100644
--- a/MdeModulePkg/Include/Library/NetLib.h
+++ b/MdeModulePkg/Include/Library/NetLib.h
@@ -2003,4 +2003,20 @@ NetIp6PseudoHeadChecksum (
IN UINT8 NextHeader,
IN UINT32 Len
);
+
+/**
+ The function frees the net buffer which allocated by the IP protocol. It releases
+ only the net buffer and doesn't call the external free function.
+
+ This function should be called after finishing the process of mIpSec->ProcessExt()
+ for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new
+ buffer for the ESP, so there needs a function to free the old net buffer.
+
+ @param[in] Nbuf The network buffer to be freed.
+
+**/
+VOID
+NetIpSecNetbufFree (
+ NET_BUF *Nbuf
+ );
#endif
diff --git a/MdeModulePkg/Library/DxeNetLib/NetBuffer.c b/MdeModulePkg/Library/DxeNetLib/NetBuffer.c
index 43bcae6600..bbbdbc048a 100644
--- a/MdeModulePkg/Library/DxeNetLib/NetBuffer.c
+++ b/MdeModulePkg/Library/DxeNetLib/NetBuffer.c
@@ -1842,3 +1842,51 @@ NetIp6PseudoHeadChecksum (
return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));
}
+/**
+ The function frees the net buffer which allocated by the IP protocol. It releases
+ only the net buffer and doesn't call the external free function.
+
+ This function should be called after finishing the process of mIpSec->ProcessExt()
+ for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new
+ buffer for the ESP, so there needs a function to free the old net buffer.
+
+ @param[in] Nbuf The network buffer to be freed.
+
+**/
+VOID
+NetIpSecNetbufFree (
+ NET_BUF *Nbuf
+ )
+{
+ NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
+ ASSERT (Nbuf->RefCnt > 0);
+
+ Nbuf->RefCnt--;
+
+ if (Nbuf->RefCnt == 0) {
+
+ //
+ // Update Vector only when NBuf is to be released. That is,
+ // all the sharing of Nbuf increse Vector's RefCnt by one
+ //
+ NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
+ ASSERT (Nbuf->Vector->RefCnt > 0);
+
+ Nbuf->Vector->RefCnt--;
+
+ if (Nbuf->Vector->RefCnt > 0) {
+ return;
+ }
+
+ //
+ // If NET_VECTOR_OWN_FIRST is set, release the first block since it is
+ // allocated by us
+ //
+ if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
+ FreePool (Nbuf->Vector->Block[0].Bulk);
+ }
+ FreePool (Nbuf->Vector);
+ FreePool (Nbuf);
+ }
+}
+
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
index 8974f5a5b7..2cad1f3bb9 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Ip4Impl.h"
-EFI_IPSEC_PROTOCOL *mIpSec = NULL;
+EFI_IPSEC2_PROTOCOL *mIpSec = NULL;
/**
Gets the current operational settings for this instance of the EFI IPv4 Protocol driver.
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
index b43f607320..86e6385ecf 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
@@ -379,6 +379,6 @@ Ip4FreeTxToken (
IN VOID *Context
);
-extern EFI_IPSEC_PROTOCOL *mIpSec;
+extern EFI_IPSEC2_PROTOCOL *mIpSec;
#endif
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
index 75333b82ef..0734e091bf 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
@@ -463,14 +463,14 @@ Ip4IpSecFree (
outbound IP packets. The process routine handls the packet with following
actions: bypass the packet, discard the packet, or protect the packet.
- @param[in] IpSb The IP4 service instance
- @param[in] Head The The caller supplied IP4 header.
- @param[in, out] Netbuf The IP4 packet to be processed by IPsec
- @param[in] Options The caller supplied options
- @param[in] OptionsLen The length of the option
+ @param[in] IpSb The IP4 service instance.
+ @param[in, out] Head The The caller supplied IP4 header.
+ @param[in, out] Netbuf The IP4 packet to be processed by IPsec.
+ @param[in, out] Options The caller supplied options.
+ @param[in, out] OptionsLen The length of the option.
@param[in] Direction The directionality in an SPD entry,
- EfiIPsecInBound or EfiIPsecOutBound
- @param[in] Context The token's wrap
+ EfiIPsecInBound or EfiIPsecOutBound.
+ @param[in] Context The token's wrap.
@retval EFI_SUCCESS The IPsec protocol is not available or disabled.
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.
@@ -483,22 +483,25 @@ Ip4IpSecFree (
**/
EFI_STATUS
Ip4IpSecProcessPacket (
- IN IP4_SERVICE *IpSb,
- IN IP4_HEAD *Head,
- IN OUT NET_BUF **Netbuf,
- IN UINT8 *Options,
- IN UINT32 OptionsLen,
- IN EFI_IPSEC_TRAFFIC_DIR Direction,
- IN VOID *Context
+ IN IP4_SERVICE *IpSb,
+ IN OUT IP4_HEAD **Head,
+ IN OUT NET_BUF **Netbuf,
+ IN OUT UINT8 **Options,
+ IN OUT UINT32 *OptionsLen,
+ IN EFI_IPSEC_TRAFFIC_DIR Direction,
+ IN VOID *Context
)
{
NET_FRAGMENT *FragmentTable;
+ NET_FRAGMENT *OriginalFragmentTable;
UINT32 FragmentCount;
+ UINT32 OriginalFragmentCount;
EFI_EVENT RecycleEvent;
NET_BUF *Packet;
IP4_TXTOKEN_WRAP *TxWrap;
IP4_IPSEC_WRAP *IpSecWrap;
EFI_STATUS Status;
+ IP4_HEAD ZeroHead;
Status = EFI_SUCCESS;
Packet = *Netbuf;
@@ -507,6 +510,8 @@ Ip4IpSecProcessPacket (
FragmentTable = NULL;
TxWrap = (IP4_TXTOKEN_WRAP *) Context;
FragmentCount = Packet->BlockOpNum;
+
+ ZeroMem (&ZeroHead, sizeof (IP4_HEAD));
if (mIpSec == NULL) {
gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec);
@@ -542,6 +547,12 @@ Ip4IpSecProcessPacket (
}
Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);
+
+ //
+ // Record the original FragmentTable and count.
+ //
+ OriginalFragmentTable = FragmentTable;
+ OriginalFragmentCount = FragmentCount;
if (EFI_ERROR (Status)) {
FreePool (FragmentTable);
@@ -551,16 +562,16 @@ Ip4IpSecProcessPacket (
//
// Convert host byte order to network byte order
//
- Ip4NtohHead (Head);
+ Ip4NtohHead (*Head);
- Status = mIpSec->Process (
+ Status = mIpSec->ProcessExt (
mIpSec,
IpSb->Controller,
IP_VERSION_4,
- (VOID *) Head,
- &Head->Protocol,
- NULL,
- 0,
+ (VOID *) (*Head),
+ &(*Head)->Protocol,
+ Options,
+ OptionsLen,
(EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable),
&FragmentCount,
Direction,
@@ -569,12 +580,16 @@ Ip4IpSecProcessPacket (
//
// Convert back to host byte order
//
- Ip4NtohHead (Head);
+ Ip4NtohHead (*Head);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
+ if (OriginalFragmentTable == FragmentTable && OriginalFragmentCount == FragmentCount) {
+ goto ON_EXIT;
+ }
+
if (Direction == EfiIPsecOutBound && TxWrap != NULL) {
TxWrap->IpSecRecycleSignal = RecycleEvent;
@@ -591,6 +606,10 @@ Ip4IpSecProcessPacket (
goto ON_EXIT;
}
+ //
+ // Free orginal Netbuf.
+ //
+ NetIpSecNetbufFree (*Netbuf);
*Netbuf = TxWrap->Packet;
} else {
@@ -617,10 +636,10 @@ Ip4IpSecProcessPacket (
goto ON_EXIT;
}
- if (Direction == EfiIPsecInBound) {
- Ip4PrependHead (Packet, Head, Options, OptionsLen);
+ if (Direction == EfiIPsecInBound && 0 != CompareMem (*Head, &ZeroHead, sizeof (IP4_HEAD))) {
+ Ip4PrependHead (Packet, *Head, *Options, *OptionsLen);
Ip4NtohHead (Packet->Ip.Ip4);
- NetbufTrim (Packet, (Head->HeadLen << 2), TRUE);
+ NetbufTrim (Packet, ((*Head)->HeadLen << 2), TRUE);
CopyMem (
IP4_GET_CLIP_INFO (Packet),
@@ -628,7 +647,6 @@ Ip4IpSecProcessPacket (
sizeof (IP4_CLIP_INFO)
);
}
-
*Netbuf = Packet;
}
@@ -637,63 +655,56 @@ ON_EXIT:
}
/**
- The IP4 input routine. It is called by the IP4_INTERFACE when a
- IP4 fragment is received from MNP.
+ Pre-process the IPv4 packet. First validates the IPv4 packet, and
+ then reassembles packet if it is necessary.
+
+ @param[in] IpSb Pointer to IP4_SERVICE.
+ @param[in, out] Packet Pointer to the Packet to be processed.
+ @param[in] Head Pointer to the IP4_HEAD.
+ @param[in] Option Pointer to a buffer which contains the IPv4 option.
+ @param[in] OptionLen The length of Option in bytes.
+ @param[in] Flag The link layer flag for the packet received, such
+ as multicast.
- @param[in] Ip4Instance The IP4 child that request the receive, most like
- it is NULL.
- @param[in] Packet The IP4 packet received.
- @param[in] IoStatus The return status of receive request.
- @param[in] Flag The link layer flag for the packet received, such
- as multicast.
- @param[in] Context The IP4 service instance that own the MNP.
+ @retval EFI_SEUCCESS The recieved packet is in well form.
+ @retval EFI_INVAILD_PARAMETER The recieved packet is malformed.
**/
-VOID
-Ip4AccpetFrame (
- IN IP4_PROTOCOL *Ip4Instance,
- IN NET_BUF *Packet,
- IN EFI_STATUS IoStatus,
- IN UINT32 Flag,
- IN VOID *Context
- )
+EFI_STATUS
+Ip4PreProcessPacket (
+ IN IP4_SERVICE *IpSb,
+ IN OUT NET_BUF **Packet,
+ IN IP4_HEAD *Head,
+ IN UINT8 *Option,
+ IN UINT32 OptionLen,
+ IN UINT32 Flag
+ )
{
- IP4_SERVICE *IpSb;
IP4_CLIP_INFO *Info;
- IP4_HEAD *Head;
UINT32 HeadLen;
- UINT32 OptionLen;
UINT32 TotalLen;
UINT16 Checksum;
- EFI_STATUS Status;
-
- IpSb = (IP4_SERVICE *) Context;
-
- if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {
- goto DROP;
- }
//
// Check that the IP4 header is correctly formatted
//
- if (Packet->TotalSize < IP4_MIN_HEADLEN) {
- goto RESTART;
+ if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {
+ return EFI_INVALID_PARAMETER;
}
-
- Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);
+
HeadLen = (Head->HeadLen << 2);
TotalLen = NTOHS (Head->TotalLen);
//
// Mnp may deliver frame trailer sequence up, trim it off.
//
- if (TotalLen < Packet->TotalSize) {
- NetbufTrim (Packet, Packet->TotalSize - TotalLen, FALSE);
+ if (TotalLen < (*Packet)->TotalSize) {
+ NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);
}
if ((Head->Ver != 4) || (HeadLen < IP4_MIN_HEADLEN) ||
- (TotalLen < HeadLen) || (TotalLen != Packet->TotalSize)) {
- goto RESTART;
+ (TotalLen < HeadLen) || (TotalLen != (*Packet)->TotalSize)) {
+ return EFI_INVALID_PARAMETER;
}
//
@@ -702,15 +713,15 @@ Ip4AccpetFrame (
Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) Head, HeadLen));
if ((Head->Checksum != 0) && (Checksum != 0)) {
- goto RESTART;
+ return EFI_INVALID_PARAMETER;
}
//
// Convert the IP header to host byte order, then get the per packet info.
//
- Packet->Ip.Ip4 = Ip4NtohHead (Head);
+ (*Packet)->Ip.Ip4 = Ip4NtohHead (Head);
- Info = IP4_GET_CLIP_INFO (Packet);
+ Info = IP4_GET_CLIP_INFO (*Packet);
Info->LinkFlag = Flag;
Info->CastType = Ip4GetHostCast (IpSb, Head->Dst, Head->Src);
Info->Start = (Head->Fragment & IP4_HEAD_OFFSET_MASK) << 3;
@@ -722,24 +733,23 @@ Ip4AccpetFrame (
// The packet is destinated to us if the CastType is non-zero.
//
if ((Info->CastType == 0) || (Info->End > IP4_MAX_PACKET_SIZE)) {
- goto RESTART;
+ return EFI_INVALID_PARAMETER;
}
//
// Validate the options. Don't call the Ip4OptionIsValid if
// there is no option to save some CPU process.
//
- OptionLen = HeadLen - IP4_MIN_HEADLEN;
-
- if ((OptionLen > 0) && !Ip4OptionIsValid ((UINT8 *) (Head + 1), OptionLen, TRUE)) {
- goto RESTART;
+
+ if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {
+ return EFI_INVALID_PARAMETER;
}
//
// Trim the head off, after this point, the packet is headless.
// and Packet->TotalLen == Info->Length.
//
- NetbufTrim (Packet, HeadLen, TRUE);
+ NetbufTrim (*Packet, HeadLen, TRUE);
//
// Reassemble the packet if this is a fragment. The packet is a
@@ -752,25 +762,86 @@ Ip4AccpetFrame (
// need to send a type 4 destination unreache ICMP message here.
//
if ((Head->Fragment & IP4_HEAD_DF_MASK) != 0) {
- goto RESTART;
+ return EFI_INVALID_PARAMETER;
}
//
// The length of all but the last fragments is in the unit of 8 bytes.
//
if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) && (Info->Length % 8 != 0)) {
- goto RESTART;
+ return EFI_INVALID_PARAMETER;
}
- Packet = Ip4Reassemble (&IpSb->Assemble, Packet);
+ *Packet = Ip4Reassemble (&IpSb->Assemble, *Packet);
//
// Packet assembly isn't complete, start receive more packet.
//
- if (Packet == NULL) {
- goto RESTART;
+ if (*Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
}
}
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The IP4 input routine. It is called by the IP4_INTERFACE when a
+ IP4 fragment is received from MNP.
+
+ @param[in] Ip4Instance The IP4 child that request the receive, most like
+ it is NULL.
+ @param[in] Packet The IP4 packet received.
+ @param[in] IoStatus The return status of receive request.
+ @param[in] Flag The link layer flag for the packet received, such
+ as multicast.
+ @param[in] Context The IP4 service instance that own the MNP.
+
+**/
+VOID
+Ip4AccpetFrame (
+ IN IP4_PROTOCOL *Ip4Instance,
+ IN NET_BUF *Packet,
+ IN EFI_STATUS IoStatus,
+ IN UINT32 Flag,
+ IN VOID *Context
+ )
+{
+ IP4_SERVICE *IpSb;
+ IP4_HEAD *Head;
+ EFI_STATUS Status;
+ IP4_HEAD ZeroHead;
+ UINT8 *Option;
+ UINT32 OptionLen;
+
+ IpSb = (IP4_SERVICE *) Context;
+ Option = NULL;
+
+ if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {
+ goto DROP;
+ }
+
+ Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);
+ OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;
+ if (OptionLen > 0) {
+ Option = (UINT8 *) (Head + 1);
+ }
+
+ //
+ // Validate packet format and reassemble packet if it is necessary.
+ //
+ Status = Ip4PreProcessPacket (
+ IpSb,
+ &Packet,
+ Head,
+ Option,
+ OptionLen,
+ Flag
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto RESTART;
+ }
//
// After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,
@@ -778,21 +849,40 @@ Ip4AccpetFrame (
//
Status = Ip4IpSecProcessPacket (
IpSb,
- Head,
+ &Head,
&Packet,
- NULL,
- 0,
+ &Option,
+ &OptionLen,
EfiIPsecInBound,
NULL
);
- if (EFI_ERROR(Status)) {
+ if (EFI_ERROR (Status)) {
goto RESTART;
}
+
+ //
+ // If the packet is protected by tunnel mode, parse the inner Ip Packet.
+ //
+ ZeroMem (&ZeroHead, sizeof (IP4_HEAD));
+ if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) {
// Packet may have been changed. Head, HeadLen, TotalLen, and
// info must be reloaded bofore use. The ownership of the packet
// is transfered to the packet process logic.
//
+ Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);
+ Status = Ip4PreProcessPacket (
+ IpSb,
+ &Packet,
+ Head,
+ Option,
+ OptionLen,
+ Flag
+ );
+ if (EFI_ERROR (Status)) {
+ goto RESTART;
+ }
+ }
Head = Packet->Ip.Ip4;
IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
index bb16726624..fda4d18c9c 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
@@ -212,14 +212,14 @@ Ip4PacketTimerTicking (
outbound IP packets. The process routine handls the packet with following
actions: bypass the packet, discard the packet, or protect the packet.
- @param[in] IpSb The IP4 service instance
- @param[in] Head The The caller supplied IP4 header.
- @param[in, out] Netbuf The IP4 packet to be processed by IPsec
- @param[in] Options The caller supplied options
- @param[in] OptionsLen The length of the option
+ @param[in] IpSb The IP4 service instance.
+ @param[in, out] Head The The caller supplied IP4 header.
+ @param[in, out] Netbuf The IP4 packet to be processed by IPsec.
+ @param[in, out] Options The caller supplied options.
+ @param[in, out] OptionsLen The length of the option.
@param[in] Direction The directionality in an SPD entry,
- EfiIPsecInBound or EfiIPsecOutBound
- @param[in] Context The token's wrap
+ EfiIPsecInBound or EfiIPsecOutBound.
+ @param[in] Context The token's wrap.
@retval EFI_SUCCESS The IPsec protocol is not available or disabled.
@retval EFI_SUCCESS The packet was bypassed and all buffers remain the same.
@@ -232,13 +232,13 @@ Ip4PacketTimerTicking (
**/
EFI_STATUS
Ip4IpSecProcessPacket (
- IN IP4_SERVICE *IpSb,
- IN IP4_HEAD *Head,
- IN OUT NET_BUF **Netbuf,
- IN UINT8 *Options,
- IN UINT32 OptionsLen,
- IN EFI_IPSEC_TRAFFIC_DIR Direction,
- IN VOID *Context
+ IN IP4_SERVICE *IpSb,
+ IN OUT IP4_HEAD **Head,
+ IN OUT NET_BUF **Netbuf,
+ IN OUT UINT8 **Options,
+ IN OUT UINT32 *OptionsLen,
+ IN EFI_IPSEC_TRAFFIC_DIR Direction,
+ IN VOID *Context
);
#endif
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
index 863ca2a464..93cc52eb57 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
@@ -251,6 +251,31 @@ Ip4Output (
}
//
+ // Before IPsec process, prepared the IP head.
+ //
+ HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
+ Head->HeadLen = (UINT8) HeadLen >> 2;
+ Head->Id = mIp4Id++;
+ Head->Ver = 4;
+
+ //
+ // Call IPsec process.
+ //
+ Status = Ip4IpSecProcessPacket (
+ IpSb,
+ &Head,
+ &Packet,
+ &Option,
+ &OptLen,
+ EfiIPsecOutBound,
+ Context
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
// Route the packet unless overrided, that is, GateWay isn't zero.
//
if (GateWay == IP4_ALLZERO_ADDRESS) {
@@ -292,29 +317,10 @@ Ip4Output (
}
//
- // TODO: currently Option/OptLen are not included into encryption scope.
- //
- Status = Ip4IpSecProcessPacket (
- IpSb,
- Head,
- &Packet,
- Option,
- OptLen,
- EfiIPsecOutBound,
- Context
- );
-
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- //
// OK, selected the source and route, fragment the packet then send
// them. Tag each fragment other than the first one as spawn from it.
//
- Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);
- HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));
- Head->Id = mIp4Id++;
+ Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);
if (Packet->TotalSize + HeadLen > Mtu) {
//