]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
Fix issue that node is still reachable after executing ifconfig –c.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4Config.c
CommitLineData
b2570da8 1/** @file\r
402fa70f 2 This code implements the IP4Config and NicIp4Config protocols.\r
b2570da8 3\r
5f6aee0f 4Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
b2570da8 6are licensed and made available under the terms and conditions of the BSD License\r
402fa70f 7which accompanies this distribution. The full text of the license may be found at<BR>\r
b2570da8 8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
b2570da8 13**/\r
14\r
15#include "Ip4Config.h"\r
74df5026 16#include "NicIp4Variable.h"\r
b2570da8 17\r
72ed3d75 18//\r
19// Ip4 Config Protocol\r
20//\r
21GLOBAL_REMOVE_IF_UNREFERENCED EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate = {\r
22 EfiIp4ConfigStart,\r
23 EfiIp4ConfigStop,\r
24 EfiIp4ConfigGetData\r
25};\r
b2570da8 26\r
27/**\r
c8d8f1e3 28 Get the NIC's configure information from the IP4 configure variable.\r
b2570da8 29 It will remove the invalid variable.\r
30\r
74df5026 31 @param Instance The IP4 CONFIG instance.\r
b2570da8 32\r
33 @return NULL if no configure for the NIC in the variable, or it is invalid.\r
c8d8f1e3 34 Otherwise the pointer to the NIC's IP configure parameter will be returned.\r
b2570da8 35\r
36**/\r
37NIC_IP4_CONFIG_INFO *\r
74df5026 38EfiNicIp4ConfigGetInfo (\r
39 IN IP4_CONFIG_INSTANCE *Instance\r
b2570da8 40 )\r
41{\r
74df5026 42 NIC_IP4_CONFIG_INFO *NicConfig;\r
b2570da8 43\r
44 //\r
74df5026 45 // Read the configuration parameter for this NIC from\r
b2570da8 46 // the EFI variable\r
47 //\r
74df5026 48 NicConfig = Ip4ConfigReadVariable (Instance);\r
49 if (NicConfig == NULL) {\r
b2570da8 50 return NULL;\r
51 }\r
52\r
53 //\r
54 // Validate the configuration, if the configuration is invalid,\r
55 // remove it from the variable.\r
56 //\r
74df5026 57 if (!Ip4ConfigIsValid (NicConfig)) {\r
58 Ip4ConfigWriteVariable (Instance, NULL);\r
b2570da8 59\r
74df5026 60 FreePool (NicConfig);\r
61 NicConfig = NULL;\r
b2570da8 62 }\r
63\r
74df5026 64 return NicConfig;\r
b2570da8 65}\r
66\r
b2570da8 67/**\r
d80ea739 68 Set the IP configure parameters for this NIC.\r
c8d8f1e3 69\r
d80ea739 70 If Reconfig is TRUE, the IP driver will be informed to discard current\r
71 auto configure parameter and restart the auto configuration process.\r
c8d8f1e3 72 If current there is a pending auto configuration, EFI_ALREADY_STARTED is\r
b2570da8 73 returned. You can only change the configure setting when either\r
74 the configure has finished or not started yet. If NicConfig, the\r
75 NIC's configure parameter is removed from the variable.\r
76\r
63886849 77 @param Instance The IP4 CONFIG instance.\r
d80ea739 78 @param NicConfig The new NIC IP4 configure parameter.\r
b2570da8 79 @param Reconfig Inform the IP4 driver to restart the auto\r
d80ea739 80 configuration.\r
81\r
82 @retval EFI_SUCCESS The configure parameter for this NIC was\r
83 set successfully.\r
b2570da8 84 @retval EFI_INVALID_PARAMETER This is NULL or the configure parameter is\r
85 invalid.\r
86 @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
d80ea739 87 @retval EFI_NOT_FOUND No auto configure parameter is found.\r
b2570da8 88\r
89**/\r
90EFI_STATUS\r
91EFIAPI\r
92EfiNicIp4ConfigSetInfo (\r
63886849 93 IN IP4_CONFIG_INSTANCE *Instance,\r
3e8c18da 94 IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL,\r
b2570da8 95 IN BOOLEAN Reconfig\r
96 )\r
97{\r
74df5026 98 EFI_STATUS Status;\r
b2570da8 99\r
100 //\r
101 // Validate the parameters\r
102 //\r
63886849 103 if (Instance == NULL) {\r
b2570da8 104 return EFI_INVALID_PARAMETER;\r
105 }\r
106\r
b2570da8 107 if ((NicConfig != NULL) && (!Ip4ConfigIsValid (NicConfig) ||\r
108 !NIC_ADDR_EQUAL (&NicConfig->NicAddr, &Instance->NicAddr))) {\r
109 return EFI_INVALID_PARAMETER;\r
110 }\r
111\r
112 if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
113 return EFI_ALREADY_STARTED;\r
114 }\r
115\r
116 //\r
117 // Update the parameter in the configure variable\r
118 //\r
74df5026 119 Status = Ip4ConfigWriteVariable (Instance, NicConfig);\r
b2570da8 120 if (EFI_ERROR (Status)) {\r
121 return Status;\r
122 }\r
123\r
124 //\r
125 // Signal the IP4 to run the auto configuration again\r
126 //\r
127 if (Reconfig && (Instance->ReconfigEvent != NULL)) {\r
5f6aee0f 128 //\r
129 // When NicConfig is NULL, NIC IP4 configuration parameter is removed,\r
130 // the auto configuration process should stop running the configuration\r
131 // policy for the EFI IPv4 Protocol driver.\r
132 //\r
133 if (NicConfig == NULL) {\r
134 Instance->DoNotStart = TRUE;\r
135 }\r
136\r
b2570da8 137 Status = gBS->SignalEvent (Instance->ReconfigEvent);\r
d8d26fb2 138 DispatchDpc ();\r
b2570da8 139 }\r
140\r
8ac1fc05 141 if (NicConfig == NULL) {\r
142 return Status;\r
143 }\r
9f82599a 144 //\r
145 // A dedicated timer is used to poll underlying media status.In case of\r
146 // cable swap, a new round auto configuration will be initiated. The timer\r
147 // starts in DHCP policy only. STATIC policy stops the timer.\r
148 // \r
149 if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
150 gBS->SetTimer (Instance->Timer, TimerPeriodic, TICKS_PER_SECOND);\r
151 } else if (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC) {\r
152 gBS->SetTimer (Instance->Timer, TimerCancel, 0);\r
153 }\r
154 \r
b2570da8 155 return Status;\r
156}\r
157\r
c8d8f1e3 158/**\r
159 Callback function when DHCP process finished. It will save the\r
160 retrieved IP configure parameter from DHCP to the NVRam.\r
161\r
162 @param Event The callback event\r
163 @param Context Opaque context to the callback\r
164\r
165 @return None\r
166\r
167**/\r
168VOID\r
169EFIAPI\r
170Ip4ConfigOnDhcp4Complete (\r
171 IN EFI_EVENT Event,\r
172 IN VOID *Context\r
173 )\r
174{\r
175 IP4_CONFIG_INSTANCE *Instance;\r
176 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
177 EFI_IP4_IPCONFIG_DATA *Ip4Config;\r
178 EFI_STATUS Status;\r
179 BOOLEAN Perment;\r
180 IP4_ADDR Subnet;\r
181 IP4_ADDR Ip1;\r
182 IP4_ADDR Ip2;\r
183\r
184 Instance = (IP4_CONFIG_INSTANCE *) Context;\r
185 ASSERT (Instance->Dhcp4 != NULL);\r
186\r
187 Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
188 Instance->Result = EFI_TIMEOUT;\r
189\r
190 //\r
191 // Get the DHCP retrieved parameters\r
192 //\r
193 Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);\r
194\r
195 if (EFI_ERROR (Status)) {\r
196 goto ON_EXIT;\r
197 }\r
198\r
199 if (Dhcp4Mode.State == Dhcp4Bound) {\r
200 //\r
201 // Save the new configuration retrieved by DHCP both in\r
202 // the instance and to NVRam. So, both the IP4 driver and\r
203 // other user can get that address.\r
204 //\r
205 Perment = FALSE;\r
206\r
207 if (Instance->NicConfig != NULL) {\r
208 ASSERT (Instance->NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
209 Perment = Instance->NicConfig->Perment;\r
766c7483 210 FreePool (Instance->NicConfig);\r
c8d8f1e3 211 }\r
212\r
213 Instance->NicConfig = AllocatePool (sizeof (NIC_IP4_CONFIG_INFO) + 2* sizeof (EFI_IP4_ROUTE_TABLE));\r
214\r
215 if (Instance->NicConfig == NULL) {\r
216 Instance->Result = EFI_OUT_OF_RESOURCES;\r
217 goto ON_EXIT;\r
218 }\r
219\r
220 Instance->NicConfig->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (Instance->NicConfig + 1);\r
221\r
222 CopyMem (&Instance->NicConfig->NicAddr, &Instance->NicAddr, sizeof (Instance->NicConfig->NicAddr));\r
223 Instance->NicConfig->Source = IP4_CONFIG_SOURCE_DHCP;\r
224 Instance->NicConfig->Perment = Perment;\r
225\r
226 Ip4Config = &Instance->NicConfig->Ip4Info;\r
227 Ip4Config->StationAddress = Dhcp4Mode.ClientAddress;\r
228 Ip4Config->SubnetMask = Dhcp4Mode.SubnetMask;\r
229\r
230 //\r
231 // Create a route for the connected network\r
232 //\r
233 Ip4Config->RouteTableSize = 1;\r
234\r
235 CopyMem (&Ip1, &Dhcp4Mode.ClientAddress, sizeof (IP4_ADDR));\r
236 CopyMem (&Ip2, &Dhcp4Mode.SubnetMask, sizeof (IP4_ADDR));\r
237\r
238 Subnet = Ip1 & Ip2;\r
239\r
240 CopyMem (&Ip4Config->RouteTable[0].SubnetAddress, &Subnet, sizeof (EFI_IPv4_ADDRESS));\r
241 CopyMem (&Ip4Config->RouteTable[0].SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
242 ZeroMem (&Ip4Config->RouteTable[0].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
243\r
244 //\r
245 // Create a route if there is a default router.\r
246 //\r
247 if (!EFI_IP4_EQUAL (&Dhcp4Mode.RouterAddress, &mZeroIp4Addr)) {\r
248 Ip4Config->RouteTableSize = 2;\r
249\r
250 ZeroMem (&Ip4Config->RouteTable[1].SubnetAddress, sizeof (EFI_IPv4_ADDRESS));\r
251 ZeroMem (&Ip4Config->RouteTable[1].SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
252 CopyMem (&Ip4Config->RouteTable[1].GatewayAddress, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
253 }\r
254\r
255 Instance->Result = EFI_SUCCESS;\r
256\r
257 //\r
258 // ignore the return status of EfiNicIp4ConfigSetInfo. Network\r
259 // stack can operate even that failed.\r
260 //\r
63886849 261 EfiNicIp4ConfigSetInfo (Instance, Instance->NicConfig, FALSE);\r
c8d8f1e3 262 }\r
263\r
264ON_EXIT:\r
265 gBS->SignalEvent (Instance->DoneEvent);\r
266 Ip4ConfigCleanDhcp4 (Instance);\r
267\r
d8d26fb2 268 DispatchDpc ();\r
c8d8f1e3 269\r
270 return ;\r
271}\r
b2570da8 272\r
273/**\r
402fa70f 274 Starts running the configuration policy for the EFI IPv4 Protocol driver.\r
d80ea739 275\r
276 The Start() function is called to determine and to begin the platform\r
277 configuration policy by the EFI IPv4 Protocol driver. This determination may\r
278 be as simple as returning EFI_UNSUPPORTED if there is no EFI IPv4 Protocol\r
279 driver configuration policy. It may be as involved as loading some defaults\r
280 from nonvolatile storage, downloading dynamic data from a DHCP server, and\r
402fa70f 281 checking permissions with a site policy server.\r
d80ea739 282 Starting the configuration policy is just the beginning. It may finish almost\r
283 instantly or it may take several minutes before it fails to retrieve configuration\r
284 information from one or more servers. Once the policy is started, drivers\r
285 should use the DoneEvent parameter to determine when the configuration policy\r
286 has completed. EFI_IP4_CONFIG_PROTOCOL.GetData() must then be called to\r
402fa70f 287 determine if the configuration succeeded or failed.\r
d80ea739 288 Until the configuration completes successfully, EFI IPv4 Protocol driver instances\r
402fa70f 289 that are attempting to use default configurations must return EFI_NO_MAPPING.\r
d80ea739 290 Once the configuration is complete, the EFI IPv4 Configuration Protocol driver\r
291 signals DoneEvent. The configuration may need to be updated in the future,\r
292 however; in this case, the EFI IPv4 Configuration Protocol driver must signal\r
293 ReconfigEvent, and all EFI IPv4 Protocol driver instances that are using default\r
294 configurations must return EFI_NO_MAPPING until the configuration policy has\r
402fa70f 295 been rerun.\r
296\r
297 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
d80ea739 298 @param DoneEvent Event that will be signaled when the EFI IPv4\r
299 Protocol driver configuration policy completes\r
402fa70f 300 execution. This event must be of type EVT_NOTIFY_SIGNAL.\r
d80ea739 301 @param ReconfigEvent Event that will be signaled when the EFI IPv4\r
302 Protocol driver configuration needs to be updated.\r
402fa70f 303 This event must be of type EVT_NOTIFY_SIGNAL.\r
d80ea739 304\r
305 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol\r
402fa70f 306 driver is now running.\r
307 @retval EFI_INVALID_PARAMETER One or more of the following parameters is NULL:\r
308 This\r
309 DoneEvent\r
310 ReconfigEvent\r
311 @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
d80ea739 312 @retval EFI_ALREADY_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 313 driver was already started.\r
314 @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.\r
d80ea739 315 @retval EFI_UNSUPPORTED This interface does not support the EFI IPv4 Protocol\r
402fa70f 316 driver configuration.\r
b2570da8 317\r
318**/\r
319EFI_STATUS\r
320EFIAPI\r
321EfiIp4ConfigStart (\r
322 IN EFI_IP4_CONFIG_PROTOCOL *This,\r
323 IN EFI_EVENT DoneEvent,\r
324 IN EFI_EVENT ReconfigEvent\r
325 )\r
326{\r
327 IP4_CONFIG_INSTANCE *Instance;\r
328 EFI_DHCP4_PROTOCOL *Dhcp4;\r
329 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
330 EFI_DHCP4_PACKET_OPTION *OptionList[1];\r
331 IP4_CONFIG_DHCP4_OPTION ParaList;\r
332 EFI_STATUS Status;\r
333 UINT32 Source;\r
334 EFI_TPL OldTpl;\r
335\r
336 if ((This == NULL) || (DoneEvent == NULL) || (ReconfigEvent == NULL)) {\r
337 return EFI_INVALID_PARAMETER;\r
338 }\r
339\r
340 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
341\r
e48e37fc 342 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 343\r
344 if (Instance->State != IP4_CONFIG_STATE_IDLE) {\r
345 Status = EFI_ALREADY_STARTED;\r
346\r
347 goto ON_EXIT;\r
348 }\r
349\r
350 Instance->DoneEvent = DoneEvent;\r
351 Instance->ReconfigEvent = ReconfigEvent;\r
352\r
74df5026 353 Instance->NicConfig = EfiNicIp4ConfigGetInfo (Instance);\r
b2570da8 354\r
355 if (Instance->NicConfig == NULL) {\r
5f6aee0f 356 if (Instance->DoNotStart) {\r
357 Instance->DoNotStart = FALSE;\r
358 Status = EFI_SUCCESS;\r
359 goto ON_EXIT;\r
360 }\r
361\r
b2570da8 362 Source = IP4_CONFIG_SOURCE_DHCP;\r
363 } else {\r
364 Source = Instance->NicConfig->Source;\r
365 }\r
366\r
367 //\r
368 // If the source is static, the auto configuration is done.\r
369 // return now.\r
370 //\r
371 if (Source == IP4_CONFIG_SOURCE_STATIC) {\r
372 Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
373 Instance->Result = EFI_SUCCESS;\r
374\r
375 gBS->SignalEvent (Instance->DoneEvent);\r
376 Status = EFI_SUCCESS;\r
377 goto ON_EXIT;\r
378 }\r
379\r
380 //\r
381 // Start the dhcp process\r
382 //\r
383 ASSERT ((Source == IP4_CONFIG_SOURCE_DHCP) && (Instance->Dhcp4 == NULL));\r
384\r
385 Status = NetLibCreateServiceChild (\r
386 Instance->Controller,\r
387 Instance->Image,\r
388 &gEfiDhcp4ServiceBindingProtocolGuid,\r
389 &Instance->Dhcp4Handle\r
390 );\r
391\r
392 if (EFI_ERROR (Status)) {\r
393 goto ON_ERROR;\r
394 }\r
395\r
396 Status = gBS->OpenProtocol (\r
397 Instance->Dhcp4Handle,\r
398 &gEfiDhcp4ProtocolGuid,\r
399 (VOID **) &Instance->Dhcp4,\r
400 Instance->Image,\r
401 Instance->Controller,\r
402 EFI_OPEN_PROTOCOL_BY_DRIVER\r
403 );\r
404\r
405 if (EFI_ERROR (Status)) {\r
406 goto ON_ERROR;\r
407 }\r
408\r
409 //\r
410 // Check the current DHCP status, if the DHCP process has\r
411 // already finished, return now.\r
412 //\r
413 Dhcp4 = Instance->Dhcp4;\r
414 Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
415\r
416 if (EFI_ERROR (Status)) {\r
417 goto ON_ERROR;\r
418 }\r
419\r
420 if (Dhcp4Mode.State == Dhcp4Bound) {\r
421 Ip4ConfigOnDhcp4Complete (NULL, Instance);\r
422\r
423 goto ON_EXIT;\r
424 }\r
425\r
426 //\r
427 // Try to start the DHCP process. Use most of the current\r
428 // DHCP configuration to avoid problems if some DHCP client\r
429 // yields the control of this DHCP service to us.\r
430 //\r
431 ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;\r
432 ParaList.Head.Length = 2;\r
433 ParaList.Head.Data[0] = DHCP_TAG_NETMASK;\r
434 ParaList.Route = DHCP_TAG_ROUTER;\r
435 OptionList[0] = &ParaList.Head;\r
436 Dhcp4Mode.ConfigData.OptionCount = 1;\r
437 Dhcp4Mode.ConfigData.OptionList = OptionList;\r
438\r
439 Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
440\r
441 if (EFI_ERROR (Status)) {\r
442 goto ON_ERROR;\r
443 }\r
444\r
445 //\r
446 // Start the DHCP process\r
447 //\r
448 Status = gBS->CreateEvent (\r
449 EVT_NOTIFY_SIGNAL,\r
e48e37fc 450 TPL_CALLBACK,\r
b2570da8 451 Ip4ConfigOnDhcp4Complete,\r
452 Instance,\r
453 &Instance->Dhcp4Event\r
454 );\r
455\r
456 if (EFI_ERROR (Status)) {\r
457 goto ON_ERROR;\r
458 }\r
459\r
460 Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
461\r
462 if (EFI_ERROR (Status)) {\r
463 goto ON_ERROR;\r
464 }\r
465\r
466 Instance->State = IP4_CONFIG_STATE_STARTED;\r
467 Instance->Result = EFI_NOT_READY;\r
468\r
469ON_ERROR:\r
470 if (EFI_ERROR (Status)) {\r
471 Ip4ConfigCleanConfig (Instance);\r
472 }\r
473\r
474ON_EXIT:\r
e48e37fc 475 gBS->RestoreTPL (OldTpl);\r
b2570da8 476\r
d8d26fb2 477 DispatchDpc ();\r
7659d0c9 478\r
b2570da8 479 return Status;\r
480}\r
481\r
482\r
483/**\r
402fa70f 484 Stops running the configuration policy for the EFI IPv4 Protocol driver.\r
d80ea739 485\r
486 The Stop() function stops the configuration policy for the EFI IPv4 Protocol driver.\r
402fa70f 487 All configuration data will be lost after calling Stop().\r
b2570da8 488\r
402fa70f 489 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
b2570da8 490\r
d80ea739 491 @retval EFI_SUCCESS The configuration policy for the EFI IPv4 Protocol\r
402fa70f 492 driver has been stopped.\r
b2570da8 493 @retval EFI_INVALID_PARAMETER This is NULL.\r
d80ea739 494 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 495 driver was not started.\r
d80ea739 496\r
b2570da8 497**/\r
498EFI_STATUS\r
499EFIAPI\r
500EfiIp4ConfigStop (\r
501 IN EFI_IP4_CONFIG_PROTOCOL *This\r
502 )\r
503{\r
504 IP4_CONFIG_INSTANCE *Instance;\r
505 EFI_STATUS Status;\r
506 EFI_TPL OldTpl;\r
507\r
508 if (This == NULL) {\r
509 return EFI_INVALID_PARAMETER;\r
510 }\r
511\r
512 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
513\r
514 Status = EFI_SUCCESS;\r
e48e37fc 515 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 516\r
517 if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
518 Status = EFI_NOT_STARTED;\r
519 goto ON_EXIT;\r
520 }\r
521\r
522 //\r
523 // Release all the configure parameters. Don't signal the user\r
524 // event. The user wants to abort the configuration, this isn't\r
525 // the configuration done or reconfiguration.\r
526 //\r
527 Ip4ConfigCleanConfig (Instance);\r
528\r
529ON_EXIT:\r
e48e37fc 530 gBS->RestoreTPL (OldTpl);\r
b2570da8 531\r
532 return Status;\r
533}\r
534\r
535\r
536/**\r
402fa70f 537 Returns the default configuration data (if any) for the EFI IPv4 Protocol driver.\r
538\r
d80ea739 539 The GetData() function returns the current configuration data for the EFI IPv4\r
402fa70f 540 Protocol driver after the configuration policy has completed.\r
d80ea739 541\r
402fa70f 542 @param This Pointer to the EFI_IP4_CONFIG_PROTOCOL instance.\r
d80ea739 543 @param ConfigDataSize On input, the size of the ConfigData buffer.\r
544 On output, the count of bytes that were written\r
402fa70f 545 into the ConfigData buffer.\r
d80ea739 546 @param ConfigData Pointer to the EFI IPv4 Configuration Protocol\r
547 driver configuration data structure.\r
548 Type EFI_IP4_IPCONFIG_DATA is defined in\r
402fa70f 549 "Related Definitions" below.\r
550\r
551 @retval EFI_SUCCESS The EFI IPv4 Protocol driver configuration has been returned.\r
552 @retval EFI_INVALID_PARAMETER This is NULL.\r
d80ea739 553 @retval EFI_NOT_STARTED The configuration policy for the EFI IPv4 Protocol\r
402fa70f 554 driver is not running.\r
c8d8f1e3 555 @retval EFI_NOT_READY EFI IPv4 Protocol driver configuration is still running.\r
556 @retval EFI_ABORTED EFI IPv4 Protocol driver configuration could not complete.\r
557 Currently not implemented.\r
d80ea739 558 @retval EFI_BUFFER_TOO_SMALL *ConfigDataSize is smaller than the configuration\r
402fa70f 559 data buffer or ConfigData is NULL.\r
b2570da8 560\r
561**/\r
562EFI_STATUS\r
563EFIAPI\r
564EfiIp4ConfigGetData (\r
565 IN EFI_IP4_CONFIG_PROTOCOL *This,\r
566 IN OUT UINTN *ConfigDataSize,\r
567 OUT EFI_IP4_IPCONFIG_DATA *ConfigData OPTIONAL\r
568 )\r
569{\r
570 IP4_CONFIG_INSTANCE *Instance;\r
571 NIC_IP4_CONFIG_INFO *NicConfig;\r
572 EFI_STATUS Status;\r
573 EFI_TPL OldTpl;\r
574 UINTN Len;\r
575\r
576 if ((This == NULL) || (ConfigDataSize == NULL)) {\r
577 return EFI_INVALID_PARAMETER;\r
578 }\r
579\r
580 Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
581\r
582 Status = EFI_SUCCESS;\r
e48e37fc 583 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
b2570da8 584\r
585 if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
586 Status = EFI_NOT_STARTED;\r
587 } else if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
588 Status = EFI_NOT_READY;\r
589 }\r
590\r
591 if (EFI_ERROR (Status)) {\r
592 goto ON_EXIT;\r
593 }\r
594\r
595 //\r
596 // Copy the configure data if auto configuration succeeds.\r
597 //\r
598 Status = Instance->Result;\r
599\r
600 if (Status == EFI_SUCCESS) {\r
601 ASSERT (Instance->NicConfig != NULL);\r
602\r
603 NicConfig = Instance->NicConfig;\r
604 Len = SIZEOF_IP4_CONFIG_INFO (&NicConfig->Ip4Info);\r
605\r
606 if ((*ConfigDataSize < Len) || (ConfigData == NULL)) {\r
607 Status = EFI_BUFFER_TOO_SMALL;\r
608 } else {\r
e48e37fc 609 CopyMem (ConfigData, &NicConfig->Ip4Info, Len);\r
7659d0c9 610 Ip4ConfigFixRouteTablePointer (ConfigData);\r
b2570da8 611 }\r
612\r
613 *ConfigDataSize = Len;\r
614 }\r
615\r
616ON_EXIT:\r
e48e37fc 617 gBS->RestoreTPL (OldTpl);\r
b2570da8 618\r
619 return Status;\r
620}\r
621\r
b2570da8 622/**\r
623 Release all the DHCP related resources.\r
624\r
625 @param This The IP4 configure instance\r
626\r
627 @return None\r
628\r
629**/\r
630VOID\r
631Ip4ConfigCleanDhcp4 (\r
632 IN IP4_CONFIG_INSTANCE *This\r
633 )\r
634{\r
635 if (This->Dhcp4 != NULL) {\r
636 This->Dhcp4->Stop (This->Dhcp4);\r
637\r
638 gBS->CloseProtocol (\r
639 This->Dhcp4Handle,\r
640 &gEfiDhcp4ProtocolGuid,\r
641 This->Image,\r
642 This->Controller\r
643 );\r
644\r
645 This->Dhcp4 = NULL;\r
646 }\r
647\r
648 if (This->Dhcp4Handle != NULL) {\r
649 NetLibDestroyServiceChild (\r
650 This->Controller,\r
651 This->Image,\r
652 &gEfiDhcp4ServiceBindingProtocolGuid,\r
653 This->Dhcp4Handle\r
654 );\r
655\r
656 This->Dhcp4Handle = NULL;\r
657 }\r
658\r
659 if (This->Dhcp4Event == NULL) {\r
660 gBS->CloseEvent (This->Dhcp4Event);\r
661 This->Dhcp4Event = NULL;\r
662 }\r
663}\r
664\r
665\r
666/**\r
7bce0c5a 667 Clean up all the configuration parameters.\r
b2570da8 668\r
669 @param Instance The IP4 configure instance\r
670\r
671 @return None\r
672\r
673**/\r
674VOID\r
675Ip4ConfigCleanConfig (\r
676 IN IP4_CONFIG_INSTANCE *Instance\r
677 )\r
678{\r
679 if (Instance->NicConfig != NULL) {\r
766c7483 680 FreePool (Instance->NicConfig);\r
b2570da8 681 Instance->NicConfig = NULL;\r
682 }\r
683\r
684 Instance->State = IP4_CONFIG_STATE_IDLE;\r
685 Instance->DoneEvent = NULL;\r
686 Instance->ReconfigEvent = NULL;\r
687\r
688 Ip4ConfigCleanDhcp4 (Instance);\r
689}\r
690\r
9f82599a 691\r
692/**\r
693 A dedicated timer is used to poll underlying media status. In case of\r
694 cable swap, a new round auto configuration will be initiated. The timer \r
695 will signal the IP4 to run the auto configuration again. IP4 driver will free\r
696 old IP address related resource, such as route table and Interface, then\r
697 initiate a DHCP process by IP4Config->Start to acquire new IP, eventually\r
698 create route table for new IP address.\r
699\r
700 @param[in] Event The IP4 service instance's heart beat timer.\r
701 @param[in] Context The IP4 service instance.\r
702\r
703**/\r
704VOID\r
705EFIAPI\r
706MediaChangeDetect (\r
707 IN EFI_EVENT Event,\r
708 IN VOID *Context\r
709 )\r
710{\r
711 BOOLEAN OldMediaPresent;\r
712 EFI_STATUS Status;\r
713 EFI_SIMPLE_NETWORK_MODE SnpModeData;\r
714 IP4_CONFIG_INSTANCE *Instance; \r
715\r
716 Instance = (IP4_CONFIG_INSTANCE *) Context;\r
717\r
718 OldMediaPresent = Instance->MediaPresent;\r
719 \r
720 //\r
721 // Get fresh mode data from MNP, since underlying media status may change\r
722 //\r
723 Status = Instance->Mnp->GetModeData (Instance->Mnp, NULL, &SnpModeData);\r
724 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
725 return;\r
726 }\r
727\r
728 Instance->MediaPresent = SnpModeData.MediaPresent;\r
729 //\r
730 // Media transimit Unpresent to Present means new link movement is detected.\r
731 //\r
732 if (!OldMediaPresent && Instance->MediaPresent) {\r
733 //\r
734 // Signal the IP4 to run the auto configuration again. IP4 driver will free\r
735 // old IP address related resource, such as route table and Interface, then \r
736 // initiate a DHCP round by IP4Config->Start to acquire new IP, eventually \r
737 // create route table for new IP address.\r
738 //\r
739 if (Instance->ReconfigEvent != NULL) {\r
740 Status = gBS->SignalEvent (Instance->ReconfigEvent);\r
741 DispatchDpc ();\r
742 }\r
743 }\r
744}\r