TianoCore EDK2 master
Loading...
Searching...
No Matches
RedfishDiscoverDxe.c
Go to the documentation of this file.
1
16
17LIST_ENTRY mRedfishDiscoverList;
18LIST_ENTRY mRedfishInstanceList;
19EFI_SMBIOS_PROTOCOL *mSmbios = NULL;
20
21UINTN mNumNetworkInterface = 0;
22UINTN mNumRestExInstance = 0;
23LIST_ENTRY mEfiRedfishDiscoverNetworkInterface;
24LIST_ENTRY mEfiRedfishDiscoverRestExInstance;
25
26EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID;
27EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
28EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;
29
31EFIAPI
33 IN EFI_HANDLE ImageHandle,
35 );
36
38EFIAPI
40 IN EFI_HANDLE ImageHandle,
42 );
43
44static REDFISH_DISCOVER_REQUIRED_PROTOCOL mRequiredProtocol[] = {
45 {
47 L"TCP4 Service Binding Protocol",
48 &gEfiTcp4ProtocolGuid,
49 &gEfiTcp4ServiceBindingProtocolGuid,
50 &mRedfishDiscoverTcp4InstanceGuid,
52 },
53 {
55 L"TCP6 Service Binding Protocol",
56 &gEfiTcp6ProtocolGuid,
57 &gEfiTcp6ServiceBindingProtocolGuid,
58 &mRedfishDiscoverTcp6InstanceGuid,
60 },
61 {
63 L"REST EX Service Binding Protocol",
64 &gEfiRestExProtocolGuid,
65 &gEfiRestExServiceBindingProtocolGuid,
66 &mRedfishDiscoverRestExInstanceGuid,
67 NULL
68 }
69};
70
86 )
87{
88 EFI_STATUS Status;
89
90 Status = RestExLibCreateChild (
91 Instance->NetworkInterface->OpenDriverControllerHandle,
92 Instance->Owner,
93 FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess,
94 EfiRestExConfigHttp,
95 EfiRestExServiceRedfish,
96 &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle
97 );
98 return Status;
99}
100
115 IN EFI_HANDLE ImageHandle,
117 IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags
118 )
119{
121
122 if (IsListEmpty (&mRedfishDiscoverList)) {
123 return NULL;
124 }
125
126 ThisInstance =
128 while (TRUE) {
129 if ((ThisInstance->Owner == ImageHandle) &&
130 (ThisInstance->DiscoverFlags == DiscoverFlags) &&
131 (ThisInstance->NetworkInterface == TargetNetworkInterface))
132 {
133 return ThisInstance;
134 }
135
136 if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) {
137 break;
138 }
139
140 ThisInstance =
141 (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry);
142 }
143
144 return NULL;
145}
146
156EFIAPI
158 IN EFI_HANDLE ImageHandle,
160 )
161{
162 EFI_STATUS Status;
163 EFI_TCP4_PROTOCOL *Tcp4;
164 EFI_TCP4_CONFIG_DATA Tcp4CfgData;
165 EFI_TCP4_OPTION Tcp4Option;
166 EFI_IP4_MODE_DATA IpModedata;
167 UINT8 SubnetMaskIndex;
168 UINT8 BitMask;
169 UINT8 PrefixLength;
170 BOOLEAN GotPrefixLength;
171
172 if (Instance == NULL) {
173 return EFI_INVALID_PARAMETER;
174 }
175
176 Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
177
178 ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));
179 ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION));
180 // Give a local host IP address just for getting subnet information.
181 Tcp4CfgData.AccessPoint.UseDefaultAddress = TRUE;
182 Tcp4CfgData.AccessPoint.RemoteAddress.Addr[0] = 127;
183 Tcp4CfgData.AccessPoint.RemoteAddress.Addr[1] = 0;
184 Tcp4CfgData.AccessPoint.RemoteAddress.Addr[2] = 0;
185 Tcp4CfgData.AccessPoint.RemoteAddress.Addr[3] = 1;
186 Tcp4CfgData.AccessPoint.RemotePort = 80;
187 Tcp4CfgData.AccessPoint.ActiveFlag = TRUE;
188
189 Tcp4CfgData.ControlOption = &Tcp4Option;
190 Tcp4Option.ReceiveBufferSize = 65535;
191 Tcp4Option.SendBufferSize = 65535;
192 Tcp4Option.MaxSynBackLog = 5;
193 Tcp4Option.ConnectionTimeout = 60;
194 Tcp4Option.DataRetries = 12;
195 Tcp4Option.FinTimeout = 2;
196 Tcp4Option.KeepAliveProbes = 6;
197 Tcp4Option.KeepAliveTime = 7200;
198 Tcp4Option.KeepAliveInterval = 30;
199 Tcp4Option.EnableNagle = TRUE;
200 Status = Tcp4->Configure (Tcp4, &Tcp4CfgData);
201 if (EFI_ERROR (Status)) {
202 if (Status == EFI_NO_MAPPING) {
203 return EFI_SUCCESS;
204 }
205
206 DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information: %r\n", __func__, Status));
207 return Status;
208 }
209
210 Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL);
211 if (EFI_ERROR (Status)) {
212 DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information: %r\n", __func__, Status));
213 return Status;
214 }
215
216 IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask);
217 Instance->SubnetAddr.v4.Addr[0] = IpModedata.ConfigData.StationAddress.Addr[0] & Instance->SubnetMask.v4.Addr[0];
218 Instance->SubnetAddr.v4.Addr[1] = IpModedata.ConfigData.StationAddress.Addr[1] & Instance->SubnetMask.v4.Addr[1];
219 Instance->SubnetAddr.v4.Addr[2] = IpModedata.ConfigData.StationAddress.Addr[2] & Instance->SubnetMask.v4.Addr[2];
220 Instance->SubnetAddr.v4.Addr[3] = IpModedata.ConfigData.StationAddress.Addr[3] & Instance->SubnetMask.v4.Addr[3];
221 //
222 // Calculate the subnet mask prefix.
223 //
224 GotPrefixLength = FALSE;
225 PrefixLength = 0;
226 SubnetMaskIndex = 0;
227 while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) {
228 BitMask = 0x80;
229 while (BitMask != 0) {
230 if ((Instance->SubnetMask.v4.Addr[SubnetMaskIndex] & BitMask) != 0) {
231 PrefixLength++;
232 } else {
233 GotPrefixLength = TRUE;
234 break;
235 }
236
237 BitMask = BitMask >> 1;
238 }
239
240 SubnetMaskIndex++;
241 }
242
243 Instance->SubnetPrefixLength = PrefixLength;
244 return EFI_SUCCESS;
245}
246
256EFIAPI
258 IN EFI_HANDLE ImageHandle,
260 )
261{
262 EFI_STATUS Status;
263 EFI_TCP6_PROTOCOL *Tcp6;
264 EFI_IP6_MODE_DATA IpModedata;
265
266 if (Instance == NULL) {
267 return EFI_INVALID_PARAMETER;
268 }
269
270 Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
271
272 ZeroMem ((VOID *)&IpModedata, sizeof (EFI_IP6_MODE_DATA));
273 Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL);
274 if (EFI_ERROR (Status)) {
275 DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information: %r\n", __func__, Status));
276 return Status;
277 }
278
279 if (IpModedata.AddressCount == 0) {
280 DEBUG ((DEBUG_MANAGEABILITY, "%a: No IPv6 address configured.\n", __func__));
281 Instance->SubnetAddrInfoIPv6Number = 0;
282 return EFI_SUCCESS;
283 }
284
285 if (Instance->SubnetAddrInfoIPv6 != NULL) {
286 FreePool (Instance->SubnetAddrInfoIPv6);
287 Instance->SubnetAddrInfoIPv6 = NULL;
288 }
289
290 Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO));
291 if (Instance->SubnetAddrInfoIPv6 == NULL) {
292 DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for IPv6 subnet address information\n", __func__));
293 return EFI_OUT_OF_RESOURCES;
294 }
295
296 Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount;
297 if ((IpModedata.AddressCount != 0) && (IpModedata.AddressList != NULL)) {
298 CopyMem (
299 (VOID *)Instance->SubnetAddrInfoIPv6,
300 (VOID *)&IpModedata.AddressList,
301 IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)
302 );
303 FreePool (IpModedata.AddressList);
304 }
305
306 return EFI_SUCCESS;
307}
308
321 IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface
322 )
323{
325
326 if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
327 return NULL;
328 }
329
330 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
331 while (TRUE) {
332 if ((MAC_COMPARE (ThisNetworkInterface, TargetNetworkInterface)) &&
333 (VALID_TCP6 (TargetNetworkInterface, ThisNetworkInterface) ||
334 VALID_TCP4 (TargetNetworkInterface, ThisNetworkInterface)))
335 {
336 return ThisNetworkInterface;
337 }
338
339 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
340 return NULL;
341 }
342
343 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
344 }
345
346 return NULL;
347}
348
360 IN EFI_HANDLE ControllerHandle
361 )
362{
364
365 if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
366 return NULL;
367 }
368
369 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
370 while (TRUE) {
371 if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
372 return ThisNetworkInterface;
373 }
374
375 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
376 return NULL;
377 }
378
379 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
380 }
381
382 return NULL;
383}
384
398 IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
399 IN EFI_REDFISH_DISCOVER_FLAG Flags
400 )
401{
403
404 if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && (TargetNetworkInterface == NULL)) {
405 return EFI_UNSUPPORTED;
406 }
407
408 if (TargetNetworkInterface == NULL) {
409 return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified.
410 }
411
412 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
413 while (TRUE) {
414 if (MAC_COMPARE (ThisNetworkInterface, TargetNetworkInterface)) {
415 break;
416 }
417
418 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
419 return EFI_UNSUPPORTED;
420 }
421
422 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
423 }
424
425 if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
426 // Validate if UDP4/6 is supported on the given network interface.
427 // SSDP is not supported.
428
429 return EFI_SUCCESS;
430 }
431
432 if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) {
433 return EFI_UNSUPPORTED; // The required protocol on this network interface is not found.
434 }
435
436 return EFI_SUCCESS;
437}
438
444UINTN
446 VOID
447 )
448{
449 UINTN Num;
451
452 if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
453 return 0;
454 }
455
456 Num = 1;
457 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
458 while (TRUE) {
459 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
460 break;
461 }
462
463 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
464 Num++;
465 }
466
467 return Num;
468}
469
479BOOLEAN
482 )
483{
484 if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) {
485 return TRUE;
486 }
487
488 return FALSE;
489}
490
497STATIC
498BOOLEAN
500 IN UINT32 NetworkProtocolType,
501 IN UINT8 IpType
502 )
503{
504 if (NetworkProtocolType == ProtocolTypeTcp4) {
505 return IpType != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4;
506 }
507
508 if (NetworkProtocolType == ProtocolTypeTcp6) {
509 return IpType != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6;
510 }
511
512 return FALSE;
513}
514
527 )
528{
529 EFI_STATUS Status;
531 REDFISH_INTERFACE_DATA *DeviceDescriptor;
532 CHAR8 UuidStr[sizeof "00000000-0000-0000-0000-000000000000" + 1];
533 CHAR16 Ipv6Str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
534 CHAR8 RedfishServiceLocateStr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
536 UINTN MacCompareStatus;
537 BOOLEAN IsHttps;
538
539 Data = NULL;
540 DeviceDescriptor = NULL;
541
542 if (mSmbios == NULL) {
543 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);
544 if (EFI_ERROR (Status)) {
545 return Status;
546 }
547 }
548
549 Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
550 if (EFI_ERROR (Status) || (Data == NULL) || (DeviceDescriptor == NULL)) {
551 DEBUG ((DEBUG_ERROR, "%a: RedfishGetHostInterfaceProtocolData is failed.\n", __func__));
552 return Status;
553 } else {
554 // Check IP Type and skip an unnecessary network protocol if does not match
555 if (FilterProtocol (Instance->NetworkInterface->NetworkProtocolType, Data->HostIpAddressFormat)) {
556 return EFI_UNSUPPORTED;
557 }
558
559 //
560 // Check if we can reach out Redfish service using this network interface.
561 // Check with MAC address using Device Descriptor Data Device Type 04 and Type 05.
562 // Those two types of Redfish host interface device has MAC information.
563 //
564 if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
565 MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);
566 } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {
567 MacCompareStatus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);
568 } else {
569 return EFI_UNSUPPORTED;
570 }
571
572 if (MacCompareStatus != 0) {
573 DEBUG ((DEBUG_MANAGEABILITY, "%a: MAC address is not matched.\n", __func__));
574 DEBUG ((
575 DEBUG_MANAGEABILITY,
576 " NetworkInterface: %02x %02x %02x %02x %02x %02x.\n",
577 Instance->NetworkInterface->MacAddress.Addr[0],
578 Instance->NetworkInterface->MacAddress.Addr[1],
579 Instance->NetworkInterface->MacAddress.Addr[2],
580 Instance->NetworkInterface->MacAddress.Addr[3],
581 Instance->NetworkInterface->MacAddress.Addr[4],
582 Instance->NetworkInterface->MacAddress.Addr[5]
583 ));
584 DEBUG ((
585 DEBUG_MANAGEABILITY,
586 " Redfish Host interface: %02x %02x %02x %02x %02x %02x.\n",
587 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[0],
588 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[1],
589 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[2],
590 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[3],
591 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[4],
592 DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[5]
593 ));
594 return EFI_UNSUPPORTED;
595 }
596
597 Instance->HostAddrFormat = Data->HostIpAddressFormat;
598 if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
599 IP4_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v4, (VOID *)Data->HostIpAddress);
600 IP4_COPY_ADDRESS ((VOID *)&Instance->HostSubnetMask.v4, (VOID *)Data->HostIpMask);
601
602 if (EFI_IP4_EQUAL (&Instance->HostIpAddress.v4, &mZeroIp4Addr)) {
603 DEBUG ((DEBUG_ERROR, "%a: invalid host IP address: ", __func__));
604 DumpIpv4Address (DEBUG_ERROR, &Instance->HostIpAddress.v4);
605 //
606 // Invalid IP address detected. Change address format to Unknown and use system default address.
607 //
608 Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
609 }
610
611 if (!IP4_IS_VALID_NETMASK (NTOHL (EFI_IP4 (Instance->HostSubnetMask.v4)))) {
612 DEBUG ((DEBUG_ERROR, "%a: invalid subnet mask address: ", __func__));
613 DumpIpv4Address (DEBUG_ERROR, &Instance->HostSubnetMask.v4);
614 //
615 // Invalid subnet mast address detected. Change address format to Unknown and use system default address.
616 //
617 Instance->HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
618 }
619 } else if (Data->HostIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
620 IP6_COPY_ADDRESS ((VOID *)&Instance->HostIpAddress.v6, (VOID *)Data->HostIpAddress);
621 }
622
623 if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
624 IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);
625
626 if (EFI_IP4_EQUAL (&Instance->TargetIpAddress.v4, &mZeroIp4Addr)) {
627 DEBUG ((DEBUG_ERROR, "%a: invalid service IP address: ", __func__));
628 DumpIpv4Address (DEBUG_ERROR, &Instance->TargetIpAddress.v4);
629 }
630 } else {
631 IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress);
632 }
633
634 if (Instance->HostIntfValidation) {
635 DEBUG ((DEBUG_ERROR, "%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __func__));
636 Status = EFI_UNSUPPORTED;
637 } else {
638 //
639 // Add this instance to list without detail information of Redfish
640 // service.
641 //
642 IsHttps = FALSE;
643 if (Data->RedfishServiceIpPort == 443) {
644 IsHttps = TRUE;
645 DEBUG ((DEBUG_MANAGEABILITY, "Redfish service port: 443\n"));
646 } else {
647 DEBUG ((DEBUG_MANAGEABILITY, "Redfish service port: 80\n"));
648 }
649
650 StrSize = sizeof (UuidStr);
651 AsciiSPrint (UuidStr, StrSize, "%g", &Data->ServiceUuid);
652 //
653 // Generate Redfish service location string.
654 //
655 if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
656 NetLibIp6ToStr ((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str));
657 if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
659 RedfishServiceLocateStr,
660 sizeof (RedfishServiceLocateStr),
661 L"%s",
662 Ipv6Str
663 );
664 } else {
666 RedfishServiceLocateStr,
667 sizeof (RedfishServiceLocateStr),
668 L"[%s]:%d",
669 Ipv6Str,
670 Data->RedfishServiceIpPort
671 );
672 }
673 } else {
674 if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
676 RedfishServiceLocateStr,
677 sizeof (RedfishServiceLocateStr),
678 "%d.%d.%d.%d",
679 Data->RedfishServiceIpAddress[0],
680 Data->RedfishServiceIpAddress[1],
681 Data->RedfishServiceIpAddress[2],
682 Data->RedfishServiceIpAddress[3]
683 );
684 } else {
686 RedfishServiceLocateStr,
687 sizeof (RedfishServiceLocateStr),
688 "%d.%d.%d.%d:%d",
689 Data->RedfishServiceIpAddress[0],
690 Data->RedfishServiceIpAddress[1],
691 Data->RedfishServiceIpAddress[2],
692 Data->RedfishServiceIpAddress[3],
693 Data->RedfishServiceIpPort
694 );
695 }
696 }
697
699 Instance,
700 NULL,
701 RedfishServiceLocateStr,
702 UuidStr,
703 NULL,
704 NULL,
705 NULL,
706 NULL,
707 IsHttps
708 );
709 }
710 }
711
712 return Status;
713}
714
721STATIC
722VOID
725 )
726{
727 if (Information->Location != NULL) {
728 FreePool (Information->Location);
729 Information->Location = NULL;
730 }
731
732 if (Information->Uuid != NULL) {
733 FreePool (Information->Uuid);
734 Information->Uuid = NULL;
735 }
736
737 if (Information->Os != NULL) {
738 FreePool (Information->Os);
739 Information->Os = NULL;
740 }
741
742 if (Information->OsVersion != NULL) {
743 FreePool (Information->OsVersion);
744 Information->OsVersion = NULL;
745 }
746
747 if (Information->Product != NULL) {
748 FreePool (Information->Product);
749 Information->Product = NULL;
750 }
751
752 if (Information->ProductVer != NULL) {
753 FreePool (Information->ProductVer);
754 Information->ProductVer = NULL;
755 }
756}
757
772STATIC
773VOID
776 IN BOOLEAN IsIpv6,
777 IN UINTN *RedfishVersion OPTIONAL,
778 IN CONST CHAR8 *RedfishLocation OPTIONAL,
779 IN CONST CHAR8 *Uuid OPTIONAL,
780 IN CONST CHAR8 *Os OPTIONAL,
781 IN CONST CHAR8 *OsVer OPTIONAL,
782 IN CONST CHAR8 *Product OPTIONAL,
783 IN CONST CHAR8 *ProductVer OPTIONAL
784 )
785{
786 UINTN AllocationSize;
787
788 if (RedfishVersion != NULL) {
789 Information->RedfishVersion = *RedfishVersion;
790 DEBUG ((DEBUG_MANAGEABILITY, "Redfish service version: %d.\n", Information->RedfishVersion));
791 }
792
793 if (RedfishLocation != NULL) {
794 AllocationSize = AsciiStrSize (RedfishLocation) * sizeof (CHAR16);
795
796 if (IsIpv6) {
797 AllocationSize += 2 * sizeof (CHAR16); // take into account '[' and ']'
798 }
799
800 Information->Location = AllocatePool (AllocationSize);
801 if (Information->Location != NULL) {
802 if (IsIpv6) {
803 UnicodeSPrintAsciiFormat (Information->Location, AllocationSize, "[%a]", RedfishLocation);
804 } else {
805 AsciiStrToUnicodeStrS (RedfishLocation, Information->Location, AllocationSize);
806 }
807
808 DEBUG ((DEBUG_MANAGEABILITY, "Redfish service location: %s.\n", Information->Location));
809 } else {
810 DEBUG ((
811 DEBUG_ERROR,
812 "%a: Can not allocate memory for Redfish service location: %a.\n",
813 __func__,
814 RedfishLocation
815 ));
816 }
817 }
818
819 if (Uuid != NULL) {
820 AllocationSize = AsciiStrSize (Uuid) * sizeof (CHAR16);
821 Information->Uuid = AllocatePool (AllocationSize);
822 if (Information->Uuid != NULL) {
823 AsciiStrToUnicodeStrS (Uuid, Information->Uuid, AllocationSize);
824 DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: %s.\n", Information->Uuid));
825 } else {
826 DEBUG ((
827 DEBUG_ERROR,
828 "%a: Can not allocate memory for Service UUID: %a.\n",
829 __func__,
830 Uuid
831 ));
832 }
833 }
834
835 if (Os != NULL) {
836 AllocationSize = AsciiStrSize (Os) * sizeof (CHAR16);
837 Information->Os = AllocatePool (AllocationSize);
838 if (Information->Os != NULL) {
839 AsciiStrToUnicodeStrS (Os, Information->Os, AllocationSize);
840 } else {
841 DEBUG ((
842 DEBUG_ERROR,
843 "%a: Can not allocate memory for Redfish service OS: %a.\n",
844 __func__,
845 Os
846 ));
847 }
848 }
849
850 if (OsVer != NULL) {
851 AllocationSize = AsciiStrSize (OsVer) * sizeof (CHAR16);
852 Information->OsVersion = AllocatePool (AllocationSize);
853 if (Information->OsVersion != NULL) {
854 AsciiStrToUnicodeStrS (OsVer, Information->OsVersion, AllocationSize);
855 DEBUG ((
856 DEBUG_MANAGEABILITY,
857 "Redfish service OS: %s, Version:%s.\n",
858 Information->Os,
859 Information->OsVersion
860 ));
861 } else {
862 DEBUG ((
863 DEBUG_ERROR,
864 "%a: Can not allocate memory for Redfish OS Version:%a.\n",
865 __func__,
866 OsVer
867 ));
868 }
869 }
870
871 if (Product != NULL) {
872 AllocationSize = AsciiStrSize (Product) * sizeof (CHAR16);
873 Information->Product = AllocatePool (AllocationSize);
874 if (Information->Product != NULL) {
875 AsciiStrToUnicodeStrS (Product, Information->Product, AllocationSize);
876 } else {
877 DEBUG ((
878 DEBUG_ERROR,
879 "%a: Can not allocate memory for Redfish service product: %a.\n",
880 __func__,
881 Product
882 ));
883 }
884 }
885
886 if (ProductVer != NULL) {
887 AllocationSize = AsciiStrSize (ProductVer) * sizeof (CHAR16);
888 Information->ProductVer = AllocatePool (AllocationSize);
889 if (Information->ProductVer != NULL) {
890 AsciiStrToUnicodeStrS (ProductVer, Information->ProductVer, AllocationSize);
891 DEBUG ((
892 DEBUG_MANAGEABILITY,
893 "Redfish service product: %s, Version:%s.\n",
894 Information->Product,
895 Information->ProductVer
896 ));
897 } else {
898 DEBUG ((
899 DEBUG_ERROR,
900 "%a: Can not allocate memory for Redfish service product Version: %a.\n",
901 __func__,
902 ProductVer
903 ));
904 }
905 }
906}
907
927 IN UINTN *RedfishVersion OPTIONAL,
928 IN CHAR8 *RedfishLocation OPTIONAL,
929 IN CHAR8 *Uuid OPTIONAL,
930 IN CHAR8 *Os OPTIONAL,
931 IN CHAR8 *OsVer OPTIONAL,
932 IN CHAR8 *Product OPTIONAL,
933 IN CHAR8 *ProductVer OPTIONAL,
934 IN BOOLEAN UseHttps
935 )
936{
937 BOOLEAN NewFound;
938 BOOLEAN InfoRefresh;
939 BOOLEAN RestExOpened;
940 BOOLEAN DeleteRestEx;
941 EFI_STATUS Status;
943 EFI_REDFISH_DISCOVERED_INSTANCE *DiscoveredInstance;
944 CHAR16 *Char16Uuid;
945 EFI_REST_EX_PROTOCOL *RestEx;
946 EFI_REST_EX_HTTP_CONFIG_DATA *RestExHttpConfigData;
948
949 NewFound = TRUE;
950 InfoRefresh = FALSE;
951 Char16Uuid = NULL;
952 RestExOpened = FALSE;
953 DeleteRestEx = FALSE;
954
955 DEBUG ((DEBUG_MANAGEABILITY, "%a:Add this instance to Redfish instance list.\n", __func__));
956
957 if (Uuid != NULL) {
958 Char16Uuid = (CHAR16 *)AllocateZeroPool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
959 AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
960 }
961
962 DiscoveredList = NULL;
963 DiscoveredInstance = NULL;
964 RestExHttpConfigData = NULL;
965
966 NetworkInterface = Instance->NetworkInterface;
967 if (!IsListEmpty (&mRedfishInstanceList)) {
968 //
969 // Is this a duplicate redfish service.
970 //
971 DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
972 NewFound = FALSE;
973 do {
974 if ((Char16Uuid == NULL) || (DiscoveredList->Instance->Information.Uuid == NULL)) {
975 //
976 // Check if this Redfish instance already found using IP address.
977 //
978 if (!CheckIsIpVersion6 (NetworkInterface)) {
979 if (CompareMem (
980 (VOID *)&Instance->TargetIpAddress.v4,
981 (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4,
982 sizeof (EFI_IPv4_ADDRESS)
983 ) == 0)
984 {
985 DiscoveredInstance = DiscoveredList->Instance;
986 if ((DiscoveredList->Instance->Information.Uuid == NULL) &&
987 (Char16Uuid != NULL))
988 {
989 InfoRefresh = TRUE;
990 DiscoveredInstance = DiscoveredList->Instance;
991 DEBUG ((DEBUG_MANAGEABILITY, "*** This Redfish Service information refresh ***\n"));
992 }
993
994 break;
995 }
996 } else {
997 if (CompareMem (
998 (VOID *)&Instance->TargetIpAddress.v6,
999 (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6,
1000 sizeof (EFI_IPv6_ADDRESS)
1001 ) == 0)
1002 {
1003 DiscoveredInstance = DiscoveredList->Instance;
1004 break;
1005 }
1006 }
1007 } else {
1008 //
1009 // Check if this Redfish instance already found using UUID.
1010 //
1011 if (StrCmp ((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) {
1012 DiscoveredInstance = DiscoveredList->Instance;
1013 break;
1014 }
1015 }
1016
1017 if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) {
1018 NewFound = TRUE;
1019 break;
1020 }
1021
1022 DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance);
1023 } while (TRUE);
1024 }
1025
1026 if (Char16Uuid != NULL) {
1027 FreePool (Char16Uuid);
1028 }
1029
1030 if (NewFound || InfoRefresh) {
1031 if (!InfoRefresh) {
1033 if (DiscoveredList == NULL) {
1034 return EFI_OUT_OF_RESOURCES;
1035 }
1036
1037 InitializeListHead (&DiscoveredList->NextInstance);
1039 if (DiscoveredInstance == NULL) {
1040 FreePool ((VOID *)DiscoveredList);
1041 return EFI_OUT_OF_RESOURCES;
1042 }
1043 } else {
1044 FreeInformationData (&DiscoveredInstance->Information);
1045 }
1046
1047 DEBUG ((DEBUG_MANAGEABILITY, "*** Redfish Service Information ***\n"));
1048
1049 DiscoveredInstance->Information.UseHttps = UseHttps;
1050
1052 &DiscoveredInstance->Information,
1053 CheckIsIpVersion6 (NetworkInterface),
1054 RedfishVersion,
1055 RedfishLocation,
1056 Uuid,
1057 Os,
1058 OsVer,
1059 Product,
1060 ProductVer
1061 );
1062
1063 if (RedfishLocation == NULL) {
1064 // This is the Redfish reported from SMBIOS 42h
1065 // without validation.
1066
1067 IP4_COPY_ADDRESS ((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4);
1068 }
1069
1070 if (!InfoRefresh) {
1071 DiscoveredList->Instance = DiscoveredInstance;
1072 InsertTailList (&mRedfishInstanceList, &DiscoveredList->NextInstance);
1073 }
1074
1075 DiscoveredInstance->Status = EFI_SUCCESS;
1076 } else {
1077 if (DiscoveredList != NULL) {
1078 DEBUG ((DEBUG_MANAGEABILITY, "*** This Redfish Service was already found ***\n"));
1079 if (DiscoveredInstance->Information.Uuid != NULL) {
1080 DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
1081 } else {
1082 DEBUG ((DEBUG_MANAGEABILITY, "Service UUID: unknown.\n"));
1083 }
1084 }
1085 }
1086
1087 Status = EFI_SUCCESS;
1088 if (NewFound || InfoRefresh) {
1089 //
1090 // Build up EFI_REDFISH_DISCOVERED_LIST in token.
1091 //
1092 Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1;
1093 Instance->DiscoverToken->DiscoverList.RedfishInstances = DiscoveredInstance;
1094 DiscoveredInstance->Status = EFI_SUCCESS;
1095 if (!InfoRefresh) {
1096 Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child.
1097 if (EFI_ERROR (Status)) {
1098 DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n", __func__));
1099 goto ON_EXIT;
1100 }
1101
1102 Status = gBS->OpenProtocol (
1103 // Configure local host information.
1104 Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
1105 &gEfiRestExProtocolGuid,
1106 (VOID **)&RestEx,
1107 Instance->NetworkInterface->OpenDriverAgentHandle,
1108 Instance->NetworkInterface->OpenDriverControllerHandle,
1109 EFI_OPEN_PROTOCOL_BY_DRIVER
1110 );
1111 if (EFI_ERROR (Status)) {
1112 DeleteRestEx = TRUE;
1113 goto ERROR_EXIT;
1114 }
1115
1116 RestExOpened = TRUE;
1117 RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));
1118 if (RestExHttpConfigData == NULL) {
1119 Status = EFI_OUT_OF_RESOURCES;
1120 DeleteRestEx = TRUE;
1121 goto EXIT_FREE_CONFIG_DATA;
1122 }
1123
1124 RestExHttpConfigData->SendReceiveTimeout = PcdGet32 (PcdRedfishSendReceiveTimeout);
1125 RestExHttpConfigData->HttpConfigData.HttpVersion = HttpVersion11;
1126 RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6 (NetworkInterface);
1127 if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) {
1128 RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));
1129 if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) {
1130 Status = EFI_OUT_OF_RESOURCES;
1131 goto EXIT_FREE_CONFIG_DATA;
1132 }
1133
1134 if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
1135 IP6_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node->LocalAddress, &Instance->HostIpAddress.v6);
1136 }
1137 } else {
1138 RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));
1139 if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) {
1140 Status = EFI_OUT_OF_RESOURCES;
1141 goto EXIT_FREE_CONFIG_DATA;
1142 }
1143
1144 if (Instance->HostAddrFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) {
1145 RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = FALSE;
1146 IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalAddress, &Instance->HostIpAddress.v4);
1147 IP4_COPY_ADDRESS (&RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->LocalSubnet, &Instance->HostSubnetMask.v4);
1148 } else {
1149 RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE;
1150 }
1151 }
1152
1153 Status = RestEx->Configure (
1154 RestEx,
1155 (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData
1156 );
1157 if (EFI_ERROR (Status)) {
1158 DEBUG ((DEBUG_ERROR, "%a: REST EX is not configured..\n", __func__));
1159 DeleteRestEx = TRUE;
1160 goto EXIT_FREE_ALL;
1161 } else {
1162 DEBUG ((DEBUG_MANAGEABILITY, "%a: REST EX is configured..\n", __func__));
1163 }
1164
1165 //
1166 // Signal client, close REST EX before signaling client.
1167 //
1168 if (RestExOpened) {
1169 gBS->CloseProtocol (
1170 Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
1171 &gEfiRestExProtocolGuid,
1172 Instance->NetworkInterface->OpenDriverAgentHandle,
1173 Instance->NetworkInterface->OpenDriverControllerHandle
1174 );
1175 RestExOpened = FALSE;
1176 }
1177 }
1178
1179 Status = gBS->SignalEvent (Instance->DiscoverToken->Event);
1180 if (EFI_ERROR (Status)) {
1181 DEBUG ((DEBUG_ERROR, "%a:No event to signal!\n", __func__));
1182 }
1183 }
1184
1185EXIT_FREE_ALL:;
1186 if ((RestExHttpConfigData != NULL) && (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL)) {
1187 FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node);
1188 }
1189
1190EXIT_FREE_CONFIG_DATA:;
1191 if (RestExHttpConfigData != NULL) {
1192 FreePool ((VOID *)RestExHttpConfigData);
1193 }
1194
1195 if (RestExOpened) {
1196 gBS->CloseProtocol (
1197 Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
1198 &gEfiRestExProtocolGuid,
1199 Instance->NetworkInterface->OpenDriverAgentHandle,
1200 Instance->NetworkInterface->OpenDriverControllerHandle
1201 );
1202 }
1203
1204ERROR_EXIT:;
1205 if (DeleteRestEx && RestExOpened) {
1206 gBS->CloseProtocol (
1207 Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
1208 &gEfiRestExProtocolGuid,
1209 Instance->NetworkInterface->OpenDriverAgentHandle,
1210 Instance->NetworkInterface->OpenDriverControllerHandle
1211 );
1212 }
1213
1214ON_EXIT:;
1215 return Status;
1216}
1217
1231 IN EFI_HANDLE ImageHandle
1232 )
1233{
1234 EFI_STATUS Status;
1235 UINT32 ProtocolType;
1236 UINT32 IPv6InfoIndex;
1237 EFI_IP6_ADDRESS_INFO *ThisSubnetAddrInfoIPv6;
1239
1240 if (Instance->GotSubnetInfo) {
1241 return EFI_SUCCESS;
1242 }
1243
1244 ProtocolType = Instance->NetworkProtocolType;
1245 if ((mRequiredProtocol[ProtocolType].GetSubnetInfo != NULL) && (Instance->GotSubnetInfo == FALSE)) {
1246 Status = mRequiredProtocol[ProtocolType].GetSubnetInfo (
1247 ImageHandle,
1248 Instance
1249 );
1250 if (EFI_ERROR (Status)) {
1251 DEBUG ((DEBUG_ERROR, "%a:Failed to get Subnet information.\n", __func__));
1252 return Status;
1253 } else {
1254 DEBUG ((DEBUG_MANAGEABILITY, "%a:MAC address: %s\n", __func__, Instance->StrMacAddr));
1255 if (CheckIsIpVersion6 (Instance)) {
1256 if (Instance->SubnetAddrInfoIPv6Number == 0) {
1257 DEBUG ((DEBUG_WARN, "%a: There is no Subnet information for IPv6 network interface.\n", __func__));
1258 return EFI_NOT_FOUND;
1259 }
1260
1261 ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information.
1262 IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
1263 Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
1264 DEBUG ((
1265 DEBUG_MANAGEABILITY,
1266 " IPv6 Subnet ID:%d, Prefix length: %d.\n",
1267 ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
1268 ThisSubnetAddrInfoIPv6->PrefixLength
1269 )
1270 );
1271 //
1272 // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes
1273 // according to the Ipv6 address information.
1274 //
1275 ThisSubnetAddrInfoIPv6++;
1276 for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) {
1277 //
1278 // Build up additional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.
1279 //
1281 if (NewNetworkInterface != NULL) {
1282 CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance.
1283 IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
1284 NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
1285 NewNetworkInterface->GotSubnetInfo = TRUE;
1286 InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry);
1287 ThisSubnetAddrInfoIPv6++;
1288 mNumNetworkInterface++;
1289 DEBUG ((
1290 DEBUG_MANAGEABILITY,
1291 " IPv6 Subnet ID:%d, Prefix length: %d.\n",
1292 ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
1293 ThisSubnetAddrInfoIPv6->PrefixLength
1294 )
1295 );
1296 } else {
1297 return EFI_OUT_OF_RESOURCES;
1298 }
1299 }
1300 } else {
1301 DEBUG ((
1302 DEBUG_MANAGEABILITY,
1303 " IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n",
1304 Instance->SubnetAddr.v4.Addr[0],
1305 Instance->SubnetAddr.v4.Addr[1],
1306 Instance->SubnetAddr.v4.Addr[2],
1307 Instance->SubnetAddr.v4.Addr[3],
1308 Instance->SubnetMask.v4.Addr[0],
1309 Instance->SubnetMask.v4.Addr[1],
1310 Instance->SubnetMask.v4.Addr[2],
1311 Instance->SubnetMask.v4.Addr[3]
1312 ));
1313 }
1314 }
1315 }
1316
1317 Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once.
1318 return EFI_SUCCESS;
1319}
1320
1339EFIAPI
1342 IN EFI_HANDLE ImageHandle,
1343 OUT UINTN *NumberOfNetworkIntfs,
1344 OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances
1345 )
1346{
1347 EFI_STATUS Status;
1348 EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn;
1349 EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
1351
1352 DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry.\n", __func__));
1353
1354 if ((This == NULL) || (NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) ||
1355 (ImageHandle == NULL))
1356 {
1357 return EFI_INVALID_PARAMETER;
1358 }
1359
1360 *NumberOfNetworkIntfs = 0;
1361 *NetworkIntfInstances = NULL;
1362
1363 if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
1364 return EFI_NOT_FOUND;
1365 }
1366
1367 RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (This);
1368
1369 //
1370 // Check the new found network interface.
1371 //
1372 if (RestExInstance->NetworkInterfaceInstances != NULL) {
1373 FreePool (RestExInstance->NetworkInterfaceInstances);
1374 RestExInstance->NetworkInterfaceInstances = NULL;
1375 }
1376
1377 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);
1378 if (ThisNetworkInterface == NULL) {
1379 return EFI_OUT_OF_RESOURCES;
1380 }
1381
1382 *NetworkIntfInstances = ThisNetworkInterface;
1383
1384 RestExInstance->NetworkInterfaceInstances = ThisNetworkInterface;
1385 RestExInstance->NumberOfNetworkInterfaces = 0;
1386
1387 ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
1388 while (TRUE) {
1389 ThisNetworkInterface->IsIpv6 = FALSE;
1390 if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
1391 ThisNetworkInterface->IsIpv6 = TRUE;
1392 }
1393
1394 CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);
1395 //
1396 // If Get Subnet Info failed then skip this interface
1397 //
1398 Status = NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info
1399 if (!EFI_ERROR (Status)) {
1400 if (!ThisNetworkInterface->IsIpv6) {
1401 IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.
1402 } else {
1403 IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information.
1404 }
1405
1406 ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength;
1407 }
1408
1409 ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId;
1410 RestExInstance->NumberOfNetworkInterfaces++;
1411 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
1412 break;
1413 }
1414
1415 ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
1416 ThisNetworkInterface++;
1417 }
1418
1419 *NumberOfNetworkIntfs = RestExInstance->NumberOfNetworkInterfaces;
1420
1421 return EFI_SUCCESS;
1422}
1423
1449EFIAPI
1452 IN EFI_HANDLE ImageHandle,
1453 IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
1454 IN EFI_REDFISH_DISCOVER_FLAG Flags,
1456 )
1457{
1459 EFI_STATUS Status1;
1460 BOOLEAN NewInstance;
1461 UINTN NumNetworkInterfaces;
1462 UINTN NetworkInterfacesIndex;
1463 EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterfaceInternal;
1464
1465 DEBUG ((DEBUG_MANAGEABILITY, "%a:Entry.\n", __func__));
1466
1467 //
1468 // Validate parameters.
1469 //
1470 if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {
1471 DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __func__));
1472 return EFI_INVALID_PARAMETER;
1473 }
1474
1475 //
1476 // Validate target network interface.
1477 //
1478 if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) {
1479 return EFI_UNSUPPORTED;
1480 }
1481
1482 if (TargetNetworkInterface != NULL) {
1483 TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);
1484 if (TargetNetworkInterfaceInternal == NULL) {
1485 DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __func__));
1486 return EFI_UNSUPPORTED;
1487 }
1488
1489 NumNetworkInterfaces = 1;
1490 } else {
1491 TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
1492 NumNetworkInterfaces = NumberOfNetworkInterface ();
1493 if (NumNetworkInterfaces == 0) {
1494 DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __func__));
1495 return EFI_UNSUPPORTED;
1496 }
1497 }
1498
1499 for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) {
1500 Status1 = EFI_SUCCESS;
1501 NewInstance = FALSE;
1502 Instance = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance.
1503 if (Instance == NULL) {
1504 DEBUG ((DEBUG_MANAGEABILITY, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __func__));
1506 if (Instance == NULL) {
1507 DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __func__));
1508 return EFI_OUT_OF_RESOURCES;
1509 }
1510
1511 InitializeListHead (&Instance->Entry);
1512 Instance->Owner = ImageHandle;
1513 Instance->DiscoverFlags = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION;
1514 Instance->NetworkInterface = TargetNetworkInterfaceInternal;
1515 //
1516 // Get subnet information in case subnet information is not set because
1517 // RedfishServiceGetNetworkInterfaces hasn't been called yet.
1518 //
1519 Status1 = NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);
1520 if (EFI_ERROR (Status1)) {
1521 //
1522 // Get subnet information could be failed for EFI_REDFISH_DISCOVER_HOST_INTERFACE case.
1523 // We will configure network in AddAndSignalNewRedfishService. So don't skip this
1524 // target network interface.
1525 //
1526 if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) == 0) {
1527 DEBUG ((DEBUG_ERROR, "%a: Get subnet information fail.\n", __func__));
1528 FreePool (Instance);
1529 continue;
1530 }
1531 }
1532
1533 NewInstance = TRUE;
1534 }
1535
1536 if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) {
1537 DEBUG ((DEBUG_MANAGEABILITY, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __func__, TargetNetworkInterfaceInternal->StrMacAddr));
1538 } else {
1539 DEBUG ((DEBUG_MANAGEABILITY, "%a:WARNING: No MAC address on this network interface.\n", __func__));
1540 }
1541
1542 Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.
1543 if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {
1544 DEBUG ((DEBUG_MANAGEABILITY, "%a:Redfish HOST interface discovery.\n", __func__));
1545 Instance->HostIntfValidation = FALSE;
1546 if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) {
1547 Instance->HostIntfValidation = TRUE;
1548 }
1549
1550 Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface.
1551 }
1552
1553 if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
1554 DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __func__));
1555 return EFI_UNSUPPORTED;
1556 } else {
1557 if (EFI_ERROR (Status1)) {
1558 if (NewInstance) {
1559 FreePool ((VOID *)Instance);
1560 }
1561
1562 DEBUG ((DEBUG_MANAGEABILITY, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1));
1563 } else {
1564 if (NewInstance) {
1565 InsertTailList (&mRedfishDiscoverList, &Instance->Entry);
1566 }
1567 }
1568 }
1569
1570 if (TargetNetworkInterface == NULL) {
1571 //
1572 // Discover Redfish services on all of network interfaces.
1573 //
1574 TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry);
1575 }
1576 }
1577
1578 return EFI_SUCCESS;
1579}
1580
1592EFIAPI
1595 IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL
1596 )
1597{
1598 DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry.\n", __func__));
1599 // This function is used to abort Redfish service discovery through SSDP
1600 // on the network interface. SSDP is optionally suppoted by EFI_REDFISH_DISCOVER_PROTOCOL,
1601 // we dont have implementation for SSDP now.
1602
1603 return EFI_UNSUPPORTED;
1604}
1605
1617EFIAPI
1620 IN EFI_REDFISH_DISCOVERED_LIST *InstanceList
1621 )
1622{
1623 UINTN NumService;
1624 BOOLEAN AnyFailRelease;
1625 EFI_REDFISH_DISCOVERED_INSTANCE *ThisRedfishInstance;
1626 EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredRedfishInstance;
1627
1628 DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry.\n", __func__));
1629
1630 if (IsListEmpty (&mRedfishInstanceList)) {
1631 DEBUG ((DEBUG_ERROR, "%a:No any discovered Redfish service.\n", __func__));
1632 return EFI_NOT_FOUND;
1633 }
1634
1635 AnyFailRelease = FALSE;
1636 ThisRedfishInstance = InstanceList->RedfishInstances;
1637 for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService++) {
1638 DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
1639 do {
1640 if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) {
1641 RemoveEntryList (&DiscoveredRedfishInstance->NextInstance);
1642 FreeInformationData (&ThisRedfishInstance->Information);
1643 FreePool ((VOID *)ThisRedfishInstance);
1644 goto ReleaseNext;
1645 }
1646
1647 if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) {
1648 break;
1649 }
1650
1651 DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance);
1652 } while (TRUE);
1653
1654 AnyFailRelease = TRUE;
1655ReleaseNext:;
1656 //
1657 // Release next discovered Redfish Service.
1658 //
1659 ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
1660 }
1661
1662 if (AnyFailRelease) {
1663 return EFI_NOT_FOUND;
1664 } else {
1665 return EFI_SUCCESS;
1666 }
1667}
1668
1683 IN EFI_HANDLE ControllerHandle,
1684 IN UINT32 NetworkProtocolType,
1685 OUT BOOLEAN *IsNewInstance,
1687 )
1688{
1689 EFI_MAC_ADDRESS MacAddress;
1690 UINTN HwAddressSize;
1693
1694 NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize);
1695 NewNetworkInterface = NULL;
1696 *IsNewInstance = TRUE;
1697 if (!IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
1698 //
1699 // Check if this instance already exist.
1700 //
1701 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
1702 if (ThisNetworkInterface != NULL) {
1703 while (TRUE) {
1704 if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) &&
1705 (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType))
1706 {
1707 NewNetworkInterface = ThisNetworkInterface;
1708 *IsNewInstance = FALSE;
1709 break;
1710 }
1711
1712 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
1713 NewNetworkInterface = NULL;
1714 break;
1715 }
1716
1717 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
1718 }
1719 }
1720 }
1721
1722 if (NewNetworkInterface == NULL) {
1723 //
1724 // Create a new instance.
1725 //
1727 if (NewNetworkInterface == NULL) {
1728 return EFI_OUT_OF_RESOURCES;
1729 }
1730
1731 NewNetworkInterface->HwAddressSize = HwAddressSize;
1732 CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize);
1733 NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr);
1734 NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle);
1735 }
1736
1737 *NetworkInterface = NewNetworkInterface;
1738 return EFI_SUCCESS;
1739}
1740
1752 )
1753{
1754 EFI_STATUS Status;
1755
1756 Status = gBS->UninstallProtocolInterface (
1757 ThisNetworkInterface->OpenDriverControllerHandle,
1758 mRequiredProtocol[ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid,
1759 &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId
1760 );
1761 RemoveEntryList (&ThisNetworkInterface->Entry);
1762 mNumNetworkInterface--;
1763 FreePool (ThisNetworkInterface);
1764 return Status;
1765}
1766
1781 IN EFI_HANDLE ControllerHandle
1782 )
1783{
1784 UINT32 *Id;
1785 UINTN Index;
1786 EFI_STATUS Status;
1787 UINTN ListCount;
1788
1789 ListCount = (sizeof (mRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
1790 for (Index = 0; Index < ListCount; Index++) {
1791 Status = gBS->OpenProtocol (
1792 ControllerHandle,
1793 mRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
1794 NULL,
1795 This->DriverBindingHandle,
1796 ControllerHandle,
1797 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
1798 );
1799 if (EFI_ERROR (Status)) {
1800 return EFI_UNSUPPORTED;
1801 }
1802
1803 Status = gBS->OpenProtocol (
1804 ControllerHandle,
1805 mRequiredProtocol[Index].DiscoveredProtocolGuid,
1806 (VOID **)&Id,
1807 This->DriverBindingHandle,
1808 ControllerHandle,
1809 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1810 );
1811 if (!EFI_ERROR (Status)) {
1812 // Already installed
1813 return EFI_UNSUPPORTED;
1814 }
1815 }
1816
1817 DEBUG ((DEBUG_MANAGEABILITY, "%a: all required protocols are found on this controller handle: %p.\n", __func__, ControllerHandle));
1818 return EFI_SUCCESS;
1819}
1820
1836 IN EFI_HANDLE ControllerHandle
1837 )
1838{
1839 UINT32 *Id;
1840 UINT32 Index;
1842 BOOLEAN IsNew;
1843 EFI_STATUS Status;
1844 VOID *TempInterface;
1845 VOID **Interface;
1846 UINT32 *ProtocolDiscoverIdPtr;
1847 EFI_HANDLE OpenDriverAgentHandle;
1848 EFI_HANDLE OpenDriverControllerHandle;
1849 EFI_HANDLE *HandleOfProtocolInterfacePtr;
1851 EFI_TPL OldTpl;
1852 BOOLEAN NewNetworkInterfaceInstalled;
1853 UINTN ListCount;
1854
1855 ListCount = (sizeof (mRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
1856 NewNetworkInterfaceInstalled = FALSE;
1857 Index = 0;
1858 RestExInstance = NULL;
1859
1860 for (Index = 0; Index < ListCount; Index++) {
1861 Status = gBS->OpenProtocol (
1862 // Already in list?
1863 ControllerHandle,
1864 mRequiredProtocol[Index].DiscoveredProtocolGuid,
1865 (VOID **)&Id,
1866 This->DriverBindingHandle,
1867 ControllerHandle,
1868 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1869 );
1870 if (!EFI_ERROR (Status)) {
1871 continue;
1872 }
1873
1874 Status = gBS->OpenProtocol (
1875 ControllerHandle,
1876 mRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
1877 &TempInterface,
1878 This->DriverBindingHandle,
1879 ControllerHandle,
1880 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1881 );
1882 if (EFI_ERROR (Status)) {
1883 continue;
1884 }
1885
1886 if (mRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
1887 OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
1888 Status = CreateRedfishDiscoverNetworkInterface (ControllerHandle, mRequiredProtocol[Index].ProtocolType, &IsNew, &NetworkInterface);
1889 if (EFI_ERROR (Status)) {
1890 gBS->RestoreTPL (OldTpl);
1891 return Status;
1892 }
1893
1894 NetworkInterface->NetworkProtocolType = mRequiredProtocol[Index].ProtocolType;
1895 NetworkInterface->OpenDriverAgentHandle = This->DriverBindingHandle;
1896 NetworkInterface->OpenDriverControllerHandle = ControllerHandle;
1897 CopyGuid (&NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid, mRequiredProtocol[Index].RequiredProtocolGuid);
1899 ProtocolDiscoverIdPtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId;
1900 OpenDriverAgentHandle = NetworkInterface->OpenDriverAgentHandle;
1901 OpenDriverControllerHandle = NetworkInterface->OpenDriverControllerHandle;
1902 HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle;
1903 Interface = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
1904 NewNetworkInterfaceInstalled = TRUE;
1905 if (IsNew) {
1906 InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry);
1907 mNumNetworkInterface++;
1908 }
1909
1910 gBS->RestoreTPL (OldTpl);
1911 } else {
1912 // Record REST_EX instance. REST_EX is created when client asks for Redfish service discovery.
1913 // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
1914 // when discovery.
1915
1917 if (RestExInstance == NULL) {
1918 return EFI_OUT_OF_RESOURCES;
1919 }
1920
1921 RestExInstance->OpenDriverAgentHandle = This->DriverBindingHandle;
1922 RestExInstance->OpenDriverControllerHandle = ControllerHandle;
1923 RestExInstance->RestExControllerHandle = ControllerHandle;
1924 InitializeListHead (&RestExInstance->Entry);
1925 InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
1926 mNumRestExInstance++;
1927 ProtocolDiscoverIdPtr = &RestExInstance->RestExId;
1928 OpenDriverAgentHandle = RestExInstance->OpenDriverAgentHandle;
1929 OpenDriverControllerHandle = RestExInstance->OpenDriverControllerHandle;
1930 HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle;
1931 Interface = (VOID **)&RestExInstance->RestExProtocolInterface;
1932 }
1933
1934 Status = gBS->InstallProtocolInterface (
1935 &ControllerHandle,
1936 mRequiredProtocol[Index].DiscoveredProtocolGuid,
1938 ProtocolDiscoverIdPtr
1939 );
1940 if (EFI_ERROR (Status)) {
1941 continue;
1942 }
1943
1944 //
1945 // Create service binding child and open it BY_DRIVER.
1946 //
1947 Status = NetLibCreateServiceChild (
1948 ControllerHandle,
1949 This->ImageHandle,
1950 mRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
1951 HandleOfProtocolInterfacePtr
1952 );
1953 if (!EFI_ERROR (Status)) {
1954 Status = gBS->OpenProtocol (
1955 *HandleOfProtocolInterfacePtr,
1956 mRequiredProtocol[Index].RequiredProtocolGuid,
1957 Interface,
1958 OpenDriverAgentHandle,
1959 OpenDriverControllerHandle,
1960 EFI_OPEN_PROTOCOL_BY_DRIVER
1961 );
1962 if (!EFI_ERROR (Status)) {
1963 if ((mRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
1964 // Install Redfish Discover Protocol when EFI REST EX protocol is discovered.
1965 // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
1966 // acquires Redfish service over network interface.
1967
1968 if (!NewNetworkInterfaceInstalled) {
1969 NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
1970 if (NetworkInterface == NULL) {
1971 DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __func__));
1972 return Status;
1973 }
1974 }
1975
1976 NewNetworkInterfaceInstalled = FALSE;
1977 NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
1978
1979 RestExInstance->Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE;
1980
1981 RestExInstance->RedfishDiscoverProtocol.GetNetworkInterfaceList = RedfishServiceGetNetworkInterface;
1982 RestExInstance->RedfishDiscoverProtocol.AcquireRedfishService = RedfishServiceAcquireService;
1983 RestExInstance->RedfishDiscoverProtocol.AbortAcquireRedfishService = RedfishServiceAbortAcquire;
1984 RestExInstance->RedfishDiscoverProtocol.ReleaseRedfishService = RedfishServiceReleaseService;
1985
1986 Status = gBS->InstallProtocolInterface (
1987 &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
1988 &gEfiRedfishDiscoverProtocolGuid,
1990 (VOID *)&RestExInstance->RedfishDiscoverProtocol
1991 );
1992 if (EFI_ERROR (Status)) {
1993 DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __func__));
1994 }
1995 } else {
1996 DEBUG ((DEBUG_MANAGEABILITY, "%a: Not REST EX, continue with next\n", __func__));
1997 continue;
1998 }
1999 }
2000
2001 return Status;
2002 }
2003 }
2004
2005 return EFI_DEVICE_ERROR;
2006}
2007
2026 IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
2027 IN EFI_HANDLE ControllerHandle,
2028 IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol,
2029 IN EFI_HANDLE DriverAgentHandle,
2030 IN EFI_HANDLE DriverControllerHandle
2031 )
2032{
2033 EFI_STATUS Status;
2034
2035 Status = gBS->CloseProtocol (
2036 ControllerHandle,
2037 ThisRequiredProtocol->RequiredProtocolGuid,
2038 DriverAgentHandle,
2039 DriverControllerHandle
2040 );
2041 if (!EFI_ERROR (Status)) {
2043 ControllerHandle,
2044 ThisBindingProtocol->ImageHandle,
2045 ThisRequiredProtocol->RequiredServiceBindingProtocolGuid,
2046 ControllerHandle
2047 );
2048 }
2049
2050 return Status;
2051}
2052
2065 IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
2066 IN EFI_HANDLE ControllerHandle
2067 )
2068{
2069 UINT32 Index;
2070 EFI_STATUS Status;
2071 VOID *Interface;
2072 EFI_TPL OldTpl;
2073 EFI_HANDLE DiscoverProtocolHandle;
2076 EFI_REDFISH_DISCOVER_PROTOCOL *RedfishDiscoverProtocol;
2077
2078 for (Index = 0; Index < (sizeof (mRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
2079 Status = gBS->HandleProtocol (
2080 ControllerHandle,
2081 mRequiredProtocol[Index].RequiredProtocolGuid,
2082 (VOID **)&Interface
2083 );
2084 if (!EFI_ERROR (Status)) {
2085 if (mRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
2086 if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
2087 return EFI_NOT_FOUND;
2088 }
2089
2090 OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
2091 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
2092 while (TRUE) {
2093 if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {
2094 DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
2095 //
2096 // Close protocol and destroy service.
2097 //
2098 Status = CloseProtocolService (
2099 ThisBindingProtocol,
2100 ControllerHandle,
2101 &mRequiredProtocol[Index],
2102 ThisNetworkInterface->OpenDriverAgentHandle,
2103 ThisNetworkInterface->OpenDriverControllerHandle
2104 );
2105 if (!EFI_ERROR (Status)) {
2106 Status = DestroyRedfishNetworkInterface (ThisNetworkInterface);
2107 }
2108
2109 gBS->RestoreTPL (OldTpl);
2110
2111 //
2112 // Disconnect EFI Redfish discover driver controller to notify the
2113 // client which uses .EFI Redfish discover protocol.
2114 //
2115 if (DiscoverProtocolHandle != NULL) {
2116 Status = gBS->HandleProtocol (
2117 DiscoverProtocolHandle,
2118 &gEfiRedfishDiscoverProtocolGuid,
2119 (VOID **)&RedfishDiscoverProtocol
2120 );
2121 if (!EFI_ERROR (Status)) {
2122 RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (RedfishDiscoverProtocol);
2123 //
2124 // Stop Redfish service discovery.
2125 //
2126 RedfishDiscoverProtocol->AbortAcquireRedfishService (
2127 RedfishDiscoverProtocol,
2128 RestExInstance->NetworkInterfaceInstances
2129 );
2130
2131 gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
2132 Status = gBS->UninstallProtocolInterface (
2133 DiscoverProtocolHandle,
2134 &gEfiRedfishDiscoverProtocolGuid,
2135 (VOID *)&RestExInstance->RedfishDiscoverProtocol
2136 );
2137 }
2138 }
2139
2140 return Status;
2141 }
2142
2143 if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
2144 break;
2145 }
2146
2147 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
2148 }
2149
2150 gBS->RestoreTPL (OldTpl);
2151 } else {
2152 if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) {
2153 return EFI_NOT_FOUND;
2154 }
2155
2156 OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
2157 RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance);
2158 while (TRUE) {
2159 if (RestExInstance->RestExChildHandle == ControllerHandle) {
2160 Status = CloseProtocolService (
2161 // Close REST_EX protocol.
2162 ThisBindingProtocol,
2163 ControllerHandle,
2164 &mRequiredProtocol[Index],
2165 RestExInstance->OpenDriverAgentHandle,
2166 RestExInstance->OpenDriverControllerHandle
2167 );
2168 RemoveEntryList (&RestExInstance->Entry);
2169 FreePool ((VOID *)RestExInstance);
2170 mNumRestExInstance--;
2171 gBS->RestoreTPL (OldTpl);
2172 return Status;
2173 }
2174
2175 if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) {
2176 break;
2177 }
2178
2179 RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
2180 }
2181
2182 gBS->RestoreTPL (OldTpl);
2183 }
2184 }
2185 }
2186
2187 return EFI_NOT_FOUND;
2188}
2189
2233EFIAPI
2236 IN EFI_HANDLE ControllerHandle,
2237 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
2238 )
2239{
2240 return TestForRequiredProtocols (This, ControllerHandle);
2241}
2242
2279EFIAPI
2282 IN EFI_HANDLE ControllerHandle,
2283 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
2284 )
2285{
2286 DEBUG ((DEBUG_MANAGEABILITY, "%a:Entry.\n", __func__));
2287 return BuildupNetworkInterface (This, ControllerHandle);
2288}
2289
2317EFIAPI
2320 IN EFI_HANDLE ControllerHandle,
2321 IN UINTN NumberOfChildren,
2322 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
2323 )
2324{
2325 return StopServiceOnNetworkInterface (This, ControllerHandle);
2326}
2327
2328EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = {
2332 REDFISH_DISCOVER_VERSION,
2333 NULL,
2334 NULL
2335};
2336
2347EFIAPI
2349 IN EFI_HANDLE ImageHandle,
2350 IN EFI_SYSTEM_TABLE *SystemTable
2351 )
2352{
2353 EFI_STATUS Status;
2354
2355 Status = EFI_SUCCESS;
2356 InitializeListHead (&mRedfishDiscoverList);
2357 InitializeListHead (&mRedfishInstanceList);
2358 InitializeListHead (&mEfiRedfishDiscoverNetworkInterface);
2359 InitializeListHead (&mEfiRedfishDiscoverRestExInstance);
2360 //
2361 // Install binding protocol to obtain UDP and REST EX protocol.
2362 //
2364 ImageHandle,
2365 SystemTable,
2366 &gRedfishDiscoverDriverBinding,
2367 ImageHandle,
2370 );
2371 return Status;
2372}
2373
2387EFIAPI
2389 IN EFI_HANDLE ImageHandle
2390 )
2391{
2392 EFI_STATUS Status;
2394
2395 Status = EFI_SUCCESS;
2396 // Destroy all network interfaces found by EFI Redfish Discover driver and
2397 // stop services created for Redfish Discover.
2398
2399 while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
2400 ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
2401 StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
2402 }
2403
2404 return Status;
2405}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
BOOLEAN EFIAPI IsNodeAtEnd(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:481
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2873
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI AsciiSPrintUnicodeFormat(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:988
UINTN EFIAPI UnicodeSPrintAsciiFormat(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:583
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI NetLibGetMacAddress(IN EFI_HANDLE ServiceHandle, OUT EFI_MAC_ADDRESS *MacAddress, OUT UINTN *AddressSize)
Definition: DxeNetLib.c:2251
EFI_STATUS EFIAPI NetLibGetMacString(IN EFI_HANDLE ServiceHandle, IN EFI_HANDLE ImageHandle OPTIONAL, OUT CHAR16 **MacString)
Definition: DxeNetLib.c:2363
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
EFI_STATUS EFIAPI NetLibIp6ToStr(IN EFI_IPv6_ADDRESS *Ip6Address, OUT CHAR16 *String, IN UINTN StringSize)
Definition: DxeNetLib.c:3218
UINT16 EFIAPI NetLibGetVlanId(IN EFI_HANDLE ServiceHandle)
Definition: DxeNetLib.c:2140
#define FixedPcdGetBool(TokenName)
Definition: PcdLib.h:120
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS DumpIpv4Address(IN UINTN ErrorLevel, IN EFI_IPv4_ADDRESS *Ipv4Address)
#define EFI_REDFISH_DISCOVER_HOST_INTERFACE
Discover Redfish server reported in SMBIOS 42h.
#define EFI_REDFISH_DISCOVER_VALIDATION
Validate Redfish service for host interface instance.
#define EFI_REDFISH_DISCOVER_SSDP
Discover Redfish server using UPnP Http search method.
EFI_STATUS DestroyRedfishNetworkInterface(IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface)
EFI_STATUS EFIAPI Tcp6GetSubnetInfo(IN EFI_HANDLE ImageHandle, IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance)
EFI_STATUS EFIAPI RedfishServiceAbortAcquire(IN EFI_REDFISH_DISCOVER_PROTOCOL *This, IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL)
STATIC VOID InitInformationData(IN EFI_REDFISH_DISCOVERED_INFORMATION *Information, IN BOOLEAN IsIpv6, IN UINTN *RedfishVersion OPTIONAL, IN CONST CHAR8 *RedfishLocation OPTIONAL, IN CONST CHAR8 *Uuid OPTIONAL, IN CONST CHAR8 *Os OPTIONAL, IN CONST CHAR8 *OsVer OPTIONAL, IN CONST CHAR8 *Product OPTIONAL, IN CONST CHAR8 *ProductVer OPTIONAL)
EFI_STATUS EFIAPI RedfishDiscoverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS CloseProtocolService(IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol, IN EFI_HANDLE ControllerHandle, IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol, IN EFI_HANDLE DriverAgentHandle, IN EFI_HANDLE DriverControllerHandle)
EFI_STATUS EFIAPI RedfishServiceGetNetworkInterface(IN EFI_REDFISH_DISCOVER_PROTOCOL *This, IN EFI_HANDLE ImageHandle, OUT UINTN *NumberOfNetworkIntfs, OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances)
EFI_STATUS ValidateTargetNetworkInterface(IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface, IN EFI_REDFISH_DISCOVER_FLAG Flags)
EFI_STATUS EFIAPI RedfishDiscoverDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
BOOLEAN CheckIsIpVersion6(IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface)
EFI_STATUS AddAndSignalNewRedfishService(IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance, IN UINTN *RedfishVersion OPTIONAL, IN CHAR8 *RedfishLocation OPTIONAL, IN CHAR8 *Uuid OPTIONAL, IN CHAR8 *Os OPTIONAL, IN CHAR8 *OsVer OPTIONAL, IN CHAR8 *Product OPTIONAL, IN CHAR8 *ProductVer OPTIONAL, IN BOOLEAN UseHttps)
EFI_STATUS CreateRedfishDiscoverNetworkInterface(IN EFI_HANDLE ControllerHandle, IN UINT32 NetworkProtocolType, OUT BOOLEAN *IsNewInstance, OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL **NetworkInterface)
STATIC VOID FreeInformationData(IN EFI_REDFISH_DISCOVERED_INFORMATION *Information)
EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * GetInstanceByOwner(IN EFI_HANDLE ImageHandle, IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterface, IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags)
EFI_STATUS BuildupNetworkInterface(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle)
EFI_STATUS TestForRequiredProtocols(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle)
EFI_STATUS EFIAPI RedfishDiscoverDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
EFI_STATUS NetworkInterfaceGetSubnetInfo(IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance, IN EFI_HANDLE ImageHandle)
EFI_STATUS DiscoverRedfishHostInterface(IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance)
UINTN NumberOfNetworkInterface(VOID)
EFI_STATUS EFIAPI RedfishServiceAcquireService(IN EFI_REDFISH_DISCOVER_PROTOCOL *This, IN EFI_HANDLE ImageHandle, IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface, IN EFI_REDFISH_DISCOVER_FLAG Flags, IN EFI_REDFISH_DISCOVERED_TOKEN *Token)
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * GetTargetNetworkInterfaceInternalByController(IN EFI_HANDLE ControllerHandle)
EFI_STATUS EFIAPI RedfishServiceReleaseService(IN EFI_REDFISH_DISCOVER_PROTOCOL *This, IN EFI_REDFISH_DISCOVERED_LIST *InstanceList)
STATIC BOOLEAN FilterProtocol(IN UINT32 NetworkProtocolType, IN UINT8 IpType)
EFI_STATUS EFIAPI Tcp4GetSubnetInfo(IN EFI_HANDLE ImageHandle, IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance)
EFI_STATUS EFIAPI RedfishDiscoverDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
EFI_STATUS StopServiceOnNetworkInterface(IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol, IN EFI_HANDLE ControllerHandle)
EFI_STATUS CreateRestExInstance(IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance, IN EFI_REDFISH_DISCOVERED_TOKEN *Token)
EFI_STATUS EFIAPI RedfishDiscoverUnload(IN EFI_HANDLE ImageHandle)
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * GetTargetNetworkInterfaceInternal(IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface)
@ ProtocolTypeTcp4
Network protocol TCPv4.
@ ProtocolTypeTcp6
Network protocol TCCv6.
@ ProtocolTypeRestEx
REST EX over network protocol.
EFI_STATUS RedfishGetHostInterfaceProtocolData(IN EFI_SMBIOS_PROTOCOL *Smbios, OUT REDFISH_INTERFACE_DATA **DeviceDescriptor, OUT REDFISH_OVER_IP_PROTOCOL_DATA **ProtocolData)
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gRedfishDiscoverComponentName
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gRedfishDiscoverComponentName2
EFI_STATUS RestExLibCreateChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_REST_EX_SERVICE_ACCESS_MODE AccessMode, IN EFI_REST_EX_CONFIG_TYPE ConfigType, IN EFI_REST_EX_SERVICE_TYPE ServiceType, OUT EFI_HANDLE *ChildInstanceHandle)
Definition: DxeRestExLib.c:38
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_HTTP_VERSION HttpVersion
Definition: Http.h:154
EFI_HTTPv6_ACCESS_POINT * IPv6Node
Definition: Http.h:176
EFI_HTTPv4_ACCESS_POINT * IPv4Node
Definition: Http.h:171
BOOLEAN LocalAddressIsIPv6
Definition: Http.h:164
EFI_IPv4_ADDRESS LocalSubnet
Definition: Http.h:124
EFI_IPv4_ADDRESS LocalAddress
Definition: Http.h:119
BOOLEAN UseDefaultAddress
Definition: Http.h:114
EFI_IPv6_ADDRESS LocalAddress
Definition: Http.h:139
EFI_IPv4_ADDRESS SubnetMask
Definition: Ip4.h:98
EFI_IPv4_ADDRESS StationAddress
Definition: Ip4.h:94
EFI_IP4_CONFIG_DATA ConfigData
Definition: Ip4.h:153
UINT8 PrefixLength
The length of the prefix associated with the Address.
Definition: Ip6.h:222
EFI_IPv6_ADDRESS Address
The IPv6 address.
Definition: Ip6.h:221
EFI_IP6_ADDRESS_INFO * AddressList
Definition: Ip6.h:336
UINT32 AddressCount
Definition: Ip6.h:330
EFI_MAC_ADDRESS MacAddress
MAC address of network interface.
REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL NetworkInterfaceProtocolInfo
Network interface protocol information.
CHAR16 * StrMacAddr
String to MAC address of network interface.
EFI_HANDLE OpenDriverControllerHandle
The controller handle to open network protocol.
UINTN HwAddressSize
The size of network interface hardware address.
EFI_HANDLE OpenDriverAgentHandle
The agent to open network protocol.
UINT8 SubnetPrefixLength
Subnet prefix-length for IPv4 and IPv6.
EFI_MAC_ADDRESS MacAddress
MAC address of network interfase to discover Redfish service.
BOOLEAN IsIpv6
Indicates it's IP versino 6.
EFI_HANDLE OpenDriverControllerHandle
The controller handle to open network protocol.
EFI_HANDLE OpenDriverAgentHandle
The agent to open network protocol.
UINT32 RestExId
The identifier installed on REST EX controller handle.
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * NetworkInterfaceInstances
EFI_REDFISH_DISCOVER_PROTOCOL RedfishDiscoverProtocol
EFI_REDFISH_DISCOVER_PROTOCOL protocol.
EFI_HANDLE RestExControllerHandle
The controller handle which provide REST EX protocol.
UINTN NumberOfNetworkInterfaces
Number of network interfaces can do Redfish service discovery.
EFI_HANDLE RestExChildHandle
The child handle created through REST EX Service Protocol.
EFI_REST_EX_PROTOCOL * RestExProtocolInterface
Pointer to EFI_REST_EX_PROTOCOL.
EFI_IP_ADDRESS RedfishHostIpAddress
IP address of Redfish service.
CHAR16 * Uuid
Redfish service UUID.
EFI_REDFISH_DISCOVERED_INFORMATION Information
Redfish service discovered.
EFI_STATUS Status
Status of Redfish service discovery.
BOOLEAN HostIntfValidation
Indicates whether to validate Redfish Host interface.
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * NetworkInterface
EFI_REDFISH_DISCOVERED_TOKEN * DiscoverToken
Token used to signal when Redfish service is discovered.
EFI_REDFISH_DISCOVER_FLAG DiscoverFlags
EFI_REDFISH_DISCOVER_FLAG.
EFI_REDFISH_DISCOVERED_INSTANCE * Instance
Pointer to EFI_REDFISH_DISCOVERED_INSTANCE.
Definition: Base.h:213
UINT8 MacAddress[6]
The MAC address of the PCI/PCIe network device.
VOID * NetworkProtocolInterface
The protocol interface of network protocol.
EFI_HANDLE ProtocolControllerHandle
The controller handle on network protocol.
UINT32 ProtocolDiscoverId
The identifier installed on network protocol handle.
EFI_GUID ProtocolServiceGuid
Network protocol service GUID.
EFI_GUID * RequiredProtocolGuid
Network protocol interface GUID.
EFI_GUID * DiscoveredProtocolGuid
Protocol interface GUID use to install identifier.
EFI_REDFISH_DISCOVER_GET_SUBNET_INFO GetSubnetInfo
Function of getting subnet information.
EFI_GUID * RequiredServiceBindingProtocolGuid
Network protocol service GUID.
Device descriptor data formated based on Device Type.
DEVICE_DESCRITOR DeviceDescriptor
The Device descriptor.
UINT8 DeviceType
The Device Type of the interface.
UINT8 MacAddress[6]
The MAC address of the PCI/PCIe network device.
PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 PciPcieDeviceV2
Device type PCI/PCIe V2 device discriptor.
USB_INTERFACE_DEVICE_DESCRIPTOR_V2 UsbDeviceV2
Device type USB V2 device discriptor.