/** @file
  Implementation of Neighbor Discovery support routines.

  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 "Ip6Impl.h"

EFI_MAC_ADDRESS mZeroMacAddress;

/**
  Update the ReachableTime in IP6 service binding instance data, in milliseconds.

  @param[in, out] IpSb     Points to the IP6_SERVICE.

**/
VOID
Ip6UpdateReachableTime (
  IN OUT IP6_SERVICE  *IpSb
  )
{
  UINT32              Random;

  Random = (NetRandomInitSeed () / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE;
  Random = Random + IP6_MIN_RANDOM_FACTOR_SCALED;
  IpSb->ReachableTime = (IpSb->BaseReachableTime * Random) / IP6_RANDOM_FACTOR_SCALE;
}

/**
  Build a array of EFI_IP6_NEIGHBOR_CACHE to be returned to the caller. The number
  of EFI_IP6_NEIGHBOR_CACHE is also returned.

  @param[in]  IpInstance        The pointer to IP6_PROTOCOL instance.
  @param[out] NeighborCount     The number of returned neighbor cache entries.
  @param[out] NeighborCache     The pointer to the array of EFI_IP6_NEIGHBOR_CACHE.

  @retval EFI_SUCCESS           The EFI_IP6_NEIGHBOR_CACHE successfully built.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the route table.

**/
EFI_STATUS
Ip6BuildEfiNeighborCache (
  IN IP6_PROTOCOL            *IpInstance,
  OUT UINT32                 *NeighborCount,
  OUT EFI_IP6_NEIGHBOR_CACHE **NeighborCache
  )
{
  IP6_NEIGHBOR_ENTRY        *Neighbor;
  LIST_ENTRY                *Entry;
  IP6_SERVICE               *IpSb;
  UINT32                    Count;
  EFI_IP6_NEIGHBOR_CACHE    *EfiNeighborCache;
  EFI_IP6_NEIGHBOR_CACHE    *NeighborCacheTmp;

  NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE);
  ASSERT (NeighborCount != NULL && NeighborCache != NULL);

  IpSb  = IpInstance->Service;
  Count = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->NeighborTable) {
    Count++;
  }

  if (Count == 0) {
    return EFI_SUCCESS;
  }

  NeighborCacheTmp = AllocatePool (Count * sizeof (EFI_IP6_NEIGHBOR_CACHE));
  if (NeighborCacheTmp == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *NeighborCount = Count;
  Count          = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->NeighborTable) {
    Neighbor = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link);

    EfiNeighborCache = NeighborCacheTmp + Count;

   EfiNeighborCache->State = Neighbor->State;
    IP6_COPY_ADDRESS (&EfiNeighborCache->Neighbor, &Neighbor->Neighbor);
    IP6_COPY_LINK_ADDRESS (&EfiNeighborCache->LinkAddress, &Neighbor->LinkAddress);

    Count++;
  }

  ASSERT (*NeighborCount == Count);
  *NeighborCache = NeighborCacheTmp;

  return EFI_SUCCESS;
}

/**
  Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number
  of prefix entries is also returned.

  @param[in]  IpInstance        The pointer to IP6_PROTOCOL instance.
  @param[out] PrefixCount       The number of returned prefix entries.
  @param[out] PrefixTable       The pointer to the array of PrefixTable.

  @retval EFI_SUCCESS           The prefix table successfully built.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the prefix table.

**/
EFI_STATUS
Ip6BuildPrefixTable (
  IN IP6_PROTOCOL           *IpInstance,
  OUT UINT32                *PrefixCount,
  OUT EFI_IP6_ADDRESS_INFO  **PrefixTable
  )
{
  LIST_ENTRY                *Entry;
  IP6_SERVICE               *IpSb;
  UINT32                    Count;
  IP6_PREFIX_LIST_ENTRY     *PrefixList;
  EFI_IP6_ADDRESS_INFO      *EfiPrefix;
  EFI_IP6_ADDRESS_INFO      *PrefixTableTmp;

  NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE);
  ASSERT (PrefixCount != NULL && PrefixTable != NULL);

  IpSb  = IpInstance->Service;
  Count = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) {
    Count++;
  }

  if (Count == 0) {
    return EFI_SUCCESS;
  }

  PrefixTableTmp = AllocatePool (Count * sizeof (EFI_IP6_ADDRESS_INFO));
  if (PrefixTableTmp == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *PrefixCount = Count;
  Count        = 0;

  NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) {
    PrefixList = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);
    EfiPrefix  = PrefixTableTmp + Count;
    IP6_COPY_ADDRESS (&EfiPrefix->Address, &PrefixList->Prefix);
    EfiPrefix->PrefixLength = PrefixList->PrefixLength;

    Count++;
  }

  ASSERT (*PrefixCount == Count);
  *PrefixTable = PrefixTableTmp;

  return EFI_SUCCESS;
}

/**
  Allocate and initialize a IP6 prefix list entry.

  @param[in]  IpSb              The pointer to IP6_SERVICE instance.
  @param[in]  OnLinkOrAuto      If TRUE, the entry is created for the on link prefix list.
                                Otherwise, it is created for the autoconfiguration prefix list.
  @param[in]  ValidLifetime     The length of time in seconds that the prefix
                                is valid for the purpose of on-link determination.
  @param[in]  PreferredLifetime The length of time in seconds that addresses
                                generated from the prefix via stateless address
                                autoconfiguration remain preferred.
  @param[in]  PrefixLength      The prefix length of the Prefix.
  @param[in]  Prefix            The prefix address.

  @return NULL if it failed to allocate memory for the prefix node. Otherwise, point
          to the created or existing prefix list entry.

**/
IP6_PREFIX_LIST_ENTRY *
Ip6CreatePrefixListEntry (
  IN IP6_SERVICE            *IpSb,
  IN BOOLEAN                OnLinkOrAuto,
  IN UINT32                 ValidLifetime,
  IN UINT32                 PreferredLifetime,
  IN UINT8                  PrefixLength,
  IN EFI_IPv6_ADDRESS       *Prefix
  )
{
  IP6_PREFIX_LIST_ENTRY     *PrefixEntry;
  IP6_ROUTE_ENTRY           *RtEntry;
  LIST_ENTRY                *ListHead;
  LIST_ENTRY                *Entry;
  IP6_PREFIX_LIST_ENTRY     *TmpPrefixEntry;

  if (Prefix == NULL || PreferredLifetime > ValidLifetime || PrefixLength > IP6_PREFIX_MAX) {
    return NULL;
  }

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  PrefixEntry = Ip6FindPrefixListEntry (
                  IpSb,
                  OnLinkOrAuto,
                  PrefixLength,
                  Prefix
                  );
  if (PrefixEntry != NULL) {
    PrefixEntry->RefCnt ++;
    return PrefixEntry;
  }

  PrefixEntry = AllocatePool (sizeof (IP6_PREFIX_LIST_ENTRY));
  if (PrefixEntry == NULL) {
    return NULL;
  }

  PrefixEntry->RefCnt            = 1;
  PrefixEntry->ValidLifetime     = ValidLifetime;
  PrefixEntry->PreferredLifetime = PreferredLifetime;
  PrefixEntry->PrefixLength      = PrefixLength;
  IP6_COPY_ADDRESS (&PrefixEntry->Prefix, Prefix);

  ListHead = OnLinkOrAuto ? &IpSb->OnlinkPrefix : &IpSb->AutonomousPrefix;

  //
  // Create a direct route entry for on-link prefix and insert to route area.
  //
  if (OnLinkOrAuto) {
    RtEntry = Ip6CreateRouteEntry (Prefix, PrefixLength, NULL);
    if (RtEntry == NULL) {
      FreePool (PrefixEntry);
      return NULL;
    }

    RtEntry->Flag = IP6_DIRECT_ROUTE;
    InsertHeadList (&IpSb->RouteTable->RouteArea[PrefixLength], &RtEntry->Link);
    IpSb->RouteTable->TotalNum++;
  }

  //
  // Insert the prefix entry in the order that a prefix with longer prefix length
  // is put ahead in the list.
  //
  NET_LIST_FOR_EACH (Entry, ListHead) {
    TmpPrefixEntry = NET_LIST_USER_STRUCT(Entry, IP6_PREFIX_LIST_ENTRY, Link);

    if (TmpPrefixEntry->PrefixLength < PrefixEntry->PrefixLength) {
      break;
    }
  }

  NetListInsertBefore (Entry, &PrefixEntry->Link);

  return PrefixEntry;
}

/**
  Destroy a IP6 prefix list entry.

  @param[in]  IpSb              The pointer to IP6_SERVICE instance.
  @param[in]  PrefixEntry       The to be destroyed prefix list entry.
  @param[in]  OnLinkOrAuto      If TRUE, the entry is removed from on link prefix list.
                                Otherwise remove from autoconfiguration prefix list.
  @param[in]  ImmediateDelete   If TRUE, remove the entry directly.
                                Otherwise, check the reference count to see whether
                                it should be removed.

**/
VOID
Ip6DestroyPrefixListEntry (
  IN IP6_SERVICE            *IpSb,
  IN IP6_PREFIX_LIST_ENTRY  *PrefixEntry,
  IN BOOLEAN                OnLinkOrAuto,
  IN BOOLEAN                ImmediateDelete
  )
{
  LIST_ENTRY      *Entry;
  IP6_INTERFACE   *IpIf;
  EFI_STATUS      Status;

  if ((!ImmediateDelete) && (PrefixEntry->RefCnt > 0) && ((--PrefixEntry->RefCnt) > 0)) {
    return ;
  }

  if (OnLinkOrAuto) {
      //
      // Remove the direct route for onlink prefix from route table.
      //
      do {
        Status = Ip6DelRoute (
                   IpSb->RouteTable,
                   &PrefixEntry->Prefix,
                   PrefixEntry->PrefixLength,
                   NULL
                   );
      } while (Status != EFI_NOT_FOUND);
  } else {
    //
    // Remove the corresponding addresses generated from this autonomous prefix.
    //
    NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
      IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);

      Ip6RemoveAddr (IpSb, &IpIf->AddressList, &IpIf->AddressCount, &PrefixEntry->Prefix, PrefixEntry->PrefixLength);
    }
  }

  RemoveEntryList (&PrefixEntry->Link);
  FreePool (PrefixEntry);
}

/**
  Search the list array to find an IP6 prefix list entry.

  @param[in]  IpSb              The pointer to IP6_SERVICE instance.
  @param[in]  OnLinkOrAuto      If TRUE, the search the link prefix list,
                                Otherwise search the autoconfiguration prefix list.
  @param[in]  PrefixLength      The prefix length of the Prefix
  @param[in]  Prefix            The prefix address.

  @return NULL if cannot find the IP6 prefix list entry. Otherwise, return the
          pointer to the IP6 prefix list entry.

**/
IP6_PREFIX_LIST_ENTRY *
Ip6FindPrefixListEntry (
  IN IP6_SERVICE            *IpSb,
  IN BOOLEAN                OnLinkOrAuto,
  IN UINT8                  PrefixLength,
  IN EFI_IPv6_ADDRESS       *Prefix
  )
{
  IP6_PREFIX_LIST_ENTRY     *PrefixList;
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *ListHead;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Prefix != NULL);

  if (OnLinkOrAuto) {
    ListHead = &IpSb->OnlinkPrefix;
  } else {
    ListHead = &IpSb->AutonomousPrefix;
  }

  NET_LIST_FOR_EACH (Entry, ListHead) {
    PrefixList = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);
    if (PrefixLength != 255) {
      //
      // Perform exactly prefix match.
      //
      if (PrefixList->PrefixLength == PrefixLength &&
        NetIp6IsNetEqual (&PrefixList->Prefix, Prefix, PrefixLength)) {
        return PrefixList;
      }
    } else {
      //
      // Perform the longest prefix match. The list is already sorted with
      // the longest length prefix put at the head of the list.
      //
      if (NetIp6IsNetEqual (&PrefixList->Prefix, Prefix, PrefixList->PrefixLength)) {
        return PrefixList;
      }
    }
  }

  return NULL;
}

