iwarp: Add RDMA Atomic operations (RFC 7306)

Bug:12928
Change-Id: Id3f9e41a62a90e36f19e1d55226826e7f9ffa3f4
Reviewed-on: https://code.wireshark.org/review/17855
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Alexis La Goutte 2016-09-22 11:14:53 +02:00 committed by Michael Mann
parent 46595f4ad0
commit 69dfe97251
1 changed files with 136 additions and 1 deletions

View File

@ -69,6 +69,8 @@ void proto_register_iwarp_ddp_rdmap(void);
#define RDMA_SEND_SE 0x05
#define RDMA_SEND_SE_INVALIDATE 0x06
#define RDMA_TERMINATE 0x07
#define RDMA_ATOMIC_REQUEST 0x0A
#define RDMA_ATOMIC_RESPONSE 0x0B
/* bitmasks */
#define DDP_TAGGED_FLAG 0x80
@ -175,6 +177,21 @@ static gint hf_iwarp_rdma_term_ddp_seg_len = -1;
static gint hf_iwarp_rdma_term_ddp_h = -1;
static gint hf_iwarp_rdma_term_rdma_h = -1;
/* Atomic */
static gint hf_iwarp_rdma_atomic_reserved = -1;
static gint hf_iwarp_rdma_atomic_opcode = -1;
static gint hf_iwarp_rdma_atomic_request_identifier = -1;
static gint hf_iwarp_rdma_atomic_remote_stag = -1;
static gint hf_iwarp_rdma_atomic_remote_tagged_offset = -1;
static gint hf_iwarp_rdma_atomic_add_data = -1;
static gint hf_iwarp_rdma_atomic_add_mask = -1;
static gint hf_iwarp_rdma_atomic_swap_data = -1;
static gint hf_iwarp_rdma_atomic_swap_mask = -1;
static gint hf_iwarp_rdma_atomic_compare_data = -1;
static gint hf_iwarp_rdma_atomic_compare_mask = -1;
static gint hf_iwarp_rdma_atomic_original_request_identifier = -1;
static gint hf_iwarp_rdma_atomic_original_remote_data_value = -1;
/* initialize the subtree pointers */
static gint ett_iwarp_rdma = -1;
@ -193,6 +210,8 @@ static const value_string rdmap_messages[] = {
{ RDMA_SEND_SE, "Send with SE" },
{ RDMA_SEND_SE_INVALIDATE, "Send with SE and Invalidate" },
{ RDMA_TERMINATE, "Terminate" },
{ RDMA_ATOMIC_REQUEST, "Atomic Request" },
{ RDMA_ATOMIC_RESPONSE, "Atomic Response" },
{ 0, NULL }
};
@ -253,6 +272,13 @@ static const value_string ddp_errcode_untagged_names[] = {
{ 0, NULL }
};
static const value_string rdma_atomic_opcode_names[] = {
{ 0x00, "FetchAdd" },
{ 0x02, "CmpSwap" },
{ 0, NULL }
};
static heur_dissector_list_t rdmap_heur_subdissector_list;
static void
@ -459,6 +485,54 @@ dissect_iwarp_rdmap(tvbuff_t *tvb, proto_tree *rdma_tree, guint32 offset,
}
}
/* dissects RDMA Atomic Request and Terminate message header */
static int
dissect_iwarp_atomic(tvbuff_t *tvb, proto_tree *atomic_tree, guint32 offset,
guint8 rdma_msg_opcode)
{
switch(rdma_msg_opcode){
case RDMA_ATOMIC_REQUEST:{
guint32 atomic_opcode;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_opcode, tvb, offset, 4, ENC_BIG_ENDIAN);
atomic_opcode = tvb_get_ntohl(tvb, offset);
offset += 4;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_request_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_remote_stag, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_remote_tagged_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
switch(atomic_opcode){
case 0: /* Add */
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_add_data, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_add_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
break;
case 2: /* Swap */
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_swap_data, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_swap_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
break;
}
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_compare_data, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_compare_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
}
break;
case RDMA_ATOMIC_RESPONSE:
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_original_request_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_original_remote_data_value, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 4;
break;
}
return offset;
}
/*
* Main dissection routine which dissects a DDP segment and interprets the
* header field rsvdULP according to RDMAP.
@ -649,6 +723,13 @@ dissect_iwarp_ddp_rdmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
|| info.opcode == RDMA_TERMINATE) {
dissect_iwarp_rdmap(tvb, rdma_tree, offset, info.opcode);
}
/* do further dissection for RDMA messages RDMA Atomic Request & Response */
if (info.opcode == RDMA_ATOMIC_REQUEST
|| info.opcode == RDMA_ATOMIC_RESPONSE) {
dissect_iwarp_atomic(tvb, rdma_tree, offset, info.opcode);
}
return tvb_captured_length(tvb);
}
@ -853,7 +934,61 @@ proto_register_iwarp_ddp_rdmap(void)
{ &hf_iwarp_rdma_term_rdma_h, {
"Terminated RDMA Header", "iwarp_rdma.term_rdma_h",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL} }
NULL, HFILL} },
/* Atomic */
{ &hf_iwarp_rdma_atomic_reserved, {
"Reserved", "iwarp_rdma.atomic.reserved",
FT_UINT32, BASE_DEC, NULL, 0xFFFFFFF0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_opcode, {
"OpCode", "iwarp_rdma.atomic.opcode",
FT_UINT32, BASE_DEC, VALS(rdma_atomic_opcode_names), 0x0000000F,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_request_identifier, {
"Request Identifier", "iwarp_rdma.atomic.request_identifier",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_remote_stag, {
"Remote STag", "iwarp_rdma.atomic.remote_stag",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_remote_tagged_offset, {
"Remote Tagged Offset", "iwarp_rdma.atomic.remote_tagged_offset",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_add_data, {
"Add Data", "iwarp_rdma.atomic.add_data",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_add_mask, {
"Add Mask", "iwarp_rdma.atomic.add_mask",
FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_swap_data, {
"Swap Data", "iwarp_rdma.atomic.swap_data",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_swap_mask, {
"Swap Mask", "iwarp_rdma.atomic.swap_mask",
FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_compare_data, {
"Compare Data", "iwarp_rdma.atomic.compare_data",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_compare_mask, {
"Compare Mask", "iwarp_rdma.atomic.compare_mask",
FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_original_request_identifier, {
"Original Request Identifier", "iwarp_rdma.atomic.original_request_identifier",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
{ &hf_iwarp_rdma_atomic_original_remote_data_value, {
"Original Request Identifier", "iwarp_rdma.atomic.original_remote_data_value",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL} },
};
/* setup protocol subtree array */