/** @file
  Network library functions providing net buffer operation support.

Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>

#include <Library/NetLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>

/**
  Allocate and build up the sketch for a NET_BUF.

  The net buffer allocated has the BlockOpNum's NET_BLOCK_OP, and its associated
  NET_VECTOR has the BlockNum's NET_BLOCK. But all the NET_BLOCK_OP and
  NET_BLOCK remain un-initialized.

  @param[in]  BlockNum       The number of NET_BLOCK in the vector of net buffer
  @param[in]  BlockOpNum     The number of NET_BLOCK_OP in the net buffer

  @return                    Pointer to the allocated NET_BUF, or NULL if the
                             allocation failed due to resource limit.

**/
NET_BUF *
NetbufAllocStruct (
  IN UINT32  BlockNum,
  IN UINT32  BlockOpNum
  )
{
  NET_BUF     *Nbuf;
  NET_VECTOR  *Vector;

  ASSERT (BlockOpNum >= 1);

  //
  // Allocate three memory blocks.
  //
  Nbuf = AllocateZeroPool (NET_BUF_SIZE (BlockOpNum));

  if (Nbuf == NULL) {
    return NULL;
  }

  Nbuf->Signature  = NET_BUF_SIGNATURE;
  Nbuf->RefCnt     = 1;
  Nbuf->BlockOpNum = BlockOpNum;
  InitializeListHead (&Nbuf->List);

  if (BlockNum != 0) {
    Vector = AllocateZeroPool (NET_VECTOR_SIZE (BlockNum));

    if (Vector == NULL) {
      goto FreeNbuf;
    }

    Vector->Signature = NET_VECTOR_SIGNATURE;
    Vector->RefCnt    = 1;
    Vector->BlockNum  = BlockNum;
    Nbuf->Vector      = Vector;
  }

  return Nbuf;

FreeNbuf:

  FreePool (Nbuf);
  return NULL;
}

/**
  Allocate a single block NET_BUF. Upon allocation, all the
  free space is in the tail room.

  @param[in]  Len              The length of the block.

  @return                      Pointer to the allocated NET_BUF, or NULL if the
                               allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufAlloc (
  IN UINT32  Len
  )
{
  NET_BUF     *Nbuf;
  NET_VECTOR  *Vector;
  UINT8       *Bulk;

  ASSERT (Len > 0);

  Nbuf = NetbufAllocStruct (1, 1);

  if (Nbuf == NULL) {
    return NULL;
  }

  Bulk = AllocatePool (Len);

  if (Bulk == NULL) {
    goto FreeNBuf;
  }

  Vector      = Nbuf->Vector;
  Vector->Len = Len;

  Vector->Block[0].Bulk = Bulk;
  Vector->Block[0].Len  = Len;

  Nbuf->BlockOp[0].BlockHead = Bulk;
  Nbuf->BlockOp[0].BlockTail = Bulk + Len;

  Nbuf->BlockOp[0].Head = Bulk;
  Nbuf->BlockOp[0].Tail = Bulk;
  Nbuf->BlockOp[0].Size = 0;

  return Nbuf;

FreeNBuf:
  FreePool (Nbuf);
  return NULL;
}

/**
  Free the net vector.

  Decrease the reference count of the net vector by one. The real resource free
  operation isn't performed until the reference count of the net vector is
  decreased to 0.

  @param[in]  Vector                Pointer to the NET_VECTOR to be freed.

**/
VOID
NetbufFreeVector (
  IN NET_VECTOR  *Vector
  )
{
  UINT32  Index;

  ASSERT (Vector != NULL);
  NET_CHECK_SIGNATURE (Vector, NET_VECTOR_SIGNATURE);
  ASSERT (Vector->RefCnt > 0);

  Vector->RefCnt--;

  if (Vector->RefCnt > 0) {
    return;
  }

  if (Vector->Free != NULL) {
    //
    // Call external free function to free the vector if it
    // isn't NULL. If NET_VECTOR_OWN_FIRST is set, release the
    // first block since it is allocated by us
    //
    if ((Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
      gBS->FreePool (Vector->Block[0].Bulk);
    }

    Vector->Free (Vector->Arg);
  } else {
    //
    // Free each memory block associated with the Vector
    //
    for (Index = 0; Index < Vector->BlockNum; Index++) {
      gBS->FreePool (Vector->Block[Index].Bulk);
    }
  }

  FreePool (Vector);
}

/**
  Free the net buffer and its associated NET_VECTOR.

  Decrease the reference count of the net buffer by one. Free the associated net
  vector and itself if the reference count of the net buffer is decreased to 0.
  The net vector free operation just decrease the reference count of the net
  vector by one and do the real resource free operation when the reference count
  of the net vector is 0.

  @param[in]  Nbuf                  Pointer to the NET_BUF to be freed.

**/
VOID
EFIAPI
NetbufFree (
  IN NET_BUF  *Nbuf
  )
{
  ASSERT (Nbuf != NULL);
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Nbuf->RefCnt > 0);

  Nbuf->RefCnt--;

  if (Nbuf->RefCnt == 0) {
    //
    // Update Vector only when NBuf is to be released. That is,
    // all the sharing of Nbuf increse Vector's RefCnt by one
    //
    NetbufFreeVector (Nbuf->Vector);
    FreePool (Nbuf);
  }
}

/**
  Create a copy of the net buffer that shares the associated net vector.

  The reference count of the newly created net buffer is set to 1. The reference
  count of the associated net vector is increased by one.

  @param[in]  Nbuf              Pointer to the net buffer to be cloned.

  @return                       Pointer to the cloned net buffer, or NULL if the
                                allocation failed due to resource limit.

**/
NET_BUF *
EFIAPI
NetbufClone (
  IN NET_BUF  *Nbuf
  )
{
  NET_BUF  *Clone;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  Clone = AllocatePool (NET_BUF_SIZE (Nbuf->BlockOpNum));

  if (Clone == NULL) {
    return NULL;
  }

  Clone->Signature = NET_BUF_SIGNATURE;
  Clone->RefCnt    = 1;
  InitializeListHead (&Clone->List);

  Clone->Ip  = Nbuf->Ip;
  Clone->Tcp = Nbuf->Tcp;

  CopyMem (Clone->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);

  NET_GET_REF (Nbuf->Vector);

  Clone->Vector     = Nbuf->Vector;
  Clone->BlockOpNum = Nbuf->BlockOpNum;
  Clone->TotalSize  = Nbuf->TotalSize;
  CopyMem (Clone->BlockOp, Nbuf->BlockOp, sizeof (NET_BLOCK_OP) * Nbuf->BlockOpNum);

  return Clone;
}

