UEFI Spec 2.7 adds the clarification on SetData interface usage to clear specific
individual data types. This patch is to support this feature.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 692 ++++++++++++++++++++++----------------
1 file changed, 399 insertions(+), 293 deletions(-)
diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
index 7c7acc7..9e9dc89 100644
--- a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
+++ b/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c
@@ -917,254 +917,333 @@ Ip6ConfigSetManualAddress (
LIST_ENTRY *Entry2;
IP6_INTERFACE *IpIf;
IP6_PREFIX_LIST_ENTRY *PrefixEntry;
EFI_STATUS Status;
BOOLEAN IsUpdated;
+ LIST_ENTRY *Next;
+ IP6_DAD_ENTRY *DadEntry;
+ IP6_DELAY_JOIN_LIST *DelayNode;
+
+ NewAddress = NULL;
+ TmpAddress = NULL;
+ CurrentAddrInfo = NULL;
+ Copy = NULL;
+ Entry = NULL;
+ Entry2 = NULL;
+ IpIf = NULL;
+ PrefixEntry = NULL;
+ Next = NULL;
+ DadEntry = NULL;
+ DelayNode = NULL;
+ Status = EFI_SUCCESS;
ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status != EFI_NOT_READY);
- if (((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {
+ if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0)) {
return EFI_BAD_BUFFER_SIZE;
}
if (Instance->Policy != Ip6ConfigPolicyManual) {
return EFI_WRITE_PROTECTED;
}
- NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
- NewAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data;
+ IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
- for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
+ DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
- if (NetIp6IsLinkLocalAddr (&NewAddress->Address) ||
- !NetIp6IsValidUnicast (&NewAddress->Address) ||
- (NewAddress->PrefixLength > 128)
- ) {
- //
- // make sure the IPv6 address is unicast and not link-local address &&
- // the prefix length is valid.
- //
- return EFI_INVALID_PARAMETER;
- }
+ if (Data != NULL && DataSize != 0) {
+ NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
+ NewAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data;
- TmpAddress = NewAddress + 1;
- for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) {
- //
- // Any two addresses in the array can't be equal.
- //
- if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) {
+ for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
+ if (NetIp6IsLinkLocalAddr (&NewAddress->Address) ||
+ !NetIp6IsValidUnicast (&NewAddress->Address) ||
+ (NewAddress->PrefixLength > 128)
+ ) {
+ //
+ // make sure the IPv6 address is unicast and not link-local address &&
+ // the prefix length is valid.
+ //
return EFI_INVALID_PARAMETER;
}
+
+ TmpAddress = NewAddress + 1;
+ for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) {
+ //
+ // Any two addresses in the array can't be equal.
+ //
+ if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+ }
}
- }
- IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
+ //
+ // Build the current source address list.
+ //
+ InitializeListHead (&CurrentSourceList);
+ CurrentSourceCount = 0;
- //
- // Build the current source address list.
- //
- InitializeListHead (&CurrentSourceList);
- CurrentSourceCount = 0;
+ NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
+ IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
- NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
- IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
+ NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
+ CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
- NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
- CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
+ Copy = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo);
+ if (Copy == NULL) {
+ break;
+ }
- Copy = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo);
- if (Copy == NULL) {
- break;
+ InsertTailList (&CurrentSourceList, &Copy->Link);
+ CurrentSourceCount++;
}
+ }
+
+ //
+ // Update the value... a long journey starts
+ //
+ NewAddress = AllocateCopyPool (DataSize, Data);
+ if (NewAddress == NULL) {
+ Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0);
- InsertTailList (&CurrentSourceList, &Copy->Link);
- CurrentSourceCount++;
+ return EFI_OUT_OF_RESOURCES;
}
- }
- //
- // Update the value... a long journey starts
- //
- NewAddress = AllocateCopyPool (DataSize, Data);
- if (NewAddress == NULL) {
- Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0);
+ //
+ // Store the new data, and init the DataItem status to EFI_NOT_READY because
+ // we may have an asynchronous configuration process.
+ //
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NewAddress;
+ DataItem->DataSize = DataSize;
+ DataItem->Status = EFI_NOT_READY;
- return EFI_OUT_OF_RESOURCES;
- }
+ //
+ // Trigger DAD, it's an asynchronous process.
+ //
+ IsUpdated = FALSE;
- //
- // Store the new data, and init the DataItem status to EFI_NOT_READY because
- // we may have an asynchronous configuration process.
- //
- DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress];
- if (DataItem->Data.Ptr != NULL) {
- FreePool (DataItem->Data.Ptr);
- }
- DataItem->Data.Ptr = NewAddress;
- DataItem->DataSize = DataSize;
- DataItem->Status = EFI_NOT_READY;
+ for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
+ if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) {
+ ASSERT (CurrentAddrInfo != NULL);
+ //
+ // Remove this already existing source address from the CurrentSourceList
+ // built before.
+ //
+ Ip6RemoveAddr (
+ NULL,
+ &CurrentSourceList,
+ &CurrentSourceCount,
+ &CurrentAddrInfo->Address,
+ 128
+ );
- //
- // Trigger DAD, it's an asynchronous process.
- //
- IsUpdated = FALSE;
+ //
+ // If the new address's prefix length is not specified, just use the previous configured
+ // prefix length for this address.
+ //
+ if (NewAddress->PrefixLength == 0) {
+ NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength;
+ }
- for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) {
- if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) {
- ASSERT (CurrentAddrInfo != NULL);
- //
- // Remove this already existing source address from the CurrentSourceList
- // built before.
- //
- Ip6RemoveAddr (
- NULL,
- &CurrentSourceList,
- &CurrentSourceCount,
- &CurrentAddrInfo->Address,
- 128
- );
+ //
+ // This manual address is already in use, see whether prefix length is changed.
+ //
+ if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) {
+ //
+ // Remove the on-link prefix table, the route entry will be removed
+ // implicitly.
+ //
+ PrefixEntry = Ip6FindPrefixListEntry (
+ IpSb,
+ TRUE,
+ CurrentAddrInfo->PrefixLength,
+ &CurrentAddrInfo->Address
+ );
+ if (PrefixEntry != NULL) {
+ Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
+ }
- //
- // If the new address's prefix length is not specified, just use the previous configured
- // prefix length for this address.
- //
- if (NewAddress->PrefixLength == 0) {
- NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength;
- }
+ //
+ // Save the prefix length.
+ //
+ CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength;
+ IsUpdated = TRUE;
+ }
- //
- // This manual address is already in use, see whether prefix length is changed.
- //
- if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) {
//
- // Remove the on-link prefix table, the route entry will be removed
- // implicitly.
+ // create a new on-link prefix entry.
//
PrefixEntry = Ip6FindPrefixListEntry (
IpSb,
TRUE,
- CurrentAddrInfo->PrefixLength,
- &CurrentAddrInfo->Address
+ NewAddress->PrefixLength,
+ &NewAddress->Address
);
- if (PrefixEntry != NULL) {
- Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
+ if (PrefixEntry == NULL) {
+ Ip6CreatePrefixListEntry (
+ IpSb,
+ TRUE,
+ (UINT32) IP6_INFINIT_LIFETIME,
+ (UINT32) IP6_INFINIT_LIFETIME,
+ NewAddress->PrefixLength,
+ &NewAddress->Address
+ );
}
+ CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast;
//
- // Save the prefix length.
+ // Artificially mark this address passed DAD be'coz it is already in use.
+ //
+ Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance);
+ } else {
+ //
+ // A new address.
//
- CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength;
IsUpdated = TRUE;
+
+ //
+ // Set the new address, this will trigger DAD and activate the address if
+ // DAD succeeds.
+ //
+ Ip6SetAddress (
+ IpSb->DefaultInterface,
+ &NewAddress->Address,
+ NewAddress->IsAnycast,
+ NewAddress->PrefixLength,
+ (UINT32) IP6_INFINIT_LIFETIME,
+ (UINT32) IP6_INFINIT_LIFETIME,
+ Ip6ManualAddrDadCallback,
+ Instance
+ );
}
+ }
+
+ //
+ // Check the CurrentSourceList, it now contains those addresses currently in
+ // use and will be removed.
+ //
+ IpIf = IpSb->DefaultInterface;
+
+ while (!IsListEmpty (&CurrentSourceList)) {
+ IsUpdated = TRUE;
+
+ CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link);
//
- // create a new on-link prefix entry.
+ // This local address is going to be removed, the IP instances that are
+ // currently using it will be destroyed.
+ //
+ Ip6RemoveAddr (
+ IpSb,
+ &IpIf->AddressList,
+ &IpIf->AddressCount,
+ &CurrentAddrInfo->Address,
+ 128
+ );
+
+ //
+ // Remove the on-link prefix table, the route entry will be removed
+ // implicitly.
//
PrefixEntry = Ip6FindPrefixListEntry (
IpSb,
TRUE,
- NewAddress->PrefixLength,
- &NewAddress->Address
+ CurrentAddrInfo->PrefixLength,
+ &CurrentAddrInfo->Address
);
- if (PrefixEntry == NULL) {
- Ip6CreatePrefixListEntry (
- IpSb,
- TRUE,
- (UINT32) IP6_INFINIT_LIFETIME,
- (UINT32) IP6_INFINIT_LIFETIME,
- NewAddress->PrefixLength,
- &NewAddress->Address
- );
+ if (PrefixEntry != NULL) {
+ Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
}
- CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast;
- //
- // Artificially mark this address passed DAD be'coz it is already in use.
- //
- Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance);
+ RemoveEntryList (&CurrentAddrInfo->Link);
+ FreePool (CurrentAddrInfo);
+ }
+
+ if (IsUpdated) {
+ if (DataItem->Status == EFI_NOT_READY) {
+ //
+ // If DAD is disabled on this interface, the configuration process is
+ // actually synchronous, and the data item's status will be changed to
+ // the final status before we reach here, just check it.
+ //
+ Status = EFI_NOT_READY;
+ } else {
+ Status = EFI_SUCCESS;
+ }
} else {
//
- // A new address.
+ // No update is taken, reset the status to success and return EFI_ABORTED.
//
- IsUpdated = TRUE;
+ DataItem->Status = EFI_SUCCESS;
+ Status = EFI_ABORTED;
+ }
+ } else {
+ //
+ // DataSize is 0 and Data is NULL, clean up the manual address.
+ //
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
- //
- // Set the new address, this will trigger DAD and activate the address if
- // DAD succeeds.
- //
- Ip6SetAddress (
- IpSb->DefaultInterface,
- &NewAddress->Address,
- NewAddress->IsAnycast,
- NewAddress->PrefixLength,
+ Ip6CleanDefaultRouterList (IpSb);
+ Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix);
+ Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix);
+ Ip6CleanAssembleTable (&IpSb->Assemble);
+
+ if (IpSb->LinkLocalOk) {
+ Ip6CreatePrefixListEntry (
+ IpSb,
+ TRUE,
(UINT32) IP6_INFINIT_LIFETIME,
(UINT32) IP6_INFINIT_LIFETIME,
- Ip6ManualAddrDadCallback,
- Instance
+ IP6_LINK_LOCAL_PREFIX_LENGTH,
+ &IpSb->LinkLocalAddr
);
}
- }
- //
- // Check the CurrentSourceList, it now contains those addresses currently in
- // use and will be removed.
- //
- IpIf = IpSb->DefaultInterface;
-
- while (!IsListEmpty (&CurrentSourceList)) {
- IsUpdated = TRUE;
-
- CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link);
-
- //
- // This local address is going to be removed, the IP instances that are
- // currently using it will be destroyed.
- //
Ip6RemoveAddr (
IpSb,
- &IpIf->AddressList,
- &IpIf->AddressCount,
- &CurrentAddrInfo->Address,
- 128
+ &IpSb->DefaultInterface->AddressList,
+ &IpSb->DefaultInterface->AddressCount,
+ NULL,
+ 0
);
- //
- // Remove the on-link prefix table, the route entry will be removed
- // implicitly.
- //
- PrefixEntry = Ip6FindPrefixListEntry (
- IpSb,
- TRUE,
- CurrentAddrInfo->PrefixLength,
- &CurrentAddrInfo->Address
- );
- if (PrefixEntry != NULL) {
- Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE);
- }
-
- RemoveEntryList (&CurrentAddrInfo->Link);
- FreePool (CurrentAddrInfo);
- }
-
- if (IsUpdated) {
- if (DataItem->Status == EFI_NOT_READY) {
+ NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
//
- // If DAD is disabled on this interface, the configuration process is
- // actually synchronous, and the data item's status will be changed to
- // the final status before we reach here, just check it.
+ // Remove all pending delay node and DAD entries for the global addresses.
//
- Status = EFI_NOT_READY;
- } else {
- Status = EFI_SUCCESS;
+ IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
+
+ NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) {
+ DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link);
+ if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) {
+ RemoveEntryList (&DelayNode->Link);
+ FreePool (DelayNode);
+ }
+ }
+
+ NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) {
+ DadEntry = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE);
+
+ if (!NetIp6IsLinkLocalAddr (&DadEntry->AddressInfo->Address)) {
+ //
+ // Fail this DAD entry if the address is not link-local.
+ //
+ Ip6OnDADFinished (FALSE, IpIf, DadEntry);
+ }
+ }
}
- } else {
- //
- // No update is taken, reset the status to success and return EFI_ABORTED.
- //
- DataItem->Status = EFI_SUCCESS;
- Status = EFI_ABORTED;
}
return Status;
}
@@ -1208,98 +1287,107 @@ Ip6ConfigSetGateway (
BOOLEAN OneAdded;
IP6_SERVICE *IpSb;
IP6_DEFAULT_ROUTER *DefaultRouter;
VOID *Tmp;
- if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
+ OldGateway = NULL;
+ NewGateway = NULL;
+ Item = NULL;
+ DefaultRouter = NULL;
+ Tmp = NULL;
+ OneRemoved = FALSE;
+ OneAdded = FALSE;
+
+ if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
return EFI_BAD_BUFFER_SIZE;
}
if (Instance->Policy != Ip6ConfigPolicyManual) {
return EFI_WRITE_PROTECTED;
}
- NewGateway = (EFI_IPv6_ADDRESS *) Data;
- NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
- for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
-
- if (!NetIp6IsValidUnicast (NewGateway + Index1)) {
-
- return EFI_INVALID_PARAMETER;
- }
-
- for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
- if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
- return EFI_INVALID_PARAMETER;
- }
- }
- }
-
IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
Item = &Instance->DataItem[Ip6ConfigDataTypeGateway];
OldGateway = Item->Data.Gateway;
OldGatewayCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
- OneRemoved = FALSE;
- OneAdded = FALSE;
-
- if (NewGatewayCount != OldGatewayCount) {
- Tmp = AllocatePool (DataSize);
- if (Tmp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- Tmp = NULL;
- }
for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
//
- // Find the gateways that are no long in the new setting and remove them.
+ // Remove this default router.
//
- for (Index2 = 0; Index2 < NewGatewayCount; Index2++) {
- if (EFI_IP6_EQUAL (OldGateway + Index1, NewGateway + Index2)) {
- OneRemoved = TRUE;
- break;
+ DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
+ if (DefaultRouter != NULL) {
+ Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
+ OneRemoved = TRUE;
+ }
+ }
+
+ if (Data != NULL && DataSize != 0) {
+ NewGateway = (EFI_IPv6_ADDRESS *) Data;
+ NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+
+ if (!NetIp6IsValidUnicast (NewGateway + Index1)) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
+ if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
+ return EFI_INVALID_PARAMETER;
+ }
}
}
- if (Index2 == NewGatewayCount) {
- //
- // Remove this default router.
- //
- DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1);
- if (DefaultRouter != NULL) {
- Ip6DestroyDefaultRouter (IpSb, DefaultRouter);
+ if (NewGatewayCount != OldGatewayCount) {
+ Tmp = AllocatePool (DataSize);
+ if (Tmp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
+ } else {
+ Tmp = NULL;
}
- }
- for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
- DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1);
- if (DefaultRouter == NULL) {
- Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME);
- OneAdded = TRUE;
+ DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1);
+ if (DefaultRouter == NULL) {
+ Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME);
+ OneAdded = TRUE;
+ }
}
- }
- if (!OneRemoved && !OneAdded) {
- Item->Status = EFI_SUCCESS;
- return EFI_ABORTED;
- } else {
+ if (!OneRemoved && !OneAdded) {
+ Item->Status = EFI_SUCCESS;
+ return EFI_ABORTED;
+ } else {
- if (Tmp != NULL) {
- if (Item->Data.Ptr != NULL) {
- FreePool (Item->Data.Ptr);
+ if (Tmp != NULL) {
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
+ }
+ Item->Data.Ptr = Tmp;
}
- Item->Data.Ptr = Tmp;
- }
- CopyMem (Item->Data.Ptr, Data, DataSize);
- Item->DataSize = DataSize;
- Item->Status = EFI_SUCCESS;
- return EFI_SUCCESS;
+ CopyMem (Item->Data.Ptr, Data, DataSize);
+ Item->DataSize = DataSize;
+ Item->Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+ }
+ } else {
+ //
+ // DataSize is 0 and Data is NULL, clean up the Gateway address.
+ //
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
+ }
+ Item->Data.Ptr = NULL;
+ Item->DataSize = 0;
+ Item->Status = EFI_NOT_FOUND;
}
+
+ return EFI_SUCCESS;
}
/**
The work function for EfiIp6ConfigSetData() to set the DNS server list for the
EFI IPv6 network stack running on the communication device that this EFI IPv6
@@ -1337,87 +1425,106 @@ Ip6ConfigSetDnsServer (
UINTN NewDnsCount;
IP6_CONFIG_DATA_ITEM *Item;
BOOLEAN OneAdded;
VOID *Tmp;
- if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) {
+ OldDns = NULL;
+ NewDns = NULL;
+ Item = NULL;
+ Tmp = NULL;
+
+ if ((DataSize == 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) != 0)) {
return EFI_BAD_BUFFER_SIZE;
}
if (Instance->Policy != Ip6ConfigPolicyManual) {
return EFI_WRITE_PROTECTED;
}
- Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
- NewDns = (EFI_IPv6_ADDRESS *) Data;
- OldDns = Item->Data.DnsServers;
- NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
- OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
- OneAdded = FALSE;
+ Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer];
- if (NewDnsCount != OldDnsCount) {
- Tmp = AllocatePool (DataSize);
- if (Tmp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- Tmp = NULL;
- }
+ if (Data != NULL && DataSize != 0) {
+ NewDns = (EFI_IPv6_ADDRESS *) Data;
+ OldDns = Item->Data.DnsServers;
+ NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
+ OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS);
+ OneAdded = FALSE;
- for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
-
- if (!NetIp6IsValidUnicast (NewDns + NewIndex)) {
- //
- // The dns server address must be unicast.
- //
- if (Tmp != NULL) {
- FreePool (Tmp);
+ if (NewDnsCount != OldDnsCount) {
+ Tmp = AllocatePool (DataSize);
+ if (Tmp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- return EFI_INVALID_PARAMETER;
+ } else {
+ Tmp = NULL;
}
- if (OneAdded) {
- //
- // If any address in the new setting is not in the old settings, skip the
- // comparision below.
- //
- continue;
- }
+ for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
- for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
- if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+ if (!NetIp6IsValidUnicast (NewDns + NewIndex)) {
//
- // If found break out.
+ // The dns server address must be unicast.
//
- break;
+ if (Tmp != NULL) {
+ FreePool (Tmp);
+ }
+ return EFI_INVALID_PARAMETER;
}
- }
- if (OldIndex == OldDnsCount) {
- OneAdded = TRUE;
+ if (OneAdded) {
+ //
+ // If any address in the new setting is not in the old settings, skip the
+ // comparision below.
+ //
+ continue;
+ }
+
+ for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
+ if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+ //
+ // If found break out.
+ //
+ break;
+ }
+ }
+
+ if (OldIndex == OldDnsCount) {
+ OneAdded = TRUE;
+ }
}
- }
- if (!OneAdded && (DataSize == Item->DataSize)) {
+ if (!OneAdded && (DataSize == Item->DataSize)) {
+ //
+ // No new item is added and the size is the same.
+ //
+ Item->Status = EFI_SUCCESS;
+ return EFI_ABORTED;
+ } else {
+ if (Tmp != NULL) {
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
+ }
+ Item->Data.Ptr = Tmp;
+ }
+
+ CopyMem (Item->Data.Ptr, Data, DataSize);
+ Item->DataSize = DataSize;
+ Item->Status = EFI_SUCCESS;
+ }
+ } else {
//
- // No new item is added and the size is the same.
+ // DataSize is 0 and Data is NULL, clean up the DnsServer address.
//
- Item->Status = EFI_SUCCESS;
- return EFI_ABORTED;
- } else {
- if (Tmp != NULL) {
- if (Item->Data.Ptr != NULL) {
- FreePool (Item->Data.Ptr);
- }
- Item->Data.Ptr = Tmp;
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
}
-
- CopyMem (Item->Data.Ptr, Data, DataSize);
- Item->DataSize = DataSize;
- Item->Status = EFI_SUCCESS;
- return EFI_SUCCESS;
+ Item->Data.Ptr = NULL;
+ Item->DataSize = 0;
+ Item->Status = EFI_NOT_FOUND;
}
+
+ return EFI_SUCCESS;
}
/**
Generate the operational state of the interface this IP6 config instance manages
and output in EFI_IP6_CONFIG_INTERFACE_INFO.
@@ -1822,13 +1929,12 @@ Ip6ConfigOnDhcp6SbInstalled (
@retval EFI_SUCCESS The specified configuration data for the EFI IPv6
network stack was set successfully.
@retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
- This is NULL.
- - Data is NULL.
- - One or more fields in Data do not match the requirement of the
- data type indicated by DataType.
+ - One or more fields in Data and DataSizedo not match the
+ requirement of the data type indicated by DataType.
@retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified
configuration data cannot be set under the current policy.
@retval EFI_ACCESS_DENIED Another set operation on the specified configuration
data is already in process.
@retval EFI_NOT_READY An asynchronous process was invoked to set the specified
@@ -1852,11 +1958,11 @@ EfiIp6ConfigSetData (
EFI_TPL OldTpl;
EFI_STATUS Status;
IP6_CONFIG_INSTANCE *Instance;
IP6_SERVICE *IpSb;
- if ((This == NULL) || (Data == NULL)) {
+ if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) {
return EFI_INVALID_PARAMETER;
}
if (DataType >= Ip6ConfigDataTypeMaximum) {
return EFI_UNSUPPORTED;
--
1.9.5.msysgit.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.