/** @file
  Udp6 driver's whole implementation.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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 cancle 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 intializes 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 stragety.

  @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 avalaible DestinationPort for this token.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (NetIp6IsUnspecifiedAddr (&UdpSessionData->DestinationAddress) &&
        NetIp6IsUnspecifiedAddr (&ConfigData->RemoteAddress)
        ) {
      //
      // The DestinationAddress is not specificed.
      //
      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, execpt 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 cancle 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 matche 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 calcuate 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;
}

