/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 | | */ |