/**
  Release the resource in the prefix list table, and destroy the list entry and
  corresponding addresses or route entries.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  ListHead          The list entry head of the prefix list table.

**/
VOID
Ip6CleanPrefixListTable (
  IN IP6_SERVICE            *IpSb,
  IN LIST_ENTRY             *ListHead
  )
{
  IP6_PREFIX_LIST_ENTRY     *PrefixList;
  BOOLEAN                   OnLink;

  OnLink = (BOOLEAN) (ListHead == &IpSb->OnlinkPrefix);

  while (!IsListEmpty (ListHead)) {
    PrefixList = NET_LIST_HEAD (ListHead, IP6_PREFIX_LIST_ENTRY, Link);
    Ip6DestroyPrefixListEntry (IpSb, PrefixList, OnLink, TRUE);
  }
}

/**
  Callback function when address resolution is finished. It will cancel
  all the queued frames if the address resolution failed, or transmit them
  if the request succeeded.

  @param[in] Context The context of the callback, a pointer to IP6_NEIGHBOR_ENTRY.

**/
VOID
Ip6OnArpResolved (
  IN VOID                   *Context
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_NEIGHBOR_ENTRY        *ArpQue;
  IP6_SERVICE               *IpSb;
  IP6_LINK_TX_TOKEN         *Token;
  EFI_STATUS                Status;
  BOOLEAN                   Sent;

  ArpQue = (IP6_NEIGHBOR_ENTRY *) Context;
  if ((ArpQue == NULL) || (ArpQue->Interface == NULL)) {
    return ;
  }

  IpSb   = ArpQue->Interface->Service;
  if ((IpSb == NULL) || (IpSb->Signature != IP6_SERVICE_SIGNATURE)) {
    return ;
  }

  //
  // ARP resolve failed for some reason. Release all the frame
  // and ARP queue itself. Ip6FreeArpQue will call the frame's
  // owner back.
  //
  if (NET_MAC_EQUAL (&ArpQue->LinkAddress, &mZeroMacAddress, IpSb->SnpMode.HwAddressSize)) {
    Ip6FreeNeighborEntry (IpSb, ArpQue, FALSE, TRUE, EFI_NO_MAPPING, NULL, NULL);
    return ;
  }

  //
  // ARP resolve succeeded, Transmit all the frame.
  //
  Sent = FALSE;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {
    RemoveEntryList (Entry);

    Token = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link);
    IP6_COPY_LINK_ADDRESS (&Token->DstMac, &ArpQue->LinkAddress);

    //
    // Insert the tx token before transmitting it via MNP as the FrameSentDpc
    // may be called before Mnp->Transmit returns which will remove this tx
    // token from the SentFrames list. Remove it from the list if the returned
    // Status of Mnp->Transmit is not EFI_SUCCESS as in this case the
    // FrameSentDpc won't be queued.
    //
    InsertTailList (&ArpQue->Interface->SentFrames, &Token->Link);

    Status = IpSb->Mnp->Transmit (IpSb->Mnp, &Token->MnpToken);
    if (EFI_ERROR (Status)) {
      RemoveEntryList (&Token->Link);
      Token->CallBack (Token->Packet, Status, 0, Token->Context);

      Ip6FreeLinkTxToken (Token);
      continue;
    } else {
      Sent = TRUE;
    }
  }

  //
  // Free the ArpQue only but not the whole neighbor entry.
  //
  Ip6FreeNeighborEntry (IpSb, ArpQue, FALSE, FALSE, EFI_SUCCESS, NULL, NULL);

  if (Sent && (ArpQue->State == EfiNeighborStale)) {
    ArpQue->State = EfiNeighborDelay;
    ArpQue->Ticks = (UINT32) IP6_GET_TICKS (IP6_DELAY_FIRST_PROBE_TIME);
  }
}

/**
  Allocate and initialize an IP6 neighbor cache entry.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  CallBack          The callback function to be called when
                                address resolution is finished.
  @param[in]  Ip6Address        Points to the IPv6 address of the neighbor.
  @param[in]  LinkAddress       Points to the MAC address of the neighbor.
                                Ignored if NULL.

  @return NULL if failed to allocate memory for the neighbor cache entry.
          Otherwise, point to the created neighbor cache entry.

**/
IP6_NEIGHBOR_ENTRY *
Ip6CreateNeighborEntry (
  IN IP6_SERVICE            *IpSb,
  IN IP6_ARP_CALLBACK       CallBack,
  IN EFI_IPv6_ADDRESS       *Ip6Address,
  IN EFI_MAC_ADDRESS        *LinkAddress OPTIONAL
  )
{
  IP6_NEIGHBOR_ENTRY        *Entry;
  IP6_DEFAULT_ROUTER        *DefaultRouter;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Ip6Address!= NULL);

  Entry = AllocateZeroPool (sizeof (IP6_NEIGHBOR_ENTRY));
  if (Entry == NULL) {
    return NULL;
  }

  Entry->RefCnt    = 1;
  Entry->IsRouter  = FALSE;
  Entry->ArpFree   = FALSE;
  Entry->Dynamic   = FALSE;
  Entry->State     = EfiNeighborInComplete;
  Entry->Transmit  = IP6_MAX_MULTICAST_SOLICIT + 1;
  Entry->CallBack  = CallBack;
  Entry->Interface = NULL;

  InitializeListHead (&Entry->Frames);

  IP6_COPY_ADDRESS (&Entry->Neighbor, Ip6Address);

  if (LinkAddress != NULL) {
    IP6_COPY_LINK_ADDRESS (&Entry->LinkAddress, LinkAddress);
  } else {
    IP6_COPY_LINK_ADDRESS (&Entry->LinkAddress, &mZeroMacAddress);
  }

  InsertHeadList (&IpSb->NeighborTable, &Entry->Link);

  //
  // If corresponding default router entry exists, establish the relationship.
  //
  DefaultRouter = Ip6FindDefaultRouter (IpSb, Ip6Address);
  if (DefaultRouter != NULL) {
    DefaultRouter->NeighborCache = Entry;
  }

  return Entry;
}

/**
  Search a IP6 neighbor cache entry.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  Ip6Address        Points to the IPv6 address of the neighbor.

  @return NULL if it failed to find the matching neighbor cache entry.
          Otherwise, point to the found neighbor cache entry.

**/
IP6_NEIGHBOR_ENTRY *
Ip6FindNeighborEntry (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Ip6Address
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_NEIGHBOR_ENTRY        *Neighbor;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Ip6Address != NULL);

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->NeighborTable) {
    Neighbor = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link);
    if (EFI_IP6_EQUAL (Ip6Address, &Neighbor->Neighbor)) {
      RemoveEntryList (Entry);
      InsertHeadList (&IpSb->NeighborTable, Entry);

      return Neighbor;
    }
  }

  return NULL;
}

/**
  Free a IP6 neighbor cache entry and remove all the frames on the address
  resolution queue that pass the FrameToCancel. That is, either FrameToCancel
  is NULL, or it returns true for the frame.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  NeighborCache     The to be free neighbor cache entry.
  @param[in]  SendIcmpError     If TRUE, send out ICMP error.
  @param[in]  FullFree          If TRUE, remove the neighbor cache entry.
                                Otherwise remove the pending frames.
  @param[in]  IoStatus          The status returned to the cancelled frames'
                                callback function.
  @param[in]  FrameToCancel     Function to select which frame to cancel.
                                This is an optional parameter that may be NULL.
  @param[in]  Context           Opaque parameter to the FrameToCancel.
                                Ignored if FrameToCancel is NULL.

  @retval EFI_INVALID_PARAMETER The input parameter is invalid.
  @retval EFI_SUCCESS           The operation finished successfully.

**/
EFI_STATUS
Ip6FreeNeighborEntry (
  IN IP6_SERVICE            *IpSb,
  IN IP6_NEIGHBOR_ENTRY     *NeighborCache,
  IN BOOLEAN                SendIcmpError,
  IN BOOLEAN                FullFree,
  IN EFI_STATUS             IoStatus,
  IN IP6_FRAME_TO_CANCEL    FrameToCancel OPTIONAL,
  IN VOID                   *Context      OPTIONAL
  )
{
  IP6_LINK_TX_TOKEN         *TxToken;
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_DEFAULT_ROUTER        *DefaultRouter;

  //
  // If FrameToCancel fails, the token will not be released.
  // To avoid the memory leak, stop this usage model.
  //
  if (FullFree && FrameToCancel != NULL) {
    return EFI_INVALID_PARAMETER;
  }

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &NeighborCache->Frames) {
    TxToken = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link);

    if (SendIcmpError && !IP6_IS_MULTICAST (&TxToken->Packet->Ip.Ip6->DestinationAddress)) {
      Ip6SendIcmpError (
        IpSb,
        TxToken->Packet,
        NULL,
        &TxToken->Packet->Ip.Ip6->SourceAddress,
        ICMP_V6_DEST_UNREACHABLE,
        ICMP_V6_ADDR_UNREACHABLE,
        NULL
        );
    }

    if ((FrameToCancel == NULL) || FrameToCancel (TxToken, Context)) {
      RemoveEntryList (Entry);
      TxToken->CallBack (TxToken->Packet, IoStatus, 0, TxToken->Context);
      Ip6FreeLinkTxToken (TxToken);
    }
  }

  if (NeighborCache->ArpFree && IsListEmpty (&NeighborCache->Frames)) {
    RemoveEntryList (&NeighborCache->ArpList);
    NeighborCache->ArpFree = FALSE;
  }

  if (FullFree) {
    if (NeighborCache->IsRouter) {
      DefaultRouter = Ip6FindDefaultRouter (IpSb, &NeighborCache->Neighbor);
      if (DefaultRouter != NULL) {
        Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
      }
    }

    RemoveEntryList (&NeighborCache->Link);
    FreePool (NeighborCache);
  }

  return EFI_SUCCESS;
}

/**
  Allocate and initialize an IP6 default router entry.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  Ip6Address        The IPv6 address of the default router.
  @param[in]  RouterLifetime    The lifetime associated with the default
                                router, in units of seconds.

  @return NULL if it failed to allocate memory for the default router node.
          Otherwise, point to the created default router node.

**/
IP6_DEFAULT_ROUTER *
Ip6CreateDefaultRouter (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Ip6Address,
  IN UINT16                 RouterLifetime
  )
{
  IP6_DEFAULT_ROUTER        *Entry;
  IP6_ROUTE_ENTRY           *RtEntry;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Ip6Address != NULL);

  Entry = AllocatePool (sizeof (IP6_DEFAULT_ROUTER));
  if (Entry == NULL) {
    return NULL;
  }

  Entry->RefCnt        = 1;
  Entry->Lifetime      = RouterLifetime;
  Entry->NeighborCache = Ip6FindNeighborEntry (IpSb, Ip6Address);
  IP6_COPY_ADDRESS (&Entry->Router, Ip6Address);

  //
  // Add a default route into route table with both Destination and PrefixLength set to zero.
  //
  RtEntry = Ip6CreateRouteEntry (NULL, 0, Ip6Address);
  if (RtEntry == NULL) {
    FreePool (Entry);
    return NULL;
  }

  InsertHeadList (&IpSb->RouteTable->RouteArea[0], &RtEntry->Link);
  IpSb->RouteTable->TotalNum++;

  InsertTailList (&IpSb->DefaultRouterList, &Entry->Link);

  return Entry;
}

/**
  Destroy an IP6 default router entry.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.
  @param[in]  DefaultRouter     The to be destroyed IP6_DEFAULT_ROUTER.

**/
VOID
Ip6DestroyDefaultRouter (
  IN IP6_SERVICE            *IpSb,
  IN IP6_DEFAULT_ROUTER     *DefaultRouter
  )
{
  EFI_STATUS                Status;

  RemoveEntryList (&DefaultRouter->Link);

  //
  // Update the Destination Cache - all entries using the time-out router as next-hop
  // should perform next-hop determination again.
  //
  do {
    Status = Ip6DelRoute (IpSb->RouteTable, NULL, 0, &DefaultRouter->Router);
  } while (Status != EFI_NOT_FOUND);

  FreePool (DefaultRouter);
}

