Hi everybody,
I'd like to provide two patches for review and integration. The patches
are in the attached.
lan-bridging.patch fixes:
- a possible crash during double-bridging over LAN
- potential mess with bridging multiple concurrent requests over LAN
- erroneous handling of the Send Message command embedded in the
ipmitool's raw command-line option.
sdr-read-fix.patch fixes a crash when dumping SDRs in a file and there's
an error getting an SDR. Also, algorithm of finding an optimal packet
size is improved.
Regards,
Dmitry
Index: include/ipmitool/ipmi.h
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/include/ipmitool/ipmi.h,v
retrieving revision 1.31
diff -p -u -r1.31 ipmi.h
--- include/ipmitool/ipmi.h 8 Jan 2009 21:21:22 -0000 1.31
+++ include/ipmitool/ipmi.h 23 Jan 2009 13:18:26 -0000
@@ -145,6 +145,7 @@ struct ipmi_rq_entry {
uint8_t rq_seq;
uint8_t *msg_data;
int msg_len;
+ int bridging_level;
struct ipmi_rq_entry *next;
};
Index: src/plugins/lan/lan.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/src/plugins/lan/lan.c,v
retrieving revision 1.63
diff -p -u -r1.63 lan.c
--- src/plugins/lan/lan.c 9 Jan 2009 21:55:47 -0000 1.63
+++ src/plugins/lan/lan.c 23 Jan 2009 13:18:27 -0000
@@ -572,44 +572,36 @@ ipmi_lan_poll_recv(struct ipmi_intf * in
if (entry) {
lprintf(LOG_DEBUG+2, "IPMI Request Match
found");
if ((intf->target_addr != our_address) &&
bridge_possible) {
- if ((rsp->data_len) &&
+ if ((rsp->data_len) &&
(rsp->payload.ipmi_response.netfn == 7) &&
(rsp->payload.ipmi_response.cmd !=
0x34)) {
- printbuf(&rsp->data[x],
rsp->data_len-x,
- "bridge command
response");
+ if (verbose > 2)
+ printbuf(&rsp->data[x],
rsp->data_len-x,
+ "bridge
command response");
}
/* bridged command: lose extra header */
- if (rsp->payload.ipmi_response.netfn ==
7 &&
- rsp->payload.ipmi_response.cmd
== 0x34) {
+ if (entry->bridging_level &&
+ rsp->payload.ipmi_response.netfn ==
7 &&
+ rsp->payload.ipmi_response.cmd ==
0x34) {
+ entry->bridging_level--;
if (rsp->data_len - x - 1 == 0)
{
rsp = !rsp->ccode ?
ipmi_lan_recv_packet(intf) : NULL;
- if (rsp && !rsp->ccode
&&
-
intf->transit_addr != intf->my_addr &&
-
intf->transit_addr != 0 &&
- (rsp->data[x - 3]
>> 2) == entry->rq_seq) {
- /* double
bridging: remove the Send Message prologue */
-
memmove(rsp->data + x - 7, rsp->data + x,
-
rsp->data_len - x - 1);
- rsp->data[x -
8] -= 8;
- rsp->data_len
-= 8;
- entry->rq_seq =
rsp->data[x - 3] >> 2;
- }
- entry->req.msg.cmd =
entry->req.msg.target_cmd;
+ if
(!entry->bridging_level)
+
entry->req.msg.cmd = entry->req.msg.target_cmd;
if (rsp == NULL) {
-
ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.cmd);
+
ipmi_req_remove_entry(entry->rq_seq, entry->req.msg.cmd);
}
continue;
} else {
- /* The bridged answer data
are inside the incoming packet */
- char bridge_cnt =
- 1 + (intf->transit_addr
!= intf->my_addr && intf->transit_addr != 0);
- memmove(rsp->data + x - 7,
- rsp->data + x + 7 *
(bridge_cnt - 1),
- rsp->data_len - (x
+ 7 * (bridge_cnt - 1)));
- rsp->data[x - 8] -= 8 *
bridge_cnt;
- rsp->data_len -= 8 *
bridge_cnt;
- entry->rq_seq = rsp->data[x
- 3] >> 2;
- entry->req.msg.cmd =
entry->req.msg.target_cmd;
- continue;
+ /* The bridged answer
data are inside the incoming packet */
+ memmove(rsp->data + x -
7,
+ rsp->data + x,
+ rsp->data_len -
x - 1);
+ rsp->data[x - 8] -= 8;
+ rsp->data_len -= 8;
+ entry->rq_seq =
rsp->data[x - 3] >> 2;
+ if
(!entry->bridging_level)
+
entry->req.msg.cmd = entry->req.msg.target_cmd;
+ continue;
}
} else {
//x +=
sizeof(rsp->payload.ipmi_response);
@@ -688,7 +680,6 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
struct ipmi_session * s = intf->session;
static int curr_seq = 0;
uint8_t our_address = intf->my_addr;
- uint8_t bridge_request = 0;
if (our_address == 0)
our_address = IPMI_BMC_SLAVE_ADDR;
@@ -735,11 +726,12 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
/* message length */
if ((intf->target_addr == our_address) || !bridge_possible) {
+ entry->bridging_level = 0;
msg[len++] = req->msg.data_len + 7;
cs = mp = len;
} else {
/* bridged request: encapsulate w/in Send Message */
- bridge_request = 1;
+ entry->bridging_level = 1;
msg[len++] = req->msg.data_len + 15 +
(intf->transit_addr != intf->my_addr && intf->transit_addr !=
0 ? 8 : 0);
cs = mp = len;
@@ -757,6 +749,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
if (intf->transit_addr == intf->my_addr || intf->transit_addr
== 0) {
msg[len++] = (0x40|intf->target_channel); /* Track
request*/
} else {
+ entry->bridging_level++;
msg[len++] = (0x40|intf->transit_channel); /*
Track request*/
cs = len;
msg[len++] = intf->transit_addr;
@@ -779,7 +772,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
msg[len++] = ipmi_csum(msg+cs, tmp);
cs = len;
- if (!bridge_request)
+ if (!entry->bridging_level)
msg[len++] = IPMI_REMOTE_SWID;
else /* Bridged message */
msg[len++] = intf->my_addr;
@@ -813,7 +806,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * in
msg[len++] = ipmi_csum(msg+cs, tmp);
/* bridged request: 2nd checksum */
- if (bridge_request) {
+ if (entry->bridging_level) {
if (intf->transit_addr != intf->my_addr && intf->transit_addr
!= 0) {
tmp = len - cs3;
msg[len++] = ipmi_csum(msg+cs3, tmp);
Index: lib/ipmi_sdr.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/lib/ipmi_sdr.c,v
retrieving revision 1.85
diff -p -u -r1.85 ipmi_sdr.c
--- lib/ipmi_sdr.c 9 Jan 2009 22:52:11 -0000 1.85
+++ lib/ipmi_sdr.c 23 Jan 2009 13:49:03 -0000
@@ -2679,14 +2679,21 @@ ipmi_sdr_get_record(struct ipmi_intf * i
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
+ sdr_max_read_len = sdr_rq.length - 1;
+ if (sdr_max_read_len > 0) {
+ /* no response may happen if requests are bridged
+ and too many bytes are requested */
+ continue;
+ } else {
free(data);
return NULL;
+ }
}
switch (rsp->ccode) {
case 0xca:
/* read too many bytes at once */
- sdr_max_read_len = (sdr_max_read_len >> 1) - 1;
+ sdr_max_read_len = sdr_rq.length - 1;
continue;
case 0xc5:
/* lost reservation */
@@ -3966,6 +3973,11 @@ ipmi_sdr_dump_bin(struct ipmi_intf *intf
sdrr->length = header->length;
sdrr->raw = ipmi_sdr_get_record(intf, header, itr);
+ if (sdrr->raw == NULL) {
+ lprintf(LOG_ERR, "ipmitool: cannot obtain SDR record %04x",
header->id);
+ return -1;
+ }
+
if (sdr_list_head == NULL)
sdr_list_head = sdrr;
else
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel