]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Ip6Dxe/Ip6ConfigNv.c
Refine code to make it more safely.
[mirror_edk2.git] / NetworkPkg / Ip6Dxe / Ip6ConfigNv.c
index ef5ea2e13a408476bf32f08eb83e543db75a15a9..4716f797d4cd8f878d08354a4f7c0a431fd2afdc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Helper functions for configuring or obtaining the parameters relating to IP6.\r
 \r
 /** @file\r
   Helper functions for configuring or obtaining the parameters relating to IP6.\r
 \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2014, 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
@@ -15,8 +15,6 @@
 \r
 #include "Ip6Impl.h"\r
 \r
 \r
 #include "Ip6Impl.h"\r
 \r
-EFI_GUID  mIp6HiiVendorDevicePathGuid = IP6_HII_VENDOR_DEVICE_PATH_GUID;\r
-EFI_GUID  mIp6ConfigNvDataGuid        = IP6_CONFIG_NVDATA_GUID;\r
 CHAR16    mIp6ConfigStorageName[]     = L"IP6_CONFIG_IFR_NVDATA";\r
 \r
 /**\r
 CHAR16    mIp6ConfigStorageName[]     = L"IP6_CONFIG_IFR_NVDATA";\r
 \r
 /**\r
@@ -556,7 +554,7 @@ Ip6ConvertAddressListToString (
 \r
   Status = HiiUpdateForm (\r
              HiiHandle,                       // HII handle\r
 \r
   Status = HiiUpdateForm (\r
              HiiHandle,                       // HII handle\r
-             &mIp6ConfigNvDataGuid,           // Formset GUID\r
+             &gIp6ConfigNvDataGuid,           // Formset GUID\r
              FORMID_MAIN_FORM,                // Form ID\r
              StartOpCodeHandle,               // Label for where to insert opcodes\r
              EndOpCodeHandle                  // Replace data\r
              FORMID_MAIN_FORM,                // Form ID\r
              StartOpCodeHandle,               // Label for where to insert opcodes\r
              EndOpCodeHandle                  // Replace data\r
@@ -602,6 +600,7 @@ Ip6ParseAddressListFromString (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  ZeroMem (&AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));\r
   LocalString = (CHAR16 *) AllocateCopyPool (StrSize (String), String);\r
   if (LocalString == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   LocalString = (CHAR16 *) AllocateCopyPool (StrSize (String), String);\r
   if (LocalString == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -671,9 +670,8 @@ Error:
 \r
 /**\r
   This function converts the interface info to string and draws it to the IP6 UI.\r
 \r
 /**\r
   This function converts the interface info to string and draws it to the IP6 UI.\r
-  The interface information includes interface name, interface type, hardware address,\r
-  address info, and route table information. The address information is also used as the\r
-  content of manual addresses in IP6 UI.\r
+  The interface information includes interface name, interface type, hardware\r
+  address and route table information.\r
 \r
   @param[in]       IfInfo          The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.\r
   @param[in]       HiiHandle       The handle that was previously registered in the\r
 \r
   @param[in]       IfInfo          The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.\r
   @param[in]       HiiHandle       The handle that was previously registered in the\r
@@ -695,11 +693,9 @@ Ip6ConvertInterfaceInfoToString (
   UINT32                         Index;\r
   UINTN                          Number;\r
   CHAR16                         *String;\r
   UINT32                         Index;\r
   UINTN                          Number;\r
   CHAR16                         *String;\r
-  CHAR16                         *LinkLocalStr;\r
   CHAR16                         PortString[ADDRESS_STR_MAX_SIZE];\r
   CHAR16                         FormatString[8];\r
   EFI_STRING_ID                  StringId;\r
   CHAR16                         PortString[ADDRESS_STR_MAX_SIZE];\r
   CHAR16                         FormatString[8];\r
   EFI_STRING_ID                  StringId;\r
-  EFI_STATUS                     Status;\r
 \r
   if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -784,54 +780,7 @@ Ip6ConvertInterfaceInfoToString (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  //\r
-  // Print the host address Information.\r
-  //\r
-  Status = Ip6ConvertAddressListToString (\r
-             PortString,\r
-             HiiHandle,\r
-             Ip6ConfigNvHostAddress,\r
-             IfInfo->AddressInfo,\r
-             IfInfo->AddressInfoCount\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Copy the Host Address Info to manual address field.\r
-  // Do not copy the link local address.\r
-  //\r
-  LinkLocalStr = StrStr (PortString, IP6_LINK_LOCAL_PREFIX);\r
-  if (LinkLocalStr != NULL) {\r
-    Number = LinkLocalStr - PortString;\r
-    if (Number > 0) {\r
-      CopyMem (IfrNvData->ManualAddress, PortString, Number * sizeof (CHAR16));\r
-    }\r
-\r
-    while ((*LinkLocalStr != L' ') && (*LinkLocalStr != L'\0')) {\r
-      LinkLocalStr++;\r
-    }\r
-\r
-    if (*LinkLocalStr != L'\0') {\r
-      LinkLocalStr++;\r
-      StrCat (IfrNvData->ManualAddress, LinkLocalStr);\r
-    }\r
-  } else {\r
-    StrCpy (IfrNvData->ManualAddress, PortString);\r
-  }\r
-\r
-  //\r
-  // Print the route table information.\r
-  //\r
-  Status = Ip6ConvertAddressListToString (\r
-             PortString,\r
-             HiiHandle,\r
-             Ip6ConfigNvRouteTable,\r
-             IfInfo->RouteTable,\r
-             IfInfo->RouteCount\r
-             );\r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -930,11 +879,11 @@ Ip6ConvertConfigNvDataToIfrNvData (
   IN     IP6_CONFIG_INSTANCE         *Instance\r
   )\r
 {\r
   IN     IP6_CONFIG_INSTANCE         *Instance\r
   )\r
 {\r
+  IP6_CONFIG_NVDATA                          *Ip6NvData;\r
   EFI_IP6_CONFIG_PROTOCOL                    *Ip6Config;\r
   UINTN                                      DataSize;\r
   VOID                                       *Data;\r
   EFI_STATUS                                 Status;\r
   EFI_IP6_CONFIG_PROTOCOL                    *Ip6Config;\r
   UINTN                                      DataSize;\r
   VOID                                       *Data;\r
   EFI_STATUS                                 Status;\r
-  EFI_IP6_CONFIG_INTERFACE_ID                InterfaceId;\r
   EFI_IP6_CONFIG_POLICY                      Policy;\r
   EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS   DadXmits;\r
   EFI_HII_HANDLE                             HiiHandle;\r
   EFI_IP6_CONFIG_POLICY                      Policy;\r
   EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS   DadXmits;\r
   EFI_HII_HANDLE                             HiiHandle;\r
@@ -946,6 +895,7 @@ Ip6ConvertConfigNvDataToIfrNvData (
   NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
 \r
   Ip6Config = &Instance->Ip6Config;\r
   NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
 \r
   Ip6Config = &Instance->Ip6Config;\r
+  Ip6NvData = &Instance->Ip6NvData;\r
   Data      = NULL;\r
   DataSize  = 0;\r
   HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
   Data      = NULL;\r
   DataSize  = 0;\r
   HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
@@ -979,18 +929,18 @@ Ip6ConvertConfigNvDataToIfrNvData (
   // Get the interface id.\r
   //\r
   DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);\r
   // Get the interface id.\r
   //\r
   DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);\r
-  ZeroMem (&InterfaceId, DataSize);\r
+  ZeroMem (&Ip6NvData->InterfaceId, DataSize);\r
   Status = Ip6Config->GetData (\r
                         Ip6Config,\r
                         Ip6ConfigDataTypeAltInterfaceId,\r
                         &DataSize,\r
   Status = Ip6Config->GetData (\r
                         Ip6Config,\r
                         Ip6ConfigDataTypeAltInterfaceId,\r
                         &DataSize,\r
-                        &InterfaceId\r
+                        &Ip6NvData->InterfaceId\r
                         );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
                         );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
-  Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &InterfaceId);\r
+  Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
 \r
   //\r
   // Get current policy.\r
 \r
   //\r
   // Get current policy.\r
@@ -1034,75 +984,6 @@ Ip6ConvertConfigNvDataToIfrNvData (
 \r
   IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;\r
 \r
 \r
   IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;\r
 \r
-  //\r
-  // Get DNS server list.\r
-  //\r
-  FreePool (Data);\r
-  Data     = NULL;\r
-  DataSize = 0;\r
-  Status   = Ip6ConfigNvGetData (\r
-               Ip6Config,\r
-               Ip6ConfigDataTypeDnsServer,\r
-               &DataSize,\r
-               (VOID **) &Data\r
-               );\r
-\r
-  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
-    goto Exit;\r
-  }\r
-\r
-  if (DataSize > 0) {\r
-    //\r
-    // Convert the DNS server address to string and draw it to UI.\r
-    //\r
-    Status = Ip6ConvertAddressListToString (\r
-               IfrNvData->DnsAddress,\r
-               HiiHandle,\r
-               Ip6ConfigNvDnsAddress,\r
-               Data,\r
-               DataSize / sizeof (EFI_IPv6_ADDRESS)\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    FreePool (Data);\r
-    Data = NULL;\r
-  }\r
-\r
-  //\r
-  // Get gateway adderss list.\r
-  //\r
-  DataSize = 0;\r
-  Status   = Ip6ConfigNvGetData (\r
-               Ip6Config,\r
-               Ip6ConfigDataTypeGateway,\r
-               &DataSize,\r
-               (VOID **) &Data\r
-               );\r
-\r
-  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
-    goto Exit;\r
-  }\r
-\r
-  if (DataSize > 0) {\r
-    //\r
-    // Convert the gateway address to string and draw it to UI.\r
-    //\r
-    Status = Ip6ConvertAddressListToString (\r
-               IfrNvData->GatewayAddress,\r
-               HiiHandle,\r
-               Ip6ConfigNvGatewayAddress,\r
-               Data,\r
-               DataSize / sizeof (EFI_IPv6_ADDRESS)\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
 Exit:\r
   if (Data != NULL) {\r
      FreePool (Data);\r
 Exit:\r
   if (Data != NULL) {\r
      FreePool (Data);\r
@@ -1113,8 +994,7 @@ Exit:
 \r
 /**\r
   Convert IFR data into IP6 configuration data. The policy, alternative interface\r
 \r
 /**\r
   Convert IFR data into IP6 configuration data. The policy, alternative interface\r
-  ID, and DAD transmit counts, and will be saved. If under manual policy, the configured\r
-  manual address, gateway address, and DNS server address will be saved.\r
+  ID, and DAD transmit counts, and will be saved. \r
 \r
   @param[in]       IfrNvData       The IFR NV data.\r
   @param[in, out]  Instance        The IP6 config instance data.\r
 \r
   @param[in]       IfrNvData       The IFR NV data.\r
   @param[in, out]  Instance        The IP6 config instance data.\r
@@ -1125,7 +1005,7 @@ Exit:
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-Ip6ConvertIfrNvDataToConfigNvData (\r
+Ip6ConvertIfrNvDataToConfigNvDataGeneral (\r
   IN     IP6_CONFIG_IFR_NVDATA       *IfrNvData,\r
   IN OUT IP6_CONFIG_INSTANCE         *Instance\r
   )\r
   IN     IP6_CONFIG_IFR_NVDATA       *IfrNvData,\r
   IN OUT IP6_CONFIG_INSTANCE         *Instance\r
   )\r
@@ -1133,12 +1013,6 @@ Ip6ConvertIfrNvDataToConfigNvData (
   IP6_CONFIG_NVDATA                  *Ip6NvData;\r
   EFI_IP6_CONFIG_PROTOCOL            *Ip6Config;\r
   EFI_STATUS                         Status;\r
   IP6_CONFIG_NVDATA                  *Ip6NvData;\r
   EFI_IP6_CONFIG_PROTOCOL            *Ip6Config;\r
   EFI_STATUS                         Status;\r
-  EFI_IP6_CONFIG_MANUAL_ADDRESS      *ManualAddress;\r
-  EFI_IPv6_ADDRESS                   *Address;\r
-  BOOLEAN                            IsAddressOk;\r
-  EFI_EVENT                          SetAddressEvent;\r
-  EFI_EVENT                          TimeoutEvent;\r
-  UINTN                              DataSize;\r
 \r
   if ((IfrNvData == NULL) || (Instance == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if ((IfrNvData == NULL) || (Instance == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1198,11 +1072,67 @@ Ip6ConvertIfrNvDataToConfigNvData (
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert IFR data into IP6 configuration data. The policy, configured\r
+  manual address, gateway address, and DNS server address will be saved.\r
+\r
+  @param[in]       IfrNvData       The IFR NV data.\r
+  @param[in, out]  Instance        The IP6 config instance data.\r
+\r
+  @retval EFI_SUCCESS              The operation finished successfully.\r
+  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.\r
+  @retval Others                   Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip6ConvertIfrNvDataToConfigNvDataAdvanced (\r
+  IN     IP6_CONFIG_IFR_NVDATA       *IfrNvData,\r
+  IN OUT IP6_CONFIG_INSTANCE         *Instance\r
+  )\r
+{\r
+  IP6_CONFIG_NVDATA                  *Ip6NvData;\r
+  EFI_IP6_CONFIG_PROTOCOL            *Ip6Config;\r
+  EFI_STATUS                         Status;\r
+  EFI_IP6_CONFIG_MANUAL_ADDRESS      *ManualAddress;\r
+  EFI_IPv6_ADDRESS                   *Address;\r
+  BOOLEAN                            IsAddressOk;\r
+  EFI_EVENT                          SetAddressEvent;\r
+  EFI_EVENT                          TimeoutEvent;\r
+  UINTN                              DataSize;\r
 \r
 \r
-  if (Ip6NvData->Policy == Ip6ConfigPolicyAutomatic) {\r
+  if ((IfrNvData == NULL) || (Instance == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IfrNvData->Policy == IP6_POLICY_AUTO) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
+  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
+  Ip6NvData = &Instance->Ip6NvData;\r
+  Ip6Config = &Instance->Ip6Config;\r
+\r
+  //\r
+  // Update those fields which don't have INTERACTIVE attribute.\r
+  //\r
+  Ip6NvData->Policy = Ip6ConfigPolicyManual;\r
+\r
+  //\r
+  // Set the configured policy.\r
+  //\r
+  Status = Ip6Config->SetData (\r
+                        Ip6Config,\r
+                        Ip6ConfigDataTypePolicy,\r
+                        sizeof (EFI_IP6_CONFIG_POLICY),\r
+                        &Ip6NvData->Policy\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Create events & timers for asynchronous settings.\r
   //\r
   //\r
   // Create events & timers for asynchronous settings.\r
   //\r
@@ -1359,6 +1289,7 @@ Exit:
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
+\r
 /**\r
   This function allows the caller to request the current\r
   configuration for one or more named elements. The resulting\r
 /**\r
   This function allows the caller to request the current\r
   configuration for one or more named elements. The resulting\r
@@ -1447,7 +1378,7 @@ Ip6FormExtractConfig (
 \r
   *Progress = Request;\r
   if ((Request != NULL) &&\r
 \r
   *Progress = Request;\r
   if ((Request != NULL) &&\r
-      !HiiIsConfigHdrMatch (Request, &mIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
+      !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -1478,7 +1409,7 @@ Ip6FormExtractConfig (
     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.\r
     //\r
     ConfigRequestHdr = HiiConstructConfigHdr (\r
     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.\r
     //\r
     ConfigRequestHdr = HiiConstructConfigHdr (\r
-                         &mIp6ConfigNvDataGuid,\r
+                         &gIp6ConfigNvDataGuid,\r
                          mIp6ConfigStorageName,\r
                          Private->ChildHandle\r
                          );\r
                          mIp6ConfigStorageName,\r
                          Private->ChildHandle\r
                          );\r
@@ -1578,7 +1509,7 @@ Ip6FormRouteConfig (
   // Check routing data in <ConfigHdr>.\r
   // Note: if only one Storage is used, then this checking could be skipped.\r
   //\r
   // Check routing data in <ConfigHdr>.\r
   // Note: if only one Storage is used, then this checking could be skipped.\r
   //\r
-  if (!HiiIsConfigHdrMatch (Configuration, &mIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
+  if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
     *Progress = Configuration;\r
     return EFI_NOT_FOUND;\r
   }\r
     *Progress = Configuration;\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -1588,6 +1519,160 @@ Ip6FormRouteConfig (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Display host addresses, route table, DNS addresses and gateway addresses in\r
+  "IPv6 Current Setting" page.\r
+\r
+  @param[in]       Instance        The IP6 config instance data.\r
+\r
+  @retval EFI_SUCCESS              The operation finished successfully.\r
+  @retval Others                   Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip6GetCurrentSetting (\r
+  IN IP6_CONFIG_INSTANCE        *Instance\r
+  )\r
+{\r
+  EFI_IP6_CONFIG_PROTOCOL       *Ip6Config;\r
+  EFI_HII_HANDLE                HiiHandle;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO *Data;\r
+  UINTN                         DataSize;\r
+  EFI_STATUS                    Status;\r
+  CHAR16                        PortString[ADDRESS_STR_MAX_SIZE];\r
+  EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;\r
+  \r
+\r
+  Ip6Config = &Instance->Ip6Config;\r
+  HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
+  Data      = NULL;\r
+\r
+  //\r
+  // Get current interface info.\r
+  //\r
+  Status = Ip6ConfigNvGetData (\r
+             Ip6Config,\r
+             Ip6ConfigDataTypeInterfaceInfo,\r
+             &DataSize,\r
+             (VOID **) &Data\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Generate dynamic text opcode for host address and draw it.\r
+  //\r
+  IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;\r
+  Status = Ip6ConvertAddressListToString (\r
+             PortString,\r
+             HiiHandle,\r
+             Ip6ConfigNvHostAddress,\r
+             IfInfo->AddressInfo,\r
+             IfInfo->AddressInfoCount\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (Data);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Generate the dynamic text opcode for route table and draw it.\r
+  //\r
+  Status = Ip6ConvertAddressListToString (\r
+             PortString,\r
+             HiiHandle,\r
+             Ip6ConfigNvRouteTable,\r
+             IfInfo->RouteTable,\r
+             IfInfo->RouteCount\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (Data);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get DNS server list.\r
+  //\r
+  FreePool (Data);\r
+  DataSize = 0;\r
+  Data = NULL;\r
+  Status = Ip6ConfigNvGetData (\r
+             Ip6Config,\r
+             Ip6ConfigDataTypeDnsServer,\r
+             &DataSize,\r
+             (VOID **) &Data\r
+             );\r
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
+    if (Data != NULL) {\r
+      FreePool (Data);\r
+    }\r
+    return Status;\r
+  }\r
+\r
+  if (DataSize > 0) {\r
+    //\r
+    // Generate the dynamic text opcode for DNS server and draw it.\r
+    //\r
+    Status = Ip6ConvertAddressListToString (\r
+               PortString,\r
+               HiiHandle,\r
+               Ip6ConfigNvDnsAddress,\r
+               Data,\r
+               DataSize / sizeof (EFI_IPv6_ADDRESS)\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (Data);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get gateway adderss list.\r
+  //\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  DataSize = 0;\r
+  Data = NULL;\r
+  Status = Ip6ConfigNvGetData (\r
+             Ip6Config,\r
+             Ip6ConfigDataTypeGateway,\r
+             &DataSize,\r
+             (VOID **) &Data\r
+             );\r
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
+    if (Data != NULL) {\r
+      FreePool (Data);\r
+    }\r
+    return Status;\r
+  }\r
+\r
+  if (DataSize > 0) {\r
+    //\r
+    // Generate the dynamic text opcode for gateway and draw it.\r
+    //\r
+    Status = Ip6ConvertAddressListToString (\r
+               PortString,\r
+               HiiHandle,\r
+               Ip6ConfigNvGatewayAddress,\r
+               Data,\r
+               DataSize / sizeof (EFI_IPv6_ADDRESS)\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (Data);\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  if (Data != NULL) {\r
+    FreePool (Data);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This function is called to provide results data to the driver.\r
   This data consists of a unique key that is used to identify\r
 /**\r
   This function is called to provide results data to the driver.\r
   This data consists of a unique key that is used to identify\r
@@ -1629,17 +1714,10 @@ Ip6FormCallback (
   IP6_FORM_CALLBACK_INFO        *Private;\r
   UINTN                         BufferSize;\r
   IP6_CONFIG_IFR_NVDATA         *IfrNvData;\r
   IP6_FORM_CALLBACK_INFO        *Private;\r
   UINTN                         BufferSize;\r
   IP6_CONFIG_IFR_NVDATA         *IfrNvData;\r
-  IP6_CONFIG_IFR_NVDATA         OldIfrNvData;\r
   EFI_STATUS                    Status;\r
   EFI_INPUT_KEY                 Key;\r
   IP6_CONFIG_INSTANCE           *Instance;\r
   IP6_CONFIG_NVDATA             *Ip6NvData;\r
   EFI_STATUS                    Status;\r
   EFI_INPUT_KEY                 Key;\r
   IP6_CONFIG_INSTANCE           *Instance;\r
   IP6_CONFIG_NVDATA             *Ip6NvData;\r
-  EFI_IP6_CONFIG_PROTOCOL       *Ip6Config;\r
-  EFI_IP6_CONFIG_INTERFACE_INFO *Data;\r
-  UINTN                         DataSize;\r
-  CHAR16                        PortString[ADDRESS_STR_MAX_SIZE];\r
-  EFI_HII_HANDLE                HiiHandle;\r
-  EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1649,130 +1727,12 @@ Ip6FormCallback (
   Instance  = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
   Ip6NvData = &Instance->Ip6NvData;\r
 \r
   Instance  = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
   Ip6NvData = &Instance->Ip6NvData;\r
 \r
-  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
-    //\r
-    // Update main Form when main Form is opened.\r
-    // This will be done only in FORM_OPEN CallBack of question with KEY_INTERFACE_ID from main Form.\r
-    //\r
-    if (QuestionId != KEY_INTERFACE_ID) {\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    Ip6Config = &Instance->Ip6Config;\r
-    HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
-\r
-    //\r
-    // Get the current interface info.\r
-    //\r
-    Status = Ip6ConfigNvGetData (\r
-               Ip6Config,\r
-               Ip6ConfigDataTypeInterfaceInfo,\r
-               &DataSize,\r
-               (VOID **) &Data\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    //\r
-    // Generate the dynamic text opcode for host address and draw it.\r
-    //\r
-    IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;\r
-    Status = Ip6ConvertAddressListToString (\r
-               PortString,\r
-               HiiHandle,\r
-               Ip6ConfigNvHostAddress,\r
-               IfInfo->AddressInfo,\r
-               IfInfo->AddressInfoCount\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    //\r
-    // Generate the dynamic text opcode for route table and draw it.\r
-    //\r
-    Status = Ip6ConvertAddressListToString (\r
-               PortString,\r
-               HiiHandle,\r
-               Ip6ConfigNvRouteTable,\r
-               IfInfo->RouteTable,\r
-               IfInfo->RouteCount\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
-    }\r
-\r
-    //\r
-    // Get DNS server list.\r
-    //\r
-    DataSize = 0;\r
-    Status = Ip6ConfigNvGetData (\r
-               Ip6Config,\r
-               Ip6ConfigDataTypeDnsServer,\r
-               &DataSize,\r
-               (VOID **) &Data\r
-               );\r
-    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
-      goto Exit;\r
-    }\r
-\r
-    if (DataSize > 0) {\r
-      //\r
-      // Generate the dynamic text opcode for DNS server and draw it.\r
-      //\r
-      Status = Ip6ConvertAddressListToString (\r
-                 PortString,\r
-                 HiiHandle,\r
-                 Ip6ConfigNvDnsAddress,\r
-                 Data,\r
-                 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
-        goto Exit;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Get gateway adderss list.\r
-    //\r
-    DataSize = 0;\r
-    Status = Ip6ConfigNvGetData (\r
-               Ip6Config,\r
-               Ip6ConfigDataTypeGateway,\r
-               &DataSize,\r
-               (VOID **) &Data\r
-               );\r
-    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
-      goto Exit;\r
-    }\r
-\r
-    if (DataSize > 0) {\r
-      //\r
-      // Generate the dynamic text opcode for gateway and draw it.\r
-      //\r
-      Status = Ip6ConvertAddressListToString (\r
-                 PortString,\r
-                 HiiHandle,\r
-                 Ip6ConfigNvGatewayAddress,\r
-                 Data,\r
-                 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
-        goto Exit;\r
-      }\r
-    }\r
-\r
-Exit:\r
-    FreePool (Data);\r
-    return Status;\r
+  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)){\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   }\r
 \r
-  if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
-    //\r
-    // Do nothing for UEFI FORM_CLOSE action\r
-    //\r
-    return EFI_SUCCESS;\r
+  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
   if ((Value == NULL) || (ActionRequest == NULL)) {\r
   }\r
 \r
   if ((Value == NULL) || (ActionRequest == NULL)) {\r
@@ -1791,98 +1751,117 @@ Exit:
 \r
   Status = EFI_SUCCESS;\r
 \r
 \r
   Status = EFI_SUCCESS;\r
 \r
-  ZeroMem (&OldIfrNvData, BufferSize);\r
-\r
   HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
 \r
   HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
 \r
-  CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
-\r
-  switch (QuestionId) {\r
-  case KEY_INTERFACE_ID:\r
-    Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
-    if (EFI_ERROR (Status)) {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &Key,\r
-        L"Invalid Interface ID!",\r
-        NULL\r
-        );\r
-    }\r
-\r
-    break;\r
+  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    switch (QuestionId) {\r
+    case KEY_GET_CURRENT_SETTING:\r
+      Status = Ip6GetCurrentSetting (Instance);\r
+      break;\r
 \r
 \r
-  case KEY_MANUAL_ADDRESS:\r
-    Status = Ip6ParseAddressListFromString (\r
-               IfrNvData->ManualAddress,\r
-               &Ip6NvData->ManualAddress,\r
-               &Ip6NvData->ManualAddressCount\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &Key,\r
-        L"Invalid Host Addresses!",\r
-        NULL\r
-        );\r
+    default:\r
+      break;\r
     }\r
     }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    switch (QuestionId) {\r
+    case KEY_SAVE_CONFIG_CHANGES:\r
+      Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
 \r
 \r
-    break;\r
+      Status = Ip6GetCurrentSetting (Instance);\r
 \r
 \r
-  case KEY_GATEWAY_ADDRESS:\r
-    Status = Ip6ParseAddressListFromString (\r
-               IfrNvData->GatewayAddress,\r
-               &Ip6NvData->GatewayAddress,\r
-               &Ip6NvData->GatewayAddressCount\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &Key,\r
-        L"Invalid Gateway Addresses!",\r
-        NULL\r
-        );\r
-    }\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
+      break;\r
 \r
 \r
-    break;\r
+    case KEY_IGNORE_CONFIG_CHANGES:\r
+      Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
+      Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
+      Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
 \r
 \r
-  case KEY_DNS_ADDRESS:\r
-    Status = Ip6ParseAddressListFromString (\r
-               IfrNvData->DnsAddress,\r
-               &Ip6NvData->DnsAddress,\r
-               &Ip6NvData->DnsAddressCount\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &Key,\r
-        L"Invalid DNS Addresses!",\r
-        NULL\r
-        );\r
-    }\r
+      Ip6NvData->ManualAddressCount  = 0;\r
+      Ip6NvData->GatewayAddressCount = 0;\r
+      Ip6NvData->DnsAddressCount     = 0;\r
 \r
 \r
-    break;\r
-\r
-  case KEY_SAVE_CONFIG_CHANGES:\r
-    CopyMem (&OldIfrNvData, IfrNvData, sizeof (IP6_CONFIG_IFR_NVDATA));\r
-    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-    break;\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+      break;\r
 \r
 \r
-  case KEY_IGNORE_CONFIG_CHANGES:\r
-    CopyMem (IfrNvData, &OldIfrNvData, sizeof (IP6_CONFIG_IFR_NVDATA));\r
-    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-    break;\r
+    case KEY_SAVE_CHANGES:\r
+      Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+      break;\r
+    \r
+    case KEY_INTERFACE_ID:\r
+      Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Interface ID!",\r
+          NULL\r
+          );\r
+      }\r
+    \r
+      break;\r
+    \r
+    case KEY_MANUAL_ADDRESS:\r
+      Status = Ip6ParseAddressListFromString (\r
+                 IfrNvData->ManualAddress,\r
+                 &Ip6NvData->ManualAddress,\r
+                 &Ip6NvData->ManualAddressCount\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Host Addresses!",\r
+          NULL\r
+          );\r
+      }\r
+    \r
+      break;\r
+    \r
+    case KEY_GATEWAY_ADDRESS:\r
+      Status = Ip6ParseAddressListFromString (\r
+                 IfrNvData->GatewayAddress,\r
+                 &Ip6NvData->GatewayAddress,\r
+                 &Ip6NvData->GatewayAddressCount\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Gateway Addresses!",\r
+          NULL\r
+          );\r
+      }\r
+    \r
+      break;\r
+    \r
+    case KEY_DNS_ADDRESS:\r
+      Status = Ip6ParseAddressListFromString (\r
+                 IfrNvData->DnsAddress,\r
+                 &Ip6NvData->DnsAddress,\r
+                 &Ip6NvData->DnsAddressCount\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid DNS Addresses!",\r
+          NULL\r
+          );\r
+      }\r
+    \r
+      break;\r
 \r
 \r
-  case KEY_SAVE_CHANGES:\r
-    Status = Ip6ConvertIfrNvDataToConfigNvData (IfrNvData, Instance);\r
-    if (EFI_ERROR (Status)) {\r
+    default:\r
       break;\r
     }\r
       break;\r
     }\r
-\r
-    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
-    break;\r
-\r
-  default:\r
-    break;\r
   }\r
 \r
   if (!EFI_ERROR (Status)) {\r
   }\r
 \r
   if (!EFI_ERROR (Status)) {\r
@@ -1948,7 +1927,7 @@ Ip6ConfigFormInit (
   VendorDeviceNode.Header.Type    = HARDWARE_DEVICE_PATH;\r
   VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
 \r
   VendorDeviceNode.Header.Type    = HARDWARE_DEVICE_PATH;\r
   VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
 \r
-  CopyGuid (&VendorDeviceNode.Guid, &mIp6HiiVendorDevicePathGuid);\r
+  CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);\r
 \r
   SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
   CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
 \r
   SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
   CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
@@ -1998,7 +1977,7 @@ Ip6ConfigFormInit (
   // Publish our HII data\r
   //\r
   CallbackInfo->RegisteredHandle = HiiAddPackages (\r
   // Publish our HII data\r
   //\r
   CallbackInfo->RegisteredHandle = HiiAddPackages (\r
-                                     &mIp6ConfigNvDataGuid,\r
+                                     &gIp6ConfigNvDataGuid,\r
                                      CallbackInfo->ChildHandle,\r
                                      Ip6DxeStrings,\r
                                      Ip6ConfigBin,\r
                                      CallbackInfo->ChildHandle,\r
                                      Ip6DxeStrings,\r
                                      Ip6ConfigBin,\r