On Wed, Nov 1, 2023 at 6:24 AM Igor Kulchytskyy <ig...@ami.com> wrote:
>
> Hi Mike,
> Thank you for review.
> Please see my answers below the text.
>
> -----Original Message-----
> From: Mike Maslenkin <mike.maslen...@gmail.com>
> Sent: Tuesday, October 31, 2023 9:00 PM
> To: devel@edk2.groups.io; Igor Kulchytskyy <ig...@ami.com>
> Cc: Abner Chang <abner.ch...@amd.com>; Nickle Wang <nick...@nvidia.com>
> Subject: [EXTERNAL] Re: [edk2-devel] [PATCH] RedfishPkg: RedfishDiscoverDxe: 
> Fix issue if IPv4 installed after RestEx
>
>
> **CAUTION: The e-mail below is from an external source. Please exercise 
> caution before opening attachments, clicking links, or following guidance.**
>
> Hi Igor
>
> please find my comments below.
>
> On Tue, Oct 31, 2023 at 8:56 PM Igor Kulchytskyy via groups.io
> <igork=ami....@groups.io> wrote:
> >
> > Supported function of the driver changed to wait for all newtwork
> > interface to be installed.
> > Filer out the network interfaces which are not supported by
> > Redfish Host Interface.
> >
> > Cc: Abner Chang <abner.ch...@amd.com>
> > Cc: Nickle Wang <nick...@nvidia.com>
> > Cc: Igor Kulchytskyy <ig...@ami.com>
> > Signed-off-by: Igor Kulchytskyy <ig...@ami.com>
> > ---
> >  RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c | 96 
> > ++++++++++++++++++--
> >  1 file changed, 89 insertions(+), 7 deletions(-)
> >
> > diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c 
> > b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
> > index 23da3b968f..a88ad55938 100644
> > --- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
> > +++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
> > @@ -322,9 +322,15 @@ GetTargetNetworkInterfaceInternal (
> >  {
> >    EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;
> >
> > +  if (IsListEmpty(&mEfiRedfishDiscoverNetworkInterface)) {
> > +    return NULL;
> > +  }
> > +
> >    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL 
> > *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
> >    while (TRUE) {
> > -    if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, 
> > &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) 
> > == 0) {
> > +    if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, 
> > &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) 
> > == 0 &&
> > +        ((TargetNetworkInterface->IsIpv6 && 
> > ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) ||
> > +            (!TargetNetworkInterface->IsIpv6 && 
> > ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp4))) {
> >        return ThisNetworkInterface;
> >      }
> >
> > @@ -354,6 +360,10 @@ GetTargetNetworkInterfaceInternalByController (
> >  {
> >    EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;
> >
> > +  if (IsListEmpty(&mEfiRedfishDiscoverNetworkInterface)) {
> > +    return NULL;
> > +  }
> > +
>
> I also have these two hunks in my pending list.
> But I suggest to add ASSERT to GetTargetNetworkInterfaceInternal, just
> because currently it is really impossible situation,
> and mEfiRedfishDiscoverNetworkInterface was checked before in scope of
>  ValidateTargetNetworkInterface().
>
> Igor: Agree.
> I also just noticed that even if GetTargetNetworkInterfaceInternal function 
> may return NULL, the return value is not verified on NULL in 
> RedfishServiceAcquireService function.
> I think we should add this verification.

Mike: Agreed. I missed that the check in ValidateTargetNetworkInterface is:
if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) &&
(TargetNetworkInterface == NULL))
not a just a IsListEmpty.

And ValidateTargetNetworkInterface is called before
GetTargetNetworkInterfaceInternal()...
But for now don't we need to add additional check for the NULL value
returned from GetTargetNetworkInterfaceInternal() in a caller ?
In RedfishServiceAcquireService():
   TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal
(TargetNetworkInterface);

The NULL value of TargetNetworkInterfaceInternal is propagated down.
So on some code branch it can not cause a problems (hopefully because
of same IsListEmpty checks), but it can on another.

