/** @file\r
\r
-Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
}\r
\r
\r
-/**\r
- The event handle for IP4 auto configuration. If IP is asked\r
- to reconfigure the default address. The original default\r
- interface and route table are removed as the default. If there\r
- is active IP children using the default address, the interface\r
- will remain valid until all the children have freed their\r
- references. If IP is signalled when auto configuration is done,\r
- it will configure the default interface and default route table\r
- with the configuration information retrieved by IP4_CONFIGURE.\r
-\r
- @param[in] Context The IP4 service binding instance.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-Ip4AutoConfigCallBackDpc (\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
- EFI_IP4_IPCONFIG_DATA *Data;\r
- EFI_IP4_ROUTE_TABLE *RouteEntry;\r
- IP4_SERVICE *IpSb;\r
- IP4_ROUTE_TABLE *RouteTable;\r
- IP4_INTERFACE *IpIf;\r
- EFI_STATUS Status;\r
- UINTN Len;\r
- UINT32 Index;\r
- IP4_ADDR StationAddress;\r
- IP4_ADDR SubnetMask;\r
- IP4_ADDR SubnetAddress;\r
- IP4_ADDR GatewayAddress;\r
- IP4_PROTOCOL *Ip4Instance;\r
- EFI_ARP_PROTOCOL *Arp;\r
- LIST_ENTRY *Entry;\r
-\r
- IpSb = (IP4_SERVICE *) Context;\r
- NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);\r
-\r
- Ip4Config = IpSb->Ip4Config;\r
-\r
- //\r
- // IP is asked to do the reconfiguration. If the default interface\r
- // has been configured, release the default interface and route\r
- // table, then create a new one. If there are some IP children\r
- // using it, the interface won't be physically freed until all the\r
- // children have released their reference to it. Also remember to\r
- // restart the receive on the default address. IP4 driver only receive\r
- // frames on the default address, and when the default interface is\r
- // freed, Ip4AcceptFrame won't be informed.\r
- //\r
- if (IpSb->ActiveEvent == IpSb->ReconfigEvent) {\r
-\r
- if (IpSb->DefaultInterface->Configured) {\r
- IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);\r
-\r
- if (IpIf == NULL) {\r
- return;\r
- }\r
-\r
- RouteTable = Ip4CreateRouteTable ();\r
-\r
- if (RouteTable == NULL) {\r
- Ip4FreeInterface (IpIf, NULL);\r
- return;\r
- }\r
-\r
- Ip4CancelReceive (IpSb->DefaultInterface);\r
- Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
- Ip4FreeRouteTable (IpSb->DefaultRouteTable);\r
-\r
- IpSb->DefaultInterface = IpIf;\r
- InsertHeadList (&IpSb->Interfaces, &IpIf->Link);\r
-\r
- IpSb->DefaultRouteTable = RouteTable;\r
- Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);\r
- }\r
-\r
- Ip4Config->Stop (Ip4Config);\r
- Ip4Config->Start (Ip4Config, IpSb->DoneEvent, IpSb->ReconfigEvent);\r
- return ;\r
- }\r
-\r
- //\r
- // Get the configure data in two steps: get the length then the data.\r
- //\r
- Len = 0;\r
-\r
- if (Ip4Config->GetData (Ip4Config, &Len, NULL) != EFI_BUFFER_TOO_SMALL) {\r
- return ;\r
- }\r
-\r
- Data = AllocatePool (Len);\r
-\r
- if (Data == NULL) {\r
- return ;\r
- }\r
-\r
- Status = Ip4Config->GetData (Ip4Config, &Len, Data);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
-\r
- IpIf = IpSb->DefaultInterface;\r
-\r
- //\r
- // If the default address has been configured don't change it.\r
- // This is unlikely to happen if EFI_IP4_CONFIG protocol has\r
- // informed us to reconfigure each time it wants to change the\r
- // configuration parameters.\r
- //\r
- if (IpIf->Configured) {\r
- goto ON_EXIT;\r
- }\r
-\r
- //\r
- // Set the default interface's address, then add a directed\r
- // route for it, that is, the route whose nexthop is zero.\r
- //\r
- StationAddress = EFI_NTOHL (Data->StationAddress);\r
- SubnetMask = EFI_NTOHL (Data->SubnetMask);\r
- Status = Ip4SetAddress (IpIf, StationAddress, SubnetMask);\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
-\r
- if (IpIf->Arp != NULL) {\r
- // \r
- // A non-NULL IpIf->Arp here means a new ARP child is created when setting default address, \r
- // but some IP children may have referenced the default interface before it is configured,\r
- // these IP instances also consume this ARP protocol so they need to open it BY_CHILD_CONTROLLER.\r
- //\r
- Arp = NULL;\r
- NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {\r
- Ip4Instance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, AddrLink, IP4_PROTOCOL_SIGNATURE);\r
- Status = gBS->OpenProtocol (\r
- IpIf->ArpHandle,\r
- &gEfiArpProtocolGuid,\r
- (VOID **) &Arp,\r
- gIp4DriverBinding.DriverBindingHandle,\r
- Ip4Instance->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
- }\r
- }\r
-\r
- Ip4AddRoute (\r
- IpSb->DefaultRouteTable,\r
- StationAddress,\r
- SubnetMask,\r
- IP4_ALLZERO_ADDRESS\r
- );\r
-\r
- //\r
- // Add routes returned by EFI_IP4_CONFIG protocol.\r
- //\r
- for (Index = 0; Index < Data->RouteTableSize; Index++) {\r
- RouteEntry = &Data->RouteTable[Index];\r
-\r
- SubnetAddress = EFI_NTOHL (RouteEntry->SubnetAddress);\r
- SubnetMask = EFI_NTOHL (RouteEntry->SubnetMask);\r
- GatewayAddress = EFI_NTOHL (RouteEntry->GatewayAddress);\r
- Ip4AddRoute (IpSb->DefaultRouteTable, SubnetAddress, SubnetMask, GatewayAddress);\r
- }\r
-\r
- IpSb->State = IP4_SERVICE_CONFIGED;\r
-\r
-ON_EXIT:\r
- FreePool (Data);\r
-}\r
-\r
-/**\r
- Request Ip4AutoConfigCallBackDpc 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
-Ip4AutoConfigCallBack (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- IP4_SERVICE *IpSb;\r
-\r
- IpSb = (IP4_SERVICE *) Context;\r
- IpSb->ActiveEvent = Event;\r
-\r
- //\r
- // Request Ip4AutoConfigCallBackDpc as a DPC at TPL_CALLBACK\r
- //\r
- QueueDpc (TPL_CALLBACK, Ip4AutoConfigCallBackDpc, Context);\r
-}\r
-\r
-\r
-/**\r
- Start the auto configuration for this IP service instance.\r
- It will locates the EFI_IP4_CONFIG_PROTOCOL, then start the\r
- auto configuration.\r
-\r
- @param[in] IpSb The IP4 service instance to configure\r
-\r
- @retval EFI_SUCCESS The auto configuration is successfull started\r
- @retval Others Failed to start auto configuration.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip4StartAutoConfig (\r
- IN IP4_SERVICE *IpSb\r
- )\r
-{\r
- EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
- EFI_STATUS Status;\r
-\r
- if (IpSb->State > IP4_SERVICE_UNSTARTED) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Create the DoneEvent and ReconfigEvent to call EFI_IP4_CONFIG\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- Ip4AutoConfigCallBack,\r
- IpSb,\r
- &IpSb->DoneEvent\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- Ip4AutoConfigCallBack,\r
- IpSb,\r
- &IpSb->ReconfigEvent\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto CLOSE_DONE_EVENT;\r
- }\r
-\r
- //\r
- // Open the EFI_IP4_CONFIG protocol then start auto configure\r
- //\r
- Status = gBS->OpenProtocol (\r
- IpSb->Controller,\r
- &gEfiIp4ConfigProtocolGuid,\r
- (VOID **) &Ip4Config,\r
- IpSb->Image,\r
- IpSb->Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto CLOSE_RECONFIG_EVENT;\r
- }\r
-\r
- Status = Ip4Config->Start (Ip4Config, IpSb->DoneEvent, IpSb->ReconfigEvent);\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->CloseProtocol (\r
- IpSb->Controller,\r
- &gEfiIp4ConfigProtocolGuid,\r
- IpSb->Image,\r
- IpSb->Controller\r
- );\r
-\r
- goto CLOSE_RECONFIG_EVENT;\r
- }\r
-\r
- IpSb->Ip4Config = Ip4Config;\r
- IpSb->State = IP4_SERVICE_STARTED;\r
- return Status;\r
-\r
-CLOSE_RECONFIG_EVENT:\r
- gBS->CloseEvent (IpSb->ReconfigEvent);\r
- IpSb->ReconfigEvent = NULL;\r
-\r
-CLOSE_DONE_EVENT:\r
- gBS->CloseEvent (IpSb->DoneEvent);\r
- IpSb->DoneEvent = NULL;\r
-\r
- return Status;\r
-}\r
-\r
-\r
/**\r
Intiialize the IP4_PROTOCOL structure to the unconfigured states.\r
\r
IpInstance->Signature = IP4_PROTOCOL_SIGNATURE;\r
CopyMem (&IpInstance->Ip4Proto, &mEfiIp4ProtocolTemplete, sizeof (IpInstance->Ip4Proto));\r
IpInstance->State = IP4_STATE_UNCONFIGED;\r
+ IpInstance->InDestroy = FALSE;\r
IpInstance->Service = IpSb;\r
\r
InitializeListHead (&IpInstance->Link);\r
IP4_ADDR Ip;\r
IP4_ADDR Netmask;\r
EFI_ARP_PROTOCOL *Arp;\r
+ EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;\r
+ EFI_IP4_CONFIG2_POLICY Policy;\r
\r
IpSb = IpInstance->Service;\r
\r
+ Ip4Config2 = NULL;\r
+\r
//\r
// User is changing packet filters. It must be stopped\r
// before the station address can be changed.\r
}\r
\r
//\r
- // Add a route to this connected network in the route table\r
+ // Add a route to this connected network in the instance route table.\r
//\r
- Ip4AddRoute (IpInstance->RouteTable, Ip, Netmask, IP4_ALLZERO_ADDRESS);\r
-\r
+ Ip4AddRoute (\r
+ IpInstance->RouteTable,\r
+ Ip & Netmask,\r
+ Netmask,\r
+ IP4_ALLZERO_ADDRESS\r
+ );\r
} else {\r
//\r
- // Use the default address. If the default configuration hasn't\r
- // been started, start it.\r
+ // Use the default address. Check the state.\r
//\r
if (IpSb->State == IP4_SERVICE_UNSTARTED) {\r
- Status = Ip4StartAutoConfig (IpSb);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
+ //\r
+ // Trigger the EFI_IP4_CONFIG2_PROTOCOL to retrieve the\r
+ // default IPv4 address if it is not available yet.\r
+ //\r
+ Policy = IpSb->Ip4Config2Instance.Policy;\r
+ if (Policy != Ip4Config2PolicyDhcp) {\r
+ Ip4Config2 = &IpSb->Ip4Config2Instance.Ip4Config2;\r
+ Policy = Ip4Config2PolicyDhcp;\r
+ Status= Ip4Config2->SetData (\r
+ Ip4Config2,\r
+ Ip4Config2DataTypePolicy,\r
+ sizeof (EFI_IP4_CONFIG2_POLICY),\r
+ &Policy\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
}\r
}\r
\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
if (EFI_ERROR (Status)) {\r
+ Ip4FreeInterface (IpIf, IpInstance);\r
goto ON_ERROR;\r
}\r
}\r
\r
@param[in] IpInstance The IP4 child to clean up.\r
\r
- @retval EFI_SUCCESS The IP4 child is cleaned up\r
- @retval EFI_DEVICE_ERROR Some resources failed to be released\r
+ @retval EFI_SUCCESS The IP4 child is cleaned up.\r
+ @retval EFI_DEVICE_ERROR Some resources failed to be released.\r
\r
**/\r
EFI_STATUS\r
}\r
\r
\r
-/**\r
- Validate that Ip/Netmask pair is OK to be used as station\r
- address. Only continuous netmasks are supported. and check\r
- that StationAddress is a unicast address on the newtwork.\r
-\r
- @param[in] Ip The IP address to validate\r
- @param[in] Netmask The netmaks of the IP\r
-\r
- @retval TRUE The Ip/Netmask pair is valid\r
- @retval FALSE The Ip/Netmask pair is invalid\r
-\r
-**/\r
-BOOLEAN\r
-Ip4StationAddressValid (\r
- IN IP4_ADDR Ip,\r
- IN IP4_ADDR Netmask\r
- )\r
-{\r
- IP4_ADDR NetBrdcastMask;\r
- INTN Len;\r
- INTN Type;\r
-\r
- //\r
- // Only support the station address with 0.0.0.0/0 to enable DHCP client.\r
- //\r
- if (Netmask == IP4_ALLZERO_ADDRESS) {\r
- return (BOOLEAN) (Ip == IP4_ALLZERO_ADDRESS);\r
- }\r
-\r
- //\r
- // Only support the continuous net masks\r
- //\r
- if ((Len = NetGetMaskLength (Netmask)) == IP4_MASK_NUM) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Station address can't be class D or class E address\r
- //\r
- if ((Type = NetGetIpClass (Ip)) > IP4_ADDR_CLASSC) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Station address can't be subnet broadcast/net broadcast address\r
- //\r
- if ((Ip == (Ip & Netmask)) || (Ip == (Ip | ~Netmask))) {\r
- return FALSE;\r
- }\r
-\r
- NetBrdcastMask = gIp4AllMasks[MIN (Len, Type << 3)];\r
-\r
- if (Ip == (Ip | ~NetBrdcastMask)) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
/**\r
Assigns an IPv4 address and subnet mask to this EFI IPv4 Protocol driver instance.\r
\r
Status = Ip4CleanProtocol (IpInstance);\r
\r
//\r
- // Don't change the state if it is DESTROY, consider the following\r
- // valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped,\r
+ // Consider the following valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped,\r
// Configure (ThisIp, NULL). If the state is changed to UNCONFIGED,\r
// the unload fails miserably.\r
//\r
should make sure that the parameters is valid.\r
\r
@param[in] IpInstance The IP4 child to change the setting.\r
- @param[in] JoinFlag TRUE to join the group, otherwise leave it\r
- @param[in] GroupAddress The target group address\r
+ @param[in] JoinFlag TRUE to join the group, otherwise leave it.\r
+ @param[in] GroupAddress The target group address.\r
\r
- @retval EFI_ALREADY_STARTED Want to join the group, but already a member of it\r
+ @retval EFI_ALREADY_STARTED Want to join the group, but already a member of it.\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.\r
- @retval EFI_DEVICE_ERROR Failed to set the group configuraton\r
+ @retval EFI_DEVICE_ERROR Failed to set the group configuraton.\r
@retval EFI_SUCCESS Successfully updated the group setting.\r
@retval EFI_NOT_FOUND Try to leave the group which it isn't a member.\r
\r
// is decreamented each time an address is removed..\r
//\r
for (Index = IpInstance->GroupCount; Index > 0 ; Index--) {\r
+ ASSERT (IpInstance->Groups != NULL);\r
Group = IpInstance->Groups[Index - 1];\r
-\r
if ((GroupAddress == NULL) || EFI_IP4_EQUAL (&Group, GroupAddress)) {\r
if (EFI_ERROR (Ip4LeaveGroup (IpInstance, NTOHL (Group)))) {\r
return EFI_DEVICE_ERROR;\r
// the gateway address must be a unicast on the connected network if not zero.\r
//\r
if ((Nexthop != IP4_ALLZERO_ADDRESS) &&\r
- (!IP4_NET_EQUAL (Nexthop, IpIf->Ip, IpIf->SubnetMask) ||\r
+ ((IpIf->SubnetMask != IP4_ALLONE_ADDRESS && !IP4_NET_EQUAL (Nexthop, IpIf->Ip, IpIf->SubnetMask)) ||\r
IP4_IS_BROADCAST (Ip4GetNetCast (Nexthop, IpIf)))) {\r
\r
Status = EFI_INVALID_PARAMETER;\r
\r
@param[in] Map The container of either user's transmit or receive\r
token.\r
- @param[in] Item Current item to check against\r
+ @param[in] Item Current item to check against.\r
@param[in] Context The Token to check againist.\r
\r
- @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP\r
+ @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP.\r
@retval EFI_SUCCESS The current item isn't the same token/event as the\r
context.\r
\r
are bound together. Check the comments in Ip4Output for information\r
about IP fragmentation.\r
\r
- @param[in] Context The token's wrap\r
+ @param[in] Context The token's wrap.\r
\r
**/\r
VOID\r
The callback function to Ip4Output to update the transmit status.\r
\r
@param Ip4Instance The Ip4Instance that request the transmit.\r
- @param Packet The user's transmit request\r
- @param IoStatus The result of the transmission\r
- @param Flag Not used during transmission\r
+ @param Packet The user's transmit request.\r
+ @param IoStatus The result of the transmission.\r
+ @param Flag Not used during transmission.\r
@param Context The token's wrap.\r
\r
**/\r
@retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length + total data length is\r
greater than MTU (or greater than the maximum packet size if\r
Token.Packet.TxData.OverrideData.\r
- DoNotFragment is TRUE.)\r
+ DoNotFragment is TRUE).\r
\r
**/\r
EFI_STATUS\r
}\r
\r
RawHdrLen = (UINT8) (RawHdrLen << 2);\r
- \r
+\r
CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);\r
\r
Ip4NtohHead (&Head);\r
Because Ip4CancelPacket and other functions are all called in\r
line, so, after Ip4CancelPacket returns, the Item has been freed.\r
\r
- @param[in] Map The IP4 child's transmit queue\r
- @param[in] Item The current transmitted packet to test.\r
- @param[in] Context The user's token to cancel.\r
+ @param[in] Map The IP4 child's transmit queue.\r
+ @param[in] Item The current transmitted packet to test.\r
+ @param[in] Context The user's token to cancel.\r
\r
@retval EFI_SUCCESS Continue to check the next Item.\r
@retval EFI_ABORTED The user's Token (Token != NULL) is cancelled.\r
Cancel the receive request. This is quiet simple, because\r
it is only enqueued in our local receive map.\r
\r
- @param[in] Map The IP4 child's receive queue\r
- @param[in] Item Current receive request to cancel.\r
- @param[in] Context The user's token to cancel\r
+ @param[in] Map The IP4 child's receive queue.\r
+ @param[in] Item Current receive request to cancel.\r
+ @param[in] Context The user's token to cancel.\r
\r
@retval EFI_SUCCESS Continue to check the next receive request on the\r
queue.\r
/**\r
Cancel the user's receive/transmit request.\r
\r
- @param[in] IpInstance The IP4 child\r
+ @param[in] IpInstance The IP4 child.\r
@param[in] Token The token to cancel. If NULL, all token will be\r
cancelled.\r
\r
- @retval EFI_SUCCESS The token is cancelled\r
+ @retval EFI_SUCCESS The token is cancelled.\r
@retval EFI_NOT_FOUND The token isn't found on either the\r
- transmit/receive queue\r
+ transmit/receive queue.\r
@retval EFI_DEVICE_ERROR Not all token is cancelled when Token is NULL.\r
\r
**/\r
packets.\r
\r
@param[in] Map The IP4 child's transmit map.\r
- @param[in] Item Current transmitted packet\r
+ @param[in] Item Current transmitted packet.\r
@param[in] Context Not used.\r
\r
- @retval EFI_SUCCESS Always returns EFI_SUCCESS\r
+ @retval EFI_SUCCESS Always returns EFI_SUCCESS.\r
\r
**/\r
EFI_STATUS\r
return EFI_SUCCESS;\r
}\r
\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
+ This heart beat timer of IP4 service instance times out all of its IP4 children's\r
+ received-but-not-delivered and transmitted-but-not-recycle packets, and provides\r
+ time input for its IGMP protocol.\r
\r
@param[in] Event The IP4 service instance's heart beat timer.\r
@param[in] Context The IP4 service instance.\r
Ip4PacketTimerTicking (IpSb);\r
Ip4IgmpTicking (IpSb);\r
}\r
+\r
+/**\r
+ This dedicated timer is used to poll underlying network media status. In case\r
+ of cable swap or wireless network switch, a new round auto configuration will\r
+ be initiated. The timer will signal the IP4 to run DHCP configuration again.\r
+ IP4 driver will free old IP address related resource, such as route table and\r
+ Interface, then initiate a DHCP process to acquire new IP, eventually create\r
+ route table 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
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4TimerReconfigChecking (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\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
+ //\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 && (IpSb->Ip4Config2Instance.Policy == Ip4Config2PolicyDhcp)) {\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