/** @file
  Multicast Listener Discovery support routines.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

/**
  Create a IP6_MLD_GROUP list entry node and record to IP6 service binding data.

  @param[in, out]  IpSb          Points to IP6 service binding instance.
  @param[in]       MulticastAddr The IPv6 multicast address to be recorded.
  @param[in]       DelayTimer    The maximum allowed delay before sending a responding
                                 report, in units of milliseconds.
  @return The created IP6_ML_GROUP list entry or NULL.

**/
IP6_MLD_GROUP *
Ip6CreateMldEntry (
  IN OUT IP6_SERVICE   *IpSb,
  IN EFI_IPv6_ADDRESS  *MulticastAddr,
  IN UINT32            DelayTimer
  )
{
  IP6_MLD_GROUP  *Entry;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr));

  Entry = AllocatePool (sizeof (IP6_MLD_GROUP));
  if (Entry != NULL) {
    Entry->RefCnt     = 1;
    Entry->DelayTimer = DelayTimer;
    Entry->SendByUs   = FALSE;
    IP6_COPY_ADDRESS (&Entry->Address, MulticastAddr);
    InsertTailList (&IpSb->MldCtrl.Groups, &Entry->Link);
  }

  return Entry;
}

/**
  Search a IP6_MLD_GROUP list entry node from a list array.

  @param[in]       IpSb          Points to IP6 service binding instance.
  @param[in]       MulticastAddr The IPv6 multicast address to be searched.

  @return The found IP6_ML_GROUP list entry or NULL.

**/
IP6_MLD_GROUP *
Ip6FindMldEntry (
  IN IP6_SERVICE       *IpSb,
  IN EFI_IPv6_ADDRESS  *MulticastAddr
  )
{
  LIST_ENTRY     *Entry;
  IP6_MLD_GROUP  *Group;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr));

  NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
    Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link);
    if (EFI_IP6_EQUAL (MulticastAddr, &Group->Address)) {
      return Group;
    }
  }

  return NULL;
}

/**
  Count the number of IP6 multicast groups that are mapped to the
  same MAC address. Several IP6 multicast address may be mapped to
  the same MAC address.

  @param[in]  MldCtrl              The MLD control block to search in.
  @param[in]  Mac                  The MAC address to search.

  @return The number of the IP6 multicast group that mapped to the same
          multicast group Mac.

**/
INTN
Ip6FindMac (
  IN IP6_MLD_SERVICE_DATA  *MldCtrl,
  IN EFI_MAC_ADDRESS       *Mac
  )
{
  LIST_ENTRY     *Entry;
  IP6_MLD_GROUP  *Group;
  INTN           Count;

  Count = 0;

  NET_LIST_FOR_EACH (Entry, &MldCtrl->Groups) {
    Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link);

    if (NET_MAC_EQUAL (&Group->Mac, Mac, sizeof (EFI_MAC_ADDRESS))) {
      Count++;
    }
  }

  return Count;
}

