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