/** @file\r
The implementation of EFI IPv4 Configuration II Protocol.\r
\r
- Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
\r
This program and the accompanying materials\r
\r
IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
\r
+ //\r
+ // Check whether the StationAddress/SubnetMask pair is valid.\r
+ //\r
+ if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
{\r
UINTN OldIndex;\r
UINTN NewIndex;\r
- UINTN Index1;\r
EFI_IPv4_ADDRESS *OldDns;\r
EFI_IPv4_ADDRESS *NewDns;\r
UINTN OldDnsCount;\r
\r
for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
-\r
- if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {\r
+ if (IP4_IS_UNSPECIFIED (NTOHL (DnsAddress)) || IP4_IS_LOCAL_BROADCAST (NTOHL (DnsAddress))) {\r
//\r
// The dns server address must be unicast.\r
//\r
- FreePool (Tmp);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {\r
- if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {\r
+ if (Tmp != NULL) {\r
FreePool (Tmp);\r
- return EFI_INVALID_PARAMETER;\r
}\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
if (OneAdded) {\r
IP4_CONFIG2_DHCP4_OPTION ParaList;\r
EFI_STATUS Status;\r
\r
-\r
IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
\r
if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
IpSb->Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- ASSERT_EFI_ERROR (Status);\r
+ if (EFI_ERROR (Status)) {\r
+ NetLibDestroyServiceChild (\r
+ IpSb->Controller,\r
+ IpSb->Image,\r
+ &gEfiDhcp4ServiceBindingProtocolGuid,\r
+ Instance->Dhcp4Handle\r
+ );\r
\r
+ Instance->Dhcp4Handle = NULL;\r
+ \r
+ return Status;\r
+ }\r
\r
//\r
// Check the current DHCP status, if the DHCP process has\r
//\r
Dhcp4 = Instance->Dhcp4;\r
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
-\r
if (Dhcp4Mode.State == Dhcp4Bound) {\r
Ip4Config2OnDhcp4Complete (NULL, Instance);\r
+ \r
return EFI_SUCCESS;\r
-\r
}\r
\r
//\r
Dhcp4Mode.ConfigData.OptionList = OptionList;\r
\r
Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
-\r
if (EFI_ERROR (Status)) {\r
+ gBS->CloseProtocol (\r
+ Instance->Dhcp4Handle,\r
+ &gEfiDhcp4ProtocolGuid,\r
+ IpSb->Image,\r
+ IpSb->Controller\r
+ );\r
+\r
+ NetLibDestroyServiceChild (\r
+ IpSb->Controller,\r
+ IpSb->Image,\r
+ &gEfiDhcp4ServiceBindingProtocolGuid,\r
+ Instance->Dhcp4Handle\r
+ );\r
+ \r
+ Instance->Dhcp4 = NULL;\r
+ \r
+ Instance->Dhcp4Handle = NULL;\r
+ \r
return Status;\r
}\r
\r
Instance,\r
&Instance->Dhcp4Event\r
);\r
-\r
if (EFI_ERROR (Status)) {\r
+ Ip4Config2DestroyDhcp4 (Instance);\r
return Status;\r
}\r
\r
Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
-\r
if (EFI_ERROR (Status)) {\r
+ Ip4Config2DestroyDhcp4 (Instance);\r
+ gBS->CloseEvent (Instance->Dhcp4Event);\r
+ Instance->Dhcp4Event = NULL;\r
+ \r
return Status;\r
}\r
\r
- IpSb->State = IP4_SERVICE_STARTED;\r
+ IpSb->State = IP4_SERVICE_STARTED;\r
DispatchDpc ();\r
+ \r
return EFI_SUCCESS;\r
-\r
}\r
\r
\r
\r
**/\r
EFI_STATUS\r
-Ip4Config2SetMaunualAddress (\r
+Ip4Config2SetManualAddress (\r
IN IP4_CONFIG2_INSTANCE *Instance,\r
IN UINTN DataSize,\r
IN VOID *Data\r
IP4_ADDR SubnetMask;\r
VOID *Ptr;\r
IP4_SERVICE *IpSb;\r
+ IP4_INTERFACE *IpIf;\r
+ IP4_ROUTE_TABLE *RouteTable;\r
+\r
+ DataItem = NULL;\r
+ Status = EFI_SUCCESS;\r
+ Ptr = NULL;\r
+ IpIf = NULL;\r
+ RouteTable = NULL;\r
\r
IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
\r
ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);\r
\r
- if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) {\r
+ if ((DataSize != 0) && ((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0)) {\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
return EFI_WRITE_PROTECTED;\r
}\r
\r
- NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);\r
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
\r
- //\r
- // Store the new data, and init the DataItem status to EFI_NOT_READY because\r
- // we may have an asynchronous configuration process.\r
- //\r
- Ptr = AllocateCopyPool (DataSize, Data);\r
- if (Ptr == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
+ if (Data != NULL && DataSize != 0) {\r
+ NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);\r
\r
- DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
- if (DataItem->Data.Ptr != NULL) {\r
- FreePool (DataItem->Data.Ptr);\r
- }\r
- \r
- DataItem->Data.Ptr = Ptr;\r
- DataItem->DataSize = DataSize;\r
- DataItem->Status = EFI_NOT_READY;\r
+ StationAddress = EFI_NTOHL (NewAddress.Address);\r
+ SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
\r
- StationAddress = EFI_NTOHL (NewAddress.Address);\r
- SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);\r
+ //\r
+ // Check whether the StationAddress/SubnetMask pair is valid.\r
+ //\r
+ if (!Ip4StationAddressValid (StationAddress, SubnetMask)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- IpSb->Reconfig = TRUE;\r
- Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- } \r
+ //\r
+ // Store the new data, and init the DataItem status to EFI_NOT_READY because\r
+ // we may have an asynchronous configuration process.\r
+ //\r
+ Ptr = AllocateCopyPool (DataSize, Data);\r
+ if (Ptr == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (DataItem->Data.Ptr != NULL) {\r
+ FreePool (DataItem->Data.Ptr);\r
+ }\r
+ \r
+ DataItem->Data.Ptr = Ptr;\r
+ DataItem->DataSize = DataSize;\r
+ DataItem->Status = EFI_NOT_READY;\r
+\r
+ IpSb->Reconfig = TRUE;\r
+ Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);\r
+\r
+ DataItem->Status = Status;\r
+\r
+ if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {\r
+ if (Ptr != NULL) {\r
+ FreePool (Ptr);\r
+ }\r
+ DataItem->Data.Ptr = NULL; \r
+ }\r
+ } else {\r
+ //\r
+ // DataSize is 0 and Data is NULL, clean up the manual address.\r
+ //\r
+ if (DataItem->Data.Ptr != NULL) {\r
+ FreePool (DataItem->Data.Ptr);\r
+ }\r
+ DataItem->Data.Ptr = NULL;\r
+ DataItem->DataSize = 0;\r
+ DataItem->Status = EFI_NOT_FOUND;\r
+\r
+ //\r
+ // Free the default router table and Interface, clean up the assemble table.\r
+ //\r
+ if (IpSb->DefaultInterface != NULL) {\r
+ if (IpSb->DefaultRouteTable != NULL) {\r
+ Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
+ IpSb->DefaultRouteTable = NULL; \r
+ }\r
+\r
+ Ip4CancelReceive (IpSb->DefaultInterface);\r
+\r
+ Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
+ IpSb->DefaultInterface = NULL;\r
+ }\r
+\r
+ Ip4CleanAssembleTable (&IpSb->Assemble);\r
+\r
+ //\r
+ // Create new default interface and route table.\r
+ // \r
+ IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
+ if (IpIf == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
- DataItem->Status = EFI_SUCCESS; \r
+ RouteTable = Ip4CreateRouteTable ();\r
+ if (RouteTable == NULL) {\r
+ Ip4FreeInterface (IpIf, NULL);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ IpSb->DefaultInterface = IpIf;\r
+ InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
+ IpSb->DefaultRouteTable = RouteTable;\r
+ Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
\r
-ON_EXIT:\r
- if (EFI_ERROR (DataItem->Status)) {\r
- if (Ptr != NULL) {\r
- FreePool (Ptr);\r
+ //\r
+ // Reset the State to unstarted. \r
+ //\r
+ if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) {\r
+ IpSb->State = IP4_SERVICE_UNSTARTED;\r
}\r
- DataItem->Data.Ptr = NULL; \r
}\r
\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r
\r
/**\r
BOOLEAN OneAdded;\r
VOID *Tmp;\r
\r
- if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
+ OldGateway = NULL;\r
+ NewGateway = NULL;\r
+ OneRemoved = FALSE;\r
+ OneAdded = FALSE;\r
+ Tmp = NULL;\r
+\r
+ if ((DataSize != 0) && (DataSize % sizeof (EFI_IPv4_ADDRESS) != 0)) {\r
return EFI_BAD_BUFFER_SIZE;\r
}\r
\r
return EFI_WRITE_PROTECTED;\r
}\r
\r
-\r
- NewGateway = (EFI_IPv4_ADDRESS *) Data;\r
- NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
- for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
- CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
- \r
- if (!NetIp4IsUnicast (NTOHL (Gateway), 0)) {\r
-\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {\r
- if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- }\r
- \r
IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
- DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
+\r
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r
OldGateway = DataItem->Data.Gateway;\r
OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
- OneRemoved = FALSE;\r
- OneAdded = FALSE;\r
-\r
- if (NewGatewayCount != OldGatewayCount) {\r
- Tmp = AllocatePool (DataSize);\r
- if (Tmp == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- } else {\r
- Tmp = NULL;\r
- }\r
\r
for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {\r
//\r
- // Remove this route entry.\r
+ // Remove the old route entry.\r
//\r
CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));\r
Ip4DelRoute (\r
NTOHL (Gateway)\r
);\r
OneRemoved = TRUE;\r
-\r
}\r
\r
- for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
- CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
- Ip4AddRoute (\r
- IpSb->DefaultRouteTable,\r
- IP4_ALLZERO_ADDRESS,\r
- IP4_ALLZERO_ADDRESS,\r
- NTOHL (Gateway)\r
- ); \r
-\r
- OneAdded = TRUE;\r
- }\r
+ if (Data != NULL && DataSize != 0) {\r
+ NewGateway = (EFI_IPv4_ADDRESS *) Data;\r
+ NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
+ CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
\r
+ if ((IpSb->DefaultInterface->SubnetMask != 0) && \r
+ !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- if (!OneRemoved && !OneAdded) {\r
- DataItem->Status = EFI_SUCCESS;\r
- return EFI_ABORTED;\r
- } else {\r
+ for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {\r
+ if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ }\r
\r
- if (Tmp != NULL) {\r
- if (DataItem->Data.Ptr != NULL) {\r
- FreePool (DataItem->Data.Ptr);\r
+ if (NewGatewayCount != OldGatewayCount) {\r
+ Tmp = AllocatePool (DataSize);\r
+ if (Tmp == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
- DataItem->Data.Ptr = Tmp;\r
+ } else {\r
+ Tmp = NULL;\r
}\r
\r
- CopyMem (DataItem->Data.Ptr, Data, DataSize);\r
- DataItem->DataSize = DataSize;\r
- DataItem->Status = EFI_SUCCESS;\r
- return EFI_SUCCESS;\r
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {\r
+ //\r
+ // Add the new route entry.\r
+ //\r
+ CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));\r
+ Ip4AddRoute (\r
+ IpSb->DefaultRouteTable,\r
+ IP4_ALLZERO_ADDRESS,\r
+ IP4_ALLZERO_ADDRESS,\r
+ NTOHL (Gateway)\r
+ ); \r
+\r
+ OneAdded = TRUE;\r
+ }\r
+\r
+ if (!OneRemoved && !OneAdded) {\r
+ DataItem->Status = EFI_SUCCESS;\r
+ return EFI_ABORTED;\r
+ } else {\r
+ if (Tmp != NULL) {\r
+ if (DataItem->Data.Ptr != NULL) {\r
+ FreePool (DataItem->Data.Ptr);\r
+ }\r
+ DataItem->Data.Ptr = Tmp;\r
+ }\r
+\r
+ CopyMem (DataItem->Data.Ptr, Data, DataSize);\r
+ DataItem->DataSize = DataSize;\r
+ DataItem->Status = EFI_SUCCESS;\r
+ }\r
+ } else {\r
+ //\r
+ // DataSize is 0 and Data is NULL, clean up the Gateway address.\r
+ //\r
+ if (DataItem->Data.Ptr != NULL) {\r
+ FreePool (DataItem->Data.Ptr);\r
+ }\r
+ DataItem->Data.Ptr = NULL;\r
+ DataItem->DataSize = 0;\r
+ DataItem->Status = EFI_NOT_FOUND;\r
}\r
\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
IN VOID *Data\r
)\r
{\r
- IP4_CONFIG2_DATA_ITEM *Item;\r
+ EFI_STATUS Status;\r
+ IP4_CONFIG2_DATA_ITEM *Item;\r
\r
- Item = NULL;\r
+ Status = EFI_SUCCESS;\r
+ Item = NULL;\r
\r
if (Instance->Policy != Ip4Config2PolicyStatic) {\r
return EFI_WRITE_PROTECTED;\r
REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);\r
}\r
\r
- return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
+ if (Data != NULL && DataSize != 0) {\r
+ Status = Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
+ } else {\r
+ //\r
+ // DataSize is 0 and Data is NULL, clean up the DnsServer address. \r
+ //\r
+ if (Item->Data.Ptr != NULL) {\r
+ FreePool (Item->Data.Ptr);\r
+ }\r
+ Item->Data.Ptr = NULL;\r
+ Item->DataSize = 0;\r
+ Item->Status = EFI_NOT_FOUND;\r
+ }\r
+ \r
+ return Status;\r
}\r
\r
/**\r
OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo\r
)\r
{\r
- IfInfo->Name[0] = L'e';\r
- IfInfo->Name[1] = L't';\r
- IfInfo->Name[2] = L'h';\r
- IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip4Config2Instance.IfIndex);\r
- IfInfo->Name[4] = 0;\r
+ UnicodeSPrint (\r
+ IfInfo->Name,\r
+ EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE,\r
+ L"eth%d",\r
+ IpSb->Ip4Config2Instance.IfIndex\r
+ );\r
\r
IfInfo->IfType = IpSb->SnpMode.IfType;\r
IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;\r
network stack was set successfully.\r
@retval EFI_INVALID_PARAMETER One or more of the following are TRUE:\r
- This is NULL.\r
- - Data is NULL.\r
- - One or more fields in Data do not match the requirement of the\r
- data type indicated by DataType.\r
+ - One or more fields in Data and DataSize do not match the \r
+ requirement of the data type indicated by DataType.\r
@retval EFI_WRITE_PROTECTED The specified configuration data is read-only or the specified\r
configuration data cannot be set under the current policy.\r
@retval EFI_ACCESS_DENIED Another set operation on the specified configuration\r
IP4_CONFIG2_INSTANCE *Instance;\r
IP4_SERVICE *IpSb;\r
\r
- if ((This == NULL) || (Data == NULL)) {\r
+ if ((This == NULL) || (Data == NULL && DataSize != 0) || (Data != NULL && DataSize == 0)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);\r
\r
DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];\r
- DataItem->SetData = Ip4Config2SetMaunualAddress;\r
+ DataItem->SetData = Ip4Config2SetManualAddress;\r
DataItem->Status = EFI_NOT_FOUND;\r
\r
DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];\r