RedfishPkg: RedfishDiscoverDxe: Optimize the Redfish Discover flow

Filter out the network interfaces which are not supported by
Redfish Host Interface.

Reviewed-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Nickle Wang <nicklew@nvidia.com>
Acked-by Mike Maslenkin <mike.maslenkin@gmail.com>
Signed-off-by: Igor Kulchytskyy <igork@ami.com>
This commit is contained in:
Igor Kulchytskyy 2023-11-14 21:55:35 -05:00 committed by mergify[bot]
parent 06b27ccb90
commit 3db76e6476
2 changed files with 105 additions and 33 deletions

View File

@ -322,9 +322,16 @@ GetTargetNetworkInterfaceInternal (
{ {
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
return NULL;
}
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) { while (TRUE) {
if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) { if ((MAC_COMPARE (ThisNetworkInterface, TargetNetworkInterface) == 0) &&
(VALID_TCP6 (TargetNetworkInterface, ThisNetworkInterface) ||
VALID_TCP4 (TargetNetworkInterface, ThisNetworkInterface)))
{
return ThisNetworkInterface; return ThisNetworkInterface;
} }
@ -354,6 +361,10 @@ GetTargetNetworkInterfaceInternalByController (
{ {
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
return NULL;
}
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) { while (TRUE) {
if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) { if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
@ -476,6 +487,42 @@ CheckIsIpVersion6 (
return FALSE; return FALSE;
} }
/**
This function returns the IP type supported by the Host Interface.
@retval 00h is Unknown
01h is Ipv4
02h is Ipv6
**/
UINT8
GetHiIpProtocolType (
VOID
)
{
EFI_STATUS Status;
REDFISH_OVER_IP_PROTOCOL_DATA *Data;
REDFISH_INTERFACE_DATA *DeviceDescriptor;
Data = NULL;
DeviceDescriptor = NULL;
if (mSmbios == NULL) {
Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);
if (EFI_ERROR (Status)) {
return REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
}
}
Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
if (!EFI_ERROR (Status) && (Data != NULL) &&
(Data->HostIpAssignmentType == RedfishHostIpAssignmentStatic))
{
return Data->HostIpAddressFormat;
}
return REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN;
}
/** /**
This function discover Redfish service through SMBIOS host interface. This function discover Redfish service through SMBIOS host interface.
@ -512,6 +559,18 @@ DiscoverRedfishHostInterface (
Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) { if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) {
if ((Instance->NetworkInterface->NetworkProtocolType == ProtocolTypeTcp4) &&
(Data->HostIpAddressFormat != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4)) // IPv4 case
{
DEBUG ((DEBUG_ERROR, "%a: Network Interface is IPv4, but Host Interface requires Ipv6\n", __func__));
return EFI_UNSUPPORTED;
} else if ((Instance->NetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) &&
(Data->HostIpAddressFormat != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6)) // IPv6 case
{
DEBUG ((DEBUG_ERROR, "%a: Network Interface is IPv6, but Host Interface requires IPv4\n", __func__));
return EFI_UNSUPPORTED;
}
// //
// Check if we can reach out Redfish service using this network interface. // Check if we can reach out Redfish service using this network interface.
// Check with MAC address using Device Descriptor Data Device Type 04 and Type 05. // Check with MAC address using Device Descriptor Data Device Type 04 and Type 05.
@ -1102,6 +1161,7 @@ RedfishServiceGetNetworkInterface (
OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances
) )
{ {
EFI_STATUS Status;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
@ -1141,13 +1201,23 @@ RedfishServiceGetNetworkInterface (
ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) { while (TRUE) {
// If Get Subnet Info failed then skip this interface
Status = NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info
if (EFI_ERROR (Status)) {
if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
break;
}
ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
continue;
}
ThisNetworkInterface->IsIpv6 = FALSE; ThisNetworkInterface->IsIpv6 = FALSE;
if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) { if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
ThisNetworkInterface->IsIpv6 = TRUE; ThisNetworkInterface->IsIpv6 = TRUE;
} }
CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize); CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);
NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info.
if (!ThisNetworkInterface->IsIpv6) { if (!ThisNetworkInterface->IsIpv6) {
IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information. IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.
} else { } else {
@ -1230,6 +1300,11 @@ RedfishServiceAcquireService (
if (TargetNetworkInterface != NULL) { if (TargetNetworkInterface != NULL) {
TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface); TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);
if (TargetNetworkInterfaceInternal == NULL) {
DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __func__));
return EFI_UNSUPPORTED;
}
NumNetworkInterfaces = 1; NumNetworkInterfaces = 1;
} else { } else {
TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
@ -1260,7 +1335,13 @@ RedfishServiceAcquireService (
// Get subnet information in case subnet information is not set because // Get subnet information in case subnet information is not set because
// RedfishServiceGetNetworkInterfaces hasn't been called yet. // RedfishServiceGetNetworkInterfaces hasn't been called yet.
// //
NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle); Status1 = NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);
if (EFI_ERROR (Status1)) {
DEBUG ((DEBUG_ERROR, "%a: Get subnet information fail.\n", __func__));
FreePool (Instance);
continue;
}
NewInstance = TRUE; NewInstance = TRUE;
} }
@ -1601,10 +1682,22 @@ BuildupNetworkInterface (
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
EFI_TPL OldTpl; EFI_TPL OldTpl;
BOOLEAN NewNetworkInterfaceInstalled; BOOLEAN NewNetworkInterfaceInstalled;
UINT8 IpType;
UINTN ListCount;
ListCount = (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
NewNetworkInterfaceInstalled = FALSE; NewNetworkInterfaceInstalled = FALSE;
Index = 0; Index = 0;
do {
// Get IP Type to filter out unnecessary network protocol if possible
IpType = GetHiIpProtocolType ();
for (Index = 0; Index < ListCount; Index++) {
// Check IP Type and skip an unnecessary network protocol if does not match
if (IS_TCP4_MATCH (IpType) || IS_TCP6_MATCH (IpType)) {
continue;
}
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
// Already in list? // Already in list?
ControllerHandle, ControllerHandle,
@ -1615,11 +1708,6 @@ BuildupNetworkInterface (
EFI_OPEN_PROTOCOL_GET_PROTOCOL EFI_OPEN_PROTOCOL_GET_PROTOCOL
); );
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Index++;
if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
break;
}
continue; continue;
} }
@ -1632,11 +1720,6 @@ BuildupNetworkInterface (
EFI_OPEN_PROTOCOL_GET_PROTOCOL EFI_OPEN_PROTOCOL_GET_PROTOCOL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Index++;
if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
break;
}
continue; continue;
} }
@ -1695,11 +1778,6 @@ BuildupNetworkInterface (
ProtocolDiscoverIdPtr ProtocolDiscoverIdPtr
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Index++;
if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
break;
}
continue; continue;
} }
@ -1756,25 +1834,13 @@ BuildupNetworkInterface (
} }
} else { } else {
DEBUG ((DEBUG_MANAGEABILITY, "%a: Not REST EX, continue with next\n", __func__)); DEBUG ((DEBUG_MANAGEABILITY, "%a: Not REST EX, continue with next\n", __func__));
Index++;
if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
break;
}
continue; continue;
} }
} }
return Status; return Status;
} else {
Index++;
if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
break;
} }
continue;
} }
} while (Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)));
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }

View File

@ -39,6 +39,12 @@
#define REDFISH_DISCOVER_VERSION 0x00010000 #define REDFISH_DISCOVER_VERSION 0x00010000
#define EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL TPL_NOTIFY #define EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL TPL_NOTIFY
#define MAC_COMPARE(ThisNetworkInterface, TargetNetworkInterface) (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize))
#define VALID_TCP6(TargetNetworkInterface, ThisNetworkInterface) (TargetNetworkInterface->IsIpv6 && (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6))
#define VALID_TCP4(TargetNetworkInterface, ThisNetworkInterface) (!TargetNetworkInterface->IsIpv6 && (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp4))
#define IS_TCP4_MATCH(IpType) ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeTcp4) && (IpType != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4))
#define IS_TCP6_MATCH(IpType) ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeTcp6) && (IpType != REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6))
// //
// GUID definitions // GUID definitions
// //