/** @file
  The internal functions and routines to transmit the IP6 packet.

  Copyright (c) 2009 - 2015, 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"

UINT32 mIp6Id;

/**
  Output all the available source addresses to a list entry head SourceList. The
  number of source addresses are also returned.

  @param[in]       IpSb             Points to an IP6 service binding instance.
  @param[out]      SourceList       The list entry head of all source addresses.
                                    It is the caller's responsibility to free the
                                    resources.
  @param[out]      SourceCount      The number of source addresses.

  @retval EFI_SUCCESS           The source addresses were copied to a list entry head
                                SourceList.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources to complete the operation.

**/
EFI_STATUS
Ip6CandidateSource (
  IN IP6_SERVICE            *IpSb,
  OUT LIST_ENTRY            *SourceList,
  OUT UINT32                *SourceCount
  )
{
  IP6_INTERFACE             *IpIf;
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Entry2;
  IP6_ADDRESS_INFO          *AddrInfo;
  IP6_ADDRESS_INFO          *Copy;

  *SourceCount = 0;

  if (IpSb->LinkLocalOk) {
    Copy = AllocatePool (sizeof (IP6_ADDRESS_INFO));
    if (Copy == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Copy->Signature         = IP6_ADDR_INFO_SIGNATURE;
    IP6_COPY_ADDRESS (&Copy->Address, &IpSb->LinkLocalAddr);
    Copy->IsAnycast         = FALSE;
    Copy->PrefixLength      = IP6_LINK_LOCAL_PREFIX_LENGTH;
    Copy->ValidLifetime     = (UINT32) IP6_INFINIT_LIFETIME;
    Copy->PreferredLifetime = (UINT32) IP6_INFINIT_LIFETIME;

    InsertTailList (SourceList, &Copy->Link);
    (*SourceCount)++;
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);

    NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
      AddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

      if (AddrInfo->IsAnycast) {
        //
        // Never use an anycast address.
        //
        continue;
      }

      Copy = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), AddrInfo);
      if (Copy == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      InsertTailList (SourceList, &Copy->Link);
      (*SourceCount)++;
    }
  }

  return EFI_SUCCESS;
}

/**
  Calculate how many bits are the same between two IPv6 addresses.

  @param[in]       AddressA         Points to an IPv6 address.
  @param[in]       AddressB         Points to another IPv6 address.

  @return The common bits of the AddressA and AddressB.

**/
UINT8
Ip6CommonPrefixLen (
  IN EFI_IPv6_ADDRESS       *AddressA,
  IN EFI_IPv6_ADDRESS       *AddressB
  )
{
  UINT8                     Count;
  UINT8                     Index;
  UINT8                     ByteA;
  UINT8                     ByteB;
  UINT8                     NumBits;

  Count = 0;
  Index = 0;

  while (Index < 16) {
    ByteA = AddressA->Addr[Index];
    ByteB = AddressB->Addr[Index];

    if (ByteA == ByteB) {
      Count += 8;
      Index++;
      continue;
    }

    //
    // Check how many bits are common between the two bytes.
    //
    NumBits = 8;
    ByteA   = (UINT8) (ByteA ^ ByteB);

    while (ByteA != 0) {
      NumBits--;
      ByteA = (UINT8) (ByteA >> 1);
    }

    return (UINT8) (Count + NumBits);
  }

  return Count;
}

