/** @file
  Driver Binding functions and Service Binding functions
  implementation for Dhcp6 Driver.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Dhcp6Impl.h"


EFI_DRIVER_BINDING_PROTOCOL gDhcp6DriverBinding = {
  Dhcp6DriverBindingSupported,
  Dhcp6DriverBindingStart,
  Dhcp6DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
  Dhcp6ServiceBindingCreateChild,
  Dhcp6ServiceBindingDestroyChild
};

/**
  Configure the default Udp6Io to receive all the DHCP6 traffic
  on this network interface.

  @param[in]  UdpIo                  The pointer to Udp6Io to be configured.
  @param[in]  Context                The pointer to the context.

  @retval EFI_SUCCESS            The Udp6Io is successfully configured.
  @retval Others                 Failed to configure the Udp6Io.

**/
EFI_STATUS
EFIAPI
Dhcp6ConfigureUdpIo (
  IN UDP_IO                 *UdpIo,
  IN VOID                   *Context
  )
{
  EFI_UDP6_PROTOCOL         *Udp6;
  EFI_UDP6_CONFIG_DATA      *Config;

  Udp6   = UdpIo->Protocol.Udp6;
  Config = &(UdpIo->Config.Udp6);

  ZeroMem (Config, sizeof (EFI_UDP6_CONFIG_DATA));

  //
  // Set Udp6 configure data for the Dhcp6 instance.
  //
  Config->AcceptPromiscuous  = FALSE;
  Config->AcceptAnyPort      = FALSE;
  Config->AllowDuplicatePort = FALSE;
  Config->TrafficClass       = 0;
  Config->HopLimit           = 128;
  Config->ReceiveTimeout     = 0;
  Config->TransmitTimeout    = 0;

  //
  // Configure an endpoint of client(0, 546), server(0, 0), the addresses
  // will be overridden later. Note that we MUST not limit RemotePort.
  // More details, refer to RFC 3315 section 5.2.
  //
  Config->StationPort        = DHCP6_PORT_CLIENT;
  Config->RemotePort         = 0;

  return Udp6->Configure (Udp6, Config);;
}


/**
  Destroy the Dhcp6 service. The Dhcp6 service may be partly initialized,
  or partly destroyed. If a resource is destroyed, it is marked as such in
  case the destroy failed and being called again later.

  @param[in, out]  Service       The pointer to Dhcp6 service to be destroyed.

**/
VOID
Dhcp6DestroyService (
  IN OUT DHCP6_SERVICE          *Service
  )
{
  //
  // All children instances should have been already destroyed here.
  //
  ASSERT (Service->NumOfChild == 0);

  if (Service->ClientId != NULL) {
    FreePool (Service->ClientId);
  }

  if (Service->UdpIo != NULL) {
    UdpIoFreeIo (Service->UdpIo);
  }

  FreePool (Service);
}


/**
  Create a new Dhcp6 service for the Nic controller.

  @param[in]  Controller             The controller to be installed DHCP6 service
                                     binding protocol.
  @param[in]  ImageHandle            The image handle of the Dhcp6 driver.
  @param[out] Service                The return pointer of the new Dhcp6 service.

  @retval EFI_SUCCESS            The Dhcp6 service is created successfully.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource.

**/
EFI_STATUS
Dhcp6CreateService (
  IN  EFI_HANDLE            Controller,
  IN  EFI_HANDLE            ImageHandle,
  OUT DHCP6_SERVICE         **Service
  )
{
  DHCP6_SERVICE             *Dhcp6Srv;
  EFI_STATUS                Status;

  *Service = NULL;
  Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));

  if (Dhcp6Srv == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Open the SNP protocol to get mode data later.
  //
  Dhcp6Srv->Snp = NULL;
  NetLibGetSnpHandle (Controller, &Dhcp6Srv->Snp);
  if (Dhcp6Srv->Snp == NULL) {
    FreePool (Dhcp6Srv);
    return EFI_DEVICE_ERROR;
  }

  //
  // Initialize the fields of the new Dhcp6 service.
  //
  Dhcp6Srv->Signature       = DHCP6_SERVICE_SIGNATURE;
  Dhcp6Srv->Controller      = Controller;
  Dhcp6Srv->Image           = ImageHandle;
  Dhcp6Srv->Xid             = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));

  CopyMem (
    &Dhcp6Srv->ServiceBinding,
    &gDhcp6ServiceBindingTemplate,
    sizeof (EFI_SERVICE_BINDING_PROTOCOL)
    );

  //
  // Locate Ip6->Ip6Config and store it for get IP6 Duplicate Address Detection transmits.
  //
  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiIp6ConfigProtocolGuid,
                  (VOID **) &Dhcp6Srv->Ip6Cfg
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Dhcp6Srv);
    return Status;
  }

  //
  // Generate client Duid: If SMBIOS system UUID is located, generate DUID in DUID-UUID format.
  // Otherwise, in DUID-LLT format.
  //
  Dhcp6Srv->ClientId        = Dhcp6GenerateClientId (Dhcp6Srv->Snp->Mode);

  if (Dhcp6Srv->ClientId == NULL) {
    FreePool (Dhcp6Srv);
    return EFI_DEVICE_ERROR;
  }

  //
  // Create an Udp6Io for stateful transmit/receive of each Dhcp6 instance.
  //
  Dhcp6Srv->UdpIo = UdpIoCreateIo (
                      Controller,
                      ImageHandle,
                      Dhcp6ConfigureUdpIo,
                      UDP_IO_UDP6_VERSION,
                      NULL
                      );

  if (Dhcp6Srv->UdpIo == NULL) {
    FreePool (Dhcp6Srv->ClientId);
    FreePool (Dhcp6Srv);
    return EFI_DEVICE_ERROR;
  }

  InitializeListHead (&Dhcp6Srv->Child);

  *Service = Dhcp6Srv;

  return EFI_SUCCESS;
}


/**
  Destroy the Dhcp6 instance and recycle the resources.

  @param[in, out]  Instance        The pointer to the Dhcp6 instance.

**/
VOID
Dhcp6DestroyInstance (
  IN OUT DHCP6_INSTANCE         *Instance
  )
{
  //
  // Clean up the retry list first.
  //
  Dhcp6CleanupRetry (Instance, DHCP6_PACKET_ALL);
  gBS->CloseEvent (Instance->Timer);

  //
  // Clean up the current configure data.
  //
  if (Instance->Config != NULL) {
    Dhcp6CleanupConfigData (Instance->Config);
    FreePool (Instance->Config);
  }

  //
  // Clean up the current Ia.
  //
  if (Instance->IaCb.Ia != NULL) {
    if (Instance->IaCb.Ia->ReplyPacket != NULL) {
      FreePool (Instance->IaCb.Ia->ReplyPacket);
    }
    FreePool (Instance->IaCb.Ia);
  }

  if (Instance->Unicast != NULL) {
    FreePool (Instance->Unicast);
  }

  if (Instance->AdSelect != NULL) {
    FreePool (Instance->AdSelect);
  }

  FreePool (Instance);
}


/**
  Create the Dhcp6 instance and initialize it.

  @param[in]  Service              The pointer to the Dhcp6 service.
  @param[out] Instance             The pointer to the Dhcp6 instance.

  @retval EFI_SUCCESS            The Dhcp6 instance is created.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.

**/
EFI_STATUS
Dhcp6CreateInstance (
  IN  DHCP6_SERVICE         *Service,
  OUT DHCP6_INSTANCE        **Instance
  )
{
  EFI_STATUS                Status;
  DHCP6_INSTANCE            *Dhcp6Ins;

  *Instance = NULL;
  Dhcp6Ins  = AllocateZeroPool (sizeof (DHCP6_INSTANCE));

  if (Dhcp6Ins == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize the fields of the new Dhcp6 instance.
  //
  Dhcp6Ins->Signature       = DHCP6_INSTANCE_SIGNATURE;
  Dhcp6Ins->UdpSts          = EFI_ALREADY_STARTED;
  Dhcp6Ins->Service         = Service;
  Dhcp6Ins->InDestroy       = FALSE;
  Dhcp6Ins->MediaPresent    = TRUE;

  CopyMem (
    &Dhcp6Ins->Dhcp6,
    &gDhcp6ProtocolTemplate,
    sizeof (EFI_DHCP6_PROTOCOL)
    );

  InitializeListHead (&Dhcp6Ins->TxList);
  InitializeListHead (&Dhcp6Ins->InfList);

  //
  // There is a timer for each Dhcp6 instance, which is used to track the
  // lease time of Ia and the retransmission time of all sent packets.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  Dhcp6OnTimerTick,
                  Dhcp6Ins,
                  &Dhcp6Ins->Timer
                  );

  if (EFI_ERROR (Status)) {
    FreePool (Dhcp6Ins);
    return Status;
  }

  *Instance = Dhcp6Ins;

  return EFI_SUCCESS;
}

