X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FIp4Dxe%2FIp4Config2Impl.c;h=6c7ac68791c3c3e638731c1d723d6f047496d679;hp=caf84fb7a5fdb097ee5b457dacc32db621970140;hb=a2f4b153ac5d0039f81bb689ad32cd48ac2aa51d;hpb=2c3200072f94313600c6fa9af57715220b51a5fb
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
index caf84fb7a5..6c7ac68791 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
@@ -1,7 +1,8 @@
/** @file
The implementation of EFI IPv4 Configuration II Protocol.
- Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+ (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -141,7 +142,7 @@ Ip4Config2OnPolicyChanged (
IpSb->DefaultRouteTable = RouteTable;
Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
- if (IpSb->State == IP4_SERVICE_CONFIGED) {
+ if (IpSb->State == IP4_SERVICE_CONFIGED || IpSb->State == IP4_SERVICE_STARTED) {
IpSb->State = IP4_SERVICE_UNSTARTED;
}
@@ -414,7 +415,7 @@ Ip4Config2BuildDefaultRouteTable (
//
Count = 0;
- for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {
+ for (Index = IP4_MASK_MAX; Index >= 0; Index--) {
NET_LIST_FOR_EACH (Entry, &(IpSb->DefaultRouteTable->RouteArea[Index])) {
RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
@@ -463,7 +464,7 @@ Ip4Config2OnDhcp4SbInstalled (
/**
Set the station address and subnetmask for the default interface.
- @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] IpSb The pointer to the IP4 service binding instance.
@param[in] StationAddress Ip address to be set.
@param[in] SubnetMask Subnet to be set.
@@ -473,13 +474,12 @@ Ip4Config2OnDhcp4SbInstalled (
**/
EFI_STATUS
Ip4Config2SetDefaultAddr (
- IN IP4_CONFIG2_INSTANCE *Instance,
+ IN IP4_SERVICE *IpSb,
IN IP4_ADDR StationAddress,
IN IP4_ADDR SubnetMask
)
{
EFI_STATUS Status;
- IP4_SERVICE *IpSb;
IP4_INTERFACE *IpIf;
IP4_PROTOCOL *Ip4Instance;
EFI_ARP_PROTOCOL *Arp;
@@ -487,7 +487,6 @@ Ip4Config2SetDefaultAddr (
IP4_ADDR Subnet;
IP4_ROUTE_TABLE *RouteTable;
- IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
IpIf = IpSb->DefaultInterface;
ASSERT (IpIf != NULL);
@@ -496,35 +495,37 @@ Ip4Config2SetDefaultAddr (
return EFI_SUCCESS;
}
- //
- // The default address is changed, free the previous interface first.
- //
- if (IpSb->DefaultRouteTable != NULL) {
- Ip4FreeRouteTable (IpSb->DefaultRouteTable);
- IpSb->DefaultRouteTable = NULL;
- }
+ if (IpSb->Reconfig) {
+ //
+ // The default address is changed, free the previous interface first.
+ //
+ if (IpSb->DefaultRouteTable != NULL) {
+ Ip4FreeRouteTable (IpSb->DefaultRouteTable);
+ IpSb->DefaultRouteTable = NULL;
+ }
- Ip4CancelReceive (IpSb->DefaultInterface);
- Ip4FreeInterface (IpSb->DefaultInterface, NULL);
- IpSb->DefaultInterface = NULL;
- //
- // Create new default interface and route table.
- //
- IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
- if (IpIf == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ Ip4CancelReceive (IpSb->DefaultInterface);
+ Ip4FreeInterface (IpSb->DefaultInterface, NULL);
+ IpSb->DefaultInterface = NULL;
+ //
+ // 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;
+ 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);
}
-
- IpSb->DefaultInterface = IpIf;
- InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
- IpSb->DefaultRouteTable = RouteTable;
- Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
if (IpSb->State == IP4_SERVICE_CONFIGED) {
IpSb->State = IP4_SERVICE_UNSTARTED;
@@ -578,6 +579,8 @@ Ip4Config2SetDefaultAddr (
);
IpSb->State = IP4_SERVICE_CONFIGED;
+ IpSb->Reconfig = FALSE;
+
return EFI_SUCCESS;
}
@@ -604,7 +607,9 @@ Ip4Config2SetDefaultIf (
EFI_STATUS Status;
IP4_SERVICE *IpSb;
- Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -612,7 +617,6 @@ Ip4Config2SetDefaultIf (
//
// Create a route if there is a default router.
//
- IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
if (GatewayAddress != IP4_ALLZERO_ADDRESS) {
Ip4AddRoute (
IpSb->DefaultRouteTable,
@@ -673,6 +677,119 @@ Ip4Config2CleanDhcp4 (
}
}
+/**
+ This worker function sets the DNS server list for the EFI IPv4 network
+ stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL
+ manages. The DNS server addresses must be unicast IPv4 addresses.
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] DataSize The size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set, points to an array of
+ EFI_IPv4_ADDRESS instances.
+
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.
+ @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.
+ @retval EFI_ABORTED The DNS server addresses to be set equal the current
+ configuration.
+ @retval EFI_SUCCESS The specified configuration data for the EFI IPv4
+ network stack was set.
+
+**/
+EFI_STATUS
+Ip4Config2SetDnsServerWorker (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ UINTN OldIndex;
+ UINTN NewIndex;
+ EFI_IPv4_ADDRESS *OldDns;
+ EFI_IPv4_ADDRESS *NewDns;
+ UINTN OldDnsCount;
+ UINTN NewDnsCount;
+ IP4_CONFIG2_DATA_ITEM *Item;
+ BOOLEAN OneAdded;
+ VOID *Tmp;
+ IP4_ADDR DnsAddress;
+
+ if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
+ NewDns = (EFI_IPv4_ADDRESS *) Data;
+ OldDns = Item->Data.DnsServers;
+ NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
+ OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);
+ OneAdded = FALSE;
+
+ if (NewDnsCount != OldDnsCount) {
+ Tmp = AllocatePool (DataSize);
+ if (Tmp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ Tmp = NULL;
+ }
+
+ for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
+ CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));
+ if (IP4_IS_UNSPECIFIED (NTOHL (DnsAddress)) || IP4_IS_LOCAL_BROADCAST (NTOHL (DnsAddress))) {
+ //
+ // The dns server address must be unicast.
+ //
+ if (Tmp != NULL) {
+ FreePool (Tmp);
+ }
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (OneAdded) {
+ //
+ // If any address in the new setting is not in the old settings, skip the
+ // comparision below.
+ //
+ continue;
+ }
+
+ for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
+ if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+ //
+ // If found break out.
+ //
+ break;
+ }
+ }
+
+ if (OldIndex == OldDnsCount) {
+ OneAdded = TRUE;
+ }
+ }
+
+ if (!OneAdded && (DataSize == Item->DataSize)) {
+ //
+ // No new item is added and the size is the same.
+ //
+ Item->Status = EFI_SUCCESS;
+ return EFI_ABORTED;
+ } else {
+ if (Tmp != NULL) {
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
+ }
+ Item->Data.Ptr = Tmp;
+ }
+
+ CopyMem (Item->Data.Ptr, Data, DataSize);
+ Item->DataSize = DataSize;
+ Item->Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+ }
+}
+
+
/**
Callback function when DHCP process finished. It will save the
@@ -697,6 +814,9 @@ Ip4Config2OnDhcp4Complete (
IP4_ADDR StationAddress;
IP4_ADDR SubnetMask;
IP4_ADDR GatewayAddress;
+ UINT32 Index;
+ UINT32 OptionCount;
+ EFI_DHCP4_PACKET_OPTION **OptionList;
Instance = (IP4_CONFIG2_INSTANCE *) Context;
ASSERT (Instance->Dhcp4 != NULL);
@@ -720,6 +840,44 @@ Ip4Config2OnDhcp4Complete (
goto Exit;
}
+ //
+ // Parse the ACK to get required DNS server information.
+ //
+ OptionCount = 0;
+ OptionList = NULL;
+
+ Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ goto Exit;
+ }
+
+ OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
+ if (OptionList == NULL) {
+ goto Exit;
+ }
+
+ Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);
+ if (EFI_ERROR (Status)) {
+ FreePool (OptionList);
+ goto Exit;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ //
+ // Look for DNS Server opcode (6).
+ //
+ if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) {
+ if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {
+ break;
+ }
+
+ Ip4Config2SetDnsServerWorker (Instance, OptionList[Index]->Length, &OptionList[Index]->Data[0]);
+ break;
+ }
+ }
+
+ FreePool (OptionList);
+
Instance->DhcpSuccess = TRUE;
}
@@ -736,7 +894,7 @@ Exit:
@param[in] Instance The IP4 config2 instance to configure
- @retval EFI_SUCCESS The auto configuration is successfull started
+ @retval EFI_SUCCESS The auto configuration is successfully started
@retval Others Failed to start auto configuration.
**/
@@ -826,10 +984,11 @@ Ip4StartAutoConfig (
// DHCP configuration to avoid problems if some DHCP client
// yields the control of this DHCP service to us.
//
- ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;
- ParaList.Head.Length = 2;
- ParaList.Head.Data[0] = DHCP_TAG_NETMASK;
- ParaList.Route = DHCP_TAG_ROUTER;
+ ParaList.Head.OpCode = DHCP4_TAG_PARA_LIST;
+ ParaList.Head.Length = 3;
+ ParaList.Head.Data[0] = DHCP4_TAG_NETMASK;
+ ParaList.Route = DHCP4_TAG_ROUTER;
+ ParaList.Dns = DHCP4_TAG_DNS_SERVER;
OptionList[0] = &ParaList.Head;
Dhcp4Mode.ConfigData.OptionCount = 1;
Dhcp4Mode.ConfigData.OptionList = OptionList;
@@ -893,7 +1052,6 @@ Ip4Config2GetIfInfo (
IN VOID *Data OPTIONAL
)
{
-
IP4_SERVICE *IpSb;
UINTN Length;
IP4_CONFIG2_DATA_ITEM *Item;
@@ -977,40 +1135,43 @@ Ip4Config2SetPolicy (
}
if (NewPolicy == Instance->Policy) {
- return EFI_ABORTED;
+ if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) {
+ return EFI_ABORTED;
+ }
} else {
- if (NewPolicy == Ip4Config2PolicyDhcp) {
- //
- // The policy is changed from static to dhcp:
- // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
- // data size, and fire up all the related events.
- //
- DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
- if (DataItem->Data.Ptr != NULL) {
- FreePool (DataItem->Data.Ptr);
- }
- DataItem->Data.Ptr = NULL;
- DataItem->DataSize = 0;
- DataItem->Status = EFI_NOT_FOUND;
- NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+ //
+ // The policy is changed. Clean the ManualAddress, Gateway and DnsServers,
+ // shrink the variable data size, and fire up all the related events.
+ //
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
- DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
- if (DataItem->Data.Ptr != NULL) {
- FreePool (DataItem->Data.Ptr);
- }
- DataItem->Data.Ptr = NULL;
- DataItem->DataSize = 0;
- DataItem->Status = EFI_NOT_FOUND;
- NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
- DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
- if (DataItem->Data.Ptr != NULL) {
- FreePool (DataItem->Data.Ptr);
- }
- DataItem->Data.Ptr = NULL;
- DataItem->DataSize = 0;
- DataItem->Status = EFI_NOT_FOUND;
- NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+
+ if (NewPolicy == Ip4Config2PolicyDhcp) {
+ SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_VOLATILE);
} else {
//
// The policy is changed from dhcp to static. Stop the DHCPv4 process
@@ -1025,6 +1186,7 @@ Ip4Config2SetPolicy (
//
if (Instance->Dhcp4Event != NULL) {
gBS->CloseEvent (Instance->Dhcp4Event);
+ Instance->Dhcp4Event = NULL;
}
}
}
@@ -1071,6 +1233,9 @@ Ip4Config2SetMaunualAddress (
IP4_ADDR StationAddress;
IP4_ADDR SubnetMask;
VOID *Ptr;
+ IP4_SERVICE *IpSb;
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY);
@@ -1084,6 +1249,13 @@ Ip4Config2SetMaunualAddress (
NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);
+ StationAddress = EFI_NTOHL (NewAddress.Address);
+ SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
+
+ if (NetGetMaskLength (SubnetMask) == IP4_MASK_NUM) {
+ return EFI_INVALID_PARAMETER;
+ }
+
//
// Store the new data, and init the DataItem status to EFI_NOT_READY because
// we may have an asynchronous configuration process.
@@ -1102,25 +1274,19 @@ Ip4Config2SetMaunualAddress (
DataItem->DataSize = DataSize;
DataItem->Status = EFI_NOT_READY;
- StationAddress = EFI_NTOHL (NewAddress.Address);
- SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
-
- Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
+ IpSb->Reconfig = TRUE;
+ Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
- DataItem->Status = EFI_SUCCESS;
+ DataItem->Status = Status;
-ON_EXIT:
- if (EFI_ERROR (DataItem->Status)) {
+ if (EFI_ERROR (DataItem->Status) && DataItem->Status != EFI_NOT_READY) {
if (Ptr != NULL) {
FreePool (Ptr);
}
DataItem->Data.Ptr = NULL;
}
- return EFI_SUCCESS;
+ return Status;
}
/**
@@ -1174,14 +1340,15 @@ Ip4Config2SetGateway (
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 (!NetIp4IsUnicast (NTOHL (Gateway), 0)) {
+ if ((IpSb->DefaultInterface->SubnetMask != 0) &&
+ !NetIp4IsUnicast (NTOHL (Gateway), IpSb->DefaultInterface->SubnetMask)) {
return EFI_INVALID_PARAMETER;
}
@@ -1192,7 +1359,6 @@ Ip4Config2SetGateway (
}
}
- IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
OldGateway = DataItem->Data.Gateway;
OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);
@@ -1285,102 +1451,21 @@ Ip4Config2SetDnsServer (
IN VOID *Data
)
{
- UINTN OldIndex;
- UINTN NewIndex;
- UINTN Index1;
- EFI_IPv4_ADDRESS *OldDns;
- EFI_IPv4_ADDRESS *NewDns;
- UINTN OldDnsCount;
- UINTN NewDnsCount;
IP4_CONFIG2_DATA_ITEM *Item;
- BOOLEAN OneAdded;
- VOID *Tmp;
- IP4_ADDR DnsAddress;
- if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
- return EFI_BAD_BUFFER_SIZE;
- }
+ Item = NULL;
if (Instance->Policy != Ip4Config2PolicyStatic) {
return EFI_WRITE_PROTECTED;
}
- Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
- NewDns = (EFI_IPv4_ADDRESS *) Data;
- OldDns = Item->Data.DnsServers;
- NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
- OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);
- OneAdded = FALSE;
-
- if (NewDnsCount != OldDnsCount) {
- Tmp = AllocatePool (DataSize);
- if (Tmp == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- Tmp = NULL;
- }
-
- for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
- CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));
-
- if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {
- //
- // The dns server address must be unicast.
- //
- FreePool (Tmp);
- return EFI_INVALID_PARAMETER;
- }
-
- for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {
- if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {
- FreePool (Tmp);
- return EFI_INVALID_PARAMETER;
- }
- }
-
- if (OneAdded) {
- //
- // If any address in the new setting is not in the old settings, skip the
- // comparision below.
- //
- continue;
- }
-
- for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
- if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
- //
- // If found break out.
- //
- break;
- }
- }
-
- if (OldIndex == OldDnsCount) {
- OneAdded = TRUE;
- }
- }
-
- if (!OneAdded && (DataSize == Item->DataSize)) {
- //
- // No new item is added and the size is the same.
- //
- Item->Status = EFI_SUCCESS;
- return EFI_ABORTED;
- } else {
- if (Tmp != NULL) {
- if (Item->Data.Ptr != NULL) {
- FreePool (Item->Data.Ptr);
- }
- Item->Data.Ptr = Tmp;
- }
+ Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
- CopyMem (Item->Data.Ptr, Data, DataSize);
- Item->DataSize = DataSize;
- Item->Status = EFI_SUCCESS;
- return EFI_SUCCESS;
+ if (DATA_ATTRIB_SET (Item->Attribute, DATA_ATTRIB_VOLATILE)) {
+ REMOVE_DATA_ATTRIB (Item->Attribute, DATA_ATTRIB_VOLATILE);
}
+ return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);
}
/**
@@ -1397,11 +1482,12 @@ Ip4Config2InitIfInfo (
OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo
)
{
- IfInfo->Name[0] = L'e';
- IfInfo->Name[1] = L't';
- IfInfo->Name[2] = L'h';
- IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip4Config2Instance.IfIndex);
- IfInfo->Name[4] = 0;
+ UnicodeSPrint (
+ IfInfo->Name,
+ EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE,
+ L"eth%d",
+ IpSb->Ip4Config2Instance.IfIndex
+ );
IfInfo->IfType = IpSb->SnpMode.IfType;
IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;
@@ -1828,7 +1914,7 @@ Ip4Config2InitInstance (
DataItem->SetData = Ip4Config2SetPolicy;
DataItem->Data.Ptr = &Instance->Policy;
DataItem->DataSize = sizeof (Instance->Policy);
- Instance->Policy = Ip4Config2PolicyDhcp;
+ Instance->Policy = Ip4Config2PolicyStatic;
SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);
DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
@@ -1859,6 +1945,8 @@ Ip4Config2InitInstance (
//
// Try to read the config data from NV variable.
+ // If not found, write initialized config data into NV variable
+ // as a default config data.
//
Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);
if (Status == EFI_NOT_FOUND) {
@@ -1868,21 +1956,7 @@ Ip4Config2InitInstance (
if (EFI_ERROR (Status)) {
return Status;
}
-
- //
- // Try to set the configured parameter.
- //
- for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; Index++) {
- DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];
- if (DataItem->Data.Ptr != NULL) {
- DataItem->SetData (
- &IpSb->Ip4Config2Instance,
- DataItem->DataSize,
- DataItem->Data.Ptr
- );
- }
- }
-
+
Instance->Ip4Config2.SetData = EfiIp4Config2SetData;
Instance->Ip4Config2.GetData = EfiIp4Config2GetData;
Instance->Ip4Config2.RegisterDataNotify = EfiIp4Config2RegisterDataNotify;
@@ -1927,6 +2001,7 @@ Ip4Config2CleanInstance (
//
if (Instance->Dhcp4Event != NULL) {
gBS->CloseEvent (Instance->Dhcp4Event);
+ Instance->Dhcp4Event = NULL;
}
for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
@@ -1949,3 +2024,53 @@ Ip4Config2CleanInstance (
RemoveEntryList (&Instance->Link);
}
+/**
+ The event handle for IP4 auto reconfiguration. The original default
+ interface and route table will be removed as the default.
+
+ @param[in] Context The IP4 service binding instance.
+
+**/
+VOID
+EFIAPI
+Ip4AutoReconfigCallBackDpc (
+ IN VOID *Context
+ )
+{
+ IP4_SERVICE *IpSb;
+
+ IpSb = (IP4_SERVICE *) Context;
+ NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
+
+ if (IpSb->State > IP4_SERVICE_UNSTARTED) {
+ IpSb->State = IP4_SERVICE_UNSTARTED;
+ }
+
+ IpSb->Reconfig = TRUE;
+
+ Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
+
+ return ;
+}
+
+
+/**
+ Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.
+
+ @param Event The event that is signalled.
+ @param Context The IP4 service binding instance.
+
+**/
+VOID
+EFIAPI
+Ip4AutoReconfigCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK
+ //
+ QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);
+}
+