/**
  Output all the available source addresses to a list entry head SourceList. The
  number of source addresses are also returned.

  @param[in]       IpSb             Points to a IP6 service binding instance.
  @param[in]       Destination      The IPv6 destination address.
  @param[out]      Source           The selected IPv6 source address according to
                                    the Destination.

  @retval EFI_SUCCESS           The source addresses were copied to a list entry
                                head SourceList.
  @retval EFI_NO_MAPPING        The IPv6 stack is not auto configured.

**/
EFI_STATUS
Ip6SelectSourceAddress (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Destination,
  OUT EFI_IPv6_ADDRESS      *Source
  )
{
  EFI_STATUS                Status;
  LIST_ENTRY                SourceList;
  UINT32                    SourceCount;
  UINT8                     ScopeD;
  LIST_ENTRY                *Entry;
  IP6_ADDRESS_INFO          *AddrInfo;
  IP6_PREFIX_LIST_ENTRY     *Prefix;
  UINT8                     LastCommonLength;
  UINT8                     CurrentCommonLength;
  EFI_IPv6_ADDRESS          *TmpAddress;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  Status = EFI_SUCCESS;
  InitializeListHead (&SourceList);

  if (!IpSb->LinkLocalOk) {
    return EFI_NO_MAPPING;
  }

  //
  // Rule 1: Prefer same address.
  //
  if (Ip6IsOneOfSetAddress (IpSb, Destination, NULL, NULL)) {
    IP6_COPY_ADDRESS (Source, Destination);
    goto Exit;
  }

  //
  // Rule 2: Prefer appropriate scope.
  //
  if (IP6_IS_MULTICAST (Destination)) {
    ScopeD = (UINT8) (Destination->Addr[1] >> 4);
  } else if (NetIp6IsLinkLocalAddr (Destination)) {
    ScopeD = 0x2;
  } else {
    ScopeD = 0xE;
  }

  if (ScopeD <= 0x2) {
    //
    // Return the link-local address if it exists
    // One IP6_SERVICE only has one link-local address.
    //
    IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr);
    goto Exit;
  }

  //
  // All candidate source addresses are global unicast address.
  //
  Ip6CandidateSource (IpSb, &SourceList, &SourceCount);

  if (SourceCount == 0) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr);

  if (SourceCount == 1) {
    goto Exit;
  }

  //
  // Rule 3: Avoid deprecated addresses.
  // TODO: check the "deprecated" state of the stateful configured address
  //
  NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) {
    Prefix = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);
    if (Prefix->PreferredLifetime == 0) {
      Ip6RemoveAddr (NULL, &SourceList, &SourceCount, &Prefix->Prefix, Prefix->PrefixLength);

      if (SourceCount == 1) {
        goto Exit;
      }
    }
  }

  //
  // TODO: Rule 4: Prefer home addresses.
  // TODO: Rule 5: Prefer outgoing interface.
  // TODO: Rule 6: Prefer matching label.
  // TODO: Rule 7: Prefer public addresses.
  //

  //
  // Rule 8: Use longest matching prefix.
  //
  LastCommonLength = Ip6CommonPrefixLen (Source, Destination);
  TmpAddress       = NULL;

  for (Entry = SourceList.ForwardLink; Entry != &SourceList; Entry = Entry->ForwardLink) {
    AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

    CurrentCommonLength = Ip6CommonPrefixLen (&AddrInfo->Address, Destination);
    if (CurrentCommonLength > LastCommonLength) {
      LastCommonLength = CurrentCommonLength;
      TmpAddress       = &AddrInfo->Address;
    }
  }

  if (TmpAddress != NULL) {
    IP6_COPY_ADDRESS (Source, TmpAddress);
  }

Exit:

  Ip6RemoveAddr (NULL, &SourceList, &SourceCount, NULL, 0);

  return Status;
}

/**
  Select an interface to send the packet generated in the IP6 driver
  itself: that is, not by the requests of the IP6 child's consumer. Such
  packets include the ICMPv6 echo replies and other ICMPv6 error packets.

  @param[in]  IpSb                 The IP4 service that wants to send the packets.
  @param[in]  Destination          The destination of the packet.
  @param[in, out]  Source          The source of the packet.

  @return NULL if no proper interface is found, otherwise, the interface that
          can be used to send the system packet from.

**/
IP6_INTERFACE *
Ip6SelectInterface (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Destination,
  IN OUT EFI_IPv6_ADDRESS   *Source
  )
{
  EFI_STATUS                Status;
  EFI_IPv6_ADDRESS          SelectedSource;
  IP6_INTERFACE             *IpIf;
  BOOLEAN                   Exist;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Destination != NULL && Source != NULL);

  if (NetIp6IsUnspecifiedAddr (Destination)) {
    return NULL;
  }

  if (!NetIp6IsUnspecifiedAddr (Source)) {
    Exist = Ip6IsOneOfSetAddress (IpSb, Source, &IpIf, NULL);
    ASSERT (Exist);

    return IpIf;
  }

  //
  // If source is unspecified, select a source according to the destination.
  //
  Status = Ip6SelectSourceAddress (IpSb, Destination, &SelectedSource);
  if (EFI_ERROR (Status)) {
    return IpSb->DefaultInterface;
  }

  Ip6IsOneOfSetAddress (IpSb, &SelectedSource, &IpIf, NULL);
  IP6_COPY_ADDRESS (Source, &SelectedSource);

  return IpIf;
}

