diff options
author | Jorge Mora <jmora1300@gmail.com> | 2020-12-02 10:54:37 -0700 |
---|---|---|
committer | AndersBroman <a.broman58@gmail.com> | 2020-12-03 07:34:06 +0000 |
commit | 31b81393be1d30444a06dc9e866509e733c02e5b (patch) | |
tree | d7e1f217d7271b920f955d17ef59e0061d7a83d6 /epan/dissectors/packet-rpcrdma.c | |
parent | 5ca608f51932302e16c9d1218425804aac5f7ef4 (diff) |
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
Diffstat (limited to 'epan/dissectors/packet-rpcrdma.c')
-rw-r--r-- | epan/dissectors/packet-rpcrdma.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/epan/dissectors/packet-rpcrdma.c b/epan/dissectors/packet-rpcrdma.c index 5b4d7c50a9..ccccbc05de 100644 --- a/epan/dissectors/packet-rpcrdma.c +++ b/epan/dissectors/packet-rpcrdma.c @@ -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 */ |