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;
}