/** @file
  Udp6 driver's whole implementation.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Udp6Impl.h"

UINT16  mUdp6RandomPort;

/**
  This function checks and timeouts the I/O datagrams holding by the corresponding
  service context.

  @param[in]  Event              The event this function is registered to.
  @param[in]  Context            The context data registered during the creation of
                                 the Event.

**/
VOID
EFIAPI
Udp6CheckTimeout (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  This function finds the udp instance by the specified <Address, Port> pair.

  @param[in]  InstanceList       Pointer to the head of the list linking the udp
                                 instances.
  @param[in]  Address            Pointer to the specified IPv6 address.
  @param[in]  Port               The udp port number.

  @retval TRUE     The specified <Address, Port> pair is found.
  @retval FALSE    Otherwise.

**/
BOOLEAN
Udp6FindInstanceByPort (
  IN LIST_ENTRY        *InstanceList,
  IN EFI_IPv6_ADDRESS  *Address,
  IN UINT16            Port
  );

/**
  This function is the packet transmitting notify function registered to the IpIo
  interface. It's called to signal the udp TxToken when the IpIo layer completes
  transmitting of the udp datagram.

  If Context is NULL, then ASSERT().
  If NotifyData is NULL, then ASSERT().

  @param[in]  Status            The completion status of the output udp datagram.
  @param[in]  Context           Pointer to the context data.
  @param[in]  Sender            Specify a EFI_IP6_PROTOCOL for sending.
  @param[in]  NotifyData        Pointer to the notify data.

**/
VOID
EFIAPI
Udp6DgramSent (
  IN EFI_STATUS         Status,
  IN VOID               *Context,
  IN IP_IO_IP_PROTOCOL  Sender,
  IN VOID               *NotifyData
  );

/**
  This function processes the received datagram passed up by the IpIo layer.

  If NetSession is NULL, then ASSERT().
  If Packet is NULL, then ASSERT().
  If Context is NULL, then ASSERT().

  @param[in]  Status            The status of this udp datagram.
  @param[in]  IcmpError         The IcmpError code, only available when Status is
                                EFI_ICMP_ERROR.
  @param[in]  NetSession        Pointer to the EFI_NET_SESSION_DATA.
  @param[in]  Packet            Pointer to the NET_BUF containing the received udp
                                datagram.
  @param[in]  Context           Pointer to the context data.

**/
VOID
EFIAPI
Udp6DgramRcvd (
  IN EFI_STATUS            Status,
  IN UINT8                 IcmpError,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN NET_BUF               *Packet,
  IN VOID                  *Context
  );

/**
  This function cancel the token specified by Arg in the Map.

  @param[in]  Map             Pointer to the NET_MAP.
  @param[in]  Item            Pointer to the NET_MAP_ITEM.
  @param[in]  Arg             Pointer to the token to be cancelled, if NULL, all
                              the tokens in this Map will be cancelled.
                              This parameter is optional and may be NULL.

  @retval EFI_SUCCESS         The token is cancelled if Arg is NULL or the token
                              is not the same as that in the Item if Arg is not
                              NULL.
  @retval EFI_ABORTED         Arg is not NULL, and the token specified by Arg is
                              cancelled.

**/
EFI_STATUS
EFIAPI
Udp6CancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg OPTIONAL
  );

/**
  This function check if the received udp datagram matches with the Instance.

  @param[in]  Instance           Pointer to the udp instance context data.
  @param[in]  Udp6Session        Pointer to the EFI_UDP6_SESSION_DATA abstracted
                                 from the received udp datagram.

  @retval TRUE     The udp datagram matches the receiving requirements of the Instance.
  @retval FALSE    The udp datagram doe not match the receiving requirements of the Instance.

**/
BOOLEAN
Udp6MatchDgram (
  IN UDP6_INSTANCE_DATA     *Instance,
  IN EFI_UDP6_SESSION_DATA  *Udp6Session
  );

