From a1503a32a887c0b9a735613a7caf5d1493affd01 Mon Sep 17 00:00:00 2001 From: tye Date: Wed, 11 Nov 2009 07:06:27 +0000 Subject: [PATCH] 1. Add Link MTU support to IP4 and TCP4 driver. 2. Integrate IPsec functionality to IP4 driver. 3. Move IP_VERSION_4/IP_VERSION_6 definition from IpIoLib to NetLib. 4. Move the Ip6/Udp6 protocol declaration from driver INF to Library INF (DxeIpIoLib and DxeUdpIoLib) for better readability. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9413 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Include/Library/IpIoLib.h | 2 - MdeModulePkg/Include/Library/NetLib.h | 2 + .../Library/DxeIpIoLib/DxeIpIoLib.inf | 9 +- .../Library/DxeUdpIoLib/DxeUdpIoLib.inf | 5 +- .../Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf | 4 +- .../Universal/Network/Ip4Dxe/Ip4Driver.c | 3 +- .../Universal/Network/Ip4Dxe/Ip4Dxe.inf | 4 +- .../Universal/Network/Ip4Dxe/Ip4Impl.c | 15 +- .../Universal/Network/Ip4Dxe/Ip4Impl.h | 48 +++- .../Universal/Network/Ip4Dxe/Ip4Input.c | 230 ++++++++++++++++++ .../Universal/Network/Ip4Dxe/Ip4Input.h | 38 +++ .../Universal/Network/Ip4Dxe/Ip4Output.c | 20 ++ .../Universal/Network/Ip4Dxe/Ip4Output.h | 27 ++ .../Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf | 4 +- .../Universal/Network/Tcp4Dxe/Tcp4Dxe.inf | 4 +- .../Universal/Network/Tcp4Dxe/Tcp4Misc.c | 6 +- .../Universal/Network/Udp4Dxe/Udp4Dxe.inf | 4 +- 17 files changed, 400 insertions(+), 25 deletions(-) diff --git a/MdeModulePkg/Include/Library/IpIoLib.h b/MdeModulePkg/Include/Library/IpIoLib.h index 14f6884d15..e079fe1f79 100644 --- a/MdeModulePkg/Include/Library/IpIoLib.h +++ b/MdeModulePkg/Include/Library/IpIoLib.h @@ -81,8 +81,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_IP4_CONFIG_DATA mIp4IoDefaultIpConfigData; extern EFI_IP6_CONFIG_DATA mIp6IoDefaultIpConfigData; -#define IP_VERSION_4 4 -#define IP_VERSION_6 6 /// /// This error will be delivered to the diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h index 07bf2cbc9f..2eab4a3329 100644 --- a/MdeModulePkg/Include/Library/NetLib.h +++ b/MdeModulePkg/Include/Library/NetLib.h @@ -51,6 +51,8 @@ typedef UINT16 TCP_PORTNO; #define IP6_ESP 50 #define IP6_NO_NEXT_HEADER 59 +#define IP_VERSION_4 4 +#define IP_VERSION_6 6 #pragma pack(1) diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf index 1e83b67df7..133aad775b 100644 --- a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf +++ b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf @@ -4,7 +4,7 @@ This module provides IP services by consuming EFI IP4 Service Binding Protocol and EFI IP4 Protocol. -Copyright (c) 2006, Intel Corporation.
+Copyright (c) 2006 - 2009, Intel Corporation.
All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -46,3 +46,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. MemoryAllocationLib BaseMemoryLib DpcLib + +[Protocols] + gEfiIp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiIp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiIp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf b/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf index 1a6115615d..a1da076f18 100644 --- a/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf +++ b/MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf @@ -4,7 +4,7 @@ This module provides UDP services by consuming EFI UDP4 Service Binding Protocol and EFI UDP4 Protocol. -Copyright (c) 2008, Intel Corporation.
+Copyright (c) 2008 - 2009, Intel Corporation.
All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -50,3 +50,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. [Protocols] gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiUdp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiUdp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf index 44c9d84bdb..f95dfed5ac 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf @@ -1,7 +1,7 @@ #/** @file # Component name for module Dhcp4 # -# Copyright (c) 2007 - 2009, Intel Corporation +# Copyright (c) 2007, Intel Corporation # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -63,6 +63,4 @@ gEfiDhcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiUdp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiUdp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 7a0f18af28..79c5bae0f3 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -1,7 +1,7 @@ /** @file The driver binding and service binding protocol for IP4 driver. -Copyright (c) 2005 - 2006, Intel Corporation.
+Copyright (c) 2005 - 2009, Intel Corporation.
All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -290,6 +290,7 @@ Ip4CreateService ( InsertHeadList (&IpSb->Interfaces, &IpSb->DefaultInterface->Link); + IpSb->MaxPacketSize = IpSb->SnpMode.MaxPacketSize - sizeof (IP4_HEAD); IpSb->MacString = NULL; *Service = IpSb; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf index 121fb17b77..0d0ea9146d 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf @@ -1,7 +1,7 @@ #/** @file # Component name for module Ip4 # -# Copyright (c) 2007, Intel Corporation +# Copyright (c) 2007 - 2009, Intel Corporation # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -80,3 +80,5 @@ gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiManagedNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiArpProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiIpSecProtocolGuid + \ No newline at end of file diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index 4788d403fe..bb5b0ef110 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -13,6 +13,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "Ip4Impl.h" +EFI_IPSEC_PROTOCOL *mIpSec = NULL; + /** Gets the current operational settings for this instance of the EFI IPv4 Protocol driver. @@ -404,6 +406,8 @@ EfiIp4GetModeData ( Ip4ModeData->RouteTable = NULL; Ip4ModeData->RouteCount = 0; + Ip4ModeData->MaxPacketSize = IpSb->MaxPacketSize; + // // return the current station address for this IP child. So, // the user can get the default address through this. Some @@ -1764,6 +1768,13 @@ Ip4FreeTxToken ( Wrap = (IP4_TXTOKEN_WRAP *) Context; + // + // Signal IpSecRecycleEvent to inform IPsec free the memory + // + if (Wrap->IpSecRecycleSignal != NULL) { + gBS->SignalEvent (Wrap->IpSecRecycleSignal); + } + // // Find the token in the instance's map. EfiIp4Transmit put the // token to the map. If that failed, NetMapFindKey will return NULL. @@ -1947,12 +1958,12 @@ EfiIp4Transmit ( } Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0); - HeadLen = sizeof (IP4_HEAD) + ((TxData->OptionsLength + 3) &~0x03); + HeadLen = (TxData->OptionsLength + 3) & (~0x03); // // If don't fragment and fragment needed, return error // - if (DontFragment && (TxData->TotalDataLength + HeadLen > IpSb->SnpMode.MaxPacketSize)) { + if (DontFragment && (TxData->TotalDataLength + HeadLen > IpSb->MaxPacketSize)) { Status = EFI_BAD_BUFFER_SIZE; goto ON_EXIT; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index 8b2e286f0c..43d6765add 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include #include #include #include @@ -80,11 +81,23 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. typedef struct { IP4_PROTOCOL *IpInstance; EFI_IP4_COMPLETION_TOKEN *Token; + EFI_EVENT IpSecRecycleSignal; NET_BUF *Packet; BOOLEAN Sent; INTN Life; } IP4_TXTOKEN_WRAP; +/// +/// IP4_IPSEC_WRAP wraps the packet received from MNP layer. The packet +/// will be released after it has been processed by the receiver. Upon then, +/// the IP4_IPSEC_WRAP will be released, and the IpSecRecycleSignal will be signaled +/// to notice IPsec to free the resources. +/// +typedef struct { + EFI_EVENT IpSecRecycleSignal; + NET_BUF *Packet; +} IP4_IPSEC_WRAP; + /// /// IP4_RXDATA_WRAP wraps the data IP4 child delivers to the /// upper layers. The received packet is kept in the Packet. @@ -110,7 +123,7 @@ struct _IP4_PROTOCOL { INTN State; IP4_SERVICE *Service; - LIST_ENTRY Link; // Link to all the IP protocol from the service + LIST_ENTRY Link; // Link to all the IP protocol from the service // // User's transmit/receive tokens, and received/deliverd packets @@ -136,7 +149,7 @@ struct _IP4_PROTOCOL { // // IGMP data for this instance // - IP4_ADDR *Groups; // stored in network byte order + IP4_ADDR *Groups; // stored in network byte order UINT32 GroupCount; EFI_IP4_CONFIG_DATA ConfigData; @@ -194,6 +207,8 @@ struct _IP4_SERVICE { // NIC this IP4_SERVICE works on. // CHAR16 *MacString; + UINT32 MaxPacketSize; + UINT32 OldMaxPacketSize; ///< The MTU before IPsec enable. }; #define IP4_INSTANCE_FROM_PROTOCOL(Ip4) \ @@ -335,4 +350,33 @@ Ip4SentPacketTicking ( IN NET_MAP_ITEM *Item, IN VOID *Context ); + +/** + The callback function for the net buffer which wraps the user's + transmit token. Although it seems this function is pretty simple, + there are some subtle things. + When user requests the IP to transmit a packet by passing it a + token, the token is wrapped in an IP4_TXTOKEN_WRAP and the data + is wrapped in an net buffer. the net buffer's Free function is + set to Ip4FreeTxToken. The Token and token wrap are added to the + IP child's TxToken map. Then the buffer is passed to Ip4Output for + transmission. If something error happened before that, the buffer + is freed, which in turn will free the token wrap. The wrap may + have been added to the TxToken map or not, and the user's event + shouldn't be fired because we are still in the EfiIp4Transmit. If + the buffer has been sent by Ip4Output, it should be removed from + the TxToken map and user's event signaled. The token wrap and buffer + are bound together. Check the comments in Ip4Output for information + about IP fragmentation. + + @param[in] Context The token's wrap + +**/ +VOID +Ip4FreeTxToken ( + IN VOID *Context + ); + +extern EFI_IPSEC_PROTOCOL *mIpSec; + #endif diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c index 7257353301..779dd496a5 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c @@ -429,6 +429,219 @@ DROP: return NULL; } +/** + The callback function for the net buffer which wraps the packet processed by + IPsec. It releases the wrap packet and also signals IPsec to free the resources. + + @param[in] Arg The wrap context + +**/ +VOID +Ip4IpSecFree ( + IN VOID *Arg + ) +{ + IP4_IPSEC_WRAP *Wrap; + + Wrap = (IP4_IPSEC_WRAP *) Arg; + + if (Wrap->IpSecRecycleSignal != NULL) { + gBS->SignalEvent (Wrap->IpSecRecycleSignal); + } + + NetbufFree (Wrap->Packet); + + FreePool (Wrap); + + return; +} + +/** + The work function to locate IPsec protocol to process the inbound or + 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] Direction The directionality in an SPD entry, + 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. + @retval EFI_SUCCESS The packet was protected. + @retval EFI_ACCESS_DENIED The packet was discarded. + @retval EFI_OUT_OF_RESOURCES There is no suffcient resource to complete the operation. + @retval EFI_BUFFER_TOO_SMALL The number of non-empty block is bigger than the + number of input data blocks when build a fragment table. + +**/ +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 + ) +{ + NET_FRAGMENT *FragmentTable; + UINT32 FragmentCount; + EFI_EVENT RecycleEvent; + NET_BUF *Packet; + IP4_TXTOKEN_WRAP *TxWrap; + IP4_IPSEC_WRAP *IpSecWrap; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + Packet = *Netbuf; + RecycleEvent = NULL; + IpSecWrap = NULL; + FragmentTable = NULL; + TxWrap = (IP4_TXTOKEN_WRAP *) Context; + FragmentCount = Packet->BlockOpNum; + + if (mIpSec == NULL) { + gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec); + if (mIpSec != NULL) { + // + // Save the original MTU + // + IpSb->OldMaxPacketSize = IpSb->MaxPacketSize; + } + } + + // + // Check whether the IPsec protocol is available. + // + if (mIpSec == NULL) { + goto ON_EXIT; + } + // + // Check whether the IPsec enable variable is set. + // + if (mIpSec->DisabledFlag) { + // + // If IPsec is disabled, restore the original MTU + // + IpSb->MaxPacketSize = IpSb->OldMaxPacketSize; + goto ON_EXIT; + } else { + // + // If IPsec is enabled, use the MTU which reduce the IPsec header length. + // + IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP4_MAX_IPSEC_HEADLEN; + } + + // + // Rebuild fragment table from netbuf to ease IPsec process. + // + FragmentTable = AllocateZeroPool (FragmentCount * sizeof (NET_FRAGMENT)); + + if (FragmentTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount); + + if (EFI_ERROR (Status)) { + FreePool (FragmentTable); + goto ON_EXIT; + } + + // + // Convert host byte order to network byte order + // + Ip4NtohHead (Head); + + Status = mIpSec->Process ( + mIpSec, + IpSb->Controller, + IP_VERSION_4, + (VOID *) Head, + &Head->Protocol, + NULL, + 0, + (EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable), + &FragmentCount, + Direction, + &RecycleEvent + ); + // + // Convert back to host byte order + // + Ip4NtohHead (Head); + + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + if (Direction == EfiIPsecOutBound && TxWrap != NULL) { + + TxWrap->IpSecRecycleSignal = RecycleEvent; + TxWrap->Packet = NetbufFromExt ( + FragmentTable, + FragmentCount, + IP4_MAX_HEADLEN, + 0, + Ip4FreeTxToken, + TxWrap + ); + if (TxWrap->Packet == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + *Netbuf = TxWrap->Packet; + + } else { + + IpSecWrap = AllocateZeroPool (sizeof (IP4_IPSEC_WRAP)); + + if (IpSecWrap == NULL) { + goto ON_EXIT; + } + + IpSecWrap->IpSecRecycleSignal = RecycleEvent; + IpSecWrap->Packet = Packet; + Packet = NetbufFromExt ( + FragmentTable, + FragmentCount, + IP4_MAX_HEADLEN, + 0, + Ip4IpSecFree, + IpSecWrap + ); + + if (Packet == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + if (Direction == EfiIPsecInBound) { + Ip4PrependHead (Packet, Head, Options, OptionsLen); + Ip4NtohHead (Packet->Ip.Ip4); + NetbufTrim (Packet, (Head->HeadLen << 2), TRUE); + + CopyMem ( + IP4_GET_CLIP_INFO (Packet), + IP4_GET_CLIP_INFO (IpSecWrap->Packet), + sizeof (IP4_CLIP_INFO) + ); + } + + *Netbuf = Packet; + } + +ON_EXIT: + return Status; +} /** The IP4 input routine. It is called by the IP4_INTERFACE when a @@ -459,6 +672,7 @@ Ip4AccpetFrame ( UINT32 OptionLen; UINT32 TotalLen; UINT16 Checksum; + EFI_STATUS Status; IpSb = (IP4_SERVICE *) Context; @@ -566,6 +780,22 @@ Ip4AccpetFrame ( } // + // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer, + // and no need consider any other ahead ext headers. + // + Status = Ip4IpSecProcessPacket ( + IpSb, + Head, + &Packet, + NULL, + 0, + EfiIPsecInBound, + NULL + ); + + if (EFI_ERROR(Status)) { + goto RESTART; + } // 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. diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h index cd1367b012..ceffece8fb 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h @@ -16,6 +16,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define IP4_MIN_HEADLEN 20 #define IP4_MAX_HEADLEN 60 +/// +/// 8(ESP header) + 16(max IV) + 16(max padding) + 2(ESP tail) + 12(max ICV) = 54 +/// +#define IP4_MAX_IPSEC_HEADLEN 54 #define IP4_ASSEMLE_HASH_SIZE 31 #define IP4_FRAGMENT_LIFE 120 @@ -203,4 +207,38 @@ Ip4PacketTimerTicking ( IN IP4_SERVICE *IpSb ); +/** + The work function to locate IPsec protocol to process the inbound or + 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] Direction The directionality in an SPD entry, + 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. + @retval EFI_SUCCESS The packet was protected. + @retval EFI_ACCESS_DENIED The packet was discarded. + @retval EFI_OUT_OF_RESOURCES There is no suffcient resource to complete the operation. + @retval EFI_BUFFER_TOO_SMALL The number of non-empty block is bigger than the + number of input data blocks when build a fragment table. + +**/ +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 + ); + #endif diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c index 53317c829b..a8a6261cfd 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c @@ -291,9 +291,29 @@ 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. + + // + // IPsec payload has been appended, so use IpSb->SnpMode.MaxPacketSize here. // Mtu = IpSb->SnpMode.MaxPacketSize; HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03)); diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.h index 8bd2ad8a54..3f0485f631 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.h @@ -95,5 +95,32 @@ Ip4CancelPacket ( IN EFI_STATUS IoStatus ); +/** + Prepend an IP4 head to the Packet. It will copy the options and + build the IP4 header fields. Used for IP4 fragmentation. + + @param Packet The packet to prepend IP4 header to + @param Head The caller supplied header. The caller should set + the following header fields: Tos, TotalLen, Id, + Fragment, Ttl, Protocol, Src and Dst. All the fields + are in host byte order. This function will fill in + the Ver, HeadLen, and checksum. + @param Option The orginal IP4 option to copy from + @param OptLen The length of the IP4 option + + @retval EFI_BAD_BUFFER_SIZE There is no enought room in the head space of + Packet. + @retval EFI_SUCCESS The IP4 header is successfully added to the packet. + +**/ +EFI_STATUS +Ip4PrependHead ( + IN OUT NET_BUF *Packet, + IN IP4_HEAD *Head, + IN UINT8 *Option, + IN UINT32 OptLen + ); + extern UINT16 mIp4Id; + #endif diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf index feb1594b25..b45914d3af 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf @@ -1,7 +1,7 @@ #/** @file # Component name for module Mtftp4 # -# Copyright (c) 2007 - 2009, Intel Corporation +# Copyright (c) 2007, Intel Corporation # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -67,6 +67,4 @@ gEfiMtftp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiUdp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiUdp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf index c298f2db0b..ba1274dfa8 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf @@ -2,7 +2,7 @@ # Component name for module Tcp4 # # FIX ME! -# Copyright (c) 2006 - 2009, Intel Corporation. +# Copyright (c) 2006, Intel Corporation. # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -77,6 +77,4 @@ gEfiTcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiTcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiIp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiIp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c index ce66231e22..f565d2f3d0 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c @@ -471,7 +471,7 @@ TcpGetRcvMss ( IN SOCKET *Sock ) { - EFI_SIMPLE_NETWORK_MODE SnpMode; + EFI_IP4_MODE_DATA Ip4Mode; TCP4_PROTO_DATA *TcpProto; EFI_IP4_PROTOCOL *Ip; @@ -481,9 +481,9 @@ TcpGetRcvMss ( Ip = (EFI_IP4_PROTOCOL *) (TcpProto->TcpService->IpIo->Ip); ASSERT (Ip != NULL); - Ip->GetModeData (Ip, NULL, NULL, &SnpMode); + Ip->GetModeData (Ip, &Ip4Mode, NULL, NULL); - return (UINT16) (SnpMode.MaxPacketSize - 40); + return (UINT16) (Ip4Mode.MaxPacketSize - sizeof (TCP_HEAD)); } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf index eae8c2031c..8303672d61 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf @@ -2,7 +2,7 @@ # Component name for module Udp4 # # FIX ME! -# Copyright (c) 2006 - 2009, Intel Corporation. +# Copyright (c) 2006, Intel Corporation. # # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -63,6 +63,4 @@ gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiIp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiIp6ProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiIp6ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED -- 2.39.2