/** @file
  Implement IP6 pseudo interface.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

/**
  Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK.

  @param[in]  Event              The transmit token's event.
  @param[in]  Context            The Context which is pointed to the token.

**/
VOID
EFIAPI
Ip6OnFrameSent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Fileter function to cancel all the frame related to an IP instance.

  @param[in]  Frame             The transmit request to test whether to cancel.
  @param[in]  Context           The context which is the Ip instance that issued
                                the transmit.

  @retval TRUE                  The frame belongs to this instance and is to be
                                removed.
  @retval FALSE                 The frame doesn't belong to this instance.

**/
BOOLEAN
Ip6CancelInstanceFrame (
  IN IP6_LINK_TX_TOKEN  *Frame,
  IN VOID               *Context
  )
{
  if (Frame->IpInstance == (IP6_PROTOCOL *)Context) {
    return TRUE;
  }

  return FALSE;
}

/**
  Set the interface's address. This will trigger the DAD process for the
  address to set. To set an already set address, the lifetimes wil be
  updated to the new value passed in.

  @param[in]  Interface             The interface to set the address.
  @param[in]  Ip6Addr               The interface's to be assigned IPv6 address.
  @param[in]  IsAnycast             If TRUE, the unicast IPv6 address is anycast.
                                    Otherwise, it is not anycast.
  @param[in]  PrefixLength          The prefix length of the Ip6Addr.
  @param[in]  ValidLifetime         The valid lifetime for this address.
  @param[in]  PreferredLifetime     The preferred lifetime for this address.
  @param[in]  DadCallback           The caller's callback to trigger when DAD finishes.
                                    This is an optional parameter that may be NULL.
  @param[in]  Context               The context that will be passed to DadCallback.
                                    This is an optional parameter that may be NULL.

  @retval EFI_SUCCESS               The interface is scheduled to be configured with
                                    the specified address.
  @retval EFI_OUT_OF_RESOURCES      Failed to set the interface's address due to
                                    lack of resources.

**/
EFI_STATUS
Ip6SetAddress (
  IN IP6_INTERFACE     *Interface,
  IN EFI_IPv6_ADDRESS  *Ip6Addr,
  IN BOOLEAN           IsAnycast,
  IN UINT8             PrefixLength,
  IN UINT32            ValidLifetime,
  IN UINT32            PreferredLifetime,
  IN IP6_DAD_CALLBACK  DadCallback  OPTIONAL,
  IN VOID              *Context     OPTIONAL
  )
{
  IP6_SERVICE            *IpSb;
  IP6_ADDRESS_INFO       *AddressInfo;
  LIST_ENTRY             *Entry;
  IP6_PREFIX_LIST_ENTRY  *PrefixEntry;
  UINT64                 Delay;
  IP6_DELAY_JOIN_LIST    *DelayNode;
  EFI_STATUS             Status;
  UINT32                 Random;

  Status = PseudoRandomU32 (&Random);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
    return Status;
  }

  NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);

  IpSb = Interface->Service;

  if (Ip6IsOneOfSetAddress (IpSb, Ip6Addr, NULL, &AddressInfo)) {
    ASSERT (AddressInfo != NULL);
    //
    // Update the lifetime.
    //
    AddressInfo->ValidLifetime     = ValidLifetime;
    AddressInfo->PreferredLifetime = PreferredLifetime;

    if (DadCallback != NULL) {
      DadCallback (TRUE, Ip6Addr, Context);
    }

    return EFI_SUCCESS;
  }

  AddressInfo = (IP6_ADDRESS_INFO *)AllocatePool (sizeof (IP6_ADDRESS_INFO));
  if (AddressInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  AddressInfo->Signature = IP6_ADDR_INFO_SIGNATURE;
  IP6_COPY_ADDRESS (&AddressInfo->Address, Ip6Addr);
  AddressInfo->IsAnycast         = IsAnycast;
  AddressInfo->PrefixLength      = PrefixLength;
  AddressInfo->ValidLifetime     = ValidLifetime;
  AddressInfo->PreferredLifetime = PreferredLifetime;

  if (AddressInfo->PrefixLength == 0) {
    //
    // Find an appropriate prefix from on-link prefixes and update the prefixlength.
    // Longest prefix match is used here.
    //
    NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) {
      PrefixEntry = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);

      if (NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) {
        AddressInfo->PrefixLength = PrefixEntry->PrefixLength;
        break;
      }
    }
  }

  if (AddressInfo->PrefixLength == 0) {
    //
    // If the prefix length is still zero, try the autonomous prefixes.
    // Longest prefix match is used here.
    //
    NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) {
      PrefixEntry = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);

      if (NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) {
        AddressInfo->PrefixLength = PrefixEntry->PrefixLength;
        break;
      }
    }
  }

  if (AddressInfo->PrefixLength == 0) {
    //
    // BUGBUG: Stil fail, use 64 as the default prefix length.
    //
    AddressInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
  }

  //
  // Node should delay joining the solicited-node multicast address by a random delay
  // between 0 and MAX_RTR_SOLICITATION_DELAY (1 second).
  // Thus queue the address to be processed in Duplicate Address Detection module
  // after the delay time (in milliseconds).
  //
  Delay = (UINT64)Random;
  Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS);
  Delay = RShiftU64 (Delay, 32);

  DelayNode = (IP6_DELAY_JOIN_LIST *)AllocatePool (sizeof (IP6_DELAY_JOIN_LIST));
  if (DelayNode == NULL) {
    FreePool (AddressInfo);
    return EFI_OUT_OF_RESOURCES;
  }

  DelayNode->DelayTime   = (UINT32)(DivU64x32 (Delay, IP6_TIMER_INTERVAL_IN_MS));
  DelayNode->Interface   = Interface;
  DelayNode->AddressInfo = AddressInfo;
  DelayNode->DadCallback = DadCallback;
  DelayNode->Context     = Context;

  InsertTailList (&Interface->DelayJoinList, &DelayNode->Link);
  return EFI_SUCCESS;
}