/**
  Clean an IP6 default router list.

  @param[in]  IpSb              The pointer to the IP6_SERVICE instance.

**/
VOID
Ip6CleanDefaultRouterList (
  IN IP6_SERVICE            *IpSb
  )
{
  IP6_DEFAULT_ROUTER        *DefaultRouter;

  while (!IsListEmpty (&IpSb->DefaultRouterList)) {
    DefaultRouter = NET_LIST_HEAD (&IpSb->DefaultRouterList, IP6_DEFAULT_ROUTER, Link);
    Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
  }
}

/**
  Search a default router node from an IP6 default router list.

  @param[in]  IpSb          The pointer to the IP6_SERVICE instance.
  @param[in]  Ip6Address    The IPv6 address of the to be searched default router node.

  @return NULL if it failed to find the matching default router node.
          Otherwise, point to the found default router node.

**/
IP6_DEFAULT_ROUTER *
Ip6FindDefaultRouter (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Ip6Address
  )
{
  LIST_ENTRY                *Entry;
  IP6_DEFAULT_ROUTER        *DefaultRouter;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  ASSERT (Ip6Address != NULL);

  NET_LIST_FOR_EACH (Entry, &IpSb->DefaultRouterList) {
    DefaultRouter = NET_LIST_USER_STRUCT (Entry, IP6_DEFAULT_ROUTER, Link);
    if (EFI_IP6_EQUAL (Ip6Address, &DefaultRouter->Router)) {
      return DefaultRouter;
    }
  }

  return NULL;
}

/**
  The function to be called after DAD (Duplicate Address Detection) is performed.

  @param[in]  IsDadPassed   If TRUE, the DAD operation succeed. Otherwise, the DAD operation failed.
  @param[in]  IpIf          Points to the IP6_INTERFACE.
  @param[in]  DadEntry      The DAD entry which already performed DAD.

**/
VOID
Ip6OnDADFinished (
  IN BOOLEAN        IsDadPassed,
  IN IP6_INTERFACE  *IpIf,
  IN IP6_DAD_ENTRY  *DadEntry
  )
{
  IP6_SERVICE               *IpSb;
  IP6_ADDRESS_INFO          *AddrInfo;
  EFI_DHCP6_PROTOCOL        *Dhcp6;
  UINT16                    OptBuf[4];
  EFI_DHCP6_PACKET_OPTION   *Oro;
  EFI_DHCP6_RETRANSMISSION  InfoReqReXmit;
  EFI_IPv6_ADDRESS          AllNodes;

  IpSb     = IpIf->Service;
  AddrInfo = DadEntry->AddressInfo;

  if (IsDadPassed) {
    //
    // DAD succeed.
    //
    if (NetIp6IsLinkLocalAddr (&AddrInfo->Address)) {
      ASSERT (!IpSb->LinkLocalOk);

      IP6_COPY_ADDRESS (&IpSb->LinkLocalAddr, &AddrInfo->Address);
      IpSb->LinkLocalOk = TRUE;
      IpIf->Configured  = TRUE;

      //
      // Check whether DHCP6 need to be started.
      //
      Dhcp6 = IpSb->Ip6ConfigInstance.Dhcp6;

      if (IpSb->Dhcp6NeedStart) {
        Dhcp6->Start (Dhcp6);
        IpSb->Dhcp6NeedStart = FALSE;
      }

      if (IpSb->Dhcp6NeedInfoRequest) {
        //
        // Set the exta options to send. Here we only want the option request option
        // with DNS SERVERS.
        //
        Oro         = (EFI_DHCP6_PACKET_OPTION *) OptBuf;
        Oro->OpCode = HTONS (DHCP6_OPT_ORO);
        Oro->OpLen  = HTONS (2);
        *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS);

        InfoReqReXmit.Irt = 4;
        InfoReqReXmit.Mrc = 64;
        InfoReqReXmit.Mrt = 60;
        InfoReqReXmit.Mrd = 0;

        Dhcp6->InfoRequest (
                 Dhcp6,
                 TRUE,
                 Oro,
                 0,
                 NULL,
                 &InfoReqReXmit,
                 IpSb->Ip6ConfigInstance.Dhcp6Event,
                 Ip6ConfigOnDhcp6Reply,
                 &IpSb->Ip6ConfigInstance
                 );
      }

      //
      // Add an on-link prefix for link-local address.
      //
      Ip6CreatePrefixListEntry (
        IpSb,
        TRUE,
        (UINT32) IP6_INFINIT_LIFETIME,
        (UINT32) IP6_INFINIT_LIFETIME,
        IP6_LINK_LOCAL_PREFIX_LENGTH,
        &IpSb->LinkLocalAddr
        );

    } else {
      //
      // Global scope unicast address.
      //
      Ip6AddAddr (IpIf, AddrInfo);

      //
      // Add an on-link prefix for this address.
      //
      Ip6CreatePrefixListEntry (
        IpSb,
        TRUE,
        AddrInfo->ValidLifetime,
        AddrInfo->PreferredLifetime,
        AddrInfo->PrefixLength,
        &AddrInfo->Address
        );

      IpIf->Configured = TRUE;
    }
  } else {
    //
    // Leave the group we joined before.
    //
    Ip6LeaveGroup (IpSb, &DadEntry->Destination);
  }

  if (DadEntry->Callback != NULL) {
    DadEntry->Callback (IsDadPassed, &AddrInfo->Address, DadEntry->Context);
  }

  if (!IsDadPassed && NetIp6IsLinkLocalAddr (&AddrInfo->Address)) {
    FreePool (AddrInfo);
    RemoveEntryList (&DadEntry->Link);
    FreePool (DadEntry);
    //
    // Leave link-scope all-nodes multicast address (FF02::1)
    //
    Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
    Ip6LeaveGroup (IpSb, &AllNodes);
    //
    // Disable IP operation since link-local address is a duplicate address.
    //
    IpSb->LinkLocalDadFail = TRUE;
    IpSb->Mnp->Configure (IpSb->Mnp, NULL);
    gBS->SetTimer (IpSb->Timer, TimerCancel, 0);
    gBS->SetTimer (IpSb->FasterTimer, TimerCancel, 0);
    return ;
  }

  if (!IsDadPassed || NetIp6IsLinkLocalAddr (&AddrInfo->Address)) {
    //
    // Free the AddressInfo we hold if DAD fails or it is a link-local address.
    //
    FreePool (AddrInfo);
  }

  RemoveEntryList (&DadEntry->Link);
  FreePool (DadEntry);
}

/**
  Create a DAD (Duplicate Address Detection) entry and queue it to be performed.

  @param[in]  IpIf          Points to the IP6_INTERFACE.
  @param[in]  AddressInfo   The address information which needs DAD performed.
  @param[in]  Callback      The callback routine that will be called after DAD
                            is performed. This is an optional parameter that
                            may be NULL.
  @param[in]  Context       The opaque parameter for a DAD callback routine.
                            This is an optional parameter that may be NULL.

  @retval EFI_SUCCESS           The DAD entry was created and queued.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory to complete the
                                operation.


**/
EFI_STATUS
Ip6InitDADProcess (
  IN IP6_INTERFACE          *IpIf,
  IN IP6_ADDRESS_INFO       *AddressInfo,
  IN IP6_DAD_CALLBACK       Callback  OPTIONAL,
  IN VOID                   *Context  OPTIONAL
  )
{
  IP6_DAD_ENTRY                             *Entry;
  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS  *DadXmits;
  IP6_SERVICE                               *IpSb;
  EFI_STATUS                                Status;
  UINT32                                    MaxDelayTick;

  NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE);
  ASSERT (AddressInfo != NULL);

  //
  // Do nothing if we have already started DAD on the address.
  //
  if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) {
    return EFI_SUCCESS;
  }

  Status   = EFI_SUCCESS;
  IpSb     = IpIf->Service;
  DadXmits = &IpSb->Ip6ConfigInstance.DadXmits;

  //
  // Allocate the resources and insert info
  //
  Entry = AllocatePool (sizeof (IP6_DAD_ENTRY));
  if (Entry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Map the incoming unicast address to solicited-node multicast address
  //
  Ip6CreateSNMulticastAddr (&AddressInfo->Address, &Entry->Destination);

  //
  // Join in the solicited-node multicast address.
  //
  Status = Ip6JoinGroup (IpSb, IpIf, &Entry->Destination);
  if (EFI_ERROR (Status)) {
    FreePool (Entry);
    return Status;
  }

  Entry->Signature    = IP6_DAD_ENTRY_SIGNATURE;
  Entry->MaxTransmit  = DadXmits->DupAddrDetectTransmits;
  Entry->Transmit     = 0;
  Entry->Receive      = 0;
  MaxDelayTick        = IP6_MAX_RTR_SOLICITATION_DELAY / IP6_TIMER_INTERVAL_IN_MS;
  Entry->RetransTick  = (MaxDelayTick * ((NET_RANDOM (NetRandomInitSeed ()) % 5) + 1)) / 5;
  Entry->AddressInfo  = AddressInfo;
  Entry->Callback     = Callback;
  Entry->Context      = Context;
  InsertTailList (&IpIf->DupAddrDetectList, &Entry->Link);

  if (Entry->MaxTransmit == 0) {
    //
    // DAD is disabled on this interface, immediately mark this DAD successful.
    //
    Ip6OnDADFinished (TRUE, IpIf, Entry);
  }

  return EFI_SUCCESS;
}

/**
  Search IP6_DAD_ENTRY from the Duplicate Address Detection List.

  @param[in]  IpSb          The pointer to the IP6_SERVICE instance.
  @param[in]  Target        The address information which needs DAD performed .
  @param[out] Interface     If not NULL, output the IP6 interface that configures
                            the tentative address.

  @return NULL if failed to find the matching DAD entry.
          Otherwise, point to the found DAD entry.

**/
IP6_DAD_ENTRY *
Ip6FindDADEntry (
  IN  IP6_SERVICE      *IpSb,
  IN  EFI_IPv6_ADDRESS *Target,
  OUT IP6_INTERFACE    **Interface OPTIONAL
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Entry2;
  IP6_INTERFACE             *IpIf;
  IP6_DAD_ENTRY             *DupAddrDetect;
  IP6_ADDRESS_INFO          *AddrInfo;

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);

    NET_LIST_FOR_EACH (Entry2, &IpIf->DupAddrDetectList) {
      DupAddrDetect = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE);
      AddrInfo      = DupAddrDetect->AddressInfo;
      if (EFI_IP6_EQUAL (&AddrInfo->Address, Target)) {
        if (Interface != NULL) {
          *Interface = IpIf;
        }
        return DupAddrDetect;
      }
    }
  }

  return NULL;
}

