/** @file\r
The implementation of common functions shared by IP6 driver.\r
\r
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
IpIf->AddressCount++;\r
}\r
\r
+/**\r
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+ \r
+ @param[in] Entry The entry to be removed.\r
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+ @retval EFI_SUCCESS The entry has been removed successfully.\r
+ @retval Others Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Ip6DestroyChildEntryByAddr (\r
+ IN LIST_ENTRY *Entry,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ IP6_PROTOCOL *Instance;\r
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
+ EFI_IPv6_ADDRESS *Address;\r
+ \r
+ Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
+ ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;\r
+ Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;\r
+\r
+ if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {\r
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Destroy the IP instance if its StationAddress is removed. It is the help function\r
for Ip6RemoveAddr().\r
IN EFI_IPv6_ADDRESS *Address\r
)\r
{\r
- BOOLEAN OneDestroyed;\r
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
- LIST_ENTRY *Entry;\r
- IP6_PROTOCOL *Instance;\r
+ LIST_ENTRY *List;\r
+ IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context;\r
\r
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);\r
\r
- ServiceBinding = &IpSb->ServiceBinding;\r
-\r
- //\r
- // Upper layer IP protocol consumers may have tight relationship between several\r
- // IP protocol instances, in other words, calling ServiceBinding->DestroyChild to\r
- // destroy one IP child may cause other related IP children destroyed too. This\r
- // will probably leave hole in the children list when we iterate it. So everytime\r
- // we just destroy one child then back to the start point to iterate the list.\r
- //\r
- do {\r
- OneDestroyed = FALSE;\r
-\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Children) {\r
- Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
-\r
- if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {\r
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
- OneDestroyed = TRUE;\r
- break;\r
- }\r
- }\r
- } while (OneDestroyed);\r
+ List = &IpSb->Children;\r
+ Context.ServiceBinding = &IpSb->ServiceBinding;\r
+ Context.Address = Address;\r
+ NetDestroyLinkList (\r
+ List,\r
+ Ip6DestroyChildEntryByAddr,\r
+ &Context,\r
+ NULL\r
+ );\r
}\r
\r
/**\r
return Mnp->McastIpToMac (Mnp, TRUE, &EfiIp, Mac);\r
}\r
\r
-/**\r
- Set the Ip6 variable data.\r
-\r
- @param[in] IpSb Points to an IP6 service binding instance.\r
-\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the variable.\r
- @retval other Set variable failed.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip6SetVariableData (\r
- IN IP6_SERVICE *IpSb\r
- )\r
-{\r
- UINT32 NumConfiguredInstance;\r
- LIST_ENTRY *Entry;\r
- UINTN VariableDataSize;\r
- EFI_IP6_VARIABLE_DATA *Ip6VariableData;\r
- EFI_IP6_ADDRESS_PAIR *Ip6AddressPair;\r
- IP6_PROTOCOL *IpInstance;\r
- CHAR16 *NewMacString;\r
- EFI_STATUS Status;\r
-\r
- NumConfiguredInstance = 0;\r
-\r
- //\r
- // Go through the children list to count the configured children.\r
- //\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Children) {\r
- IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
-\r
- if (IpInstance->State == IP6_STATE_CONFIGED) {\r
- NumConfiguredInstance++;\r
- }\r
- }\r
-\r
- //\r
- // Calculate the size of the Ip6VariableData. As there may be no IP child,\r
- // we should add extra buffer for the address paris only if the number of configured\r
- // children is more than 1.\r
- //\r
- VariableDataSize = sizeof (EFI_IP6_VARIABLE_DATA);\r
-\r
- if (NumConfiguredInstance > 1) {\r
- VariableDataSize += sizeof (EFI_IP6_ADDRESS_PAIR) * (NumConfiguredInstance - 1);\r
- }\r
-\r
- Ip6VariableData = AllocatePool (VariableDataSize);\r
- if (Ip6VariableData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ip6VariableData->DriverHandle = IpSb->Image;\r
- Ip6VariableData->AddressCount = NumConfiguredInstance;\r
-\r
- Ip6AddressPair = &Ip6VariableData->AddressPairs[0];\r
-\r
- //\r
- // Go through the children list to fill the configured children's address pairs.\r
- //\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Children) {\r
- IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
-\r
- if (IpInstance->State == IP6_STATE_CONFIGED) {\r
- Ip6AddressPair->InstanceHandle = IpInstance->Handle;\r
- Ip6AddressPair->PrefixLength = IpInstance->PrefixLength;\r
- IP6_COPY_ADDRESS (&Ip6AddressPair->Ip6Address, &IpInstance->ConfigData.StationAddress);\r
-\r
- Ip6AddressPair++;\r
- }\r
- }\r
-\r
- //\r
- // Get the mac string.\r
- //\r
- Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &NewMacString);\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
-\r
- if (IpSb->MacString != NULL) {\r
- //\r
- // The variable is set already, we're going to update it.\r
- //\r
- if (StrCmp (IpSb->MacString, NewMacString) != 0) {\r
- //\r
- // The mac address is changed, delete the previous variable first.\r
- //\r
- gRT->SetVariable (\r
- IpSb->MacString,\r
- &gEfiIp6ServiceBindingProtocolGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- 0,\r
- NULL\r
- );\r
- }\r
-\r
- FreePool (IpSb->MacString);\r
- }\r
-\r
- IpSb->MacString = NewMacString;\r
-\r
- Status = gRT->SetVariable (\r
- IpSb->MacString,\r
- &gEfiIp6ServiceBindingProtocolGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- VariableDataSize,\r
- (VOID *) Ip6VariableData\r
- );\r
-\r
-Exit:\r
- FreePool (Ip6VariableData);\r
- return Status;\r
-}\r
-\r
-/**\r
- Clear the variable and free the resource.\r
-\r
- @param[in] IpSb Ip6 service binding instance.\r
-\r
-**/\r
-VOID\r
-Ip6ClearVariableData (\r
- IN IP6_SERVICE *IpSb\r
- )\r
-{\r
- ASSERT (IpSb->MacString != NULL);\r
-\r
- gRT->SetVariable (\r
- IpSb->MacString,\r
- &gEfiIp6ServiceBindingProtocolGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
- 0,\r
- NULL\r
- );\r
-\r
- FreePool (IpSb->MacString);\r
- IpSb->MacString = NULL;\r
-}\r
-\r
/**\r
Convert the multibyte field in IP header's byter order.\r
In spite of its name, it can also be used to convert from\r