/** @file
  IP6 internal functions to process the incoming packets.

  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Ip6Impl.h"

/**
  Create an empty assemble entry for the packet identified by
  (Dst, Src, Id). The default life for the packet is 60 seconds.

  @param[in]  Dst                    The destination address.
  @param[in]  Src                    The source address.
  @param[in]  Id                     The ID field in the IP header.

  @return NULL if failed to allocate memory for the entry. Otherwise,
          the pointer to the just created reassemble entry.

**/
IP6_ASSEMBLE_ENTRY *
Ip6CreateAssembleEntry (
  IN EFI_IPv6_ADDRESS       *Dst,
  IN EFI_IPv6_ADDRESS       *Src,
  IN UINT32                 Id
  )
{
  IP6_ASSEMBLE_ENTRY        *Assemble;

  Assemble = AllocatePool (sizeof (IP6_ASSEMBLE_ENTRY));
  if (Assemble == NULL) {
    return NULL;
  }

  IP6_COPY_ADDRESS (&Assemble->Dst, Dst);
  IP6_COPY_ADDRESS (&Assemble->Src, Src);
  InitializeListHead (&Assemble->Fragments);

  Assemble->Id       = Id;
  Assemble->Life     = IP6_FRAGMENT_LIFE + 1;

  Assemble->TotalLen = 0;
  Assemble->CurLen   = 0;
  Assemble->Head     = NULL;
  Assemble->Info     = NULL;
  Assemble->Packet   = NULL;

  return Assemble;
}

/**
  Release all the fragments of a packet, then free the assemble entry.

  @param[in]  Assemble               The assemble entry to free.

**/
VOID
Ip6FreeAssembleEntry (
  IN IP6_ASSEMBLE_ENTRY     *Assemble
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  NET_BUF                   *Fragment;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Assemble->Fragments) {
    Fragment = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    RemoveEntryList (Entry);
    NetbufFree (Fragment);
  }

  if (Assemble->Packet != NULL) {
    NetbufFree (Assemble->Packet);
  }

  FreePool (Assemble);
}

/**
  Release all the fragments of the packet. This is the callback for
  the assembled packet's OnFree. It will free the assemble entry,
  which in turn frees all the fragments of the packet.

  @param[in]  Arg                    The assemble entry to free.

**/
VOID
EFIAPI
Ip6OnFreeFragments (
  IN VOID                   *Arg
  )
{
  Ip6FreeAssembleEntry ((IP6_ASSEMBLE_ENTRY *) Arg);
}

/**
  Trim the packet to fit in [Start, End), and update per the
  packet information.

  @param[in, out]  Packet   Packet to trim.
  @param[in]       Start    The sequence of the first byte to fit in.
  @param[in]       End      One beyond the sequence of last byte to fit in.

**/
VOID
Ip6TrimPacket (
  IN OUT NET_BUF            *Packet,
  IN INTN                   Start,
  IN INTN                   End
  )
{
  IP6_CLIP_INFO             *Info;
  INTN                      Len;

  Info = IP6_GET_CLIP_INFO (Packet);

  ASSERT (Info->Start + Info->Length == Info->End);
  ASSERT ((Info->Start < End) && (Start < Info->End));

   if (Info->Start < Start) {
    Len = Start - Info->Start;

    NetbufTrim (Packet, (UINT32) Len, NET_BUF_HEAD);
    Info->Start   = (UINT32) Start;
    Info->Length -= (UINT32) Len;
  }

  if (End < Info->End) {
    Len = End - Info->End;

    NetbufTrim (Packet, (UINT32) Len, NET_BUF_TAIL);
    Info->End     = (UINT32) End;
    Info->Length -= (UINT32) Len;
  }
}

