Merge remote-tracking branch 'yotam/master'
diff --git a/Makefile b/Makefile
index dceb3e6..cb60398 100644
--- a/Makefile
+++ b/Makefile
@@ -100,17 +100,9 @@
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of12.py
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of13.py
-CTEST_EXEC = ${LOXI_OUTPUT_DIR}/locitest/locitest
-CTEST_SOURCE = ${LOXI_OUTPUT_DIR}/locitest/src/*.c
-CTEST_SOURCE += ${LOXI_OUTPUT_DIR}/loci/src/*.c
-CTEST_INC = -I ${LOXI_OUTPUT_DIR}/loci/inc
-CTEST_INC += -I ${LOXI_OUTPUT_DIR}/locitest/inc
-CTEST_INC += -I ${LOXI_OUTPUT_DIR}/loci/src
-CTEST_CFLAGS = -Wall -Werror -g
-
check-c: c
- gcc ${CTEST_CFLAGS} -o ${CTEST_EXEC} ${CTEST_SOURCE} ${CTEST_INC}
- ${CTEST_EXEC}
+ make -C ${LOXI_OUTPUT_DIR}/locitest
+ ${LOXI_OUTPUT_DIR}/locitest/locitest
pylint:
pylint -E ${LOXI_PY_FILES}
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 96614e5..9910b7f 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -66,6 +66,8 @@
import loxi_front_end.type_maps as type_maps
import loxi_utils.loxi_utils as loxi_utils
import loxi_front_end.identifiers as identifiers
+import util
+import test_data
def var_name_map(m_type):
"""
@@ -341,6 +343,7 @@
extern int run_list_limits_tests(void);
extern int test_ext_objs(void);
+extern int test_datafiles(void);
""")
@@ -1967,3 +1970,16 @@
}
""")
+def gen_datafiles_tests(out, name):
+ tests = []
+ for filename in test_data.list_files():
+ data = test_data.read(filename)
+ if not 'c' in data:
+ continue
+ name = filename[:-5].replace("/", "_")
+ tests.append(dict(name=name,
+ filename=filename,
+ c=data['c'],
+ binary=data['binary']))
+
+ util.render_template(out, "test_data.c", tests=tests)
diff --git a/c_gen/templates/locitest/Makefile b/c_gen/templates/locitest/Makefile
new file mode 100644
index 0000000..ed4ba13
--- /dev/null
+++ b/c_gen/templates/locitest/Makefile
@@ -0,0 +1,12 @@
+SRCS := $(wildcard src/*.c)
+SRCS += $(wildcard ../loci/src/*.c)
+
+OBJS := $(SRCS:.c=.o)
+
+CFLAGS := -Wall -Werror -g
+CFLAGS += -Iinc -I../loci/inc -I ../loci/src
+
+all: locitest
+
+locitest: $(OBJS)
+ $(CC) $^ -o $@
diff --git a/c_gen/templates/locitest/main.c b/c_gen/templates/locitest/main.c
index 3b24035..86f7ae6 100644
--- a/c_gen/templates/locitest/main.c
+++ b/c_gen/templates/locitest/main.c
@@ -41,5 +41,7 @@
RUN_TEST(ext_objs);
+ TEST_ASSERT(test_datafiles() == TEST_PASS);
+
return global_error;
}
diff --git a/c_gen/templates/locitest/test_data.c b/c_gen/templates/locitest/test_data.c
new file mode 100644
index 0000000..f4e985f
--- /dev/null
+++ b/c_gen/templates/locitest/test_data.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University */
+/* Copyright (c) 2011, 2012 Open Networking Foundation */
+/* Copyright (c) 2012, 2013 Big Switch Networks, Inc. */
+/* See the file LICENSE.loci which should have been included in the source distribution */
+
+/**
+ *
+ * AUTOMATICALLY GENERATED FILE. Edits will be lost on regen.
+ *
+ * Data file tests for all versions.
+ */
+
+#include <locitest/test_common.h>
+
+<?py
+def hexarray(data, indent):
+ i = 0
+ text = []
+ text.append(" " * indent)
+ for byte in data:
+ text.append("0x%02x, " % ord(byte))
+ i += 1
+ if i == 8:
+ text.append("\n" + " " * indent)
+ i = 0
+ #endif
+ #endfor
+ return "".join(text)
+#end
+?>
+
+static void
+hexdump(const uint8_t *data, int len)
+{
+ int i = 0, j;
+ while (i < len) {
+ printf("%02x: ", i);
+ for (j = 0; j < 8 && i < len; j++, i++) {
+ printf("%02x ", data[i]);
+ }
+ printf("\n");
+ }
+}
+
+static void
+show_failure(const uint8_t *a, int a_len, const uint8_t *b, int b_len)
+{
+ printf("\n--- Expected: (len=%d)\n", a_len);
+ hexdump(a, a_len);
+ printf("\n--- Actual: (len=%d)\n", b_len);
+ hexdump(b, b_len);
+}
+
+:: for test in tests:
+/* Generated from ${test['filename']} */
+static int
+test_${test['name']}(void) {
+ uint8_t binary[] = {
+${hexarray(test['binary'], indent=8)}
+ };
+
+ of_object_t *obj;
+
+${'\n'.join([' ' * 4 + x for x in test['c'].split("\n")])}
+
+ if (sizeof(binary) != WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj))
+ || memcmp(binary, WBUF_BUF(OF_OBJECT_TO_WBUF(obj)), sizeof(binary))) {
+ show_failure(binary, sizeof(binary),
+ WBUF_BUF(OF_OBJECT_TO_WBUF(obj)),
+ WBUF_CURRENT_BYTES(OF_OBJECT_TO_WBUF(obj)));
+ of_object_delete(obj);
+ return TEST_FAIL;
+ }
+
+ of_object_delete(obj);
+ return TEST_PASS;
+}
+
+:: #endfor
+
+int
+test_datafiles(void)
+{
+:: for test in tests:
+ RUN_TEST(${test['name']});
+:: #endfor
+ return TEST_PASS;
+}
diff --git a/generic_utils.py b/generic_utils.py
index eeb26d6..0bf289e 100644
--- a/generic_utils.py
+++ b/generic_utils.py
@@ -31,6 +31,7 @@
Intended to be imported into another namespace
"""
+import collections
import functools
import sys
import of_g
@@ -99,8 +100,6 @@
#
################################################################
-import collections
-
class OrderedSet(collections.MutableSet):
"""
A set implementations that retains insertion order. From the receipe
@@ -164,6 +163,59 @@
return len(self) == len(other) and list(self) == list(other)
return set(self) == set(other)
+################################################################
+#
+# OrderedDefaultDict
+#
+################################################################
+
+class OrderedDefaultDict(collections.OrderedDict):
+ """
+ A Dictionary that maintains insertion order where missing values
+ are provided by a factory function, i.e., a combination of
+ the semantics of collections.defaultdict and collections.OrderedDict.
+ """
+ def __init__(self, default_factory=None, *a, **kw):
+ if (default_factory is not None and
+ not callable(default_factory)):
+ raise TypeError('first argument must be callable')
+ collections.OrderedDict.__init__(self, *a, **kw)
+ self.default_factory = default_factory
+
+ def __getitem__(self, key):
+ try:
+ return collections.OrderedDict.__getitem__(self, key)
+ except KeyError:
+ return self.__missing__(key)
+
+ def __missing__(self, key):
+ if self.default_factory is None:
+ raise KeyError(key)
+ self[key] = value = self.default_factory()
+ return value
+
+ def __reduce__(self):
+ if self.default_factory is None:
+ args = tuple()
+ else:
+ args = self.default_factory,
+ return type(self), args, None, None, self.items()
+
+ def copy(self):
+ return self.__copy__()
+
+ def __copy__(self):
+ return type(self)(self.default_factory, self)
+
+ def __deepcopy__(self, memo):
+ import copy
+ return type(self)(self.default_factory,
+ copy.deepcopy(self.items()))
+ def __repr__(self):
+ return 'OrderedDefaultDict(%s, %s)' % (self.default_factory,
+ collections.OrderedDict.__repr__(self))
+
+
def find(iterable, func):
"""
find the first item in iterable for which func returns something true'ish.
diff --git a/java_gen/codegen.py b/java_gen/codegen.py
index 0765c91..258b81c 100644
--- a/java_gen/codegen.py
+++ b/java_gen/codegen.py
@@ -36,6 +36,7 @@
import of_g
from loxi_ir import *
import lang_java
+import test_data
import loxi_utils.loxi_utils as loxi_utils
@@ -43,17 +44,17 @@
def gen_all_java(out, name):
basedir= '%s/openflowj' % of_g.options.install_dir
- srcdir = "%s/src/main/java/" % basedir
print "Outputting to %s" % basedir
if os.path.exists(basedir):
shutil.rmtree(basedir)
os.makedirs(basedir)
copy_prewrite_tree(basedir)
- gen = JavaGenerator(srcdir)
+ gen = JavaGenerator(basedir)
gen.create_of_interfaces()
gen.create_of_classes()
gen.create_of_const_enums()
+ gen.create_of_factories()
with open('%s/README.java-lang' % os.path.dirname(__file__)) as readme_src:
out.writelines(readme_src.readlines())
@@ -67,11 +68,14 @@
self.basedir = basedir
self.java_model = java_model.model
- def render_class(self, clazz, template, **context):
+ def render_class(self, clazz, template, src_dir=None, **context):
+ if not src_dir:
+ src_dir = "src/main/java/"
+
context['class_name'] = clazz.name
context['package'] = clazz.package
- filename = os.path.join(self.basedir, "%s/%s.java" % (clazz.package.replace(".", "/"), clazz.name))
+ filename = os.path.join(self.basedir, src_dir, "%s/%s.java" % (clazz.package.replace(".", "/"), clazz.name))
dirname = os.path.dirname(filename)
if not os.path.exists(dirname):
os.makedirs(dirname)
@@ -87,6 +91,10 @@
self.render_class(clazz=enum,
template='const.java', enum=enum, all_versions=self.java_model.versions)
+ for version in enum.versions:
+ clazz = java_model.OFGenericClass(package="org.openflow.protocol.ver{}".format(version.of_version), name="{}SerializerVer{}".format(enum.name, version.of_version))
+ self.render_class(clazz=clazz, template="const_serializer.java", enum=enum, version=version)
+
def create_of_interfaces(self):
""" Create the base interfaces for of classes"""
for interface in self.java_model.interfaces:
@@ -98,15 +106,30 @@
def create_of_classes(self):
""" Create the OF classes with implementations for each of the interfaces and versions """
for interface in self.java_model.interfaces:
- if interface.name == "OFTableMod":
- continue
- if not loxi_utils.class_is_message(interface.c_name) and not loxi_utils.class_is_oxm(interface.c_name):
- continue
for java_class in interface.versioned_classes:
+ if not self.java_model.generate_class(java_class):
+ continue
self.render_class(clazz=java_class,
template='of_class.java', version=java_class.version, msg=java_class,
impl_class=java_class.name)
+ self.create_unit_test(java_class.unit_test)
+
+ def create_unit_test(self, unit_test):
+ if unit_test.has_test_data:
+ self.render_class(clazz=unit_test,
+ template='unit_test.java', src_dir="src/test/java",
+ version=unit_test.java_class.version,
+ test=unit_test, msg=unit_test.java_class,
+ test_data=unit_test.test_data)
+
+ def create_of_factories(self):
+ factory = self.java_model.of_factory
+ self.render_class(clazz=factory, template="of_factory_interface.java", factory=factory)
+ for factory_class in factory.factory_classes:
+ self.render_class(clazz=factory_class, template="of_factory_class.java", factory=factory_class, model=self.java_model)
+ self.render_class(clazz=java_model.OFGenericClass(package="org.openflow.protocol", name="OFFactories"), template="of_factories.java", versions=self.java_model.versions)
+
def copy_prewrite_tree(basedir):
""" Recursively copy the directory structure from ./java_gen/pre-write
into $basedir"""
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 35f334c..6f5cfaa 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -29,24 +29,26 @@
# A lot of this stuff could/should probably be merged with the python utilities
import collections
-from collections import namedtuple, defaultdict
+from collections import namedtuple, defaultdict, OrderedDict
import logging
import os
import pdb
import re
-from generic_utils import find, memoize, OrderedSet
+from generic_utils import find, memoize, OrderedSet, OrderedDefaultDict
import of_g
from loxi_ir import *
import loxi_front_end.type_maps as type_maps
-import loxi_utils.loxi_utils as utils
+import loxi_utils.loxi_utils as loxi_utils
import py_gen.util as py_utils
+import test_data
import java_gen.java_type as java_type
class JavaModel(object):
- write_blacklist = defaultdict(lambda: set(), OFOxm=set(('typeLen',)))
- virtual_interfaces = set(['OFOxm' ])
+ enum_blacklist = set(("OFDefinitions","OFFlowWildcards"))
+ write_blacklist = defaultdict(lambda: set(), OFOxm=set(('typeLen',)), OFAction=set(('type',)))
+ virtual_interfaces = set(['OFOxm', 'OFAction' ])
@property
@memoize
@@ -56,12 +58,15 @@
@property
@memoize
def interfaces(self):
- version_map_per_class = collections.defaultdict(lambda: {})
+ version_map_per_class = collections.OrderedDict()
for raw_version, of_protocol in of_g.ir.items():
jversion = JavaOFVersion(of_protocol.wire_version)
for of_class in of_protocol.classes:
+ if not of_class.name in version_map_per_class:
+ version_map_per_class[of_class.name] = collections.OrderedDict()
+
version_map_per_class[of_class.name][jversion] = of_class
interfaces = []
@@ -73,17 +78,18 @@
@property
@memoize
def enums(self):
- enum_entry_version_value_map = collections.defaultdict(lambda: collections.defaultdict(lambda: collections.OrderedDict()))
+ name_version_enum_map = OrderedDefaultDict(lambda: OrderedDict())
for version in self.versions:
of_protocol = of_g.ir[version.int_version]
for enum in of_protocol.enums:
- for entry_name, entry_value in enum.values:
- enum_entry_version_value_map[enum.name][entry_name][version] = entry_value
+ name_version_enum_map[enum.name][version] = enum
- enums = [ JavaEnum(name, entry_version_value_map) for name, entry_version_value_map
- in enum_entry_version_value_map.items() ]
+ enums = [ JavaEnum(name, version_enum_map) for name, version_enum_map,
+ in name_version_enum_map.items() ]
+ # inelegant - need java name here
+ enums = [ enum for enum in enums if enum.name not in self.enum_blacklist ]
return enums
@memoize
@@ -93,6 +99,41 @@
except KeyError:
raise KeyError("Could not find enum with name %s" % name)
+ @property
+ @memoize
+ def of_factory(self):
+ return OFFactory(
+ package="org.openflow.protocol",
+ name="OFFactory",
+ members=self.interfaces)
+
+ def generate_class(self, clazz):
+ if clazz.interface.is_virtual:
+ return False
+ if clazz.interface.name == "OFTableMod":
+ return False
+ if loxi_utils.class_is_message(clazz.interface.c_name):
+ return True
+ if loxi_utils.class_is_oxm(clazz.interface.c_name):
+ return True
+ else:
+ return False
+
+
+class OFFactory(namedtuple("OFFactory", ("package", "name", "members"))):
+ @property
+ def factory_classes(self):
+ return [ OFFactoryClass(
+ package="org.openflow.protocol.ver{}".format(version.of_version),
+ name="OFFactoryVer{}".format(version.of_version),
+ interface=self,
+ version=version
+ ) for version in model.versions ]
+
+
+OFGenericClass = namedtuple("OFGenericClass", ("package", "name"))
+OFFactoryClass = namedtuple("OFFactory", ("package", "name", "interface", "version"))
+
model = JavaModel()
#######################################################################
@@ -139,7 +180,7 @@
self.c_name = c_name
self.version_map = version_map
self.name = java_type.name_c_to_caps_camel(c_name)
- self.builder_name = self.name + "Builder"
+ self.variable_name = self.name[2].lower() + self.name[3:]
self.constant_name = c_name.upper().replace("OF_", "")
pck_suffix, parent_interface = self.class_info()
@@ -152,15 +193,15 @@
def class_info(self):
if re.match(r'OFFlow(Add|Modify(Strict)?|Delete(Strict)?)$', self.name):
return ("", "OFFlowMod")
- elif utils.class_is_message(self.c_name):
+ elif loxi_utils.class_is_message(self.c_name):
return ("", "OFMessage")
- elif utils.class_is_action(self.c_name):
+ elif loxi_utils.class_is_action(self.c_name):
return ("action", "OFAction")
- elif utils.class_is_oxm(self.c_name):
+ elif loxi_utils.class_is_oxm(self.c_name):
return ("oxm", "OFOxm")
- elif utils.class_is_instruction(self.c_name):
+ elif loxi_utils.class_is_instruction(self.c_name):
return ("instruction", "OFInstruction")
- elif utils.class_is_meter_band(self.c_name):
+ elif loxi_utils.class_is_meter_band(self.c_name):
return ("meterband", "OFMeterBand")
else:
return ("", None)
@@ -188,10 +229,17 @@
return self.name in model.virtual_interfaces
@property
+ def is_universal(self):
+ return len(self.all_versions) == len(model.versions)
+
+ @property
@memoize
def all_versions(self):
return self.version_map.keys()
+ def has_version(self, version):
+ return version in self.version_map
+
def versioned_class(self, version):
return JavaOFClass(self, version, self.version_map[version])
@@ -218,12 +266,22 @@
self.version = version
self.constant_name = self.c_name.upper().replace("OF_", "")
self.package = "org.openflow.protocol.ver%s" % version.of_version
+ self.generated = False
+
+ @property
+ @memoize
+ def unit_test(self):
+ return JavaUnitTest(self)
@property
def name(self):
return "%sVer%s" % (self.interface.name, self.version.of_version)
@property
+ def variable_name(self):
+ return self.name[3:]
+
+ @property
def length(self):
if self.is_fixed_length:
return self.min_length
@@ -403,7 +461,7 @@
if hasattr(self.member, "length"):
return self.member.length
else:
- count, base = utils.type_dec_to_count_base(self.member.type)
+ count, base = loxi_utils.type_dec_to_count_base(self.member.type)
return of_g.of_base_types[base]['bytes'] * count
@staticmethod
@@ -441,22 +499,70 @@
return False
return (self.name,) == (other.name,)
+
+#######################################################################
+### Unit Test
+#######################################################################
+
+class JavaUnitTest(object):
+ def __init__(self, java_class):
+ self.java_class = java_class
+ self.data_file_name = "of{version}/{name}.data".format(version=java_class.version.of_version,
+ name=java_class.c_name[3:])
+ @property
+ def package(self):
+ return self.java_class.package
+
+ @property
+ def name(self):
+ return self.java_class.name + "Test"
+
+ @property
+ def has_test_data(self):
+ return test_data.exists(self.data_file_name)
+
+ @property
+ @memoize
+ def test_data(self):
+ return test_data.read(self.data_file_name)
+
+
#######################################################################
### Enums
#######################################################################
class JavaEnum(object):
- def __init__(self, c_name, entry_version_value_map):
+ def __init__(self, c_name, version_enum_map):
self.c_name = c_name
self.name = "OF" + java_type.name_c_to_caps_camel("_".join(c_name.split("_")[1:]))
# Port_features has constants that start with digits
self.name_prefix = "PF_" if self.name == "OFPortFeatures" else ""
+ self.version_enums = version_enum_map
+
+ entry_name_version_value_map = OrderedDefaultDict(lambda: OrderedDict())
+ for version, ir_enum in version_enum_map.items():
+ for ir_entry in ir_enum.entries:
+ if "virtual" in ir_entry.params:
+ continue
+ entry_name_version_value_map[ir_entry.name][version] = ir_entry.value
+
self.entries = [ JavaEnumEntry(self, name, version_value_map)
- for (name, version_value_map) in entry_version_value_map.items() ]
+ for (name, version_value_map) in entry_name_version_value_map.items() ]
self.package = "org.openflow.protocol"
+ def wire_type(self, version):
+ ir_enum = self.version_enums[version]
+ if "wire_type" in ir_enum.params:
+ return java_type.convert_enum_wire_type_to_jtype(ir_enum.params["wire_type"])
+ else:
+ return java_type.u8
+
+ @property
+ def versions(self):
+ return self.version_enums.keys()
+
@memoize
def entry_by_name(self, name):
try:
@@ -481,11 +587,18 @@
# values: Map JavaVersion->Value
class JavaEnumEntry(object):
def __init__(self, enum, name, values):
+ self.enum = enum
self.name = enum.name_prefix + "_".join(name.split("_")[1:]).upper()
self.values = values
+ def has_value(self, version):
+ return version in self.values
+
def value(self, version):
- res = self.version_value_map[version]
+ return self.values[version]
+
+ def format_value(self, version):
+ res = self.enum.wire_type(version).format_value(self.values[version])
return res
def all_values(self, versions, not_present=None):
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 8580f37..2d8a547 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -21,19 +21,19 @@
return camel
-ANY = 0xFFFFFFFFFFFFFFFF
+java_primitive_types = set("byte char short int long".split(" "))
+ANY = 0xFFFFFFFFFFFFFFFF
class VersionOp:
def __init__(self, version=ANY, read=None, write=None):
self.version = version
self.read = read
self.write = write
-
+
def __str__(self):
return "[Version: %d, Read: '%s', Write: '%s']" % (self.version, self.read, self.write)
-
class JType(object):
""" Wrapper class to hold C to Java type conversion information """
def __init__(self, pub_type, priv_type=None, size=None, read_op=None, write_op=None):
@@ -54,6 +54,21 @@
self.ops[version] = VersionOp(version, read, write)
return self
+ def cast(self, min):
+ """ declares that the value has to be cast to itself for values >= min.
+ This is to deal with Java signedness """
+ def format_cast_value(value):
+ if value >= min:
+ return "(%s) 0x%x" % (self.pub_type, value)
+ else:
+ return "0x%x" % (value)
+
+ self.format_value = format_cast_value
+ return self
+
+ def format_value(self, value):
+ return value
+
@property
def public_type(self):
""" return the public type """
@@ -98,6 +113,15 @@
else:
return _write_op.replace("$name", str(name)).replace("$version", version.of_version)
+ @property
+ def is_primitive(self):
+ return self.pub_type in java_primitive_types
+
+ @property
+ def is_array(self):
+ return self.pub_type.endswith("[]")
+
+
hello_elem_list = JType("List<OFHelloElement>") \
.op(read='ChannelUtils.readHelloElementList(bb)', write='ChannelUtils.writeHelloElementList(bb)')
u8 = JType('byte', size=1) \
@@ -176,6 +200,8 @@
ipv6 = JType("IPv6") \
.op(read="IPv6.read16Bytes(bb)", \
write="$name.write16Bytes(bb)")
+packetin_reason = JType("OFPacketInReason")\
+ .op(read="OFPacketInReasonSerializerVer$version.readFrom(bb)", write="OFPacketInReasonSerializerVer$version.writeTo(bb, $name)")
default_mtype_to_jtype_convert_map = {
'uint8_t' : u8,
@@ -213,12 +239,23 @@
## This is where we drop in special case handling for certain types
exceptions = {
- 'OFPacketIn': {
- 'data' : octets
+ 'of_packet_in': {
+ 'data' : octets,
+ 'reason': packetin_reason
},
}
+enum_wire_types = {
+ "uint8_t": JType("byte").op(read="bb.readByte()", write="bb.writeByte($name)").cast(min=1<<7),
+ "uint16_t": JType("short").op(read="bb.readShort()", write="bb.writeShort($name)").cast(min=1<<15),
+ "uint32_t": JType("int").op(read="bb.readInt()", write="bb.writeInt($name)").cast(min=1<<31),
+ "uint64_t": JType("long").op(read="bb.readLong()", write="bb.writeLong($name)").cast(min=1<<31)
+}
+
+def convert_enum_wire_type_to_jtype(wire_type):
+ return enum_wire_types[wire_type]
+
def make_standard_list_jtype(c_type):
m = re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type)
if not m:
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java
deleted file mode 100644
index d15812b..0000000
--- a/java_gen/pre-written/src/main/java/org/openflow/types/OFMeterBand.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.openflow.types;
-
-public interface OFMeterBand {
-
-}
diff --git a/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java b/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java
index 9dc197f..f6dc408 100644
--- a/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java
+++ b/java_gen/pre-written/src/main/java/org/openflow/types/OFPort.java
@@ -520,7 +520,7 @@
}
public static OFPort read2Bytes(ChannelBuffer c) throws OFParseError {
- return OFPort.of((c.readUnsignedShort() & 0x0FFFF));
+ return OFPort.ofShort(c.readShort());
}
public void write4Bytes(ChannelBuffer c) {
diff --git a/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java b/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java
index dab6ff2..afd03ad 100644
--- a/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java
+++ b/java_gen/pre-written/src/main/java/org/openflow/util/ChannelUtils.java
@@ -22,9 +22,9 @@
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.instruction.OFInstruction;
import org.openflow.protocol.match.Match;
+import org.openflow.protocol.meterband.OFMeterBand;
import org.openflow.types.OFFlowModCmd;
import org.openflow.types.OFHelloElement;
-import org.openflow.types.OFMeterBand;
import org.openflow.types.OFPhysicalPort;
import com.google.common.base.Charsets;
@@ -43,18 +43,19 @@
return byteArray;
}
- static public void writeBytes(final ChannelBuffer bb, final byte byteArray[]) {
+ static public void writeBytes(final ChannelBuffer bb,
+ final byte byteArray[]) {
bb.writeBytes(byteArray);
}
- public static List<OFPhysicalPort> readPhysicalPortList(final ChannelBuffer bb,
- final int i) {
+ public static List<OFPhysicalPort> readPhysicalPortList(
+ final ChannelBuffer bb, final int i) {
// TODO Auto-generated method stub
return null;
}
- public static List<OFInstruction> readInstructionsList(final ChannelBuffer bb,
- final int i) {
+ public static List<OFInstruction> readInstructionsList(
+ final ChannelBuffer bb, final int i) {
// TODO Auto-generated method stub
return null;
}
@@ -69,12 +70,14 @@
return null;
}
- public static List<OFAction> readActionsList(final ChannelBuffer bb, final int i) {
+ public static List<OFAction> readActionsList(final ChannelBuffer bb,
+ final int i) {
// TODO Auto-generated method stub
return null;
}
- public static List<OFBsnInterface> readBsnInterfaceList(final ChannelBuffer bb) {
+ public static List<OFBsnInterface> readBsnInterfaceList(
+ final ChannelBuffer bb) {
// TODO Auto-generated method stub
return null;
}
@@ -84,22 +87,24 @@
return null;
}
- public static List<OFPacketQueue> readPacketQueueList(final ChannelBuffer bb,
+ public static List<OFPacketQueue> readPacketQueueList(
+ final ChannelBuffer bb, final int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFHelloElement> readHelloElementList(
+ final ChannelBuffer bb) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static List<OFBucket> readBucketList(final ChannelBuffer bb,
final int i) {
// TODO Auto-generated method stub
return null;
}
- public static List<OFHelloElement> readHelloElementList(final ChannelBuffer bb) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public static List<OFBucket> readBucketList(final ChannelBuffer bb, final int i) {
- // TODO Auto-generated method stub
- return null;
- }
-
public static List<OFMeterBand> readMeterBandList(final ChannelBuffer bb) {
// TODO Auto-generated method stub
return null;
@@ -126,18 +131,21 @@
return new String(dst, Charsets.US_ASCII);
}
- public static void writeFixedLengthString(ChannelBuffer bb, String string, int length) {
+ public static void writeFixedLengthString(ChannelBuffer bb, String string,
+ int length) {
int l = string.length();
- if(l > length) {
- throw new IllegalArgumentException("Error writing string: length="+l+" > max Length="+length);
+ if (l > length) {
+ throw new IllegalArgumentException("Error writing string: length="
+ + l + " > max Length=" + length);
}
bb.writeBytes(string.getBytes(Charsets.US_ASCII));
- if(l < length) {
+ if (l < length) {
bb.writeZero(length - l);
}
}
- public static void writeBsnInterfaceList(ChannelBuffer bb, List<OFBsnInterface> interfaces) {
+ public static void writeBsnInterfaceList(ChannelBuffer bb,
+ List<OFBsnInterface> interfaces) {
// TODO Auto-generated method stub
}
@@ -312,5 +320,4 @@
}
-
}
diff --git a/java_gen/templates/_imports.java b/java_gen/templates/_imports.java
index 7700546..50ba198 100644
--- a/java_gen/templates/_imports.java
+++ b/java_gen/templates/_imports.java
@@ -1,7 +1,9 @@
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.openflow.protocol.*;
import org.openflow.protocol.action.*;
+import org.openflow.protocol.meterband.*;
import org.openflow.protocol.instruction.*;
import org.openflow.protocol.match.*;
import org.openflow.protocol.oxm.*;
@@ -10,3 +12,4 @@
import org.openflow.util.*;
import org.openflow.exceptions.*;
import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
diff --git a/java_gen/templates/_singleton.java b/java_gen/templates/_singleton.java
new file mode 100644
index 0000000..8ea9f01
--- /dev/null
+++ b/java_gen/templates/_singleton.java
@@ -0,0 +1,10 @@
+
+ private ${msg.name}() {}
+
+ private final static class Holder {
+ private static final ${msg.name} INSTANCE = new ${msg.name}();
+ }
+
+ public static ${msg.name} getInstance() {
+ return Holder.INSTANCE;
+ }
diff --git a/java_gen/templates/const.java b/java_gen/templates/const.java
index 7870529..11c09ab 100644
--- a/java_gen/templates/const.java
+++ b/java_gen/templates/const.java
@@ -37,16 +37,7 @@
public enum ${class_name} {
//:: for i, entry in enumerate(enum.entries):
-//:: values = [ ("0x%x" % val) if val is not None else "-1" for val in entry.all_values(all_versions) ]
- ${entry.name}(new int[] { ${ ", ".join( values) } } )${ ", " if i < len(enum.entries)-1 else ";" }
+ ${entry.name}${ ", " if i < len(enum.entries)-1 else ";" }
//:: #endfor
- private final int[] wireValues;
- ${class_name}(int[] wireValues) {
- this.wireValues = wireValues;
- }
-
- public int getWireValue(OFVersion version) {
- return this.wireValues[version.getWireVersion()];
- }
}
diff --git a/java_gen/templates/const_serializer.java b/java_gen/templates/const_serializer.java
new file mode 100644
index 0000000..4e21070
--- /dev/null
+++ b/java_gen/templates/const_serializer.java
@@ -0,0 +1,85 @@
+//:: # 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.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package ${package};
+
+import org.openflow.types.*;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.exceptions.OFParseError;
+import org.openflow.protocol.OFVersion;
+import ${enum.package}.${enum.name};
+
+public class ${class_name} {
+ //:: wire_type = enum.wire_type(version)
+ //:: int_wire_type = enum.wire_type(version).pub_type
+ //:: entries = sorted([ (entry, entry.value(version)) for entry in enum.entries if entry.has_value(version) ], lambda (_,va), (_2,vb): va.__cmp__(vb))
+
+ //:: for entry, _ in entries:
+ public final static ${int_wire_type} ${entry.name}_VAL = ${entry.format_value(version)};
+ //:: #endfor
+
+ public static ${enum.name} readFrom(ChannelBuffer bb) throws OFParseError {
+ try {
+ return ofWireValue(${wire_type.read_op(version)});
+ } catch (IllegalArgumentException e) {
+ throw new OFParseError(e);
+ }
+ }
+
+ public static void writeTo(ChannelBuffer bb, ${enum.name} e) {
+ ${wire_type.write_op(version=version, name="toWireValue(e)")};
+ }
+
+ public static ${enum.name} ofWireValue(${int_wire_type} val) {
+ switch(val) {
+ //:: for entry, _ in entries:
+ case ${entry.name}_VAL:
+ return ${enum.name}.${entry.name};
+ //:: #endfor
+ default:
+ throw new IllegalArgumentException("Illegal wire value for type ${enum.name} in version ${version}: " + val);
+ }
+ }
+
+ public static ${int_wire_type} toWireValue(${enum.name} e) {
+ switch(e) {
+ //:: for entry, _ in entries:
+ case ${entry.name}:
+ return ${entry.name}_VAL;
+ //:: #endfor
+ default:
+ throw new IllegalArgumentException("Illegal enum value for type ${enum.name} in version ${version}: " + e);
+ }
+ }
+
+}
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 9665c49..18dae2b 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -65,11 +65,11 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False)
- public ${msg.name}.Builder createBuilder() {
- return new BuilderImplWithParent(this);
+ public ${msg.interface.name}.Builder createBuilder() {
+ return new BuilderWithParent(this);
}
- static class BuilderImplWithParent implements ${msg.interface.name}.Builder {
+ static class BuilderWithParent implements ${msg.interface.name}.Builder {
final ${impl_class} parentMessage;
// OF message fields
@@ -78,7 +78,7 @@
private ${prop.java_type.public_type} ${prop.name};
//:: #endfor
- BuilderImplWithParent(${impl_class} parentMessage) {
+ BuilderWithParent(${impl_class} parentMessage) {
this.parentMessage = parentMessage;
}
@@ -94,7 +94,7 @@
}
}
- static class BuilderImpl implements ${msg.interface.name}.Builder {
+ static class Builder implements ${msg.interface.name}.Builder {
// OF message fields
//:: for prop in msg.data_members:
private boolean ${prop.name}Set;
@@ -205,5 +205,64 @@
}
}
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder("${msg.name}(");
+ //:: for i, prop in enumerate(msg.data_members):
+ //:: if i > 0:
+ b.append(", ");
+ //:: #endif
+ b.append("${prop.name}=").append(${ "Arrays.toString(%s)" % prop.name if prop.java_type.is_array else prop.name });
+ //:: #endfor
+ b.append(")");
+ return b.toString();
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ${msg.name} other = (${msg.name}) obj;
+
+ //:: for prop in msg.data_members:
+ //:: if prop.java_type.is_primitive:
+ if( ${prop.name} != other.${prop.name})
+ return false;
+ //:: elif prop.java_type.is_array:
+ if (!Arrays.equals(${prop.name}, other.${prop.name}))
+ return false;
+ //:: else:
+ if (${prop.name} == null) {
+ if (other.${prop.name} != null)
+ return false;
+ } else if (!${prop.name}.equals(other.${prop.name}))
+ return false;
+ //:: #endif
+ //:: #endfor
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+
+ //:: for prop in msg.data_members:
+ //:: if prop.java_type.is_primitive:
+ result = prime * result + ${prop.name};
+ //:: elif prop.java_type.is_array:
+ result = prime * result + Arrays.hashCode(${prop.name});
+ //:: else:
+ result = prime * result + ((${prop.name} == null) ? 0 : ${prop.name}.hashCode());
+ //:: #endif
+ //:: #endfor
+ return result;
+ }
+
}
diff --git a/java_gen/templates/of_factories.java b/java_gen/templates/of_factories.java
new file mode 100644
index 0000000..cce134d
--- /dev/null
+++ b/java_gen/templates/of_factories.java
@@ -0,0 +1,49 @@
+//:: # 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.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package org.openflow.protocol;
+
+//:: include("_imports.java")
+
+public final class OFFactories {
+ public static OFFactory getFactory(OFVersion version) {
+ switch(version) {
+ //:: for v in versions:
+ case ${v.constant_version}:
+ return org.openflow.protocol.ver${v.of_version}.OFFactoryVer${v.of_version}.getInstance();
+ //:: #endfor
+ default:
+ throw new IllegalArgumentException("Unknown version: "+version);
+ }
+ }
+}
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
new file mode 100644
index 0000000..8620787
--- /dev/null
+++ b/java_gen/templates/of_factory_class.java
@@ -0,0 +1,56 @@
+//:: # 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.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package ${factory.package};
+
+//:: include("_imports.java")
+
+public class ${factory.name} implements ${factory.interface.name} {
+//:: for i in factory.interface.members:
+ //:: if i.is_virtual:
+ //:: continue
+ //:: #endif
+
+//:: if i.has_version(factory.version) and model.generate_class(i.versioned_class(factory.version)):
+ public ${i.name}.Builder create${i.name[2:]}Builder() {
+ return new ${i.versioned_class(factory.version).name}.Builder();
+ }
+//:: else:
+ public ${i.name}.Builder create${i.name[2:]}Builder() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("${i.name} not supported in version ${factory.version}");
+ }
+//:: #endif
+//:: #endfor
+
+ //:: include("_singleton.java", msg=factory)
+}
diff --git a/java_gen/templates/of_factory_interface.java b/java_gen/templates/of_factory_interface.java
new file mode 100644
index 0000000..467504e
--- /dev/null
+++ b/java_gen/templates/of_factory_interface.java
@@ -0,0 +1,45 @@
+//:: # 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.
+//::
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package org.openflow.protocol;
+
+//:: include("_imports.java")
+
+public interface ${factory.name} {
+//:: for i in factory.members:
+ //:: if i.is_virtual:
+ //:: continue
+ //:: #endif
+ ${i.name}.Builder create${i.name[2:]}Builder()${ "" if i.is_universal else " throws UnsupportedOperationException"};
+//:: #endfor
+}
diff --git a/java_gen/templates/unit_test.java b/java_gen/templates/unit_test.java
new file mode 100644
index 0000000..1462465
--- /dev/null
+++ b/java_gen/templates/unit_test.java
@@ -0,0 +1,102 @@
+//:: # 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.
+//::
+//:: from loxi_ir import *
+//:: import itertools
+//:: import of_g
+//:: include('_copyright.java')
+
+//:: include('_autogen.java')
+
+package ${test.package};
+
+//:: include("_imports.java", msg=msg)
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class ${test.name} {
+ //:: var_type = msg.interface.name
+ //:: var_name = msg.interface.variable_name
+ OFFactory factory;
+
+ final static byte[] ${msg.constant_name}_SERIALIZED =
+ new byte[] { ${", ".join("%s0x%x" % (("" if ord(c)<128 else "(byte) "), ord(c)) for c in test_data["binary"] ) } };
+
+ @Before
+ public void setup() {
+ factory = OFFactories.getFactory(OFVersion.${version.constant_version});
+ }
+
+ //:: if "java" in test_data:
+ @Test
+ public void testWrite() {
+ ${var_type}.Builder builder = factory.create${var_type[2:]}Builder();
+ ${test_data["java"]};
+ ${var_type} ${var_name} = builder.getMessage();
+ ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
+ ${var_name}.writeTo(bb);
+ byte[] written = new byte[bb.readableBytes()];
+ bb.readBytes(written);
+
+ assertArrayEquals(${msg.constant_name}_SERIALIZED, written);
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ ${var_type}.Builder builder = factory.create${var_type[2:]}Builder();
+ ${test_data["java"]};
+ ${var_type} ${var_name}Built = builder.getMessage();
+
+ ChannelBuffer input = ChannelBuffers.copiedBuffer(${msg.constant_name}_SERIALIZED);
+
+ // FIXME should invoke the overall reader once implemented
+ ${var_type} ${var_name}Read = ${msg.name}.READER.readFrom(input);
+
+ assertEquals(${var_name}Read, ${var_name}Built);
+ }
+ //:: else:
+ // FIXME: No java stanza in test_data for this class. Add for more comprehensive unit testing
+ //:: #endif
+
+ @Test
+ public void testReadWrite() throws Exception {
+ ChannelBuffer input = ChannelBuffers.copiedBuffer(${msg.constant_name}_SERIALIZED);
+
+ // FIXME should invoke the overall reader once implemented
+ ${var_type} ${var_name} = ${msg.name}.READER.readFrom(input);
+
+ // write message again
+ ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
+ ${var_name}.writeTo(bb);
+ byte[] written = new byte[bb.readableBytes()];
+ bb.readBytes(written);
+
+ assertArrayEquals(${msg.constant_name}_SERIALIZED, written);
+ }
+
+}
diff --git a/lang_c.py b/lang_c.py
index aae08ea..fc016f2 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -97,6 +97,7 @@
'locitest/src/test_msg.c': c_test_gen.gen_msg_test,
'locitest/src/test_scalar_acc.c': c_test_gen.gen_message_scalar_test,
'locitest/src/test_uni_acc.c': c_test_gen.gen_unified_accessor_tests,
+ 'locitest/src/test_data.c': c_test_gen.gen_datafiles_tests,
# Static locitest code
'locitest/inc/locitest/unittest.h': static,
@@ -107,4 +108,5 @@
'locitest/src/test_utils.c': static,
'locitest/src/test_validator.c': static,
'locitest/src/main.c': static,
+ 'locitest/Makefile': static,
}
diff --git a/loxi_front_end/frontend.py b/loxi_front_end/frontend.py
index ab98c26..c12eaae 100644
--- a/loxi_front_end/frontend.py
+++ b/loxi_front_end/frontend.py
@@ -64,7 +64,14 @@
ofclass = OFClass(name=decl_ast[1], members=members)
ofinput.classes.append(ofclass)
if decl_ast[0] == 'enum':
- enum = OFEnum(name=decl_ast[1], values=[(x[0], x[1]) for x in decl_ast[2]])
+ # 0: "enum"
+ # 1: name
+ # 2: potentially list of [param_name, param_value]
+ # 3: list of [constant_name, constant_value]+
+ enum = OFEnum(name=decl_ast[1],
+ entries=[OFEnumEntry(name=x[0], value=x[2], params={param:value for param, value in x[1] }) for x in decl_ast[3]],
+ params = { param: value for param, value in decl_ast[2] }
+ )
ofinput.enums.append(enum)
elif decl_ast[0] == 'metadata':
if decl_ast[1] == 'version':
diff --git a/loxi_front_end/parser.py b/loxi_front_end/parser.py
index 503a05a..03d5af1 100644
--- a/loxi_front_end/parser.py
+++ b/loxi_front_end/parser.py
@@ -59,10 +59,20 @@
s('}') - s(';')
# Enums
-enum_member = P.Group(identifier + s('=') + integer)
+enum_param_name = kw("wire_type") | kw("bitmask") | kw("complete")
+enum_param = P.Group(enum_param_name - s('=') - any_type)
+enum_param_list = P.Forward()
+enum_param_list << enum_param + P.Optional(s(',') + P.Optional(enum_param_list))
+
+enum_member_param_name = kw("virtual")
+enum_member_param = P.Group(enum_member_param_name - s('=') - any_type)
+enum_member_param_list = P.Forward()
+enum_member_param_list << enum_member_param + P.Optional(s(',') + P.Optional(enum_member_param_list))
+
+enum_member = P.Group(identifier - P.Group(P.Optional(s('(') - enum_member_param_list - s(')'))) - s('=') + integer)
enum_list = P.Forward()
enum_list << enum_member + P.Optional(s(',') + P.Optional(enum_list))
-enum = kw('enum') - identifier - s('{') + \
+enum = kw('enum') - identifier - P.Group(P.Optional(s('(') - enum_param_list - s(')'))) - s('{') + \
P.Group(P.Optional(enum_list)) + \
s('}') - s(';')
diff --git a/loxi_ir.py b/loxi_ir.py
index 9a27272..8f1e822 100644
--- a/loxi_ir.py
+++ b/loxi_ir.py
@@ -39,6 +39,7 @@
'OFFieldLengthMember',
'OFPadMember',
'OFEnum',
+ 'OFEnumEntry'
]
"""
@@ -131,6 +132,13 @@
All values are Python ints.
@param name
-@param values List of (name, value) tuples in input order
+@param entries List of OFEnumEntry objects in input order
+@params dict of optional params. Currently defined:
+ - wire_type: the low_level type of the enum values (uint8,...)
"""
-OFEnum = namedtuple('OFEnum', ['name', 'values'])
+class OFEnum(namedtuple('OFEnum', ['name', 'entries', 'params'])):
+ @property
+ def values(self):
+ return [(e.name, e.value) for e in self.entries]
+
+OFEnumEntry = namedtuple('OFEnumEntry', ['name', 'value', 'params'])
diff --git a/loxigen.py b/loxigen.py
index 36d6872..92204ca 100755
--- a/loxigen.py
+++ b/loxigen.py
@@ -451,10 +451,10 @@
versions[version_name]['classes'][ofclass.name] = legacy_members
for enum in ofinput.enums:
- for name, value in enum.values:
+ for entry in enum.entries:
identifiers.add_identifier(
- translation.loxi_name(name),
- name, enum.name, value, wire_version,
+ translation.loxi_name(entry.name),
+ entry.name, enum.name, entry.value, wire_version,
of_g.identifiers, of_g.identifiers_by_group)
for wire_version, ofinputs in ofinputs_by_version.items():
diff --git a/openflow_input/bsn_vport b/openflow_input/bsn_vport
index 0cf30bf..03b4b43 100644
--- a/openflow_input/bsn_vport
+++ b/openflow_input/bsn_vport
@@ -38,7 +38,7 @@
// When the ingress or egress VID has this value, no outer tag should be used.
// In this case, the corresponding TPID is ignored.
-enum ofp_bsn_vport_q_in_q_untagged {
+enum ofp_bsn_vport_q_in_q_untagged(wire_type=uint16_t, complete=False) {
OF_BSN_VPORT_Q_IN_Q_UNTAGGED = 0xffff,
};
diff --git a/openflow_input/standard-1.0 b/openflow_input/standard-1.0
index e9cb6f0..ceb2016 100644
--- a/openflow_input/standard-1.0
+++ b/openflow_input/standard-1.0
@@ -61,7 +61,7 @@
OFPQ_MIN_RATE_UNCFG = 0xffff,
};
-enum ofp_type {
+enum ofp_type(wire_type=uint8_t) {
OFPT_HELLO = 0,
OFPT_ERROR = 1,
OFPT_ECHO_REQUEST = 2,
@@ -86,7 +86,7 @@
OFPT_QUEUE_GET_CONFIG_REPLY = 21,
};
-enum ofp_port_config {
+enum ofp_port_config(wire_type=uint32_t, bitmask=True) {
OFPPC_PORT_DOWN = 0x1,
OFPPC_NO_STP = 0x2,
OFPPC_NO_RECV = 0x4,
@@ -96,16 +96,19 @@
OFPPC_NO_PACKET_IN = 0x40,
};
-enum ofp_port_state {
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
OFPPS_STP_LISTEN = 0,
OFPPS_LINK_DOWN = 1,
OFPPS_STP_LEARN = 0x100,
OFPPS_STP_FORWARD = 0x200,
OFPPS_STP_BLOCK = 0x300,
- OFPPS_STP_MASK = 0x300,
+ OFPPS_STP_MASK(virtual=True) = 0x300,
};
-enum ofp_port {
+// FIXME: these constants are currently 32 bit due to implementation
+// details of loci, which is in violation of the OpenFlow spec.
+// Should recast to 32 bits and fix/glue the c backend
+enum ofp_port(wire_type=uint16_t, complete=False) {
OFPP_MAX = 0xffffff00,
OFPP_IN_PORT = 0xfffffff8,
OFPP_TABLE = 0xfffffff9,
@@ -117,7 +120,7 @@
OFPP_NONE = 0xffffffff,
};
-enum ofp_port_features {
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
OFPPF_10MB_HD = 0x1,
OFPPF_10MB_FD = 0x2,
OFPPF_100MB_HD = 0x4,
@@ -132,12 +135,12 @@
OFPPF_PAUSE_ASYM = 0x800,
};
-enum ofp_queue_properties {
+enum ofp_queue_properties(wire_type=uint32_t) {
OFPQT_NONE = 0,
OFPQT_MIN_RATE = 1,
};
-enum ofp_flow_wildcards {
+enum ofp_flow_wildcards(wire_type=uint32_t, bitmask=True) {
OFPFW_IN_PORT = 0x1,
OFPFW_DL_VLAN = 0x2,
OFPFW_DL_SRC = 0x4,
@@ -159,7 +162,7 @@
OFPFW_ALL = 0x3fffff,
};
-enum ofp_action_type {
+enum ofp_action_type(wire_type=uint16_t) {
OFPAT_OUTPUT = 0,
OFPAT_SET_VLAN_VID = 1,
OFPAT_SET_VLAN_PCP = 2,
@@ -175,7 +178,7 @@
OFPAT_VENDOR = 0xffff,
};
-enum ofp_capabilities {
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
OFPC_FLOW_STATS = 0x1,
OFPC_TABLE_STATS = 0x2,
OFPC_PORT_STATS = 0x4,
@@ -186,14 +189,14 @@
OFPC_ARP_MATCH_IP = 0x80,
};
-enum ofp_config_flags {
+enum ofp_config_flags(wire_type=uint32_t, bitmask=True) {
OFPC_FRAG_NORMAL = 0x0,
OFPC_FRAG_DROP = 0x1,
OFPC_FRAG_REASM = 0x2,
OFPC_FRAG_MASK = 0x3,
};
-enum ofp_flow_mod_command {
+enum ofp_flow_mod_command(wire_type=uint16_t) {
OFPFC_ADD = 0,
OFPFC_MODIFY = 1,
OFPFC_MODIFY_STRICT = 2,
@@ -201,17 +204,17 @@
OFPFC_DELETE_STRICT = 4,
};
-enum ofp_flow_mod_flags {
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
OFPFF_SEND_FLOW_REM = 0x1,
OFPFF_CHECK_OVERLAP = 0x2,
OFPFF_EMERG = 0x4,
};
-enum ofp_stats_reply_flags {
+enum ofp_stats_reply_flags(wire_type=uint16_t, bitmask=True) {
OFPSF_REPLY_MORE = 0x1,
};
-enum ofp_stats_types {
+enum ofp_stats_types(wire_type=uint16_t) {
OFPST_DESC = 0,
OFPST_FLOW = 1,
OFPST_AGGREGATE = 2,
@@ -221,24 +224,24 @@
OFPST_VENDOR = 0xffff,
};
-enum ofp_packet_in_reason {
+enum ofp_packet_in_reason(wire_type=uint8_t) {
OFPR_NO_MATCH = 0,
OFPR_ACTION = 1,
};
-enum ofp_flow_removed_reason {
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
OFPRR_IDLE_TIMEOUT = 0,
OFPRR_HARD_TIMEOUT = 1,
OFPRR_DELETE = 2,
};
-enum ofp_port_reason {
+enum ofp_port_reason(wire_type=uint8_t) {
OFPPR_ADD = 0,
OFPPR_DELETE = 1,
OFPPR_MODIFY = 2,
};
-enum ofp_error_type {
+enum ofp_error_type(wire_type=uint16_t) {
OFPET_HELLO_FAILED = 0,
OFPET_BAD_REQUEST = 1,
OFPET_BAD_ACTION = 2,
@@ -247,12 +250,12 @@
OFPET_QUEUE_OP_FAILED = 5,
};
-enum ofp_hello_failed_code {
+enum ofp_hello_failed_code(wire_type=uint16_t) {
OFPHFC_INCOMPATIBLE = 0,
OFPHFC_EPERM = 1,
};
-enum ofp_bad_request_code {
+enum ofp_bad_request_code(wire_type=uint16_t) {
OFPBRC_BAD_VERSION = 0,
OFPBRC_BAD_TYPE = 1,
OFPBRC_BAD_STAT = 2,
@@ -264,7 +267,7 @@
OFPBRC_BUFFER_UNKNOWN = 8,
};
-enum ofp_bad_action_code {
+enum ofp_bad_action_code(wire_type=uint16_t) {
OFPBAC_BAD_TYPE = 0,
OFPBAC_BAD_LEN = 1,
OFPBAC_BAD_VENDOR = 2,
@@ -276,7 +279,7 @@
OFPBAC_BAD_QUEUE = 8,
};
-enum ofp_flow_mod_failed_code {
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
OFPFMFC_ALL_TABLES_FULL = 0,
OFPFMFC_OVERLAP = 1,
OFPFMFC_EPERM = 2,
@@ -285,12 +288,12 @@
OFPFMFC_UNSUPPORTED = 5,
};
-enum ofp_port_mod_failed_code {
+enum ofp_port_mod_failed_code(wire_type=uint16_t) {
OFPPMFC_BAD_PORT = 0,
OFPPMFC_BAD_HW_ADDR = 1,
};
-enum ofp_queue_op_failed_code {
+enum ofp_queue_op_failed_code(wire_type=uint16_t) {
OFPQOFC_BAD_PORT = 0,
OFPQOFC_BAD_QUEUE = 1,
OFPQOFC_EPERM = 2,
diff --git a/openflow_input/standard-1.1 b/openflow_input/standard-1.1
index 553e665..18faaa8 100644
--- a/openflow_input/standard-1.1
+++ b/openflow_input/standard-1.1
@@ -63,7 +63,7 @@
OFPQ_MIN_RATE_UNCFG = 0xffff,
};
-enum ofp_port {
+enum ofp_port(wire_type=uint32_t) {
OFPP_MAX = 0xffffff00,
OFPP_IN_PORT = 0xfffffff8,
OFPP_TABLE = 0xfffffff9,
@@ -74,11 +74,11 @@
OFPP_LOCAL = 0xfffffffe,
};
-enum ofp_port_no {
+enum ofp_port_no(wire_type=uint32_t, complete=no) {
OFPP_ANY = 0xffffffff,
};
-enum ofp_type {
+enum ofp_type(wire_type=uint8_t) {
OFPT_HELLO = 0,
OFPT_ERROR = 1,
OFPT_ECHO_REQUEST = 2,
@@ -105,22 +105,22 @@
OFPT_QUEUE_GET_CONFIG_REPLY = 23,
};
-enum ofp_config_flags {
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
OFPC_FRAG_NORMAL = 0,
OFPC_FRAG_DROP = 1,
OFPC_FRAG_REASM = 2,
- OFPC_FRAG_MASK = 3,
+ OFPC_FRAG_MASK(virtual=True) = 3,
OFPC_INVALID_TTL_TO_CONTROLLER = 4,
};
-enum ofp_table_config {
+enum ofp_table_config(wire_type=uint32_t, bitmask=True) {
OFPTC_TABLE_MISS_CONTROLLER = 0,
OFPTC_TABLE_MISS_CONTINUE = 1,
OFPTC_TABLE_MISS_DROP = 2,
- OFPTC_TABLE_MISS_MASK = 3,
+ OFPTC_TABLE_MISS_MASK(virtual=True) = 3,
};
-enum ofp_capabilities {
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
OFPC_FLOW_STATS = 0x1,
OFPC_TABLE_STATS = 0x2,
OFPC_PORT_STATS = 0x4,
@@ -130,20 +130,20 @@
OFPC_ARP_MATCH_IP = 0x80,
};
-enum ofp_port_config {
+enum ofp_port_config(wire_type=uint32_t, bitmask=True) {
OFPPC_PORT_DOWN = 0x1,
OFPPC_NO_RECV = 0x4,
OFPPC_NO_FWD = 0x20,
OFPPC_NO_PACKET_IN = 0x40,
};
-enum ofp_port_state {
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
OFPPS_LINK_DOWN = 0x1,
OFPPS_BLOCKED = 0x2,
OFPPS_LIVE = 0x4,
};
-enum ofp_port_features {
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
OFPPF_10MB_HD = 0x1,
OFPPF_10MB_FD = 0x2,
OFPPF_100MB_HD = 0x4,
@@ -162,18 +162,18 @@
OFPPF_PAUSE_ASYM = 0x8000,
};
-enum ofp_port_reason {
+enum ofp_port_reason(wire_type=uint8_t) {
OFPPR_ADD = 0,
OFPPR_DELETE = 1,
OFPPR_MODIFY = 2,
};
-enum ofp_packet_in_reason {
+enum ofp_packet_in_reason(wire_type=uint8_t) {
OFPR_NO_MATCH = 0,
OFPR_ACTION = 1,
};
-enum ofp_action_type {
+enum ofp_action_type(wire_type=uint16_t) {
OFPAT_OUTPUT = 0,
OFPAT_SET_VLAN_VID = 1,
OFPAT_SET_VLAN_PCP = 2,
@@ -202,7 +202,7 @@
OFPAT_EXPERIMENTER = 0xffff,
};
-enum ofp_flow_mod_command {
+enum ofp_flow_mod_command(wire_type=uint8_t) {
OFPFC_ADD = 0,
OFPFC_MODIFY = 1,
OFPFC_MODIFY_STRICT = 2,
@@ -210,13 +210,13 @@
OFPFC_DELETE_STRICT = 4,
};
-enum ofp_group_mod_command {
+enum ofp_group_mod_command(wire_type=uint16_t) {
OFPGC_ADD = 0,
OFPGC_MODIFY = 1,
OFPGC_DELETE = 2,
};
-enum ofp_flow_wildcards {
+enum ofp_flow_wildcards(wire_type=uint32_t, bitmask=True) {
OFPFW_IN_PORT = 0x1,
OFPFW_DL_VLAN = 0x2,
OFPFW_DL_VLAN_PCP = 0x4,
@@ -227,19 +227,19 @@
OFPFW_TP_DST = 0x80,
OFPFW_MPLS_LABEL = 0x100,
OFPFW_MPLS_TC = 0x200,
- OFPFW_ALL = 0x3ff,
+ OFPFW_ALL(virtual=True) = 0x3ff,
};
-enum ofp_vlan_id {
+enum ofp_vlan_id(wire_type=uint16_t) {
OFPVID_ANY = 0xfffe,
OFPVID_NONE = 0xffff,
};
-enum ofp_match_type {
+enum ofp_match_type(wire_type=uint16_t) {
OFPMT_STANDARD = 0,
};
-enum ofp_instruction_type {
+enum ofp_instruction_type(wire_type=uint16_t, bitmask=True) {
OFPIT_GOTO_TABLE = 0x1,
OFPIT_WRITE_METADATA = 0x2,
OFPIT_WRITE_ACTIONS = 0x3,
@@ -248,32 +248,32 @@
OFPIT_EXPERIMENTER = 0xffff,
};
-enum ofp_flow_mod_flags {
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
OFPFF_SEND_FLOW_REM = 0x1,
OFPFF_CHECK_OVERLAP = 0x2,
};
-enum ofp_group {
+enum ofp_group(wire_type=uint32_t, complete=False) {
OFPG_MAX = 0xffffff00,
OFPG_ALL = 0xfffffffc,
OFPG_ANY = 0xffffffff,
};
-enum ofp_group_type {
+enum ofp_group_type(wire_type=uint8_t) {
OFPGT_ALL = 0,
OFPGT_SELECT = 1,
OFPGT_INDIRECT = 2,
OFPGT_FF = 3,
};
-enum ofp_flow_removed_reason {
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
OFPRR_IDLE_TIMEOUT = 0,
OFPRR_HARD_TIMEOUT = 1,
OFPRR_DELETE = 2,
OFPRR_GROUP_DELETE = 3,
};
-enum ofp_error_type {
+enum ofp_error_type(wire_type=uint16_t) {
OFPET_HELLO_FAILED = 0,
OFPET_BAD_REQUEST = 1,
OFPET_BAD_ACTION = 2,
@@ -287,12 +287,12 @@
OFPET_SWITCH_CONFIG_FAILED = 10,
};
-enum ofp_hello_failed_code {
+enum ofp_hello_failed_code(wire_type=uint16_t) {
OFPHFC_INCOMPATIBLE = 0,
OFPHFC_EPERM = 1,
};
-enum ofp_bad_request_code {
+enum ofp_bad_request_code(wire_type=uint16_t) {
OFPBRC_BAD_VERSION = 0,
OFPBRC_BAD_TYPE = 1,
OFPBRC_BAD_STAT = 2,
@@ -305,7 +305,7 @@
OFPBRC_BAD_TABLE_ID = 9,
};
-enum ofp_bad_action_code {
+enum ofp_bad_action_code(wire_type=uint16_t) {
OFPBAC_BAD_TYPE = 0,
OFPBAC_BAD_LEN = 1,
OFPBAC_BAD_EXPERIMENTER = 2,
@@ -321,7 +321,7 @@
OFPBAC_BAD_TAG = 12,
};
-enum ofp_bad_instruction_code {
+enum ofp_bad_instruction_code(wire_type=uint16_t) {
OFPBIC_UNKNOWN_INST = 0,
OFPBIC_UNSUP_INST = 1,
OFPBIC_BAD_TABLE_ID = 2,
@@ -330,7 +330,7 @@
OFPBIC_UNSUP_EXP_INST = 5,
};
-enum ofp_bad_match_code {
+enum ofp_bad_match_code(wire_type=uint16_t) {
OFPBMC_BAD_TYPE = 0,
OFPBMC_BAD_LEN = 1,
OFPBMC_BAD_TAG = 2,
@@ -341,7 +341,7 @@
OFPBMC_BAD_VALUE = 7,
};
-enum ofp_flow_mod_failed_code {
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
OFPFMFC_UNKNOWN = 0,
OFPFMFC_TABLE_FULL = 1,
OFPFMFC_BAD_TABLE_ID = 2,
@@ -351,7 +351,7 @@
OFPFMFC_BAD_COMMAND = 6,
};
-enum ofp_group_mod_failed_code {
+enum ofp_group_mod_failed_code(wire_type=uint16_t) {
OFPGMFC_GROUP_EXISTS = 0,
OFPGMFC_INVALID_GROUP = 1,
OFPGMFC_WEIGHT_UNSUPPORTED = 2,
@@ -363,30 +363,30 @@
OFPGMFC_UNKNOWN_GROUP = 8,
};
-enum ofp_port_mod_failed_code {
+enum ofp_port_mod_failed_code(wire_type=uint16_t) {
OFPPMFC_BAD_PORT = 0,
OFPPMFC_BAD_HW_ADDR = 1,
OFPPMFC_BAD_CONFIG = 2,
OFPPMFC_BAD_ADVERTISE = 3,
};
-enum ofp_table_mod_failed_code {
+enum ofp_table_mod_failed_code(wire_type=uint16_t) {
OFPTMFC_BAD_TABLE = 0,
OFPTMFC_BAD_CONFIG = 1,
};
-enum ofp_queue_op_failed_code {
+enum ofp_queue_op_failed_code(wire_type=uint16_t) {
OFPQOFC_BAD_PORT = 0,
OFPQOFC_BAD_QUEUE = 1,
OFPQOFC_EPERM = 2,
};
-enum ofp_switch_config_failed_code {
+enum ofp_switch_config_failed_code(wire_type=uint16_t) {
OFPSCFC_BAD_FLAGS = 0,
OFPSCFC_BAD_LEN = 1,
};
-enum ofp_stats_types {
+enum ofp_stats_types(wire_type=uint16_t) {
OFPST_DESC = 0,
OFPST_FLOW = 1,
OFPST_AGGREGATE = 2,
@@ -398,11 +398,11 @@
OFPST_EXPERIMENTER = 0xffff,
};
-enum ofp_stats_reply_flags {
+enum ofp_stats_reply_flags(wire_type=uint16_t, bitmask=True) {
OFPSF_REPLY_MORE = 0x1,
};
-enum ofp_queue_properties {
+enum ofp_queue_properties(wire_type=uint16_t) {
OFPQT_NONE = 0,
OFPQT_MIN_RATE = 1,
};
diff --git a/openflow_input/standard-1.2 b/openflow_input/standard-1.2
index 8b4fa3f..f4d31d6 100644
--- a/openflow_input/standard-1.2
+++ b/openflow_input/standard-1.2
@@ -59,7 +59,7 @@
OFPQ_MAX_RATE_UNCFG = 0xffff,
};
-enum ofp_port {
+enum ofp_port(wire_type=uint32_t) {
OFPP_MAX = 0xffffff00,
OFPP_IN_PORT = 0xfffffff8,
OFPP_TABLE = 0xfffffff9,
@@ -70,11 +70,11 @@
OFPP_LOCAL = 0xfffffffe,
};
-enum ofp_port_no {
+enum ofp_port_no(wire_type=uint32_t, complete=no) {
OFPP_ANY = 0xffffffff,
};
-enum ofp_type {
+enum ofp_type(wire_type=uint8_t) {
OFPT_HELLO = 0,
OFPT_ERROR = 1,
OFPT_ECHO_REQUEST = 2,
@@ -103,7 +103,7 @@
OFPT_ROLE_REPLY = 25,
};
-enum ofp_config_flags {
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
OFPC_FRAG_NORMAL = 0,
OFPC_FRAG_DROP = 1,
OFPC_FRAG_REASM = 2,
@@ -111,19 +111,19 @@
OFPC_INVALID_TTL_TO_CONTROLLER = 4,
};
-enum ofp_table_config {
+enum ofp_table_config(wire_type=uint32_t, bitmask=True) {
OFPTC_TABLE_MISS_CONTROLLER = 0,
OFPTC_TABLE_MISS_CONTINUE = 1,
OFPTC_TABLE_MISS_DROP = 2,
OFPTC_TABLE_MISS_MASK = 3,
};
-enum ofp_table {
+enum ofp_table(wire_type=uint8_t, complete=False) {
OFPTT_MAX = 0xfe,
OFPTT_ALL = 0xff,
};
-enum ofp_capabilities {
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
OFPC_FLOW_STATS = 0x1,
OFPC_TABLE_STATS = 0x2,
OFPC_PORT_STATS = 0x4,
@@ -133,20 +133,20 @@
OFPC_PORT_BLOCKED = 0x100,
};
-enum ofp_port_config {
+enum ofp_port_config(wire_type=uint32_t, bitmask=True) {
OFPPC_PORT_DOWN = 0x1,
OFPPC_NO_RECV = 0x4,
OFPPC_NO_FWD = 0x20,
OFPPC_NO_PACKET_IN = 0x40,
};
-enum ofp_port_state {
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
OFPPS_LINK_DOWN = 0x1,
OFPPS_BLOCKED = 0x2,
OFPPS_LIVE = 0x4,
};
-enum ofp_port_features {
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
OFPPF_10MB_HD = 0x1,
OFPPF_10MB_FD = 0x2,
OFPPF_100MB_HD = 0x4,
@@ -165,30 +165,30 @@
OFPPF_PAUSE_ASYM = 0x8000,
};
-enum ofp_port_reason {
+enum ofp_port_reason(wire_type=uint8_t) {
OFPPR_ADD = 0,
OFPPR_DELETE = 1,
OFPPR_MODIFY = 2,
};
-enum ofp_match_type {
+enum ofp_match_type(wire_type=uint16_t) {
OFPMT_STANDARD = 0,
OFPMT_OXM = 1,
};
-enum ofp_oxm_class {
+enum ofp_oxm_class(wire_type=uint16_t) {
OFPXMC_NXM_0 = 0,
OFPXMC_NXM_1 = 1,
OFPXMC_OPENFLOW_BASIC = 0x8000,
OFPXMC_EXPERIMENTER = 0xffff,
};
-enum ofp_vlan_id {
+enum ofp_vlan_id(wire_type=uint16_t) {
OFPVID_NONE = 0,
OFPVID_PRESENT = 0x1000,
};
-enum ofp_action_type {
+enum ofp_action_type(wire_type=uint16_t) {
OFPAT_OUTPUT = 0,
OFPAT_COPY_TTL_OUT = 0xb,
OFPAT_COPY_TTL_IN = 0xc,
@@ -206,12 +206,12 @@
OFPAT_EXPERIMENTER = 0xffff,
};
-enum ofp_controller_max_len {
+enum ofp_controller_max_len(wire_type=uint16_t, complete=False) {
OFPCML_MAX = 0xffe5,
OFPCML_NO_BUFFER = 0xffff,
};
-enum ofp_instruction_type {
+enum ofp_instruction_type(wire_type=uint16_t, bitmask=True) {
OFPIT_GOTO_TABLE = 0x1,
OFPIT_WRITE_METADATA = 0x2,
OFPIT_WRITE_ACTIONS = 0x3,
@@ -220,7 +220,7 @@
OFPIT_EXPERIMENTER = 0xffff,
};
-enum ofp_flow_mod_command {
+enum ofp_flow_mod_command(wire_type=uint8_t) {
OFPFC_ADD = 0,
OFPFC_MODIFY = 1,
OFPFC_MODIFY_STRICT = 2,
@@ -228,45 +228,45 @@
OFPFC_DELETE_STRICT = 4,
};
-enum ofp_flow_mod_flags {
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
OFPFF_SEND_FLOW_REM = 0x1,
OFPFF_CHECK_OVERLAP = 0x2,
OFPFF_RESET_COUNTS = 0x4,
};
-enum ofp_group {
+enum ofp_group(wire_type=uint32_t, complete=False) {
OFPG_MAX = 0xffffff00,
OFPG_ALL = 0xfffffffc,
OFPG_ANY = 0xffffffff,
};
-enum ofp_group_mod_command {
+enum ofp_group_mod_command(wire_type=uint16_t) {
OFPGC_ADD = 0,
OFPGC_MODIFY = 1,
OFPGC_DELETE = 2,
};
-enum ofp_group_type {
+enum ofp_group_type(wire_type=uint8_t) {
OFPGT_ALL = 0,
OFPGT_SELECT = 1,
OFPGT_INDIRECT = 2,
OFPGT_FF = 3,
};
-enum ofp_packet_in_reason {
+enum ofp_packet_in_reason(wire_type=uint8_t) {
OFPR_NO_MATCH = 0,
OFPR_ACTION = 1,
OFPR_INVALID_TTL = 2,
};
-enum ofp_flow_removed_reason {
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
OFPRR_IDLE_TIMEOUT = 0,
OFPRR_HARD_TIMEOUT = 1,
OFPRR_DELETE = 2,
OFPRR_GROUP_DELETE = 3,
};
-enum ofp_error_type {
+enum ofp_error_type(wire_type=uint16_t) {
OFPET_HELLO_FAILED = 0,
OFPET_BAD_REQUEST = 1,
OFPET_BAD_ACTION = 2,
@@ -282,12 +282,12 @@
OFPET_EXPERIMENTER = 0xffff,
};
-enum ofp_hello_failed_code {
+enum ofp_hello_failed_code(wire_type=uint16_t) {
OFPHFC_INCOMPATIBLE = 0,
OFPHFC_EPERM = 1,
};
-enum ofp_bad_request_code {
+enum ofp_bad_request_code(wire_type=uint16_t) {
OFPBRC_BAD_VERSION = 0,
OFPBRC_BAD_TYPE = 1,
OFPBRC_BAD_STAT = 2,
@@ -303,7 +303,7 @@
OFPBRC_BAD_PACKET = 12,
};
-enum ofp_bad_action_code {
+enum ofp_bad_action_code(wire_type=uint16_t) {
OFPBAC_BAD_TYPE = 0,
OFPBAC_BAD_LEN = 1,
OFPBAC_BAD_EXPERIMENTER = 2,
@@ -322,7 +322,7 @@
OFPBAC_BAD_SET_ARGUMENT = 15,
};
-enum ofp_bad_instruction_code {
+enum ofp_bad_instruction_code(wire_type=uint16_t) {
OFPBIC_UNKNOWN_INST = 0,
OFPBIC_UNSUP_INST = 1,
OFPBIC_BAD_TABLE_ID = 2,
@@ -334,7 +334,7 @@
OFPBIC_EPERM = 8,
};
-enum ofp_bad_match_code {
+enum ofp_bad_match_code(wire_type=uint16_t) {
OFPBMC_BAD_TYPE = 0,
OFPBMC_BAD_LEN = 1,
OFPBMC_BAD_TAG = 2,
@@ -349,7 +349,7 @@
OFPBMC_EPERM = 11,
};
-enum ofp_flow_mod_failed_code {
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
OFPFMFC_UNKNOWN = 0,
OFPFMFC_TABLE_FULL = 1,
OFPFMFC_BAD_TABLE_ID = 2,
@@ -360,7 +360,7 @@
OFPFMFC_BAD_FLAGS = 7,
};
-enum ofp_group_mod_failed_code {
+enum ofp_group_mod_failed_code(wire_type=uint16_t) {
OFPGMFC_GROUP_EXISTS = 0,
OFPGMFC_INVALID_GROUP = 1,
OFPGMFC_WEIGHT_UNSUPPORTED = 2,
@@ -378,7 +378,7 @@
OFPGMFC_EPERM = 14,
};
-enum ofp_port_mod_failed_code {
+enum ofp_port_mod_failed_code(wire_type=uint16_t) {
OFPPMFC_BAD_PORT = 0,
OFPPMFC_BAD_HW_ADDR = 1,
OFPPMFC_BAD_CONFIG = 2,
@@ -386,31 +386,31 @@
OFPPMFC_EPERM = 4,
};
-enum ofp_table_mod_failed_code {
+enum ofp_table_mod_failed_code(wire_type=uint16_t) {
OFPTMFC_BAD_TABLE = 0,
OFPTMFC_BAD_CONFIG = 1,
OFPTMFC_EPERM = 2,
};
-enum ofp_queue_op_failed_code {
+enum ofp_queue_op_failed_code(wire_type=uint16_t) {
OFPQOFC_BAD_PORT = 0,
OFPQOFC_BAD_QUEUE = 1,
OFPQOFC_EPERM = 2,
};
-enum ofp_switch_config_failed_code {
+enum ofp_switch_config_failed_code(wire_type=uint16_t) {
OFPSCFC_BAD_FLAGS = 0,
OFPSCFC_BAD_LEN = 1,
OFPSCFC_EPERM = 2,
};
-enum ofp_role_request_failed_code {
+enum ofp_role_request_failed_code (wire_type=uint16_t){
OFPRRFC_STALE = 0,
OFPRRFC_UNSUP = 1,
OFPRRFC_BAD_ROLE = 2,
};
-enum ofp_stats_types {
+enum ofp_stats_types(wire_type=uint16_t) {
OFPST_DESC = 0,
OFPST_FLOW = 1,
OFPST_AGGREGATE = 2,
@@ -423,24 +423,24 @@
OFPST_EXPERIMENTER = 0xffff,
};
-enum ofp_stats_reply_flags {
+enum ofp_stats_reply_flags(wire_type=uint16_t, bitmask=True) {
OFPSF_REPLY_MORE = 0x1,
};
-enum ofp_group_capabilities {
+enum ofp_group_capabilities(wire_type=uint32_t, bitmask=True) {
OFPGFC_SELECT_WEIGHT = 0x1,
OFPGFC_SELECT_LIVENESS = 0x2,
OFPGFC_CHAINING = 0x4,
OFPGFC_CHAINING_CHECKS = 0x8,
};
-enum ofp_queue_properties {
+enum ofp_queue_properties(wire_type=uint16_t) {
OFPQT_MIN_RATE = 0x1,
OFPQT_MAX_RATE = 0x2,
OFPQT_EXPERIMENTER = 0xffff,
};
-enum ofp_controller_role {
+enum ofp_controller_role(wire_type=uint32_t) {
OFPCR_ROLE_NOCHANGE = 0,
OFPCR_ROLE_EQUAL = 1,
OFPCR_ROLE_MASTER = 2,
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 0d5cec3..b0aa242 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -58,11 +58,11 @@
OFPQ_MIN_RATE_UNCFG = 0xffff,
};
-enum ofp_port_no {
+enum ofp_port_no(wire_type=uint32_t, complete=no) {
OFPP_ANY = 0xffffffff,
};
-enum ofp_port {
+enum ofp_port(wire_type=uint32_t) {
OFPP_MAX = 0xffffff00,
OFPP_IN_PORT = 0xfffffff8,
OFPP_TABLE = 0xfffffff9,
@@ -73,7 +73,7 @@
OFPP_LOCAL = 0xfffffffe,
};
-enum ofp_type {
+enum ofp_type(wire_type=uint8_t) {
OFPT_HELLO = 0,
OFPT_ERROR = 1,
OFPT_ECHO_REQUEST = 2,
@@ -106,23 +106,23 @@
OFPT_METER_MOD = 29,
};
-enum ofp_config_flags {
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
OFPC_FRAG_NORMAL = 0,
OFPC_FRAG_DROP = 1,
OFPC_FRAG_REASM = 2,
OFPC_FRAG_MASK = 3,
};
-enum ofp_table_config {
+enum ofp_table_config(wire_type=uint32_t, bitmask=True) {
OFPTC_DEPRECATED_MASK = 0x3,
};
-enum ofp_table {
+enum ofp_table(wire_type=uint8_t, complete=False) {
OFPTT_MAX = 0xfe,
OFPTT_ALL = 0xff,
};
-enum ofp_capabilities {
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
OFPC_FLOW_STATS = 0x1,
OFPC_TABLE_STATS = 0x2,
OFPC_PORT_STATS = 0x4,
@@ -132,20 +132,20 @@
OFPC_PORT_BLOCKED = 0x100,
};
-enum ofp_port_config {
+enum ofp_port_config(wire_type=uint32_t, bitmask=True) {
OFPPC_PORT_DOWN = 0x1,
OFPPC_NO_RECV = 0x4,
OFPPC_NO_FWD = 0x20,
OFPPC_NO_PACKET_IN = 0x40,
};
-enum ofp_port_state {
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
OFPPS_LINK_DOWN = 0x1,
OFPPS_BLOCKED = 0x2,
OFPPS_LIVE = 0x4,
};
-enum ofp_port_features {
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
OFPPF_10MB_HD = 0x1,
OFPPF_10MB_FD = 0x2,
OFPPF_100MB_HD = 0x4,
@@ -164,30 +164,32 @@
OFPPF_PAUSE_ASYM = 0x8000,
};
-enum ofp_port_reason {
+enum ofp_port_reason(wire_type=uint8_t) {
OFPPR_ADD = 0,
OFPPR_DELETE = 1,
OFPPR_MODIFY = 2,
};
-enum ofp_match_type {
+enum ofp_match_type(wire_type=uint16_t) {
OFPMT_STANDARD = 0,
OFPMT_OXM = 1,
};
-enum ofp_oxm_class {
+enum ofp_oxm_class(wire_type=uint16_t) {
OFPXMC_NXM_0 = 0,
OFPXMC_NXM_1 = 1,
OFPXMC_OPENFLOW_BASIC = 0x8000,
OFPXMC_EXPERIMENTER = 0xffff,
};
-enum ofp_vlan_id {
+enum ofp_vlan_id(wire_type=uint16_t) {
OFPVID_NONE = 0,
OFPVID_PRESENT = 0x1000,
};
-enum ofp_ipv6exthdr_flags {
+// FIXME: OF spec specified this as '9' bits, implicitly adding
+// to full byte
+enum ofp_ipv6exthdr_flags(wire_type=uint16_t, bitmask=True) {
OFPIEH_NONEXT = 0x1,
OFPIEH_ESP = 0x2,
OFPIEH_AUTH = 0x4,
@@ -199,7 +201,7 @@
OFPIEH_UNSEQ = 0x100,
};
-enum ofp_action_type {
+enum ofp_action_type(wire_type=uint16_t) {
OFPAT_OUTPUT = 0,
OFPAT_COPY_TTL_OUT = 0xb,
OFPAT_COPY_TTL_IN = 0xc,
@@ -219,12 +221,12 @@
OFPAT_EXPERIMENTER = 0xffff,
};
-enum ofp_controller_max_len {
+enum ofp_controller_max_len(wire_type=uint16_t, complete=False) {
OFPCML_MAX = 0xffe5,
OFPCML_NO_BUFFER = 0xffff,
};
-enum ofp_instruction_type {
+enum ofp_instruction_type(wire_type=uint16_t, bitmask=True) {
OFPIT_GOTO_TABLE = 0x1,
OFPIT_WRITE_METADATA = 0x2,
OFPIT_WRITE_ACTIONS = 0x3,
@@ -234,7 +236,7 @@
OFPIT_EXPERIMENTER = 0xffff,
};
-enum ofp_flow_mod_command {
+enum ofp_flow_mod_command(wire_type=uint8_t) {
OFPFC_ADD = 0,
OFPFC_MODIFY = 1,
OFPFC_MODIFY_STRICT = 2,
@@ -242,7 +244,7 @@
OFPFC_DELETE_STRICT = 4,
};
-enum ofp_flow_mod_flags {
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
OFPFF_SEND_FLOW_REM = 0x1,
OFPFF_CHECK_OVERLAP = 0x2,
OFPFF_RESET_COUNTS = 0x4,
@@ -250,65 +252,65 @@
OFPFF_NO_BYT_COUNTS = 0x10,
};
-enum ofp_group {
+enum ofp_group(wire_type=uint32_t, complete=False) {
OFPG_MAX = 0xffffff00,
OFPG_ALL = 0xfffffffc,
OFPG_ANY = 0xffffffff,
};
-enum ofp_group_mod_command {
+enum ofp_group_mod_command(wire_type=uint16_t) {
OFPGC_ADD = 0,
OFPGC_MODIFY = 1,
OFPGC_DELETE = 2,
};
-enum ofp_group_type {
+enum ofp_group_type(wire_type=uint8_t) {
OFPGT_ALL = 0,
OFPGT_SELECT = 1,
OFPGT_INDIRECT = 2,
OFPGT_FF = 3,
};
-enum ofp_packet_in_reason {
+enum ofp_packet_in_reason(wire_type=uint8_t) {
OFPR_NO_MATCH = 0,
OFPR_ACTION = 1,
OFPR_INVALID_TTL = 2,
};
-enum ofp_flow_removed_reason {
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
OFPRR_IDLE_TIMEOUT = 0,
OFPRR_HARD_TIMEOUT = 1,
OFPRR_DELETE = 2,
OFPRR_GROUP_DELETE = 3,
};
-enum ofp_meter {
+enum ofp_meter(wire_type=uint32_t, complete=False) {
OFPM_MAX = 0xffff0000,
OFPM_SLOWPATH = 0xfffffffd,
OFPM_CONTROLLER = 0xfffffffe,
OFPM_ALL = 0xffffffff,
};
-enum ofp_meter_band_type {
+enum ofp_meter_band_type(wire_type=uint16_t) {
OFPMBT_DROP = 0x1,
OFPMBT_DSCP_REMARK = 0x2,
OFPMBT_EXPERIMENTER = 0xffff,
};
-enum ofp_meter_mod_command {
+enum ofp_meter_mod_command(wire_type=uint16_t) {
OFPMC_ADD = 0,
OFPMC_MODIFY = 1,
OFPMC_DELETE = 2,
};
-enum ofp_meter_flags {
+enum ofp_meter_flags(wire_type=uint16_t, bitmask=True) {
OFPMF_KBPS = 0x1,
OFPMF_PKTPS = 0x2,
OFPMF_BURST = 0x4,
OFPMF_STATS = 0x8,
};
-enum ofp_error_type {
+enum ofp_error_type(wire_type=uint16_t) {
OFPET_HELLO_FAILED = 0,
OFPET_BAD_REQUEST = 1,
OFPET_BAD_ACTION = 2,
@@ -326,12 +328,12 @@
OFPET_EXPERIMENTER = 0xffff,
};
-enum ofp_hello_failed_code {
+enum ofp_hello_failed_code(wire_type=uint16_t) {
OFPHFC_INCOMPATIBLE = 0,
OFPHFC_EPERM = 1,
};
-enum ofp_bad_request_code {
+enum ofp_bad_request_code(wire_type=uint16_t) {
OFPBRC_BAD_VERSION = 0,
OFPBRC_BAD_TYPE = 1,
OFPBRC_BAD_MULTIPART = 2,
@@ -348,7 +350,7 @@
OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13,
};
-enum ofp_bad_action_code {
+enum ofp_bad_action_code(wire_type=uint16_t) {
OFPBAC_BAD_TYPE = 0,
OFPBAC_BAD_LEN = 1,
OFPBAC_BAD_EXPERIMENTER = 2,
@@ -367,7 +369,7 @@
OFPBAC_BAD_SET_ARGUMENT = 15,
};
-enum ofp_bad_instruction_code {
+enum ofp_bad_instruction_code(wire_type=uint16_t) {
OFPBIC_UNKNOWN_INST = 0,
OFPBIC_UNSUP_INST = 1,
OFPBIC_BAD_TABLE_ID = 2,
@@ -379,7 +381,7 @@
OFPBIC_EPERM = 8,
};
-enum ofp_bad_match_code {
+enum ofp_bad_match_code(wire_type=uint16_t) {
OFPBMC_BAD_TYPE = 0,
OFPBMC_BAD_LEN = 1,
OFPBMC_BAD_TAG = 2,
@@ -394,7 +396,7 @@
OFPBMC_EPERM = 11,
};
-enum ofp_flow_mod_failed_code {
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
OFPFMFC_UNKNOWN = 0,
OFPFMFC_TABLE_FULL = 1,
OFPFMFC_BAD_TABLE_ID = 2,
@@ -405,7 +407,7 @@
OFPFMFC_BAD_FLAGS = 7,
};
-enum ofp_group_mod_failed_code {
+enum ofp_group_mod_failed_code(wire_type=uint16_t) {
OFPGMFC_GROUP_EXISTS = 0,
OFPGMFC_INVALID_GROUP = 1,
OFPGMFC_WEIGHT_UNSUPPORTED = 2,
@@ -423,7 +425,7 @@
OFPGMFC_EPERM = 14,
};
-enum ofp_port_mod_failed_code {
+enum ofp_port_mod_failed_code(wire_type=uint16_t) {
OFPPMFC_BAD_PORT = 0,
OFPPMFC_BAD_HW_ADDR = 1,
OFPPMFC_BAD_CONFIG = 2,
@@ -431,31 +433,31 @@
OFPPMFC_EPERM = 4,
};
-enum ofp_table_mod_failed_code {
+enum ofp_table_mod_failed_code(wire_type=uint16_t) {
OFPTMFC_BAD_TABLE = 0,
OFPTMFC_BAD_CONFIG = 1,
OFPTMFC_EPERM = 2,
};
-enum ofp_queue_op_failed_code {
+enum ofp_queue_op_failed_code(wire_type=uint16_t) {
OFPQOFC_BAD_PORT = 0,
OFPQOFC_BAD_QUEUE = 1,
OFPQOFC_EPERM = 2,
};
-enum ofp_switch_config_failed_code {
+enum ofp_switch_config_failed_code(wire_type=uint16_t) {
OFPSCFC_BAD_FLAGS = 0,
OFPSCFC_BAD_LEN = 1,
OFPSCFC_EPERM = 2,
};
-enum ofp_role_request_failed_code {
+enum ofp_role_request_failed_code(wire_type=uint16_t){
OFPRRFC_STALE = 0,
OFPRRFC_UNSUP = 1,
OFPRRFC_BAD_ROLE = 2,
};
-enum ofp_meter_mod_failed_code {
+enum ofp_meter_mod_failed_code(wire_type=uint16_t) {
OFPMMFC_UNKNOWN = 0,
OFPMMFC_METER_EXISTS = 1,
OFPMMFC_INVALID_METER = 2,
@@ -470,7 +472,7 @@
OFPMMFC_OUT_OF_BANDS = 11,
};
-enum ofp_table_features_failed_code {
+enum ofp_table_features_failed_code(wire_type=uint16_t) {
OFPTFFC_BAD_TABLE = 0,
OFPTFFC_BAD_METADATA = 1,
OFPTFFC_BAD_TYPE = 2,
@@ -479,7 +481,7 @@
OFPTFFC_EPERM = 5,
};
-enum ofp_multipart_types {
+enum ofp_multipart_types(wire_type=uint16_t) {
OFPMP_DESC = 0,
OFPMP_FLOW = 1,
OFPMP_AGGREGATE = 2,
@@ -497,15 +499,15 @@
OFPMP_EXPERIMENTER = 0xffff,
};
-enum ofp_multipart_request_flags {
+enum ofp_multipart_request_flags(wire_type=uint16_t, bitmask=True) {
OFPMPF_REQ_MORE = 0x1,
};
-enum ofp_multipart_reply_flags {
+enum ofp_multipart_reply_flags(wire_type=uint16_t, bitmask=True) {
OFPMPF_REPLY_MORE = 0x1,
};
-enum ofp_table_feature_prop_type {
+enum ofp_table_feature_prop_type(wire_type=uint16_t) {
OFPTFPT_INSTRUCTIONS = 0,
OFPTFPT_INSTRUCTIONS_MISS = 1,
OFPTFPT_NEXT_TABLES = 2,
@@ -524,27 +526,27 @@
OFPTFPT_EXPERIMENTER_MISS = 0xffff,
};
-enum ofp_group_capabilities {
+enum ofp_group_capabilities(wire_type=uint32_t, bitmask=True) {
OFPGFC_SELECT_WEIGHT = 0x1,
OFPGFC_SELECT_LIVENESS = 0x2,
OFPGFC_CHAINING = 0x4,
OFPGFC_CHAINING_CHECKS = 0x8,
};
-enum ofp_queue_properties {
+enum ofp_queue_properties(wire_type=uint16_t) {
OFPQT_MIN_RATE = 0x1,
OFPQT_MAX_RATE = 0x2,
OFPQT_EXPERIMENTER = 0xffff,
};
-enum ofp_controller_role {
+enum ofp_controller_role(wire_type=uint32_t) {
OFPCR_ROLE_NOCHANGE = 0,
OFPCR_ROLE_EQUAL = 1,
OFPCR_ROLE_MASTER = 2,
OFPCR_ROLE_SLAVE = 3,
};
-enum ofp_hello_elem_type {
+enum ofp_hello_elem_type(wire_type=uint16_t) {
OFPHET_VERSIONBITMAP = 1,
};
diff --git a/test_data/__init__.py b/test_data/__init__.py
index f21770b..7a55c11 100644
--- a/test_data/__init__.py
+++ b/test_data/__init__.py
@@ -45,6 +45,9 @@
result.append(dirname + '/' + filename)
return sorted(result)
+def exists(name):
+ return os.path.exists(os.path.join(_test_data_dir, name))
+
def read(name):
"""
Read, parse, and return a test data file
diff --git a/test_data/of10/action_bsn_set_tunnel_dst.data b/test_data/of10/action_bsn_set_tunnel_dst.data
index 7e1f43d..7a5747c 100644
--- a/test_data/of10/action_bsn_set_tunnel_dst.data
+++ b/test_data/of10/action_bsn_set_tunnel_dst.data
@@ -8,3 +8,6 @@
ofp.action.bsn_set_tunnel_dst(dst=0x12345678)
-- python pretty-printer
bsn_set_tunnel_dst { dst = 0x12345678 }
+-- c
+obj = of_action_bsn_set_tunnel_dst_new(OF_VERSION_1_0);
+of_action_bsn_set_tunnel_dst_dst_set(obj, 0x12345678);
diff --git a/test_data/of10/desc_stats_reply.data b/test_data/of10/desc_stats_reply.data
index b4b3eb1..c000bb0 100644
--- a/test_data/of10/desc_stats_reply.data
+++ b/test_data/of10/desc_stats_reply.data
@@ -145,3 +145,27 @@
sw_desc="Indigo-2 LRI pre-release",
serial_num="11235813213455",
dp_desc="Indigo-2 LRI forwarding module")
+-- c
+obj = of_desc_stats_reply_new(OF_VERSION_1_0);
+of_desc_stats_reply_xid_set(obj, 3);
+of_desc_stats_reply_flags_set(obj, OF_STATS_REPLY_FLAG_REPLY_MORE);
+{
+ of_desc_str_t mfr_desc = "The Indigo-2 Community";
+ of_desc_stats_reply_mfr_desc_set(obj, mfr_desc);
+}
+{
+ of_desc_str_t hw_desc = "Unknown server";
+ of_desc_stats_reply_hw_desc_set(obj, hw_desc);
+}
+{
+ of_desc_str_t sw_desc = "Indigo-2 LRI pre-release";
+ of_desc_stats_reply_sw_desc_set(obj, sw_desc);
+}
+{
+ of_desc_str_t dp_desc = "Indigo-2 LRI forwarding module";
+ of_desc_stats_reply_dp_desc_set(obj, dp_desc);
+}
+{
+ of_serial_num_t serial_num = "11235813213455";
+ of_desc_stats_reply_serial_num_set(obj, serial_num);
+}
diff --git a/test_data/of10/echo_request.data b/test_data/of10/echo_request.data
index abe06fc..701376e 100644
--- a/test_data/of10/echo_request.data
+++ b/test_data/of10/echo_request.data
@@ -7,3 +7,10 @@
ofp.message.echo_request(xid=0x12345678, data="ab\x01")
-- python pretty-printer
echo_request { xid = 0x12345678, data = 'ab\x01' }
+-- c
+obj = of_echo_request_new(OF_VERSION_1_0);
+of_echo_request_xid_set(obj, 0x12345678);
+{
+ of_octets_t data = { .data=(uint8_t *)"ab\x01", .bytes=3 };
+ of_echo_request_data_set(obj, &data);
+}
diff --git a/test_data/of10/flow_add.data b/test_data/of10/flow_add.data
index 9801a36..fc09a23 100644
--- a/test_data/of10/flow_add.data
+++ b/test_data/of10/flow_add.data
@@ -1,6 +1,6 @@
-- binary
01 0e 00 70 12 34 56 78
-00 00 00 0c 00 03 01 23
+00 10 00 02 00 03 01 23
45 67 89 ab cd ef 01 23
45 67 00 00 00 00 00 00
00 00 00 00 c0 a8 03 7f
@@ -17,7 +17,7 @@
ofp.message.flow_add(
xid=0x12345678,
match=ofp.match(
- wildcards=ofp.OFPFW_DL_SRC|ofp.OFPFW_DL_DST,
+ wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
in_port=3,
ipv4_src=0xc0a8037f,
ipv4_dst=0xffffffff,
@@ -33,7 +33,7 @@
flow_add {
xid = 0x12345678,
match = match_v1 {
- wildcards = OFPFW_DL_SRC|OFPFW_DL_DST,
+ wildcards = OFPFW_DL_VLAN|OFPFW_DL_VLAN_PCP,
in_port = 3,
eth_src = 01:23:45:67:89:ab,
eth_dst = cd:ef:01:23:45:67,
@@ -60,3 +60,49 @@
bsn_set_tunnel_dst { dst = 0x0 }
]
}
+-- c
+obj = of_flow_add_new(OF_VERSION_1_0);
+of_flow_add_xid_set(obj, 0x12345678);
+of_flow_add_idle_timeout_set(obj, 5);
+of_flow_add_flags_set(obj, 2);
+{
+ of_match_t match = { OF_VERSION_1_0 };
+ match.fields.in_port = 3;
+ match.fields.eth_src = (of_mac_addr_t) { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } };
+ match.fields.eth_dst = (of_mac_addr_t) { { 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 } };
+ match.fields.ipv4_src = 0xc0a8037f;
+ match.fields.ipv4_dst = 0xffffffff;
+ OF_MATCH_MASK_IN_PORT_EXACT_SET(&match);
+ OF_MATCH_MASK_ETH_SRC_EXACT_SET(&match);
+ OF_MATCH_MASK_ETH_DST_EXACT_SET(&match);
+ //OF_MATCH_MASK_VLAN_VID_EXACT_SET(&match);
+ //OF_MATCH_MASK_VLAN_PCP_EXACT_SET(&match);
+ OF_MATCH_MASK_ETH_TYPE_EXACT_SET(&match);
+ OF_MATCH_MASK_IP_DSCP_EXACT_SET(&match);
+ OF_MATCH_MASK_IP_PROTO_EXACT_SET(&match);
+ OF_MATCH_MASK_IPV4_SRC_EXACT_SET(&match);
+ OF_MATCH_MASK_IPV4_DST_EXACT_SET(&match);
+ OF_MATCH_MASK_TCP_SRC_EXACT_SET(&match);
+ OF_MATCH_MASK_TCP_DST_EXACT_SET(&match);
+ of_flow_add_match_set(obj, &match);
+}
+{
+ of_list_action_t actions;
+ of_flow_add_actions_bind(obj, &actions);
+ {
+ of_action_t action;
+ of_action_output_init(&action.output, OF_VERSION_1_0, -1, 1);
+ of_list_action_append_bind(&actions, &action);
+ of_action_output_port_set(&action.output, OF_PORT_DEST_FLOOD);
+ }
+ {
+ of_action_t action;
+ of_action_nicira_dec_ttl_init(&action.nicira_dec_ttl, OF_VERSION_1_0, -1, 1);
+ of_list_action_append_bind(&actions, &action);
+ }
+ {
+ of_action_t action;
+ of_action_bsn_set_tunnel_dst_init(&action.bsn_set_tunnel_dst, OF_VERSION_1_0, -1, 1);
+ of_list_action_append_bind(&actions, &action);
+ }
+}
diff --git a/test_data/of10/flow_stats_entry.data b/test_data/of10/flow_stats_entry.data
index 45c6569..2f9df64 100644
--- a/test_data/of10/flow_stats_entry.data
+++ b/test_data/of10/flow_stats_entry.data
@@ -40,3 +40,36 @@
actions=[
ofp.action.output(port=1),
ofp.action.output(port=2)])
+-- c
+obj = of_flow_stats_entry_new(OF_VERSION_1_0);
+{
+ of_object_t list;
+ of_flow_stats_entry_actions_bind(obj, &list);
+ {
+ of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(obj, 0);
+ of_action_output_port_set(obj, 1);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(obj, 0);
+ of_action_output_port_set(obj, 2);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+}
+of_flow_stats_entry_byte_count_set(obj, 1000);
+of_flow_stats_entry_cookie_set(obj, 81985529216486895);
+of_flow_stats_entry_duration_nsec_set(obj, 2);
+of_flow_stats_entry_duration_sec_set(obj, 1);
+of_flow_stats_entry_hard_timeout_set(obj, 10);
+of_flow_stats_entry_idle_timeout_set(obj, 5);
+{
+ of_match_t match = { OF_VERSION_1_0 };
+ of_flow_stats_entry_match_set(obj, &match);
+}
+of_flow_stats_entry_packet_count_set(obj, 10);
+of_flow_stats_entry_priority_set(obj, 100);
+of_flow_stats_entry_table_id_set(obj, 3);
diff --git a/test_data/of10/flow_stats_reply.data b/test_data/of10/flow_stats_reply.data
index 38db4d5..185235b 100644
--- a/test_data/of10/flow_stats_reply.data
+++ b/test_data/of10/flow_stats_reply.data
@@ -90,3 +90,93 @@
actions=[ofp.action.output(port=1),
ofp.action.output(port=2),
ofp.action.output(port=3)])])
+-- c
+obj = of_flow_stats_reply_new(OF_VERSION_1_0);
+of_flow_stats_reply_flags_set(obj, 0);
+of_flow_stats_reply_xid_set(obj, 6);
+{
+ of_object_t *entries = of_list_flow_stats_entry_new(OF_VERSION_1_0);
+ {
+ of_object_t *elem = of_flow_stats_entry_new(OF_VERSION_1_0);
+ of_flow_stats_entry_byte_count_set(elem, 1000);
+ of_flow_stats_entry_cookie_set(elem, 81985529216486895);
+ of_flow_stats_entry_duration_nsec_set(elem, 2);
+ of_flow_stats_entry_duration_sec_set(elem, 1);
+ of_flow_stats_entry_hard_timeout_set(elem, 10);
+ of_flow_stats_entry_idle_timeout_set(elem, 5);
+ of_flow_stats_entry_packet_count_set(elem, 10);
+ of_flow_stats_entry_priority_set(elem, 100);
+ of_flow_stats_entry_table_id_set(elem, 3);
+ {
+ of_match_t match = { OF_VERSION_1_0 };
+ of_flow_stats_entry_match_set(elem, &match);
+ }
+ {
+ of_object_t *actions = of_list_action_new(OF_VERSION_1_0);
+ {
+ of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(elem, 0);
+ of_action_output_port_set(elem, 1);
+ of_list_append(actions, elem);
+ of_object_delete(elem);
+ }
+ {
+ of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(elem, 0);
+ of_action_output_port_set(elem, 2);
+ of_list_append(actions, elem);
+ of_object_delete(elem);
+ }
+ of_flow_stats_entry_actions_set(elem, actions);
+ of_object_delete(actions);
+ }
+ of_list_append(entries, elem);
+ of_object_delete(elem);
+ }
+ {
+ of_object_t *elem = of_flow_stats_entry_new(OF_VERSION_1_0);
+ of_flow_stats_entry_byte_count_set(elem, 1000);
+ of_flow_stats_entry_cookie_set(elem, 81985529216486895);
+ of_flow_stats_entry_duration_nsec_set(elem, 2);
+ of_flow_stats_entry_duration_sec_set(elem, 1);
+ of_flow_stats_entry_hard_timeout_set(elem, 10);
+ of_flow_stats_entry_idle_timeout_set(elem, 5);
+ of_flow_stats_entry_packet_count_set(elem, 10);
+ of_flow_stats_entry_priority_set(elem, 100);
+ of_flow_stats_entry_table_id_set(elem, 4);
+ {
+ of_match_t match = { OF_VERSION_1_0 };
+ of_flow_stats_entry_match_set(elem, &match);
+ }
+ {
+ of_object_t *actions = of_list_action_new(OF_VERSION_1_0);
+ {
+ of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(elem, 0);
+ of_action_output_port_set(elem, 1);
+ of_list_append(actions, elem);
+ of_object_delete(elem);
+ }
+ {
+ of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(elem, 0);
+ of_action_output_port_set(elem, 2);
+ of_list_append(actions, elem);
+ of_object_delete(elem);
+ }
+ {
+ of_object_t *elem = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(elem, 0);
+ of_action_output_port_set(elem, 3);
+ of_list_append(actions, elem);
+ of_object_delete(elem);
+ }
+ of_flow_stats_entry_actions_set(elem, actions);
+ of_object_delete(actions);
+ }
+ of_list_append(entries, elem);
+ of_object_delete(elem);
+ }
+ of_flow_stats_reply_entries_set(obj, entries);
+ of_object_delete(entries);
+}
diff --git a/test_data/of10/hello.data b/test_data/of10/hello.data
index 2603365..d29dff9 100644
--- a/test_data/of10/hello.data
+++ b/test_data/of10/hello.data
@@ -4,3 +4,8 @@
12 34 56 78 # xid
-- python
ofp.message.hello(xid=0x12345678)
+-- c
+obj = of_hello_new(OF_VERSION_1_0);
+of_hello_xid_set(obj, 305419896);
+-- java
+builder.setXid(0x12345678)
diff --git a/test_data/of10/packet_in.data b/test_data/of10/packet_in.data
index f8d026b..2cd98b0 100644
--- a/test_data/of10/packet_in.data
+++ b/test_data/of10/packet_in.data
@@ -16,3 +16,22 @@
in_port=ofp.OFPP_LOCAL,
reason=ofp.OFPR_ACTION,
data='abc')
+-- c
+obj = of_packet_in_new(OF_VERSION_1_0);
+of_packet_in_buffer_id_set(obj, 2882400001);
+{
+ of_octets_t data = { .bytes=3, .data=(uint8_t *)"\x61\x62\x63" };
+ of_packet_in_data_set(obj, &data);
+}
+of_packet_in_in_port_set(obj, 65534);
+of_packet_in_reason_set(obj, 1);
+of_packet_in_total_len_set(obj, 9);
+of_packet_in_xid_set(obj, 305419896);
+-- java
+builder
+ .setXid(0x12345678)
+ .setBufferId(0xabcdef01)
+ .setTotalLen(9)
+ .setInPort(OFPort.LOCAL)
+ .setReason(OFPacketInReason.ACTION)
+ .setData(new byte[] { 0x61, 0x62, 0x63 } );
diff --git a/test_data/of10/packet_out.data b/test_data/of10/packet_out.data
index a3892f6..fdd1c3d 100644
--- a/test_data/of10/packet_out.data
+++ b/test_data/of10/packet_out.data
@@ -23,3 +23,31 @@
ofp.action.output(port=1),
ofp.action.output(port=2)],
data='abc')
+-- c
+obj = of_packet_out_new(OF_VERSION_1_0);
+of_packet_out_buffer_id_set(obj, 2882400001);
+of_packet_out_in_port_set(obj, 65534);
+of_packet_out_xid_set(obj, 305419896);
+{
+ of_object_t *list = of_list_action_new(OF_VERSION_1_0);
+ {
+ of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(obj, 0);
+ of_action_output_port_set(obj, 1);
+ of_list_append(list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_action_output_new(OF_VERSION_1_0);
+ of_action_output_max_len_set(obj, 0);
+ of_action_output_port_set(obj, 2);
+ of_list_append(list, obj);
+ of_object_delete(obj);
+ }
+ of_packet_out_actions_set(obj, list);
+ of_object_delete(list);
+}
+{
+ of_octets_t data = { .bytes=3, .data=(uint8_t *)"\x61\x62\x63" };
+ of_packet_out_data_set(obj, &data);
+}
diff --git a/test_data/of10/port_desc.data b/test_data/of10/port_desc.data
index c3c2e38..56242cc 100644
--- a/test_data/of10/port_desc.data
+++ b/test_data/of10/port_desc.data
@@ -19,3 +19,20 @@
advertised=ofp.OFPPF_1GB_FD,
supported=ofp.OFPPF_AUTONEG,
peer=ofp.OFPPF_PAUSE_ASYM)
+-- c
+obj = of_port_desc_new(OF_VERSION_1_0);
+of_port_desc_advertised_set(obj, 32);
+of_port_desc_config_set(obj, 16);
+of_port_desc_curr_set(obj, 1);
+{
+ of_mac_addr_t hw_addr = { { 1, 2, 3, 4, 5, 6 } };
+ of_port_desc_hw_addr_set(obj, hw_addr);
+}
+{
+ of_port_name_t name = "foo";
+ of_port_desc_name_set(obj, name);
+}
+of_port_desc_peer_set(obj, 2048);
+of_port_desc_port_no_set(obj, 65533);
+of_port_desc_state_set(obj, 512);
+of_port_desc_supported_set(obj, 512);
diff --git a/test_data/of10/port_mod.data b/test_data/of10/port_mod.data
index 972a4e8..53e09ce 100644
--- a/test_data/of10/port_mod.data
+++ b/test_data/of10/port_mod.data
@@ -16,3 +16,14 @@
config=0x90ABCDEF,
mask=0xFF11FF11,
advertise=0xCAFE6789)
+-- c
+obj = of_port_mod_new(OF_VERSION_1_0);
+of_port_mod_advertise_set(obj, 3405670281);
+of_port_mod_config_set(obj, 2427178479);
+{
+ of_mac_addr_t hw_addr = { { 1, 2, 3, 4, 5, 6 } };
+ of_port_mod_hw_addr_set(obj, hw_addr);
+}
+of_port_mod_mask_set(obj, 4279369489);
+of_port_mod_port_no_set(obj, 65533);
+of_port_mod_xid_set(obj, 2);
diff --git a/test_data/of10/port_stats_reply.data b/test_data/of10/port_stats_reply.data
index 45a3532..4378387 100644
--- a/test_data/of10/port_stats_reply.data
+++ b/test_data/of10/port_stats_reply.data
@@ -37,3 +37,47 @@
xid=5, flags=0, entries=[
ofp.port_stats_entry(port_no=1, rx_packets=56, collisions=5),
ofp.port_stats_entry(port_no=ofp.OFPP_LOCAL, rx_packets=1, collisions=1)])
+-- c
+obj = of_port_stats_reply_new(OF_VERSION_1_0);
+{
+ of_object_t list;
+ of_port_stats_reply_entries_bind(obj, &list);
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_0);
+ of_port_stats_entry_collisions_set(obj, 5);
+ of_port_stats_entry_port_no_set(obj, 1);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_crc_err_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_rx_frame_err_set(obj, 0);
+ of_port_stats_entry_rx_over_err_set(obj, 0);
+ of_port_stats_entry_rx_packets_set(obj, 56);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 0);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_0);
+ of_port_stats_entry_collisions_set(obj, 1);
+ of_port_stats_entry_port_no_set(obj, 65534);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_crc_err_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_rx_frame_err_set(obj, 0);
+ of_port_stats_entry_rx_over_err_set(obj, 0);
+ of_port_stats_entry_rx_packets_set(obj, 1);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 0);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+}
+of_port_stats_reply_flags_set(obj, 0);
+of_port_stats_reply_xid_set(obj, 5);
diff --git a/test_data/of10/port_status.data b/test_data/of10/port_status.data
index 04da9fd..7589eae 100644
--- a/test_data/of10/port_status.data
+++ b/test_data/of10/port_status.data
@@ -28,3 +28,27 @@
advertised=ofp.OFPPF_1GB_FD,
supported=ofp.OFPPF_AUTONEG,
peer=ofp.OFPPF_PAUSE_ASYM))
+-- c
+obj = of_port_status_new(OF_VERSION_1_0);
+{
+ of_object_t *desc = of_port_desc_new(OF_VERSION_1_0);
+ of_port_desc_advertised_set(desc, 32);
+ of_port_desc_config_set(desc, 16);
+ of_port_desc_curr_set(desc, 1);
+ {
+ of_mac_addr_t hw_addr = { { 1, 2, 3, 4, 5, 6 } };
+ of_port_desc_hw_addr_set(desc, hw_addr);
+ }
+ {
+ of_port_name_t name = "foo";
+ of_port_desc_name_set(desc, name);
+ }
+ of_port_desc_peer_set(desc, 2048);
+ of_port_desc_port_no_set(desc, 65533);
+ of_port_desc_state_set(desc, 512);
+ of_port_desc_supported_set(desc, 512);
+ of_port_status_desc_set(obj, desc);
+ of_object_delete(desc);
+}
+of_port_status_reason_set(obj, 1);
+of_port_status_xid_set(obj, 4);
diff --git a/test_data/of10/queue_get_config_reply.data b/test_data/of10/queue_get_config_reply.data
index 5e3453d..1016cad 100644
--- a/test_data/of10/queue_get_config_reply.data
+++ b/test_data/of10/queue_get_config_reply.data
@@ -35,3 +35,49 @@
ofp.packet_queue(queue_id=2, properties=[
ofp.queue_prop_min_rate(rate=6),
ofp.queue_prop_min_rate(rate=7)])])
+-- c
+obj = of_queue_get_config_reply_new(OF_VERSION_1_0);
+of_queue_get_config_reply_port_set(obj, 65534);
+{
+ of_object_t list;
+ of_queue_get_config_reply_queues_bind(obj, &list);
+ {
+ of_object_t *obj = of_packet_queue_new(OF_VERSION_1_0);
+ {
+ of_object_t list;
+ of_packet_queue_properties_bind(obj, &list);
+ {
+ of_object_t *obj = of_queue_prop_min_rate_new(OF_VERSION_1_0);
+ of_queue_prop_min_rate_rate_set(obj, 5);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ }
+ of_packet_queue_queue_id_set(obj, 1);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_packet_queue_new(OF_VERSION_1_0);
+ {
+ of_object_t list;
+ of_packet_queue_properties_bind(obj, &list);
+ {
+ of_object_t *obj = of_queue_prop_min_rate_new(OF_VERSION_1_0);
+ of_queue_prop_min_rate_rate_set(obj, 6);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_queue_prop_min_rate_new(OF_VERSION_1_0);
+ of_queue_prop_min_rate_rate_set(obj, 7);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ }
+ of_packet_queue_queue_id_set(obj, 2);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+}
+of_queue_get_config_reply_xid_set(obj, 305419896);
diff --git a/test_data/of10/table_stats_entry.data b/test_data/of10/table_stats_entry.data
index 1a99237..017e8ba 100644
--- a/test_data/of10/table_stats_entry.data
+++ b/test_data/of10/table_stats_entry.data
@@ -19,3 +19,15 @@
active_count=2,
lookup_count=1099511627775,
matched_count=9300233470495232273L)
+-- c
+obj = of_table_stats_entry_new(OF_VERSION_1_0);
+of_table_stats_entry_active_count_set(obj, 2);
+of_table_stats_entry_lookup_count_set(obj, 1099511627775ULL);
+of_table_stats_entry_matched_count_set(obj, 9300233470495232273ULL);
+of_table_stats_entry_max_entries_set(obj, 5);
+{
+ of_table_name_t name = "foo";
+ of_table_stats_entry_name_set(obj, name);
+}
+of_table_stats_entry_table_id_set(obj, 3);
+of_table_stats_entry_wildcards_set(obj, 4194303);