]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
NetworkPkg: Fix memory leak problem in PXE driver.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDriver.c
index 8ee831f521a5324c3c07d4d02e944ca2702b908b..8dd787be1a00aed74701804713b3d7a6ff77ed75 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Driver Binding functions implementationfor for UefiPxeBc Driver.\r
 \r
 /** @file\r
   Driver Binding functions implementationfor for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -253,6 +254,7 @@ PxeBcDestroyIp4Children (
            &Private->PxeBc,\r
            NULL\r
            );\r
            &Private->PxeBc,\r
            NULL\r
            );\r
+    FreePool (Private->Ip4Nic->DevicePath);\r
 \r
     if (Private->Snp != NULL) { \r
       //\r
 \r
     if (Private->Snp != NULL) { \r
       //\r
@@ -413,6 +415,8 @@ PxeBcDestroyIp6Children (
            &Private->PxeBc,\r
            NULL\r
            );\r
            &Private->PxeBc,\r
            NULL\r
            );\r
+    FreePool (Private->Ip6Nic->DevicePath);\r
+    \r
     if (Private->Snp != NULL) {\r
       //\r
       // Close SNP from the child virtual handle\r
     if (Private->Snp != NULL) {\r
       //\r
       // Close SNP from the child virtual handle\r
@@ -441,6 +445,103 @@ PxeBcDestroyIp6Children (
   Private->Mode.Ipv6Available = FALSE;\r
 }\r
 \r
   Private->Mode.Ipv6Available = FALSE;\r
 }\r
 \r
+/**\r
+  Check whether UNDI protocol supports IPv6.\r
+\r
+  @param[in]   ControllerHandle  Controller handle.\r
+  @param[in]   Private           Pointer to PXEBC_PRIVATE_DATA.\r
+  @param[out]  Ipv6Support       TRUE if UNDI supports IPv6.\r
+\r
+  @retval EFI_SUCCESS            Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.\r
+  @retval EFI_NOT_FOUND          Don't know whether UNDI supports IPv6 since NII or AIP is not available.\r
+\r
+**/\r
+EFI_STATUS\r
+PxeBcCheckIpv6Support (\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  PXEBC_PRIVATE_DATA           *Private,\r
+  OUT BOOLEAN                      *Ipv6Support\r
+  )\r
+{\r
+  EFI_HANDLE                       Handle;\r
+  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+  EFI_STATUS                       Status;\r
+  EFI_GUID                         *InfoTypesBuffer;\r
+  UINTN                            InfoTypeBufferCount;\r
+  UINTN                            TypeIndex;\r
+  BOOLEAN                          Supported;\r
+  VOID                             *InfoBlock;\r
+  UINTN                            InfoBlockSize;\r
+\r
+  ASSERT (Private != NULL && Ipv6Support != NULL);\r
+\r
+  //\r
+  // Check whether the UNDI supports IPv6 by NII protocol.\r
+  //\r
+  if (Private->Nii != NULL) {\r
+    *Ipv6Support = Private->Nii->Ipv6Supported;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Check whether the UNDI supports IPv6 by AIP protocol.\r
+  //\r
+\r
+  //\r
+  // Get the NIC handle by SNP protocol.\r
+  //  \r
+  Handle = NetLibGetSnpHandle (ControllerHandle, NULL);\r
+  if (Handle == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Aip    = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiAdapterInformationProtocolGuid,\r
+                  (VOID *) &Aip\r
+                  );\r
+  if (EFI_ERROR (Status) || Aip == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  InfoTypesBuffer     = NULL;\r
+  InfoTypeBufferCount = 0;\r
+  Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);\r
+  if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) {\r
+    FreePool (InfoTypesBuffer);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Supported = FALSE;\r
+  for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {\r
+    if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {\r
+      Supported = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (InfoTypesBuffer);\r
+  if (!Supported) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // We now have adapter information block.\r
+  //\r
+  InfoBlock     = NULL;\r
+  InfoBlockSize = 0;\r
+  Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);\r
+  if (EFI_ERROR (Status) || InfoBlock == NULL) {\r
+    FreePool (InfoBlock);\r
+    return EFI_NOT_FOUND;\r
+  }  \r
+\r
+  *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support;\r
+  FreePool (InfoBlock);\r
+  return EFI_SUCCESS;\r
+\r
+}\r
 \r
 /**\r
   Create the opened instances based on IPv4.\r
 \r
 /**\r
   Create the opened instances based on IPv4.\r
@@ -644,6 +745,18 @@ PxeBcCreateIp4Children (
   Private->Ip4Nic->Private   = Private;\r
   Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;\r
 \r
   Private->Ip4Nic->Private   = Private;\r
   Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;\r
 \r
+   //\r
+  // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiIp4Config2ProtocolGuid,\r
+                  (VOID **) &Private->Ip4Config2\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
   //\r
   // Create a device path node for Ipv4 virtual nic, and append it.\r
   //\r
   //\r
   // Create a device path node for Ipv4 virtual nic, and append it.\r
   //\r
@@ -951,6 +1064,30 @@ PxeBcCreateIp6Children (
 \r
   Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;\r
 \r
 \r
   Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;\r
 \r
+  if (Ip6ModeData.AddressList != NULL) {\r
+    FreePool (Ip6ModeData.AddressList);\r
+  }\r
+\r
+  if (Ip6ModeData.GroupTable != NULL) {\r
+    FreePool (Ip6ModeData.GroupTable);\r
+  }\r
+\r
+  if (Ip6ModeData.RouteTable != NULL) {\r
+    FreePool (Ip6ModeData.RouteTable);\r
+  }\r
+\r
+  if (Ip6ModeData.NeighborCache != NULL) {\r
+    FreePool (Ip6ModeData.NeighborCache);\r
+  }\r
+\r
+  if (Ip6ModeData.PrefixTable != NULL) {\r
+    FreePool (Ip6ModeData.PrefixTable);\r
+  }\r
+\r
+  if (Ip6ModeData.IcmpTypeList != NULL) {\r
+    FreePool (Ip6ModeData.IcmpTypeList);\r
+  }\r
+\r
   //\r
   // Locate Ip6->Ip6Config and store it for set IPv6 address.\r
   //\r
   //\r
   // Locate Ip6->Ip6Config and store it for set IPv6 address.\r
   //\r
@@ -1056,7 +1193,18 @@ PxeBcCreateIp6Children (
   // Set IPv6 avaiable flag and set default configure data for\r
   // Udp6Read and Ip6 instance.\r
   //\r
   // Set IPv6 avaiable flag and set default configure data for\r
   // Udp6Read and Ip6 instance.\r
   //\r
-  Private->Mode.Ipv6Available     = TRUE;\r
+  Status = PxeBcCheckIpv6Support (ControllerHandle, Private, &Private->Mode.Ipv6Available);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Fail to get the data whether UNDI supports IPv6. Set default value.\r
+    //\r
+    Private->Mode.Ipv6Available   = TRUE;\r
+  }\r
+\r
+  if (!Private->Mode.Ipv6Available) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
   Udp6CfgData                     = &Private->Udp6CfgData;\r
   Ip6CfgData                      = &Private->Ip6CfgData;\r
 \r
   Udp6CfgData                     = &Private->Udp6CfgData;\r
   Ip6CfgData                      = &Private->Ip6CfgData;\r
 \r
@@ -1400,7 +1548,6 @@ PxeBcStop (
   EFI_LOAD_FILE_PROTOCOL          *LoadFile;\r
   EFI_STATUS                      Status;\r
   EFI_HANDLE                      NicHandle;\r
   EFI_LOAD_FILE_PROTOCOL          *LoadFile;\r
   EFI_STATUS                      Status;\r
   EFI_HANDLE                      NicHandle;\r
-  BOOLEAN                         IsIpv6;\r
   PXEBC_PRIVATE_PROTOCOL          *Id;\r
 \r
   Private    = NULL;\r
   PXEBC_PRIVATE_PROTOCOL          *Id;\r
 \r
   Private    = NULL;\r
@@ -1408,7 +1555,6 @@ PxeBcStop (
   VirtualNic = NULL;\r
   LoadFile   = NULL;\r
   Id         = NULL;\r
   VirtualNic = NULL;\r
   LoadFile   = NULL;\r
   Id         = NULL;\r
-  IsIpv6     = FALSE;\r
 \r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
 \r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r