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