diff options
author | Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@hpe.com> | 2015-09-30 03:01:13 +0000 |
---|---|---|
committer | sfu5 <sfu5@Edk2> | 2015-09-30 03:01:13 +0000 |
commit | 9feefde0cb4fb4edb8b3e5a0168e756d81f46e79 (patch) | |
tree | b3f716fe207d682445749e2d09dadb5fd972f3bd /MdeModulePkg | |
parent | 33ecfa8af9e36f80d6faf154f64e3d185dd55f5a (diff) | |
download | edk2-9feefde0cb4fb4edb8b3e5a0168e756d81f46e79.tar.gz edk2-9feefde0cb4fb4edb8b3e5a0168e756d81f46e79.tar.bz2 edk2-9feefde0cb4fb4edb8b3e5a0168e756d81f46e79.zip |
MdeModulePkg Ip4Dxe: Ip4Config2 to request DHCP Option6 DNS server IP
Ip4Config2 protocol implementation must request for DNS server info when the
policy is set to DHCP. And when a DHCP server responds to it with a list of
DNS server addresses, it must parse it and set it for the instance. Without
this, nobody can do a Ip4Config->GetData for DNS server IPs before calling
Dns->Configure(). This will mean a DHCP is initiated when calling
Dns->Configure(), thus causing serious performance issues. This patch
attempts to address this issue.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@hpe.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hpe.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18560 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg')
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c | 258 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h | 4 |
2 files changed, 168 insertions, 94 deletions
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index 637d7cd659..edbddba021 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -2,6 +2,7 @@ The implementation of EFI IPv4 Configuration II Protocol.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -677,6 +678,126 @@ 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;
+ 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 = &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;
+ }
+
+ 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
@@ -701,6 +822,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);
@@ -724,6 +848,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 == DHCP_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;
}
@@ -831,9 +993,10 @@ Ip4StartAutoConfig ( // yields the control of this DHCP service to us.
//
ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;
- ParaList.Head.Length = 2;
+ ParaList.Head.Length = 3;
ParaList.Head.Data[0] = DHCP_TAG_NETMASK;
ParaList.Route = DHCP_TAG_ROUTER;
+ ParaList.Dns = DHCP_TAG_DNS_SERVER;
OptionList[0] = &ParaList.Head;
Dhcp4Mode.ConfigData.OptionCount = 1;
Dhcp4Mode.ConfigData.OptionList = OptionList;
@@ -1293,102 +1456,11 @@ 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;
- }
-
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;
- }
-
- CopyMem (Item->Data.Ptr, Data, DataSize);
- Item->DataSize = DataSize;
- Item->Status = EFI_SUCCESS;
- return EFI_SUCCESS;
- }
-
+ return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);
}
/**
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h index e74b9ae407..ab72525646 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h @@ -2,6 +2,7 @@ Definitions for EFI IPv4 Configuration II Protocol implementation.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -27,7 +28,7 @@ #define DHCP_TAG_PARA_LIST 55
#define DHCP_TAG_NETMASK 1
#define DHCP_TAG_ROUTER 3
-
+#define DHCP_TAG_DNS_SERVER 6
#define DATA_ATTRIB_SET(Attrib, Bits) (BOOLEAN)((Attrib) & (Bits))
#define SET_DATA_ATTRIB(Attrib, Bits) ((Attrib) |= (Bits))
@@ -207,6 +208,7 @@ struct _IP4_CONFIG2_INSTANCE { typedef struct {
EFI_DHCP4_PACKET_OPTION Head;
UINT8 Route;
+ UINT8 Dns;
} IP4_CONFIG2_DHCP4_OPTION;
#pragma pack()
|