Merge branch 'master' of github.com:floodlight/loxigen
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 0d1cc87..83c89b5 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -79,8 +79,8 @@
                 "OFOxmEthSrcMasked":        OxmMapEntry("MacAddress", "ETH_SRC", True),
                 "OFOxmEthType":             OxmMapEntry("EthType", "ETH_TYPE", False),
                 "OFOxmEthTypeMasked":       OxmMapEntry("EthType", "ETH_TYPE", True),
-                "OFOxmVlanVid":             OxmMapEntry("VlanVid", "VLAN_VID", False),
-                "OFOxmVlanVidMasked":       OxmMapEntry("VlanVid", "VLAN_VID", True),
+                "OFOxmVlanVid":             OxmMapEntry("OFVlanVidMatch", "VLAN_VID", False),
+                "OFOxmVlanVidMasked":       OxmMapEntry("OFVlanVidMatch", "VLAN_VID", True),
                 "OFOxmVlanPcp":             OxmMapEntry("VlanPcp", "VLAN_PCP", False),
                 "OFOxmVlanPcpMasked":       OxmMapEntry("VlanPcp", "VLAN_PCP", True),
                 "OFOxmIpDscp":              OxmMapEntry("IpDscp", "IP_DSCP", False),
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index d2e60f7..333efd8 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -358,9 +358,11 @@
             write="$name.write2Bytes(bb)",
             default="EthType.NONE")
 vlan_vid = JType("VlanVid")\
