Merge into master from pull request #153:
Rewrite LOCI wire type pushing (https://github.com/floodlight/loxigen/pull/153)
diff --git a/wireshark_gen/field_info.py b/wireshark_gen/field_info.py
index ec81665..cf3192c 100644
--- a/wireshark_gen/field_info.py
+++ b/wireshark_gen/field_info.py
@@ -106,6 +106,7 @@
     ('of_echo_reply', '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',
     ('of_action_output', 'type'): 'ofp_action_type',
     ('of_action_group', 'type'): 'ofp_action_type',
     ('of_action_id', 'type'): 'ofp_action_type',
diff --git a/wireshark_gen/templates/_ofclass_dissector.lua b/wireshark_gen/templates/_ofclass_dissector.lua
index 0eb45eb..1e1520f 100644
--- a/wireshark_gen/templates/_ofclass_dissector.lua
+++ b/wireshark_gen/templates/_ofclass_dissector.lua
@@ -39,6 +39,9 @@
 -- Discriminator is ${ofclass.discriminator.name}
 :: #endif
 function ${name}(reader, subtree)
+:: if ofclass.virtual:
+    return ${ofclass.name}_v${version.wire_version}_dissectors[reader.peek(${ofclass.discriminator.offset},${ofclass.discriminator.length}):uint()](reader, subtree)
+:: else:
 :: for m in ofclass.members:
 :: if isinstance(m, OFPadMember):
     reader.skip(${m.length})
@@ -49,4 +52,5 @@
     ${reader_name}(reader, ${version.wire_version}, subtree, '${field_name}')
 :: #endfor
     return '${ofclass.name}'
+:: #endif
 end
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index 9a5e4fa..10f13ca 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -135,7 +135,7 @@
         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 = dissect_of_action(child_reader, child_subtree, version)
+        local info = of_action_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
     list:set_text("List of actions")
@@ -151,7 +151,7 @@
         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 = dissect_of_port_desc(child_reader, child_subtree, version)
+        local info = of_port_desc_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -166,7 +166,7 @@
         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 = dissect_of_flow_stats_entry(child_reader, child_subtree, version)
+        local info = of_flow_stats_entry_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -181,7 +181,7 @@
         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 = dissect_of_port_stats_entry(child_reader, child_subtree, version)
+        local info = of_port_stats_entry_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -196,7 +196,7 @@
         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 = dissect_of_table_stats_entry(child_reader, child_subtree, version)
+        local info = of_table_stats_entry_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -211,7 +211,7 @@
         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 = dissect_of_queue_stats_entry(child_reader, child_subtree, version)
+        local info = of_queue_stats_entry_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -244,7 +244,7 @@
         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 = dissect_of_oxm(child_reader, child_subtree, version)
+        local info = of_oxm_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
     subtree:set_text("OXM")
@@ -256,7 +256,7 @@
         return
     end
     local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
-    local info = dissect_of_instruction(reader, child_subtree, version)
+    local info = of_instruction_dissectors[version](reader, child_subtree)
     child_subtree:set_text("Instructions")
 end
 
@@ -270,7 +270,7 @@
         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 = dissect_of_bucket(child_reader, child_subtree, version)
+        local info = of_bucket_dissectors[version](child_reader, child_subtree)
         child_subtree:set_text(info)
     end
 end
@@ -280,6 +280,6 @@
         return
     end
     local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
-    local info = dissect_of_oxm(reader, child_subtree, version)
+    local info = of_oxm_dissectors[version](reader, child_subtree)
     child_subtree:set_text(info)
 end
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index d9eb76a..bdbe2ec 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -39,8 +39,6 @@
 
 :: include('_ofreader.lua')
 
-:: include('_oftype_readers.lua')
-
 p_of = Proto ("of", "OpenFlow")
 
 local openflow_versions = {
@@ -89,7 +87,6 @@
 :: #endfor
 
 --- Dissectors for each class
-
 :: for version, ofproto in ir.items():
 :: for ofclass in ofproto.classes:
 :: name = 'dissect_%s_v%d' % (ofclass.name, version.wire_version)
@@ -105,25 +102,25 @@
 
 local of_message_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_header_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_header_v${version.wire_version},
 :: #endfor
 }
 
 local of_oxm_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_oxm_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_oxm_v${version.wire_version},
 :: #endfor
 }
 
 local of_action_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_action_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_action_v${version.wire_version},
 :: #endfor
 }
 
 local of_instruction_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_instruction_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_instruction_v${version.wire_version},
 :: #endfor
 }
 
