/** @file
  Dhcp6 internal functions implementation.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Dhcp6Impl.h"


/**
  Enqueue the packet into the retry list in case of timeout.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Packet          The pointer to the Dhcp6 packet to retry.
  @param[in]  Elapsed         The pointer to the elapsed time value in the packet.
  @param[in]  RetryCtl        The pointer to the transmission control of the packet.
                              This parameter is optional and may be NULL.

  @retval EFI_SUCCESS           Successfully enqueued the packet into the retry list according
                                to its message type.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected message type.

**/
EFI_STATUS
Dhcp6EnqueueRetry (
  IN DHCP6_INSTANCE            *Instance,
  IN EFI_DHCP6_PACKET          *Packet,
  IN UINT16                    *Elapsed,
  IN EFI_DHCP6_RETRANSMISSION  *RetryCtl     OPTIONAL
  )
{
  DHCP6_TX_CB                  *TxCb;
  DHCP6_IA_CB                  *IaCb;

  ASSERT (Packet != NULL);

  IaCb = &Instance->IaCb;
  TxCb = AllocateZeroPool (sizeof (DHCP6_TX_CB));

  if (TxCb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Save tx packet pointer, and it will be destroyed when reply received.
  //
  TxCb->TxPacket = Packet;
  TxCb->Xid      = Packet->Dhcp6.Header.TransactionId;

  //
  // Save pointer to elapsed-time value so we can update it on retransmits.
  //
  TxCb->Elapsed  = Elapsed;

  //
  // Calculate the retransmission according to the message type.
  //
  switch (Packet->Dhcp6.Header.MessageType) {
  case Dhcp6MsgSolicit:
    //
    // Calculate the retransmission threshold value for solicit packet.
    // Use the default value by rfc-3315 if user doesn't configure.
    //
    if (RetryCtl == NULL) {
      TxCb->RetryCtl.Irt = DHCP6_SOL_IRT;
      TxCb->RetryCtl.Mrc = DHCP6_SOL_MRC;
      TxCb->RetryCtl.Mrt = DHCP6_SOL_MRT;
      TxCb->RetryCtl.Mrd = DHCP6_SOL_MRD;
    } else {
      TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_SOL_IRT;
      TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_SOL_MRC;
      TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_SOL_MRT;
      TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_SOL_MRD;
    }

    TxCb->RetryExp       = Dhcp6CalculateExpireTime (
                             TxCb->RetryCtl.Irt,
                             TRUE,
                             FALSE
                             );
    break;

  case Dhcp6MsgRequest:
    //
    // Calculate the retransmission threshold value for request packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_REQ_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_REQ_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_REQ_MRT;
    TxCb->RetryCtl.Mrd = DHCP6_REQ_MRD;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgConfirm:
    //
    // Calculate the retransmission threshold value for confirm packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_CNF_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_CNF_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_CNF_MRT;
    TxCb->RetryCtl.Mrd = DHCP6_CNF_MRD;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgRenew:
    //
    // Calculate the retransmission threshold value for renew packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_REB_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_REB_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_REB_MRT;
    TxCb->RetryCtl.Mrd = IaCb->T2 - IaCb->T1;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgRebind:
    //
    // Calculate the retransmission threshold value for rebind packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_REN_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_REN_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_REN_MRT;
    TxCb->RetryCtl.Mrd = IaCb->AllExpireTime - IaCb->T2;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgDecline:
    //
    // Calculate the retransmission threshold value for decline packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_DEC_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_DEC_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_DEC_MRT;
    TxCb->RetryCtl.Mrd = DHCP6_DEC_MRD;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgRelease:
    //
    // Calculate the retransmission threshold value for release packet.
    //
    TxCb->RetryCtl.Irt = DHCP6_REL_IRT;
    TxCb->RetryCtl.Mrc = DHCP6_REL_MRC;
    TxCb->RetryCtl.Mrt = DHCP6_REL_MRT;
    TxCb->RetryCtl.Mrd = DHCP6_REL_MRD;
    TxCb->RetryExp     = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Irt,
                           TRUE,
                           TRUE
                           );
    break;

  case Dhcp6MsgInfoRequest:
    //
    // Calculate the retransmission threshold value for info-request packet.
    // Use the default value by rfc-3315 if user doesn't configure.
    //
    if (RetryCtl == NULL) {
      TxCb->RetryCtl.Irt = DHCP6_INF_IRT;
      TxCb->RetryCtl.Mrc = DHCP6_INF_MRC;
      TxCb->RetryCtl.Mrt = DHCP6_INF_MRT;
      TxCb->RetryCtl.Mrd = DHCP6_INF_MRD;
    } else {
      TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_INF_IRT;
      TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_INF_MRC;
      TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_INF_MRT;
      TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_INF_MRD;
    }

    TxCb->RetryExp       = Dhcp6CalculateExpireTime (
                             TxCb->RetryCtl.Irt,
                             TRUE,
                             TRUE
                             );
    break;

  default:
    //
    // Unexpected message type.
    //
    FreePool(TxCb);
    return EFI_DEVICE_ERROR;
  }

  //
  // Insert into the retransmit list of the instance.
  //
  InsertTailList (&Instance->TxList, &TxCb->Link);

  return EFI_SUCCESS;
}


/**
  Dequeue the packet from retry list if reply received or timeout at last.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  PacketXid       The packet transaction id to match.
  @param[in]  NeedSignal      If TRUE, then an timeout event need be signaled when it is existed.
                              Otherwise, this parameter is ignored.

  @retval EFI_SUCCESS         Successfully dequeued the packet into retry list .
  @retval EFI_NOT_FOUND       There is no xid matched in retry list.

**/
EFI_STATUS
Dhcp6DequeueRetry (
  IN DHCP6_INSTANCE         *Instance,
  IN UINT32                 PacketXid,
  IN BOOLEAN                NeedSignal
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *NextEntry;
  DHCP6_TX_CB               *TxCb;
  DHCP6_INF_CB              *InfCb;

  //
  // Seek the retransmit node in the retransmit list by packet xid.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) {

    TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link);
    ASSERT(TxCb->TxPacket);

    if (TxCb->Xid == PacketXid) {

      if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) {

        //
        // Seek the info-request node in the info-request list by packet xid.
        //
        NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->InfList) {

          InfCb = NET_LIST_USER_STRUCT (Entry, DHCP6_INF_CB, Link);

          if (InfCb->Xid == PacketXid) {
            //
            // Remove the info-request node, and signal the event if timeout.
            //
            if (InfCb->TimeoutEvent != NULL && NeedSignal) {
              gBS->SignalEvent (InfCb->TimeoutEvent);
            }

            RemoveEntryList (&InfCb->Link);
            FreePool (InfCb);
          }
        }
      }
      //
      // Remove the retransmit node.
      //
      RemoveEntryList (&TxCb->Link);
      ASSERT(TxCb->TxPacket);
      FreePool (TxCb->TxPacket);
      FreePool (TxCb);
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}


/**
  Clean up the specific nodes in the retry list.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Scope           The scope of cleanup nodes.

**/
VOID
Dhcp6CleanupRetry (
  IN DHCP6_INSTANCE         *Instance,
  IN UINT32                 Scope
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *NextEntry;
  DHCP6_TX_CB               *TxCb;
  DHCP6_INF_CB              *InfCb;

  //
  // Clean up all the stateful messages from the retransmit list.
  //
  if (Scope == DHCP6_PACKET_STATEFUL || Scope == DHCP6_PACKET_ALL) {

    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) {

      TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link);
      ASSERT(TxCb->TxPacket);

      if (TxCb->TxPacket->Dhcp6.Header.MessageType != Dhcp6MsgInfoRequest) {
        RemoveEntryList (&TxCb->Link);
        FreePool (TxCb->TxPacket);
        FreePool (TxCb);
      }
    }
  }

  //
  // Clean up all the stateless messages from the retransmit list.
  //
  if (Scope == DHCP6_PACKET_STATELESS || Scope == DHCP6_PACKET_ALL) {

    //
    // Clean up all the retransmit list for stateless messages.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) {

      TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link);
      ASSERT(TxCb->TxPacket);

      if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) {
        RemoveEntryList (&TxCb->Link);
        FreePool (TxCb->TxPacket);
        FreePool (TxCb);
      }
    }

    //
    // Clean up all the info-request messages list.
    //
    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->InfList) {

      InfCb = NET_LIST_USER_STRUCT (Entry, DHCP6_INF_CB, Link);

      if (InfCb->TimeoutEvent != NULL) {
        gBS->SignalEvent (InfCb->TimeoutEvent);
      }
      RemoveEntryList (&InfCb->Link);
      FreePool (InfCb);
    }
  }
}

