From 7648748e99eeeadec38fda7568adb260c4acc861 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 25 Feb 2016 10:48:58 +0800 Subject: [PATCH] MdeModulePkg: Change the default IPv4 config policy Git version '3d0a49ad' commit provided a scenario to resolve the performance issue for IPv4, but it's not workable for IPv6. To avoid IPv4 and IPv6 inconsistency, we decided to revert that version fix. If so, the default policy for Ip4Config2 is Ip4Config2PolicyDhcp, which results in all NIC ports attempting DHCP. So, this patch is used to changes the the default IPv4 config policy to Ip4Config2PolicyStatic and also defer the SetData operation after Ip4Config2Protocol installed. This update let the other platform drivers have chance to change the default config data by consume Ip4Config2Protocol. Cc: Subramanian Sriram Cc: El-Haj-Mahmoud Samer Cc: Ye Ting Cc: Fu Siyuan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu Reviewed-by: Subramanian Sriram Reviewed-by: Fu Siyuan Reviewed-by: Ye Ting --- .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c | 76 ++++++++++++---- .../Universal/Network/Ip4Dxe/Ip4Config2Impl.h | 36 +++++++- .../Universal/Network/Ip4Dxe/Ip4Driver.c | 53 ++++++++++- .../Universal/Network/Ip4Dxe/Ip4Dxe.inf | 2 +- .../Universal/Network/Ip4Dxe/Ip4Impl.c | 90 ++----------------- 5 files changed, 150 insertions(+), 107 deletions(-) diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index edbddba021..1f763b6bfe 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -1,7 +1,7 @@ /** @file The implementation of EFI IPv4 Configuration II Protocol. - Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
This program and the accompanying materials @@ -1144,7 +1144,9 @@ Ip4Config2SetPolicy ( } if (NewPolicy == Instance->Policy) { - return EFI_ABORTED; + if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) { + return EFI_ABORTED; + } } else { if (NewPolicy == Ip4Config2PolicyDhcp) { // @@ -1908,7 +1910,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]; @@ -1939,6 +1941,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) { @@ -1948,21 +1952,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; @@ -2029,3 +2019,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); +} + diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h index ab72525646..77bdc8dcb6 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h @@ -1,7 +1,7 @@ /** @file Definitions for EFI IPv4 Configuration II Protocol implementation. - Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
This program and the accompanying materials @@ -212,6 +212,26 @@ typedef struct { } IP4_CONFIG2_DHCP4_OPTION; #pragma pack() +/** + Read the configuration data from variable storage according to the VarName and + gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the + data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the + configuration data to IP4_CONFIG2_INSTANCE. + + @param[in] VarName The pointer to the variable name + @param[in, out] Instance The pointer to the IP4 config2 instance data. + + @retval EFI_NOT_FOUND The variable can not be found or already corrupted. + @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation. + @retval EFI_SUCCESS The configuration data was retrieved successfully. + +**/ +EFI_STATUS +Ip4Config2ReadConfigData ( + IN CHAR16 *VarName, + IN OUT IP4_CONFIG2_INSTANCE *Instance + ); + /** Start the DHCP configuration for this IP service instance. It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the @@ -253,6 +273,20 @@ Ip4Config2CleanInstance ( IN OUT IP4_CONFIG2_INSTANCE *Instance ); +/** + 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 + ); + /** Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources. diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 3dc4d88f13..fb83784da9 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -1,7 +1,7 @@ /** @file The driver binding and service binding protocol for IP4 driver. -Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.
This program and the accompanying materials @@ -254,7 +254,7 @@ Ip4CreateService ( // // Create various resources. First create the route table, timer - // event and MNP child. IGMP, interface's initialization depend + // event, ReconfigEvent and MNP child. IGMP, interface's initialization depend // on the MNP child. // IpSb->DefaultRouteTable = Ip4CreateRouteTable (); @@ -276,6 +276,17 @@ Ip4CreateService ( goto ON_ERROR; } + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + Ip4AutoReconfigCallBack, + IpSb, + &IpSb->ReconfigEvent + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + Status = NetLibCreateServiceChild ( Controller, ImageHandle, @@ -511,6 +522,13 @@ Ip4DriverBindingStart ( { EFI_STATUS Status; IP4_SERVICE *IpSb; + EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2; + UINTN Index; + IP4_CONFIG2_DATA_ITEM *DataItem; + + IpSb = NULL; + Ip4Cfg2 = NULL; + DataItem = NULL; // // Test for the Ip4 service binding protocol @@ -536,6 +554,8 @@ Ip4DriverBindingStart ( ASSERT (IpSb != NULL); + Ip4Cfg2 = &IpSb->Ip4Config2Instance.Ip4Config2; + // // Install the Ip4ServiceBinding Protocol onto ControlerHandle // @@ -544,13 +564,40 @@ Ip4DriverBindingStart ( &gEfiIp4ServiceBindingProtocolGuid, &IpSb->ServiceBinding, &gEfiIp4Config2ProtocolGuid, - &IpSb->Ip4Config2Instance.Ip4Config2, + Ip4Cfg2, NULL ); if (EFI_ERROR (Status)) { goto FREE_SERVICE; } + + // + // Read the config data from NV variable again. + // The default data can be changed by other drivers. + // + Status = Ip4Config2ReadConfigData (IpSb->MacString, &IpSb->Ip4Config2Instance); + if (EFI_ERROR (Status)) { + goto UNINSTALL_PROTOCOL; + } + + // + // Consume the installed EFI_IP4_CONFIG2_PROTOCOL to set the default data items. + // + for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; Index++) { + DataItem = &IpSb->Ip4Config2Instance.DataItem[Index]; + if (DataItem->Data.Ptr != NULL) { + Status = Ip4Cfg2->SetData ( + Ip4Cfg2, + Index, + DataItem->DataSize, + DataItem->Data.Ptr + ); + if (EFI_ERROR(Status)) { + goto UNINSTALL_PROTOCOL; + } + } + } // // Ready to go: start the receiving and timer. diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf index f561af0c75..313528783d 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf @@ -6,7 +6,7 @@ # subset of the Internet Control Message Protocol (ICMP) and may include support for # the Internet Group Management Protocol (IGMP). # -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index b9a294b199..58adba7c8c 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -563,57 +563,6 @@ Ip4InitProtocol ( } -/** - 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); -} - - /** Configure the IP4 child. If the child is already configured, change the configuration parameter. Otherwise configure it @@ -724,32 +673,11 @@ Ip4ConfigProtocol ( } else { // - // Use the default address. If the default configuration hasn't - // been started, start it. + // Use the default address. Check the state. // if (IpSb->State == IP4_SERVICE_UNSTARTED) { - // - // Create the ReconfigEvent to start the new configuration. - // - if (IpSb->ReconfigEvent == NULL) { - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - Ip4AutoReconfigCallBack, - IpSb, - &IpSb->ReconfigEvent - ); - - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - } - - Status = Ip4StartAutoConfig (&IpSb->Ip4Config2Instance); - - if (EFI_ERROR (Status)) { - goto CLOSE_RECONFIG_EVENT; - } + Status = EFI_NO_MAPPING; + goto ON_ERROR; } IpIf = IpSb->DefaultInterface; @@ -778,7 +706,7 @@ Ip4ConfigProtocol ( EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { - goto CLOSE_RECONFIG_EVENT; + goto ON_ERROR; } } InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink); @@ -797,12 +725,6 @@ Ip4ConfigProtocol ( return EFI_SUCCESS; -CLOSE_RECONFIG_EVENT: - if (IpSb->ReconfigEvent != NULL) { - gBS->CloseEvent (IpSb->ReconfigEvent); - IpSb->ReconfigEvent = NULL; - } - ON_ERROR: Ip4FreeRouteTable (IpInstance->RouteTable); IpInstance->RouteTable = NULL; @@ -2417,7 +2339,7 @@ Ip4TimerTicking ( // // Media transimit Unpresent to Present means new link movement is detected. // - if (!OldMediaPresent && IpSb->MediaPresent) { + if (!OldMediaPresent && IpSb->MediaPresent && (IpSb->Ip4Config2Instance.Policy == Ip4Config2PolicyDhcp)) { // // Signal the IP4 to run the dhcp configuration again. IP4 driver will free // old IP address related resource, such as route table and Interface, then