From nobody Fri Dec 27 17:24:37 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1501050528194564.3108409424441; Tue, 25 Jul 2017 23:28:48 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0DBF321D0DE74; Tue, 25 Jul 2017 23:26:41 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0013221C91278 for ; Tue, 25 Jul 2017 23:26:38 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP; 25 Jul 2017 23:28:41 -0700 Received: from jiaxinwu-mobl2.ccr.corp.intel.com ([10.239.196.131]) by orsmga003.jf.intel.com with ESMTP; 25 Jul 2017 23:28:39 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,413,1496127600"; d="scan'208";a="997280375" From: Jiaxin Wu To: edk2-devel@lists.01.org Date: Wed, 26 Jul 2017 14:28:31 +0800 Message-Id: <1501050511-16884-4-git-send-email-jiaxin.wu@intel.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1501050511-16884-1-git-send-email-jiaxin.wu@intel.com> References: <1501050511-16884-1-git-send-email-jiaxin.wu@intel.com> Subject: [edk2] [Patch 3/3] NetworkPkg/Ip6Dxe: Support SetData interface to clear specific configuration X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ye Ting , Fu Siyuan , Wu Jiaxin MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" UEFI Spec 2.7 adds the clarification on SetData interface usage to clear sp= ecific individual data types. This patch is to support this feature. Cc: Ye Ting Cc: Fu Siyuan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Wu Jiaxin --- NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 692 ++++++++++++++++++++++------------= ---- 1 file changed, 399 insertions(+), 293 deletions(-) diff --git a/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/NetworkPkg/Ip6Dxe/Ip6Confi= gImpl.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 =3D NULL; + TmpAddress =3D NULL; + CurrentAddrInfo =3D NULL; + Copy =3D NULL; + Entry =3D NULL; + Entry2 =3D NULL; + IpIf =3D NULL; + PrefixEntry =3D NULL; + Next =3D NULL; + DadEntry =3D NULL; + DelayNode =3D NULL; + Status =3D EFI_SUCCESS; =20 ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status !=3D E= FI_NOT_READY); =20 - if (((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) !=3D 0) || (Dat= aSize =3D=3D 0)) { + if ((DataSize !=3D 0) && ((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDR= ESS)) !=3D 0)) { return EFI_BAD_BUFFER_SIZE; } =20 if (Instance->Policy !=3D Ip6ConfigPolicyManual) { return EFI_WRITE_PROTECTED; } =20 - NewAddressCount =3D DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); - NewAddress =3D (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data; + IpSb =3D IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); =20 - for (Index1 =3D 0; Index1 < NewAddressCount; Index1++, NewAddress++) { + DataItem =3D &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; =20 - 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 !=3D NULL && DataSize !=3D 0) { + NewAddressCount =3D DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); + NewAddress =3D (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data; =20 - TmpAddress =3D NewAddress + 1; - for (Index2 =3D Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAdd= ress++) { - // - // Any two addresses in the array can't be equal. - // - if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) { + for (Index1 =3D 0; Index1 < NewAddressCount; Index1++, NewAddress++) { =20 + if (NetIp6IsLinkLocalAddr (&NewAddress->Address) || + !NetIp6IsValidUnicast (&NewAddress->Address) || + (NewAddress->PrefixLength > 128) + ) { + // + // make sure the IPv6 address is unicast and not link-local addres= s && + // the prefix length is valid. + // return EFI_INVALID_PARAMETER; } + + TmpAddress =3D NewAddress + 1; + for (Index2 =3D Index1 + 1; Index2 < NewAddressCount; Index2++, TmpA= ddress++) { + // + // Any two addresses in the array can't be equal. + // + if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) { + + return EFI_INVALID_PARAMETER; + } + } } - } =20 - IpSb =3D IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); + // + // Build the current source address list. + // + InitializeListHead (&CurrentSourceList); + CurrentSourceCount =3D 0; =20 - // - // Build the current source address list. - // - InitializeListHead (&CurrentSourceList); - CurrentSourceCount =3D 0; + NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { + IpIf =3D NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INT= ERFACE_SIGNATURE); =20 - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf =3D NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTER= FACE_SIGNATURE); + NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) { + CurrentAddrInfo =3D NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_IN= FO, Link, IP6_ADDR_INFO_SIGNATURE); =20 - NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) { - CurrentAddrInfo =3D NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO= , Link, IP6_ADDR_INFO_SIGNATURE); + Copy =3D AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), C= urrentAddrInfo); + if (Copy =3D=3D NULL) { + break; + } =20 - Copy =3D AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), Cur= rentAddrInfo); - if (Copy =3D=3D NULL) { - break; + InsertTailList (&CurrentSourceList, &Copy->Link); + CurrentSourceCount++; } + } + + // + // Update the value... a long journey starts + // + NewAddress =3D AllocateCopyPool (DataSize, Data); + if (NewAddress =3D=3D NULL) { + Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, = 0); =20 - InsertTailList (&CurrentSourceList, &Copy->Link); - CurrentSourceCount++; + return EFI_OUT_OF_RESOURCES; } - } =20 - // - // Update the value... a long journey starts - // - NewAddress =3D AllocateCopyPool (DataSize, Data); - if (NewAddress =3D=3D NULL) { - Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0); + // + // Store the new data, and init the DataItem status to EFI_NOT_READY b= ecause + // we may have an asynchronous configuration process. + // + if (DataItem->Data.Ptr !=3D NULL) { + FreePool (DataItem->Data.Ptr); + } + DataItem->Data.Ptr =3D NewAddress; + DataItem->DataSize =3D DataSize; + DataItem->Status =3D EFI_NOT_READY; =20 - return EFI_OUT_OF_RESOURCES; - } + // + // Trigger DAD, it's an asynchronous process. + // + IsUpdated =3D FALSE; =20 - // - // Store the new data, and init the DataItem status to EFI_NOT_READY bec= ause - // we may have an asynchronous configuration process. - // - DataItem =3D &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; - if (DataItem->Data.Ptr !=3D NULL) { - FreePool (DataItem->Data.Ptr); - } - DataItem->Data.Ptr =3D NewAddress; - DataItem->DataSize =3D DataSize; - DataItem->Status =3D EFI_NOT_READY; + for (Index1 =3D 0; Index1 < NewAddressCount; Index1++, NewAddress++) { + if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &Current= AddrInfo)) { + ASSERT (CurrentAddrInfo !=3D NULL); + // + // Remove this already existing source address from the CurrentSou= rceList + // built before. + // + Ip6RemoveAddr ( + NULL, + &CurrentSourceList, + &CurrentSourceCount, + &CurrentAddrInfo->Address, + 128 + ); =20 - // - // Trigger DAD, it's an asynchronous process. - // - IsUpdated =3D FALSE; + // + // If the new address's prefix length is not specified, just use t= he previous configured + // prefix length for this address. + // + if (NewAddress->PrefixLength =3D=3D 0) { + NewAddress->PrefixLength =3D CurrentAddrInfo->PrefixLength; + } =20 - for (Index1 =3D 0; Index1 < NewAddressCount; Index1++, NewAddress++) { - if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAd= drInfo)) { - ASSERT (CurrentAddrInfo !=3D NULL); - // - // Remove this already existing source address from the CurrentSourc= eList - // built before. - // - Ip6RemoveAddr ( - NULL, - &CurrentSourceList, - &CurrentSourceCount, - &CurrentAddrInfo->Address, - 128 - ); + // + // This manual address is already in use, see whether prefix lengt= h is changed. + // + if (NewAddress->PrefixLength !=3D CurrentAddrInfo->PrefixLength) { + // + // Remove the on-link prefix table, the route entry will be remo= ved + // implicitly. + // + PrefixEntry =3D Ip6FindPrefixListEntry ( + IpSb, + TRUE, + CurrentAddrInfo->PrefixLength, + &CurrentAddrInfo->Address + ); + if (PrefixEntry !=3D NULL) { + Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); + } =20 - // - // If the new address's prefix length is not specified, just use the= previous configured - // prefix length for this address. - // - if (NewAddress->PrefixLength =3D=3D 0) { - NewAddress->PrefixLength =3D CurrentAddrInfo->PrefixLength; - } + // + // Save the prefix length. + // + CurrentAddrInfo->PrefixLength =3D NewAddress->PrefixLength; + IsUpdated =3D TRUE; + } =20 - // - // This manual address is already in use, see whether prefix length = is changed. - // - if (NewAddress->PrefixLength !=3D CurrentAddrInfo->PrefixLength) { // - // Remove the on-link prefix table, the route entry will be removed - // implicitly. + // create a new on-link prefix entry. // PrefixEntry =3D Ip6FindPrefixListEntry ( IpSb, TRUE, - CurrentAddrInfo->PrefixLength, - &CurrentAddrInfo->Address + NewAddress->PrefixLength, + &NewAddress->Address ); - if (PrefixEntry !=3D NULL) { - Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); + if (PrefixEntry =3D=3D NULL) { + Ip6CreatePrefixListEntry ( + IpSb, + TRUE, + (UINT32) IP6_INFINIT_LIFETIME, + (UINT32) IP6_INFINIT_LIFETIME, + NewAddress->PrefixLength, + &NewAddress->Address + ); } =20 + CurrentAddrInfo->IsAnycast =3D 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 =3D NewAddress->PrefixLength; IsUpdated =3D TRUE; + + // + // Set the new address, this will trigger DAD and activate the add= ress 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 curren= tly in + // use and will be removed. + // + IpIf =3D IpSb->DefaultInterface; + + while (!IsListEmpty (&CurrentSourceList)) { + IsUpdated =3D TRUE; + + CurrentAddrInfo =3D NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_I= NFO, Link); =20 // - // 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 =3D Ip6FindPrefixListEntry ( IpSb, TRUE, - NewAddress->PrefixLength, - &NewAddress->Address + CurrentAddrInfo->PrefixLength, + &CurrentAddrInfo->Address ); - if (PrefixEntry =3D=3D NULL) { - Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - NewAddress->PrefixLength, - &NewAddress->Address - ); + if (PrefixEntry !=3D NULL) { + Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); } =20 - CurrentAddrInfo->IsAnycast =3D 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 =3D=3D EFI_NOT_READY) { + // + // If DAD is disabled on this interface, the configuration process= is + // actually synchronous, and the data item's status will be change= d to + // the final status before we reach here, just check it. + // + Status =3D EFI_NOT_READY; + } else { + Status =3D EFI_SUCCESS; + } } else { // - // A new address. + // No update is taken, reset the status to success and return EFI_AB= ORTED. // - IsUpdated =3D TRUE; + DataItem->Status =3D EFI_SUCCESS; + Status =3D EFI_ABORTED; + } + } else { + // + // DataSize is 0 and Data is NULL, clean up the manual address. + // + if (DataItem->Data.Ptr !=3D NULL) { + FreePool (DataItem->Data.Ptr); + } + DataItem->Data.Ptr =3D NULL; + DataItem->DataSize =3D 0; + DataItem->Status =3D EFI_NOT_FOUND; =20 - // - // Set the new address, this will trigger DAD and activate the addre= ss 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 ); } - } =20 - // - // Check the CurrentSourceList, it now contains those addresses currentl= y in - // use and will be removed. - // - IpIf =3D IpSb->DefaultInterface; - - while (!IsListEmpty (&CurrentSourceList)) { - IsUpdated =3D TRUE; - - CurrentAddrInfo =3D NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INF= O, 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 ); =20 - // - // Remove the on-link prefix table, the route entry will be removed - // implicitly. - // - PrefixEntry =3D Ip6FindPrefixListEntry ( - IpSb, - TRUE, - CurrentAddrInfo->PrefixLength, - &CurrentAddrInfo->Address - ); - if (PrefixEntry !=3D NULL) { - Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); - } - - RemoveEntryList (&CurrentAddrInfo->Link); - FreePool (CurrentAddrInfo); - } - - if (IsUpdated) { - if (DataItem->Status =3D=3D 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 addr= esses. // - Status =3D EFI_NOT_READY; - } else { - Status =3D EFI_SUCCESS; + IpIf =3D NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INT= ERFACE_SIGNATURE); + + NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) { + DelayNode =3D NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, L= ink); + if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) { + RemoveEntryList (&DelayNode->Link); + FreePool (DelayNode); + } + } + + NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) { + DadEntry =3D 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_ABOR= TED. - // - DataItem->Status =3D EFI_SUCCESS; - Status =3D EFI_ABORTED; } =20 return Status; } =20 @@ -1208,98 +1287,107 @@ Ip6ConfigSetGateway ( BOOLEAN OneAdded; IP6_SERVICE *IpSb; IP6_DEFAULT_ROUTER *DefaultRouter; VOID *Tmp; =20 - if ((DataSize % sizeof (EFI_IPv6_ADDRESS) !=3D 0) || (DataSize =3D=3D 0)= ) { + OldGateway =3D NULL; + NewGateway =3D NULL; + Item =3D NULL; + DefaultRouter =3D NULL; + Tmp =3D NULL; + OneRemoved =3D FALSE; + OneAdded =3D FALSE; + + if ((DataSize !=3D 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) !=3D 0)) { return EFI_BAD_BUFFER_SIZE; } =20 if (Instance->Policy !=3D Ip6ConfigPolicyManual) { return EFI_WRITE_PROTECTED; } =20 - NewGateway =3D (EFI_IPv6_ADDRESS *) Data; - NewGatewayCount =3D DataSize / sizeof (EFI_IPv6_ADDRESS); - for (Index1 =3D 0; Index1 < NewGatewayCount; Index1++) { - - if (!NetIp6IsValidUnicast (NewGateway + Index1)) { - - return EFI_INVALID_PARAMETER; - } - - for (Index2 =3D Index1 + 1; Index2 < NewGatewayCount; Index2++) { - if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) { - return EFI_INVALID_PARAMETER; - } - } - } - IpSb =3D IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); Item =3D &Instance->DataItem[Ip6ConfigDataTypeGateway]; OldGateway =3D Item->Data.Gateway; OldGatewayCount =3D Item->DataSize / sizeof (EFI_IPv6_ADDRESS); - OneRemoved =3D FALSE; - OneAdded =3D FALSE; - - if (NewGatewayCount !=3D OldGatewayCount) { - Tmp =3D AllocatePool (DataSize); - if (Tmp =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - Tmp =3D NULL; - } =20 for (Index1 =3D 0; Index1 < OldGatewayCount; Index1++) { // - // Find the gateways that are no long in the new setting and remove th= em. + // Remove this default router. // - for (Index2 =3D 0; Index2 < NewGatewayCount; Index2++) { - if (EFI_IP6_EQUAL (OldGateway + Index1, NewGateway + Index2)) { - OneRemoved =3D TRUE; - break; + DefaultRouter =3D Ip6FindDefaultRouter (IpSb, OldGateway + Index1); + if (DefaultRouter !=3D NULL) { + Ip6DestroyDefaultRouter (IpSb, DefaultRouter); + OneRemoved =3D TRUE; + } + } + + if (Data !=3D NULL && DataSize !=3D 0) { + NewGateway =3D (EFI_IPv6_ADDRESS *) Data; + NewGatewayCount =3D DataSize / sizeof (EFI_IPv6_ADDRESS); + for (Index1 =3D 0; Index1 < NewGatewayCount; Index1++) { + + if (!NetIp6IsValidUnicast (NewGateway + Index1)) { + + return EFI_INVALID_PARAMETER; + } + + for (Index2 =3D Index1 + 1; Index2 < NewGatewayCount; Index2++) { + if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) { + return EFI_INVALID_PARAMETER; + } } } =20 - if (Index2 =3D=3D NewGatewayCount) { - // - // Remove this default router. - // - DefaultRouter =3D Ip6FindDefaultRouter (IpSb, OldGateway + Index1); - if (DefaultRouter !=3D NULL) { - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); + if (NewGatewayCount !=3D OldGatewayCount) { + Tmp =3D AllocatePool (DataSize); + if (Tmp =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; } + } else { + Tmp =3D NULL; } - } =20 - for (Index1 =3D 0; Index1 < NewGatewayCount; Index1++) { + for (Index1 =3D 0; Index1 < NewGatewayCount; Index1++) { =20 - DefaultRouter =3D Ip6FindDefaultRouter (IpSb, NewGateway + Index1); - if (DefaultRouter =3D=3D NULL) { - Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LI= FETIME); - OneAdded =3D TRUE; + DefaultRouter =3D Ip6FindDefaultRouter (IpSb, NewGateway + Index1); + if (DefaultRouter =3D=3D NULL) { + Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_= LIFETIME); + OneAdded =3D TRUE; + } } - } =20 - if (!OneRemoved && !OneAdded) { - Item->Status =3D EFI_SUCCESS; - return EFI_ABORTED; - } else { + if (!OneRemoved && !OneAdded) { + Item->Status =3D EFI_SUCCESS; + return EFI_ABORTED; + } else { =20 - if (Tmp !=3D NULL) { - if (Item->Data.Ptr !=3D NULL) { - FreePool (Item->Data.Ptr); + if (Tmp !=3D NULL) { + if (Item->Data.Ptr !=3D NULL) { + FreePool (Item->Data.Ptr); + } + Item->Data.Ptr =3D Tmp; } - Item->Data.Ptr =3D Tmp; - } =20 - CopyMem (Item->Data.Ptr, Data, DataSize); - Item->DataSize =3D DataSize; - Item->Status =3D EFI_SUCCESS; - return EFI_SUCCESS; + CopyMem (Item->Data.Ptr, Data, DataSize); + Item->DataSize =3D DataSize; + Item->Status =3D EFI_SUCCESS; + return EFI_SUCCESS; + } + } else { + // + // DataSize is 0 and Data is NULL, clean up the Gateway address. + // + if (Item->Data.Ptr !=3D NULL) { + FreePool (Item->Data.Ptr); + } + Item->Data.Ptr =3D NULL; + Item->DataSize =3D 0; + Item->Status =3D EFI_NOT_FOUND; } + + return EFI_SUCCESS; } =20 /** The work function for EfiIp6ConfigSetData() to set the DNS server list f= or 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; =20 - if ((DataSize % sizeof (EFI_IPv6_ADDRESS) !=3D 0) || (DataSize =3D=3D 0)= ) { + OldDns =3D NULL; + NewDns =3D NULL; + Item =3D NULL; + Tmp =3D NULL; + + if ((DataSize =3D=3D 0) && (DataSize % sizeof (EFI_IPv6_ADDRESS) !=3D 0)= ) { return EFI_BAD_BUFFER_SIZE; } =20 if (Instance->Policy !=3D Ip6ConfigPolicyManual) { return EFI_WRITE_PROTECTED; } =20 - Item =3D &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; - NewDns =3D (EFI_IPv6_ADDRESS *) Data; - OldDns =3D Item->Data.DnsServers; - NewDnsCount =3D DataSize / sizeof (EFI_IPv6_ADDRESS); - OldDnsCount =3D Item->DataSize / sizeof (EFI_IPv6_ADDRESS); - OneAdded =3D FALSE; + Item =3D &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; =20 - if (NewDnsCount !=3D OldDnsCount) { - Tmp =3D AllocatePool (DataSize); - if (Tmp =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - Tmp =3D NULL; - } + if (Data !=3D NULL && DataSize !=3D 0) { + NewDns =3D (EFI_IPv6_ADDRESS *) Data; + OldDns =3D Item->Data.DnsServers; + NewDnsCount =3D DataSize / sizeof (EFI_IPv6_ADDRESS); + OldDnsCount =3D Item->DataSize / sizeof (EFI_IPv6_ADDRESS); + OneAdded =3D FALSE; =20 - for (NewIndex =3D 0; NewIndex < NewDnsCount; NewIndex++) { - - if (!NetIp6IsValidUnicast (NewDns + NewIndex)) { - // - // The dns server address must be unicast. - // - if (Tmp !=3D NULL) { - FreePool (Tmp); + if (NewDnsCount !=3D OldDnsCount) { + Tmp =3D AllocatePool (DataSize); + if (Tmp =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; } - return EFI_INVALID_PARAMETER; + } else { + Tmp =3D NULL; } =20 - if (OneAdded) { - // - // If any address in the new setting is not in the old settings, ski= p the - // comparision below. - // - continue; - } + for (NewIndex =3D 0; NewIndex < NewDnsCount; NewIndex++) { =20 - for (OldIndex =3D 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 !=3D NULL) { + FreePool (Tmp); + } + return EFI_INVALID_PARAMETER; } - } =20 - if (OldIndex =3D=3D OldDnsCount) { - OneAdded =3D TRUE; + if (OneAdded) { + // + // If any address in the new setting is not in the old settings, s= kip the + // comparision below. + // + continue; + } + + for (OldIndex =3D 0; OldIndex < OldDnsCount; OldIndex++) { + if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) { + // + // If found break out. + // + break; + } + } + + if (OldIndex =3D=3D OldDnsCount) { + OneAdded =3D TRUE; + } } - } =20 - if (!OneAdded && (DataSize =3D=3D Item->DataSize)) { + if (!OneAdded && (DataSize =3D=3D Item->DataSize)) { + // + // No new item is added and the size is the same. + // + Item->Status =3D EFI_SUCCESS; + return EFI_ABORTED; + } else { + if (Tmp !=3D NULL) { + if (Item->Data.Ptr !=3D NULL) { + FreePool (Item->Data.Ptr); + } + Item->Data.Ptr =3D Tmp; + } + + CopyMem (Item->Data.Ptr, Data, DataSize); + Item->DataSize =3D DataSize; + Item->Status =3D 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.=20 // - Item->Status =3D EFI_SUCCESS; - return EFI_ABORTED; - } else { - if (Tmp !=3D NULL) { - if (Item->Data.Ptr !=3D NULL) { - FreePool (Item->Data.Ptr); - } - Item->Data.Ptr =3D Tmp; + if (Item->Data.Ptr !=3D NULL) { + FreePool (Item->Data.Ptr); } - - CopyMem (Item->Data.Ptr, Data, DataSize); - Item->DataSize =3D DataSize; - Item->Status =3D EFI_SUCCESS; - return EFI_SUCCESS; + Item->Data.Ptr =3D NULL; + Item->DataSize =3D 0; + Item->Status =3D EFI_NOT_FOUND; } + + return EFI_SUCCESS; } =20 /** 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 ( =20 @retval EFI_SUCCESS The specified configuration data for the E= FI 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 DataSized= o not match the=20 + requirement of the data type indicated b= y DataType. @retval EFI_WRITE_PROTECTED The specified configuration data is read-o= nly or the specified configuration data cannot be set under the= current policy. @retval EFI_ACCESS_DENIED Another set operation on the specified con= figuration 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; =20 - if ((This =3D=3D NULL) || (Data =3D=3D NULL)) { + if ((This =3D=3D NULL) || (Data =3D=3D NULL && DataSize !=3D 0) || (Data= !=3D NULL && DataSize =3D=3D 0)) { return EFI_INVALID_PARAMETER; } =20 if (DataType >=3D Ip6ConfigDataTypeMaximum) { return EFI_UNSUPPORTED; --=20 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel