Merge into master from pull request #372:
In ports 512 - merge into master (https://github.com/floodlight/loxigen/pull/372)
diff --git a/.build/push-artifacts.sh b/.build/push-artifacts.sh
index 8c7b60b..ec81d62 100755
--- a/.build/push-artifacts.sh
+++ b/.build/push-artifacts.sh
@@ -9,9 +9,11 @@
     exit 1
 fi
 
+ARTIFACT_REPO_BRANCH=${2-master}
+
 ARTIFACT_REPO=$(mktemp -d --tmpdir "push-artifacts-repo.XXXXXXX")
 
-git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO}
+git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO} -b ${ARTIFACT_REPO_BRANCH}
 find ${ARTIFACT_REPO} -mindepth 1 -maxdepth 1 -type d \! -name '.*' -print0 | xargs -0 rm -r
 make LOXI_OUTPUT_DIR=${ARTIFACT_REPO} clean all
 
@@ -55,7 +57,7 @@
 
     git tag -a -f "loxi/${loxi_head}" -m "Tag Loxigen Revision ${loxi_head}"
     git push --tags
-    git push
+    git push origin HEAD
 )
 
 rm -rf ${ARTIFACT_REPO}
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 6e88d6d..955f34f 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -394,24 +394,6 @@
     %(cls)s_t *obj, int value);
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
 
-    out.write("""
-/*
- * Declarations for list population and check primitives
- */
-""")
-
-    for version in of_g.of_version_range:
-        for cls in of_g.ordered_list_objects:
-            if version in of_g.unified[cls]:
-               out.write("""
-extern int
-    list_setup_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value);
-extern int
-    list_check_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value);
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-
     out.write("\n#endif /* _TEST_COMMON_H_ */\n")
 
 def gen_common_test(out, name):
@@ -486,7 +468,6 @@
 
     gen_fill_string(out)
     gen_scalar_set_check_funs(out)
-    gen_list_set_check_funs(out)
     gen_unified_accessor_funs(out)
 
     gen_ident_tests(out)
@@ -758,115 +739,6 @@
     TEST_OK(%(cls)s_next(list, &elt));
 """ % dict(cls=cls))
 