/**
  Generate router solicit message and send it out to Destination Address or
  All Router Link Local scope multicast address.

  @param[in]  IpSb               The IP service to send the packet.
  @param[in]  Interface          If not NULL, points to the IP6 interface to send
                                 the packet.
  @param[in]  SourceAddress      If not NULL, the source address of the message.
  @param[in]  DestinationAddress If not NULL, the destination address of the message.
  @param[in]  SourceLinkAddress  If not NULL, the MAC address of the source.
                                 A source link-layer address option will be appended
                                 to the message.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            The router solicit message was successfully sent.

**/
EFI_STATUS
Ip6SendRouterSolicit (
  IN IP6_SERVICE            *IpSb,
  IN IP6_INTERFACE          *Interface          OPTIONAL,
  IN EFI_IPv6_ADDRESS       *SourceAddress      OPTIONAL,
  IN EFI_IPv6_ADDRESS       *DestinationAddress OPTIONAL,
  IN EFI_MAC_ADDRESS        *SourceLinkAddress  OPTIONAL
  )
{
  NET_BUF                   *Packet;
  EFI_IP6_HEADER            Head;
  IP6_ICMP_INFORMATION_HEAD *IcmpHead;
  IP6_ETHER_ADDR_OPTION     *LinkLayerOption;
  UINT16                    PayloadLen;
  IP6_INTERFACE             *IpIf;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  IpIf = Interface;
  if (IpIf == NULL && IpSb->DefaultInterface != NULL) {
    IpIf = IpSb->DefaultInterface;
  }

  //
  // Generate the packet to be sent
  //

  PayloadLen = (UINT16) sizeof (IP6_ICMP_INFORMATION_HEAD);
  if (SourceLinkAddress != NULL) {
    PayloadLen += sizeof (IP6_ETHER_ADDR_OPTION);
  }

  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_ICMP;
  Head.HopLimit       = IP6_HOP_LIMIT;

  if (SourceAddress != NULL) {
    IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress);
  } else {
    ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS));
  }


  if (DestinationAddress != NULL) {
    IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress);
  } else {
    Ip6SetToAllNodeMulticast (TRUE, IP6_LINK_LOCAL_SCOPE, &Head.DestinationAddress);
  }

  NetbufReserve (Packet, sizeof (EFI_IP6_HEADER));

  //
  // Fill in the ICMP header, and Source link-layer address if contained.
  //

  IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE);
  ASSERT (IcmpHead != NULL);
  ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD));
  IcmpHead->Head.Type = ICMP_V6_ROUTER_SOLICIT;
  IcmpHead->Head.Code = 0;

  LinkLayerOption = NULL;
  if (SourceLinkAddress != NULL) {
    LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace (
                                                  Packet,
                                                  sizeof (IP6_ETHER_ADDR_OPTION),
                                                  FALSE
                                                  );
    ASSERT (LinkLayerOption != NULL);
    LinkLayerOption->Type   = Ip6OptionEtherSource;
    LinkLayerOption->Length = (UINT8) sizeof (IP6_ETHER_ADDR_OPTION);
    CopyMem (LinkLayerOption->EtherAddr, SourceLinkAddress, 6);
  }

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, IpIf, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

/**
  Generate a Neighbor Advertisement message and send it out to Destination Address.

  @param[in]  IpSb               The IP service to send the packet.
  @param[in]  SourceAddress      The source address of the message.
  @param[in]  DestinationAddress The destination address of the message.
  @param[in]  TargetIp6Address   The target address field in the Neighbor Solicitation
                                 message that prompted this advertisement.
  @param[in]  TargetLinkAddress  The MAC address for the target, i.e. the sender
                                 of the advertisement.
  @param[in]  IsRouter           If TRUE, indicates the sender is a router.
  @param[in]  Override           If TRUE, indicates the advertisement should override
                                 an existing cache entry and update the MAC address.
  @param[in]  Solicited          If TRUE, indicates the advertisement was sent
                                 in response to a Neighbor Solicitation from
                                 the Destination address.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            The Neighbor Advertise message was successfully sent.

**/
EFI_STATUS
Ip6SendNeighborAdvertise (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *SourceAddress,
  IN EFI_IPv6_ADDRESS       *DestinationAddress,
  IN EFI_IPv6_ADDRESS       *TargetIp6Address,
  IN EFI_MAC_ADDRESS        *TargetLinkAddress,
  IN BOOLEAN                IsRouter,
  IN BOOLEAN                Override,
  IN BOOLEAN                Solicited
  )
{
  NET_BUF                   *Packet;
  EFI_IP6_HEADER            Head;
  IP6_ICMP_INFORMATION_HEAD *IcmpHead;
  IP6_ETHER_ADDR_OPTION     *LinkLayerOption;
  EFI_IPv6_ADDRESS          *Target;
  UINT16                    PayloadLen;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  //
  // The Neighbor Advertisement message must include a Target link-layer address option
  // when responding to multicast solicitation and should include such option when
  // responding to unicast solicitation. It also must include such option as unsolicited
  // advertisement.
  //
  ASSERT (DestinationAddress != NULL && TargetIp6Address != NULL && TargetLinkAddress != NULL);

  PayloadLen = (UINT16) (sizeof (IP6_ICMP_INFORMATION_HEAD) + sizeof (EFI_IPv6_ADDRESS) + sizeof (IP6_ETHER_ADDR_OPTION));

  //
  // Generate the packet to be sent
  //

  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_ICMP;
  Head.HopLimit       = IP6_HOP_LIMIT;

  IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress);
  IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress);

  NetbufReserve (Packet, sizeof (EFI_IP6_HEADER));

  //
  // Fill in the ICMP header, Target address, and Target link-layer address.
  // Set the Router flag, Solicited flag and Override flag.
  //

  IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE);
  ASSERT (IcmpHead != NULL);
  ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD));
  IcmpHead->Head.Type = ICMP_V6_NEIGHBOR_ADVERTISE;
  IcmpHead->Head.Code = 0;

  if (IsRouter) {
    IcmpHead->Fourth |= IP6_IS_ROUTER_FLAG;
  }

  if (Solicited) {
    IcmpHead->Fourth |= IP6_SOLICITED_FLAG;
  }

  if (Override) {
    IcmpHead->Fourth |= IP6_OVERRIDE_FLAG;
  }

  Target = (EFI_IPv6_ADDRESS *) NetbufAllocSpace (Packet, sizeof (EFI_IPv6_ADDRESS), FALSE);
  ASSERT (Target != NULL);
  IP6_COPY_ADDRESS (Target, TargetIp6Address);

  LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace (
                                                Packet,
                                                sizeof (IP6_ETHER_ADDR_OPTION),
                                                FALSE
                                                );
  ASSERT (LinkLayerOption != NULL);
  LinkLayerOption->Type   = Ip6OptionEtherTarget;
  LinkLayerOption->Length = 1;
  CopyMem (LinkLayerOption->EtherAddr, TargetLinkAddress, 6);

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, NULL, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

/**
  Generate the Neighbor Solicitation message and send it to the Destination Address.

  @param[in]  IpSb               The IP service to send the packet
  @param[in]  SourceAddress      The source address of the message.
  @param[in]  DestinationAddress The destination address of the message.
  @param[in]  TargetIp6Address   The IP address of the target of the solicitation.
                                 It must not be a multicast address.
  @param[in]  SourceLinkAddress  The MAC address for the sender. If not NULL,
                                 a source link-layer address option will be appended
                                 to the message.

  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            The Neighbor Advertise message was successfully sent.

**/
EFI_STATUS
Ip6SendNeighborSolicit (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *SourceAddress,
  IN EFI_IPv6_ADDRESS       *DestinationAddress,
  IN EFI_IPv6_ADDRESS       *TargetIp6Address,
  IN EFI_MAC_ADDRESS        *SourceLinkAddress OPTIONAL
  )
{
  NET_BUF                   *Packet;
  EFI_IP6_HEADER            Head;
  IP6_ICMP_INFORMATION_HEAD *IcmpHead;
  IP6_ETHER_ADDR_OPTION     *LinkLayerOption;
  EFI_IPv6_ADDRESS          *Target;
  BOOLEAN                   IsDAD;
  UINT16                    PayloadLen;
  IP6_NEIGHBOR_ENTRY        *Neighbor;

  //
  // Check input parameters
  //
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  if (DestinationAddress == NULL || TargetIp6Address == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  IsDAD = FALSE;

  if (SourceAddress == NULL || (SourceAddress != NULL && NetIp6IsUnspecifiedAddr (SourceAddress))) {
    IsDAD = TRUE;
  }

  //
  // The Neighbor Solicitation message should include a source link-layer address option
  // if the solicitation is not sent by performing DAD - Duplicate Address Detection.
  // Otherwise must not include it.
  //
  PayloadLen = (UINT16) (sizeof (IP6_ICMP_INFORMATION_HEAD) + sizeof (EFI_IPv6_ADDRESS));

  if (!IsDAD) {
    if (SourceLinkAddress == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    PayloadLen = (UINT16) (PayloadLen + sizeof (IP6_ETHER_ADDR_OPTION));
  }

  //
  // Generate the packet to be sent
  //

  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_ICMP;
  Head.HopLimit       = IP6_HOP_LIMIT;

  if (SourceAddress != NULL) {
    IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress);
  } else {
    ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS));
  }

  IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress);

  NetbufReserve (Packet, sizeof (EFI_IP6_HEADER));

  //
  // Fill in the ICMP header, Target address, and Source link-layer address.
  //
  IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE);
  ASSERT (IcmpHead != NULL);
  ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD));
  IcmpHead->Head.Type = ICMP_V6_NEIGHBOR_SOLICIT;
  IcmpHead->Head.Code = 0;

  Target = (EFI_IPv6_ADDRESS *) NetbufAllocSpace (Packet, sizeof (EFI_IPv6_ADDRESS), FALSE);
  ASSERT (Target != NULL);
  IP6_COPY_ADDRESS (Target, TargetIp6Address);

  LinkLayerOption = NULL;
  if (!IsDAD) {

    //
    // Fill in the source link-layer address option
    //
    LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace (
                                                  Packet,
                                                  sizeof (IP6_ETHER_ADDR_OPTION),
                                                  FALSE
                                                  );
    ASSERT (LinkLayerOption != NULL);
    LinkLayerOption->Type   = Ip6OptionEtherSource;
    LinkLayerOption->Length = 1;
    CopyMem (LinkLayerOption->EtherAddr, SourceLinkAddress, 6);
  }

  //
  // Create a Neighbor Cache entry in the INCOMPLETE state when performing
  // address resolution.
  //
  if (!IsDAD && Ip6IsSNMulticastAddr (DestinationAddress)) {
    Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address);
    if (Neighbor == NULL) {
      Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, TargetIp6Address, NULL);
      ASSERT (Neighbor != NULL);
    }
  }

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, IpSb->DefaultInterface, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

/**
  Process the Neighbor Solicitation message. The message may be sent for Duplicate
  Address Detection or Address Resolution.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the message.
  @param[in]  Packet             The content of the message with IP head removed.

  @retval EFI_SUCCESS            The packet processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval EFI_ICMP_ERROR         The packet indicates that DAD is failed.
  @retval Others                 Failed to process the packet.

**/
EFI_STATUS
Ip6ProcessNeighborSolicit (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD Icmp;
  EFI_IPv6_ADDRESS          Target;
  IP6_ETHER_ADDR_OPTION     LinkLayerOption;
  BOOLEAN                   IsDAD;
  BOOLEAN                   IsUnicast;
  BOOLEAN                   IsMaintained;
  IP6_DAD_ENTRY             *DupAddrDetect;
  IP6_INTERFACE             *IpIf;
  IP6_NEIGHBOR_ENTRY        *Neighbor;
  BOOLEAN                   Solicited;
  BOOLEAN                   UpdateCache;
  EFI_IPv6_ADDRESS          Dest;
  UINT16                    OptionLen;
  UINT8                     *Option;
  BOOLEAN                   Provided;
  EFI_STATUS                Status;
  VOID                      *MacAddress;

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
  NetbufCopy (Packet, sizeof (Icmp), sizeof (Target), Target.Addr);

  //
  // Perform Message Validation:
  // The IP Hop Limit field has a value of 255, i.e., the packet
  // could not possibly have been forwarded by a router.
  // ICMP Code is 0.
  // Target Address is not a multicast address.
  //
  Status = EFI_INVALID_PARAMETER;

  if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 || !NetIp6IsValidUnicast (&Target)) {
    goto Exit;
  }

  //
  // ICMP length is 24 or more octets.
  //
  OptionLen = 0;
  if (Head->PayloadLength < IP6_ND_LENGTH) {
    goto Exit;
  } else {
    OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH);
    if (OptionLen != 0) {
      Option    = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);
      ASSERT (Option != NULL);

      //
      // All included options should have a length that is greater than zero.
      //
      if (!Ip6IsNDOptionValid (Option, OptionLen)) {
        goto Exit;
      }
    }
  }

  IsDAD        = NetIp6IsUnspecifiedAddr (&Head->SourceAddress);
  IsUnicast    = (BOOLEAN) !Ip6IsSNMulticastAddr (&Head->DestinationAddress);
  IsMaintained = Ip6IsOneOfSetAddress (IpSb, &Target, &IpIf, NULL);

  Provided = FALSE;
  if (OptionLen >= sizeof (IP6_ETHER_ADDR_OPTION)) {
    NetbufCopy (
      Packet,
      IP6_ND_LENGTH,
      sizeof (IP6_ETHER_ADDR_OPTION),
      (UINT8 *) &LinkLayerOption
      );
    //
    // The solicitation for neighbor discovery should include a source link-layer
    // address option. If the option is not recognized, silently ignore it.
    //
    if (LinkLayerOption.Type == Ip6OptionEtherSource) {
      if (IsDAD) {
        //
        // If the IP source address is the unspecified address, the source
        // link-layer address option must not be included in the message.
        //
        goto Exit;
      }

      Provided = TRUE;
    }
  }

  //
  // If the IP source address is the unspecified address, the IP
  // destination address is a solicited-node multicast address.
  //
  if (IsDAD && IsUnicast) {
    goto Exit;
  }

  //
  // If the target address is tentative, and the source address is a unicast address,
  // the solicitation's sender is performing address resolution on the target;
  //  the solicitation should be silently ignored.
  //
  if (!IsDAD && !IsMaintained) {
    goto Exit;
  }

  //
  // If received unicast neighbor solicitation but destination is not this node,
  // drop the packet.
  //
  if (IsUnicast && !IsMaintained) {
    goto Exit;
  }

  //
  // In DAD, when target address is a tentative address,
  // process the received neighbor solicitation message but not send out response.
  //
  if (IsDAD && !IsMaintained) {
    DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf);
    if (DupAddrDetect != NULL) {
      //
      // Check the MAC address of the incoming packet.
      //
      if (IpSb->RecvRequest.MnpToken.Packet.RxData == NULL) {
        goto Exit;
      }

      MacAddress = IpSb->RecvRequest.MnpToken.Packet.RxData->SourceAddress;
      if (MacAddress != NULL) {
        if (CompareMem (
              MacAddress,
              &IpSb->SnpMode.CurrentAddress,
              IpSb->SnpMode.HwAddressSize
              ) != 0) {
          //
          // The NS is from another node to performing DAD on the same address.
          // Fail DAD for the tentative address.
          //
          Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect);
          Status = EFI_ICMP_ERROR;
        } else {
          //
          // The below layer loopback the NS we sent. Record it and wait for more.
          //
          DupAddrDetect->Receive++;
          Status = EFI_SUCCESS;
        }
      }
    }
    goto Exit;
  }

  //
  // If the solicitation does not contain a link-layer address, DO NOT create or
  // update the neighbor cache entries.
  //
  if (Provided) {
    Neighbor    = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress);
    UpdateCache = FALSE;

    if (Neighbor == NULL) {
      Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, &Head->SourceAddress, NULL);
      if (Neighbor == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }
      UpdateCache = TRUE;
    } else {
      if (CompareMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6) != 0) {
        UpdateCache = TRUE;
      }
    }

    if (UpdateCache) {
      Neighbor->State = EfiNeighborStale;
      Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
      CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6);
      //
      // Send queued packets if exist.
      //
      Neighbor->CallBack ((VOID *) Neighbor);
    }
  }

  //
  // Sends a Neighbor Advertisement as response.
  // Set the Router flag to zero since the node is a host.
  // If the source address of the solicitation is unspeicifed, and target address
  // is one of the maintained address, reply a unsolicited multicast advertisement.
  //
  if (IsDAD && IsMaintained) {
    Solicited = FALSE;
    Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &Dest);
  } else {
    Solicited = TRUE;
    IP6_COPY_ADDRESS (&Dest, &Head->SourceAddress);
  }

  Status = Ip6SendNeighborAdvertise (
             IpSb,
             &Target,
             &Dest,
             &Target,
             &IpSb->SnpMode.CurrentAddress,
             FALSE,
             TRUE,
             Solicited
             );
Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Process the Neighbor Advertisement message.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the message.
  @param[in]  Packet             The content of the message with IP head removed.

  @retval EFI_SUCCESS            The packet processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval EFI_ICMP_ERROR         The packet indicates that DAD is failed.
  @retval Others                 Failed to process the packet.

**/
EFI_STATUS
Ip6ProcessNeighborAdvertise (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD Icmp;
  EFI_IPv6_ADDRESS          Target;
  IP6_ETHER_ADDR_OPTION     LinkLayerOption;
  BOOLEAN                   Provided;
  INTN                      Compare;
  IP6_NEIGHBOR_ENTRY        *Neighbor;
  IP6_DEFAULT_ROUTER        *DefaultRouter;
  BOOLEAN                   Solicited;
  BOOLEAN                   IsRouter;
  BOOLEAN                   Override;
  IP6_DAD_ENTRY             *DupAddrDetect;
  IP6_INTERFACE             *IpIf;
  UINT16                    OptionLen;
  UINT8                     *Option;
  EFI_STATUS                Status;

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
  NetbufCopy (Packet, sizeof (Icmp), sizeof (Target), Target.Addr);

  //
  // Validate the incoming Neighbor Advertisement
  //
  Status = EFI_INVALID_PARAMETER;
  //
  // The IP Hop Limit field has a value of 255, i.e., the packet
  // could not possibly have been forwarded by a router.
  // ICMP Code is 0.
  // Target Address is not a multicast address.
  //
  if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 || !NetIp6IsValidUnicast (&Target)) {
    goto Exit;
  }

  //
  // ICMP length is 24 or more octets.
  //
  Provided  = FALSE;
  OptionLen = 0;
  if (Head->PayloadLength < IP6_ND_LENGTH) {
    goto Exit;
  } else {
    OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH);
    if (OptionLen != 0) {
      Option    = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL);
      ASSERT (Option != NULL);

      //
      // All included options should have a length that is greater than zero.
      //
      if (!Ip6IsNDOptionValid (Option, OptionLen)) {
        goto Exit;
      }
    }
  }

  //
  // If the IP destination address is a multicast address, Solicited Flag is ZERO.
  //
  Solicited = FALSE;
  if ((Icmp.Fourth & IP6_SOLICITED_FLAG) == IP6_SOLICITED_FLAG) {
    Solicited = TRUE;
  }
  if (IP6_IS_MULTICAST (&Head->DestinationAddress) && Solicited) {
    goto Exit;
  }

  //
  // DAD - Check whether the Target is one of our tentative address.
  //
  DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf);
  if (DupAddrDetect != NULL) {
    //
    // DAD fails, some other node is using this address.
    //
    NetbufFree (Packet);
    Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect);
    return EFI_ICMP_ERROR;
  }

  //
  // Search the Neighbor Cache for the target's entry. If no entry exists,
  // the advertisement should be silently discarded.
  //
  Neighbor = Ip6FindNeighborEntry (IpSb, &Target);
  if (Neighbor == NULL) {
    goto Exit;
  }

  //
  // Get IsRouter Flag and Override Flag
  //
  IsRouter = FALSE;
  Override = FALSE;
  if ((Icmp.Fourth & IP6_IS_ROUTER_FLAG) == IP6_IS_ROUTER_FLAG) {
    IsRouter = TRUE;
  }
  if ((Icmp.Fourth & IP6_OVERRIDE_FLAG) == IP6_OVERRIDE_FLAG) {
    Override = TRUE;
  }

  //
  // Check whether link layer option is included.
  //
  if (OptionLen >= sizeof (IP6_ETHER_ADDR_OPTION)) {
    NetbufCopy (
      Packet,
      IP6_ND_LENGTH,
      sizeof (IP6_ETHER_ADDR_OPTION),
      (UINT8 *) &LinkLayerOption
      );

    if (LinkLayerOption.Type == Ip6OptionEtherTarget) {
      Provided = TRUE;
    }
  }

  Compare = 0;
  if (Provided) {
    Compare = CompareMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6);
  }

  if (!Neighbor->IsRouter && IsRouter) {
    DefaultRouter = Ip6FindDefaultRouter (IpSb, &Target);
    if (DefaultRouter != NULL) {
      DefaultRouter->NeighborCache = Neighbor;
    }
  }

  if (Neighbor->State == EfiNeighborInComplete) {
    //
    // If the target's Neighbor Cache entry is in INCOMPLETE state and no
    // Target Link-Layer address option is included while link layer has
    // address, the message should be silently discarded.
    //
    if (!Provided) {
      goto Exit;
    }
    //
    // Update the Neighbor Cache
    //
    CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6);
    if (Solicited) {
      Neighbor->State = EfiNeighborReachable;
      Neighbor->Ticks = IP6_GET_TICKS (IpSb->ReachableTime);
    } else {
      Neighbor->State = EfiNeighborStale;
      Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
      //
      // Send any packets queued for the neighbor awaiting address resolution.
      //
      Neighbor->CallBack ((VOID *) Neighbor);
    }

    Neighbor->IsRouter = IsRouter;

  } else {
    if (!Override && Compare != 0) {
      //
      // When the Override Flag is clear and supplied link-layer address differs from
      // that in the cache, if the state of the entry is not REACHABLE, ignore the
      // message. Otherwise set it to STALE but do not update the entry in any
      // other way.
      //
      if (Neighbor->State == EfiNeighborReachable) {
        Neighbor->State = EfiNeighborStale;
        Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
      }
    } else {
      if (Compare != 0) {
        CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6);
      }
      //
      // Update the entry's state
      //
      if (Solicited) {
        Neighbor->State = EfiNeighborReachable;
        Neighbor->Ticks = IP6_GET_TICKS (IpSb->ReachableTime);
      } else {
        if (Compare != 0) {
          Neighbor->State = EfiNeighborStale;
          Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
        }
      }

      //
      // When IsRouter is changed from TRUE to FALSE, remove the router from the
      // Default Router List and remove the Destination Cache entries for all destinations
      // using the neighbor as a router.
      //
      if (Neighbor->IsRouter && !IsRouter) {
        DefaultRouter = Ip6FindDefaultRouter (IpSb, &Target);
        if (DefaultRouter != NULL) {
          Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
        }
      }

      Neighbor->IsRouter = IsRouter;
    }
  }

  if (Neighbor->State == EfiNeighborReachable) {
    Neighbor->CallBack ((VOID *) Neighbor);
  }

  Status = EFI_SUCCESS;

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Process the Router Advertisement message according to RFC4861.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the message.
  @param[in]  Packet             The content of the message with the IP head removed.

  @retval EFI_SUCCESS            The packet processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to complete the
                                 operation.
  @retval Others                 Failed to process the packet.