/**
  Create an IP6_INTERFACE.

  @param[in]  IpSb                  The IP6 service binding instance.
  @param[in]  LinkLocal             If TRUE, the instance is created for link-local address.
                                    Otherwise, it is not for a link-local address.

  @return Point to the created IP6_INTERFACE, otherwise NULL.

**/
IP6_INTERFACE *
Ip6CreateInterface (
  IN IP6_SERVICE  *IpSb,
  IN BOOLEAN      LinkLocal
  )
{
  EFI_STATUS        Status;
  IP6_INTERFACE     *Interface;
  EFI_IPv6_ADDRESS  *Ip6Addr;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  Interface = AllocatePool (sizeof (IP6_INTERFACE));
  if (Interface == NULL) {
    return NULL;
  }

  Interface->Signature = IP6_INTERFACE_SIGNATURE;
  Interface->RefCnt    = 1;

  InitializeListHead (&Interface->AddressList);
  Interface->AddressCount = 0;
  Interface->Configured   = FALSE;

  Interface->Service    = IpSb;
  Interface->Controller = IpSb->Controller;
  Interface->Image      = IpSb->Image;

  InitializeListHead (&Interface->ArpQues);
  InitializeListHead (&Interface->SentFrames);

  Interface->DupAddrDetect = IpSb->Ip6ConfigInstance.DadXmits.DupAddrDetectTransmits;
  InitializeListHead (&Interface->DupAddrDetectList);

  InitializeListHead (&Interface->DelayJoinList);

  InitializeListHead (&Interface->IpInstances);
  Interface->PromiscRecv = FALSE;

  if (!LinkLocal) {
    return Interface;
  }

  //
  // Get the link local addr
  //
  Ip6Addr = Ip6CreateLinkLocalAddr (IpSb);
  if (Ip6Addr == NULL) {
    goto ON_ERROR;
  }

  //
  // Perform DAD - Duplicate Address Detection.
  //
  Status = Ip6SetAddress (
             Interface,
             Ip6Addr,
             FALSE,
             IP6_LINK_LOCAL_PREFIX_LENGTH,
             (UINT32)IP6_INFINIT_LIFETIME,
             (UINT32)IP6_INFINIT_LIFETIME,
             NULL,
             NULL
             );

  FreePool (Ip6Addr);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return Interface;

ON_ERROR:

  FreePool (Interface);
  return NULL;
}

/**
  Free the interface used by IpInstance. All the IP instance with
  the same Ip/prefix pair share the same interface. It is reference
  counted. All the frames that haven't been sent will be cancelled.
  Because the IpInstance is optional, the caller must remove
  IpInstance from the interface's instance list.

  @param[in]  Interface         The interface used by the IpInstance.
  @param[in]  IpInstance        The IP instance that free the interface. NULL if
                                the IP driver is releasing the default interface.

**/
VOID
Ip6CleanInterface (
  IN  IP6_INTERFACE  *Interface,
  IN  IP6_PROTOCOL   *IpInstance           OPTIONAL
  )
{
  IP6_DAD_ENTRY        *Duplicate;
  IP6_DELAY_JOIN_LIST  *Delay;

  NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE);
  ASSERT (Interface->RefCnt > 0);

  //
  // Remove all the pending transmit token related to this IP instance.
  //
  Ip6CancelFrames (Interface, EFI_ABORTED, Ip6CancelInstanceFrame, IpInstance);

  if (--Interface->RefCnt > 0) {
    return;
  }

  //
  // Destroy the interface if this is the last IP instance.
  // Remove all the system transmitted packets
  // from this interface, cancel the receive request if exists.
  //
  Ip6CancelFrames (Interface, EFI_ABORTED, Ip6CancelInstanceFrame, NULL);

  ASSERT (IsListEmpty (&Interface->IpInstances));
  ASSERT (IsListEmpty (&Interface->ArpQues));
  ASSERT (IsListEmpty (&Interface->SentFrames));

  while (!IsListEmpty (&Interface->DupAddrDetectList)) {
    Duplicate = NET_LIST_HEAD (&Interface->DupAddrDetectList, IP6_DAD_ENTRY, Link);
    NetListRemoveHead (&Interface->DupAddrDetectList);
    FreePool (Duplicate);
  }

  while (!IsListEmpty (&Interface->DelayJoinList)) {
    Delay = NET_LIST_HEAD (&Interface->DelayJoinList, IP6_DELAY_JOIN_LIST, Link);
    NetListRemoveHead (&Interface->DelayJoinList);
    FreePool (Delay);
  }

  Ip6RemoveAddr (Interface->Service, &Interface->AddressList, &Interface->AddressCount, NULL, 0);

  RemoveEntryList (&Interface->Link);
  FreePool (Interface);
}

/**
  Create and wrap a transmit request into a newly allocated IP6_LINK_TX_TOKEN.

  @param[in]  Interface         The interface to send out from.
  @param[in]  IpInstance        The IpInstance that transmit the packet.  NULL if
                                the packet is sent by the IP6 driver itself.
  @param[in]  Packet            The packet to transmit
  @param[in]  CallBack          Call back function to execute if transmission
                                finished.
  @param[in]  Context           Opaque parameter to the callback.

  @return The wrapped token if succeed or NULL.

**/
IP6_LINK_TX_TOKEN *
Ip6CreateLinkTxToken (
  IN IP6_INTERFACE       *Interface,
  IN IP6_PROTOCOL        *IpInstance    OPTIONAL,
  IN NET_BUF             *Packet,
  IN IP6_FRAME_CALLBACK  CallBack,
  IN VOID                *Context
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *MnpToken;
  EFI_MANAGED_NETWORK_TRANSMIT_DATA     *MnpTxData;
  IP6_LINK_TX_TOKEN                     *Token;
  EFI_STATUS                            Status;
  UINT32                                Count;

  Token = AllocatePool (sizeof (IP6_LINK_TX_TOKEN) + (Packet->BlockOpNum - 1) * sizeof (EFI_MANAGED_NETWORK_FRAGMENT_DATA));

  if (Token == NULL) {
    return NULL;
  }

  Token->Signature = IP6_LINK_TX_SIGNATURE;
  InitializeListHead (&Token->Link);

  Token->IpInstance = IpInstance;
  Token->CallBack   = CallBack;
  Token->Packet     = Packet;
  Token->Context    = Context;
  ZeroMem (&Token->DstMac, sizeof (EFI_MAC_ADDRESS));
  IP6_COPY_LINK_ADDRESS (&Token->SrcMac, &Interface->Service->SnpMode.CurrentAddress);

  MnpToken         = &(Token->MnpToken);
  MnpToken->Status = EFI_NOT_READY;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip6OnFrameSent,
                  Token,
                  &MnpToken->Event
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Token);
    return NULL;
  }

  MnpTxData               = &Token->MnpTxData;
  MnpToken->Packet.TxData = MnpTxData;

  MnpTxData->DestinationAddress = &Token->DstMac;
  MnpTxData->SourceAddress      = &Token->SrcMac;
  MnpTxData->ProtocolType       = IP6_ETHER_PROTO;
  MnpTxData->DataLength         = Packet->TotalSize;
  MnpTxData->HeaderLength       = 0;

  Count = Packet->BlockOpNum;

  NetbufBuildExt (Packet, (NET_FRAGMENT *)MnpTxData->FragmentTable, &Count);
  MnpTxData->FragmentCount = (UINT16)Count;

  return Token;
}

/**
  Free the link layer transmit token. It will close the event,
  then free the memory used.

  @param[in]  Token                 Token to free.

**/
VOID
Ip6FreeLinkTxToken (
  IN IP6_LINK_TX_TOKEN  *Token
  )
{
  NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE);

  gBS->CloseEvent (Token->MnpToken.Event);
  FreePool (Token);
}

/**
  Callback function when the received packet is freed.
  Check Ip6OnFrameReceived for information.

  @param[in]  Context       Points to EFI_MANAGED_NETWORK_RECEIVE_DATA.

**/
VOID
EFIAPI
Ip6RecycleFrame (
  IN VOID  *Context
  )
{
  EFI_MANAGED_NETWORK_RECEIVE_DATA  *RxData;

  RxData = (EFI_MANAGED_NETWORK_RECEIVE_DATA *)Context;

  gBS->SignalEvent (RxData->RecycleEvent);
}

/**
  Received a frame from MNP. Wrap it in net buffer then deliver
  it to IP's input function. The ownship of the packet also
  is transferred to IP. When Ip is finished with this packet, it
  will call NetbufFree to release the packet, NetbufFree will
  again call the Ip6RecycleFrame to signal MNP's event and free
  the token used.

  @param[in]  Context         Context for the callback.

**/
VOID
EFIAPI
Ip6OnFrameReceivedDpc (
  IN VOID  *Context
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *MnpToken;
  EFI_MANAGED_NETWORK_RECEIVE_DATA      *MnpRxData;
  IP6_LINK_RX_TOKEN                     *Token;
  NET_FRAGMENT                          Netfrag;
  NET_BUF                               *Packet;
  UINT32                                Flag;
  IP6_SERVICE                           *IpSb;

  Token = (IP6_LINK_RX_TOKEN *)Context;
  NET_CHECK_SIGNATURE (Token, IP6_LINK_RX_SIGNATURE);

  //
  // First clear the interface's receive request in case the
  // caller wants to call Ip6ReceiveFrame in the callback.
  //
  IpSb = (IP6_SERVICE *)Token->Context;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  MnpToken  = &Token->MnpToken;
  MnpRxData = MnpToken->Packet.RxData;

  if (EFI_ERROR (MnpToken->Status) || (MnpRxData == NULL)) {
    Token->CallBack (NULL, MnpToken->Status, 0, Token->Context);
    return;
  }

  //
  // Wrap the frame in a net buffer then deliver it to IP input.
  // IP will reassemble the packet, and deliver it to upper layer
  //
  Netfrag.Len  = MnpRxData->DataLength;
  Netfrag.Bulk = MnpRxData->PacketData;

  Packet = NetbufFromExt (&Netfrag, 1, IP6_MAX_HEADLEN, 0, Ip6RecycleFrame, Token->MnpToken.Packet.RxData);

  if (Packet == NULL) {
    gBS->SignalEvent (MnpRxData->RecycleEvent);

    Token->CallBack (NULL, EFI_OUT_OF_RESOURCES, 0, Token->Context);

    return;
  }

  Flag  = (MnpRxData->BroadcastFlag ? IP6_LINK_BROADCAST : 0);
  Flag |= (MnpRxData->MulticastFlag ? IP6_LINK_MULTICAST : 0);
  Flag |= (MnpRxData->PromiscuousFlag ? IP6_LINK_PROMISC : 0);

  Token->CallBack (Packet, EFI_SUCCESS, Flag, Token->Context);
}

/**
  Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK.

  @param  Event                 The receive event delivered to MNP for receive.
  @param  Context               Context for the callback.

**/
VOID
EFIAPI
Ip6OnFrameReceived (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip6OnFrameReceivedDpc, Context);
}

/**
  Request to receive the packet from the interface.

  @param[in]  CallBack          Function to call when receive finished.
  @param[in]  IpSb              Points to IP6 service binding instance.

  @retval EFI_ALREADY_STARTED   There is already a pending receive request.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource to receive.
  @retval EFI_SUCCESS           The receive request has been started.

**/
EFI_STATUS
Ip6ReceiveFrame (
  IN  IP6_FRAME_CALLBACK  CallBack,
  IN  IP6_SERVICE         *IpSb
  )
{
  EFI_STATUS         Status;
  IP6_LINK_RX_TOKEN  *Token;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  Token           = &IpSb->RecvRequest;
  Token->CallBack = CallBack;
  Token->Context  = (VOID *)IpSb;

  Status = IpSb->Mnp->Receive (IpSb->Mnp, &Token->MnpToken);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Callback function when frame transmission is finished. It will
  call the frame owner's callback function to tell it the result.

  @param[in]  Context        Context which points to the token.

**/
VOID
EFIAPI
Ip6OnFrameSentDpc (
  IN VOID  *Context
  )
{
  IP6_LINK_TX_TOKEN  *Token;

  Token = (IP6_LINK_TX_TOKEN *)Context;
  NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE);

  RemoveEntryList (&Token->Link);

  Token->CallBack (
           Token->Packet,
           Token->MnpToken.Status,
           0,
           Token->Context
           );

  Ip6FreeLinkTxToken (Token);
}

/**
  Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK.

  @param[in]  Event                 The transmit token's event.
  @param[in]  Context               Context which points to the token.

**/
VOID
EFIAPI
Ip6OnFrameSent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip6OnFrameSentDpc, Context);
}