/**
  Check whether the TxCb is still a valid control block in the instance's retry list.

  @param[in]  Instance       The pointer to DHCP6_INSTANCE.
  @param[in]  TxCb           The control block for a transmitted message.

  @retval   TRUE      The control block is in Instance's retry list.
  @retval   FALSE     The control block is NOT in Instance's retry list.

**/
BOOLEAN
Dhcp6IsValidTxCb (
  IN  DHCP6_INSTANCE          *Instance,
  IN  DHCP6_TX_CB             *TxCb
  )
{
  LIST_ENTRY                *Entry;

  NET_LIST_FOR_EACH (Entry, &Instance->TxList) {
    if (TxCb == NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Clean up the session of the instance stateful exchange.

  @param[in, out]  Instance        The pointer to the Dhcp6 instance.
  @param[in]       Status          The return status from udp.

**/
VOID
Dhcp6CleanupSession (
  IN OUT DHCP6_INSTANCE          *Instance,
  IN     EFI_STATUS              Status
  )
{
  UINTN                          Index;
  EFI_DHCP6_IA                   *Ia;

  ASSERT(Instance->Config);
  ASSERT(Instance->IaCb.Ia);

  //
  // Clean up the retransmit list for stateful messages.
  //
  Dhcp6CleanupRetry (Instance, DHCP6_PACKET_STATEFUL);

  if (Instance->Unicast != NULL) {
    FreePool (Instance->Unicast);
  }

  if (Instance->AdSelect != NULL) {
    FreePool (Instance->AdSelect);
  }

  if (Instance->IaCb.Ia->ReplyPacket != NULL) {
    FreePool (Instance->IaCb.Ia->ReplyPacket);
  }

  //
  // Reinitialize the Ia fields of the instance.
  //
  Instance->UdpSts                  = Status;
  Instance->AdSelect                = NULL;
  Instance->AdPref                  = 0;
  Instance->Unicast                 = NULL;
  Instance->IaCb.T1                 = 0;
  Instance->IaCb.T2                 = 0;
  Instance->IaCb.AllExpireTime      = 0;
  Instance->IaCb.LeaseTime          = 0;

  //
  // Clear start time
  //
  Instance->StartTime               = 0;

  Ia                                = Instance->IaCb.Ia;
  Ia->State                         = Dhcp6Init;
  Ia->ReplyPacket                   = NULL;

  //
  // Set the addresses as zero lifetime, and then the notify
  // function in Ip6Config will remove these timeout address.
  //
  for (Index = 0; Index < Ia->IaAddressCount; Index++) {
    Ia->IaAddress[Index].PreferredLifetime = 0;
    Ia->IaAddress[Index].ValidLifetime     = 0;
  }

  //
  //
  // Signal the Ia information updated event to informal user.
  //
  if (Instance->Config->IaInfoEvent != NULL) {
    gBS->SignalEvent (Instance->Config->IaInfoEvent);
  }
}


/**
  Callback to user when Dhcp6 transmit/receive occurs.

  @param[in]      Instance        The pointer to the Dhcp6 instance.
  @param[in]      Event           The current Dhcp6 event.
  @param[in, out] Packet          The pointer to the packet sending or received.

  @retval EFI_SUCCESS           The user function returns success.
  @retval EFI_NOT_READY         Direct the caller to continue collecting the offer.
  @retval EFI_ABORTED           The user function ask it to abort.

**/
EFI_STATUS
EFIAPI
Dhcp6CallbackUser (
  IN     DHCP6_INSTANCE       *Instance,
  IN     EFI_DHCP6_EVENT      Event,
  IN OUT EFI_DHCP6_PACKET     **Packet
  )
{
  EFI_STATUS                  Status;
  EFI_DHCP6_PACKET            *NewPacket;
  EFI_DHCP6_CALLBACK          Callback;
  VOID                        *Context;

  ASSERT (Packet != NULL);
  ASSERT (Instance->Config != NULL);
  ASSERT (Instance->IaCb.Ia != NULL);

  NewPacket = NULL;
  Status    = EFI_SUCCESS;
  Callback  = Instance->Config->Dhcp6Callback;
  Context   = Instance->Config->CallbackContext;

  //
  // Callback to user with the new message if has.
  //
  if (Callback != NULL) {

    Status = Callback (
               &Instance->Dhcp6,
               Context,
               Instance->IaCb.Ia->State,
               Event,
               *Packet,
               &NewPacket
               );
    //
    // Updated the new packet from user to replace the original one.
    //
    if (NewPacket != NULL) {
      ASSERT (*Packet != NULL);
      FreePool (*Packet);
      *Packet = NewPacket;
    }
  }

  return Status;
}


/**
  Update Ia according to the new reply message.

  @param[in, out]  Instance        The pointer to the Dhcp6 instance.
  @param[in]       Packet          The pointer to reply messages.

  @retval EFI_SUCCESS         Updated the Ia information successfully.
  @retval EFI_DEVICE_ERROR    An unexpected error.

**/
EFI_STATUS
Dhcp6UpdateIaInfo (
  IN OUT DHCP6_INSTANCE           *Instance,
  IN     EFI_DHCP6_PACKET         *Packet
  )
{
  EFI_STATUS                  Status;
  UINT8                       *Option;
  UINT8                       *IaInnerOpt;
  UINT16                      IaInnerLen;
  UINT16                      StsCode;
  UINT32                      T1;
  UINT32                      T2;

  ASSERT (Instance->Config != NULL);
  //
  // If the reply was received in response to a solicit with rapid commit option,
  // request, renew or rebind message, the client updates the information it has
  // recorded about IAs from the IA options contained in the reply message:
  //   1. record the T1 and T2 times
  //   2. add any new addresses in the IA
  //   3. discard any addresses from the IA, that have a valid lifetime of 0
  //   4. update lifetimes for any addresses that already recorded
  //   5. leave unchanged any information about addresses
  //
  // See details in the section-18.1.8 of rfc-3315.
  //
  Option = Dhcp6SeekIaOption (
             Packet->Dhcp6.Option,
             Packet->Length - sizeof (EFI_DHCP6_HEADER),
             &Instance->Config->IaDescriptor
             );
  if (Option == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // The format of the IA_NA option is:
  //
  //     0                   1                   2                   3
  //     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_IA_NA         |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        IAID (4 octets)                        |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                              T1                               |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                              T2                               |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    .                         IA_NA-options                         .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //
  // The format of the IA_TA option is:
  //
  //     0                   1                   2                   3
  //     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_IA_TA          |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        IAID (4 octets)                        |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    .                         IA_TA-options                         .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // sizeof (option-code + option-len + IaId)           = 8
  // sizeof (option-code + option-len + IaId + T1)      = 12
  // sizeof (option-code + option-len + IaId + T1 + T2) = 16
  //
  // The inner options still start with 2 bytes option-code and 2 bytes option-len.
  //
  if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
    T1 = NTOHL (ReadUnaligned32 ((UINT32 *) (Option + 8)));
    T2 = NTOHL (ReadUnaligned32 ((UINT32 *) (Option + 12)));
    //
    // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2,
    // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes
    // the remainder of the message as though the server had not  included the invalid IA_NA option.
    //
    if (T1 > T2 && T2 > 0) {
      return EFI_DEVICE_ERROR;
    }
    IaInnerOpt = Option + 16;
    IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 2))) - 12);
  } else {
    T1 = 0;
    T2 = 0;
    IaInnerOpt = Option + 8;
    IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 2))) - 4);
  }

  //
  // The format of the Status Code option is:
  //
  //   0                   1                   2                   3
  //   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_STATUS_CODE      |         option-len            |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //  |          status-code          |                               |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
  //  .                                                               .
  //  .                        status-message                         .
  //  .                                                               .
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // sizeof (option-code + option-len) = 4
  //
  StsCode = Dhcp6StsSuccess;
  Option  = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);

  if (Option != NULL) {
    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 4)));
    if (StsCode != Dhcp6StsSuccess) {
      return EFI_DEVICE_ERROR;
    }
  }

  //
  // Generate control block for the Ia.
  //
  Status = Dhcp6GenerateIaCb (
             Instance,
             IaInnerOpt,
             IaInnerLen,
             T1,
             T2
             );

  return Status;
}



