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