mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 10:37:22 +00:00
ID:369 - Fix lanplus interface bridging and response matching
Request/response matching for bridged and double-bridged requests is broken. This patch reworks the sending and command construction code, and fixes the response matching problems. Since the polling code is retried several times, it was moved into a separate function in order to make the code more readable. Commit for: Dmitry Bazhenov
This commit is contained in:
parent
c87aa0b96a
commit
6dec83ff5d
@ -601,7 +601,7 @@ ipmiv2_lan_ping(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* ipmi_lan_poll_recv
|
* ipmi_lan_poll_single
|
||||||
*
|
*
|
||||||
* Receive whatever comes back. Ignore received packets that don't correspond
|
* Receive whatever comes back. Ignore received packets that don't correspond
|
||||||
* to a request we've sent.
|
* to a request we've sent.
|
||||||
@ -609,50 +609,42 @@ ipmiv2_lan_ping(struct ipmi_intf * intf)
|
|||||||
* Returns: the ipmi_rs packet describing the/a reponse we expect.
|
* Returns: the ipmi_rs packet describing the/a reponse we expect.
|
||||||
*/
|
*/
|
||||||
static struct ipmi_rs *
|
static struct ipmi_rs *
|
||||||
ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
ipmi_lan_poll_single(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
struct rmcp_hdr rmcp_rsp;
|
struct rmcp_hdr * rmcp_rsp;
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_session * session = intf->session;
|
struct ipmi_session * session = intf->session;
|
||||||
int offset, rv;
|
int offset, rv;
|
||||||
uint16_t payload_size;
|
uint16_t payload_size;
|
||||||
uint8_t ourAddress = intf->my_addr;
|
|
||||||
|
|
||||||
if (ourAddress == 0) {
|
|
||||||
ourAddress = IPMI_BMC_SLAVE_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* receive packet */
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
rsp = ipmi_lan_recv_packet(intf);
|
||||||
|
|
||||||
/*
|
/* check if no packet has come */
|
||||||
* Not positive why we're looping. Do we sometimes get stuff we don't
|
if (rsp == NULL) {
|
||||||
* expect?
|
return NULL;
|
||||||
*/
|
}
|
||||||
while (rsp != NULL) {
|
|
||||||
|
|
||||||
/* parse response headers */
|
/* parse response headers */
|
||||||
memcpy(&rmcp_rsp, rsp->data, 4);
|
rmcp_rsp = (struct rmcp_hdr *)rsp->data;
|
||||||
|
|
||||||
if (rmcp_rsp.class == RMCP_CLASS_ASF) {
|
if (rmcp_rsp->class == RMCP_CLASS_ASF) {
|
||||||
/* might be ping response packet */
|
/* might be ping response packet */
|
||||||
rv = ipmi_handle_pong(intf, rsp);
|
rv = ipmi_handle_pong(intf, rsp);
|
||||||
return (rv <= 0) ? NULL : rsp;
|
return (rv <= 0) ? NULL : rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmcp_rsp.class != RMCP_CLASS_IPMI) {
|
if (rmcp_rsp->class != RMCP_CLASS_IPMI) {
|
||||||
lprintf(LOG_DEBUG, "Invalid RMCP class: %x",
|
lprintf(LOG_DEBUG, "Invalid RMCP class: %x", rmcp_rsp->class);
|
||||||
rmcp_rsp.class);
|
/* read one more packet */
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
return (struct ipmi_rs *)1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The authtype / payload type determines what we are receiving
|
* The authtype / payload type determines what we are receiving
|
||||||
*/
|
*/
|
||||||
offset = 4;
|
offset = 4;
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* The current packet could be one of several things:
|
* The current packet could be one of several things:
|
||||||
@ -670,38 +662,35 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
read_session_data(rsp, &offset, intf->session);
|
read_session_data(rsp, &offset, intf->session);
|
||||||
|
|
||||||
if (lanplus_has_valid_auth_code(rsp, intf->session) == 0)
|
if (lanplus_has_valid_auth_code(rsp, intf->session) == 0) {
|
||||||
{
|
|
||||||
lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!");
|
lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!");
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
return NULL;
|
||||||
assert(0);
|
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
|
if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE) &&
|
||||||
(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
||||||
(rsp->session.bEncrypted))
|
(rsp->session.bEncrypted)) {
|
||||||
|
|
||||||
{
|
|
||||||
lanplus_decrypt_payload(session->v2_data.crypt_alg,
|
lanplus_decrypt_payload(session->v2_data.crypt_alg,
|
||||||
session->v2_data.k2,
|
session->v2_data.k2,
|
||||||
rsp->data + offset,
|
rsp->data + offset,
|
||||||
rsp->session.msglen,
|
rsp->session.msglen,
|
||||||
rsp->data + offset,
|
rsp->data + offset,
|
||||||
&payload_size);
|
&payload_size);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
payload_size = rsp->session.msglen;
|
payload_size = rsp->session.msglen;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle IPMI responses (case #1 and #2) -- all IPMI reponses
|
* Handle IPMI responses (case #1 and #2) -- all IPMI reponses
|
||||||
*/
|
*/
|
||||||
if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI)
|
if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) {
|
||||||
{
|
|
||||||
struct ipmi_rq_entry * entry;
|
struct ipmi_rq_entry * entry;
|
||||||
int payload_start = offset;
|
int payload_start = offset;
|
||||||
int extra_data_length;
|
int extra_data_length;
|
||||||
|
int loop = 1;
|
||||||
|
|
||||||
|
while (loop--) {
|
||||||
|
/* fill-in response data */
|
||||||
read_ipmi_response(rsp, &offset);
|
read_ipmi_response(rsp, &offset);
|
||||||
|
|
||||||
lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header");
|
lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header");
|
||||||
@ -737,51 +726,54 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
|
entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,
|
||||||
rsp->payload.ipmi_response.cmd);
|
rsp->payload.ipmi_response.cmd);
|
||||||
|
|
||||||
if (entry != NULL) {
|
if (entry == NULL) {
|
||||||
|
lprintf(LOG_INFO, "IPMI Request Match NOT FOUND");
|
||||||
|
/* read one more packet */
|
||||||
|
return (struct ipmi_rs *)1;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t target_cmd = entry->req.msg.target_cmd;
|
||||||
|
|
||||||
lprintf(LOG_DEBUG+2, "IPMI Request Match found");
|
lprintf(LOG_DEBUG+2, "IPMI Request Match found");
|
||||||
if ( intf->target_addr != intf->my_addr &&
|
|
||||||
bridgePossible &&
|
if (entry->bridging_level) {
|
||||||
rsp->data_len &&
|
|
||||||
rsp->payload.ipmi_response.cmd == 0x34 &&
|
|
||||||
(rsp->payload.ipmi_response.netfn == 0x06 ||
|
|
||||||
rsp->payload.ipmi_response.netfn == 0x07) &&
|
|
||||||
rsp->payload.ipmi_response.rs_lun == 0 )
|
|
||||||
{
|
|
||||||
/* Check completion code */
|
/* Check completion code */
|
||||||
if (rsp->data[offset-1] == 0)
|
if (rsp->ccode) {
|
||||||
{
|
lprintf(LOG_DEBUG, "WARNING: Bridged "
|
||||||
|
"cmd ccode = 0x%02x", rsp->ccode);
|
||||||
|
} else {
|
||||||
|
/* decrement bridging level */
|
||||||
|
entry->bridging_level--;
|
||||||
|
if (!entry->bridging_level) {
|
||||||
|
entry->req.msg.cmd = entry->req.msg.target_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if bridged response is embedded */
|
||||||
|
if (payload_size > 8) {
|
||||||
|
printbuf(&rsp->data[offset], (rsp->data_len-offset-1),
|
||||||
|
"bridge command response");
|
||||||
|
/*
|
||||||
|
* decrement payload size
|
||||||
|
* (cks2 for outer Send Message)
|
||||||
|
*/
|
||||||
|
payload_size--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* need to make a loop for embedded bridged response
|
||||||
|
*/
|
||||||
|
loop++;
|
||||||
|
} else {
|
||||||
lprintf(LOG_DEBUG, "Bridged command answer,"
|
lprintf(LOG_DEBUG, "Bridged command answer,"
|
||||||
" waiting for next answer... ");
|
" waiting for next answer... ");
|
||||||
ipmi_req_remove_entry(
|
/* read one more packet */
|
||||||
rsp->payload.ipmi_response.rq_seq,
|
return (struct ipmi_rs *)1;
|
||||||
rsp->payload.ipmi_response.cmd);
|
|
||||||
return ipmi_lan_poll_recv(intf);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
lprintf(LOG_DEBUG, "WARNING: Bridged "
|
|
||||||
"cmd ccode = 0x%02x",
|
|
||||||
rsp->data[offset-1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp->data_len &&
|
|
||||||
rsp->payload.ipmi_response.cmd == 0x34) {
|
|
||||||
memcpy(rsp->data, &rsp->data[offset],
|
|
||||||
(rsp->data_len-offset));
|
|
||||||
if (verbose > 2)
|
|
||||||
printbuf( &rsp->data[offset],
|
|
||||||
(rsp->data_len-offset),
|
|
||||||
"bridge command response");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove request entry */
|
||||||
ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq,
|
ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq,
|
||||||
rsp->payload.ipmi_response.cmd);
|
rsp->payload.ipmi_response.cmd);
|
||||||
} else {
|
|
||||||
lprintf(LOG_INFO, "IPMI Request Match NOT FOUND");
|
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Good packet. Shift response data to start of array.
|
* Good packet. Shift response data to start of array.
|
||||||
@ -789,108 +781,100 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
|||||||
* rsp->data_len becomes the length of that data
|
* rsp->data_len becomes the length of that data
|
||||||
*/
|
*/
|
||||||
extra_data_length = payload_size - (offset - payload_start) - 1;
|
extra_data_length = payload_size - (offset - payload_start) - 1;
|
||||||
if (rsp != NULL && extra_data_length)
|
if (extra_data_length) {
|
||||||
{
|
|
||||||
rsp->data_len = extra_data_length;
|
rsp->data_len = extra_data_length;
|
||||||
memmove(rsp->data, rsp->data + offset, extra_data_length);
|
memmove(rsp->data, rsp->data + offset, extra_data_length);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
rsp->data_len = 0;
|
rsp->data_len = 0;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open Response
|
* Open Response
|
||||||
*/
|
*/
|
||||||
else if (rsp->session.payloadtype ==
|
} else if (rsp->session.payloadtype ==
|
||||||
IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE)
|
IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE) {
|
||||||
{
|
|
||||||
if (session->v2_data.session_state !=
|
if (session->v2_data.session_state !=
|
||||||
LANPLUS_STATE_OPEN_SESSION_SENT)
|
LANPLUS_STATE_OPEN_SESSION_SENT) {
|
||||||
{
|
|
||||||
lprintf(LOG_ERR, "Error: Received an Unexpected Open Session "
|
lprintf(LOG_ERR, "Error: Received an Unexpected Open Session "
|
||||||
"Response");
|
"Response");
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
/* read one more packet */
|
||||||
continue;
|
return (struct ipmi_rs *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_open_session_response(rsp, offset);
|
read_open_session_response(rsp, offset);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RAKP 2
|
* RAKP 2
|
||||||
*/
|
*/
|
||||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2)
|
} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2) {
|
||||||
{
|
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT) {
|
||||||
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT)
|
|
||||||
{
|
|
||||||
lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message");
|
lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message");
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
/* read one more packet */
|
||||||
continue;
|
return (struct ipmi_rs *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_rakp2_message(rsp, offset, session->v2_data.auth_alg);
|
read_rakp2_message(rsp, offset, session->v2_data.auth_alg);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RAKP 4
|
* RAKP 4
|
||||||
*/
|
*/
|
||||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4)
|
} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4) {
|
||||||
{
|
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT) {
|
||||||
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT)
|
|
||||||
{
|
|
||||||
lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message");
|
lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message");
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
/* read one more packet */
|
||||||
continue;
|
return (struct ipmi_rs *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_rakp4_message(rsp, offset, session->v2_data.auth_alg);
|
read_rakp4_message(rsp, offset, session->v2_data.auth_alg);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SOL
|
* SOL
|
||||||
*/
|
*/
|
||||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)
|
} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) {
|
||||||
{
|
|
||||||
int payload_start = offset;
|
int payload_start = offset;
|
||||||
int extra_data_length;
|
int extra_data_length;
|
||||||
|
|
||||||
if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE)
|
if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) {
|
||||||
{
|
|
||||||
lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet");
|
lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet");
|
||||||
rsp = ipmi_lan_recv_packet(intf);
|
/* read one more packet */
|
||||||
continue;
|
return (struct ipmi_rs *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_sol_packet(rsp, &offset);
|
read_sol_packet(rsp, &offset);
|
||||||
extra_data_length = payload_size - (offset - payload_start);
|
extra_data_length = payload_size - (offset - payload_start);
|
||||||
if (rsp && extra_data_length)
|
if (rsp && extra_data_length) {
|
||||||
{
|
|
||||||
rsp->data_len = extra_data_length;
|
rsp->data_len = extra_data_length;
|
||||||
memmove(rsp->data, rsp->data + offset, extra_data_length);
|
memmove(rsp->data, rsp->data + offset, extra_data_length);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
rsp->data_len = 0;
|
rsp->data_len = 0;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else
|
* Unknown Payload type
|
||||||
{
|
*/
|
||||||
|
} else {
|
||||||
lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x",
|
lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x",
|
||||||
rsp->session.payloadtype);
|
rsp->session.payloadtype);
|
||||||
assert(0);
|
/* read one more packet */
|
||||||
|
return (struct ipmi_rs *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* ipmi_lan_poll_recv
|
||||||
|
*
|
||||||
|
* Receive whatever comes back. Ignore received packets that don't correspond
|
||||||
|
* to a request we've sent.
|
||||||
|
*
|
||||||
|
* Returns: the ipmi_rs packet describing the/a reponse we expect.
|
||||||
|
*/
|
||||||
|
static struct ipmi_rs *
|
||||||
|
ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||||
|
{
|
||||||
|
struct ipmi_rs * rsp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* poll single packet */
|
||||||
|
rsp = ipmi_lan_poll_single(intf);
|
||||||
|
} while (rsp == (struct ipmi_rs *) 1);
|
||||||
|
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1412,7 +1396,7 @@ void getIpmiPayloadWireRep(
|
|||||||
tmp = len - cs;
|
tmp = len - cs;
|
||||||
msg[len++] = ipmi_csum(msg+cs, tmp);
|
msg[len++] = ipmi_csum(msg+cs, tmp);
|
||||||
cs3 = len;
|
cs3 = len;
|
||||||
msg[len++] = intf->my_addr;
|
msg[len++] = IPMI_REMOTE_SWID;
|
||||||
msg[len++] = curr_seq << 2;
|
msg[len++] = curr_seq << 2;
|
||||||
msg[len++] = 0x34; /* Send Message rqst */
|
msg[len++] = 0x34; /* Send Message rqst */
|
||||||
#if 0 /* From lan.c example */
|
#if 0 /* From lan.c example */
|
||||||
@ -1435,7 +1419,10 @@ void getIpmiPayloadWireRep(
|
|||||||
bridgePossible);
|
bridgePossible);
|
||||||
|
|
||||||
/* rsAddr */
|
/* rsAddr */
|
||||||
msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
|
if (bridgedRequest)
|
||||||
|
msg[len++] = intf->target_addr;
|
||||||
|
else
|
||||||
|
msg[len++] = IPMI_BMC_SLAVE_ADDR;
|
||||||
|
|
||||||
/* net Fn */
|
/* net Fn */
|
||||||
msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
|
msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
|
||||||
@ -1446,7 +1433,7 @@ void getIpmiPayloadWireRep(
|
|||||||
cs = len;
|
cs = len;
|
||||||
|
|
||||||
/* rqAddr */
|
/* rqAddr */
|
||||||
if (!bridgedRequest)
|
if (bridgedRequest < 2)
|
||||||
msg[len++] = IPMI_REMOTE_SWID;
|
msg[len++] = IPMI_REMOTE_SWID;
|
||||||
else /* Bridged message */
|
else /* Bridged message */
|
||||||
msg[len++] = intf->my_addr;
|
msg[len++] = intf->my_addr;
|
||||||
@ -1896,24 +1883,24 @@ ipmi_lanplus_build_v2x_ipmi_cmd(
|
|||||||
|
|
||||||
|
|
||||||
/* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
|
/* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */
|
||||||
if ((intf->target_addr == intf->my_addr) || (!bridgePossible))
|
if ((intf->target_addr == intf->my_addr) || (!bridgePossible)) {
|
||||||
{
|
|
||||||
entry = ipmi_req_add_entry(intf, req, curr_seq);
|
entry = ipmi_req_add_entry(intf, req, curr_seq);
|
||||||
}
|
/* it's a bridge command */
|
||||||
else /* it's a bridge command */
|
} else {
|
||||||
{
|
|
||||||
unsigned char backup_cmd;
|
unsigned char backup_cmd;
|
||||||
|
|
||||||
/* Add entry for cmd */
|
/* Add entry for cmd */
|
||||||
entry = ipmi_req_add_entry(intf, req, curr_seq);
|
entry = ipmi_req_add_entry(intf, req, curr_seq);
|
||||||
|
|
||||||
if(entry)
|
if (entry) {
|
||||||
{
|
entry->req.msg.target_cmd = entry->req.msg.cmd;
|
||||||
/* Add entry for bridge cmd */
|
entry->req.msg.cmd = 0x34;
|
||||||
backup_cmd = req->msg.cmd;
|
|
||||||
req->msg.cmd = 0x34;
|
if (intf->transit_addr &&
|
||||||
entry = ipmi_req_add_entry(intf, req, curr_seq);
|
intf->transit_addr != intf->my_addr)
|
||||||
req->msg.cmd = backup_cmd;
|
entry->bridging_level = 2;
|
||||||
|
else
|
||||||
|
entry->bridging_level = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user