/**
  Seek StatusCode Option in package. A Status Code option may appear in the
  options field of a DHCP message and/or in the options field of another option.
  See details in section 22.13, RFC3315.

  @param[in]       Instance        The pointer to the Dhcp6 instance.
  @param[in]       Packet          The pointer to reply messages.
  @param[out]      Option          The pointer to status code option.

  @retval EFI_SUCCESS              Seek status code option successfully.
  @retval EFI_DEVICE_ERROR         An unexpected error.

**/
EFI_STATUS
Dhcp6SeekStsOption (
  IN     DHCP6_INSTANCE           *Instance,
  IN     EFI_DHCP6_PACKET         *Packet,
  OUT    UINT8                    **Option
  )
{
  UINT8                       *IaInnerOpt;
  UINT16                      IaInnerLen;
  UINT16                      StsCode;

  //
  // Seek StatusCode option directly in DHCP message body. That is, search in
  // non-encapsulated option fields.
  //
  *Option = Dhcp6SeekOption (
              Packet->Dhcp6.Option,
              Packet->Length - 4,
              Dhcp6OptStatusCode
              );

  if (*Option != NULL) {
    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 4)));
    if (StsCode != Dhcp6StsSuccess) {
      return EFI_DEVICE_ERROR;
    }
  }

  //
  // Seek in encapsulated options, IA_NA and IA_TA.
  //
  *Option = Dhcp6SeekIaOption (
              Packet->Dhcp6.Option,
              Packet->Length - sizeof (EFI_DHCP6_HEADER),
              &Instance->Config->IaDescriptor
              );
  if (*Option == NULL) {
    return EFI_SUCCESS;
  }

  //
  // The format of the IA_NA option is:
  //
  //     0                   1                   2                   3
  //     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_IA_NA         |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        IAID (4 octets)                        |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                              T1                               |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                              T2                               |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    .                         IA_NA-options                         .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //
  // The format of the IA_TA option is:
  //
  //     0                   1                   2                   3
  //     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_IA_TA          |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        IAID (4 octets)                        |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    .                         IA_TA-options                         .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // sizeof (option-code + option-len + IaId)           = 8
  // sizeof (option-code + option-len + IaId + T1)      = 12
  // sizeof (option-code + option-len + IaId + T1 + T2) = 16
  //
  // The inner options still start with 2 bytes option-code and 2 bytes option-len.
  //
  if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
    IaInnerOpt = *Option + 16;
    IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 2))) - 12);
  } else {
    IaInnerOpt = *Option + 8;
    IaInnerLen = (UINT16) (NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 2))) - 4);
  }

  //
  // The format of the Status Code option is:
  //
  //   0                   1                   2                   3
  //   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_STATUS_CODE      |         option-len            |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //  |          status-code          |                               |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
  //  .                                                               .
  //  .                        status-message                         .
  //  .                                                               .
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // sizeof (option-code + option-len) = 4
  //
  *Option  = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);
  if (*Option != NULL) {
    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (*Option + 4)));
    if (StsCode != Dhcp6StsSuccess) {
      return EFI_DEVICE_ERROR;
    }
  }

  return EFI_SUCCESS;
}


/**
  Transmit Dhcp6 message by udpio.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Packet          The pointer to transmit message.
  @param[in]  Elapsed         The pointer to the elapsed time value to fill in.

  @retval EFI_SUCCESS           Successfully transmitted the packet.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval Others                Failed to transmit the packet.

**/
EFI_STATUS
Dhcp6TransmitPacket (
  IN DHCP6_INSTANCE         *Instance,
  IN EFI_DHCP6_PACKET       *Packet,
  IN UINT16                 *Elapsed
  )
{
  EFI_STATUS                Status;
  NET_BUF                   *Wrap;
  NET_FRAGMENT              Frag;
  UDP_END_POINT             EndPt;
  DHCP6_SERVICE             *Service;

  Service = Instance->Service;

  //
  // Wrap it into a netbuf then send it.
  //
  Frag.Bulk = (UINT8 *) &Packet->Dhcp6.Header;
  Frag.Len  = Packet->Length;

  //
  // Do not register free packet here, which will be handled in retry list.
  //
  Wrap = NetbufFromExt (&Frag, 1, 0, 0, Dhcp6DummyExtFree, NULL);

  if (Wrap == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Multicast the Dhcp6 message, unless get the unicast server address by option.
  //
  ZeroMem (&EndPt, sizeof (UDP_END_POINT));

  if (Instance->Unicast != NULL) {
    CopyMem (
      &EndPt.RemoteAddr,
      Instance->Unicast,
      sizeof (EFI_IPv6_ADDRESS)
      );
  } else {
    CopyMem (
      &EndPt.RemoteAddr,
      &mAllDhcpRelayAndServersAddress,
      sizeof (EFI_IPv6_ADDRESS)
      );
  }

  EndPt.RemotePort = DHCP6_PORT_SERVER;
  EndPt.LocalPort  = DHCP6_PORT_CLIENT;

  //
  // Update the elapsed time value.
  //
  if (Elapsed != NULL) {
    SetElapsedTime (Elapsed, Instance);
  }

  //
  // Send out the message by the configured Udp6Io.
  //
  Status = UdpIoSendDatagram (
             Service->UdpIo,
             Wrap,
             &EndPt,
             NULL,
             Dhcp6OnTransmitted,
             NULL
             );

  if (EFI_ERROR (Status)) {
    NetbufFree (Wrap);
    return Status;
  }

  return EFI_SUCCESS;
}


/**
  Create the solicit message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.

  @retval EFI_SUCCESS           Created and sent the solicit message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval Others                Failed to send the solicit message.

**/
EFI_STATUS
Dhcp6SendSolicitMsg   (
  IN DHCP6_INSTANCE            *Instance
  )
{
  EFI_STATUS                   Status;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET_OPTION      *UserOpt;
  EFI_DHCP6_DUID               *ClientId;
  DHCP6_SERVICE                *Service;
  UINT8                        *Cursor;
  UINT16                       *Elapsed;
  UINT32                       UserLen;
  UINTN                        Index;
  UINT16                       Length;

  Service  = Instance->Service;
  ClientId = Service->ClientId;
  UserLen  = 0;

  ASSERT (Service->ClientId != NULL);
  ASSERT (Instance->Config != NULL);
  ASSERT (Instance->IaCb.Ia != NULL);

  //
  // Calculate the added length of customized option list.
  //
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
    UserLen += (NTOHS (Instance->Config->OptionList[Index]->OpLen) + 4);
  }

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgSolicit;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for solicit message.
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendIaOption (
             Cursor,
             Instance->IaCb.Ia,
             Instance->IaCb.T1,
             Instance->IaCb.T2,
             Packet->Dhcp6.Header.MessageType
             );

  //
  // Append user-defined when configurate Dhcp6 service.
  //
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {

    UserOpt = Instance->Config->OptionList[Index];
    Cursor  = Dhcp6AppendOption(
                Cursor,
                UserOpt->OpCode,
                UserOpt->OpLen,
                UserOpt->Data
                );
  }

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send solicit packet with the state transition from Dhcp6init to
  // Dhcp6selecting.
  //
  Instance->IaCb.Ia->State = Dhcp6Selecting;
  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (
           Instance,
           Packet,
           Elapsed,
           Instance->Config->SolicitRetransmission
           );
}

/**
  Configure some parameter to initiate SolicitMsg.

  @param[in]  Instance          The pointer to the Dhcp6 instance.

  @retval EFI_SUCCESS           Created and sent the solicit message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval Others                Failed to send the solicit message.

**/
EFI_STATUS
Dhcp6InitSolicitMsg   (
  IN DHCP6_INSTANCE            *Instance
  )
{
  Instance->IaCb.T1 = 0;
  Instance->IaCb.T2 = 0;
  Instance->IaCb.Ia->IaAddressCount = 0;

  return Dhcp6SendSolicitMsg (Instance);
}


/**
  Create the request message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.

  @retval EFI_SUCCESS           Created and sent the request message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to send the request message.

**/
EFI_STATUS
Dhcp6SendRequestMsg (
  IN DHCP6_INSTANCE            *Instance
  )
{
  EFI_STATUS                   Status;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET_OPTION      *UserOpt;
  EFI_DHCP6_DUID               *ClientId;
  EFI_DHCP6_DUID               *ServerId;
  DHCP6_SERVICE                *Service;
  UINT8                        *Option;
  UINT8                        *Cursor;
  UINT16                       *Elapsed;
  UINT32                       UserLen;
  UINTN                        Index;
  UINT16                       Length;

  ASSERT(Instance->AdSelect != NULL);
  ASSERT(Instance->Config != NULL);
  ASSERT(Instance->IaCb.Ia != NULL);
  ASSERT(Instance->Service != NULL);

  Service  = Instance->Service;
  ClientId = Service->ClientId;

  ASSERT(ClientId != NULL);

  //
  // Get the server Id from the selected advertisement message.
  //
  Option = Dhcp6SeekOption (
             Instance->AdSelect->Dhcp6.Option,
             Instance->AdSelect->Length - 4,
             Dhcp6OptServerId
             );
  if (Option == NULL) {
    return EFI_DEVICE_ERROR;
  }

  ServerId = (EFI_DHCP6_DUID *) (Option + 2);

  //
  // Calculate the added length of customized option list.
  //
  UserLen = 0;
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
    UserLen += (NTOHS (Instance->Config->OptionList[Index]->OpLen) + 4);
  }

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgRequest;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for request message.
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptServerId),
             ServerId->Length,
             ServerId->Duid
             );

  Cursor = Dhcp6AppendIaOption (
             Cursor,
             Instance->IaCb.Ia,
             Instance->IaCb.T1,
             Instance->IaCb.T2,
             Packet->Dhcp6.Header.MessageType
             );

  //
  // Append user-defined when configurate Dhcp6 service.
  //
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {

    UserOpt = Instance->Config->OptionList[Index];
    Cursor  = Dhcp6AppendOption(
                Cursor,
                UserOpt->OpCode,
                UserOpt->OpLen,
                UserOpt->Data
                );
  }

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send request packet with the state transition from Dhcp6selecting to
  // Dhcp6requesting.
  //
  Instance->IaCb.Ia->State = Dhcp6Requesting;
  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}


