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>
---
.../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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.