Merge into master from pull request #161:
List reading (https://github.com/floodlight/loxigen/pull/161)
diff --git a/loxi_ir/ir.py b/loxi_ir/ir.py
index 6fae92b..6a053c6 100644
--- a/loxi_ir/ir.py
+++ b/loxi_ir/ir.py
@@ -176,6 +176,10 @@
raise Exception("Not a fixed length class: {}".format(self.name))
@property
+ def length_member(self):
+ return find(lambda m: type(m) == OFLengthMember, self.members)
+
+ @property
def has_internal_alignment(self):
return self.params.get('length_includes_align') == 'True'
diff --git a/wireshark_gen/field_info.py b/wireshark_gen/field_info.py
index cf3192c..91c6aba 100644
--- a/wireshark_gen/field_info.py
+++ b/wireshark_gen/field_info.py
@@ -104,6 +104,8 @@
('of_barrier_reply', 'type'): 'ofp_type',
('of_echo_request', 'type'): 'ofp_type',
('of_echo_reply', 'type'): 'ofp_type',
+ ('of_flow_delete', 'type'): 'ofp_type',
+ ('of_flow_add', 'type'): 'ofp_type',
('of_match_v3', 'type'): 'ofp_match_type',
('of_action_set_nw_ttl', 'type'): 'ofp_action_type',
('of_action_set_field', 'type'): 'ofp_action_type',
diff --git a/wireshark_gen/templates/_ofclass_dissector.lua b/wireshark_gen/templates/_ofclass_dissector.lua
index 1e1520f..d327b49 100644
--- a/wireshark_gen/templates/_ofclass_dissector.lua
+++ b/wireshark_gen/templates/_ofclass_dissector.lua
@@ -39,17 +39,39 @@
-- Discriminator is ${ofclass.discriminator.name}
:: #endif
function ${name}(reader, subtree)
+:: field_length_members = []
:: if ofclass.virtual:
return ${ofclass.name}_v${version.wire_version}_dissectors[reader.peek(${ofclass.discriminator.offset},${ofclass.discriminator.length}):uint()](reader, subtree)
:: else:
+:: if not ofclass.is_fixed_length:
+ local _length = reader.peek(${ofclass.length_member.offset}, ${ofclass.length_member.base_length}):uint()
+ local orig_reader = reader
+ reader = orig_reader.slice(_length)
+:: #endif
:: for m in ofclass.members:
:: if isinstance(m, OFPadMember):
reader.skip(${m.length})
:: continue
:: #endif
+:: if isinstance(m, OFFieldLengthMember):
+ local _${m.field_name}_length = reader.peek(0, ${m.base_length}):uint()
+:: field_length_members.append(m.field_name)
+:: #endif
+:: if m.oftype.startswith("list"):
+:: class_name = m.oftype.replace('_t)', '').replace('(', '').replace('list', '')
+:: if m.name in field_length_members:
+ read_list(reader.slice(_${m.name}_length), dissect_${class_name}_v${version.wire_version}, subtree, '${class_name}')
+:: else:
+ read_list(reader, dissect_${class_name}_v${version.wire_version}, subtree, '${class_name}')
+:: #endif
+:: if ofclass.has_external_alignment:
+ orig_reader.skip_align()
+:: #endif
+:: else:
:: field_name = make_field_name(version, ofclass.name, m.name)
:: reader_name = get_reader(version, ofclass, m)
${reader_name}(reader, ${version.wire_version}, subtree, '${field_name}')
+:: #endif
:: #endfor
return '${ofclass.name}'
:: #endif
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index 10f13ca..586bbbf 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -57,11 +57,11 @@
function read_of_match_t(reader, version, subtree, field_name)
if version == 1 then
- dissect_of_match_v1_v1(reader, subtree:add(fields[field_name]))
+ dissect_of_match_v1_v1(reader, subtree:add("of_match"))
elseif version == 2 then
- dissect_of_match_v2_v2(reader, subtree:add(fields[field_name]))
+ dissect_of_match_v2_v2(reader, subtree:add("of_match"))
elseif version >= 3 then
- dissect_of_match_v3_v3(reader, subtree:add(fields[field_name]))
+ dissect_of_match_v3_v3(reader, subtree:add("of_match"))
end
end
@@ -105,122 +105,6 @@
end
end
-function read_list_of_action_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
-
- local list_len = 0
-
- if string.find(field_name,'packet_out') then
- if version == 1 then
- list_len = reader.peek(-2,2):uint()
- else
- list_len = reader.peek(-8,2):uint()
- end
- end
-
- local list = nil
- local reader2 = nil
-
- if list_len == 0 then
- list = subtree:add(fields[field_name], reader.peek_all(0))
- reader2 = reader
- else
- list = subtree:add(fields[field_name], reader.peek(0, list_len))
- reader2 = reader.slice(list_len)
- end
-
- while not reader2.is_empty() do
- local action_len = reader2.peek(2, 2):uint()
- local child_reader = reader2.slice(action_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_action_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
- list:set_text("List of actions")
-end
-
-function read_list_of_port_desc_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list = subtree:add(fields[field_name], reader.peek_all(0))
- list:set_text("List of port descriptions")
- while not reader.is_empty() do
- local port_desc_len = 64
- local child_reader = reader.slice(port_desc_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_port_desc_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
-function read_list_of_flow_stats_entry_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list = subtree:add(fields[field_name], reader.peek_all(0))
- list:set_text("List of flow stats entries")
- while not reader.is_empty() do
- local stats_len = reader.peek(0,2):uint()
- local child_reader = reader.slice(stats_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_flow_stats_entry_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
-function read_list_of_port_stats_entry_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list = subtree:add(fields[field_name], reader.peek_all(0))
- list:set_text("List of port stats entries")
- while not reader.is_empty() do
- local stats_len = 112
- local child_reader = reader.slice(stats_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_port_stats_entry_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
-function read_list_of_table_stats_entry_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list = subtree:add(fields[field_name], reader.peek_all(0))
- list:set_text("List of table stats entries")
- while not reader.is_empty() do
- local stats_len = 24
- local child_reader = reader.slice(stats_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_table_stats_entry_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
-function read_list_of_queue_stats_entry_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list = subtree:add(fields[field_name], reader.peek_all(0))
- list:set_text("List of flow stats entries")
- while not reader.is_empty() do
- local stats_len = 40
- local child_reader = reader.slice(stats_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_queue_stats_entry_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
-function read_list_of_packet_queue_t(reader, version, subtree, field_name)
- -- TODO
- read_of_octets_t()
-end
-
function read_of_desc_str_t(reader, version, subtree, field_name)
read_scalar(reader, subtree, field_name, 256)
end
@@ -229,52 +113,6 @@
read_scalar(reader, subtree, field_name, 32)
end
-function read_list_of_oxm_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local list_len = reader.peek(-2,2):uint()
- local reader2 = reader.slice(list_len - 4)
- local list = nil
- if not reader2.is_empty() then
- list = subtree:add(fields[field_name], reader2.peek_all(0))
- list:set_text("List of matches")
- end
- while not reader2.is_empty() do
- local match_len = 4 + reader2.peek(3,1):uint()
- local child_reader = reader2.slice(match_len)
- local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = of_oxm_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
- subtree:set_text("OXM")
- reader.skip_align()
-end
-
-function read_list_of_instruction_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
- local info = of_instruction_dissectors[version](reader, child_subtree)
- child_subtree:set_text("Instructions")
-end
-
-function read_list_of_bucket_t(reader, version, subtree, field_name)
- if reader.is_empty() then
- return
- end
- local bucket_list_subtree = subtree:add(fields[field_name], reader.peek_all(0))
- bucket_list_subtree:set_text("List of buckets")
- while not reader.is_empty() do
- local bucket_len = reader.peek(0,2):uint()
- local child_reader = reader.slice(bucket_len)
- local child_subtree = bucket_list_subtree:add(fields[field_name], child_reader.peek_all(0))
- local info = of_bucket_dissectors[version](child_reader, child_subtree)
- child_subtree:set_text(info)
- end
-end
-
function read_of_oxm_t(reader, version, subtree, field_name)
if reader.is_empty() then
return
@@ -283,3 +121,16 @@
local info = of_oxm_dissectors[version](reader, child_subtree)
child_subtree:set_text(info)
end
+
+function read_list(reader, dissector, subtree, field_name)
+ if not reader.is_empty() then
+ local list_subtree = subtree:add(field_name .. " list", reader.peek_all(0))
+ while not reader.is_empty() do
+ local atom_subtree = list_subtree:add(field_name, reader.peek_all(0))
+ local info = dissector(reader, atom_subtree)
+ atom_subtree:set_text(info)
+ end
+ else
+ return
+ end
+end
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index bdbe2ec..ea8bb95 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -112,66 +112,6 @@
:: #endfor
}
-local of_action_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_action_v${version.wire_version},
-:: #endfor
-}
-
-local of_instruction_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_instruction_v${version.wire_version},
-:: #endfor
-}
-
-local of_bucket_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_bucket_v${version.wire_version},
-:: #endfor
-}
-
-local of_port_desc_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_port_desc_v${version.wire_version},
-:: #endfor
-}
-
-local of_stats_reply_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_stats_reply_v${version.wire_version},
-:: #endfor
-}
-
-local of_stats_request_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_stats_request_v${version.wire_version},
-:: #endfor
-}
-
-local of_flow_stats_entry_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_flow_stats_entry_v${version.wire_version},
-:: #endfor
-}
-
-local of_port_stats_entry_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_port_stats_entry_v${version.wire_version},
-:: #endfor
-}
-
-local of_table_stats_entry_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_table_stats_entry_v${version.wire_version},
-:: #endfor
-}
-
-local of_queue_stats_entry_dissectors = {
-:: for version in ir:
- [${version.wire_version}] = dissect_of_queue_stats_entry_v${version.wire_version},
-:: #endfor
-}
-
:: include('_oftype_readers.lua')
function dissect_of_message(buf, root)