Reviwed-by: Ye Ting <ting...@intel.com> 

-----Original Message-----
From: Wu, Jiaxin 
Sent: Wednesday, August 19, 2015 4:55 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting; Zhang, Lubo
Subject: [Patch] MdeModulePkg: Fix default router table and interface missing 
error

Ip4StartAutoConfig() will always free its default router table and interface,
which may cause IP instance missing its correct default interface. e.g. when
the policy is dhcp, and one child is configured to use default address.

Cc: Ye Ting <ting...@intel.com>
Cc: Zhang Lubo <lubo.zh...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin...@intel.com>
---
 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c      | 74 ++++++++++++----------
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c  |  4 ++
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c    |  2 +
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h    |  2 +
 4 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
index caf84fb..637d7cd 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
@@ -147,10 +147,11 @@ Ip4Config2OnPolicyChanged (
 
   //
   // Start the dhcp configuration.
   //
   if (NewPolicy == Ip4Config2PolicyDhcp) {
+    IpSb->Reconfig = TRUE;
     Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
   }
 
 }
 
@@ -461,72 +462,72 @@ Ip4Config2OnDhcp4SbInstalled (
 }
 
 /**
   Set the station address and subnetmask for the default interface.
 
-  @param[in]  Instance           The pointer to the IP4 config2 instance data.
+  @param[in]  IpSb               The pointer to the IP4 service binding 
instance.
   @param[in]  StationAddress     Ip address to be set.
   @param[in]  SubnetMask         Subnet to be set.
 
   @retval EFI_SUCCESS   Set default address successful.     
   @retval Others        Some errors occur in setting.     
 
 **/
 EFI_STATUS
 Ip4Config2SetDefaultAddr (
-  IN IP4_CONFIG2_INSTANCE   *Instance,
+  IN IP4_SERVICE            *IpSb,
   IN IP4_ADDR               StationAddress,
   IN IP4_ADDR               SubnetMask
   )
 {
   EFI_STATUS                Status;
-  IP4_SERVICE               *IpSb;
   IP4_INTERFACE             *IpIf;
   IP4_PROTOCOL              *Ip4Instance;
   EFI_ARP_PROTOCOL          *Arp;
   LIST_ENTRY                *Entry;
   IP4_ADDR                  Subnet;
   IP4_ROUTE_TABLE           *RouteTable;
 
-  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
   IpIf = IpSb->DefaultInterface;
   ASSERT (IpIf != NULL);
 
   if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {
     IpSb->State = IP4_SERVICE_CONFIGED;
     return EFI_SUCCESS;
   }
 
-  //
-  // The default address is changed, free the previous interface first.
-  //
-  if (IpSb->DefaultRouteTable != NULL) {
-    Ip4FreeRouteTable (IpSb->DefaultRouteTable);
-    IpSb->DefaultRouteTable = NULL;    
-  }
+  if (IpSb->Reconfig) {
+    //
+    // The default address is changed, free the previous interface first.
+    //
+    if (IpSb->DefaultRouteTable != NULL) {
+      Ip4FreeRouteTable (IpSb->DefaultRouteTable);
+      IpSb->DefaultRouteTable = NULL;    
+    }
 
-  Ip4CancelReceive (IpSb->DefaultInterface);
-  Ip4FreeInterface (IpSb->DefaultInterface, NULL);
-  IpSb->DefaultInterface = NULL;
-  //
-  // Create new default interface and route table.
-  //    
-  IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
-  if (IpIf == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
+    Ip4CancelReceive (IpSb->DefaultInterface);
+    Ip4FreeInterface (IpSb->DefaultInterface, NULL);
+    IpSb->DefaultInterface = NULL;
+    //
+    // Create new default interface and route table.
+    //    
+    IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
+    if (IpIf == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
 
-  RouteTable = Ip4CreateRouteTable ();
-  if (RouteTable == NULL) {
-    Ip4FreeInterface (IpIf, NULL);
-    return EFI_OUT_OF_RESOURCES;
+    RouteTable = Ip4CreateRouteTable ();
+    if (RouteTable == NULL) {
+      Ip4FreeInterface (IpIf, NULL);
+      return EFI_OUT_OF_RESOURCES;
+    }
+    
+    IpSb->DefaultInterface  = IpIf;
+    InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
+    IpSb->DefaultRouteTable = RouteTable;
+    Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
   }
-  
-  IpSb->DefaultInterface  = IpIf;
-  InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
-  IpSb->DefaultRouteTable = RouteTable;
-  Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
 
   if (IpSb->State == IP4_SERVICE_CONFIGED) {
     IpSb->State = IP4_SERVICE_UNSTARTED;
   }
 
@@ -576,10 +577,12 @@ Ip4Config2SetDefaultAddr (
     SubnetMask,
     IP4_ALLZERO_ADDRESS
     );
 
   IpSb->State = IP4_SERVICE_CONFIGED;
+  IpSb->Reconfig = FALSE;
+  
   return EFI_SUCCESS;
 }
 
 /**
   Set the station address, subnetmask and gateway address for the default 
interface.
@@ -602,19 +605,20 @@ Ip4Config2SetDefaultIf (
   )
 {
   EFI_STATUS                Status;
   IP4_SERVICE               *IpSb;
 
-  Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
+  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   //
   // Create a route if there is a default router.
   //
-  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
   if (GatewayAddress != IP4_ALLZERO_ADDRESS) {
     Ip4AddRoute (
       IpSb->DefaultRouteTable,
       IP4_ALLZERO_ADDRESS,
       IP4_ALLZERO_ADDRESS,
@@ -1069,10 +1073,13 @@ Ip4Config2SetMaunualAddress (
   IP4_CONFIG2_DATA_ITEM          *DataItem;
   EFI_STATUS                     Status;
   IP4_ADDR                       StationAddress;
   IP4_ADDR                       SubnetMask;
   VOID                           *Ptr;
+  IP4_SERVICE                    *IpSb;
+
+  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
 
   ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != 
EFI_NOT_READY);
 
   if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize 
== 0)) {
     return EFI_BAD_BUFFER_SIZE;
@@ -1103,11 +1110,12 @@ Ip4Config2SetMaunualAddress (
   DataItem->Status   = EFI_NOT_READY;
 
   StationAddress = EFI_NTOHL (NewAddress.Address);
   SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
 
-  Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
+  IpSb->Reconfig = TRUE;
+  Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask);
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }  
 
   DataItem->Status = EFI_SUCCESS;   
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
index 4d3ccec..d8ab948 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
@@ -209,10 +209,12 @@ Ip4CreateService (
   ZeroMem (&IpSb->SnpMode, sizeof (EFI_SIMPLE_NETWORK_MODE));
 
   IpSb->Timer = NULL;
 
   IpSb->ReconfigEvent = NULL;
+
+  IpSb->Reconfig = FALSE;
   
   IpSb->MediaPresent = TRUE;
 
   //
   // Create various resources. First create the route table, timer
@@ -394,10 +396,12 @@ Ip4CleanService (
     gBS->CloseEvent (IpSb->ReconfigEvent);
 
     IpSb->ReconfigEvent = NULL;
   }
 
+  IpSb->Reconfig = FALSE;
+
   if (IpSb->MacString != NULL) {
     FreePool (IpSb->MacString);
   }
 
   Ip4Config2CleanInstance (&IpSb->Ip4Config2Instance);
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
index ac8fb1a..b9a294b 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
@@ -582,10 +582,12 @@ Ip4AutoReconfigCallBackDpc (
   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 ;
 }
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
index 4bb0089..a1a76bd 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
@@ -203,10 +203,12 @@ struct _IP4_SERVICE {
 
   EFI_EVENT                       Timer;
 
   EFI_EVENT                       ReconfigEvent;
 
+  BOOLEAN                         Reconfig;
+
   //
   // Underlying media present status. 
   //
   BOOLEAN                         MediaPresent;
 
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to