/** @file\r
+ Network library functions providing net buffer operation support.\r
\r
-Copyright (c) 2005 - 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- NetBuffer.c\r
-\r
-Abstract:\r
-\r
-\r
-\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
**/\r
\r
-#include <PiDxe.h>
-
-#include <Library/NetLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi.h>\r
+\r
+#include <Library/NetLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
\r
\r
/**\r
- Allocate and build up the sketch for a NET_BUF. The net buffer allocated\r
- has the BlockOpNum's NET_BLOCK_OP, and its associated NET_VECTOR has the\r
- BlockNum's NET_BLOCK.\r
+ Allocate and build up the sketch for a NET_BUF.\r
\r
- @param BlockNum The number of NET_BLOCK in the Vector of net buffer\r
- @param BlockOpNum The number of NET_BLOCK_OP in the net buffer\r
+ The net buffer allocated has the BlockOpNum's NET_BLOCK_OP, and its associated\r
+ NET_VECTOR has the BlockNum's NET_BLOCK. But all the NET_BLOCK_OP and\r
+ NET_BLOCK remain un-initialized.\r
\r
- @retval * Pointer to the allocated NET_BUF. If NULL the\r
- allocation failed due to resource limit.\r
+ @param[in] BlockNum The number of NET_BLOCK in the vector of net buffer\r
+ @param[in] BlockOpNum The number of NET_BLOCK_OP in the net buffer\r
+\r
+ @return Pointer to the allocated NET_BUF, or NULL if the\r
+ allocation failed due to resource limit.\r
\r
**/\r
-STATIC\r
NET_BUF *\r
NetbufAllocStruct (\r
IN UINT32 BlockNum,\r
\r
FreeNbuf:\r
\r
- gBS->FreePool (Nbuf);\r
+ FreePool (Nbuf);\r
return NULL;\r
}\r
\r
Allocate a single block NET_BUF. Upon allocation, all the\r
free space is in the tail room.\r
\r
- @param Len The length of the block.\r
+ @param[in] Len The length of the block.\r
\r
- @retval * Pointer to the allocated NET_BUF. If NULL the\r
- allocation failed due to resource limit.\r
+ @return Pointer to the allocated NET_BUF, or NULL if the\r
+ allocation failed due to resource limit.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufAlloc (\r
IN UINT32 Len\r
)\r
return Nbuf;\r
\r
FreeNBuf:\r
- gBS->FreePool (Nbuf);\r
+ FreePool (Nbuf);\r
return NULL;\r
}\r
\r
-\r
/**\r
- Free the vector\r
+ Free the net vector.\r
\r
- @param Vector Pointer to the NET_VECTOR to be freed.\r
+ Decrease the reference count of the net vector by one. The real resource free\r
+ operation isn't performed until the reference count of the net vector is\r
+ decreased to 0.\r
\r
- @return None.\r
+ @param[in] Vector Pointer to the NET_VECTOR to be freed.\r
\r
**/\r
-STATIC\r
VOID\r
NetbufFreeVector (\r
IN NET_VECTOR *Vector\r
{\r
UINT32 Index;\r
\r
+ ASSERT (Vector != NULL);\r
NET_CHECK_SIGNATURE (Vector, NET_VECTOR_SIGNATURE);\r
ASSERT (Vector->RefCnt > 0);\r
\r
// isn't NULL. If NET_VECTOR_OWN_FIRST is set, release the\r
// first block since it is allocated by us\r
//\r
- if (Vector->Flag & NET_VECTOR_OWN_FIRST) {\r
+ if ((Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {\r
gBS->FreePool (Vector->Block[0].Bulk);\r
}\r
\r
}\r
}\r
\r
- gBS->FreePool (Vector);\r
+ FreePool (Vector);\r
}\r
\r
\r
/**\r
- Free the buffer and its associated NET_VECTOR.\r
+ Free the net buffer and its associated NET_VECTOR.\r
\r
- @param Nbuf Pointer to the NET_BUF to be freed.\r
+ Decrease the reference count of the net buffer by one. Free the associated net\r
+ vector and itself if the reference count of the net buffer is decreased to 0.\r
+ The net vector free operation just decrease the reference count of the net\r
+ vector by one and do the real resource free operation when the reference count\r
+ of the net vector is 0.\r
\r
- @return None.\r
+ @param[in] Nbuf Pointer to the NET_BUF to be freed.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufFree (\r
IN NET_BUF *Nbuf\r
)\r
{\r
+ ASSERT (Nbuf != NULL);\r
NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
ASSERT (Nbuf->RefCnt > 0);\r
\r
// all the sharing of Nbuf increse Vector's RefCnt by one\r
//\r
NetbufFreeVector (Nbuf->Vector);\r
- gBS->FreePool (Nbuf);\r
+ FreePool (Nbuf);\r
}\r
}\r
\r
\r
/**\r
- Create a copy of NET_BUF that share the associated NET_DATA.\r
+ Create a copy of the net buffer that shares the associated net vector.\r
\r
- @param Nbuf Pointer to the net buffer to be cloned.\r
+ The reference count of the newly created net buffer is set to 1. The reference\r
+ count of the associated net vector is increased by one.\r
\r
- @retval * Pointer to the cloned net buffer.\r
+ @param[in] Nbuf Pointer to the net buffer to be cloned.\r
+\r
+ @return Pointer to the cloned net buffer, or NULL if the\r
+ allocation failed due to resource limit.\r
\r
**/\r
-NET_BUF *\r
+NET_BUF *\r
+EFIAPI\r
NetbufClone (\r
IN NET_BUF *Nbuf\r
)\r
\r
\r
/**\r
- Create a duplicated copy of Nbuf, data is copied. Also leave some\r
- head space before the data.\r
+ Create a duplicated copy of the net buffer with data copied and HeadSpace\r
+ bytes of head space reserved.\r
+\r
+ The duplicated net buffer will allocate its own memory to hold the data of the\r
+ source net buffer.\r
\r
- @param Nbuf Pointer to the net buffer to be cloned.\r
- @param Duplicate Pointer to the net buffer to duplicate to, if NULL\r
- a new net buffer is allocated.\r
- @param HeadSpace Length of the head space to reserve\r
+ @param[in] Nbuf Pointer to the net buffer to be duplicated from.\r
+ @param[in, out] Duplicate Pointer to the net buffer to duplicate to, if\r
+ NULL a new net buffer is allocated.\r
+ @param[in] HeadSpace Length of the head space to reserve.\r
\r
- @retval * Pointer to the duplicated net buffer.\r
+ @return Pointer to the duplicated net buffer, or NULL if\r
+ the allocation failed due to resource limit.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufDuplicate (\r
IN NET_BUF *Nbuf,\r
- IN NET_BUF *Duplicate OPTIONAL,\r
+ IN OUT NET_BUF *Duplicate OPTIONAL,\r
IN UINT32 HeadSpace\r
)\r
{\r
/**\r
Free a list of net buffers.\r
\r
- @param Head Pointer to the head of linked net buffers.\r
-\r
- @return None.\r
+ @param[in, out] Head Pointer to the head of linked net buffers.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufFreeList (\r
- IN LIST_ENTRY *Head\r
+ IN OUT LIST_ENTRY *Head\r
)\r
{\r
LIST_ENTRY *Entry;\r
\r
\r
/**\r
- Get the position of some byte in the net buffer. This can be used\r
- to, for example, retrieve the IP header in the packet. It also\r
- returns the fragment that contains the byte which is used mainly by\r
- the buffer implementation itself.\r
+ Get the index of NET_BLOCK_OP that contains the byte at Offset in the net\r
+ buffer.\r
+\r
+ This can be used to, for example, retrieve the IP header in the packet. It\r
+ also can be used to get the fragment that contains the byte which is used\r
+ mainly by the library implementation itself.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Offset The index or offset of the byte\r
- @param Index Index of the fragment that contains the block\r
+ @param[in] Nbuf Pointer to the net buffer.\r
+ @param[in] Offset The offset of the byte.\r
+ @param[out] Index Index of the NET_BLOCK_OP that contains the byte at\r
+ Offset.\r
\r
- @retval * Pointer to the nth byte of data in the net buffer.\r
- If NULL, there is no such data in the net buffer.\r
+ @return Pointer to the Offset'th byte of data in the net buffer, or NULL\r
+ if there is no such data in the net buffer.\r
\r
**/\r
UINT8 *\r
+EFIAPI\r
NetbufGetByte (\r
IN NET_BUF *Nbuf,\r
IN UINT32 Offset,\r
\r
\r
/**\r
- Set the NET_BLOCK and corresponding NET_BLOCK_OP in\r
- the buffer. All the pointers in NET_BLOCK and NET_BLOCK_OP\r
- are set to the bulk's head and tail respectively. So, this\r
- function alone can't be used by NetbufAlloc.\r
+ Set the NET_BLOCK and corresponding NET_BLOCK_OP in the net buffer and\r
+ corresponding net vector according to the bulk pointer and bulk length.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Bulk Pointer to the data.\r
- @param Len Length of the bulk data.\r
- @param Index The data block index in the net buffer the bulk\r
- data should belong to.\r
+ All the pointers in the Index'th NET_BLOCK and NET_BLOCK_OP are set to the\r
+ bulk's head and tail respectively. So, this function alone can't be used by\r
+ NetbufAlloc.\r
\r
- @return None.\r
+ @param[in, out] Nbuf Pointer to the net buffer.\r
+ @param[in] Bulk Pointer to the data.\r
+ @param[in] Len Length of the bulk data.\r
+ @param[in] Index The data block index in the net buffer the bulk\r
+ data should belong to.\r
\r
**/\r
-STATIC\r
VOID\r
NetbufSetBlock (\r
- IN NET_BUF *Nbuf,\r
+ IN OUT NET_BUF *Nbuf,\r
IN UINT8 *Bulk,\r
IN UINT32 Len,\r
IN UINT32 Index\r
\r
\r
/**\r
- Set the NET_BLOCK_OP in the buffer. The corresponding NET_BLOCK\r
- structure is left untouched. Some times, there is no 1:1 relationship\r
- between NET_BLOCK and NET_BLOCK_OP. For example, that in NetbufGetFragment.\r
+ Set the NET_BLOCK_OP in the net buffer. The corresponding NET_BLOCK\r
+ structure is left untouched.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Bulk Pointer to the data.\r
- @param Len Length of the bulk data.\r
- @param Index The data block index in the net buffer the bulk\r
- data should belong to.\r
+ Some times, there is no 1:1 relationship between NET_BLOCK and NET_BLOCK_OP.\r
+ For example, that in NetbufGetFragment.\r
\r
- @return None.\r
+ @param[in, out] Nbuf Pointer to the net buffer.\r
+ @param[in] Bulk Pointer to the data.\r
+ @param[in] Len Length of the bulk data.\r
+ @param[in] Index The data block index in the net buffer the bulk\r
+ data should belong to.\r
\r
**/\r
-STATIC\r
VOID\r
NetbufSetBlockOp (\r
- IN NET_BUF *Nbuf,\r
+ IN OUT NET_BUF *Nbuf,\r
IN UINT8 *Bulk,\r
IN UINT32 Len,\r
IN UINT32 Index\r
\r
\r
/**\r
- Helper function for NetbufClone. It is necessary because NetbufGetFragment\r
- may allocate the first block to accomodate the HeadSpace and HeadLen. So, it\r
- need to create a new NET_VECTOR. But, we want to avoid data copy by sharing\r
- the old NET_VECTOR.\r
+ Helper function for NetbufGetFragment. NetbufGetFragment may allocate the\r
+ first block to reserve HeadSpace bytes header space. So it needs to create a\r
+ new net vector for the first block and can avoid copy for the remaining data\r
+ by sharing the old net vector.\r
\r
- @param Arg Point to the old NET_VECTOR\r
-\r
- @return NONE\r
+ @param[in] Arg Point to the old NET_VECTOR.\r
\r
**/\r
-STATIC\r
VOID\r
+EFIAPI\r
NetbufGetFragmentFree (\r
IN VOID *Arg\r
)\r
}\r
\r
\r
-\r
/**\r
- Create a NET_BUF structure which contains Len byte data of\r
- Nbuf starting from Offset. A new NET_BUF structure will be\r
- created but the associated data in NET_VECTOR is shared.\r
- This function exists to do IP packet fragmentation.\r
+ Create a NET_BUF structure which contains Len byte data of Nbuf starting from\r
+ Offset.\r
\r
- @param Nbuf Pointer to the net buffer to be cloned.\r
- @param Offset Starting point of the data to be included in new\r
- buffer.\r
- @param Len How many data to include in new data\r
- @param HeadSpace How many bytes of head space to reserve for\r
- protocol header\r
+ A new NET_BUF structure will be created but the associated data in NET_VECTOR\r
+ is shared. This function exists to do IP packet fragmentation.\r
\r
- @retval * Pointer to the cloned net buffer.\r
+ @param[in] Nbuf Pointer to the net buffer to be extracted.\r
+ @param[in] Offset Starting point of the data to be included in the new\r
+ net buffer.\r
+ @param[in] Len Bytes of data to be included in the new net buffer.\r
+ @param[in] HeadSpace Bytes of head space to reserve for protocol header.\r
+\r
+ @return Pointer to the cloned net buffer, or NULL if the\r
+ allocation failed due to resource limit.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufGetFragment (\r
IN NET_BUF *Nbuf,\r
IN UINT32 Offset,\r
FirstSkip = Offset - Cur;\r
FirstLen = BlockOp[Index].Size - FirstSkip;\r
\r
- //\r
- //redundant assignment to make compiler happy.\r
- //\r
Last = 0;\r
LastLen = 0;\r
\r
FirstLen = Len;\r
}\r
\r
+ ASSERT (Last >= First);\r
BlockOpNum = Last - First + 1;\r
CurBlockOp = 0;\r
\r
Vector->Len = HeadSpace;\r
\r
//\r
- //Reserve the head space in the first block\r
+ // Reserve the head space in the first block\r
//\r
NetbufSetBlock (Child, FirstBulk, HeadSpace, 0);\r
Child->BlockOp[0].Head += HeadSpace;\r
Child->BlockOp[0].Size = 0;\r
CurBlockOp++;\r
\r
- }else {\r
+ } else {\r
Child = NetbufAllocStruct (0, BlockOpNum);\r
\r
if (Child == NULL) {\r
CurBlockOp++\r
);\r
\r
- for (Index = First + 1; Index <= Last - 1 ; Index++) {\r
+ for (Index = First + 1; Index < Last; Index++) {\r
NetbufSetBlockOp (\r
Child,\r
BlockOp[Index].Head,\r
\r
FreeChild:\r
\r
- gBS->FreePool (Child);\r
+ FreePool (Child);\r
return NULL;\r
}\r
\r
/**\r
Build a NET_BUF from external blocks.\r
\r
- @param ExtFragment Pointer to the data block.\r
- @param ExtNum The number of the data block.\r
- @param HeadSpace The head space to be reserved.\r
- @param HeadLen The length of the protocol header, This function\r
- will pull that number of data into a linear block.\r
- @param ExtFree Pointer to the caller provided free function.\r
- @param Arg The argument passed to ExtFree when ExtFree is\r
- called.\r
+ A new NET_BUF structure will be created from external blocks. Additional block\r
+ of memory will be allocated to hold reserved HeadSpace bytes of header room\r
+ and existing HeadLen bytes of header but the external blocks are shared by the\r
+ net buffer to avoid data copying.\r
\r
- @retval * Pointer to the net buffer built from the data\r
- blocks.\r
+ @param[in] ExtFragment Pointer to the data block.\r
+ @param[in] ExtNum The number of the data blocks.\r
+ @param[in] HeadSpace The head space to be reserved.\r
+ @param[in] HeadLen The length of the protocol header, This function\r
+ will pull that number of data into a linear block.\r
+ @param[in] ExtFree Pointer to the caller provided free function.\r
+ @param[in] Arg The argument passed to ExtFree when ExtFree is\r
+ called.\r
+\r
+ @return Pointer to the net buffer built from the data blocks,\r
+ or NULL if the allocation failed due to resource\r
+ limit.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufFromExt (\r
IN NET_FRAGMENT *ExtFragment,\r
IN UINT32 ExtNum,\r
Vector = Nbuf->Vector;\r
Vector->Free = ExtFree;\r
Vector->Arg = Arg;\r
- Vector->Flag = (FirstBlockLen ? NET_VECTOR_OWN_FIRST : 0);\r
+ Vector->Flag = ((FirstBlockLen != 0) ? NET_VECTOR_OWN_FIRST : 0);\r
\r
//\r
// Set the first block up which may contain\r
Vector->Len = TotalLen + HeadSpace;\r
Nbuf->TotalSize = TotalLen;\r
\r
- if (SavedIndex) {\r
+ if (SavedIndex != 0) {\r
ExtFragment[SavedIndex] = SavedFragment;\r
}\r
\r
return Nbuf;\r
\r
FreeFirstBlock:\r
- gBS->FreePool (FirstBlock);\r
+ if (FirstBlock != NULL) {\r
+ FreePool (FirstBlock);\r
+ }\r
return NULL;\r
}\r
\r
\r
/**\r
- Build a fragment table to contain the fragments in the\r
- buffer. This is the opposite of the NetbufFromExt.\r
+ Build a fragment table to contain the fragments in the net buffer. This is the\r
+ opposite operation of the NetbufFromExt.\r
\r
- @param Nbuf Point to the net buffer\r
- @param ExtFragment Pointer to the data block.\r
- @param ExtNum The number of the data block.\r
+ @param[in] Nbuf Point to the net buffer.\r
+ @param[in, out] ExtFragment Pointer to the data block.\r
+ @param[in, out] ExtNum The number of the data blocks.\r
\r
- @retval EFI_BUFFER_TOO_SMALL The number of non-empty block is bigger than ExtNum\r
- @retval EFI_SUCCESS Fragment table built.\r
+ @retval EFI_BUFFER_TOO_SMALL The number of non-empty block is bigger than\r
+ ExtNum.\r
+ @retval EFI_SUCCESS Fragment table is built successfully.\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
NetbufBuildExt (\r
IN NET_BUF *Nbuf,\r
- IN NET_FRAGMENT *ExtFragment,\r
- IN UINT32 *ExtNum\r
+ IN OUT NET_FRAGMENT *ExtFragment,\r
+ IN OUT UINT32 *ExtNum\r
)\r
{\r
UINT32 Index;\r
\r
\r
/**\r
- Build a NET_BUF from a list of NET_BUF.\r
+ Build a net buffer from a list of net buffers.\r
\r
- @param BufList A List of NET_BUF.\r
- @param HeadSpace The head space to be reserved.\r
- @param HeaderLen The length of the protocol header, This function\r
- will pull that number of data into a linear block.\r
- @param ExtFree Pointer to the caller provided free function.\r
- @param Arg The argument passed to ExtFree when ExtFree is\r
- called.\r
+ All the fragments will be collected from the list of NEW_BUF and then a new\r
+ net buffer will be created through NetbufFromExt.\r
\r
- @retval * Pointer to the net buffer built from the data\r
- blocks.\r
+ @param[in] BufList A List of the net buffer.\r
+ @param[in] HeadSpace The head space to be reserved.\r
+ @param[in] HeaderLen The length of the protocol header, This function\r
+ will pull that number of data into a linear block.\r
+ @param[in] ExtFree Pointer to the caller provided free function.\r
+ @param[in] Arg The argument passed to ExtFree when ExtFree is called.\r
+\r
+ @return Pointer to the net buffer built from the list of net\r
+ buffers.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufFromBufList (\r
IN LIST_ENTRY *BufList,\r
IN UINT32 HeadSpace,\r
NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
\r
for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {\r
- if (Nbuf->BlockOp[Index].Size) {\r
+ if (Nbuf->BlockOp[Index].Size != 0) {\r
Fragment[Current].Bulk = Nbuf->BlockOp[Index].Head;\r
Fragment[Current].Len = Nbuf->BlockOp[Index].Size;\r
Current++;\r
}\r
\r
Nbuf = NetbufFromExt (Fragment, Current, HeadSpace, HeaderLen, ExtFree, Arg);\r
- gBS->FreePool (Fragment);\r
+ FreePool (Fragment);\r
\r
return Nbuf;\r
}\r
\r
\r
/**\r
- Reserve some space in the header room of the buffer.\r
- Upon allocation, all the space are in the tail room\r
- of the buffer. Call this function to move some space\r
- to the header room. This function is quite limited in\r
- that it can only reserver space from the first block\r
- of an empty NET_BUF not built from the external. But\r
- it should be enough for the network stack.\r
+ Reserve some space in the header room of the net buffer.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Len The length of buffer to be reserverd.\r
+ Upon allocation, all the space are in the tail room of the buffer. Call this\r
+ function to move some space to the header room. This function is quite limited\r
+ in that it can only reserve space from the first block of an empty NET_BUF not\r
+ built from the external. But it should be enough for the network stack.\r
\r
- @return None.\r
+ @param[in, out] Nbuf Pointer to the net buffer.\r
+ @param[in] Len The length of buffer to be reserved from the header.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufReserve (\r
- IN NET_BUF *Nbuf,\r
+ IN OUT NET_BUF *Nbuf,\r
IN UINT32 Len\r
)\r
{\r
\r
\r
/**\r
- Allocate some space from the header or tail of the buffer.\r
+ Allocate Len bytes of space from the header or tail of the buffer.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Len The length of the buffer to be allocated.\r
- @param FromHead The flag to indicate whether reserve the data from\r
- head or tail. TRUE for from head, and FALSE for\r
- from tail.\r
+ @param[in, out] Nbuf Pointer to the net buffer.\r
+ @param[in] Len The length of the buffer to be allocated.\r
+ @param[in] FromHead The flag to indicate whether reserve the data\r
+ from head (TRUE) or tail (FALSE).\r
\r
- @retval * Pointer to the first byte of the allocated buffer.\r
+ @return Pointer to the first byte of the allocated buffer,\r
+ or NULL if there is no sufficient space.\r
\r
**/\r
-UINT8 *\r
+UINT8*\r
+EFIAPI\r
NetbufAllocSpace (\r
- IN NET_BUF *Nbuf,\r
+ IN OUT NET_BUF *Nbuf,\r
IN UINT32 Len,\r
IN BOOLEAN FromHead\r
)\r
UINT32 Index;\r
UINT8 *SavedTail;\r
\r
+ Index = 0;\r
+\r
NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);\r
\r
\r
\r
/**\r
- Trim a single NET_BLOCK.\r
-\r
- @param BlockOp Pointer to the NET_BLOCK.\r
- @param Len The length of the data to be trimmed.\r
- @param FromHead The flag to indicate whether trim data from head or\r
- tail. TRUE for from head, and FALSE for from tail.\r
+ Trim a single NET_BLOCK by Len bytes from the header or tail.\r
\r
- @return None.\r
+ @param[in, out] BlockOp Pointer to the NET_BLOCK.\r
+ @param[in] Len The length of the data to be trimmed.\r
+ @param[in] FromHead The flag to indicate whether trim data from head\r
+ (TRUE) or tail (FALSE).\r
\r
**/\r
-STATIC\r
VOID\r
NetblockTrim (\r
- IN NET_BLOCK_OP *BlockOp,\r
+ IN OUT NET_BLOCK_OP *BlockOp,\r
IN UINT32 Len,\r
IN BOOLEAN FromHead\r
)\r
{\r
- ASSERT (BlockOp && (BlockOp->Size >= Len));\r
+ ASSERT ((BlockOp != NULL) && (BlockOp->Size >= Len));\r
\r
BlockOp->Size -= Len;\r
\r
\r
\r
/**\r
- Trim some data from the header or tail of the buffer.\r
+ Trim Len bytes from the header or tail of the net buffer.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Len The length of the data to be trimmed.\r
- @param FromHead The flag to indicate whether trim data from head or\r
- tail. TRUE for from head, and FALSE for from tail.\r
+ @param[in, out] Nbuf Pointer to the net buffer.\r
+ @param[in] Len The length of the data to be trimmed.\r
+ @param[in] FromHead The flag to indicate whether trim data from head\r
+ (TRUE) or tail (FALSE).\r
\r
- @retval UINTN Length of the actually trimmed data.\r
+ @return Length of the actually trimmed data, which is possible to be less\r
+ than Len because the TotalSize of Nbuf is less than Len.\r
\r
**/\r
UINT32\r
+EFIAPI\r
NetbufTrim (\r
- IN NET_BUF *Nbuf,\r
+ IN OUT NET_BUF *Nbuf,\r
IN UINT32 Len,\r
IN BOOLEAN FromHead\r
)\r
\r
NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
\r
+ if (Len == 0 || Nbuf->TotalSize == 0) {\r
+ return 0;\r
+ }\r
+\r
if (Len > Nbuf->TotalSize) {\r
Len = Nbuf->TotalSize;\r
}\r
\r
\r
/**\r
- Copy the data from the specific offset to the destination.\r
+ Copy Len bytes of data from the specific offset of the net buffer to the\r
+ destination memory.\r
\r
- @param Nbuf Pointer to the net buffer.\r
- @param Offset The sequence number of the first byte to copy.\r
- @param Len Length of the data to copy.\r
- @param Dest The destination of the data to copy to.\r
+ The Len bytes of data may cross the several fragments of the net buffer.\r
\r
- @retval UINTN The length of the copied data.\r
+ @param[in] Nbuf Pointer to the net buffer.\r
+ @param[in] Offset The sequence number of the first byte to copy.\r
+ @param[in] Len Length of the data to copy.\r
+ @param[in] Dest The destination of the data to copy to.\r
+\r
+ @return The length of the actual copied data, or 0 if the offset\r
+ specified exceeds the total size of net buffer.\r
\r
**/\r
UINT32\r
+EFIAPI\r
NetbufCopy (\r
IN NET_BUF *Nbuf,\r
IN UINT32 Offset,\r
/**\r
Initiate the net buffer queue.\r
\r
- @param NbufQue Pointer to the net buffer queue to be initiated.\r
-\r
- @return None.\r
+ @param[in, out] NbufQue Pointer to the net buffer queue to be initialized.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufQueInit (\r
- IN NET_BUF_QUEUE *NbufQue\r
+ IN OUT NET_BUF_QUEUE *NbufQue\r
)\r
{\r
NbufQue->Signature = NET_QUE_SIGNATURE;\r
\r
\r
/**\r
- Allocate an initialized net buffer queue.\r
-\r
- None.\r
+ Allocate and initialize a net buffer queue.\r
\r
- @retval * Pointer to the allocated net buffer queue.\r
+ @return Pointer to the allocated net buffer queue, or NULL if the\r
+ allocation failed due to resource limit.\r
\r
**/\r
NET_BUF_QUEUE *\r
+EFIAPI\r
NetbufQueAlloc (\r
VOID\r
)\r
/**\r
Free a net buffer queue.\r
\r
- @param NbufQue Poitner to the net buffer queue to be freed.\r
+ Decrease the reference count of the net buffer queue by one. The real resource\r
+ free operation isn't performed until the reference count of the net buffer\r
+ queue is decreased to 0.\r
\r
- @return None.\r
+ @param[in] NbufQue Pointer to the net buffer queue to be freed.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufQueFree (\r
IN NET_BUF_QUEUE *NbufQue\r
)\r
{\r
+ ASSERT (NbufQue != NULL);\r
NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);\r
\r
NbufQue->RefCnt--;\r
\r
if (NbufQue->RefCnt == 0) {\r
NetbufQueFlush (NbufQue);\r
- gBS->FreePool (NbufQue);\r
+ FreePool (NbufQue);\r
}\r
}\r
\r
\r
/**\r
- Append a buffer to the end of the queue.\r
-\r
- @param NbufQue Pointer to the net buffer queue.\r
- @param Nbuf Pointer to the net buffer to be appended.\r
+ Append a net buffer to the net buffer queue.\r
\r
- @return None.\r
+ @param[in, out] NbufQue Pointer to the net buffer queue.\r
+ @param[in, out] Nbuf Pointer to the net buffer to be appended.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufQueAppend (\r
- IN NET_BUF_QUEUE *NbufQue,\r
- IN NET_BUF *Nbuf\r
+ IN OUT NET_BUF_QUEUE *NbufQue,\r
+ IN OUT NET_BUF *Nbuf\r
)\r
{\r
NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);\r
\r
\r
/**\r
- Remove a net buffer from head in the specific queue.\r
+ Remove a net buffer from the head in the specific queue and return it.\r
\r
- @param NbufQue Pointer to the net buffer queue.\r
+ @param[in, out] NbufQue Pointer to the net buffer queue.\r
\r
- @retval * Pointer to the net buffer removed from the specific\r
- queue.\r
+ @return Pointer to the net buffer removed from the specific queue,\r
+ or NULL if there is no net buffer in the specific queue.\r
\r
**/\r
NET_BUF *\r
+EFIAPI\r
NetbufQueRemove (\r
- IN NET_BUF_QUEUE *NbufQue\r
+ IN OUT NET_BUF_QUEUE *NbufQue\r
)\r
{\r
NET_BUF *First;\r
\r
\r
/**\r
- Copy some data from the buffer queue to the destination.\r
+ Copy Len bytes of data from the net buffer queue at the specific offset to the\r
+ destination memory.\r
+\r
+ The copying operation is the same as NetbufCopy but applies to the net buffer\r
+ queue instead of the net buffer.\r
\r
- @param NbufQue Pointer to the net buffer queue.\r
- @param Offset The sequence number of the first byte to copy.\r
- @param Len Length of the data to copy.\r
- @param Dest The destination of the data to copy to.\r
+ @param[in] NbufQue Pointer to the net buffer queue.\r
+ @param[in] Offset The sequence number of the first byte to copy.\r
+ @param[in] Len Length of the data to copy.\r
+ @param[out] Dest The destination of the data to copy to.\r
\r
- @retval UINTN The length of the copied data.\r
+ @return The length of the actual copied data, or 0 if the offset\r
+ specified exceeds the total size of net buffer queue.\r
\r
**/\r
UINT32\r
+EFIAPI\r
NetbufQueCopy (\r
IN NET_BUF_QUEUE *NbufQue,\r
IN UINT32 Offset,\r
IN UINT32 Len,\r
- IN UINT8 *Dest\r
+ OUT UINT8 *Dest\r
)\r
{\r
LIST_ENTRY *Entry;\r
Cur += Nbuf->TotalSize;\r
}\r
\r
+ ASSERT (Nbuf != NULL);\r
+\r
//\r
// Copy the data in the first buffer.\r
//\r
\r
\r
/**\r
- Trim some data from the queue header, release the buffer if\r
- whole buffer is trimmed.\r
+ Trim Len bytes of data from the buffer queue and free any net buffer\r
+ that is completely trimmed.\r
+\r
+ The trimming operation is the same as NetbufTrim but applies to the net buffer\r
+ queue instead of the net buffer.\r
\r
- @param NbufQue Pointer to the net buffer queue.\r
- @param Len Length of the data to trim.\r
+ @param[in, out] NbufQue Pointer to the net buffer queue.\r
+ @param[in] Len Length of the data to trim.\r
\r
- @retval UINTN The length of the data trimmed.\r
+ @return The actual length of the data trimmed.\r
\r
**/\r
UINT32\r
+EFIAPI\r
NetbufQueTrim (\r
- IN NET_BUF_QUEUE *NbufQue,\r
+ IN OUT NET_BUF_QUEUE *NbufQue,\r
IN UINT32 Len\r
)\r
{\r
/**\r
Flush the net buffer queue.\r
\r
- @param NbufQue Pointer to the queue to be flushed.\r
-\r
- @return None.\r
+ @param[in, out] NbufQue Pointer to the queue to be flushed.\r
\r
**/\r
VOID\r
+EFIAPI\r
NetbufQueFlush (\r
- IN NET_BUF_QUEUE *NbufQue\r
+ IN OUT NET_BUF_QUEUE *NbufQue\r
)\r
{\r
NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);\r
\r
\r
/**\r
- Compute checksum for a bulk of data.\r
+ Compute the checksum for a bulk of data.\r
\r
- @param Bulk Pointer to the data.\r
- @param Len Length of the data, in bytes.\r
+ @param[in] Bulk Pointer to the data.\r
+ @param[in] Len Length of the data, in bytes.\r
\r
- @retval UINT16 The computed checksum.\r
+ @return The computed checksum.\r
\r
**/\r
UINT16\r
+EFIAPI\r
NetblockChecksum (\r
IN UINT8 *Bulk,\r
IN UINT32 Len\r
\r
Sum = 0;\r
\r
+ //\r
+ // Add left-over byte, if any\r
+ //\r
+ if (Len % 2 != 0) {\r
+ Sum += *(Bulk + Len - 1);\r
+ }\r
+\r
while (Len > 1) {\r
Sum += *(UINT16 *) Bulk;\r
Bulk += 2;\r
Len -= 2;\r
}\r
\r
- //\r
- // Add left-over byte, if any\r
- //\r
- if (Len > 0) {\r
- Sum += *(UINT8 *) Bulk;\r
- }\r
-\r
//\r
// Fold 32-bit sum to 16 bits\r
//\r
- while (Sum >> 16) {\r
+ while ((Sum >> 16) != 0) {\r
Sum = (Sum & 0xffff) + (Sum >> 16);\r
\r
}\r
/**\r
Add two checksums.\r
\r
- @param Checksum1 The first checksum to be added.\r
- @param Checksum2 The second checksum to be added.\r
+ @param[in] Checksum1 The first checksum to be added.\r
+ @param[in] Checksum2 The second checksum to be added.\r
\r
- @retval UINT16 The new checksum.\r
+ @return The new checksum.\r
\r
**/\r
UINT16\r
+EFIAPI\r
NetAddChecksum (\r
IN UINT16 Checksum1,\r
IN UINT16 Checksum2\r
//\r
// two UINT16 can only add up to a carry of 1.\r
//\r
- if (Sum >> 16) {\r
+ if ((Sum >> 16) != 0) {\r
Sum = (Sum & 0xffff) + 1;\r
\r
}\r
/**\r
Compute the checksum for a NET_BUF.\r
\r
- @param Nbuf Pointer to the net buffer.\r
+ @param[in] Nbuf Pointer to the net buffer.\r
\r
- @retval UINT16 The computed checksum.\r
+ @return The computed checksum.\r
\r
**/\r
UINT16\r
+EFIAPI\r
NetbufChecksum (\r
IN NET_BUF *Nbuf\r
)\r
\r
BlockSum = NetblockChecksum (BlockOp[Index].Head, BlockOp[Index].Size);\r
\r
- if (Offset & 0x01) {\r
+ if ((Offset & 0x01) != 0) {\r
//\r
// The checksum starts with an odd byte, swap\r
// the checksum before added to total checksum\r
//\r
- BlockSum = (UINT16) NET_SWAP_SHORT (BlockSum);\r
+ BlockSum = SwapBytes16 (BlockSum);\r
}\r
\r
TotalSum = NetAddChecksum (BlockSum, TotalSum);\r
\r
/**\r
Compute the checksum for TCP/UDP pseudo header.\r
- Src, Dst are in network byte order. and Len is\r
- in host byte order.\r
\r
- @param Src The source address of the packet.\r
- @param Dst The destination address of the packet.\r
- @param Proto The protocol type of the packet.\r
- @param Len The length of the packet.\r
+ Src and Dst are in network byte order, and Len is in host byte order.\r
\r
- @retval UINT16 The computed checksum.\r
+ @param[in] Src The source address of the packet.\r
+ @param[in] Dst The destination address of the packet.\r
+ @param[in] Proto The protocol type of the packet.\r
+ @param[in] Len The length of the packet.\r
+\r
+ @return The computed checksum.\r
\r
**/\r
UINT16\r
+EFIAPI\r
NetPseudoHeadChecksum (\r
IN IP4_ADDR Src,\r
IN IP4_ADDR Dst,\r
\r
return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));\r
}\r
+\r
+/**\r
+ Compute the checksum for TCP6/UDP6 pseudo header.\r
+\r
+ Src and Dst are in network byte order, and Len is in host byte order.\r
+\r
+ @param[in] Src The source address of the packet.\r
+ @param[in] Dst The destination address of the packet.\r
+ @param[in] NextHeader The protocol type of the packet.\r
+ @param[in] Len The length of the packet.\r
+\r
+ @return The computed checksum.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+NetIp6PseudoHeadChecksum (\r
+ IN EFI_IPv6_ADDRESS *Src,\r
+ IN EFI_IPv6_ADDRESS *Dst,\r
+ IN UINT8 NextHeader,\r
+ IN UINT32 Len\r
+ )\r
+{\r
+ NET_IP6_PSEUDO_HDR Hdr;\r
+\r
+ //\r
+ // Zero the memory to relieve align problems\r
+ //\r
+ ZeroMem (&Hdr, sizeof (Hdr));\r
+\r
+ IP6_COPY_ADDRESS (&Hdr.SrcIp, Src);\r
+ IP6_COPY_ADDRESS (&Hdr.DstIp, Dst);\r
+\r
+ Hdr.NextHeader = NextHeader;\r
+ Hdr.Len = HTONL (Len);\r
+\r
+ return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));\r
+}\r
+\r
+/**\r
+ The function frees the net buffer which allocated by the IP protocol. It releases\r
+ only the net buffer and doesn't call the external free function.\r
+\r
+ This function should be called after finishing the process of mIpSec->ProcessExt()\r
+ for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new\r
+ buffer for the ESP, so there needs a function to free the old net buffer.\r
+\r
+ @param[in] Nbuf The network buffer to be freed.\r
+\r
+**/\r
+VOID\r
+NetIpSecNetbufFree (\r
+ NET_BUF *Nbuf\r
+ )\r
+{\r
+ NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
+ ASSERT (Nbuf->RefCnt > 0);\r
+\r
+ Nbuf->RefCnt--;\r
+\r
+ if (Nbuf->RefCnt == 0) {\r
+\r
+ //\r
+ // Update Vector only when NBuf is to be released. That is,\r
+ // all the sharing of Nbuf increse Vector's RefCnt by one\r
+ //\r
+ NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);\r
+ ASSERT (Nbuf->Vector->RefCnt > 0);\r
+\r
+ Nbuf->Vector->RefCnt--;\r
+\r
+ if (Nbuf->Vector->RefCnt > 0) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // If NET_VECTOR_OWN_FIRST is set, release the first block since it is\r
+ // allocated by us\r
+ //\r
+ if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {\r
+ FreePool (Nbuf->Vector->Block[0].Bulk);\r
+ }\r
+ FreePool (Nbuf->Vector);\r
+ FreePool (Nbuf);\r
+ }\r
+}\r
+\r