From 2bcdc52f92ef9148cfcb0d4b3351599564e38142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Wed, 6 May 2026 01:25:09 -0300 Subject: [PATCH] fix: accept RMCP message tag 0 from OpenBMC with session ID correlation OpenBMC-based BMCs return message tag 0 in RAKP2/RAKP4 instead of echoing the tag from the request. xCAT rejected these as stale responses and retried indefinitely until timeout. Accept tag 0 but verify the remote console session ID in the response matches our current sidm. This prevents stale retries from corrupting session state while allowing OpenBMC responses through. Applied to got_rmcp_response, got_rakp2, and got_rakp4. Ref: #7511 --- xCAT-server/lib/perl/xCAT/IPMI.pm | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/xCAT-server/lib/perl/xCAT/IPMI.pm b/xCAT-server/lib/perl/xCAT/IPMI.pm index 26933533a..bd3389181 100644 --- a/xCAT-server/lib/perl/xCAT/IPMI.pm +++ b/xCAT-server/lib/perl/xCAT/IPMI.pm @@ -780,8 +780,12 @@ sub got_rmcp_response { #we would ignore an RMCP+ open session response if we are not in an IPMI2 negotiation, so we have to have *some* state that isn't established for this to be kosher return 9; #now's not the time for this response, ignore it } - unless ($byte == $self->{rmcptag}) { #make sure this rmcp response is specifically the last one we sent.... we don't want to happily proceed with the risk a retry request blew up our temp session id without letting us know - return 9; + unless ($byte == $self->{rmcptag}) { + return 9 unless $byte == 0; + my @sid_check = @data[3..6]; + unless (pack("C4", @sid_check) eq pack("C4", @{ $self->{sidm} })) { + return 9; + } } $byte = shift @data; unless ($byte == 0x00) { @@ -895,8 +899,12 @@ sub got_rakp4 { unless ($self->{sessionestablishmentcontext} == STATE_EXPECTINGRAKP4) { #ignore rakp4 unless we are explicitly expecting RAKP4 return 9; #now's not the time for this response, ignore it } - unless ($byte == $self->{rmcptag}) { #make sure this rmcp response is specifically the last one we sent.... we don't want to happily proceed with the risk a retry request blew up our temp session id without letting us know - return 9; + unless ($byte == $self->{rmcptag}) { + return 9 unless $byte == 0; + my @sid_check = @data[3..6]; + unless (pack("C4", @sid_check) eq pack("C4", @{ $self->{sidm} })) { + return 9; + } } $byte = shift @data; unless ($byte == 0x00) { @@ -955,8 +963,12 @@ sub got_rakp2 { #the reason being that if an old rakp1 retry actually made it and we were just too aggressive, then a previous rakp2 is invalidated and invalid session id or the integrity check value is bad return 9; #now's not the time for this response, ignore it } - unless ($byte == $self->{rmcptag}) { #make sure this rmcp response is specifically the last one we sent.... we don't want to happily proceed with the risk a retry request blew up our temp session id without letting us know - return 9; + unless ($byte == $self->{rmcptag}) { + return 9 unless $byte == 0; + my @sid_check = @data[3..6]; + unless (pack("C4", @sid_check) eq pack("C4", @{ $self->{sidm} })) { + return 9; + } } $byte = shift @data; unless ($byte == 0x00) {