]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiDhcp.c
UefiCpuPkg CpuCommFeaturesLib: Fix GP fault issue about ProcTrace
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiDhcp.c
index 3706256db5f76e676035117383ad19be93a4bc05..d8c9fff6c65d8406149a88c7fd4af8e1163c430c 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   iSCSI DHCP4 related configuration routines.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -123,11 +117,25 @@ IScsiDhcpExtractRootPath (
     IpMode = ConfigData->AutoConfigureMode;\r
   }\r
 \r
-  Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);\r
-  CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));\r
+  //\r
+  // Server name is expressed as domain name, just save it.\r
+  //\r
+  if ((!NET_IS_DIGIT (*(Field->Str))) && (*(Field->Str) != '[')) {\r
+    ConfigNvData->DnsMode = TRUE;\r
+    if (Field->Len > sizeof (ConfigNvData->TargetUrl)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    CopyMem (&ConfigNvData->TargetUrl, Field->Str, Field->Len);\r
+    ConfigNvData->TargetUrl[Field->Len + 1] = '\0';\r
+  } else {\r
+    ConfigNvData->DnsMode = FALSE;\r
+    ZeroMem(ConfigNvData->TargetUrl, sizeof (ConfigNvData->TargetUrl));\r
+    Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);\r
+    CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_EXIT;\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_EXIT;\r
+    }\r
   }\r
   //\r
   // Check the protocol type.\r
@@ -175,7 +183,7 @@ IScsiDhcpExtractRootPath (
     goto ON_EXIT;\r
   }\r
 \r
-  AsciiStrCpy (ConfigNvData->TargetName, Field->Str);\r
+  AsciiStrCpyS (ConfigNvData->TargetName, ISCSI_NAME_MAX_SIZE, Field->Str);\r
 \r
 ON_EXIT:\r
 \r