/**
  Create a duplicated copy of the net buffer with data copied and HeadSpace
  bytes of head space reserved.

  The duplicated net buffer will allocate its own memory to hold the data of the
  source net buffer.

  @param[in]       Nbuf         Pointer to the net buffer to be duplicated from.
  @param[in, out]  Duplicate    Pointer to the net buffer to duplicate to, if
                                NULL a new net buffer is allocated.
  @param[in]      HeadSpace     Length of the head space to reserve.

  @return                       Pointer to the duplicated net buffer, or NULL if
                                the allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufDuplicate (
  IN NET_BUF      *Nbuf,
  IN OUT NET_BUF  *Duplicate        OPTIONAL,
  IN UINT32       HeadSpace
  )
{
  UINT8  *Dst;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if (Duplicate == NULL) {
    Duplicate = NetbufAlloc (Nbuf->TotalSize + HeadSpace);
  }

  if (Duplicate == NULL) {
    return NULL;
  }

  //
  // Don't set the IP and TCP head point, since it is most
  // like that they are pointing to the memory of Nbuf.
  //
  CopyMem (Duplicate->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
  NetbufReserve (Duplicate, HeadSpace);

  Dst = NetbufAllocSpace (Duplicate, Nbuf->TotalSize, NET_BUF_TAIL);
  NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dst);

  return Duplicate;
}

/**
  Free a list of net buffers.

  @param[in, out]  Head              Pointer to the head of linked net buffers.

**/
VOID
EFIAPI
NetbufFreeList (
  IN OUT LIST_ENTRY  *Head
  )
{
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;
  NET_BUF     *Nbuf;

  Entry = Head->ForwardLink;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

    RemoveEntryList (Entry);
    NetbufFree (Nbuf);
  }

  ASSERT (IsListEmpty (Head));
}

/**
  Get the index of NET_BLOCK_OP that contains the byte at Offset in the net
  buffer.

  This can be used to, for example, retrieve the IP header in the packet. It
  also can be used to get the fragment that contains the byte which is used
  mainly by the library implementation itself.

  @param[in]   Nbuf      Pointer to the net buffer.
  @param[in]   Offset    The offset of the byte.
  @param[out]  Index     Index of the NET_BLOCK_OP that contains the byte at
                         Offset.

  @return       Pointer to the Offset'th byte of data in the net buffer, or NULL
                if there is no such data in the net buffer.

**/
UINT8  *
EFIAPI
NetbufGetByte (
  IN  NET_BUF  *Nbuf,
  IN  UINT32   Offset,
  OUT UINT32   *Index  OPTIONAL
  )
{
  NET_BLOCK_OP  *BlockOp;
  UINT32        Loop;
  UINT32        Len;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if (Offset >= Nbuf->TotalSize) {
    return NULL;
  }

  BlockOp = Nbuf->BlockOp;
  Len     = 0;

  for (Loop = 0; Loop < Nbuf->BlockOpNum; Loop++) {
    if (Len + BlockOp[Loop].Size <= Offset) {
      Len += BlockOp[Loop].Size;
      continue;
    }

    if (Index != NULL) {
      *Index = Loop;
    }

    return BlockOp[Loop].Head + (Offset - Len);
  }

  return NULL;
}

/**
  Set the NET_BLOCK and corresponding NET_BLOCK_OP in the net buffer and
  corresponding net vector according to the bulk pointer and bulk length.

  All the pointers in the Index'th NET_BLOCK and NET_BLOCK_OP are set to the
  bulk's head and tail respectively. So, this function alone can't be used by
  NetbufAlloc.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Bulk       Pointer to the data.
  @param[in]       Len        Length of the bulk data.
  @param[in]       Index      The data block index in the net buffer the bulk
                              data should belong to.

**/
VOID
NetbufSetBlock (
  IN OUT NET_BUF  *Nbuf,
  IN UINT8        *Bulk,
  IN UINT32       Len,
  IN UINT32       Index
  )
{
  NET_BLOCK_OP  *BlockOp;
  NET_BLOCK     *Block;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
  ASSERT (Index < Nbuf->BlockOpNum);

  Block              = &(Nbuf->Vector->Block[Index]);
  BlockOp            = &(Nbuf->BlockOp[Index]);
  Block->Len         = Len;
  Block->Bulk        = Bulk;
  BlockOp->BlockHead = Bulk;
  BlockOp->BlockTail = Bulk + Len;
  BlockOp->Head      = Bulk;
  BlockOp->Tail      = Bulk + Len;
  BlockOp->Size      = Len;
}

/**
  Set the NET_BLOCK_OP in the net buffer. The corresponding NET_BLOCK
  structure is left untouched.

  Some times, there is no 1:1 relationship between NET_BLOCK and NET_BLOCK_OP.
  For example, that in NetbufGetFragment.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Bulk       Pointer to the data.
  @param[in]       Len        Length of the bulk data.
  @param[in]       Index      The data block index in the net buffer the bulk
                              data should belong to.

**/
VOID
NetbufSetBlockOp (
  IN OUT NET_BUF  *Nbuf,
  IN UINT8        *Bulk,
  IN UINT32       Len,
  IN UINT32       Index
  )
{
  NET_BLOCK_OP  *BlockOp;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Index < Nbuf->BlockOpNum);

  BlockOp            = &(Nbuf->BlockOp[Index]);
  BlockOp->BlockHead = Bulk;
  BlockOp->BlockTail = Bulk + Len;
  BlockOp->Head      = Bulk;
  BlockOp->Tail      = Bulk + Len;
  BlockOp->Size      = Len;
}

