/** @file
  Implement IP4 pseudo interface.

Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip4Impl.h"

//
// Mac address with all zero, used to determine whether the ARP
// resolve succeeded. Failed ARP requests zero the MAC address buffer.
//
EFI_MAC_ADDRESS  mZeroMacAddress;

/**
  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 is point to the token.

**/
VOID
EFIAPI
Ip4OnFrameSentDpc (
  IN VOID  *Context
  );

/**
  Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK.

  @param[in]  Event              The transmit token's event.
  @param[in]  Context            Context which is point to the token.

**/
VOID
EFIAPI
Ip4OnFrameSent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Callback function when ARP request are finished. It will cancelled
  all the queued frame if the ARP requests failed. Or transmit them
  if the request succeed.

  @param[in]  Context           The context of the callback, a point to the ARP
                                queue

**/
VOID
EFIAPI
Ip4OnArpResolvedDpc (
  IN VOID  *Context
  );

/**
  Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK.

  @param  Event             The Arp request event.
  @param  Context           The context of the callback, a point to the ARP
                            queue.

**/
VOID
EFIAPI
Ip4OnArpResolved (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Received a frame from MNP, wrap it in net buffer then deliver
  it to IP's input function. The ownship of the packet also
  transferred to IP. When Ip is finished with this packet, it
  will call NetbufFree to release the packet, NetbufFree will
  again call the Ip4RecycleFrame to signal MNP's event and free
  the token used.

  @param  Context               Context for the callback.

**/
VOID
EFIAPI
Ip4OnFrameReceivedDpc (
  IN VOID  *Context
  );

/**
  Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK.

  @param Event      The receive event delivered to MNP for receive.
  @param Context    Context for the callback.

**/
VOID
EFIAPI
Ip4OnFrameReceived (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  Remove all the frames on the ARP queue that pass the FrameToCancel,
  that is, either FrameToCancel is NULL or it returns true for the frame.

  @param[in]  ArpQue            ARP frame to remove the frames from.
  @param[in]  IoStatus          The status returned to the cancelled frames'
                                callback function.
  @param[in]  FrameToCancel     Function to select which frame to cancel.
  @param[in]  Context           Opaque parameter to the FrameToCancel.

**/
VOID
Ip4CancelFrameArp (
  IN IP4_ARP_QUE          *ArpQue,
  IN EFI_STATUS           IoStatus,
  IN IP4_FRAME_TO_CANCEL  FrameToCancel  OPTIONAL,
  IN VOID                 *Context
  );

/**
  Wrap a transmit request into a newly allocated IP4_LINK_TX_TOKEN.

  @param[in]  Interface         The interface to send out to.
  @param[in]  IpInstance        The IpInstance that transmit the packet.  NULL if
                                the packet is sent by the IP4 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 call back.
  @param[in]  IpSb              The pointer to the IP4 service binding instance.

  @retval   Token               The wrapped token if succeed
  @retval   NULL                The wrapped token if NULL

**/
IP4_LINK_TX_TOKEN *
Ip4WrapLinkTxToken (
  IN IP4_INTERFACE       *Interface,
  IN IP4_PROTOCOL        *IpInstance     OPTIONAL,
  IN NET_BUF             *Packet,
  IN IP4_FRAME_CALLBACK  CallBack,
  IN VOID                *Context,
  IN IP4_SERVICE         *IpSb
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *MnpToken;
  EFI_MANAGED_NETWORK_TRANSMIT_DATA     *MnpTxData;
  IP4_LINK_TX_TOKEN                     *Token;
  EFI_STATUS                            Status;
  UINT32                                Count;

  Token = AllocatePool (
            sizeof (IP4_LINK_TX_TOKEN) + \
            (Packet->BlockOpNum - 1) * sizeof (EFI_MANAGED_NETWORK_FRAGMENT_DATA)
            );

  if (Token == NULL) {
    return NULL;
  }

  Token->Signature = IP4_FRAME_TX_SIGNATURE;
  InitializeListHead (&Token->Link);

  Token->Interface  = Interface;
  Token->IpInstance = IpInstance;
  Token->IpSb       = IpSb;
  Token->CallBack   = CallBack;
  Token->Packet     = Packet;
  Token->Context    = Context;
  CopyMem (&Token->DstMac, &mZeroMacAddress, sizeof (Token->DstMac));
  CopyMem (&Token->SrcMac, &Interface->Mac, sizeof (Token->SrcMac));

  MnpToken         = &(Token->MnpToken);
  MnpToken->Status = EFI_NOT_READY;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip4OnFrameSent,
                  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       = IP4_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
Ip4FreeLinkTxToken (
  IN IP4_LINK_TX_TOKEN  *Token
  )
{
  NET_CHECK_SIGNATURE (Token, IP4_FRAME_TX_SIGNATURE);

  gBS->CloseEvent (Token->MnpToken.Event);
  FreePool (Token);
}

/**
  Create an IP_ARP_QUE structure to request ARP service.

  @param[in]  Interface         The interface to send ARP from.
  @param[in]  DestIp            The destination IP (host byte order) to request MAC
                                for

  @return Point to newly created IP4_ARP_QUE if succeed, otherwise NULL.

**/
IP4_ARP_QUE *
Ip4CreateArpQue (
  IN IP4_INTERFACE  *Interface,
  IN IP4_ADDR       DestIp
  )
{
  IP4_ARP_QUE  *ArpQue;
  EFI_STATUS   Status;

  ArpQue = AllocatePool (sizeof (IP4_ARP_QUE));

  if (ArpQue == NULL) {
    return NULL;
  }

  ArpQue->Signature = IP4_FRAME_ARP_SIGNATURE;
  InitializeListHead (&ArpQue->Link);

  InitializeListHead (&ArpQue->Frames);
  ArpQue->Interface = Interface;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip4OnArpResolved,
                  ArpQue,
                  &ArpQue->OnResolved
                  );

  if (EFI_ERROR (Status)) {
    FreePool (ArpQue);
    return NULL;
  }

  ArpQue->Ip = DestIp;
  CopyMem (&ArpQue->Mac, &mZeroMacAddress, sizeof (ArpQue->Mac));

  return ArpQue;
}

/**
  Remove all the transmit requests queued on the ARP queue, then free it.

  @param[in]  ArpQue            Arp queue to free
  @param[in]  IoStatus          The transmit status returned to transmit requests'
                                callback.

**/
VOID
Ip4FreeArpQue (
  IN IP4_ARP_QUE  *ArpQue,
  IN EFI_STATUS   IoStatus
  )
{
  NET_CHECK_SIGNATURE (ArpQue, IP4_FRAME_ARP_SIGNATURE);

  //
  // Remove all the frame waiting the ARP response
  //
  Ip4CancelFrameArp (ArpQue, IoStatus, NULL, NULL);

  gBS->CloseEvent (ArpQue->OnResolved);
  FreePool (ArpQue);
}

/**
  Create a link layer receive token to wrap the receive request

  @param[in]  Interface         The interface to receive from
  @param[in]  IpInstance        The instance that request the receive (NULL for IP4
                                driver itself)
  @param[in]  CallBack          Call back function to execute when finished.
  @param[in]  Context           Opaque parameters to the callback

  @return Point to created IP4_LINK_RX_TOKEN if succeed, otherwise NULL.

**/
IP4_LINK_RX_TOKEN *
Ip4CreateLinkRxToken (
  IN IP4_INTERFACE       *Interface,
  IN IP4_PROTOCOL        *IpInstance,
  IN IP4_FRAME_CALLBACK  CallBack,
  IN VOID                *Context
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *MnpToken;
  IP4_LINK_RX_TOKEN                     *Token;
  EFI_STATUS                            Status;

  Token = AllocatePool (sizeof (IP4_LINK_RX_TOKEN));
  if (Token == NULL) {
    return NULL;
  }

  Token->Signature  = IP4_FRAME_RX_SIGNATURE;
  Token->Interface  = Interface;
  Token->IpInstance = IpInstance;
  Token->CallBack   = CallBack;
  Token->Context    = Context;

  MnpToken         = &Token->MnpToken;
  MnpToken->Status = EFI_NOT_READY;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip4OnFrameReceived,
                  Token,
                  &MnpToken->Event
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Token);
    return NULL;
  }

  MnpToken->Packet.RxData = NULL;
  return Token;
}

