/** @file
  Implementation of Neighbor Discovery support routines.

  Copyright (c) 2009 - 2012, 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_NUM) {
    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 (IP6_CONFIG_DHCP6_OPTION_ORO);
        Oro->OpLen  = HTONS (2);
        *((UINT16 *) &Oro->Data[0]) = HTONS (IP6_CONFIG_DHCP6_OPTION_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]--;
    }
  }
}

