/** @file
  Implementation of EFI_IP6_PROTOCOL protocol interfaces.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2014, 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_IPSEC2_PROTOCOL    *mIpSec = NULL;

EFI_IP6_PROTOCOL mEfiIp6ProtocolTemplete = {
  EfiIp6GetModeData,
  EfiIp6Configure,
  EfiIp6Groups,
  EfiIp6Routes,
  EfiIp6Neighbors,
  EfiIp6Transmit,
  EfiIp6Receive,
  EfiIp6Cancel,
  EfiIp6Poll
};

/**
  Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.

  The GetModeData() function returns the current operational mode data for this driver instance.
  The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to
  retrieve the operational mode data of underlying networks or drivers.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[out] Ip6ModeData        Pointer to the EFI IPv6 Protocol mode data structure.
  @param[out] MnpConfigData      Pointer to the managed network configuration data structure.
  @param[out] SnpModeData        Pointer to the simple network mode data structure.

  @retval EFI_SUCCESS            The operation completed successfully.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_OUT_OF_RESOURCES   The required mode data could not be allocated.

**/
EFI_STATUS
EFIAPI
EfiIp6GetModeData (
  IN EFI_IP6_PROTOCOL                 *This,
  OUT EFI_IP6_MODE_DATA               *Ip6ModeData     OPTIONAL,
  OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData   OPTIONAL,
  OUT EFI_SIMPLE_NETWORK_MODE         *SnpModeData     OPTIONAL
  )
{
  IP6_PROTOCOL              *IpInstance;
  IP6_SERVICE               *IpSb;
  IP6_INTERFACE             *IpIf;
  EFI_IP6_CONFIG_DATA       *Config;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl     = gBS->RaiseTPL (TPL_CALLBACK);
  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;
  IpIf       = IpInstance->Interface;

  if (IpSb->LinkLocalDadFail) {
    return EFI_INVALID_PARAMETER;
  }

  if (Ip6ModeData != NULL) {
    //
    // IsStarted is "whether the EfiIp6Configure has been called".
    // IsConfigured is "whether the station address has been configured"
    //
    Ip6ModeData->IsStarted     = (BOOLEAN) (IpInstance->State == IP6_STATE_CONFIGED);
    Ip6ModeData->MaxPacketSize = IpSb->MaxPacketSize;
    CopyMem (&Ip6ModeData->ConfigData, &IpInstance->ConfigData, sizeof (EFI_IP6_CONFIG_DATA));
    Ip6ModeData->IsConfigured  = FALSE;

    Ip6ModeData->AddressCount  = 0;
    Ip6ModeData->AddressList   = NULL;

    Ip6ModeData->GroupCount    = IpInstance->GroupCount;
    Ip6ModeData->GroupTable    = NULL;

    Ip6ModeData->RouteCount    = 0;
    Ip6ModeData->RouteTable    = NULL;

    Ip6ModeData->NeighborCount = 0;
    Ip6ModeData->NeighborCache = NULL;

    Ip6ModeData->PrefixCount   = 0;
    Ip6ModeData->PrefixTable   = NULL;

    Ip6ModeData->IcmpTypeCount = 23;
    Ip6ModeData->IcmpTypeList  = AllocateCopyPool (
                                   Ip6ModeData->IcmpTypeCount * sizeof (EFI_IP6_ICMP_TYPE),
                                   mIp6SupportedIcmp
                                   );
    if (Ip6ModeData->IcmpTypeList == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    //
    // Return the currently configured IPv6 addresses and corresponding prefix lengths.
    //
    Status = Ip6BuildEfiAddressList (
               IpSb,
               &Ip6ModeData->AddressCount,
               &Ip6ModeData->AddressList
               );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    //
    // Return the current station address for this IP child.
    // If UseAnyStationAddress is set to TRUE, IP6 driver will
    // select a source address from its address list. Otherwise use the
    // StationAddress in config data.
    //
    if (Ip6ModeData->IsStarted) {
      Config = &Ip6ModeData->ConfigData;

      if (IpIf->Configured || NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
        Ip6ModeData->IsConfigured = TRUE;
      } else {
        Ip6ModeData->IsConfigured = FALSE;
      }

      //
      // Build a EFI route table for user from the internal route table.
      //
      Status = Ip6BuildEfiRouteTable (
                 IpSb->RouteTable,
                 &Ip6ModeData->RouteCount,
                 &Ip6ModeData->RouteTable
                 );

      if (EFI_ERROR (Status)) {
        goto Error;
      }
    }

    if (Ip6ModeData->IsConfigured) {
      //
      // Return the joined multicast group addresses.
      //
      if (IpInstance->GroupCount != 0) {
        Ip6ModeData->GroupTable = AllocateCopyPool (
                                    IpInstance->GroupCount * sizeof (EFI_IPv6_ADDRESS),
                                    IpInstance->GroupList
                                    );
        if (Ip6ModeData->GroupTable == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Error;
        }
      }
      //
      // Return the neighbor cache entries
      //
      Status = Ip6BuildEfiNeighborCache (
                 IpInstance,
                 &Ip6ModeData->NeighborCount,
                 &Ip6ModeData->NeighborCache
                 );
      if (EFI_ERROR (Status)) {
        goto Error;
      }

      //
      // Return the prefix table entries
      //
      Status = Ip6BuildPrefixTable (
                 IpInstance,
                 &Ip6ModeData->PrefixCount,
                 &Ip6ModeData->PrefixTable
                 );
      if (EFI_ERROR (Status)) {
        goto Error;
      }

    }
  }

  //
  // Get fresh mode data from MNP, since underlying media status may change
  //
  Status = IpSb->Mnp->GetModeData (IpSb->Mnp, MnpConfigData, SnpModeData);

  goto Exit;

Error:
  if (Ip6ModeData != NULL) {
    if (Ip6ModeData->AddressList != NULL) {
      FreePool (Ip6ModeData->AddressList);
    }

    if (Ip6ModeData->GroupTable != NULL) {
      FreePool (Ip6ModeData->GroupTable);
    }

    if (Ip6ModeData->RouteTable != NULL) {
      FreePool (Ip6ModeData->RouteTable);
    }

    if (Ip6ModeData->NeighborCache != NULL) {
      FreePool (Ip6ModeData->NeighborCache);
    }

    if (Ip6ModeData->PrefixTable != NULL) {
      FreePool (Ip6ModeData->PrefixTable);
    }

    if (Ip6ModeData->IcmpTypeList != NULL) {
      FreePool (Ip6ModeData->IcmpTypeList);
    }
  }

Exit:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Validate that Ipv6 address is OK to be used as station address or next hop address/ neighbor.

  @param[in]  IpSb               The IP6 service instance.
  @param[in]  Ip                 The IPv6 address to validate.
  @param[in]  Flag               If TRUE, validate if the address is OK to be used
                                 as station address. If FALSE, validate if the
                                 address is OK to be used as the next hop address/
                                 neighbor.

  @retval TRUE                   The Ip address is valid and could be used.
  @retval FALSE                  Invalid Ip address.

**/
BOOLEAN
Ip6IsValidAddress (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *Ip,
  IN BOOLEAN                Flag
  )
{
  if (!NetIp6IsUnspecifiedAddr (Ip)) {
    if (!NetIp6IsValidUnicast(Ip)) {
      return FALSE;
    }
    if (Ip6IsOneOfSetAddress (IpSb, Ip, NULL, NULL)) {
      return Flag;
    }
  } else {
    return Flag;
  }

  return (BOOLEAN) !Flag;
}

/**
  Validate whether the value of protocol is illegal or not. Protocol is the 'Next Header' field
  in the last IPv6 extension header, or basic IPv6 header is there's no extension header.

  @param[in]  Protocol           Default value of 'Next Header'

  @retval TRUE                   The protocol is illegal.
  @retval FALSE                  The protocol is legal.

**/
BOOLEAN
Ip6IsIllegalProtocol (
  IN UINT8                  Protocol
  )
{
  if (Protocol == IP6_HOP_BY_HOP || Protocol == EFI_IP_PROTO_ICMP || Protocol == IP4_PROTO_IGMP) {
    return TRUE;
  }

  if (Protocol == 41 || Protocol == 43 || Protocol == 44 || Protocol == 59 || Protocol == 60 || Protocol == 124) {
    return TRUE;
  }

  return FALSE;
}

/**
  Intiialize the IP6_PROTOCOL structure to the unconfigured states.

  @param[in]       IpSb                   The IP6 service instance.
  @param[in, out]  IpInstance             The IP6 child instance.

**/
VOID
Ip6InitProtocol (
  IN IP6_SERVICE            *IpSb,
  IN OUT IP6_PROTOCOL       *IpInstance
  )
{
  ASSERT ((IpSb != NULL) && (IpInstance != NULL));

  ZeroMem (IpInstance, sizeof (IP6_PROTOCOL));

  IpInstance->Signature = IP6_PROTOCOL_SIGNATURE;
  IpInstance->State     = IP6_STATE_UNCONFIGED;
  IpInstance->Service   = IpSb;
  IpInstance->GroupList = NULL;
  CopyMem (&IpInstance->Ip6Proto, &mEfiIp6ProtocolTemplete, sizeof (EFI_IP6_PROTOCOL));

  NetMapInit  (&IpInstance->RxTokens);
  NetMapInit  (&IpInstance->TxTokens);
  InitializeListHead (&IpInstance->Received);
  InitializeListHead (&IpInstance->Delivered);

  EfiInitializeLock (&IpInstance->RecycleLock, TPL_NOTIFY);
}

/**
  Configure the IP6 child. If the child is already configured,
  change the configuration parameter. Otherwise, configure it
  for the first time. The caller should validate the configuration
  before deliver them to it. It also don't do configure NULL.

  @param[in, out]  IpInstance         The IP6 child to configure.
  @param[in]       Config             The configure data.

  @retval EFI_SUCCESS            The IP6 child is successfully configured.
  @retval EFI_DEVICE_ERROR       Failed to free the pending transive or to
                                 configure  underlying MNP, or other errors.
  @retval EFI_NO_MAPPING         The IP6 child is configured to use the default
                                 address, but the default address hasn't been
                                 configured. The IP6 child doesn't need to be
                                 reconfigured when the default address is configured.
  @retval EFI_OUT_OF_RESOURCES   No more memory space is available.
  @retval other                  Other error occurs.

**/
EFI_STATUS
Ip6ConfigProtocol (
  IN OUT IP6_PROTOCOL        *IpInstance,
  IN     EFI_IP6_CONFIG_DATA *Config
  )
{
  IP6_SERVICE               *IpSb;
  IP6_INTERFACE             *IpIf;
  EFI_STATUS                Status;
  EFI_IP6_CONFIG_DATA       *Current;
  IP6_ADDRESS_INFO          *AddressInfo;
  BOOLEAN                   StationZero;
  BOOLEAN                   DestZero;
  EFI_IPv6_ADDRESS          Source;
  BOOLEAN                   AddrOk;

  IpSb    = IpInstance->Service;
  Current = &IpInstance->ConfigData;

  //
  // User is changing packet filters. It must be stopped
  // before the station address can be changed.
  //
  if (IpInstance->State == IP6_STATE_CONFIGED) {
    //
    // Cancel all the pending transmit/receive from upper layer
    //
    Status = Ip6Cancel (IpInstance, NULL);

    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
    return EFI_SUCCESS;
  }

  //
  // Set up the interface.
  //
  StationZero = NetIp6IsUnspecifiedAddr (&Config->StationAddress);
  DestZero    = NetIp6IsUnspecifiedAddr (&Config->DestinationAddress);

  if (StationZero && DestZero) {
    //
    // StationAddress is still zero.
    //

    NET_GET_REF (IpSb->DefaultInterface);
    IpInstance->Interface = IpSb->DefaultInterface;
    InsertTailList (&IpSb->DefaultInterface->IpInstances, &IpInstance->AddrLink);

    CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
    IpInstance->State = IP6_STATE_CONFIGED;

    return EFI_SUCCESS;
  }

  if (StationZero && !DestZero) {
    Status = Ip6SelectSourceAddress (IpSb, &Config->DestinationAddress, &Source);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    IP6_COPY_ADDRESS (&Source, &Config->StationAddress);
  }

  AddrOk = Ip6IsOneOfSetAddress (IpSb, &Source, &IpIf, &AddressInfo);
  if (AddrOk) {
    if (AddressInfo != NULL) {
      IpInstance->PrefixLength = AddressInfo->PrefixLength;
    } else {
      IpInstance->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
    }
  } else {
    //
    // The specified source address is not one of the addresses IPv6 maintains.
    //
    return EFI_INVALID_PARAMETER;
  }


  NET_GET_REF (IpIf);
  IpInstance->Interface = IpIf;
  InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);

  CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
  IP6_COPY_ADDRESS (&Current->StationAddress, &Source);
  IpInstance->State = IP6_STATE_CONFIGED;

  return EFI_SUCCESS;
}

/**
  Clean up the IP6 child, and release all the resources used by it.

  @param[in, out]  IpInstance    The IP6 child to clean up.

  @retval EFI_SUCCESS            The IP6 child is cleaned up.
  @retval EFI_DEVICE_ERROR       Some resources failed to be released.

**/
EFI_STATUS
Ip6CleanProtocol (
  IN OUT IP6_PROTOCOL            *IpInstance
  )
{
  if (EFI_ERROR (Ip6Cancel (IpInstance, NULL))) {
    return EFI_DEVICE_ERROR;
  }

  if (EFI_ERROR (Ip6Groups (IpInstance, FALSE, NULL))) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Some packets haven't been recycled. It is because either the
  // user forgets to recycle the packets, or because the callback
  // hasn't been called. Just leave it alone.
  //
  if (!IsListEmpty (&IpInstance->Delivered)) {
    ;
  }

  if (IpInstance->Interface != NULL) {
    RemoveEntryList (&IpInstance->AddrLink);
    Ip6CleanInterface (IpInstance->Interface, IpInstance);
    IpInstance->Interface = NULL;
  }

  if (IpInstance->GroupList != NULL) {
    FreePool (IpInstance->GroupList);
    IpInstance->GroupList   = NULL;
    IpInstance->GroupCount  = 0;
  }

  NetMapClean (&IpInstance->TxTokens);

  NetMapClean (&IpInstance->RxTokens);

  return EFI_SUCCESS;
}

/**
  Configure the MNP parameter used by IP. The IP driver uses one MNP
  child to transmit/receive frames. By default, it configures MNP
  to receive unicast/multicast/broadcast. Also, it will enable/disable
  the promiscuous receive according to whether there is IP child
  enable that or not. If Force is FALSE, it will iterate through
  all the IP children to check whether the promiscuous receive
  setting has been changed. If it hasn't been changed, it won't
  reconfigure the MNP. If Force is TRUE, the MNP is configured
  whether that is changed or not.

  @param[in]  IpSb               The IP6 service instance that is to be changed.
  @param[in]  Force              Force the configuration or not.

  @retval EFI_SUCCESS            The MNP successfully configured/reconfigured.
  @retval Others                 Configuration failed.

**/
EFI_STATUS
Ip6ServiceConfigMnp (
  IN IP6_SERVICE            *IpSb,
  IN BOOLEAN                Force
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *ProtoEntry;
  IP6_INTERFACE             *IpIf;
  IP6_PROTOCOL              *IpInstance;
  BOOLEAN                   Reconfig;
  BOOLEAN                   PromiscReceive;
  EFI_STATUS                Status;

  Reconfig       = FALSE;
  PromiscReceive = FALSE;

  if (!Force) {
    //
    // Iterate through the IP children to check whether promiscuous
    // receive setting has been changed. Update the interface's receive
    // filter also.
    //
    NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {

      IpIf              = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);
      IpIf->PromiscRecv = FALSE;

      NET_LIST_FOR_EACH (ProtoEntry, &IpIf->IpInstances) {
        IpInstance = NET_LIST_USER_STRUCT (ProtoEntry, IP6_PROTOCOL, AddrLink);

        if (IpInstance->ConfigData.AcceptPromiscuous) {
          IpIf->PromiscRecv = TRUE;
          PromiscReceive    = TRUE;
        }
      }
    }

    //
    // If promiscuous receive isn't changed, it isn't necessary to reconfigure.
    //
    if (PromiscReceive == IpSb->MnpConfigData.EnablePromiscuousReceive) {
      return EFI_SUCCESS;
    }

    Reconfig  = TRUE;
    IpSb->MnpConfigData.EnablePromiscuousReceive = PromiscReceive;
  }

  Status = IpSb->Mnp->Configure (IpSb->Mnp, &IpSb->MnpConfigData);

  //
  // recover the original configuration if failed to set the configure.
  //
  if (EFI_ERROR (Status) && Reconfig) {
    IpSb->MnpConfigData.EnablePromiscuousReceive = (BOOLEAN) !PromiscReceive;
  }

  return Status;
}