/**
  Generate MLD report message and send it out to MulticastAddr.

  @param[in]  IpSb               The IP service to send the packet.
  @param[in]  Interface          The IP interface to send the packet.
                                 If NULL, a system interface will be selected.
  @param[in]  MulticastAddr      The specific IPv6 multicast address to which
                                 the message sender is listening.

  @retval EFI_OUT_OF_RESOURCES   There are not sufficient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            The MLD report message was successfully sent out.

**/
EFI_STATUS
Ip6SendMldReport (
  IN IP6_SERVICE       *IpSb,
  IN IP6_INTERFACE     *Interface OPTIONAL,
  IN EFI_IPv6_ADDRESS  *MulticastAddr
  )
{
  IP6_MLD_HEAD    *MldHead;
  NET_BUF         *Packet;
  EFI_IP6_HEADER  Head;
  UINT16          PayloadLen;
  UINTN           OptionLen;
  UINT8           *Options;
  EFI_STATUS      Status;
  UINT16          HeadChecksum;
  UINT16          PseudoChecksum;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr));

  //
  // Generate the packet to be sent
  // IPv6 basic header + Hop by Hop option + MLD message
  //

  OptionLen = 0;
  Status    = Ip6FillHopByHop (NULL, &OptionLen, IP6_ICMP);
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  PayloadLen = (UINT16)(OptionLen + sizeof (IP6_MLD_HEAD));
  Packet     = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32)PayloadLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Create the basic IPv6 header.
  // RFC3590: Use link-local address as source address if it is available,
  // otherwise use the unspecified address.
  //
  Head.FlowLabelL    = 0;
  Head.FlowLabelH    = 0;
  Head.PayloadLength = HTONS (PayloadLen);
  Head.NextHeader    = IP6_HOP_BY_HOP;
  Head.HopLimit      = 1;
  IP6_COPY_ADDRESS (&Head.DestinationAddress, MulticastAddr);

  //
  // If Link-Local address is not ready, we use unspecified address.
  //
  IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr);

  NetbufReserve (Packet, sizeof (EFI_IP6_HEADER));

  //
  // Fill a IPv6 Router Alert option in a Hop-by-Hop Options Header
  //
  Options = NetbufAllocSpace (Packet, (UINT32)OptionLen, FALSE);
  ASSERT (Options != NULL);
  Status = Ip6FillHopByHop (Options, &OptionLen, IP6_ICMP);
  if (EFI_ERROR (Status)) {
    NetbufFree (Packet);
    Packet = NULL;
    return Status;
  }

  //
  // Fill in MLD message - Report
  //
  MldHead = (IP6_MLD_HEAD *)NetbufAllocSpace (Packet, sizeof (IP6_MLD_HEAD), FALSE);
  ASSERT (MldHead != NULL);
  ZeroMem (MldHead, sizeof (IP6_MLD_HEAD));
  MldHead->Head.Type = ICMP_V6_LISTENER_REPORT;
  MldHead->Head.Code = 0;
  IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr);

  HeadChecksum   = NetblockChecksum ((UINT8 *)MldHead, sizeof (IP6_MLD_HEAD));
  PseudoChecksum = NetIp6PseudoHeadChecksum (
                     &Head.SourceAddress,
                     &Head.DestinationAddress,
                     IP6_ICMP,
                     sizeof (IP6_MLD_HEAD)
                     );

  MldHead->Head.Checksum = (UINT16) ~NetAddChecksum (HeadChecksum, PseudoChecksum);

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, Interface, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

/**
  Generate MLD Done message and send it out to MulticastAddr.

  @param[in]  IpSb               The IP service to send the packet.
  @param[in]  MulticastAddr      The specific IPv6 multicast address to which
                                 the message sender is ceasing to listen.

  @retval EFI_OUT_OF_RESOURCES   There are not sufficient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            The MLD report message was successfully sent out.

**/
EFI_STATUS
Ip6SendMldDone (
  IN IP6_SERVICE       *IpSb,
  IN EFI_IPv6_ADDRESS  *MulticastAddr
  )
{
  IP6_MLD_HEAD      *MldHead;
  NET_BUF           *Packet;
  EFI_IP6_HEADER    Head;
  UINT16            PayloadLen;
  UINTN             OptionLen;
  UINT8             *Options;
  EFI_STATUS        Status;
  EFI_IPv6_ADDRESS  Destination;
  UINT16            HeadChecksum;
  UINT16            PseudoChecksum;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr));

  //
  // Generate the packet to be sent
  // IPv6 basic header + Hop by Hop option + MLD message
  //

  OptionLen = 0;
  Status    = Ip6FillHopByHop (NULL, &OptionLen, IP6_ICMP);
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  PayloadLen = (UINT16)(OptionLen + sizeof (IP6_MLD_HEAD));
  Packet     = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32)PayloadLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Create the basic IPv6 header.
  //
  Head.FlowLabelL    = 0;
  Head.FlowLabelH    = 0;
  Head.PayloadLength = HTONS (PayloadLen);
  Head.NextHeader    = IP6_HOP_BY_HOP;
  Head.HopLimit      = 1;

  //
  // If Link-Local address is not ready, we use unspecified address.
  //
  IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr);

  Ip6SetToAllNodeMulticast (TRUE, IP6_LINK_LOCAL_SCOPE, &Destination);
  IP6_COPY_ADDRESS (&Head.DestinationAddress, &Destination);

  NetbufReserve (Packet, sizeof (EFI_IP6_HEADER));

  //
  // Fill a IPv6 Router Alert option in a Hop-by-Hop Options Header
  //
  Options = NetbufAllocSpace (Packet, (UINT32)OptionLen, FALSE);
  ASSERT (Options != NULL);
  Status = Ip6FillHopByHop (Options, &OptionLen, IP6_ICMP);
  if (EFI_ERROR (Status)) {
    NetbufFree (Packet);
    Packet = NULL;
    return Status;
  }

  //
  // Fill in MLD message - Done
  //
  MldHead = (IP6_MLD_HEAD *)NetbufAllocSpace (Packet, sizeof (IP6_MLD_HEAD), FALSE);
  ASSERT (MldHead != NULL);
  ZeroMem (MldHead, sizeof (IP6_MLD_HEAD));
  MldHead->Head.Type = ICMP_V6_LISTENER_DONE;
  MldHead->Head.Code = 0;
  IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr);

  HeadChecksum   = NetblockChecksum ((UINT8 *)MldHead, sizeof (IP6_MLD_HEAD));
  PseudoChecksum = NetIp6PseudoHeadChecksum (
                     &Head.SourceAddress,
                     &Head.DestinationAddress,
                     IP6_ICMP,
                     sizeof (IP6_MLD_HEAD)
                     );

  MldHead->Head.Checksum = (UINT16) ~NetAddChecksum (HeadChecksum, PseudoChecksum);

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, NULL, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