-        .op(version=1, read="VlanVid.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="VlanVid.NONE") \
-        .op(version=2, read="VlanVid.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="VlanVid.NONE") \
-        .op(version=ANY, read="VlanVid.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="VlanVid.NONE")
+        .op(version=ANY, read="VlanVid.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="VlanVid.ZERO")
+vlan_vid_match = JType("OFVlanVidMatch")\
+        .op(version=1, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
+        .op(version=2, read="OFVlanVidMatch.read2BytesOF10(bb)", write="$name.write2BytesOF10(bb)", default="OFVlanVidMatch.NONE") \
+        .op(version=ANY, read="OFVlanVidMatch.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFVlanVidMatch.NONE")
 vlan_pcp = JType("VlanPcp")\
         .op(read="VlanPcp.readByte(bb)",
             write="$name.writeByte(bb)",
@@ -523,8 +525,8 @@
         'of_oxm_sctp_dst_masked' : { 'value' : transport_port, 'value_mask' : transport_port },
         'of_oxm_eth_type' : { 'value' : eth_type },
         'of_oxm_eth_type_masked' : { 'value' : eth_type, 'value_mask' : eth_type },
-        'of_oxm_vlan_vid' : { 'value' : vlan_vid },
-        'of_oxm_vlan_vid_masked' : { 'value' : vlan_vid, 'value_mask' : vlan_vid },
+        'of_oxm_vlan_vid' : { 'value' : vlan_vid_match },
+        'of_oxm_vlan_vid_masked' : { 'value' : vlan_vid_match, 'value_mask' : vlan_vid_match },
         'of_oxm_vlan_pcp' : { 'value' : vlan_pcp },
         'of_oxm_vlan_pcp_masked' : { 'value' : vlan_pcp, 'value_mask' : vlan_pcp },
         'of_oxm_ip_dscp' : { 'value' : ip_dscp },
@@ -579,7 +581,7 @@
         'of_oxm_bsn_l3_dst_class_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
 
         'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
-        'of_match_v1': { 'vlan_vid' : vlan_vid, 'vlan_pcp': vlan_pcp,
+        'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
                 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
                 'tcp_src': transport_port, 'tcp_dst': transport_port,
                 'in_port': of_port_match_v1
@@ -588,6 +590,19 @@
         'of_bsn_set_l2_table_reply': { 'l2_table_enable': boolean },
         'of_bsn_set_pktin_suppression_request': { 'enabled': boolean },
         'of_flow_stats_request': { 'out_group': of_group_default_any },
+
+        'of_action_bsn_mirror': { 'dest_port': of_port },
+        'of_action_push_mpls': { 'ethertype': eth_type },
+        'of_action_push_pbb': { 'ethertype': eth_type },
+        'of_action_push_vlan': { 'ethertype': eth_type },
+        'of_action_set_nw_dst': { 'nw_addr': ipv4 },
+        'of_action_set_nw_ecn': { 'nw_ecn': ip_ecn },
+        'of_action_set_nw_src': { 'nw_addr': ipv4 },
+        'of_action_set_nw_dst': { 'tp_port': transport_port },
+        'of_action_set_tp_dst': { 'tp_port': transport_port },
+        'of_action_set_tp_src': { 'tp_port': transport_port },
+        'of_action_set_vlan_pcp': { 'vlan_pcp': vlan_pcp },
+        'of_action_set_vlan_vid': { 'vlan_vid': vlan_vid },
 }
 
 
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index e93b6f5..e516b6e 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>org.projectfloodlight</groupId>
     <artifactId>openflowj</artifactId>
-    <version>0.3.0-SNAPSHOT</version>
+    <version>0.3.1-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>OpenFlowJ-Loxi</name>
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index 1831626..92d4878 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -18,12 +18,12 @@
 import org.projectfloodlight.openflow.types.OFMetadata;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.OFValueType;
+import org.projectfloodlight.openflow.types.OFVlanVidMatch;
 import org.projectfloodlight.openflow.types.TransportPort;
 import org.projectfloodlight.openflow.types.U32;
 import org.projectfloodlight.openflow.types.U8;
-import org.projectfloodlight.openflow.types.VlanPcp;
-import org.projectfloodlight.openflow.types.VlanVid;
 import org.projectfloodlight.openflow.types.VRF;
+import org.projectfloodlight.openflow.types.VlanPcp;
 
 @SuppressWarnings("unchecked")
 public class MatchField<F extends OFValueType<F>> {
@@ -56,12 +56,12 @@
     public final static MatchField<EthType> ETH_TYPE =
             new MatchField<EthType>("eth_type", MatchFields.ETH_TYPE);
 
-    public final static MatchField<VlanVid> VLAN_VID =
-            new MatchField<VlanVid>("vlan_vid", MatchFields.VLAN_VID);
+    public final static MatchField<OFVlanVidMatch> VLAN_VID =
+            new MatchField<OFVlanVidMatch>("vlan_vid", MatchFields.VLAN_VID);
 
     public final static MatchField<VlanPcp> VLAN_PCP =
             new MatchField<VlanPcp>("vlan_pcp", MatchFields.VLAN_PCP,
-                    new Prerequisite<VlanVid>(MatchField.VLAN_VID));
+                    new Prerequisite<OFVlanVidMatch>(MatchField.VLAN_VID));
 
     public final static MatchField<IpDscp> IP_DSCP =
             new MatchField<IpDscp>("ip_dscp", MatchFields.IP_DSCP,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
new file mode 100644
index 0000000..29d6e02
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
@@ -0,0 +1,183 @@
+package org.projectfloodlight.openflow.types;
+
+import javax.annotation.Nullable;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+
+import com.google.common.hash.PrimitiveSink;
+import com.google.common.primitives.Shorts;
+
+/** Represents an OpenFlow Vlan VID for use in Matches, as specified by the OpenFlow 1.3 spec.
+ *
+ *  <b> Note: this is not just the 12-bit vlan tag. OpenFlow defines
+ *      the additional mask bits 0x1000 to represent the presence of a vlan
+ *      tag. This additional bit will be stripped when writing a OF1.0 value
+ *      tag.
+ *  </b>
+ *
+ *
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ *
+ */
+public class OFVlanVidMatch implements OFValueType<OFVlanVidMatch> {
+
+    private static final short VALIDATION_MASK = 0x1FFF;
+    private static final short PRESENT_VAL = 0x1000;
+    private static final short VLAN_MASK = 0x0FFF;
+    private static final short NONE_VAL = 0x0000;
+    private static final short UNTAGGED_VAL_OF13 = (short) 0x0000;
+    private static final short UNTAGGED_VAL_OF10 = (short) 0xFFFF;
+    final static int LENGTH = 2;
+
+    /** presence of a VLAN tag is indicated by the presence of bit 0x1000 */
+    public static final OFVlanVidMatch PRESENT = new OFVlanVidMatch(PRESENT_VAL);
+
+    /** this value means 'not set' in OF1.0 (e.g., in a match). not used elsewhere */
+    public static final OFVlanVidMatch NONE = new OFVlanVidMatch(NONE_VAL);
+
+    /** for use with masking operations */
+    public static final OFVlanVidMatch NO_MASK = new OFVlanVidMatch((short)0xFFFF);
+    public static final OFVlanVidMatch FULL_MASK = NONE;
+
+    /** an untagged packet is specified as 0000 in OF 1.0, but 0xFFFF in OF1.0. Special case that. */
+    public static final OFVlanVidMatch UNTAGGED = new OFVlanVidMatch(NONE_VAL) {
+        @Override
+        public void write2BytesOF10(ChannelBuffer c) {
+            c.writeShort(UNTAGGED_VAL_OF10);
+        }
+    };
+
+    private final short vid;
+
+    private OFVlanVidMatch(short vid) {
+        this.vid = vid;
+    }
+
+    public static OFVlanVidMatch ofRawVid(short vid) {
+        if(vid == UNTAGGED_VAL_OF13)
+            return UNTAGGED;
+        else if(vid == PRESENT_VAL)
+            return PRESENT;
+        else if ((vid & VALIDATION_MASK) != vid)
+            throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
+        return new OFVlanVidMatch(vid);
+    }
+
+    public static OFVlanVidMatch ofVlanVid(VlanVid vid) {
+        return ofVlan(vid.getVlan());
+    }
+
+
+    public static OFVlanVidMatch ofVlan(int vlan) {
+        if( (vlan & VLAN_MASK) != vlan)
+            throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vlan));
+        return ofRawVid( (short) (vlan | PRESENT_VAL));
+    }
+
+    public static OFVlanVidMatch ofVlanOF10(short of10vlan) {
+        if(of10vlan == NONE_VAL) {
+            return NONE;
+        } else if(of10vlan == UNTAGGED_VAL_OF10) {
+            return UNTAGGED;
+        } else {
+            return ofVlan(of10vlan);
+        }
+    }
+
+    /** @return whether or not this VlanId has the present (0x1000) bit set */
+    public boolean isPresentBitSet() {
+       return (vid & PRESENT_VAL) != 0;
+    }
+
+    /** @return the actual VLAN tag this vid identifies */
+    public short getVlan() {
+        return (short) (vid & VLAN_MASK);
+    }
+
+    /** @return the actual vlan tag this vid identifies as a VlanVid object, if this
+     *  VlanVidMatch has the present bit set (i.e., identifies a tagged VLAN).
+     *  Else, returns null.
+     */
+    @Nullable
+    public VlanVid getVlanVid() {
+        return isPresentBitSet() ? VlanVid.ofVlan((short) (vid & VLAN_MASK)) : null;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof OFVlanVidMatch))
+            return false;
+        OFVlanVidMatch other = (OFVlanVidMatch)obj;
+        if (other.vid != this.vid)
+            return false;
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int prime = 13873;
+        return this.vid * prime;
+    }
+
+    @Override
+    public String toString() {
+        return "0x" + Integer.toHexString(vid);
+    }
+
+    public short getRawVid() {
+        return vid;
+    }
+
+
+    @Override
+    public int getLength() {
+        return LENGTH;
+    }
+
+
+    volatile byte[] bytesCache = null;
+
+    public byte[] getBytes() {
+        if (bytesCache == null) {
+            synchronized (this) {
+                if (bytesCache == null) {
+                    bytesCache =
+                            new byte[] { (byte) ((vid >>> 8) & 0xFF),
+                                         (byte) ((vid >>> 0) & 0xFF) };
+                }
+            }
+        }
+        return bytesCache;
+    }
+
+    public void write2Bytes(ChannelBuffer c) {
+        c.writeShort(this.vid);
+    }
+
+    public void write2BytesOF10(ChannelBuffer c) {
+        c.writeShort(this.getVlan());
+    }
+
+    public static OFVlanVidMatch read2Bytes(ChannelBuffer c) throws OFParseError {
+        return OFVlanVidMatch.ofRawVid(c.readShort());
+    }
+
+    public static OFVlanVidMatch read2BytesOF10(ChannelBuffer c) throws OFParseError {
+        return OFVlanVidMatch.ofVlanOF10(c.readShort());
+    }
+
+    @Override
+    public OFVlanVidMatch applyMask(OFVlanVidMatch mask) {
+        return OFVlanVidMatch.ofRawVid((short)(this.vid & mask.vid));
+    }
+
+    @Override
+    public int compareTo(OFVlanVidMatch o) {
+        return Shorts.compare(vid, o.vid);
+    }
+    @Override
+    public void putTo(PrimitiveSink sink) {
+        sink.putShort(vid);
+    }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatchWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatchWithMask.java
new file mode 100644
index 0000000..c91c28c
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatchWithMask.java
@@ -0,0 +1,10 @@
+package org.projectfloodlight.openflow.types;
+
+public class OFVlanVidMatchWithMask extends Masked<OFVlanVidMatch> {
+    private OFVlanVidMatchWithMask(OFVlanVidMatch value, OFVlanVidMatch mask) {
+        super(value, mask);
+    }
+
+    /* a combination of Vlan Vid and mask that matches any tagged packet */
+    public final static OFVlanVidMatchWithMask ANY_TAGGED = new OFVlanVidMatchWithMask(OFVlanVidMatch.PRESENT, OFVlanVidMatch.PRESENT);
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
index d370711..b63e4dc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVid.java
@@ -6,45 +6,23 @@
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.Shorts;
 
-/** Represents an OpenFlow Vlan VID, as specified by the OpenFlow 1.3 spec.
- *
- *  <b> Note: this is not just the 12-bit vlan tag. OpenFlow defines
- *      the additional mask bits 0x1000 to represent the presence of a vlan
- *      tag. This additional bit will be stripped when writing a OF1.0 value
- *      tag.
- *  </b>
- *
+/** Represents an 802.1Q Vlan VID (12 bits).
  *
  * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
  *
  */
 public class VlanVid implements OFValueType<VlanVid> {
 
-    private static final short VALIDATION_MASK = 0x1FFF;
-    private static final short PRESENT_VAL = 0x1000;
-    private static final short VLAN_MASK = 0x0FFF;
-    private static final short NONE_VAL = 0x0000;
-    private static final short UNTAGGED_VAL_OF13 = (short) 0x0000;
-    private static final short UNTAGGED_VAL_OF10 = (short) 0xFFFF;
+    private static final short VALIDATION_MASK = 0x0FFF;
+    private static final short ZERO_VAL = 0x0000;
     final static int LENGTH = 2;
 
-    /** presence of a VLAN tag is idicated by the presence of bit 0x1000 */
-    public static final VlanVid PRESENT = new VlanVid(PRESENT_VAL);
-
     /** this value means 'not set' in OF1.0 (e.g., in a match). not used elsewhere */
-    public static final VlanVid NONE = new VlanVid(NONE_VAL);
+    public static final VlanVid ZERO = new VlanVid(ZERO_VAL);
 
     /** for use with masking operations */
     public static final VlanVid NO_MASK = new VlanVid((short)0xFFFF);
-    public static final VlanVid FULL_MASK = NONE;
-
-    /** an untagged packet is specified as 0000 in OF 1.0, but 0xFFFF in OF1.0. Special case that. */
-    public static final VlanVid UNTAGGED = new VlanVid(NONE_VAL) {
-        @Override
-        public void write2BytesOF10(ChannelBuffer c) {
-            c.writeShort(UNTAGGED_VAL_OF10);
-        }
-    };
+    public static final VlanVid FULL_MASK = ZERO;
 
     private final short vid;
 
@@ -52,40 +30,15 @@
         this.vid = vid;
     }
 
-    public static VlanVid ofRawVid(short vid) {
-        if(vid == UNTAGGED_VAL_OF13)
-            return UNTAGGED;
-        else if(vid == PRESENT_VAL)
-            return PRESENT;
-        else if ((vid & VALIDATION_MASK) != vid)
+    public static VlanVid ofVlan(short vid) {
+        if ((vid & VALIDATION_MASK) != vid)
             throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
         return new VlanVid(vid);
     }
 
-    public static VlanVid ofVlan(int vlan) {
-        if( (vlan & VLAN_MASK) != vlan)
-            throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vlan));
-        return ofRawVid( (short) (vlan | PRESENT_VAL));
-    }
-
-    public static VlanVid ofVlanOF10(short of10vlan) {
-        if(of10vlan == NONE_VAL) {
-            return NONE;
-        } else if(of10vlan == UNTAGGED_VAL_OF10) {
-            return UNTAGGED;
-        } else {
-            return ofVlan(of10vlan);
-        }
-    }
-
-    /** @return whether or not this VlanId has the present (0x1000) bit set */
-    public boolean isPresentBitSet() {
-       return (vid & PRESENT_VAL) != 0;
-    }
-
     /** @return the actual VLAN tag this vid identifies */
     public short getVlan() {
-        return (short) (vid & VLAN_MASK);
+        return vid;
     }
 
     @Override
@@ -109,17 +62,11 @@
         return "0x" + Integer.toHexString(vid);
     }
 
-    public short getRawVid() {
-        return vid;
-    }
-
-
     @Override
     public int getLength() {
         return LENGTH;
     }
 
-
     volatile byte[] bytesCache = null;
 
     public byte[] getBytes() {
@@ -144,22 +91,19 @@
     }
 
     public static VlanVid read2Bytes(ChannelBuffer c) throws OFParseError {
-        return VlanVid.ofRawVid(c.readShort());
-    }
-
-    public static VlanVid read2BytesOF10(ChannelBuffer c) throws OFParseError {
-        return VlanVid.ofVlanOF10(c.readShort());
+        return VlanVid.ofVlan(c.readShort());
     }
 
     @Override
     public VlanVid applyMask(VlanVid mask) {
-        return VlanVid.ofRawVid((short)(this.vid & mask.vid));
+        return VlanVid.ofVlan((short)(this.vid & mask.vid));
     }
 
     @Override
     public int compareTo(VlanVid o) {
         return Shorts.compare(vid, o.vid);
     }
+
     @Override
     public void putTo(PrimitiveSink sink) {
         sink.putShort(vid);
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVidWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVidWithMask.java
deleted file mode 100644
index cb81d31..0000000
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/VlanVidWithMask.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.projectfloodlight.openflow.types;
-
-public class VlanVidWithMask extends Masked<VlanVid> {
-    private VlanVidWithMask(VlanVid value, VlanVid mask) {
-        super(value, mask);
-    }
-
-    /* a combination of Vlan Vid and mask that matches any tagged packet */
-    public final static VlanVidWithMask ANY_TAGGED = new VlanVidWithMask(VlanVid.PRESENT, VlanVid.PRESENT);
-
-}
diff --git a/java_gen/templates/custom/OFMatchV1Ver10.Builder.java b/java_gen/templates/custom/OFMatchV1Ver10.Builder.java
index 239828e..396e3a0 100644
--- a/java_gen/templates/custom/OFMatchV1Ver10.Builder.java
+++ b/java_gen/templates/custom/OFMatchV1Ver10.Builder.java
@@ -381,7 +381,7 @@
                     wildcards &= ~OFPFW_DL_VLAN_PCP;
                     break;
                 case VLAN_VID:
-                    setVlanVid((VlanVid) value);
+                    setVlanVid((OFVlanVidMatch) value);
                     wildcards &= ~OFPFW_DL_VLAN;
                     break;
                 default:
@@ -492,7 +492,7 @@
                     wildcards |= OFPFW_DL_VLAN_PCP;
                     break;
                 case VLAN_VID:
-                    setVlanVid(VlanVid.NONE);
+                    setVlanVid(OFVlanVidMatch.NONE);
                     wildcards |= OFPFW_DL_VLAN;
                     break;
                 default:
diff --git a/wireshark_gen/field_info.py b/wireshark_gen/field_info.py
index 4a80a8e..ec81665 100644
--- a/wireshark_gen/field_info.py
+++ b/wireshark_gen/field_info.py
@@ -113,9 +113,52 @@
     ('of_instruction_write_actions', 'type'): 'ofp_instruction_type',
     ('of_group_mod', 'group_type'): 'ofp_group_type',
     ('of_group_mod', 'type'): 'ofp_type',
-    ('of_group_mod', 'command'): 'ofp_group_mod_commane',
+    ('of_group_mod', 'command'): 'ofp_group_mod_command',
     ('of_group_mod', 'group_id'): 'ofp_group',
-
+    ('of_packet_out', 'type'): 'ofp_type',
+    ('of_packet_in', 'type'): 'ofp_type',
+    ('of_packet_in', 'reason'): 'ofp_packet_in_reason',
+    ('of_flow_stats_request', 'type'): 'ofp_type',
+    ('of_flow_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_desc_stats_request', 'type'): 'ofp_type',
+    ('of_desc_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_queue_stats_request', 'type'): 'ofp_type',
+    ('of_queue_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_port_stats_request', 'type'): 'ofp_type',
+    ('of_port_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_table_stats_request', 'type'): 'ofp_type',
+    ('of_table_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_port_desc_stats_request', 'type'): 'ofp_type',
+    ('of_port_desc_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_meter_stats_request', 'type'): 'ofp_type',
+    ('of_meter_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_meter_features_stats_request', 'type'): 'ofp_type',
+    ('of_meter_features_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_meter_config_stats_request', 'type'): 'ofp_type',
+    ('of_meter_config_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_group_stats_request', 'type'): 'ofp_type',
+    ('of_group_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_group_features_stats_request', 'type'): 'ofp_type',
+    ('of_group_features_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_group_desc_stats_request', 'type'): 'ofp_type',
+    ('of_group_desc_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_aggregate_stats_request', 'type'): 'ofp_type',
+    ('of_aggregate_stats_request', 'stats_type'): 'ofp_stats_type',
+    ('of_async_get_request', 'type'): 'ofp_type',
+    ('of_flow_stats_reply', 'type'): 'ofp_type',
+    ('of_flow_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_desc_stats_reply', 'type'): 'ofp_type',
+    ('of_desc_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_queue_stats_reply', 'type'): 'ofp_type',
+    ('of_queue_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_port_stats_reply', 'type'): 'ofp_type',
+    ('of_port_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_table_stats_reply', 'type'): 'ofp_type',
+    ('of_table_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_port_desc_stats_reply', 'type'): 'ofp_type',
+    ('of_port_desc_stats_reply', 'stats_type'): 'ofp_stats_type',
+    ('of_aggregate_stats_reply', 'type'): 'ofp_type',
+    ('of_aggregate_stats_reply', 'stats_type'): 'ofp_stats_type',
 }
 
 # Override oftype_to_base for certain field names
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index 4f5d7f9..9a5e4fa 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -81,6 +81,10 @@
     end
 end
 
+function read_of_port_name_t(reader, version, subtree, field_name)
+    read_scalar(reader, subtree, field_name, 16)
+end
+
 function read_of_mac_addr_t(reader, version, subtree, field_name)
     read_scalar(reader, subtree, field_name, 6)
 end
@@ -106,10 +110,30 @@
         return
     end
 
-    local list = subtree:add(fields[field_name], reader.peek_all(0))
-    while not reader.is_empty() do
-        local action_len = reader.peek(2, 2):uint()
-        local child_reader = reader.slice(action_len)
+    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 = dissect_of_action(child_reader, child_subtree, version)
         child_subtree:set_text(info)
@@ -118,11 +142,91 @@
 end
 
 function read_list_of_port_desc_t(reader, version, subtree, field_name)
-    -- TODO
+    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 = dissect_of_port_desc(child_reader, child_subtree, version)
+        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 = dissect_of_flow_stats_entry(child_reader, child_subtree, version)
+        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 = dissect_of_port_stats_entry(child_reader, child_subtree, version)
+        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 = dissect_of_table_stats_entry(child_reader, child_subtree, version)
+        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 = dissect_of_queue_stats_entry(child_reader, child_subtree, version)
+        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
+
+function read_of_serial_num_t(reader, version, subtree, field_name)
+    read_scalar(reader, subtree, field_name, 32)
 end
 
 function read_list_of_oxm_t(reader, version, subtree, field_name)
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index f2791d1..841e502 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -125,6 +125,48 @@
 :: #endfor
 }
 