@@ -187,14 +195,14 @@ ON_EXIT:
 /**\r
   The callback function registerd to the DHCP4 instance that is used to select\r
   the qualified DHCP OFFER.\r
-  \r
+\r
   @param[in]  This         The DHCP4 protocol.\r
   @param[in]  Context      The context set when configuring the DHCP4 protocol.\r
   @param[in]  CurrentState The current state of the DHCP4 protocol.\r
   @param[in]  Dhcp4Event   The event occurs in the current state.\r
-  @param[in]  Packet       The DHCP packet that is to be sent or was already received. \r
+  @param[in]  Packet       The DHCP packet that is to be sent or was already received.\r
   @param[out] NewPacket    The packet used to replace the above Packet.\r
-  \r
+\r
   @retval EFI_SUCCESS      Either the DHCP OFFER is qualified or we're not intereseted\r
                            in the Dhcp4Event.\r
   @retval EFI_NOT_READY    The DHCP OFFER packet doesn't match our requirements.\r
@@ -240,7 +248,7 @@ IScsiDhcpSelectOffer (
   }\r
 \r
   for (Index = 0; Index < OptionCount; Index++) {\r
-    if (OptionList[Index]->OpCode != DHCP4_TAG_ROOT_PATH) {\r
+    if (OptionList[Index]->OpCode != DHCP4_TAG_ROOTPATH) {\r
       continue;\r
     }\r
 \r
@@ -253,7 +261,7 @@ IScsiDhcpSelectOffer (
     break;\r
   }\r
 \r
-  if ((Index == OptionCount)) {\r
+  if (Index == OptionCount) {\r
     Status = EFI_NOT_READY;\r
   }\r
 \r
@@ -326,7 +334,7 @@ IScsiParseDhcpAck (
     //\r
     // Get DNS server addresses and DHCP server address from this offer.\r
     //\r
-    if (OptionList[Index]->OpCode == DHCP4_TAG_DNS) {\r
+    if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) {\r
 \r
       if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {\r
         Status = EFI_INVALID_PARAMETER;\r
@@ -358,6 +366,50 @@ IScsiParseDhcpAck (
   return Status;\r
 }\r
 \r
+/**\r
+  This function will switch the IP4 configuration policy to Static.\r
+\r
+  @param[in]  Ip4Config2          Pointer to the IP4 configuration protocol.\r
+\r
+  @retval     EFI_SUCCESS         The policy is already configured to static.\r
+  @retval     Others              Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+IScsiSetIp4Policy (\r
+  IN EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2\r
+  )\r
+{\r
+  EFI_IP4_CONFIG2_POLICY          Policy;\r
+  EFI_STATUS                      Status;\r
+  UINTN                           DataSize;\r
+\r
+  DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);\r
+  Status = Ip4Config2->GetData (\r
+                         Ip4Config2,\r
+                         Ip4Config2DataTypePolicy,\r
+                         &DataSize,\r
+                         &Policy\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (Policy != Ip4Config2PolicyStatic) {\r
+    Policy = Ip4Config2PolicyStatic;\r
+    Status= Ip4Config2->SetData (\r
+                          Ip4Config2,\r
+                          Ip4Config2DataTypePolicy,\r
+                          sizeof (EFI_IP4_CONFIG2_POLICY),\r
+                          &Policy\r
+                          );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Parse the DHCP ACK to get the address configuration and DNS information.\r
@@ -380,26 +432,44 @@ IScsiDoDhcp (
   )\r
 {\r
   EFI_HANDLE                    Dhcp4Handle;\r
+  EFI_IP4_CONFIG2_PROTOCOL      *Ip4Config2;\r
   EFI_DHCP4_PROTOCOL            *Dhcp4;\r
   EFI_STATUS                    Status;\r
   EFI_DHCP4_PACKET_OPTION       *ParaList;\r
   EFI_DHCP4_CONFIG_DATA         Dhcp4ConfigData;\r
   ISCSI_SESSION_CONFIG_NVDATA   *NvData;\r
-  BOOLEAN                       MediaPresent;\r
+  EFI_STATUS                    MediaStatus;\r
 \r
   Dhcp4Handle = NULL;\r
+  Ip4Config2  = NULL;\r
   Dhcp4       = NULL;\r
   ParaList    = NULL;\r
 \r
   //\r
   // Check media status before doing DHCP.\r
   //\r
-  MediaPresent = TRUE;\r
-  NetLibDetectMedia (Controller, &MediaPresent);\r
-  if (!MediaPresent) {\r
+  MediaStatus = EFI_SUCCESS;\r
+  NetLibDetectMediaWaitTimeout (Controller, ISCSI_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus);\r
+  if (MediaStatus!= EFI_SUCCESS) {\r
+    AsciiPrint ("\n  Error: Could not detect network connection.\n");\r
     return EFI_NO_MEDIA;\r
   }\r
 \r
+  //\r
+  // DHCP4 service allows only one of its children to be configured in\r
+  // the active state, If the DHCP4 D.O.R.A started by IP4 auto\r
+  // configuration and has not been completed, the Dhcp4 state machine\r
+  // will not be in the right state for the iSCSI to start a new round D.O.R.A.\r
+  // So, we need to switch it's policy to static.\r
+  //\r
+  Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = IScsiSetIp4Policy (Ip4Config2);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
   //\r
   // Create a DHCP4 child instance and get the protocol.\r
   //\r
@@ -440,8 +510,8 @@ IScsiDoDhcp (
   ParaList->Length  = (UINT8) (NvData->TargetInfoFromDhcp ? 4 : 3);\r
   ParaList->Data[0] = DHCP4_TAG_NETMASK;\r
   ParaList->Data[1] = DHCP4_TAG_ROUTER;\r
-  ParaList->Data[2] = DHCP4_TAG_DNS;\r
-  ParaList->Data[3] = DHCP4_TAG_ROOT_PATH;\r
+  ParaList->Data[2] = DHCP4_TAG_DNS_SERVER;\r
+  ParaList->Data[3] = DHCP4_TAG_ROOTPATH;\r
 \r
   ZeroMem (&Dhcp4ConfigData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
   Dhcp4ConfigData.OptionCount = 1;\r