/**
  Reassemble the IP fragments. If all the fragments of the packet
  have been received, it will wrap the packet in a net buffer then
  return it to caller. If the packet can't be assembled, NULL is
  returned.

  @param[in, out] Table  The assemble table used. A new assemble entry will be created
                         if the Packet is from a new chain of fragments.
  @param[in]      Packet The fragment to assemble. It might be freed if the fragment
                         can't be re-assembled.

  @return NULL if the packet can't be reassembled. The pointer to the just assembled
          packet if all the fragments of the packet have arrived.

**/
NET_BUF *
Ip6Reassemble (
  IN OUT IP6_ASSEMBLE_TABLE *Table,
  IN NET_BUF                *Packet
  )
{
  EFI_IP6_HEADER            *Head;
  IP6_CLIP_INFO             *This;
  IP6_CLIP_INFO             *Node;
  IP6_ASSEMBLE_ENTRY        *Assemble;
  IP6_ASSEMBLE_ENTRY        *Entry;
  LIST_ENTRY                *ListHead;
  LIST_ENTRY                *Prev;
  LIST_ENTRY                *Cur;
  NET_BUF                   *Fragment;
  NET_BUF                   *TmpPacket;
  NET_BUF                   *NewPacket;
  NET_BUF                   *Duplicate;
  UINT8                     *DupHead;
  INTN                      Index;
  UINT16                    UnFragmentLen;
  UINT8                     *NextHeader;

  Head = Packet->Ip.Ip6;
  This = IP6_GET_CLIP_INFO (Packet);

  ASSERT (Head != NULL);

  //
  // Find the corresponding assemble entry by (Dst, Src, Id)
  //
  Assemble  = NULL;
  Index     = IP6_ASSEMBLE_HASH (&Head->DestinationAddress, &Head->SourceAddress, This->Id);

  NET_LIST_FOR_EACH (Cur, &Table->Bucket[Index]) {
    Entry = NET_LIST_USER_STRUCT (Cur, IP6_ASSEMBLE_ENTRY, Link);

    if (Entry->Id == This->Id &&
        EFI_IP6_EQUAL (&Entry->Src, &Head->SourceAddress) &&
        EFI_IP6_EQUAL (&Entry->Dst, &Head->DestinationAddress)
          ) {
      Assemble = Entry;
      break;
    }
  }

  //
  // Create a new entry if can not find an existing one, insert it to assemble table
  //
  if (Assemble == NULL) {
    Assemble = Ip6CreateAssembleEntry (
                 &Head->DestinationAddress,
                 &Head->SourceAddress,
                 This->Id
                 );

    if (Assemble == NULL) {
      goto Error;
    }

    InsertHeadList (&Table->Bucket[Index], &Assemble->Link);
  }

  //
  // Find the point to insert the packet: before the first
  // fragment with THIS.Start < CUR.Start. the previous one
  // has PREV.Start <= THIS.Start < CUR.Start.
  //
  ListHead = &Assemble->Fragments;

  NET_LIST_FOR_EACH (Cur, ListHead) {
    Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);

    if (This->Start < IP6_GET_CLIP_INFO (Fragment)->Start) {
      break;
    }
  }

  //
  // Check whether the current fragment overlaps with the previous one.
  // It holds that: PREV.Start <= THIS.Start < THIS.End. Only need to
  // check whether THIS.Start < PREV.End for overlap. If two fragments
  // overlaps, trim the overlapped part off THIS fragment.
  //
  if ((Prev = Cur->BackLink) != ListHead) {
    Fragment  = NET_LIST_USER_STRUCT (Prev, NET_BUF, List);
    Node      = IP6_GET_CLIP_INFO (Fragment);

    if (This->Start < Node->End) {
      if (This->End <= Node->End) {
        goto Error;
      }

      //
      // Trim the previous fragment from tail.
      //
      Ip6TrimPacket (Fragment, Node->Start, This->Start);
    }
  }

  //
  // Insert the fragment into the packet. The fragment may be removed
  // from the list by the following checks.
  //
  NetListInsertBefore (Cur, &Packet->List);

  //
  // Check the packets after the insert point. It holds that:
  // THIS.Start <= NODE.Start < NODE.End. The equality holds
  // if PREV and NEXT are continuous. THIS fragment may fill
  // several holes. Remove the completely overlapped fragments
  //
  while (Cur != ListHead) {
    Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);
    Node     = IP6_GET_CLIP_INFO (Fragment);

    //
    // Remove fragments completely overlapped by this fragment
    //
    if (Node->End <= This->End) {
      Cur = Cur->ForwardLink;

      RemoveEntryList (&Fragment->List);
      Assemble->CurLen -= Node->Length;

      NetbufFree (Fragment);
      continue;
    }

    //
    // The conditions are: THIS.Start <= NODE.Start, and THIS.End <
    // NODE.End. Two fragments overlaps if NODE.Start < THIS.End.
    // If two fragments start at the same offset, remove THIS fragment
    // because ((THIS.Start == NODE.Start) && (THIS.End < NODE.End)).
    //
    if (Node->Start < This->End) {
      if (This->Start == Node->Start) {
        RemoveEntryList (&Packet->List);
        goto Error;
      }

      Ip6TrimPacket (Packet, This->Start, Node->Start);
    }

    break;
  }

  //
  // Update the assemble info: increase the current length. If it is
  // the frist fragment, update the packet's IP head and per packet
  // info. If it is the last fragment, update the total length.
  //
  Assemble->CurLen += This->Length;

  if (This->Start == 0) {
    //
    // Once the first fragment is enqueued, it can't be removed
    // from the fragment list. So, Assemble->Head always point
    // to valid memory area.
    //
    if ((Assemble->Head != NULL) || (Assemble->Packet != NULL)) {
      goto Error;
    }

    //
    // Backup the first fragment in case the reasembly of that packet fail.
    //
    Duplicate = NetbufDuplicate (Packet, NULL, sizeof (EFI_IP6_HEADER));
    if (Duplicate == NULL) {
      goto Error;
    }

    //
    // Revert IP head to network order.
    //
    DupHead = NetbufGetByte (Duplicate, 0, NULL);
    ASSERT (DupHead != NULL);
    Duplicate->Ip.Ip6 = Ip6NtohHead ((EFI_IP6_HEADER *) DupHead);
    Assemble->Packet  = Duplicate;

    //
    // Adjust the unfragmentable part in first fragment
    //
    UnFragmentLen = (UINT16) (This->HeadLen - sizeof (EFI_IP6_HEADER));
    if (UnFragmentLen == 0) {
      //
      // There is not any unfragmentable extension header.
      //
      ASSERT (Head->NextHeader == IP6_FRAGMENT);
      Head->NextHeader = This->NextHeader;
    } else {
      NextHeader = NetbufGetByte (
                     Packet,
                     This->FormerNextHeader + sizeof (EFI_IP6_HEADER),
                     0
                     );
      if (NextHeader == NULL) {
        goto Error;
      }

      *NextHeader = This->NextHeader;
    }

    Assemble->Head = Head;
    Assemble->Info = IP6_GET_CLIP_INFO (Packet);
  }

  //
  // Don't update the length more than once.
  //
  if ((This->LastFrag != 0) && (Assemble->TotalLen == 0)) {
    Assemble->TotalLen = This->End;
  }

  //
  // Deliver the whole packet if all the fragments received.
  // All fragments received if:
  //  1. received the last one, so, the totoal length is know
  //  2. received all the data. If the last fragment on the
  //     queue ends at the total length, all data is received.
  //
  if ((Assemble->TotalLen != 0) && (Assemble->CurLen >= Assemble->TotalLen)) {

    RemoveEntryList (&Assemble->Link);

    //
    // If the packet is properly formated, the last fragment's End
    // equals to the packet's total length. Otherwise, the packet
    // is a fake, drop it now.
    //
    Fragment = NET_LIST_USER_STRUCT (ListHead->BackLink, NET_BUF, List);
    if (IP6_GET_CLIP_INFO (Fragment)->End != (INTN) Assemble->TotalLen) {
      Ip6FreeAssembleEntry (Assemble);
      goto Error;
    }

    Fragment = NET_LIST_HEAD (ListHead, NET_BUF, List);
    This     = Assemble->Info;

    //
    // This TmpPacket is used to hold the unfragmentable part, i.e.,
    // the IPv6 header and the unfragmentable extension headers. Be noted that
    // the Fragment Header is exluded.
    //
    TmpPacket = NetbufGetFragment (Fragment, 0, This->HeadLen, 0);
    ASSERT (TmpPacket != NULL);

    NET_LIST_FOR_EACH (Cur, ListHead) {
      //
      // Trim off the unfragment part plus the fragment header from all fragments.
      //
      Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);
      NetbufTrim (Fragment, This->HeadLen + sizeof (IP6_FRAGMENT_HEADER), TRUE);
    }

    InsertHeadList (ListHead, &TmpPacket->List);

    //
    // Wrap the packet in a net buffer then deliver it up
    //
    NewPacket = NetbufFromBufList (
                  &Assemble->Fragments,
                  0,
                  0,
                  Ip6OnFreeFragments,
                  Assemble
                  );

    if (NewPacket == NULL) {
      Ip6FreeAssembleEntry (Assemble);
      goto Error;
    }

    NewPacket->Ip.Ip6 = Assemble->Head;

    CopyMem (IP6_GET_CLIP_INFO (NewPacket), Assemble->Info, sizeof (IP6_CLIP_INFO));

    return NewPacket;
  }

  return NULL;

Error:
  NetbufFree (Packet);
  return NULL;
}