/**
  Helper function for NetbufGetFragment. NetbufGetFragment may allocate the
  first block to reserve HeadSpace bytes header space. So it needs to create a
  new net vector for the first block and can avoid copy for the remaining data
  by sharing the old net vector.

  @param[in]  Arg                   Point to the old NET_VECTOR.

**/
VOID
EFIAPI
NetbufGetFragmentFree (
  IN VOID  *Arg
  )
{
  NET_VECTOR  *Vector;

  Vector = (NET_VECTOR *)Arg;
  NetbufFreeVector (Vector);
}

/**
  Create a NET_BUF structure which contains Len byte data of Nbuf starting from
  Offset.

  A new NET_BUF structure will be created but the associated data in NET_VECTOR
  is shared. This function exists to do IP packet fragmentation.

  @param[in]  Nbuf         Pointer to the net buffer to be extracted.
  @param[in]  Offset       Starting point of the data to be included in the new
                           net buffer.
  @param[in]  Len          Bytes of data to be included in the new net buffer.
  @param[in]  HeadSpace    Bytes of head space to reserve for protocol header.

  @return                  Pointer to the cloned net buffer, or NULL if the
                           allocation failed due to resource limit.

**/
NET_BUF  *
EFIAPI
NetbufGetFragment (
  IN NET_BUF  *Nbuf,
  IN UINT32   Offset,
  IN UINT32   Len,
  IN UINT32   HeadSpace
  )
{
  NET_BUF       *Child;
  NET_VECTOR    *Vector;
  NET_BLOCK_OP  *BlockOp;
  UINT32        CurBlockOp;
  UINT32        BlockOpNum;
  UINT8         *FirstBulk;
  UINT32        Index;
  UINT32        First;
  UINT32        Last;
  UINT32        FirstSkip;
  UINT32        FirstLen;
  UINT32        LastLen;
  UINT32        Cur;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if ((Len == 0) || (Offset + Len > Nbuf->TotalSize)) {
    return NULL;
  }

  //
  // First find the first and last BlockOp that contains
  // the valid data, and compute the offset of the first
  // BlockOp and length of the last BlockOp
  //
  BlockOp = Nbuf->BlockOp;
  Cur     = 0;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (Offset < Cur + BlockOp[Index].Size) {
      break;
    }

    Cur += BlockOp[Index].Size;
  }

  //
  // First is the index of the first BlockOp, FirstSkip is
  // the offset of the first byte in the first BlockOp.
  //
  First     = Index;
  FirstSkip = Offset - Cur;
  FirstLen  = BlockOp[Index].Size - FirstSkip;

  Last    = 0;
  LastLen = 0;

  if (Len > FirstLen) {
    Cur += BlockOp[Index].Size;
    Index++;

    for ( ; Index < Nbuf->BlockOpNum; Index++) {
      if (Offset + Len <= Cur + BlockOp[Index].Size) {
        Last    = Index;
        LastLen = Offset + Len - Cur;
        break;
      }

      Cur += BlockOp[Index].Size;
    }
  } else {
    Last     = First;
    LastLen  = Len;
    FirstLen = Len;
  }

  ASSERT (Last >= First);
  BlockOpNum = Last - First + 1;
  CurBlockOp = 0;

  if (HeadSpace != 0) {
    //
    // Allocate an extra block to accommodate the head space.
    //
    BlockOpNum++;

    Child = NetbufAllocStruct (1, BlockOpNum);

    if (Child == NULL) {
      return NULL;
    }

    FirstBulk = AllocatePool (HeadSpace);

    if (FirstBulk == NULL) {
      goto FreeChild;
    }

    Vector       = Child->Vector;
    Vector->Free = NetbufGetFragmentFree;
    Vector->Arg  = Nbuf->Vector;
    Vector->Flag = NET_VECTOR_OWN_FIRST;
    Vector->Len  = HeadSpace;

    //
    // Reserve the head space in the first block
    //
    NetbufSetBlock (Child, FirstBulk, HeadSpace, 0);
    Child->BlockOp[0].Head += HeadSpace;
    Child->BlockOp[0].Size  =  0;
    CurBlockOp++;
  } else {
    Child = NetbufAllocStruct (0, BlockOpNum);

    if (Child == NULL) {
      return NULL;
    }

    Child->Vector = Nbuf->Vector;
  }

  NET_GET_REF (Nbuf->Vector);
  Child->TotalSize = Len;

  //
  // Set all the BlockOp up, the first and last one are special
  // and need special process.
  //
  NetbufSetBlockOp (
    Child,
    Nbuf->BlockOp[First].Head + FirstSkip,
    FirstLen,
    CurBlockOp++
    );

  for (Index = First + 1; Index < Last; Index++) {
    NetbufSetBlockOp (
      Child,
      BlockOp[Index].Head,
      BlockOp[Index].Size,
      CurBlockOp++
      );
  }

  if (First != Last) {
    NetbufSetBlockOp (
      Child,
      BlockOp[Last].Head,
      LastLen,
      CurBlockOp
      );
  }

  CopyMem (Child->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
  return Child;

FreeChild:

  FreePool (Child);
  return NULL;
}