>
>
> Also I wonder why check patch doesn't complain about missed spaces in
> "IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)" call for example.
>
> >    ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL 
> > *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
> >    while (TRUE) {
> >      if (ThisNetworkInterface->OpenDriverControllerHandle == 
> > ControllerHandle) {
> > @@ -476,6 +486,38 @@ CheckIsIpVersion6 (
> >    return FALSE;
> >  }
> >
> > +/**
> > +  This function returns the  IP type supported by the Host Interface
> > +
> > +  @retval IP Type
> > +  //  Unknown=00h,
> > +  //  Ipv4=01h,
> > +  //  Ipv6=02h,
> > +
> > +**/
> > +UINT8
>
> STATIC ?
> Igor: WHY?

Mike: Just because it is local function,  No need to grep over
RedfishPkg to find all its implementations if any.

>
> > +GetHiIpProtocolType()
> > +{
> > +  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 0;
>
> In this driver REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP{4,6}
> used and accessible.
> so, 0 means  REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN
> And these values actually checked in scope of BuildupNetworkInterface() below.
> Igor: Thank you. Missed that macro.
>
> > +    }
> > +  }
> > +  Status = RedfishGetHostInterfaceProtocolData (mSmbios, 
> > &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
> > +  if (!EFI_ERROR (Status) && (Data != NULL) &&
> > +      (Data->HostIpAssignmentType == RedfishHostIpAssignmentStatic)) {
> > +      return Data->HostIpAddressFormat;
> > +  }
> > +  return 0;
>
> Same here, 0 is a magic value for
> REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN
>
> > +}
> > +
> >  /**
> >    This function discover Redfish service through SMBIOS host interface.
> >
> > @@ -512,6 +554,15 @@ DiscoverRedfishHostInterface (
> >
> >    Status = RedfishGetHostInterfaceProtocolData (mSmbios, 
> > &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
> >    if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) 
> > {
> > +
> > +    if (Instance->NetworkInterface->NetworkProtocolType == 
> > ProtocolTypeTcp4 && Data->HostIpAddressFormat != 
> > REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4) { // IPv4 case
> > +      DEBUG((DEBUG_ERROR, "%a: Network Interface is IPv4, but Host 
> > Interface requires Ipv6\n"));
>
> Missed argument for %a format
> Missed space "DEBUG (("
>
> Igor: Inattentiveness. Thank you.
>
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +    else if (Instance->NetworkInterface->NetworkProtocolType == 
> > ProtocolTypeTcp6 && Data->HostIpAddressFormat != 
> > REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) { // IPv6 case
> > +      DEBUG((DEBUG_ERROR, "%a: Network Interface is IPv6, but Host 
> > Interface requires IPv4\n"));
>
> Missed argument for %a format
> Missed space "DEBUG (("
>
> Igor: Inattentiveness. Thank you.
>
> > +      return EFI_UNSUPPORTED;
> > +    }
> >      //
> >      // 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.
> > @@ -1102,6 +1153,7 @@ RedfishServiceGetNetworkInterface (
> >    OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE  **NetworkIntfInstances
> >    )
> >  {
> > +  EFI_STATUS                                       Status;
> >    EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  
> > *ThisNetworkInterfaceIntn;
> >    EFI_REDFISH_DISCOVER_NETWORK_INTERFACE           *ThisNetworkInterface;
> >    EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;
> > @@ -1141,6 +1193,16 @@ RedfishServiceGetNetworkInterface (
> >
> >    ThisNetworkInterfaceIntn = 
> > (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode 
> > (&mEfiRedfishDiscoverNetworkInterface);
> >    while (TRUE) {
> > +    // If Get Subnet Info skip this interface
> > +    Status = NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, 
> > ImageHandle); // Get subnet info
> > +    if (EFI_ERROR(Status)) {
> > +      if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, 
> > &ThisNetworkInterfaceIntn->Entry)) {
> > +        break;
> > +      }
> > +      ThisNetworkInterfaceIntn = 
> > (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode 
> > (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
> > +      continue;
> > +    }
> > +
> >      ThisNetworkInterface->IsIpv6 = FALSE;
> >      if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
> >        ThisNetworkInterface->IsIpv6 = TRUE;
> > @@ -1260,7 +1322,12 @@ RedfishServiceAcquireService (
> >        // Get subnet information in case subnet information is not set 
> > because
> >        // RedfishServiceGetNetworkInterfaces hasn't been called yet.
> >        //
> > -      NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, 
> > ImageHandle);
> > +      Status1 = NetworkInterfaceGetSubnetInfo 
> > (TargetNetworkInterfaceInternal, ImageHandle);
> > +      if (EFI_ERROR(Status1)) {
> > +        DEBUG ((DEBUG_ERROR, "%a: Get subnet information fail.\n", 
> > __func__));
> > +        FreePool(Instance);
> > +        continue;
> > +      }
> >        NewInstance = TRUE;
> >      }
> >
> > @@ -1535,7 +1602,7 @@ TestForRequiredProtocols (
> >    UINT32      *Id;
> >    UINTN       Index;
> >    EFI_STATUS  Status;
> > -  UINTN       ListCount;
> > +  UINTN       ListCount, SuccessfulCount = 0;
> >
> >    ListCount = (sizeof (gRequiredProtocol) / sizeof 
> > (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
> >    for (Index = 0; Index < ListCount; Index++) {
> > @@ -1557,13 +1624,14 @@ TestForRequiredProtocols (
> >                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
> >                        );
> >        if (EFI_ERROR (Status)) {
> > -        if (Index == ListCount - 1) {
> > -          DEBUG ((DEBUG_INFO, "%a: all required protocols are found on 
> > this controller handle: %p.\n", __func__, ControllerHandle));
> > -          return EFI_SUCCESS;
> > -        }
> > +        SuccessfulCount++;
> >        }
> It may be SuccessfulCount must have one indentation less, i.e in scope
> of  upper "if (!EFI_ERROR (Status)) {", not in scope of "if (EFI_ERROR
> (Status)) {" in context.
>
> Igor: We need TestForRequiredProtocols return SUCCESS when all protocols 
> listed in gRequiredProtocol installed.
> When this happened the BuildupNetworkInterface function would be called, and 
> we iterate through gRequiredProtocol array and build network interfaces.
> We also install DiscoveredProtocolGuid to prevent BuildupNetworkInterface to 
> be called after that.
> If we have SuccessfulCount in scope of  upper "if (!EFI_ERROR (Status)) {", 
> then BuildupNetworkInterface will be called if something installed on that 
> ControllerHandle, like DNS protocol, for example.
>
> >      }
> >    }
> > +  if (ListCount == SuccessfulCount) {
> > +    DEBUG ((DEBUG_INFO, "%a: all required protocols are found on this 
> > controller handle: %p.\n", __func__, ControllerHandle));
> > +    return EFI_SUCCESS;
> > +  }
> >
> >    return EFI_UNSUPPORTED;
> >  }
> > @@ -1600,10 +1668,24 @@ BuildupNetworkInterface (
> >    EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;
> >    EFI_TPL                                          OldTpl;
> >    BOOLEAN                                          
> > NewNetworkInterfaceInstalled;
> > +  UINT8                                            IpType;
> >
> >    NewNetworkInterfaceInstalled = FALSE;
> >    Index                        = 0;
> > +
> > +
> > +  // Get IP Type to filter out unnecessary network protocol if possible
> > +  IpType = GetHiIpProtocolType();
> > +
> >    do {
> > +    // Check IP Type and skip an unnecessary network protocol if does not 
> > match
> > +    if (IpType != 0) {
>
> IpType is invariant to this loop.
> Eiher we may check it's value before the loop or we can just drop it,
> because "&& IpType ==
> REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP{4,6}"
> is equal to "IpType != 0" Do I miss something?
>
> Igor: You are right. Can be dropped.
>
> > +      if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeTcp4 && 
> > IpType == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) ||
> > +          (gRequiredProtocol[Index].ProtocolType == ProtocolTypeTcp6 && 
> > IpType == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4)) {
> > +        Index++;
>
> Ops. You can not do just  { Index++;continue }
> You need
> {
>       Index++;
>       if (Index == (sizeof (gRequiredProtocol) / sizeof
> (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
>         break;
>       }
>       continue;
> }
>
> Igor: continue statement causes the program control to pass to the 
> conditional tests. So, Index will be verified in while check.

Mike: Please disregard my comment :)
Definitely yes. I messed things up a bit, when I saw that this complex
loop become a bit more complex.
It's not clear why original code contains those checks and explicit breaks.

So, I rewrote this do while, to a simple for() iterating on index <
ARRAY_SIZE() similar to loop in TestForRequiredProtocols()


>
> It's a terrible function. I have a patch, that improves this loop:
> https://github.com/ghbaccount/edk2/commit/adc3218d3d96083c85cef6c396dde8ddb96530fb
>
> > +        continue;
> > +      }
> > +    }
> >      Status = gBS->OpenProtocol (
> >                      // Already in list?
> >                      ControllerHandle,
> > --
> > 2.37.1.windows.1
>
> Regards,
> Mike.
> -The information contained in this message may be confidential and 
> proprietary to American Megatrends (AMI). This communication is intended to 
> be read only by the individual or entity to whom it is addressed or by their 
> designee. If the reader of this message is not the intended recipient, you 
> are on notice that any distribution of this message, in any form, is strictly 
> prohibited. Please promptly notify the sender by reply e-mail or by telephone 
> at 770-246-8600, and then delete or destroy all copies of the transmission.

Regards,
Mike.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#110472): https://edk2.groups.io/g/devel/message/110472
Mute This Topic: https://groups.io/mt/102303105/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to