2021-03-24 08:35:54 +01:00
/** @file
2023-03-27 16:28:58 +02:00
The implementation of EFI Redfish Discover Protocol .
2021-03-24 08:35:54 +01:00
( C ) Copyright 2021 Hewlett Packard Enterprise Development LP < BR >
2022-08-30 06:15:47 +02:00
Copyright ( c ) 2022 , AMD Incorporated . All rights reserved .
2023-03-27 16:28:58 +02:00
Copyright ( c ) 2023 , NVIDIA CORPORATION & AFFILIATES . All rights reserved .
2021-06-30 03:41:21 +02:00
Copyright ( c ) 2023 , Ampere Computing LLC . All rights reserved . < BR >
2021-03-24 08:35:54 +01:00
SPDX - License - Identifier : BSD - 2 - Clause - Patent
* */
# include "RedfishDiscoverInternal.h"
LIST_ENTRY mRedfishDiscoverList ;
LIST_ENTRY mRedfishInstanceList ;
EFI_SMBIOS_PROTOCOL * mSmbios = NULL ;
UINTN mNumNetworkInterface = 0 ;
UINTN mNumRestExInstance = 0 ;
LIST_ENTRY mEfiRedfishDiscoverNetworkInterface ;
LIST_ENTRY mEfiRedfishDiscoverRestExInstance ;
EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID ;
EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID ;
EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID ;
EFI_STATUS
EFIAPI
Tcp4GetSubnetInfo (
IN EFI_HANDLE ImageHandle ,
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * Instance
) ;
EFI_STATUS
EFIAPI
Tcp6GetSubnetInfo (
IN EFI_HANDLE ImageHandle ,
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * Instance
) ;
2023-11-15 03:55:35 +01:00
static REDFISH_DISCOVER_REQUIRED_PROTOCOL mRequiredProtocol [ ] = {
2021-03-24 08:35:54 +01:00
{
ProtocolTypeTcp4 ,
L " TCP4 Service Binding Protocol " ,
& gEfiTcp4ProtocolGuid ,
& gEfiTcp4ServiceBindingProtocolGuid ,
& mRedfishDiscoverTcp4InstanceGuid ,
Tcp4GetSubnetInfo
} ,
{
ProtocolTypeTcp6 ,
L " TCP6 Service Binding Protocol " ,
& gEfiTcp6ProtocolGuid ,
& gEfiTcp6ServiceBindingProtocolGuid ,
& mRedfishDiscoverTcp6InstanceGuid ,
Tcp6GetSubnetInfo
} ,
{
ProtocolTypeRestEx ,
L " REST EX Service Binding Protocol " ,
& gEfiRestExProtocolGuid ,
& gEfiRestExServiceBindingProtocolGuid ,
& mRedfishDiscoverRestExInstanceGuid ,
NULL
}
} ;
/**
This function creates REST EX instance for the found Resfish service .
by known owner handle .
@ param [ in ] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
@ param [ in ] Token Client token .
@ retval NULL Instance not found .
@ retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner .
* */
EFI_STATUS
CreateRestExInstance (
IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * Instance ,
IN EFI_REDFISH_DISCOVERED_TOKEN * Token
)
{
EFI_STATUS Status ;
Status = RestExLibCreateChild (
2021-06-28 12:26:55 +02:00
Instance - > NetworkInterface - > OpenDriverControllerHandle ,
2021-03-24 08:35:54 +01:00
Instance - > Owner ,
FixedPcdGetBool ( PcdRedfishDiscoverAccessModeInBand ) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess ,
EfiRestExConfigHttp ,
EfiRestExServiceRedfish ,
& Token - > DiscoverList . RedfishInstances - > Information . RedfishRestExHandle
) ;
return Status ;
}
/**
This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
by known owner handle .
@ param [ in ] ImageHandle Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE .
@ param [ in ] TargetNetworkInterface Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE .
@ param [ in ] DiscoverFlags EFI_REDFISH_DISCOVER_FLAG
@ retval NULL Instance not found .
@ retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner .
* */
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_REDFISH_DISCOVERED_INTERNAL_INSTANCE * ThisInstance ;
if ( IsListEmpty ( & mRedfishDiscoverList ) ) {
return NULL ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisInstance =
( EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * ) GetFirstNode ( & mRedfishDiscoverList ) ;
while ( TRUE ) {
if ( ( ThisInstance - > Owner = = ImageHandle ) & &
( ThisInstance - > DiscoverFlags = = DiscoverFlags ) & &
( ThisInstance - > NetworkInterface = = TargetNetworkInterface ) )
{
return ThisInstance ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mRedfishDiscoverList , & ThisInstance - > Entry ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisInstance =
( EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * ) GetNextNode ( & mRedfishDiscoverList , & ThisInstance - > Entry ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return NULL ;
}
/**
This function gets the subnet information of this TCP4 instance .
@ param [ in ] ImageHandle EFI handle with this image .
@ param [ in ] Instance Instance of Network interface .
@ retval EFI_STATUS Get subnet information successfully .
@ retval Otherwise Fail to get subnet information .
* */
EFI_STATUS
EFIAPI
Tcp4GetSubnetInfo (
IN EFI_HANDLE ImageHandle ,
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * Instance
)
{
EFI_STATUS Status ;
EFI_TCP4_PROTOCOL * Tcp4 ;
EFI_TCP4_CONFIG_DATA Tcp4CfgData ;
EFI_TCP4_OPTION Tcp4Option ;
EFI_IP4_MODE_DATA IpModedata ;
UINT8 SubnetMaskIndex ;
UINT8 BitMask ;
UINT8 PrefixLength ;
BOOLEAN GotPrefixLength ;
if ( Instance = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Tcp4 = ( EFI_TCP4_PROTOCOL * ) Instance - > NetworkInterfaceProtocolInfo . NetworkProtocolInterface ;
ZeroMem ( ( VOID * ) & Tcp4CfgData , sizeof ( EFI_TCP4_CONFIG_DATA ) ) ;
ZeroMem ( ( VOID * ) & Tcp4Option , sizeof ( EFI_TCP4_OPTION ) ) ;
// Give a local host IP address just for getting subnet information.
Tcp4CfgData . AccessPoint . UseDefaultAddress = TRUE ;
Tcp4CfgData . AccessPoint . RemoteAddress . Addr [ 0 ] = 127 ;
Tcp4CfgData . AccessPoint . RemoteAddress . Addr [ 1 ] = 0 ;
Tcp4CfgData . AccessPoint . RemoteAddress . Addr [ 2 ] = 0 ;
Tcp4CfgData . AccessPoint . RemoteAddress . Addr [ 3 ] = 1 ;
Tcp4CfgData . AccessPoint . RemotePort = 80 ;
Tcp4CfgData . AccessPoint . ActiveFlag = TRUE ;
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Tcp4CfgData . ControlOption = & Tcp4Option ;
Tcp4Option . ReceiveBufferSize = 65535 ;
Tcp4Option . SendBufferSize = 65535 ;
Tcp4Option . MaxSynBackLog = 5 ;
Tcp4Option . ConnectionTimeout = 60 ;
Tcp4Option . DataRetries = 12 ;
Tcp4Option . FinTimeout = 2 ;
Tcp4Option . KeepAliveProbes = 6 ;
Tcp4Option . KeepAliveTime = 7200 ;
Tcp4Option . KeepAliveInterval = 30 ;
Tcp4Option . EnableNagle = TRUE ;
Status = Tcp4 - > Configure ( Tcp4 , & Tcp4CfgData ) ;
if ( EFI_ERROR ( Status ) ) {
2023-10-23 14:40:42 +02:00
if ( Status = = EFI_NO_MAPPING ) {
return EFI_SUCCESS ;
}
DEBUG ( ( DEBUG_ERROR , " %a: Can't get subnet information: %r \n " , __func__ , Status ) ) ;
2021-03-24 08:35:54 +01:00
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = Tcp4 - > GetModeData ( Tcp4 , NULL , NULL , & IpModedata , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
2023-10-23 14:40:42 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: Can't get IP mode data information: %r \n " , __func__ , Status ) ) ;
2021-03-24 08:35:54 +01:00
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
IP4_COPY_ADDRESS ( & Instance - > SubnetMask , & IpModedata . ConfigData . SubnetMask ) ;
Instance - > SubnetAddr . v4 . Addr [ 0 ] = IpModedata . ConfigData . StationAddress . Addr [ 0 ] & Instance - > SubnetMask . v4 . Addr [ 0 ] ;
Instance - > SubnetAddr . v4 . Addr [ 1 ] = IpModedata . ConfigData . StationAddress . Addr [ 1 ] & Instance - > SubnetMask . v4 . Addr [ 1 ] ;
Instance - > SubnetAddr . v4 . Addr [ 2 ] = IpModedata . ConfigData . StationAddress . Addr [ 2 ] & Instance - > SubnetMask . v4 . Addr [ 2 ] ;
Instance - > SubnetAddr . v4 . Addr [ 3 ] = IpModedata . ConfigData . StationAddress . Addr [ 3 ] & Instance - > SubnetMask . v4 . Addr [ 3 ] ;
//
// Calculate the subnet mask prefix.
//
GotPrefixLength = FALSE ;
PrefixLength = 0 ;
SubnetMaskIndex = 0 ;
while ( GotPrefixLength = = FALSE & & SubnetMaskIndex < 4 ) {
BitMask = 0x80 ;
while ( BitMask ! = 0 ) {
if ( ( Instance - > SubnetMask . v4 . Addr [ SubnetMaskIndex ] & BitMask ) ! = 0 ) {
PrefixLength + + ;
} else {
GotPrefixLength = TRUE ;
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
BitMask = BitMask > > 1 ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
SubnetMaskIndex + + ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Instance - > SubnetPrefixLength = PrefixLength ;
return EFI_SUCCESS ;
}
/**
This function gets the subnet information of this TCP6 instance .
@ param [ in ] ImageHandle EFI handle with this image .
@ param [ in ] Instance Instance of Network interface .
@ retval EFI_STATUS Get subnet information successfully .
@ retval Otherwise Fail to get subnet information .
* */
EFI_STATUS
EFIAPI
Tcp6GetSubnetInfo (
IN EFI_HANDLE ImageHandle ,
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * Instance
)
{
EFI_STATUS Status ;
EFI_TCP6_PROTOCOL * Tcp6 ;
EFI_IP6_MODE_DATA IpModedata ;
if ( Instance = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Tcp6 = ( EFI_TCP6_PROTOCOL * ) Instance - > NetworkInterfaceProtocolInfo . NetworkProtocolInterface ;
2022-10-28 12:16:55 +02:00
ZeroMem ( ( VOID * ) & IpModedata , sizeof ( EFI_IP6_MODE_DATA ) ) ;
2021-03-24 08:35:54 +01:00
Status = Tcp6 - > GetModeData ( Tcp6 , NULL , NULL , & IpModedata , NULL , NULL ) ;
if ( EFI_ERROR ( Status ) ) {
2023-10-23 14:40:42 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: Can't get IP mode data information: %r \n " , __func__ , Status ) ) ;
2021-03-24 08:35:54 +01:00
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IpModedata . AddressCount = = 0 ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a: No IPv6 address configured. \n " , __func__ ) ) ;
2023-03-27 16:28:58 +02:00
Instance - > SubnetAddrInfoIPv6Number = 0 ;
return EFI_SUCCESS ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( Instance - > SubnetAddrInfoIPv6 ! = NULL ) {
FreePool ( Instance - > SubnetAddrInfoIPv6 ) ;
2023-03-27 16:28:58 +02:00
Instance - > SubnetAddrInfoIPv6 = NULL ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Instance - > SubnetAddrInfoIPv6 = AllocateZeroPool ( IpModedata . AddressCount * sizeof ( EFI_IP6_ADDRESS_INFO ) ) ;
if ( Instance - > SubnetAddrInfoIPv6 = = NULL ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: Failed to allocate memory for IPv6 subnet address information \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_OUT_OF_RESOURCES ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Instance - > SubnetAddrInfoIPv6Number = IpModedata . AddressCount ;
2022-10-28 12:16:55 +02:00
if ( ( IpModedata . AddressCount ! = 0 ) & & ( IpModedata . AddressList ! = NULL ) ) {
CopyMem (
( VOID * ) Instance - > SubnetAddrInfoIPv6 ,
( VOID * ) & IpModedata . AddressList ,
IpModedata . AddressCount * sizeof ( EFI_IP6_ADDRESS_INFO )
) ;
FreePool ( IpModedata . AddressList ) ;
}
2021-03-24 08:35:54 +01:00
return EFI_SUCCESS ;
}
/**
This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
instance with the given EFI_REDFISH_DISCOVER_NETWORK_INTERFACE .
@ param [ in ] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE .
NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs .
@ retval Non - NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned .
@ retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned .
* */
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
GetTargetNetworkInterfaceInternal (
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * TargetNetworkInterface
)
{
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
2023-11-15 03:55:35 +01:00
if ( IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) ) {
return NULL ;
}
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
2023-11-15 03:55:35 +01:00
if ( ( MAC_COMPARE ( ThisNetworkInterface , TargetNetworkInterface ) ) & &
( VALID_TCP6 ( TargetNetworkInterface , ThisNetworkInterface ) | |
VALID_TCP4 ( TargetNetworkInterface , ThisNetworkInterface ) ) )
{
2021-03-24 08:35:54 +01:00
return ThisNetworkInterface ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
return NULL ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return NULL ;
}
2022-08-30 06:15:47 +02:00
/**
This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
instance with the given Controller handle .
@ param [ in ] ControllerHandle The controller handle associated with network interface .
@ retval Non - NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned .
@ retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned .
* */
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
GetTargetNetworkInterfaceInternalByController (
IN EFI_HANDLE ControllerHandle
)
{
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
2023-11-15 03:55:35 +01:00
if ( IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) ) {
return NULL ;
}
2022-08-30 06:15:47 +02:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
if ( ThisNetworkInterface - > OpenDriverControllerHandle = = ControllerHandle ) {
return ThisNetworkInterface ;
}
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
return NULL ;
}
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
}
return NULL ;
}
2021-03-24 08:35:54 +01:00
/**
This function validate if target network interface is ready for discovering
Redfish service .
@ param [ in ] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE .
NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs .
@ param [ in ] Flags EFI_REDFISH_DISCOVER_FLAG
@ retval EFI_SUCCESS Target network interface is ready to use .
@ retval EFI_UNSUPPORTED Target network interface is not ready to use .
* */
EFI_STATUS
ValidateTargetNetworkInterface (
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * TargetNetworkInterface ,
IN EFI_REDFISH_DISCOVER_FLAG Flags
)
{
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
if ( IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) & & ( TargetNetworkInterface = = NULL ) ) {
return EFI_UNSUPPORTED ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( TargetNetworkInterface = = NULL ) {
return EFI_SUCCESS ; // Return EFI_SUCCESS if no network interface is specified.
}
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
2023-11-15 03:55:35 +01:00
if ( MAC_COMPARE ( ThisNetworkInterface , TargetNetworkInterface ) ) {
2021-03-24 08:35:54 +01:00
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
return EFI_UNSUPPORTED ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ( Flags & EFI_REDFISH_DISCOVER_SSDP ) ! = 0 ) {
// Validate if UDP4/6 is supported on the given network interface.
// SSDP is not supported.
return EFI_SUCCESS ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisNetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolControllerHandle = = NULL ) {
return EFI_UNSUPPORTED ; // The required protocol on this network interface is not found.
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return EFI_SUCCESS ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
/**
This function returns number of network interface instance .
@ retval UINTN Number of network interface instances .
* */
UINTN
NumberOfNetworkInterface (
VOID
)
{
UINTN Num ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
if ( IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) ) {
return 0 ;
}
Num = 1 ;
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
Num + + ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Num ;
}
/**
This function checks the IP version supported on this
2023-03-27 16:28:58 +02:00
network interface .
2021-03-24 08:35:54 +01:00
@ param [ in ] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
@ retval TRUE Is IPv6 , otherwise IPv4 .
* */
BOOLEAN
CheckIsIpVersion6 (
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface
)
{
if ( ThisNetworkInterface - > NetworkProtocolType = = ProtocolTypeTcp6 ) {
return TRUE ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return FALSE ;
}
2023-11-15 03:55:35 +01:00
/**
This function returns the IP type supported by the Host Interface .
@ retval 00 h is Unknown
01 h is Ipv4
02 h is Ipv6
* */
STATIC
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 ;
}
/**
Check if Network Protocol Type matches with SMBIOS Type 42 IP Address Type .
@ param [ in ] NetworkProtocolType The Network Protocol Type to check with .
@ param [ in ] IpType The Host IP Address Type from SMBIOS Type 42.
* */
STATIC
BOOLEAN
FilterProtocol (
IN UINT32 NetworkProtocolType ,
IN UINT8 IpType
)
{
if ( NetworkProtocolType = = ProtocolTypeTcp4 ) {
return IpType ! = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4 ;
}
if ( NetworkProtocolType = = ProtocolTypeTcp6 ) {
return IpType ! = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6 ;
}
return FALSE ;
}
2021-03-24 08:35:54 +01:00
/**
This function discover Redfish service through SMBIOS host interface .
@ param [ in ] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
@ retval EFI_SUCCESS Redfish service is discovered through SMBIOS Host interface .
2023-03-27 16:28:58 +02:00
@ retval Others Fail to discover Redfish service through SMBIOS host interface
2021-03-24 08:35:54 +01:00
* */
EFI_STATUS
DiscoverRedfishHostInterface (
IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * Instance
)
{
EFI_STATUS Status ;
REDFISH_OVER_IP_PROTOCOL_DATA * Data ;
REDFISH_INTERFACE_DATA * DeviceDescriptor ;
CHAR8 UuidStr [ sizeof " 00000000-0000-0000-0000-000000000000 " + 1 ] ;
CHAR16 Ipv6Str [ sizeof " ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff " + 1 ] ;
CHAR8 RedfishServiceLocateStr [ sizeof " ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff " + 1 ] ;
UINTN StrSize ;
2023-03-27 16:28:58 +02:00
UINTN MacCompareStatus ;
2021-03-24 08:35:54 +01:00
BOOLEAN IsHttps ;
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Data = NULL ;
DeviceDescriptor = NULL ;
if ( mSmbios = = NULL ) {
Status = gBS - > LocateProtocol ( & gEfiSmbiosProtocolGuid , NULL , ( VOID * * ) & mSmbios ) ;
if ( EFI_ERROR ( Status ) ) {
return Status ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = RedfishGetHostInterfaceProtocolData ( mSmbios , & DeviceDescriptor , & Data ) ; // Search for SMBIOS type 42h
if ( ! EFI_ERROR ( Status ) & & ( Data ! = NULL ) & & ( DeviceDescriptor ! = NULL ) ) {
2023-11-15 03:55:35 +01:00
// Check IP Type and skip an unnecessary network protocol if does not match
if ( FilterProtocol ( Instance - > NetworkInterface - > NetworkProtocolType , Data - > HostIpAddressFormat ) ) {
return EFI_UNSUPPORTED ;
}
2021-03-24 08:35:54 +01:00
//
2023-03-27 16:28:58 +02:00
// 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.
2021-03-24 08:35:54 +01:00
// Those two types of Redfish host interface device has MAC information.
//
if ( DeviceDescriptor - > DeviceType = = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2 ) {
2023-03-27 16:28:58 +02:00
MacCompareStatus = CompareMem ( & Instance - > NetworkInterface - > MacAddress , & DeviceDescriptor - > DeviceDescriptor . PciPcieDeviceV2 . MacAddress , 6 ) ;
2021-03-24 08:35:54 +01:00
} else if ( DeviceDescriptor - > DeviceType = = REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 ) {
2023-03-27 16:28:58 +02:00
MacCompareStatus = CompareMem ( & Instance - > NetworkInterface - > MacAddress , & DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress , 6 ) ;
2021-03-24 08:35:54 +01:00
} else {
return EFI_UNSUPPORTED ;
}
2021-12-05 23:54:11 +01:00
2023-03-27 16:28:58 +02:00
if ( MacCompareStatus ! = 0 ) {
2023-11-23 11:25:08 +01:00
DEBUG ( ( DEBUG_ERROR , " %a: MAC address is not matched. \n " , __func__ ) ) ;
DEBUG ( (
DEBUG_ERROR ,
" NetworkInterface: %02x %02x %02x %02x %02x %02x. \n " ,
Instance - > NetworkInterface - > MacAddress . Addr [ 0 ] ,
Instance - > NetworkInterface - > MacAddress . Addr [ 1 ] ,
Instance - > NetworkInterface - > MacAddress . Addr [ 2 ] ,
Instance - > NetworkInterface - > MacAddress . Addr [ 3 ] ,
Instance - > NetworkInterface - > MacAddress . Addr [ 4 ] ,
Instance - > NetworkInterface - > MacAddress . Addr [ 5 ]
) ) ;
DEBUG ( (
DEBUG_ERROR ,
" Redfish Host interface: %02x %02x %02x %02x %02x %02x. \n " ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 0 ] ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 1 ] ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 2 ] ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 3 ] ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 4 ] ,
DeviceDescriptor - > DeviceDescriptor . UsbDeviceV2 . MacAddress [ 5 ]
) ) ;
2021-03-24 08:35:54 +01:00
return EFI_UNSUPPORTED ;
}
2023-03-27 16:28:58 +02:00
Instance - > HostAddrFormat = Data - > HostIpAddressFormat ;
if ( Data - > HostIpAddressFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4 ) {
IP4_COPY_ADDRESS ( ( VOID * ) & Instance - > HostIpAddress . v4 , ( VOID * ) Data - > HostIpAddress ) ;
IP4_COPY_ADDRESS ( ( VOID * ) & Instance - > HostSubnetMask . v4 , ( VOID * ) Data - > HostIpMask ) ;
if ( EFI_IP4_EQUAL ( & Instance - > HostIpAddress . v4 , & mZeroIp4Addr ) ) {
2023-07-24 15:03:04 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: invalid host IP address: " , __func__ ) ) ;
DumpIpv4Address ( DEBUG_ERROR , & Instance - > HostIpAddress . v4 ) ;
2023-03-27 16:28:58 +02:00
//
// Invalid IP address detected. Change address format to Unknown and use system default address.
//
Instance - > HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN ;
}
2023-07-24 15:03:04 +02:00
if ( ! IP4_IS_VALID_NETMASK ( NTOHL ( EFI_IP4 ( Instance - > HostSubnetMask . v4 ) ) ) ) {
DEBUG ( ( DEBUG_ERROR , " %a: invalid subnet mask address: " , __func__ ) ) ;
DumpIpv4Address ( DEBUG_ERROR , & Instance - > HostSubnetMask . v4 ) ;
2023-03-27 16:28:58 +02:00
//
// Invalid subnet mast address detected. Change address format to Unknown and use system default address.
//
Instance - > HostAddrFormat = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN ;
}
} else if ( Data - > HostIpAddressFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6 ) {
IP6_COPY_ADDRESS ( ( VOID * ) & Instance - > HostIpAddress . v6 , ( VOID * ) Data - > HostIpAddress ) ;
}
if ( Data - > RedfishServiceIpAddressFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4 ) {
2021-03-24 08:35:54 +01:00
IP4_COPY_ADDRESS ( ( VOID * ) & Instance - > TargetIpAddress . v4 , ( VOID * ) Data - > RedfishServiceIpAddress ) ;
2023-03-27 16:28:58 +02:00
if ( EFI_IP4_EQUAL ( & Instance - > TargetIpAddress . v4 , & mZeroIp4Addr ) ) {
2023-07-24 15:03:04 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: invalid service IP address: " , __func__ ) ) ;
DumpIpv4Address ( DEBUG_ERROR , & Instance - > TargetIpAddress . v4 ) ;
2023-03-27 16:28:58 +02:00
}
2021-03-24 08:35:54 +01:00
} else {
IP6_COPY_ADDRESS ( ( VOID * ) & Instance - > TargetIpAddress . v6 , ( VOID * ) Data - > RedfishServiceIpAddress ) ;
}
if ( Instance - > HostIntfValidation ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
Status = EFI_UNSUPPORTED ;
} else {
//
2023-03-27 16:28:58 +02:00
// Add this instance to list without detail information of Redfish
2021-03-24 08:35:54 +01:00
// service.
//
IsHttps = FALSE ;
if ( Data - > RedfishServiceIpPort = = 443 ) {
IsHttps = TRUE ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
StrSize = sizeof ( UuidStr ) ;
AsciiSPrint ( UuidStr , StrSize , " %g " , & Data - > ServiceUuid ) ;
//
// Generate Redfish service location string.
//
if ( Data - > RedfishServiceIpAddressFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6 ) {
NetLibIp6ToStr ( ( IPv6_ADDRESS * ) & Data - > RedfishServiceIpAddress , Ipv6Str , sizeof ( Ipv6Str ) ) ;
if ( ( Data - > RedfishServiceIpPort = = 0 ) | | ( IsHttps = = TRUE ) ) {
AsciiSPrintUnicodeFormat (
RedfishServiceLocateStr ,
sizeof ( RedfishServiceLocateStr ) ,
L " %s " ,
Ipv6Str
) ;
} else {
AsciiSPrintUnicodeFormat (
RedfishServiceLocateStr ,
sizeof ( RedfishServiceLocateStr ) ,
L " [%s]:%d " ,
Ipv6Str ,
Data - > RedfishServiceIpPort
) ;
}
} else {
if ( ( Data - > RedfishServiceIpPort = = 0 ) | | ( IsHttps = = TRUE ) ) {
AsciiSPrint (
RedfishServiceLocateStr ,
sizeof ( RedfishServiceLocateStr ) ,
" %d.%d.%d.%d " ,
Data - > RedfishServiceIpAddress [ 0 ] ,
Data - > RedfishServiceIpAddress [ 1 ] ,
Data - > RedfishServiceIpAddress [ 2 ] ,
Data - > RedfishServiceIpAddress [ 3 ]
) ;
} else {
AsciiSPrint (
RedfishServiceLocateStr ,
sizeof ( RedfishServiceLocateStr ) ,
" %d.%d.%d.%d:%d " ,
Data - > RedfishServiceIpAddress [ 0 ] ,
Data - > RedfishServiceIpAddress [ 1 ] ,
Data - > RedfishServiceIpAddress [ 2 ] ,
Data - > RedfishServiceIpAddress [ 3 ] ,
Data - > RedfishServiceIpPort
) ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = AddAndSignalNewRedfishService (
Instance ,
NULL ,
RedfishServiceLocateStr ,
UuidStr ,
NULL ,
NULL ,
NULL ,
NULL ,
IsHttps
) ;
}
2023-11-23 11:25:08 +01:00
} else {
DEBUG ( ( DEBUG_ERROR , " %a: RedfishGetHostInterfaceProtocolData is failed. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Status ;
}
/**
The function adds a new found Redfish service to internal list and
notify client .
@ param [ in ] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE .
@ param [ in ] RedfishVersion Redfish version .
@ param [ in ] RedfishLocation Redfish location .
@ param [ in ] Uuid Service UUID string .
@ param [ in ] Os OS string .
@ param [ in ] OsVer OS version string .
@ param [ in ] Product Product string .
2023-03-27 16:28:58 +02:00
@ param [ in ] ProductVer Product version string .
2021-03-24 08:35:54 +01:00
@ param [ in ] UseHttps Redfish service requires secured connection .
@ retval EFI_SUCCESS Redfish service is added to list successfully .
* */
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
)
{
BOOLEAN NewFound ;
BOOLEAN InfoRefresh ;
BOOLEAN RestExOpened ;
BOOLEAN DeleteRestEx ;
EFI_STATUS Status ;
EFI_REDFISH_DISCOVERED_INTERNAL_LIST * DiscoveredList ;
EFI_REDFISH_DISCOVERED_INSTANCE * DiscoveredInstance ;
CHAR16 * Char16Uuid ;
EFI_REST_EX_PROTOCOL * RestEx ;
EFI_REST_EX_HTTP_CONFIG_DATA * RestExHttpConfigData ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * NetworkInterface ;
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
NewFound = TRUE ;
InfoRefresh = FALSE ;
Char16Uuid = NULL ;
RestExOpened = FALSE ;
DeleteRestEx = FALSE ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:Add this instance to Redfish instance list. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
if ( Uuid ! = NULL ) {
Char16Uuid = ( CHAR16 * ) AllocateZeroPool ( AsciiStrSize ( ( const CHAR8 * ) Uuid ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) Uuid , Char16Uuid , AsciiStrSize ( ( const CHAR8 * ) Uuid ) * sizeof ( CHAR16 ) ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
DiscoveredList = NULL ;
DiscoveredInstance = NULL ;
RestExHttpConfigData = NULL ;
NetworkInterface = Instance - > NetworkInterface ;
if ( ! IsListEmpty ( & mRedfishInstanceList ) ) {
//
// Is this a duplicate redfish service.
//
DiscoveredList = ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST * ) GetFirstNode ( & mRedfishInstanceList ) ;
NewFound = FALSE ;
do {
if ( ( Char16Uuid = = NULL ) | | ( DiscoveredList - > Instance - > Information . Uuid = = NULL ) ) {
//
2023-03-27 16:28:58 +02:00
// Check if this Redfish instance already found using IP address.
2021-03-24 08:35:54 +01:00
//
if ( ! CheckIsIpVersion6 ( NetworkInterface ) ) {
if ( CompareMem (
( VOID * ) & Instance - > TargetIpAddress . v4 ,
( VOID * ) & DiscoveredList - > Instance - > Information . RedfishHostIpAddress . v4 ,
sizeof ( EFI_IPv4_ADDRESS )
) = = 0 )
{
DiscoveredInstance = DiscoveredList - > Instance ;
if ( ( DiscoveredList - > Instance - > Information . Uuid = = NULL ) & &
( Char16Uuid ! = NULL ) )
{
InfoRefresh = TRUE ;
DiscoveredInstance = DiscoveredList - > Instance ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " *** This Redfish Service information refresh *** \n " ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
break ;
}
} else {
if ( CompareMem (
( VOID * ) & Instance - > TargetIpAddress . v6 ,
( VOID * ) & DiscoveredList - > Instance - > Information . RedfishHostIpAddress . v6 ,
sizeof ( EFI_IPv6_ADDRESS )
) = = 0 )
{
DiscoveredInstance = DiscoveredList - > Instance ;
break ;
}
}
} else {
//
// Check if this Redfish instance already found using UUID.
//
if ( StrCmp ( ( const CHAR16 * ) Char16Uuid , ( const CHAR16 * ) DiscoveredList - > Instance - > Information . Uuid ) = = 0 ) {
DiscoveredInstance = DiscoveredList - > Instance ;
break ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mRedfishInstanceList , & DiscoveredList - > NextInstance ) ) {
NewFound = TRUE ;
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
DiscoveredList = ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST * ) GetNextNode ( & mRedfishInstanceList , & DiscoveredList - > NextInstance ) ;
} while ( TRUE ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( NewFound | | InfoRefresh ) {
if ( ! InfoRefresh ) {
DiscoveredList = ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST ) ) ;
if ( DiscoveredList = = NULL ) {
return EFI_OUT_OF_RESOURCES ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
InitializeListHead ( & DiscoveredList - > NextInstance ) ;
DiscoveredInstance = ( EFI_REDFISH_DISCOVERED_INSTANCE * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVERED_INSTANCE ) ) ;
if ( DiscoveredInstance = = NULL ) {
FreePool ( ( VOID * ) DiscoveredList ) ;
return EFI_OUT_OF_RESOURCES ;
}
}
2021-12-05 23:54:11 +01:00
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " *** Redfish Service Information *** \n " ) ) ;
2021-03-24 08:35:54 +01:00
DiscoveredInstance - > Information . UseHttps = UseHttps ;
if ( RedfishVersion ! = NULL ) {
DiscoveredInstance - > Information . RedfishVersion = * RedfishVersion ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Redfish service version: %d. \n " , DiscoveredInstance - > Information . RedfishVersion ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( RedfishLocation ! = NULL ) {
DiscoveredInstance - > Information . Location = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) RedfishLocation ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) RedfishLocation , DiscoveredInstance - > Information . Location , AsciiStrSize ( ( const CHAR8 * ) RedfishLocation ) * sizeof ( CHAR16 ) ) ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Redfish service location: %s. \n " , DiscoveredInstance - > Information . Location ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( Uuid ! = NULL ) {
DiscoveredInstance - > Information . Uuid = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) Uuid ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) Uuid , DiscoveredInstance - > Information . Uuid , AsciiStrSize ( ( const CHAR8 * ) Uuid ) * sizeof ( CHAR16 ) ) ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Service UUID: %s. \n " , DiscoveredInstance - > Information . Uuid ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( Os ! = NULL ) {
DiscoveredInstance - > Information . Os = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) Os ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) Os , DiscoveredInstance - > Information . Os , AsciiStrSize ( ( const CHAR8 * ) Os ) * sizeof ( CHAR16 ) ) ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Redfish service OS: %s, Version:%s. \n " , DiscoveredInstance - > Information . Os , DiscoveredInstance - > Information . OsVersion ) ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( OsVer ! = NULL ) {
DiscoveredInstance - > Information . OsVersion = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) OsVer ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) OsVer , DiscoveredInstance - > Information . OsVersion , AsciiStrSize ( ( const CHAR8 * ) OsVer ) * sizeof ( CHAR16 ) ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ( Product ! = NULL ) & & ( ProductVer ! = NULL ) ) {
DiscoveredInstance - > Information . Product = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) Product ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) Product , DiscoveredInstance - > Information . Product , AsciiStrSize ( ( const CHAR8 * ) Product ) * sizeof ( CHAR16 ) ) ;
DiscoveredInstance - > Information . ProductVer = ( CHAR16 * ) AllocatePool ( AsciiStrSize ( ( const CHAR8 * ) ProductVer ) * sizeof ( CHAR16 ) ) ;
AsciiStrToUnicodeStrS ( ( const CHAR8 * ) ProductVer , DiscoveredInstance - > Information . ProductVer , AsciiStrSize ( ( const CHAR8 * ) ProductVer ) * sizeof ( CHAR16 ) ) ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Redfish service product: %s, Version:%s. \n " , DiscoveredInstance - > Information . Product , DiscoveredInstance - > Information . ProductVer ) ) ;
2021-03-24 08:35:54 +01:00
}
if ( RedfishLocation = = NULL ) {
// This is the Redfish reported from SMBIOS 42h
// without validation.
IP4_COPY_ADDRESS ( ( VOID * ) & DiscoveredInstance - > Information . RedfishHostIpAddress . v4 , ( VOID * ) & Instance - > TargetIpAddress . v4 ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ! InfoRefresh ) {
DiscoveredList - > Instance = DiscoveredInstance ;
InsertTailList ( & mRedfishInstanceList , & DiscoveredList - > NextInstance ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
DiscoveredInstance - > Status = EFI_SUCCESS ;
} else {
if ( DiscoveredList ! = NULL ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " *** This Redfish Service was already found *** \n " ) ) ;
2021-03-24 08:35:54 +01:00
if ( DiscoveredInstance - > Information . Uuid ! = NULL ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Service UUID: %s. \n " , DiscoveredInstance - > Information . Uuid ) ) ;
2021-03-24 08:35:54 +01:00
} else {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " Service UUID: unknown. \n " ) ) ;
2021-03-24 08:35:54 +01:00
}
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( Char16Uuid ! = NULL ) {
FreePool ( ( VOID * ) Char16Uuid ) ;
}
Status = EFI_SUCCESS ;
if ( NewFound | | InfoRefresh ) {
//
// Build up EFI_REDFISH_DISCOVERED_LIST in token.
//
Instance - > DiscoverToken - > DiscoverList . NumberOfServiceFound = 1 ;
Instance - > DiscoverToken - > DiscoverList . RedfishInstances = DiscoveredInstance ;
DiscoveredInstance - > Status = EFI_SUCCESS ;
if ( ! InfoRefresh ) {
Status = CreateRestExInstance ( Instance , Instance - > DiscoverToken ) ; // Create REST EX child.
if ( EFI_ERROR ( Status ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Can't create REST EX child instance. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
goto ON_EXIT ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = gBS - > OpenProtocol (
// Configure local host information.
Instance - > DiscoverToken - > DiscoverList . RedfishInstances - > Information . RedfishRestExHandle ,
& gEfiRestExProtocolGuid ,
( VOID * * ) & RestEx ,
Instance - > NetworkInterface - > OpenDriverAgentHandle ,
Instance - > NetworkInterface - > OpenDriverControllerHandle ,
EFI_OPEN_PROTOCOL_BY_DRIVER
) ;
if ( EFI_ERROR ( Status ) ) {
DeleteRestEx = TRUE ;
goto ERROR_EXIT ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
RestExOpened = TRUE ;
RestExHttpConfigData = AllocateZeroPool ( sizeof ( EFI_REST_EX_HTTP_CONFIG_DATA ) ) ;
if ( RestExHttpConfigData = = NULL ) {
Status = EFI_OUT_OF_RESOURCES ;
DeleteRestEx = TRUE ;
goto EXIT_FREE_CONFIG_DATA ;
}
2021-12-05 23:54:11 +01:00
2023-10-18 13:59:20 +02:00
RestExHttpConfigData - > SendReceiveTimeout = PcdGet32 ( PcdRedfishSendReceiveTimeout ) ;
2021-03-24 08:35:54 +01:00
RestExHttpConfigData - > HttpConfigData . HttpVersion = HttpVersion11 ;
RestExHttpConfigData - > HttpConfigData . LocalAddressIsIPv6 = CheckIsIpVersion6 ( NetworkInterface ) ;
if ( RestExHttpConfigData - > HttpConfigData . LocalAddressIsIPv6 ) {
RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv6Node = AllocateZeroPool ( sizeof ( EFI_HTTPv6_ACCESS_POINT ) ) ;
if ( RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv6Node = = NULL ) {
Status = EFI_OUT_OF_RESOURCES ;
goto EXIT_FREE_CONFIG_DATA ;
}
2023-03-27 16:28:58 +02:00
if ( Instance - > HostAddrFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6 ) {
IP6_COPY_ADDRESS ( & RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv6Node - > LocalAddress , & Instance - > HostIpAddress . v6 ) ;
}
2021-03-24 08:35:54 +01:00
} else {
RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node = AllocateZeroPool ( sizeof ( EFI_HTTPv4_ACCESS_POINT ) ) ;
if ( RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node = = NULL ) {
Status = EFI_OUT_OF_RESOURCES ;
goto EXIT_FREE_CONFIG_DATA ;
}
2021-12-05 23:54:11 +01:00
2023-03-27 16:28:58 +02:00
if ( Instance - > HostAddrFormat = = REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4 ) {
RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node - > UseDefaultAddress = FALSE ;
IP4_COPY_ADDRESS ( & RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node - > LocalAddress , & Instance - > HostIpAddress . v4 ) ;
IP4_COPY_ADDRESS ( & RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node - > LocalSubnet , & Instance - > HostSubnetMask . v4 ) ;
} else {
RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node - > UseDefaultAddress = TRUE ;
}
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = RestEx - > Configure (
RestEx ,
( EFI_REST_EX_CONFIG_DATA ) ( UINT8 * ) RestExHttpConfigData
) ;
if ( EFI_ERROR ( Status ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:REST EX configured.. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
DeleteRestEx = TRUE ;
goto EXIT_FREE_ALL ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
//
// Signal client, close REST EX before signaling client.
//
if ( RestExOpened ) {
gBS - > CloseProtocol (
Instance - > DiscoverToken - > DiscoverList . RedfishInstances - > Information . RedfishRestExHandle ,
& gEfiRestExProtocolGuid ,
Instance - > NetworkInterface - > OpenDriverAgentHandle ,
Instance - > NetworkInterface - > OpenDriverControllerHandle
) ;
RestExOpened = FALSE ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = gBS - > SignalEvent ( Instance - > DiscoverToken - > Event ) ;
2021-06-30 03:41:21 +02:00
if ( EFI_ERROR ( Status ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:No event to signal! \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
}
}
EXIT_FREE_ALL : ;
if ( ( RestExHttpConfigData ! = NULL ) & & ( RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node ! = NULL ) ) {
FreePool ( RestExHttpConfigData - > HttpConfigData . AccessPoint . IPv4Node ) ;
}
EXIT_FREE_CONFIG_DATA : ;
if ( RestExHttpConfigData ! = NULL ) {
FreePool ( ( VOID * ) RestExHttpConfigData ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( RestExOpened ) {
gBS - > CloseProtocol (
Instance - > DiscoverToken - > DiscoverList . RedfishInstances - > Information . RedfishRestExHandle ,
& gEfiRestExProtocolGuid ,
Instance - > NetworkInterface - > OpenDriverAgentHandle ,
Instance - > NetworkInterface - > OpenDriverControllerHandle
) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ERROR_EXIT : ;
if ( DeleteRestEx & & RestExOpened ) {
gBS - > CloseProtocol (
Instance - > DiscoverToken - > DiscoverList . RedfishInstances - > Information . RedfishRestExHandle ,
& gEfiRestExProtocolGuid ,
Instance - > NetworkInterface - > OpenDriverAgentHandle ,
Instance - > NetworkInterface - > OpenDriverControllerHandle
) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ON_EXIT : ;
return Status ;
}
/**
This function gets the subnet information of this network interface instance .
can discover Redfish service on it .
@ param [ in ] Instance EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance .
@ param [ in ] ImageHandle EFI Image handle request the network interface list .
@ retval EFI_SUCCESS
* */
EFI_STATUS
NetworkInterfaceGetSubnetInfo (
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * Instance ,
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status ;
UINT32 ProtocolType ;
UINT32 IPv6InfoIndex ;
EFI_IP6_ADDRESS_INFO * ThisSubnetAddrInfoIPv6 ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * NewNetworkInterface ;
if ( Instance - > GotSubnetInfo ) {
return EFI_SUCCESS ;
}
ProtocolType = Instance - > NetworkProtocolType ;
2023-11-15 03:55:35 +01:00
if ( ( mRequiredProtocol [ ProtocolType ] . GetSubnetInfo ! = NULL ) & & ( Instance - > GotSubnetInfo = = FALSE ) ) {
Status = mRequiredProtocol [ ProtocolType ] . GetSubnetInfo (
2021-03-24 08:35:54 +01:00
ImageHandle ,
Instance
) ;
if ( EFI_ERROR ( Status ) ) {
2023-10-23 14:40:42 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Failed to get Subnet information. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return Status ;
} else {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:MAC address: %s \n " , __func__ , Instance - > StrMacAddr ) ) ;
2021-03-24 08:35:54 +01:00
if ( CheckIsIpVersion6 ( Instance ) ) {
if ( Instance - > SubnetAddrInfoIPv6Number = = 0 ) {
2023-10-23 14:40:42 +02:00
DEBUG ( ( DEBUG_WARN , " %a: There is no Subnet information for IPv6 network interface. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_NOT_FOUND ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisSubnetAddrInfoIPv6 = Instance - > SubnetAddrInfoIPv6 ; // First IPv6 address information.
IP6_COPY_ADDRESS ( & Instance - > SubnetAddr . v6 , & ThisSubnetAddrInfoIPv6 - > Address ) ;
Instance - > SubnetPrefixLength = ThisSubnetAddrInfoIPv6 - > PrefixLength ;
DEBUG ( (
2023-05-30 09:06:13 +02:00
DEBUG_MANAGEABILITY ,
2021-03-24 08:35:54 +01:00
" IPv6 Subnet ID:%d, Prefix length: %d. \n " ,
ThisSubnetAddrInfoIPv6 - > Address . Addr [ 7 ] + ( UINT16 ) ThisSubnetAddrInfoIPv6 - > Address . Addr [ 6 ] * 256 ,
ThisSubnetAddrInfoIPv6 - > PrefixLength
)
) ;
//
// If this is IPv6, then we may have to propagate network interface for IPv6 network scopes
// according to the Ipv6 address information.
//
ThisSubnetAddrInfoIPv6 + + ;
for ( IPv6InfoIndex = 0 ; IPv6InfoIndex < Instance - > SubnetAddrInfoIPv6Number - 1 ; IPv6InfoIndex + + ) {
//
2023-03-27 16:28:58 +02:00
// Build up additional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.
2021-03-24 08:35:54 +01:00
//
NewNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL ) ) ;
if ( NewNetworkInterface ! = NULL ) {
CopyMem ( ( VOID * ) NewNetworkInterface , ( VOID * ) Instance , sizeof ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL ) ) ; // Clone information of first instance.
IP6_COPY_ADDRESS ( & NewNetworkInterface - > SubnetAddr . v6 , & ThisSubnetAddrInfoIPv6 - > Address ) ;
NewNetworkInterface - > SubnetPrefixLength = ThisSubnetAddrInfoIPv6 - > PrefixLength ;
NewNetworkInterface - > GotSubnetInfo = TRUE ;
InsertTailList ( & mEfiRedfishDiscoverNetworkInterface , & NewNetworkInterface - > Entry ) ;
ThisSubnetAddrInfoIPv6 + + ;
mNumNetworkInterface + + ;
DEBUG ( (
2023-05-30 09:06:13 +02:00
DEBUG_MANAGEABILITY ,
2021-03-24 08:35:54 +01:00
" IPv6 Subnet ID:%d, Prefix length: %d. \n " ,
ThisSubnetAddrInfoIPv6 - > Address . Addr [ 7 ] + ( UINT16 ) ThisSubnetAddrInfoIPv6 - > Address . Addr [ 6 ] * 256 ,
ThisSubnetAddrInfoIPv6 - > PrefixLength
)
) ;
} else {
return EFI_OUT_OF_RESOURCES ;
}
}
} else {
DEBUG ( (
2023-05-30 09:06:13 +02:00
DEBUG_MANAGEABILITY ,
2021-03-24 08:35:54 +01:00
" IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d. \n " ,
Instance - > SubnetAddr . v4 . Addr [ 0 ] ,
Instance - > SubnetAddr . v4 . Addr [ 1 ] ,
Instance - > SubnetAddr . v4 . Addr [ 2 ] ,
Instance - > SubnetAddr . v4 . Addr [ 3 ] ,
Instance - > SubnetMask . v4 . Addr [ 0 ] ,
Instance - > SubnetMask . v4 . Addr [ 1 ] ,
Instance - > SubnetMask . v4 . Addr [ 2 ] ,
Instance - > SubnetMask . v4 . Addr [ 3 ]
) ) ;
}
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Instance - > GotSubnetInfo = TRUE ; // Only try to get Subnet Info once.
return EFI_SUCCESS ;
}
/**
This function gets the network interface list which Redfish discover protocol
can discover Redfish service on it .
@ param [ in ] This EFI_REDFISH_DISCOVER_PROTOCOL instance .
@ param [ in ] ImageHandle EFI Image handle request the network interface list ,
@ param [ out ] NumberOfNetworkIntfs Number of network interfaces can do Redfish service discovery .
@ param [ out ] NetworkIntfInstances Network interface instances . It ' s an array of instance . The number of entries
in array is indicated by NumberOfNetworkIntfs .
Caller has to release the memory
allocated by Redfish discover protocol .
@ retval EFI_SUCCESS The information of network interface is returned in NumberOfNetworkIntfs and
NetworkIntfInstances .
@ retval Others Fail to return the information of network interface .
* */
EFI_STATUS
EFIAPI
RedfishServiceGetNetworkInterface (
IN EFI_REDFISH_DISCOVER_PROTOCOL * This ,
IN EFI_HANDLE ImageHandle ,
OUT UINTN * NumberOfNetworkIntfs ,
OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * * NetworkIntfInstances
)
{
2023-11-15 03:55:35 +01:00
EFI_STATUS Status ;
2021-03-24 08:35:54 +01:00
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterfaceIntn ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * ThisNetworkInterface ;
2023-04-20 20:36:38 +02:00
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * RestExInstance ;
2021-03-24 08:35:54 +01:00
2023-04-20 20:36:38 +02:00
if ( ( This = = NULL ) | | ( NetworkIntfInstances = = NULL ) | | ( NumberOfNetworkIntfs = = NULL ) | |
( ImageHandle = = NULL ) )
{
2021-03-24 08:35:54 +01:00
return EFI_INVALID_PARAMETER ;
}
* NumberOfNetworkIntfs = 0 ;
* NetworkIntfInstances = NULL ;
if ( IsListEmpty ( ( const LIST_ENTRY * ) & mEfiRedfishDiscoverNetworkInterface ) ) {
return EFI_NOT_FOUND ;
}
2023-04-20 20:36:38 +02:00
RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL ( This ) ;
//
// Check the new found network interface.
//
if ( RestExInstance - > NetworkInterfaceInstances ! = NULL ) {
FreePool ( RestExInstance - > NetworkInterfaceInstances ) ;
RestExInstance - > NetworkInterfaceInstances = NULL ;
}
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE ) * mNumNetworkInterface ) ;
if ( ThisNetworkInterface = = NULL ) {
return EFI_OUT_OF_RESOURCES ;
}
2021-12-05 23:54:11 +01:00
2023-04-20 20:36:38 +02:00
* NetworkIntfInstances = ThisNetworkInterface ;
RestExInstance - > NetworkInterfaceInstances = ThisNetworkInterface ;
RestExInstance - > NumberOfNetworkInterfaces = 0 ;
2021-03-24 08:35:54 +01:00
ThisNetworkInterfaceIntn = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
2023-11-15 03:55:35 +01:00
// 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 ;
}
2021-03-24 08:35:54 +01:00
ThisNetworkInterface - > IsIpv6 = FALSE ;
if ( CheckIsIpVersion6 ( ThisNetworkInterfaceIntn ) ) {
ThisNetworkInterface - > IsIpv6 = TRUE ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
CopyMem ( ( VOID * ) & ThisNetworkInterface - > MacAddress , & ThisNetworkInterfaceIntn - > MacAddress , ThisNetworkInterfaceIntn - > HwAddressSize ) ;
if ( ! ThisNetworkInterface - > IsIpv6 ) {
IP4_COPY_ADDRESS ( & ThisNetworkInterface - > SubnetId . v4 , & ThisNetworkInterfaceIntn - > SubnetAddr . v4 ) ; // IPv4 subnet information.
} else {
IP6_COPY_ADDRESS ( & ThisNetworkInterface - > SubnetId . v6 , & ThisNetworkInterfaceIntn - > SubnetAddr . v6 ) ; // IPv6 subnet information in IPv6 address information.
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface - > SubnetPrefixLength = ThisNetworkInterfaceIntn - > SubnetPrefixLength ;
ThisNetworkInterface - > VlanId = ThisNetworkInterfaceIntn - > VlanId ;
2023-04-20 20:36:38 +02:00
RestExInstance - > NumberOfNetworkInterfaces + + ;
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterfaceIntn - > Entry ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterfaceIntn = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterfaceIntn - > Entry ) ;
ThisNetworkInterface + + ;
}
2021-12-05 23:54:11 +01:00
2023-04-20 20:36:38 +02:00
* NumberOfNetworkIntfs = RestExInstance - > NumberOfNetworkInterfaces ;
2021-03-24 08:35:54 +01:00
return EFI_SUCCESS ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
/**
This function acquires Redfish services by discovering static Redfish setting
according to Redfish Host Interface or through SSDP . Returns a list of EFI
2023-03-27 16:28:58 +02:00
handles in EFI_REDFISH_DISCOVERED_LIST . Each of EFI handle has corresponding
EFI REST EX instance installed on it . Each REST EX instance is a child instance which
created through EFI REST EX service protocol for communicating with specific
2021-03-24 08:35:54 +01:00
Redfish service .
@ param [ in ] This EFI_REDFISH_DISCOVER_PROTOCOL instance .
@ param [ in ] ImageHandle EFI image owns these Redfish service instances .
@ param [ in ] TargetNetworkInterface Target network interface to do the discovery .
NULL means discover Redfish service on all network interfaces on platform .
@ param [ in ] Flags Redfish service discover flags .
@ param [ in ] Token EFI_REDFISH_DISCOVERED_TOKEN instance .
The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in
EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire ( )
and must be freed when caller invoke Release ( ) .
@ retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned .
@ retval EFI_INVALID_PARAMETERS ImageHandle = = NULL , Flags = = 0 , Token = = NULL , Token - > Timeout > 5 ,
or Token - > Event = = NULL .
@ retval Others Fail acquire Redfish services .
* */
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_DISCOVERED_INTERNAL_INSTANCE * Instance ;
EFI_STATUS Status1 ;
BOOLEAN NewInstance ;
UINTN NumNetworkInterfaces ;
UINTN NetworkInterfacesIndex ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * TargetNetworkInterfaceInternal ;
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:Entry. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
//
// Validate parameters.
//
if ( ( ImageHandle = = NULL ) | | ( Token = = NULL ) | | ( ( Flags & ~ EFI_REDFISH_DISCOVER_VALIDATION ) = = 0 ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Invalid parameters. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_INVALID_PARAMETER ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
//
// Validate target network interface.
//
if ( EFI_ERROR ( ValidateTargetNetworkInterface ( TargetNetworkInterface , Flags ) ) ) {
return EFI_UNSUPPORTED ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( TargetNetworkInterface ! = NULL ) {
TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal ( TargetNetworkInterface ) ;
2023-11-15 03:55:35 +01:00
if ( TargetNetworkInterfaceInternal = = NULL ) {
DEBUG ( ( DEBUG_ERROR , " %a:No network interface on platform. \n " , __func__ ) ) ;
return EFI_UNSUPPORTED ;
}
NumNetworkInterfaces = 1 ;
2021-03-24 08:35:54 +01:00
} else {
TargetNetworkInterfaceInternal = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
NumNetworkInterfaces = NumberOfNetworkInterface ( ) ;
if ( NumNetworkInterfaces = = 0 ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:No network interface on platform. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_UNSUPPORTED ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
for ( NetworkInterfacesIndex = 0 ; NetworkInterfacesIndex < NumNetworkInterfaces ; NetworkInterfacesIndex + + ) {
Status1 = EFI_SUCCESS ;
NewInstance = FALSE ;
Instance = GetInstanceByOwner ( ImageHandle , TargetNetworkInterfaceInternal , Flags & ~ EFI_REDFISH_DISCOVER_VALIDATION ) ; // Check if we can re-use previous instance.
if ( Instance = = NULL ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
Instance = ( EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE ) ) ;
if ( Instance = = NULL ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Memory allocation fail. \n " , __func__ ) ) ;
2023-04-20 20:36:38 +02:00
return EFI_OUT_OF_RESOURCES ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
InitializeListHead ( & Instance - > Entry ) ;
Instance - > Owner = ImageHandle ;
Instance - > DiscoverFlags = Flags & ~ EFI_REDFISH_DISCOVER_VALIDATION ;
Instance - > NetworkInterface = TargetNetworkInterfaceInternal ;
//
// Get subnet information in case subnet information is not set because
// RedfishServiceGetNetworkInterfaces hasn't been called yet.
//
2023-11-15 03:55:35 +01:00
Status1 = NetworkInterfaceGetSubnetInfo ( TargetNetworkInterfaceInternal , ImageHandle ) ;
if ( EFI_ERROR ( Status1 ) ) {
DEBUG ( ( DEBUG_ERROR , " %a: Get subnet information fail. \n " , __func__ ) ) ;
FreePool ( Instance ) ;
continue ;
}
2021-03-24 08:35:54 +01:00
NewInstance = TRUE ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( TargetNetworkInterfaceInternal - > StrMacAddr ! = NULL ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:Acquire Redfish service on network interface MAC address:%s. \n " , __func__ , TargetNetworkInterfaceInternal - > StrMacAddr ) ) ;
2021-03-24 08:35:54 +01:00
} else {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:WARNING: No MAC address on this network interface. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
}
Instance - > DiscoverToken = Token ; // Always use the latest Token passed by caller.
if ( ( Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE ) ! = 0 ) {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a:Redfish HOST interface discovery. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
Instance - > HostIntfValidation = FALSE ;
if ( ( Flags & EFI_REDFISH_DISCOVER_VALIDATION ) ! = 0 ) {
Instance - > HostIntfValidation = TRUE ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status1 = DiscoverRedfishHostInterface ( Instance ) ; // Discover Redfish service through Redfish Host Interface.
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ( Flags & EFI_REDFISH_DISCOVER_SSDP ) ! = 0 ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:Redfish service discovery through SSDP is not supported \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_UNSUPPORTED ;
} else {
2023-04-20 20:36:38 +02:00
if ( EFI_ERROR ( Status1 ) ) {
if ( NewInstance ) {
FreePool ( ( VOID * ) Instance ) ;
}
DEBUG ( ( DEBUG_ERROR , " %a:Something wrong on Redfish service discovery Status1=%r. \n " , __func__ , Status1 ) ) ;
2021-03-24 08:35:54 +01:00
} else {
if ( NewInstance ) {
InsertTailList ( & mRedfishDiscoverList , & Instance - > Entry ) ;
}
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( TargetNetworkInterface = = NULL ) {
//
// Discover Redfish services on all of network interfaces.
//
TargetNetworkInterfaceInternal = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & TargetNetworkInterfaceInternal - > Entry ) ;
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return EFI_SUCCESS ;
}
/**
This function aborts Redfish service discovery on the given network interface .
@ param [ in ] This EFI_REDFISH_DISCOVER_PROTOCOL instance .
@ param [ in ] TargetNetworkInterface Target network interface to do the discovery .
@ retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned .
@ retval Others Fail to abort Redfish service discovery .
* */
EFI_STATUS
EFIAPI
RedfishServiceAbortAcquire (
IN EFI_REDFISH_DISCOVER_PROTOCOL * This ,
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE * TargetNetworkInterface OPTIONAL
)
{
// This function is used to abort Redfish service discovery through SSDP
2023-03-27 16:28:58 +02:00
// on the network interface. SSDP is optionally suppoted by EFI_REDFISH_DISCOVER_PROTOCOL,
2021-03-24 08:35:54 +01:00
// we dont have implementation for SSDP now.
return EFI_UNSUPPORTED ;
}
/**
This function releases Redfish services found by RedfishServiceAcquire ( ) .
@ param [ in ] This EFI_REDFISH_DISCOVER_PROTOCOL instance .
@ param [ in ] InstanceList The Redfish service to release .
@ retval EFI_SUCCESS REST EX instances of discovered Redfish are released .
@ retval Others Fail to remove the entry
* */
EFI_STATUS
EFIAPI
RedfishServiceReleaseService (
IN EFI_REDFISH_DISCOVER_PROTOCOL * This ,
IN EFI_REDFISH_DISCOVERED_LIST * InstanceList
)
{
UINTN NumService ;
BOOLEAN AnyFailRelease ;
EFI_REDFISH_DISCOVERED_INSTANCE * ThisRedfishInstance ;
EFI_REDFISH_DISCOVERED_INTERNAL_LIST * DiscoveredRedfishInstance ;
if ( IsListEmpty ( & mRedfishInstanceList ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a:No any discovered Redfish service. \n " , __func__ ) ) ;
2021-03-24 08:35:54 +01:00
return EFI_NOT_FOUND ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
AnyFailRelease = FALSE ;
ThisRedfishInstance = InstanceList - > RedfishInstances ;
for ( NumService = 0 ; NumService < InstanceList - > NumberOfServiceFound ; NumService + + ) {
DiscoveredRedfishInstance = ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST * ) GetFirstNode ( & mRedfishInstanceList ) ;
do {
if ( DiscoveredRedfishInstance - > Instance = = ThisRedfishInstance ) {
RemoveEntryList ( & DiscoveredRedfishInstance - > NextInstance ) ;
if ( ThisRedfishInstance - > Information . Location ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . Location ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisRedfishInstance - > Information . Uuid ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . Uuid ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisRedfishInstance - > Information . Os ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . Os ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisRedfishInstance - > Information . OsVersion ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . OsVersion ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisRedfishInstance - > Information . Product ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . Product ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( ThisRedfishInstance - > Information . ProductVer ! = NULL ) {
FreePool ( ThisRedfishInstance - > Information . ProductVer ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
FreePool ( ( VOID * ) ThisRedfishInstance ) ;
goto ReleaseNext ;
}
if ( IsNodeAtEnd ( & mRedfishInstanceList , & DiscoveredRedfishInstance - > NextInstance ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
DiscoveredRedfishInstance = ( EFI_REDFISH_DISCOVERED_INTERNAL_LIST * ) GetNextNode ( & mRedfishInstanceList , & DiscoveredRedfishInstance - > NextInstance ) ;
} while ( TRUE ) ;
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
AnyFailRelease = TRUE ;
ReleaseNext : ;
//
// Release next discovered Redfish Service.
//
ThisRedfishInstance = ( EFI_REDFISH_DISCOVERED_INSTANCE * ) ( ( UINT8 * ) ThisRedfishInstance + sizeof ( EFI_REDFISH_DISCOVERED_INSTANCE ) ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( AnyFailRelease ) {
return EFI_NOT_FOUND ;
} else {
return EFI_SUCCESS ;
}
}
/**
This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the
given network interface .
@ param [ in ] ControllerHandle MAC address of this network interface .
@ param [ in ] NetworkProtocolType Network protocol type .
@ param [ out ] IsNewInstance BOOLEAN means new instance or not .
@ param [ out ] NetworkInterface Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL .
@ retval EFI_STATUS
* */
EFI_STATUS
CreateRedfishDiscoverNetworkInterface (
IN EFI_HANDLE ControllerHandle ,
IN UINT32 NetworkProtocolType ,
OUT BOOLEAN * IsNewInstance ,
OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * * NetworkInterface
)
{
EFI_MAC_ADDRESS MacAddress ;
UINTN HwAddressSize ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * NewNetworkInterface ;
NetLibGetMacAddress ( ControllerHandle , & MacAddress , & HwAddressSize ) ;
NewNetworkInterface = NULL ;
* IsNewInstance = TRUE ;
if ( ! IsListEmpty ( ( const LIST_ENTRY * ) & mEfiRedfishDiscoverNetworkInterface ) ) {
//
// Check if this instance already exist.
//
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
if ( ThisNetworkInterface ! = NULL ) {
while ( TRUE ) {
if ( ( CompareMem ( ( CONST VOID * ) & ThisNetworkInterface - > MacAddress . Addr , ( CONST VOID * ) & MacAddress . Addr , HwAddressSize ) = = 0 ) & &
( ThisNetworkInterface - > NetworkProtocolType = = NetworkProtocolType ) )
{
NewNetworkInterface = ThisNetworkInterface ;
* IsNewInstance = FALSE ;
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
NewNetworkInterface = NULL ;
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
}
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( NewNetworkInterface = = NULL ) {
//
// Create a new instance.
//
NewNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL ) ) ;
if ( NewNetworkInterface = = NULL ) {
return EFI_OUT_OF_RESOURCES ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
NewNetworkInterface - > HwAddressSize = HwAddressSize ;
CopyMem ( & NewNetworkInterface - > MacAddress . Addr , & MacAddress . Addr , NewNetworkInterface - > HwAddressSize ) ;
NetLibGetMacString ( ControllerHandle , NULL , & NewNetworkInterface - > StrMacAddr ) ;
NewNetworkInterface - > VlanId = NetLibGetVlanId ( ControllerHandle ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
* NetworkInterface = NewNetworkInterface ;
return EFI_SUCCESS ;
}
/**
2023-03-27 16:28:58 +02:00
This function destroy network interface
2021-03-24 08:35:54 +01:00
@ param [ in ] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance .
@ retval EFI_STATUS
* */
EFI_STATUS
2023-03-27 16:28:58 +02:00
DestroyRedfishNetworkInterface (
2021-03-24 08:35:54 +01:00
IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface
)
{
EFI_STATUS Status ;
Status = gBS - > UninstallProtocolInterface (
ThisNetworkInterface - > OpenDriverControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ ThisNetworkInterface - > NetworkProtocolType ] . DiscoveredProtocolGuid ,
2021-03-24 08:35:54 +01:00
& ThisNetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolDiscoverId
) ;
RemoveEntryList ( & ThisNetworkInterface - > Entry ) ;
mNumNetworkInterface - - ;
FreePool ( ThisNetworkInterface ) ;
return Status ;
}
/**
Tests to see if the required protocols are provided on the given
controller handle .
@ param [ in ] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to test . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ retval EFI_SUCCESS One of required protocol is found .
@ retval EFI_UNSUPPORTED None of required protocol is found .
* */
EFI_STATUS
TestForRequiredProtocols (
IN EFI_DRIVER_BINDING_PROTOCOL * This ,
IN EFI_HANDLE ControllerHandle
)
{
2023-03-27 16:28:58 +02:00
UINT32 * Id ;
2021-03-24 08:35:54 +01:00
UINTN Index ;
EFI_STATUS Status ;
2023-03-27 16:28:58 +02:00
UINTN ListCount ;
2021-03-24 08:35:54 +01:00
2023-11-15 03:55:35 +01:00
ListCount = ( sizeof ( mRequiredProtocol ) / sizeof ( REDFISH_DISCOVER_REQUIRED_PROTOCOL ) ) ;
2023-03-27 16:28:58 +02:00
for ( Index = 0 ; Index < ListCount ; Index + + ) {
2021-03-24 08:35:54 +01:00
Status = gBS - > OpenProtocol (
ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . RequiredServiceBindingProtocolGuid ,
2021-03-24 08:35:54 +01:00
NULL ,
This - > DriverBindingHandle ,
ControllerHandle ,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
) ;
2023-11-15 03:52:51 +01:00
if ( EFI_ERROR ( Status ) ) {
return EFI_UNSUPPORTED ;
}
Status = gBS - > OpenProtocol (
ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . DiscoveredProtocolGuid ,
2023-11-15 03:52:51 +01:00
( VOID * * ) & Id ,
This - > DriverBindingHandle ,
ControllerHandle ,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
) ;
2021-03-24 08:35:54 +01:00
if ( ! EFI_ERROR ( Status ) ) {
2023-11-15 03:52:51 +01:00
// Already installed
return EFI_UNSUPPORTED ;
2021-03-24 08:35:54 +01:00
}
}
2021-12-05 23:54:11 +01:00
2023-11-15 03:52:51 +01:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a: all required protocols are found on this controller handle: %p. \n " , __func__ , ControllerHandle ) ) ;
return EFI_SUCCESS ;
2021-03-24 08:35:54 +01:00
}
/**
Build up network interface and create corresponding service through the given
controller handle .
@ param [ in ] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to test . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ retval EFI_SUCCESS One of required protocol is found .
@ retval EFI_UNSUPPORTED None of required protocol is found .
@ retval EFI_UNSUPPORTED Failed to build up network interface .
* */
EFI_STATUS
BuildupNetworkInterface (
IN EFI_DRIVER_BINDING_PROTOCOL * This ,
IN EFI_HANDLE ControllerHandle
)
{
2023-03-27 16:28:58 +02:00
UINT32 * Id ;
2021-03-24 08:35:54 +01:00
UINT32 Index ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * NetworkInterface ;
BOOLEAN IsNew ;
EFI_STATUS Status ;
VOID * TempInterface ;
VOID * * Interface ;
UINT32 * ProtocolDiscoverIdPtr ;
EFI_HANDLE OpenDriverAgentHandle ;
EFI_HANDLE OpenDriverControllerHandle ;
EFI_HANDLE * HandleOfProtocolInterfacePtr ;
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * RestExInstance ;
EFI_TPL OldTpl ;
BOOLEAN NewNetworkInterfaceInstalled ;
2023-11-15 03:55:35 +01:00
UINT8 IpType ;
UINTN ListCount ;
2021-03-24 08:35:54 +01:00
2023-11-15 03:55:35 +01:00
ListCount = ( sizeof ( mRequiredProtocol ) / sizeof ( REDFISH_DISCOVER_REQUIRED_PROTOCOL ) ) ;
2021-03-24 08:35:54 +01:00
NewNetworkInterfaceInstalled = FALSE ;
Index = 0 ;
2023-11-15 03:55:35 +01:00
// 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 ( FilterProtocol ( mRequiredProtocol [ Index ] . ProtocolType , IpType ) ) {
continue ;
}
2021-03-24 08:35:54 +01:00
Status = gBS - > OpenProtocol (
// Already in list?
ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . DiscoveredProtocolGuid ,
2021-03-24 08:35:54 +01:00
( VOID * * ) & Id ,
This - > DriverBindingHandle ,
ControllerHandle ,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
) ;
if ( ! EFI_ERROR ( Status ) ) {
continue ;
}
Status = gBS - > OpenProtocol (
ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . RequiredServiceBindingProtocolGuid ,
2021-03-24 08:35:54 +01:00
& TempInterface ,
This - > DriverBindingHandle ,
ControllerHandle ,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
) ;
if ( EFI_ERROR ( Status ) ) {
continue ;
}
2021-12-05 23:54:11 +01:00
2023-11-15 03:55:35 +01:00
if ( mRequiredProtocol [ Index ] . ProtocolType ! = ProtocolTypeRestEx ) {
2021-03-24 08:35:54 +01:00
OldTpl = gBS - > RaiseTPL ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL ) ;
2023-11-15 03:55:35 +01:00
Status = CreateRedfishDiscoverNetworkInterface ( ControllerHandle , mRequiredProtocol [ Index ] . ProtocolType , & IsNew , & NetworkInterface ) ;
2021-03-24 08:35:54 +01:00
if ( EFI_ERROR ( Status ) ) {
gBS - > RestoreTPL ( OldTpl ) ;
return Status ;
}
2021-12-05 23:54:11 +01:00
2023-11-15 03:55:35 +01:00
NetworkInterface - > NetworkProtocolType = mRequiredProtocol [ Index ] . ProtocolType ;
2023-03-27 16:28:58 +02:00
NetworkInterface - > OpenDriverAgentHandle = This - > DriverBindingHandle ;
NetworkInterface - > OpenDriverControllerHandle = ControllerHandle ;
2023-11-15 03:55:35 +01:00
CopyGuid ( & NetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolGuid , mRequiredProtocol [ Index ] . RequiredProtocolGuid ) ;
CopyGuid ( & NetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolServiceGuid , mRequiredProtocol [ Index ] . RequiredServiceBindingProtocolGuid ) ;
2021-03-24 08:35:54 +01:00
ProtocolDiscoverIdPtr = & NetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolDiscoverId ;
OpenDriverAgentHandle = NetworkInterface - > OpenDriverAgentHandle ;
OpenDriverControllerHandle = NetworkInterface - > OpenDriverControllerHandle ;
HandleOfProtocolInterfacePtr = & NetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolControllerHandle ;
Interface = & NetworkInterface - > NetworkInterfaceProtocolInfo . NetworkProtocolInterface ;
NewNetworkInterfaceInstalled = TRUE ;
if ( IsNew ) {
InsertTailList ( & mEfiRedfishDiscoverNetworkInterface , & NetworkInterface - > Entry ) ;
mNumNetworkInterface + + ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
gBS - > RestoreTPL ( OldTpl ) ;
} else {
2023-03-27 16:28:58 +02:00
// Record REST_EX instance. REST_EX is created when client asks for Redfish service discovery.
2021-03-24 08:35:54 +01:00
// Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
// when discovery.
RestExInstance = ( EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * ) AllocateZeroPool ( sizeof ( EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL ) ) ;
if ( RestExInstance = = NULL ) {
return EFI_OUT_OF_RESOURCES ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
RestExInstance - > OpenDriverAgentHandle = This - > DriverBindingHandle ;
RestExInstance - > OpenDriverControllerHandle = ControllerHandle ;
RestExInstance - > RestExControllerHandle = ControllerHandle ;
InitializeListHead ( & RestExInstance - > Entry ) ;
InsertTailList ( & mEfiRedfishDiscoverRestExInstance , & RestExInstance - > Entry ) ;
mNumRestExInstance + + ;
ProtocolDiscoverIdPtr = & RestExInstance - > RestExId ;
OpenDriverAgentHandle = RestExInstance - > OpenDriverAgentHandle ;
OpenDriverControllerHandle = RestExInstance - > OpenDriverControllerHandle ;
HandleOfProtocolInterfacePtr = & RestExInstance - > RestExChildHandle ;
Interface = ( VOID * * ) & RestExInstance - > RestExProtocolInterface ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
Status = gBS - > InstallProtocolInterface (
& ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . DiscoveredProtocolGuid ,
2021-03-24 08:35:54 +01:00
EFI_NATIVE_INTERFACE ,
ProtocolDiscoverIdPtr
) ;
if ( EFI_ERROR ( Status ) ) {
continue ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
//
// Create service binding child and open it BY_DRIVER.
//
Status = NetLibCreateServiceChild (
ControllerHandle ,
This - > ImageHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . RequiredServiceBindingProtocolGuid ,
2021-03-24 08:35:54 +01:00
HandleOfProtocolInterfacePtr
) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = gBS - > OpenProtocol (
* HandleOfProtocolInterfacePtr ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . RequiredProtocolGuid ,
2021-03-24 08:35:54 +01:00
Interface ,
OpenDriverAgentHandle ,
OpenDriverControllerHandle ,
EFI_OPEN_PROTOCOL_BY_DRIVER
) ;
if ( ! EFI_ERROR ( Status ) ) {
2023-11-15 03:55:35 +01:00
if ( ( mRequiredProtocol [ Index ] . ProtocolType = = ProtocolTypeRestEx ) ) {
2023-03-27 16:28:58 +02:00
// Install Redfish Discover Protocol when EFI REST EX protocol is discovered.
2022-08-30 06:15:47 +02:00
// This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
2023-03-27 16:28:58 +02:00
// acquires Redfish service over network interface.
2022-08-30 06:15:47 +02:00
if ( ! NewNetworkInterfaceInstalled ) {
NetworkInterface = GetTargetNetworkInterfaceInternalByController ( ControllerHandle ) ;
if ( NetworkInterface = = NULL ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: Can't find network interface by ControllerHandle \n " , __func__ ) ) ;
2022-08-30 06:15:47 +02:00
return Status ;
}
}
NewNetworkInterfaceInstalled = FALSE ;
NetworkInterface - > EfiRedfishDiscoverProtocolHandle = NULL ;
2023-04-20 20:36:38 +02:00
RestExInstance - > Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE ;
RestExInstance - > RedfishDiscoverProtocol . GetNetworkInterfaceList = RedfishServiceGetNetworkInterface ;
RestExInstance - > RedfishDiscoverProtocol . AcquireRedfishService = RedfishServiceAcquireService ;
RestExInstance - > RedfishDiscoverProtocol . AbortAcquireRedfishService = RedfishServiceAbortAcquire ;
RestExInstance - > RedfishDiscoverProtocol . ReleaseRedfishService = RedfishServiceReleaseService ;
Status = gBS - > InstallProtocolInterface (
& NetworkInterface - > EfiRedfishDiscoverProtocolHandle ,
& gEfiRedfishDiscoverProtocolGuid ,
EFI_NATIVE_INTERFACE ,
( VOID * ) & RestExInstance - > RedfishDiscoverProtocol
) ;
2022-08-30 06:15:47 +02:00
if ( EFI_ERROR ( Status ) ) {
2023-04-06 21:51:09 +02:00
DEBUG ( ( DEBUG_ERROR , " %a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL \n " , __func__ ) ) ;
2022-08-30 06:15:47 +02:00
}
2023-03-27 16:28:58 +02:00
} else {
2023-05-30 09:06:13 +02:00
DEBUG ( ( DEBUG_MANAGEABILITY , " %a: Not REST EX, continue with next \n " , __func__ ) ) ;
2023-03-27 16:28:58 +02:00
continue ;
2021-03-24 08:35:54 +01:00
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Status ;
}
2023-11-15 03:55:35 +01:00
}
2021-12-05 23:54:11 +01:00
2023-03-27 16:28:58 +02:00
return EFI_DEVICE_ERROR ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
/**
2023-03-27 16:28:58 +02:00
Close the protocol opened for Redfish discovery . This function also destroy
2021-03-24 08:35:54 +01:00
the network services .
@ param [ in ] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to test . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ param [ in ] ThisRequiredProtocol Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL .
@ param [ in ] DriverAgentHandle Driver agent handle which used to open protocol earlier .
@ param [ in ] DriverControllerHandle Driver controller handle which used to open protocol earlier .
2023-03-27 16:28:58 +02:00
@ retval EFI_SUCCESS Protocol is closed successfully .
@ retval Others Protocol is closed unsuccessfully .
2021-03-24 08:35:54 +01:00
* */
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 Status ;
Status = gBS - > CloseProtocol (
ControllerHandle ,
ThisRequiredProtocol - > RequiredProtocolGuid ,
DriverAgentHandle ,
DriverControllerHandle
) ;
if ( ! EFI_ERROR ( Status ) ) {
NetLibDestroyServiceChild (
ControllerHandle ,
ThisBindingProtocol - > ImageHandle ,
ThisRequiredProtocol - > RequiredServiceBindingProtocolGuid ,
ControllerHandle
) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
/**
Stop the services on network interface .
@ param [ in ] ThisBindingProtocol A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to test . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ retval EFI_SUCCESS One of required protocol is found .
2023-03-27 16:28:58 +02:00
@ retval Others Failed to stop the services on network interface .
2021-03-24 08:35:54 +01:00
* */
EFI_STATUS
StopServiceOnNetworkInterface (
IN EFI_DRIVER_BINDING_PROTOCOL * ThisBindingProtocol ,
IN EFI_HANDLE ControllerHandle
)
{
UINT32 Index ;
EFI_STATUS Status ;
VOID * Interface ;
EFI_TPL OldTpl ;
2022-08-30 06:15:47 +02:00
EFI_HANDLE DiscoverProtocolHandle ;
2021-03-24 08:35:54 +01:00
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * RestExInstance ;
2023-04-20 20:36:38 +02:00
EFI_REDFISH_DISCOVER_PROTOCOL * RedfishDiscoverProtocol ;
2021-12-05 23:54:11 +01:00
2023-11-15 03:55:35 +01:00
for ( Index = 0 ; Index < ( sizeof ( mRequiredProtocol ) / sizeof ( REDFISH_DISCOVER_REQUIRED_PROTOCOL ) ) ; Index + + ) {
2021-03-24 08:35:54 +01:00
Status = gBS - > HandleProtocol (
ControllerHandle ,
2023-11-15 03:55:35 +01:00
mRequiredProtocol [ Index ] . RequiredProtocolGuid ,
2021-03-24 08:35:54 +01:00
( VOID * * ) & Interface
) ;
if ( ! EFI_ERROR ( Status ) ) {
2023-11-15 03:55:35 +01:00
if ( mRequiredProtocol [ Index ] . ProtocolType ! = ProtocolTypeRestEx ) {
2021-03-24 08:35:54 +01:00
if ( IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) ) {
return EFI_NOT_FOUND ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
OldTpl = gBS - > RaiseTPL ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL ) ;
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
while ( TRUE ) {
if ( ThisNetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolControllerHandle = = ControllerHandle ) {
2022-08-30 06:15:47 +02:00
DiscoverProtocolHandle = ThisNetworkInterface - > EfiRedfishDiscoverProtocolHandle ;
//
// Close protocol and destroy service.
//
2021-03-24 08:35:54 +01:00
Status = CloseProtocolService (
ThisBindingProtocol ,
ControllerHandle ,
2023-11-15 03:55:35 +01:00
& mRequiredProtocol [ Index ] ,
2021-03-24 08:35:54 +01:00
ThisNetworkInterface - > OpenDriverAgentHandle ,
ThisNetworkInterface - > OpenDriverControllerHandle
) ;
if ( ! EFI_ERROR ( Status ) ) {
2023-03-27 16:28:58 +02:00
Status = DestroyRedfishNetworkInterface ( ThisNetworkInterface ) ;
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
gBS - > RestoreTPL ( OldTpl ) ;
2022-08-30 06:15:47 +02:00
//
// Disconnect EFI Redfish discover driver controller to notify the
2023-03-27 16:28:58 +02:00
// client which uses .EFI Redfish discover protocol.
2022-08-30 06:15:47 +02:00
//
if ( DiscoverProtocolHandle ! = NULL ) {
2023-04-20 20:36:38 +02:00
Status = gBS - > HandleProtocol (
2022-08-30 06:15:47 +02:00
DiscoverProtocolHandle ,
& gEfiRedfishDiscoverProtocolGuid ,
2023-04-20 20:36:38 +02:00
( VOID * * ) & RedfishDiscoverProtocol
2022-08-30 06:15:47 +02:00
) ;
2023-04-20 20:36:38 +02:00
if ( ! EFI_ERROR ( Status ) ) {
RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL ( RedfishDiscoverProtocol ) ;
//
// Stop Redfish service discovery.
//
RedfishDiscoverProtocol - > AbortAcquireRedfishService (
RedfishDiscoverProtocol ,
RestExInstance - > NetworkInterfaceInstances
) ;
gBS - > DisconnectController ( DiscoverProtocolHandle , NULL , NULL ) ;
Status = gBS - > UninstallProtocolInterface (
DiscoverProtocolHandle ,
& gEfiRedfishDiscoverProtocolGuid ,
( VOID * ) & RestExInstance - > RedfishDiscoverProtocol
) ;
}
2021-03-24 08:35:54 +01:00
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverNetworkInterface , & ThisNetworkInterface - > Entry ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
gBS - > RestoreTPL ( OldTpl ) ;
} else {
if ( IsListEmpty ( & mEfiRedfishDiscoverRestExInstance ) ) {
return EFI_NOT_FOUND ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
OldTpl = gBS - > RaiseTPL ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL ) ;
RestExInstance = ( EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverRestExInstance ) ;
while ( TRUE ) {
if ( RestExInstance - > RestExChildHandle = = ControllerHandle ) {
Status = CloseProtocolService (
// Close REST_EX protocol.
ThisBindingProtocol ,
ControllerHandle ,
2023-11-15 03:55:35 +01:00
& mRequiredProtocol [ Index ] ,
2021-03-24 08:35:54 +01:00
RestExInstance - > OpenDriverAgentHandle ,
RestExInstance - > OpenDriverControllerHandle
) ;
RemoveEntryList ( & RestExInstance - > Entry ) ;
FreePool ( ( VOID * ) RestExInstance ) ;
mNumRestExInstance - - ;
gBS - > RestoreTPL ( OldTpl ) ;
return Status ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
if ( IsNodeAtEnd ( & mEfiRedfishDiscoverRestExInstance , & RestExInstance - > Entry ) ) {
break ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
RestExInstance = ( EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL * ) GetNextNode ( & mEfiRedfishDiscoverRestExInstance , & RestExInstance - > Entry ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
gBS - > RestoreTPL ( OldTpl ) ;
}
}
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return EFI_NOT_FOUND ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
/**
Tests to see if this driver supports a given controller . If a child device is provided ,
it further tests to see if this driver supports creating a handle for the specified child device .
This function checks to see if the driver specified by This supports the device specified by
ControllerHandle . Drivers will typically use the device path attached to
ControllerHandle and / or the services from the bus I / O abstraction attached to
ControllerHandle to determine if the driver supports ControllerHandle . This function
may be called many times during platform initialization . In order to reduce boot times , the tests
performed by this function must be very small , and take as little time as possible to execute . This
function must not change the state of any hardware devices , and this function must be aware that the
device specified by ControllerHandle may already be managed by the same driver or a
different driver . This function must match its calls to AllocatePages ( ) with FreePages ( ) ,
AllocatePool ( ) with FreePool ( ) , and OpenProtocol ( ) with CloseProtocol ( ) .
Because ControllerHandle may have been previously started by the same driver , if a protocol is
already in the opened state , then it must not be closed with CloseProtocol ( ) . This is required
to guarantee the state of ControllerHandle is not modified by this function .
@ param [ in ] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to test . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ param [ in ] RemainingDevicePath A pointer to the remaining portion of a device path . This
parameter is ignored by device drivers , and is optional for bus
drivers . For bus drivers , if this parameter is not NULL , then
the bus driver must determine if the bus controller specified
by ControllerHandle and the child controller specified
by RemainingDevicePath are both supported by this
bus driver .
@ retval EFI_SUCCESS The device specified by ControllerHandle and
RemainingDevicePath is supported by the driver specified by This .
@ retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
RemainingDevicePath is already being managed by the driver
specified by This .
@ retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
RemainingDevicePath is already being managed by a different
driver or an application that requires exclusive access .
Currently not implemented .
@ retval EFI_UNSUPPORTED The device specified by ControllerHandle and
RemainingDevicePath is not supported by the driver specified by This .
* */
EFI_STATUS
EFIAPI
RedfishDiscoverDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL * This ,
IN EFI_HANDLE ControllerHandle ,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
{
return TestForRequiredProtocols ( This , ControllerHandle ) ;
}
/**
Starts a device controller or a bus controller .
The Start ( ) function is designed to be invoked from the EFI boot service ConnectController ( ) .
As a result , much of the error checking on the parameters to Start ( ) has been moved into this
common boot service . It is legal to call Start ( ) from other locations ,
but the following calling restrictions must be followed , or the system behavior will not be deterministic .
1. ControllerHandle must be a valid EFI_HANDLE .
2. If RemainingDevicePath is not NULL , then it must be a pointer to a naturally aligned
EFI_DEVICE_PATH_PROTOCOL .
3. Prior to calling Start ( ) , the Supported ( ) function for the driver specified by This must
have been called with the same calling parameters , and Supported ( ) must have returned EFI_SUCCESS .
@ param [ in ] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle The handle of the controller to start . This handle
must support a protocol interface that supplies
an I / O abstraction to the driver .
@ param [ in ] RemainingDevicePath A pointer to the remaining portion of a device path . This
parameter is ignored by device drivers , and is optional for bus
drivers . For a bus driver , if this parameter is NULL , then handles
for all the children of Controller are created by this driver .
If this parameter is not NULL and the first Device Path Node is
not the End of Device Path Node , then only the handle for the
child device specified by the first Device Path Node of
RemainingDevicePath is created by this driver .
If the first Device Path Node of RemainingDevicePath is
the End of Device Path Node , no child handle is created by this
driver .
@ retval EFI_SUCCESS The device was started .
@ retval EFI_DEVICE_ERROR The device could not be started due to a device error . Currently not implemented .
@ retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources .
2023-03-27 16:28:58 +02:00
@ retval Others The driver failed to start the device .
2021-03-24 08:35:54 +01:00
* */
EFI_STATUS
EFIAPI
RedfishDiscoverDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL * This ,
IN EFI_HANDLE ControllerHandle ,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
{
return BuildupNetworkInterface ( This , ControllerHandle ) ;
}
/**
Stops a device controller or a bus controller .
The Stop ( ) function is designed to be invoked from the EFI boot service DisconnectController ( ) .
As a result , much of the error checking on the parameters to Stop ( ) has been moved
into this common boot service . It is legal to call Stop ( ) from other locations ,
but the following calling restrictions must be followed , or the system behavior will not be deterministic .
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
same driver ' s Start ( ) function .
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
EFI_HANDLE . In addition , all of these handles must have been created in this driver ' s
Start ( ) function , and the Start ( ) function must have called OpenProtocol ( ) on
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER .
@ param [ in ] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance .
@ param [ in ] ControllerHandle A handle to the device being stopped . The handle must
support a bus specific I / O protocol for the driver
to use to stop the device .
@ param [ in ] NumberOfChildren The number of child device handles in ChildHandleBuffer .
@ param [ in ] ChildHandleBuffer An array of child handles to be freed . May be NULL
if NumberOfChildren is 0.
@ retval EFI_SUCCESS The device was stopped .
@ retval EFI_DEVICE_ERROR The device could not be stopped due to a device error .
* */
EFI_STATUS
EFIAPI
RedfishDiscoverDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL * This ,
IN EFI_HANDLE ControllerHandle ,
IN UINTN NumberOfChildren ,
IN EFI_HANDLE * ChildHandleBuffer OPTIONAL
)
{
return StopServiceOnNetworkInterface ( This , ControllerHandle ) ;
}
EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = {
RedfishDiscoverDriverBindingSupported ,
RedfishDiscoverDriverBindingStart ,
RedfishDiscoverDriverBindingStop ,
REDFISH_DISCOVER_VERSION ,
NULL ,
NULL
} ;
/**
This is the declaration of an EFI image entry point .
@ param ImageHandle The firmware allocated handle for the UEFI image .
@ param SystemTable A pointer to the EFI System Table .
@ retval EFI_SUCCESS The operation completed successfully .
@ retval Others An unexpected error occurred .
* */
EFI_STATUS
EFIAPI
RedfishDiscoverEntryPoint (
IN EFI_HANDLE ImageHandle ,
IN EFI_SYSTEM_TABLE * SystemTable
)
{
EFI_STATUS Status ;
Status = EFI_SUCCESS ;
InitializeListHead ( & mRedfishDiscoverList ) ;
InitializeListHead ( & mRedfishInstanceList ) ;
InitializeListHead ( & mEfiRedfishDiscoverNetworkInterface ) ;
InitializeListHead ( & mEfiRedfishDiscoverRestExInstance ) ;
//
2023-03-27 16:28:58 +02:00
// Install binding protocol to obtain UDP and REST EX protocol.
2021-03-24 08:35:54 +01:00
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle ,
SystemTable ,
& gRedfishDiscoverDriverBinding ,
ImageHandle ,
& gRedfishDiscoverComponentName ,
& gRedfishDiscoverComponentName2
) ;
return Status ;
}
/**
This is the unload handle for Redfish discover module .
Disconnect the driver specified by ImageHandle from all the devices in the handle database .
Uninstall all the protocols installed in the driver entry point .
@ param [ in ] ImageHandle The drivers ' driver image .
@ retval EFI_SUCCESS The image is unloaded .
@ retval Others Failed to unload the image .
* */
EFI_STATUS
EFIAPI
RedfishDiscoverUnload (
IN EFI_HANDLE ImageHandle
)
{
EFI_STATUS Status ;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ThisNetworkInterface ;
Status = EFI_SUCCESS ;
// Destroy all network interfaces found by EFI Redfish Discover driver and
// stop services created for Redfish Discover.
while ( ! IsListEmpty ( & mEfiRedfishDiscoverNetworkInterface ) ) {
ThisNetworkInterface = ( EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * ) GetFirstNode ( & mEfiRedfishDiscoverNetworkInterface ) ;
StopServiceOnNetworkInterface ( & gRedfishDiscoverDriverBinding , ThisNetworkInterface - > NetworkInterfaceProtocolInfo . ProtocolControllerHandle ) ;
}
2021-12-05 23:54:11 +01:00
2021-03-24 08:35:54 +01:00
return Status ;
}