/**
  Build a NET_BUF from external blocks.

  A new NET_BUF structure will be created from external blocks. Additional block
  of memory will be allocated to hold reserved HeadSpace bytes of header room
  and existing HeadLen bytes of header but the external blocks are shared by the
  net buffer to avoid data copying.

  @param[in]  ExtFragment           Pointer to the data block.
  @param[in]  ExtNum                The number of the data blocks.
  @param[in]  HeadSpace             The head space to be reserved.
  @param[in]  HeadLen               The length of the protocol header, This function
                                    will pull that number of data into a linear block.
  @param[in]  ExtFree               Pointer to the caller provided free function.
  @param[in]  Arg                   The argument passed to ExtFree when ExtFree is
                                    called.

  @return                  Pointer to the net buffer built from the data blocks,
                           or NULL if the allocation failed due to resource
                           limit.

**/
NET_BUF  *
EFIAPI
NetbufFromExt (
  IN NET_FRAGMENT         *ExtFragment,
  IN UINT32               ExtNum,
  IN UINT32               HeadSpace,
  IN UINT32               HeadLen,
  IN NET_VECTOR_EXT_FREE  ExtFree,
  IN VOID                 *Arg          OPTIONAL
  )
{
  NET_BUF       *Nbuf;
  NET_VECTOR    *Vector;
  NET_FRAGMENT  SavedFragment;
  UINT32        SavedIndex;
  UINT32        TotalLen;
  UINT32        BlockNum;
  UINT8         *FirstBlock;
  UINT32        FirstBlockLen;
  UINT8         *Header;
  UINT32        CurBlock;
  UINT32        Index;
  UINT32        Len;
  UINT32        Copied;

  ASSERT ((ExtFragment != NULL) && (ExtNum > 0) && (ExtFree != NULL));

  SavedFragment.Bulk = NULL;
  SavedFragment.Len  = 0;

  FirstBlockLen = 0;
  FirstBlock    = NULL;
  BlockNum      = ExtNum;
  Index         = 0;
  TotalLen      = 0;
  SavedIndex    = 0;
  Len           = 0;
  Copied        = 0;

  //
  // No need to consolidate the header if the first block is
  // longer than the header length or there is only one block.
  //
  if ((ExtFragment[0].Len >= HeadLen) || (ExtNum == 1)) {
    HeadLen = 0;
  }

  //
  // Allocate an extra block if we need to:
  //  1. Allocate some header space
  //  2. aggreate the packet header
  //
  if ((HeadSpace != 0) || (HeadLen != 0)) {
    FirstBlockLen = HeadLen + HeadSpace;
    FirstBlock    = AllocatePool (FirstBlockLen);

    if (FirstBlock == NULL) {
      return NULL;
    }

    BlockNum++;
  }

  //
  // Copy the header to the first block, reduce the NET_BLOCK
  // to allocate by one for each block that is completely covered
  // by the first bulk.
  //
  if (HeadLen != 0) {
    Len    = HeadLen;
    Header = FirstBlock + HeadSpace;

    for (Index = 0; Index < ExtNum; Index++) {
      if (Len >= ExtFragment[Index].Len) {
        CopyMem (Header, ExtFragment[Index].Bulk, ExtFragment[Index].Len);

        Copied   += ExtFragment[Index].Len;
        Len      -= ExtFragment[Index].Len;
        Header   += ExtFragment[Index].Len;
        TotalLen += ExtFragment[Index].Len;
        BlockNum--;

        if (Len == 0) {
          //
          // Increment the index number to point to the next
          // non-empty fragment.
          //
          Index++;
          break;
        }
      } else {
        CopyMem (Header, ExtFragment[Index].Bulk, Len);

        Copied   += Len;
        TotalLen += Len;

        //
        // Adjust the block structure to exclude the data copied,
        // So, the left-over block can be processed as other blocks.
        // But it must be recovered later. (SavedIndex > 0) always
        // holds since we don't aggreate the header if the first block
        // is bigger enough that the header is continuous
        //
        SavedIndex               = Index;
        SavedFragment            = ExtFragment[Index];
        ExtFragment[Index].Bulk += Len;
        ExtFragment[Index].Len  -= Len;
        break;
      }
    }
  }

  Nbuf = NetbufAllocStruct (BlockNum, BlockNum);

  if (Nbuf == NULL) {
    goto FreeFirstBlock;
  }

  Vector       = Nbuf->Vector;
  Vector->Free = ExtFree;
  Vector->Arg  = Arg;
  Vector->Flag = ((FirstBlockLen != 0) ? NET_VECTOR_OWN_FIRST : 0);

  //
  // Set the first block up which may contain
  // some head space and aggregated header
  //
  CurBlock = 0;

  if (FirstBlockLen != 0) {
    NetbufSetBlock (Nbuf, FirstBlock, HeadSpace + Copied, 0);
    Nbuf->BlockOp[0].Head += HeadSpace;
    Nbuf->BlockOp[0].Size  =  Copied;

    CurBlock++;
  }

  for ( ; Index < ExtNum; Index++) {
    NetbufSetBlock (Nbuf, ExtFragment[Index].Bulk, ExtFragment[Index].Len, CurBlock);
    TotalLen += ExtFragment[Index].Len;
    CurBlock++;
  }

  Vector->Len     = TotalLen + HeadSpace;
  Nbuf->TotalSize = TotalLen;

  if (SavedIndex != 0) {
    ExtFragment[SavedIndex] = SavedFragment;
  }

  return Nbuf;

FreeFirstBlock:
  if (FirstBlock != NULL) {
    FreePool (FirstBlock);
  }

  return NULL;
}

/**
  Build a fragment table to contain the fragments in the net buffer. This is the
  opposite operation of the NetbufFromExt.

  @param[in]       Nbuf                  Point to the net buffer.
  @param[in, out]  ExtFragment           Pointer to the data block.
  @param[in, out]  ExtNum                The number of the data blocks.

  @retval EFI_BUFFER_TOO_SMALL  The number of non-empty block is bigger than
                                ExtNum.
  @retval EFI_SUCCESS           Fragment table is built successfully.

**/
EFI_STATUS
EFIAPI
NetbufBuildExt (
  IN NET_BUF           *Nbuf,
  IN OUT NET_FRAGMENT  *ExtFragment,
  IN OUT UINT32        *ExtNum
  )
{
  UINT32  Index;
  UINT32  Current;

  Current = 0;

  for (Index = 0; (Index < Nbuf->BlockOpNum); Index++) {
    if (Nbuf->BlockOp[Index].Size == 0) {
      continue;
    }

    if (Current < *ExtNum) {
      ExtFragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
      ExtFragment[Current].Len  = Nbuf->BlockOp[Index].Size;
      Current++;
    } else {
      return EFI_BUFFER_TOO_SMALL;
    }
  }

  *ExtNum = Current;
  return EFI_SUCCESS;
}