/**
  Free the link layer request token. It will close the event
  then free the memory used.

  @param[in]  Token                 Request token to free.

**/
VOID
Ip4FreeFrameRxToken (
  IN IP4_LINK_RX_TOKEN  *Token
  )
{
  NET_CHECK_SIGNATURE (Token, IP4_FRAME_RX_SIGNATURE);

  gBS->CloseEvent (Token->MnpToken.Event);
  FreePool (Token);
}

/**
  Remove all the frames on the ARP queue that pass the FrameToCancel,
  that is, either FrameToCancel is NULL or it returns true for the frame.

  @param[in]  ArpQue            ARP frame to remove the frames from.
  @param[in]  IoStatus          The status returned to the cancelled frames'
                                callback function.
  @param[in]  FrameToCancel     Function to select which frame to cancel.
  @param[in]  Context           Opaque parameter to the FrameToCancel.

**/
VOID
Ip4CancelFrameArp (
  IN IP4_ARP_QUE          *ArpQue,
  IN EFI_STATUS           IoStatus,
  IN IP4_FRAME_TO_CANCEL  FrameToCancel  OPTIONAL,
  IN VOID                 *Context
  )
{
  LIST_ENTRY         *Entry;
  LIST_ENTRY         *Next;
  IP4_LINK_TX_TOKEN  *Token;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {
    Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);

    if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) {
      RemoveEntryList (Entry);

      Token->CallBack (Token->IpInstance, Token->Packet, IoStatus, 0, Token->Context);
      Ip4FreeLinkTxToken (Token);
    }
  }
}

/**
  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.

**/
VOID
Ip4CancelFrames (
  IN IP4_INTERFACE        *Interface,
  IN EFI_STATUS           IoStatus,
  IN IP4_FRAME_TO_CANCEL  FrameToCancel    OPTIONAL,
  IN VOID                 *Context
  )
{
  LIST_ENTRY         *Entry;
  LIST_ENTRY         *Next;
  IP4_ARP_QUE        *ArpQue;
  IP4_LINK_TX_TOKEN  *Token;

  //
  // Cancel all the pending frames on ARP requests
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->ArpQues) {
    ArpQue = NET_LIST_USER_STRUCT (Entry, IP4_ARP_QUE, Link);

    Ip4CancelFrameArp (ArpQue, IoStatus, FrameToCancel, Context);

    if (IsListEmpty (&ArpQue->Frames)) {
      Interface->Arp->Cancel (Interface->Arp, &ArpQue->Ip, ArpQue->OnResolved);
    }
  }

  //
  // 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, IP4_LINK_TX_TOKEN, Link);

    if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) {
      Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken);
    }
  }
}

/**
  Create an IP4_INTERFACE. Delay the creation of ARP instance until
  the interface is configured.

  @param[in]  Mnp               The shared MNP child of this IP4 service binding
                                instance.
  @param[in]  Controller        The controller this IP4 service binding instance
                                is installed. Most like the UNDI handle.
  @param[in]  ImageHandle       This driver's image handle.

  @return Point to the created IP4_INTERFACE, otherwise NULL.

**/
IP4_INTERFACE *
Ip4CreateInterface (
  IN  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp,
  IN  EFI_HANDLE                    Controller,
  IN  EFI_HANDLE                    ImageHandle
  )
{
  IP4_INTERFACE            *Interface;
  EFI_SIMPLE_NETWORK_MODE  SnpMode;

  if (Mnp == NULL) {
    return NULL;
  }

  Interface = AllocatePool (sizeof (IP4_INTERFACE));

  if (Interface == NULL) {
    return NULL;
  }

  Interface->Signature = IP4_INTERFACE_SIGNATURE;
  InitializeListHead (&Interface->Link);
  Interface->RefCnt = 1;

  Interface->Ip         = IP4_ALLZERO_ADDRESS;
  Interface->SubnetMask = IP4_ALLZERO_ADDRESS;
  Interface->Configured = FALSE;

  Interface->Controller = Controller;
  Interface->Image      = ImageHandle;
  Interface->Mnp        = Mnp;
  Interface->Arp        = NULL;
  Interface->ArpHandle  = NULL;

  InitializeListHead (&Interface->ArpQues);
  InitializeListHead (&Interface->SentFrames);

  Interface->RecvRequest = NULL;

  //
  // Get the interface's Mac address and broadcast mac address from SNP
  //
  if (EFI_ERROR (Mnp->GetModeData (Mnp, NULL, &SnpMode))) {
    FreePool (Interface);
    return NULL;
  }

  CopyMem (&Interface->Mac, &SnpMode.CurrentAddress, sizeof (Interface->Mac));
  CopyMem (&Interface->BroadcastMac, &SnpMode.BroadcastAddress, sizeof (Interface->BroadcastMac));
  Interface->HwaddrLen = SnpMode.HwAddressSize;

  InitializeListHead (&Interface->IpInstances);
  Interface->PromiscRecv = FALSE;

  return Interface;
}

