aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-rpcrdma.c
diff options
context:
space:
mode:
authorJorge Mora <jmora1300@gmail.com>2020-12-02 10:54:37 -0700
committerAndersBroman <a.broman58@gmail.com>2020-12-03 07:34:06 +0000
commit31b81393be1d30444a06dc9e866509e733c02e5b (patch)
treed7e1f217d7271b920f955d17ef59e0061d7a83d6 /epan/dissectors/packet-rpcrdma.c
parent5ca608f51932302e16c9d1218425804aac5f7ef4 (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.c16
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 */