/src/wireshark/epan/dissectors/packet-lnet.c
Line | Count | Source |
1 | | /* packet-lnet.c |
2 | | * Routines for lnet dissection |
3 | | * Copyright (c) 2012, 2013, 2017 Intel Corporation. |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | * LNet - Lustre Networking |
14 | | * |
15 | | * A network abstraction layer for passing data at near wire-speed. |
16 | | * Supports RDMA where available and run across a variety of network hosts. |
17 | | * |
18 | | * http://doc.lustre.org/lustre_manual.xhtml#understandinglustrenetworking |
19 | | */ |
20 | | |
21 | | #include "config.h" |
22 | | |
23 | | #include <epan/packet.h> |
24 | | #include <epan/expert.h> |
25 | | #include <epan/to_str.h> |
26 | | #include <epan/proto_data.h> |
27 | | |
28 | | |
29 | | #include "packet-tcp.h" |
30 | | #include "packet-lnet.h" |
31 | | VALUE_STRING_ARRAY2(portal_index); |
32 | | |
33 | | void proto_reg_handoff_lnet(void); |
34 | | void proto_register_lnet(void); |
35 | | |
36 | | static dissector_handle_t lnet_handle; |
37 | | |
38 | | /* Initialize the protocol and registered fields */ |
39 | | static int proto_lnet; |
40 | | |
41 | | static int hf_lnet_ksm_type; |
42 | | static int hf_lnet_ksm_csum; |
43 | | static int hf_lnet_ksm_zc_req_cookie; |
44 | | static int hf_lnet_ksm_zc_ack_cookie; |
45 | | |
46 | | static int hf_lnet_ib_magic; |
47 | | static int hf_lnet_ib_version; |
48 | | static int hf_lnet_ib_type; |
49 | | static int hf_lnet_ib_credits; |
50 | | static int hf_lnet_ib_nob; |
51 | | static int hf_lnet_ib_csum; |
52 | | static int hf_lnet_ib_srcstamp; |
53 | | static int hf_lnet_ib_dststamp; |
54 | | |
55 | | static int hf_lnet_src_nid; |
56 | | static int hf_lnet_dest_nid; |
57 | | |
58 | | static int hf_lnet_nid_addr; |
59 | | static int hf_lnet_nid_lnet_type; |
60 | | static int hf_lnet_nid_interface; |
61 | | |
62 | | static int hf_lnet_dest_pid; |
63 | | static int hf_lnet_src_pid; |
64 | | |
65 | | static int hf_lnet_msg_type; |
66 | | static int hf_lnet_payload_length; |
67 | | static int hf_lnet_payload; |
68 | | static int hf_lnet_msg_filler; |
69 | | |
70 | | static int hf_dst_wmd_interface; |
71 | | static int hf_dst_wmd_object; |
72 | | |
73 | | static int hf_match_bits; |
74 | | static int hf_mlength; |
75 | | |
76 | | static int hf_hdr_data; |
77 | | static int hf_ptl_index; |
78 | | static int hf_offset; |
79 | | |
80 | | static int hf_src_offset; |
81 | | static int hf_sink_length; |
82 | | |
83 | | static int hf_hello_incarnation; |
84 | | static int hf_hello_type; |
85 | | |
86 | | static int hf_lnet_o2ib_connparam; |
87 | | static int hf_lnet_o2ib_connparam_qdepth; |
88 | | static int hf_lnet_o2ib_connparam_max_frags; |
89 | | static int hf_lnet_o2ib_connparam_max_size; |
90 | | static int hf_lnet_o2ib_cookie; |
91 | | static int hf_lnet_o2ib_src_cookie; |
92 | | static int hf_lnet_o2ib_dest_cookie; |
93 | | static int hf_lnet_o2ib_status; |
94 | | |
95 | | static int hf_lnet_rdma_desc; |
96 | | static int hf_lnet_rdma_desc_key; |
97 | | static int hf_lnet_rdma_desc_nfrags; |
98 | | |
99 | | static int hf_lnet_rdma_frag_size; |
100 | | static int hf_lnet_rdma_frag_addr; |
101 | | |
102 | | /* Initialize the subtree pointers */ |
103 | | static int ett_lnet; |
104 | | static int ett_lnet_nid; |
105 | | static int ett_lnet_o2ib_connparams; |
106 | | static int ett_lnet_rdma_desc; |
107 | | static int ett_lnet_rdma_frag; |
108 | | |
109 | | static expert_field ei_lnet_buflen; |
110 | | static expert_field ei_lnet_type; |
111 | | |
112 | 14 | #define LNET_TCP_PORT 988 /* Not IANA registered */ |
113 | | |
114 | 16 | #define LNET_HEADER_LEN 52 |
115 | 2 | #define LNET_PTL_INDEX_OFFSET_PUT (88 + extra_bytes) |
116 | | |
117 | | #define EXTRA_IB_HEADER_SIZE 24 |
118 | | |
119 | | static dissector_table_t subdissector_table; |
120 | | |
121 | | /********************************************************************\ |
122 | | * |
123 | | * LNet Definitions |
124 | | * |
125 | | * NID : Network IDentifiyer |
126 | | * IP@PORT# |
127 | | * e.g. 192.168.1.1@tcp0 or 10.10.10.1@o2ib4 |
128 | | * |
129 | | \********************************************************************/ |
130 | | |
131 | | #define lndnames_VALUE_STRING_LIST(XXX) \ |
132 | | XXX(QSWLND, 1) \ |
133 | | XXX(SOCKLND, 2) \ |
134 | | XXX(GMLND, 3) \ |
135 | | XXX(PTLLND, 4) \ |
136 | | XXX(O2IBLND, 5) \ |
137 | | XXX(CIBLND, 6) \ |
138 | | XXX(OPENIBLND, 7) \ |
139 | | XXX(IIBLND, 8) \ |
140 | | XXX(LOLND, 9) \ |
141 | | XXX(RALND, 10) \ |
142 | | XXX(VIBLND, 11) \ |
143 | | XXX(MXLND, 12) \ |
144 | | XXX(GNILND, 13) \ |
145 | | XXX(GNIIPLND, 14) \ |
146 | | XXX(PTL4LND, 15) |
147 | | |
148 | | VALUE_STRING_ENUM2(lndnames); |
149 | | VALUE_STRING_ARRAY2(lndnames); |
150 | | |
151 | | /* These are the NID protocol names */ |
152 | | static const value_string lndprotos[] = { |
153 | | { QSWLND, "elan" }, /* removed v2_7_50 */ |
154 | | { SOCKLND, "tcp" }, |
155 | | { GMLND, "gm" }, /* removed v2_0_0-rc1a-16-gc660aac */ |
156 | | { PTLLND, "ptl" }, /* removed v2_7_50 */ |
157 | | { O2IBLND, "o2ib" }, |
158 | | { CIBLND, "cib" }, /* removed v2_0_0-rc1a-175-gd2b8a0e */ |
159 | | { OPENIBLND, "openib" }, /* removed v2_0_0-rc1a-175-gd2b8a0e */ |
160 | | { IIBLND, "iib" }, /* removed v2_0_0-rc1a-175-gd2b8a0e */ |
161 | | { LOLND, "lo" }, |
162 | | { RALND, "ra" }, /* removed v2_7_50_0-34-g8be9e41 */ |
163 | | { VIBLND, "vib" }, /* removed v2_0_0-rc1a-175-gd2b8a0e */ |
164 | | { MXLND, "mx" }, /* removed v2_7_50_0-34-g8be9e41 */ |
165 | | { GNILND, "gni" }, |
166 | | { GNIIPLND, "gip" }, |
167 | | { PTL4LND, "ptlf" }, |
168 | | { 0, NULL} |
169 | | }; |
170 | | |
171 | | enum MSG_type { |
172 | | LNET_MSG_ACK = 0, |
173 | | LNET_MSG_PUT, |
174 | | LNET_MSG_GET, |
175 | | LNET_MSG_REPLY, |
176 | | LNET_MSG_HELLO, |
177 | | }; |
178 | | |
179 | | static const value_string lnet_msg_type[] = { |
180 | | { LNET_MSG_ACK , "ACK"}, |
181 | | { LNET_MSG_PUT , "PUT"}, |
182 | | { LNET_MSG_GET , "GET"}, |
183 | | { LNET_MSG_REPLY, "REPLY"}, |
184 | | { LNET_MSG_HELLO, "HELLO"}, |
185 | | { 0, NULL} |
186 | | }; |
187 | | |
188 | | /* PROTO MAGIC for LNDs */ |
189 | 303 | #define LNET_PROTO_IB_MAGIC 0x0be91b91 |
190 | | #define LNET_PROTO_MAGIC 0x45726963 /* ! */ |
191 | | #define LNET_PROTO_PING_MAGIC 0x70696E67 /* 'ping' */ |
192 | | #define LNET_PROTO_ACCEPTOR_MAGIC 0xacce7100 |
193 | | #define LNET_PROTO_GNI_MAGIC 0xb00fbabe /* ask Kim */ |
194 | | #define LNET_PROTO_TCP_MAGIC 0xeebc0ded |
195 | | |
196 | | static const value_string lnet_magic[] = { |
197 | | { LNET_PROTO_IB_MAGIC, "IB_MAGIC" }, |
198 | | { LNET_PROTO_MAGIC, "LNET_MAGIC" }, /* place holder */ |
199 | | { LNET_PROTO_PING_MAGIC, "PING_MAGIC" }, |
200 | | { LNET_PROTO_ACCEPTOR_MAGIC, "ACCEPTOR_MAGIC" }, |
201 | | { LNET_PROTO_GNI_MAGIC, "GNI_MAGIC" }, |
202 | | { LNET_PROTO_TCP_MAGIC, "TCP_MAGIC" }, |
203 | | { 0, NULL } |
204 | | }; |
205 | | |
206 | | /* SOCKLND constants. */ |
207 | | #define ksm_type_VALUE_STRING_LIST(XXX) \ |
208 | | XXX(KSOCK_MSG_NOOP, 0xc0) \ |
209 | | XXX(KSOCK_MSG_LNET, 0xc1) |
210 | | |
211 | | VALUE_STRING_ENUM2(ksm_type); |
212 | | VALUE_STRING_ARRAY2(ksm_type); |
213 | | |
214 | | static const value_string ib_version_t[] = { |
215 | | {0x11, "1"}, |
216 | | {0x12, "2"}, |
217 | | {0, NULL} |
218 | | }; |
219 | | |
220 | | #define lnet_ib_type_VALUE_STRING_LIST(XXX) \ |
221 | | XXX(IBLND_MSG_CONNREQ, 0xc0) \ |
222 | | XXX(IBLND_MSG_CONNACK, 0xc1) \ |
223 | | XXX(IBLND_MSG_NOOP, 0xd0) \ |
224 | | XXX(IBLND_MSG_IMMEDIATE, 0xd1) \ |
225 | | XXX(IBLND_MSG_PUT_REQ, 0xd2) \ |
226 | | XXX(IBLND_MSG_PUT_NAK, 0xd3) \ |
227 | | XXX(IBLND_MSG_PUT_ACK, 0xd4) \ |
228 | | XXX(IBLND_MSG_PUT_DONE, 0xd5) \ |
229 | | XXX(IBLND_MSG_GET_REQ, 0xd6) \ |
230 | | XXX(IBLND_MSG_GET_DONE, 0xd7) |
231 | | |
232 | | VALUE_STRING_ENUM2(lnet_ib_type); |
233 | | VALUE_STRING_ARRAY2(lnet_ib_type); |
234 | | |
235 | | /********************************************************************\ |
236 | | * |
237 | | * LNet Conversation |
238 | | * |
239 | | \********************************************************************/ |
240 | | |
241 | | typedef struct _lnet_conv_info_t { |
242 | | wmem_map_t *pdus; |
243 | | } lnet_conv_info_t; |
244 | | |
245 | | static struct lnet_trans_info * |
246 | 2 | get_lnet_conv(packet_info *pinfo, uint64_t match_bits) { |
247 | 2 | conversation_t *conversation; |
248 | | |
249 | 2 | struct lnet_trans_info *info; |
250 | | |
251 | 2 | lnet_conv_info_t *conv_info; |
252 | | |
253 | | // Ignore ports because this is kernel level and there can only be one Lustre instance per server |
254 | 2 | conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, conversation_pt_to_conversation_type(pinfo->ptype), |
255 | 2 | 0, 0, 0); |
256 | 2 | if (conversation == NULL) |
257 | 1 | conversation = conversation_new(pinfo->num, &pinfo->src, |
258 | 1 | &pinfo->dst, conversation_pt_to_conversation_type(pinfo->ptype), 0, 0, 0); |
259 | | |
260 | 2 | conv_info = (lnet_conv_info_t *)conversation_get_proto_data(conversation, proto_lnet); |
261 | 2 | if (!conv_info) { |
262 | 1 | conv_info = wmem_new0(wmem_file_scope(), lnet_conv_info_t); |
263 | 1 | conv_info->pdus = wmem_map_new(wmem_file_scope(), g_int64_hash, g_int64_equal); |
264 | | |
265 | 1 | conversation_add_proto_data(conversation, proto_lnet, conv_info); |
266 | 1 | } |
267 | | |
268 | 2 | info = (struct lnet_trans_info *)wmem_map_lookup(conv_info->pdus, &match_bits); |
269 | 2 | if (info == NULL) { |
270 | 1 | info = wmem_new0(wmem_file_scope(), struct lnet_trans_info); |
271 | 1 | info->match_bits = match_bits; |
272 | 1 | wmem_map_insert(conv_info->pdus, &info->match_bits, info); |
273 | 1 | } |
274 | | |
275 | 2 | return info; |
276 | 2 | } |
277 | | |
278 | | /********************************************************************\ |
279 | | * |
280 | | * LND:O2IB Structures |
281 | | * |
282 | | \********************************************************************/ |
283 | | |
284 | | static int |
285 | | dissect_struct_o2ib_connparam(tvbuff_t *tvb, proto_tree *parent_tree, int offset) |
286 | 0 | { |
287 | 0 | proto_tree *tree; |
288 | 0 | proto_item *item; |
289 | |
|
290 | 0 | item = proto_tree_add_item(parent_tree, hf_lnet_o2ib_connparam, tvb, offset, 8, ENC_NA); |
291 | 0 | tree = proto_item_add_subtree(item, ett_lnet_o2ib_connparams); |
292 | |
|
293 | 0 | proto_tree_add_item(tree, hf_lnet_o2ib_connparam_qdepth, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
294 | 0 | offset+=2; |
295 | 0 | proto_tree_add_item(tree, hf_lnet_o2ib_connparam_max_frags, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
296 | 0 | offset+=2; |
297 | 0 | proto_tree_add_item(tree, hf_lnet_o2ib_connparam_max_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
298 | 0 | offset+=4; |
299 | 0 | return offset; |
300 | 0 | } |
301 | | |
302 | | /* kib_rdma_desc_t */ |
303 | | /* { */ |
304 | | /* __u32 rd_key; /\* local/remote key *\/ */ |
305 | | /* __u32 rd_nfrags; /\* # fragments *\/ */ |
306 | | /* kib_rdma_frag_t rd_frags[0]; /\* buffer frags *\/ */ |
307 | | /* } |
308 | | * kib_rdma_frag_t */ |
309 | | /* { */ |
310 | | /* __u32 rf_nob; /\* # bytes this frag *\/ */ |
311 | | /* __u64 rf_addr; /\* CAVEAT EMPTOR: misaligned!! *\/ */ |
312 | | /* } */ |
313 | | static int |
314 | | dissect_struct_rdma_desc(tvbuff_t *tvb, proto_tree *parent_tree, int offset) |
315 | 0 | { |
316 | 0 | proto_tree *tree, *ftree; |
317 | 0 | int old_offset; |
318 | 0 | uint32_t frags, i; |
319 | |
|
320 | 0 | proto_item *item; |
321 | |
|
322 | 0 | old_offset = offset; |
323 | |
|
324 | 0 | item = proto_tree_add_item(parent_tree, hf_lnet_rdma_desc, tvb, offset, -1, ENC_NA); |
325 | 0 | tree = proto_item_add_subtree(item, ett_lnet_rdma_desc); |
326 | | |
327 | | /* @@ SAVE KEY and use to intercept infiniband payload */ |
328 | 0 | proto_tree_add_item(tree, hf_lnet_rdma_desc_key, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
329 | 0 | offset += 4; |
330 | 0 | proto_tree_add_item_ret_uint(tree, hf_lnet_rdma_desc_nfrags, tvb, offset, 4, ENC_LITTLE_ENDIAN, &frags); |
331 | 0 | offset += 4; |
332 | |
|
333 | 0 | for (i=0; i < frags; ++i) { |
334 | 0 | ftree = proto_tree_add_subtree_format(tree, tvb, offset, 12, ett_lnet_rdma_frag, NULL, "RDMA Fragment [%d]", i); |
335 | 0 | proto_tree_add_item(ftree, hf_lnet_rdma_frag_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
336 | 0 | offset += 4; |
337 | 0 | proto_tree_add_item(ftree, hf_lnet_rdma_frag_addr, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
338 | 0 | offset += 8; |
339 | 0 | } |
340 | |
|
341 | 0 | proto_item_set_len(item, offset-old_offset); |
342 | 0 | return offset; |
343 | 0 | } |
344 | | |
345 | | |
346 | | /********************************************************************\ |
347 | | * |
348 | | * NID Dissection & Healper Function |
349 | | * |
350 | | \********************************************************************/ |
351 | | |
352 | | // EXPORTED |
353 | | int |
354 | | lnet_dissect_struct_nid(tvbuff_t * tvb, packet_info* pinfo, proto_tree *parent_tree, int offset, int hf_index) |
355 | 117 | { |
356 | 117 | proto_tree *tree; |
357 | 117 | proto_item *item; |
358 | 117 | uint32_t ip, interface, proto; |
359 | | |
360 | 117 | item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, 8, ENC_NA); |
361 | 117 | tree = proto_item_add_subtree(item, ett_lnet_nid); |
362 | | |
363 | 117 | ip = tvb_get_ipv4(tvb, offset); |
364 | 117 | proto_tree_add_item(tree, hf_lnet_nid_addr, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
365 | 117 | offset+=4; |
366 | 117 | proto_tree_add_item_ret_uint(tree, hf_lnet_nid_interface, tvb, offset, 2, ENC_LITTLE_ENDIAN, &interface); |
367 | 117 | offset+=2; |
368 | 117 | proto_tree_add_item_ret_uint(tree, hf_lnet_nid_lnet_type, tvb, offset, 2, ENC_LITTLE_ENDIAN, &proto); |
369 | 117 | offset+=2; |
370 | | |
371 | 117 | if (ip != 0) { |
372 | 82 | address addr; |
373 | 82 | set_address(&addr, AT_IPv4, 4, &ip); |
374 | 82 | proto_item_append_text(item, ": %s@%s%d", address_to_name(&addr), val_to_str(pinfo->pool, proto, lndprotos, "E(%d)"), interface); |
375 | 82 | } |
376 | | |
377 | 117 | return offset; |
378 | 117 | } |
379 | | |
380 | | /********************************************************************\ |
381 | | * |
382 | | * Other Dissection |
383 | | * |
384 | | \********************************************************************/ |
385 | | |
386 | | static int |
387 | | dissect_csum(tvbuff_t * tvb, packet_info *pinfo, proto_tree *tree, int offset, unsigned lnd_type) |
388 | 600 | { |
389 | 600 | uint32_t csum; |
390 | 600 | proto_item *ti; |
391 | | |
392 | 600 | csum = tvb_get_letohl(tvb, offset); |
393 | | // @@ convert this to proto_tree_add_checksum() |
394 | 600 | switch (lnd_type) { |
395 | 580 | case SOCKLND: |
396 | 580 | ti = proto_tree_add_item(tree, hf_lnet_ib_csum, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
397 | 580 | break; |
398 | | |
399 | 11 | case O2IBLND: |
400 | 11 | ti = proto_tree_add_item(tree, hf_lnet_ksm_csum, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
401 | 11 | break; |
402 | | |
403 | 0 | default: |
404 | 0 | ti = proto_tree_add_expert_format(tree, pinfo, &ei_lnet_type, tvb, offset, 4, |
405 | 0 | "Checksum for unprocessed type: %s", |
406 | 0 | val_to_str(pinfo->pool, lnd_type, lndnames, "Unknown(%d)")); |
407 | 0 | break; |
408 | 600 | } |
409 | | |
410 | 591 | if (csum == 0) |
411 | 158 | proto_item_append_text(ti, " (DISABLED)"); |
412 | | |
413 | 591 | return offset + 4; |
414 | 600 | } |
415 | | |
416 | | /********************************************************************\ |
417 | | * |
418 | | * Message Type Dissection |
419 | | * |
420 | | \********************************************************************/ |
421 | | |
422 | | static int |
423 | | dissect_lnet_put(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint64_t *match) |
424 | 2 | { |
425 | | /* typedef struct lnet_put { |
426 | | lnet_handle_wire_t ack_wmd; |
427 | | __u64 match_bits; |
428 | | __u64 hdr_data; |
429 | | __u32 ptl_index; |
430 | | __u32 offset; |
431 | | } WIRE_ATTR lnet_put_t; */ |
432 | 2 | const char *port; |
433 | 2 | uint32_t ptl_index; |
434 | | |
435 | 2 | proto_tree_add_item(tree, hf_dst_wmd_interface, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
436 | 2 | offset += 8; |
437 | 2 | proto_tree_add_item(tree, hf_dst_wmd_object, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
438 | 2 | offset += 8; |
439 | | |
440 | 2 | proto_tree_add_item_ret_uint64(tree, hf_match_bits, tvb, offset, 8, ENC_LITTLE_ENDIAN, match); |
441 | 2 | offset += 8; |
442 | 2 | proto_tree_add_item(tree, hf_hdr_data, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
443 | 2 | offset += 8; |
444 | | |
445 | | /* print ptl_index */ |
446 | 2 | proto_tree_add_item_ret_uint(tree, hf_ptl_index, tvb, offset, 4, ENC_LITTLE_ENDIAN, &ptl_index); |
447 | 2 | offset += 4; |
448 | | |
449 | 2 | port = val_to_str(pinfo->pool, ptl_index, portal_index, "Unknown(%d)"); |
450 | 2 | col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", port); |
451 | 2 | proto_item_append_text(tree, ", %s" , port); |
452 | | |
453 | 2 | proto_tree_add_item(tree, hf_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
454 | 2 | offset += 4; |
455 | 2 | return offset; |
456 | 2 | } |
457 | | |
458 | | static int |
459 | | dissect_lnet_get(tvbuff_t * tvb, packet_info *pinfo, proto_tree *tree, int offset, uint64_t *match) |
460 | 0 | { |
461 | | /* typedef struct lnet_get { |
462 | | lnet_handle_wire_t return_wmd; |
463 | | __u64 match_bits; |
464 | | __u32 ptl_index; |
465 | | __u32 src_offset; |
466 | | __u32 sink_length; |
467 | | } WIRE_ATTR lnet_get_t; |
468 | | */ |
469 | 0 | const char *port; |
470 | 0 | uint32_t ptl_index; |
471 | |
|
472 | 0 | proto_tree_add_item(tree, hf_dst_wmd_interface, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
473 | 0 | offset += 8; |
474 | 0 | proto_tree_add_item(tree, hf_dst_wmd_object, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
475 | 0 | offset += 8; |
476 | 0 | proto_tree_add_item_ret_uint64(tree, hf_match_bits, tvb, offset, 8, ENC_LITTLE_ENDIAN, match); |
477 | 0 | offset += 8; |
478 | |
|
479 | 0 | proto_tree_add_item_ret_uint(tree, hf_ptl_index, tvb, offset, 4, ENC_LITTLE_ENDIAN, &ptl_index); |
480 | 0 | offset += 4; |
481 | |
|
482 | 0 | port = val_to_str(pinfo->pool, ptl_index, portal_index, "Unknown (%d)"); |
483 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", port); |
484 | 0 | proto_item_append_text(tree, ", %s", port); |
485 | |
|
486 | 0 | proto_tree_add_item(tree, hf_src_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
487 | 0 | offset += 4; |
488 | 0 | proto_tree_add_item(tree, hf_sink_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
489 | 0 | offset += 4; |
490 | 0 | return offset; |
491 | 0 | } |
492 | | |
493 | | static int |
494 | | dissect_lnet_reply(tvbuff_t * tvb, proto_tree *tree, int offset) |
495 | 1 | { |
496 | | /* typedef struct lnet_reply { |
497 | | lnet_handle_wire_t dst_wmd; |
498 | | } WIRE_ATTR lnet_reply_t; */ |
499 | | |
500 | 1 | proto_tree_add_item(tree, hf_dst_wmd_interface, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
501 | 1 | offset+=8; |
502 | 1 | proto_tree_add_item(tree, hf_dst_wmd_object, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
503 | 1 | offset+=8; |
504 | | |
505 | 1 | return offset; |
506 | 1 | } |
507 | | |
508 | | |
509 | | static int |
510 | | dissect_lnet_hello(tvbuff_t * tvb, proto_tree *tree, int offset) |
511 | 1 | { |
512 | | /* typedef struct lnet_hello { |
513 | | __u64 incarnation; |
514 | | __u32 type; |
515 | | } WIRE_ATTR lnet_hello_t; */ |
516 | | |
517 | 1 | proto_tree_add_item(tree, hf_hello_incarnation, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
518 | 1 | offset+=8; |
519 | 1 | proto_tree_add_item(tree, hf_hello_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
520 | 1 | offset+=4; |
521 | 1 | return offset; |
522 | 1 | } |
523 | | |
524 | | static int |
525 | | dissect_lnet_ack(tvbuff_t * tvb, proto_tree *tree, int offset, uint64_t *match) |
526 | 13 | { |
527 | | /* typedef struct lnet_ack { |
528 | | lnet_handle_wire_t dst_wmd; |
529 | | __u64 match_bits; |
530 | | __u32 mlength; |
531 | | } WIRE_ATTR lnet_ack_t; */ |
532 | | |
533 | 13 | proto_tree_add_item(tree, hf_dst_wmd_interface, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
534 | 13 | offset+=8; |
535 | 13 | proto_tree_add_item(tree, hf_dst_wmd_object, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
536 | 13 | offset+=8; |
537 | 13 | proto_tree_add_item_ret_uint64(tree, hf_match_bits, tvb, offset, 8, ENC_LITTLE_ENDIAN, match); |
538 | 13 | offset+=8; |
539 | 13 | proto_tree_add_item(tree, hf_mlength, tvb, offset,4, ENC_LITTLE_ENDIAN); |
540 | 13 | offset+=4; |
541 | 13 | return offset; |
542 | 13 | } |
543 | | |
544 | | /********************************************************************\ |
545 | | * |
546 | | * Dissect Header Functions |
547 | | * |
548 | | \********************************************************************/ |
549 | | |
550 | | static int |
551 | | dissect_ksock_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) |
552 | 595 | { |
553 | 595 | proto_item *ti; |
554 | 595 | uint64_t val; |
555 | | |
556 | 595 | proto_tree_add_item(tree, hf_lnet_ksm_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
557 | 595 | offset += 4; |
558 | 595 | offset = dissect_csum(tvb, pinfo, tree, offset, SOCKLND); |
559 | 595 | ti = proto_tree_add_item_ret_uint64(tree, hf_lnet_ksm_zc_req_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN, &val); |
560 | 595 | if (val == 0) |
561 | 102 | proto_item_append_text(ti, " (NO ACK REQUIRED)"); |
562 | 595 | offset += 8; |
563 | 595 | ti = proto_tree_add_item_ret_uint64(tree, hf_lnet_ksm_zc_ack_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN, &val); |
564 | 595 | if (val == 0) |
565 | 107 | proto_item_append_text(ti, " (NOT ACK)"); |
566 | 595 | offset += 8; |
567 | 595 | return offset; |
568 | 595 | } |
569 | | static int |
570 | | dissect_ksock_msg_noop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
571 | 555 | { |
572 | 555 | return dissect_ksock_msg(tvb, pinfo, tree, 0); |
573 | 555 | } |
574 | | |
575 | | static int |
576 | | dissect_ib_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint32_t *msg_type, uint32_t *msg_length) |
577 | 11 | { |
578 | | /* typedef struct |
579 | | * { |
580 | | * __u32 ibm_magic; * I'm an ibnal message * |
581 | | * __u16 ibm_version; * this is my version * |
582 | | |
583 | | * __u8 ibm_type; * msg type * |
584 | | * __u8 ibm_credits; * returned credits * |
585 | | * __u32 ibm_nob; * # bytes in message * |
586 | | * __u32 ibm_cksum; * checksum (0 == no |
587 | | * checksum) * |
588 | | * __u64 ibm_srcnid; * sender's NID * |
589 | | * __u64 ibm_srcstamp; * sender's incarnation * |
590 | | * __u64 ibm_dstnid; * destination's NID * |
591 | | * __u64 ibm_dststamp; * destination's |
592 | | * incarnation * |
593 | | |
594 | | * union { |
595 | | * kib_connparams_t connparams; |
596 | | * kib_immediate_msg_t immediate; |
597 | | * kib_putreq_msg_t putreq; |
598 | | * kib_putack_msg_t putack; |
599 | | * kib_get_msg_t get; |
600 | | * kib_completion_msg_t completion; |
601 | | * } WIRE_ATTR ibm_u; |
602 | | *} WIRE_ATTR kib_msg_t; */ |
603 | | |
604 | 11 | proto_tree_add_item(tree, hf_lnet_ib_magic, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
605 | 11 | offset += 4; |
606 | 11 | proto_tree_add_item(tree, hf_lnet_ib_version, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
607 | 11 | offset += 2; |
608 | 11 | proto_tree_add_item_ret_uint(tree, hf_lnet_ib_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, msg_type); |
609 | 11 | offset += 1; |
610 | 11 | proto_tree_add_item(tree, hf_lnet_ib_credits, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
611 | 11 | offset += 1; |
612 | 11 | proto_tree_add_item_ret_uint(tree, hf_lnet_ib_nob, tvb, offset, 4, ENC_LITTLE_ENDIAN, msg_length); |
613 | 11 | offset += 4; |
614 | 11 | offset = dissect_csum(tvb, pinfo, tree, offset, O2IBLND); |
615 | | |
616 | 11 | offset = lnet_dissect_struct_nid(tvb, pinfo, tree, offset, hf_lnet_src_nid); |
617 | | |
618 | 11 | proto_tree_add_item(tree, hf_lnet_ib_srcstamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
619 | 11 | offset += 8; |
620 | | |
621 | 11 | offset = lnet_dissect_struct_nid(tvb, pinfo, tree, offset, hf_lnet_dest_nid); |
622 | | |
623 | 11 | proto_tree_add_item(tree, hf_lnet_ib_dststamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
624 | 11 | offset += 8; |
625 | | |
626 | | /* LNet payloads only exist when the LND msg type is IMMEDIATE. |
627 | | Return a zero offset for all other types. */ |
628 | 11 | return offset; |
629 | 11 | } |
630 | | |
631 | | /********************************************************************\ |
632 | | * |
633 | | * Main Packet Dissection |
634 | | * |
635 | | \********************************************************************/ |
636 | | static int |
637 | | dissect_lnet_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
638 | 51 | { |
639 | 51 | proto_item *ti; |
640 | | |
641 | 51 | proto_tree *lnet_tree; |
642 | | /* Other misc. local variables. */ |
643 | 51 | unsigned offset = 0; |
644 | 51 | uint32_t msg_length = 0; |
645 | 51 | uint32_t payload_length = 0; |
646 | 51 | int32_t msg_filler_length = 0; |
647 | | |
648 | 51 | uint64_t match; |
649 | 51 | uint32_t msg_type = 0; |
650 | 51 | uint32_t ib_msg_type = 0; |
651 | 51 | unsigned extra_bytes = GPOINTER_TO_UINT(data); |
652 | 51 | bool ib_msg_payload = false; |
653 | | |
654 | 51 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "LNET"); |
655 | 51 | col_clear(pinfo->cinfo, COL_INFO); |
656 | | |
657 | 51 | ti = proto_tree_add_item(tree, proto_lnet, tvb, 0, -1, ENC_NA); |
658 | 51 | lnet_tree = proto_item_add_subtree(ti, ett_lnet); |
659 | | |
660 | 51 | if (extra_bytes) { |
661 | 11 | offset = dissect_ib_msg(tvb, pinfo, lnet_tree, offset, &ib_msg_type, &msg_length); |
662 | | |
663 | 11 | switch (ib_msg_type) { |
664 | 0 | case IBLND_MSG_CONNREQ: |
665 | 0 | case IBLND_MSG_CONNACK: |
666 | | // kib_connparams_t; |
667 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "LNET %s", |
668 | 0 | val_to_str(pinfo->pool, ib_msg_type, lnet_ib_type, "Unknown(%d)")); |
669 | 0 | offset = dissect_struct_o2ib_connparam(tvb, lnet_tree, offset); |
670 | 0 | msg_filler_length = tvb_reported_length_remaining(tvb, offset); |
671 | 0 | ib_msg_payload = true; |
672 | 0 | break; |
673 | | |
674 | 0 | case IBLND_MSG_NOOP: |
675 | | // No further data |
676 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "LNET %s", |
677 | 0 | val_to_str(pinfo->pool, ib_msg_type, lnet_ib_type, "Unknown(%d)")); |
678 | 0 | ib_msg_payload = true; |
679 | 0 | break; |
680 | | |
681 | 0 | case IBLND_MSG_IMMEDIATE: |
682 | | // Normal LNET Message |
683 | 0 | break; |
684 | | |
685 | 0 | case IBLND_MSG_PUT_REQ: |
686 | | // kib_putreq_msg_t |
687 | | // lnet_hdr + cookie |
688 | 0 | break; |
689 | | |
690 | 0 | case IBLND_MSG_PUT_ACK: |
691 | | // kib_putack_msg_t; |
692 | | // src cookie + dest cookie + rdma_desc_t |
693 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "LNET %s", |
694 | 0 | val_to_str(pinfo->pool, ib_msg_type, lnet_ib_type, "Unknown(%d)")); |
695 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_src_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
696 | 0 | offset+=8; |
697 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_dest_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
698 | 0 | offset+=8; |
699 | 0 | offset = dissect_struct_rdma_desc(tvb, lnet_tree, offset); |
700 | 0 | ib_msg_payload = true; |
701 | 0 | break; |
702 | | |
703 | 0 | case IBLND_MSG_GET_REQ: |
704 | | // kib_get_msg_t |
705 | | // lnet_hdr + cookie + rdma_desc_t |
706 | 0 | break; |
707 | | |
708 | 0 | case IBLND_MSG_PUT_NAK: |
709 | 0 | case IBLND_MSG_PUT_DONE: |
710 | 0 | case IBLND_MSG_GET_DONE: |
711 | | // kib_completion_msg_t; |
712 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "LNET %s", |
713 | 0 | val_to_str(pinfo->pool, ib_msg_type, lnet_ib_type, "Unknown(%d)")); |
714 | |
|
715 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
716 | 0 | offset+=8; |
717 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_status, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
718 | 0 | offset+=4; |
719 | 0 | ib_msg_payload = true; |
720 | 0 | break; |
721 | 11 | } |
722 | | |
723 | 40 | } else { |
724 | | /* dissect the first 24 bytes (ksock_msg_t in |
725 | | * lnet/socklnd.h |
726 | | */ |
727 | 40 | offset = dissect_ksock_msg(tvb, pinfo, lnet_tree, offset); |
728 | 40 | } |
729 | | |
730 | 48 | if (!ib_msg_payload) { |
731 | | /* LNET HEADER */ |
732 | 48 | offset = lnet_dissect_struct_nid(tvb, pinfo, lnet_tree, offset, hf_lnet_dest_nid); |
733 | 48 | offset = lnet_dissect_struct_nid(tvb, pinfo, lnet_tree, offset, hf_lnet_src_nid); |
734 | | |
735 | | /* pid */ |
736 | 48 | proto_tree_add_item(lnet_tree, hf_lnet_src_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
737 | 48 | offset += 4; |
738 | 48 | proto_tree_add_item(lnet_tree, hf_lnet_dest_pid, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
739 | 48 | offset += 4; |
740 | | |
741 | | /* put some nice info on lnet line */ |
742 | 48 | proto_tree_add_item_ret_uint(lnet_tree, hf_lnet_msg_type, tvb, offset, 4, ENC_LITTLE_ENDIAN, &msg_type); |
743 | 48 | proto_item_append_text(ti, " %s", val_to_str(pinfo->pool, msg_type, lnet_msg_type, "Unknown(%d)")); |
744 | 48 | col_add_fstr(pinfo->cinfo, COL_INFO, "LNET_%s", val_to_str(pinfo->pool, msg_type, lnet_msg_type, "Unknown(%d)")); |
745 | 48 | offset += 4; |
746 | | |
747 | | /* payload data (to follow) length :*/ |
748 | 48 | proto_tree_add_item_ret_uint(lnet_tree, hf_lnet_payload_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &payload_length); |
749 | 48 | offset += 4; |
750 | | |
751 | 48 | match = 0; |
752 | 48 | switch (msg_type) { |
753 | 13 | case LNET_MSG_ACK: |
754 | 13 | offset = dissect_lnet_ack(tvb, lnet_tree, offset, &match); |
755 | 13 | break; |
756 | 2 | case LNET_MSG_PUT: |
757 | 2 | offset = dissect_lnet_put(tvb, pinfo, lnet_tree, offset, &match); |
758 | 2 | break; |
759 | 0 | case LNET_MSG_GET: |
760 | 0 | offset = dissect_lnet_get(tvb, pinfo, lnet_tree, offset, &match); |
761 | 0 | break; |
762 | 1 | case LNET_MSG_REPLY: |
763 | 1 | offset = dissect_lnet_reply(tvb, lnet_tree, offset); |
764 | 1 | break; |
765 | 1 | case LNET_MSG_HELLO: |
766 | 1 | offset = dissect_lnet_hello(tvb, lnet_tree, offset); |
767 | 1 | break; |
768 | 27 | default: |
769 | 27 | break; |
770 | 48 | } |
771 | | |
772 | 43 | switch (ib_msg_type) { |
773 | 41 | case 0: // not actually an ib_msg |
774 | 41 | break; |
775 | 0 | case IBLND_MSG_PUT_REQ: |
776 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
777 | 0 | offset += 8; |
778 | | /*@@ SAVE payload_length with O2IB cookie for IBLND_MSG_PUT_ACK */ |
779 | 0 | payload_length = 0; |
780 | 0 | break; |
781 | 0 | case IBLND_MSG_GET_REQ: |
782 | 0 | proto_tree_add_item(lnet_tree, hf_lnet_o2ib_cookie, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
783 | 0 | offset += 8; |
784 | 0 | offset = dissect_struct_rdma_desc(tvb, lnet_tree, offset); |
785 | 0 | break; |
786 | 43 | } |
787 | | |
788 | | /* padding */ |
789 | 43 | msg_filler_length = 72 - offset + 24 + extra_bytes; |
790 | | /* |
791 | | if (msg_filler_length > 72) |
792 | | goto out; |
793 | | */ |
794 | | /* +24 : ksock_message take 24bytes, and already in offset */ |
795 | 43 | } |
796 | | |
797 | 43 | if (msg_filler_length > 0) { |
798 | 41 | proto_tree_add_item(lnet_tree, hf_lnet_msg_filler, tvb, offset, msg_filler_length, ENC_NA); |
799 | 41 | offset += msg_filler_length; |
800 | 41 | } |
801 | | |
802 | 43 | if (payload_length > 0) { |
803 | 29 | tvbuff_t *next_tvb; |
804 | 29 | struct lnet_trans_info *conv; |
805 | | |
806 | 29 | next_tvb = tvb_new_subset_length(tvb, offset, payload_length); |
807 | 29 | switch (msg_type) { |
808 | 2 | case LNET_MSG_PUT: |
809 | 2 | conv = get_lnet_conv(pinfo, match); |
810 | | |
811 | 2 | offset += dissector_try_uint_with_data(subdissector_table, tvb_get_letohl(tvb, LNET_PTL_INDEX_OFFSET_PUT), |
812 | 2 | next_tvb, pinfo, tree, true, conv); |
813 | 2 | break; |
814 | 16 | default: |
815 | | /* display of payload */ |
816 | 16 | proto_tree_add_item(lnet_tree, hf_lnet_payload, tvb, offset, payload_length, ENC_NA); |
817 | 16 | offset += payload_length; |
818 | 16 | break; |
819 | 29 | } |
820 | 29 | } |
821 | | |
822 | 32 | if (tvb_captured_length(tvb) != offset) { |
823 | 14 | expert_add_info_format(pinfo, ti, &ei_lnet_buflen, |
824 | 14 | "Capture:%d offset:%d (length:%d) msg_type:%d ib_type:%02x", |
825 | 14 | tvb_captured_length(tvb), offset, msg_length, msg_type, ib_msg_type); |
826 | 14 | } |
827 | 32 | return offset; |
828 | 43 | } |
829 | | |
830 | | /********************************************************************\ |
831 | | * |
832 | | * Length Functions (these are SOCK LND only) |
833 | | * |
834 | | \********************************************************************/ |
835 | | #if 0 |
836 | | static unsigned |
837 | | get_lnet_ib_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
838 | | { |
839 | | uint32_t plen; |
840 | | |
841 | | /* Ensure this is an LNET IB segment */ |
842 | | if (tvb_get_letohl(tvb, 0) != LNET_PROTO_IB_MAGIC) |
843 | | return 0; |
844 | | |
845 | | /* Get the IB message length (see dissect_ib_msg() for .ibm_nob) |
846 | | */ |
847 | | plen = tvb_get_letohl(tvb, offset + 8); |
848 | | |
849 | | return plen; |
850 | | } |
851 | | #endif |
852 | | |
853 | | static unsigned |
854 | | get_lnet_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) |
855 | 42 | { |
856 | 42 | uint32_t plen; |
857 | 42 | unsigned extra_bytes = GPOINTER_TO_UINT(data); |
858 | | |
859 | | /* Get the payload length: |
860 | | * 24 = ksm header, |
861 | | * 28 = the rest of the headers |
862 | | */ |
863 | 42 | plen = tvb_get_letohl(tvb, offset + 28 + 24 + extra_bytes); |
864 | | |
865 | | /* That length doesn't include the header; add that in. |
866 | | * +24 == ksock msg header.. :D |
867 | | */ |
868 | 42 | return plen + 72 + 24 + extra_bytes; |
869 | 42 | } |
870 | | |
871 | | static unsigned |
872 | | get_noop_message_len(packet_info *pinfo _U_, tvbuff_t *tvb _U_, |
873 | | int offset _U_, void *data _U_) |
874 | 555 | { |
875 | 555 | return 24; |
876 | 555 | } |
877 | | |
878 | | /******************************************************************** \ |
879 | | * |
880 | | * Core Functions |
881 | | * |
882 | | \********************************************************************/ |
883 | | |
884 | | static int |
885 | | dissect_lnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
886 | 62 | { |
887 | 62 | switch (tvb_get_letohl(tvb, 0)) { |
888 | 45 | case KSOCK_MSG_NOOP: |
889 | 45 | tcp_dissect_pdus(tvb, pinfo, tree, true, 0, |
890 | 45 | get_noop_message_len, |
891 | 45 | dissect_ksock_msg_noop, GUINT_TO_POINTER(0)); |
892 | 45 | break; |
893 | 16 | case KSOCK_MSG_LNET: |
894 | 16 | tcp_dissect_pdus(tvb, pinfo, tree, true, LNET_HEADER_LEN, |
895 | 16 | get_lnet_message_len, |
896 | 16 | dissect_lnet_message, GUINT_TO_POINTER(0)); |
897 | 16 | break; |
898 | 62 | } |
899 | 16 | return tvb_captured_length(tvb); |
900 | 62 | } |
901 | | |
902 | | static bool |
903 | | dissect_lnet_ib_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
904 | 374 | { |
905 | | /* We can tell if this is an LNet payload by looking at the first |
906 | | * 32-bit word for our magic number. */ |
907 | 374 | if (tvb_captured_length(tvb) < 4 || tvb_get_letohl(tvb, 0) != LNET_PROTO_IB_MAGIC) |
908 | | /* Not an LNet payload. */ |
909 | 363 | return false; |
910 | | |
911 | 11 | dissect_lnet_message(tvb, pinfo, tree, GUINT_TO_POINTER(EXTRA_IB_HEADER_SIZE)); |
912 | 11 | return true; |
913 | 374 | } |
914 | | |
915 | | void |
916 | | proto_register_lnet(void) |
917 | 14 | { |
918 | 14 | static hf_register_info hf[] = { |
919 | 14 | { &hf_lnet_ksm_type, |
920 | 14 | { "Type of socklnd message", "lnet.ksm_type", FT_UINT32, BASE_HEX, VALS(ksm_type), 0x0, NULL, HFILL }}, |
921 | 14 | { &hf_lnet_ksm_csum, |
922 | 14 | { "Checksum", "lnet.ksm_csum", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
923 | 14 | { &hf_lnet_ksm_zc_req_cookie, |
924 | 14 | { "Ack required", "lnet.ksm_zc_req_cookie", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
925 | 14 | { &hf_lnet_ksm_zc_ack_cookie, |
926 | 14 | { "Ack", "lnet.ksm_zc_ack_cookie", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
927 | | |
928 | | /* Infiniband Fields */ |
929 | 14 | { &hf_lnet_ib_magic, |
930 | 14 | { "Magic of IB message", "lnet.ib.magic", FT_UINT32, BASE_HEX, VALS(lnet_magic), 0x0, NULL, HFILL} }, |
931 | 14 | { &hf_lnet_ib_version, |
932 | 14 | { "Version", "lnet.ib.version", FT_UINT16, BASE_HEX, VALS(ib_version_t), 0x0, NULL, HFILL} }, |
933 | 14 | { &hf_lnet_ib_type, |
934 | 14 | { "Type of IB message", "lnet.ib.type", FT_UINT8, BASE_HEX, VALS(lnet_ib_type), 0x0, NULL, HFILL} }, |
935 | 14 | { &hf_lnet_ib_credits, |
936 | 14 | { "Returned Credits", "lnet.ib.credits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} }, |
937 | 14 | { &hf_lnet_ib_nob, |
938 | 14 | { "Number of Bytes", "lnet.ib.nob", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} }, |
939 | 14 | { &hf_lnet_ib_csum, |
940 | 14 | { "Checksum", "lnet.ib_csum", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL} }, |
941 | 14 | { &hf_lnet_ib_srcstamp, |
942 | 14 | { "Sender Timestamp", "lnet.ib.srcstamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL }}, |
943 | 14 | { &hf_lnet_ib_dststamp, |
944 | 14 | { "Destination Timestamp", "lnet.ib.dststamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL }}, |
945 | | |
946 | 14 | { &hf_lnet_src_nid, |
947 | 14 | { "Src nid", "lnet.src_nid", FT_NONE, BASE_NONE, NULL, 0x0, "Source NID", HFILL }}, |
948 | 14 | { &hf_lnet_dest_nid, |
949 | 14 | { "Dest nid", "lnet.dest_nid", FT_NONE, BASE_NONE, NULL, 0x0, "Destination NID", HFILL }}, |
950 | | |
951 | 14 | { &hf_lnet_nid_addr, |
952 | 14 | { "lnd address", "lnet.nid.addr", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
953 | 14 | { &hf_lnet_nid_lnet_type, |
954 | 14 | { "lnd network type", "lnet.nid.type", FT_UINT16, BASE_DEC, VALS(lndnames), 0x0, NULL, HFILL }}, |
955 | 14 | { &hf_lnet_nid_interface, |
956 | 14 | { "lnd network interface", "lnet.nid.net_interface", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
957 | | |
958 | 14 | { &hf_lnet_dest_pid, |
959 | 14 | { "Dest pid", "lnet.dest_pid", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, "Destination pid", HFILL }}, |
960 | 14 | { &hf_lnet_src_pid, |
961 | 14 | { "Src pid", "lnet.src_pid", FT_UINT32, BASE_DEC_HEX, NULL, 0x0, "Source nid", HFILL }}, |
962 | | |
963 | 14 | { &hf_lnet_msg_type, |
964 | 14 | { "Message type", "lnet.msg_type", FT_UINT32, BASE_DEC, VALS(lnet_msg_type), 0x0, NULL, HFILL }}, |
965 | 14 | { &hf_lnet_payload_length, |
966 | 14 | { "Payload length", "lnet.payload_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
967 | 14 | { &hf_lnet_payload, |
968 | 14 | { "Payload", "lnet.payload", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
969 | | |
970 | 14 | { &hf_dst_wmd_interface, |
971 | 14 | { "DST MD index interface", "lnet.msg_dst_interface_cookie", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, |
972 | 14 | { &hf_dst_wmd_object, |
973 | 14 | { "DST MD index object", "lnet.msg_dst_object_cookie", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, |
974 | 14 | { &hf_match_bits, |
975 | 14 | { "Match bits", "lnet.msg_dst_match_bits", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL}}, |
976 | 14 | { &hf_mlength, |
977 | 14 | { "Message length", "lnet.msg_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
978 | | |
979 | | /* Put */ |
980 | 14 | { &hf_hdr_data, |
981 | 14 | { "hdr data", "lnet.msg_hdr_data", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL}}, |
982 | 14 | { &hf_ptl_index, |
983 | 14 | { "ptl index", "lnet.ptl_index", FT_UINT32, BASE_DEC, VALS(portal_index), 0x0, NULL, HFILL}}, |
984 | 14 | { &hf_offset, |
985 | 14 | { "offset", "lnet.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
986 | | |
987 | | /* Get*/ |
988 | 14 | { &hf_src_offset, |
989 | 14 | { "src offset", "lnet.src_offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
990 | 14 | { &hf_sink_length, |
991 | 14 | { "sink length", "lnet.sink_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
992 | | |
993 | | /* Hello */ |
994 | 14 | { &hf_hello_incarnation, |
995 | 14 | { "hello incarnation", "lnet.hello_incarnation", FT_UINT64, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL}}, |
996 | 14 | { &hf_hello_type, |
997 | 14 | { "hello type", "lnet.hello_type", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, |
998 | | |
999 | 14 | { &hf_lnet_msg_filler, |
1000 | 14 | { "msg filler (padding)", "lnet.ptl_filler", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
1001 | | |
1002 | | /* O2IB Specific */ |
1003 | 14 | { &hf_lnet_o2ib_connparam, |
1004 | 14 | { "O2IB ConnParam", "lnet.connparam", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
1005 | 14 | { &hf_lnet_o2ib_connparam_qdepth, |
1006 | 14 | { "Queue Depth", "lnet.connparam.qdepth", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1007 | 14 | { &hf_lnet_o2ib_connparam_max_frags, |
1008 | 14 | { "Max Fragments", "lnet.connparam.max_frags", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1009 | 14 | { &hf_lnet_o2ib_connparam_max_size, |
1010 | 14 | { "Max Msg Size", "lnet.connparam.max_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1011 | | |
1012 | 14 | { &hf_lnet_o2ib_cookie, |
1013 | 14 | { "O2IB Cookie", "lnet.o2ib.cookie", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1014 | 14 | { &hf_lnet_o2ib_src_cookie, |
1015 | 14 | { "O2IB Source Cookie", "lnet.o2ib.src_cookie", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1016 | 14 | { &hf_lnet_o2ib_dest_cookie, |
1017 | 14 | { "O2IB Dest Cookie", "lnet.o2ib.dest_cookie", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1018 | 14 | { &hf_lnet_o2ib_status, |
1019 | 14 | { "O2IB Status", "lnet.o2ib.status", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1020 | | |
1021 | 14 | { &hf_lnet_rdma_desc, |
1022 | 14 | { "RDMA Description", "lnet.rdma", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
1023 | 14 | { &hf_lnet_rdma_desc_key, |
1024 | 14 | { "RDMA Key", "lnet.rdma.key", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1025 | 14 | { &hf_lnet_rdma_desc_nfrags, |
1026 | 14 | { "RDMA # of Fragments", "lnet.rdma.nfrags", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1027 | | |
1028 | 14 | { &hf_lnet_rdma_frag_size, |
1029 | 14 | { "RDMA Frag Size (bytes)", "lnet.rdma_frag.size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1030 | 14 | { &hf_lnet_rdma_frag_addr, |
1031 | 14 | { "RDMA Frag Address", "lnet.rdma_frag.addr", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1032 | 14 | }; |
1033 | | |
1034 | 14 | static int *ett[] = { |
1035 | 14 | &ett_lnet, |
1036 | 14 | &ett_lnet_nid, |
1037 | 14 | &ett_lnet_o2ib_connparams, |
1038 | 14 | &ett_lnet_rdma_desc, |
1039 | 14 | &ett_lnet_rdma_frag, |
1040 | 14 | }; |
1041 | | |
1042 | 14 | expert_module_t *expert_lnet; |
1043 | 14 | static ei_register_info ei[] = { |
1044 | 14 | { &ei_lnet_buflen, |
1045 | 14 | { "lnet.bad_buflen", PI_MALFORMED, PI_ERROR, "Buffer length mis-match", EXPFILL } }, |
1046 | 14 | { &ei_lnet_type, |
1047 | 14 | { "lnet.bad_type", PI_PROTOCOL, PI_ERROR, "LNET Type mis-match", EXPFILL } } |
1048 | 14 | }; |
1049 | | |
1050 | 14 | proto_lnet = proto_register_protocol("Lustre Network", "LNet", "lnet"); |
1051 | | |
1052 | 14 | proto_register_field_array(proto_lnet, hf, array_length(hf)); |
1053 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
1054 | 14 | expert_lnet = expert_register_protocol(proto_lnet); |
1055 | 14 | expert_register_field_array(expert_lnet, ei, array_length(ei)); |
1056 | | |
1057 | 14 | lnet_handle = register_dissector("lnet", dissect_lnet, proto_lnet); |
1058 | | |
1059 | 14 | subdissector_table = register_dissector_table("lnet.ptl_index", "lnet portal index", |
1060 | 14 | proto_lnet, |
1061 | 14 | FT_UINT32 , BASE_DEC); |
1062 | 14 | } |
1063 | | |
1064 | | void |
1065 | | proto_reg_handoff_lnet(void) |
1066 | 14 | { |
1067 | 14 | heur_dissector_add("infiniband.payload", dissect_lnet_ib_heur, "LNet over IB", |
1068 | 14 | "lnet_ib", proto_lnet, HEURISTIC_ENABLE); |
1069 | 14 | heur_dissector_add("infiniband.mad.cm.private", dissect_lnet_ib_heur, "LNet over IB CM", |
1070 | 14 | "lnet_ib_cm_private", proto_lnet, HEURISTIC_ENABLE); |
1071 | 14 | dissector_add_for_decode_as("infiniband", lnet_handle); |
1072 | 14 | dissector_add_uint_with_preference("tcp.port", LNET_TCP_PORT, lnet_handle); |
1073 | 14 | } |
1074 | | |
1075 | | /* |
1076 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1077 | | * |
1078 | | * Local variables: |
1079 | | * c-basic-offset: 4 |
1080 | | * tab-width: 8 |
1081 | | * indent-tabs-mode: nil |
1082 | | * End: |
1083 | | * |
1084 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1085 | | * :indentSize=4:tabSize=8:noTabs=true: |
1086 | | */ |