/**
  Build a net buffer from a list of net buffers.

  All the fragments will be collected from the list of NEW_BUF and then a new
  net buffer will be created through NetbufFromExt.

  @param[in]   BufList    A List of the net buffer.
  @param[in]   HeadSpace  The head space to be reserved.
  @param[in]   HeaderLen  The length of the protocol header, This function
                          will pull that number of data into a linear block.
  @param[in]   ExtFree    Pointer to the caller provided free function.
  @param[in]   Arg        The argument passed to ExtFree when ExtFree is called.

  @return                 Pointer to the net buffer built from the list of net
                          buffers.

**/
NET_BUF  *
EFIAPI
NetbufFromBufList (
  IN LIST_ENTRY           *BufList,
  IN UINT32               HeadSpace,
  IN UINT32               HeaderLen,
  IN NET_VECTOR_EXT_FREE  ExtFree,
  IN VOID                 *Arg              OPTIONAL
  )
{
  NET_FRAGMENT  *Fragment;
  UINT32        FragmentNum;
  LIST_ENTRY    *Entry;
  NET_BUF       *Nbuf;
  UINT32        Index;
  UINT32        Current;

  //
  // Compute how many blocks are there
  //
  FragmentNum = 0;

  NET_LIST_FOR_EACH (Entry, BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
    FragmentNum += Nbuf->BlockOpNum;
  }

  //
  // Allocate and copy block points
  //
  Fragment = AllocatePool (sizeof (NET_FRAGMENT) * FragmentNum);

  if (Fragment == NULL) {
    return NULL;
  }

  Current = 0;

  NET_LIST_FOR_EACH (Entry, BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
    NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

    for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
      if (Nbuf->BlockOp[Index].Size != 0) {
        Fragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
        Fragment[Current].Len  = Nbuf->BlockOp[Index].Size;
        Current++;
      }
    }
  }

  Nbuf = NetbufFromExt (Fragment, Current, HeadSpace, HeaderLen, ExtFree, Arg);
  FreePool (Fragment);

  return Nbuf;
}

/**
  Reserve some space in the header room of the net buffer.

  Upon allocation, all the space are in the tail room of the buffer. Call this
  function to move some space to the header room. This function is quite limited
  in that it can only reserve space from the first block of an empty NET_BUF not
  built from the external. But it should be enough for the network stack.

  @param[in, out]  Nbuf     Pointer to the net buffer.
  @param[in]       Len      The length of buffer to be reserved from the header.

**/
VOID
EFIAPI
NetbufReserve (
  IN OUT NET_BUF  *Nbuf,
  IN UINT32       Len
  )
{
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);

  ASSERT ((Nbuf->BlockOpNum == 1) && (Nbuf->TotalSize == 0));
  ASSERT ((Nbuf->Vector->Free == NULL) && (Nbuf->Vector->Len >= Len));

  Nbuf->BlockOp[0].Head += Len;
  Nbuf->BlockOp[0].Tail += Len;

  ASSERT (Nbuf->BlockOp[0].Tail <= Nbuf->BlockOp[0].BlockTail);
}

/**
  Allocate Len bytes of space from the header or tail of the buffer.

  @param[in, out]  Nbuf       Pointer to the net buffer.
  @param[in]       Len        The length of the buffer to be allocated.
  @param[in]       FromHead   The flag to indicate whether reserve the data
                              from head (TRUE) or tail (FALSE).

  @return                     Pointer to the first byte of the allocated buffer,
                              or NULL if there is no sufficient space.

**/
UINT8 *
EFIAPI
NetbufAllocSpace (
  IN OUT NET_BUF  *Nbuf,
  IN UINT32       Len,
  IN BOOLEAN      FromHead
  )
{
  NET_BLOCK_OP  *BlockOp;
  UINT32        Index;
  UINT8         *SavedTail;

  Index = 0;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);

  ASSERT (Len > 0);

  if (FromHead) {
    //
    // Allocate some space from head. If the buffer is empty,
    // allocate from the first block. If it isn't, allocate
    // from the first non-empty block, or the block before that.
    //
    if (Nbuf->TotalSize == 0) {
      Index = 0;
    } else {
      NetbufGetByte (Nbuf, 0, &Index);

      if ((Index != 0) && (NET_HEADSPACE (&(Nbuf->BlockOp[Index])) < Len)) {
        Index--;
      }
    }

    BlockOp = &(Nbuf->BlockOp[Index]);

    if (NET_HEADSPACE (BlockOp) < Len) {
      return NULL;
    }

    BlockOp->Head   -= Len;
    BlockOp->Size   += Len;
    Nbuf->TotalSize += Len;

    return BlockOp->Head;
  } else {
    //
    // Allocate some space from the tail. If the buffer is empty,
    // allocate from the first block. If it isn't, allocate
    // from the last non-empty block, or the block after that.
    //
    if (Nbuf->TotalSize == 0) {
      Index = 0;
    } else {
      NetbufGetByte (Nbuf, Nbuf->TotalSize - 1, &Index);

      if ((NET_TAILSPACE (&(Nbuf->BlockOp[Index])) < Len) &&
          (Index < Nbuf->BlockOpNum - 1))
      {
        Index++;
      }
    }

    BlockOp = &(Nbuf->BlockOp[Index]);

    if (NET_TAILSPACE (BlockOp) < Len) {
      return NULL;
    }

    SavedTail = BlockOp->Tail;

    BlockOp->Tail   += Len;
    BlockOp->Size   += Len;
    Nbuf->TotalSize += Len;

    return SavedTail;
  }
}

/**
  Trim a single NET_BLOCK by Len bytes from the header or tail.

  @param[in, out]  BlockOp      Pointer to the NET_BLOCK.
  @param[in]       Len          The length of the data to be trimmed.
  @param[in]       FromHead     The flag to indicate whether trim data from head
                                (TRUE) or tail (FALSE).

**/
VOID
NetblockTrim (
  IN OUT NET_BLOCK_OP  *BlockOp,
  IN UINT32            Len,
  IN BOOLEAN           FromHead
  )
{
  ASSERT ((BlockOp != NULL) && (BlockOp->Size >= Len));

  BlockOp->Size -= Len;

  if (FromHead) {
    BlockOp->Head += Len;
  } else {
    BlockOp->Tail -= Len;
  }
}