/**
  Set the interface's address, create and configure
  the ARP child if necessary.

  @param  Interface         The interface to set the address.
  @param  IpAddr            The interface's IP address.
  @param  SubnetMask        The interface's netmask.

  @retval EFI_SUCCESS           The interface is configured with Ip/netmask pair,
                                and a ARP is created for it.
  @retval Others                Failed to set the interface's address.

**/
EFI_STATUS
Ip4SetAddress (
  IN OUT IP4_INTERFACE  *Interface,
  IN     IP4_ADDR       IpAddr,
  IN     IP4_ADDR       SubnetMask
  )
{
  EFI_ARP_CONFIG_DATA  ArpConfig;
  EFI_STATUS           Status;

  NET_CHECK_SIGNATURE (Interface, IP4_INTERFACE_SIGNATURE);

  //
  // Set the ip/netmask, then compute the subnet broadcast
  // and network broadcast for easy access. When computing
  // network broadcast, the subnet mask is most like longer
  // than the default netmask (not subneted) as defined in
  // RFC793. If that isn't the case, we are aggregating the
  // networks, use the subnet's mask instead.
  //
  Interface->Ip            = IpAddr;
  Interface->SubnetMask    = SubnetMask;
  Interface->SubnetBrdcast = (IpAddr | ~SubnetMask);
  Interface->NetBrdcast    = (IpAddr | ~SubnetMask);

  //
  // Do clean up for Arp child
  //
  if (Interface->ArpHandle != NULL) {
    if (Interface->Arp != NULL) {
      gBS->CloseProtocol (
             Interface->ArpHandle,
             &gEfiArpProtocolGuid,
             Interface->Image,
             Interface->Controller
             );

      Interface->Arp = NULL;
    }

    NetLibDestroyServiceChild (
      Interface->Controller,
      Interface->Image,
      &gEfiArpServiceBindingProtocolGuid,
      Interface->ArpHandle
      );

    Interface->ArpHandle = NULL;
  }

  //
  // If the address is NOT all zero, create then configure an ARP child.
  // Pay attention: DHCP configures its station address as 0.0.0.0/0
  //
  if (IpAddr != IP4_ALLZERO_ADDRESS) {
    Status = NetLibCreateServiceChild (
               Interface->Controller,
               Interface->Image,
               &gEfiArpServiceBindingProtocolGuid,
               &Interface->ArpHandle
               );

    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gBS->OpenProtocol (
                    Interface->ArpHandle,
                    &gEfiArpProtocolGuid,
                    (VOID **)&Interface->Arp,
                    Interface->Image,
                    Interface->Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    IpAddr                    = HTONL (IpAddr);
    ArpConfig.SwAddressType   = IP4_ETHER_PROTO;
    ArpConfig.SwAddressLength = 4;
    ArpConfig.StationAddress  = &IpAddr;
    ArpConfig.EntryTimeOut    = 0;
    ArpConfig.RetryCount      = 0;
    ArpConfig.RetryTimeOut    = 0;

    Status = Interface->Arp->Configure (Interface->Arp, &ArpConfig);

    if (EFI_ERROR (Status)) {
      gBS->CloseProtocol (
             Interface->ArpHandle,
             &gEfiArpProtocolGuid,
             Interface->Image,
             Interface->Controller
             );

      goto ON_ERROR;
    }
  }

  Interface->Configured = TRUE;
  return EFI_SUCCESS;

ON_ERROR:
  NetLibDestroyServiceChild (
    Interface->Controller,
    Interface->Image,
    &gEfiArpServiceBindingProtocolGuid,
    Interface->ArpHandle
    );

  return Status;
}

/**
  Filter 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
Ip4CancelInstanceFrame (
  IN IP4_LINK_TX_TOKEN  *Frame,
  IN VOID               *Context
  )
{
  if (Frame->IpInstance == (IP4_PROTOCOL *)Context) {
    return TRUE;
  }

  return FALSE;
}

/**
  If there is a pending receive request, cancel it. Don't call
  the receive request's callback because this function can be only
  called if the instance or driver is tearing itself down. It
  doesn't make sense to call it back. But it is necessary to call
  the transmit token's callback to give it a chance to free the
  packet and update the upper layer's transmit request status, say
  that from the UDP.

  @param[in]  Interface         The interface used by the IpInstance

**/
VOID
Ip4CancelReceive (
  IN IP4_INTERFACE  *Interface
  )
{
  EFI_TPL            OldTpl;
  IP4_LINK_RX_TOKEN  *Token;

  if ((Token = Interface->RecvRequest) != NULL) {
    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

    Interface->RecvRequest = NULL;
    Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken);

    gBS->RestoreTPL (OldTpl);
  }
}

/**
  Free the interface used by IpInstance. All the IP instance with
  the same Ip/Netmask pair share the same interface. It is reference
  counted. All the frames haven't been sent will be cancelled.
  Because the IpInstance is optional, the caller must remove
  IpInstance from the interface's instance list itself.

  @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.

  @retval EFI_SUCCESS           The interface use IpInstance is freed.

**/
EFI_STATUS
Ip4FreeInterface (
  IN  IP4_INTERFACE  *Interface,
  IN  IP4_PROTOCOL   *IpInstance           OPTIONAL
  )
{
  NET_CHECK_SIGNATURE (Interface, IP4_INTERFACE_SIGNATURE);
  ASSERT (Interface->RefCnt > 0);

  //
  // Remove all the pending transmit token related to this IP instance.
  //
  Ip4CancelFrames (Interface, EFI_ABORTED, Ip4CancelInstanceFrame, IpInstance);

  if (--Interface->RefCnt > 0) {
    return EFI_SUCCESS;
  }

  //
  // Destroy the interface if this is the last IP instance that
  // has the address. Remove all the system transmitted packets
  // from this interface, cancel the receive request if there is
  // one, and destroy the ARP requests.
  //
  Ip4CancelFrames (Interface, EFI_ABORTED, Ip4CancelInstanceFrame, NULL);
  Ip4CancelReceive (Interface);

  ASSERT (IsListEmpty (&Interface->IpInstances));
  ASSERT (IsListEmpty (&Interface->ArpQues));
  ASSERT (IsListEmpty (&Interface->SentFrames));

  if (Interface->Arp != NULL) {
    gBS->CloseProtocol (
           Interface->ArpHandle,
           &gEfiArpProtocolGuid,
           Interface->Image,
           Interface->Controller
           );

    NetLibDestroyServiceChild (
      Interface->Controller,
      Interface->Image,
      &gEfiArpServiceBindingProtocolGuid,
      Interface->ArpHandle
      );
  }

  RemoveEntryList (&Interface->Link);
  FreePool (Interface);

  return EFI_SUCCESS;
}

/**
  This function tries to send all the queued frames in ArpQue to the default gateway if
  the ARP resolve for direct destination address is failed when using /32 subnet mask.

  @param[in]   ArpQue           The ARP queue of a failed request.

  @retval EFI_SUCCESS           All the queued frames have been send to the default route.
  @retval Others                Failed to send the queued frames.

**/
EFI_STATUS
Ip4SendFrameToDefaultRoute (
  IN  IP4_ARP_QUE  *ArpQue
  )
{
  LIST_ENTRY             *Entry;
  LIST_ENTRY             *Next;
  IP4_ROUTE_CACHE_ENTRY  *RtCacheEntry;
  IP4_LINK_TX_TOKEN      *Token;
  IP4_ADDR               Gateway;
  EFI_STATUS             Status;
  IP4_ROUTE_ENTRY        *DefaultRoute;

  //
  // ARP resolve failed when using /32 subnet mask.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {
    RemoveEntryList (Entry);
    Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);
    ASSERT (Token->Interface->SubnetMask == IP4_ALLONE_ADDRESS);
    //
    // Find the default gateway IP address. The default route was saved to the RtCacheEntry->Tag in Ip4Route().
    //
    RtCacheEntry = NULL;
    if (Token->IpInstance != NULL) {
      RtCacheEntry = Ip4FindRouteCache (Token->IpInstance->RouteTable, NTOHL (ArpQue->Ip), Token->Interface->Ip);
    }

    if (RtCacheEntry == NULL) {
      RtCacheEntry = Ip4FindRouteCache (Token->IpSb->DefaultRouteTable, NTOHL (ArpQue->Ip), Token->Interface->Ip);
    }

    if (RtCacheEntry == NULL) {
      Status = EFI_NO_MAPPING;
      goto ON_ERROR;
    }

    DefaultRoute = (IP4_ROUTE_ENTRY *)RtCacheEntry->Tag;
    if (DefaultRoute == NULL) {
      Status = EFI_NO_MAPPING;
      goto ON_ERROR;
    }

    //
    // Try to send the frame to the default route.
    //
    Gateway = DefaultRoute->NextHop;
    if (ArpQue->Ip == Gateway) {
      //
      // ARP resolve for the default route is failed, return error to caller.
      //
      Status = EFI_NO_MAPPING;
      goto ON_ERROR;
    }

    RtCacheEntry->NextHop = Gateway;
    Status                = Ip4SendFrame (Token->Interface, Token->IpInstance, Token->Packet, Gateway, Token->CallBack, Token->Context, Token->IpSb);
    if (EFI_ERROR (Status)) {
      Status = EFI_NO_MAPPING;
      goto ON_ERROR;
    }

    Ip4FreeRouteCacheEntry (RtCacheEntry);
  }

  return EFI_SUCCESS;