/**
  Callback function which provided by user to remove one node in NetDestroyLinkList process.

  @param[in]    Entry           The entry to be removed.
  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.

  @retval EFI_SUCCESS           The entry has been removed successfully.
  @retval Others                Fail to remove the entry.

**/
EFI_STATUS
EFIAPI
Dhcp6DestroyChildEntry (
  IN LIST_ENTRY         *Entry,
  IN VOID               *Context
  )
{
  DHCP6_INSTANCE                   *Instance;
  EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;

  if (Entry == NULL || Context == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE);
  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;

  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}


/**
  Entry point of the DHCP6 driver to install various protocols.

  @param[in]  ImageHandle           The handle of the UEFI image file.
  @param[in]  SystemTable           The pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval Others                Unexpected error occurs.

**/
EFI_STATUS
EFIAPI
Dhcp6DriverEntryPoint (
  IN EFI_HANDLE                   ImageHandle,
  IN EFI_SYSTEM_TABLE             *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gDhcp6DriverBinding,
           ImageHandle,
           &gDhcp6ComponentName,
           &gDhcp6ComponentName2
           );
}


/**
  Test to see if this driver supports ControllerHandle. This service
  is called by the EFI boot service ConnectController(). In
  order to make drivers as small as possible, there are a few calling
  restrictions for this service. ConnectController() must
  follow these calling restrictions. If any other agent wishes to call
  Supported() it must also follow these calling restrictions.

  @param[in]  This                The pointer to the driver binding protocol.
  @param[in]  ControllerHandle    The handle of device to be tested.
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child
                                  device to be started.

  @retval EFI_SUCCESS         This driver supports this device.
  @retval Others              This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Dhcp6DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return gBS->OpenProtocol (
                ControllerHandle,
                &gEfiUdp6ServiceBindingProtocolGuid,
                NULL,
                This->DriverBindingHandle,
                ControllerHandle,
                EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                );
}


/**
  Start this driver on ControllerHandle. This service is called by the
  EFI boot service ConnectController(). In order to make
  drivers as small as possible, there are a few calling restrictions for
  this service. ConnectController() must follow these
  calling restrictions. If any other agent wishes to call Start() it
  must also follow these calling restrictions.

  @param[in]  This                 The pointer to the driver binding protocol.
  @param[in]  ControllerHandle     The handle of device to be started.
  @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child
                                   device to be started.

  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Dhcp6DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS                      Status;
  DHCP6_SERVICE                   *Service;

  //
  // Check the Dhcp6 service whether already started.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDhcp6ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Create and initialize the Dhcp6 service.
  //
  Status = Dhcp6CreateService (
             ControllerHandle,
             This->DriverBindingHandle,
             &Service
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Service != NULL);

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiDhcp6ServiceBindingProtocolGuid,
                  &Service->ServiceBinding,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    Dhcp6DestroyService (Service);
    return Status;
  }

  return EFI_SUCCESS;
}


/**
  Stop this driver on ControllerHandle. This service is called by the
  EFI boot service DisconnectController(). In order to
  make drivers as small as possible, there are a few calling
  restrictions for this service. DisconnectController()
  must follow these calling restrictions. If any other agent wishes
  to call Stop() it must also follow these calling restrictions.

  @param[in]  This              Protocol instance pointer.
  @param[in]  ControllerHandle  Handle of device to stop driver on
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                                children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS           This driver is removed ControllerHandle
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
  @retval other                 This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
Dhcp6DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer   OPTIONAL
  )
{
  EFI_STATUS                       Status;
  EFI_HANDLE                       NicHandle;
  EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;
  DHCP6_SERVICE                    *Service;
  LIST_ENTRY                       *List;
  UINTN                            ListLength;

  //
  // Find and check the Nic handle by the controller handle.
  //
  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);

  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiDhcp6ServiceBindingProtocolGuid,
                  (VOID **) &ServiceBinding,
                  This->DriverBindingHandle,
                  NicHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);
  if (!IsListEmpty (&Service->Child)) {
    //
    // Destroy all the children instances before destroy the service.
    //
    List = &Service->Child;
    Status = NetDestroyLinkList (
               List,
               Dhcp6DestroyChildEntry,
               ServiceBinding,
               &ListLength
               );
    if (EFI_ERROR (Status) || ListLength != 0) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {
    Status = EFI_DEVICE_ERROR;
  }

  if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {
    //
    // Destroy the service itself if no child instance left.
    //
    Status = gBS->UninstallProtocolInterface (
                    NicHandle,
                    &gEfiDhcp6ServiceBindingProtocolGuid,
                    ServiceBinding
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    Dhcp6DestroyService (Service);
    Status = EFI_SUCCESS;
  }

ON_EXIT:
  return Status;
}


/**
  Creates a child handle and installs a protocol.

  The CreateChild() function installs a protocol on ChildHandle.
  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.

  @param[in]      This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL,
                              then a new handle is created. If it is a pointer to an existing
                              UEFI handle, then the protocol is added to the existing UEFI handle.

  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval other                 The child handle was not created.

**/
EFI_STATUS
EFIAPI
Dhcp6ServiceBindingCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN OUT EFI_HANDLE                    *ChildHandle
  )
{
  EFI_STATUS                       Status;
  EFI_TPL                          OldTpl;
  DHCP6_SERVICE                    *Service;
  DHCP6_INSTANCE                   *Instance;
  VOID                             *Udp6;

  if (This == NULL || ChildHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Service = DHCP6_SERVICE_FROM_THIS (This);

  Status  = Dhcp6CreateInstance (Service, &Instance);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Instance != NULL);

  //
  // Start the timer when the instance is ready to use.
  //
  Status = gBS->SetTimer (
                  Instance->Timer,
                  TimerPeriodic,
                  TICKS_PER_SECOND
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Install the DHCP6 protocol onto ChildHandle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiDhcp6ProtocolGuid,
                  &Instance->Dhcp6,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Instance->Handle = *ChildHandle;

  //
  // Open the UDP6 protocol BY_CHILD.
  //
  Status = gBS->OpenProtocol (
                  Service->UdpIo->UdpHandle,
                  &gEfiUdp6ProtocolGuid,
                  (VOID **) &Udp6,
                  gDhcp6DriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );

  if (EFI_ERROR (Status)) {

    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiDhcp6ProtocolGuid,
           &Instance->Dhcp6,
           NULL
           );
    goto ON_ERROR;
  }

  //
  // Add into the children list of its parent service.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  InsertTailList (&Service->Child, &Instance->Link);
  Service->NumOfChild++;

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

ON_ERROR:

  Dhcp6DestroyInstance (Instance);
  return Status;
}