/**
  Trim Len bytes from the header or tail of the net buffer.

  @param[in, out]  Nbuf         Pointer to the net buffer.
  @param[in]       Len          The length of the data to be trimmed.
  @param[in]      FromHead      The flag to indicate whether trim data from head
                                (TRUE) or tail (FALSE).

  @return    Length of the actually trimmed data, which is possible to be less
             than Len because the TotalSize of Nbuf is less than Len.

**/
UINT32
EFIAPI
NetbufTrim (
  IN OUT NET_BUF  *Nbuf,
  IN UINT32       Len,
  IN BOOLEAN      FromHead
  )
{
  NET_BLOCK_OP  *BlockOp;
  UINT32        Index;
  UINT32        Trimmed;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  if ((Len == 0) || (Nbuf->TotalSize == 0)) {
    return 0;
  }

  if (Len > Nbuf->TotalSize) {
    Len = Nbuf->TotalSize;
  }

  //
  // If FromTail is true, iterate backward. That
  // is, init Index to NBuf->BlockNum - 1, and
  // decrease it by 1 during each loop. Otherwise,
  // iterate forward. That is, init Index to 0, and
  // increase it by 1 during each loop.
  //
  Trimmed          = 0;
  Nbuf->TotalSize -= Len;

  Index   = (FromHead ? 0 : Nbuf->BlockOpNum - 1);
  BlockOp = Nbuf->BlockOp;

  for ( ; ;) {
    if (BlockOp[Index].Size == 0) {
      Index += (FromHead ? 1 : -1);
      continue;
    }

    if (Len > BlockOp[Index].Size) {
      Len     -= BlockOp[Index].Size;
      Trimmed += BlockOp[Index].Size;
      NetblockTrim (&BlockOp[Index], BlockOp[Index].Size, FromHead);
    } else {
      Trimmed += Len;
      NetblockTrim (&BlockOp[Index], Len, FromHead);
      break;
    }

    Index += (FromHead ? 1 : -1);
  }

  return Trimmed;
}

/**
  Copy Len bytes of data from the specific offset of the net buffer to the
  destination memory.

  The Len bytes of data may cross the several fragments of the net buffer.

  @param[in]   Nbuf         Pointer to the net buffer.
  @param[in]   Offset       The sequence number of the first byte to copy.
  @param[in]   Len          Length of the data to copy.
  @param[in]   Dest         The destination of the data to copy to.

  @return           The length of the actual copied data, or 0 if the offset
                    specified exceeds the total size of net buffer.

**/
UINT32
EFIAPI
NetbufCopy (
  IN NET_BUF  *Nbuf,
  IN UINT32   Offset,
  IN UINT32   Len,
  IN UINT8    *Dest
  )
{
  NET_BLOCK_OP  *BlockOp;
  UINT32        Skip;
  UINT32        Left;
  UINT32        Copied;
  UINT32        Index;
  UINT32        Cur;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Dest);

  if ((Len == 0) || (Nbuf->TotalSize <= Offset)) {
    return 0;
  }

  if (Nbuf->TotalSize - Offset < Len) {
    Len = Nbuf->TotalSize - Offset;
  }

  BlockOp = Nbuf->BlockOp;

  //
  // Skip to the offset. Don't make "Offset-By-One" error here.
  // Cur + BLOCK.SIZE is the first sequence number of next block.
  // So, (Offset < Cur + BLOCK.SIZE) means that the  first byte
  // is in the current block. if (Offset == Cur + BLOCK.SIZE), the
  // first byte is the next block's first byte.
  //
  Cur = 0;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (BlockOp[Index].Size == 0) {
      continue;
    }

    if (Offset < Cur + BlockOp[Index].Size) {
      break;
    }

    Cur += BlockOp[Index].Size;
  }

  //
  // Cur is the sequence number of the first byte in the block
  // Offset - Cur is the number of bytes before first byte to
  // to copy in the current block.
  //
  Skip = Offset - Cur;
  Left = BlockOp[Index].Size - Skip;

  if (Len <= Left) {
    CopyMem (Dest, BlockOp[Index].Head + Skip, Len);
    return Len;
  }

  CopyMem (Dest, BlockOp[Index].Head + Skip, Left);

  Dest  += Left;
  Len   -= Left;
  Copied = Left;

  Index++;

  for ( ; Index < Nbuf->BlockOpNum; Index++) {
    if (Len > BlockOp[Index].Size) {
      Len    -= BlockOp[Index].Size;
      Copied += BlockOp[Index].Size;

      CopyMem (Dest, BlockOp[Index].Head, BlockOp[Index].Size);
      Dest += BlockOp[Index].Size;
    } else {
      Copied += Len;
      CopyMem (Dest, BlockOp[Index].Head, Len);
      break;
    }
  }

  return Copied;
}

/**
  Initiate the net buffer queue.

  @param[in, out]  NbufQue   Pointer to the net buffer queue to be initialized.

**/
VOID
EFIAPI
NetbufQueInit (
  IN OUT NET_BUF_QUEUE  *NbufQue
  )
{
  NbufQue->Signature = NET_QUE_SIGNATURE;
  NbufQue->RefCnt    = 1;
  InitializeListHead (&NbufQue->List);

  InitializeListHead (&NbufQue->BufList);
  NbufQue->BufSize = 0;
  NbufQue->BufNum  = 0;
}

/**
  Allocate and initialize a net buffer queue.

  @return         Pointer to the allocated net buffer queue, or NULL if the
                  allocation failed due to resource limit.

**/
NET_BUF_QUEUE  *
EFIAPI
NetbufQueAlloc (
  VOID
  )
{
  NET_BUF_QUEUE  *NbufQue;

  NbufQue = AllocatePool (sizeof (NET_BUF_QUEUE));
  if (NbufQue == NULL) {
    return NULL;
  }

  NetbufQueInit (NbufQue);

  return NbufQue;
}