/**
  Init the MLD data of the IP6 service instance. Configure
  MNP to receive ALL SYSTEM multicast.

  @param[in]  IpSb              The IP6 service whose MLD is to be initialized.

  @retval EFI_OUT_OF_RESOURCES  There are not sufficient resourcet to complete the
                                operation.
  @retval EFI_SUCCESS           The MLD module successfully initialized.

**/
EFI_STATUS
Ip6InitMld (
  IN IP6_SERVICE  *IpSb
  )
{
  EFI_IPv6_ADDRESS  AllNodes;
  IP6_MLD_GROUP     *Group;
  EFI_STATUS        Status;

  //
  // Join the link-scope all-nodes multicast address (FF02::1).
  // This address is started in Idle Listener state and never transitions to
  // another state, and never sends a Report or Done for that address.
  //

  Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);

  Group = Ip6CreateMldEntry (IpSb, &AllNodes, (UINT32)IP6_INFINIT_LIFETIME);
  if (Group == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = Ip6GetMulticastMac (IpSb->Mnp, &AllNodes, &Group->Mac);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  //
  // Configure MNP to receive all-nodes multicast
  //
  Status = IpSb->Mnp->Groups (IpSb->Mnp, TRUE, &Group->Mac);
  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ERROR;
  }

  return EFI_SUCCESS;

ERROR:
  RemoveEntryList (&Group->Link);
  FreePool (Group);
  return Status;
}

/**
  Add a group address to the array of group addresses.
  The caller should make sure that no duplicated address
  existed in the array.

  @param[in, out]  IpInstance       Points to an IP6_PROTOCOL instance.
  @param[in]       Group            The IP6 multicast address to add.

  @retval EFI_OUT_OF_RESOURCES      There are not sufficient resources to complete
                                    the operation.
  @retval EFI_SUCCESS               The address is added to the group address array.

**/
EFI_STATUS
Ip6CombineGroups (
  IN OUT IP6_PROTOCOL  *IpInstance,
  IN EFI_IPv6_ADDRESS  *Group
  )
{
  EFI_IPv6_ADDRESS  *GroupList;

  NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE);
  ASSERT (Group != NULL && IP6_IS_MULTICAST (Group));

  IpInstance->GroupCount++;

  GroupList = AllocatePool (IpInstance->GroupCount * sizeof (EFI_IPv6_ADDRESS));
  if (GroupList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (IpInstance->GroupCount > 1) {
    ASSERT (IpInstance->GroupList != NULL);

    CopyMem (
      GroupList,
      IpInstance->GroupList,
      (IpInstance->GroupCount - 1) * sizeof (EFI_IPv6_ADDRESS)
      );

    FreePool (IpInstance->GroupList);
  }

  IP6_COPY_ADDRESS (GroupList + (IpInstance->GroupCount - 1), Group);

  IpInstance->GroupList = GroupList;

  return EFI_SUCCESS;
}