/**
  Create the decline message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  DecIa           The pointer to the decline Ia.

  @retval EFI_SUCCESS           Created and sent the decline message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to send the decline message.

**/
EFI_STATUS
Dhcp6SendDeclineMsg (
  IN DHCP6_INSTANCE            *Instance,
  IN EFI_DHCP6_IA              *DecIa
  )
{
  EFI_STATUS                   Status;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET             *LastReply;
  EFI_DHCP6_DUID               *ClientId;
  EFI_DHCP6_DUID               *ServerId;
  DHCP6_SERVICE                *Service;
  UINT8                        *Option;
  UINT8                        *Cursor;
  UINT16                       *Elapsed;
  UINT16                       Length;

  ASSERT (Instance->Config != NULL);
  ASSERT (Instance->IaCb.Ia != NULL);
  ASSERT (Instance->Service != NULL);

  Service   = Instance->Service;
  ClientId  = Service->ClientId;
  LastReply = Instance->IaCb.Ia->ReplyPacket;

  ASSERT (ClientId != NULL);
  ASSERT (LastReply != NULL);

  //
  // Get the server Id from the last reply message.
  //
  Option = Dhcp6SeekOption (
             LastReply->Dhcp6.Option,
             LastReply->Length - 4,
             Dhcp6OptServerId
             );
  if (Option == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // EFI_DHCP6_DUID contains a length field of 2 bytes.
  //
  ServerId = (EFI_DHCP6_DUID *) (Option + 2);

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgDecline;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for rebind/renew message.
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptServerId),
             ServerId->Length,
             ServerId->Duid
             );

  Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType);

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send decline packet with the state transition from Dhcp6bound to
  // Dhcp6declining.
  //
  Instance->IaCb.Ia->State = Dhcp6Declining;
  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}


/**
  Create the release message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  RelIa           The pointer to the release Ia.

  @retval EFI_SUCCESS           Created and sent the release message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to send the release message.

**/
EFI_STATUS
Dhcp6SendReleaseMsg (
  IN DHCP6_INSTANCE            *Instance,
  IN EFI_DHCP6_IA              *RelIa
  )
{
  EFI_STATUS                   Status;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET             *LastReply;
  EFI_DHCP6_DUID               *ClientId;
  EFI_DHCP6_DUID               *ServerId;
  DHCP6_SERVICE                *Service;
  UINT8                        *Option;
  UINT8                        *Cursor;
  UINT16                       *Elapsed;
  UINT16                       Length;

  ASSERT(Instance->Config);
  ASSERT(Instance->IaCb.Ia);

  Service   = Instance->Service;
  ClientId  = Service->ClientId;
  LastReply = Instance->IaCb.Ia->ReplyPacket;

  ASSERT(ClientId);
  ASSERT(LastReply);

  //
  // Get the server Id from the last reply message.
  //
  Option = Dhcp6SeekOption (
             LastReply->Dhcp6.Option,
             LastReply->Length - 4,
             Dhcp6OptServerId
             );
  if (Option == NULL) {
    return EFI_DEVICE_ERROR;
  }

  ServerId = (EFI_DHCP6_DUID *) (Option + 2);

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgRelease;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for rebind/renew message
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  //
  // ServerId is extracted from packet, it's network order.
  //
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptServerId),
             ServerId->Length,
             ServerId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType);

  //
  // Determine the size/length of packet
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send release packet with the state transition from Dhcp6bound to
  // Dhcp6releasing.
  //
  Instance->IaCb.Ia->State = Dhcp6Releasing;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}


/**
  Create the renew/rebind message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  RebindRequest   If TRUE, it is a Rebind type message.
                              Otherwise, it is a Renew type message.

  @retval EFI_SUCCESS           Created and sent the renew/rebind message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to send the renew/rebind message.

**/
EFI_STATUS
Dhcp6SendRenewRebindMsg (
  IN DHCP6_INSTANCE         *Instance,
  IN BOOLEAN                RebindRequest
  )
{
  EFI_STATUS                Status;
  EFI_DHCP6_PACKET          *Packet;
  EFI_DHCP6_PACKET          *LastReply;
  EFI_DHCP6_PACKET_OPTION   *UserOpt;
  EFI_DHCP6_DUID            *ClientId;
  EFI_DHCP6_DUID            *ServerId;
  EFI_DHCP6_STATE           State;
  EFI_DHCP6_EVENT           Event;
  DHCP6_SERVICE             *Service;
  UINT8                     *Option;
  UINT8                     *Cursor;
  UINT16                    *Elapsed;
  UINT32                    UserLen;
  UINTN                     Index;
  UINT16                    Length;

  ASSERT(Instance->Config);
  ASSERT(Instance->IaCb.Ia);

  Service   = Instance->Service;
  ClientId  = Service->ClientId;

  ASSERT(ClientId);

  //
  // Calculate the added length of customized option list.
  //
  UserLen = 0;
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
    UserLen += (NTOHS (Instance->Config->OptionList[Index]->OpLen) + 4);
  }

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = RebindRequest ? Dhcp6MsgRebind : Dhcp6MsgRenew;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for rebind/renew message.
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendIaOption (
             Cursor,
             Instance->IaCb.Ia,
             Instance->IaCb.T1,
             Instance->IaCb.T2,
             Packet->Dhcp6.Header.MessageType
             );

  if (!RebindRequest) {
    //
    // Get the server Id from the last reply message and
    // insert it for rebind request.
    //
    LastReply = Instance->IaCb.Ia->ReplyPacket;
    ASSERT (LastReply);

    Option = Dhcp6SeekOption (
               LastReply->Dhcp6.Option,
               LastReply->Length - 4,
               Dhcp6OptServerId
               );
    if (Option == NULL) {
      FreePool (Packet);
      return EFI_DEVICE_ERROR;
    }

    ServerId = (EFI_DHCP6_DUID *) (Option + 2);

    Cursor = Dhcp6AppendOption (
               Cursor,
               HTONS (Dhcp6OptServerId),
               ServerId->Length,
               ServerId->Duid
               );
  }

  //
  // Append user-defined when configurate Dhcp6 service.
  //
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {

    UserOpt = Instance->Config->OptionList[Index];
    Cursor  = Dhcp6AppendOption(
                Cursor,
                UserOpt->OpCode,
                UserOpt->OpLen,
                UserOpt->Data
                );
  }

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  State  = (RebindRequest) ? Dhcp6Rebinding : Dhcp6Renewing;
  Event  = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing;

  Status = Dhcp6CallbackUser (Instance, Event, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send renew/rebind packet with the state transition from Dhcp6bound to
  // Dhcp6renew/rebind.
  // And sync the lease time when send renew/rebind, in case that user send
  // renew/rebind actively.
  //
  Instance->IaCb.Ia->State = State;
  Instance->IaCb.LeaseTime = (RebindRequest) ? Instance->IaCb.T2 : Instance->IaCb.T1;
  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}

/**
  Start the information request process.

  @param[in]  Instance          The pointer to the Dhcp6 instance.
  @param[in]  SendClientId      If TRUE, the client identifier option will be included in
                                information request message. Otherwise, the client identifier
                                option will not be included.
  @param[in]  OptionRequest     The pointer to the option request option.
  @param[in]  OptionCount       The number options in the OptionList.
  @param[in]  OptionList        The array pointers to the appended options.
  @param[in]  Retransmission    The pointer to the retransmission control.
  @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           Start the info-request process successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_NO_MAPPING        No source address is available for use.
  @retval Others                Failed to start the info-request process.

**/
EFI_STATUS
Dhcp6StartInfoRequest (
  IN DHCP6_INSTANCE            *Instance,
  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_INF_CB                 *InfCb;
  DHCP6_SERVICE                *Service;
  EFI_TPL                      OldTpl;

  Service  = Instance->Service;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  Instance->UdpSts = EFI_ALREADY_STARTED;
  //
  // Create and initialize the control block for the info-request.
  //
  InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));

  if (InfCb == NULL) {
    gBS->RestoreTPL (OldTpl);
    return EFI_OUT_OF_RESOURCES;
  }

  InfCb->ReplyCallback   = ReplyCallback;
  InfCb->CallbackContext = CallbackContext;
  InfCb->TimeoutEvent    = TimeoutEvent;

  InsertTailList (&Instance->InfList, &InfCb->Link);

  //
  // Send the info-request message to start exchange process.
  //
  Status = Dhcp6SendInfoRequestMsg (
             Instance,
             InfCb,
             SendClientId,
             OptionRequest,
             OptionCount,
             OptionList,
             Retransmission
             );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Register receive callback for the stateless exchange process.
  //
  Status = UdpIoRecvDatagram(
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
    goto ON_ERROR;
  }

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

ON_ERROR:
  gBS->RestoreTPL (OldTpl);
  RemoveEntryList (&InfCb->Link);
  FreePool (InfCb);

  return Status;
}

/**
  Create the information request message and send it.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  InfCb           The pointer to the information request control block.
  @param[in]  SendClientId    If TRUE, the client identifier option will be included in
                              information request message. Otherwise, the client identifier
                              option will not be included.
  @param[in]  OptionRequest   The pointer to the option request option.
  @param[in]  OptionCount     The number options in the OptionList.
  @param[in]  OptionList      The array pointers to the appended options.
  @param[in]  Retransmission  The pointer to the retransmission control.

  @retval EFI_SUCCESS           Created and sent the info-request message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval Others                Failed to send the info-request message.

**/
EFI_STATUS
Dhcp6SendInfoRequestMsg (
  IN DHCP6_INSTANCE            *Instance,
  IN DHCP6_INF_CB              *InfCb,
  IN BOOLEAN                   SendClientId,
  IN EFI_DHCP6_PACKET_OPTION   *OptionRequest,
  IN UINT32                    OptionCount,
  IN EFI_DHCP6_PACKET_OPTION   *OptionList[],
  IN EFI_DHCP6_RETRANSMISSION  *Retransmission
  )
{
  EFI_STATUS                   Status;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET_OPTION      *UserOpt;
  EFI_DHCP6_DUID               *ClientId;
  DHCP6_SERVICE                *Service;
  UINT8                        *Cursor;
  UINT16                       *Elapsed;
  UINT32                       UserLen;
  UINTN                        Index;
  UINT16                       Length;

  ASSERT(OptionRequest);

  Service  = Instance->Service;
  ClientId = Service->ClientId;
  UserLen  = NTOHS (OptionRequest->OpLen) + 4;

  ASSERT(ClientId);

  //
  // Calculate the added length of customized option list.
  //
  for (Index = 0; Index < OptionCount; Index++) {
    UserLen += (NTOHS (OptionList[Index]->OpLen) + 4);
  }

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgInfoRequest;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  InfCb->Xid                         = Packet->Dhcp6.Header.TransactionId;

  //
  // Assembly Dhcp6 options for info-request message.
  //
  Cursor = Packet->Dhcp6.Option;

  if (SendClientId) {
    Length = HTONS (ClientId->Length);
    Cursor = Dhcp6AppendOption (
               Cursor,
               HTONS (Dhcp6OptClientId),
               Length,
               ClientId->Duid
               );
  }

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendOption (
             Cursor,
             OptionRequest->OpCode,
             OptionRequest->OpLen,
             OptionRequest->Data
             );

  //
  // Append user-defined when configurate Dhcp6 service.
  //
  for (Index = 0; Index < OptionCount; Index++) {

    UserOpt = OptionList[Index];
    Cursor  = Dhcp6AppendOption(
                Cursor,
                UserOpt->OpCode,
                UserOpt->OpLen,
                UserOpt->Data
                );
  }

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  //
  // Send info-request packet with no state.
  //
  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission);
}


/**
  Create the Confirm message and send it.

  @param[in]  Instance          The pointer to the Dhcp6 instance.

  @retval EFI_SUCCESS           Created and sent the confirm message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to send the confirm message.

**/
EFI_STATUS
Dhcp6SendConfirmMsg (
  IN DHCP6_INSTANCE            *Instance
  )
{
  UINT8                        *Cursor;
  UINTN                        Index;
  UINT16                       Length;
  UINT32                       UserLen;
  EFI_STATUS                   Status;
  DHCP6_SERVICE                *Service;
  EFI_DHCP6_DUID               *ClientId;
  EFI_DHCP6_PACKET             *Packet;
  EFI_DHCP6_PACKET_OPTION      *UserOpt;
  UINT16                       *Elapsed;

  ASSERT (Instance->Config != NULL);
  ASSERT (Instance->IaCb.Ia != NULL);
  ASSERT (Instance->Service != NULL);

  Service  = Instance->Service;
  ClientId = Service->ClientId;
  ASSERT (ClientId != NULL);

  //
  // Calculate the added length of customized option list.
  //
  UserLen = 0;
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
    UserLen += (NTOHS (Instance->Config->OptionList[Index]->OpLen) + 4);
  }

  //
  // Create the Dhcp6 packet and initialize common fields.
  //
  Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
  Packet->Length                     = sizeof (EFI_DHCP6_HEADER);
  Packet->Dhcp6.Header.MessageType   = Dhcp6MsgConfirm;
  Packet->Dhcp6.Header.TransactionId = Service->Xid++;

  //
  // Assembly Dhcp6 options for solicit message.
  //
  Cursor = Packet->Dhcp6.Option;

  Length = HTONS (ClientId->Length);
  Cursor = Dhcp6AppendOption (
             Cursor,
             HTONS (Dhcp6OptClientId),
             Length,
             ClientId->Duid
             );

  Cursor = Dhcp6AppendETOption (
             Cursor,
             Instance,
             &Elapsed
             );

  Cursor = Dhcp6AppendIaOption (
             Cursor,
             Instance->IaCb.Ia,
             Instance->IaCb.T1,
             Instance->IaCb.T2,
             Packet->Dhcp6.Header.MessageType
             );

  //
  // Append user-defined when configurate Dhcp6 service.
  //
  for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
    UserOpt = Instance->Config->OptionList[Index];
    Cursor  = Dhcp6AppendOption (
                Cursor,
                UserOpt->OpCode,
                UserOpt->OpLen,
                UserOpt->Data
                );
  }

  //
  // Determine the size/length of packet.
  //
  Packet->Length += (UINT32) (Cursor - Packet->Dhcp6.Option);
  ASSERT (Packet->Size > Packet->Length + 8);

  //
  // Callback to user with the packet to be sent and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Send confirm packet with the state transition from Dhcp6Bound to
  // Dhcp6Confirming.
  //
  Instance->IaCb.Ia->State = Dhcp6Confirming;
  //
  // Clear initial time for current transaction.
  //
  Instance->StartTime = 0;

  Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  //
  // Enqueue the sent packet for the retransmission in case reply timeout.
  //
  return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
}