/**
  Free a net buffer queue.

  Decrease the reference count of the net buffer queue by one. The real resource
  free operation isn't performed until the reference count of the net buffer
  queue is decreased to 0.

  @param[in]  NbufQue               Pointer to the net buffer queue to be freed.

**/
VOID
EFIAPI
NetbufQueFree (
  IN NET_BUF_QUEUE  *NbufQue
  )
{
  ASSERT (NbufQue != NULL);
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  NbufQue->RefCnt--;

  if (NbufQue->RefCnt == 0) {
    NetbufQueFlush (NbufQue);
    FreePool (NbufQue);
  }
}

/**
  Append a net buffer to the net buffer queue.

  @param[in, out]  NbufQue            Pointer to the net buffer queue.
  @param[in, out]  Nbuf               Pointer to the net buffer to be appended.

**/
VOID
EFIAPI
NetbufQueAppend (
  IN OUT NET_BUF_QUEUE  *NbufQue,
  IN OUT NET_BUF        *Nbuf
  )
{
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  InsertTailList (&NbufQue->BufList, &Nbuf->List);

  NbufQue->BufSize += Nbuf->TotalSize;
  NbufQue->BufNum++;
}

/**
  Remove a net buffer from the head in the specific queue and return it.

  @param[in, out]  NbufQue               Pointer to the net buffer queue.

  @return           Pointer to the net buffer removed from the specific queue,
                    or NULL if there is no net buffer in the specific queue.

**/
NET_BUF  *
EFIAPI
NetbufQueRemove (
  IN OUT NET_BUF_QUEUE  *NbufQue
  )
{
  NET_BUF  *First;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  if (NbufQue->BufNum == 0) {
    return NULL;
  }

  First = NET_LIST_USER_STRUCT (NbufQue->BufList.ForwardLink, NET_BUF, List);

  NetListRemoveHead (&NbufQue->BufList);

  NbufQue->BufSize -= First->TotalSize;
  NbufQue->BufNum--;
  return First;
}

/**
  Copy Len bytes of data from the net buffer queue at the specific offset to the
  destination memory.

  The copying operation is the same as NetbufCopy but applies to the net buffer
  queue instead of the net buffer.

  @param[in]   NbufQue         Pointer to the net buffer queue.
  @param[in]   Offset          The sequence number of the first byte to copy.
  @param[in]   Len             Length of the data to copy.
  @param[out]  Dest            The destination of the data to copy to.

  @return       The length of the actual copied data, or 0 if the offset
                specified exceeds the total size of net buffer queue.

**/
UINT32
EFIAPI
NetbufQueCopy (
  IN NET_BUF_QUEUE  *NbufQue,
  IN UINT32         Offset,
  IN UINT32         Len,
  OUT UINT8         *Dest
  )
{
  LIST_ENTRY  *Entry;
  NET_BUF     *Nbuf;
  UINT32      Skip;
  UINT32      Left;
  UINT32      Cur;
  UINT32      Copied;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
  ASSERT (Dest != NULL);

  if ((Len == 0) || (NbufQue->BufSize <= Offset)) {
    return 0;
  }

  if (NbufQue->BufSize - Offset < Len) {
    Len = NbufQue->BufSize - Offset;
  }

  //
  // skip to the Offset
  //
  Cur  = 0;
  Nbuf = NULL;

  NET_LIST_FOR_EACH (Entry, &NbufQue->BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Offset < Cur + Nbuf->TotalSize) {
      break;
    }

    Cur += Nbuf->TotalSize;
  }

  ASSERT (Nbuf != NULL);

  //
  // Copy the data in the first buffer.
  //
  Skip = Offset - Cur;
  Left = Nbuf->TotalSize - Skip;

  if (Len < Left) {
    return NetbufCopy (Nbuf, Skip, Len, Dest);
  }

  NetbufCopy (Nbuf, Skip, Left, Dest);
  Dest  += Left;
  Len   -= Left;
  Copied = Left;

  //
  // Iterate over the others
  //
  Entry = Entry->ForwardLink;

  while ((Len > 0) && (Entry != &NbufQue->BufList)) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Len > Nbuf->TotalSize) {
      Len    -= Nbuf->TotalSize;
      Copied += Nbuf->TotalSize;

      NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dest);
      Dest += Nbuf->TotalSize;
    } else {
      NetbufCopy (Nbuf, 0, Len, Dest);
      Copied += Len;
      break;
    }

    Entry = Entry->ForwardLink;
  }

  return Copied;
}

/**
  Trim Len bytes of data from the buffer queue and free any net buffer
  that is completely trimmed.

  The trimming operation is the same as NetbufTrim but applies to the net buffer
  queue instead of the net buffer.

  @param[in, out]  NbufQue               Pointer to the net buffer queue.
  @param[in]       Len                   Length of the data to trim.

  @return   The actual length of the data trimmed.

**/
UINT32
EFIAPI
NetbufQueTrim (
  IN OUT NET_BUF_QUEUE  *NbufQue,
  IN UINT32             Len
  )
{
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;
  NET_BUF     *Nbuf;
  UINT32      Trimmed;

  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  if (Len == 0) {
    return 0;
  }

  if (Len > NbufQue->BufSize) {
    Len = NbufQue->BufSize;
  }

  NbufQue->BufSize -= Len;
  Trimmed           = 0;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &NbufQue->BufList) {
    Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    if (Len >= Nbuf->TotalSize) {
      Trimmed += Nbuf->TotalSize;
      Len     -= Nbuf->TotalSize;

      RemoveEntryList (Entry);
      NetbufFree (Nbuf);

      NbufQue->BufNum--;

      if (Len == 0) {
        break;
      }
    } else {
      Trimmed += NetbufTrim (Nbuf, Len, NET_BUF_HEAD);
      break;
    }
  }

  return Trimmed;
}

/**
  Flush the net buffer queue.

  @param[in, out]  NbufQue               Pointer to the queue to be flushed.

**/
VOID
EFIAPI
NetbufQueFlush (
  IN OUT NET_BUF_QUEUE  *NbufQue
  )
{
  NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);

  NetbufFreeList (&NbufQue->BufList);

  NbufQue->BufNum  = 0;
  NbufQue->BufSize = 0;
}

/**
  Compute the checksum for a bulk of data.

  @param[in]   Bulk                  Pointer to the data.
  @param[in]   Len                   Length of the data, in bytes.

  @return    The computed checksum.

**/
UINT16
EFIAPI
NetblockChecksum (
  IN UINT8   *Bulk,
  IN UINT32  Len
  )
{
  register UINT32  Sum;

  Sum = 0;

  //
  // Add left-over byte, if any
  //
  if (Len % 2 != 0) {
    Sum += *(Bulk + Len - 1);
  }

  while (Len > 1) {
    Sum  += *(UINT16 *)Bulk;
    Bulk += 2;
    Len  -= 2;
  }

  //
  // Fold 32-bit sum to 16 bits
  //
  while ((Sum >> 16) != 0) {
    Sum = (Sum & 0xffff) + (Sum >> 16);
  }

  return (UINT16)Sum;
}

/**
  Add two checksums.

  @param[in]   Checksum1             The first checksum to be added.
  @param[in]   Checksum2             The second checksum to be added.

  @return         The new checksum.

**/
UINT16
EFIAPI
NetAddChecksum (
  IN UINT16  Checksum1,
  IN UINT16  Checksum2
  )
{
  UINT32  Sum;

  Sum = Checksum1 + Checksum2;

  //
  // two UINT16 can only add up to a carry of 1.
  //
  if ((Sum >> 16) != 0) {
    Sum = (Sum & 0xffff) + 1;
  }

  return (UINT16)Sum;
}

/**
  Compute the checksum for a NET_BUF.

  @param[in]   Nbuf                  Pointer to the net buffer.

  @return    The computed checksum.

**/
UINT16
EFIAPI
NetbufChecksum (
  IN NET_BUF  *Nbuf
  )
{
  NET_BLOCK_OP  *BlockOp;
  UINT32        Offset;
  UINT16        TotalSum;
  UINT16        BlockSum;
  UINT32        Index;

  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);

  TotalSum = 0;
  Offset   = 0;
  BlockOp  = Nbuf->BlockOp;

  for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
    if (BlockOp[Index].Size == 0) {
      continue;
    }

    BlockSum = NetblockChecksum (BlockOp[Index].Head, BlockOp[Index].Size);

    if ((Offset & 0x01) != 0) {
      //
      // The checksum starts with an odd byte, swap
      // the checksum before added to total checksum
      //
      BlockSum = SwapBytes16 (BlockSum);
    }

    TotalSum = NetAddChecksum (BlockSum, TotalSum);
    Offset  += BlockOp[Index].Size;
  }

  return TotalSum;
}

/**
  Compute the checksum for TCP/UDP pseudo header.

  Src and Dst are in network byte order, and Len is in host byte order.

  @param[in]   Src                   The source address of the packet.
  @param[in]   Dst                   The destination address of the packet.
  @param[in]   Proto                 The protocol type of the packet.
  @param[in]   Len                   The length of the packet.

  @return   The computed checksum.

**/
UINT16
EFIAPI
NetPseudoHeadChecksum (
  IN IP4_ADDR  Src,
  IN IP4_ADDR  Dst,
  IN UINT8     Proto,
  IN UINT16    Len
  )
{
  NET_PSEUDO_HDR  Hdr;

  //
  // Zero the memory to relieve align problems
  //
  ZeroMem (&Hdr, sizeof (Hdr));

  Hdr.SrcIp    = Src;
  Hdr.DstIp    = Dst;
  Hdr.Protocol = Proto;
  Hdr.Len      = HTONS (Len);

  return NetblockChecksum ((UINT8 *)&Hdr, sizeof (Hdr));
}

/**
  Compute the checksum for TCP6/UDP6 pseudo header.

  Src and Dst are in network byte order, and Len is in host byte order.

  @param[in]   Src                   The source address of the packet.
  @param[in]   Dst                   The destination address of the packet.
  @param[in]   NextHeader            The protocol type of the packet.
  @param[in]   Len                   The length of the packet.

  @return   The computed checksum.

**/
UINT16
EFIAPI
NetIp6PseudoHeadChecksum (
  IN EFI_IPv6_ADDRESS  *Src,
  IN EFI_IPv6_ADDRESS  *Dst,
  IN UINT8             NextHeader,
  IN UINT32            Len
  )
{
  NET_IP6_PSEUDO_HDR  Hdr;

  //
  // Zero the memory to relieve align problems
  //
  ZeroMem (&Hdr, sizeof (Hdr));

  IP6_COPY_ADDRESS (&Hdr.SrcIp, Src);
  IP6_COPY_ADDRESS (&Hdr.DstIp, Dst);

  Hdr.NextHeader = NextHeader;
  Hdr.Len        = HTONL (Len);

  return NetblockChecksum ((UINT8 *)&Hdr, sizeof (Hdr));
}

/**
  The function frees the net buffer which allocated by the IP protocol. It releases
  only the net buffer and doesn't call the external free function.

  This function should be called after finishing the process of mIpSec->ProcessExt()
  for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new
  buffer for the ESP, so there needs a function to free the old net buffer.

  @param[in]  Nbuf       The network buffer to be freed.

**/
VOID
NetIpSecNetbufFree (
  NET_BUF  *Nbuf
  )
{
  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
  ASSERT (Nbuf->RefCnt > 0);

  Nbuf->RefCnt--;

  if (Nbuf->RefCnt == 0) {
    //
    // Update Vector only when NBuf is to be released. That is,
    // all the sharing of Nbuf increse Vector's RefCnt by one
    //
    NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
    ASSERT (Nbuf->Vector->RefCnt > 0);

    Nbuf->Vector->RefCnt--;

    if (Nbuf->Vector->RefCnt > 0) {
      return;
    }

    //
    // If NET_VECTOR_OWN_FIRST is set, release the first block since it is
    // allocated by us
    //
    if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
      FreePool (Nbuf->Vector->Block[0].Bulk);
    }

    FreePool (Nbuf->Vector);
    FreePool (Nbuf);
  }
}