+local of_port_desc_dissectors = {
+:: for version in ir:
+    [${version}] = dissect_of_port_desc_v${version},
+:: #endfor
+}
+
+local of_stats_reply_dissectors = {
+:: for version in ir:
+    [${version}] = of_stats_reply_v${version}_dissectors,
+:: #endfor
+}
+
+local of_stats_request_dissectors = {
+:: for version in ir:
+    [${version}] = of_stats_request_v${version}_dissectors,
+:: #endfor
+}
+
+local of_flow_stats_entry_dissectors = {
+:: for version in ir:
+    [${version}] = dissect_of_flow_stats_entry_v${version},
+:: #endfor
+}
+
+local of_port_stats_entry_dissectors = {
+:: for version in ir:
+    [${version}] = dissect_of_port_stats_entry_v${version},
+:: #endfor
+}
+
+local of_table_stats_entry_dissectors = {
+:: for version in ir:
+    [${version}] = dissect_of_table_stats_entry_v${version},
+:: #endfor
+}
+
+local of_queue_stats_entry_dissectors = {
+:: for version in ir:
+    [${version}] = dissect_of_queue_stats_entry_v${version},
+:: #endfor
+}
+
 function dissect_of_message(buf, root)
     local reader = OFReader.new(buf)
     local subtree = root:add(p_of, buf(0))
@@ -137,7 +179,13 @@
     end
 
     local info = "unknown"
-    if of_message_dissectors[version_val] and of_message_dissectors[version_val][type_val] then
+    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
 
@@ -183,6 +231,51 @@
     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