Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-netlink-ovs_vport.c
Line
Count
Source
1
/* packet-netlink-ovs_vport.c
2
 * Routines for Open vSwitch virtual port netlink protocol dissection
3
 * Copyright 2026, Red Hat Inc.
4
 * By Timothy Redaelli <tredaelli@redhat.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/* ovs_vport manages Open vSwitch virtual ports via Generic Netlink.
14
 * Each vport is bound to a datapath and has a type (netdev, internal,
15
 * GRE, VXLAN, Geneve), a port number, and optional tunnel options.
16
 *
17
 * Relevant Linux kernel header file:
18
 * include/uapi/linux/openvswitch.h
19
 */
20
21
#include "config.h"
22
23
#include <epan/packet.h>
24
25
#include "packet-netlink.h"
26
27
void proto_register_netlink_ovs_vport(void);
28
void proto_reg_handoff_netlink_ovs_vport(void);
29
30
/* from <include/uapi/linux/openvswitch.h> prefixed with WS_ */
31
enum ws_ovs_vport_cmd {
32
  WS_OVS_VPORT_CMD_UNSPEC,
33
  WS_OVS_VPORT_CMD_NEW,
34
  WS_OVS_VPORT_CMD_DEL,
35
  WS_OVS_VPORT_CMD_GET,
36
  WS_OVS_VPORT_CMD_SET,
37
};
38
39
enum ws_ovs_vport_type {
40
  WS_OVS_VPORT_TYPE_UNSPEC,
41
  WS_OVS_VPORT_TYPE_NETDEV,
42
  WS_OVS_VPORT_TYPE_INTERNAL,
43
  WS_OVS_VPORT_TYPE_GRE,
44
  WS_OVS_VPORT_TYPE_VXLAN,
45
  WS_OVS_VPORT_TYPE_GENEVE,
46
};
47
48
enum ws_ovs_vport_attr {
49
  WS_OVS_VPORT_ATTR_UNSPEC,
50
  WS_OVS_VPORT_ATTR_PORT_NO,
51
  WS_OVS_VPORT_ATTR_TYPE,
52
  WS_OVS_VPORT_ATTR_NAME,
53
  WS_OVS_VPORT_ATTR_OPTIONS,
54
  WS_OVS_VPORT_ATTR_UPCALL_PID,
55
  WS_OVS_VPORT_ATTR_STATS,
56
  WS_OVS_VPORT_ATTR_PAD,
57
  WS_OVS_VPORT_ATTR_IFINDEX,
58
  WS_OVS_VPORT_ATTR_NETNSID,
59
  WS_OVS_VPORT_ATTR_UPCALL_STATS,
60
};
61
62
enum ws_ovs_tunnel_attr {
63
  WS_OVS_TUNNEL_ATTR_UNSPEC,
64
  WS_OVS_TUNNEL_ATTR_DST_PORT,
65
  WS_OVS_TUNNEL_ATTR_EXTENSION,
66
};
67
68
enum ws_ovs_vxlan_ext {
69
  WS_OVS_VXLAN_EXT_UNSPEC,
70
  WS_OVS_VXLAN_EXT_GBP,
71
};
72
73
enum ws_ovs_vport_upcall_attr {
74
  WS_OVS_VPORT_UPCALL_ATTR_SUCCESS,
75
  WS_OVS_VPORT_UPCALL_ATTR_FAIL,
76
};
77
78
static const value_string ws_ovs_vport_commands_vals[] = {
79
  { WS_OVS_VPORT_CMD_UNSPEC,  "OVS_VPORT_CMD_UNSPEC" },
80
  { WS_OVS_VPORT_CMD_NEW, "OVS_VPORT_CMD_NEW" },
81
  { WS_OVS_VPORT_CMD_DEL, "OVS_VPORT_CMD_DEL" },
82
  { WS_OVS_VPORT_CMD_GET, "OVS_VPORT_CMD_GET" },
83
  { WS_OVS_VPORT_CMD_SET, "OVS_VPORT_CMD_SET" },
84
  { 0, NULL }
85
};
86
87
static const value_string ws_ovs_vport_type_vals[] = {
88
  { WS_OVS_VPORT_TYPE_UNSPEC, "OVS_VPORT_TYPE_UNSPEC" },
89
  { WS_OVS_VPORT_TYPE_NETDEV, "OVS_VPORT_TYPE_NETDEV" },
90
  { WS_OVS_VPORT_TYPE_INTERNAL, "OVS_VPORT_TYPE_INTERNAL" },
91
  { WS_OVS_VPORT_TYPE_GRE,  "OVS_VPORT_TYPE_GRE" },
92
  { WS_OVS_VPORT_TYPE_VXLAN,  "OVS_VPORT_TYPE_VXLAN" },
93
  { WS_OVS_VPORT_TYPE_GENEVE, "OVS_VPORT_TYPE_GENEVE" },
94
  { 0, NULL }
95
};
96
97
static const value_string ws_ovs_vport_attr_vals[] = {
98
  { WS_OVS_VPORT_ATTR_UNSPEC,   "OVS_VPORT_ATTR_UNSPEC" },
99
  { WS_OVS_VPORT_ATTR_PORT_NO,    "OVS_VPORT_ATTR_PORT_NO" },
100
  { WS_OVS_VPORT_ATTR_TYPE,   "OVS_VPORT_ATTR_TYPE" },
101
  { WS_OVS_VPORT_ATTR_NAME,   "OVS_VPORT_ATTR_NAME" },
102
  { WS_OVS_VPORT_ATTR_OPTIONS,    "OVS_VPORT_ATTR_OPTIONS" },
103
  { WS_OVS_VPORT_ATTR_UPCALL_PID, "OVS_VPORT_ATTR_UPCALL_PID" },
104
  { WS_OVS_VPORT_ATTR_STATS,    "OVS_VPORT_ATTR_STATS" },
105
  { WS_OVS_VPORT_ATTR_PAD,    "OVS_VPORT_ATTR_PAD" },
106
  { WS_OVS_VPORT_ATTR_IFINDEX,    "OVS_VPORT_ATTR_IFINDEX" },
107
  { WS_OVS_VPORT_ATTR_NETNSID,    "OVS_VPORT_ATTR_NETNSID" },
108
  { WS_OVS_VPORT_ATTR_UPCALL_STATS, "OVS_VPORT_ATTR_UPCALL_STATS" },
109
  { 0, NULL }
110
};
111
112
static const value_string ws_ovs_tunnel_attr_vals[] = {
113
  { WS_OVS_TUNNEL_ATTR_UNSPEC,    "OVS_TUNNEL_ATTR_UNSPEC" },
114
  { WS_OVS_TUNNEL_ATTR_DST_PORT,    "OVS_TUNNEL_ATTR_DST_PORT" },
115
  { WS_OVS_TUNNEL_ATTR_EXTENSION, "OVS_TUNNEL_ATTR_EXTENSION" },
116
  { 0, NULL }
117
};
118
119
static const value_string ws_ovs_vxlan_ext_vals[] = {
120
  { WS_OVS_VXLAN_EXT_UNSPEC,  "OVS_VXLAN_EXT_UNSPEC" },
121
  { WS_OVS_VXLAN_EXT_GBP, "OVS_VXLAN_EXT_GBP" },
122
  { 0, NULL }
123
};
124
125
static const value_string ws_ovs_vport_upcall_attr_vals[] = {
126
  { WS_OVS_VPORT_UPCALL_ATTR_SUCCESS, "OVS_VPORT_UPCALL_ATTR_SUCCESS" },
127
  { WS_OVS_VPORT_UPCALL_ATTR_FAIL,  "OVS_VPORT_UPCALL_ATTR_FAIL" },
128
  { 0, NULL }
129
};
130
131
struct netlink_ovs_vport_info {
132
  packet_info *pinfo;
133
};
134
135
static dissector_handle_t netlink_ovs_vport_handle;
136
137
static int proto_netlink_ovs_vport;
138
139
static int hf_ovs_vport_commands;
140
static int hf_ovs_vport_dp_ifindex;
141
static int hf_ovs_vport_attr;
142
static int hf_ovs_vport_port_no;
143
static int hf_ovs_vport_type;
144
static int hf_ovs_vport_name;
145
static int hf_ovs_vport_upcall_pid;
146
static int hf_ovs_vport_ifindex;
147
static int hf_ovs_vport_netnsid;
148
static int hf_ovs_vport_stats_rx_packets;
149
static int hf_ovs_vport_stats_tx_packets;
150
static int hf_ovs_vport_stats_rx_bytes;
151
static int hf_ovs_vport_stats_tx_bytes;
152
static int hf_ovs_vport_stats_rx_errors;
153
static int hf_ovs_vport_stats_tx_errors;
154
static int hf_ovs_vport_stats_rx_dropped;
155
static int hf_ovs_vport_stats_tx_dropped;
156
static int hf_ovs_vport_tunnel_attr;
157
static int hf_ovs_vport_tunnel_dst_port;
158
static int hf_ovs_vport_vxlan_ext_attr;
159
static int hf_ovs_vport_vxlan_ext_gbp;
160
static int hf_ovs_vport_upcall_stats_attr;
161
static int hf_ovs_vport_upcall_success;
162
static int hf_ovs_vport_upcall_fail;
163
164
static int ett_ovs_vport;
165
static int ett_ovs_vport_attrs;
166
static int ett_ovs_vport_stats;
167
static int ett_ovs_vport_tunnel_attrs;
168
static int ett_ovs_vport_vxlan_ext_attrs;
169
static int ett_ovs_vport_upcall_stats_attrs;
170
171
static int
172
dissect_ovs_vport_vxlan_ext_attrs(tvbuff_t *tvb, void *data _U_,
173
  struct packet_netlink_data *nl_data, proto_tree *tree,
174
  int nla_type, int offset, int len)
175
0
{
176
0
  enum ws_ovs_vxlan_ext type = (enum ws_ovs_vxlan_ext) nla_type;
177
178
0
  switch (type) {
179
0
  case WS_OVS_VXLAN_EXT_GBP:
180
0
    if (len == 4) {
181
0
      proto_tree_add_item(tree, hf_ovs_vport_vxlan_ext_gbp, tvb,
182
0
        offset, 4, nl_data->encoding);
183
0
      return 1;
184
0
    }
185
0
    return 0;
186
0
  default:
187
0
    return 0;
188
0
  }
189
0
}
190
191
static int
192
dissect_ovs_vport_tunnel_attrs(tvbuff_t *tvb, void *data,
193
  struct packet_netlink_data *nl_data, proto_tree *tree,
194
  int nla_type, int offset, int len)
195
0
{
196
0
  enum ws_ovs_tunnel_attr type = (enum ws_ovs_tunnel_attr) nla_type;
197
198
0
  switch (type) {
199
0
  case WS_OVS_TUNNEL_ATTR_DST_PORT:
200
0
    if (len == 2) {
201
0
      proto_tree_add_item(tree, hf_ovs_vport_tunnel_dst_port, tvb,
202
0
        offset, 2, nl_data->encoding);
203
0
      return 1;
204
0
    }
205
0
    return 0;
206
0
  case WS_OVS_TUNNEL_ATTR_EXTENSION:
207
0
    return dissect_netlink_attributes(tvb,
208
0
      hf_ovs_vport_vxlan_ext_attr,
209
0
      ett_ovs_vport_vxlan_ext_attrs, data, nl_data,
210
0
      tree, offset, len,
211
0
      dissect_ovs_vport_vxlan_ext_attrs);
212
0
  default:
213
0
    return 0;
214
0
  }
215
0
}
216
217
static int
218
dissect_ovs_vport_upcall_stats_attrs(tvbuff_t *tvb, void *data _U_,
219
  struct packet_netlink_data *nl_data, proto_tree *tree,
220
  int nla_type, int offset, int len)