ON_ERROR:
  if (RtCacheEntry != NULL) {
    Ip4FreeRouteCacheEntry (RtCacheEntry);
  }

  Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context);
  Ip4FreeLinkTxToken (Token);
  return Status;
}

/**
  Callback function when ARP request are finished. It will cancel
  all the queued frame if the ARP requests failed. Or transmit them
  if the request succeed.

  @param[in]  Context           The context of the callback, a point to the ARP
                                queue

**/
VOID
EFIAPI
Ip4OnArpResolvedDpc (
  IN VOID  *Context
  )
{
  LIST_ENTRY         *Entry;
  LIST_ENTRY         *Next;
  IP4_ARP_QUE        *ArpQue;
  IP4_INTERFACE      *Interface;
  IP4_LINK_TX_TOKEN  *Token;
  EFI_STATUS         Status;
  EFI_STATUS         IoStatus;

  ArpQue = (IP4_ARP_QUE *)Context;
  NET_CHECK_SIGNATURE (ArpQue, IP4_FRAME_ARP_SIGNATURE);

  RemoveEntryList (&ArpQue->Link);

  //
  // ARP resolve failed for some reason.
  //
  if (NET_MAC_EQUAL (&ArpQue->Mac, &mZeroMacAddress, ArpQue->Interface->HwaddrLen)) {
    if (ArpQue->Interface->SubnetMask != IP4_ALLONE_ADDRESS) {
      //
      // Release all the frame and ARP queue itself. Ip4FreeArpQue will call the frame's
      // owner back.
      //
      IoStatus = EFI_NO_MAPPING;
    } else {
      //
      // ARP resolve failed when using 32bit subnet mask, try to send the packets to the
      // default route.
      //
      IoStatus = Ip4SendFrameToDefaultRoute (ArpQue);
    }

    goto ON_EXIT;
  }

  //
  // ARP resolve succeeded, Transmit all the frame. Release the ARP
  // queue. It isn't necessary for us to cache the ARP binding because
  // we always check the ARP cache first before transmit.
  //
  IoStatus  = EFI_SUCCESS;
  Interface = ArpQue->Interface;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {
    RemoveEntryList (Entry);

    Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);
    CopyMem (&Token->DstMac, &ArpQue->Mac, sizeof (Token->DstMac));

    //
    // Insert the tx token before transmitting it via MNP as the FrameSentDpc
    // may be called before Mnp->Transmit returns which will remove this tx
    // token from the SentFrames list. Remove it from the list if the returned
    // Status of Mnp->Transmit is not EFI_SUCCESS as in this case the
    // FrameSentDpc won't be queued.
    //
    InsertTailList (&Interface->SentFrames, &Token->Link);

    Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);
    if (EFI_ERROR (Status)) {
      RemoveEntryList (&Token->Link);
      Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context);

      Ip4FreeLinkTxToken (Token);
      continue;
    }
  }

ON_EXIT:
  Ip4FreeArpQue (ArpQue, IoStatus);
}

/**
  Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK.

  @param  Event             The Arp request event.
  @param  Context           The context of the callback, a point to the ARP
                            queue.

**/
VOID
EFIAPI
Ip4OnArpResolved (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip4OnArpResolvedDpc, Context);
}

/**
  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 is point to the token.

**/
VOID
EFIAPI
Ip4OnFrameSentDpc (
  IN VOID  *Context
  )
{
  IP4_LINK_TX_TOKEN  *Token;

  Token = (IP4_LINK_TX_TOKEN *)Context;
  NET_CHECK_SIGNATURE (Token, IP4_FRAME_TX_SIGNATURE);

  RemoveEntryList (&Token->Link);

  Token->CallBack (
           Token->IpInstance,
           Token->Packet,
           Token->MnpToken.Status,
           0,
           Token->Context
           );

  Ip4FreeLinkTxToken (Token);
}

