X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FDhcp6Dxe%2FDhcp6Driver.c;h=de53a1a9b4125c6723af85e163a1dd669c28eb46;hb=b575ca32c8b05af5c23f46728ccf4937f2889ba8;hp=d14f169f07807b78664a698fdd5f23c628a2fa25;hpb=a3bcde70e6dc69000f85cc5deee98101d2ae200a;p=mirror_edk2.git diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c index d14f169f07..de53a1a9b4 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c @@ -2,7 +2,7 @@ Driver Binding functions and Service Binding functions implementationfor for Dhcp6 Driver. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = { Dhcp6ServiceBindingDestroyChild }; - /** Configure the default Udp6Io to receive all the DHCP6 traffic on this network interface. @@ -82,7 +81,7 @@ Dhcp6ConfigureUdpIo ( /** - Destory the Dhcp6 service. The Dhcp6 service may be partly initialized, + 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. @@ -95,7 +94,7 @@ Dhcp6DestroyService ( ) { // - // All children instances should have been already destoryed here. + // All children instances should have been already destroyed here. // ASSERT (Service->NumOfChild == 0); @@ -132,6 +131,7 @@ Dhcp6CreateService ( ) { DHCP6_SERVICE *Dhcp6Srv; + EFI_STATUS Status; *Service = NULL; Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE)); @@ -154,7 +154,6 @@ Dhcp6CreateService ( // Initialize the fields of the new Dhcp6 service. // Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE; - Dhcp6Srv->InDestory = FALSE; Dhcp6Srv->Controller = Controller; Dhcp6Srv->Image = ImageHandle; Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ())); @@ -166,7 +165,21 @@ Dhcp6CreateService ( ); // - // Generate client Duid in the format of Duid-llt. + // 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); @@ -279,7 +292,7 @@ Dhcp6CreateInstance ( Dhcp6Ins->Signature = DHCP6_INSTANCE_SIGNATURE; Dhcp6Ins->UdpSts = EFI_ALREADY_STARTED; Dhcp6Ins->Service = Service; - Dhcp6Ins->InDestory = FALSE; + Dhcp6Ins->InDestroy = FALSE; Dhcp6Ins->MediaPresent = TRUE; CopyMem ( @@ -313,6 +326,36 @@ Dhcp6CreateInstance ( 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. @@ -483,11 +526,11 @@ Dhcp6DriverBindingStop ( ) { EFI_STATUS Status; - EFI_TPL OldTpl; EFI_HANDLE NicHandle; EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; DHCP6_SERVICE *Service; - DHCP6_INSTANCE *Instance; + LIST_ENTRY *List; + UINTN ListLength; // // Find and check the Nic handle by the controller handle. @@ -495,7 +538,7 @@ Dhcp6DriverBindingStop ( NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -512,50 +555,44 @@ Dhcp6DriverBindingStop ( } Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding); - - if (Service->InDestory) { - return EFI_SUCCESS; + if (!IsListEmpty (&Service->Child)) { + // + // Destroy all the children instances before destory the service. + // + List = &Service->Child; + Status = NetDestroyLinkList ( + List, + Dhcp6DestroyChildEntry, + ServiceBinding, + &ListLength + ); + if (EFI_ERROR (Status) || ListLength != 0) { + Status = EFI_DEVICE_ERROR; + } } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) { + Status = EFI_DEVICE_ERROR; + } - if (NumberOfChildren == 0) { + if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) { // - // Destory the service itself if no child instance left. + // Destroy the service itself if no child instance left. // - Service->InDestory = TRUE; - Status = gBS->UninstallProtocolInterface ( NicHandle, &gEfiDhcp6ServiceBindingProtocolGuid, ServiceBinding ); - if (EFI_ERROR (Status)) { - Service->InDestory = FALSE; goto ON_EXIT; } Dhcp6DestroyService (Service); - - } else { - // - // Destory all the children instances before destory the service. - // - while (!IsListEmpty (&Service->Child)) { - Instance = NET_LIST_HEAD (&Service->Child, DHCP6_INSTANCE, Link); - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } - // - // Any of child failed to be destroyed. - // - if (Service->NumOfChild != 0) { - Status = EFI_DEVICE_ERROR; - } + Status = EFI_SUCCESS; } - + ON_EXIT: - gBS->RestoreTPL (OldTpl); return Status; } @@ -686,7 +723,7 @@ ON_ERROR: @retval EFI_SUCCES 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 not a valid UEFI Handle. + @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 @@ -732,13 +769,13 @@ Dhcp6ServiceBindingDestroyChild ( return EFI_INVALID_PARAMETER; } - if (Instance->InDestory) { + if (Instance->InDestroy) { return EFI_SUCCESS; } OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - Instance->InDestory = TRUE; + Instance->InDestroy = TRUE; Status = gBS->CloseProtocol ( Service->UdpIo->UdpHandle, @@ -748,7 +785,7 @@ Dhcp6ServiceBindingDestroyChild ( ); if (EFI_ERROR (Status)) { - Instance->InDestory = FALSE; + Instance->InDestroy = FALSE; gBS->RestoreTPL (OldTpl); return Status; } @@ -756,14 +793,15 @@ Dhcp6ServiceBindingDestroyChild ( // // 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->InDestory = FALSE; + Instance->InDestroy = FALSE; gBS->RestoreTPL (OldTpl); return Status; } @@ -774,9 +812,8 @@ Dhcp6ServiceBindingDestroyChild ( RemoveEntryList (&Instance->Link); Service->NumOfChild--; - Dhcp6DestroyInstance (Instance); - gBS->RestoreTPL (OldTpl); + Dhcp6DestroyInstance (Instance); return EFI_SUCCESS; }