/**
  This function removes the Wrap specified by Context and releases relevant resources.

  @param[in]  Event                  The Event this notify function is registered to.
  @param[in]  Context                Pointer to the context data.

**/
VOID
EFIAPI
Udp6RecycleRxDataWrap (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  This function wraps the Packet into RxData.

  @param[in]  Instance           Pointer to the instance context data.
  @param[in]  Packet             Pointer to the buffer containing the received
                                 datagram.
  @param[in]  RxData             Pointer to the EFI_UDP6_RECEIVE_DATA of this
                                 datagram.

  @return Pointer to the structure wrapping the RxData and the Packet. NULL will
          be returned if any error occurs.

**/
UDP6_RXDATA_WRAP *
Udp6WrapRxData (
  IN UDP6_INSTANCE_DATA     *Instance,
  IN NET_BUF                *Packet,
  IN EFI_UDP6_RECEIVE_DATA  *RxData
  );

/**
  This function enqueues the received datagram into the instances' receiving queues.

  @param[in]  Udp6Service        Pointer to the udp service context data.
  @param[in]  Packet             Pointer to the buffer containing the received
                                 datagram.
  @param[in]  RxData             Pointer to the EFI_UDP6_RECEIVE_DATA of this
                                 datagram.

  @return The times this datagram is enqueued.

**/
UINTN
Udp6EnqueueDgram (
  IN UDP6_SERVICE_DATA      *Udp6Service,
  IN NET_BUF                *Packet,
  IN EFI_UDP6_RECEIVE_DATA  *RxData
  );

/**
  This function delivers the datagrams enqueued in the instances.

  @param[in]  Udp6Service            Pointer to the udp service context data.

**/
VOID
Udp6DeliverDgram (
  IN UDP6_SERVICE_DATA  *Udp6Service
  );

/**
  This function demultiplexes the received udp datagram to the appropriate instances.

  @param[in]  Udp6Service        Pointer to the udp service context data.
  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA abstracted from
                                 the received datagram.
  @param[in]  Packet             Pointer to the buffer containing the received udp
                                 datagram.

**/
VOID
Udp6Demultiplex (
  IN UDP6_SERVICE_DATA     *Udp6Service,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN NET_BUF               *Packet
  );

/**
  This function handles the received Icmp Error message and demultiplexes it to the
  instance.

  @param[in]       Udp6Service        Pointer to the udp service context data.
  @param[in]       IcmpError          The icmp error code.
  @param[in]       NetSession         Pointer to the EFI_NET_SESSION_DATA abstracted
                                      from the received Icmp Error packet.
  @param[in, out]  Packet             Pointer to the Icmp Error packet.

**/
VOID
Udp6IcmpHandler (
  IN UDP6_SERVICE_DATA     *Udp6Service,
  IN UINT8                 IcmpError,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN OUT NET_BUF           *Packet
  );

/**
  This function builds and sends out a icmp port unreachable message.

  @param[in]  IpIo               Pointer to the IP_IO instance.
  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA of the packet
                                 causes this icmp error message.
  @param[in]  Udp6Header         Pointer to the udp header of the datagram causes
                                 this icmp error message.

**/
VOID
Udp6SendPortUnreach (
  IN IP_IO                 *IpIo,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN VOID                  *Udp6Header
  );

/**
  Find the key in the netmap

  @param[in]  Map                    The netmap to search within.
  @param[in]  Key                    The key to search.

  @return The point to the item contains the Key, or NULL if Key isn't in the map.

**/
NET_MAP_ITEM *
Udp6MapMultiCastAddr (
  IN  NET_MAP  *Map,
  IN  VOID     *Key
  );

/**
  Create the Udp service context data.

  @param[in]  Udp6Service        Pointer to the UDP6_SERVICE_DATA.
  @param[in]  ImageHandle        The image handle of this udp6 driver.
  @param[in]  ControllerHandle   The controller handle this udp6 driver binds on.

  @retval EFI_SUCCESS            The udp6 service context data was created and
                                 initialized.
  @retval EFI_OUT_OF_RESOURCES   Cannot allocate memory.
  @retval Others                 An error condition occurred.

**/
EFI_STATUS
Udp6CreateService (
  IN UDP6_SERVICE_DATA  *Udp6Service,
  IN EFI_HANDLE         ImageHandle,
  IN EFI_HANDLE         ControllerHandle
  )
{
  EFI_STATUS       Status;
  IP_IO_OPEN_DATA  OpenData;

  ZeroMem (Udp6Service, sizeof (UDP6_SERVICE_DATA));

  Udp6Service->Signature        = UDP6_SERVICE_DATA_SIGNATURE;
  Udp6Service->ServiceBinding   = mUdp6ServiceBinding;
  Udp6Service->ImageHandle      = ImageHandle;
  Udp6Service->ControllerHandle = ControllerHandle;
  Udp6Service->ChildrenNumber   = 0;

  InitializeListHead (&Udp6Service->ChildrenList);

  //
  // Create the IpIo for this service context.
  //
  Udp6Service->IpIo = IpIoCreate (ImageHandle, ControllerHandle, IP_VERSION_6);
  if (Udp6Service->IpIo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Set the OpenData used to open the IpIo.
  //
  CopyMem (
    &OpenData.IpConfigData.Ip6CfgData,
    &mIp6IoDefaultIpConfigData,
    sizeof (EFI_IP6_CONFIG_DATA)
    );
  OpenData.RcvdContext   = (VOID *)Udp6Service;
  OpenData.SndContext    = NULL;
  OpenData.PktRcvdNotify = Udp6DgramRcvd;
  OpenData.PktSentNotify = Udp6DgramSent;

  //
  // Configure and start the IpIo.
  //
  Status = IpIoOpen (Udp6Service->IpIo, &OpenData);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create the event for Udp timeout checking.
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  Udp6CheckTimeout,
                  Udp6Service,
                  &Udp6Service->TimeoutEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Start the timeout timer event.
  //
  Status = gBS->SetTimer (
                  Udp6Service->TimeoutEvent,
                  TimerPeriodic,
                  UDP6_TIMEOUT_INTERVAL
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (Udp6Service->TimeoutEvent != NULL) {
    gBS->CloseEvent (Udp6Service->TimeoutEvent);
  }

  IpIoDestroy (Udp6Service->IpIo);
  Udp6Service->IpIo = NULL;

  return Status;
}

/**
  Clean the Udp service context data.

  @param[in, out]  Udp6Service      Pointer to the UDP6_SERVICE_DATA.

**/
VOID
Udp6CleanService (
  IN OUT UDP6_SERVICE_DATA  *Udp6Service
  )
{
  //
  // Close the TimeoutEvent timer.
  //
  gBS->CloseEvent (Udp6Service->TimeoutEvent);

  //
  // Destroy the IpIo.
  //
  IpIoDestroy (Udp6Service->IpIo);
  Udp6Service->IpIo = NULL;

  ZeroMem (Udp6Service, sizeof (UDP6_SERVICE_DATA));
}

/**
  This function checks and times out the I/O datagrams listed in the
  UDP6_SERVICE_DATA which is specified by the input parameter Context.


  @param[in]  Event              The event this function registered to.
  @param[in]  Context            The context data registered during the creation of
                                 the Event.

**/
VOID
EFIAPI
Udp6CheckTimeout (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  UDP6_SERVICE_DATA   *Udp6Service;
  LIST_ENTRY          *Entry;
  UDP6_INSTANCE_DATA  *Instance;
  LIST_ENTRY          *WrapEntry;
  LIST_ENTRY          *NextEntry;
  UDP6_RXDATA_WRAP    *Wrap;

  Udp6Service = (UDP6_SERVICE_DATA *)Context;
  NET_CHECK_SIGNATURE (Udp6Service, UDP6_SERVICE_DATA_SIGNATURE);

  NET_LIST_FOR_EACH (Entry, &Udp6Service->ChildrenList) {
    //
    // Iterate all the instances belonging to this service context.
    //
    Instance = NET_LIST_USER_STRUCT (Entry, UDP6_INSTANCE_DATA, Link);
    NET_CHECK_SIGNATURE (Instance, UDP6_INSTANCE_DATA_SIGNATURE);

    if (!Instance->Configured || (Instance->ConfigData.ReceiveTimeout == 0)) {
      //
      // Skip this instance if it's not configured or no receive timeout.
      //
      continue;
    }

    NET_LIST_FOR_EACH_SAFE (WrapEntry, NextEntry, &Instance->RcvdDgramQue) {
      //
      // Iterate all the rxdatas belonging to this udp instance.
      //
      Wrap = NET_LIST_USER_STRUCT (WrapEntry, UDP6_RXDATA_WRAP, Link);

      if (Wrap->TimeoutTick < UDP6_TIMEOUT_INTERVAL / 10) {
        //
        // Remove this RxData if it timeouts.
        //
        Udp6RecycleRxDataWrap (NULL, (VOID *)Wrap);
      } else {
        Wrap->TimeoutTick -= UDP6_TIMEOUT_INTERVAL / 10;
      }
    }
  }
}

/**
  This function initializes the new created udp instance.

  @param[in]       Udp6Service      Pointer to the UDP6_SERVICE_DATA.
  @param[in, out]  Instance         Pointer to the un-initialized UDP6_INSTANCE_DATA.

**/
VOID
Udp6InitInstance (
  IN UDP6_SERVICE_DATA       *Udp6Service,
  IN OUT UDP6_INSTANCE_DATA  *Instance
  )
{
  //
  // Set the signature.
  //
  Instance->Signature = UDP6_INSTANCE_DATA_SIGNATURE;

  //
  // Init the lists.
  //
  InitializeListHead (&Instance->Link);
  InitializeListHead (&Instance->RcvdDgramQue);
  InitializeListHead (&Instance->DeliveredDgramQue);

  //
  // Init the NET_MAPs.
  //
  NetMapInit (&Instance->TxTokens);
  NetMapInit (&Instance->RxTokens);
  NetMapInit (&Instance->McastIps);

  //
  // Save the pointer to the UDP6_SERVICE_DATA, and initialize other members.
  //
  Instance->Udp6Service = Udp6Service;
  CopyMem (&Instance->Udp6Proto, &mUdp6Protocol, sizeof (EFI_UDP6_PROTOCOL));
  Instance->IcmpError   = EFI_SUCCESS;
  Instance->Configured  = FALSE;
  Instance->IsNoMapping = FALSE;
  Instance->InDestroy   = FALSE;
}

/**
  This function cleans the udp instance.

  @param[in, out]  Instance       Pointer to the UDP6_INSTANCE_DATA to clean.

**/
VOID
Udp6CleanInstance (
  IN OUT UDP6_INSTANCE_DATA  *Instance
  )
{
  NetMapClean (&Instance->McastIps);
  NetMapClean (&Instance->RxTokens);
  NetMapClean (&Instance->TxTokens);
}

/**
  This function finds the udp instance by the specified <Address, Port> pair.

  @param[in]  InstanceList       Pointer to the head of the list linking the udp
                                 instances.
  @param[in]  Address            Pointer to the specified IPv6 address.
  @param[in]  Port               The udp port number.

  @retval TRUE     The specified <Address, Port> pair is found.
  @retval FALSE    Otherwise.

**/
BOOLEAN
Udp6FindInstanceByPort (
  IN LIST_ENTRY        *InstanceList,
  IN EFI_IPv6_ADDRESS  *Address,
  IN UINT16            Port
  )
{
  LIST_ENTRY            *Entry;
  UDP6_INSTANCE_DATA    *Instance;
  EFI_UDP6_CONFIG_DATA  *ConfigData;

  NET_LIST_FOR_EACH (Entry, InstanceList) {
    //
    // Iterate all the udp instances.
    //
    Instance   = NET_LIST_USER_STRUCT (Entry, UDP6_INSTANCE_DATA, Link);
    ConfigData = &Instance->ConfigData;

    if (!Instance->Configured || ConfigData->AcceptAnyPort) {
      //
      // If the instance is not configured, or the configdata of the instance indicates
      // this instance accepts any port, skip it.
      //
      continue;
    }

    if (EFI_IP6_EQUAL (&ConfigData->StationAddress, Address) &&
        (ConfigData->StationPort == Port)
        )
    {
      //
      // If both the address and the port are the same, return TRUE.
      //
      return TRUE;
    }
  }

  //
  // Return FALSE when matching fails.
  //
  return FALSE;
}

/**
  This function tries to bind the udp instance according to the configured port
  allocation strategy.

  @param[in]  InstanceList       Pointer to the head of the list linking the udp
                                 instances.
  @param[in]  ConfigData         Pointer to the ConfigData of the instance to be
                                 bound.

  @retval EFI_SUCCESS            The bound operation completed successfully.
  @retval EFI_ACCESS_DENIED      The <Address, Port> specified by the ConfigData is
                                 already used by other instance.
  @retval EFI_OUT_OF_RESOURCES   No available port resources.

**/
EFI_STATUS
Udp6Bind (
  IN LIST_ENTRY            *InstanceList,
  IN EFI_UDP6_CONFIG_DATA  *ConfigData
  )
{
  EFI_IPv6_ADDRESS  *StationAddress;
  UINT16            StartPort;

  if (ConfigData->AcceptAnyPort) {
    return EFI_SUCCESS;
  }

  StationAddress = &ConfigData->StationAddress;

  if (ConfigData->StationPort != 0) {
    if (!ConfigData->AllowDuplicatePort &&
        Udp6FindInstanceByPort (InstanceList, StationAddress, ConfigData->StationPort)
        )
    {
      //
      // Do not allow duplicate ports and the port is already used by other instance.
      //
      return EFI_ACCESS_DENIED;
    }
  } else {
    //
    // Select a random port for this instance.
    //
    if (ConfigData->AllowDuplicatePort) {
      //
      // Just pick up the random port if the instance allows duplicate port.
      //
      ConfigData->StationPort = mUdp6RandomPort;
    } else {
      StartPort = mUdp6RandomPort;

      while (Udp6FindInstanceByPort (InstanceList, StationAddress, mUdp6RandomPort)) {
        mUdp6RandomPort++;
        if (mUdp6RandomPort == 0) {
          mUdp6RandomPort = UDP6_PORT_KNOWN;
        }

        if (mUdp6RandomPort == StartPort) {
          //
          // No available port.
          //
          return EFI_OUT_OF_RESOURCES;
        }
      }

      ConfigData->StationPort = mUdp6RandomPort;
    }

    mUdp6RandomPort++;
    if (mUdp6RandomPort == 0) {
      mUdp6RandomPort = UDP6_PORT_KNOWN;
    }
  }

  return EFI_SUCCESS;
}

/**
  This function is used to check whether the NewConfigData has any un-reconfigurable
  parameters changed compared to the OldConfigData.

  @param[in]  OldConfigData    Pointer to the current ConfigData the udp instance
                               uses.
  @param[in]  NewConfigData    Pointer to the new ConfigData.

  @retval TRUE     The instance is reconfigurable according to the NewConfigData.
  @retval FALSE    Otherwise.

**/
BOOLEAN
Udp6IsReconfigurable (
  IN EFI_UDP6_CONFIG_DATA  *OldConfigData,
  IN EFI_UDP6_CONFIG_DATA  *NewConfigData
  )
{
  if ((NewConfigData->AcceptAnyPort != OldConfigData->AcceptAnyPort) ||
      (NewConfigData->AcceptPromiscuous != OldConfigData->AcceptPromiscuous) ||
      (NewConfigData->AllowDuplicatePort != OldConfigData->AllowDuplicatePort)
      )
  {
    //
    // The receiving filter parameters cannot be changed.
    //
    return FALSE;
  }

  if ((!NewConfigData->AcceptAnyPort) &&
      (NewConfigData->StationPort != OldConfigData->StationPort)
      )
  {
    //
    // The port is not changeable.
    //
    return FALSE;
  }

  if (!EFI_IP6_EQUAL (&NewConfigData->StationAddress, &OldConfigData->StationAddress)) {
    //
    //  The StationAddress is not the same.
    //
    return FALSE;
  }

  if (!EFI_IP6_EQUAL (&NewConfigData->RemoteAddress, &OldConfigData->RemoteAddress)) {
    //
    // The remoteaddress is not the same.
    //
    return FALSE;
  }

  if (!NetIp6IsUnspecifiedAddr (&NewConfigData->RemoteAddress) &&
      (NewConfigData->RemotePort != OldConfigData->RemotePort)
      )
  {
    //
    // The RemotePort differs if it's designated in the configdata.
    //
    return FALSE;
  }

  //
  // All checks pass, return TRUE.
  //
  return TRUE;
}

/**
  This function builds the Ip6 configdata from the Udp6ConfigData.

  @param[in]       Udp6ConfigData         Pointer to the EFI_UDP6_CONFIG_DATA.
  @param[in, out]  Ip6ConfigData          Pointer to the EFI_IP6_CONFIG_DATA.

**/
VOID
Udp6BuildIp6ConfigData (
  IN EFI_UDP6_CONFIG_DATA     *Udp6ConfigData,
  IN OUT EFI_IP6_CONFIG_DATA  *Ip6ConfigData
  )
{
  CopyMem (
    Ip6ConfigData,
    &mIp6IoDefaultIpConfigData,
    sizeof (EFI_IP6_CONFIG_DATA)
    );
  Ip6ConfigData->DefaultProtocol   = EFI_IP_PROTO_UDP;
  Ip6ConfigData->AcceptPromiscuous = Udp6ConfigData->AcceptPromiscuous;
  IP6_COPY_ADDRESS (&Ip6ConfigData->StationAddress, &Udp6ConfigData->StationAddress);
  IP6_COPY_ADDRESS (&Ip6ConfigData->DestinationAddress, &Udp6ConfigData->RemoteAddress);
  //
  // Use the -1 magic number to disable the receiving process of the ip instance.
  //
  Ip6ConfigData->ReceiveTimeout = (UINT32)(-1);
}

/**
  This function validates the TxToken. It returns the error code according to the spec.

  @param[in]  Instance           Pointer to the udp instance context data.
  @param[in]  TxToken            Pointer to the token to be checked.

  @retval EFI_SUCCESS            The TxToken is valid.
  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                 Token.Event is NULL;
                                 Token.Packet.TxData is NULL;
                                 Token.Packet.TxData.FragmentCount is zero;
                                 Token.Packet.TxData.DataLength is not equal to the
                                 sum of fragment lengths;
                                 One or more of the
                                 Token.Packet.TxData.FragmentTable[].FragmentLength
                                 fields is zero;
                                 One or more of the
                                 Token.Packet.TxData.FragmentTable[].FragmentBuffer
                                 fields is NULL;
                                 UdpSessionData.DestinationAddress are not valid
                                 unicast IPv6 addresses if the UdpSessionData is
                                 not NULL;
                                 UdpSessionData.DestinationPort and
                                 ConfigData.RemotePort are all zero if the
                                 UdpSessionData is not NULL.
  @retval EFI_BAD_BUFFER_SIZE    The data length is greater than the maximum UDP
                                 packet size.

**/
EFI_STATUS
Udp6ValidateTxToken (
  IN UDP6_INSTANCE_DATA         *Instance,
  IN EFI_UDP6_COMPLETION_TOKEN  *TxToken
  )
{
  EFI_UDP6_TRANSMIT_DATA  *TxData;
  UINT32                  Index;
  UINT32                  TotalLen;
  EFI_UDP6_CONFIG_DATA    *ConfigData;
  EFI_UDP6_SESSION_DATA   *UdpSessionData;

  if (TxToken->Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  TxData = TxToken->Packet.TxData;

  if ((TxData == NULL) || (TxData->FragmentCount == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  TotalLen = 0;
  for (Index = 0; Index < TxData->FragmentCount; Index++) {
    if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
        (TxData->FragmentTable[Index].FragmentLength == 0)
        )
    {
      //
      // If the FragmentBuffer is NULL, or the FragmentLeng is zero.
      //
      return EFI_INVALID_PARAMETER;
    }

    TotalLen += TxData->FragmentTable[Index].FragmentLength;
  }

  if (TotalLen != TxData->DataLength) {
    //
    // The TotalLen calculated by adding all the FragmentLeng doesn't equal to the
    // DataLength.
    //
    return EFI_INVALID_PARAMETER;
  }

  ConfigData     = &Instance->ConfigData;
  UdpSessionData = TxData->UdpSessionData;

  if (UdpSessionData != NULL) {
    if ((UdpSessionData->DestinationPort == 0) && (ConfigData->RemotePort == 0)) {
      //
      // Ambiguous; no available DestinationPort for this token.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (NetIp6IsUnspecifiedAddr (&UdpSessionData->DestinationAddress) &&
        NetIp6IsUnspecifiedAddr (&ConfigData->RemoteAddress)
        )
    {
      //
      // The DestinationAddress is not specified.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (!NetIp6IsUnspecifiedAddr (&UdpSessionData->DestinationAddress) &&
        !NetIp6IsUnspecifiedAddr (&ConfigData->RemoteAddress)
        )
    {
      //
      // The ConfigData.RemoteAddress is not zero and the UdpSessionData.DestinationAddress
      // is not zero too.
      //
      return EFI_INVALID_PARAMETER;
    }
  } else if (NetIp6IsUnspecifiedAddr (&ConfigData->RemoteAddress)) {
    //
    // The configured RemoteAddress is all zero, and the user doesn't override the
    // destination address.
    //
    return EFI_INVALID_PARAMETER;
  }

  if (TxData->DataLength > UDP6_MAX_DATA_SIZE) {
    return EFI_BAD_BUFFER_SIZE;
  }

  return EFI_SUCCESS;
}

/**
  This function checks whether the specified Token duplicates the one in the Map.

  @param[in]  Map                Pointer to the NET_MAP.
  @param[in]  Item               Pointer to the NET_MAP_ITEM contain the pointer to
                                 the Token.
  @param[in]  Context            Pointer to the Token to be checked.

  @retval EFI_SUCCESS            The Token specified by Context differs from the
                                 one in the Item.
  @retval EFI_ACCESS_DENIED      The Token duplicates with the one in the Item.

**/
EFI_STATUS
EFIAPI
Udp6TokenExist (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Context
  )
{
  EFI_UDP6_COMPLETION_TOKEN  *Token;
  EFI_UDP6_COMPLETION_TOKEN  *TokenInItem;

  Token       = (EFI_UDP6_COMPLETION_TOKEN *)Context;
  TokenInItem = (EFI_UDP6_COMPLETION_TOKEN *)Item->Key;

  if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
    //
    // The Token duplicates with the TokenInItem in case either the two pointers are the
    // same, or the Events of these two tokens are the same.
    //
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  This function calculates the checksum for the Packet, utilizing the pre-calculated
  pseudo HeadSum to reduce some overhead.

  @param[in]  Packet           Pointer to the NET_BUF contains the udp datagram.
  @param[in]  HeadSum          Checksum of the pseudo header, except the length
                               field.

  @return The 16-bit checksum of this udp datagram.

**/
UINT16
Udp6Checksum (
  IN NET_BUF  *Packet,
  IN UINT16   HeadSum
  )
{
  UINT16  Checksum;

  Checksum = NetbufChecksum (Packet);
  Checksum = NetAddChecksum (Checksum, HeadSum);

  Checksum = NetAddChecksum (Checksum, HTONS ((UINT16)Packet->TotalSize));
  Checksum = (UINT16)(~Checksum);
  return Checksum;
}

/**
  This function removes the specified Token from the TokenMap.

  @param[in]  TokenMap           Pointer to the NET_MAP containing the tokens.
  @param[in]  Token              Pointer to the Token to be removed.

  @retval EFI_SUCCESS            The specified Token is removed from the TokenMap.
  @retval EFI_NOT_FOUND          The specified Token is not found in the TokenMap.

**/
EFI_STATUS
Udp6RemoveToken (
  IN NET_MAP                    *TokenMap,
  IN EFI_UDP6_COMPLETION_TOKEN  *Token
  )
{
  NET_MAP_ITEM  *Item;

  //
  // Find the Token first.
  //
  Item = NetMapFindKey (TokenMap, (VOID *)Token);

  if (Item != NULL) {
    //
    // Remove the token if it's found in the map.
    //
    NetMapRemoveItem (TokenMap, Item, NULL);

    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  This function is the packet transmitting notify function registered to the IpIo
  interface. It's called to signal the udp TxToken when IpIo layer completes the
  transmitting of the udp datagram.

  If Context is NULL, then ASSERT().
  If NotifyData is NULL, then ASSERT().

  @param[in]  Status            The completion status of the output udp datagram.
  @param[in]  Context           Pointer to the context data.
  @param[in]  Sender            Specify a EFI_IP6_PROTOCOL for sending.
  @param[in]  NotifyData        Pointer to the notify data.

**/
VOID
EFIAPI
Udp6DgramSent (
  IN EFI_STATUS         Status,
  IN VOID               *Context,
  IN IP_IO_IP_PROTOCOL  Sender,
  IN VOID               *NotifyData
  )
{
  UDP6_INSTANCE_DATA         *Instance;
  EFI_UDP6_COMPLETION_TOKEN  *Token;

  ASSERT (Context != NULL && NotifyData != NULL);

  Instance = (UDP6_INSTANCE_DATA *)Context;
  Token    = (EFI_UDP6_COMPLETION_TOKEN *)NotifyData;

  if (Udp6RemoveToken (&Instance->TxTokens, Token) == EFI_SUCCESS) {
    //
    // The token may be cancelled. Only signal it if the remove operation succeeds.
    //
    Token->Status = Status;
    gBS->SignalEvent (Token->Event);
    DispatchDpc ();
  }
}

/**
  This function processes the received datagram passed up by the IpIo layer.

  If NetSession is NULL, then ASSERT().
  If Packet is NULL, then ASSERT().
  If Context is NULL, then ASSERT().

  @param[in]  Status            The status of this udp datagram.
  @param[in]  IcmpError         The IcmpError code, only available when Status is
                                EFI_ICMP_ERROR.
  @param[in]  NetSession        Pointer to the EFI_NET_SESSION_DATA.
  @param[in]  Packet            Pointer to the NET_BUF containing the received udp
                                datagram.
  @param[in]  Context           Pointer to the context data.

**/
VOID
EFIAPI
Udp6DgramRcvd (
  IN EFI_STATUS            Status,
  IN UINT8                 IcmpError,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN NET_BUF               *Packet,
  IN VOID                  *Context
  )
{
  ASSERT (NetSession != NULL && Packet != NULL && Context != NULL);
  NET_CHECK_SIGNATURE (Packet, NET_BUF_SIGNATURE);

  //
  // IpIo only passes received packets with Status EFI_SUCCESS or EFI_ICMP_ERROR.
  //
  if (Status == EFI_SUCCESS) {
    //
    // Demultiplex the received datagram.
    //
    Udp6Demultiplex ((UDP6_SERVICE_DATA *)Context, NetSession, Packet);
  } else {
    //
    // Handle the ICMP6 Error packet.
    //
    Udp6IcmpHandler ((UDP6_SERVICE_DATA *)Context, IcmpError, NetSession, Packet);
  }

  //
  // Dispatch the DPC queued by the NotifyFunction of the rx token's events
  // that are signaled with received data.
  //
  DispatchDpc ();
}

/**
  This function removes the multicast group specified by Arg from the Map.

  @param[in]  Map                Pointer to the NET_MAP.
  @param[in]  Item               Pointer to the NET_MAP_ITEM.
  @param[in]  Arg                Pointer to the Arg, it's the pointer to a
                                 multicast IPv6 Address. This parameter is
                                 optional and may be NULL.

  @retval EFI_SUCCESS            The multicast address is removed.
  @retval EFI_ABORTED            The specified multicast address is removed, and the
                                 Arg is not NULL.

**/
EFI_STATUS
EFIAPI
Udp6LeaveGroup (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg OPTIONAL
  )
{
  EFI_IPv6_ADDRESS  *McastIp;

  McastIp = Arg;

  if ((McastIp != NULL) &&
      !EFI_IP6_EQUAL (McastIp, ((EFI_IPv6_ADDRESS *)Item->Key))
      )
  {
    //
    // McastIp is not NULL and the multicast address contained in the Item
    // is not the same as McastIp.
    //
    return EFI_SUCCESS;
  }

  FreePool (Item->Key);

  //
  // Remove this Item.
  //
  NetMapRemoveItem (Map, Item, NULL);

  if (McastIp != NULL) {
    //
    // Return EFI_ABORTED in case McastIp is not NULL to terminate the iteration.
    //
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  This function cancel the token specified by Arg in the Map.

  @param[in]  Map             Pointer to the NET_MAP.
  @param[in]  Item            Pointer to the NET_MAP_ITEM.
  @param[in]  Arg             Pointer to the token to be cancelled. If NULL, all
                              the tokens in this Map will be cancelled.
                              This parameter is optional and may be NULL.

  @retval EFI_SUCCESS         The token is cancelled if Arg is NULL, or the token
                              is not the same as that in the Item, if Arg is not
                              NULL.
  @retval EFI_ABORTED         Arg is not NULL, and the token specified by Arg is
                              cancelled.

**/
EFI_STATUS
EFIAPI
Udp6CancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg OPTIONAL
  )
{
  EFI_UDP6_COMPLETION_TOKEN  *TokenToCancel;
  NET_BUF                    *Packet;
  IP_IO                      *IpIo;

  if ((Arg != NULL) && (Item->Key != Arg)) {
    return EFI_SUCCESS;
  }

  if (Item->Value != NULL) {
    //
    // If the token is a transmit token, the corresponding Packet is recorded in
    // Item->Value, invoke IpIo to cancel this packet first. The IpIoCancelTxToken
    // will invoke Udp6DgramSent, the token will be signaled and this Item will
    // be removed from the Map there.
    //
    Packet = (NET_BUF *)(Item->Value);
    IpIo   = (IP_IO *)(*((UINTN *)&Packet->ProtoData[0]));

    IpIoCancelTxToken (IpIo, Packet);
  } else {
    //
    // The token is a receive token. Abort it and remove it from the Map.
    //
    TokenToCancel = (EFI_UDP6_COMPLETION_TOKEN *)Item->Key;
    NetMapRemoveItem (Map, Item, NULL);

    TokenToCancel->Status = EFI_ABORTED;
    gBS->SignalEvent (TokenToCancel->Event);
  }

  if (Arg != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  This function removes all the Wrap datas in the RcvdDgramQue.

  @param[in]  Instance    Pointer to the Udp6 Instance.

**/
VOID
Udp6FlushRcvdDgram (
  IN UDP6_INSTANCE_DATA  *Instance
  )
{
  UDP6_RXDATA_WRAP  *Wrap;

  while (!IsListEmpty (&Instance->RcvdDgramQue)) {
    //
    // Iterate all the Wraps in the RcvdDgramQue.
    //
    Wrap = NET_LIST_HEAD (&Instance->RcvdDgramQue, UDP6_RXDATA_WRAP, Link);

    //
    // The Wrap will be removed from the RcvdDgramQue by this function call.
    //
    Udp6RecycleRxDataWrap (NULL, (VOID *)Wrap);
  }
}

/**
  Cancel Udp6 tokens from the Udp6 instance.

  @param[in]  Instance           Pointer to the udp instance context data.
  @param[in]  Token              Pointer to the token to be canceled. If NULL, all
                                 tokens in this instance will be cancelled.
                                 This parameter is optional and may be NULL.

  @retval EFI_SUCCESS            The Token is cancelled.
  @retval EFI_NOT_FOUND          The Token is not found.

**/
EFI_STATUS
Udp6InstanceCancelToken (
  IN UDP6_INSTANCE_DATA         *Instance,
  IN EFI_UDP6_COMPLETION_TOKEN  *Token OPTIONAL
  )
{
  EFI_STATUS  Status;

  //
  // Cancel this token from the TxTokens map.
  //
  Status = NetMapIterate (&Instance->TxTokens, Udp6CancelTokens, Token);

  if ((Token != NULL) && (Status == EFI_ABORTED)) {
    //
    // If Token isn't NULL and Status is EFI_ABORTED, the token is cancelled from
    // the TxTokens and returns success.
    //
    return EFI_SUCCESS;
  }

  //
  // Try to cancel this token from the RxTokens map in condition either the Token
  // is NULL or the specified Token is not in TxTokens.
  //
  Status = NetMapIterate (&Instance->RxTokens, Udp6CancelTokens, Token);

  if ((Token != NULL) && (Status == EFI_SUCCESS)) {
    //
    // If Token isn't NULL and Status is EFI_SUCCESS, the token is neither in the
    // TxTokens nor the RxTokens, or say, it's not found.
    //
    return EFI_NOT_FOUND;
  }

  ASSERT (
    (Token != NULL) ||
    ((0 == NetMapGetCount (&Instance->TxTokens)) &&
     (0 == NetMapGetCount (&Instance->RxTokens)))
    );

  return EFI_SUCCESS;
}

/**
  This function checks if the received udp datagram matches with the Instance.

  @param[in]  Instance           Pointer to the udp instance context data.
  @param[in]  Udp6Session        Pointer to the EFI_UDP6_SESSION_DATA abstracted
                                 from the received udp datagram.

  @retval TRUE     The udp datagram matches the receiving requirements of the Instance.
  @retval FALSE    The udp datagram does not match the receiving requirements of the Instance.

**/
BOOLEAN
Udp6MatchDgram (
  IN UDP6_INSTANCE_DATA     *Instance,
  IN EFI_UDP6_SESSION_DATA  *Udp6Session
  )
{
  EFI_UDP6_CONFIG_DATA  *ConfigData;
  EFI_IPv6_ADDRESS      Destination;

  ConfigData = &Instance->ConfigData;

  if (ConfigData->AcceptPromiscuous) {
    //
    // Always matches if this instance is in the promiscuous state.
    //
    return TRUE;
  }

  if ((!ConfigData->AcceptAnyPort && (Udp6Session->DestinationPort != ConfigData->StationPort)) ||
      ((ConfigData->RemotePort != 0) && (Udp6Session->SourcePort != ConfigData->RemotePort))
      )
  {
    //
    // The local port or the remote port doesn't match.
    //
    return FALSE;
  }

  if (!NetIp6IsUnspecifiedAddr (&ConfigData->RemoteAddress) &&
      !EFI_IP6_EQUAL (&ConfigData->RemoteAddress, &Udp6Session->SourceAddress)
      )
  {
    //
    // This datagram doesn't come from the instance's specified sender.
    //
    return FALSE;
  }

  if (NetIp6IsUnspecifiedAddr (&ConfigData->StationAddress) ||
      EFI_IP6_EQUAL (&Udp6Session->DestinationAddress, &ConfigData->StationAddress)
      )
  {
    //
    // The instance is configured to receive datagrams destinated to any station IP or
    // the destination address of this datagram matches the configured station IP.
    //
    return TRUE;
  }

  IP6_COPY_ADDRESS (&Destination, &Udp6Session->DestinationAddress);

  if (IP6_IS_MULTICAST (&Destination) &&
      (NULL != Udp6MapMultiCastAddr (&Instance->McastIps, &Destination))
      )
  {
    //
    // It's a multicast packet and the multicast address is accepted by this instance.
    //
    return TRUE;
  }

  return FALSE;
}

/**
  This function removes the Wrap specified by Context and release relevant resources.

  @param[in]  Event                  The Event this notify function registered to.
  @param[in]  Context                Pointer to the context data.

**/
VOID
EFIAPI
Udp6RecycleRxDataWrap (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  UDP6_RXDATA_WRAP  *Wrap;

  Wrap = (UDP6_RXDATA_WRAP *)Context;

  //
  // Remove the Wrap from the list it belongs to.
  //
  RemoveEntryList (&Wrap->Link);

  //
  // Free the Packet associated with this Wrap.
  //
  NetbufFree (Wrap->Packet);

  //
  // Close the event.
  //
  gBS->CloseEvent (Wrap->RxData.RecycleSignal);

  FreePool (Wrap);
}

/**
  This function wraps the Packet into RxData.

  @param[in]  Instance           Pointer to the instance context data.
  @param[in]  Packet             Pointer to the buffer containing the received
                                 datagram.
  @param[in]  RxData             Pointer to the EFI_UDP6_RECEIVE_DATA of this
                                 datagram.

  @return Pointer to the structure wrapping the RxData and the Packet. NULL will
          be returned if any error occurs.

**/
UDP6_RXDATA_WRAP *
Udp6WrapRxData (
  IN UDP6_INSTANCE_DATA     *Instance,
  IN NET_BUF                *Packet,
  IN EFI_UDP6_RECEIVE_DATA  *RxData
  )
{
  EFI_STATUS        Status;
  UDP6_RXDATA_WRAP  *Wrap;

  //
  // Allocate buffer for the Wrap.
  //
  Wrap = AllocateZeroPool (
           sizeof (UDP6_RXDATA_WRAP) +
           (Packet->BlockOpNum - 1) * sizeof (EFI_UDP6_FRAGMENT_DATA)
           );
  if (Wrap == NULL) {
    return NULL;
  }

  InitializeListHead (&Wrap->Link);

  CopyMem (&Wrap->RxData, RxData, sizeof (EFI_UDP6_RECEIVE_DATA));
  //
  // Create the Recycle event.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Udp6RecycleRxDataWrap,
                  Wrap,
                  &Wrap->RxData.RecycleSignal
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Wrap);
    return NULL;
  }

  Wrap->Packet      = Packet;
  Wrap->TimeoutTick = Instance->ConfigData.ReceiveTimeout;

  return Wrap;
}

/**
  This function enqueues the received datagram into the instances' receiving queues.

  @param[in]  Udp6Service        Pointer to the udp service context data.
  @param[in]  Packet             Pointer to the buffer containing the received
                                 datagram.
  @param[in]  RxData             Pointer to the EFI_UDP6_RECEIVE_DATA of this
                                 datagram.

  @return The times this datagram is enqueued.

**/
UINTN
Udp6EnqueueDgram (
  IN UDP6_SERVICE_DATA      *Udp6Service,
  IN NET_BUF                *Packet,
  IN EFI_UDP6_RECEIVE_DATA  *RxData
  )
{
  LIST_ENTRY          *Entry;
  UDP6_INSTANCE_DATA  *Instance;
  UDP6_RXDATA_WRAP    *Wrap;
  UINTN               Enqueued;

  Enqueued = 0;

  NET_LIST_FOR_EACH (Entry, &Udp6Service->ChildrenList) {
    //
    // Iterate the instances.
    //
    Instance = NET_LIST_USER_STRUCT (Entry, UDP6_INSTANCE_DATA, Link);

    if (!Instance->Configured) {
      continue;
    }

    if (Udp6MatchDgram (Instance, &RxData->UdpSession)) {
      //
      // Wrap the RxData and put this Wrap into the instances RcvdDgramQue.
      //
      Wrap = Udp6WrapRxData (Instance, Packet, RxData);
      if (Wrap == NULL) {
        continue;
      }

      NET_GET_REF (Packet);

      InsertTailList (&Instance->RcvdDgramQue, &Wrap->Link);

      Enqueued++;
    }
  }

  return Enqueued;
}

/**
  This function delivers the received datagrams to the specified instance.

  @param[in]  Instance               Pointer to the instance context data.

**/
VOID
Udp6InstanceDeliverDgram (
  IN UDP6_INSTANCE_DATA  *Instance
  )
{
  UDP6_RXDATA_WRAP           *Wrap;
  EFI_UDP6_COMPLETION_TOKEN  *Token;
  NET_BUF                    *Dup;
  EFI_UDP6_RECEIVE_DATA      *RxData;
  EFI_TPL                    OldTpl;

  if (!IsListEmpty (&Instance->RcvdDgramQue) &&
      !NetMapIsEmpty (&Instance->RxTokens)
      )
  {
    Wrap = NET_LIST_HEAD (&Instance->RcvdDgramQue, UDP6_RXDATA_WRAP, Link);

    if (NET_BUF_SHARED (Wrap->Packet)) {
      //
      // Duplicate the Packet if it is shared between instances.
      //
      Dup = NetbufDuplicate (Wrap->Packet, NULL, 0);
      if (Dup == NULL) {
        return;
      }

      NetbufFree (Wrap->Packet);

      Wrap->Packet = Dup;
    }

    NetListRemoveHead (&Instance->RcvdDgramQue);

    Token = (EFI_UDP6_COMPLETION_TOKEN *)NetMapRemoveHead (&Instance->RxTokens, NULL);

    //
    // Build the FragmentTable and set the FragmentCount in RxData.
    //
    RxData                = &Wrap->RxData;
    RxData->FragmentCount = Wrap->Packet->BlockOpNum;

    NetbufBuildExt (
      Wrap->Packet,
      (NET_FRAGMENT *)RxData->FragmentTable,
      &RxData->FragmentCount
      );

    Token->Status        = EFI_SUCCESS;
    Token->Packet.RxData = &Wrap->RxData;

    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    InsertTailList (&Instance->DeliveredDgramQue, &Wrap->Link);
    gBS->RestoreTPL (OldTpl);

    gBS->SignalEvent (Token->Event);
  }
}

/**
  This function delivers the datagrams enqueued in the instances.

  @param[in]  Udp6Service            Pointer to the udp service context data.

**/
VOID
Udp6DeliverDgram (
  IN UDP6_SERVICE_DATA  *Udp6Service
  )
{
  LIST_ENTRY          *Entry;
  UDP6_INSTANCE_DATA  *Instance;

  NET_LIST_FOR_EACH (Entry, &Udp6Service->ChildrenList) {
    //
    // Iterate the instances.
    //
    Instance = NET_LIST_USER_STRUCT (Entry, UDP6_INSTANCE_DATA, Link);

    if (!Instance->Configured) {
      continue;
    }

    //
    // Deliver the datagrams of this instance.
    //
    Udp6InstanceDeliverDgram (Instance);
  }
}

/**
  This function demultiplexes the received udp datagram to the appropriate instances.

  @param[in]  Udp6Service        Pointer to the udp service context data.
  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA abstracted from
                                 the received datagram.
  @param[in]  Packet             Pointer to the buffer containing the received udp
                                 datagram.

**/
VOID
Udp6Demultiplex (
  IN UDP6_SERVICE_DATA     *Udp6Service,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN NET_BUF               *Packet
  )
{
  EFI_UDP_HEADER         *Udp6Header;
  UINT16                 HeadSum;
  EFI_UDP6_RECEIVE_DATA  RxData;
  EFI_UDP6_SESSION_DATA  *Udp6Session;
  UINTN                  Enqueued;

  if (Packet->TotalSize < UDP6_HEADER_SIZE) {
    NetbufFree (Packet);
    return;
  }

  //
  // Get the datagram header from the packet buffer.
  //
  Udp6Header = (EFI_UDP_HEADER *)NetbufGetByte (Packet, 0, NULL);
  ASSERT (Udp6Header != NULL);
  if (Udp6Header == NULL) {
    NetbufFree (Packet);
    return;
  }

  if (Udp6Header->Checksum != 0) {
    //
    // check the checksum.
    //
    HeadSum = NetIp6PseudoHeadChecksum (
                &NetSession->Source.v6,
                &NetSession->Dest.v6,
                EFI_IP_PROTO_UDP,
                0
                );

    if (Udp6Checksum (Packet, HeadSum) != 0) {
      //
      // Wrong checksum.
      //
      NetbufFree (Packet);
      return;
    }
  }

  Udp6Session                  = &RxData.UdpSession;
  Udp6Session->SourcePort      = NTOHS (Udp6Header->SrcPort);
  Udp6Session->DestinationPort = NTOHS (Udp6Header->DstPort);

  IP6_COPY_ADDRESS (&Udp6Session->SourceAddress, &NetSession->Source);
  IP6_COPY_ADDRESS (&Udp6Session->DestinationAddress, &NetSession->Dest);

  //
  // Trim the UDP header.
  //
  NetbufTrim (Packet, UDP6_HEADER_SIZE, TRUE);

  RxData.DataLength = (UINT32)Packet->TotalSize;

  //
  // Try to enqueue this datagram into the instances.
  //
  Enqueued = Udp6EnqueueDgram (Udp6Service, Packet, &RxData);

  if (Enqueued == 0) {
    //
    // Send the port unreachable ICMP packet before we free this NET_BUF
    //
    Udp6SendPortUnreach (Udp6Service->IpIo, NetSession, Udp6Header);
  }

  //
  // Try to free the packet before deliver it.
  //
  NetbufFree (Packet);

  if (Enqueued > 0) {
    //
    // Deliver the datagram.
    //
    Udp6DeliverDgram (Udp6Service);
  }
}

/**
  This function builds and sends out a icmp port unreachable message.

  @param[in]  IpIo               Pointer to the IP_IO instance.
  @param[in]  NetSession         Pointer to the EFI_NET_SESSION_DATA of the packet
                                 causes this icmp error message.
  @param[in]  Udp6Header         Pointer to the udp header of the datagram causes
                                 this icmp error message.

**/
VOID
Udp6SendPortUnreach (
  IN IP_IO                 *IpIo,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN VOID                  *Udp6Header
  )
{
  NET_BUF              *Packet;
  UINT32               Len;
  IP6_ICMP_ERROR_HEAD  *IcmpErrHdr;
  UINT8                *Ptr;
  IP_IO_OVERRIDE       Override;
  IP_IO_IP_INFO        *IpSender;
  EFI_IP6_MODE_DATA    *Ip6ModeData;
  EFI_STATUS           Status;
  EFI_IP6_PROTOCOL     *Ip6Protocol;

  Ip6ModeData = NULL;

  //
  // An ICMPv6 error message MUST NOT be originated as A packet destined to
  // 1) an IPv6 multicast address 2) The IPv6 Unspecified Address
  //
  if (NetSession->IpVersion == IP_VERSION_6) {
    if (NetIp6IsUnspecifiedAddr (&NetSession->Dest.v6) ||
        IP6_IS_MULTICAST (&NetSession->Dest.v6)
        )
    {
      goto EXIT;
    }
  }

  IpSender = IpIoFindSender (&IpIo, NetSession->IpVersion, &NetSession->Dest);

  //
  // Get the Ipv6 Mode Data.
  //
  Ip6ModeData = AllocateZeroPool (sizeof (EFI_IP6_MODE_DATA));
  ASSERT (Ip6ModeData != NULL);
  if (Ip6ModeData == NULL) {
    goto EXIT;
  }

  //
  // If not finding the related IpSender use the default IpIo to send out
  // the port unreachable ICMP message.
  //
  if (IpSender == NULL) {
    Ip6Protocol = IpIo->Ip.Ip6;
  } else {
    Ip6Protocol = IpSender->Ip.Ip6;
  }

  Status = Ip6Protocol->GetModeData (
                          Ip6Protocol,
                          Ip6ModeData,
                          NULL,
                          NULL
                          );

  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // The ICMP6 packet length, includes whole invoking packet and ICMP6 error header.
  //
  Len = NetSession->IpHdrLen +
        NTOHS (((EFI_UDP_HEADER *)Udp6Header)->Length) +
        sizeof (IP6_ICMP_ERROR_HEAD);

  //
  // If the ICMP6 packet length larger than IP MTU, adjust its length to MTU.
  //
  if (Ip6ModeData->MaxPacketSize < Len) {
    Len = Ip6ModeData->MaxPacketSize;
  }

  //
  // Allocate buffer for the icmp error message.
  //
  Packet = NetbufAlloc (Len);
  if (Packet == NULL) {
    goto EXIT;
  }

  //
  // Allocate space for the IP6_ICMP_ERROR_HEAD.
  //
  IcmpErrHdr = (IP6_ICMP_ERROR_HEAD *)NetbufAllocSpace (Packet, Len, FALSE);
  ASSERT (IcmpErrHdr != NULL);
  if (IcmpErrHdr == NULL) {
    goto EXIT;
  }

  //
  // Set the required fields for the icmp port unreachable message.
  //
  IcmpErrHdr->Head.Type     = ICMP_V6_DEST_UNREACHABLE;
  IcmpErrHdr->Head.Code     = ICMP_V6_PORT_UNREACHABLE;
  IcmpErrHdr->Head.Checksum = 0;
  IcmpErrHdr->Fourth        = 0;

  //
  // Copy as much of invoking Packet as possible without the ICMPv6 packet
  // exceeding the minimum Ipv6 MTU. The length of IP6_ICMP_ERROR_HEAD contains
  // the length of EFI_IP6_HEADER, so when using the length of IP6_ICMP_ERROR_HEAD
  // for pointer movement that fact should be considered.
  //
  Ptr = (VOID *)&IcmpErrHdr->Head;
  Ptr = (UINT8 *)(UINTN)((UINTN)Ptr + sizeof (IP6_ICMP_ERROR_HEAD) - sizeof (EFI_IP6_HEADER));
  CopyMem (Ptr, NetSession->IpHdr.Ip6Hdr, NetSession->IpHdrLen);
  CopyMem (
    Ptr + NetSession->IpHdrLen,
    Udp6Header,
    Len - NetSession->IpHdrLen - sizeof (IP6_ICMP_ERROR_HEAD) + sizeof (EFI_IP6_HEADER)
    );

  //
  // Set the checksum as zero, and IP6 driver will calculate it with pseudo header.
  //
  IcmpErrHdr->Head.Checksum = 0;

  //
  // Fill the override data.
  //
  Override.Ip6OverrideData.FlowLabel = 0;
  Override.Ip6OverrideData.HopLimit  = 255;
  Override.Ip6OverrideData.Protocol  = IP6_ICMP;

  //
  // Send out this icmp packet.
  //
  IpIoSend (IpIo, Packet, IpSender, NULL, NULL, &NetSession->Source, &Override);

  NetbufFree (Packet);

EXIT:
  if (Ip6ModeData != NULL) {
    FreePool (Ip6ModeData);
  }
}

/**
  This function handles the received Icmp Error message and de-multiplexes it to the
  instance.

  @param[in]       Udp6Service        Pointer to the udp service context data.
  @param[in]       IcmpError          The icmp error code.
  @param[in]       NetSession         Pointer to the EFI_NET_SESSION_DATA abstracted
                                      from the received Icmp Error packet.
  @param[in, out]  Packet             Pointer to the Icmp Error packet.

**/
VOID
Udp6IcmpHandler (
  IN UDP6_SERVICE_DATA     *Udp6Service,
  IN UINT8                 IcmpError,
  IN EFI_NET_SESSION_DATA  *NetSession,
  IN OUT NET_BUF           *Packet
  )
{
  EFI_UDP_HEADER         *Udp6Header;
  EFI_UDP6_SESSION_DATA  Udp6Session;
  LIST_ENTRY             *Entry;
  UDP6_INSTANCE_DATA     *Instance;

  if (Packet->TotalSize < UDP6_HEADER_SIZE) {
    NetbufFree (Packet);
    return;
  }

  Udp6Header = (EFI_UDP_HEADER *)NetbufGetByte (Packet, 0, NULL);
  ASSERT (Udp6Header != NULL);
  if (Udp6Header == NULL) {
    NetbufFree (Packet);
    return;
  }

  IP6_COPY_ADDRESS (&Udp6Session.SourceAddress, &NetSession->Source);
  IP6_COPY_ADDRESS (&Udp6Session.DestinationAddress, &NetSession->Dest);

  Udp6Session.SourcePort      = NTOHS (Udp6Header->DstPort);
  Udp6Session.DestinationPort = NTOHS (Udp6Header->SrcPort);

  NET_LIST_FOR_EACH (Entry, &Udp6Service->ChildrenList) {
    //
    // Iterate all the instances.
    //
    Instance = NET_LIST_USER_STRUCT (Entry, UDP6_INSTANCE_DATA, Link);

    if (!Instance->Configured) {
      continue;
    }

    if (Udp6MatchDgram (Instance, &Udp6Session)) {
      //
      // Translate the Icmp Error code according to the udp spec.
      //
      Instance->IcmpError = IpIoGetIcmpErrStatus (IcmpError, IP_VERSION_6, NULL, NULL);

      if (IcmpError > ICMP_ERR_UNREACH_PORT) {
        Instance->IcmpError = EFI_ICMP_ERROR;
      }

      //
      // Notify the instance with the received Icmp Error.
      //
      Udp6ReportIcmpError (Instance);

      break;
    }
  }

  NetbufFree (Packet);
}

/**
  This function reports the received ICMP error.

  @param[in]  Instance          Pointer to the udp instance context data.

**/
VOID
Udp6ReportIcmpError (
  IN UDP6_INSTANCE_DATA  *Instance
  )
{
  EFI_UDP6_COMPLETION_TOKEN  *Token;

  if (NetMapIsEmpty (&Instance->RxTokens)) {
    //
    // There are no receive tokens to deliver the ICMP error.
    //
    return;
  }

  if (EFI_ERROR (Instance->IcmpError)) {
    //
    // Try to get a RxToken from the RxTokens map.
    //
    Token = (EFI_UDP6_COMPLETION_TOKEN *)NetMapRemoveHead (&Instance->RxTokens, NULL);

    if (Token != NULL) {
      //
      // Report the error through the Token.
      //
      Token->Status = Instance->IcmpError;
      gBS->SignalEvent (Token->Event);

      //
      // Clear the IcmpError.
      //
      Instance->IcmpError = EFI_SUCCESS;
    }
  }
}

/**
  This function is a dummy ext-free function for the NET_BUF created for the output
  udp datagram.

  @param[in]  Context                Pointer to the context data.

**/
VOID
EFIAPI
Udp6NetVectorExtFree (
  IN VOID  *Context
  )
{
}

/**
  Find the key in the netmap.

  @param[in]  Map                    The netmap to search within.
  @param[in]  Key                    The key to search.

  @return The point to the item contains the Key, or NULL, if Key isn't in the map.

**/
NET_MAP_ITEM *
Udp6MapMultiCastAddr (
  IN  NET_MAP  *Map,
  IN  VOID     *Key
  )
{
  LIST_ENTRY        *Entry;
  NET_MAP_ITEM      *Item;
  EFI_IPv6_ADDRESS  *Addr;

  ASSERT (Map != NULL);
  NET_LIST_FOR_EACH (Entry, &Map->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
    Addr = (EFI_IPv6_ADDRESS *)Item->Key;
    if (EFI_IP6_EQUAL (Addr, Key)) {
      return Item;
    }
  }
  return NULL;
}