/**
  Handle with the Dhcp6 reply message.

  @param[in]  Instance        The pointer to Dhcp6 instance.
  @param[in]  Packet          The pointer to the Dhcp6 reply message.

  @retval EFI_SUCCESS           Processed the reply message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to process the reply message.

**/
EFI_STATUS
Dhcp6HandleReplyMsg (
  IN DHCP6_INSTANCE           *Instance,
  IN EFI_DHCP6_PACKET         *Packet
  )
{
  EFI_STATUS                  Status;
  UINT8                       *Option;
  UINT16                      StsCode;

  ASSERT (Instance->Config != NULL);
  ASSERT (Instance->IaCb.Ia != NULL);
  ASSERT (Packet != NULL);

  Status = EFI_SUCCESS;

  if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {
    return EFI_DEVICE_ERROR;
  }

  //
  // If the client subsequently receives a valid reply message that includes a
  // rapid commit option since send a solicit with rapid commit option before,
  // preocess the reply message and discard any reply messages received in
  // response to the request message.
  // See details in the section-17.1.4 of rfc-3315.
  //
  Option = Dhcp6SeekOption (
             Packet->Dhcp6.Option,
             Packet->Length - 4,
             Dhcp6OptRapidCommit
             );

  if ((Option != NULL && !Instance->Config->RapidCommit) || (Option == NULL && Instance->Config->RapidCommit)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // As to a valid reply packet in response to a request/renew/rebind packet,
  // ignore the packet if not contains the Ia option
  //
  if (Instance->IaCb.Ia->State == Dhcp6Requesting ||
      Instance->IaCb.Ia->State == Dhcp6Renewing ||
      Instance->IaCb.Ia->State == Dhcp6Rebinding
      ) {

    Option = Dhcp6SeekIaOption (
               Packet->Dhcp6.Option,
               Packet->Length,
               &Instance->Config->IaDescriptor
               );
    if (Option == NULL) {
      return EFI_SUCCESS;
    }
  }

  //
  // Callback to user with the received packet and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6RcvdReply, &Packet);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // When receive a valid reply packet in response to a decline/release packet,
  // the client considers the decline/release event completed regardless of the
  // status code.
  //
  if (Instance->IaCb.Ia->State == Dhcp6Declining || Instance->IaCb.Ia->State == Dhcp6Releasing) {

    if (Instance->IaCb.Ia->IaAddressCount != 0) {
      Instance->IaCb.Ia->State       = Dhcp6Bound;
    } else {
      ASSERT (Instance->IaCb.Ia->ReplyPacket);
      FreePool (Instance->IaCb.Ia->ReplyPacket);
      Instance->IaCb.Ia->ReplyPacket = NULL;
      Instance->IaCb.Ia->State       = Dhcp6Init;
    }

    //
    // For sync, set the success flag out of polling in decline/release.
    //
    Instance->UdpSts = EFI_SUCCESS;

    //
    // For async, signal the Ia event to inform Ia information update.
    //
    if (Instance->Config->IaInfoEvent != NULL) {
      gBS->SignalEvent (Instance->Config->IaInfoEvent);
    }

    //
    // Reset start time for next exchange.
    //
    Instance->StartTime       = 0;

    Status = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // Upon the receipt of a valid reply packet in response to a solicit, request,
  // confirm, renew and rebind, the behavior depends on the status code option.
  // See the details in the section-18.1.8 of rfc-3315.
  //
  Option = NULL;
  Status = Dhcp6SeekStsOption (
             Instance,
             Packet,
             &Option
             );

  if (!EFI_ERROR (Status)) {
    //
    // No status code or no error status code means succeed to reply.
    //
    Status = Dhcp6UpdateIaInfo (Instance, Packet);
    if (!EFI_ERROR (Status)) {
      //
      // Reset start time for next exchange.
      //
      Instance->StartTime       = 0;

      //
      // Set bound state and store the reply packet.
      //
      if (Instance->IaCb.Ia->ReplyPacket != NULL) {
        FreePool (Instance->IaCb.Ia->ReplyPacket);
      }

      Instance->IaCb.Ia->ReplyPacket = AllocateZeroPool (Packet->Size);

      if (Instance->IaCb.Ia->ReplyPacket == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      CopyMem (Instance->IaCb.Ia->ReplyPacket, Packet, Packet->Size);

      Instance->IaCb.Ia->State = Dhcp6Bound;

      //
      // For sync, set the success flag out of polling in start/renewrebind.
      //
      Instance->UdpSts         = EFI_SUCCESS;

      //
      // Maybe this is a new round DHCP process due to some reason, such as NotOnLink
      // ReplyMsg for ConfirmMsg should trigger new round to acquire new address. In that
      // case, clear old address.ValidLifetime and append to new address. Therefore, DHCP
      // consumers can be notified to flush old address.
      //
      Dhcp6AppendCacheIa (Instance);

      //
      // For async, signal the Ia event to inform Ia information update.
      //
      if (Instance->Config->IaInfoEvent != NULL) {
        gBS->SignalEvent (Instance->Config->IaInfoEvent);
      }
    } else if (Status == EFI_NOT_FOUND) {
      //
      // Refer to RFC3315 Chapter 18.1.8, for each IA in the original Renew or Rebind message,
      // the client sends a Renew or Rebind if the IA is not in the Reply message.
      // Return EFI_SUCCESS so we can continue to restart the Renew/Rebind process.
      //
      return EFI_SUCCESS;
    }

    goto ON_EXIT;

  } else if (Option != NULL) {
    //
    // Any error status code option is found.
    //
    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) (Option + 4)));
    switch (StsCode) {
    case Dhcp6StsUnspecFail:
      //
      // It indicates the server is unable to process the message due to an
      // unspecified failure condition, so just retry if possible.
      //
      break;

    case Dhcp6StsUseMulticast:
      //
      // It indicates the server receives a message via unicast from a client
      // to which the server has not sent a unicast option, so retry it by
      // multi-cast address.
      //
      if (Instance->Unicast != NULL) {
        FreePool (Instance->Unicast);
        Instance->Unicast = NULL;
      }
      break;

    case Dhcp6StsNotOnLink:
      if (Instance->IaCb.Ia->State == Dhcp6Confirming) {
        //
        // Before initiate new round DHCP, cache the current IA.
        //
        Status = Dhcp6CacheIa (Instance);
        if (EFI_ERROR (Status)) {
          return  Status;
        }

        //
        // Restart S.A.R.R process to acquire new address.
        //
        Status = Dhcp6InitSolicitMsg (Instance);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
      break;

    case Dhcp6StsNoBinding:
      if (Instance->IaCb.Ia->State == Dhcp6Renewing || Instance->IaCb.Ia->State == Dhcp6Rebinding) {
        //
        // Refer to RFC3315 Chapter 18.1.8, for each IA in the original Renew or Rebind message, the client
        // sends a Request message if the IA contained a Status Code option with the NoBinding status.
        //
        Status = Dhcp6SendRequestMsg(Instance);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
      break;

    default:
      //
      // The other status code, just restart solicitation.
      //
      break;
    }
  }

  return EFI_SUCCESS;

ON_EXIT:

  if (!EFI_ERROR(Status)) {
    Status = Dhcp6DequeueRetry (
               Instance,
               Packet->Dhcp6.Header.TransactionId,
               FALSE
               );
  }

  return Status;
}


/**
  Select the appointed Dhcp6 advertisement message.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  AdSelect        The pointer to the selected Dhcp6 advertisement message.

  @retval EFI_SUCCESS           Selected the right advertisement message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval Others                Failed to select the advertise message.

**/
EFI_STATUS
Dhcp6SelectAdvertiseMsg (
  IN DHCP6_INSTANCE           *Instance,
  IN EFI_DHCP6_PACKET         *AdSelect
  )
{
  EFI_STATUS                  Status;
  UINT8                       *Option;

  ASSERT (AdSelect != NULL);

  //
  // Callback to user with the selected advertisement packet, and the user
  // might overwrite it.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6SelectAdvertise, &AdSelect);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Instance->AdSelect = AdSelect;

  //
  // Dequeue the sent packet for the retransmission since advertisement selected.
  //
  Status = Dhcp6DequeueRetry (
             Instance,
             AdSelect->Dhcp6.Header.TransactionId,
             FALSE
             );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Check whether there is server unicast option in the selected advertise
  // packet, and update it.
  //
  Option = Dhcp6SeekOption(
             AdSelect->Dhcp6.Option,
             AdSelect->Length - 4,
             Dhcp6OptServerUnicast
             );

  if (Option != NULL) {

    Instance->Unicast = AllocateZeroPool (sizeof(EFI_IPv6_ADDRESS));

    if (Instance->Unicast == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Instance->Unicast, Option + 4, sizeof(EFI_IPv6_ADDRESS));
  }

  //
  // Update the information of the Ia by the selected advertisement message.
  //
  Status = Dhcp6UpdateIaInfo (Instance, AdSelect);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Send the request message to continue the S.A.R.R. process.
  //
  return Dhcp6SendRequestMsg (Instance);
}


/**
  Handle with the Dhcp6 advertisement message.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Packet          The pointer to the Dhcp6 advertisement message.

  @retval EFI_SUCCESS           Processed the advertisement message successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval EFI_DEVICE_ERROR      An unexpected error.
  @retval Others                Failed to process the advertise message.

**/
EFI_STATUS
Dhcp6HandleAdvertiseMsg (
  IN DHCP6_INSTANCE           *Instance,
  IN EFI_DHCP6_PACKET         *Packet
  )
{
  EFI_STATUS                  Status;
  UINT8                       *Option;
  BOOLEAN                     Timeout;

  ASSERT(Instance->Config);
  ASSERT(Instance->IaCb.Ia);

  Timeout = FALSE;

  //
  // If the client does receives a valid reply message that includes a rapid
  // commit option since a solicit with rapid commit option sent before, select
  // this reply message. Or else, process the advertise messages as normal.
  // See details in the section-17.1.4 of rfc-3315.
  //
  Option = Dhcp6SeekOption(
             Packet->Dhcp6.Option,
             Packet->Length - 4,
             Dhcp6OptRapidCommit
             );

  if (Option != NULL && Instance->Config->RapidCommit && Packet->Dhcp6.Header.MessageType == Dhcp6MsgReply) {

    return Dhcp6HandleReplyMsg (Instance, Packet);
  }

  if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgAdvertise) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Client must ignore any advertise message that includes a status code option
  // containing the value noaddrsavail, with the exception that the client may
  // display the associated status message to the user.
  // See the details in the section-17.1.3 of rfc-3315.
  //
  Status = Dhcp6SeekStsOption (
             Instance,
             Packet,
             &Option
             );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Callback to user with the received packet and check the user's feedback.
  //
  Status = Dhcp6CallbackUser (Instance, Dhcp6RcvdAdvertise, &Packet);

  if (!EFI_ERROR (Status)) {
    //
    // Success means user choose the current advertisement packet.
    //
    if (Instance->AdSelect != NULL) {
      FreePool (Instance->AdSelect);
    }

    //
    // Store the selected advertisement packet and set a flag.
    //
    Instance->AdSelect = AllocateZeroPool (Packet->Size);

    if (Instance->AdSelect == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Instance->AdSelect, Packet, Packet->Size);

    Instance->AdPref = 0xff;

  } else if (Status == EFI_NOT_READY) {
    //
    // Not_ready means user wants to continue to receive more advertise packets.
    //
    if (Instance->AdPref == 0xff && Instance->AdSelect == NULL) {
      //
      // It's a tricky point. The timer routine set adpref as 0xff if the first
      // rt timeout and no advertisement received, which means any advertisement
      // received will be selected after the first rt.
      //
      Timeout = TRUE;
    }

    //
    // Check whether the current packet has a 255 preference option or not.
    // Take non-preference option as 0 value.
    //
    Option = Dhcp6SeekOption(
               Packet->Dhcp6.Option,
               Packet->Length - 4,
               Dhcp6OptPreference
               );

    if (Instance->AdSelect == NULL || (Option != NULL && *(Option + 4) > Instance->AdPref)) {
      //
      // No advertisements received before or preference is more than other
      // advertisements received before. Then store the new packet and the
      // preference value.
      //
      if (Instance->AdSelect != NULL) {
        FreePool (Instance->AdSelect);
      }

      Instance->AdSelect = AllocateZeroPool (Packet->Size);

      if (Instance->AdSelect == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (Instance->AdSelect, Packet, Packet->Size);

      if (Option != NULL) {
        Instance->AdPref = *(Option + 4);
      }
    } else {
      //
      // Non-preference and other advertisements received before or current
      // preference is less than other advertisements received before.
      // Leave the packet alone.
    }

  } else {
    //
    // Other error status means termination.
    //
    return Status;
  }

  //
  // Client must collect advertise messages as more as possible until the first
  // RT has elapsed, or get a highest preference 255 advertise.
  // See details in the section-17.1.2 of rfc-3315.
  //
  if (Instance->AdPref == 0xff || Timeout) {
    Status = Dhcp6SelectAdvertiseMsg (Instance, Instance->AdSelect);
  }

  return Status;
}


/**
  The Dhcp6 stateful exchange process routine.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Packet          The pointer to the received Dhcp6 message.

**/
VOID
Dhcp6HandleStateful (
  IN DHCP6_INSTANCE         *Instance,
  IN EFI_DHCP6_PACKET       *Packet
  )
{
  EFI_STATUS                Status;
  EFI_DHCP6_DUID            *ClientId;
  DHCP6_SERVICE             *Service;
  UINT8                     *Option;

  Service  = Instance->Service;
  ClientId = Service->ClientId;
  Status   = EFI_SUCCESS;

  if (Instance->Config == NULL) {
    goto ON_CONTINUE;
  }

  ASSERT (ClientId);
  ASSERT (Instance->Config);
  ASSERT (Instance->IaCb.Ia);

  //
  // Discard the packet if not advertisement or reply packet.
  //
  if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgAdvertise && Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {
    goto ON_CONTINUE;
  }

  //
  // Check whether include client Id or not.
  //
  Option = Dhcp6SeekOption(
             Packet->Dhcp6.Option,
             Packet->Length - 4,
             Dhcp6OptClientId
             );

  if (Option == NULL || CompareMem (Option + 4, ClientId->Duid, ClientId->Length) != 0) {
    goto ON_CONTINUE;
  }

  //
  // Check whether include server Id or not.
  //
  Option = Dhcp6SeekOption(
             Packet->Dhcp6.Option,
             Packet->Length - 4,
             Dhcp6OptServerId
             );

  if (Option == NULL) {
    goto ON_CONTINUE;
  }

  switch (Instance->IaCb.Ia->State) {
  case Dhcp6Selecting:
    //
    // Handle the advertisement message when in the Dhcp6Selecting state.
    // Do not need check return status, if failed, just continue to the next.
    //
    Dhcp6HandleAdvertiseMsg (Instance, Packet);
    break;

  case Dhcp6Requesting:
  case Dhcp6Confirming:
  case Dhcp6Renewing:
  case Dhcp6Rebinding:
  case Dhcp6Releasing:
  case Dhcp6Declining:
    //
    // Handle the reply message when in the Dhcp6Requesting,  Dhcp6Renewing
    // Dhcp6Rebinding, Dhcp6Releasing and Dhcp6Declining state.
    // If failed here, it should reset the current session.
    //
    Status = Dhcp6HandleReplyMsg (Instance, Packet);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
    break;
  default:
    //
    // Other state has not supported yet.
    //
    break;
  }

ON_CONTINUE:
  //
  // Continue to receive the following Dhcp6 message.
  //
  Status = UdpIoRecvDatagram (
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );
ON_EXIT:
  if (EFI_ERROR (Status)) {
    Dhcp6CleanupSession (Instance, Status);
  }
}


/**
  The Dhcp6 stateless exchange process routine.

  @param[in]  Instance        The pointer to the Dhcp6 instance.
  @param[in]  Packet          The pointer to the received Dhcp6 message.

**/
VOID
Dhcp6HandleStateless (
  IN DHCP6_INSTANCE         *Instance,
  IN EFI_DHCP6_PACKET       *Packet
  )
{
  EFI_STATUS                Status;
  DHCP6_SERVICE             *Service;
  DHCP6_INF_CB              *InfCb;
  UINT8                     *Option;
  BOOLEAN                   IsMatched;

  Service   = Instance->Service;
  Status    = EFI_SUCCESS;
  IsMatched = FALSE;
  InfCb     = NULL;

  if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {
    goto ON_EXIT;
  }

  //
  // Check whether it's a desired Info-request message by Xid.
  //
  while (!IsListEmpty (&Instance->InfList)) {
    InfCb = NET_LIST_HEAD (&Instance->InfList, DHCP6_INF_CB, Link);
    if (InfCb->Xid == Packet->Dhcp6.Header.TransactionId) {
      IsMatched = TRUE;
      break;
    }
  }

  if (!IsMatched) {
    goto ON_EXIT;
  }

  //
  // Check whether include server Id or not.
  //
  Option = Dhcp6SeekOption (
             Packet->Dhcp6.Option,
             Packet->Length - 4,
             Dhcp6OptServerId
             );

  if (Option == NULL) {
    goto ON_EXIT;
  }

  //
  // Callback to user with the received packet and check the user's feedback.
  //
  Status = InfCb->ReplyCallback (
                    &Instance->Dhcp6,
                    InfCb->CallbackContext,
                    Packet
                    );

  if (Status == EFI_NOT_READY) {
    //
    // Success or aborted will both stop this info-request exchange process,
    // but not ready means user wants to continue to receive reply.
    //
    goto ON_EXIT;
  }

  //
  // Dequeue the sent packet from the txlist if the xid matched, and ignore
  // if no xid matched.
  //
  Dhcp6DequeueRetry (
    Instance,
    Packet->Dhcp6.Header.TransactionId,
    FALSE
    );

  //
  // For sync, set the status out of polling for info-request.
  //
  Instance->UdpSts = Status;

ON_EXIT:

  Status = UdpIoRecvDatagram (
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );

  if (EFI_ERROR (Status)) {
    Dhcp6CleanupRetry (Instance, DHCP6_PACKET_STATELESS);
  }
}


/**
  The receive callback function for Dhcp6 exchange process.

  @param[in]  Udp6Wrap        The pointer to the received net buffer.
  @param[in]  EndPoint        The pointer to the udp end point.
  @param[in]  IoStatus        The return status from udp io.
  @param[in]  Context         The opaque parameter to the function.

**/
VOID
EFIAPI
Dhcp6ReceivePacket (
  IN NET_BUF                *Udp6Wrap,
  IN UDP_END_POINT          *EndPoint,
  IN EFI_STATUS             IoStatus,
  IN VOID                   *Context
  )
{
  EFI_DHCP6_HEADER          *Head;
  EFI_DHCP6_PACKET          *Packet;
  DHCP6_SERVICE             *Service;
  DHCP6_INSTANCE            *Instance;
  DHCP6_TX_CB               *TxCb;
  UINT32                    Size;
  BOOLEAN                   IsDispatched;
  BOOLEAN                   IsStateless;
  LIST_ENTRY                *Entry1;
  LIST_ENTRY                *Next1;
  LIST_ENTRY                *Entry2;
  LIST_ENTRY                *Next2;
  EFI_STATUS                Status;

  ASSERT (Udp6Wrap != NULL);
  ASSERT (Context != NULL);

  Service      = (DHCP6_SERVICE *) Context;
  Instance     = NULL;
  Packet       = NULL;
  IsDispatched = FALSE;
  IsStateless  = FALSE;

  if (EFI_ERROR (IoStatus)) {
    return ;
  }

  if (Udp6Wrap->TotalSize < sizeof (EFI_DHCP6_HEADER)) {
    goto ON_CONTINUE;
  }

  //
  // Copy the net buffer received from upd6 to a Dhcp6 packet.
  //
  Size   = sizeof (EFI_DHCP6_PACKET) + Udp6Wrap->TotalSize;
  Packet = (EFI_DHCP6_PACKET *) AllocateZeroPool (Size);

  if (Packet == NULL) {
    goto ON_CONTINUE;
  }

  Packet->Size   = Size;
  Head           = &Packet->Dhcp6.Header;
  Packet->Length = NetbufCopy (Udp6Wrap, 0, Udp6Wrap->TotalSize, (UINT8 *) Head);

  if (Packet->Length == 0) {
    goto ON_CONTINUE;
  }

  //
  // Dispatch packet to right instance by transaction id.
  //
  NET_LIST_FOR_EACH_SAFE (Entry1, Next1, &Service->Child) {

    Instance = NET_LIST_USER_STRUCT (Entry1, DHCP6_INSTANCE, Link);

    NET_LIST_FOR_EACH_SAFE (Entry2, Next2, &Instance->TxList) {

      TxCb = NET_LIST_USER_STRUCT (Entry2, DHCP6_TX_CB, Link);

      if (Packet->Dhcp6.Header.TransactionId == TxCb->Xid) {
        //
        // Find the corresponding packet in tx list, and check it whether belongs
        // to stateful exchange process.
        //
        if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) {
          IsStateless = TRUE;
        }
        IsDispatched  = TRUE;
        break;
      }
    }

    if (IsDispatched) {
      break;
    }
  }

  //
  // Skip this packet if not dispatched to any instance.
  //
  if (!IsDispatched) {
    goto ON_CONTINUE;
  }

  //
  // Dispatch the received packet ot the right instance.
  //
  if (IsStateless) {
    Dhcp6HandleStateless (Instance, Packet);
  } else {
    Dhcp6HandleStateful (Instance, Packet);
  }

ON_CONTINUE:

  if (!IsDispatched) {
    Status = UdpIoRecvDatagram (
             Service->UdpIo,
             Dhcp6ReceivePacket,
             Service,
             0
             );
    if (EFI_ERROR (Status)) {
      NET_LIST_FOR_EACH_SAFE (Entry1, Next1, &Service->Child) {
        Instance = NET_LIST_USER_STRUCT (Entry1, DHCP6_INSTANCE, Link);
        Dhcp6CleanupRetry (Instance, DHCP6_PACKET_ALL);
      }
    }
  }

  NetbufFree (Udp6Wrap);

  if (Packet != NULL) {
    FreePool (Packet);
  }
}

/**
  Detect Link movement for specified network device.

  This routine will try to invoke Snp->GetStatus() to get the media status.
  If media present status switches from unpresent to present, a link movement
  is detected. Note that the underlying UNDI driver may not support reporting
  media status from GET_STATUS command. If that, fail to detect link movement.

  @param[in]  Instance       The pointer to DHCP6_INSTANCE.

  @retval     TRUE           A link movement is detected.
  @retval     FALSE          A link movement is not detected.

**/
BOOLEAN
Dhcp6LinkMovDetect (
  IN  DHCP6_INSTANCE            *Instance
  )
{
  UINT32                       InterruptStatus;
  BOOLEAN                      MediaPresent;
  EFI_STATUS                   Status;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;

  ASSERT (Instance != NULL);
  Snp = Instance->Service->Snp;
  MediaPresent = Instance->MediaPresent;

  //
  // Check whether SNP support media detection
  //
  if (!Snp->Mode->MediaPresentSupported) {
    return FALSE;
  }

  //
  // Invoke Snp->GetStatus() to refresh MediaPresent field in SNP mode data
  //
  Status = Snp->GetStatus (Snp, &InterruptStatus, NULL);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  Instance->MediaPresent = Snp->Mode->MediaPresent;
  //
  // Media transimit Unpresent to Present means new link movement is detected.
  //
  if (!MediaPresent && Instance->MediaPresent) {
    return TRUE;
  }
  return FALSE;
}


/**
  The timer routine of the Dhcp6 instance for each second.

  @param[in]  Event           The timer event.
  @param[in]  Context         The opaque parameter to the function.

**/
VOID
EFIAPI
Dhcp6OnTimerTick (
  IN EFI_EVENT              Event,
  IN VOID                   *Context
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *NextEntry;
  DHCP6_INSTANCE            *Instance;
  DHCP6_TX_CB               *TxCb;
  DHCP6_IA_CB               *IaCb;
  UINT32                    LossTime;
  EFI_STATUS                Status;

  ASSERT (Context != NULL);

  Instance = (DHCP6_INSTANCE *) Context;

  //
  // 1. Loop the tx list, count live time of every tx packet to check whether
  //    need re-transmit or not.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) {

    TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link);

    TxCb->TickTime++;

    if (TxCb->TickTime > TxCb->RetryExp) {
      //
      // Handle the first rt in the transmission of solicit specially.
      //
      if ((TxCb->RetryCnt == 0 || TxCb->SolicitRetry) && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {
        if (Instance->AdSelect == NULL) {
          //
          // Set adpref as 0xff here to indicate select any advertisement
          // afterwards.
          //
          Instance->AdPref = 0xff;
        } else {
          //
          // Select the advertisement received before.
          //
          Status = Dhcp6SelectAdvertiseMsg (Instance, Instance->AdSelect);
          if (Status == EFI_ABORTED) {
            goto ON_CLOSE;
          } else if (EFI_ERROR (Status)) {
            TxCb->RetryCnt++;
          }
          return;
        }
      }
      //
      // Increase the retry count for the packet and add up the total loss time.
      //
      TxCb->RetryCnt++;
      TxCb->RetryLos += TxCb->RetryExp;

      //
      // Check whether overflow the max retry count limit for this packet
      //
      if (TxCb->RetryCtl.Mrc != 0 && TxCb->RetryCtl.Mrc < TxCb->RetryCnt) {
        Status = EFI_NO_RESPONSE;
        goto ON_CLOSE;
      }

      //
      // Check whether overflow the max retry duration for this packet
      //
      if (TxCb->RetryCtl.Mrd != 0 && TxCb->RetryCtl.Mrd <= TxCb->RetryLos) {
        Status = EFI_NO_RESPONSE;
        goto ON_CLOSE;
      }

      //
      // Re-calculate retry expire timeout for the next time.
      //
      // Firstly, Check the new calculated time whether overflow the max retry
      // expire time.
      //
      TxCb->RetryExp = Dhcp6CalculateExpireTime (
                         TxCb->RetryExp,
                         FALSE,
                         TRUE
                         );

      if (TxCb->RetryCtl.Mrt != 0 && TxCb->RetryCtl.Mrt < TxCb->RetryExp) {
        TxCb->RetryExp = Dhcp6CalculateExpireTime (
                           TxCb->RetryCtl.Mrt,
                           TRUE,
                           TRUE
                           );
      }

      //
      // Secondly, Check the new calculated time whether overflow the max retry
      // duration time.
      //
      LossTime = TxCb->RetryLos + TxCb->RetryExp;
      if (TxCb->RetryCtl.Mrd != 0 && TxCb->RetryCtl.Mrd < LossTime) {
        TxCb->RetryExp = TxCb->RetryCtl.Mrd - TxCb->RetryLos;
      }

      //
      // Reset the tick time for the next retransmission
      //
      TxCb->TickTime = 0;

      //
      // Retransmit the last sent packet again.
      //
      Dhcp6TransmitPacket (Instance, TxCb->TxPacket, TxCb->Elapsed);
      TxCb->SolicitRetry = FALSE;
      if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {
        TxCb->SolicitRetry = TRUE;
      }
    }
  }

  //
  // 2. Check the configured Ia, count lease time of every valid Ia to check
  // whether need to renew or rebind this Ia.
  //
  IaCb = &Instance->IaCb;

  if (Instance->Config == NULL || IaCb->Ia == NULL) {
    return;
  }

  if (IaCb->Ia->State == Dhcp6Bound || IaCb->Ia->State == Dhcp6Renewing || IaCb->Ia->State == Dhcp6Rebinding) {

    IaCb->LeaseTime++;

    if (IaCb->LeaseTime > IaCb->T2 && IaCb->Ia->State == Dhcp6Bound) {
      //
      // Exceed t2, send rebind packet to extend the Ia lease.
      //
      Dhcp6SendRenewRebindMsg (Instance, TRUE);

    } else if (IaCb->LeaseTime > IaCb->T1 && IaCb->Ia->State == Dhcp6Bound) {

      //
      // Exceed t1, send renew packet to extend the Ia lease.
      //
      Dhcp6SendRenewRebindMsg (Instance, FALSE);
    }
  }

  //
  // 3. In any situation when a client may have moved to a new link, the
  //    client MUST initiate a Confirm/Reply message exchange.
  //
  if (Dhcp6LinkMovDetect (Instance) && (IaCb->Ia->State == Dhcp6Bound)) {
    Dhcp6SendConfirmMsg (Instance);
  }

  return;

 ON_CLOSE:

  if (Dhcp6IsValidTxCb (Instance, TxCb) &&
      TxCb->TxPacket != NULL &&
      (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest ||
      TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgRenew       ||
      TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm)
      ) {
    //
    // The failure of renew/Confirm will still switch to the bound state.
    //
    if ((TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgRenew) ||
        (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm)) {
      ASSERT (Instance->IaCb.Ia);
      Instance->IaCb.Ia->State = Dhcp6Bound;
    }
    //
    // The failure of info-request will return no response.
    //
    if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) {
      Instance->UdpSts = EFI_NO_RESPONSE;
    }
    Dhcp6DequeueRetry (
      Instance,
      TxCb->Xid,
      TRUE
      );
  } else {
    //
    // The failure of the others will terminate current state machine if timeout.
    //
    Dhcp6CleanupSession (Instance, Status);
  }
}