221
0
{
222
0
  enum ws_ovs_vport_upcall_attr type =
223
0
    (enum ws_ovs_vport_upcall_attr) nla_type;
224
225
0
  switch (type) {
226
0
  case WS_OVS_VPORT_UPCALL_ATTR_SUCCESS:
227
0
    if (len == 8) {
228
0
      proto_tree_add_item(tree, hf_ovs_vport_upcall_success, tvb,
229
0
        offset, 8, nl_data->encoding);
230
0
      return 1;
231
0
    }
232
0
    return 0;
233
0
  case WS_OVS_VPORT_UPCALL_ATTR_FAIL:
234
0
    if (len == 8) {
235
0
      proto_tree_add_item(tree, hf_ovs_vport_upcall_fail, tvb,
236
0
        offset, 8, nl_data->encoding);
237
0
      return 1;
238
0
    }
239
0
    return 0;
240
0
  default:
241
0
    return 0;
242
0
  }
243
0
}
244
245
static int
246
dissect_ovs_vport_attrs(tvbuff_t *tvb, void *data,
247
  struct packet_netlink_data *nl_data, proto_tree *tree,
248
  int nla_type, int offset, int len)
249
0
{
250
0
  enum ws_ovs_vport_attr type = (enum ws_ovs_vport_attr) nla_type;
251
0
  struct netlink_ovs_vport_info *info =
252
0
    (struct netlink_ovs_vport_info *) data;
253
0
  uint32_t value;
254
0
  const uint8_t *str;
255
0
  proto_item *pi;
256
0
  proto_tree *ptree;
257
258
0
  switch (type) {
259
0
  case WS_OVS_VPORT_ATTR_PORT_NO:
260
0
    proto_tree_add_item_ret_uint(tree, hf_ovs_vport_port_no, tvb,
261
0
      offset, 4, nl_data->encoding, &value);
262
0
    proto_item_append_text(tree, ": %u", value);
263
0
    return 1;
264
265
0
  case WS_OVS_VPORT_ATTR_TYPE:
266
0
    DISSECTOR_ASSERT(info);
267
0
    proto_tree_add_item_ret_uint(tree, hf_ovs_vport_type,
268
0
      tvb, offset, 4, nl_data->encoding, &value);
269
0
    proto_item_append_text(tree, ": %s",
270
0
      val_to_str(info->pinfo->pool, value,
271
0
        ws_ovs_vport_type_vals,
272
0
        "Unknown (%u)"));
273
0
    return 1;
274
275
0
  case WS_OVS_VPORT_ATTR_NAME:
276
0
    DISSECTOR_ASSERT(info);
277
0
    proto_tree_add_item_ret_string(tree,
278
0
      hf_ovs_vport_name, tvb,
279
0
      offset, len, ENC_ASCII | ENC_NA,
280
0
      info->pinfo->pool, &str);
281
0
    proto_item_append_text(tree, ": %s", str);
282
0
    return 1;
283
284
0
  case WS_OVS_VPORT_ATTR_OPTIONS:
285
0
    return dissect_netlink_attributes(tvb,
286
0
      hf_ovs_vport_tunnel_attr,
287
0
      ett_ovs_vport_tunnel_attrs, data, nl_data,
288
0
      tree, offset, len,
289
0
      dissect_ovs_vport_tunnel_attrs);
290
291
0
  case WS_OVS_VPORT_ATTR_UPCALL_PID:
292
0
    for (int i = 0; i + 4 <= len; i += 4) {
293
0
      proto_tree_add_item(tree,
294
0
        hf_ovs_vport_upcall_pid, tvb,
295
0
        offset + i, 4, nl_data->encoding);
296
0
    }
297
0
    return 1;
298
299
0
  case WS_OVS_VPORT_ATTR_STATS:
300
    /* struct ovs_vport_stats: 8 x u64 counters = 64 bytes */
301
0
    if (len == 64) {
302
0
      int off = offset;
303
0
      pi = proto_tree_add_subtree(tree, tvb, offset,
304
0
        len, ett_ovs_vport_stats, NULL, "Vport Statistics");
305
0
      ptree = proto_item_add_subtree(pi, ett_ovs_vport_stats);
306
0
      proto_tree_add_item(ptree,
307
0
        hf_ovs_vport_stats_rx_packets, tvb, off, 8,
308
0
        nl_data->encoding);
309
0
      off += 8;
310
0
      proto_tree_add_item(ptree,
311
0
        hf_ovs_vport_stats_tx_packets, tvb, off, 8,
312
0
        nl_data->encoding);
313
0
      off += 8;
314
0
      proto_tree_add_item(ptree,
315
0
        hf_ovs_vport_stats_rx_bytes, tvb, off, 8,
316
0
        nl_data->encoding);
317
0
      off += 8;
318
0
      proto_tree_add_item(ptree,
319
0
        hf_ovs_vport_stats_tx_bytes, tvb, off, 8,
320
0
        nl_data->encoding);
321
0
      off += 8;
322
0
      proto_tree_add_item(ptree,
323
0
        hf_ovs_vport_stats_rx_errors, tvb, off, 8,
324
0
        nl_data->encoding);
325
0
      off += 8;
326
0
      proto_tree_add_item(ptree,
327
0
        hf_ovs_vport_stats_tx_errors, tvb, off, 8,
328
0
        nl_data->encoding);
329
0
      off += 8;
330
0
      proto_tree_add_item(ptree,
331
0
        hf_ovs_vport_stats_rx_dropped, tvb, off, 8,
332
0
        nl_data->encoding);
333
0
      off += 8;
334
0
      proto_tree_add_item(ptree,
335
0
        hf_ovs_vport_stats_tx_dropped, tvb, off, 8,
336
0
        nl_data->encoding);
337
0
      return 1;
338
0
    }
339
0
    return 0;
340
341
0
  case WS_OVS_VPORT_ATTR_IFINDEX:
342
0
    proto_tree_add_item_ret_uint(tree, hf_ovs_vport_ifindex, tvb,
343
0
      offset, 4, nl_data->encoding, &value);
344
0
    proto_item_append_text(tree, ": %u", value);
345
0
    return 1;
346
347
0
  case WS_OVS_VPORT_ATTR_NETNSID:
348
0
    proto_tree_add_item_ret_uint(tree, hf_ovs_vport_netnsid, tvb,
349
0
      offset, 4, nl_data->encoding, &value);
350
0
    proto_item_append_text(tree, ": %u", value);
351
0
    return 1;
352
353
0
  case WS_OVS_VPORT_ATTR_UPCALL_STATS:
354
0
    return dissect_netlink_attributes(tvb,
355
0
      hf_ovs_vport_upcall_stats_attr,
356
0
      ett_ovs_vport_upcall_stats_attrs, data, nl_data,
357
0
      tree, offset, len,
358
0
      dissect_ovs_vport_upcall_stats_attrs);
359
360
0
  default:
361
0
    return 0;
362
0
  }
363
0
}
364
365
static int
366
dissect_netlink_ovs_vport(tvbuff_t *tvb, packet_info *pinfo,
367
  proto_tree *tree, void *data)
368
0
{
369
0
  genl_info_t *genl_info = (genl_info_t *) data;
370
0
  struct netlink_ovs_vport_info info;
371
0
  proto_tree *nlmsg_tree;
372
0
  proto_item *pi;
373
0
  int offset;
374
375
0
  DISSECTOR_ASSERT(genl_info);
376
377
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ovs_vport");
378
0
  col_clear(pinfo->cinfo, COL_INFO);
379
380
0
  offset = dissect_genl_header(tvb, genl_info, genl_info->nl_data,
381
0
    hf_ovs_vport_commands);
382
383
0
  if (tvb_reported_length_remaining(tvb, offset) < 4)
384
0
    return offset;
385
386
0
  pi = proto_tree_add_item(tree, proto_netlink_ovs_vport, tvb, offset,
387
0
    -1, ENC_NA);
388
0
  nlmsg_tree = proto_item_add_subtree(pi, ett_ovs_vport);
389
390
0
  proto_tree_add_item(nlmsg_tree, hf_ovs_vport_dp_ifindex, tvb, offset,
391
0
    4, genl_info->nl_data->encoding);
392
0
  offset += 4;
393
394
0
  if (!tvb_reported_length_remaining(tvb, offset))
395
0
    return offset;
396
397
0
  info.pinfo = pinfo;
398
0
  offset = dissect_netlink_attributes_to_end(tvb, hf_ovs_vport_attr,
399
0
    ett_ovs_vport_attrs, &info, genl_info->nl_data,
400
0
    nlmsg_tree, offset, dissect_ovs_vport_attrs);
401
402
0
  return offset;
403
0
}
404
405
void
406
proto_register_netlink_ovs_vport(void)
407
15
{
408
15
  static hf_register_info hf[] = {
409
15
    { &hf_ovs_vport_commands,
410
15
      { "Command", "ovs_vport.cmd",
411
15
        FT_UINT8, BASE_DEC, VALS(ws_ovs_vport_commands_vals),
412
15
        0x00, NULL, HFILL }
413
15
    },
414
15
    { &hf_ovs_vport_dp_ifindex,
415
15
      { "Datapath ifindex", "ovs_vport.dp_ifindex",
416
15
        FT_INT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
417
15
    },
418
15
    { &hf_ovs_vport_attr,
419
15
      { "Attribute type", "ovs_vport.attr_type",
420
15
        FT_UINT16, BASE_DEC, VALS(ws_ovs_vport_attr_vals),
421
15
        NLA_TYPE_MASK, NULL, HFILL }
422
15
    },
423
15
    { &hf_ovs_vport_port_no,
424
15
      { "Port number", "ovs_vport.port_no",
425
15
        FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
426
15
    },
427
15
    { &hf_ovs_vport_type,
428
15
      { "Vport type", "ovs_vport.type",
429
15
        FT_UINT32, BASE_DEC, VALS(ws_ovs_vport_type_vals),
430
15
        0x00, NULL, HFILL }
431
15
    },
432
15
    { &hf_ovs_vport_name,
433
15
      { "Name", "ovs_vport.name",
434
15
        FT_STRINGZ, BASE_NONE, NULL, 0x00, NULL, HFILL }
435
15
    },
436
15
    { &hf_ovs_vport_upcall_pid,
437
15
      { "Upcall PID", "ovs_vport.upcall_pid",
438
15
        FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
439
15
    },
440
15
    { &hf_ovs_vport_ifindex,
441
15
      { "Interface index", "ovs_vport.ifindex",
442
15
        FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
443
15
    },
444
15
    { &hf_ovs_vport_netnsid,
445
15
      { "Network namespace ID", "ovs_vport.netnsid",
446
15
        FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
447
15
    },
448
15
    { &hf_ovs_vport_stats_rx_packets,
449
15
      { "Rx packets", "ovs_vport.stats.rx_packets",
450
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
451
15
    },
452
15
    { &hf_ovs_vport_stats_tx_packets,
453
15
      { "Tx packets", "ovs_vport.stats.tx_packets",
454
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
455
15
    },
456
15
    { &hf_ovs_vport_stats_rx_bytes,
457
15
      { "Rx bytes", "ovs_vport.stats.rx_bytes",
458
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
459
15
    },
460
15
    { &hf_ovs_vport_stats_tx_bytes,
461
15
      { "Tx bytes", "ovs_vport.stats.tx_bytes",
462
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
463
15
    },
464
15
    { &hf_ovs_vport_stats_rx_errors,
465
15
      { "Rx errors", "ovs_vport.stats.rx_errors",
466
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
467
15
    },
468
15
    { &hf_ovs_vport_stats_tx_errors,
469
15
      { "Tx errors", "ovs_vport.stats.tx_errors",
470
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
471
15
    },
472
15
    { &hf_ovs_vport_stats_rx_dropped,
473
15
      { "Rx dropped", "ovs_vport.stats.rx_dropped",
474
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
475
15
    },
476
15
    { &hf_ovs_vport_stats_tx_dropped,
477
15
      { "Tx dropped", "ovs_vport.stats.tx_dropped",
478
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
479
15
    },
480
15
    { &hf_ovs_vport_tunnel_attr,
481
15
      { "Tunnel attribute type", "ovs_vport.tunnel.attr_type",
482
15
        FT_UINT16, BASE_DEC, VALS(ws_ovs_tunnel_attr_vals),
483
15
        NLA_TYPE_MASK, NULL, HFILL }
484
15
    },
485
15
    { &hf_ovs_vport_tunnel_dst_port,
486
15
      { "Tunnel destination port",
487
15
        "ovs_vport.tunnel.dst_port",
488
15
        FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL }
489
15
    },
490
15
    { &hf_ovs_vport_vxlan_ext_attr,
491
15
      { "VXLAN extension attribute type",
492
15
        "ovs_vport.vxlan_ext.attr_type",
493
15
        FT_UINT16, BASE_DEC, VALS(ws_ovs_vxlan_ext_vals),
494
15
        NLA_TYPE_MASK, NULL, HFILL }
495
15
    },
496
15
    { &hf_ovs_vport_vxlan_ext_gbp,
497
15
      { "VXLAN GBP", "ovs_vport.vxlan_ext.gbp",
498
15
        FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
499
15
    },
500
15
    { &hf_ovs_vport_upcall_stats_attr,
501
15
      { "Upcall stats attribute type",
502
15
        "ovs_vport.upcall_stats.attr_type",
503
15
        FT_UINT16, BASE_DEC,
504
15
        VALS(ws_ovs_vport_upcall_attr_vals),
505
15
        NLA_TYPE_MASK, NULL, HFILL }
506
15
    },
507
15
    { &hf_ovs_vport_upcall_success,
508
15
      { "Upcall success", "ovs_vport.upcall_stats.success",
509
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
510
15
    },
511
15
    { &hf_ovs_vport_upcall_fail,
512
15
      { "Upcall fail", "ovs_vport.upcall_stats.fail",
513
15
        FT_UINT64, BASE_DEC, NULL, 0x00, NULL, HFILL }
514
15
    },
515
15
  };
516
517
15
  static int *ett[] = {
518
15
    &ett_ovs_vport,
519
15
    &ett_ovs_vport_attrs,
520
15
    &ett_ovs_vport_stats,
521
15
    &ett_ovs_vport_tunnel_attrs,
522
15
    &ett_ovs_vport_vxlan_ext_attrs,
523
15
    &ett_ovs_vport_upcall_stats_attrs,
524
15
  };
525
526
15
  proto_netlink_ovs_vport = proto_register_protocol(
527
15
    "Linux ovs_vport (Open vSwitch Vport) protocol",
528
15
    "ovs_vport", "ovs_vport");
529
15
  proto_register_field_array(proto_netlink_ovs_vport, hf,
530
15
    array_length(hf));
531
15
  proto_register_subtree_array(ett, array_length(ett));
532
533
15
  netlink_ovs_vport_handle = register_dissector("ovs_vport",
534
15
    dissect_netlink_ovs_vport, proto_netlink_ovs_vport);
535
15
}
536
537
void
538
proto_reg_handoff_netlink_ovs_vport(void)
539
15
{
540
15
  dissector_add_string("genl.family", "ovs_vport",
541
15
    netlink_ovs_vport_handle);
542
15
}
543
544
/*
545
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
546
 *
547
 * Local variables:
548
 * c-basic-offset: 8
549
 * tab-width: 8
550
 * indent-tabs-mode: t
551
 * End:
552
 *
553
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
554
 * :indentSize=8:tabSize=8:noTabs=false:
555
 */