/**
  The callback function for the net buffer that wraps the packet processed by
  IPsec. It releases the wrap packet and also signals IPsec to free the resources.

  @param[in]  Arg       The wrap context.

**/
VOID
EFIAPI
Ip6IpSecFree (
  IN VOID                   *Arg
  )
{
  IP6_IPSEC_WRAP            *Wrap;

  Wrap = (IP6_IPSEC_WRAP *) Arg;

  if (Wrap->IpSecRecycleSignal != NULL) {
    gBS->SignalEvent (Wrap->IpSecRecycleSignal);
  }

  NetbufFree (Wrap->Packet);

  FreePool (Wrap);

  return;
}

/**
  The work function to locate the IPsec protocol to process the inbound or
  outbound IP packets. The process routine handles the packet with the following
  actions: bypass the packet, discard the packet, or protect the packet.

  @param[in]       IpSb          The IP6 service instance.
  @param[in, out]  Head          The caller-supplied IP6 header.
  @param[in, out]  LastHead      The next header field of last IP header.
  @param[in, out]  Netbuf        The IP6 packet to be processed by IPsec.
  @param[in, out]  ExtHdrs       The caller-supplied options.
  @param[in, out]  ExtHdrsLen    The length of the option.
  @param[in]       Direction     The directionality in an SPD entry,
                                 EfiIPsecInBound, or EfiIPsecOutBound.
  @param[in]       Context       The token's wrap.

  @retval EFI_SUCCESS            The IPsec protocol is not available or disabled.
  @retval EFI_SUCCESS            The packet was bypassed, and all buffers remain the same.
  @retval EFI_SUCCESS            The packet was protected.
  @retval EFI_ACCESS_DENIED      The packet was discarded.
  @retval EFI_OUT_OF_RESOURCES   There are not suffcient resources to complete the operation.
  @retval EFI_BUFFER_TOO_SMALL   The number of non-empty blocks is bigger than the
                                 number of input data blocks when building a fragment table.

**/
EFI_STATUS
Ip6IpSecProcessPacket (
  IN     IP6_SERVICE            *IpSb,
  IN OUT EFI_IP6_HEADER         **Head,
  IN OUT UINT8                  *LastHead,
  IN OUT NET_BUF                **Netbuf,
  IN OUT UINT8                  **ExtHdrs,
  IN OUT UINT32                 *ExtHdrsLen,
  IN     EFI_IPSEC_TRAFFIC_DIR  Direction,
  IN     VOID                   *Context
  )
{
  NET_FRAGMENT              *FragmentTable;
  NET_FRAGMENT              *OriginalFragmentTable;
  UINT32                    FragmentCount;
  UINT32                    OriginalFragmentCount;
  EFI_EVENT                 RecycleEvent;
  NET_BUF                   *Packet;
  IP6_TXTOKEN_WRAP          *TxWrap;
  IP6_IPSEC_WRAP            *IpSecWrap;
  EFI_STATUS                Status;
  EFI_IP6_HEADER            *PacketHead;
  UINT8                     *Buf;
  EFI_IP6_HEADER            ZeroHead;

  Status        = EFI_SUCCESS;
  Packet        = *Netbuf;
  RecycleEvent  = NULL;
  IpSecWrap     = NULL;
  FragmentTable = NULL;
  PacketHead    = NULL;
  Buf           = NULL;
  TxWrap        = (IP6_TXTOKEN_WRAP *) Context;
  FragmentCount = Packet->BlockOpNum;
  ZeroMem (&ZeroHead, sizeof (EFI_IP6_HEADER));

  if (mIpSec == NULL) {
    gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &mIpSec);

    //
    // Check whether the ipsec protocol is available.
    //
    if (mIpSec == NULL) {
      goto ON_EXIT;
    }
  }

  //
  // Check whether the ipsec enable variable is set.
  //
  if (mIpSec->DisabledFlag) {
    //
    // If IPsec is disabled, restore the original MTU
    //
    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize;
    goto ON_EXIT;
  } else {
    //
    // If IPsec is enabled, use the MTU which reduce the IPsec header length.
    //
    IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP6_MAX_IPSEC_HEADLEN;
  }


  //
  // Bypass all multicast inbound or outbound traffic.
  //
  if (IP6_IS_MULTICAST (&(*Head)->DestinationAddress) || IP6_IS_MULTICAST (&(*Head)->SourceAddress)) {
    goto ON_EXIT;
  }

  //
  // Rebuild fragment table from netbuf to ease ipsec process.
  //
  FragmentTable = AllocateZeroPool (FragmentCount * sizeof (NET_FRAGMENT));

  if (FragmentTable == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);
  OriginalFragmentTable = FragmentTable;
  OriginalFragmentCount = FragmentCount;

  if (EFI_ERROR(Status)) {
    FreePool (FragmentTable);
    goto ON_EXIT;
  }

  //
  // Convert host byte order to network byte order
  //
  Ip6NtohHead (*Head);

  Status = mIpSec->ProcessExt (
                     mIpSec,
                     IpSb->Controller,
                     IP_VERSION_6,
                     (VOID *) (*Head),
                     LastHead,
                     (VOID **) ExtHdrs,
                     ExtHdrsLen,
                     (EFI_IPSEC_FRAGMENT_DATA  **) (&FragmentTable),
                     &FragmentCount,
                     Direction,
                     &RecycleEvent
                     );
  //
  // Convert back to host byte order
  //
  Ip6NtohHead (*Head);

  if (EFI_ERROR (Status)) {
    FreePool (OriginalFragmentTable);
    goto ON_EXIT;
  }

  if (OriginalFragmentCount == FragmentCount && OriginalFragmentTable == FragmentTable) {
    //
    // For ByPass Packet
    //
    FreePool (FragmentTable);
    goto ON_EXIT;
  } else {
    //
    // Free the FragmentTable which allocated before calling the IPsec.
    //
    FreePool (OriginalFragmentTable);
  }

  if (Direction == EfiIPsecOutBound && TxWrap != NULL) {
    TxWrap->IpSecRecycleSignal = RecycleEvent;
    TxWrap->Packet             = NetbufFromExt (
                                   FragmentTable,
                                   FragmentCount,
                                   IP6_MAX_HEADLEN,
                                   0,
                                   Ip6FreeTxToken,
                                   TxWrap
                                   );
    if (TxWrap->Packet == NULL) {
      TxWrap->Packet = *Netbuf;
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    CopyMem (
      IP6_GET_CLIP_INFO (TxWrap->Packet),
      IP6_GET_CLIP_INFO (Packet),
      sizeof (IP6_CLIP_INFO)
      );
    
    NetIpSecNetbufFree(Packet);
    *Netbuf = TxWrap->Packet;

  } else {

    IpSecWrap = AllocateZeroPool (sizeof (IP6_IPSEC_WRAP));

    if (IpSecWrap == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      gBS->SignalEvent (RecycleEvent);
      goto ON_EXIT;
    }

    IpSecWrap->IpSecRecycleSignal = RecycleEvent;
    IpSecWrap->Packet             = Packet;
    Packet                        = NetbufFromExt (
                                      FragmentTable,
                                      FragmentCount,
                                      IP6_MAX_HEADLEN,
                                      0,
                                      Ip6IpSecFree,
                                      IpSecWrap
                                      );

    if (Packet == NULL) {
      Packet = IpSecWrap->Packet;
      gBS->SignalEvent (RecycleEvent);
      FreePool (IpSecWrap);
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }

    if (Direction == EfiIPsecInBound && 0 != CompareMem (&ZeroHead, *Head, sizeof (EFI_IP6_HEADER))) {

      PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace (
                                        Packet,
                                        sizeof (EFI_IP6_HEADER) + *ExtHdrsLen,
                                        NET_BUF_HEAD
                                        );
      if (PacketHead == NULL) {
        *Netbuf = Packet;
        Status  = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      CopyMem (PacketHead, *Head, sizeof (EFI_IP6_HEADER));
      *Head = PacketHead;
      Packet->Ip.Ip6 = PacketHead;

      if (*ExtHdrs != NULL) {
        Buf = (UINT8 *) (PacketHead + 1);
        CopyMem (Buf, *ExtHdrs, *ExtHdrsLen);
      }

      NetbufTrim (Packet, sizeof (EFI_IP6_HEADER) + *ExtHdrsLen, TRUE);
      CopyMem (
        IP6_GET_CLIP_INFO (Packet),
        IP6_GET_CLIP_INFO (IpSecWrap->Packet),
        sizeof (IP6_CLIP_INFO)
        );
    }
    *Netbuf = Packet;
  }

ON_EXIT:
  return Status;
}

/**
  Pre-process the IPv6 packet. First validates the IPv6 packet, and
  then reassembles packet if it is necessary.

  @param[in]      IpSb          The IP6 service instance.
  @param[in, out] Packet        The received IP6 packet to be processed.
  @param[in]      Flag          The link layer flag for the packet received, such
                                as multicast.
  @param[out]     Payload       The pointer to the payload of the recieved packet. 
                                it starts from the first byte of the extension header.                                 
  @param[out]     LastHead      The pointer of NextHeader of the last extension
                                header processed by IP6.
  @param[out]     ExtHdrsLen    The length of the whole option.
  @param[out]     UnFragmentLen The length of unfragmented length of extension headers.
  @param[out]     Fragmented    Indicate whether the packet is fragmented. 
  @param[out]     Head          The pointer to the EFI_IP6_Header.

  @retval     EFI_SUCCESS              The received packet is well format.
  @retval     EFI_INVALID_PARAMETER    The received packet is malformed.

**/
EFI_STATUS
Ip6PreProcessPacket (
  IN     IP6_SERVICE     *IpSb,
  IN OUT NET_BUF         **Packet,
  IN     UINT32          Flag,
     OUT UINT8           **Payload,
     OUT UINT8           **LastHead,
     OUT UINT32          *ExtHdrsLen,
     OUT UINT32          *UnFragmentLen,
     OUT BOOLEAN         *Fragmented, 
     OUT EFI_IP6_HEADER  **Head
  )
{
  UINT16                    PayloadLen;
  UINT16                    TotalLen;
  UINT32                    FormerHeadOffset;
  UINT32                    HeadLen;
  IP6_FRAGMENT_HEADER       *FragmentHead;
  UINT16                    FragmentOffset;
  IP6_CLIP_INFO             *Info;
  EFI_IPv6_ADDRESS          Loopback;

  HeadLen    = 0;
  PayloadLen = 0;
  //
  // Check whether the input packet is a valid packet
  //
  if ((*Packet)->TotalSize < IP6_MIN_HEADLEN) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get header information of the packet.
  //
  *Head = (EFI_IP6_HEADER *) NetbufGetByte (*Packet, 0, NULL);
  if (*Head == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Multicast addresses must not be used as source addresses in IPv6 packets.
  //
  if (((*Head)->Version != 6) || (IP6_IS_MULTICAST (&(*Head)->SourceAddress))) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // A packet with a destination address of loopback ::1/128 or unspecified must be dropped.
  //
  ZeroMem (&Loopback, sizeof (EFI_IPv6_ADDRESS));
  Loopback.Addr[15] = 0x1;
  if ((CompareMem (&Loopback, &(*Head)->DestinationAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) ||
      (NetIp6IsUnspecifiedAddr (&(*Head)->DestinationAddress))) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Convert the IP header to host byte order.
  //
  (*Packet)->Ip.Ip6 = Ip6NtohHead (*Head);

  //
  // Get the per packet info.
  //
  Info           = IP6_GET_CLIP_INFO (*Packet);
  Info->LinkFlag = Flag;
  Info->CastType = 0;

  if (IpSb->MnpConfigData.EnablePromiscuousReceive) {
    Info->CastType = Ip6Promiscuous;
  }

  if (Ip6IsOneOfSetAddress (IpSb, &(*Head)->DestinationAddress, NULL, NULL)) {
    Info->CastType = Ip6Unicast;
  } else if (IP6_IS_MULTICAST (&(*Head)->DestinationAddress)) {
    if (Ip6FindMldEntry (IpSb, &(*Head)->DestinationAddress) != NULL) {
      Info->CastType = Ip6Multicast;
    }
  }

  //
  // Drop the packet that is not delivered to us.
  //
  if (Info->CastType == 0) {
    return EFI_INVALID_PARAMETER;
  }


  PayloadLen = (*Head)->PayloadLength;

  Info->Start    = 0;
  Info->Length   = PayloadLen;
  Info->End      = Info->Start + Info->Length;
  Info->HeadLen  = (UINT16) sizeof (EFI_IP6_HEADER);
  Info->Status   = EFI_SUCCESS;
  Info->LastFrag = FALSE;

  TotalLen   = (UINT16) (PayloadLen + sizeof (EFI_IP6_HEADER));

  //
  // Mnp may deliver frame trailer sequence up, trim it off.
  //
  if (TotalLen < (*Packet)->TotalSize) {
    NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);
  }

  if (TotalLen != (*Packet)->TotalSize) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check the extension headers, if exist validate them
  //
  if (PayloadLen != 0) {
    *Payload = AllocatePool ((UINTN) PayloadLen);
    if (*Payload == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    NetbufCopy (*Packet, sizeof (EFI_IP6_HEADER), PayloadLen, *Payload);
  }

  if (!Ip6IsExtsValid (
         IpSb,
         *Packet,
         &(*Head)->NextHeader,
         *Payload,
         (UINT32) PayloadLen,
         TRUE,
         &FormerHeadOffset,
         LastHead,
         ExtHdrsLen,
         UnFragmentLen,
         Fragmented
         )) {
    return EFI_INVALID_PARAMETER;
  }

  HeadLen        = sizeof (EFI_IP6_HEADER) + *UnFragmentLen;

  if (*Fragmented) {
    //
    // Get the fragment offset from the Fragment header
    //
    FragmentHead = (IP6_FRAGMENT_HEADER *) NetbufGetByte (*Packet, HeadLen, NULL);
    if (FragmentHead == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    FragmentOffset = NTOHS (FragmentHead->FragmentOffset);

    if ((FragmentOffset & 0x1) == 0) {
      Info->LastFrag = TRUE;
    }

    FragmentOffset &= (~0x1);

    //
    // This is the first fragment of the packet
    //
    if (FragmentOffset == 0) {
      Info->NextHeader = FragmentHead->NextHeader;
    }

    Info->HeadLen          = (UINT16) HeadLen;
    HeadLen                += sizeof (IP6_FRAGMENT_HEADER);
    Info->Start            = FragmentOffset;
    Info->Length           = TotalLen - (UINT16) HeadLen;
    Info->End              = Info->Start + Info->Length;
    Info->Id               = FragmentHead->Identification;
    Info->FormerNextHeader = FormerHeadOffset;

    //
    // Fragments should in the unit of 8 octets long except the last one.
    //
    if ((Info->LastFrag == 0) && (Info->Length % 8 != 0)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Reassemble the packet.
    //
    *Packet = Ip6Reassemble (&IpSb->Assemble, *Packet);
    if (*Packet == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Re-check the assembled packet to get the right values.
    //
    *Head       = (*Packet)->Ip.Ip6;
    PayloadLen  = (*Head)->PayloadLength;
    if (PayloadLen != 0) {
      if (*Payload != NULL) {
        FreePool (*Payload);
      }

      *Payload = AllocatePool ((UINTN) PayloadLen);
      if (*Payload == NULL) {
        return EFI_INVALID_PARAMETER;
      }

      NetbufCopy (*Packet, sizeof (EFI_IP6_HEADER), PayloadLen, *Payload);
    }

    if (!Ip6IsExtsValid (
           IpSb,
           *Packet,
           &(*Head)->NextHeader,
           *Payload,
           (UINT32) PayloadLen,
           TRUE,
           NULL,
           LastHead,
           ExtHdrsLen,
           UnFragmentLen,
           Fragmented
           )) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Trim the head off, after this point, the packet is headless.
  // and Packet->TotalLen == Info->Length.
  //
  NetbufTrim (*Packet, sizeof (EFI_IP6_HEADER) + *ExtHdrsLen, TRUE);
  
  return EFI_SUCCESS;
}

/**
  The IP6 input routine. It is called by the IP6_INTERFACE when an
  IP6 fragment is received from MNP.

  @param[in]  Packet             The IP6 packet received.
  @param[in]  IoStatus           The return status of receive request.
  @param[in]  Flag               The link layer flag for the packet received, such
                                 as multicast.
  @param[in]  Context            The IP6 service instance that owns the MNP.

**/
VOID
Ip6AcceptFrame (
  IN NET_BUF                *Packet,
  IN EFI_STATUS             IoStatus,
  IN UINT32                 Flag,
  IN VOID                   *Context
  )
{
  IP6_SERVICE               *IpSb;
  EFI_IP6_HEADER            *Head;
  UINT8                     *Payload;
  UINT8                     *LastHead;
  UINT32                    UnFragmentLen;
  UINT32                    ExtHdrsLen;
  BOOLEAN                   Fragmented;
  EFI_STATUS                Status;
  EFI_IP6_HEADER            ZeroHead;

  IpSb = (IP6_SERVICE *) Context;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  Payload  = NULL;
  LastHead = NULL;

  //
  // Check input parameters
  //
  if (EFI_ERROR (IoStatus) || (IpSb->State == IP6_SERVICE_DESTROY)) {
    goto Drop;
  }
  
  //
  // Pre-Process the Ipv6 Packet and then reassemble if it is necessary.
  //
  Status = Ip6PreProcessPacket (
             IpSb, 
             &Packet, 
             Flag, 
             &Payload, 
             &LastHead, 
             &ExtHdrsLen, 
             &UnFragmentLen, 
             &Fragmented,
             &Head
             );
  if (EFI_ERROR (Status)) {
    goto Restart;
  }
  //
  // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,
  // and no need consider any other ahead ext headers.
  //
  Status = Ip6IpSecProcessPacket (
             IpSb,
             &Head,
             LastHead, // need get the lasthead value for input
             &Packet,
             &Payload,
             &ExtHdrsLen,
             EfiIPsecInBound,
             NULL
             );

  if (EFI_ERROR (Status)) {
    goto Restart;
  }

  //
  // If the packet is protected by IPsec Tunnel Mode, Check the Inner Ip Packet.
  //
  ZeroMem (&ZeroHead, sizeof (EFI_IP6_HEADER));
  if (0 == CompareMem (Head, &ZeroHead, sizeof (EFI_IP6_HEADER))) {
    Status = Ip6PreProcessPacket (
               IpSb, 
               &Packet, 
               Flag, 
               &Payload, 
               &LastHead, 
               &ExtHdrsLen, 
               &UnFragmentLen, 
               &Fragmented, 
               &Head
               );
    if (EFI_ERROR (Status)) {
      goto Restart;
    }
  }

  //
  // Check the Packet again.
  //
  if (Packet == NULL) {
    goto Restart;
  }
  
  //
  // Packet may have been changed. The ownership of the packet
  // is transfered to the packet process logic.
  //
  Head  = Packet->Ip.Ip6;
  IP6_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;

  switch (*LastHead) {
  case IP6_ICMP:
    Ip6IcmpHandle (IpSb, Head, Packet);
    break;
  default:
    Ip6Demultiplex (IpSb, Head, Packet);
  }

  Packet = NULL;

  //
  // Dispatch the DPCs queued by the NotifyFunction of the rx token's events
  // which are signaled with received data.
  //
  DispatchDpc ();

Restart:
  if (Payload != NULL) {
    FreePool (Payload);
  }

  Ip6ReceiveFrame (Ip6AcceptFrame, IpSb);

Drop:
  if (Packet != NULL) {
    NetbufFree (Packet);
  }

  return ;
}

/**
  Initialize an already allocated assemble table. This is generally
  the assemble table embedded in the IP6 service instance.

  @param[in, out]  Table    The assemble table to initialize.

**/
VOID
Ip6CreateAssembleTable (
  IN OUT IP6_ASSEMBLE_TABLE *Table
  )
{
  UINT32                    Index;

  for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) {
    InitializeListHead (&Table->Bucket[Index]);
  }
}

/**
  Clean up the assemble table by removing all of the fragments
  and assemble entries.

  @param[in, out]  Table    The assemble table to clean up.

**/
VOID
Ip6CleanAssembleTable (
  IN OUT IP6_ASSEMBLE_TABLE *Table
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_ASSEMBLE_ENTRY        *Assemble;
  UINT32                    Index;

  for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &Table->Bucket[Index]) {
      Assemble = NET_LIST_USER_STRUCT (Entry, IP6_ASSEMBLE_ENTRY, Link);

      RemoveEntryList (Entry);
      Ip6FreeAssembleEntry (Assemble);
    }
  }
}


/**
  The signal handle of IP6's recycle event. It is called back
  when the upper layer releases the packet.

  @param[in]  Event         The IP6's recycle event.
  @param[in]  Context       The context of the handle, which is a IP6_RXDATA_WRAP.

**/
VOID
EFIAPI
Ip6OnRecyclePacket (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  IP6_RXDATA_WRAP           *Wrap;

  Wrap = (IP6_RXDATA_WRAP *) Context;

  EfiAcquireLockOrFail (&Wrap->IpInstance->RecycleLock);
  RemoveEntryList (&Wrap->Link);
  EfiReleaseLock (&Wrap->IpInstance->RecycleLock);

  ASSERT (!NET_BUF_SHARED (Wrap->Packet));
  NetbufFree (Wrap->Packet);

  gBS->CloseEvent (Wrap->RxData.RecycleSignal);
  FreePool (Wrap);
}

/**
  Wrap the received packet to a IP6_RXDATA_WRAP, which will be
  delivered to the upper layer. Each IP6 child that accepts the
  packet will get a not-shared copy of the packet which is wrapped
  in the IP6_RXDATA_WRAP. The IP6_RXDATA_WRAP->RxData is passed
  to the upper layer. The upper layer will signal the recycle event in
  it when it is done with the packet.

  @param[in]  IpInstance    The IP6 child to receive the packet.
  @param[in]  Packet        The packet to deliver up.

  @return NULL if it failed to wrap the packet; otherwise, the wrapper.

**/
IP6_RXDATA_WRAP *
Ip6WrapRxData (
  IN IP6_PROTOCOL           *IpInstance,
  IN NET_BUF                *Packet
  )
{
  IP6_RXDATA_WRAP           *Wrap;
  EFI_IP6_RECEIVE_DATA      *RxData;
  EFI_STATUS                Status;

  Wrap = AllocatePool (IP6_RXDATA_WRAP_SIZE (Packet->BlockOpNum));

  if (Wrap == NULL) {
    return NULL;
  }

  InitializeListHead (&Wrap->Link);

  Wrap->IpInstance  = IpInstance;
  Wrap->Packet      = Packet;
  RxData            = &Wrap->RxData;

  ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME));

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip6OnRecyclePacket,
                  Wrap,
                  &RxData->RecycleSignal
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Wrap);
    return NULL;
  }

  ASSERT (Packet->Ip.Ip6 != NULL);

  //
  // The application expects a network byte order header.
  //
  RxData->HeaderLength  = sizeof (EFI_IP6_HEADER);
  RxData->Header        = (EFI_IP6_HEADER *) Ip6NtohHead (Packet->Ip.Ip6);
  RxData->DataLength    = Packet->TotalSize;

  //
  // Build the fragment table to be delivered up.
  //
  RxData->FragmentCount = Packet->BlockOpNum;
  NetbufBuildExt (Packet, (NET_FRAGMENT *) RxData->FragmentTable, &RxData->FragmentCount);

  return Wrap;
}

/**
  Check whether this IP child accepts the packet.

  @param[in]  IpInstance    The IP child to check.
  @param[in]  Head          The IP header of the packet.
  @param[in]  Packet        The data of the packet.

  @retval     TRUE          The child wants to receive the packet.
  @retval     FALSE         The child does not want to receive the packet.

**/
BOOLEAN
Ip6InstanceFrameAcceptable (
  IN IP6_PROTOCOL           *IpInstance,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_ERROR_HEAD       Icmp;
  EFI_IP6_CONFIG_DATA       *Config;
  IP6_CLIP_INFO             *Info;
  UINT8                     *Proto;
  UINT32                    Index;
  UINT8                     *ExtHdrs;
  UINT16                    ErrMsgPayloadLen;
  UINT8                     *ErrMsgPayload;

  Config = &IpInstance->ConfigData;
  Proto  = NULL;

  //
  // Dirty trick for the Tiano UEFI network stack implmentation. If
  // ReceiveTimeout == -1, the receive of the packet for this instance
  // is disabled. The UEFI spec don't have such captibility. We add
  // this to improve the performance because IP will make a copy of
  // the received packet for each accepting instance. Some IP instances
  // used by UDP/TCP only send packets, they don't wants to receive.
  //
  if (Config->ReceiveTimeout == (UINT32)(-1)) {
    return FALSE;
  }

  if (Config->AcceptPromiscuous) {
    return TRUE;
  }

  //
  // Check whether the protocol is acceptable.
  //
  ExtHdrs = NetbufGetByte (Packet, 0, NULL);

  if (!Ip6IsExtsValid (
         IpInstance->Service,
         Packet,
         &Head->NextHeader,
         ExtHdrs,
         (UINT32) Head->PayloadLength,
         TRUE,
         NULL,
         &Proto,
         NULL,
         NULL,
         NULL
         )) {
    return FALSE;
  }

  //
  // The upper layer driver may want to receive the ICMPv6 error packet
  // invoked by its packet, like UDP.
  //
  if ((*Proto == IP6_ICMP) && (!Config->AcceptAnyProtocol) && (*Proto != Config->DefaultProtocol)) {
    NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);

    if (Icmp.Head.Type <= ICMP_V6_ERROR_MAX) {
      if (!Config->AcceptIcmpErrors) {
        return FALSE;
      }

      //
      // Get the protocol of the invoking packet of ICMPv6 error packet.
      //
      ErrMsgPayloadLen = NTOHS (Icmp.IpHead.PayloadLength);
      ErrMsgPayload    = NetbufGetByte (Packet, sizeof (Icmp), NULL);

      if (!Ip6IsExtsValid (
             NULL,
             NULL,
             &Icmp.IpHead.NextHeader,
             ErrMsgPayload,
             ErrMsgPayloadLen,
             TRUE,
             NULL,
             &Proto,
             NULL,
             NULL,
             NULL
             )) {
        return FALSE;
      }
    }
  }

  //
  // Match the protocol
  //
  if (!Config->AcceptAnyProtocol && (*Proto != Config->DefaultProtocol)) {
    return FALSE;
  }

  //
  // Check for broadcast, the caller has computed the packet's
  // cast type for this child's interface.
  //
  Info = IP6_GET_CLIP_INFO (Packet);

  //
  // If it is a multicast packet, check whether we are in the group.
  //
  if (Info->CastType == Ip6Multicast) {
    //
    // Receive the multicast if the instance wants to receive all packets.
    //
    if (NetIp6IsUnspecifiedAddr (&IpInstance->ConfigData.StationAddress)) {
      return TRUE;
    }

    for (Index = 0; Index < IpInstance->GroupCount; Index++) {
      if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, &Head->DestinationAddress)) {
        break;
      }
    }

    return (BOOLEAN)(Index < IpInstance->GroupCount);
  }

  return TRUE;
}

/**
  Enqueue a shared copy of the packet to the IP6 child if the
  packet is acceptable to it. Here the data of the packet is
  shared, but the net buffer isn't.

  @param  IpInstance             The IP6 child to enqueue the packet to.
  @param  Head                   The IP header of the received packet.
  @param  Packet                 The data of the received packet.

  @retval EFI_NOT_STARTED        The IP child hasn't been configured.
  @retval EFI_INVALID_PARAMETER  The child doesn't want to receive the packet.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate some resources
  @retval EFI_SUCCESS            A shared copy the packet is enqueued to the child.

**/
EFI_STATUS
Ip6InstanceEnquePacket (
  IN IP6_PROTOCOL           *IpInstance,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_CLIP_INFO             *Info;
  NET_BUF                   *Clone;

  //
  // Check whether the packet is acceptable to this instance.
  //
  if (IpInstance->State != IP6_STATE_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (!Ip6InstanceFrameAcceptable (IpInstance, Head, Packet)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Enque a shared copy of the packet.
  //
  Clone = NetbufClone (Packet);

  if (Clone == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Set the receive time out for the assembled packet. If it expires,
  // packet will be removed from the queue.
  //
  Info        = IP6_GET_CLIP_INFO (Clone);
  Info->Life  = IP6_US_TO_SEC (IpInstance->ConfigData.ReceiveTimeout);

  InsertTailList (&IpInstance->Received, &Clone->List);
  return EFI_SUCCESS;
}

/**
  Deliver the received packets to the upper layer if there are both received
  requests and enqueued packets. If the enqueued packet is shared, it will
  duplicate it to a non-shared packet, release the shared packet, then
  deliver the non-shared packet up.

  @param[in]  IpInstance         The IP child to deliver the packet up.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources to deliver the
                                 packets.
  @retval EFI_SUCCESS            All the enqueued packets that can be delivered
                                 are delivered up.

**/
EFI_STATUS
Ip6InstanceDeliverPacket (
  IN IP6_PROTOCOL           *IpInstance
  )
{
  EFI_IP6_COMPLETION_TOKEN  *Token;
  IP6_RXDATA_WRAP           *Wrap;
  NET_BUF                   *Packet;
  NET_BUF                   *Dup;
  UINT8                     *Head;

  //
  // Deliver a packet if there are both a packet and a receive token.
  //
  while (!IsListEmpty (&IpInstance->Received) && !NetMapIsEmpty (&IpInstance->RxTokens)) {

    Packet = NET_LIST_HEAD (&IpInstance->Received, NET_BUF, List);

    if (!NET_BUF_SHARED (Packet)) {
      //
      // If this is the only instance that wants the packet, wrap it up.
      //
      Wrap = Ip6WrapRxData (IpInstance, Packet);

      if (Wrap == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      RemoveEntryList (&Packet->List);

    } else {
      //
      // Create a duplicated packet if this packet is shared
      //
      Dup = NetbufDuplicate (Packet, NULL, sizeof (EFI_IP6_HEADER));

      if (Dup == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Copy the IP head over. The packet to deliver up is
      // headless. Trim the head off after copy. The IP head
      // may be not continuous before the data.
      //
      Head        = NetbufAllocSpace (Dup, sizeof (EFI_IP6_HEADER), NET_BUF_HEAD);
      ASSERT (Head != NULL);
      Dup->Ip.Ip6 = (EFI_IP6_HEADER *) Head;

      CopyMem (Head, Packet->Ip.Ip6, sizeof (EFI_IP6_HEADER));
      NetbufTrim (Dup, sizeof (EFI_IP6_HEADER), TRUE);

      Wrap = Ip6WrapRxData (IpInstance, Dup);

      if (Wrap == NULL) {
        NetbufFree (Dup);
        return EFI_OUT_OF_RESOURCES;
      }

      RemoveEntryList (&Packet->List);
      NetbufFree (Packet);

      Packet = Dup;
    }

    //
    // Insert it into the delivered packet, then get a user's
    // receive token, pass the wrapped packet up.
    //
    EfiAcquireLockOrFail (&IpInstance->RecycleLock);
    InsertHeadList (&IpInstance->Delivered, &Wrap->Link);
    EfiReleaseLock (&IpInstance->RecycleLock);

    Token                = NetMapRemoveHead (&IpInstance->RxTokens, NULL);
    Token->Status        = IP6_GET_CLIP_INFO (Packet)->Status;
    Token->Packet.RxData = &Wrap->RxData;

    gBS->SignalEvent (Token->Event);
  }

  return EFI_SUCCESS;
}

/**
  Enqueue a received packet to all the IP children that share
  the same interface.

  @param[in]  IpSb          The IP6 service instance that receive the packet.
  @param[in]  Head          The header of the received packet.
  @param[in]  Packet        The data of the received packet.
  @param[in]  IpIf          The interface to enqueue the packet to.

  @return The number of the IP6 children that accepts the packet.

**/
INTN
Ip6InterfaceEnquePacket (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet,
  IN IP6_INTERFACE          *IpIf
  )
{
  IP6_PROTOCOL              *IpInstance;
  IP6_CLIP_INFO             *Info;
  LIST_ENTRY                *Entry;
  INTN                      Enqueued;
  INTN                      LocalType;
  INTN                      SavedType;

  //
  // First, check that the packet is acceptable to this interface
  // and find the local cast type for the interface.
  //
  LocalType = 0;
  Info      = IP6_GET_CLIP_INFO (Packet);

  if (IpIf->PromiscRecv) {
    LocalType = Ip6Promiscuous;
  } else {
    LocalType = Info->CastType;
  }

  //
  // Iterate through the ip instances on the interface, enqueue
  // the packet if filter passed. Save the original cast type,
  // and pass the local cast type to the IP children on the
  // interface. The global cast type will be restored later.
  //
  SavedType       = Info->CastType;
  Info->CastType  = (UINT32) LocalType;

  Enqueued        = 0;

  NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
    IpInstance = NET_LIST_USER_STRUCT (Entry, IP6_PROTOCOL, AddrLink);
    NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE);

    if (Ip6InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {
      Enqueued++;
    }
  }

  Info->CastType = (UINT32) SavedType;
  return Enqueued;
}

/**
  Deliver the packet for each IP6 child on the interface.

  @param[in]  IpSb          The IP6 service instance that received the packet.
  @param[in]  IpIf          The IP6 interface to deliver the packet.

**/
VOID
Ip6InterfaceDeliverPacket (
  IN IP6_SERVICE            *IpSb,
  IN IP6_INTERFACE          *IpIf
  )
{
  IP6_PROTOCOL              *IpInstance;
  LIST_ENTRY                *Entry;

  NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
    IpInstance = NET_LIST_USER_STRUCT (Entry, IP6_PROTOCOL, AddrLink);
    Ip6InstanceDeliverPacket (IpInstance);
  }
}

/**
  De-multiplex the packet. the packet delivery is processed in two
  passes. The first pass will enqueue a shared copy of the packet
  to each IP6 child that accepts the packet. The second pass will
  deliver a non-shared copy of the packet to each IP6 child that
  has pending receive requests. Data is copied if more than one
  child wants to consume the packet, because each IP child needs
  its own copy of the packet to make changes.

  @param[in]  IpSb          The IP6 service instance that received the packet.
  @param[in]  Head          The header of the received packet.
  @param[in]  Packet        The data of the received packet.

  @retval EFI_NOT_FOUND     No IP child accepts the packet.
  @retval EFI_SUCCESS       The packet is enqueued or delivered to some IP
                            children.

**/
EFI_STATUS
Ip6Demultiplex (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{

  LIST_ENTRY                *Entry;
  IP6_INTERFACE             *IpIf;
  INTN                      Enqueued;

  //
  // Two pass delivery: first, enque a shared copy of the packet
  // to each instance that accept the packet.
  //
  Enqueued = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);

    if (IpIf->Configured) {
      Enqueued += Ip6InterfaceEnquePacket (IpSb, Head, Packet, IpIf);
    }
  }

  //
  // Second: deliver a duplicate of the packet to each instance.
  // Release the local reference first, so that the last instance
  // getting the packet will not copy the data.
  //
  NetbufFree (Packet);
  Packet = NULL;

  if (Enqueued == 0) {
    return EFI_NOT_FOUND;
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);

    if (IpIf->Configured) {
      Ip6InterfaceDeliverPacket (IpSb, IpIf);
    }
  }

  return EFI_SUCCESS;
}

/**
  Decrease the life of the transmitted packets. If it is
  decreased to zero, cancel the packet. This function is
  called by Ip6packetTimerTicking that provides timeout for both the
  received-but-not-delivered and transmitted-but-not-recycle
  packets.

  @param[in]  Map           The IP6 child's transmit map.
  @param[in]  Item          Current transmitted packet.
  @param[in]  Context       Not used.

  @retval EFI_SUCCESS       Always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
Ip6SentPacketTicking (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item,
  IN VOID                   *Context
  )
{
  IP6_TXTOKEN_WRAP          *Wrap;

  Wrap = (IP6_TXTOKEN_WRAP *) Item->Value;
  ASSERT (Wrap != NULL);

  if ((Wrap->Life > 0) && (--Wrap->Life == 0)) {
    Ip6CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED);
  }

  return EFI_SUCCESS;
}

/**
  Timeout the fragments, and the enqueued, and transmitted packets.

  @param[in]  IpSb          The IP6 service instance to timeout.

**/
VOID
Ip6PacketTimerTicking (
  IN IP6_SERVICE            *IpSb
  )
{
  LIST_ENTRY                *InstanceEntry;
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_PROTOCOL              *IpInstance;
  IP6_ASSEMBLE_ENTRY        *Assemble;
  NET_BUF                   *Packet;
  IP6_CLIP_INFO             *Info;
  UINT32                    Index;

  //
  // First, time out the fragments. The packet's life is counting down
  // once the first-arriving fragment of that packet was received.
  //
  for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) {
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &(IpSb->Assemble.Bucket[Index])) {
      Assemble = NET_LIST_USER_STRUCT (Entry, IP6_ASSEMBLE_ENTRY, Link);

      if ((Assemble->Life > 0) && (--Assemble->Life == 0)) {
        //
        // If the first fragment (the one with a Fragment Offset of zero)
        // has been received, an ICMP Time Exceeded - Fragment Reassembly
        // Time Exceeded message should be sent to the source of that fragment.
        //
        if ((Assemble->Packet != NULL) &&
            !IP6_IS_MULTICAST (&Assemble->Head->DestinationAddress)) {
          Ip6SendIcmpError (
            IpSb,
            Assemble->Packet,
            NULL,
            &Assemble->Head->SourceAddress,
            ICMP_V6_TIME_EXCEEDED,
            ICMP_V6_TIMEOUT_REASSEMBLE,
            NULL
            );
        }

        //
        // If reassembly of a packet is not completed within 60 seconds of
        // the reception of the first-arriving fragment of that packet, the
        // reassembly must be abandoned and all the fragments that have been
        // received for that packet must be discarded.
        //
        RemoveEntryList (Entry);
        Ip6FreeAssembleEntry (Assemble);
      }
    }
  }

  NET_LIST_FOR_EACH (InstanceEntry, &IpSb->Children) {
    IpInstance = NET_LIST_USER_STRUCT (InstanceEntry, IP6_PROTOCOL, Link);

    //
    // Second, time out the assembled packets enqueued on each IP child.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpInstance->Received) {
      Packet = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
      Info   = IP6_GET_CLIP_INFO (Packet);

      if ((Info->Life > 0) && (--Info->Life == 0)) {
        RemoveEntryList (Entry);
        NetbufFree (Packet);
      }
    }

    //
    // Third: time out the transmitted packets.
    //
    NetMapIterate (&IpInstance->TxTokens, Ip6SentPacketTicking, NULL);
  }
}

