Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */