]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: IP4 should re-initiate a DHCP if it detects network reconnection
authorJiaxin Wu <jiaxin.wu@intel.com>
Tue, 18 Aug 2015 03:12:16 +0000 (03:12 +0000)
committerjiaxinwu <jiaxinwu@Edk2>
Tue, 18 Aug 2015 03:12:16 +0000 (03:12 +0000)
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 <ting.ye@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Lubo Zhang <lubo.zhang@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18232 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h

index fcb2bdd56270287a414d5805147926333d8f0ba8..caf84fb7a5fdb097ee5b457dacc32db621970140 100644 (file)
@@ -492,6 +492,7 @@ Ip4Config2SetDefaultAddr (
   ASSERT (IpIf != NULL);\r
 \r
   if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {\r
+    IpSb->State = IP4_SERVICE_CONFIGED;\r
     return EFI_SUCCESS;\r
   }\r
 \r
index 101390cdf85270d5d733f34ca819ac8e83458e81..4d3ccec61047c9b1ddde686a43e21ac2b38401c9 100644 (file)
@@ -210,6 +210,10 @@ Ip4CreateService (
 \r
   IpSb->Timer = NULL;\r
 \r
+  IpSb->ReconfigEvent = NULL;\r
+  \r
+  IpSb->MediaPresent = TRUE;\r
+\r
   //\r
   // Create various resources. First create the route table, timer\r
   // event and MNP child. IGMP, interface's initialization depend\r
@@ -386,6 +390,12 @@ Ip4CleanService (
     IpSb->Timer = NULL;\r
   }\r
 \r
+  if (IpSb->ReconfigEvent != NULL) {\r
+    gBS->CloseEvent (IpSb->ReconfigEvent);\r
+\r
+    IpSb->ReconfigEvent = NULL;\r
+  }\r
+\r
   if (IpSb->MacString != NULL) {\r
     FreePool (IpSb->MacString);\r
   }\r
index 2fb4f4c1ca2abd3d7dc820fc5798445cc44abf4a..ac8fb1a7b03173d40a140c7b4fe78674e3074cfe 100644 (file)
@@ -563,6 +563,54 @@ Ip4InitProtocol (
 }\r
 \r
 \r
+/**\r
+  The event handle for IP4 auto reconfiguration. The original default\r
+  interface and route table will be removed as the default.\r
+\r
+  @param[in]  Context                The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBackDpc (\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  IP4_SERVICE               *IpSb;\r
+\r
+  IpSb      = (IP4_SERVICE *) Context;\r
+  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
+\r
+  if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
+    IpSb->State = IP4_SERVICE_UNSTARTED;\r
+  }\r
+\r
+  Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
+\r
+  return ;\r
+}\r
+\r
+\r
+/**\r
+  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.\r
+\r
+  @param Event     The event that is signalled.\r
+  @param Context   The IP4 service binding instance.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4AutoReconfigCallBack (\r
+  IN EFI_EVENT              Event,\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  //\r
+  // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK\r
+  //\r
+  QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);\r
+}\r
+\r
 \r
 /**\r
   Configure the IP4 child. If the child is already configured,\r
@@ -678,10 +726,27 @@ Ip4ConfigProtocol (
     // been started, start it.\r
     //\r
     if (IpSb->State == IP4_SERVICE_UNSTARTED) {\r
+      //\r
+      // Create the ReconfigEvent to start the new configuration.\r
+      //\r
+      if (IpSb->ReconfigEvent == NULL) {\r
+        Status = gBS->CreateEvent (\r
+                        EVT_NOTIFY_SIGNAL,\r
+                        TPL_NOTIFY,\r
+                        Ip4AutoReconfigCallBack,\r
+                        IpSb,\r
+                        &IpSb->ReconfigEvent\r
+                        );\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          goto ON_ERROR;\r
+        }\r
+      }\r
+      \r
       Status = Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);\r
 \r
       if (EFI_ERROR (Status)) {\r
-        goto ON_ERROR;\r
+        goto CLOSE_RECONFIG_EVENT;\r
       }\r
     }\r
 \r
@@ -711,7 +776,7 @@ Ip4ConfigProtocol (
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
     if (EFI_ERROR (Status)) {\r
-      goto ON_ERROR;\r
+      goto CLOSE_RECONFIG_EVENT;\r
     }\r
   }\r
   InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);\r
@@ -730,6 +795,12 @@ Ip4ConfigProtocol (
 \r
   return EFI_SUCCESS;\r
 \r
+CLOSE_RECONFIG_EVENT:\r
+  if (IpSb->ReconfigEvent != NULL) {\r
+    gBS->CloseEvent (IpSb->ReconfigEvent);\r
+    IpSb->ReconfigEvent = NULL;\r
+  }\r
+\r
 ON_ERROR:\r
   Ip4FreeRouteTable (IpInstance->RouteTable);\r
   IpInstance->RouteTable = NULL;\r
@@ -2295,10 +2366,16 @@ Ip4SentPacketTicking (
 \r
 \r
 /**\r
-  The heart beat timer of IP4 service instance. It times out\r
-  all of its IP4 children's received-but-not-delivered and\r
-  transmitted-but-not-recycle packets, and provides time input\r
-  for its IGMP protocol.\r
+  There are two steps for this the heart beat timer of IP4 service instance. \r
+  First, it times out all of its IP4 children's received-but-not-delivered \r
+  and transmitted-but-not-recycle packets, and provides time input for its \r
+  IGMP protocol.\r
+  Second, a dedicated timer is used to poll underlying media status. In case \r
+  of cable swap, a new round auto configuration will be initiated. The timer \r
+  will signal the IP4 to run DHCP configuration again. IP4 driver will free\r
+  old IP address related resource, such as route table and Interface, then\r
+  initiate a DHCP process to acquire new IP, eventually create route table \r
+  for new IP address.\r
 \r
   @param[in]  Event                  The IP4 service instance's heart beat timer.\r
   @param[in]  Context                The IP4 service instance.\r
@@ -2312,10 +2389,42 @@ Ip4TimerTicking (
   )\r
 {\r
   IP4_SERVICE               *IpSb;\r
+  BOOLEAN                   OldMediaPresent;\r
+  EFI_STATUS                Status;\r
+  EFI_SIMPLE_NETWORK_MODE   SnpModeData;\r
 \r
   IpSb = (IP4_SERVICE *) Context;\r
   NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
+  \r
+  OldMediaPresent = IpSb->MediaPresent;\r
 \r
   Ip4PacketTimerTicking (IpSb);\r
   Ip4IgmpTicking (IpSb);\r
+\r
+  //\r
+  // Get fresh mode data from MNP, since underlying media status may change. \r
+  // Here, it needs to mention that the MediaPresent can also be checked even if \r
+  // EFI_NOT_STARTED returned while this MNP child driver instance isn't configured.\r
+  //\r
+  Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &SnpModeData);\r
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
+    return;\r
+  }\r
+\r
+  IpSb->MediaPresent = SnpModeData.MediaPresent;\r
+  //\r
+  // Media transimit Unpresent to Present means new link movement is detected.\r
+  //\r
+  if (!OldMediaPresent && IpSb->MediaPresent) {\r
+    //\r
+    // Signal the IP4 to run the dhcp configuration again. IP4 driver will free\r
+    // old IP address related resource, such as route table and Interface, then \r
+    // initiate a DHCP round to acquire new IP, eventually \r
+    // create route table for new IP address.\r
+    //\r
+    if (IpSb->ReconfigEvent != NULL) {\r
+      Status = gBS->SignalEvent (IpSb->ReconfigEvent);\r
+      DispatchDpc ();\r
+    }\r
+  }\r
 }\r
index 84dfa80f1cf34f4670c613ed01471d68638f0e02..4bb0089413ff9f39e160dce66fae1cdfe7904e51 100644 (file)
@@ -203,6 +203,13 @@ struct _IP4_SERVICE {
 \r
   EFI_EVENT                       Timer;\r
 \r
+  EFI_EVENT                       ReconfigEvent;\r
+\r
+  //\r
+  // Underlying media present status. \r
+  //\r
+  BOOLEAN                         MediaPresent;\r
+\r
   //\r
   // IPv4 Configuration II Protocol instance\r
   //\r