]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Ip6Dxe/Ip6ConfigNv.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / Ip6Dxe / Ip6ConfigNv.c
1 /** @file
2 Helper functions for configuring or obtaining the parameters relating to IP6.
3
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "Ip6Impl.h"
11
12 CHAR16 mIp6ConfigStorageName[] = L"IP6_CONFIG_IFR_NVDATA";
13
14 /**
15 The notify function of create event when performing a manual configuration.
16
17 @param[in] Event The pointer of Event.
18 @param[in] Context The pointer of Context.
19
20 **/
21 VOID
22 EFIAPI
23 Ip6ConfigManualAddressNotify (
24 IN EFI_EVENT Event,
25 IN VOID *Context
26 )
27 {
28 *((BOOLEAN *)Context) = TRUE;
29 }
30
31 /**
32 Get the configuration data for the EFI IPv6 network stack running on the
33 communication. It is a help function to the call EfiIp6ConfigGetData().
34
35 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
36 @param[in] DataType The type of data to get.
37 @param[out] DataSize The size of buffer required in bytes.
38 @param[out] Data The data buffer in which the configuration data is returned. The
39 type of the data buffer associated with the DataType.
40 It is the caller's responsibility to free the resource.
41
42 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
43 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
44 - Ip6Config is NULL or invalid.
45 - DataSize is NULL.
46 - Data is NULL.
47 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.
48 @retval EFI_NOT_READY The specified configuration data is not ready due to an
49 asynchronous configuration process already in progress.
50 @retval EFI_NOT_FOUND The specified configuration data was not found.
51
52 **/
53 EFI_STATUS
54 Ip6ConfigNvGetData (
55 IN EFI_IP6_CONFIG_PROTOCOL *Ip6Config,
56 IN EFI_IP6_CONFIG_DATA_TYPE DataType,
57 OUT UINTN *DataSize,
58 OUT VOID **Data
59 )
60 {
61 UINTN BufferSize;
62 VOID *Buffer;
63 EFI_STATUS Status;
64
65 if ((Ip6Config == NULL) || (Data == NULL) || (DataSize == NULL)) {
66 return EFI_INVALID_PARAMETER;
67 }
68
69 BufferSize = 0;
70 Status = Ip6Config->GetData (
71 Ip6Config,
72 DataType,
73 &BufferSize,
74 NULL
75 );
76 if (Status != EFI_BUFFER_TOO_SMALL) {
77 return Status;
78 }
79
80 Buffer = AllocateZeroPool (BufferSize);
81 if (Buffer == NULL) {
82 return EFI_OUT_OF_RESOURCES;
83 }
84
85 Status = Ip6Config->GetData (
86 Ip6Config,
87 DataType,
88 &BufferSize,
89 Buffer
90 );
91 if (EFI_ERROR (Status)) {
92 FreePool (Buffer);
93 return Status;
94 }
95
96 *DataSize = BufferSize;
97 *Data = Buffer;
98
99 return EFI_SUCCESS;
100 }
101
102 /**
103 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
104 with ListHead.
105
106 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.
107
108 **/
109 VOID
110 Ip6FreeAddressInfoList (
111 IN LIST_ENTRY *ListHead
112 )
113 {
114 IP6_ADDRESS_INFO_ENTRY *Node;
115 LIST_ENTRY *Entry;
116 LIST_ENTRY *NextEntry;
117
118 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ListHead) {
119 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
120 RemoveEntryList (&Node->Link);
121 FreePool (Node);
122 }
123 }
124
125 /**
126 Convert the IPv6 address into a formatted string.
127
128 @param[in] Ip6 The IPv6 address.
129 @param[out] Str The formatted IP string.
130
131 **/
132 VOID
133 Ip6ToStr (
134 IN EFI_IPv6_ADDRESS *Ip6,
135 OUT CHAR16 *Str
136 )
137 {
138 UINTN Index;
139 BOOLEAN Short;
140 UINTN Number;
141 CHAR16 FormatString[8];
142
143 Short = FALSE;
144
145 for (Index = 0; Index < 15; Index = Index + 2) {
146 if (!Short &&
147 (Index % 2 == 0) &&
148 (Ip6->Addr[Index] == 0) &&
149 (Ip6->Addr[Index + 1] == 0)
150 )
151 {
152 //
153 // Deal with the case of ::.
154 //
155 if (Index == 0) {
156 *Str = L':';
157 *(Str + 1) = L':';
158 Str = Str + 2;
159 } else {
160 *Str = L':';
161 Str = Str + 1;
162 }
163
164 while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {
165 Index = Index + 2;
166 }
167
168 Short = TRUE;
169
170 if (Index == 16) {
171 //
172 // :: is at the end of the address.
173 //
174 *Str = L'\0';
175 break;
176 }
177 }
178
179 ASSERT (Index < 15);
180
181 if (Ip6->Addr[Index] == 0) {
182 Number = UnicodeSPrint (Str, 2 * IP6_STR_MAX_SIZE, L"%x:", (UINTN)Ip6->Addr[Index + 1]);
183 } else {
184 if (Ip6->Addr[Index + 1] < 0x10) {
185 CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));
186 } else {
187 CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));
188 }
189
190 Number = UnicodeSPrint (
191 Str,
192 2 * IP6_STR_MAX_SIZE,
193 (CONST CHAR16 *)FormatString,
194 (UINTN)Ip6->Addr[Index],
195 (UINTN)Ip6->Addr[Index + 1]
196 );
197 }
198
199 Str = Str + Number;
200
201 if (Index + 2 == 16) {
202 *Str = L'\0';
203 if (*(Str - 1) == L':') {
204 *(Str - 1) = L'\0';
205 }
206 }
207 }
208 }
209
210 /**
211 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
212
213 @param[out] String The buffer to store the converted string.
214 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
215
216 @retval EFI_SUCCESS The string converted successfully.
217 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
218
219 **/
220 EFI_STATUS
221 Ip6ConvertInterfaceIdToString (
222 OUT CHAR16 *String,
223 IN EFI_IP6_CONFIG_INTERFACE_ID *IfId
224 )
225 {
226 UINT8 Index;
227 UINTN Number;
228
229 if ((String == NULL) || (IfId == NULL)) {
230 return EFI_INVALID_PARAMETER;
231 }
232
233 for (Index = 0; Index < 8; Index++) {
234 Number = UnicodeSPrint (
235 String,
236 2 * INTERFACE_ID_STR_STORAGE,
237 L"%x:",
238 (UINTN)IfId->Id[Index]
239 );
240 String = String + Number;
241 }
242
243 *(String - 1) = '\0';
244
245 return EFI_SUCCESS;
246 }
247
248 /**
249 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
250
251 @param[in] String The buffer of the string to be parsed.
252 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
253
254 @retval EFI_SUCCESS The operation finished successfully.
255 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
256
257 **/
258 EFI_STATUS
259 Ip6ParseInterfaceIdFromString (
260 IN CONST CHAR16 *String,
261 OUT EFI_IP6_CONFIG_INTERFACE_ID *IfId
262 )
263 {
264 UINT8 Index;
265 CHAR16 *IfIdStr;
266 CHAR16 *TempStr;
267 UINTN NodeVal;
268
269 if ((String == NULL) || (IfId == NULL)) {
270 return EFI_INVALID_PARAMETER;
271 }
272
273 IfIdStr = (CHAR16 *)String;
274
275 ZeroMem (IfId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID));
276
277 for (Index = 0; Index < 8; Index++) {
278 TempStr = IfIdStr;
279
280 while ((*IfIdStr != L'\0') && (*IfIdStr != L':')) {
281 IfIdStr++;
282 }
283
284 //
285 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
286 // If the number of X is less than 8, zero is appended to the InterfaceId.
287 //
288 if ((*IfIdStr == ':') && (Index == 7)) {
289 return EFI_INVALID_PARAMETER;
290 }
291
292 //
293 // Convert the string to interface id. AsciiStrHexToUintn stops at the
294 // first character that is not a valid hex character, ':' or '\0' here.
295 //
296 NodeVal = StrHexToUintn (TempStr);
297 if (NodeVal > 0xFF) {
298 return EFI_INVALID_PARAMETER;
299 }
300
301 IfId->Id[Index] = (UINT8)NodeVal;
302
303 IfIdStr++;
304 }
305
306 return EFI_SUCCESS;
307 }
308
309 /**
310 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
311 a help function.
312
313 @param[in] StartLabelNumber The number of start label.
314 @param[out] StartOpCodeHandle Points to the start opcode handle.
315 @param[out] StartLabel Points to the created start opcode.
316 @param[out] EndOpCodeHandle Points to the end opcode handle.
317 @param[out] EndLabel Points to the created end opcode.
318
319 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
320 operation.
321 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
322 @retval EFI_SUCCESS The operation completed successfully.
323
324 **/
325 EFI_STATUS
326 Ip6CreateOpCode (
327 IN UINT16 StartLabelNumber,
328 OUT VOID **StartOpCodeHandle,
329 OUT EFI_IFR_GUID_LABEL **StartLabel,
330 OUT VOID **EndOpCodeHandle,
331 OUT EFI_IFR_GUID_LABEL **EndLabel
332 )
333 {
334 EFI_STATUS Status;
335 EFI_IFR_GUID_LABEL *InternalStartLabel;
336 EFI_IFR_GUID_LABEL *InternalEndLabel;
337
338 if ((StartOpCodeHandle == NULL) || (StartLabel == NULL) || (EndOpCodeHandle == NULL) || (EndLabel == NULL)) {
339 return EFI_INVALID_PARAMETER;
340 }
341
342 *StartOpCodeHandle = NULL;
343 *EndOpCodeHandle = NULL;
344 Status = EFI_OUT_OF_RESOURCES;
345
346 //
347 // Initialize the container for dynamic opcodes.
348 //
349 *StartOpCodeHandle = HiiAllocateOpCodeHandle ();
350 if (*StartOpCodeHandle == NULL) {
351 return Status;
352 }
353
354 *EndOpCodeHandle = HiiAllocateOpCodeHandle ();
355 if (*EndOpCodeHandle == NULL) {
356 goto Exit;
357 }
358
359 //
360 // Create Hii Extend Label OpCode as the start opcode.
361 //
362 InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
363 *StartOpCodeHandle,
364 &gEfiIfrTianoGuid,
365 NULL,
366 sizeof (EFI_IFR_GUID_LABEL)
367 );
368 if (InternalStartLabel == NULL) {
369 goto Exit;
370 }
371
372 InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
373 InternalStartLabel->Number = StartLabelNumber;
374
375 //
376 // Create Hii Extend Label OpCode as the end opcode.
377 //
378 InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
379 *EndOpCodeHandle,
380 &gEfiIfrTianoGuid,
381 NULL,
382 sizeof (EFI_IFR_GUID_LABEL)
383 );
384 if (InternalEndLabel == NULL) {
385 goto Exit;
386 }
387
388 InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
389 InternalEndLabel->Number = LABEL_END;
390
391 *StartLabel = InternalStartLabel;
392 *EndLabel = InternalEndLabel;
393
394 return EFI_SUCCESS;
395
396 Exit:
397
398 if (*StartOpCodeHandle != NULL) {
399 HiiFreeOpCodeHandle (*StartOpCodeHandle);
400 }
401
402 if (*EndOpCodeHandle != NULL) {
403 HiiFreeOpCodeHandle (*EndOpCodeHandle);
404 }
405
406 return Status;
407 }
408
409 /**
410 This function converts the different format of address list to string format and
411 then generates the corresponding text opcode to illustrate the address info in
412 IP6 configuration page. Currently, the following formats are supported:
413 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
414 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
415 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
416
417 @param[in, out] String The pointer to the buffer to store the converted
418 string.
419 @param[in] HiiHandle A handle that was previously registered in the
420 HII Database.
421 @param[in] AddressType The address type.
422 @param[in] AddressInfo Pointer to the address list.
423 @param[in] AddressCount The address count of the address list.
424
425 @retval EFI_SUCCESS The operation finished successfully.
426 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
427 @retval EFI_UNSUPPORTED The AddressType is not supported.
428
429
430 **/
431 EFI_STATUS
432 Ip6ConvertAddressListToString (
433 IN OUT CHAR16 *String,
434 IN EFI_HII_HANDLE HiiHandle,
435 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,
436 IN VOID *AddressInfo,
437 IN UINTN AddressCount
438 )
439 {
440 UINTN Index;
441 UINTN Number;
442 CHAR16 *TempStr;
443 EFI_STATUS Status;
444 VOID *StartOpCodeHandle;
445 EFI_IFR_GUID_LABEL *StartLabel;
446 VOID *EndOpCodeHandle;
447 EFI_IFR_GUID_LABEL *EndLabel;
448 UINT16 StartLabelNumber;
449 EFI_STRING_ID TextTwo;
450 UINT8 *AddressHead;
451 UINT8 PrefixLength;
452 EFI_IPv6_ADDRESS *Address;
453
454 if ((String == NULL) || (HiiHandle == NULL) || (AddressInfo == NULL)) {
455 return EFI_INVALID_PARAMETER;
456 }
457
458 if (AddressType == Ip6ConfigNvHostAddress) {
459 StartLabelNumber = HOST_ADDRESS_LABEL;
460 } else if (AddressType == Ip6ConfigNvGatewayAddress) {
461 StartLabelNumber = GATEWAY_ADDRESS_LABEL;
462 } else if (AddressType == Ip6ConfigNvDnsAddress) {
463 StartLabelNumber = DNS_ADDRESS_LABEL;
464 } else if (AddressType == Ip6ConfigNvRouteTable) {
465 StartLabelNumber = ROUTE_TABLE_LABEL;
466 } else {
467 ASSERT (FALSE);
468 return EFI_UNSUPPORTED;
469 }
470
471 Status = Ip6CreateOpCode (
472 StartLabelNumber,
473 &StartOpCodeHandle,
474 &StartLabel,
475 &EndOpCodeHandle,
476 &EndLabel
477 );
478 if (EFI_ERROR (Status)) {
479 return Status;
480 }
481
482 AddressHead = (UINT8 *)AddressInfo;
483
484 for (Index = 0; Index < AddressCount; Index++) {
485 if (AddressType == Ip6ConfigNvHostAddress) {
486 AddressInfo = AddressHead + sizeof (EFI_IP6_ADDRESS_INFO) * Index;
487 Address = &((EFI_IP6_ADDRESS_INFO *)AddressInfo)->Address;
488 } else if (AddressType == Ip6ConfigNvRouteTable) {
489 AddressInfo = AddressHead + sizeof (EFI_IP6_ROUTE_TABLE) * Index;
490 Address = &((EFI_IP6_ROUTE_TABLE *)AddressInfo)->Destination;
491 } else {
492 AddressInfo = AddressHead + sizeof (EFI_IPv6_ADDRESS) * Index;
493 Address = AddressInfo;
494 }
495
496 //
497 // Convert the IP address info to string.
498 //
499 Ip6ToStr (Address, String);
500 TempStr = String + StrLen (String);
501
502 if ((AddressType == Ip6ConfigNvHostAddress) || (AddressType == Ip6ConfigNvRouteTable)) {
503 if (AddressType == Ip6ConfigNvHostAddress) {
504 PrefixLength = ((EFI_IP6_ADDRESS_INFO *)AddressInfo)->PrefixLength;
505 } else {
506 PrefixLength = ((EFI_IP6_ROUTE_TABLE *)AddressInfo)->PrefixLength;
507 }
508
509 //
510 // Append the prefix length to the string.
511 //
512 *TempStr = L'/';
513 TempStr++;
514 Number = UnicodeSPrint (TempStr, 6, L"%d", PrefixLength);
515 TempStr = TempStr + Number;
516 }
517
518 if (AddressType == Ip6ConfigNvRouteTable) {
519 //
520 // Append " >> " to the string.
521 //
522 Number = UnicodeSPrint (TempStr, 8, L" >> ");
523 TempStr = TempStr + Number;
524
525 //
526 // Append the gateway address to the string.
527 //
528 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE *)AddressInfo)->Gateway, TempStr);
529 TempStr = TempStr + StrLen (TempStr);
530 }
531
532 //
533 // Generate a text opcode and update the UI.
534 //
535 TextTwo = HiiSetString (HiiHandle, 0, String, NULL);
536 if (TextTwo == 0) {
537 Status = EFI_INVALID_PARAMETER;
538 goto Exit;
539 }
540
541 HiiCreateTextOpCode (StartOpCodeHandle, STR_NULL, STR_NULL, TextTwo);
542
543 String = TempStr;
544 *String = IP6_ADDRESS_DELIMITER;
545 String++;
546 }
547
548 *(String - 1) = '\0';
549
550 Status = HiiUpdateForm (
551 HiiHandle, // HII handle
552 &gIp6ConfigNvDataGuid, // Formset GUID
553 FORMID_MAIN_FORM, // Form ID
554 StartOpCodeHandle, // Label for where to insert opcodes
555 EndOpCodeHandle // Replace data
556 );
557
558 Exit:
559 HiiFreeOpCodeHandle (StartOpCodeHandle);
560 HiiFreeOpCodeHandle (EndOpCodeHandle);
561
562 return Status;
563 }
564
565 /**
566 Parse address list in string format and convert it to a list array of node in
567 IP6_ADDRESS_INFO_ENTRY.
568
569 @param[in] String The buffer to string to be parsed.
570 @param[out] ListHead The list head of array.
571 @param[out] AddressCount The number of list nodes in the array.
572
573 @retval EFI_SUCCESS The operation finished successfully.
574 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
575 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
576
577 **/
578 EFI_STATUS
579 Ip6ParseAddressListFromString (
580 IN CONST CHAR16 *String,
581 OUT LIST_ENTRY *ListHead,
582 OUT UINT32 *AddressCount
583 )
584 {
585 EFI_STATUS Status;
586 CHAR16 *LocalString;
587 CHAR16 *Temp;
588 CHAR16 *TempStr;
589 EFI_IP6_ADDRESS_INFO AddressInfo;
590 IP6_ADDRESS_INFO_ENTRY *Node;
591 BOOLEAN Last;
592 UINT32 Count;
593
594 if ((String == NULL) || (ListHead == NULL) || (AddressCount == NULL)) {
595 return EFI_INVALID_PARAMETER;
596 }
597
598 ZeroMem (&AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));
599 LocalString = (CHAR16 *)AllocateCopyPool (StrSize (String), String);
600 if (LocalString == NULL) {
601 return EFI_OUT_OF_RESOURCES;
602 }
603
604 //
605 // Clean the original address list.
606 //
607 Ip6FreeAddressInfoList (ListHead);
608
609 Temp = LocalString;
610 Last = FALSE;
611 Count = 0;
612
613 while (*LocalString != L'\0') {
614 TempStr = LocalString;
615 while ((*LocalString != L'\0') && (*LocalString != IP6_ADDRESS_DELIMITER)) {
616 LocalString++;
617 }
618
619 if (*LocalString == L'\0') {
620 Last = TRUE;
621 }
622
623 *LocalString = L'\0';
624
625 Status = NetLibStrToIp6andPrefix (TempStr, &AddressInfo.Address, &AddressInfo.PrefixLength);
626 if (EFI_ERROR (Status)) {
627 goto Error;
628 }
629
630 if (AddressInfo.PrefixLength == 0xFF) {
631 AddressInfo.PrefixLength = 0;
632 }
633
634 if (!NetIp6IsValidUnicast (&AddressInfo.Address)) {
635 Status = EFI_INVALID_PARAMETER;
636 goto Error;
637 }
638
639 Node = AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY));
640 if (Node == NULL) {
641 Status = EFI_OUT_OF_RESOURCES;
642 goto Error;
643 }
644
645 CopyMem (&Node->AddrInfo, &AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));
646 InsertTailList (ListHead, &Node->Link);
647 Count++;
648
649 if (Last) {
650 break;
651 }
652
653 LocalString++;
654 }
655
656 FreePool (Temp);
657 *AddressCount = Count;
658 return EFI_SUCCESS;
659
660 Error:
661 Ip6FreeAddressInfoList (ListHead);
662 FreePool (Temp);
663 return Status;
664 }
665
666 /**
667 This function converts the interface info to string and draws it to the IP6 UI.
668 The interface information includes interface name, interface type, hardware
669 address and route table information.
670
671 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
672 @param[in] HiiHandle The handle that was previously registered in the
673 HII Database.
674 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
675
676 @retval EFI_SUCCESS The operation finished successfully.
677 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
678 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
679
680 **/
681 EFI_STATUS
682 Ip6ConvertInterfaceInfoToString (
683 IN EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo,
684 IN EFI_HII_HANDLE HiiHandle,
685 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData
686 )
687 {
688 UINT32 Index;
689 UINTN Number;
690 CHAR16 *String;
691 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];
692 CHAR16 FormatString[8];
693 EFI_STRING_ID StringId;
694
695 if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {
696 return EFI_INVALID_PARAMETER;
697 }
698
699 //
700 // Print the interface name.
701 //
702 StringId = HiiSetString (
703 HiiHandle,
704 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT),
705 IfInfo->Name,
706 NULL
707 );
708 if (StringId == 0) {
709 return EFI_OUT_OF_RESOURCES;
710 }
711
712 //
713 // Print the interface type.
714 //
715 if (IfInfo->IfType == Ip6InterfaceTypeEthernet) {
716 CopyMem (PortString, IP6_ETHERNET, sizeof (IP6_ETHERNET));
717 } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) {
718 CopyMem (PortString, IP6_EXPERIMENTAL_ETHERNET, sizeof (IP6_EXPERIMENTAL_ETHERNET));
719 } else {
720 //
721 // Refer to RFC1700, chapter Number Hardware Type.
722 //
723 UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType);
724 }
725
726 StringId = HiiSetString (
727 HiiHandle,
728 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT),
729 PortString,
730 NULL
731 );
732 if (StringId == 0) {
733 return EFI_OUT_OF_RESOURCES;
734 }
735
736 //
737 // Convert the hardware address.
738 //
739 String = PortString;
740 ASSERT (IfInfo->HwAddressSize <= 32);
741
742 for (Index = 0; Index < IfInfo->HwAddressSize; Index++) {
743 if (IfInfo->HwAddress.Addr[Index] < 0x10) {
744 CopyMem (FormatString, L"0%x-", sizeof (L"0%x-"));
745 } else {
746 CopyMem (FormatString, L"%x-", sizeof (L"%x-"));
747 }
748
749 Number = UnicodeSPrint (
750 String,
751 8,
752 (CONST CHAR16 *)FormatString,
753 (UINTN)IfInfo->HwAddress.Addr[Index]
754 );
755 String = String + Number;
756 }
757
758 if (Index != 0) {
759 ASSERT (String > PortString);
760 String--;
761 *String = '\0';
762 }
763
764 //
765 // Print the hardware address.
766 //
767 StringId = HiiSetString (
768 HiiHandle,
769 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT),
770 PortString,
771 NULL
772 );
773 if (StringId == 0) {
774 return EFI_OUT_OF_RESOURCES;
775 }
776
777 return EFI_SUCCESS;
778 }
779
780 /**
781 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
782
783 @param[in] Instance Points to IP6 config instance data.
784 @param[in] AddressType The address type.
785 @param[out] AddressInfo The pointer to the buffer to store the address list.
786 @param[out] AddressSize The address size of the address list.
787
788 @retval EFI_SUCCESS The operation finished successfully.
789 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
790 @retval EFI_UNSUPPORTED The AddressType is not supported.
791
792 **/
793 EFI_STATUS
794 Ip6BuildNvAddressInfo (
795 IN IP6_CONFIG_INSTANCE *Instance,
796 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,
797 OUT VOID **AddressInfo,
798 OUT UINTN *AddressSize
799 )
800 {
801 IP6_CONFIG_NVDATA *Ip6NvData;
802 LIST_ENTRY *Entry;
803 LIST_ENTRY *ListHead;
804 IP6_ADDRESS_INFO_ENTRY *Node;
805 VOID *AddressList;
806 VOID *TmpStr;
807 UINTN DataSize;
808 EFI_IPv6_ADDRESS *Ip6Address;
809 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;
810
811 if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) {
812 return EFI_INVALID_PARAMETER;
813 }
814
815 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
816
817 Ip6NvData = &Instance->Ip6NvData;
818
819 if (AddressType == Ip6ConfigNvHostAddress) {
820 ListHead = &Ip6NvData->ManualAddress;
821 DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount;
822 } else if (AddressType == Ip6ConfigNvGatewayAddress) {
823 ListHead = &Ip6NvData->GatewayAddress;
824 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount;
825 } else if (AddressType == Ip6ConfigNvDnsAddress) {
826 ListHead = &Ip6NvData->DnsAddress;
827 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount;
828 } else {
829 return EFI_UNSUPPORTED;
830 }
831
832 AddressList = AllocateZeroPool (DataSize);
833 if (AddressList == NULL) {
834 return EFI_OUT_OF_RESOURCES;
835 }
836
837 TmpStr = AddressList;
838
839 NET_LIST_FOR_EACH (Entry, ListHead) {
840 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
841 if (AddressType == Ip6ConfigNvHostAddress) {
842 ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *)AddressList;
843 IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address);
844 ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength;
845 AddressList = (UINT8 *)AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
846 } else {
847 Ip6Address = (EFI_IPv6_ADDRESS *)AddressList;
848 IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address);
849 AddressList = (UINT8 *)AddressList + sizeof (EFI_IPv6_ADDRESS);
850 }
851 }
852
853 *AddressInfo = TmpStr;
854 *AddressSize = DataSize;
855 return EFI_SUCCESS;
856 }
857
858 /**
859 Convert the IP6 configuration data into the IFR data.
860
861 @param[in, out] IfrNvData The IFR NV data.
862 @param[in] Instance The IP6 config instance data.
863
864 @retval EFI_SUCCESS The operation finished successfully.
865 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
866 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
867 @retval Others Other errors as indicated.
868
869 **/
870 EFI_STATUS
871 Ip6ConvertConfigNvDataToIfrNvData (
872 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData,
873 IN IP6_CONFIG_INSTANCE *Instance
874 )
875 {
876 IP6_CONFIG_NVDATA *Ip6NvData;
877 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
878 UINTN DataSize;
879 VOID *Data;
880 EFI_STATUS Status;
881 EFI_IP6_CONFIG_POLICY Policy;
882 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;
883 EFI_HII_HANDLE HiiHandle;
884
885 if ((IfrNvData == NULL) || (Instance == NULL)) {
886 return EFI_INVALID_PARAMETER;
887 }
888
889 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
890
891 Ip6Config = &Instance->Ip6Config;
892 Ip6NvData = &Instance->Ip6NvData;
893 Data = NULL;
894 DataSize = 0;
895 HiiHandle = Instance->CallbackInfo.RegisteredHandle;
896
897 //
898 // Get the current interface info.
899 //
900 Status = Ip6ConfigNvGetData (
901 Ip6Config,
902 Ip6ConfigDataTypeInterfaceInfo,
903 &DataSize,
904 (VOID **)&Data
905 );
906 if (EFI_ERROR (Status)) {
907 goto Exit;
908 }
909
910 //
911 // Convert the interface info to string and print.
912 //
913 Status = Ip6ConvertInterfaceInfoToString (
914 (EFI_IP6_CONFIG_INTERFACE_INFO *)Data,
915 HiiHandle,
916 IfrNvData
917 );
918 if (EFI_ERROR (Status)) {
919 goto Exit;
920 }
921
922 //
923 // Get the interface id.
924 //
925 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
926 ZeroMem (&Ip6NvData->InterfaceId, DataSize);
927 Status = Ip6Config->GetData (
928 Ip6Config,
929 Ip6ConfigDataTypeAltInterfaceId,
930 &DataSize,
931 &Ip6NvData->InterfaceId
932 );
933 if (EFI_ERROR (Status)) {
934 goto Exit;
935 }
936
937 Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);
938
939 //
940 // Get current policy.
941 //
942 DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
943 Status = Ip6Config->GetData (
944 Ip6Config,
945 Ip6ConfigDataTypePolicy,
946 &DataSize,
947 &Policy
948 );
949
950 if (EFI_ERROR (Status)) {
951 goto Exit;
952 }
953
954 if (Policy == Ip6ConfigPolicyManual) {
955 IfrNvData->Policy = IP6_POLICY_MANUAL;
956 } else if (Policy == Ip6ConfigPolicyAutomatic) {
957 IfrNvData->Policy = IP6_POLICY_AUTO;
958 } else {
959 ASSERT (FALSE);
960 Status = EFI_UNSUPPORTED;
961 goto Exit;
962 }
963
964 //
965 // Get Duplicate Address Detection Transmits count.
966 //
967 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
968 Status = Ip6Config->GetData (
969 Ip6Config,
970 Ip6ConfigDataTypeDupAddrDetectTransmits,
971 &DataSize,
972 &DadXmits
973 );
974
975 if (EFI_ERROR (Status)) {
976 goto Exit;
977 }
978
979 IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;
980
981 Exit:
982 if (Data != NULL) {
983 FreePool (Data);
984 }
985
986 return Status;
987 }
988
989 /**
990 Convert IFR data into IP6 configuration data. The policy, alternative interface
991 ID, and DAD transmit counts, and will be saved.
992
993 @param[in] IfrNvData The IFR NV data.
994 @param[in, out] Instance The IP6 config instance data.
995
996 @retval EFI_SUCCESS The operation finished successfully.
997 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
998 @retval Others Other errors as indicated.
999
1000 **/
1001 EFI_STATUS
1002 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1003 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,
1004 IN OUT IP6_CONFIG_INSTANCE *Instance
1005 )
1006 {
1007 IP6_CONFIG_NVDATA *Ip6NvData;
1008 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1009 EFI_STATUS Status;
1010
1011 if ((IfrNvData == NULL) || (Instance == NULL)) {
1012 return EFI_INVALID_PARAMETER;
1013 }
1014
1015 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
1016 Ip6NvData = &Instance->Ip6NvData;
1017 Ip6Config = &Instance->Ip6Config;
1018
1019 //
1020 // Update those fields which don't have INTERACTIVE attribute.
1021 //
1022 if (IfrNvData->Policy == IP6_POLICY_AUTO) {
1023 Ip6NvData->Policy = Ip6ConfigPolicyAutomatic;
1024 } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) {
1025 Ip6NvData->Policy = Ip6ConfigPolicyManual;
1026 }
1027
1028 Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount;
1029
1030 //
1031 // Set the configured policy.
1032 //
1033 Status = Ip6Config->SetData (
1034 Ip6Config,
1035 Ip6ConfigDataTypePolicy,
1036 sizeof (EFI_IP6_CONFIG_POLICY),
1037 &Ip6NvData->Policy
1038 );
1039 if (EFI_ERROR (Status)) {
1040 return Status;
1041 }
1042
1043 //
1044 // Set the duplicate address detection transmits count.
1045 //
1046 Status = Ip6Config->SetData (
1047 Ip6Config,
1048 Ip6ConfigDataTypeDupAddrDetectTransmits,
1049 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
1050 &Ip6NvData->DadTransmitCount
1051 );
1052 if (EFI_ERROR (Status)) {
1053 return Status;
1054 }
1055
1056 //
1057 // Set the alternative interface ID
1058 //
1059 Status = Ip6Config->SetData (
1060 Ip6Config,
1061 Ip6ConfigDataTypeAltInterfaceId,
1062 sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
1063 &Ip6NvData->InterfaceId
1064 );
1065 if (EFI_ERROR (Status)) {
1066 return Status;
1067 }
1068
1069 return EFI_SUCCESS;
1070 }
1071
1072 /**
1073 Convert IFR data into IP6 configuration data. The policy, configured
1074 manual address, gateway address, and DNS server address will be saved.
1075
1076 @param[in] IfrNvData The IFR NV data.
1077 @param[in, out] Instance The IP6 config instance data.
1078
1079 @retval EFI_SUCCESS The operation finished successfully.
1080 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1081 @retval Others Other errors as indicated.
1082
1083 **/
1084 EFI_STATUS
1085 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1086 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,
1087 IN OUT IP6_CONFIG_INSTANCE *Instance
1088 )
1089 {
1090 IP6_CONFIG_NVDATA *Ip6NvData;
1091 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1092 EFI_STATUS Status;
1093 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;
1094 EFI_IPv6_ADDRESS *Address;
1095 BOOLEAN IsAddressOk;
1096 EFI_EVENT SetAddressEvent;
1097 EFI_EVENT TimeoutEvent;
1098 UINTN DataSize;
1099
1100 if ((IfrNvData == NULL) || (Instance == NULL)) {
1101 return EFI_INVALID_PARAMETER;
1102 }
1103
1104 if (IfrNvData->Policy == IP6_POLICY_AUTO) {
1105 return EFI_SUCCESS;
1106 }
1107
1108 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
1109 Ip6NvData = &Instance->Ip6NvData;
1110 Ip6Config = &Instance->Ip6Config;
1111
1112 //
1113 // Update those fields which don't have INTERACTIVE attribute.
1114 //
1115 Ip6NvData->Policy = Ip6ConfigPolicyManual;
1116
1117 //
1118 // Set the configured policy.
1119 //
1120 Status = Ip6Config->SetData (
1121 Ip6Config,
1122 Ip6ConfigDataTypePolicy,
1123 sizeof (EFI_IP6_CONFIG_POLICY),
1124 &Ip6NvData->Policy
1125 );
1126 if (EFI_ERROR (Status)) {
1127 return Status;
1128 }
1129
1130 //
1131 // Create events & timers for asynchronous settings.
1132 //
1133 SetAddressEvent = NULL;
1134 TimeoutEvent = NULL;
1135 ManualAddress = NULL;
1136 Address = NULL;
1137
1138 Status = gBS->CreateEvent (
1139 EVT_NOTIFY_SIGNAL,
1140 TPL_NOTIFY,
1141 Ip6ConfigManualAddressNotify,
1142 &IsAddressOk,
1143 &SetAddressEvent
1144 );
1145 if (EFI_ERROR (Status)) {
1146 goto Exit;
1147 }
1148
1149 Status = gBS->CreateEvent (
1150 EVT_TIMER,
1151 TPL_CALLBACK,
1152 NULL,
1153 NULL,
1154 &TimeoutEvent
1155 );
1156 if (EFI_ERROR (Status)) {
1157 goto Exit;
1158 }
1159
1160 //
1161 // Set the manual address list. This is an asynchronous process.
1162 //
1163 if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) {
1164 Status = Ip6BuildNvAddressInfo (
1165 Instance,
1166 Ip6ConfigNvHostAddress,
1167 (VOID **)&ManualAddress,
1168 &DataSize
1169 );
1170 if (EFI_ERROR (Status)) {
1171 goto Exit;
1172 }
1173
1174 IsAddressOk = FALSE;
1175
1176 Status = Ip6Config->RegisterDataNotify (
1177 Ip6Config,
1178 Ip6ConfigDataTypeManualAddress,
1179 SetAddressEvent
1180 );
1181 if (EFI_ERROR (Status)) {
1182 goto Exit;
1183 }
1184
1185 Status = Ip6Config->SetData (
1186 Ip6Config,
1187 Ip6ConfigDataTypeManualAddress,
1188 DataSize,
1189 (VOID *)ManualAddress
1190 );
1191 if (Status == EFI_NOT_READY) {
1192 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
1193 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
1194 if (IsAddressOk) {
1195 Status = EFI_SUCCESS;
1196 }
1197
1198 break;
1199 }
1200 }
1201
1202 Status = Ip6Config->UnregisterDataNotify (
1203 Ip6Config,
1204 Ip6ConfigDataTypeManualAddress,
1205 SetAddressEvent
1206 );
1207 if (EFI_ERROR (Status)) {
1208 goto Exit;
1209 }
1210 }
1211
1212 //
1213 // Set gateway address list.
1214 //
1215 if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) {
1216 Status = Ip6BuildNvAddressInfo (
1217 Instance,
1218 Ip6ConfigNvGatewayAddress,
1219 (VOID **)&Address,
1220 &DataSize
1221 );
1222 if (EFI_ERROR (Status)) {
1223 goto Exit;
1224 }
1225
1226 Status = Ip6Config->SetData (
1227 Ip6Config,
1228 Ip6ConfigDataTypeGateway,
1229 DataSize,
1230 (VOID *)Address
1231 );
1232 if (EFI_ERROR (Status)) {
1233 goto Exit;
1234 }
1235
1236 FreePool (Address);
1237 Address = NULL;
1238 }
1239
1240 //
1241 // Set DNS server address list.
1242 //
1243 if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) {
1244 Status = Ip6BuildNvAddressInfo (
1245 Instance,
1246 Ip6ConfigNvDnsAddress,
1247 (VOID **)&Address,
1248 &DataSize
1249 );
1250 if (EFI_ERROR (Status)) {
1251 goto Exit;
1252 }
1253
1254 Status = Ip6Config->SetData (
1255 Ip6Config,
1256 Ip6ConfigDataTypeDnsServer,
1257 DataSize,
1258 (VOID *)Address
1259 );
1260 if (EFI_ERROR (Status)) {
1261 goto Exit;
1262 }
1263 }
1264
1265 Status = EFI_SUCCESS;
1266
1267 Exit:
1268 if (SetAddressEvent != NULL) {
1269 gBS->CloseEvent (SetAddressEvent);
1270 }
1271
1272 if (TimeoutEvent != NULL) {
1273 gBS->CloseEvent (TimeoutEvent);
1274 }
1275
1276 if (ManualAddress != NULL) {
1277 FreePool (ManualAddress);
1278 }
1279
1280 if (Address != NULL) {
1281 FreePool (Address);
1282 }
1283
1284 return Status;
1285 }
1286
1287 /**
1288 This function allows the caller to request the current
1289 configuration for one or more named elements. The resulting
1290 string is in <ConfigAltResp> format. Any and all alternative
1291 configuration strings shall also be appended to the end of the
1292 current configuration string. If they are, they must appear
1293 after the current configuration. They must contain the same
1294 routing (GUID, NAME, PATH) as the current configuration string.
1295 They must have an additional description indicating the type of
1296 alternative configuration the string represents,
1297 "ALTCFG=<StringToken>". That <StringToken> (when
1298 converted from Hex UNICODE to binary) is a reference to a
1299 string in the associated string pack.
1300
1301 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1302 @param[in] Request A null-terminated Unicode string in
1303 <ConfigRequest> format. Note that this
1304 includes the routing information as well as
1305 the configurable name / value pairs. It is
1306 invalid for this string to be in
1307 <MultiConfigRequest> format.
1308 @param[out] Progress On return, points to a character in the
1309 Request string. Points to the string's null
1310 terminator if request was successful. Points
1311 to the most recent "&" before the first
1312 failing name / value pair (or the beginning
1313 of the string if the failure is in the first
1314 name / value pair) if the request was not
1315 successful.
1316 @param[out] Results A null-terminated Unicode string in
1317 <ConfigAltResp> format which has all values
1318 filled in for the names in the Request string.
1319 String to be allocated by the called function.
1320
1321 @retval EFI_SUCCESS The Results string is filled with the
1322 values corresponding to all requested
1323 names.
1324 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1325 parts of the results that must be
1326 stored awaiting possible future
1327 protocols.
1328 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1329 for the Request parameter
1330 would result in this type of
1331 error. In this case, the
1332 Progress parameter would be
1333 set to NULL.
1334 @retval EFI_NOT_FOUND Routing data doesn't match any
1335 known driver. Progress set to the
1336 first character in the routing header.
1337 Note: There is no requirement that the
1338 driver validate the routing data. It
1339 must skip the <ConfigHdr> in order to
1340 process the names.
1341 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1342 to most recent & before the
1343 error or the beginning of the
1344 string.
1345 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1346 to the & before the name in
1347 question. Currently not implemented.
1348 **/
1349 EFI_STATUS
1350 EFIAPI
1351 Ip6FormExtractConfig (
1352 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1353 IN CONST EFI_STRING Request,
1354 OUT EFI_STRING *Progress,
1355 OUT EFI_STRING *Results
1356 )
1357 {
1358 EFI_STATUS Status;
1359 IP6_FORM_CALLBACK_INFO *Private;
1360 IP6_CONFIG_INSTANCE *Ip6ConfigInstance;
1361 IP6_CONFIG_IFR_NVDATA *IfrNvData;
1362 EFI_STRING ConfigRequestHdr;
1363 EFI_STRING ConfigRequest;
1364 BOOLEAN AllocatedRequest;
1365 UINTN Size;
1366 UINTN BufferSize;
1367
1368 if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {
1369 return EFI_INVALID_PARAMETER;
1370 }
1371
1372 *Progress = Request;
1373 if ((Request != NULL) &&
1374 !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName))
1375 {
1376 return EFI_NOT_FOUND;
1377 }
1378
1379 ConfigRequestHdr = NULL;
1380 ConfigRequest = NULL;
1381 AllocatedRequest = FALSE;
1382 Size = 0;
1383
1384 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
1385 Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
1386 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1387
1388 IfrNvData = (IP6_CONFIG_IFR_NVDATA *)AllocateZeroPool (BufferSize);
1389 if (IfrNvData == NULL) {
1390 return EFI_OUT_OF_RESOURCES;
1391 }
1392
1393 Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance);
1394 if (EFI_ERROR (Status)) {
1395 goto Exit;
1396 }
1397
1398 ConfigRequest = Request;
1399 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
1400 //
1401 // Request has no request element, construct full request string.
1402 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1403 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1404 //
1405 ConfigRequestHdr = HiiConstructConfigHdr (
1406 &gIp6ConfigNvDataGuid,
1407 mIp6ConfigStorageName,
1408 Private->ChildHandle
1409 );
1410 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
1411 ConfigRequest = AllocateZeroPool (Size);
1412 ASSERT (ConfigRequest != NULL);
1413 AllocatedRequest = TRUE;
1414 UnicodeSPrint (
1415 ConfigRequest,
1416 Size,
1417 L"%s&OFFSET=0&WIDTH=%016LX",
1418 ConfigRequestHdr,
1419 (UINT64)BufferSize
1420 );
1421 FreePool (ConfigRequestHdr);
1422 }
1423
1424 //
1425 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1426 //
1427 Status = gHiiConfigRouting->BlockToConfig (
1428 gHiiConfigRouting,
1429 ConfigRequest,
1430 (UINT8 *)IfrNvData,
1431 BufferSize,
1432 Results,
1433 Progress
1434 );
1435
1436 Exit:
1437 FreePool (IfrNvData);
1438 //
1439 // Free the allocated config request string.
1440 //
1441 if (AllocatedRequest) {
1442 FreePool (ConfigRequest);
1443 ConfigRequest = NULL;
1444 }
1445
1446 //
1447 // Set Progress string to the original request string.
1448 //
1449 if (Request == NULL) {
1450 *Progress = NULL;
1451 } else if (StrStr (Request, L"OFFSET") == NULL) {
1452 *Progress = Request + StrLen (Request);
1453 }
1454
1455 return Status;
1456 }
1457
1458 /**
1459 This function applies changes in a driver's configuration.
1460 Input is a Configuration, which has the routing data for this
1461 driver followed by name / value configuration pairs. The driver
1462 must apply those pairs to its configurable storage. If the
1463 driver's configuration is stored in a linear block of data
1464 and the driver's name / value pairs are in <BlockConfig>
1465 format, it may use the ConfigToBlock helper function (above) to
1466 simplify the job. Currently not implemented.
1467
1468 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1469 @param[in] Configuration A null-terminated Unicode string in
1470 <ConfigString> format.
1471 @param[out] Progress A pointer to a string filled in with the
1472 offset of the most recent '&' before the
1473 first failing name / value pair (or the
1474 beginning of the string if the failure
1475 is in the first name / value pair) or
1476 the terminating NULL if all was
1477 successful.
1478
1479 @retval EFI_SUCCESS The results have been distributed or are
1480 awaiting distribution.
1481 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1482 parts of the results that must be
1483 stored awaiting possible future
1484 protocols.
1485 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1486 Results parameter would result
1487 in this type of error.
1488 @retval EFI_NOT_FOUND Target for the specified routing data
1489 was not found.
1490 **/
1491 EFI_STATUS
1492 EFIAPI
1493 Ip6FormRouteConfig (
1494 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1495 IN CONST EFI_STRING Configuration,
1496 OUT EFI_STRING *Progress
1497 )
1498 {
1499 if ((This == NULL) || (Configuration == NULL) || (Progress == NULL)) {
1500 return EFI_INVALID_PARAMETER;
1501 }
1502
1503 //
1504 // Check routing data in <ConfigHdr>.
1505 // Note: if only one Storage is used, then this checking could be skipped.
1506 //
1507 if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {
1508 *Progress = Configuration;
1509 return EFI_NOT_FOUND;
1510 }
1511
1512 *Progress = Configuration + StrLen (Configuration);
1513
1514 return EFI_SUCCESS;
1515 }
1516
1517 /**
1518 Display host addresses, route table, DNS addresses and gateway addresses in
1519 "IPv6 Current Setting" page.
1520
1521 @param[in] Instance The IP6 config instance data.
1522
1523 @retval EFI_SUCCESS The operation finished successfully.
1524 @retval Others Other errors as indicated.
1525
1526 **/
1527 EFI_STATUS
1528 Ip6GetCurrentSetting (
1529 IN IP6_CONFIG_INSTANCE *Instance
1530 )
1531 {
1532 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1533 EFI_HII_HANDLE HiiHandle;
1534 EFI_IP6_CONFIG_INTERFACE_INFO *Data;
1535 UINTN DataSize;
1536 EFI_STATUS Status;
1537 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];
1538 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
1539
1540 Ip6Config = &Instance->Ip6Config;
1541 HiiHandle = Instance->CallbackInfo.RegisteredHandle;
1542 Data = NULL;
1543
1544 //
1545 // Get current interface info.
1546 //
1547 Status = Ip6ConfigNvGetData (
1548 Ip6Config,
1549 Ip6ConfigDataTypeInterfaceInfo,
1550 &DataSize,
1551 (VOID **)&Data
1552 );
1553 if (EFI_ERROR (Status)) {
1554 return Status;
1555 }
1556
1557 //
1558 // Generate dynamic text opcode for host address and draw it.
1559 //
1560 IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *)Data;
1561 Status = Ip6ConvertAddressListToString (
1562 PortString,
1563 HiiHandle,
1564 Ip6ConfigNvHostAddress,
1565 IfInfo->AddressInfo,
1566 IfInfo->AddressInfoCount
1567 );
1568 if (EFI_ERROR (Status)) {
1569 FreePool (Data);
1570 return Status;
1571 }
1572
1573 //
1574 // Generate the dynamic text opcode for route table and draw it.
1575 //
1576 Status = Ip6ConvertAddressListToString (
1577 PortString,
1578 HiiHandle,
1579 Ip6ConfigNvRouteTable,
1580 IfInfo->RouteTable,
1581 IfInfo->RouteCount
1582 );
1583 if (EFI_ERROR (Status)) {
1584 FreePool (Data);
1585 return Status;
1586 }
1587
1588 //
1589 // Get DNS server list.
1590 //
1591 FreePool (Data);
1592 DataSize = 0;
1593 Data = NULL;
1594 Status = Ip6ConfigNvGetData (
1595 Ip6Config,
1596 Ip6ConfigDataTypeDnsServer,
1597 &DataSize,
1598 (VOID **)&Data
1599 );
1600 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
1601 if (Data != NULL) {
1602 FreePool (Data);
1603 }
1604
1605 return Status;
1606 }
1607
1608 if (DataSize > 0) {
1609 //
1610 // Generate the dynamic text opcode for DNS server and draw it.
1611 //
1612 Status = Ip6ConvertAddressListToString (
1613 PortString,
1614 HiiHandle,
1615 Ip6ConfigNvDnsAddress,
1616 Data,
1617 DataSize / sizeof (EFI_IPv6_ADDRESS)
1618 );
1619 if (EFI_ERROR (Status)) {
1620 FreePool (Data);
1621 return Status;
1622 }
1623 }
1624
1625 //
1626 // Get gateway address list.
1627 //
1628 if (Data != NULL) {
1629 FreePool (Data);
1630 }
1631
1632 DataSize = 0;
1633 Data = NULL;
1634 Status = Ip6ConfigNvGetData (
1635 Ip6Config,
1636 Ip6ConfigDataTypeGateway,
1637 &DataSize,
1638 (VOID **)&Data
1639 );
1640 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
1641 if (Data != NULL) {
1642 FreePool (Data);
1643 }
1644
1645 return Status;
1646 }
1647
1648 if (DataSize > 0) {
1649 //
1650 // Generate the dynamic text opcode for gateway and draw it.
1651 //
1652 Status = Ip6ConvertAddressListToString (
1653 PortString,
1654 HiiHandle,
1655 Ip6ConfigNvGatewayAddress,
1656 Data,
1657 DataSize / sizeof (EFI_IPv6_ADDRESS)
1658 );
1659 if (EFI_ERROR (Status)) {
1660 FreePool (Data);
1661 return Status;
1662 }
1663 }
1664
1665 if (Data != NULL) {
1666 FreePool (Data);
1667 }
1668
1669 return EFI_SUCCESS;
1670 }
1671
1672 /**
1673 This function is called to provide results data to the driver.
1674 This data consists of a unique key that is used to identify
1675 which data is either being passed back or being asked for.
1676
1677 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1678 @param[in] Action Specifies the type of action taken by the browser.
1679 @param[in] QuestionId A unique value which is sent to the original
1680 exporting driver so that it can identify the type
1681 of data to expect. The format of the data tends to
1682 vary based on the opcode that generated the callback.
1683 @param[in] Type The type of value for the question.
1684 @param[in] Value A pointer to the data being sent to the original
1685 exporting driver.
1686 @param[out] ActionRequest On return, points to the action requested by the
1687 callback function.
1688
1689 @retval EFI_SUCCESS The callback successfully handled the action.
1690 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1691 variable and its data.
1692 @retval EFI_DEVICE_ERROR The variable could not be saved.
1693 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1694 callback. Currently not implemented.
1695 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1696 @retval Others Other errors as indicated.
1697
1698 **/
1699 EFI_STATUS
1700 EFIAPI
1701 Ip6FormCallback (
1702 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1703 IN EFI_BROWSER_ACTION Action,
1704 IN EFI_QUESTION_ID QuestionId,
1705 IN UINT8 Type,
1706 IN EFI_IFR_TYPE_VALUE *Value,
1707 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1708 )
1709 {
1710 IP6_FORM_CALLBACK_INFO *Private;
1711 UINTN BufferSize;
1712 IP6_CONFIG_IFR_NVDATA *IfrNvData;
1713 EFI_STATUS Status;
1714 EFI_INPUT_KEY Key;
1715 IP6_CONFIG_INSTANCE *Instance;
1716 IP6_CONFIG_NVDATA *Ip6NvData;
1717
1718 if (This == NULL) {
1719 return EFI_INVALID_PARAMETER;
1720 }
1721
1722 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
1723 Instance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
1724 Ip6NvData = &Instance->Ip6NvData;
1725
1726 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
1727 return EFI_SUCCESS;
1728 }
1729
1730 if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
1731 return EFI_UNSUPPORTED;
1732 }
1733
1734 if ((Value == NULL) || (ActionRequest == NULL)) {
1735 return EFI_INVALID_PARAMETER;
1736 }
1737
1738 //
1739 // Retrieve uncommitted data from Browser
1740 //
1741
1742 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1743 IfrNvData = AllocateZeroPool (BufferSize);
1744 if (IfrNvData == NULL) {
1745 return EFI_OUT_OF_RESOURCES;
1746 }
1747
1748 Status = EFI_SUCCESS;
1749
1750 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData);
1751
1752 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1753 switch (QuestionId) {
1754 case KEY_GET_CURRENT_SETTING:
1755 Status = Ip6GetCurrentSetting (Instance);
1756 break;
1757
1758 default:
1759 break;
1760 }
1761 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1762 switch (QuestionId) {
1763 case KEY_SAVE_CONFIG_CHANGES:
1764 Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);
1765 if (EFI_ERROR (Status)) {
1766 break;
1767 }
1768
1769 Status = Ip6GetCurrentSetting (Instance);
1770
1771 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1772 break;
1773
1774 case KEY_IGNORE_CONFIG_CHANGES:
1775 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
1776 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
1777 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);
1778
1779 Ip6NvData->ManualAddressCount = 0;
1780 Ip6NvData->GatewayAddressCount = 0;
1781 Ip6NvData->DnsAddressCount = 0;
1782
1783 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1784 break;
1785
1786 case KEY_SAVE_CHANGES:
1787 Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);
1788 if (EFI_ERROR (Status)) {
1789 break;
1790 }
1791
1792 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
1793 break;
1794
1795 case KEY_INTERFACE_ID:
1796 Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);
1797 if (EFI_ERROR (Status)) {
1798 CreatePopUp (
1799 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1800 &Key,
1801 L"Invalid Interface ID!",
1802 NULL
1803 );
1804 }
1805
1806 break;
1807
1808 case KEY_MANUAL_ADDRESS:
1809 Status = Ip6ParseAddressListFromString (
1810 IfrNvData->ManualAddress,
1811 &Ip6NvData->ManualAddress,
1812 &Ip6NvData->ManualAddressCount
1813 );
1814 if (EFI_ERROR (Status)) {
1815 CreatePopUp (
1816 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1817 &Key,
1818 L"Invalid Host Addresses!",
1819 NULL
1820 );
1821 }
1822
1823 break;
1824
1825 case KEY_GATEWAY_ADDRESS:
1826 Status = Ip6ParseAddressListFromString (
1827 IfrNvData->GatewayAddress,
1828 &Ip6NvData->GatewayAddress,
1829 &Ip6NvData->GatewayAddressCount
1830 );
1831 if (EFI_ERROR (Status)) {
1832 CreatePopUp (
1833 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1834 &Key,
1835 L"Invalid Gateway Addresses!",
1836 NULL
1837 );
1838 }
1839
1840 break;
1841
1842 case KEY_DNS_ADDRESS:
1843 Status = Ip6ParseAddressListFromString (
1844 IfrNvData->DnsAddress,
1845 &Ip6NvData->DnsAddress,
1846 &Ip6NvData->DnsAddressCount
1847 );
1848 if (EFI_ERROR (Status)) {
1849 CreatePopUp (
1850 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1851 &Key,
1852 L"Invalid DNS Addresses!",
1853 NULL
1854 );
1855 }
1856
1857 break;
1858
1859 default:
1860 break;
1861 }
1862 }
1863
1864 if (!EFI_ERROR (Status)) {
1865 //
1866 // Pass changed uncommitted data back to Form Browser.
1867 //
1868 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1869 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData, NULL);
1870 }
1871
1872 FreePool (IfrNvData);
1873 return Status;
1874 }
1875
1876 /**
1877 Install HII Config Access protocol for network device and allocate resources.
1878
1879 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1880
1881 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1882 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1883 @retval Others Other errors as indicated.
1884
1885 **/
1886 EFI_STATUS
1887 Ip6ConfigFormInit (
1888 IN OUT IP6_CONFIG_INSTANCE *Instance
1889 )
1890 {
1891 EFI_STATUS Status;
1892 IP6_SERVICE *IpSb;
1893 IP6_FORM_CALLBACK_INFO *CallbackInfo;
1894 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
1895 VENDOR_DEVICE_PATH VendorDeviceNode;
1896 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;
1897 CHAR16 *MacString;
1898 CHAR16 MenuString[128];
1899 CHAR16 PortString[128];
1900 CHAR16 *OldMenuString;
1901 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
1902
1903 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
1904 ASSERT (IpSb != NULL);
1905
1906 Status = gBS->HandleProtocol (
1907 IpSb->Controller,
1908 &gEfiDevicePathProtocolGuid,
1909 (VOID **)&ParentDevicePath
1910 );
1911 if (EFI_ERROR (Status)) {
1912 return Status;
1913 }
1914
1915 CallbackInfo = &Instance->CallbackInfo;
1916 CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;
1917
1918 //
1919 // Construct device path node for EFI HII Config Access protocol,
1920 // which consists of controller physical device path and one hardware
1921 // vendor guid node.
1922 //
1923 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
1924 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
1925 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
1926
1927 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
1928
1929 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
1930 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
1931 ParentDevicePath,
1932 (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode
1933 );
1934 if (CallbackInfo->HiiVendorDevicePath == NULL) {
1935 Status = EFI_OUT_OF_RESOURCES;
1936 goto Error;
1937 }
1938
1939 ConfigAccess = &CallbackInfo->HiiConfigAccess;
1940 ConfigAccess->ExtractConfig = Ip6FormExtractConfig;
1941 ConfigAccess->RouteConfig = Ip6FormRouteConfig;
1942 ConfigAccess->Callback = Ip6FormCallback;
1943
1944 //
1945 // Install Device Path Protocol and Config Access protocol on new handle
1946 //
1947 Status = gBS->InstallMultipleProtocolInterfaces (
1948 &CallbackInfo->ChildHandle,
1949 &gEfiDevicePathProtocolGuid,
1950 CallbackInfo->HiiVendorDevicePath,
1951 &gEfiHiiConfigAccessProtocolGuid,
1952 ConfigAccess,
1953 NULL
1954 );
1955 if (!EFI_ERROR (Status)) {
1956 //
1957 // Open the Parent Handle for the child
1958 //
1959 Status = gBS->OpenProtocol (
1960 IpSb->Controller,
1961 &gEfiManagedNetworkServiceBindingProtocolGuid,
1962 (VOID **)&MnpSb,
1963 IpSb->Image,
1964 CallbackInfo->ChildHandle,
1965 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1966 );
1967 }
1968
1969 if (EFI_ERROR (Status)) {
1970 goto Error;
1971 }
1972
1973 //
1974 // Publish our HII data
1975 //
1976 CallbackInfo->RegisteredHandle = HiiAddPackages (
1977 &gIp6ConfigNvDataGuid,
1978 CallbackInfo->ChildHandle,
1979 Ip6DxeStrings,
1980 Ip6ConfigBin,
1981 NULL
1982 );
1983 if (CallbackInfo->RegisteredHandle == NULL) {
1984 Status = EFI_OUT_OF_RESOURCES;
1985 goto Error;
1986 }
1987
1988 //
1989 // Append MAC string in the menu help string and tile help string
1990 //
1991 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);
1992 if (!EFI_ERROR (Status)) {
1993 OldMenuString = HiiGetString (
1994 CallbackInfo->RegisteredHandle,
1995 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),
1996 NULL
1997 )
1998 ;
1999 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
2000 HiiSetString (
2001 CallbackInfo->RegisteredHandle,
2002 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),
2003 MenuString,
2004 NULL
2005 );
2006 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);
2007 HiiSetString (
2008 CallbackInfo->RegisteredHandle,
2009 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),
2010 PortString,
2011 NULL
2012 );
2013
2014 FreePool (MacString);
2015 FreePool (OldMenuString);
2016
2017 InitializeListHead (&Instance->Ip6NvData.ManualAddress);
2018 InitializeListHead (&Instance->Ip6NvData.GatewayAddress);
2019 InitializeListHead (&Instance->Ip6NvData.DnsAddress);
2020
2021 return EFI_SUCCESS;
2022 }
2023
2024 Error:
2025 Ip6ConfigFormUnload (Instance);
2026 return Status;
2027 }
2028
2029 /**
2030 Uninstall the HII Config Access protocol for network devices and free up the resources.
2031
2032 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2033
2034 **/
2035 VOID
2036 Ip6ConfigFormUnload (
2037 IN OUT IP6_CONFIG_INSTANCE *Instance
2038 )
2039 {
2040 IP6_SERVICE *IpSb;
2041 IP6_FORM_CALLBACK_INFO *CallbackInfo;
2042 IP6_CONFIG_NVDATA *Ip6NvData;
2043
2044 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
2045 ASSERT (IpSb != NULL);
2046
2047 CallbackInfo = &Instance->CallbackInfo;
2048
2049 if (CallbackInfo->ChildHandle != NULL) {
2050 //
2051 // Close the child handle
2052 //
2053 gBS->CloseProtocol (
2054 IpSb->Controller,
2055 &gEfiManagedNetworkServiceBindingProtocolGuid,
2056 IpSb->Image,
2057 CallbackInfo->ChildHandle
2058 );
2059 //
2060 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2061 //
2062 gBS->UninstallMultipleProtocolInterfaces (
2063 CallbackInfo->ChildHandle,
2064 &gEfiDevicePathProtocolGuid,
2065 CallbackInfo->HiiVendorDevicePath,
2066 &gEfiHiiConfigAccessProtocolGuid,
2067 &CallbackInfo->HiiConfigAccess,
2068 NULL
2069 );
2070 }
2071
2072 if (CallbackInfo->HiiVendorDevicePath != NULL) {
2073 FreePool (CallbackInfo->HiiVendorDevicePath);
2074 }
2075
2076 if (CallbackInfo->RegisteredHandle != NULL) {
2077 //
2078 // Remove HII package list
2079 //
2080 HiiRemovePackages (CallbackInfo->RegisteredHandle);
2081 }
2082
2083 Ip6NvData = &Instance->Ip6NvData;
2084
2085 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
2086 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
2087 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);
2088
2089 Ip6NvData->ManualAddressCount = 0;
2090 Ip6NvData->GatewayAddressCount = 0;
2091 Ip6NvData->DnsAddressCount = 0;
2092 }