/** @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);

  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) {
      if (DupAddrDetect->Transmit == 0) {
        //
        // The NS is from another node to performing DAD on the same address since
        // we haven't send out any NS yet. Fail DAD for the tentative address.
        //
        Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect);
        Status = EFI_ICMP_ERROR;
        goto Exit;
      }

      //
      // 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]--;
    }
  }
}

