/** @file
  This EFI_DHCP6_PROTOCOL interface implementation.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Dhcp6Impl.h"

//
// Well-known multi-cast address defined in section-24.1 of rfc-3315
//
//   ALL_DHCP_Relay_Agents_and_Servers address: FF02::1:2
//   ALL_DHCP_Servers address:                  FF05::1:3
//
EFI_IPv6_ADDRESS   mAllDhcpRelayAndServersAddress = {{0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2}};
EFI_IPv6_ADDRESS   mAllDhcpServersAddress         = {{0xFF, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3}};

EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate = {
  EfiDhcp6GetModeData,
  EfiDhcp6Configure,
  EfiDhcp6Start,
  EfiDhcp6InfoRequest,
  EfiDhcp6RenewRebind,
  EfiDhcp6Decline,
  EfiDhcp6Release,
  EfiDhcp6Stop,
  EfiDhcp6Parse
};

/**
  Starts the DHCPv6 standard S.A.R.R. process.

  The Start() function starts the DHCPv6 standard process. This function can
  be called only when the state of Dhcp6 instance is in the Dhcp6Init state.
  If the DHCP process completes successfully, the state of the Dhcp6 instance
  will be transferred through Dhcp6Selecting and Dhcp6Requesting to the
  Dhcp6Bound state.
  Refer to rfc-3315 for precise state transitions during this process. At the
  time when each event occurs in this process, the callback function that was set
  by EFI_DHCP6_PROTOCOL.Configure() will be called, and the user can take this
  opportunity to control the process.

  @param[in]  This              The pointer to Dhcp6 protocol.

  @retval EFI_SUCCESS           The DHCPv6 standard process has started, or it has
                                completed when CompletionEvent is NULL.
  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured.
  @retval EFI_INVALID_PARAMETER This is NULL.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_TIMEOUT           The DHCPv6 configuration process failed because no
                                response was received from the server within the
                                specified timeout value.
  @retval EFI_ABORTED           The user aborted the DHCPv6 process.
  @retval EFI_ALREADY_STARTED   Some other Dhcp6 instance already started the DHCPv6
                                standard process.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
  @retval EFI_NO_MEDIA          There was a media error.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Start (
  IN EFI_DHCP6_PROTOCOL        *This
  )
{
  EFI_STATUS                   Status;
  EFI_TPL                      OldTpl;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;
  EFI_STATUS                   MediaStatus;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  //
  // The instance hasn't been configured.
  //
  if (Instance->Config == NULL) {
    return EFI_ACCESS_DENIED;
  }

  ASSERT (Instance->IaCb.Ia != NULL);

  //
  // The instance has already been started.
  //
  if (Instance->IaCb.Ia->State != Dhcp6Init) {
    return EFI_ALREADY_STARTED;
  }

  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Check Media Satus.
  //
  MediaStatus = EFI_SUCCESS;
  NetLibDetectMediaWaitTimeout (Service->Controller, DHCP_CHECK_MEDIA_WAITING_TIME, &MediaStatus);
  if (MediaStatus != EFI_SUCCESS) {
    Status = EFI_NO_MEDIA;
    goto ON_ERROR;
  }

  Instance->UdpSts = EFI_ALREADY_STARTED;

  //
  // Send the solicit message to start S.A.R.R process.
  //
  Status = Dhcp6SendSolicitMsg (Instance);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Register receive callback for the stateful exchange process.
  //
  Status = UdpIoRecvDatagram(
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ON_ERROR;
  }

  gBS->RestoreTPL (OldTpl);

  //
  // Poll udp out of the net tpl if synchronous call.
  //
  if (Instance->Config->IaInfoEvent == NULL) {

    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6);
    }
    return Instance->UdpSts;
  }

  return EFI_SUCCESS;

ON_ERROR:

  gBS->RestoreTPL (OldTpl);
  return Status;
}


/**
  Stops the DHCPv6 standard S.A.R.R. process.

  The Stop() function is used to stop the DHCPv6 standard process. After this
  function is called successfully, the state of Dhcp6 instance is transferred
  into Dhcp6Init. EFI_DHCP6_PROTOCOL.Configure() needs to be called
  before DHCPv6 standard process can be started again. This function can be
  called when the Dhcp6 instance is in any state.

  @param[in]  This              The pointer to the Dhcp6 protocol.

  @retval EFI_SUCCESS           The Dhcp6 instance is now in the Dhcp6Init state.
  @retval EFI_INVALID_PARAMETER This is NULL.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Stop (
  IN EFI_DHCP6_PROTOCOL        *This
  )
{
  EFI_TPL                      OldTpl;
  EFI_STATUS                   Status;
  EFI_UDP6_PROTOCOL            *Udp6;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;
  Udp6     = Service->UdpIo->Protocol.Udp6;
  Status   = EFI_SUCCESS;

  //
  // The instance hasn't been configured.
  //
  if (Instance->Config == NULL) {
    return Status;
  }

  ASSERT (Instance->IaCb.Ia != NULL);

  //
  // No valid REPLY message received yet, cleanup this instance directly.
  //
  if (Instance->IaCb.Ia->State == Dhcp6Init ||
      Instance->IaCb.Ia->State == Dhcp6Selecting ||
      Instance->IaCb.Ia->State == Dhcp6Requesting
      ) {
    goto ON_EXIT;
  }

  //
  // Release the current ready Ia.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance->UdpSts = EFI_ALREADY_STARTED;
  Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);
  gBS->RestoreTPL (OldTpl);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll udp out of the net tpl if synchoronus call.
  //
  if (Instance->Config->IaInfoEvent == NULL) {
    ASSERT (Udp6 != NULL);
    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Udp6->Poll (Udp6);
    }
    Status = Instance->UdpSts;
  }

ON_EXIT:
  //
  // Clean up the session data for the released Ia.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  Dhcp6CleanupSession (Instance, EFI_SUCCESS);
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Returns the current operating mode data for the Dhcp6 instance.

  The GetModeData() function returns the current operating mode and
  cached data packet for the Dhcp6 instance.

  @param[in]  This              The pointer to the Dhcp6 protocol.
  @param[out] Dhcp6ModeData     The pointer to the Dhcp6 mode data.
  @param[out] Dhcp6ConfigData   The pointer to the Dhcp6 configure data.

  @retval EFI_SUCCESS           The mode data was returned.
  @retval EFI_INVALID_PARAMETER This is NULL.
  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Protocol instance was not
                                configured.
**/
EFI_STATUS
EFIAPI
EfiDhcp6GetModeData (
  IN  EFI_DHCP6_PROTOCOL       *This,
  OUT EFI_DHCP6_MODE_DATA      *Dhcp6ModeData      OPTIONAL,
  OUT EFI_DHCP6_CONFIG_DATA    *Dhcp6ConfigData    OPTIONAL
  )
{
  EFI_TPL                      OldTpl;
  EFI_DHCP6_IA                 *Ia;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;
  UINT32                       IaSize;
  UINT32                       IdSize;

  if (This == NULL || (Dhcp6ModeData == NULL && Dhcp6ConfigData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  if (Instance->Config == NULL && Dhcp6ConfigData != NULL) {
    return EFI_ACCESS_DENIED;
  }

  ASSERT (Service->ClientId != NULL);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // User needs a copy of instance config data.
  //
  if (Dhcp6ConfigData != NULL) {
    ZeroMem (Dhcp6ConfigData, sizeof(EFI_DHCP6_CONFIG_DATA));
    //
    // Duplicate config data, including all reference buffers.
    //
    if (EFI_ERROR (Dhcp6CopyConfigData (Dhcp6ConfigData, Instance->Config))) {
      goto ON_ERROR;
    }
  }

  //
  // User need a copy of instance mode data.
  //
  if (Dhcp6ModeData != NULL) {
    ZeroMem (Dhcp6ModeData, sizeof (EFI_DHCP6_MODE_DATA));
    //
    // Duplicate a copy of EFI_DHCP6_DUID for client Id.
    //
    IdSize = Service->ClientId->Length + sizeof (Service->ClientId->Length);

    Dhcp6ModeData->ClientId = AllocateZeroPool (IdSize);
    if (Dhcp6ModeData->ClientId == NULL) {
      goto ON_ERROR;
    }

    CopyMem (
      Dhcp6ModeData->ClientId,
      Service->ClientId,
      IdSize
      );

    Ia = Instance->IaCb.Ia;
    if (Ia != NULL) {
      //
      // Duplicate a copy of EFI_DHCP6_IA for configured Ia.
      //
      IaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount -1) * sizeof (EFI_DHCP6_IA_ADDRESS);

      Dhcp6ModeData->Ia = AllocateZeroPool (IaSize);
      if (Dhcp6ModeData->Ia == NULL) {
        goto ON_ERROR;
      }

      CopyMem (
        Dhcp6ModeData->Ia,
        Ia,
        IaSize
        );

      //
      // Duplicate a copy of reply packet if has.
      //
      if (Ia->ReplyPacket != NULL) {
        Dhcp6ModeData->Ia->ReplyPacket = AllocateZeroPool (Ia->ReplyPacket->Size);
        if (Dhcp6ModeData->Ia->ReplyPacket == NULL) {
          goto ON_ERROR;
        }
        CopyMem (
          Dhcp6ModeData->Ia->ReplyPacket,
          Ia->ReplyPacket,
          Ia->ReplyPacket->Size
          );
      }
    }
  }

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;

ON_ERROR:

  if (Dhcp6ConfigData != NULL) {
    Dhcp6CleanupConfigData (Dhcp6ConfigData);
  }
  if (Dhcp6ModeData != NULL) {
    Dhcp6CleanupModeData (Dhcp6ModeData);
  }
  gBS->RestoreTPL (OldTpl);

  return EFI_OUT_OF_RESOURCES;
}


/**
  Initializes, changes, or resets the operational settings for the Dhcp6 instance.

  The Configure() function is used to initialize or clean up the configuration
  data of the Dhcp6 instance:
  - When Dhcp6CfgData is not NULL and Configure() is called successfully, the
    configuration data will be initialized in the Dhcp6 instance, and the state
    of the configured IA will be transferred into Dhcp6Init.
  - When Dhcp6CfgData is NULL and Configure() is called successfully, the
    configuration data will be cleaned up and no IA will be associated with
    the Dhcp6 instance.
  To update the configuration data for an Dhcp6 instance, the original data
  must be cleaned up before setting the new configuration data.

  @param[in]  This                   The pointer to the Dhcp6 protocol
  @param[in]  Dhcp6CfgData           The pointer to the EFI_DHCP6_CONFIG_DATA.

  @retval EFI_SUCCESS           The Dhcp6 is configured successfully with the
                                Dhcp6Init state, or cleaned up the original
                                configuration setting.
  @retval EFI_ACCESS_DENIED     The Dhcp6 instance was already configured.
                                The Dhcp6 instance has already started the
                                DHCPv6 S.A.R.R when Dhcp6CfgData is NULL.
  @retval EFI_INVALID_PARAMETER Some of the parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Configure (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN EFI_DHCP6_CONFIG_DATA     *Dhcp6CfgData    OPTIONAL
  )
{
  EFI_TPL                      OldTpl;
  EFI_STATUS                   Status;
  LIST_ENTRY                   *Entry;
  DHCP6_INSTANCE               *Other;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;
  UINTN                        Index;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  //
  // Check the parameter of configure data.
  //
  if (Dhcp6CfgData != NULL) {
    if (Dhcp6CfgData->OptionCount > 0 && Dhcp6CfgData->OptionList == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    if (Dhcp6CfgData->OptionList != NULL) {
      for (Index = 0; Index < Dhcp6CfgData->OptionCount; Index++) {
        if (Dhcp6CfgData->OptionList[Index]->OpCode == Dhcp6OptClientId ||
            Dhcp6CfgData->OptionList[Index]->OpCode == Dhcp6OptRapidCommit ||
            Dhcp6CfgData->OptionList[Index]->OpCode == Dhcp6OptReconfigureAccept ||
            Dhcp6CfgData->OptionList[Index]->OpCode == Dhcp6OptIana ||
            Dhcp6CfgData->OptionList[Index]->OpCode == Dhcp6OptIata
            ) {
          return EFI_INVALID_PARAMETER;
        }
      }
    }

    if (Dhcp6CfgData->IaDescriptor.Type != EFI_DHCP6_IA_TYPE_NA &&
        Dhcp6CfgData->IaDescriptor.Type != EFI_DHCP6_IA_TYPE_TA
        ) {
      return EFI_INVALID_PARAMETER;
    }

    if (Dhcp6CfgData->IaInfoEvent == NULL && Dhcp6CfgData->SolicitRetransmission == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if (Dhcp6CfgData->SolicitRetransmission != NULL &&
        Dhcp6CfgData->SolicitRetransmission->Mrc == 0 &&
        Dhcp6CfgData->SolicitRetransmission->Mrd == 0
        ) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Make sure the (IaId, IaType) is unique over all the instances.
    //
    NET_LIST_FOR_EACH (Entry, &Service->Child) {
      Other = NET_LIST_USER_STRUCT (Entry, DHCP6_INSTANCE, Link);
      if (Other->IaCb.Ia != NULL &&
          Other->IaCb.Ia->Descriptor.Type == Dhcp6CfgData->IaDescriptor.Type &&
          Other->IaCb.Ia->Descriptor.IaId == Dhcp6CfgData->IaDescriptor.IaId
          ) {
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (Dhcp6CfgData != NULL) {
    //
    // It's not allowed to configure one instance twice without configure null.
    //
    if (Instance->Config != NULL) {
      gBS->RestoreTPL (OldTpl);
      return EFI_ACCESS_DENIED;
    }

    //
    // Duplicate config data including all reference buffers.
    //
    Instance->Config = AllocateZeroPool (sizeof (EFI_DHCP6_CONFIG_DATA));
    if (Instance->Config == NULL) {
      gBS->RestoreTPL (OldTpl);
      return EFI_OUT_OF_RESOURCES;
    }

    Status = Dhcp6CopyConfigData (Instance->Config, Dhcp6CfgData);
    if (EFI_ERROR(Status)) {
      FreePool (Instance->Config);
      gBS->RestoreTPL (OldTpl);
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Initialize the Ia descriptor from the config data, and leave the other
    // fields of the Ia as default value 0.
    //
    Instance->IaCb.Ia = AllocateZeroPool (sizeof(EFI_DHCP6_IA));
    if (Instance->IaCb.Ia == NULL) {
      Dhcp6CleanupConfigData (Instance->Config);
      FreePool (Instance->Config);
      gBS->RestoreTPL (OldTpl);
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem (
      &Instance->IaCb.Ia->Descriptor,
      &Dhcp6CfgData->IaDescriptor,
      sizeof(EFI_DHCP6_IA_DESCRIPTOR)
      );

  } else {

    if (Instance->Config == NULL) {
      ASSERT (Instance->IaCb.Ia == NULL);
      gBS->RestoreTPL (OldTpl);
      return EFI_SUCCESS;
    }

    //
    // It's not allowed to configure a started instance as null.
    //
    if (Instance->IaCb.Ia->State != Dhcp6Init) {
      gBS->RestoreTPL (OldTpl);
      return EFI_ACCESS_DENIED;
    }

    Dhcp6CleanupConfigData (Instance->Config);
    FreePool (Instance->Config);
    Instance->Config = NULL;

    FreePool (Instance->IaCb.Ia);
    Instance->IaCb.Ia = NULL;
  }

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;
}


/**
  Request configuration information without the assignment of any
  Ia addresses of the client.

  The InfoRequest() function is used to request configuration information
  without the assignment of any IPv6 address of the client. The client sends
  out an Information Request packet to obtain the required configuration
  information, and DHCPv6 server responds with a Reply packet containing
  the information for the client. The received Reply packet will be passed
  to the user by ReplyCallback function. If the user returns EFI_NOT_READY from
  ReplyCallback, the Dhcp6 instance will continue to receive other Reply
  packets unless timeout according to the Retransmission parameter.
  Otherwise, the Information Request exchange process will be finished
  successfully if user returns EFI_SUCCESS from ReplyCallback.

  @param[in]  This              The pointer to the Dhcp6 protocol.
  @param[in]  SendClientId      If TRUE, the DHCPv6 protocol instance will build Client
                                Identifier option and include it into Information Request
                                packet. Otherwise, Client Identifier option will not be included.
  @param[in]  OptionRequest     The pointer to the buffer of option request options.
  @param[in]  OptionCount       The option number in the OptionList.
  @param[in]  OptionList        The list of appended options.
  @param[in]  Retransmission    The pointer to the retransmission of the message.
  @param[in]  TimeoutEvent      The event of timeout.
  @param[in]  ReplyCallback     The callback function when the reply was received.
  @param[in]  CallbackContext   The pointer to the parameter passed to the callback.

  @retval EFI_SUCCESS           The DHCPv6 information request exchange process
                                completed when TimeoutEvent is NULL. Information
                                Request packet has been sent to DHCPv6 server when
                                TimeoutEvent is not NULL.
  @retval EFI_NO_RESPONSE       The DHCPv6 information request exchange process failed
                                because of no response, or not all requested-options
                                are responded by DHCPv6 servers when Timeout happened.
  @retval EFI_ABORTED           The DHCPv6 information request exchange process was aborted
                                by user.
  @retval EFI_INVALID_PARAMETER Some parameter is NULL.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiDhcp6InfoRequest (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN BOOLEAN                   SendClientId,
  IN EFI_DHCP6_PACKET_OPTION   *OptionRequest,
  IN UINT32                    OptionCount,
  IN EFI_DHCP6_PACKET_OPTION   *OptionList[]    OPTIONAL,
  IN EFI_DHCP6_RETRANSMISSION  *Retransmission,
  IN EFI_EVENT                 TimeoutEvent     OPTIONAL,
  IN EFI_DHCP6_INFO_CALLBACK   ReplyCallback,
  IN VOID                      *CallbackContext OPTIONAL
  )
{
  EFI_STATUS                   Status;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;
  UINTN                        Index;
  EFI_EVENT                    Timer;
  EFI_STATUS                   TimerStatus;
  UINTN                        GetMappingTimeOut;

  if (This == NULL || OptionRequest == NULL || Retransmission == NULL || ReplyCallback == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Retransmission != NULL && Retransmission->Mrc == 0 && Retransmission->Mrd == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (OptionCount > 0 && OptionList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (OptionList != NULL) {
    for (Index = 0; Index < OptionCount; Index++) {
      if (OptionList[Index]->OpCode == Dhcp6OptClientId || OptionList[Index]->OpCode == Dhcp6OptRequestOption) {
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  Status = Dhcp6StartInfoRequest (
             Instance,
             SendClientId,
             OptionRequest,
             OptionCount,
             OptionList,
             Retransmission,
             TimeoutEvent,
             ReplyCallback,
             CallbackContext
             );
  if (Status == EFI_NO_MAPPING) {
    //
    // The link local address is not ready, wait for some time and restart
    // the DHCP6 information request process.
    //
    Status = Dhcp6GetMappingTimeOut(Service->Ip6Cfg, &GetMappingTimeOut);
    if (EFI_ERROR(Status)) {
      return Status;
    }

    Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Start the timer, wait for link local address DAD to finish.
    //
    Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut);
    if (EFI_ERROR (Status)) {
      gBS->CloseEvent (Timer);
      return Status;
    }

    do {
      TimerStatus = gBS->CheckEvent (Timer);
      if (!EFI_ERROR (TimerStatus)) {
        Status = Dhcp6StartInfoRequest (
                   Instance,
                   SendClientId,
                   OptionRequest,
                   OptionCount,
                   OptionList,
                   Retransmission,
                   TimeoutEvent,
                   ReplyCallback,
                   CallbackContext
                   );
      }
    } while (TimerStatus == EFI_NOT_READY);

    gBS->CloseEvent (Timer);
  }
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Poll udp out of the net tpl if synchoronus call.
  //
  if (TimeoutEvent == NULL) {

    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6);
    }
    return Instance->UdpSts;
  }

  return EFI_SUCCESS;
}


/**
  Manually extend the valid and preferred lifetimes for the IPv6 addresses
  of the configured IA and update other configuration parameters by sending a
  Renew or Rebind packet.

  The RenewRebind() function is used to manually extend the valid and preferred
  lifetimes for the IPv6 addresses of the configured IA, and update other
  configuration parameters by sending Renew or Rebind packet.
  - When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound,
    it sends Renew packet to the previously DHCPv6 server and transfer the
    state of the configured IA to Dhcp6Renewing. If valid Reply packet received,
    the state transfers to Dhcp6Bound and the valid and preferred timer restarts.
    If fails, the state transfers to Dhcp6Bound, but the timer continues.
  - When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound,
    it will send a Rebind packet. If valid Reply packet is received, the state transfers
    to Dhcp6Bound and the valid and preferred timer restarts. If it fails, the state
    transfers to Dhcp6Init, and the IA can't be used.

  @param[in]  This              The pointer to the Dhcp6 protocol.
  @param[in]  RebindRequest     If TRUE, Rebind packet will be sent and enter Dhcp6Rebinding state.
                                Otherwise, Renew packet will be sent and enter Dhcp6Renewing state.

  @retval EFI_SUCCESS           The DHCPv6 renew/rebind exchange process has
                                completed and at least one IPv6 address of the
                                configured IA has been bound again when
                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
                                The EFI DHCPv6 Protocol instance has sent Renew
                                or Rebind packet when
                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
  @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
                                state of the configured IA is not in Dhcp6Bound.
  @retval EFI_ALREADY_STARTED   The state of the configured IA has already entered
                                Dhcp6Renewing when RebindRequest is FALSE.
                                The state of the configured IA has already entered
                                Dhcp6Rebinding when RebindRequest is TRUE.
  @retval EFI_ABORTED           The DHCPv6 renew/rebind exchange process aborted
                                by the user.
  @retval EFI_NO_RESPONSE       The DHCPv6 renew/rebind exchange process failed
                                because of no response.
  @retval EFI_NO_MAPPING        No IPv6 address has been bound to the configured
                                IA after the DHCPv6 renew/rebind exchange process.
  @retval EFI_INVALID_PARAMETER Some parameter is NULL.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiDhcp6RenewRebind (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN BOOLEAN                   RebindRequest
  )
{
  EFI_STATUS                   Status;
  EFI_TPL                      OldTpl;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  //
  // The instance hasn't been configured.
  //
  if (Instance->Config == NULL) {
    return EFI_ACCESS_DENIED;
  }

  ASSERT (Instance->IaCb.Ia != NULL);

  //
  // The instance has already entered renewing or rebinding state.
  //
  if ((Instance->IaCb.Ia->State == Dhcp6Rebinding && RebindRequest) ||
      (Instance->IaCb.Ia->State == Dhcp6Renewing && !RebindRequest)
      ) {
    return EFI_ALREADY_STARTED;
  }

  if (Instance->IaCb.Ia->State != Dhcp6Bound) {
    return EFI_ACCESS_DENIED;
  }

  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);
  Instance->UdpSts = EFI_ALREADY_STARTED;

  //
  // Send renew/rebind message to start exchange process.
  //
  Status = Dhcp6SendRenewRebindMsg (Instance, RebindRequest);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Register receive callback for the stateful exchange process.
  //
  Status = UdpIoRecvDatagram(
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ON_ERROR;
  }

  gBS->RestoreTPL (OldTpl);

  //
  // Poll udp out of the net tpl if synchoronus call.
  //
  if (Instance->Config->IaInfoEvent == NULL) {

    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6);
    }
    return Instance->UdpSts;
  }

  return EFI_SUCCESS;

ON_ERROR:

  gBS->RestoreTPL (OldTpl);
  return Status;
}


/**
  Inform that one or more addresses assigned by a server are already
  in use by another node.

  The Decline() function is used to manually decline the assignment of
  IPv6 addresses, which have been already used by another node. If all
  IPv6 addresses of the configured IA are declined through this function,
  the state of the IA will switch through Dhcp6Declining to Dhcp6Init.
  Otherwise, the state of the IA will restore to Dhcp6Bound after the
  declining process. The Decline() can only be called when the IA is in
  Dhcp6Bound state. If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL,
  this function is a blocking operation. It will return after the
  declining process finishes, or aborted by user.

  @param[in]  This              The pointer to EFI_DHCP6_PROTOCOL.
  @param[in]  AddressCount      The number of declining addresses.
  @param[in]  Addresses         The pointer to the buffer stored the declining
                                addresses.

  @retval EFI_SUCCESS           The DHCPv6 decline exchange process completed
                                when EFI_DHCP6_CONFIG_DATA.IaInfoEvent was NULL.
                                The Dhcp6 instance sent Decline packet when
                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent was not NULL.
  @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
                                state of the configured IA is not in Dhcp6Bound.
  @retval EFI_ABORTED           The DHCPv6 decline exchange process aborted by user.
  @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with
                                the configured IA for this instance.
  @retval EFI_INVALID_PARAMETER Some parameter is NULL.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Decline (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN UINT32                    AddressCount,
  IN EFI_IPv6_ADDRESS          *Addresses
  )
{
  EFI_STATUS                   Status;
  EFI_TPL                      OldTpl;
  EFI_DHCP6_IA                 *DecIa;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;

  if (This == NULL || AddressCount == 0 || Addresses == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  //
  // The instance hasn't been configured.
  //
  if (Instance->Config == NULL) {
    return EFI_ACCESS_DENIED;
  }

  ASSERT (Instance->IaCb.Ia != NULL);

  if (Instance->IaCb.Ia->State != Dhcp6Bound) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Check whether all the declined addresses belongs to the configured Ia.
  //
  Status = Dhcp6CheckAddress (Instance->IaCb.Ia, AddressCount, Addresses);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);
  Instance->UdpSts = EFI_ALREADY_STARTED;

  //
  // Deprive of all the declined addresses from the configured Ia, and create a
  // DeclineIa used to create decline message.
  //
  DecIa = Dhcp6DepriveAddress (Instance->IaCb.Ia, AddressCount, Addresses);

  if (DecIa == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  //
  // Send the decline message to start exchange process.
  //
  Status = Dhcp6SendDeclineMsg (Instance, DecIa);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Register receive callback for the stateful exchange process.
  //
  Status = UdpIoRecvDatagram(
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ON_ERROR;
  }

  FreePool (DecIa);
  gBS->RestoreTPL (OldTpl);

  //
  // Poll udp out of the net tpl if synchoronus call.
  //
  if (Instance->Config->IaInfoEvent == NULL) {

    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6);
    }
    return Instance->UdpSts;
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (DecIa != NULL) {
    FreePool (DecIa);
  }
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Release one or more addresses associated with the configured Ia
  for current instance.

  The Release() function is used to manually release one or more
  IPv6 addresses. If AddressCount is zero, it will release all IPv6
  addresses of the configured IA. If all IPv6 addresses of the IA are
  released through this function, the state of the IA will switch
  through Dhcp6Releasing to Dhcp6Init, otherwise, the state of the
  IA will restore to Dhcp6Bound after the releasing process.
  The Release() can only be called when the IA is in Dhcp6Bound state.
  If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is
  a blocking operation. It will return after the releasing process
  finishes, or is aborted by user.

  @param[in]  This              The pointer to the Dhcp6 protocol.
  @param[in]  AddressCount      The number of releasing addresses.
  @param[in]  Addresses         The pointer to the buffer stored the releasing
                                addresses.

  @retval EFI_SUCCESS           The DHCPv6 release exchange process
                                completed when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
                                was NULL. The Dhcp6 instance was sent Release
                                packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
                                was not NULL.
  @retval EFI_ACCESS_DENIED     The Dhcp6 instance hasn't been configured, or the
                                state of the configured IA is not in Dhcp6Bound.
  @retval EFI_ABORTED           The DHCPv6 release exchange process aborted by user.
  @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with
                                the configured IA for this instance.
  @retval EFI_INVALID_PARAMETER Some parameter is NULL.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Release (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN UINT32                    AddressCount,
  IN EFI_IPv6_ADDRESS          *Addresses
  )
{
  EFI_STATUS                   Status;
  EFI_TPL                      OldTpl;
  EFI_DHCP6_IA                 *RelIa;
  DHCP6_INSTANCE               *Instance;
  DHCP6_SERVICE                *Service;

  if (This == NULL || (AddressCount != 0 && Addresses == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (This);
  Service  = Instance->Service;

  //
  // The instance hasn't been configured.
  //
  if (Instance->Config == NULL) {
    return EFI_ACCESS_DENIED;
  }

  ASSERT (Instance->IaCb.Ia != NULL);

  if (Instance->IaCb.Ia->State != Dhcp6Bound) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Check whether all the released addresses belongs to the configured Ia.
  //
  Status = Dhcp6CheckAddress (Instance->IaCb.Ia, AddressCount, Addresses);

  if (EFI_ERROR(Status)) {
    return Status;
  }

  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);
  Instance->UdpSts = EFI_ALREADY_STARTED;

  //
  // Deprive of all the released addresses from the configured Ia, and create a
  // ReleaseIa used to create release message.
  //
  RelIa = Dhcp6DepriveAddress (Instance->IaCb.Ia, AddressCount, Addresses);

  if (RelIa == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  //
  // Send the release message to start exchange process.
  //
  Status = Dhcp6SendReleaseMsg (Instance, RelIa);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Register receive callback for the stateful exchange process.
  //
  Status = UdpIoRecvDatagram(
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ON_ERROR;
  }

  FreePool (RelIa);
  gBS->RestoreTPL (OldTpl);

  //
  // Poll udp out of the net tpl if synchoronus call.
  //
  if (Instance->Config->IaInfoEvent == NULL) {
    while (Instance->UdpSts == EFI_ALREADY_STARTED) {
      Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6);
    }
    return Instance->UdpSts;
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (RelIa != NULL) {
    FreePool (RelIa);
  }
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Parse the option data in the Dhcp6 packet.

  The Parse() function is used to retrieve the option list in the DHCPv6 packet.

  @param[in]      This              The pointer to the Dhcp6 protocol.
  @param[in]      Packet            The pointer to the Dhcp6 packet.
  @param[in, out] OptionCount       The number of option in the packet.
  @param[out]     PacketOptionList  The array of pointers to each option in the packet.

  @retval EFI_SUCCESS           The packet was successfully parsed.
  @retval EFI_INVALID_PARAMETER Some parameter is NULL.
  @retval EFI_BUFFER_TOO_SMALL  *OptionCount is smaller than the number of options
                                that were found in the Packet.

**/
EFI_STATUS
EFIAPI
EfiDhcp6Parse (
  IN EFI_DHCP6_PROTOCOL        *This,
  IN EFI_DHCP6_PACKET          *Packet,
  IN OUT UINT32                *OptionCount,
  OUT EFI_DHCP6_PACKET_OPTION  *PacketOptionList[]  OPTIONAL
  )
{
  UINT32                       OptCnt;
  UINT32                       OptLen;
  UINT16                       DataLen;
  UINT8                        *Start;
  UINT8                        *End;

  if (This == NULL || Packet == NULL || OptionCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*OptionCount != 0 && PacketOptionList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Packet->Length > Packet->Size || Packet->Length < sizeof (EFI_DHCP6_HEADER)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  //  The format of Dhcp6 option:
  //
  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |          option-code          |   option-len (option data)    |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                          option-data                          |
  //    |                      (option-len octets)                      |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  OptCnt = 0;
  OptLen = Packet->Length - sizeof (EFI_DHCP6_HEADER);
  Start  = Packet->Dhcp6.Option;
  End    = Start + OptLen;

  //
  // Calculate the number of option in the packet.
  //
  while (Start < End) {
    DataLen = ((EFI_DHCP6_PACKET_OPTION *) Start)->OpLen;
    Start  += (NTOHS (DataLen) + 4);
    OptCnt++;
  }

  //
  // It will return buffer too small if pass-in option count is smaller than the
  // actual count of options in the packet.
  //
  if (OptCnt > *OptionCount) {
    *OptionCount = OptCnt;
    return EFI_BUFFER_TOO_SMALL;
  }

  ZeroMem (
    PacketOptionList,
    (*OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *))
    );

  OptCnt = 0;
  Start  = Packet->Dhcp6.Option;

  while (Start < End) {

    PacketOptionList[OptCnt] = (EFI_DHCP6_PACKET_OPTION *) Start;
    DataLen = ((EFI_DHCP6_PACKET_OPTION *) Start)->OpLen;
    Start  += (NTOHS (DataLen) + 4);
    OptCnt++;
  }

  return EFI_SUCCESS;
}