/**
  Remove a group address from the array of group addresses.
  Although the function doesn't assume the byte order of Group,
  the network byte order is used by the caller.

  @param[in, out]  IpInstance       Points to an IP6_PROTOCOL instance.
  @param[in]       Group            The IP6 multicast address to remove.

  @retval EFI_NOT_FOUND             Cannot find the to be removed group address.
  @retval EFI_SUCCESS               The group address was successfully removed.

**/
EFI_STATUS
Ip6RemoveGroup (
  IN OUT IP6_PROTOCOL  *IpInstance,
  IN EFI_IPv6_ADDRESS  *Group
  )
{
  UINT32  Index;
  UINT32  Count;

  Count = IpInstance->GroupCount;

  for (Index = 0; Index < Count; Index++) {
    if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, Group)) {
      break;
    }
  }

  if (Index == Count) {
    return EFI_NOT_FOUND;
  }

  while (Index < Count - 1) {
    IP6_COPY_ADDRESS (IpInstance->GroupList + Index, IpInstance->GroupList + Index + 1);
    Index++;
  }

  ASSERT (IpInstance->GroupCount > 0);
  IpInstance->GroupCount--;

  return EFI_SUCCESS;
}

/**
  Join the multicast group on behalf of this IP6 service binding instance.

  @param[in]  IpSb               The IP6 service binding instance.
  @param[in]  Interface          Points to an IP6_INTERFACE structure.
  @param[in]  Address            The group address to join.

  @retval EFI_SUCCESS            Successfully join the multicast group.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
  @retval Others                 Failed to join the multicast group.

**/
EFI_STATUS
Ip6JoinGroup (
  IN IP6_SERVICE       *IpSb,
  IN IP6_INTERFACE     *Interface,
  IN EFI_IPv6_ADDRESS  *Address
  )
{
  IP6_MLD_GROUP  *Group;
  EFI_STATUS     Status;

  Group = Ip6FindMldEntry (IpSb, Address);
  if (Group != NULL) {
    Group->RefCnt++;
    return EFI_SUCCESS;
  }

  //
  // Repeat the report once or twice after short delays [Unsolicited Report Interval] (default:10s)
  // Simulate this operation as a Multicast-Address-Specific Query was received for that address.
  //
  Group = Ip6CreateMldEntry (IpSb, Address, IP6_UNSOLICITED_REPORT_INTERVAL);
  if (Group == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Group->SendByUs = TRUE;

  Status = Ip6GetMulticastMac (IpSb->Mnp, Address, &Group->Mac);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = IpSb->Mnp->Groups (IpSb->Mnp, TRUE, &Group->Mac);
  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ERROR;
  }

  //
  // Send unsolicited report when a node starts listening to a multicast address
  //
  Status = Ip6SendMldReport (IpSb, Interface, Address);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  return EFI_SUCCESS;

ERROR:
  RemoveEntryList (&Group->Link);
  FreePool (Group);
  return Status;
}

/**
  Leave the IP6 multicast group.

  @param[in]  IpSb               The IP6 service binding instance.
  @param[in]  Address            The group address to leave.

  @retval EFI_NOT_FOUND          The IP6 service instance isn't in the group.
  @retval EFI_SUCCESS            Successfully leave the multicast group..
  @retval Others                 Failed to leave the multicast group.

**/
EFI_STATUS
Ip6LeaveGroup (
  IN IP6_SERVICE       *IpSb,
  IN EFI_IPv6_ADDRESS  *Address
  )
{
  IP6_MLD_GROUP  *Group;
  EFI_STATUS     Status;

  Group = Ip6FindMldEntry (IpSb, Address);
  if (Group == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // If more than one instance is in the group, decrease
  // the RefCnt then return.
  //
  if ((Group->RefCnt > 0) && (--Group->RefCnt > 0)) {
    return EFI_SUCCESS;
  }

  //
  // If multiple IP6 group addresses are mapped to the same
  // multicast MAC address, don't configure the MNP to leave
  // the MAC.
  //
  if (Ip6FindMac (&IpSb->MldCtrl, &Group->Mac) == 1) {
    Status = IpSb->Mnp->Groups (IpSb->Mnp, FALSE, &Group->Mac);
    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
      return Status;
    }
  }

  //
  // Send a leave report if we are the last node to report
  //
  if (Group->SendByUs) {
    Status = Ip6SendMldDone (IpSb, Address);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  RemoveEntryList (&Group->Link);
  FreePool (Group);

  return EFI_SUCCESS;
}

/**
  Worker function for EfiIp6Groups(). The caller
  should make sure that the parameters are valid.

  @param[in]  IpInstance        The IP6 child to change the setting.
  @param[in]  JoinFlag          TRUE to join the group, otherwise leave it.
  @param[in]  GroupAddress      The target group address. If NULL, leave all
                                the group addresses.

  @retval EFI_ALREADY_STARTED   Wants to join the group, but is already a member of it
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate sufficient resources.
  @retval EFI_DEVICE_ERROR      Failed to set the group configuration.
  @retval EFI_SUCCESS           Successfully updated the group setting.
  @retval EFI_NOT_FOUND         Try to leave the group which it isn't a member.

**/
EFI_STATUS
Ip6Groups (
  IN IP6_PROTOCOL      *IpInstance,
  IN BOOLEAN           JoinFlag,
  IN EFI_IPv6_ADDRESS  *GroupAddress       OPTIONAL
  )
{
  EFI_STATUS        Status;
  IP6_SERVICE       *IpSb;
  UINT32            Index;
  EFI_IPv6_ADDRESS  *Group;

  IpSb = IpInstance->Service;

  if (JoinFlag) {
    ASSERT (GroupAddress != NULL);

    for (Index = 0; Index < IpInstance->GroupCount; Index++) {
      if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, GroupAddress)) {
        return EFI_ALREADY_STARTED;
      }
    }

    Status = Ip6JoinGroup (IpSb, IpInstance->Interface, GroupAddress);
    if (!EFI_ERROR (Status)) {
      return Ip6CombineGroups (IpInstance, GroupAddress);
    }

    return Status;
  }

  //
  // Leave the group. Leave all the groups if GroupAddress is NULL.
  //
  for (Index = IpInstance->GroupCount; Index > 0; Index--) {
    Group = IpInstance->GroupList + (Index - 1);

    if ((GroupAddress == NULL) || EFI_IP6_EQUAL (Group, GroupAddress)) {
      Status = Ip6LeaveGroup (IpInstance->Service, Group);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Ip6RemoveGroup (IpInstance, Group);

      if (IpInstance->GroupCount == 0) {
        ASSERT (Index == 1);
        FreePool (IpInstance->GroupList);
        IpInstance->GroupList = NULL;
      }

      if (GroupAddress != NULL) {
        return EFI_SUCCESS;
      }
    }
  }

  return ((GroupAddress != NULL) ? EFI_NOT_FOUND : EFI_SUCCESS);
}

/**
  Set a random value of the delay timer for the multicast address from the range
  [0, Maximum Response Delay]. If a timer for any address is already
  running, it is reset to the new random value only if the requested
  Maximum Response Delay is less than the remaining value of the
  running timer.  If the Query packet specifies a Maximum Response
  Delay of zero, each timer is effectively set to zero, and the action
  specified below for timer expiration is performed immediately.

  @param[in]      IpSb               The IP6 service binding instance.
  @param[in]      MaxRespDelay       The Maximum Response Delay, in milliseconds.
  @param[in]      MulticastAddr      The multicast address.
  @param[in, out] Group              Points to a IP6_MLD_GROUP list entry node.

  @retval EFI_SUCCESS                The delay timer is successfully updated or
                                     timer expiration is performed immediately.
  @retval Others                     Failed to send out MLD report message.

**/
EFI_STATUS
Ip6UpdateDelayTimer (
  IN IP6_SERVICE        *IpSb,
  IN UINT16             MaxRespDelay,
  IN EFI_IPv6_ADDRESS   *MulticastAddr,
  IN OUT IP6_MLD_GROUP  *Group
  )
{
  UINT32      Delay;
  EFI_STATUS  Status;
  UINT32      Random;

  Status = PseudoRandomU32 (&Random);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
    return Status;
  }

  //
  // If the Query packet specifies a Maximum Response Delay of zero, perform timer
  // expiration immediately.
  //
  if (MaxRespDelay == 0) {
    Group->DelayTimer = 0;
    return Ip6SendMldReport (IpSb, NULL, MulticastAddr);
  }

  Delay = (UINT32)(MaxRespDelay / 1000);

  //
  // Sets a delay timer to a random value selected from the range [0, Maximum Response Delay]
  // If a timer is already running, resets it if the request Maximum Response Delay
  // is less than the remaining value of the running timer.
  //
  if ((Group->DelayTimer == 0) || (Delay < Group->DelayTimer)) {
    Group->DelayTimer = Delay / 4294967295UL * Random;
  }

  return EFI_SUCCESS;
}

/**
  Process the Multicast Listener Query message.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the MLD query packet.
  @param[in]  Packet             The content of the MLD query packet with IP head
                                 removed.

  @retval EFI_SUCCESS            The MLD query packet processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval Others                 Failed to process the packet.

**/
EFI_STATUS
Ip6ProcessMldQuery (
  IN IP6_SERVICE     *IpSb,
  IN EFI_IP6_HEADER  *Head,
  IN NET_BUF         *Packet
  )
{
  EFI_IPv6_ADDRESS  AllNodes;
  IP6_MLD_GROUP     *Group;
  IP6_MLD_HEAD      MldPacket;
  LIST_ENTRY        *Entry;
  EFI_STATUS        Status;

  Status = EFI_INVALID_PARAMETER;

  //
  // Check the validity of the packet, generic query or specific query
  //
  if (!NetIp6IsUnspecifiedAddr (&Head->SourceAddress) && !NetIp6IsLinkLocalAddr (&Head->SourceAddress)) {
    goto Exit;
  }

  if ((Head->HopLimit != 1) || !IP6_IS_MULTICAST (&Head->DestinationAddress)) {
    goto Exit;
  }

  //
  // The Packet points to MLD report raw data without Hop-By-Hop option.
  //
  NetbufCopy (Packet, 0, sizeof (IP6_MLD_HEAD), (UINT8 *)&MldPacket);
  MldPacket.MaxRespDelay = NTOHS (MldPacket.MaxRespDelay);

  Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
  if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &AllNodes)) {
    //
    // Receives a Multicast-Address-Specific Query, check it firstly
    //
    if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) {
      goto Exit;
    }

    //
    // The node is not listening but it receives the specific query. Just return.
    //
    Group = Ip6FindMldEntry (IpSb, &MldPacket.Group);
    if (Group == NULL) {
      Status = EFI_SUCCESS;
      goto Exit;
    }

    Status = Ip6UpdateDelayTimer (
               IpSb,
               MldPacket.MaxRespDelay,
               &MldPacket.Group,
               Group
               );
    goto Exit;
  }

  //
  // Receives a General Query, sets a delay timer for each multicast address it is listening
  //
  NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
    Group  = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link);
    Status = Ip6UpdateDelayTimer (IpSb, MldPacket.MaxRespDelay, &Group->Address, Group);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  Status = EFI_SUCCESS;

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Process the Multicast Listener Report message.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the MLD report packet.
  @param[in]  Packet             The content of the MLD report packet with IP head
                                 removed.

  @retval EFI_SUCCESS            The MLD report packet processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.

**/
EFI_STATUS
Ip6ProcessMldReport (
  IN IP6_SERVICE     *IpSb,
  IN EFI_IP6_HEADER  *Head,
  IN NET_BUF         *Packet
  )
{
  IP6_MLD_HEAD   MldPacket;
  IP6_MLD_GROUP  *Group;
  EFI_STATUS     Status;

  Status = EFI_INVALID_PARAMETER;

  //
  // Validate the incoming message, if invalid, drop it.
  //
  if (!NetIp6IsUnspecifiedAddr (&Head->SourceAddress) && !NetIp6IsLinkLocalAddr (&Head->SourceAddress)) {
    goto Exit;
  }

  if ((Head->HopLimit != 1) || !IP6_IS_MULTICAST (&Head->DestinationAddress)) {
    goto Exit;
  }

  //
  // The Packet points to MLD report raw data without Hop-By-Hop option.
  //
  NetbufCopy (Packet, 0, sizeof (IP6_MLD_HEAD), (UINT8 *)&MldPacket);
  if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) {
    goto Exit;
  }

  Group = Ip6FindMldEntry (IpSb, &MldPacket.Group);
  if (Group == NULL) {
    goto Exit;
  }

  //
  // The report is sent by another node, stop its own timer relates to the multicast address and clear
  //

  if (!Group->SendByUs) {
    Group->DelayTimer = 0;
  }

  Status = EFI_SUCCESS;

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  The heartbeat timer of MLD module. It sends out a solicited MLD report when
  DelayTimer expires.

  @param[in]  IpSb              The IP6 service binding instance.

**/
VOID
Ip6MldTimerTicking (
  IN IP6_SERVICE  *IpSb
  )
{
  IP6_MLD_GROUP  *Group;
  LIST_ENTRY     *Entry;

  //
  // Send solicited report when timer expires
  //
  NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) {
    Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link);
    if ((Group->DelayTimer > 0) && (--Group->DelayTimer == 0)) {
      Ip6SendMldReport (IpSb, NULL, &Group->Address);
    }
  }
}