**/
EFI_STATUS
Ip6ProcessRouterAdvertise (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD Icmp;
  UINT32                    ReachableTime;
  UINT32                    RetransTimer;
  UINT16                    RouterLifetime;
  UINT16                    Offset;
  UINT8                     Type;
  UINT8                     Length;
  IP6_ETHER_ADDR_OPTION     LinkLayerOption;
  UINT32                    Fourth;
  UINT8                     CurHopLimit;
  BOOLEAN                   Mflag;
  BOOLEAN                   Oflag;
  IP6_DEFAULT_ROUTER        *DefaultRouter;
  IP6_NEIGHBOR_ENTRY        *NeighborCache;
  EFI_MAC_ADDRESS           LinkLayerAddress;
  IP6_MTU_OPTION            MTUOption;
  IP6_PREFIX_INFO_OPTION    PrefixOption;
  IP6_PREFIX_LIST_ENTRY     *PrefixList;
  BOOLEAN                   OnLink;
  BOOLEAN                   Autonomous;
  EFI_IPv6_ADDRESS          StatelessAddress;
  EFI_STATUS                Status;
  UINT16                    OptionLen;
  UINT8                     *Option;
  INTN                      Result;

  Status = EFI_INVALID_PARAMETER;

  if (IpSb->Ip6ConfigInstance.Policy != Ip6ConfigPolicyAutomatic) {
    //
    // Skip the process below as it's not required under the current policy.
    //
    goto Exit;
  }

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);

  //
  // Validate the incoming Router Advertisement
  //

  //
  // The IP source address must be a link-local address
  //
  if (!NetIp6IsLinkLocalAddr (&Head->SourceAddress)) {
    goto Exit;
  }
  //
  // The IP Hop Limit field has a value of 255, i.e. the packet
  // could not possibly have been forwarded by a router.
  // ICMP Code is 0.
  // ICMP length (derived from the IP length) is 16 or more octets.
  //
  if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 ||
      Head->PayloadLength < IP6_RA_LENGTH) {
    goto Exit;
  }

  //
  // All included options have a length that is greater than zero.
  //
  OptionLen = (UINT16) (Head->PayloadLength - IP6_RA_LENGTH);
  if (OptionLen != 0) {
    Option    = NetbufGetByte (Packet, IP6_RA_LENGTH, NULL);
    ASSERT (Option != NULL);

    if (!Ip6IsNDOptionValid (Option, OptionLen)) {
      goto Exit;
    }
  }

  //
  // Process Fourth field.
  // In Router Advertisement, Fourth is composed of CurHopLimit (8bit), M flag, O flag,
  // and Router Lifetime (16 bit).
  //

  Fourth = NTOHL (Icmp.Fourth);
  CopyMem (&RouterLifetime, &Fourth, sizeof (UINT16));

  //
  // If the source address already in the default router list, update it.
  // Otherwise create a new entry.
  // A Lifetime of zero indicates that the router is not a default router.
  //
  DefaultRouter = Ip6FindDefaultRouter (IpSb, &Head->SourceAddress);
  if (DefaultRouter == NULL) {
    if (RouterLifetime != 0) {
      DefaultRouter = Ip6CreateDefaultRouter (IpSb, &Head->SourceAddress, RouterLifetime);
      if (DefaultRouter == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }
    }
  } else {
    if (RouterLifetime != 0) {
      DefaultRouter->Lifetime = RouterLifetime;
      //
      // Check the corresponding neighbor cache entry here.
      //
      if (DefaultRouter->NeighborCache == NULL) {
        DefaultRouter->NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress);
      }
    } else {
      //
      // If the address is in the host's default router list and the router lifetime is zero,
      // immediately time-out the entry.
      //
      Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
    }
  }

  CurHopLimit = *((UINT8 *) &Fourth + 3);
  if (CurHopLimit != 0) {
    IpSb->CurHopLimit = CurHopLimit;
  }

  Mflag = FALSE;
  Oflag = FALSE;
  if ((*((UINT8 *) &Fourth + 2) & IP6_M_ADDR_CONFIG_FLAG) == IP6_M_ADDR_CONFIG_FLAG) {
    Mflag = TRUE;
  } else {
    if ((*((UINT8 *) &Fourth + 2) & IP6_O_CONFIG_FLAG) == IP6_O_CONFIG_FLAG) {
      Oflag = TRUE;
    }
  }

  if (Mflag || Oflag) {
    //
    // Use Ip6Config to get available addresses or other configuration from DHCP.
    //
    Ip6ConfigStartStatefulAutoConfig (&IpSb->Ip6ConfigInstance, Oflag);
  }

  //
  // Process Reachable Time and Retrans Timer fields.
  //
  NetbufCopy (Packet, sizeof (Icmp), sizeof (UINT32), (UINT8 *) &ReachableTime);
  NetbufCopy (Packet, sizeof (Icmp) + sizeof (UINT32), sizeof (UINT32), (UINT8 *) &RetransTimer);
  ReachableTime = NTOHL (ReachableTime);
  RetransTimer  = NTOHL (RetransTimer);

  if (ReachableTime != 0 && ReachableTime != IpSb->BaseReachableTime) {
    //
    // If new value is not unspecified and differs from the previous one, record it
    // in BaseReachableTime and recompute a ReachableTime.
    //
    IpSb->BaseReachableTime = ReachableTime;
    Ip6UpdateReachableTime (IpSb);
  }

  if (RetransTimer != 0) {
    IpSb->RetransTimer = RetransTimer;
  }

  //
  // IsRouter flag must be set to TRUE if corresponding neighbor cache entry exists.
  //
  NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress);
  if (NeighborCache != NULL) {
    NeighborCache->IsRouter = TRUE;
  }

  //
  // If an valid router advertisment is received, stops router solicitation.
  //
  IpSb->RouterAdvertiseReceived = TRUE;

  //
  // The only defined options that may appear are the Source
  // Link-Layer Address, Prefix information and MTU options.
  // All included options have a length that is greater than zero.
  //
  Offset = 16;
  while (Offset < Head->PayloadLength) {
    NetbufCopy (Packet, Offset, sizeof (UINT8), &Type);
    switch (Type) {
    case Ip6OptionEtherSource:
      //
      // Update the neighbor cache
      //
      NetbufCopy (Packet, Offset, sizeof (IP6_ETHER_ADDR_OPTION), (UINT8 *) &LinkLayerOption);
      if (LinkLayerOption.Length <= 0) {
        goto Exit;
      }

      ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS));
      CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6);

      if (NeighborCache == NULL) {
        NeighborCache = Ip6CreateNeighborEntry (
                          IpSb,
                          Ip6OnArpResolved,
                          &Head->SourceAddress,
                          &LinkLayerAddress
                          );
        if (NeighborCache == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Exit;
        }
        NeighborCache->IsRouter = TRUE;
        NeighborCache->State    = EfiNeighborStale;
        NeighborCache->Ticks    = (UINT32) IP6_INFINIT_LIFETIME;
      } else {
        Result = CompareMem (&LinkLayerAddress, &NeighborCache->LinkAddress, 6);

        //
        // If the link-local address is the same as that already in the cache,
        // the cache entry's state remains unchanged. Otherwise update the
        // reachability state to STALE.
        //
        if ((NeighborCache->State == EfiNeighborInComplete) || (Result != 0)) {
          CopyMem (&NeighborCache->LinkAddress, &LinkLayerAddress, 6);

          NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME;

          if (NeighborCache->State == EfiNeighborInComplete) {
            //
            // Send queued packets if exist.
            //
            NeighborCache->State = EfiNeighborStale;
            NeighborCache->CallBack ((VOID *) NeighborCache);
          } else {
            NeighborCache->State = EfiNeighborStale;
          }
        }
      }

      Offset = (UINT16) (Offset + (UINT16) LinkLayerOption.Length * 8);
      break;
    case Ip6OptionPrefixInfo:
      NetbufCopy (Packet, Offset, sizeof (IP6_PREFIX_INFO_OPTION), (UINT8 *) &PrefixOption);
      if (PrefixOption.Length != 4) {
        goto Exit;
      }
      PrefixOption.ValidLifetime     = NTOHL (PrefixOption.ValidLifetime);
      PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime);

      //
      // Get L and A flag, recorded in the lower 2 bits of Reserved1
      //
      OnLink = FALSE;
      if ((PrefixOption.Reserved1 & IP6_ON_LINK_FLAG) == IP6_ON_LINK_FLAG) {
        OnLink = TRUE;
      }
      Autonomous = FALSE;
      if ((PrefixOption.Reserved1 & IP6_AUTO_CONFIG_FLAG) == IP6_AUTO_CONFIG_FLAG) {
        Autonomous = TRUE;
      }

      //
      // If the prefix is the link-local prefix, silently ignore the prefix option.
      //
      if (PrefixOption.PrefixLength == IP6_LINK_LOCAL_PREFIX_LENGTH &&
          NetIp6IsLinkLocalAddr (&PrefixOption.Prefix)
          ) {
        Offset += sizeof (IP6_PREFIX_INFO_OPTION);
        break;
      }
      //
      // Do following if on-link flag is set according to RFC4861.
      //
      if (OnLink) {
        PrefixList = Ip6FindPrefixListEntry (
                       IpSb,
                       TRUE,
                       PrefixOption.PrefixLength,
                       &PrefixOption.Prefix
                       );
        //
        // Create a new entry for the prefix, if the ValidLifetime is zero,
        // silently ignore the prefix option.
        //
        if (PrefixList == NULL && PrefixOption.ValidLifetime != 0) {
          PrefixList = Ip6CreatePrefixListEntry (
                         IpSb,
                         TRUE,
                         PrefixOption.ValidLifetime,
                         PrefixOption.PreferredLifetime,
                         PrefixOption.PrefixLength,
                         &PrefixOption.Prefix
                         );
          if (PrefixList == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto Exit;
          }
        } else if (PrefixList != NULL) {
          if (PrefixOption.ValidLifetime != 0) {
            PrefixList->ValidLifetime = PrefixOption.ValidLifetime;
          } else {
            //
            // If the prefix exists and incoming ValidLifetime is zero, immediately
            // remove the prefix.
            Ip6DestroyPrefixListEntry (IpSb, PrefixList, OnLink, TRUE);
          }
        }
      }

      //
      // Do following if Autonomous flag is set according to RFC4862.
      //
      if (Autonomous && PrefixOption.PreferredLifetime <= PrefixOption.ValidLifetime) {
        PrefixList = Ip6FindPrefixListEntry (
                       IpSb,
                       FALSE,
                       PrefixOption.PrefixLength,
                       &PrefixOption.Prefix
                       );
        //
        // Create a new entry for the prefix, and form an address by prefix + interface id
        // If the sum of the prefix length and interface identifier length
        // does not equal 128 bits, the Prefix Information option MUST be ignored.
        //
        if (PrefixList == NULL &&
            PrefixOption.ValidLifetime != 0 &&
            PrefixOption.PrefixLength + IpSb->InterfaceIdLen * 8 == 128
            ) {
          //
          // Form the address in network order.
          //
          CopyMem (&StatelessAddress, &PrefixOption.Prefix, sizeof (UINT64));
          CopyMem (&StatelessAddress.Addr[8], IpSb->InterfaceId, sizeof (UINT64));

          //
          // If the address is not yet in the assigned address list, adds it into.
          //
          if (!Ip6IsOneOfSetAddress (IpSb, &StatelessAddress, NULL, NULL)) {
            //
            // And also not in the DAD process, check its uniqeness firstly.
            //
            if (Ip6FindDADEntry (IpSb, &StatelessAddress, NULL) == NULL) {
              Status = Ip6SetAddress (
                         IpSb->DefaultInterface,
                         &StatelessAddress,
                         FALSE,
                         PrefixOption.PrefixLength,
                         PrefixOption.ValidLifetime,
                         PrefixOption.PreferredLifetime,
                         NULL,
                         NULL
                         );
              if (EFI_ERROR (Status)) {
                goto Exit;
              }
            }
          }

          //
          // Adds the prefix option to stateless prefix option list.
          //
          PrefixList = Ip6CreatePrefixListEntry (
                         IpSb,
                         FALSE,
                         PrefixOption.ValidLifetime,
                         PrefixOption.PreferredLifetime,
                         PrefixOption.PrefixLength,
                         &PrefixOption.Prefix
                         );
          if (PrefixList == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto Exit;
          }
        } else if (PrefixList != NULL) {

          //
          // Reset the preferred lifetime of the address if the advertised prefix exists.
          // Perform specific action to valid lifetime together.
          //
          PrefixList->PreferredLifetime = PrefixOption.PreferredLifetime;
          if ((PrefixOption.ValidLifetime > 7200) ||
              (PrefixOption.ValidLifetime > PrefixList->ValidLifetime)) {
            //
            // If the received Valid Lifetime is greater than 2 hours or
            // greater than RemainingLifetime, set the valid lifetime of the
            // corresponding address to the advertised Valid Lifetime.
            //
            PrefixList->ValidLifetime = PrefixOption.ValidLifetime;

          } else if (PrefixList->ValidLifetime <= 7200) {
            //
            // If RemainingLifetime is less than or equls to 2 hours, ignore the
            // Prefix Information option with regards to the valid lifetime.
            // TODO: If this option has been authenticated, set the valid lifetime.
            //
          } else {
            //
            // Otherwise, reset the valid lifetime of the corresponding
            // address to 2 hours.
            //
            PrefixList->ValidLifetime = 7200;
          }
        }
      }

      Offset += sizeof (IP6_PREFIX_INFO_OPTION);
      break;
    case Ip6OptionMtu:
      NetbufCopy (Packet, Offset, sizeof (IP6_MTU_OPTION), (UINT8 *) &MTUOption);
      if (MTUOption.Length != 1) {
        goto Exit;
      }

      //
      // Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order
      // to omit implementation of Path MTU Discovery. Thus ignore the MTU option
      // in Router Advertisement.
      //

      Offset += sizeof (IP6_MTU_OPTION);
      break;
    default:
      //
      // Silently ignore unrecognized options
      //
      NetbufCopy (Packet, Offset + sizeof (UINT8), sizeof (UINT8), &Length);
      if (Length <= 0) {
        goto Exit;
      }

      Offset = (UINT16) (Offset + (UINT16) Length * 8);
      break;
    }
  }

  Status = EFI_SUCCESS;

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Process the ICMPv6 redirect message. Find the instance, then update
  its route cache.

  @param[in]  IpSb               The IP6 service binding instance that received
                                 the packet.
  @param[in]  Head               The IP head of the received ICMPv6 packet.
  @param[in]  Packet             The content of the ICMPv6 redirect packet with
                                 the IP head removed.

  @retval EFI_INVALID_PARAMETER  The parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Insuffcient resources to complete the
                                 operation.
  @retval EFI_SUCCESS            Successfully updated the route caches.