/**
  Destroys a child handle with a protocol installed on it.

  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
  last protocol on ChildHandle, then ChildHandle is destroyed.

  @param[in]  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param[in]  ChildHandle Handle of the child to destroy

  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
  @retval EFI_INVALID_PARAMETER Child handle is NULL.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
                                because its services are being used.
  @retval other                 The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
Dhcp6ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
{
  EFI_STATUS                       Status;
  EFI_TPL                          OldTpl;
  EFI_DHCP6_PROTOCOL               *Dhcp6;
  DHCP6_SERVICE                    *Service;
  DHCP6_INSTANCE                   *Instance;

  if (This == NULL || ChildHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Retrieve the private context data structures
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiDhcp6ProtocolGuid,
                  (VOID **) &Dhcp6,
                  gDhcp6DriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Instance = DHCP6_INSTANCE_FROM_THIS (Dhcp6);
  Service  = DHCP6_SERVICE_FROM_THIS (This);

  if (Instance->Service != Service) {
    return EFI_INVALID_PARAMETER;
  }

  if (Instance->InDestroy) {
    return EFI_SUCCESS;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance->InDestroy = TRUE;

  Status = gBS->CloseProtocol (
                  Service->UdpIo->UdpHandle,
                  &gEfiUdp6ProtocolGuid,
                  gDhcp6DriverBinding.DriverBindingHandle,
                  ChildHandle
                  );

  if (EFI_ERROR (Status)) {
    Instance->InDestroy = FALSE;
    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  //
  // Uninstall the MTFTP6 protocol first to enable a top down destruction.
  //
  gBS->RestoreTPL (OldTpl);
  Status = gBS->UninstallProtocolInterface (
                  ChildHandle,
                  &gEfiDhcp6ProtocolGuid,
                  Dhcp6
                  );
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  if (EFI_ERROR (Status)) {
    Instance->InDestroy = FALSE;
    gBS->RestoreTPL (OldTpl);
    return Status;
  }

  //
  // Remove it from the children list of its parent service.
  //
  RemoveEntryList (&Instance->Link);
  Service->NumOfChild--;

  gBS->RestoreTPL (OldTpl);

  Dhcp6DestroyInstance (Instance);
  return EFI_SUCCESS;
}
