]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeNetLib/NetBuffer.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Library / DxeNetLib / NetBuffer.c
index 427073d66d68a231caa2a545407b65dc51a6ba96..2408e9a10456e97d1427bcad71f938769e017c49 100644 (file)
@@ -1,47 +1,34 @@
 /** @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
@@ -84,7 +71,7 @@ NetbufAllocStruct (
 \r
 FreeNbuf:\r
 \r
-  gBS->FreePool (Nbuf);\r
+  FreePool (Nbuf);\r
   return NULL;\r
 }\r
 \r
@@ -93,10 +80,10 @@ FreeNbuf:
   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
@@ -139,20 +126,20 @@ NetbufAlloc (
   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
@@ -160,6 +147,7 @@ NetbufFreeVector (
 {\r
   UINT32                    Index;\r
 \r
+  ASSERT (Vector != NULL);\r
   NET_CHECK_SIGNATURE (Vector, NET_VECTOR_SIGNATURE);\r
   ASSERT (Vector->RefCnt > 0);\r
 \r
@@ -175,7 +163,7 @@ NetbufFreeVector (
     // 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
@@ -190,16 +178,20 @@ NetbufFreeVector (
     }\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
@@ -208,6 +200,7 @@ NetbufFree (
   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
@@ -219,20 +212,24 @@ NetbufFree (
     // 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
@@ -269,22 +266,26 @@ NetbufClone (
 \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
@@ -317,15 +318,13 @@ NetbufDuplicate (
 /**\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
@@ -347,17 +346,20 @@ NetbufFreeList (
 \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
@@ -401,24 +403,23 @@ NetbufGetByte (
 \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
@@ -445,23 +446,22 @@ NetbufSetBlock (
 \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
@@ -482,18 +482,16 @@ NetbufSetBlockOp (
 \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
@@ -505,21 +503,21 @@ NetbufGetFragmentFree (
 }\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
+  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
-  @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
+  @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
-  @retval *                     Pointer to the cloned net buffer.\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
@@ -575,9 +573,6 @@ NetbufGetFragment (
   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
@@ -601,6 +596,7 @@ NetbufGetFragment (
     FirstLen = Len;\r
   }\r
 \r
+  ASSERT (Last >= First);\r
   BlockOpNum = Last - First + 1;\r
   CurBlockOp = 0;\r
 \r
@@ -629,14 +625,14 @@ NetbufGetFragment (
     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
@@ -660,7 +656,7 @@ NetbufGetFragment (
     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
@@ -683,7 +679,7 @@ NetbufGetFragment (
 \r
 FreeChild:\r
 \r
-  gBS->FreePool (Child);\r
+  FreePool (Child);\r
   return NULL;\r
 }\r
 \r
@@ -692,17 +688,23 @@ FreeChild:
 /**\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
+  @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
-  @retval *                     Pointer to the net buffer built from the data\r
-                                blocks.\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
@@ -827,7 +829,7 @@ NetbufFromExt (
   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
@@ -852,36 +854,39 @@ NetbufFromExt (
   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
@@ -909,18 +914,20 @@ NetbufBuildExt (
 \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
+  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
-  @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
+  @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
-  @retval *                     Pointer to the net buffer built from the data\r
-                                blocks.\r
+  @return                 Pointer to the net buffer built from the list of net\r
+                          buffers.\r
 \r
 **/\r
 NET_BUF  *\r
@@ -967,7 +974,7 @@ NetbufFromBufList (
     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
@@ -976,31 +983,28 @@ NetbufFromBufList (
   }\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
@@ -1018,21 +1022,21 @@ NetbufReserve (
 \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
@@ -1041,6 +1045,8 @@ NetbufAllocSpace (
   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
@@ -1110,25 +1116,22 @@ NetbufAllocSpace (
 \r
 \r
 /**\r
-  Trim a single NET_BLOCK.\r
+  Trim a single NET_BLOCK by Len bytes from the header or tail.\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
-\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
@@ -1141,20 +1144,21 @@ NetblockTrim (
 \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
@@ -1165,6 +1169,10 @@ NetbufTrim (
 \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
@@ -1206,14 +1214,18 @@ NetbufTrim (
 \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
+  The Len bytes of data may cross the several fragments of the net buffer.\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
+  @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
-  @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.\r
 \r
 **/\r
 UINT32\r
@@ -1308,15 +1320,13 @@ NetbufCopy (
 /**\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
@@ -1330,11 +1340,10 @@ NetbufQueInit (
 \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
@@ -1359,9 +1368,11 @@ NetbufQueAlloc (
 /**\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
@@ -1370,31 +1381,30 @@ NetbufQueFree (
   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
+  Append a net buffer to the net buffer queue.\r
 \r
-  @param  NbufQue               Pointer to the net buffer queue.\r
-  @param  Nbuf                  Pointer to the net buffer to be appended.\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
@@ -1408,18 +1418,18 @@ NetbufQueAppend (
 \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
@@ -1441,22 +1451,28 @@ NetbufQueRemove (
 \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
-  @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
+  The copying operation is the same as NetbufCopy but applies to the net buffer\r
+  queue instead of the net buffer.\r
 \r
-  @retval UINTN                 The length of the copied data.\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
+  @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
@@ -1493,6 +1509,8 @@ NetbufQueCopy (
     Cur += Nbuf->TotalSize;\r
   }\r
 \r
+  ASSERT (Nbuf != NULL);\r
+\r
   //\r
   // Copy the data in the first buffer.\r
   //\r
@@ -1537,19 +1555,22 @@ NetbufQueCopy (
 \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
-  @param  NbufQue               Pointer to the net buffer queue.\r
-  @param  Len                   Length of the data to trim.\r
+  The trimming operation is the same as NetbufTrim but applies to the net buffer\r
+  queue instead of the net buffer.\r
 \r
-  @retval UINTN                 The length of the data trimmed.\r
+  @param[in, out]  NbufQue               Pointer to the net buffer queue.\r
+  @param[in]       Len                   Length of the data to trim.\r
+\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
@@ -1600,15 +1621,13 @@ NetbufQueTrim (
 /**\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
@@ -1621,12 +1640,12 @@ NetbufQueFlush (
 \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
@@ -1640,23 +1659,23 @@ NetblockChecksum (
 \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
@@ -1668,10 +1687,10 @@ NetblockChecksum (
 /**\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
@@ -1688,7 +1707,7 @@ NetAddChecksum (
   //\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
@@ -1700,9 +1719,9 @@ NetAddChecksum (
 /**\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
@@ -1730,12 +1749,12 @@ NetbufChecksum (
 \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
@@ -1748,15 +1767,15 @@ NetbufChecksum (
 \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
+  @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
-  @retval UINT16                The computed checksum.\r
+  @return   The computed checksum.\r
 \r
 **/\r
 UINT16\r
@@ -1782,3 +1801,90 @@ NetPseudoHeadChecksum (
 \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