X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FIp4Dxe%2FIp4Input.c;h=09b8f2bac23554b5f759d78630c58025fd61e23f;hp=be87ec5d9835496eaf3fe364d43ed43794a13cbf;hb=4f0f2316ed7699e233b362b83c7fbd63c2adf97e;hpb=abd0c26488ba0fcb952b6d7ad366049958c8c9ed diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c index be87ec5d98..09b8f2bac2 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c @@ -1,7 +1,9 @@ /** @file IP4 input process. -Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.
+(C) Copyright 2015 Hewlett-Packard Development Company, L.P.
+ 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 @@ -292,7 +294,7 @@ Ip4Reassemble ( // check whether THIS.Start < PREV.End for overlap. If two fragments // overlaps, trim the overlapped part off THIS fragment. // - if ((Cur != Head) && ((Prev = Cur->BackLink) != Head)) { + if ((Prev = Cur->BackLink) != Head) { Fragment = NET_LIST_USER_STRUCT (Prev, NET_BUF, List); Node = IP4_GET_CLIP_INFO (Fragment); @@ -419,7 +421,15 @@ Ip4Reassemble ( } NewPacket->Ip.Ip4 = Assemble->Head; - CopyMem (IP4_GET_CLIP_INFO (NewPacket), Assemble->Info, sizeof (*IP4_GET_CLIP_INFO (NewPacket))); + + ASSERT (Assemble->Info != NULL); + + CopyMem ( + IP4_GET_CLIP_INFO (NewPacket), + Assemble->Info, + sizeof (*IP4_GET_CLIP_INFO (NewPacket)) + ); + return NewPacket; } @@ -504,6 +514,11 @@ Ip4IpSecProcessPacket ( IP4_HEAD ZeroHead; Status = EFI_SUCCESS; + + if (!mIpSec2Installed) { + goto ON_EXIT; + } + Packet = *Netbuf; RecycleEvent = NULL; IpSecWrap = NULL; @@ -514,7 +529,7 @@ Ip4IpSecProcessPacket ( ZeroMem (&ZeroHead, sizeof (IP4_HEAD)); if (mIpSec == NULL) { - gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec); + gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &mIpSec); if (mIpSec == NULL) { goto ON_EXIT; } @@ -570,7 +585,7 @@ Ip4IpSecProcessPacket ( IP_VERSION_4, (VOID *) (*Head), &(*Head)->Protocol, - (VOID **)Options, + (VOID **) Options, OptionsLen, (EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable), &FragmentCount, @@ -583,11 +598,21 @@ Ip4IpSecProcessPacket ( Ip4NtohHead (*Head); if (EFI_ERROR (Status)) { + FreePool (OriginalFragmentTable); goto ON_EXIT; } if (OriginalFragmentTable == FragmentTable && OriginalFragmentCount == FragmentCount) { + // + // For ByPass Packet + // + FreePool (FragmentTable); goto ON_EXIT; + } else { + // + // Free the FragmentTable which allocated before calling the IPsec. + // + FreePool (OriginalFragmentTable); } if (Direction == EfiIPsecOutBound && TxWrap != NULL) { @@ -602,6 +627,11 @@ Ip4IpSecProcessPacket ( TxWrap ); if (TxWrap->Packet == NULL) { + // + // Recover the TxWrap->Packet, if meet a error, and the caller will free + // the TxWrap. + // + TxWrap->Packet = *Netbuf; Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } @@ -617,6 +647,8 @@ Ip4IpSecProcessPacket ( IpSecWrap = AllocateZeroPool (sizeof (IP4_IPSEC_WRAP)); if (IpSecWrap == NULL) { + Status = EFI_OUT_OF_RESOURCES; + gBS->SignalEvent (RecycleEvent); goto ON_EXIT; } @@ -632,6 +664,9 @@ Ip4IpSecProcessPacket ( ); if (Packet == NULL) { + Packet = IpSecWrap->Packet; + gBS->SignalEvent (RecycleEvent); + FreePool (IpSecWrap); Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } @@ -686,7 +721,7 @@ Ip4PreProcessPacket ( UINT16 Checksum; // - // Check that the IP4 header is correctly formatted + // Check if the IP4 header is correctly formatted. // if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) { return EFI_INVALID_PARAMETER; @@ -746,7 +781,7 @@ Ip4PreProcessPacket ( } // - // Trim the head off, after this point, the packet is headless. + // Trim the head off, after this point, the packet is headless, // and Packet->TotalLen == Info->Length. // NetbufTrim (*Packet, HeadLen, TRUE); @@ -817,11 +852,12 @@ Ip4AccpetFrame ( IpSb = (IP4_SERVICE *) Context; Option = NULL; - if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) { + if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTROY)) { goto DROP; } - Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); + Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); + ASSERT (Head != NULL); OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN; if (OptionLen > 0) { Option = (UINT8 *) (Head + 1); @@ -848,11 +884,11 @@ Ip4AccpetFrame ( // and no need consider any other ahead ext headers. // Status = Ip4IpSecProcessPacket ( - IpSb, - &Head, - &Packet, + IpSb, + &Head, + &Packet, &Option, - &OptionLen, + &OptionLen, EfiIPsecInBound, NULL ); @@ -871,18 +907,21 @@ Ip4AccpetFrame ( // is transfered to the packet process logic. // Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); + ASSERT (Head != NULL); Status = Ip4PreProcessPacket ( - IpSb, - &Packet, - Head, + IpSb, + &Packet, + Head, Option, - OptionLen, + OptionLen, Flag ); if (EFI_ERROR (Status)) { goto RESTART; } } + + ASSERT (Packet != NULL); Head = Packet->Ip.Ip4; IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS; @@ -896,7 +935,7 @@ Ip4AccpetFrame ( break; default: - Ip4Demultiplex (IpSb, Head, Packet); + Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen); } Packet = NULL; @@ -1119,8 +1158,8 @@ Ip4OnRecyclePacket ( to the upper layer. Upper layer will signal the recycle event in it when it is done with the packet. - @param[in] IpInstance The IP4 child to receive the packet - @param[in] Packet The packet to deliver up. + @param[in] IpInstance The IP4 child to receive the packet. + @param[in] Packet The packet to deliver up. @retval Wrap if warp the packet succeed. @retval NULL failed to wrap the packet . @@ -1135,6 +1174,7 @@ Ip4WrapRxData ( IP4_RXDATA_WRAP *Wrap; EFI_IP4_RECEIVE_DATA *RxData; EFI_STATUS Status; + BOOLEAN RawData; Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum)); @@ -1148,7 +1188,7 @@ Ip4WrapRxData ( Wrap->Packet = Packet; RxData = &Wrap->RxData; - ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME)); + ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA)); Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, @@ -1165,17 +1205,21 @@ Ip4WrapRxData ( ASSERT (Packet->Ip.Ip4 != NULL); + ASSERT (IpInstance != NULL); + RawData = IpInstance->ConfigData.RawData; + // // The application expects a network byte order header. // - RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2); - RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4); - - RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN; - RxData->Options = NULL; + if (!RawData) { + RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2); + RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4); + RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN; + RxData->Options = NULL; - if (RxData->OptionsLength != 0) { - RxData->Options = (VOID *) (RxData->Header + 1); + if (RxData->OptionsLength != 0) { + RxData->Options = (VOID *) (RxData->Header + 1); + } } RxData->DataLength = Packet->TotalSize; @@ -1214,6 +1258,7 @@ Ip4InstanceDeliverPacket ( NET_BUF *Packet; NET_BUF *Dup; UINT8 *Head; + UINT32 HeadLen; // // Deliver a packet if there are both a packet and a receive token. @@ -1239,22 +1284,32 @@ Ip4InstanceDeliverPacket ( // // Create a duplicated packet if this packet is shared // - Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN); + if (IpInstance->ConfigData.RawData) { + HeadLen = 0; + } else { + HeadLen = IP4_MAX_HEADLEN; + } + + Dup = NetbufDuplicate (Packet, NULL, HeadLen); if (Dup == NULL) { return EFI_OUT_OF_RESOURCES; } - // - // Copy the IP head over. The packet to deliver up is - // headless. Trim the head off after copy. The IP head - // may be not continuous before the data. - // - Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD); - Dup->Ip.Ip4 = (IP4_HEAD *) Head; - - CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2); - NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE); + if (!IpInstance->ConfigData.RawData) { + // + // Copy the IP head over. The packet to deliver up is + // headless. Trim the head off after copy. The IP head + // may be not continuous before the data. + // + Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD); + ASSERT (Head != NULL); + + Dup->Ip.Ip4 = (IP4_HEAD *) Head; + + CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2); + NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE); + } Wrap = Ip4WrapRxData (IpInstance, Dup); @@ -1292,10 +1347,12 @@ Ip4InstanceDeliverPacket ( Enqueue a received packet to all the IP children that share the same interface. - @param[in] IpSb The IP4 service instance that receive the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet - @param[in] IpIf The interface to enqueue the packet to + @param[in] IpSb The IP4 service instance that receive the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. + @param[in] IpIf The interface to enqueue the packet to. @return The number of the IP4 children that accepts the packet @@ -1305,6 +1362,8 @@ Ip4InterfaceEnquePacket ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen, IN IP4_INTERFACE *IpIf ) { @@ -1370,6 +1429,13 @@ Ip4InterfaceEnquePacket ( IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink); NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE); + // + // In RawData mode, add IPv4 headers and options back to packet. + // + if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)){ + Ip4PrependHead (Packet, Head, Option, OptionLen); + } + if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) { Enqueued++; } @@ -1416,11 +1482,13 @@ Ip4InterfaceDeliverPacket ( child wants to consume the packet because each IP child needs its own copy of the packet to make changes. - @param[in] IpSb The IP4 service instance that received the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet + @param[in] IpSb The IP4 service instance that received the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. - @retval EFI_NOT_FOUND No IP child accepts the packet + @retval EFI_NOT_FOUND No IP child accepts the packet. @retval EFI_SUCCESS The packet is enqueued or delivered to some IP children. @@ -1429,7 +1497,9 @@ EFI_STATUS Ip4Demultiplex ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, - IN NET_BUF *Packet + IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen ) { LIST_ENTRY *Entry; @@ -1446,7 +1516,14 @@ Ip4Demultiplex ( IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link); if (IpIf->Configured) { - Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf); + Enqueued += Ip4InterfaceEnquePacket ( + IpSb, + Head, + Packet, + Option, + OptionLen, + IpIf + ); } }