@@ -141,13 +138,13 @@
 
 local of_stats_reply_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_stats_reply_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_stats_reply_v${version.wire_version},
 :: #endfor
 }
 
 local of_stats_request_dissectors = {
 :: for version in ir:
-    [${version.wire_version}] = of_stats_request_v${version.wire_version}_dissectors,
+    [${version.wire_version}] = dissect_of_stats_request_v${version.wire_version},
 :: #endfor
 }
 
@@ -175,6 +172,8 @@
 :: #endfor
 }
 
+:: include('_oftype_readers.lua')
+
 function dissect_of_message(buf, root)
     local reader = OFReader.new(buf)
     local subtree = root:add(p_of, buf(0))
@@ -187,103 +186,11 @@
     end
 
     local info = "unknown"
-    if type_val == 19 then
-        local stats_type = buf(8,2):uint()
-        info = of_stats_reply_dissectors[version_val][stats_type](reader,subtree)
-    elseif type_val == 18 then
-        local stats_type = buf(8,2):uint()
-        info = of_stats_request_dissectors[version_val][stats_type](reader,subtree)
-    elseif of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then
-        info = of_message_dissectors[version_val][type_val](reader, subtree)
-    end
+    info = of_message_dissectors[version_val](reader, subtree)
 
     return protocol, info
 end
 
-function dissect_of_oxm(reader, subtree, version_val)
-    local type_val = reader.peek(0,4):uint()
-    local info = "unknown"
-    if of_oxm_dissectors[version_val] and of_oxm_dissectors[version_val][type_val] then
-        info = of_oxm_dissectors[version_val][type_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_action(reader, subtree, version_val)
-    local type_val = reader.peek(0,2):uint()
-    local info = "unknown"
-    if of_action_dissectors[version_val] and of_action_dissectors[version_val][type_val] then
-        info = of_action_dissectors[version_val][type_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_instruction(reader, subtree, version_val)
-    local type_val = reader.peek(0,2):uint()
-    local info = "unknown"
-    if of_instruction_dissectors[version_val] and of_instruction_dissectors[version_val][type_val] then
-        info = of_instruction_dissectors[version_val][type_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_bucket(reader, subtree, version_val)
-    local info = "unknown"
-    if of_bucket_dissectors[version_val] then
-        info = of_bucket_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_port_desc(reader, subtree, version_val)
-    local info = "unknown"
-    if of_port_desc_dissectors[version_val] then
-        info = of_port_desc_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_flow_stats_entry(reader, subtree, version_val)
-    local info = "unknown"
-    if of_flow_stats_entry_dissectors[version_val] then
-        info = of_flow_stats_entry_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_port_stats_entry(reader, subtree, version_val)
-    local info = "unknown"
-    if of_port_stats_entry_dissectors[version_val] then
-        info = of_port_stats_entry_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_table_stats_entry(reader, subtree, version_val)
-    local info = "unknown"
-    if of_table_stats_entry_dissectors[version_val] then
-        info = of_table_stats_entry_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
-function dissect_of_queue_stats_entry(reader, subtree, version_val)
-    local info = "unknown"
-    if of_queue_stats_entry_dissectors[version_val] then
-        info = of_queue_stats_entry_dissectors[version_val](reader, subtree)
-    end
-
-    return info
-end
-
 -- of dissector function
 function p_of.dissector (buf, pkt, root)
     local offset = 0