/** @file
  Implementation of EFI_IP6_PROTOCOL protocol interfaces.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2016, 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_MAX)) {
    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);

}