/**
  Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK.

  @param[in]  Event              The transmit token's event.
  @param[in]  Context            Context which is point to the token.

**/
VOID
EFIAPI
Ip4OnFrameSent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip4OnFrameSentDpc, Context);
}

/**
  Send a frame from the interface. If the next hop is broadcast or
  multicast address, it is transmitted immediately. If the next hop
  is a unicast, it will consult ARP to resolve the NextHop's MAC.
  If some error happened, 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 IP4 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 call back.
  @param[in]  IpSb              The pointer to the IP4 service binding instance.

  @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 is successfully transmitted.
  @retval other                 Other error occurs.

**/
EFI_STATUS
Ip4SendFrame (
  IN  IP4_INTERFACE       *Interface,
  IN  IP4_PROTOCOL        *IpInstance       OPTIONAL,
  IN  NET_BUF             *Packet,
  IN  IP4_ADDR            NextHop,
  IN  IP4_FRAME_CALLBACK  CallBack,
  IN  VOID                *Context,
  IN IP4_SERVICE          *IpSb
  )
{
  IP4_LINK_TX_TOKEN  *Token;
  LIST_ENTRY         *Entry;
  IP4_ARP_QUE        *ArpQue;
  EFI_ARP_PROTOCOL   *Arp;
  EFI_STATUS         Status;

  ASSERT (Interface->Configured);

  Token = Ip4WrapLinkTxToken (Interface, IpInstance, Packet, CallBack, Context, IpSb);

  if (Token == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get the destination MAC address for multicast and broadcasts.
  // Don't depend on ARP to solve the address since there maybe no
  // ARP at all. Ip4Output has set NextHop to 255.255.255.255 for
  // all the broadcasts.
  //
  if (NextHop == IP4_ALLONE_ADDRESS) {
    CopyMem (&Token->DstMac, &Interface->BroadcastMac, sizeof (Token->DstMac));
    goto SEND_NOW;
  } else if (IP4_IS_MULTICAST (NextHop)) {
    Status = Ip4GetMulticastMac (Interface->Mnp, NextHop, &Token->DstMac);

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    goto SEND_NOW;
  }

  //
  // Can only send out multicast/broadcast if the IP address is zero
  //
  if ((Arp = Interface->Arp) == NULL) {
    Status = EFI_NO_MAPPING;
    goto ON_ERROR;
  }

  //
  // First check whether this binding is in the ARP cache.
  //
  NextHop = HTONL (NextHop);
  Status  = Arp->Request (Arp, &NextHop, NULL, &Token->DstMac);

  if (Status == EFI_SUCCESS) {
    goto SEND_NOW;
  } else if (Status != EFI_NOT_READY) {
    goto ON_ERROR;
  }

  //
  // Have to do asynchronous ARP resolution. First check
  // whether there is already a pending request.
  //
  ArpQue = NULL;

  NET_LIST_FOR_EACH (Entry, &Interface->ArpQues) {
    ArpQue = NET_LIST_USER_STRUCT (Entry, IP4_ARP_QUE, Link);

    if (ArpQue->Ip == NextHop) {
      break;
    }
  }

  //
  // Found a pending ARP request, enqueue the frame then return
  //
  if (Entry != &Interface->ArpQues) {
    InsertTailList (&ArpQue->Frames, &Token->Link);
    return EFI_SUCCESS;
  }

  //
  // First frame to NextHop, issue an asynchronous ARP requests
  //
  ArpQue = Ip4CreateArpQue (Interface, NextHop);

  if (ArpQue == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  Status = Arp->Request (Arp, &ArpQue->Ip, ArpQue->OnResolved, ArpQue->Mac.Addr);

  if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
    Ip4FreeArpQue (ArpQue, EFI_NO_MAPPING);
    goto ON_ERROR;
  }

  InsertHeadList (&ArpQue->Frames, &Token->Link);
  InsertHeadList (&Interface->ArpQues, &ArpQue->Link);
  return EFI_SUCCESS;

SEND_NOW:
  //
  // 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 = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);
  if (EFI_ERROR (Status)) {
    RemoveEntryList (&Token->Link);
    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:
  Ip4FreeLinkTxToken (Token);
  return Status;
}

/**
  Call back function when the received packet is freed.
  Check Ip4OnFrameReceived for information.

  @param  Context          Context, which is the IP4_LINK_RX_TOKEN.

**/
VOID
EFIAPI
Ip4RecycleFrame (
  IN VOID  *Context
  )
{
  IP4_LINK_RX_TOKEN  *Frame;

  Frame = (IP4_LINK_RX_TOKEN *)Context;
  NET_CHECK_SIGNATURE (Frame, IP4_FRAME_RX_SIGNATURE);

  gBS->SignalEvent (Frame->MnpToken.Packet.RxData->RecycleEvent);
  Ip4FreeFrameRxToken (Frame);
}

/**
  Received a frame from MNP, wrap it in net buffer then deliver
  it to IP's input function. The ownship of the packet also
  transferred to IP. When Ip is finished with this packet, it
  will call NetbufFree to release the packet, NetbufFree will
  again call the Ip4RecycleFrame to signal MNP's event and free
  the token used.

  @param  Context               Context for the callback.

**/
VOID
EFIAPI
Ip4OnFrameReceivedDpc (
  IN VOID  *Context
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *MnpToken;
  EFI_MANAGED_NETWORK_RECEIVE_DATA      *MnpRxData;
  IP4_LINK_RX_TOKEN                     *Token;
  NET_FRAGMENT                          Netfrag;
  NET_BUF                               *Packet;
  UINT32                                Flag;

  Token = (IP4_LINK_RX_TOKEN *)Context;
  NET_CHECK_SIGNATURE (Token, IP4_FRAME_RX_SIGNATURE);

  //
  // First clear the interface's receive request in case the
  // caller wants to call Ip4ReceiveFrame in the callback.
  //
  Token->Interface->RecvRequest = NULL;

  MnpToken  = &Token->MnpToken;
  MnpRxData = MnpToken->Packet.RxData;

  if (EFI_ERROR (MnpToken->Status) || (MnpRxData == NULL)) {
    Token->CallBack (Token->IpInstance, NULL, MnpToken->Status, 0, Token->Context);
    Ip4FreeFrameRxToken (Token);

    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, 0, IP4_MAX_HEADLEN, Ip4RecycleFrame, Token);

  if (Packet == NULL) {
    gBS->SignalEvent (MnpRxData->RecycleEvent);

    Token->CallBack (Token->IpInstance, NULL, EFI_OUT_OF_RESOURCES, 0, Token->Context);
    Ip4FreeFrameRxToken (Token);

    return;
  }

  Flag  = (MnpRxData->BroadcastFlag ? IP4_LINK_BROADCAST : 0);
  Flag |= (MnpRxData->MulticastFlag ? IP4_LINK_MULTICAST : 0);
  Flag |= (MnpRxData->PromiscuousFlag ? IP4_LINK_PROMISC : 0);

  Token->CallBack (Token->IpInstance, Packet, EFI_SUCCESS, Flag, Token->Context);
}

/**
  Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK.

  @param Event      The receive event delivered to MNP for receive.
  @param Context    Context for the callback.

**/
VOID
EFIAPI
Ip4OnFrameReceived (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  //
  // Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK
  //
  QueueDpc (TPL_CALLBACK, Ip4OnFrameReceivedDpc, Context);
}

/**
  Request to receive the packet from the interface.

  @param[in]  Interface         The interface to receive the frames from.
  @param[in]  IpInstance        The instance that requests the receive. NULL for
                                the driver itself.
  @param[in]  CallBack          Function to call when receive finished.
  @param[in]  Context           Opaque parameter to the callback.

  @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.
  @retval other                 Other error occurs.

**/
EFI_STATUS
Ip4ReceiveFrame (
  IN  IP4_INTERFACE       *Interface,
  IN  IP4_PROTOCOL        *IpInstance       OPTIONAL,
  IN  IP4_FRAME_CALLBACK  CallBack,
  IN  VOID                *Context
  )
{
  IP4_LINK_RX_TOKEN  *Token;
  EFI_STATUS         Status;

  NET_CHECK_SIGNATURE (Interface, IP4_INTERFACE_SIGNATURE);

  if (Interface->RecvRequest != NULL) {
    return EFI_ALREADY_STARTED;
  }

  Token = Ip4CreateLinkRxToken (Interface, IpInstance, CallBack, Context);

  if (Token == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Interface->RecvRequest = Token;
  Status                 = Interface->Mnp->Receive (Interface->Mnp, &Token->MnpToken);
  if (EFI_ERROR (Status)) {
    Interface->RecvRequest = NULL;
    Ip4FreeFrameRxToken (Token);
    return Status;
  }

  return EFI_SUCCESS;
}
