diff options
author | Jiaxin Wu <jiaxin.wu@intel.com> | 2015-08-18 03:12:16 +0000 |
---|---|---|
committer | jiaxinwu <jiaxinwu@Edk2> | 2015-08-18 03:12:16 +0000 |
commit | 2c3200072f94313600c6fa9af57715220b51a5fb (patch) | |
tree | 193a4af5d4aadc25e1b3bb1c1b359a8b39f7baeb /MdeModulePkg | |
parent | 36673054200c24a38bedea10e19765830bd2ad2c (diff) | |
download | edk2-2c3200072f94313600c6fa9af57715220b51a5fb.tar.gz edk2-2c3200072f94313600c6fa9af57715220b51a5fb.tar.bz2 edk2-2c3200072f94313600c6fa9af57715220b51a5fb.zip |
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 <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
Diffstat (limited to 'MdeModulePkg')
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c | 1 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c | 10 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c | 121 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h | 7 |
4 files changed, 133 insertions, 6 deletions
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index fcb2bdd562..caf84fb7a5 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -492,6 +492,7 @@ Ip4Config2SetDefaultAddr ( ASSERT (IpIf != NULL);
if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {
+ IpSb->State = IP4_SERVICE_CONFIGED;
return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 101390cdf8..4d3ccec610 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -210,6 +210,10 @@ Ip4CreateService ( 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 @@ Ip4CleanService ( IpSb->Timer = NULL;
}
+ if (IpSb->ReconfigEvent != NULL) {
+ gBS->CloseEvent (IpSb->ReconfigEvent);
+
+ IpSb->ReconfigEvent = NULL;
+ }
+
if (IpSb->MacString != NULL) {
FreePool (IpSb->MacString);
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index 2fb4f4c1ca..ac8fb1a7b0 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -563,6 +563,54 @@ 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;
+ }
+
+ 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,
@@ -678,10 +726,27 @@ Ip4ConfigProtocol ( // 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 @@ Ip4ConfigProtocol ( 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 @@ 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;
@@ -2295,10 +2366,16 @@ Ip4SentPacketTicking ( /**
- 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 @@ Ip4TimerTicking ( )
{
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 ();
+ }
+ }
}
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index 84dfa80f1c..4bb0089413 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -203,6 +203,13 @@ struct _IP4_SERVICE { EFI_EVENT Timer;
+ EFI_EVENT ReconfigEvent;
+
+ //
+ // Underlying media present status.
+ //
+ BOOLEAN MediaPresent;
+
//
// IPv4 Configuration II Protocol instance
//
|