**/
EFI_STATUS
Ip6ProcessRedirect (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD *Icmp;
  EFI_IPv6_ADDRESS          *Target;
  EFI_IPv6_ADDRESS          *IcmpDest;
  UINT8                     *Option;
  UINT16                    OptionLen;
  IP6_ROUTE_ENTRY           *RouteEntry;
  IP6_ROUTE_CACHE_ENTRY     *RouteCache;
  IP6_NEIGHBOR_ENTRY        *NeighborCache;
  INT32                     Length;
  UINT8                     OptLen;
  IP6_ETHER_ADDR_OPTION     *LinkLayerOption;
  EFI_MAC_ADDRESS           Mac;
  UINT32                    Index;
  BOOLEAN                   IsRouter;
  EFI_STATUS                Status;
  INTN                      Result;

  Status = EFI_INVALID_PARAMETER;

  Icmp = (IP6_ICMP_INFORMATION_HEAD *) NetbufGetByte (Packet, 0, NULL);
  if (Icmp == NULL) {
    goto Exit;
  }

  //
  // Validate the incoming Redirect message
  //

  //
  // The IP Hop Limit field has a value of 255, i.e. the packet
  // could not possibly have been forwarded by a router.
  // ICMP Code is 0.
  // ICMP length (derived from the IP length) is 40 or more octets.
  //
  if (Head->HopLimit != IP6_HOP_LIMIT || Icmp->Head.Code != 0 ||
      Head->PayloadLength < IP6_REDITECT_LENGTH) {
    goto Exit;
  }

  //
  // The IP source address must be a link-local address
  //
  if (!NetIp6IsLinkLocalAddr (&Head->SourceAddress)) {
    goto Exit;
  }

  //
  // The dest of this ICMP redirect message is not us.
  //
  if (!Ip6IsOneOfSetAddress (IpSb, &Head->DestinationAddress, NULL, NULL)) {
    goto Exit;
  }

  //
  // All included options have a length that is greater than zero.
  //
  OptionLen = (UINT16) (Head->PayloadLength - IP6_REDITECT_LENGTH);
  if (OptionLen != 0) {
    Option    = NetbufGetByte (Packet, IP6_REDITECT_LENGTH, NULL);
    ASSERT (Option != NULL);

    if (!Ip6IsNDOptionValid (Option, OptionLen)) {
      goto Exit;
    }
  }

  Target   = (EFI_IPv6_ADDRESS *) (Icmp + 1);
  IcmpDest = Target + 1;

  //
  // The ICMP Destination Address field in the redirect message does not contain
  // a multicast address.
  //
  if (IP6_IS_MULTICAST (IcmpDest)) {
    goto Exit;
  }

  //
  // The ICMP Target Address is either a link-local address (when redirected to
  // a router) or the same as the ICMP Destination Address (when redirected to
  // the on-link destination).
  //
  IsRouter = (BOOLEAN) !EFI_IP6_EQUAL (Target, IcmpDest);
  if (!NetIp6IsLinkLocalAddr (Target) && IsRouter) {
    goto Exit;
  }

  //
  // Check the options. The only interested option here is the target-link layer
  // address option.
  //
  Length          = Packet->TotalSize - 40;
  Option          = (UINT8 *) (IcmpDest + 1);
  LinkLayerOption = NULL;
  while (Length > 0) {
    switch (*Option) {
    case Ip6OptionEtherTarget:

      LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) Option;
      OptLen          = LinkLayerOption->Length;
      if (OptLen != 1) {
        //
        // For ethernet, the length must be 1.
        //
        goto Exit;
      }
      break;

    default:

      OptLen = *(Option + 1);
      if (OptLen == 0) {
        //
        // A length of 0 is invalid.
        //
        goto Exit;
      }
      break;
    }

    Length -= 8 * OptLen;
    Option += 8 * OptLen;
  }

  if (Length != 0) {
    goto Exit;
  }

  //
  // The IP source address of the Redirect is the same as the current
  // first-hop router for the specified ICMP Destination Address.
  //
  RouteCache = Ip6FindRouteCache (IpSb->RouteTable, IcmpDest, &Head->DestinationAddress);
  if (RouteCache != NULL) {
    if (!EFI_IP6_EQUAL (&RouteCache->NextHop, &Head->SourceAddress)) {
      //
      // The source of this Redirect message must match the NextHop of the
      // corresponding route cache entry.
      //
      goto Exit;
    }

    //
    // Update the NextHop.
    //
    IP6_COPY_ADDRESS (&RouteCache->NextHop, Target);

    if (!IsRouter) {
      RouteEntry = (IP6_ROUTE_ENTRY *) RouteCache->Tag;
      RouteEntry->Flag = RouteEntry->Flag | IP6_DIRECT_ROUTE;
    }

  } else {
    //
    // Get the Route Entry.
    //
    RouteEntry = Ip6FindRouteEntry (IpSb->RouteTable, IcmpDest, NULL);
    if (RouteEntry == NULL) {
      RouteEntry = Ip6CreateRouteEntry (IcmpDest, 0, NULL);
      if (RouteEntry == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }
    }

    if (!IsRouter) {
      RouteEntry->Flag = IP6_DIRECT_ROUTE;
    }

    //
    // Create a route cache for this.
    //
    RouteCache = Ip6CreateRouteCacheEntry (
                   IcmpDest,
                   &Head->DestinationAddress,
                   Target,
                   (UINTN) RouteEntry
                   );
    if (RouteCache == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    //
    // Insert the newly created route cache entry.
    //
    Index = IP6_ROUTE_CACHE_HASH (IcmpDest, &Head->DestinationAddress);
    InsertHeadList (&IpSb->RouteTable->Cache.CacheBucket[Index], &RouteCache->Link);
  }

  //
  // Try to locate the neighbor cache for the Target.
  //
  NeighborCache = Ip6FindNeighborEntry (IpSb, Target);

  if (LinkLayerOption != NULL) {
    if (NeighborCache == NULL) {
      //
      // Create a neighbor cache for the Target.
      //
      ZeroMem (&Mac, sizeof (EFI_MAC_ADDRESS));
      CopyMem (&Mac, LinkLayerOption->EtherAddr, 6);
      NeighborCache = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, Target, &Mac);
      if (NeighborCache == NULL) {
        //
        // Just report a success here. The neighbor cache can be created in
        // some other place.
        //
        Status = EFI_SUCCESS;
        goto Exit;
      }

      NeighborCache->State = EfiNeighborStale;
      NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
    } else {
      Result = CompareMem (LinkLayerOption->EtherAddr, &NeighborCache->LinkAddress, 6);

      //
      // If the link-local address is the same as that already in the cache,
      // the cache entry's state remains unchanged. Otherwise update the
      // reachability state to STALE.
      //
      if ((NeighborCache->State == EfiNeighborInComplete) || (Result != 0)) {
        CopyMem (&NeighborCache->LinkAddress, LinkLayerOption->EtherAddr, 6);

        NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME;

        if (NeighborCache->State == EfiNeighborInComplete) {
          //
          // Send queued packets if exist.
          //
          NeighborCache->State = EfiNeighborStale;
          NeighborCache->CallBack ((VOID *) NeighborCache);
        } else {
          NeighborCache->State = EfiNeighborStale;
        }
      }
    }
  }

  if (NeighborCache != NULL && IsRouter) {
    //
    // The Target is a router, set IsRouter to TRUE.
    //
    NeighborCache->IsRouter = TRUE;
  }

  Status = EFI_SUCCESS;

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Add Neighbor cache entries. It is a work function for EfiIp6Neighbors().

  @param[in]  IpSb               The IP6 service binding instance.
  @param[in]  TargetIp6Address   Pointer to Target IPv6 address.
  @param[in]  TargetLinkAddress  Pointer to link-layer address of the target. Ignored if NULL.
  @param[in]  Timeout            Time in 100-ns units that this entry will remain in the neighbor
                                 cache. It will be deleted after Timeout. A value of zero means that
                                 the entry is permanent. A non-zero value means that the entry is
                                 dynamic.
  @param[in]  Override           If TRUE, the cached link-layer address of the matching entry will
                                 be overridden and updated; if FALSE, and if a
                                 corresponding cache entry already existed, EFI_ACCESS_DENIED
                                 will be returned.

  @retval  EFI_SUCCESS           The neighbor cache entry has been added.
  @retval  EFI_OUT_OF_RESOURCES  Could not add the entry to the neighbor cache
                                 due to insufficient resources.
  @retval  EFI_NOT_FOUND         TargetLinkAddress is NULL.
  @retval  EFI_ACCESS_DENIED     The to-be-added entry is already defined in the neighbor cache,
                                 and that entry is tagged as un-overridden (when DeleteFlag
                                 is FALSE).

**/
EFI_STATUS
Ip6AddNeighbor (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *TargetIp6Address,
  IN EFI_MAC_ADDRESS        *TargetLinkAddress OPTIONAL,
  IN UINT32                 Timeout,
  IN BOOLEAN                Override
  )
{
  IP6_NEIGHBOR_ENTRY        *Neighbor;

  Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address);
  if (Neighbor != NULL) {
    if (!Override) {
      return EFI_ACCESS_DENIED;
    } else {
      if (TargetLinkAddress != NULL) {
        IP6_COPY_LINK_ADDRESS (&Neighbor->LinkAddress, TargetLinkAddress);
      }
    }
  } else {
    if (TargetLinkAddress == NULL) {
      return EFI_NOT_FOUND;
    }

    Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, TargetIp6Address, TargetLinkAddress);
    if (Neighbor == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  Neighbor->State = EfiNeighborReachable;

  if (Timeout != 0) {
    Neighbor->Ticks   = IP6_GET_TICKS (Timeout / TICKS_PER_MS);
    Neighbor->Dynamic = TRUE;
  } else {
    Neighbor->Ticks   = (UINT32) IP6_INFINIT_LIFETIME;
  }

  return EFI_SUCCESS;
}

/**
  Delete or update Neighbor cache entries. It is a work function for EfiIp6Neighbors().

  @param[in]  IpSb               The IP6 service binding instance.
  @param[in]  TargetIp6Address   Pointer to Target IPv6 address.
  @param[in]  TargetLinkAddress  Pointer to link-layer address of the target. Ignored if NULL.
  @param[in]  Timeout            Time in 100-ns units that this entry will remain in the neighbor
                                 cache. It will be deleted after Timeout. A value of zero means that
                                 the entry is permanent. A non-zero value means that the entry is
                                 dynamic.
  @param[in]  Override           If TRUE, the cached link-layer address of the matching entry will
                                 be overridden and updated; if FALSE, and if a
                                 corresponding cache entry already existed, EFI_ACCESS_DENIED
                                 will be returned.

  @retval  EFI_SUCCESS           The neighbor cache entry has been updated or deleted.
  @retval  EFI_NOT_FOUND         This entry is not in the neighbor cache.

**/
EFI_STATUS
Ip6DelNeighbor (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *TargetIp6Address,
  IN EFI_MAC_ADDRESS        *TargetLinkAddress OPTIONAL,
  IN UINT32                 Timeout,
  IN BOOLEAN                Override
  )
{
  IP6_NEIGHBOR_ENTRY        *Neighbor;

  Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address);
  if (Neighbor == NULL) {
    return EFI_NOT_FOUND;
  }

  RemoveEntryList (&Neighbor->Link);
  FreePool (Neighbor);

  return EFI_SUCCESS;
}

/**
  The heartbeat timer of ND module in IP6_TIMER_INTERVAL_IN_MS milliseconds.
  This time routine handles DAD module and neighbor state transition.
  It is also responsible for sending out router solicitations.

  @param[in]  Event                 The IP6 service instance's heartbeat timer.
  @param[in]  Context               The IP6 service instance.

**/
VOID
EFIAPI
Ip6NdFasterTimerTicking (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  LIST_ENTRY                *Entry2;
  IP6_INTERFACE             *IpIf;
  IP6_DELAY_JOIN_LIST       *DelayNode;
  EFI_IPv6_ADDRESS          Source;
  IP6_DAD_ENTRY             *DupAddrDetect;
  EFI_STATUS                Status;
  IP6_NEIGHBOR_ENTRY        *NeighborCache;
  EFI_IPv6_ADDRESS          Destination;
  IP6_SERVICE               *IpSb;
  BOOLEAN                   Flag;

  IpSb = (IP6_SERVICE *) Context;
  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  ZeroMem (&Source, sizeof (EFI_IPv6_ADDRESS));

  //
  // A host SHOULD transmit up to MAX_RTR_SOLICITATIONS (3) Router
  // Solicitation messages, each separated by at least
  // RTR_SOLICITATION_INTERVAL (4) seconds.
  //
  if ((IpSb->Ip6ConfigInstance.Policy == Ip6ConfigPolicyAutomatic) &&
      !IpSb->RouterAdvertiseReceived &&
      IpSb->SolicitTimer > 0
      ) {
    if ((IpSb->Ticks == 0) || (--IpSb->Ticks == 0)) {
      Status = Ip6SendRouterSolicit (IpSb, NULL, NULL, NULL, NULL);
      if (!EFI_ERROR (Status)) {
        IpSb->SolicitTimer--;
        IpSb->Ticks = (UINT32) IP6_GET_TICKS (IP6_RTR_SOLICITATION_INTERVAL);
      }
    }
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);

    //
    // Process the delay list to join the solicited-node multicast address.
    //
    NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) {
      DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link);
      if ((DelayNode->DelayTime == 0) || (--DelayNode->DelayTime == 0)) {
        //
        // The timer expires, init the duplicate address detection.
        //
        Ip6InitDADProcess (
          DelayNode->Interface,
          DelayNode->AddressInfo,
          DelayNode->DadCallback,
          DelayNode->Context
          );

        //
        // Remove the delay node
        //
        RemoveEntryList (&DelayNode->Link);
        FreePool (DelayNode);
      }
    }

    //
    // Process the duplicate address detection list.
    //
    NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) {
      DupAddrDetect = NET_LIST_USER_STRUCT (Entry2, IP6_DAD_ENTRY, Link);

      if ((DupAddrDetect->RetransTick == 0) || (--DupAddrDetect->RetransTick == 0)) {
        //
        // The timer expires, check the remaining transmit counts.
        //
        if (DupAddrDetect->Transmit < DupAddrDetect->MaxTransmit) {
          //
          // Send the Neighbor Solicitation message with
          // Source - unspecified address, destination - solicited-node multicast address
          // Target - the address to be validated
          //
          Status = Ip6SendNeighborSolicit (
                     IpSb,
                     NULL,
                     &DupAddrDetect->Destination,
                     &DupAddrDetect->AddressInfo->Address,
                     NULL
                     );
          if (EFI_ERROR (Status)) {
            return;
          }

          DupAddrDetect->Transmit++;
          DupAddrDetect->RetransTick = IP6_GET_TICKS (IpSb->RetransTimer);
        } else {
          //
          // All required solicitation has been sent out, and the RetransTime after the last
          // Neighbor Solicit is elapsed, finish the DAD process.
          //
          Flag = FALSE;
          if ((DupAddrDetect->Receive == 0) ||
              (DupAddrDetect->Transmit <= DupAddrDetect->Receive)) {
            Flag = TRUE;
          }

          Ip6OnDADFinished (Flag, IpIf, DupAddrDetect);
        }
      }
    }
  }

  //
  // Polling the state of Neighbor cache
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->NeighborTable) {
    NeighborCache = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link);

    switch (NeighborCache->State) {
    case EfiNeighborInComplete:
      if (NeighborCache->Ticks > 0) {
        --NeighborCache->Ticks;
      }

      //
      // Retransmit Neighbor Solicitation messages approximately every
      // RetransTimer milliseconds while awaiting a response.
      //
      if (NeighborCache->Ticks == 0) {
        if (NeighborCache->Transmit > 1) {
          //
          // Send out multicast neighbor solicitation for address resolution.
          // After last neighbor solicitation message has been sent out, wait
          // for RetransTimer and then remove entry if no response is received.
          //
          Ip6CreateSNMulticastAddr (&NeighborCache->Neighbor, &Destination);
          Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source);
          if (EFI_ERROR (Status)) {
            return;
          }

          Status = Ip6SendNeighborSolicit (
                     IpSb,
                     &Source,
                     &Destination,
                     &NeighborCache->Neighbor,
                     &IpSb->SnpMode.CurrentAddress
                     );
          if (EFI_ERROR (Status)) {
            return;
          }
        }

        //
        // Update the retransmit times.
        //
        if (NeighborCache->Transmit > 0) {
          --NeighborCache->Transmit;
          NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer);
        }
      }

      if (NeighborCache->Transmit == 0) {
        //
        // Timeout, send ICMP destination unreachable packet and then remove entry
        //
        Status = Ip6FreeNeighborEntry (
                   IpSb,
                   NeighborCache,
                   TRUE,
                   TRUE,
                   EFI_ICMP_ERROR,
                   NULL,
                   NULL
                   );
        if (EFI_ERROR (Status)) {
          return;
        }
      }

      break;

    case EfiNeighborReachable:
      //
      // This entry is inserted by EfiIp6Neighbors() as static entry
      // and will not timeout.
      //
      if (!NeighborCache->Dynamic && (NeighborCache->Ticks == IP6_INFINIT_LIFETIME)) {
        break;
      }

      if ((NeighborCache->Ticks == 0) || (--NeighborCache->Ticks == 0)) {
        if (NeighborCache->Dynamic) {
          //
          // This entry is inserted by EfiIp6Neighbors() as dynamic entry
          // and will be deleted after timeout.
          //
          Status = Ip6FreeNeighborEntry (
                     IpSb,
                     NeighborCache,
                     FALSE,
                     TRUE,
                     EFI_TIMEOUT,
                     NULL,
                     NULL
                     );
          if (EFI_ERROR (Status)) {
            return;
          }
        } else {
          NeighborCache->State = EfiNeighborStale;
          NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME;
        }
      }

      break;

    case EfiNeighborDelay:
      if ((NeighborCache->Ticks == 0) || (--NeighborCache->Ticks == 0)) {

        NeighborCache->State    = EfiNeighborProbe;
        NeighborCache->Ticks    = IP6_GET_TICKS (IpSb->RetransTimer);
        NeighborCache->Transmit = IP6_MAX_UNICAST_SOLICIT + 1;
        //
        // Send out unicast neighbor solicitation for Neighbor Unreachability Detection
        //
        Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source);
        if (EFI_ERROR (Status)) {
          return;
        }

        Status = Ip6SendNeighborSolicit (
                   IpSb,
                   &Source,
                   &NeighborCache->Neighbor,
                   &NeighborCache->Neighbor,
                   &IpSb->SnpMode.CurrentAddress
                   );
        if (EFI_ERROR (Status)) {
          return;
        }

        NeighborCache->Transmit--;
      }

      break;

    case EfiNeighborProbe:
      if (NeighborCache->Ticks > 0) {
        --NeighborCache->Ticks;
      }

      //
      // Retransmit Neighbor Solicitation messages approximately every
      // RetransTimer milliseconds while awaiting a response.
      //
      if (NeighborCache->Ticks == 0) {
        if (NeighborCache->Transmit > 1) {
          //
          // Send out unicast neighbor solicitation for Neighbor Unreachability
          // Detection. After last neighbor solicitation message has been sent out,
          // wait for RetransTimer and then remove entry if no response is received.
          //
          Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source);
          if (EFI_ERROR (Status)) {
            return;
          }

          Status = Ip6SendNeighborSolicit (
                     IpSb,
                     &Source,
                     &NeighborCache->Neighbor,
                     &NeighborCache->Neighbor,
                     &IpSb->SnpMode.CurrentAddress
                     );
          if (EFI_ERROR (Status)) {
            return;
          }
        }

        //
        // Update the retransmit times.
        //
        if (NeighborCache->Transmit > 0) {
          --NeighborCache->Transmit;
          NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer);
        }
      }

      if (NeighborCache->Transmit == 0) {
        //
        // Delete the neighbor entry.
        //
        Status = Ip6FreeNeighborEntry (
                   IpSb,
                   NeighborCache,
                   FALSE,
                   TRUE,
                   EFI_TIMEOUT,
                   NULL,
                   NULL
                   );
        if (EFI_ERROR (Status)) {
          return;
        }
      }

      break;

    default:
      break;
    }
  }
}

/**
  The heartbeat timer of ND module in 1 second. This time routine handles following
  things: 1) maitain default router list; 2) maintain prefix options;
  3) maintain route caches.

  @param[in]  IpSb              The IP6 service binding instance.

**/
VOID
Ip6NdTimerTicking (
  IN IP6_SERVICE            *IpSb
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Next;
  IP6_DEFAULT_ROUTER        *DefaultRouter;
  IP6_PREFIX_LIST_ENTRY     *PrefixOption;
  UINT8                     Index;
  IP6_ROUTE_CACHE_ENTRY     *RouteCache;

  //
  // Decrease the lifetime of default router, if expires remove it from default router list.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->DefaultRouterList) {
    DefaultRouter = NET_LIST_USER_STRUCT (Entry, IP6_DEFAULT_ROUTER, Link);
    if (DefaultRouter->Lifetime != IP6_INF_ROUTER_LIFETIME) {
      if ((DefaultRouter->Lifetime == 0) || (--DefaultRouter->Lifetime == 0)) {
        Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
      }
    }
  }

  //
  // Decrease Valid lifetime and Preferred lifetime of Prefix options and corresponding addresses.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->AutonomousPrefix) {
    PrefixOption = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);
    if (PrefixOption->ValidLifetime != (UINT32) IP6_INFINIT_LIFETIME) {
      if ((PrefixOption->ValidLifetime > 0) && (--PrefixOption->ValidLifetime > 0)) {
        if ((PrefixOption->PreferredLifetime != (UINT32) IP6_INFINIT_LIFETIME) &&
            (PrefixOption->PreferredLifetime > 0)
            ) {
          --PrefixOption->PreferredLifetime;
        }
      } else {
        Ip6DestroyPrefixListEntry (IpSb, PrefixOption, FALSE, TRUE);
      }
    }
  }

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->OnlinkPrefix) {
    PrefixOption = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link);
    if (PrefixOption->ValidLifetime != (UINT32) IP6_INFINIT_LIFETIME) {
      if ((PrefixOption->ValidLifetime == 0) || (--PrefixOption->ValidLifetime == 0)) {
        Ip6DestroyPrefixListEntry (IpSb, PrefixOption, TRUE, TRUE);
      }
    }
  }

  //
  // Each bucket of route cache can contain at most IP6_ROUTE_CACHE_MAX entries.
  // Remove the entries at the tail of the bucket. These entries
  // are likely to be used least.
  // Reclaim frequency is set to 1 second.
  //
  for (Index = 0; Index < IP6_ROUTE_CACHE_HASH_SIZE; Index++) {
    while (IpSb->RouteTable->Cache.CacheNum[Index] > IP6_ROUTE_CACHE_MAX) {
      Entry = NetListRemoveTail (&IpSb->RouteTable->Cache.CacheBucket[Index]);
      if (Entry == NULL) {
        break;
      }

      RouteCache = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_CACHE_ENTRY, Link);
      Ip6FreeRouteCacheEntry (RouteCache);
      ASSERT (IpSb->RouteTable->Cache.CacheNum[Index] > 0);
      IpSb->RouteTable->Cache.CacheNum[Index]--;
    }
  }
}

