/** @file
  Multicast Listener Discovery support routines.

  Copyright (c) 2009 - 2010, 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 "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_SUCESS                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 twcie after short delays [Unsolicited Report Interval] (default:10s)
  // Simulate this operation as a Multicast-Address-Specific Query was received for that addresss.
  //
  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 configuraton.
  @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;

  //
  // 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 * NET_RANDOM (NetRandomInitSeed ());
  }

  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);
    }
  }
}