/**
  The default callback function for the system generated packet.
  It will free the packet.

  @param[in]  Packet        The packet that transmitted.
  @param[in]  IoStatus      The result of the transmission, succeeded or failed.
  @param[in]  LinkFlag      Not used when transmitted. Check IP6_FRAME_CALLBACK
                            for reference.
  @param[in]  Context       The context provided by us.

**/
VOID
Ip6SysPacketSent (
  NET_BUF                   *Packet,
  EFI_STATUS                IoStatus,
  UINT32                    LinkFlag,
  VOID                      *Context
  )
{
  NetbufFree (Packet);
  Packet = NULL;
}

/**
  Prefix an IP6 basic head and unfragmentable extension headers and a fragment header
  to the Packet. Used for IP6 fragmentation.

  @param[in]  IpSb             The IP6 service instance to transmit the packet.
  @param[in]  Packet           The packet to prefix the IP6 header to.
  @param[in]  Head             The caller supplied header.
  @param[in]  FragmentOffset   The fragment offset of the data following the header.
  @param[in]  ExtHdrs          The length of the original extension header.
  @param[in]  ExtHdrsLen       The length of the extension headers.
  @param[in]  LastHeader       The pointer of next header of last extension header.
  @param[in]  HeadLen          The length of the unfragmented part of the IP6 header.

  @retval EFI_BAD_BUFFER_SIZE  There is no enough room in the head space of
                               Packet.
  @retval EFI_SUCCESS          The operation performed successfully.

**/
EFI_STATUS
Ip6PrependHead (
  IN IP6_SERVICE            *IpSb,
  IN NET_BUF                *Packet,
  IN EFI_IP6_HEADER         *Head,
  IN UINT16                 FragmentOffset,
  IN UINT8                  *ExtHdrs,
  IN UINT32                 ExtHdrsLen,
  IN UINT8                  LastHeader,
  IN UINT32                 HeadLen
  )
{
  UINT32                    Len;
  UINT32                    UnFragExtHdrsLen;
  EFI_IP6_HEADER            *PacketHead;
  UINT8                     *UpdatedExtHdrs;
  EFI_STATUS                Status;
  UINT8                     NextHeader;

  UpdatedExtHdrs = NULL;

  //
  // HeadLen is the length of the fixed part of the sequences of fragments, i.e.
  // the unfragment part.
  //
  PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace (Packet, HeadLen, NET_BUF_HEAD);
  if (PacketHead == NULL) {
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // Set the head up, convert the host byte order to network byte order
  //
  CopyMem (PacketHead, Head, sizeof (EFI_IP6_HEADER));
  PacketHead->PayloadLength = HTONS ((UINT16) (Packet->TotalSize - sizeof (EFI_IP6_HEADER)));
  Packet->Ip.Ip6            = PacketHead;

  Len              = HeadLen - sizeof (EFI_IP6_HEADER);
  UnFragExtHdrsLen = Len - sizeof (IP6_FRAGMENT_HEADER);

  if (UnFragExtHdrsLen == 0) {
    PacketHead->NextHeader = IP6_FRAGMENT;
  }

  //
  // Append the extension headers: firstly copy the unfragmentable headers, then append
  // fragmentation header.
  //
  if ((FragmentOffset & IP6_FRAGMENT_OFFSET_MASK) == 0) {
    NextHeader = Head->NextHeader;
  } else {
    NextHeader = PacketHead->NextHeader;
  }

  Status = Ip6FillFragmentHeader (
             IpSb,
             NextHeader,
             LastHeader,
             ExtHdrs,
             ExtHdrsLen,
             FragmentOffset,
             &UpdatedExtHdrs
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  CopyMem (
    (UINT8 *) (PacketHead + 1),
    UpdatedExtHdrs,
    UnFragExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER)
    );

  FreePool (UpdatedExtHdrs);
  return EFI_SUCCESS;
}

/**
  Transmit an IP6 packet. The packet comes either from the IP6
  child's consumer (IpInstance != NULL) or the IP6 driver itself
  (IpInstance == NULL). It will route the packet, fragment it,
  then transmit all the fragments through an interface.

  @param[in]  IpSb             The IP6 service instance to transmit the packet.
  @param[in]  Interface        The IP6 interface to transmit the packet. Ignored
                               if NULL.
  @param[in]  IpInstance       The IP6 child that issues the transmission.  It is
                               NULL if the packet is from the system.
  @param[in]  Packet           The user data to send, excluding the IP header.
  @param[in]  Head             The caller supplied header. The caller should set
                               the  following header fields: NextHeader, HopLimit,
                               Src, Dest, FlowLabel, PayloadLength. This function
                               will fill in the Ver, TrafficClass.
  @param[in]  ExtHdrs          The extension headers to append to the IPv6 basic
                               header.
  @param[in]  ExtHdrsLen       The length of the extension headers.
  @param[in]  Callback         The callback function to issue when transmission
                               completed.
  @param[in]  Context          The opaque context for the callback.

  @retval EFI_INVALID_PARAMETER Any input parameter or the packet is invalid.
  @retval EFI_NO_MAPPING        There is no interface to the destination.
  @retval EFI_NOT_FOUND         There is no route to the destination.
  @retval EFI_SUCCESS           The packet successfully transmitted.
  @retval EFI_OUT_OF_RESOURCES  Failed to finish the operation due to lack of
                                resources.
  @retval Others                Failed to transmit the packet.

**/
EFI_STATUS
Ip6Output (
  IN IP6_SERVICE            *IpSb,
  IN IP6_INTERFACE          *Interface   OPTIONAL,
  IN IP6_PROTOCOL           *IpInstance  OPTIONAL,
  IN NET_BUF                *Packet,
  IN EFI_IP6_HEADER         *Head,
  IN UINT8                  *ExtHdrs,
  IN UINT32                 ExtHdrsLen,
  IN IP6_FRAME_CALLBACK     Callback,
  IN VOID                   *Context
  )
{
  IP6_INTERFACE             *IpIf;
  EFI_IPv6_ADDRESS          NextHop;
  IP6_NEIGHBOR_ENTRY        *NeighborCache;
  IP6_ROUTE_CACHE_ENTRY     *RouteCache;
  EFI_STATUS                Status;
  UINT32                    Mtu;
  UINT32                    HeadLen;
  UINT16                    FragmentOffset;
  UINT8                     *LastHeader;
  UINT32                    UnFragmentLen;
  UINT32                    UnFragmentHdrsLen;
  UINT32                    FragmentHdrsLen;
  UINT16                    *Checksum;
  UINT16                    PacketChecksum;
  UINT16                    PseudoChecksum;
  UINT32                    Index;
  UINT32                    PacketLen;
  UINT32                    RealExtLen;
  UINT32                    Offset;
  NET_BUF                   *TmpPacket;
  NET_BUF                   *Fragment;
  UINT32                    Num;
  UINT8                     *Buf;
  EFI_IP6_HEADER            *PacketHead;
  IP6_ICMP_HEAD             *IcmpHead;
  IP6_TXTOKEN_WRAP          *Wrap;
  IP6_ROUTE_ENTRY           *RouteEntry;
  UINT8                     *UpdatedExtHdrs;
  UINT8                     NextHeader;
  UINT8                     LastHeaderBackup;
  BOOLEAN                   FragmentHeadInserted;
  UINT8                     *ExtHdrsBackup;
  UINT8                     NextHeaderBackup;
  EFI_IPv6_ADDRESS          Source;
  EFI_IPv6_ADDRESS          Destination;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  //
  // RFC2460: Each extension header is an integer multiple of 8 octets long,
  // in order to retain 8-octet alignment for subsequent headers.
  //
  if ((ExtHdrsLen & 0x7) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  LastHeader = NULL;

  Ip6IsExtsValid (
    NULL,
    NULL,
    &Head->NextHeader,
    ExtHdrs,
    ExtHdrsLen,
    FALSE,
    NULL,
    &LastHeader,
    NULL,
    NULL,
    NULL
    );

  //
  // Select an interface/source for system packet, application
  // should select them itself.
  //
  IpIf = Interface;
  if (IpIf == NULL) {
    //
    // IpInstance->Interface is NULL when IpInstance is configured with both stationaddress
    // and destinationaddress is unspecified.
    //
    if (IpInstance == NULL || IpInstance->Interface == NULL) {
      IpIf = Ip6SelectInterface (IpSb, &Head->DestinationAddress, &Head->SourceAddress);
      if (IpInstance != NULL) {
        IpInstance->Interface = IpIf;
      }
    } else {
      IpIf = IpInstance->Interface;
    }
  }

  if (IpIf == NULL) {
    return EFI_NO_MAPPING;
  }

  //
  // Update the common field in Head here.
  //
  Head->Version       = 6;
  Head->TrafficClassL = 0;
  Head->TrafficClassH = 0;

  Checksum            = NULL;
  NextHeader          = *LastHeader;

  switch (NextHeader) {
  case EFI_IP_PROTO_UDP:
    Packet->Udp = (EFI_UDP_HEADER *) NetbufGetByte (Packet, 0, NULL);
    ASSERT (Packet->Udp != NULL);
    if (Packet->Udp->Checksum == 0) {
      Checksum = &Packet->Udp->Checksum;
    }
    break;

  case EFI_IP_PROTO_TCP:
    Packet->Tcp = (TCP_HEAD *) NetbufGetByte (Packet, 0, NULL);
    ASSERT (Packet->Tcp != NULL);
    if (Packet->Tcp->Checksum == 0) {
      Checksum = &Packet->Tcp->Checksum;
    }
    break;

  case IP6_ICMP:
    //
    // Don't send ICMP packet to an IPv6 anycast address.
    //
    if (Ip6IsAnycast (IpSb, &Head->DestinationAddress)) {
      return EFI_INVALID_PARAMETER;
    }

    IcmpHead = (IP6_ICMP_HEAD *) NetbufGetByte (Packet, 0, NULL);
    ASSERT (IcmpHead != NULL);
    if (IcmpHead->Checksum == 0) {
      Checksum = &IcmpHead->Checksum;
    }
    break;

  default:
    break;
  }

  if (Checksum != NULL) {
    //
    // Calculate the checksum for upper layer protocol if it is not calculated due to lack of
    // IPv6 source address.
    //
    PacketChecksum = NetbufChecksum (Packet);
    PseudoChecksum = NetIp6PseudoHeadChecksum (
                      &Head->SourceAddress,
                      &Head->DestinationAddress,
                      NextHeader,
                      Packet->TotalSize
                      );
    *Checksum = (UINT16) ~NetAddChecksum (PacketChecksum, PseudoChecksum);
  }

  Status = Ip6IpSecProcessPacket (
             IpSb,
             &Head,
             LastHeader, // no need get the lasthead value for output
             &Packet,
             &ExtHdrs,
             &ExtHdrsLen,
             EfiIPsecOutBound,
             Context
             );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  LastHeader = NULL;
  //
  // Check incoming parameters.
  //
  if (!Ip6IsExtsValid (
         IpSb,
         Packet,
         &Head->NextHeader,
         ExtHdrs,
         ExtHdrsLen,
         FALSE,
         NULL,
         &LastHeader,
         &RealExtLen,
         &UnFragmentHdrsLen,
         NULL
         )) {
    return EFI_INVALID_PARAMETER;
  }

  if ((RealExtLen & 0x7) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  LastHeaderBackup = *LastHeader;

  //
  // Perform next hop determination:
  // For multicast packets, the next-hop is always the destination address and
  // is considered to be on-link.
  //
  if (IP6_IS_MULTICAST (&Head->DestinationAddress)) {
    IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress);
  } else {
    //
    // For unicast packets, use a combination of the Destination Cache, the Prefix List
    // and the Default Router List to determine the IP address of the appropriate next hop.
    //

    NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->DestinationAddress);
    if (NeighborCache != NULL) {
      //
      // Hit Neighbor Cache.
      //
      IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress);
    } else {
      //
      // Not in Neighbor Cache, check Router cache
      //
      RouteCache = Ip6Route (IpSb, &Head->DestinationAddress, &Head->SourceAddress);
      if (RouteCache == NULL) {
        return EFI_NOT_FOUND;
      }

      IP6_COPY_ADDRESS (&NextHop, &RouteCache->NextHop);
      Ip6FreeRouteCacheEntry (RouteCache);
    }
  }

  //
  // Examines the Neighbor Cache for link-layer information about that neighbor.
  // DO NOT create neighbor cache if neighbor is itself - when reporting ICMP error.
  //
  if (!IP6_IS_MULTICAST (&NextHop) && !EFI_IP6_EQUAL (&Head->DestinationAddress, &Head->SourceAddress)) {
    NeighborCache = Ip6FindNeighborEntry (IpSb, &NextHop);
    if (NeighborCache == NULL) {
      NeighborCache = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, &NextHop, NULL);

      if (NeighborCache == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Send out multicast neighbor solicitation for address resolution immediately.
      //
      Ip6CreateSNMulticastAddr (&NeighborCache->Neighbor, &Destination);
      Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = Ip6SendNeighborSolicit (
                 IpSb,
                 &Source,
                 &Destination,
                 &NeighborCache->Neighbor,
                 &IpSb->SnpMode.CurrentAddress
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      --NeighborCache->Transmit;
      NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer) + 1;
    }

    NeighborCache->Interface = IpIf;
  }

  UpdatedExtHdrs       = NULL;
  ExtHdrsBackup        = NULL;
  NextHeaderBackup     = 0;
  FragmentHeadInserted = FALSE;

  //
  // Check whether we received Packet Too Big message for the packet sent to the
  // Destination. If yes include a Fragment Header in the subsequent packets.
  //
  RouteEntry = Ip6FindRouteEntry (
                 IpSb->RouteTable,
                 &Head->DestinationAddress,
                 NULL
                 );
  if (RouteEntry != NULL) {
    if ((RouteEntry->Flag & IP6_PACKET_TOO_BIG) == IP6_PACKET_TOO_BIG) {

      //
      // FragmentHead is inserted after Hop-by-Hop Options header, Destination
      // Options header (first occur), Routing header, and before Fragment header,
      // Authentication header, Encapsulating Security Payload header, and
      // Destination Options header (last occur), and upper-layer header.
      //
      Status = Ip6FillFragmentHeader (
                 IpSb,
                 Head->NextHeader,
                 LastHeaderBackup,
                 ExtHdrs,
                 ExtHdrsLen,
                 0,
                 &UpdatedExtHdrs
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) {
        NextHeaderBackup = Head->NextHeader;
        Head->NextHeader = IP6_FRAGMENT;
      }

      ExtHdrsBackup    = ExtHdrs;
      ExtHdrs          = UpdatedExtHdrs;
      ExtHdrsLen       = ExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER);
      RealExtLen       = RealExtLen + sizeof (IP6_FRAGMENT_HEADER);

      mIp6Id++;

      FragmentHeadInserted = TRUE;
    }

    Ip6FreeRouteEntry (RouteEntry);
  }

  //
  // OK, selected the source and route, fragment the packet then send
  // them. Tag each fragment other than the first one as spawn from it.
  // Each extension header is an integer multiple of 8 octets long, in
  // order to retain 8-octet alignment for subsequent headers.
  //
  Mtu     = IpSb->MaxPacketSize + sizeof (EFI_IP6_HEADER);
  HeadLen = sizeof (EFI_IP6_HEADER) + RealExtLen;

  if (Packet->TotalSize + HeadLen > Mtu) {
    //
    // Remove the inserted Fragment Header since we need fragment the packet.
    //
    if (FragmentHeadInserted) {
      ExtHdrs    = ExtHdrsBackup;
      ExtHdrsLen = ExtHdrsLen - sizeof (IP6_FRAGMENT_HEADER);

      if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) {
        Head->NextHeader = NextHeaderBackup;
      }
    }

    FragmentHdrsLen = ExtHdrsLen - UnFragmentHdrsLen;

    //
    // The packet is beyond the maximum which can be described through the
    // fragment offset field in Fragment header.
    //
    if ((((Packet->TotalSize + FragmentHdrsLen) >> 3) & (~0x1fff)) != 0) {
      Status = EFI_BAD_BUFFER_SIZE;
      goto Error;
    }

    if (FragmentHdrsLen != 0) {
      //
      // Append the fragmentable extension hdrs before the upper layer payload
      // to form a new NET_BUF. This NET_BUF contains all the buffer which will
      // be fragmented below.
      //
      TmpPacket = NetbufGetFragment (Packet, 0, Packet->TotalSize, FragmentHdrsLen);
      ASSERT (TmpPacket != NULL);

      //
      // Allocate the space to contain the fragmentable hdrs and copy the data.
      //
      Buf = NetbufAllocSpace (TmpPacket, FragmentHdrsLen, TRUE);
      ASSERT (Buf != NULL);
      CopyMem (Buf, ExtHdrs + UnFragmentHdrsLen, FragmentHdrsLen);

      //
      // Free the old Packet.
      //
      NetbufFree (Packet);
      Packet = TmpPacket;
    }

    //
    // The unfragment part which appears in every fragmented IPv6 packet includes
    // the IPv6 header, the unfragmentable extension hdrs and the fragment header.
    //
    UnFragmentLen = sizeof (EFI_IP6_HEADER) + UnFragmentHdrsLen + sizeof (IP6_FRAGMENT_HEADER);

    //
    // Mtu now is the length of the fragment part in a full-length fragment.
    //
    Mtu = (Mtu - UnFragmentLen) & (~0x07);
    Num = (Packet->TotalSize + Mtu - 1) / Mtu;

    for (Index = 0, Offset = 0, PacketLen = Mtu; Index < Num; Index++) {
      //
      // Get fragment from the Packet, append UnFragnmentLen spare buffer
      // before the fragmented data, the corresponding data is filled in later.
      //
      Fragment = NetbufGetFragment (Packet, Offset, PacketLen, UnFragmentLen);
      if (Fragment == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error;
      }

      FragmentOffset = (UINT16) ((UINT16) Offset | 0x1);
      if (Index == Num - 1){
        //
        // The last fragment, clear the M flag.
        //
        FragmentOffset &= (~0x1);
      }

      Status = Ip6PrependHead (
                 IpSb,
                 Fragment,
                 Head,
                 FragmentOffset,
                 ExtHdrs,
                 ExtHdrsLen,
                 LastHeaderBackup,
                 UnFragmentLen
                 );
      ASSERT (Status == EFI_SUCCESS);

      Status = Ip6SendFrame (
                 IpIf,
                 IpInstance,
                 Fragment,
                 &NextHop,
                 Ip6SysPacketSent,
                 Packet
                 );
      if (EFI_ERROR (Status)) {
        goto Error;
      }

      //
      // The last fragment of upper layer packet, update the IP6 token status.
      //
      if ((Index == Num -1) && (Context != NULL)) {
        Wrap                = (IP6_TXTOKEN_WRAP *) Context;
        Wrap->Token->Status = Status;
      }

      Offset    += PacketLen;
      PacketLen = Packet->TotalSize - Offset;
      if (PacketLen > Mtu) {
        PacketLen = Mtu;
      }
    }

    NetbufFree (Packet);
    mIp6Id++;

    if (UpdatedExtHdrs != NULL) {
      FreePool (UpdatedExtHdrs);
    }

    return EFI_SUCCESS;
  }

  //
  // Need not fragment the packet, send it in one frame.
  //
  PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace (Packet, HeadLen, NET_BUF_HEAD);
  if (PacketHead == NULL) {
    Status = EFI_BAD_BUFFER_SIZE;
    goto Error;
  }

  CopyMem (PacketHead, Head, sizeof (EFI_IP6_HEADER));
  Packet->Ip.Ip6 = PacketHead;

  if (ExtHdrs != NULL) {
    Buf = (UINT8 *) (PacketHead + 1);
    CopyMem (Buf, ExtHdrs, ExtHdrsLen);
  }

  if (UpdatedExtHdrs != NULL) {
    //
    // A Fragment Header is inserted to the packet, update the payload length.
    //
    PacketHead->PayloadLength = (UINT16) (NTOHS (PacketHead->PayloadLength) +
                                sizeof (IP6_FRAGMENT_HEADER));
    PacketHead->PayloadLength = HTONS (PacketHead->PayloadLength);
    FreePool (UpdatedExtHdrs);
  }

  return Ip6SendFrame (
           IpIf,
           IpInstance,
           Packet,
           &NextHop,
           Callback,
           Context
           );

Error:
  if (UpdatedExtHdrs != NULL) {
    FreePool (UpdatedExtHdrs);
  }
  Ip6CancelPacket (IpIf, Packet, Status);
  return Status;
}

/**
  The filter function to find a packet and all its fragments.
  The packet's fragments have their Context set to the packet.

  @param[in]  Frame            The frames hold by the low level interface.
  @param[in]  Context          Context to the function, which is the packet.

  @retval TRUE                 This is the packet to cancel or its fragments.
  @retval FALSE                This is an unrelated packet.

**/
BOOLEAN
Ip6CancelPacketFragments (
  IN IP6_LINK_TX_TOKEN   *Frame,
  IN VOID                *Context
  )
{
  if ((Frame->Packet == (NET_BUF *) Context) || (Frame->Context == Context)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Remove all the frames on the interface that pass the FrameToCancel,
  either queued on ARP queues or that have already been delivered to
  MNP and not yet recycled.

  @param[in]  Interface     Interface to remove the frames from.
  @param[in]  IoStatus      The transmit status returned to the frames' callback.
  @param[in]  FrameToCancel Function to select the frame to cancel; NULL to select all.
  @param[in]  Context       Opaque parameters passed to FrameToCancel. Ignored if
                            FrameToCancel is NULL.

**/
VOID
Ip6CancelFrames (
  IN IP6_INTERFACE          *Interface,
  IN EFI_STATUS             IoStatus,
  IN IP6_FRAME_TO_CANCEL    FrameToCancel   OPTIONAL,
  IN VOID                   *Context        OPTIONAL
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_LINK_TX_TOKEN         *Token;
  IP6_SERVICE               *IpSb;
  IP6_NEIGHBOR_ENTRY        *ArpQue;
  EFI_STATUS                Status;

  IpSb = Interface->Service;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  //
  // Cancel all the pending frames on ARP requests
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->ArpQues) {
    ArpQue = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, ArpList);

    Status = Ip6FreeNeighborEntry (
               IpSb,
               ArpQue,
               FALSE,
               FALSE,
               IoStatus,
               FrameToCancel,
               Context
               );
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Cancel all the frames that have been delivered to MNP
  // but not yet recycled.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->SentFrames) {
    Token = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link);

    if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) {
      IpSb->Mnp->Cancel (IpSb->Mnp, &Token->MnpToken);
    }
  }
}

/**
  Cancel the Packet and all its fragments.

  @param[in]  IpIf                 The interface from which the Packet is sent.
  @param[in]  Packet               The Packet to cancel.
  @param[in]  IoStatus             The status returns to the sender.

**/
VOID
Ip6CancelPacket (
  IN IP6_INTERFACE    *IpIf,
  IN NET_BUF          *Packet,
  IN EFI_STATUS       IoStatus
  )
{
  Ip6CancelFrames (IpIf, IoStatus, Ip6CancelPacketFragments, Packet);
}

