From: Jiaxin Wu Date: Tue, 28 Feb 2017 00:35:08 +0000 (+0800) Subject: MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration X-Git-Tag: edk2-stable201903~3661 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=1126570464470572bcd7d59b83c6c39120e73c87 MdeModulePkg/Ip4Dxe: Support SetData interface to clear specific configuration 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 Reviewed-by: Ye Ting --- diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index 3e38085621..26530e3a2b 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -1241,12 +1241,20 @@ Ip4Config2SetManualAddress ( 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; } @@ -1254,46 +1262,102 @@ Ip4Config2SetManualAddress ( 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; @@ -1342,7 +1406,13 @@ Ip4Config2SetGateway ( 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; } @@ -1352,41 +1422,13 @@ Ip4Config2SetGateway ( 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 ( @@ -1396,40 +1438,78 @@ Ip4Config2SetGateway ( 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; } /** @@ -1461,9 +1541,11 @@ Ip4Config2SetDnsServer ( 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; @@ -1475,7 +1557,21 @@ Ip4Config2SetDnsServer ( 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; } /** @@ -1554,9 +1650,8 @@ Ip4Config2OnDhcp4Event ( 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 @@ -1584,7 +1679,7 @@ EfiIp4Config2SetData ( 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; }