/**
  Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance.

  The Configure() function is used to set, change, or reset the operational parameters and filter
  settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic
  can be sent or received by this instance. Once the parameters have been reset (by calling this
  function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these
  parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped
  independently of each other by enabling or disabling their receive filter settings with the
  Configure() function.

  If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required
  to be one of the currently configured IPv6 addresses listed in the EFI IPv6 drivers, or else
  EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is
  unspecified, the IPv6 driver will bind a source address according to the source address selection
  algorithm. Clients could frequently call GetModeData() to check get currently configured IPv6
  address list in the EFI IPv6 driver. If both Ip6ConfigData.StationAddress and
  Ip6ConfigData.Destination are unspecified, when transmitting the packet afterwards, the
  source address filled in each outgoing IPv6 packet is decided based on the destination of this packet.

  If operational parameters are reset or changed, any pending transmit and receive requests will be
  cancelled. Their completion token status will be set to EFI_ABORTED and their events will be
  signaled.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  Ip6ConfigData      Pointer to the EFI IPv6 Protocol configuration data structure.
                                 If NULL, reset the configuration data.

  @retval EFI_SUCCESS            The driver instance was successfully opened.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 - This is NULL.
                                 - Ip6ConfigData.StationAddress is neither zero nor
                                   a unicast IPv6 address.
                                 - Ip6ConfigData.StationAddress is neither zero nor
                                   one of the configured IP addresses in the EFI IPv6 driver.
                                 - Ip6ConfigData.DefaultProtocol is illegal.
  @retval EFI_OUT_OF_RESOURCES   The EFI IPv6 Protocol driver instance data could not be allocated.
  @retval EFI_NO_MAPPING         The IPv6 driver was responsible for choosing a source address for
                                 this instance, but no source address was available for use.
  @retval EFI_ALREADY_STARTED    The interface is already open and must be stopped before the IPv6
                                 address or prefix length can be changed.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred. The EFI IPv6
                                 Protocol driver instance was not opened.
  @retval EFI_UNSUPPORTED        Default protocol specified through
                                 Ip6ConfigData.DefaulProtocol isn't supported.

**/
EFI_STATUS
EFIAPI
EfiIp6Configure (
  IN EFI_IP6_PROTOCOL          *This,
  IN EFI_IP6_CONFIG_DATA       *Ip6ConfigData OPTIONAL
  )
{
  IP6_PROTOCOL              *IpInstance;
  EFI_IP6_CONFIG_DATA       *Current;
  EFI_TPL                   OldTpl;
  EFI_STATUS                Status;
  IP6_SERVICE               *IpSb;

  //
  // First, validate the parameters
  //
  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl     = gBS->RaiseTPL (TPL_CALLBACK);

  Status     = EFI_INVALID_PARAMETER;

  //
  // Validate the configuration first.
  //
  if (Ip6ConfigData != NULL) {
    //
    // Check whether the station address is valid.
    //
    if (!Ip6IsValidAddress (IpSb, &Ip6ConfigData->StationAddress, TRUE)) {
       goto Exit;
    }
    //
    // Check whether the default protocol is valid.
    //
    if (Ip6IsIllegalProtocol (Ip6ConfigData->DefaultProtocol)) {
      goto Exit;
    }

    //
    // User can only update packet filters when already configured.
    // If it wants to change the station address, it must configure(NULL)
    // the instance firstly.
    //
    if (IpInstance->State == IP6_STATE_CONFIGED) {
      Current = &IpInstance->ConfigData;

      if (!EFI_IP6_EQUAL (&Current->StationAddress, &Ip6ConfigData->StationAddress)) {
        Status = EFI_ALREADY_STARTED;
        goto Exit;
      }

      if (NetIp6IsUnspecifiedAddr (&Current->StationAddress) && IP6_NO_MAPPING (IpInstance)) {
        Status = EFI_NO_MAPPING;
        goto Exit;
      }
    }
  }

  //
  // Configure the instance or clean it up.
  //
  if (Ip6ConfigData != NULL) {
    Status = Ip6ConfigProtocol (IpInstance, Ip6ConfigData);
  } else {
    Status = Ip6CleanProtocol (IpInstance);

    //
    // Don't change the state if it is DESTROY, consider the following
    // valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped,
    // Configure (ThisIp, NULL). If the state is changed to UNCONFIGED,
    // the unload fails miserably.
    //
    if (IpInstance->State == IP6_STATE_CONFIGED) {
      IpInstance->State = IP6_STATE_UNCONFIGED;
    }
  }

  //
  // Update the MNP's configure data. Ip6ServiceConfigMnp will check
  // whether it is necessary to reconfigure the MNP.
  //
  Ip6ServiceConfigMnp (IpInstance->Service, FALSE);

Exit:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Joins and leaves multicast groups.

  The Groups() function is used to join and leave multicast group sessions. Joining a group will
  enable reception of matching multicast packets. Leaving a group will disable reception of matching
  multicast packets. Source-Specific Multicast isn't required to be supported.

  If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  JoinFlag           Set to TRUE to join the multicast group session, and FALSE to leave.
  @param[in]  GroupAddress       Pointer to the IPv6 multicast address.
                                 This is an optional parameter that may be NULL.

  @retval EFI_SUCCESS            The operation completed successfully.
  @retval EFI_INVALID_PARAMETER  One or more of the following is TRUE:
                                 - This is NULL.
                                 - JoinFlag is TRUE and GroupAddress is NULL.
                                 - GroupAddress is not NULL and *GroupAddress is
                                   not a multicast IPv6 address.
                                 - GroupAddress is not NULL and *GroupAddress is in the
                                   range of SSM destination address.
  @retval EFI_NOT_STARTED        This instance has not been started.
  @retval EFI_OUT_OF_RESOURCES   System resources could not be allocated.
  @retval EFI_UNSUPPORTED        This EFI IPv6 Protocol implementation does not support multicast groups.
  @retval EFI_ALREADY_STARTED    The group address is already in the group table (when
                                 JoinFlag is TRUE).
  @retval EFI_NOT_FOUND          The group address is not in the group table (when JoinFlag is FALSE).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiIp6Groups (
  IN EFI_IP6_PROTOCOL  *This,
  IN BOOLEAN           JoinFlag,
  IN EFI_IPv6_ADDRESS  *GroupAddress  OPTIONAL
  )
{
  EFI_TPL                   OldTpl;
  EFI_STATUS                Status;
  IP6_PROTOCOL              *IpInstance;
  IP6_SERVICE               *IpSb;

  if ((This == NULL) || (JoinFlag && GroupAddress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (GroupAddress != NULL && !IP6_IS_MULTICAST (GroupAddress)) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl     = gBS->RaiseTPL (TPL_CALLBACK);

  if (IpInstance->State != IP6_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Status = Ip6Groups (IpInstance, JoinFlag, GroupAddress);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Adds and deletes routing table entries.

  The Routes() function adds a route to, or deletes a route from, the routing table.

  Routes are determined by comparing the leftmost PrefixLength bits of Destination with
  the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the
  configured station address.

  The default route is added with Destination and PrefixLegth both set to all zeros. The
  default route matches all destination IPv6 addresses that do not match any other routes.

  All EFI IPv6 Protocol instances share a routing table.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  DeleteRoute        Set to TRUE to delete this route from the routing table. Set to
                                 FALSE to add this route to the routing table. Destination,
                                 PrefixLength and Gateway are used as the key to each
                                 route entry.
  @param[in]  Destination        The address prefix of the subnet that needs to be routed.
                                 This is an optional parameter that may be NULL.
  @param[in]  PrefixLength       The prefix length of Destination. Ignored if Destination
                                 is NULL.
  @param[in]  GatewayAddress     The unicast gateway IPv6 address for this route.
                                 This is an optional parameter that may be NULL.

  @retval EFI_SUCCESS            The operation completed successfully.
  @retval EFI_NOT_STARTED        The driver instance has not been started.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 - This is NULL.
                                 - When DeleteRoute is TRUE, both Destination and
                                   GatewayAddress are NULL.
                                 - When DeleteRoute is FALSE, either Destination or
                                   GatewayAddress is NULL.
                                 - *GatewayAddress is not a valid unicast IPv6 address.
                                 - *GatewayAddress is one of the local configured IPv6
                                   addresses.
  @retval EFI_OUT_OF_RESOURCES   Could not add the entry to the routing table.
  @retval EFI_NOT_FOUND          This route is not in the routing table (when DeleteRoute is TRUE).
  @retval EFI_ACCESS_DENIED      The route is already defined in the routing table (when
                                 DeleteRoute is FALSE).

**/
EFI_STATUS
EFIAPI
EfiIp6Routes (
  IN EFI_IP6_PROTOCOL    *This,
  IN BOOLEAN             DeleteRoute,
  IN EFI_IPv6_ADDRESS    *Destination    OPTIONAL,
  IN UINT8               PrefixLength,
  IN EFI_IPv6_ADDRESS    *GatewayAddress OPTIONAL
  )
{
  IP6_PROTOCOL              *IpInstance;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  IP6_SERVICE               *IpSb;

  if ((This == NULL) || (PrefixLength >= IP6_PREFIX_NUM)) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  if (IpInstance->State != IP6_STATE_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (DeleteRoute && (Destination == NULL) && (GatewayAddress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!DeleteRoute && (Destination == NULL || GatewayAddress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (GatewayAddress != NULL) {
    if (!Ip6IsValidAddress (IpSb, GatewayAddress, FALSE)) {
      return EFI_INVALID_PARAMETER;
    }

    if (!NetIp6IsUnspecifiedAddr (GatewayAddress) &&
        !NetIp6IsNetEqual (GatewayAddress, &IpInstance->ConfigData.StationAddress, PrefixLength)
          ) {
      return EFI_INVALID_PARAMETER;
    }
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Update the route table
  //
  if (DeleteRoute) {
    Status = Ip6DelRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress);
  } else {
    Status = Ip6AddRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress);
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Add or delete Neighbor cache entries.

  The Neighbors() function is used to add, update, or delete an entry from neighbor cache.
  IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as
  network traffic is processed. Most neighbor cache entries will timeout and be deleted if the network
  traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not
  timeout) or dynamic (will timeout).

  The implementation should follow the neighbor cache timeout mechanism which is defined in
  RFC4861. The default neighbor cache timeout value should be tuned for the expected network
  environment

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  DeleteFlag         Set to TRUE to delete the specified cache entry, set to FALSE to
                                 add (or update, if it already exists and Override is TRUE) the
                                 specified cache entry. TargetIp6Address is used as the key
                                 to find the requested cache entry.
  @param[in]  TargetIp6Address   Pointer to the Target IPv6 address.
  @param[in]  TargetLinkAddress  Pointer to the 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, EFI_ACCESS_DENIED
                                 will be returned if a corresponding cache entry already existed.

  @retval  EFI_SUCCESS           The data has been queued for transmission.
  @retval  EFI_NOT_STARTED       This instance has not been started.
  @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
                                 - This is NULL.
                                 - TargetIpAddress is NULL.
                                 - *TargetLinkAddress is invalid when not NULL.
                                 - *TargetIpAddress is not a valid unicast IPv6 address.
                                 - *TargetIpAddress is one of the local configured IPv6
                                   addresses.
  @retval  EFI_OUT_OF_RESOURCES  Could not add the entry to the neighbor cache.
  @retval  EFI_NOT_FOUND         This entry is not in the neighbor cache (when DeleteFlag  is
                                 TRUE or when DeleteFlag  is FALSE while
                                 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 Override
                                 is FALSE).

**/
EFI_STATUS
EFIAPI
EfiIp6Neighbors (
  IN EFI_IP6_PROTOCOL          *This,
  IN BOOLEAN                   DeleteFlag,
  IN EFI_IPv6_ADDRESS          *TargetIp6Address,
  IN EFI_MAC_ADDRESS           *TargetLinkAddress OPTIONAL,
  IN UINT32                    Timeout,
  IN BOOLEAN                   Override
  )
{
  EFI_TPL                   OldTpl;
  EFI_STATUS                Status;
  IP6_PROTOCOL              *IpInstance;
  IP6_SERVICE               *IpSb;

  if (This == NULL || TargetIp6Address == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (NetIp6IsUnspecifiedAddr (TargetIp6Address)) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  if (!Ip6IsValidAddress (IpSb, TargetIp6Address, FALSE)) {
    return EFI_INVALID_PARAMETER;
  }

  if (TargetLinkAddress != NULL) {
    if (!Ip6IsValidLinkAddress (IpSb, TargetLinkAddress)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (Ip6IsOneOfSetAddress (IpSb, TargetIp6Address, NULL, NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  if (IpInstance->State != IP6_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  if (DeleteFlag) {
    Status = Ip6DelNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override);
  } else {
    Status = Ip6AddNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override);
  }

Exit:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Check whether the user's token or event has already
  been enqueue on IP6's list.

  @param[in]  Map                The container of either user's transmit or receive
                                 token.
  @param[in]  Item               Current item to check against.
  @param[in]  Context            The Token to check againist.

  @retval EFI_ACCESS_DENIED      The token or event has already been enqueued in IP
  @retval EFI_SUCCESS            The current item isn't the same token/event as the
                                 context.

**/
EFI_STATUS
EFIAPI
Ip6TokenExist (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item,
  IN VOID                   *Context
  )
{
  EFI_IP6_COMPLETION_TOKEN  *Token;
  EFI_IP6_COMPLETION_TOKEN  *TokenInItem;

  Token       = (EFI_IP6_COMPLETION_TOKEN *) Context;
  TokenInItem = (EFI_IP6_COMPLETION_TOKEN *) Item->Key;

  if (Token == TokenInItem || Token->Event == TokenInItem->Event) {
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  Validate the user's token against the current station address.

  @param[in]  Token              User's token to validate.

  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
  @retval EFI_BAD_BUFFER_SIZE    The user's option/data is too long.
  @retval EFI_SUCCESS            The token is OK.

**/
EFI_STATUS
Ip6TxTokenValid (
  IN EFI_IP6_COMPLETION_TOKEN   *Token
  )
{
  EFI_IP6_TRANSMIT_DATA     *TxData;
  UINT32                    Index;
  UINT32                    DataLength;

  if (Token == NULL || Token->Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  TxData = Token->Packet.TxData;

  if (TxData == NULL || (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (TxData->FragmentCount == 0 || TxData->DataLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  for (DataLength = 0, Index = 0; Index < TxData->FragmentCount; Index++) {
    if (TxData->FragmentTable[Index].FragmentLength == 0 || TxData->FragmentTable[Index].FragmentBuffer == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    DataLength += TxData->FragmentTable[Index].FragmentLength;
  }

  if (TxData->DataLength != DataLength) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // TODO: Token.Packet.TxData.DataLength is too short to transmit.
  // return EFI_BUFFER_TOO_SMALL;
  //

  //
  // If Token.Packet.TxData.DataLength is beyond the maximum that which can be
  // described through the Fragment Offset field in Fragment header when performing
  // fragmentation.
  //
  if (TxData->DataLength > 64 * 1024) {
    return EFI_BAD_BUFFER_SIZE;
  }

  return EFI_SUCCESS;
}

/**
  The callback function for the net buffer which wraps the user's
  transmit token. Although  this function seems simple, there
  are some subtle aspects.
  When user requests the IP to transmit a packet by passing it a
  token, the token is wrapped in an IP6_TXTOKEN_WRAP and the data
  is wrapped in an net buffer. The net buffer's Free function is
  set to Ip6FreeTxToken. The Token and token wrap are added to the
  IP child's TxToken map. Then the buffer is passed to Ip6Output for
  transmission. If an error happened before that, the buffer
  is freed, which in turn frees the token wrap. The wrap may
  have been added to the TxToken map or not, and the user's event
  shouldn't be fired because we are still in the EfiIp6Transmit. If
  the buffer has been sent by Ip6Output, it should be removed from
  the TxToken map and user's event signaled. The token wrap and buffer
  are bound together. Check the comments in Ip6Output for information
  about IP fragmentation.

  @param[in]  Context                The token's wrap.

**/
VOID
EFIAPI
Ip6FreeTxToken (
  IN VOID                   *Context
  )
{
  IP6_TXTOKEN_WRAP          *Wrap;
  NET_MAP_ITEM              *Item;

  Wrap = (IP6_TXTOKEN_WRAP *) Context;

  //
  // Signal IpSecRecycleEvent to inform IPsec free the memory
  //
  if (Wrap->IpSecRecycleSignal != NULL) {
    gBS->SignalEvent (Wrap->IpSecRecycleSignal);
  }

  //
  // Find the token in the instance's map. EfiIp6Transmit put the
  // token to the map. If that failed, NetMapFindKey will return NULL.
  //
  Item = NetMapFindKey (&Wrap->IpInstance->TxTokens, Wrap->Token);

  if (Item != NULL) {
    NetMapRemoveItem (&Wrap->IpInstance->TxTokens, Item, NULL);
  }

  if (Wrap->Sent) {
    gBS->SignalEvent (Wrap->Token->Event);

    //
    // Dispatch the DPC queued by the NotifyFunction of Token->Event.
    //
    DispatchDpc ();
  }

  FreePool (Wrap);
}


/**
  The callback function to Ip6Output to update the transmit status.

  @param[in]  Packet           The user's transmit packet.
  @param[in]  IoStatus         The result of the transmission.
  @param[in]  Flag             Not used during transmission.
  @param[in]  Context          The token's wrap.

**/
VOID
Ip6OnPacketSent (
  IN NET_BUF                   *Packet,
  IN EFI_STATUS                IoStatus,
  IN UINT32                    Flag,
  IN VOID                      *Context
  )
{
  IP6_TXTOKEN_WRAP             *Wrap;

  //
  // This is the transmission request from upper layer,
  // not the IP6 driver itself.
  //
  Wrap                = (IP6_TXTOKEN_WRAP *) Context;
  Wrap->Token->Status = IoStatus;

  NetbufFree (Wrap->Packet);
}

/**
  Places outgoing data packets into the transmit queue.

  The Transmit() function places a sending request in the transmit queue of this
  EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some
  errors occur, the event in the token will be signaled, and the status is updated.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  Token              Pointer to the transmit token.

  @retval  EFI_SUCCESS           The data has been queued for transmission.
  @retval  EFI_NOT_STARTED       This instance has not been started.
  @retval  EFI_NO_MAPPING        The IPv6 driver was responsible for choosing
                                 a source address for this transmission,
                                 but no source address was available for use.
  @retval  EFI_INVALID_PARAMETER One or more of the following is TRUE:
                                 - This is NULL.
                                 - Token is NULL.
                                 - Token.Event is NULL.
                                 - Token.Packet.TxData is NULL.
                                 - Token.Packet.ExtHdrsLength is not zero and
                                   Token.Packet.ExtHdrs is NULL.
                                 - Token.Packet.FragmentCount is zero.
                                 - One or more of the Token.Packet.TxData.
                                   FragmentTable[].FragmentLength fields is zero.
                                 - One or more of the Token.Packet.TxData.
                                   FragmentTable[].FragmentBuffer fields is NULL.
                                 - Token.Packet.TxData.DataLength is zero or not
                                   equal to the sum of fragment lengths.
                                 - Token.Packet.TxData.DestinationAddress is non
                                   zero when DestinationAddress is configured as
                                   non-zero when doing Configure() for this
                                   EFI IPv6 protocol instance.
                                 - Token.Packet.TxData.DestinationAddress is
                                   unspecified when DestinationAddress is unspecified
                                   when doing Configure() for this EFI IPv6 protocol
                                   instance.
  @retval  EFI_ACCESS_DENIED     The transmit completion token with the same Token.
                                 Event was already in the transmit queue.
  @retval  EFI_NOT_READY         The completion token could not be queued because
                                 the transmit queue is full.
  @retval  EFI_NOT_FOUND         Not route is found to destination address.
  @retval  EFI_OUT_OF_RESOURCES  Could not queue the transmit data.
  @retval  EFI_BUFFER_TOO_SMALL  Token.Packet.TxData.TotalDataLength is too
                                 short to transmit.
  @retval  EFI_BAD_BUFFER_SIZE   If Token.Packet.TxData.DataLength is beyond the
                                 maximum that which can be described through the
                                 Fragment Offset field in Fragment header when
                                 performing fragmentation.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiIp6Transmit (
  IN EFI_IP6_PROTOCOL          *This,
  IN EFI_IP6_COMPLETION_TOKEN  *Token
  )
{
  IP6_SERVICE               *IpSb;
  IP6_PROTOCOL              *IpInstance;
  EFI_IP6_CONFIG_DATA       *Config;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  EFI_IP6_HEADER            Head;
  EFI_IP6_TRANSMIT_DATA     *TxData;
  EFI_IP6_OVERRIDE_DATA     *Override;
  IP6_TXTOKEN_WRAP          *Wrap;
  UINT8                     *ExtHdrs;

  //
  // Check input parameters.
  //
  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ExtHdrs = NULL;

  Status = Ip6TxTokenValid (Token);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl     = gBS->RaiseTPL (TPL_CALLBACK);

  if (IpInstance->State != IP6_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  Config = &IpInstance->ConfigData;

  //
  // Check whether the token or signal already existed.
  //
  if (EFI_ERROR (NetMapIterate (&IpInstance->TxTokens, Ip6TokenExist, Token))) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  //
  // Build the IP header, fill in the information from ConfigData or OverrideData
  //
  ZeroMem (&Head, sizeof(EFI_IP6_HEADER));
  TxData = Token->Packet.TxData;
  IP6_COPY_ADDRESS (&Head.SourceAddress, &Config->StationAddress);
  IP6_COPY_ADDRESS (&Head.DestinationAddress, &Config->DestinationAddress);

  Status = EFI_INVALID_PARAMETER;

  if (NetIp6IsUnspecifiedAddr (&TxData->DestinationAddress)) {
    if (NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
      goto Exit;
    }

    ASSERT (!NetIp6IsUnspecifiedAddr (&Config->StationAddress));

  } else {
    //
    // StationAddress is unspecified only when ConfigData.Dest is unspecified.
    // Use TxData.Dest to override the DestinationAddress.
    //
    if (!NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
      goto Exit;
    }

    if (NetIp6IsUnspecifiedAddr (&Config->StationAddress)) {
      Status = Ip6SelectSourceAddress (
                 IpSb,
                 &TxData->DestinationAddress,
                 &Head.SourceAddress
                 );
      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    }

    IP6_COPY_ADDRESS (&Head.DestinationAddress, &TxData->DestinationAddress);
  }

  //
  // Fill in Head infos.
  //
  Head.NextHeader = Config->DefaultProtocol;
  if (TxData->ExtHdrsLength != 0) {
    Head.NextHeader = TxData->NextHeader;
  }

  if (TxData->OverrideData != NULL) {
    Override        = TxData->OverrideData;
    Head.NextHeader = Override->Protocol;
    Head.HopLimit   = Override->HopLimit;
    Head.FlowLabelL = HTONS ((UINT16) Override->FlowLabel);
    Head.FlowLabelH = (UINT8) ((Override->FlowLabel >> 16) & 0x0F);
  } else {
    Head.HopLimit   = Config->HopLimit;
    Head.FlowLabelL = HTONS ((UINT16) Config->FlowLabel);
    Head.FlowLabelH = (UINT8) ((Config->FlowLabel >> 16) & 0x0F);
  }

  Head.PayloadLength = HTONS ((UINT16) (TxData->ExtHdrsLength + TxData->DataLength));

  //
  // OK, it survives all the validation check. Wrap the token in
  // a IP6_TXTOKEN_WRAP and the data in a netbuf
  //
  Status = EFI_OUT_OF_RESOURCES;
  Wrap   = AllocateZeroPool (sizeof (IP6_TXTOKEN_WRAP));
  if (Wrap == NULL) {
    goto Exit;
  }

  Wrap->IpInstance  = IpInstance;
  Wrap->Token       = Token;
  Wrap->Sent        = FALSE;
  Wrap->Life        = IP6_US_TO_SEC (Config->TransmitTimeout);
  Wrap->Packet      = NetbufFromExt (
                        (NET_FRAGMENT *) TxData->FragmentTable,
                        TxData->FragmentCount,
                        IP6_MAX_HEADLEN,
                        0,
                        Ip6FreeTxToken,
                        Wrap
                        );

  if (Wrap->Packet == NULL) {
    FreePool (Wrap);
    goto Exit;
  }

  Token->Status = EFI_NOT_READY;

  Status = NetMapInsertTail (&IpInstance->TxTokens, Token, Wrap);
  if (EFI_ERROR (Status)) {
    //
    // NetbufFree will call Ip6FreeTxToken, which in turn will
    // free the IP6_TXTOKEN_WRAP. Now, the token wrap hasn't been
    // enqueued.
    //
    NetbufFree (Wrap->Packet);
    goto Exit;
  }

  //
  // Allocate a new buffer to store IPv6 extension headers to avoid updating
  // the original data in EFI_IP6_COMPLETION_TOKEN.
  //
  if (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs != NULL) {
    ExtHdrs = (UINT8 *) AllocateCopyPool (TxData->ExtHdrsLength, TxData->ExtHdrs);
    if (ExtHdrs == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }
  }

  //
  // Mark the packet sent before output it. Mark it not sent again if the
  // returned status is not EFI_SUCCESS;
  //
  Wrap->Sent = TRUE;

  Status = Ip6Output (
             IpSb,
             NULL,
             IpInstance,
             Wrap->Packet,
             &Head,
             ExtHdrs,
             TxData->ExtHdrsLength,
             Ip6OnPacketSent,
             Wrap
             );
  if (EFI_ERROR (Status)) {
    Wrap->Sent = FALSE;
    NetbufFree (Wrap->Packet);
  }

Exit:
  gBS->RestoreTPL (OldTpl);

  if (ExtHdrs != NULL) {
    FreePool (ExtHdrs);
  }

  return Status;
}

/**
  Places a receiving request into the receiving queue.

  The Receive() function places a completion token into the receive packet queue.
  This function is always asynchronous.

  The Token.Event field in the completion token must be filled in by the caller
  and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol
  driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event
  is signaled.

  Current Udp implementation creates an IP child for each Udp child.
  It initates a asynchronous receive immediately no matter whether
  there is no mapping or not. Therefore, disable the returning EFI_NO_MAPPING for now.
  To enable it, the following check must be performed:

  if (NetIp6IsUnspecifiedAddr (&Config->StationAddress) && IP6_NO_MAPPING (IpInstance)) {
    Status = EFI_NO_MAPPING;
    goto Exit;
  }

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  Token              Pointer to a token that is associated with the receive data descriptor.

  @retval EFI_SUCCESS            The receive completion token was cached.
  @retval EFI_NOT_STARTED        This EFI IPv6 Protocol instance has not been started.
  @retval EFI_NO_MAPPING         When IP6 driver responsible for binding source address to this instance,
                                 while no source address is available for use.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 - This is NULL.
                                 - Token is NULL.
                                 - Token.Event is NULL.
  @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued due to a lack of system
                                 resources (usually memory).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
                                 The EFI IPv6 Protocol instance has been reset to startup defaults.
  @retval EFI_ACCESS_DENIED      The receive completion token with the same Token.Event was already
                                 in the receive queue.
  @retval EFI_NOT_READY          The receive request could not be queued because the receive queue is full.

**/
EFI_STATUS
EFIAPI
EfiIp6Receive (
  IN EFI_IP6_PROTOCOL          *This,
  IN EFI_IP6_COMPLETION_TOKEN  *Token
  )
{
  IP6_PROTOCOL              *IpInstance;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  IP6_SERVICE               *IpSb;

  if (This == NULL || Token == NULL || Token->Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (IpInstance->State != IP6_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  //
  // Check whether the toke is already on the receive queue.
  //
  Status = NetMapIterate (&IpInstance->RxTokens, Ip6TokenExist, Token);

  if (EFI_ERROR (Status)) {
    Status = EFI_ACCESS_DENIED;
    goto Exit;
  }

  //
  // Queue the token then check whether there is pending received packet.
  //
  Status = NetMapInsertTail (&IpInstance->RxTokens, Token, NULL);

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = Ip6InstanceDeliverPacket (IpInstance);

  //
  // Dispatch the DPC queued by the NotifyFunction of this instane's receive
  // event.
  //
  DispatchDpc ();

Exit:
  gBS->RestoreTPL (OldTpl);
  return Status;
}


/**
  Cancel the transmitted but not recycled packet. If a matching
  token is found, it will call Ip6CancelPacket to cancel the
  packet. Ip6CancelPacket cancels all the fragments of the
  packet. When all the fragments are freed, the IP6_TXTOKEN_WRAP
  is deleted from the Map, and user's event is signalled.
  Because Ip6CancelPacket and other functions are all called in
  line, after Ip6CancelPacket returns, the Item has been freed.

  @param[in]  Map                The IP6 child's transmit queue.
  @param[in]  Item               The current transmitted packet to test.
  @param[in]  Context            The user's token to cancel.

  @retval EFI_SUCCESS            Continue to check the next Item.
  @retval EFI_ABORTED            The user's Token (Token != NULL) is cancelled.

**/
EFI_STATUS
EFIAPI
Ip6CancelTxTokens (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item,
  IN VOID                   *Context
  )
{
  EFI_IP6_COMPLETION_TOKEN  *Token;
  IP6_TXTOKEN_WRAP          *Wrap;

  Token = (EFI_IP6_COMPLETION_TOKEN *) Context;

  //
  // Return EFI_SUCCESS to check the next item in the map if
  // this one doesn't match.
  //
  if ((Token != NULL) && (Token != Item->Key)) {
    return EFI_SUCCESS;
  }

  Wrap = (IP6_TXTOKEN_WRAP *) Item->Value;
  ASSERT (Wrap != NULL);

  //
  // Don't access the Item, Wrap and Token's members after this point.
  // Item and wrap has been freed. And we no longer own the Token.
  //
  Ip6CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED);

  //
  // If only one item is to be cancel, return EFI_ABORTED to stop
  // iterating the map any more.
  //
  if (Token != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}


/**
  Cancel the receive request. This is simple, because
  it is only enqueued in our local receive map.

  @param[in]  Map                The IP6 child's receive queue.
  @param[in]  Item               Current receive request to cancel.
  @param[in]  Context            The user's token to cancel.


  @retval EFI_SUCCESS            Continue to check the next receive request on the
                                 queue.
  @retval EFI_ABORTED            The user's token (token != NULL) has been
                                 cancelled.

**/
EFI_STATUS
EFIAPI
Ip6CancelRxTokens (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item,
  IN VOID                   *Context
  )
{
  EFI_IP6_COMPLETION_TOKEN  *Token;
  EFI_IP6_COMPLETION_TOKEN  *This;

  Token = (EFI_IP6_COMPLETION_TOKEN *) Context;
  This  = Item->Key;

  if ((Token != NULL) && (Token != This)) {
    return EFI_SUCCESS;
  }

  NetMapRemoveItem (Map, Item, NULL);

  This->Status        = EFI_ABORTED;
  This->Packet.RxData = NULL;
  gBS->SignalEvent (This->Event);

  if (Token != NULL) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Cancel the user's receive/transmit request. It is the worker function of
  EfiIp6Cancel API.

  @param[in]  IpInstance         The IP6 child.
  @param[in]  Token              The token to cancel. If NULL, all token will be
                                 cancelled.

  @retval EFI_SUCCESS            The token is cancelled.
  @retval EFI_NOT_FOUND          The token isn't found on either the
                                 transmit/receive queue.
  @retval EFI_DEVICE_ERROR       Not all tokens are cancelled when Token is NULL.

**/
EFI_STATUS
Ip6Cancel (
  IN IP6_PROTOCOL             *IpInstance,
  IN EFI_IP6_COMPLETION_TOKEN *Token          OPTIONAL
  )
{
  EFI_STATUS                Status;

  //
  // First check the transmitted packet. Ip6CancelTxTokens returns
  // EFI_ABORTED to mean that the token has been cancelled when
  // token != NULL. So, return EFI_SUCCESS for this condition.
  //
  Status = NetMapIterate (&IpInstance->TxTokens, Ip6CancelTxTokens, Token);
  if (EFI_ERROR (Status)) {
    if ((Token != NULL) && (Status == EFI_ABORTED)) {
      return EFI_SUCCESS;
    }

    return Status;
  }

  //
  // Check the receive queue. Ip6CancelRxTokens also returns EFI_ABORT
  // for Token!=NULL and it is cancelled.
  //
  Status = NetMapIterate (&IpInstance->RxTokens, Ip6CancelRxTokens, Token);
  //
  // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's
  // events.
  //
  DispatchDpc ();
  if (EFI_ERROR (Status)) {
    if ((Token != NULL) && (Status == EFI_ABORTED)) {
      return EFI_SUCCESS;
    }

    return Status;
  }

  //
  // OK, if the Token is found when Token != NULL, the NetMapIterate
  // will return EFI_ABORTED, which has been interrupted as EFI_SUCCESS.
  //
  if (Token != NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // If Token == NULL, cancel all the tokens. return error if not
  // all of them are cancelled.
  //
  if (!NetMapIsEmpty (&IpInstance->TxTokens) || !NetMapIsEmpty (&IpInstance->RxTokens)) {

    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Abort an asynchronous transmit or receive request.

  The Cancel() function is used to abort a pending transmit or receive request.
  If the token is in the transmit or receive request queues, after calling this
  function, Token->Status will be set to EFI_ABORTED, and then Token->Event will
  be signaled. If the token is not in one of the queues, which usually means the
  asynchronous operation has completed, this function will not signal the token,
  and EFI_NOT_FOUND is returned.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
  @param[in]  Token              Pointer to a token that has been issued by
                                 EFI_IP6_PROTOCOL.Transmit() or
                                 EFI_IP6_PROTOCOL.Receive(). If NULL, all pending
                                 tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is
                                 defined in EFI_IP6_PROTOCOL.Transmit().

  @retval EFI_SUCCESS            The asynchronous I/O request was aborted and
                                 Token->Event was signaled. When Token is NULL, all
                                 pending requests were aborted, and their events were signaled.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_NOT_STARTED        This instance has not been started.
  @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O request was
                                 not found in the transmit or receive queue. It has either completed
                                 or was not issued by Transmit() and Receive().
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiIp6Cancel (
  IN EFI_IP6_PROTOCOL          *This,
  IN EFI_IP6_COMPLETION_TOKEN  *Token    OPTIONAL
  )
{
  IP6_PROTOCOL              *IpInstance;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (IpInstance->State != IP6_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto Exit;
  }

  Status = Ip6Cancel (IpInstance, Token);

Exit:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Polls for incoming data packets, and processes outgoing data packets.

  The Poll() function polls for incoming data packets and processes outgoing data
  packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll()
  function to increase the rate that data packets are moved between the communications
  device and the transmit and receive queues.

  In some systems the periodic timer event may not poll the underlying communications
  device fast enough to transmit and/or receive all data packets without missing
  incoming packets or dropping outgoing packets. Drivers and applications that are
  experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function
  more often.

  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.

  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.
  @retval  EFI_NOT_STARTED       This EFI IPv6 Protocol instance has not been started.
  @retval  EFI_INVALID_PARAMETER This is NULL.
  @retval  EFI_DEVICE_ERROR      An unexpected system error or network error occurred.
  @retval  EFI_NOT_READY         No incoming or outgoing data was processed.
  @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.
                                 Consider increasing the polling rate.

**/
EFI_STATUS
EFIAPI
EfiIp6Poll (
  IN EFI_IP6_PROTOCOL          *This
  )
{
  IP6_PROTOCOL                  *IpInstance;
  IP6_SERVICE                   *IpSb;
  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
  IpSb       = IpInstance->Service;

  if (IpSb->LinkLocalDadFail) {
    return EFI_DEVICE_ERROR;
  }

  if (IpInstance->State == IP6_STATE_UNCONFIGED) {
    return EFI_NOT_STARTED;
  }

  Mnp = IpInstance->Service->Mnp;

  //
  // Don't lock the Poll function to enable the deliver of
  // the packet polled up.
  //
  return Mnp->Poll (Mnp);

}

