From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 116A621AEB0D9 for ; Tue, 25 Jul 2017 23:26:37 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga105.fm.intel.com with ESMTP; 25 Jul 2017 23:28:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,413,1496127600"; d="scan'208";a="997280367" Received: from jiaxinwu-mobl2.ccr.corp.intel.com ([10.239.196.131]) by orsmga003.jf.intel.com with ESMTP; 25 Jul 2017 23:28:37 -0700 From: Jiaxin Wu To: edk2-devel@lists.01.org Cc: Ye Ting , Fu Siyuan , Wu Jiaxin Date: Wed, 26 Jul 2017 14:28:30 +0800 Message-Id: <1501050511-16884-3-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: [Patch 2/3] MdeModulePkg/Ip4Dxe: 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: , X-List-Received-Date: Wed, 26 Jul 2017 06:26:37 -0000 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 Cc: Fu Siyuan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Wu Jiaxin --- .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c | 285 ++++++++++++++------- 1 file changed, 190 insertions(+), 95 deletions(-) diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index 3e38085..26530e3 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -1239,63 +1239,127 @@ Ip4Config2SetManualAddress ( EFI_STATUS Status; IP4_ADDR StationAddress; IP4_ADDR SubnetMask; VOID *Ptr; IP4_SERVICE *IpSb; + IP4_INTERFACE *IpIf; + IP4_ROUTE_TABLE *RouteTable; + + DataItem = NULL; + Status = EFI_SUCCESS; + Ptr = NULL; + IpIf = NULL; + RouteTable = NULL; IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY); - if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) { + if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0)) { return EFI_BAD_BUFFER_SIZE; } if (Instance->Policy != Ip4Config2PolicyStatic) { return EFI_WRITE_PROTECTED; } - NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data); + DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress]; - StationAddress = EFI_NTOHL (NewAddress.Address); - SubnetMask = EFI_NTOHL (NewAddress.SubnetMask); + if (Data != NULL && DataSize != 0) { + NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data); - // - // Check whether the StationAddress/SubnetMask pair is valid. - // - if (!Ip4StationAddressValid (StationAddress, SubnetMask)) { - return EFI_INVALID_PARAMETER; - } + StationAddress = EFI_NTOHL (NewAddress.Address); + SubnetMask = EFI_NTOHL (NewAddress.SubnetMask); - // - // Store the new data, and init the DataItem status to EFI_NOT_READY because - // we may have an asynchronous configuration process. - // - Ptr = AllocateCopyPool (DataSize, Data); - if (Ptr == NULL) { - return EFI_OUT_OF_RESOURCES; - } + // + // Check whether the StationAddress/SubnetMask pair is valid. + // + if (!Ip4StationAddressValid (StationAddress, SubnetMask)) { + return EFI_INVALID_PARAMETER; + } - DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress]; - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); - } - - DataItem->Data.Ptr = Ptr; - DataItem->DataSize = DataSize; - DataItem->Status = EFI_NOT_READY; + // + // Store the new data, and init the DataItem status to EFI_NOT_READY because + // we may have an asynchronous configuration process. + // + Ptr = AllocateCopyPool (DataSize, Data); + if (Ptr == NULL) { + return EFI_OUT_OF_RESOURCES; + } - IpSb->Reconfig = TRUE; - Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask); + if (DataItem->Data.Ptr != NULL) { + FreePool (DataItem->Data.Ptr); + } + + DataItem->Data.Ptr = Ptr; + DataItem->DataSize = DataSize; + DataItem->Status = EFI_NOT_READY; + + IpSb->Reconfig = TRUE; + Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask); - DataItem->Status = Status; + DataItem->Status = Status; - if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) { - if (Ptr != NULL) { - FreePool (Ptr); + if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) { + if (Ptr != NULL) { + FreePool (Ptr); + } + DataItem->Data.Ptr = NULL; + } + } 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; + + // + // Free the default router table and Interface, clean up the assemble table. + // + if (IpSb->DefaultInterface != NULL) { + if (IpSb->DefaultRouteTable != NULL) { + Ip4FreeRouteTable (IpSb->DefaultRouteTable); + IpSb->DefaultRouteTable = NULL; + } + + Ip4CancelReceive (IpSb->DefaultInterface); + + Ip4FreeInterface (IpSb->DefaultInterface, NULL); + IpSb->DefaultInterface = NULL; + } + + Ip4CleanAssembleTable (&IpSb->Assemble); + + // + // Create new default interface and route table. + // + IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image); + if (IpIf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RouteTable = Ip4CreateRouteTable (); + if (RouteTable == NULL) { + Ip4FreeInterface (IpIf, NULL); + return EFI_OUT_OF_RESOURCES; + } + + IpSb->DefaultInterface = IpIf; + InsertHeadList (&IpSb->Interfaces, &IpIf->Link); + IpSb->DefaultRouteTable = RouteTable; + Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb); + + // + // Reset the State to unstarted. + // + if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) { + IpSb->State = IP4_SERVICE_UNSTARTED; } - DataItem->Data.Ptr = NULL; } return Status; } @@ -1340,98 +1404,114 @@ Ip4Config2SetGateway ( UINTN NewGatewayCount; BOOLEAN OneRemoved; BOOLEAN OneAdded; VOID *Tmp; - if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) { + OldGateway = NULL; + NewGateway = NULL; + OneRemoved = FALSE; + OneAdded = FALSE; + Tmp = NULL; + + if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv4_ADDRESS) != 0)) { return EFI_BAD_BUFFER_SIZE; } if (Instance->Policy != Ip4Config2PolicyStatic) { return EFI_WRITE_PROTECTED; } IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); - NewGateway = (EFI_IPv4_ADDRESS *) Data; - NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS); - for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { - CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR)); - - if ((IpSb->DefaultInterface->SubnetMask != 0) && - !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) { - return EFI_INVALID_PARAMETER; - } - - for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) { - if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) { - return EFI_INVALID_PARAMETER; - } - } - } - - DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway]; + DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway]; OldGateway = DataItem->Data.Gateway; OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_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++) { // - // Remove this route entry. + // Remove the old route entry. // CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR)); Ip4DelRoute ( IpSb->DefaultRouteTable, IP4_ALLZERO_ADDRESS, IP4_ALLZERO_ADDRESS, NTOHL (Gateway) ); OneRemoved = TRUE; - } - for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { - CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR)); - Ip4AddRoute ( - IpSb->DefaultRouteTable, - IP4_ALLZERO_ADDRESS, - IP4_ALLZERO_ADDRESS, - NTOHL (Gateway) - ); - - OneAdded = TRUE; - } + if (Data != NULL && DataSize != 0) { + NewGateway = (EFI_IPv4_ADDRESS *) Data; + NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS); + for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { + CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR)); + if ((IpSb->DefaultInterface->SubnetMask != 0) && + !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) { + return EFI_INVALID_PARAMETER; + } - if (!OneRemoved && !OneAdded) { - DataItem->Status = EFI_SUCCESS; - return EFI_ABORTED; - } else { + for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) { + if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) { + return EFI_INVALID_PARAMETER; + } + } + } - if (Tmp != NULL) { - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); + if (NewGatewayCount != OldGatewayCount) { + Tmp = AllocatePool (DataSize); + if (Tmp == NULL) { + return EFI_OUT_OF_RESOURCES; } - DataItem->Data.Ptr = Tmp; + } else { + Tmp = NULL; } - CopyMem (DataItem->Data.Ptr, Data, DataSize); - DataItem->DataSize = DataSize; - DataItem->Status = EFI_SUCCESS; - return EFI_SUCCESS; + for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { + // + // Add the new route entry. + // + CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR)); + Ip4AddRoute ( + IpSb->DefaultRouteTable, + IP4_ALLZERO_ADDRESS, + IP4_ALLZERO_ADDRESS, + NTOHL (Gateway) + ); + + OneAdded = TRUE; + } + + if (!OneRemoved && !OneAdded) { + DataItem->Status = EFI_SUCCESS; + return EFI_ABORTED; + } else { + if (Tmp != NULL) { + if (DataItem->Data.Ptr != NULL) { + FreePool (DataItem->Data.Ptr); + } + DataItem->Data.Ptr = Tmp; + } + + CopyMem (DataItem->Data.Ptr, Data, DataSize); + DataItem->DataSize = DataSize; + DataItem->Status = EFI_SUCCESS; + } + } else { + // + // DataSize is 0 and Data is NULL, clean up the Gateway address. + // + if (DataItem->Data.Ptr != NULL) { + FreePool (DataItem->Data.Ptr); + } + DataItem->Data.Ptr = NULL; + DataItem->DataSize = 0; + DataItem->Status = EFI_NOT_FOUND; } + return EFI_SUCCESS; } /** The work function is to set the DNS server list for the EFI IPv4 network stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL @@ -1459,13 +1539,15 @@ Ip4Config2SetDnsServer ( IN IP4_CONFIG2_INSTANCE *Instance, IN UINTN DataSize, IN VOID *Data ) { - IP4_CONFIG2_DATA_ITEM *Item; + EFI_STATUS Status; + IP4_CONFIG2_DATA_ITEM *Item; - Item = NULL; + Status = EFI_SUCCESS; + Item = NULL; if (Instance->Policy != Ip4Config2PolicyStatic) { return EFI_WRITE_PROTECTED; } @@ -1473,11 +1555,25 @@ Ip4Config2SetDnsServer ( if (DATA_ATTRIB_SET (Item->Attribute, DATA_ATTRIB_VOLATILE)) { REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE); } - return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data); + if (Data != NULL && DataSize != 0) { + Status = Ip4Config2SetDnsServerWorker (Instance, DataSize, Data); + } else { + // + // DataSize is 0 and Data is NULL, clean up the DnsServer address. + // + if (Item->Data.Ptr != NULL) { + FreePool (Item->Data.Ptr); + } + Item->Data.Ptr = NULL; + Item->DataSize = 0; + Item->Status = EFI_NOT_FOUND; + } + + return Status; } /** Generate the operational state of the interface this IP4 config2 instance manages and output in EFI_IP4_CONFIG2_INTERFACE_INFO. @@ -1552,13 +1648,12 @@ Ip4Config2OnDhcp4Event ( @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 DataSize do 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 @@ -1582,11 +1677,11 @@ EfiIp4Config2SetData ( EFI_TPL OldTpl; EFI_STATUS Status; IP4_CONFIG2_INSTANCE *Instance; IP4_SERVICE *IpSb; - if ((This == NULL) || (Data == NULL)) { + if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) { return EFI_INVALID_PARAMETER; } if (DataType >= Ip4Config2DataTypeMaximum) { return EFI_UNSUPPORTED; -- 1.9.5.msysgit.1