-def setup_list_fn(out, version, cls):
-    """
-    Generate a helper function that populates a list with two
-    of each type of subclass it supports
-    """
-    out.write("""
-/**
- * Set up a list of type %(cls)s with two of each type of subclass
- */
-int
-list_setup_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value)
-{
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-    base_type = loxi_utils.list_to_entry_type(cls)
-    out.write("""
-    of_object_t elt;
-    int cur_len = 0;
-    (void) elt;
-    (void) cur_len;
-""" % dict(cls=cls, base_type=base_type))
-
-    sub_classes =  type_maps.sub_class_map(base_type, version)
-    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
-    v_name = loxi_utils.version_to_name(version)
-
-    if not type_maps.class_is_virtual(base_type):
-        out.write("    /* No subclasses for %s */\n"% base_type)
-        out.write("    %s_t *elt_p;\n" % base_type)
-        out.write("\n    elt_p = &elt;\n")
-    else:
-        out.write("    /* Declare pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s_t *%s;\n" % (subcls, instance))
-        out.write("\n    /* Instantiate pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s = &elt;\n" % (instance))
-
-    if not type_maps.class_is_virtual(base_type): # No inheritance case
-        setup_instance(out, cls, base_type, "elt_p", v_name, version)
-    else:
-        for instance, subcls in sub_classes:
-            setup_instance(out, cls, subcls, instance, v_name, version)
-    out.write("""
-
-    return value;
-}
-""")
-
-def check_list_fn(out, version, cls):
-    """
-    Generate a helper function that checks a list populated by above fn
-    """
-    out.write("""
-/**
- * Check a list of type %(cls)s generated by
- * list_setup_%(cls)s_%(v_name)s
- */
-int
-list_check_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value)
-{
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-    base_type = loxi_utils.list_to_entry_type(cls)
-    out.write("""
-    of_object_t elt;
-    (void) elt;
-""" % dict(cls=cls, base_type=base_type))
-
-    sub_classes =  type_maps.sub_class_map(base_type, version)
-    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
-    v_name = loxi_utils.version_to_name(version)
-
-    if not type_maps.class_is_virtual(base_type):
-        out.write("    /* No subclasses for %s */\n"% base_type)
-        out.write("    %s_t *elt_p;\n" % base_type)
-        out.write("\n    elt_p = &elt;\n")
-    else:
-        out.write("    /* Declare pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s_t *%s;\n" % (subcls, instance))
-        out.write("\n    /* Instantiate pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s = &elt;\n" % (instance))
-
-    if not type_maps.class_is_virtual(base_type) or sub_classes:
-        out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
-
-    if not type_maps.class_is_virtual(base_type): # No inheritance case
-        check_instance(out, cls, base_type, "elt_p", v_name, version, True)
-    else:
-        count = 0
-        for instance, subcls in sub_classes:
-            count += 1
-            check_instance(out, cls, subcls, instance, v_name,
-                           version, count==len(sub_classes))
-
-    out.write("""
-    return value;
-}
-""" % dict(base_type=base_type))
-
-def gen_list_set_check_funs(out):
-    for version in of_g.of_version_range:
-        for cls in of_g.ordered_list_objects:
-            if version in of_g.unified[cls]:
-                setup_list_fn(out, version, cls)
-                check_list_fn(out, version, cls)
-
 # Maybe: Get a map from list class to parent, mem_name of container
 
 def list_test(out, version, cls):
@@ -889,7 +761,7 @@
     TEST_ASSERT(list->parent == NULL);
     TEST_ASSERT(list->object_id == %(enum_cls)s);
 
-    value = list_setup_%(cls)s_%(v_name)s(list, value);
+    value = %(cls)s_%(v_name)s_populate(list, value);
     TEST_ASSERT(value != 0);
 """ % dict(cls=cls, base_type=base_type, v_name=loxi_utils.version_to_name(version),
            enum_cls=loxi_utils.enum_name(cls)))
@@ -897,7 +769,7 @@
     out.write("""
     /* Now check values */
     value = 1;
-    value = list_check_%(cls)s_%(v_name)s(list, value);
+    value = %(cls)s_%(v_name)s_check(list, value);
     TEST_ASSERT(value != 0);
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
 
@@ -1185,8 +1057,15 @@
     out.write("""
     of_object_t elt;
     int cur_len = 0;
+    static int recursion;
     (void) elt;
     (void) cur_len;
+
+    if (recursion > 0) {
+        return value;
+    }
+
+    recursion++;
 """ % dict(cls=cls, base_type=base_type))
 
     sub_classes =  type_maps.sub_class_map(base_type, version)
@@ -1211,6 +1090,7 @@
         for instance, subcls in sub_classes:
             setup_instance(out, cls, subcls, instance, v_name, version)
     out.write("""
+    recursion--;
     return value;
 }
 """)
@@ -1232,6 +1112,13 @@
     of_object_t elt;
     int count = 0;
     int rv;
+    static int recursion;
+
+    if (recursion > 0) {
+        return value;
+    }
+
+    recursion++;
 """ % dict(cls=cls, base_type=base_type))
 
 
@@ -1300,6 +1187,7 @@
         of_object_delete((of_object_t *)dup);
     }
 
+    recursion--;
     return value;
 }
 """ % dict(cls=cls, u_cls=cls.upper(), entry_count=entry_count))
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 79cea7a..c8f70e6 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -587,6 +587,8 @@
             if not find(lambda x: x.name == "mask", self.ir_model_members):
                 virtual_members.append(
                         JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type))
+        elif self.name =="OFErrorMsg":
+            virtual_members += [ JavaVirtualMember(self, "data", java_type.error_cause_data) ]
 
         if not find(lambda m: m.name == "version", self.ir_model_members):
             virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version))
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
index a919f62..3ee588f 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/MultiplePktInReasonUtil.java
@@ -22,10 +22,10 @@
      * reasons in Match.MetaData field.
      * */
     public static Set<OFBsnPktinFlag> getOFBsnPktinFlags(OFPacketIn pktIn) {
-        if(pktIn.getVersion() != OFVersion.OF_13) {
+        if(pktIn.getVersion().compareTo(OFVersion.OF_13) < 0) {
             throw new IllegalArgumentException("multiple pkt in reasons are "
                                                + "only supported by BVS using "
-                                               + "openflow 1.3");
+                                               + "openflow version >= 1.3");
         }
 
         Match match = pktIn.getMatch();
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
new file mode 100644
index 0000000..965e314
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
@@ -0,0 +1,53 @@
+package org.projectfloodlight.protocol;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+import static org.hamcrest.Matchers.is;
+
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests auxiliary OFPortDesc methods for all versions of OpenFlow
+ *
+ * @author Jason Parraga <jason.parraga@bigswitch.com>
+ */
+public class OFPortDescTest {
+
+    @Test
+    public void testIsEnabled() {
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_10));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_11));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_12));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_13));
+       testIsEnabledForFactory(OFFactories.getFactory(OFVersion.OF_14));
+    }
+
+    public void testIsEnabledForFactory(OFFactory factory) {
+        // Default
+        OFPortDesc desc = factory.buildPortDesc()
+                .build();
+        assertThat(desc.isEnabled(), is(true));
+
+        // Partially disabled
+        desc = factory.buildPortDesc()
+                .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+                .build();
+        assertThat(desc.isEnabled(), is(false));
+
+        // Fully disabled
+        desc = factory.buildPortDesc()
+                .setConfig(new HashSet<OFPortConfig>(Arrays.asList(OFPortConfig.PORT_DOWN)))
+                .setState(new HashSet<OFPortState>(Arrays.asList(OFPortState.LINK_DOWN)))
+                .build();
+        assertThat(desc.isEnabled(), is(false));
+    }
+}
diff --git a/java_gen/templates/custom/OFPortDesc.java b/java_gen/templates/custom/OFPortDesc.java
new file mode 100644
index 0000000..3be1b70
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDesc.java
@@ -0,0 +1,11 @@
+
+    /**
+     * Returns true if the port is up, i.e., it's neither administratively
+     * down nor link down. It currently does NOT take STP state into
+     * consideration
+     * @return whether the port is up
+     */
+    public boolean isEnabled() {
+        return (!state.contains(OFPortState.LINK_DOWN) && !config.contains(OFPortConfig.PORT_DOWN));
+    }
+    
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer10.java b/java_gen/templates/custom/OFPortDescVer10.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer10.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer11.java b/java_gen/templates/custom/OFPortDescVer11.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer11.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer12.java b/java_gen/templates/custom/OFPortDescVer12.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer12.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer13.java b/java_gen/templates/custom/OFPortDescVer13.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer13.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/OFPortDescVer14.java b/java_gen/templates/custom/OFPortDescVer14.java
new file mode 100644
index 0000000..782a726
--- /dev/null
+++ b/java_gen/templates/custom/OFPortDescVer14.java
@@ -0,0 +1 @@
+//:: include("custom/OFPortDesc.java", msg=msg, has_parent=False)
\ No newline at end of file
diff --git a/java_gen/templates/custom/interface/OFPortDesc.java b/java_gen/templates/custom/interface/OFPortDesc.java
new file mode 100644
index 0000000..ecf39f3
--- /dev/null
+++ b/java_gen/templates/custom/interface/OFPortDesc.java
@@ -0,0 +1,2 @@
+    // Additional method
+    boolean isEnabled();
\ No newline at end of file
diff --git a/java_gen/templates/of_interface.java b/java_gen/templates/of_interface.java
index a515ad1..18e2cf1 100644
--- a/java_gen/templates/of_interface.java
+++ b/java_gen/templates/of_interface.java
@@ -27,6 +27,7 @@
 //::
 //:: import itertools
 //:: import re
+//:: import os
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
@@ -39,6 +40,10 @@
 //:: for prop in msg.members:
     ${prop.java_type.public_type} ${prop.getter_name}()${ "" if prop.is_universal else " throws UnsupportedOperationException"};
 //:: #endfor
+//:: if os.path.exists("%s/custom/interface/%s.java" % (template_dir, msg.name)):
+//:: include("custom/interface/%s.java" % msg.name, msg=msg)
+//:: #endif
+    
 
     void writeTo(ChannelBuffer channelBuffer);
 
diff --git a/openflow_input/bsn_generic_stats b/openflow_input/bsn_generic_stats
new file mode 100644
index 0000000..b67d8e3
--- /dev/null
+++ b/openflow_input/bsn_generic_stats
@@ -0,0 +1,67 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 4
+#version 5
+
+// This extension provides flexibility for stats requests like gentable
+// does for table programming.
+
+struct of_bsn_generic_stats_request : of_bsn_stats_request {
+    uint8_t version;
+    uint8_t type == 18;
+    uint16_t length;
+    uint32_t xid;
+    uint16_t stats_type == 0xffff;
+    enum ofp_stats_request_flags flags;
+    pad(4);
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 16;
+    of_str64_t name;
+    list(of_bsn_tlv_t) tlvs;
+};
+
+struct of_bsn_generic_stats_entry {
+    uint16_t length;
+    list(of_bsn_tlv_t) tlvs;
+};
+
+struct of_bsn_generic_stats_reply : of_bsn_stats_reply {
+    uint8_t version;
+    uint8_t type == 19;
+    uint16_t length;
+    uint32_t xid;
+    uint16_t stats_type == 0xffff;
+    enum ofp_stats_reply_flags flags;
+    pad(4);
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 16;
+    list(of_bsn_generic_stats_entry_t) entries;
+};
diff --git a/openflow_input/bsn_lua b/openflow_input/bsn_lua
new file mode 100644
index 0000000..9b6438e
--- /dev/null
+++ b/openflow_input/bsn_lua
@@ -0,0 +1,68 @@
+// Copyright 2015, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+// IVS supports running sandboxed Lua code as the forwarding pipeline.
+// This extension allows the controller to upload the Lua code.
+
+#version 4
+#version 5
+
+// Upload chunks of Lua code to the switch
+//
+// If the MORE flag is not set, the old VM will be cleaned up and
+// a new VM will be initialized with the uploaded code. Each chunk
+// of code is executed in the VM in the order it was received.
+//
+// If the FORCE flag is not set, the switch will check to see if the
+// old and new code is identical. If they are identical the message
+// will be ignored.
+//
+// As part of the VM cleanup, all gentables registered by Lua code
+// will be unregistered.
+//
+// Consecutive messages with the same filename are concatenated,
+// to support chunks larger than 64K.
+
+enum ofp_bsn_lua_upload_flags(wire_type=uint16_t, bitmask=True) {
+    OFP_BSN_LUA_UPLOAD_MORE = 0x1,
+    OFP_BSN_LUA_UPLOAD_FORCE = 0x2,
+};
+
+struct of_bsn_lua_upload : of_bsn_header {
+    uint8_t version;
+    uint8_t type == 4;
+    uint16_t length;
+    uint32_t xid;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 64;
+    enum ofp_bsn_lua_upload_flags flags;
+    of_str64_t filename;
+    of_octets_t data;
+};
diff --git a/openflow_input/bsn_tlv b/openflow_input/bsn_tlv
index 16637cd..65a7fb1 100644
--- a/openflow_input/bsn_tlv
+++ b/openflow_input/bsn_tlv
@@ -394,3 +394,41 @@
     uint16_t length;
     uint32_t value; /* Milliseconds */
 };
+
+/* A reference to an entry in another gentable */
+struct of_bsn_tlv_reference : of_bsn_tlv {
+    uint16_t type == 59;
+    uint16_t length;
+    uint16_t table_id;
+    list(of_bsn_tlv_t) key;
+};
+
+struct of_bsn_tlv_ipv4_netmask : of_bsn_tlv {
+    uint16_t type == 60;
+    uint16_t length;
+    of_ipv4_t value;
+};
+
+struct of_bsn_tlv_mpls_label : of_bsn_tlv {
+    uint16_t type == 61;
+    uint16_t length;
+    uint32_t value;
+};
+
+struct of_bsn_tlv_mpls_control_word : of_bsn_tlv {
+    uint16_t type == 62;
+    uint16_t length;
+    uint8_t value;
+};
+
+struct of_bsn_tlv_mpls_sequenced : of_bsn_tlv {
+    uint16_t type == 63;
+    uint16_t length;
+    uint8_t value;
+};
+
+struct of_bsn_tlv_bucket : of_bsn_tlv {
+    uint16_t type == 64;
+    uint16_t length;
+    list(of_bsn_tlv_t) value;
+};
diff --git a/openflow_input/standard-1.4 b/openflow_input/standard-1.4
index 54fce4a..edcc781 100644
--- a/openflow_input/standard-1.4
+++ b/openflow_input/standard-1.4
@@ -165,6 +165,7 @@
     OFPPF_AUTONEG = 0x2000,
     OFPPF_PAUSE = 0x4000,
     OFPPF_PAUSE_ASYM = 0x8000,
