/** @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;
}

