aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-openflow_v6.c
diff options
context:
space:
mode:
authorChristophe GUERBER <christophe.guerber@gmail.com>2019-01-17 09:51:31 +0100
committerAnders Broman <a.broman58@gmail.com>2019-01-20 07:49:46 +0000
commit77c9b211249c6ac4caa0f5ce41869f568495e756 (patch)
treed39831e1a98b5db3ff4b85b9f987fdf75a5dd39f /epan/dissectors/packet-openflow_v6.c
parent7c1d99cb895a31e9b6d6263a16cad569737ec30f (diff)
OpenFlow 1.5: implement version specific parts
B.18.1 Egress Tables (EXT-306): B.18.2 Packet Type aware pipeline (EXT-112) B.18.3 Extensible Flow Entry Statistics (EXT-334) B.18.4 Flow Entry Statistics Trigger (EXT-335) B.18.6 Packet Register pipeline fields (EXT-244) B.18.11 Scheduled Bundles (EXT-340) B.18.12 Controller connection status (EXT-454) B.18.14 Enable setting all pipeline fields in packet-out (EXT-427) B.18.15 Port properties for pipeline fields (EXT-388) B.18.16 Port property for recirculation (EXT-399) B.18.21 Rename some type for consistency (EXT-302) Change-Id: I02d2370f6cf661e400bb8b690213589cd030a541 Reviewed-on: https://code.wireshark.org/review/31566 Reviewed-by: Jaap Keuter <jaap.keuter@xs4all.nl> Petri-Dish: Jaap Keuter <jaap.keuter@xs4all.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-openflow_v6.c')
-rw-r--r--epan/dissectors/packet-openflow_v6.c1716
1 files changed, 1237 insertions, 479 deletions
diff --git a/epan/dissectors/packet-openflow_v6.c b/epan/dissectors/packet-openflow_v6.c
index 3ea3a408fe..70e84b081a 100644
--- a/epan/dissectors/packet-openflow_v6.c
+++ b/epan/dissectors/packet-openflow_v6.c
@@ -60,6 +60,7 @@ static int hf_openflow_v6_action_type = -1;
static int hf_openflow_v6_action_length = -1;
static int hf_openflow_v6_action_experimenter_experimenter = -1;
static int hf_openflow_v6_oxm_experimenter_value = -1;
+static int hf_openflow_v6_oxm_register = -1;
static int hf_openflow_v6_action_output_port = -1;
static int hf_openflow_v6_action_output_max_len = -1;
static int hf_openflow_v6_action_output_pad = -1;
@@ -98,7 +99,6 @@ static int hf_openflow_v6_instruction_write_metadata_pad = -1;
static int hf_openflow_v6_instruction_write_metadata_value = -1;
static int hf_openflow_v6_instruction_write_metadata_mask = -1;
static int hf_openflow_v6_instruction_actions_pad = -1;
-static int hf_openflow_v6_instruction_meter_meter_id = -1;
static int hf_openflow_v6_port_desc_prop_type = -1;
static int hf_openflow_v6_port_desc_prop_length = -1;
static int hf_openflow_v6_port_desc_prop_ethernet_pad = -1;
@@ -285,6 +285,8 @@ static int hf_openflow_v6_switch_features_capabilities_group_stats = -1;
static int hf_openflow_v6_switch_features_capabilities_ip_reasm = -1;
static int hf_openflow_v6_switch_features_capabilities_queue_stats = -1;
static int hf_openflow_v6_switch_features_capabilities_port_blocked = -1;
+static int hf_openflow_v6_switch_features_capabilities_bundles = -1;
+static int hf_openflow_v6_switch_features_capabilities_flow_monitoring = -1;
static int hf_openflow_v6_switch_features_reserved = -1;
static int hf_openflow_v6_switch_config_flags = -1;
static int hf_openflow_v6_switch_config_flags_fragments = -1;
@@ -299,16 +301,11 @@ static int hf_openflow_v6_flow_removed_cookie = -1;
static int hf_openflow_v6_flow_removed_priority = -1;
static int hf_openflow_v6_flow_removed_reason = -1;
static int hf_openflow_v6_flow_removed_table_id = -1;
-static int hf_openflow_v6_flow_removed_duration_sec = -1;
-static int hf_openflow_v6_flow_removed_duration_nsec = -1;
static int hf_openflow_v6_flow_removed_idle_timeout = -1;
static int hf_openflow_v6_flow_removed_hard_timeout = -1;
-static int hf_openflow_v6_flow_removed_packet_count = -1;
-static int hf_openflow_v6_flow_removed_byte_count = -1;
static int hf_openflow_v6_port_status_reason = -1;
static int hf_openflow_v6_port_status_pad = -1;
static int hf_openflow_v6_packet_out_buffer_id = -1;
-static int hf_openflow_v6_packet_out_in_port = -1;
static int hf_openflow_v6_packet_out_acts_len = -1;
static int hf_openflow_v6_packet_out_pad = -1;
static int hf_openflow_v6_flowmod_cookie = -1;
@@ -469,27 +466,10 @@ static int hf_openflow_v6_switch_description_serial_num = -1;
static int hf_openflow_v6_switch_description_dp_desc = -1;
static int hf_openflow_v6_flow_stats_length = -1;
static int hf_openflow_v6_flow_stats_table_id = -1;
-static int hf_openflow_v6_flow_stats_pad = -1;
static int hf_openflow_v6_flow_stats_duration_sec = -1;
static int hf_openflow_v6_flow_stats_duration_nsec = -1;
static int hf_openflow_v6_flow_stats_priority = -1;
-static int hf_openflow_v6_flow_stats_idle_timeout = -1;
-static int hf_openflow_v6_flow_stats_hard_timeout = -1;
-static int hf_openflow_v6_flow_stats_flags = -1;
-static int hf_openflow_v6_flow_stats_flags_send_flow_rem = -1;
-static int hf_openflow_v6_flow_stats_flags_check_overlap = -1;
-static int hf_openflow_v6_flow_stats_flags_reset_counts = -1;
-static int hf_openflow_v6_flow_stats_flags_no_packet_counts = -1;
-static int hf_openflow_v6_flow_stats_flags_no_byte_counts = -1;
-static int hf_openflow_v6_flow_stats_importance = -1;
static int hf_openflow_v6_flow_stats_pad2 = -1;
-static int hf_openflow_v6_flow_stats_cookie = -1;
-static int hf_openflow_v6_flow_stats_packet_count = -1;
-static int hf_openflow_v6_flow_stats_byte_count = -1;
-static int hf_openflow_v6_aggregate_stats_packet_count = -1;
-static int hf_openflow_v6_aggregate_stats_byte_count = -1;
-static int hf_openflow_v6_aggregate_stats_flow_count = -1;
-static int hf_openflow_v6_aggregate_stats_pad = -1;
static int hf_openflow_v6_table_stats_table_id = -1;
static int hf_openflow_v6_table_stats_pad = -1;
static int hf_openflow_v6_table_stats_active_count = -1;
@@ -755,6 +735,66 @@ static int hf_openflow_v6_bundle_add_pad = -1;
static int hf_openflow_v6_bundle_add_flags = -1;
static int hf_openflow_v6_bundle_add_flags_atomic = -1;
static int hf_openflow_v6_bundle_add_flags_ordered = -1;
+static int hf_openflow_v6_oxs_class = -1;
+static int hf_openflow_v6_oxs_field = -1;
+static int hf_openflow_v6_oxs_reserved = -1;
+static int hf_openflow_v6_oxs_length = -1;
+static int hf_openflow_v6_oxs_basic_duration_sec = -1;
+static int hf_openflow_v6_oxs_basic_duration_nsec = -1;
+static int hf_openflow_v6_oxs_basic_idle_sec = -1;
+static int hf_openflow_v6_oxs_basic_idle_nsec = -1;
+static int hf_openflow_v6_oxs_basic_flow_count = -1;
+static int hf_openflow_v6_oxs_basic_packet_count = -1;
+static int hf_openflow_v6_oxs_basic_byte_count = -1;
+static int hf_openflow_v6_oxs_experimenter_experimenter = -1;
+static int hf_openflow_v6_oxs_experimenter_value = -1;
+static int hf_openflow_v6_instruction_stat_trigger_flags = -1;
+static int hf_openflow_v6_instruction_stat_triffer_flags_periodic = -1;
+static int hf_openflow_v6_instruction_stat_triffer_flags_only_first = -1;
+static int hf_openflow_v6_instruction_stat_triffer_flags_reserved = -1;
+static int hf_openflow_v6_port_desc_prop_recirculate_port_no = -1;
+static int hf_openflow_v6_bundle_features_request_flags = -1;
+static int hf_openflow_v6_bundle_features_request_pad = -1;
+static int hf_openflow_v6_stats_reserved = -1;
+static int hf_openflow_v6_stats_length = -1;
+static int hf_openflow_v6_stats_pad = -1;
+static int hf_openflow_v6_flow_desc_length = -1;
+static int hf_openflow_v6_flow_desc_pad2 = -1;
+static int hf_openflow_v6_flow_desc_table_id = -1;
+static int hf_openflow_v6_flow_desc_pad = -1;
+static int hf_openflow_v6_flow_desc_priority = -1;
+static int hf_openflow_v6_flow_desc_idle_timeout = -1;
+static int hf_openflow_v6_flow_desc_hard_timeout = -1;
+static int hf_openflow_v6_flow_desc_flags = -1;
+static int hf_openflow_v6_flow_desc_flags_send_flow_rem = -1;
+static int hf_openflow_v6_flow_desc_flags_check_overlap = -1;
+static int hf_openflow_v6_flow_desc_flags_reset_counts = -1;
+static int hf_openflow_v6_flow_desc_flags_no_packet_counts = -1;
+static int hf_openflow_v6_flow_desc_flags_no_byte_counts = -1;
+static int hf_openflow_v6_flow_desc_importance = -1;
+static int hf_openflow_v6_flow_desc_cookie = -1;
+static int hf_openflow_v6_controller_status_length = -1;
+static int hf_openflow_v6_controller_status_short_id = -1;
+static int hf_openflow_v6_controller_status_role = -1;
+static int hf_openflow_v6_controller_status_reason = -1;
+static int hf_openflow_v6_controller_status_channel_status = -1;
+static int hf_openflow_v6_controller_status_pad = -1;
+static int hf_openflow_v6_time_seconds = -1;
+static int hf_openflow_v6_time_nanoseconds = -1;
+static int hf_openflow_v6_time_pad = -1;
+static int hf_openflow_v6_bundle_feature_prop_type = -1;
+static int hf_openflow_v6_bundle_feature_prop_length = -1;
+static int hf_openflow_v6_bundle_feature_prop_time_pad = -1;
+static int hf_openflow_v6_bundle_feature_prop_experimenter_experimenter = -1;
+static int hf_openflow_v6_bundle_feature_prop_experimenter_exp_type = -1;
+static int hf_openflow_v6_bundle_feature_prop_pad = -1;
+static int hf_openflow_v6_controller_status_prop_type = -1;
+static int hf_openflow_v6_controller_status_prop_length = -1;
+static int hf_openflow_v6_controller_status_prop_experimenter_experimenter = -1;
+static int hf_openflow_v6_controller_status_prop_experimenter_exp_type = -1;
+static int hf_openflow_v6_controller_status_prop_pad = -1;
+static int hf_openflow_v6_flow_stats_reason = -1;
+static int hf_openflow_v6_controller_status_prop_uri = -1;
static gint ett_openflow_v6 = -1;
static gint ett_openflow_v6_flowmod_flags = -1;
@@ -798,7 +838,6 @@ static gint ett_openflow_v6_table_feature_prop_oxm_id = -1;
static gint ett_openflow_v6_flow_monitor_request_flags = -1;
static gint ett_openflow_v6_multipart_request_flags = -1;
static gint ett_openflow_v6_flow_stats = -1;
-static gint ett_openflow_v6_flow_stats_flags = -1;
static gint ett_openflow_v6_table_stats = -1;
static gint ett_openflow_v6_port_stats = -1;
static gint ett_openflow_v6_queue_stats = -1;
@@ -837,6 +876,11 @@ static gint ett_openflow_v6_bundle_control_flags = -1;
static gint ett_openflow_v6_bundle_prop = -1;
static gint ett_openflow_v6_bundle_add_flags = -1;
static gint ett_openflow_v6_bundle_add_message = -1;
+static gint ett_openflow_v6_instruction_stat_trigger_flags = -1;
+static gint ett_openflow_v6_flow_desc = -1;
+static gint ett_openflow_v6_flow_desc_flags = -1;
+static gint ett_openflow_v6_bundle_feature_prop = -1;
+static gint ett_openflow_v6_controller_status_prop = -1;
static expert_field ei_openflow_v6_match_undecoded = EI_INIT;
static expert_field ei_openflow_v6_oxm_undecoded = EI_INIT;
@@ -860,6 +904,8 @@ static expert_field ei_openflow_v6_async_config_prop_undecoded = EI_INIT;
static expert_field ei_openflow_v6_bundle_prop_undecoded = EI_INIT;
static expert_field ei_openflow_v6_message_undecoded = EI_INIT;
static expert_field ei_openflow_v6_length_too_short = EI_INIT;
+static expert_field ei_openflow_v6_bundle_feature_prop_undecoded = EI_INIT;
+static expert_field ei_openflow_v6_controller_status_prop_undecoded = EI_INIT;
static const value_string openflow_v6_version_values[] = {
{ 0x06, "1.5" },
@@ -899,6 +945,7 @@ static const value_string openflow_v6_version_values[] = {
#define OFPT_REQUESTFORWARD 32
#define OFPT_BUNDLE_CONTROL 33
#define OFPT_BUNDLE_ADD_MESSAGE 34
+#define OFPT_CONTROLLER_STATUS 35
static const value_string openflow_v6_type_values[] = {
{ OFPT_HELLO, "OFPT_HELLO" },
{ OFPT_ERROR, "OFPT_ERROR" },
@@ -933,6 +980,7 @@ static const value_string openflow_v6_type_values[] = {
{ OFPT_REQUESTFORWARD, "OFPT_REQUESTFORWARD" },
{ OFPT_BUNDLE_CONTROL, "OFPT_BUNDLE_CONTROL" },
{ OFPT_BUNDLE_ADD_MESSAGE, "OFPT_BUNDLE_ADD_MESSAGE" },
+ { OFPT_CONTROLLER_STATUS, "OFPT_CONTROLLER_STATUS" },
{ 0, NULL }
};
static value_string_ext openflow_v6_type_values_ext = VALUE_STRING_EXT_INIT(openflow_v6_type_values);
@@ -992,14 +1040,126 @@ static const value_string openflow_v6_buffer_reserved_values[] = {
{ 0, NULL}
};
+/*
+ * OXS
+ */
+#define OFPXSC_OPENFLOW_BASIC 0x8002
+#define OFPXSC_EXPERIMENTER 0xFFFF
+static const value_string openflow_v6_oxs_class_values[] = {
+ { OFPXSC_OPENFLOW_BASIC, "OFPXSC_OPENFLOW_BASIC" },
+ { OFPXSC_EXPERIMENTER, "OFPXSC_EXPERIMENTER" },
+ { 0, NULL }
+};
+
+#define OFPXST_OFB_DURATION 0 /* Time flow entry has been alive. */
+#define OFPXST_OFB_IDLE_TIME 1 /* Time flow entry has been idle. */
+#define OFPXST_OFB_FLOW_COUNT 3 /* Number of aggregated flow entries. */
+#define OFPXST_OFB_PACKET_COUNT 4 /* Number of packets in flow entry. */
+#define OFPXST_OFB_BYTE_COUNT 5 /* Number of bytes in flow entry. */
+static const value_string openflow_v6_oxs_basic_field_values[] = {
+ { OFPXST_OFB_DURATION, "OFPXST_OFB_DURATION" },
+ { OFPXST_OFB_IDLE_TIME, "OFPXST_OFB_IDLE_TIME" },
+ { OFPXST_OFB_FLOW_COUNT, "OFPXST_OFB_FLOW_COUNT" },
+ { OFPXST_OFB_PACKET_COUNT, "OFPXST_OFB_PACKET_COUNT" },
+ { OFPXST_OFB_BYTE_COUNT, "OFPXST_OFB_BYTE_COUNT" },
+ { 0, NULL }
+};
+
+#define OXS_FIELD_MASK 0xfe
+#define OXS_RESERVED_MASK 0x01
+
+static int
+dissect_openflow_v6_oxs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ guint32 oxs_class;
+ guint32 oxs_field;
+ guint32 oxs_payload_length;
+
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxs_class, tvb, offset, 2, ENC_BIG_ENDIAN, &oxs_class);
+ offset+=2;
+
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxs_field, tvb, offset, 1, ENC_BIG_ENDIAN, &oxs_field);
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
+
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxs_length, tvb, offset, 1, ENC_BIG_ENDIAN, &oxs_payload_length);
+ offset+=1;
+
+ if (oxs_class == OFPXSC_OPENFLOW_BASIC) {
+ switch (oxs_field) {
+ case OFPXST_OFB_DURATION:
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_duration_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_duration_nsec, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+ break;
+ case OFPXST_OFB_IDLE_TIME:
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_idle_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_idle_nsec, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+ break;
+ case OFPXST_OFB_FLOW_COUNT:
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_flow_count, tvb, offset, 4, ENC_BIG_ENDIAN);
+ break;
+ case OFPXST_OFB_PACKET_COUNT:
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
+ break;
+ case OFPXST_OFB_BYTE_COUNT:
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_basic_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
+ break;
+ }
+ } else if (oxs_class == OFPXSC_EXPERIMENTER) {
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN);
+
+ proto_tree_add_item(tree, hf_openflow_v6_oxs_experimenter_value, tvb, offset+4, oxs_payload_length - 4, ENC_NA);
+ }
+ offset+=oxs_payload_length;
+
+ return offset;
+}
+
+static int
+dissect_openflow_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ guint32 stats_length;
+ int oxs_end;
+ guint32 padding;
+
+ proto_tree_add_item(tree, hf_openflow_v6_stats_reserved, tvb, offset, 2, ENC_NA);
+
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_stats_length, tvb, offset+2, 2, ENC_BIG_ENDIAN, &stats_length);
+
+ oxs_end = offset + stats_length;
+ offset+=4;
+
+ while (offset < oxs_end) {
+ offset = dissect_openflow_v6_oxs(tvb, pinfo, tree, offset, oxs_end - offset);
+ }
+
+ if (offset > oxs_end) {
+ // XXX EI if offset > oxs_end?
+ offset = oxs_end;
+ }
+
+ padding = ((stats_length + 7) & ~7) - stats_length;
+ if (padding) {
+ proto_tree_add_item(tree, hf_openflow_v6_stats_pad, tvb, oxs_end, padding, ENC_NA);
+ offset += padding;
+ }
+
+ return offset;
+}
+
+/*
+ * OXM
+ */
#define OFPXMC_NXM_0 0x0000 /* Backward compatibility with NXM */
#define OFPXMC_NXM_1 0x0001 /* Backward compatibility with NXM */
#define OFPXMC_OPENFLOW_BASIC 0x8000 /* Basic class for OpenFlow */
+#define OFPXMC_PACKET_REGS 0x8001 /* Packet registers (pipeline fields). */
#define OFPXMC_EXPERIMENTER 0xFFFF /* Experimenter class */
static const value_string openflow_v6_oxm_class_values[] = {
{ 0x0000, "OFPXMC_NMX_0" },
{ 0x0001, "OFPXMC_NXM_1" },
{ 0x8000, "OFPXMC_OPENFLOW_BASIC" },
+ { 0x8001, "OFPXMC_PACKET_REGS" },
{ 0xFFFF, "OFPXMC_EXPERIMENTER" },
{ 0, NULL}
};
@@ -1097,34 +1257,69 @@ static const value_string openflow_v6_oxm_basic_field_values[] = {
};
static value_string_ext openflow_v6_oxm_basic_field_values_ext = VALUE_STRING_EXT_INIT(openflow_v6_oxm_basic_field_values);
+#define OFPHTN_ONF 0
+#define OFPHTN_ETHERTYPE 1
+#define OFPHTN_IP_PROTO 2
+#define OFPHTN_UDP_TCP_PORT 3
+#define OFPHTN_IPV4_OPTION 4
+static const value_string openflow_v6_header_type_namespace_values[] = {
+ { OFPHTN_ONF, "OFPHTN_ONF" },
+ { OFPHTN_ETHERTYPE, "OFPHTN_ETHERTYPE" },
+ { OFPHTN_IP_PROTO, "OFPHTN_IP_PROTO" },
+ { OFPHTN_UDP_TCP_PORT, "OFPHTN_UDP_TCP_PORT" },
+ { OFPHTN_IPV4_OPTION, "OFPHTN_IPV4_OPTION" },
+ { 0, NULL }
+};
+
#define OXM_FIELD_MASK 0xfe
-#define OXM_FIELD_OFFSET 1
#define OXM_HM_MASK 0x01
+
+typedef struct oxm_header {
+ guint32 oxm_class;
+ guint32 oxm_hm;
+ guint32 oxm_field;
+ guint32 oxm_length;
+} oxm_header;
static int
-dissect_openflow_oxm_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+dissect_openflow_oxm_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_, oxm_header *retval)
{
- guint16 oxm_class;
+ guint32 oxm_class;
+ guint32 oxm_hm;
+ guint32 oxm_field;
+ guint32 oxm_length;
/* oxm_class */
- oxm_class = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_oxm_class, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_class, tvb, offset, 2, ENC_BIG_ENDIAN, &oxm_class);
offset+=2;
/* oxm_field */
- if (oxm_class == OFPXMC_OPENFLOW_BASIC) {
- proto_tree_add_bits_item(tree, hf_openflow_v6_oxm_field_basic, tvb, (offset * 8), 7, ENC_NA);
- } else {
- proto_tree_add_bits_item(tree, hf_openflow_v6_oxm_field, tvb, (offset * 8), 7, ENC_NA);
+ switch (oxm_class) {
+ case OFPXMC_OPENFLOW_BASIC:
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_field_basic, tvb, (offset * 8), 7, ENC_NA, &oxm_field);
+ break;
+ case OFPXMC_PACKET_REGS:
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_register, tvb, offset, 1, ENC_BIG_ENDIAN, &oxm_field);
+ break;
+ default:
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_field, tvb, offset, 1, ENC_BIG_ENDIAN, &oxm_field);
+ break;
}
/* oxm_hm */
- proto_tree_add_bits_item(tree, hf_openflow_v6_oxm_hm, tvb, (offset * 8) + 7, 1, ENC_NA);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_hm, tvb, offset, 1, ENC_BIG_ENDIAN, &oxm_hm);
offset+=1;
/* oxm_length */
- proto_tree_add_item(tree, hf_openflow_v6_oxm_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_oxm_length, tvb, offset, 1, ENC_BIG_ENDIAN, &oxm_length);
offset+=1;
+ if (retval) {
+ retval->oxm_class = oxm_class;
+ retval->oxm_hm = oxm_hm;
+ retval->oxm_field = oxm_field;
+ retval->oxm_length = oxm_length;
+ }
+
return offset;
}
@@ -1134,31 +1329,26 @@ static int
dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *oxm_tree;
- guint16 oxm_class;
guint16 oxm_end;
- guint8 oxm_field_hm;
- guint8 oxm_hm;
- guint8 oxm_field;
- guint8 oxm_length;
+ oxm_header header;
guint8 field_length;
+ guint32 packet_type_namespace;
+ proto_item *ti;
- oxm_class = tvb_get_ntohs(tvb, offset);
- oxm_field_hm = tvb_get_guint8(tvb, offset + 2);
- oxm_length = tvb_get_guint8(tvb, offset + 3);
- oxm_end = offset + 4 + oxm_length;
+ header.oxm_length = tvb_get_guint8(tvb, offset + 3);
- oxm_field = (oxm_field_hm & OXM_FIELD_MASK) >> OXM_FIELD_OFFSET;
- oxm_hm = oxm_field_hm & OXM_HM_MASK;
- field_length = (oxm_hm == 0) ? oxm_length : (oxm_length / 2);
+ oxm_tree = proto_tree_add_subtree(tree, tvb, offset, header.oxm_length + 4, ett_openflow_v6_oxm, NULL, "OXM field");
- oxm_tree = proto_tree_add_subtree(tree, tvb, offset, oxm_length + 4, ett_openflow_v6_oxm, NULL, "OXM field");
+ offset = dissect_openflow_oxm_header_v6(tvb, pinfo, oxm_tree, offset, length, &header);
- offset = dissect_openflow_oxm_header_v6(tvb, pinfo, oxm_tree, offset, length);
+ oxm_end = offset + 4 + header.oxm_length;
+ field_length = (header.oxm_hm == 0) ? header.oxm_length : (header.oxm_length / 2);
- if (oxm_class == OFPXMC_OPENFLOW_BASIC) {
- switch(oxm_field) {
+ if (header.oxm_class == OFPXMC_OPENFLOW_BASIC) {
+ switch(header.oxm_field) {
case OFPXMT_OFB_IN_PORT:
case OFPXMT_OFB_IN_PHY_PORT:
+ case OFPXMT_OFB_ACTSET_OUTPUT:
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_uint32, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
break;
@@ -1171,7 +1361,7 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
case OFPXMT_OFB_IPV6_ND_TLL: /*The target link-layer address option in an IPv6 Neighbor Discovery message */
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_etheraddr, tvb, offset, 6, ENC_NA);
offset+=6;
- if (oxm_hm) {
+ if (header.oxm_hm) {
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask_etheraddr, tvb, offset, 6, ENC_NA);
offset+=6;
}
@@ -1186,7 +1376,7 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_vlan_present, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_vlan_vid, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
- if (oxm_hm) {
+ if (header.oxm_hm) {
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask_vlan, tvb, offset, 2, ENC_NA);
offset+=2;
}
@@ -1203,7 +1393,7 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
case OFPXMT_OFB_ARP_TPA:
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_ipv4addr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
- if (oxm_hm) {
+ if (header.oxm_hm) {
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask_ipv4addr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
}
@@ -1223,7 +1413,7 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
case OFPXMT_OFB_IPV6_DST:
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_ipv6addr, tvb, offset, 16, ENC_NA);
offset+=16;
- if (oxm_hm) {
+ if (header.oxm_hm) {
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask_ipv6addr, tvb, offset, 16, ENC_NA);
offset+=16;
}
@@ -1240,6 +1430,15 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
}
break;
+ case OFPXMT_OFB_PACKET_TYPE:
+ ti = proto_tree_add_item_ret_uint(oxm_tree, hf_openflow_v6_oxm_value_uint16, tvb, offset, 2, ENC_BIG_ENDIAN, &packet_type_namespace);
+ proto_item_append_text(ti, " (%s)", val_to_str_const(packet_type_namespace, openflow_v6_header_type_namespace_values, "Unknown"));
+ offset+=2;
+
+ proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value_uint16, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+ break;
+
default:
/* value */
if (field_length > 0) {
@@ -1248,7 +1447,7 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
}
/* mask */
- if (field_length > 0 && oxm_hm != 0) {
+ if (field_length > 0 && header.oxm_hm != 0) {
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask, tvb, offset, field_length, ENC_NA);
offset += field_length;
}
@@ -1261,16 +1460,23 @@ dissect_openflow_oxm_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
offset = oxm_end;
}
- } else if (oxm_class == OFPXMC_EXPERIMENTER) {
+ } else if (header.oxm_class == OFPXMC_PACKET_REGS) {
+ proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_value, tvb, offset, 8, ENC_NA);
+ offset+=8;
+ if (header.oxm_hm) {
+ proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_mask, tvb, offset, 8, ENC_NA);
+ offset+=8;
+ }
+ } else if (header.oxm_class == OFPXMC_EXPERIMENTER) {
/* uint32_t experimenter; */
proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
- proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_experimenter_value, tvb, offset, oxm_length - 4, ENC_NA);
- offset+=(oxm_length - 4);
+ proto_tree_add_item(oxm_tree, hf_openflow_v6_oxm_experimenter_value, tvb, offset, header.oxm_length - 4, ENC_NA);
+ offset+=(header.oxm_length - 4);
} else {
proto_tree_add_expert_format(oxm_tree, pinfo, &ei_openflow_v6_oxm_undecoded,
- tvb, offset, oxm_length, "Unknown OXM body.");
- offset+=oxm_length;
+ tvb, offset, header.oxm_length, "Unknown OXM body.");
+ offset+=header.oxm_length;
}
return offset;
@@ -1289,7 +1495,7 @@ dissect_openflow_match_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
{
proto_item *ti;
proto_tree *match_tree;
- guint16 match_type;
+ guint32 match_type;
guint16 match_length;
gint32 fields_end;
guint16 pad_length;
@@ -1297,8 +1503,7 @@ dissect_openflow_match_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
match_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_match, &ti, "Match");
/* uint16_t type; */
- match_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(match_tree, hf_openflow_v6_match_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(match_tree, hf_openflow_v6_match_type, tvb, offset, 2, ENC_BIG_ENDIAN, &match_type);
offset+=2;
/* uint16_t length; (excluding padding) */
@@ -1372,14 +1577,13 @@ dissect_openflow_meter_band_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
{
proto_item *ti;
proto_tree *band_tree;
- guint16 band_type;
+ guint32 band_type;
guint16 band_len;
band_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_meter_band, &ti, "Meter band");
/* uint16_t type; */
- band_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(band_tree, hf_openflow_v6_meter_band_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(band_tree, hf_openflow_v6_meter_band_type, tvb, offset, 2, ENC_BIG_ENDIAN, &band_type);
offset+=2;
/* uint16_t len; */
@@ -1450,15 +1654,14 @@ static int
dissect_openflow_hello_element_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length)
{
proto_tree *elem_tree;
- guint16 elem_type;
+ guint32 elem_type;
guint16 elem_length;
guint16 pad_length;
elem_tree = proto_tree_add_subtree(tree, tvb, offset, length - offset, ett_openflow_v6_hello_element, NULL, "Element");
/* uint16_t type; */
- elem_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(elem_tree, hf_openflow_v6_hello_element_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(elem_tree, hf_openflow_v6_hello_element_type, tvb, offset, 2, ENC_BIG_ENDIAN, &elem_type);
offset+=2;
/* uint16_t length; */
@@ -1774,11 +1977,10 @@ dissect_openflow_error_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
{
proto_tree *data_tree;
proto_item *data_ti;
- guint16 error_type;
+ guint32 error_type;
/* uint16_t type; */
- error_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_error_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_error_type, tvb, offset, 2, ENC_BIG_ENDIAN, &error_type);
offset +=2;
/* uint16_t code; */
@@ -1937,13 +2139,16 @@ dissect_openflow_experimenter_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
}
}
-#define OFPC_FLOW_STATS 1<<0
-#define OFPC_TABLE_STATS 1<<1
-#define OFPC_PORT_STATS 1<<2
-#define OFPC_GROUP_STATS 1<<3
-#define OFPC_IP_REASM 1<<5
-#define OFPC_QUEUE_STATS 1<<6
-#define OFPC_PORT_BLOCKED 1<<8
+#define OFPC_FLOW_STATS 1<<0 /* Flow statistics. */
+#define OFPC_TABLE_STATS 1<<1 /* Table statistics. */
+#define OFPC_PORT_STATS 1<<2 /* Port statistics. */
+#define OFPC_GROUP_STATS 1<<3 /* Group statistics. */
+#define OFPC_IP_REASM 1<<5 /* Can reassemble IP fragments. */
+#define OFPC_QUEUE_STATS 1<<6 /* Queue statistics. */
+#define OFPC_PORT_BLOCKED 1<<8 /* Switch will block looping ports. */
+#define OFPC_BUNDLES 1<<9 /* Switch supports bundles. */
+#define OFPC_FLOW_MONITORING 1<<10 /* Switch supports flow monitoring. */
+
static void
dissect_openflow_switch_features_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
@@ -1981,6 +2186,8 @@ dissect_openflow_switch_features_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
proto_tree_add_item(cap_tree, hf_openflow_v6_switch_features_capabilities_ip_reasm, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(cap_tree, hf_openflow_v6_switch_features_capabilities_queue_stats, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(cap_tree, hf_openflow_v6_switch_features_capabilities_port_blocked, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(cap_tree, hf_openflow_v6_switch_features_capabilities_bundles, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(cap_tree, hf_openflow_v6_switch_features_capabilities_flow_monitoring, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
/* uint32_t reserved; */
@@ -2123,29 +2330,17 @@ static const value_string openflow_v6_flow_removed_reason_values[] = {
static void
dissect_openflow_flow_removed_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
- /* uint64_t cookie; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
-
- /* uint16_t priority; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset+=2;
-
- /* uint8_t reason; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset+=1;
-
/* uint8_t table_id; */
proto_tree_add_item(tree, hf_openflow_v6_flow_removed_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
offset+=1;
- /* uint32_t duration_sec; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_duration_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
+ /* uint8_t reason; */
+ proto_tree_add_item(tree, hf_openflow_v6_flow_removed_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
- /* uint32_t duration_nsec; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_duration_nsec, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
+ /* uint16_t priority; */
+ proto_tree_add_item(tree, hf_openflow_v6_flow_removed_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
/* uint16_t idle_timeout; */
proto_tree_add_item(tree, hf_openflow_v6_flow_removed_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
@@ -2155,16 +2350,15 @@ dissect_openflow_flow_removed_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
proto_tree_add_item(tree, hf_openflow_v6_flow_removed_hard_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
- /* uint64_t packet_count; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
-
- /* uint64_t byte_count; */
- proto_tree_add_item(tree, hf_openflow_v6_flow_removed_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
+ /* uint64_t cookie; */
+ proto_tree_add_item(tree, hf_openflow_v6_flow_removed_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
offset+=8;
/* struct ofp_match match; */
- dissect_openflow_match_v6(tvb, pinfo, tree, offset, length);
+ offset = dissect_openflow_match_v6(tvb, pinfo, tree, offset, length);
+
+ /* struct ofp_stats */
+ dissect_openflow_stats_v6(tvb, pinfo, tree, offset, length);
}
#define OFPAT_OUTPUT 0 /* Output to switch port. */
@@ -2215,11 +2409,10 @@ static const value_string openflow_v6_action_type_values[] = {
static int
dissect_openflow_action_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
- guint16 act_type;
+ guint32 act_type;
/* uint16_t type; */
- act_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_action_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_action_type, tvb, offset, 2, ENC_BIG_ENDIAN, &act_type);
offset+=2;
/* uint16_t length; */
@@ -2620,14 +2813,20 @@ dissect_openflow_port_desc_prop_optical_v6(tvbuff_t *tvb, packet_info *pinfo _U_
-#define OFPPDPT_ETHERNET 0
-#define OFPPDPT_OPTICAL 1
+#define OFPPDPT_ETHERNET 0
+#define OFPPDPT_OPTICAL 1
+#define OFPPDPT_PIPELINE_INPUT 2
+#define OFPPDPT_PIPELINE_OUTPUT 3
+#define OFPPDPT_RECIRCULATE 4
#define OFPPDPT_EXPERIMENTER 0xFFFF
static const value_string openflow_v6_port_desc_prop_type_values[] = {
- { OFPPDPT_ETHERNET, "OFPPDPT_ETHERNET" },
- { OFPPDPT_OPTICAL, "OFPPDPT_OPTICAL" },
- { OFPPDPT_EXPERIMENTER, "OFPPDPT_EXPERIMENTER" },
- { 0, NULL }
+ { OFPPDPT_ETHERNET, "OFPPDPT_ETHERNET" },
+ { OFPPDPT_OPTICAL, "OFPPDPT_OPTICAL" },
+ { OFPPDPT_PIPELINE_INPUT, "OFPPDPT_PIPELINE_INPUT" },
+ { OFPPDPT_PIPELINE_OUTPUT, "OFPPDPT_PIPELINE_OUTPUT" },
+ { OFPPDPT_RECIRCULATE, "OFPPDPT_RECIRCULATE" },
+ { OFPPDPT_EXPERIMENTER, "OFPPDPT_EXPERIMENTER" },
+ { 0, NULL }
};
static int
@@ -2635,20 +2834,18 @@ dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
{
proto_tree *prop_tree;
proto_item *prop_item;
- guint16 prop_type;
- guint16 prop_length;
-
- prop_type = tvb_get_ntohs(tvb, offset);
- prop_length = tvb_get_ntohs(tvb, offset);
+ guint32 prop_type;
+ guint32 prop_length;
+ int fields_end;
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_length, ett_openflow_v6_port_desc_prop, NULL, "Port desc. property");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_port_desc_prop, NULL, "Port desc. property");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_port_desc_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_port_desc_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_port_desc_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_port_desc_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
offset+=2;
switch (prop_type) {
@@ -2660,6 +2857,24 @@ dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
offset = dissect_openflow_port_desc_prop_optical_v6(tvb, pinfo, prop_tree, offset, length);
break;
+ case OFPPDPT_PIPELINE_INPUT:
+ case OFPPDPT_PIPELINE_OUTPUT:
+ fields_end = offset + prop_length - 4;
+ while(offset < fields_end) {
+ offset = dissect_openflow_oxm_v6(tvb, pinfo, prop_tree, offset, length);
+ }
+ offset+=((prop_length + 7) & ~7) - prop_length;
+ break;
+
+ case OFPPDPT_RECIRCULATE:
+ fields_end = offset + prop_length - 4;
+ while(offset < fields_end) {
+ proto_tree_add_item(tree, hf_openflow_v6_port_desc_prop_recirculate_port_no, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ offset+=((prop_length + 7) & ~7) - prop_length;
+ break;
+
case OFPPDPT_EXPERIMENTER:
if (prop_length <= 12) {
expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short);
@@ -2712,6 +2927,7 @@ dissect_openflow_port_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
{
proto_item *ti;
proto_tree *port_tree, *conf_tree, *state_tree;
+ guint32 port_length;
guint16 port_end;
port_tree = proto_tree_add_subtree(tree, tvb, offset, 64, ett_openflow_v6_port, NULL, "Port");
@@ -2721,8 +2937,8 @@ dissect_openflow_port_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
offset+=4;
/* uint16_t length; */
- port_end = tvb_get_ntohs(tvb, offset) + offset - 4;
- proto_tree_add_item(port_tree, hf_openflow_v6_port_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(port_tree, hf_openflow_v6_port_length, tvb, offset, 2, ENC_BIG_ENDIAN, &port_length);
+ port_end = port_length + offset - 4;
offset+=2;
/* uint8_t pad[2]; */
@@ -2803,7 +3019,7 @@ static void
dissect_openflow_packet_out_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *data_tree;
- guint16 acts_len;
+ guint32 acts_len;
gint32 acts_end;
tvbuff_t *next_tvb;
gboolean save_writable;
@@ -2814,18 +3030,16 @@ dissect_openflow_packet_out_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
proto_tree_add_item(tree, hf_openflow_v6_packet_out_buffer_id, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
- /* uint32_t in_port; */
- proto_tree_add_item(tree, hf_openflow_v6_packet_out_in_port, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
-
/* uint16_t actions_len; */
- acts_len = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_packet_out_acts_len, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_packet_out_acts_len, tvb, offset, 2, ENC_BIG_ENDIAN, &acts_len);
offset+=2;
- /* uint8_t pad[6]; */
- proto_tree_add_item(tree, hf_openflow_v6_packet_out_pad, tvb, offset, 6, ENC_NA);
- offset+=6;
+ /* uint8_t pad[2]; */
+ proto_tree_add_item(tree, hf_openflow_v6_packet_out_pad, tvb, offset, 2, ENC_NA);
+ offset+=2;
+
+ /* struct ofp_match match; */
+ offset = dissect_openflow_match_v6(tvb, pinfo, tree, offset, length);
/* struct ofp_action_header actions[0]; */
acts_end = offset + acts_len;
@@ -2887,19 +3101,22 @@ static const value_string openflow_v6_instruction_type_values[] = {
};
-
+typedef struct inst_header {
+ guint32 type;
+ guint32 length;
+} inst_header;
static int
-dissect_openflow_instruction_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+dissect_openflow_instruction_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_, inst_header *retval)
{
- guint16 inst_type;
+ guint32 inst_type;
+ guint32 inst_length;
/* uint16_t type; */
- inst_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_instruction_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_instruction_type, tvb, offset, 2, ENC_BIG_ENDIAN, &inst_type);
offset+=2;
/* uint16_t length; */
- proto_tree_add_item(tree, hf_openflow_v6_instruction_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_instruction_length, tvb, offset, 2, ENC_BIG_ENDIAN, &inst_length);
offset+=2;
if (inst_type == OFPIT_EXPERIMENTER) {
@@ -2908,30 +3125,37 @@ dissect_openflow_instruction_header_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
offset+=4;
}
+ if (retval) {
+ retval->type = inst_type;
+ retval->length = inst_length;
+ }
+
return offset;
}
-
+#define OFPSTF_PERIODIC 1 << 0
+#define OFPSTF_ONLY_FIRST 1 << 1
static int
dissect_openflow_instruction_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
- proto_tree *inst_tree;
- guint16 inst_type;
- guint16 inst_length;
- gint32 acts_end;
-
- inst_type = tvb_get_ntohs(tvb, offset);
- inst_length = tvb_get_ntohs(tvb, offset + 2);
+ proto_item *ti;
+ proto_tree *inst_tree, *flags_tree;
+ inst_header header;
+ gint32 inst_end;
- inst_tree = proto_tree_add_subtree(tree, tvb, offset, inst_length, ett_openflow_v6_instruction, NULL, "Instruction");
+ inst_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_instruction, &ti, "Instruction");
- offset = dissect_openflow_instruction_header_v6(tvb, pinfo, inst_tree, offset, length);
+ offset = dissect_openflow_instruction_header_v6(tvb, pinfo, inst_tree, offset, length, &header);
+ proto_item_set_len(ti, header.length);
- if (inst_length < 8) {
- inst_length = 8;
+ if (header.length < 8) {
+ // XXX Shouldn't it be reported with an expert info?
+ header.length = 8;
}
- switch (inst_type) {
+ inst_end = offset + header.length - 4;
+
+ switch (header.type) {
case OFPIT_GOTO_TABLE:
/* uint8_t table_id; */
proto_tree_add_item(inst_tree, hf_openflow_v6_instruction_goto_table_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -2962,28 +3186,34 @@ dissect_openflow_instruction_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
proto_tree_add_item(inst_tree, hf_openflow_v6_instruction_actions_pad, tvb, offset, 4, ENC_NA);
offset+=4;
- acts_end = offset + inst_length - 8;
- while (offset < acts_end) {
+ while (offset < inst_end) {
offset = dissect_openflow_action_v6(tvb, pinfo, inst_tree, offset, length);
}
break;
- case OFPIT_METER:
- /* uint32_t meter_id; */
- proto_tree_add_item(inst_tree, hf_openflow_v6_instruction_meter_meter_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ case OFPIT_STAT_TRIGGER:
+ ti = proto_tree_add_item(inst_tree, hf_openflow_v6_instruction_stat_trigger_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
+ flags_tree = proto_item_add_subtree(ti, ett_openflow_v6_instruction_stat_trigger_flags);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_instruction_stat_triffer_flags_periodic, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_instruction_stat_triffer_flags_only_first, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_instruction_stat_triffer_flags_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=4;
+
+ while (offset < inst_end) {
+ offset = dissect_openflow_stats_v6(tvb, pinfo, inst_tree, offset, length);
+ }
break;
case OFPIT_EXPERIMENTER:
proto_tree_add_expert_format(inst_tree, pinfo, &ei_openflow_v6_instruction_undecoded,
- tvb, offset, inst_length - 8, "Experimenter instruction body.");
- offset += inst_length - 8;
+ tvb, offset, header.length - 8, "Experimenter instruction body.");
+ offset += header.length - 8;
break;
default:
proto_tree_add_expert_format(inst_tree, pinfo, &ei_openflow_v6_instruction_undecoded,
- tvb, offset, inst_length - 4, "Unknown instruction body.");
- offset += inst_length - 4;
+ tvb, offset, header.length - 4, "Unknown instruction body.");
+ offset += header.length - 4;
break;
}
@@ -3264,21 +3494,19 @@ static int
dissect_openflow_portmod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *prop_tree;
- proto_item *prop_item;
- guint16 prop_type;
- guint16 prop_length;
+ proto_item *prop_item, *ti;
+ guint32 prop_type;
+ guint32 prop_length;
- prop_type = tvb_get_ntohs(tvb, offset);
- prop_length = tvb_get_ntohs(tvb, offset + 2);
-
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_length, ett_openflow_v6_portmod_prop, NULL, "Portmod property");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_portmod_prop, &ti, "Portmod property");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_portmod_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_portmod_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_portmod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_portmod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
+ proto_item_set_len(ti, prop_length);
offset+=2;
switch (prop_type) {
@@ -3394,20 +3622,20 @@ dissect_openflow_tablemod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t
proto_item *ti, *prop_item;
proto_tree *prop_tree, *flags_tree;
- guint16 prop_type;
- guint16 prop_length;
+ guint32 prop_type;
+ guint32 prop_length;
- prop_type = tvb_get_ntohs(tvb, offset);
prop_length = tvb_get_ntohs(tvb, offset + 2);
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_length, ett_openflow_v6_tablemod_prop, NULL, "Tablemod property");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_tablemod_prop, &ti, "Tablemod property");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_tablemod_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_tablemod_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_tablemod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_tablemod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
+ proto_item_set_len(ti, prop_length);
offset+=2;
switch (prop_type) {
@@ -3583,23 +3811,28 @@ dissect_openflow_aggregate_stats_request_v6(tvbuff_t *tvb, packet_info *pinfo _U
}
-#define OFPTFPT_INSTRUCTIONS 0
-#define OFPTFPT_INSTRUCTIONS_MISS 1
-#define OFPTFPT_NEXT_TABLES 2
-#define OFPTFPT_NEXT_TABLES_MISS 3
-#define OFPTFPT_WRITE_ACTIONS 4
-#define OFPTFPT_WRITE_ACTIONS_MISS 5
-#define OFPTFPT_APPLY_ACTIONS 6
-#define OFPTFPT_APPLY_ACTIONS_MISS 7
-#define OFPTFPT_MATCH 8
-#define OFPTFPT_WILDCARDS 10
-#define OFPTFPT_WRITE_SETFIELD 12
-#define OFPTFPT_WRITE_SETFIELD_MISS 13
-#define OFPTFPT_APPLY_SETFIELD 14
-#define OFPTFPT_APPLY_SETFIELD_MISS 15
-#define OFPTFPT_TABLE_SYNC_FROM 16
-#define OFPTFPT_EXPERIMENTER 0xFFFE
-#define OFPTFPT_EXPERIMENTER_MISS 0xFFFF
+#define OFPTFPT_INSTRUCTIONS 0
+#define OFPTFPT_INSTRUCTIONS_MISS 1
+#define OFPTFPT_NEXT_TABLES 2
+#define OFPTFPT_NEXT_TABLES_MISS 3
+#define OFPTFPT_WRITE_ACTIONS 4
+#define OFPTFPT_WRITE_ACTIONS_MISS 5
+#define OFPTFPT_APPLY_ACTIONS 6
+#define OFPTFPT_APPLY_ACTIONS_MISS 7
+#define OFPTFPT_MATCH 8
+#define OFPTFPT_WILDCARDS 10
+#define OFPTFPT_WRITE_SETFIELD 12
+#define OFPTFPT_WRITE_SETFIELD_MISS 13
+#define OFPTFPT_APPLY_SETFIELD 14
+#define OFPTFPT_APPLY_SETFIELD_MISS 15
+#define OFPTFPT_TABLE_SYNC_FROM 16
+#define OFPTFPT_WRITE_COPYFIELD 18
+#define OFPTFPT_WRITE_COPYFIELD_MISS 19
+#define OFPTFPT_APPLY_COPYFIELD 20
+#define OFPTFPT_APPLY_COPYFIELD_MISS 21
+#define OFPTFPT_PACKET_TYPES 22
+#define OFPTFPT_EXPERIMENTER 0xFFFE
+#define OFPTFPT_EXPERIMENTER_MISS 0xFFFF
static const value_string openflow_v6_table_feature_prop_type_values[] = {
{ OFPTFPT_INSTRUCTIONS, "OFPTFPT_INSTRUCTIONS" },
{ OFPTFPT_INSTRUCTIONS_MISS, "OFPTFPT_INSTRUCTIONS_MISS" },
@@ -3618,7 +3851,14 @@ static const value_string openflow_v6_table_feature_prop_type_values[] = {
{ OFPTFPT_EXPERIMENTER, "OFPTFPT_EXPERIMENTER" },
{ OFPTFPT_EXPERIMENTER_MISS, "OFPTFPT_EXPERIMENTER_MISS" },
{ OFPTFPT_TABLE_SYNC_FROM, "OFPTFPT_TABLE_SYNC_FROM" },
- { 0, NULL }
+ { OFPTFPT_WRITE_COPYFIELD, "OFPTFPT_WRITE_COPYFIELD" },
+ { OFPTFPT_WRITE_COPYFIELD_MISS,"OFPTFPT_WRITE_COPYFIELD_MISS" },
+ { OFPTFPT_APPLY_COPYFIELD, "OFPTFPT_APPLY_COPYFIELD" },
+ { OFPTFPT_APPLY_COPYFIELD_MISS,"OFPTFPT_APPLY_COPYFIELD_MISS" },
+ { OFPTFPT_PACKET_TYPES, "OFPTFPT_PACKET_TYPES" },
+ { OFPTFPT_EXPERIMENTER, "OFPTFPT_EXPERIMENTER" },
+ { OFPTFPT_EXPERIMENTER_MISS, "OFPTFPT_EXPERIMENTER_MISS" },
+ { 0, NULL }
};
@@ -3627,8 +3867,8 @@ dissect_openflow_table_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
{
proto_item *ti;
proto_tree *prop_tree, *elem_tree;
- guint16 prop_type;
- guint16 prop_length;
+ guint32 prop_type;
+ guint32 prop_length;
guint16 elem_begin;
gint32 body_end;
guint16 pad_length;
@@ -3636,14 +3876,12 @@ dissect_openflow_table_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_table_feature_prop, &ti, "Table feature property");
/* uint16_t type; */
- prop_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(prop_tree, hf_openflow_v6_table_feature_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_table_feature_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t length; */
- prop_length = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_table_feature_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
proto_item_set_len(ti, prop_length);
- proto_tree_add_item(prop_tree, hf_openflow_v6_table_feature_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
if (prop_length < 4) {
@@ -3660,7 +3898,7 @@ dissect_openflow_table_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
elem_begin = offset;
elem_tree = proto_tree_add_subtree(prop_tree, tvb, offset, -1, ett_openflow_v6_table_feature_prop_instruction_id, &ti, "Instruction ID");
- offset = dissect_openflow_instruction_header_v6(tvb, pinfo, elem_tree, offset, length);
+ offset = dissect_openflow_instruction_header_v6(tvb, pinfo, elem_tree, offset, length, NULL);
proto_item_set_len(ti, offset - elem_begin);
}
break;
@@ -3692,11 +3930,15 @@ dissect_openflow_table_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
case OFPTFPT_WRITE_SETFIELD_MISS:
case OFPTFPT_APPLY_SETFIELD:
case OFPTFPT_APPLY_SETFIELD_MISS:
+ case OFPTFPT_WRITE_COPYFIELD:
+ case OFPTFPT_WRITE_COPYFIELD_MISS:
+ case OFPTFPT_APPLY_COPYFIELD:
+ case OFPTFPT_APPLY_COPYFIELD_MISS:
while (offset < body_end) {
elem_begin = offset;
elem_tree = proto_tree_add_subtree(prop_tree, tvb, offset, -1, ett_openflow_v6_table_feature_prop_oxm_id, &ti, "OXM ID");
- offset = dissect_openflow_oxm_header_v6(tvb, pinfo, elem_tree, offset, length);
+ offset = dissect_openflow_oxm_header_v6(tvb, pinfo, elem_tree, offset, length, NULL);
proto_item_set_len(ti, offset - elem_begin);
}
break;
@@ -3708,6 +3950,16 @@ dissect_openflow_table_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
}
break;
+ case OFPTFPT_PACKET_TYPES:
+ while (offset < body_end) {
+ elem_begin = offset;
+ elem_tree = proto_tree_add_subtree(prop_tree, tvb, offset, -1, ett_openflow_v6_table_feature_prop_oxm_id, &ti, "OXM ID");
+
+ offset = dissect_openflow_oxm_v6(tvb, pinfo, elem_tree, offset, length);
+ proto_item_set_len(ti, offset - elem_begin);
+ }
+ break;
+
case OFPTFPT_EXPERIMENTER:
case OFPTFPT_EXPERIMENTER_MISS:
/* uint32_t experimenter; */
@@ -3747,16 +3999,15 @@ dissect_openflow_table_features_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
{
proto_item *ti;
proto_tree *feat_tree, *caps_tree;
- guint16 feat_length;
+ guint32 feat_length;
gint32 feat_end;
feat_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_table_features, &ti, "Table features");
/* uint16_t length; */
- feat_length = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item_ret_uint(feat_tree, hf_openflow_v6_table_features_length, tvb, offset, 2, ENC_BIG_ENDIAN, &feat_length);
feat_end = offset + feat_length;
proto_item_set_len(ti, feat_length);
- proto_tree_add_item(feat_tree, hf_openflow_v6_table_features_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* uint8_t table_id; */
@@ -3946,43 +4197,170 @@ dissect_openflow_flow_monitor_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_,
dissect_openflow_match_v6(tvb, pinfo, tree, offset, length);
}
-#define OFPMP_DESC 0
-#define OFPMP_FLOW 1
-#define OFPMP_AGGREGATE 2
-#define OFPMP_TABLE 3
-#define OFPMP_PORT_STATS 4
-#define OFPMP_QUEUE_STATS 5
-#define OFPMP_GROUP 6
-#define OFPMP_GROUP_DESC 7
-#define OFPMP_GROUP_FEATURES 8
-#define OFPMP_METER 9
-#define OFPMP_METER_DESC 10
-#define OFPMP_METER_FEATURES 11
-#define OFPMP_TABLE_FEATURES 12
-#define OFPMP_PORT_DESC 13
-#define OFPMP_TABLE_DESC 14
-#define OFPMP_QUEUE_DESC 15
-#define OFPMP_FLOW_MONITOR 16
+static int
+dissect_openflow_time_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ /* uint64_t seconds; */
+ proto_tree_add_item(tree, hf_openflow_v6_time_seconds, tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset+=8;
+
+ /* uint32_t nanoseconds; */
+ proto_tree_add_item(tree, hf_openflow_v6_time_nanoseconds, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint8_t pad[4]; */
+ proto_tree_add_item(tree, hf_openflow_v6_time_pad, tvb, offset, 4, ENC_NA);
+ offset+=4;
+
+ return offset;
+}
+
+#define OFPTMPBF_TIME_CAPABILITY 1
+#define OFPTMPBF_EXPERIMENTER 0xFFFF
+static const value_string openflow_v6_bundle_feature_prop_type_values[] = {
+ { OFPTMPBF_TIME_CAPABILITY, "OFPTMPBF_TIME_CAPABILITY" },
+ { OFPTMPBF_EXPERIMENTER, "OFPTMPBF_EXPERIMENTER" },
+ { 0, NULL }
+};
+
+
+static int
+dissect_openflow_bundle_feature_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length)
+{
+ proto_item *ti;
+ proto_tree *prop_tree;
+ guint32 prop_type;
+ guint32 prop_length;
+ gint32 body_end;
+ guint16 pad_length;
+
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_bundle_feature_prop, &ti, "Bundle feature property");
+
+ /* uint16_t type; */
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_bundle_feature_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
+ offset+=2;
+
+ /* uint16_t length; */
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_bundle_feature_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
+ proto_item_set_len(ti, prop_length);
+ offset+=2;
+
+ if (prop_length < 4) {
+ prop_length = 4;
+ }
+
+ body_end = offset + prop_length - 4;
+
+ /* body */
+ switch (prop_type) {
+ case OFPTMPBF_TIME_CAPABILITY:
+ /* uint8_t pad[4]; */
+ proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_feature_prop_time_pad, tvb, offset, 4, ENC_NA);
+ offset+=4;
+
+ /* struct ofp_time sched_accuracy; */
+ offset = dissect_openflow_time_v6(tvb, pinfo, tree, offset, length);
+
+ /* struct ofp_time sched_max_future; */
+ offset = dissect_openflow_time_v6(tvb, pinfo, tree, offset, length);
+
+ /* struct ofp_time sched_max_past; */
+ offset = dissect_openflow_time_v6(tvb, pinfo, tree, offset, length);
+
+ /* struct ofp_time timestamp; */
+ offset = dissect_openflow_time_v6(tvb, pinfo, tree, offset, length);
+ break;
+ case OFPTMPBF_EXPERIMENTER:
+ /* uint32_t experimenter; */
+ proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_feature_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint32_t exp_type; */
+ proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_feature_prop_experimenter_exp_type, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint32_t experimenter_data[0]; */
+ proto_tree_add_expert_format(prop_tree, pinfo, &ei_openflow_v6_bundle_feature_prop_undecoded,
+ tvb, offset, body_end - offset, "Experimenter bundle property body.");
+ offset = body_end;
+ break;
+
+ default:
+ proto_tree_add_expert_format(prop_tree, pinfo, &ei_openflow_v6_bundle_feature_prop_undecoded,
+ tvb, offset, body_end - offset, "Unknown bundle property body.");
+ offset = body_end;
+ break;
+ };
+
+ pad_length = (prop_length + 7)/8*8 - prop_length;
+ if (pad_length > 0) {
+ proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_feature_prop_pad, tvb, offset, pad_length, ENC_NA);
+ offset+=pad_length;
+ }
+
+ return offset;
+}
+
+static void
+dissect_openflow_bundle_features_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ /* uint32_t feature_request_flags; */
+ proto_tree_add_item(tree, hf_openflow_v6_bundle_features_request_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint8_t pad[4]; */
+ proto_tree_add_item(tree, hf_openflow_v6_bundle_features_request_pad, tvb, offset, 4, ENC_NA);
+ offset+=4;
+
+ /* struct ofp_bundle_features_prop_header properties[0]; */
+ while (offset < length) {
+ offset = dissect_openflow_bundle_feature_prop_v6(tvb, pinfo, tree, offset, length);
+ }
+}
+
+#define OFPMP_DESC 0
+#define OFPMP_FLOW_DESC 1
+#define OFPMP_AGGREGATE_STATS 2
+#define OFPMP_TABLE_STATS 3
+#define OFPMP_PORT_STATS 4
+#define OFPMP_QUEUE_STATS 5
+#define OFPMP_GROUP_STATS 6
+#define OFPMP_GROUP_DESC 7
+#define OFPMP_GROUP_FEATURES 8
+#define OFPMP_METER_STATS 9
+#define OFPMP_METER_DESC 10
+#define OFPMP_METER_FEATURES 11
+#define OFPMP_TABLE_FEATURES 12
+#define OFPMP_PORT_DESC 13
+#define OFPMP_TABLE_DESC 14
+#define OFPMP_QUEUE_DESC 15
+#define OFPMP_FLOW_MONITOR 16
+#define OFPMP_FLOW_STATS 17
+#define OFPMP_CONTROLLER_STATUS 18
+#define OFPMP_BUNDLE_FEATURES 19
#define OFPMP_EXPERIMENTER 0xffff
static const value_string openflow_v6_multipart_type_values[] = {
- { OFPMP_DESC, "OFPMP_DESC" },
- { OFPMP_FLOW, "OFPMP_FLOW" },
- { OFPMP_AGGREGATE, "OFPMP_AGGREGATE" },
- { OFPMP_TABLE, "OFPMP_TABLE" },
- { OFPMP_PORT_STATS, "OFPMP_PORT_STATS" },
- { OFPMP_QUEUE_STATS, "OFPMP_QUEUE_STATS" },
- { OFPMP_GROUP, "OFPMP_GROUP" },
- { OFPMP_GROUP_DESC, "OFPMP_GROUP_DESC" },
- { OFPMP_GROUP_FEATURES, "OFPMP_GROUP_FEATURES" },
- { OFPMP_METER, "OFPMP_METER" },
- { OFPMP_METER_DESC, "OFPMP_METER_DESC" },
- { OFPMP_METER_FEATURES, "OFPMP_METER_FEATURES" },
- { OFPMP_TABLE_FEATURES, "OFPMP_TABLE_FEATURES" },
- { OFPMP_PORT_DESC, "OFPMP_PORT_DESC" },
- { OFPMP_TABLE_DESC, "OFPMP_TABLE_DESC" },
- { OFPMP_QUEUE_DESC, "OFPMP_QUEUE_DESC" },
- { OFPMP_FLOW_MONITOR, "OFPMP_FLOW_MONITOR" },
- { OFPMP_EXPERIMENTER, "OFPMP_EXPERIMENTER" },
+ { OFPMP_DESC, "OFPMP_DESC" },
+ { OFPMP_FLOW_DESC, "OFPMP_FLOW_DESC" },
+ { OFPMP_AGGREGATE_STATS, "OFPMP_AGGREGATE_STATS" },
+ { OFPMP_TABLE_STATS, "OFPMP_TABLE_STATS" },
+ { OFPMP_PORT_STATS, "OFPMP_PORT_STATS" },
+ { OFPMP_QUEUE_STATS, "OFPMP_QUEUE_STATS" },
+ { OFPMP_GROUP_STATS, "OFPMP_GROUP_STATS" },
+ { OFPMP_GROUP_DESC, "OFPMP_GROUP_DESC" },
+ { OFPMP_GROUP_FEATURES, "OFPMP_GROUP_FEATURES" },
+ { OFPMP_METER_STATS, "OFPMP_METER_STATS" },
+ { OFPMP_METER_DESC, "OFPMP_METER_DESC" },
+ { OFPMP_METER_FEATURES, "OFPMP_METER_FEATURES" },
+ { OFPMP_TABLE_FEATURES, "OFPMP_TABLE_FEATURES" },
+ { OFPMP_PORT_DESC, "OFPMP_PORT_DESC" },
+ { OFPMP_TABLE_DESC, "OFPMP_TABLE_DESC" },
+ { OFPMP_QUEUE_DESC, "OFPMP_QUEUE_DESC" },
+ { OFPMP_FLOW_MONITOR, "OFPMP_FLOW_MONITOR" },
+ { OFPMP_FLOW_STATS, "OFPMP_FLOW_STATS" },
+ { OFPMP_CONTROLLER_STATUS, "OFPMP_CONTROLLER_STATUS" },
+ { OFPMP_BUNDLE_FEATURES, "OFPMP_BUNDLE_FEATURES" },
+ { OFPMP_EXPERIMENTER, "OFPMP_EXPERIMENTER" },
{ 0, NULL }
};
@@ -3992,11 +4370,10 @@ dissect_openflow_multipart_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
{
proto_item *ti;
proto_tree *flags_tree;
- guint16 type;
+ guint32 type;
/* uint16_t type; */
- type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_multipart_request_type , tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_multipart_request_type , tvb, offset, 2, ENC_BIG_ENDIAN, &type);
offset+=2;
/* uint16_t flags; */
@@ -4011,18 +4388,18 @@ dissect_openflow_multipart_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
offset+=4;
/* uint8_t body[0]; */
- switch(type){
+ switch (type) {
case OFPMP_DESC:
/* The request body is empty. */
break;
- case OFPMP_FLOW:
+ case OFPMP_FLOW_DESC:
dissect_openflow_flow_stats_request_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_AGGREGATE:
+ case OFPMP_AGGREGATE_STATS:
dissect_openflow_aggregate_stats_request_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_TABLE:
- /* The request body is empty. */
+ case OFPMP_TABLE_STATS:
+ /* The request body is empty. */
break;
case OFPMP_PORT_STATS:
dissect_openflow_port_stats_request_v6(tvb, pinfo, tree, offset, length);
@@ -4030,7 +4407,7 @@ dissect_openflow_multipart_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
case OFPMP_QUEUE_STATS:
dissect_openflow_queue_stats_request_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_GROUP:
+ case OFPMP_GROUP_STATS:
dissect_openflow_group_stats_request_v6(tvb, pinfo, tree, offset, length);
break;
case OFPMP_GROUP_DESC:
@@ -4039,7 +4416,7 @@ dissect_openflow_multipart_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
case OFPMP_GROUP_FEATURES:
/* The request body is empty. */
break;
- case OFPMP_METER:
+ case OFPMP_METER_STATS:
dissect_openflow_meter_stats_request_v6(tvb, pinfo, tree, offset, length);
break;
case OFPMP_METER_DESC:
@@ -4065,6 +4442,15 @@ dissect_openflow_multipart_request_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
case OFPMP_FLOW_MONITOR:
dissect_openflow_flow_monitor_request_v6(tvb, pinfo, tree, offset, length);
break;
+ case OFPMP_FLOW_STATS:
+ dissect_openflow_flow_stats_request_v6(tvb, pinfo, tree, offset, length);
+ break;
+ case OFPMP_CONTROLLER_STATUS:
+ /* The request body is empty. */
+ break;
+ case OFPMP_BUNDLE_FEATURES:
+ dissect_openflow_bundle_features_request_v6(tvb, pinfo, tree, offset, length);
+ break;
case OFPMP_EXPERIMENTER:
/* uint32_t experimenter; */
proto_tree_add_item(tree, hf_openflow_v6_multipart_request_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -4116,111 +4502,131 @@ dissect_openflow_switch_description_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pr
static int
-dissect_openflow_flow_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+dissect_openflow_flow_desc_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_item *ti;
- proto_tree *stats_tree, *flags_tree;
- guint16 stats_len;
- gint32 stats_end;
+ proto_tree *desc_tree, *flags_tree;
+ guint32 desc_len;
+ gint32 desc_end;
- stats_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_flow_stats, &ti, "Flow stats");
+ desc_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_flow_desc, &ti, "Flow desc");
/* uint16_t length; */
- stats_len = tvb_get_ntohs(tvb, offset);
- stats_end = offset + stats_len;
- proto_item_set_len(ti, stats_len);
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(desc_tree, hf_openflow_v6_flow_desc_length, tvb, offset, 2, ENC_BIG_ENDIAN, &desc_len);
+ desc_end = offset + desc_len;
+ proto_item_set_len(ti, desc_len);
+ offset+=2;
+
+ /* uint8_t pad2[2]; */
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_pad2, tvb, offset, 2, ENC_NA);
offset+=2;
/* uint8_t table_id; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
offset+=1;
/* uint8_t pad; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_pad, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_pad, tvb, offset, 1, ENC_NA);
offset+=1;
- /* uint32_t duration_sec; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_duration_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
-
- /* uint32_t duration_nsec; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_duration_nsec, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
-
/* uint16_t priority; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* uint16_t idle_timeout; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_idle_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* uint16_t hard_timeout; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_hard_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_hard_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* uint16_t flags; */
- ti = proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
- flags_tree = proto_item_add_subtree(ti, ett_openflow_v6_flow_stats_flags);
-
- proto_tree_add_item(flags_tree, hf_openflow_v6_flow_stats_flags_send_flow_rem, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_openflow_v6_flow_stats_flags_check_overlap, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_openflow_v6_flow_stats_flags_reset_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_openflow_v6_flow_stats_flags_no_packet_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_openflow_v6_flow_stats_flags_no_byte_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
+ ti = proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
+ flags_tree = proto_item_add_subtree(ti, ett_openflow_v6_flow_desc_flags);
+
+ proto_tree_add_item(flags_tree, hf_openflow_v6_flow_desc_flags_send_flow_rem, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_flow_desc_flags_check_overlap, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_flow_desc_flags_reset_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_flow_desc_flags_no_packet_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_openflow_v6_flow_desc_flags_no_byte_counts, tvb, offset, 2, ENC_BIG_ENDIAN);
offset+=2;
/* uint16_t importance; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_importance, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=2;
-
- /* uint8_t pad2[2]; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_pad2, tvb, offset, 4, ENC_NA);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_importance, tvb, offset, 4, ENC_BIG_ENDIAN);
offset+=2;
/* uint64_t cookie; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
-
- /* uint64_t packet_count; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
-
- /* uint64_t byte_count; */
- proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
+ proto_tree_add_item(desc_tree, hf_openflow_v6_flow_desc_cookie, tvb, offset, 8, ENC_BIG_ENDIAN);
offset+=8;
/* struct ofp_match match; */
- offset = dissect_openflow_match_v6(tvb, pinfo, stats_tree, offset, length);
+ offset = dissect_openflow_match_v6(tvb, pinfo, desc_tree, offset, length);
+
+ /* struct ofp_stats stats; */
+ offset = dissect_openflow_stats_v6(tvb, pinfo, desc_tree, offset, length);
/* struct ofp_instruction instructions[0]; */
- while (offset < stats_end) {
- offset = dissect_openflow_instruction_v6(tvb, pinfo, stats_tree, offset, length);
+ while (offset < desc_end) {
+ offset = dissect_openflow_instruction_v6(tvb, pinfo, desc_tree, offset, length);
}
return offset;
}
-static void
-dissect_openflow_aggregate_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+#define OFPFSR_STATS_REQUEST 0
+#define OFPFSR_STAT_TRIGGER 1
+static const value_string openflow_v6_flow_stats_reason_values[] = {
+ { OFPFSR_STATS_REQUEST, "OFPFSR_STATS_REQUEST" },
+ { OFPFSR_STAT_TRIGGER, "OFPFSR_STAT_TRIGGER" },
+ { 0, NULL }
+};
+
+static int
+dissect_openflow_flow_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
- /* uint64_t packet_count; */
- proto_tree_add_item(tree, hf_openflow_v6_aggregate_stats_packet_count, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
+ proto_item *ti;
+ proto_tree *stats_tree;
+ guint32 stats_len;
- /* uint64_t byte_count; */
- proto_tree_add_item(tree, hf_openflow_v6_aggregate_stats_byte_count, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset+=8;
+ stats_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_flow_stats, &ti, "Flow stats");
- /* uint32_t flow_count; */
- proto_tree_add_item(tree, hf_openflow_v6_aggregate_stats_flow_count, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset+=4;
+ /* uint16_t length; */
+ proto_tree_add_item_ret_uint(stats_tree, hf_openflow_v6_flow_stats_length, tvb, offset, 2, ENC_BIG_ENDIAN, &stats_len);
+ proto_item_set_len(ti, stats_len);
+ offset+=2;
- /* uint8_t pad[4]; */
- proto_tree_add_item(tree, hf_openflow_v6_aggregate_stats_pad, tvb, offset, 4, ENC_NA);
- /*offset+=4;*/
+ /* uint8_t pad2[2]; */
+ proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_pad2, tvb, offset, 2, ENC_NA);
+ offset+=1;
+
+ /* uint8_t table_id; */
+ proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_table_id, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
+
+ /* uint8_t reason; */
+ proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
+
+ /* uint16_t priority; */
+ proto_tree_add_item(stats_tree, hf_openflow_v6_flow_stats_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+
+ /* struct ofp_match match; */
+ offset = dissect_openflow_match_v6(tvb, pinfo, stats_tree, offset, length);
+
+ /* struct ofp_stats stats; */
+ offset = dissect_openflow_stats_v6(tvb, pinfo, stats_tree, offset, length);
+
+ return offset;
+}
+
+
+static void
+dissect_openflow_aggregate_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ dissect_openflow_stats_v6(tvb, pinfo, tree, offset, length);
}
@@ -4369,21 +4775,19 @@ static int
dissect_openflow_port_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *prop_tree;
- proto_item *prop_item;
- guint16 prop_type;
- guint16 prop_length;
-
- prop_type = tvb_get_ntohs(tvb, offset);
- prop_length = tvb_get_ntohs(tvb, offset);
+ proto_item *ti, *prop_item;
+ guint32 prop_type;
+ guint32 prop_length;
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_length, ett_openflow_v6_port_stats_prop, NULL, "Port stats. property");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_port_stats_prop, &ti, "Port stats. property");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_port_stats_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_port_stats_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_port_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_port_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
+ proto_item_set_len(ti, prop_length);
offset+=2;
switch (prop_type) {
@@ -4434,13 +4838,14 @@ static int
dissect_openflow_port_stats_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *stats_tree;
+ guint32 stats_length;
guint16 stats_end;
stats_tree = proto_tree_add_subtree(tree, tvb, offset, 112, ett_openflow_v6_port_stats, NULL, "Port stats");
/* uint16_t length; */
- stats_end = tvb_get_ntohs(tvb, offset) + offset - 4;
- proto_tree_add_item(stats_tree, hf_openflow_v6_port_stats_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(stats_tree, hf_openflow_v6_port_stats_length, tvb, offset, 2, ENC_BIG_ENDIAN, &stats_length);
+ stats_end = stats_length + offset - 4;
offset+=2;
/* uint8_t pad[2]; */
@@ -4506,16 +4911,15 @@ dissect_openflow_table_desc_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
{
proto_item *ti;
proto_tree *desc_tree, *conf_tree;
- guint16 desc_length;
+ guint32 desc_length;
gint32 desc_end;
- desc_length = tvb_get_ntohs(tvb, offset);
- desc_end = offset + desc_length;
-
- desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_length, ett_openflow_v6_table_desc, NULL, "Table desc");
+ desc_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_table_desc, &ti, "Table desc");
/* uint16_t length; */
- proto_tree_add_item(desc_tree, hf_openflow_v6_table_desc_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(desc_tree, hf_openflow_v6_table_desc_length, tvb, offset, 2, ENC_BIG_ENDIAN, &desc_length);
+ proto_item_set_len(ti, desc_length);
+ desc_end = offset + desc_length;
offset+=2;
/* uint8_t table_id; */
@@ -4555,16 +4959,15 @@ dissect_openflow_queue_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, prot
{
proto_tree *prop_tree;
proto_item *prop_item;
- guint16 prop_type;
+ guint32 prop_type;
guint16 prop_length;
- prop_type = tvb_get_ntohs(tvb, offset);
prop_length = tvb_get_ntohs(tvb, offset + 2);
prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_length, ett_openflow_v6_queue_stats_prop, NULL, "Queue stats property");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_queue_stats_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_queue_stats_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
@@ -5104,14 +5507,13 @@ dissect_openflow_queue_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
{
proto_item *ti;
proto_tree *prop_tree;
- guint16 prop_type;
+ guint32 prop_type;
guint16 prop_len;
prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_queue_desc_prop, &ti, "Queue property");
/* uint16_t property; */
- prop_type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(prop_tree, hf_openflow_v6_queue_desc_prop_property, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_queue_desc_prop_property, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset+=2;
/* uint16_t len; */
@@ -5221,6 +5623,140 @@ dissect_openflow_queue_desc_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
}
+#define OFPCSPT_URI 0
+#define OFPCSPT_EXPERIMENTER 0xFFFF
+static const value_string openflow_v6_controller_status_prop_type_values[] = {
+ { OFPCSPT_URI, "OFPCSPT_URI" },
+ { OFPCSPT_EXPERIMENTER, "OFPCSPT_EXPERIMENTER" },
+ { 0, NULL }
+};
+
+
+static int
+dissect_openflow_controller_status_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ proto_item *ti;
+ proto_tree *prop_tree;
+ guint32 prop_type;
+ guint32 prop_length;
+ gint32 body_end;
+ guint16 pad_length;
+
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_controller_status_prop, &ti, "Controller status property");
+
+ /* uint16_t type; */
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_controller_status_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
+ offset+=2;
+
+ /* uint16_t length; */
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_controller_status_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_length);
+ proto_item_set_len(ti, prop_length);
+ offset+=2;
+
+ if (prop_length < 4) {
+ prop_length = 4;
+ }
+
+ body_end = offset + prop_length - 4;
+
+ /* body */
+ switch (prop_type) {
+ case OFPCSPT_URI:
+ /* uint8_t uri[0]; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_prop_uri, tvb, offset, prop_length - 4, ENC_ASCII|ENC_NA);
+ offset += body_end;
+ break;
+ case OFPCSPT_EXPERIMENTER:
+ /* uint32_t experimenter; */
+ proto_tree_add_item(prop_tree, hf_openflow_v6_controller_status_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint32_t exp_type; */
+ proto_tree_add_item(prop_tree, hf_openflow_v6_controller_status_prop_experimenter_exp_type, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint32_t experimenter_data[0]; */
+ proto_tree_add_expert_format(prop_tree, pinfo, &ei_openflow_v6_controller_status_prop_undecoded,
+ tvb, offset, body_end - offset, "Experimenter controller property body.");
+ offset = body_end;
+ break;
+
+ default:
+ proto_tree_add_expert_format(prop_tree, pinfo, &ei_openflow_v6_controller_status_prop_undecoded,
+ tvb, offset, body_end - offset, "Unknown controller property body.");
+ offset = body_end;
+ break;
+ };
+
+ pad_length = (prop_length + 7)/8*8 - prop_length;
+ if (pad_length > 0) {
+ proto_tree_add_item(prop_tree, hf_openflow_v6_controller_status_prop_pad, tvb, offset, pad_length, ENC_NA);
+ offset+=pad_length;
+ }
+
+ return offset;
+}
+
+#define OFPCSR_REQUEST 0
+#define OFPCSR_CHANNEL_STATUS 1
+#define OFPCSR_ROLE 2
+#define OFPCSR_CONTROLLER_ADDED 3
+#define OFPCSR_CONTROLLER_REMOVED 4
+#define OFPCSR_SHORT_ID 5
+#define OFPCSR_EXPERIMENTER 6
+static const value_string openflow_v6_controller_status_reason_values[] = {
+ { OFPCSR_REQUEST, "OFPCSR_REQUEST" },
+ { OFPCSR_CHANNEL_STATUS, "OFPCSR_CHANNEL_STATUS" },
+ { OFPCSR_ROLE, "OFPCSR_ROLE" },
+ { OFPCSR_CONTROLLER_ADDED, "OFPCSR_CONTROLLER_ADDED" },
+ { OFPCSR_CONTROLLER_REMOVED, "OFPCSR_CONTROLLER_REMOVED" },
+ { OFPCSR_SHORT_ID, "OFPCSR_SHORT_ID" },
+ { OFPCSR_EXPERIMENTER, "OFPCSR_EXPERIMENTER" },
+ { 0, NULL }
+};
+
+#define OFPCT_STATUS_UP 0
+#define OFPCT_STATUS_DOWN 1
+static const value_string openflow_v6_controller_status_channel_status_values[] = {
+ { OFPCT_STATUS_UP, "OFPCT_STATUS_UP" },
+ { OFPCT_STATUS_DOWN, "OFPCT_STATUS_DOWN" },
+ { 0, NULL }
+};
+
+static int
+dissect_openflow_controller_status_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
+{
+ /* uint16_t length; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+
+ /* uint16_t short_id; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_short_id, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset+=2;
+
+ /* uint32_t role; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_role, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset+=4;
+
+ /* uint8_t reason; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
+
+ /* uint8_t channel_status; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_channel_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset+=1;
+
+ /* uint8_t pad[6]; */
+ proto_tree_add_item(tree, hf_openflow_v6_controller_status_pad, tvb, offset, 6, ENC_NA);
+ offset+=6;
+
+ /* struct ofp_controller_status_prop_header properties[0]; */
+ // XXX Should it be a while loop?
+ dissect_openflow_controller_status_prop_v6(tvb, pinfo, tree, offset, length);
+
+ return offset;
+}
+
#define OFPFME_INITIAL 0
#define OFPFME_ADDED 1
#define OFPFME_REMOVED 2
@@ -5243,23 +5779,21 @@ static int
dissect_openflow_flow_update_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_)
{
proto_tree *update_tree;
- guint16 update_len;
- guint16 update_event;
+ guint32 update_len;
+ guint32 update_event;
gint32 update_end;
proto_item *ti;
- update_len = tvb_get_ntohs(tvb, offset);
- update_end = offset + update_len;
- update_event = tvb_get_ntohs(tvb, offset + 2);
-
- update_tree = proto_tree_add_subtree(tree, tvb, offset, update_len, ett_openflow_v6_flow_update, NULL, "Flow update");
+ update_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_flow_update, &ti, "Flow update");
/* uint16_t length; */
- proto_tree_add_item(update_tree, hf_openflow_v6_flow_update_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(update_tree, hf_openflow_v6_flow_update_length, tvb, offset, 2, ENC_BIG_ENDIAN, &update_len);
+ update_end = offset + update_len;
+ proto_item_set_len(ti, update_len);
offset+=2;
/* uint16_t event; */
- ti = proto_tree_add_item(update_tree, hf_openflow_v6_flow_update_event, tvb, offset, 2, ENC_BIG_ENDIAN);
+ ti = proto_tree_add_item_ret_uint(update_tree, hf_openflow_v6_flow_update_event, tvb, offset, 2, ENC_BIG_ENDIAN, &update_event);
offset+=2;
if (update_len < 4) {
@@ -5345,11 +5879,10 @@ dissect_openflow_multipart_reply_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
{
proto_item *ti;
proto_tree *flags_tree;
- guint16 type;
+ guint32 type;
/* uint16_t type; */
- type = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(tree, hf_openflow_v6_multipart_reply_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_openflow_v6_multipart_reply_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
offset+=2;
/* uint16_t flags; */
@@ -5367,15 +5900,13 @@ dissect_openflow_multipart_reply_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
case OFPMP_DESC:
dissect_openflow_switch_description_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_FLOW:
- while (offset < length) {
- offset = dissect_openflow_flow_stats_v6(tvb, pinfo, tree, offset, length);
- }
+ case OFPMP_FLOW_DESC:
+ dissect_openflow_flow_desc_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_AGGREGATE:
+ case OFPMP_AGGREGATE_STATS:
dissect_openflow_aggregate_stats_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_TABLE:
+ case OFPMP_TABLE_STATS:
while (offset < length) {
offset = dissect_openflow_table_stats_v6(tvb, pinfo, tree, offset, length);
}
@@ -5390,7 +5921,7 @@ dissect_openflow_multipart_reply_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
offset = dissect_openflow_queue_stats_v6(tvb, pinfo, tree, offset, length);
}
break;
- case OFPMP_GROUP:
+ case OFPMP_GROUP_STATS:
while (offset < length) {
offset = dissect_openflow_group_stats_v6(tvb, pinfo, tree, offset, length);
}
@@ -5403,7 +5934,7 @@ dissect_openflow_multipart_reply_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
case OFPMP_GROUP_FEATURES:
dissect_openflow_group_features_v6(tvb, pinfo, tree, offset, length);
break;
- case OFPMP_METER:
+ case OFPMP_METER_STATS:
while (offset < length) {
offset = dissect_openflow_meter_stats_v6(tvb, pinfo, tree, offset, length);
}
@@ -5441,6 +5972,14 @@ dissect_openflow_multipart_reply_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto
offset = dissect_openflow_flow_update_v6(tvb, pinfo, tree, offset, length);
}
break;
+ case OFPMP_FLOW_STATS:
+ while (offset < length) {
+ offset = dissect_openflow_flow_stats_v6(tvb, pinfo, tree, offset, length);
+ }
+ break;
+ case OFPMP_CONTROLLER_STATUS:
+ dissect_openflow_controller_status_v6(tvb, pinfo, tree, offset, length);
+ break;
case OFPMP_EXPERIMENTER:
/* uint32_t experimenter; */
@@ -5562,20 +6101,18 @@ dissect_openflow_async_config_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro
{
proto_item *ti, *prop_item;
proto_tree *prop_tree, *pi_tree, *ps_tree, *fr_tree, *rs_tree, *ts_tree, *rf_tree;
- guint16 prop_type;
- guint16 prop_len;
+ guint32 prop_type;
+ guint32 prop_len;
- prop_type = tvb_get_ntohs(tvb, offset);
- prop_len = tvb_get_ntohs(tvb, offset + 2);
-
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_len, ett_openflow_v6_async_config_prop, NULL, "Async config prop");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_async_config_prop, &ti, "Async config prop");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_async_config_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_async_config_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
offset += 2;
/* uint16_t length; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_async_config_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_async_config_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_len);
+ proto_item_set_len(ti, prop_len);
offset += 2;
switch (prop_type) {
@@ -5812,8 +6349,10 @@ dissect_openflow_requestforward_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
}
+#define OFPBPT_TIME 0x0001
#define OFPBPT_EXPERIMENTER 0xFFFF
static const value_string openflow_v6_bundle_prop_type_values[] = {
+ { OFPBPT_TIME, "OFPBPT_TIME" },
{ OFPBPT_EXPERIMENTER, "OFPBPT_EXPERIMENTER" },
{ 0, NULL }
};
@@ -5822,22 +6361,26 @@ static int
dissect_openflow_bundle_prop_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 length)
{
proto_tree *prop_tree;
- proto_item *prop_item;
- guint16 prop_type;
- guint16 prop_len;
-
- prop_type = tvb_get_ntohs(tvb, offset);
- prop_len = tvb_get_ntohs(tvb, offset + 2);
+ proto_item *prop_item, *ti;
+ guint32 prop_type;
+ guint32 prop_len;
- prop_tree = proto_tree_add_subtree(tree, tvb, offset, prop_len, ett_openflow_v6_bundle_prop, NULL, "Bundle prop");
+ prop_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_openflow_v6_bundle_prop, &ti, "Bundle prop");
/* uint16_t type; */
- proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_bundle_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_type);
+ offset+=2;
/* uint16_t length; */
- prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ prop_item = proto_tree_add_item_ret_uint(prop_tree, hf_openflow_v6_bundle_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN, &prop_len);
+ proto_item_set_len(ti, prop_len);
+ offset+=2;
switch (prop_type) {
+ case OFPBPT_TIME:
+ dissect_openflow_time_v6(tvb, pinfo, tree, offset, length);
+ offset += prop_len - 4;
+ break;
case OFPBPT_EXPERIMENTER:
if (prop_len <= 12) {
expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short);
@@ -6071,6 +6614,9 @@ dissect_openflow_message_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
case OFPT_BUNDLE_ADD_MESSAGE:
dissect_openflow_bundle_add_v6(tvb, pinfo, tree, offset, length);
break;
+ case OFPT_CONTROLLER_STATUS:
+ dissect_openflow_controller_status_v6(tvb, pinfo, tree, offset, length);
+ break;
default:
if (length > 8) {
@@ -6141,17 +6687,17 @@ proto_register_openflow_v6(void)
},
{ &hf_openflow_v6_oxm_field,
{ "Field", "openflow_v6.oxm.field",
- FT_UINT8, BASE_DEC, NULL, 0x0,
+ FT_UINT8, BASE_DEC, NULL, OXM_FIELD_MASK,
NULL, HFILL }
},
{ &hf_openflow_v6_oxm_field_basic,
{ "Field", "openflow_v6.oxm.field",
- FT_UINT8, BASE_DEC | BASE_EXT_STRING, &openflow_v6_oxm_basic_field_values_ext, 0x0,
+ FT_UINT8, BASE_DEC | BASE_EXT_STRING, &openflow_v6_oxm_basic_field_values_ext, OXM_FIELD_MASK,
NULL, HFILL }
},
{ &hf_openflow_v6_oxm_hm,
{ "Has mask", "openflow_v6.oxm.hm",
- FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ FT_BOOLEAN, 8, NULL, OXM_HM_MASK,
NULL, HFILL }
},
{ &hf_openflow_v6_oxm_length,
@@ -6469,11 +7015,6 @@ proto_register_openflow_v6(void)
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_instruction_meter_meter_id,
- { "Meter ID", "openflow_v6.instruction.meter.meter_id",
- FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(openflow_v6_meter_id_reserved_values), 0x0,
- NULL, HFILL }
- },
{ &hf_openflow_v6_port_desc_prop_type,
{ "Type", "openflow_v6.port.desc_prop.type",
FT_UINT16, BASE_DEC, VALS(openflow_v6_port_desc_prop_type_values), 0x0,
@@ -7404,6 +7945,16 @@ proto_register_openflow_v6(void)
FT_BOOLEAN, 32, NULL, OFPC_PORT_BLOCKED,
NULL, HFILL }
},
+ { &hf_openflow_v6_switch_features_capabilities_bundles,
+ { "OFPC_BUNDLES", "openflow_v6.switch_features.capabilities.bundles",
+ FT_BOOLEAN, 32, NULL, OFPC_BUNDLES,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_switch_features_capabilities_flow_monitoring,
+ { "OFPC_FLOW_MONITORING", "openflow_v6.switch_features.capabilities.flow_monitoring",
+ FT_BOOLEAN, 32, NULL, OFPC_FLOW_MONITORING,
+ NULL, HFILL }
+ },
{ &hf_openflow_v6_switch_features_reserved,
{ "Reserved", "openflow_v6.switch_features_reserved",
FT_UINT32, BASE_HEX, NULL, 0x0,
@@ -7474,16 +8025,6 @@ proto_register_openflow_v6(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_removed_duration_sec,
- { "Duration sec", "openflow_v6.flow_removed.duration_sec",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_flow_removed_duration_nsec,
- { "Duration nsec", "openflow_v6.flow_removed.duration_nsec",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
{ &hf_openflow_v6_flow_removed_idle_timeout,
{ "Idle timeout", "openflow_v6.flow_removed.idle_timeout",
FT_UINT16, BASE_DEC, NULL, 0x0,
@@ -7494,16 +8035,6 @@ proto_register_openflow_v6(void)
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_removed_packet_count,
- { "Packet count", "openflow_v6.flow_removed.packet_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_flow_removed_byte_count,
- { "Byte count", "openflow_v6.flow_removed.byte_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
{ &hf_openflow_v6_port_status_reason,
{ "Reason", "openflow_v6.port_status.reason",
FT_UINT8, BASE_DEC, VALS(openflow_v6_port_status_reason_values), 0x0,
@@ -7519,11 +8050,6 @@ proto_register_openflow_v6(void)
FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(openflow_v6_buffer_reserved_values), 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_packet_out_in_port,
- { "In port", "openflow_v6.packet_out.in_port",
- FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(openflow_v6_port_reserved_values), 0x0,
- NULL, HFILL }
- },
{ &hf_openflow_v6_packet_out_acts_len,
{ "Actions length", "openflow_v6.packet_out.acts_len",
FT_UINT16, BASE_DEC, NULL, 0x0,
@@ -8314,121 +8840,81 @@ proto_register_openflow_v6(void)
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_length,
- { "Length", "openflow_v6.flow_stats.length",
+ { &hf_openflow_v6_flow_desc_length,
+ { "Length", "openflow_v6.flow_desc.length",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_table_id,
- { "Table ID", "openflow_v6.flow_stats.table_id",
+ { &hf_openflow_v6_flow_desc_table_id,
+ { "Table ID", "openflow_v6.flow_desc.table_id",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_pad,
- { "Pad", "openflow_v6.flow_stats.pad",
+ { &hf_openflow_v6_flow_desc_pad,
+ { "Pad", "openflow_v6.flow_desc.pad",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_duration_sec,
- { "Duration sec", "openflow_v6.flow_stats.duration_sec",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_flow_stats_duration_nsec,
- { "Duration nsec", "openflow_v6.flow_stats.duration_nsec",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_flow_stats_priority,
- { "Priority", "openflow_v6.flow_stats.priority",
+ { &hf_openflow_v6_flow_desc_priority,
+ { "Priority", "openflow_v6.flow_desc.priority",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_idle_timeout,
- { "Idle timeout", "openflow_v6.flow_stats.idle_timeout",
+ { &hf_openflow_v6_flow_desc_idle_timeout,
+ { "Idle timeout", "openflow_v6.flow_desc.idle_timeout",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_hard_timeout,
- { "Hard timeout", "openflow_v6.flow_stats.hard_timeout",
+ { &hf_openflow_v6_flow_desc_hard_timeout,
+ { "Hard timeout", "openflow_v6.flow_desc.hard_timeout",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags,
- { "Flags", "openflow_v6.flow_stats.flags",
+ { &hf_openflow_v6_flow_desc_flags,
+ { "Flags", "openflow_v6.flow_desc.flags",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags_send_flow_rem,
- { "Send flow removed", "openflow_v6.flow_stats.flags.send_flow_rem",
+ { &hf_openflow_v6_flow_desc_flags_send_flow_rem,
+ { "Send flow removed", "openflow_v6.flow_desc.flags.send_flow_rem",
FT_BOOLEAN, 16, NULL, OFPFF_SEND_FLOW_REM,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags_check_overlap,
- { "Check overlap", "openflow_v6.flow_stats.flags.check_overlap",
+ { &hf_openflow_v6_flow_desc_flags_check_overlap,
+ { "Check overlap", "openflow_v6.flow_desc.flags.check_overlap",
FT_BOOLEAN, 16, NULL, OFPFF_CHECK_OVERLAP,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags_reset_counts,
- { "Reset counts", "openflow_v6.flow_stats.flags.reset_counts",
+ { &hf_openflow_v6_flow_desc_flags_reset_counts,
+ { "Reset counts", "openflow_v6.flow_desc.flags.reset_counts",
FT_BOOLEAN, 16, NULL, OFPFF_RESET_COUNTS,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags_no_packet_counts,
- { "Don't count packets", "openflow_v6.flow_stats.flags.no_packet_counts",
+ { &hf_openflow_v6_flow_desc_flags_no_packet_counts,
+ { "Don't count packets", "openflow_v6.flow_desc.flags.no_packet_counts",
FT_BOOLEAN, 16, NULL, OFPFF_NO_PKT_COUNTS,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_flags_no_byte_counts,
- { "Don't count bytes", "openflow_v6.flow_stats.flags.no_byte_counts",
+ { &hf_openflow_v6_flow_desc_flags_no_byte_counts,
+ { "Don't count bytes", "openflow_v6.flow_desc.flags.no_byte_counts",
FT_BOOLEAN, 16, NULL, OFPFF_NO_BYT_COUNTS,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_importance,
- { "Importance", "openflow_v6.flow_stats.importance",
+ { &hf_openflow_v6_flow_desc_importance,
+ { "Importance", "openflow_v6.flow_desc.importance",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_pad2,
- { "Pad", "openflow_v6.flow_stats.pad2",
+ { &hf_openflow_v6_flow_desc_pad2,
+ { "Pad", "openflow_v6.flow_desc.pad2",
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_cookie,
- { "Cookie", "openflow_v6.flow_stats.cookie",
+ { &hf_openflow_v6_flow_desc_cookie,
+ { "Cookie", "openflow_v6.flow_desc.cookie",
FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
- { &hf_openflow_v6_flow_stats_packet_count,
- { "Packet count", "openflow_v6.flow_stats.packet_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_flow_stats_byte_count,
- { "Byte count", "openflow_v6.flow_stats.byte_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_aggregate_stats_packet_count,
- { "Packet count", "openflow_v6.aggregate_stats.packet_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_aggregate_stats_byte_count,
- { "Byte count", "openflow_v6.aggregate_stats.byte_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_aggregate_stats_flow_count,
- { "Flow count", "openflow_v6.aggregate_stats.flow_count",
- FT_UINT64, BASE_DEC, NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_openflow_v6_aggregate_stats_pad,
- { "Pad", "openflow_v6.aggregate_stats.pad",
- FT_BYTES, BASE_NONE, NULL, 0x0,
- NULL, HFILL }
- },
{ &hf_openflow_v6_table_stats_table_id,
{ "Table ID", "openflow_v6.table_stats.table_id",
FT_UINT8, BASE_DEC|BASE_SPECIAL_VALS, VALS(openflow_v6_table_reserved_values), 0x0,
@@ -9754,7 +10240,267 @@ proto_register_openflow_v6(void)
{ "OFPBF_ORDERED", "openflow_v6.bundle_add.flags.ordered",
FT_BOOLEAN, 16, NULL, OFPBF_ORDERED,
NULL, HFILL }
- }
+ },
+ { &hf_openflow_v6_oxs_class,
+ { "Class", "openflow_v6.oxs.class",
+ FT_UINT16, BASE_HEX, VALS(openflow_v6_oxs_class_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_field,
+ { "Field", "openflow_v6.oxs.field",
+ FT_UINT8, BASE_DEC, VALS(openflow_v6_oxs_basic_field_values), OXS_FIELD_MASK,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_reserved,
+ { "Reserved", "openflow_v6.oxs.reserved",
+ FT_UINT8, BASE_HEX, NULL, OXS_RESERVED_MASK,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_length,
+ { "Length", "openflow_v6.oxs.length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_duration_sec,
+ { "Duration", "openflow_v6.oxs.duration_sec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_duration_nsec,
+ { "Duration", "openflow_v6.oxs.duration_nsec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_idle_sec,
+ { "Idle", "openflow_v6.oxs.idle_sec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_idle_nsec,
+ { "Idle", "openflow_v6.oxs.idle_nsec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_flow_count,
+ { "Flow count", "openflow_v6.oxs.flow_count",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_packet_count,
+ { "Packet count", "openflow_v6.oxs.packet_count",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_basic_byte_count,
+ { "Byte count", "openflow_v6.oxs.byte_count",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_experimenter_experimenter,
+ { "Experimenter ID", "openflow_v6.oxs.experimenter.experimenter",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxs_experimenter_value,
+ { "Experimenter ID", "openflow_v6.oxs.experimenter.value",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_stats_reserved,
+ { "Reserved", "openflow_v6.stats.reserved",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_stats_length,
+ { "Length", "openflow_v6.stats.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_stats_pad,
+ { "Pad", "openflow_v6.stats.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_oxm_register,
+ { "Register", "openflow_v6.oxm.register",
+ FT_UINT8, BASE_DEC, NULL, OXM_FIELD_MASK,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_instruction_stat_trigger_flags,
+ { "Flags", "openflow_v6.instruction.stat_trigger.flags",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_instruction_stat_triffer_flags_periodic,
+ { "Flags", "openflow_v6.instruction.stat_trigger.flags.periodic",
+ FT_UINT32, BASE_HEX, NULL, OFPSTF_PERIODIC,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_instruction_stat_triffer_flags_only_first,
+ { "Flags", "openflow_v6.instruction.stat_trigger.flags.only_first",
+ FT_UINT32, BASE_HEX, NULL, OFPSTF_ONLY_FIRST,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_instruction_stat_triffer_flags_reserved,
+ { "Flags", "openflow_v6.instruction.stat_trigger.flags.reserved",
+ FT_UINT32, BASE_HEX, NULL, 0xfffffffc,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_length,
+ { "Length", "openflow_v6.controller_status.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_short_id,
+ { "Short ID", "openflow_v6.controller_status.short_id",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_role,
+ { "Role", "openflow_v6.controller_status.role",
+ FT_UINT32, BASE_HEX, VALS(openflow_v6_controller_role_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_reason,
+ { "Reason", "openflow_v6.controller_status.reason",
+ FT_UINT8, BASE_DEC, VALS(openflow_v6_controller_status_reason_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_channel_status,
+ { "Reason", "openflow_v6.controller_status.channel_status",
+ FT_UINT8, BASE_DEC, VALS(openflow_v6_controller_status_channel_status_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_pad,
+ { "Reason", "openflow_v6.controller_status.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_time_seconds,
+ { "Seconds", "openflow_v6.time.seconds",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_time_nanoseconds,
+ { "Nanoseconds", "openflow_v6.time.nanoseconds",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_time_pad,
+ { "Pad", "openflow_v6.time.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_type,
+ { "Type", "openflow_v6.bundle_feature.prop.type",
+ FT_UINT16, BASE_HEX, VALS(openflow_v6_bundle_feature_prop_type_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_length,
+ { "Length", "openflow_v6.bundle_feature.prop.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_time_pad,
+ { "Pad", "openflow_v6.bundle_feature.prop.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_experimenter_experimenter,
+ { "Experimenter", "openflow_v6.bundle_feature.prop.experimenter.experimenter",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_experimenter_exp_type,
+ { "Type", "openflow_v6.bundle_feature.prop.experimenter.type",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_feature_prop_pad,
+ { "Pad", "openflow_v6.bundle_feature.prop.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_type,
+ { "Type", "openflow_v6.controller_status.prop.type",
+ FT_UINT16, BASE_DEC, VALS(openflow_v6_controller_status_prop_type_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_length,
+ { "Length", "openflow_v6.controller_status.prop.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_experimenter_experimenter,
+ { "Experimenter", "openflow_v6.controller_status.prop.experimenter.experimenter",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_experimenter_exp_type,
+ { "Type", "openflow_v6.controller_status.prop.experimenter.type",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_pad,
+ { "Pad", "openflow_v6.controller_status.prop.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_port_desc_prop_recirculate_port_no,
+ { "Port No", "openflow_v6.port.stats_prop.recirculate.port_no",
+ FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(openflow_v6_port_reserved_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_features_request_flags,
+ { "Flags", "openflow_v6.bundle_features_request.flags",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_bundle_features_request_pad,
+ { "Pad", "openflow_v6.bundle_features_request.pad",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_pad2,
+ { "Pad", "openflow_v6.flow_stats.pad2",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_reason,
+ { "Reason", "openflow_v6.flow_stats.reason",
+ FT_UINT8, BASE_DEC, VALS(openflow_v6_flow_stats_reason_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_length,
+ { "Length", "openflow_v6.flow_stats.length",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_table_id,
+ { "Table ID", "openflow_v6.flow_stats.table_id",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_duration_sec,
+ { "Duration sec", "openflow_v6.flow_stats.duration_sec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_duration_nsec,
+ { "Duration nsec", "openflow_v6.flow_stats.duration_nsec",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_flow_stats_priority,
+ { "Priority", "openflow_v6.flow_stats.priority",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_openflow_v6_controller_status_prop_uri,
+ { "URI", "openflow_v6.controller_status.prop.uri",
+ FT_STRINGZ, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
};
static gint *ett[] = {
@@ -9800,7 +10546,6 @@ proto_register_openflow_v6(void)
&ett_openflow_v6_flow_monitor_request_flags,
&ett_openflow_v6_multipart_request_flags,
&ett_openflow_v6_flow_stats,
- &ett_openflow_v6_flow_stats_flags,
&ett_openflow_v6_table_stats,
&ett_openflow_v6_port_stats,
&ett_openflow_v6_queue_stats,
@@ -9838,7 +10583,12 @@ proto_register_openflow_v6(void)
&ett_openflow_v6_bundle_control_flags,
&ett_openflow_v6_bundle_prop,
&ett_openflow_v6_bundle_add_flags,
- &ett_openflow_v6_bundle_add_message
+ &ett_openflow_v6_bundle_add_message,
+ &ett_openflow_v6_instruction_stat_trigger_flags,
+ &ett_openflow_v6_flow_desc,
+ &ett_openflow_v6_flow_desc_flags,
+ &ett_openflow_v6_bundle_feature_prop,
+ &ett_openflow_v6_controller_status_prop,
};
static ei_register_info ei[] = {
@@ -9929,7 +10679,15 @@ proto_register_openflow_v6(void)
{&ei_openflow_v6_length_too_short,
{ "openflow_v6.message.length_too_short", PI_MALFORMED, PI_ERROR,
"Length is too short.", EXPFILL }
- }
+ },
+ {&ei_openflow_v6_bundle_feature_prop_undecoded,
+ { "openflow_v6.bundle_feature.prop.undecoded", PI_UNDECODED, PI_NOTE,
+ "Unknown bundle feature prop body.", EXPFILL }
+ },
+ {&ei_openflow_v6_controller_status_prop_undecoded,
+ { "openflow_v6.controller_status.prop.undecoded", PI_UNDECODED, PI_NOTE,
+ "Unknown controller status prop body.", EXPFILL }
+ },
};