+    OFPPF_BSN_BREAKOUT_CAPABLE = 0x80000000,
 };
 
 enum ofp_port_reason(wire_type=uint8_t) {
diff --git a/py_gen/templates/_unpack.py b/py_gen/templates/_unpack.py
index cce9de3..f5c4e34 100644
--- a/py_gen/templates/_unpack.py
+++ b/py_gen/templates/_unpack.py
@@ -35,7 +35,7 @@
 ::     elif type(m) == OFLengthMember:
         _${m.name} = ${gen_unpack_expr(m.oftype, 'reader', version=version)}
         orig_reader = reader
-        reader = orig_reader.slice(_${m.name} - (${m.offset} + ${m.length}))
+        reader = orig_reader.slice(_${m.name}, ${m.offset + m.length})
 ::     elif type(m) == OFFieldLengthMember:
 ::         field_length_members[m.field_name] = m
         _${m.name} = ${gen_unpack_expr(m.oftype, 'reader', version=version)}
diff --git a/py_gen/templates/generic_util.py b/py_gen/templates/generic_util.py
index 039d82a..02f1c0e 100644
--- a/py_gen/templates/generic_util.py
+++ b/py_gen/templates/generic_util.py
@@ -105,7 +105,7 @@
         self.offset += length
 
     def skip_align(self):
-        new_offset = ((self.start + self.offset + 7) / 8 * 8) - self.start
+        new_offset = (self.offset + 7) / 8 * 8
         if new_offset > self.length:
             raise loxi.ProtocolError("Buffer too short")
         self.offset = new_offset
@@ -114,9 +114,10 @@
         return self.offset == self.length
 
     # Used when parsing objects that have their own length fields
-    def slice(self, length):
-        if self.offset + length > self.length:
+    def slice(self, length, rewind=0):
+        if self.offset + length - rewind > self.length:
             raise loxi.ProtocolError("Buffer too short")
-        reader = OFReader(self.buf, self.start + self.offset, length)
-        self.offset += length
+        reader = OFReader(self.buf, self.start + self.offset - rewind, length)
+        reader.skip(rewind)
+        self.offset += length - rewind
         return reader
diff --git a/py_gen/tests/generic_util.py b/py_gen/tests/generic_util.py
index 03885a2..20a23a4 100644
--- a/py_gen/tests/generic_util.py
+++ b/py_gen/tests/generic_util.py
@@ -102,17 +102,17 @@
         self.assertEquals(reader.is_empty(), True)
 
     def test_skip_align(self):
-        reader = OFReader("abcd" + "efgh" + "ijkl" + "mnop" + "qr")
+        reader = OFReader("abcd" + "efgh" + "ijkl" + "mnop" + "qrst")
         reader.skip_align()
         self.assertEquals(reader.peek('2s')[0], 'ab')
         self.assertEquals(reader.read('2s')[0], "ab")
         reader.skip_align()
         self.assertEquals(reader.peek('2s')[0], 'ij')
         self.assertEquals(reader.read('2s')[0], 'ij')
-        child = reader.slice(8)
-        self.assertEquals(child.peek('2s')[0], 'kl')
+        child = reader.slice(10)
+        self.assertEquals(child.read('2s')[0], 'kl')
         child.skip_align()
-        self.assertEquals(child.peek('2s')[0], 'qr')
+        self.assertEquals(child.peek('2s')[0], 'st')
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index ef826c1..f96fccf 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -159,8 +159,8 @@
             local msg_len = buf(offset+2,2):uint()
 
             -- Detect obviously broken messages
-            if msg_version == 0 or msg_version > 4 then break end
-            if msg_type > 29 then break end
+            if msg_version == 0 or msg_version > 5 then break end
+            if msg_type > 34 then break end
             if msg_len < 8 then break end
 
             if offset + msg_len > buf:len() then