/**
  Send a frame from the interface. If the next hop is a multicast address,
  it is transmitted immediately. If the next hop is a unicast,
  and the NextHop's MAC is not known, it will perform address resolution.
  If an error occurred, the CallBack won't be called. So, the caller
  must test the return value, and take action when there is an error.

  @param[in]  Interface         The interface to send the frame from
  @param[in]  IpInstance        The IP child that request the transmission.
                                NULL if it is the IP6 driver itself.
  @param[in]  Packet            The packet to transmit.
  @param[in]  NextHop           The immediate destination to transmit the packet to.
  @param[in]  CallBack          Function to call back when transmit finished.
  @param[in]  Context           Opaque parameter to the callback.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource to send the frame.
  @retval EFI_NO_MAPPING        Can't resolve the MAC for the nexthop.
  @retval EFI_SUCCESS           The packet successfully transmitted.

**/
EFI_STATUS
Ip6SendFrame (
  IN  IP6_INTERFACE       *Interface,
  IN  IP6_PROTOCOL        *IpInstance      OPTIONAL,
  IN  NET_BUF             *Packet,
  IN  EFI_IPv6_ADDRESS    *NextHop,
  IN  IP6_FRAME_CALLBACK  CallBack,
  IN  VOID                *Context
  )
{
  IP6_SERVICE         *IpSb;
  IP6_LINK_TX_TOKEN   *Token;
  EFI_STATUS          Status;
  IP6_NEIGHBOR_ENTRY  *NeighborCache;
  LIST_ENTRY          *Entry;
  IP6_NEIGHBOR_ENTRY  *ArpQue;

  IpSb = Interface->Service;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  //
  // Only when link local address is performing DAD, the interface could be used in unconfigured.
  //
  if (IpSb->LinkLocalOk) {
    ASSERT (Interface->Configured);
  }

  Token = Ip6CreateLinkTxToken (Interface, IpInstance, Packet, CallBack, Context);

  if (Token == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (IP6_IS_MULTICAST (NextHop)) {
    Status = Ip6GetMulticastMac (IpSb->Mnp, NextHop, &Token->DstMac);
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    goto SendNow;
  }

  //
  // If send to itself, directly send out
  //
  if (EFI_IP6_EQUAL (&Packet->Ip.Ip6->DestinationAddress, &Packet->Ip.Ip6->SourceAddress)) {
    IP6_COPY_LINK_ADDRESS (&Token->DstMac, &IpSb->SnpMode.CurrentAddress);
    goto SendNow;
  }

  //
  // If unicast, check the neighbor state.
  //

  NeighborCache = Ip6FindNeighborEntry (IpSb, NextHop);
  ASSERT (NeighborCache != NULL);

  if (NeighborCache->Interface == NULL) {
    NeighborCache->Interface = Interface;
  }

  switch (NeighborCache->State) {
    case EfiNeighborStale:
      NeighborCache->State = EfiNeighborDelay;
      NeighborCache->Ticks = (UINT32)IP6_GET_TICKS (IP6_DELAY_FIRST_PROBE_TIME);
    //
    // Fall through
    //
    case EfiNeighborReachable:
    case EfiNeighborDelay:
    case EfiNeighborProbe:
      IP6_COPY_LINK_ADDRESS (&Token->DstMac, &NeighborCache->LinkAddress);
      goto SendNow;
      break;

    default:
      break;
  }

  //
  // Have to do asynchronous ARP resolution. First check whether there is
  // already a pending request.
  //
  NET_LIST_FOR_EACH (Entry, &Interface->ArpQues) {
    ArpQue = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, ArpList);
    if (ArpQue == NeighborCache) {
      InsertTailList (&NeighborCache->Frames, &Token->Link);
      NeighborCache->ArpFree = TRUE;
      return EFI_SUCCESS;
    }
  }

  //
  // First frame requires ARP.
  //
  InsertTailList (&NeighborCache->Frames, &Token->Link);
  InsertTailList (&Interface->ArpQues, &NeighborCache->ArpList);

  NeighborCache->ArpFree = TRUE;

  return EFI_SUCCESS;

SendNow:
  //
  // Insert the tx token into the SentFrames list before calling Mnp->Transmit.
  // Remove it if the returned status is not EFI_SUCCESS.
  //
  InsertTailList (&Interface->SentFrames, &Token->Link);
  Status = IpSb->Mnp->Transmit (IpSb->Mnp, &Token->MnpToken);
  if (EFI_ERROR (Status)) {
    RemoveEntryList (&Token->Link);
    goto Error;
  }

  return EFI_SUCCESS;

Error:
  Ip6FreeLinkTxToken (Token);
  return Status;
}

/**
  The heartbeat timer of IP6 service instance. It times out
  all of its IP6 children's received-but-not-delivered and
  transmitted-but-not-recycle packets.

  @param[in]  Event                 The IP6 service instance's heartbeat timer.
  @param[in]  Context               The IP6 service instance.

**/
VOID
EFIAPI
Ip6TimerTicking (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  IP6_SERVICE  *IpSb;

  IpSb = (IP6_SERVICE *)Context;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  Ip6PacketTimerTicking (IpSb);
  Ip6NdTimerTicking (IpSb);
  Ip6MldTimerTicking (IpSb);
}
