/** @file
  This EFI_DHCP6_PROTOCOL interface implementation.

  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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;

  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);
  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;
}

