forked from osmocom/wireshark
RPCoRDMA: fix reassembly for Position-Zero Read Chunk
A Long Call or Position-Zero Read Chunk (PZRC) MUST include appropriate XDR roundup padding to maintain proper XDR alignment of their contents. For a PZRC, padding has already been added to the payload stream thus all padding added by the InfiniBand layer must be removed before adding the fragment to the reassembly table. See: https://tools.ietf.org/html/rfc8166#section-3.5 (Section 3.5.3) Closes #17054
This commit is contained in:
parent
5ca608f519
commit
31b81393be
|
@ -1763,7 +1763,7 @@ dissect_infiniband_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
|
|||
|
||||
/* General Variables */
|
||||
gboolean bthFollows = FALSE; /* Tracks if we are parsing a BTH. This is a significant decision point */
|
||||
struct infinibandinfo info = { 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
struct infinibandinfo info = { 0, 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
gint32 nextHeaderSequence = -1; /* defined by this dissector. #define which indicates the upcoming header sequence from OpCode */
|
||||
guint8 nxtHdr = 0; /* Keyed off for header dissection order */
|
||||
guint16 packetLength = 0; /* Packet Length. We track this as tvb_length - offset. */
|
||||
|
@ -1912,6 +1912,7 @@ skip_lrh:
|
|||
bthFollows = TRUE;
|
||||
/* Get the OpCode - this tells us what headers are following */
|
||||
info.opCode = tvb_get_guint8(tvb, offset);
|
||||
info.pad_count = (tvb_get_guint8(tvb, offset+1) & 0x30) >> 4;
|
||||
|
||||
if ((info.opCode >> 5) == 0x2) {
|
||||
info.dctConnect = !(tvb_get_guint8(tvb, offset + 1) & 0x80);
|
||||
|
@ -3816,7 +3817,7 @@ static void parse_CM_DRsp(proto_tree *top_tree, packet_info *pinfo, tvbuff_t *tv
|
|||
static void parse_COM_MGT(proto_tree *parentTree, packet_info *pinfo, tvbuff_t *tvb, gint *offset, proto_tree* top_tree)
|
||||
{
|
||||
MAD_Data MadData;
|
||||
struct infinibandinfo info = { 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
struct infinibandinfo info = { 0, 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
gint local_offset;
|
||||
const char *label;
|
||||
proto_item *CM_header_item;
|
||||
|
@ -5971,7 +5972,7 @@ static void dissect_general_info(tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
|||
MAD_Data MadData;
|
||||
|
||||
/* BTH - Base Trasport Header */
|
||||
struct infinibandinfo info = { 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
struct infinibandinfo info = { 0, 0, FALSE, 0, NULL, 0, 0, 0 };
|
||||
gint bthSize = 12;
|
||||
void *src_addr, /* the address to be displayed in the source/destination columns */
|
||||
*dst_addr; /* (lid/gid number) will be stored here */
|
||||
|
|
|
@ -114,6 +114,7 @@ typedef struct {
|
|||
*/
|
||||
struct infinibandinfo {
|
||||
guint8 opCode; /* OpCode from BTH header. */
|
||||
guint8 pad_count; /* PadCount from BTH header. */
|
||||
gboolean dctConnect; /* indicator for DCT connect/disconnect */
|
||||
guint16 cm_attribute_id; /* attribute id for CM messages */
|
||||
proto_tree* payload_tree;
|
||||
|
|
|
@ -203,6 +203,7 @@ typedef struct {
|
|||
guint32 msgno; /* Message number base so fragments are
|
||||
sequential between segment requests */
|
||||
chunk_type_t type; /* Chunk type for segment */
|
||||
guint32 xdrpos; /* Position in XDR stream -- RDMA read only */
|
||||
guint32 length; /* Length of segment in bytes */
|
||||
wmem_array_t *requests; /* List of requests for segment */
|
||||
} segment_info_t;
|
||||
|
@ -485,7 +486,7 @@ static tvbuff_t *add_fragment(tvbuff_t *tvb, gint offset, guint32 msgid,
|
|||
gint32 msg_num, gboolean more_frags, rdma_conv_info_t *p_rdma_conv_info,
|
||||
packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
guint32 nbytes;
|
||||
guint32 nbytes, frag_size;
|
||||
tvbuff_t *new_tvb = NULL;
|
||||
fragment_head *fd_head = NULL;
|
||||
|
||||
|
@ -495,6 +496,18 @@ static tvbuff_t *add_fragment(tvbuff_t *tvb, gint offset, guint32 msgid,
|
|||
nbytes = tvb_captured_length_remaining(tvb, offset);
|
||||
if (nbytes > 0 || more_frags) {
|
||||
/* Add message fragment to reassembly table */
|
||||
if (gp_infiniband_info->pad_count > 0 && p_rdma_conv_info != NULL && \
|
||||
p_rdma_conv_info->segment_info != NULL && \
|
||||
p_rdma_conv_info->segment_info->type == RDMA_READ_CHUNK && \
|
||||
p_rdma_conv_info->segment_info->xdrpos == 0) {
|
||||
/* Do not include any padding bytes inserted by Infiniband
|
||||
* layer if this is a PZRC (Position-Zero Read Chunk) since
|
||||
* payload stream already has any necessary padding bytes */
|
||||
frag_size = tvb_reported_length_remaining(tvb, offset) - gp_infiniband_info->pad_count;
|
||||
if (frag_size < nbytes) {
|
||||
nbytes = frag_size;
|
||||
}
|
||||
}
|
||||
fd_head = fragment_add_seq_check(&rpcordma_reassembly_table,
|
||||
tvb, offset, pinfo,
|
||||
msgid, NULL, (guint32)msg_num,
|
||||
|
@ -998,6 +1011,7 @@ process_rdma_list(tvbuff_t *tvb, guint offset, wmem_array_t *p_list,
|
|||
p_segment_info->msgid = msgid;
|
||||
p_segment_info->msgno = msg_num + 1;
|
||||
p_segment_info->type = p_rdma_chunk->type;
|
||||
p_segment_info->xdrpos = xdrpos;
|
||||
p_segment_info->length = p_rdma_segment->length;
|
||||
p_segment_info->requests = wmem_array_new(wmem_file_scope(), sizeof(request_t));
|
||||
/* Add segment to the list of segments */
|
||||
|
|
Loading…
Reference in New Issue