Revision: 18232
          http://sourceforge.net/p/edk2/code/18232
Author:   jiaxinwu
Date:     2015-08-18 03:12:16 +0000 (Tue, 18 Aug 2015)
Log Message:
-----------
MdeModulePkg: IP4 should re-initiate a DHCP if it detects network reconnection

v2:
* Update the MediaPresent detect declaring.

IP4 driver should re-initiate a DHCP if it detects that there is a network.
To fix this issue, we can implement the DHCP re-initiate policy while the media
change detected. The Ip4 driver should set a timer to signal the Ip4 to run the
DHCP configuration again(D.O.R.A). IP4 driver should free old IP address related
resource, then initiate a DHCP process to acquire new IP.

Cc: Ye Ting <[email protected]>
Cc: Zhang Lubo <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <[email protected]>
Reviewed-by: Ye Ting <[email protected]>
Reviewed-by: Lubo Zhang <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
    trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
    trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
    trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h

Modified: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c   
2015-08-18 03:08:27 UTC (rev 18231)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c   
2015-08-18 03:12:16 UTC (rev 18232)
@@ -492,6 +492,7 @@
   ASSERT (IpIf != NULL);
 
   if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {
+    IpSb->State = IP4_SERVICE_CONFIGED;
     return EFI_SUCCESS;
   }
 

Modified: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c        
2015-08-18 03:08:27 UTC (rev 18231)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c        
2015-08-18 03:12:16 UTC (rev 18232)
@@ -210,6 +210,10 @@
 
   IpSb->Timer = NULL;
 
+  IpSb->ReconfigEvent = NULL;
+  
+  IpSb->MediaPresent = TRUE;
+
   //
   // Create various resources. First create the route table, timer
   // event and MNP child. IGMP, interface's initialization depend
@@ -386,6 +390,12 @@
     IpSb->Timer = NULL;
   }
 
+  if (IpSb->ReconfigEvent != NULL) {
+    gBS->CloseEvent (IpSb->ReconfigEvent);
+
+    IpSb->ReconfigEvent = NULL;
+  }
+
   if (IpSb->MacString != NULL) {
     FreePool (IpSb->MacString);
   }

Modified: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c  2015-08-18 
03:08:27 UTC (rev 18231)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c  2015-08-18 
03:12:16 UTC (rev 18232)
@@ -563,8 +563,56 @@
 }
 
 
+/**
+  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;
+  }
+
+  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
   for the first time. The caller should validate the configuration
@@ -678,10 +726,27 @@
     // been started, start it.
     //
     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 ON_ERROR;
+        goto CLOSE_RECONFIG_EVENT;
       }
     }
 
@@ -711,7 +776,7 @@
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                     );
     if (EFI_ERROR (Status)) {
-      goto ON_ERROR;
+      goto CLOSE_RECONFIG_EVENT;
     }
   }
   InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
@@ -730,6 +795,12 @@
 
   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;
@@ -2295,10 +2366,16 @@
 
 
 /**
-  The heart beat timer of IP4 service instance. It times out
-  all of its IP4 children's received-but-not-delivered and
-  transmitted-but-not-recycle packets, and provides time input
-  for its IGMP protocol.
+  There are two steps for this the heart beat timer of IP4 service instance. 
+  First, it times out all of its IP4 children's received-but-not-delivered 
+  and transmitted-but-not-recycle packets, and provides time input for its 
+  IGMP protocol.
+  Second, a dedicated timer is used to poll underlying media status. In case 
+  of cable swap, a new round auto configuration will be initiated. The timer 
+  will signal the IP4 to run DHCP configuration again. IP4 driver will free
+  old IP address related resource, such as route table and Interface, then
+  initiate a DHCP process to acquire new IP, eventually create route table 
+  for new IP address.
 
   @param[in]  Event                  The IP4 service instance's heart beat 
timer.
   @param[in]  Context                The IP4 service instance.
@@ -2312,10 +2389,42 @@
   )
 {
   IP4_SERVICE               *IpSb;
+  BOOLEAN                   OldMediaPresent;
+  EFI_STATUS                Status;
+  EFI_SIMPLE_NETWORK_MODE   SnpModeData;
 
   IpSb = (IP4_SERVICE *) Context;
   NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
+  
+  OldMediaPresent = IpSb->MediaPresent;
 
   Ip4PacketTimerTicking (IpSb);
   Ip4IgmpTicking (IpSb);
+
+  //
+  // Get fresh mode data from MNP, since underlying media status may change. 
+  // Here, it needs to mention that the MediaPresent can also be checked even 
if 
+  // EFI_NOT_STARTED returned while this MNP child driver instance isn't 
configured.
+  //
+  Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &SnpModeData);
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
+    return;
+  }
+
+  IpSb->MediaPresent = SnpModeData.MediaPresent;
+  //
+  // Media transimit Unpresent to Present means new link movement is detected.
+  //
+  if (!OldMediaPresent && IpSb->MediaPresent) {
+    //
+    // 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 
+    // initiate a DHCP round to acquire new IP, eventually 
+    // create route table for new IP address.
+    //
+    if (IpSb->ReconfigEvent != NULL) {
+      Status = gBS->SignalEvent (IpSb->ReconfigEvent);
+      DispatchDpc ();
+    }
+  }
 }

Modified: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h  2015-08-18 
03:08:27 UTC (rev 18231)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h  2015-08-18 
03:12:16 UTC (rev 18232)
@@ -203,7 +203,14 @@
 
   EFI_EVENT                       Timer;
 
+  EFI_EVENT                       ReconfigEvent;
+
   //
+  // Underlying media present status. 
+  //
+  BOOLEAN                         MediaPresent;
+
+  //
   // IPv4 Configuration II Protocol instance
   //
   IP4_CONFIG2_INSTANCE            Ip4Config2Instance;


------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to