Merge remote-tracking branch 'origin/ihplus' into merge-ihplus
diff --git a/Makefile b/Makefile
index 018db0b..5f3d8e5 100644
--- a/Makefile
+++ b/Makefile
@@ -131,6 +131,7 @@
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of11.py
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of12.py
PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of13.py
+ PYTHONPATH=${LOXI_OUTPUT_DIR}/pyloxi:. python py_gen/tests/of14.py
check-c: c
make -j4 -C ${LOXI_OUTPUT_DIR}/locitest
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index 047b254..ace386d 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -119,135 +119,6 @@
if not m_name in of_g.ordered_members[cls]:
of_g.ordered_members[cls].append(m_name)
-def update_offset(cls, wire_version, name, offset, m_type):
- """
- Update (and return) the offset based on type.
- @param cls The parent class
- @param wire_version The wire version being processed
- @param name The name of the data member
- @param offset The current offset
- @param m_type The type declaration being processed
- @returns A pair (next_offset, len_update) next_offset is the new offset
- of the next object or -1 if this is a var-length object. len_update
- is the increment that should be added to the length. Note that (for
- of_match_v3) it is variable length, but it adds 8 bytes to the fixed
- length of the object
- If offset is already -1, do not update
- Otherwise map to base type and count and update (if possible)
- """
- if offset < 0: # Don't update offset once set to -1
- return offset, 0
-
- count, base_type = loxi_utils.type_dec_to_count_base(m_type)
-
- len_update = 0
- if base_type in of_g.of_mixed_types:
- base_type = of_g.of_mixed_types[base_type][wire_version]
-
- base_class = base_type[:-2]
- if (base_class, wire_version) in of_g.is_fixed_length:
- bytes = of_g.base_length[(base_class, wire_version)]
- else:
- if base_type == "of_match_v3_t":
- # This is a special case: it has non-zero min length
- # but is variable length
- bytes = -1
- len_update = 8
- elif base_type == "of_oxm_header_t":
- # This is a special case: it has non-zero min length
- # but is variable length
- bytes = -1
- len_update = 4
- elif base_type == "of_bsn_vport_header_t":
- # This is a special case: it has non-zero min length
- # but is variable length
- bytes = -1
- len_update = 4
- elif base_type in of_g.of_base_types:
- bytes = of_g.of_base_types[base_type]["bytes"]
- else:
- print "UNKNOWN TYPE for %s %s: %s" % (cls, name, base_type)
- log("UNKNOWN TYPE for %s %s: %s" % (cls, name, base_type))
- bytes = -1
-
- # If bytes
- if bytes > 0:
- len_update = count * bytes
-
- if bytes == -1:
- return -1, len_update
-
- return offset + (count * bytes), len_update
-
-def calculate_offsets_and_lengths(ordered_classes, classes, wire_version):
- """
- Generate the offsets for fixed offset class members
- Also calculate the class_sizes when possible.
-
- @param classes The classes to process
- @param wire_version The wire version for this set of classes
-
- Updates global variables
- """
-
- lists = set()
-
- # Generate offsets
- for cls in ordered_classes:
- fixed_offset = 0 # The last "good" offset seen
- offset = 0
- last_offset = 0
- last_name = "-"
- for member in classes[cls]:
- m_type = member["m_type"]
- name = member["name"]
- if last_offset == -1:
- if name == "pad":
- log("Skipping pad for special offset for %s" % cls)
- else:
- log("SPECIAL OFS: Member %s (prev %s), class %s ver %d" %
- (name, last_name, cls, wire_version))
- if (((cls, name) in of_g.special_offsets) and
- (of_g.special_offsets[(cls, name)] != last_name)):
- debug("ERROR: special offset prev name changed")
- debug(" cls %s. name %s. version %d. was %s. now %s" %
- cls, name, wire_version,
- of_g.special_offsets[(cls, name)], last_name)
- sys.exit(1)
- of_g.special_offsets[(cls, name)] = last_name
-
- member["offset"] = offset
- if m_type.find("list(") == 0:
- (list_name, base_type) = loxi_utils.list_name_extract(m_type)
- lists.add(list_name)
- member["m_type"] = list_name + "_t"
- offset = -1
- elif m_type.find("struct") == 0:
- debug("ERROR found struct: %s.%s " % (cls, name))
- sys.exit(1)
- elif m_type == "octets":
- log("offset gen skipping octets: %s.%s " % (cls, name))
- offset = -1
- else:
- offset, len_update = update_offset(cls, wire_version, name,
- offset, m_type)
- if offset != -1:
- fixed_offset = offset
- else:
- fixed_offset += len_update
- log("offset is -1 for %s.%s version %d " %
- (cls, name, wire_version))
- last_offset = offset
- last_name = name
- of_g.base_length[(cls, wire_version)] = fixed_offset
- if (offset != -1):
- of_g.is_fixed_length.add((cls, wire_version))
-
- for list_type in lists:
- classes[list_type] = []
- of_g.ordered_classes[wire_version].append(list_type)
- of_g.base_length[(list_type, wire_version)] = 0
-
def order_and_assign_object_ids():
"""
Order all classes and assign object ids to all classes.
@@ -329,27 +200,30 @@
pad_count = 0
for m in ofclass.members:
if type(m) == OFPadMember:
- m_name = 'pad%d' % pad_count
- if m_name == 'pad0': m_name = 'pad'
- legacy_members.append(dict(m_type='uint8_t[%d]' % m.length,
- name=m_name))
- pad_count += 1
+ continue
else:
- # HACK the C backend does not yet support of_oxm_t
- if m.oftype == 'of_oxm_t':
- m_type = 'of_oxm_header_t'
- # HACK the C backend does not yet support of_bsn_vport_t
- elif m.oftype == 'of_bsn_vport_t':
- m_type = 'of_bsn_vport_header_t'
+ if m.oftype.find("list(") == 0:
+ (list_name, base_type) = loxi_utils.list_name_extract(m.oftype)
+ m_type = list_name + "_t"
else:
enum = find(lambda e: e.name == m.oftype, protocol.enums)
if enum and "wire_type" in enum.params:
m_type = enum.params["wire_type"]
else:
m_type = m.oftype
- legacy_members.append(dict(m_type=m_type, name=m.name))
+
+ if m.offset is None:
+ m_offset = -1
+ else:
+ m_offset = m.offset
+
+ legacy_members.append(dict(m_type=m_type, name=m.name, offset=m_offset))
versions[version_name]['classes'][ofclass.name] = legacy_members
+ of_g.base_length[(ofclass.name, version.wire_version)] = ofclass.base_length
+ if ofclass.is_fixed_length:
+ of_g.is_fixed_length.add((ofclass.name, version.wire_version))
+
for enum in protocol.enums:
for entry in enum.entries:
identifiers.add_identifier(
@@ -368,22 +242,38 @@
Add information computed from the input, including offsets and
lengths of struct members and the set of list and action_id types.
"""
+ # Create lists
+ for version, protocol in loxi_globals.ir.items():
+ lists = set()
+ classes = versions[of_g.of_version_wire2name[version.wire_version]]['classes']
- # Generate header classes for inheritance parents
- for wire_version, ordered_classes in of_g.ordered_classes.items():
- classes = versions[of_g.of_version_wire2name[wire_version]]['classes']
- for cls in ordered_classes:
- if type_maps.class_is_inheritance_root(cls):
- new_cls = cls + '_header'
- of_g.ordered_classes[wire_version].append(new_cls)
- classes[new_cls] = classes[cls]
+ for ofclass in protocol.classes:
+ for m in ofclass.members:
+ if isinstance(m, OFDataMember) and m.oftype.find("list(") == 0:
+ (list_name, base_type) = loxi_utils.list_name_extract(m.oftype)
+ lists.add(list_name)
- for wire_version in of_g.wire_ver_map.keys():
- version_name = of_g.of_version_wire2name[wire_version]
- calculate_offsets_and_lengths(
- of_g.ordered_classes[wire_version],
- versions[version_name]['classes'],
- wire_version)
+ for list_type in lists:
+ classes[list_type] = []
+ of_g.ordered_classes[version.wire_version].append(list_type)
+ of_g.base_length[(list_type, version.wire_version)] = 0
+
+ # Find special offsets
+ # These are defined as members (except padding) that don't have a fixed
+ # offset. The special_offsets map stores the name of the previous member.
+ for version, protocol in loxi_globals.ir.items():
+ for ofclass in protocol.classes:
+ prev_member = None
+ for m in ofclass.members:
+ if isinstance(m, OFPadMember):
+ continue
+ if m.offset == None:
+ old = of_g.special_offsets.get((ofclass.name, m.name))
+ if old and old != prev_member.name:
+ raise Exception("Error: special offset changed: version=%s cls=%s member=%s old=%s new=%s" %
+ (version, ofclass.name, m.name, old, prev_member.name))
+ of_g.special_offsets[(ofclass.name, m.name)] = prev_member.name
+ prev_member = m
def unify_input():
"""
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index 3229403..968d939 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -403,7 +403,6 @@
int of_object_wire_init(of_object_t *obj, of_object_id_t base_object_id, int max_len);
extern const int *const of_object_fixed_len[OF_VERSION_ARRAY_MAX];
-extern const int *const of_object_extra_len[OF_VERSION_ARRAY_MAX];
""")
c_type_maps.gen_type_data_header(out)
c_match.gen_declarations(out)
@@ -530,7 +529,7 @@
/**
* Check if a version is supported
*/
-#define OF_VERSION_OKAY(v) ((v) >= OF_VERSION_1_0 && (v) <= OF_VERSION_1_3)
+#define OF_VERSION_OKAY(v) ((v) >= OF_VERSION_1_0 && (v) <= OF_VERSION_1_4)
""")
gen_version_enum(out)
@@ -725,24 +724,6 @@
#define U64_HTON(val) U64_NTOH(val)
#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
#endif
-
-/****************************************************************
- *
- * The following are internal definitions used by the automatically
- * generated code. Users should not reference these definitions
- * as they may change between versions of this code
- *
- ****************************************************************/
-
-#define OF_MESSAGE_IN_MATCH_POINTER(obj) \\
- (WIRE_BUF_POINTER(&((obj)->wire_buffer), OF_MESSAGE_IN_MATCH_OFFSET))
-#define OF_MESSAGE_IN_MATCH_LEN(ptr) BUF_U16_GET(&ptr[2])
-#define OF_MESSAGE_IN_DATA_OFFSET(obj) \\
- (FIXED_LEN + OF_MESSAGE_IN_MATCH_LEN(OF_MESSAGE_IN_MATCH_POINTER(obj)) + 2)
-
-#define OF_MESSAGE_OUT_DATA_OFFSET(obj) \\
- (FIXED_LEN + of_message_out_actions_len_get(obj))
-
""")
def external_h_top_matter(out, name):
@@ -772,7 +753,6 @@
* Per-class static delete functions
* Per-class, per-member accessor declarations
* Per-class structure definitions
- * Generic union (inheritance) definitions
* Pointer set function declarations
* Some special case macros
*
@@ -985,38 +965,14 @@
#
################################################################
-def gen_generics(out):
- for (cls, subclasses) in type_maps.inheritance_map.items():
- out.write("""
-/**
- * Inheritance super class for %(cls)s
- *
- * This class is the union of %(cls)s classes. You can refer
- * to it untyped by refering to the member 'header' whose structure
- * is common across all sub-classes.
- */
-
-union %(cls)s_u {
- %(cls)s_header_t header; /* Generic instance */
-""" % dict(cls=cls))
- for subcls in sorted(subclasses):
- instance = loxi_utils.class_to_instance(subcls, cls)
- out.write(" %s_%s_t %s;\n" % (cls, instance, instance))
- out.write("};\n")
-
def gen_struct_typedefs(out):
"""
Generate typedefs for all struct objects
@param out The file for output, already open
"""
- out.write("\n/* LOCI inheritance parent typedefs */\n")
- for cls in type_maps.inheritance_map:
- out.write("typedef union %(cls)s_u %(cls)s_t;\n" % dict(cls=cls))
out.write("\n/* LOCI object typedefs */\n")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
- continue
template = "typedef of_object_t %(cls)s_t;\n"
out.write(template % dict(cls=cls))
@@ -1055,7 +1011,7 @@
****************************************************************/
""")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls) and not loxi_utils.class_is_list(cls):
continue
out.write("\n/* Unified accessor functions for %s */\n" % cls)
for m_name in of_g.ordered_members[cls]:
@@ -1095,13 +1051,13 @@
e_type = loxi_utils.list_to_entry_type(cls)
out.write("""
extern int %(cls)s_first(
- %(cls)s_t *list, %(e_type)s_t *obj);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_next(
- %(cls)s_t *list, %(e_type)s_t *obj);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append_bind(
- %(cls)s_t *list, %(e_type)s_t *obj);
+ %(cls)s_t *list, of_object_t *iter);
extern int %(cls)s_append(
- %(cls)s_t *list, %(e_type)s_t *obj);
+ %(cls)s_t *list, of_object_t *iter);
/**
* Iteration macro for list of type %(cls)s
@@ -1243,7 +1199,7 @@
LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
""" % dict(m_name=m_name))
- elif m_type == "of_oxm_header_t":
+ elif m_type == "of_oxm_t":
out.write("""
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
@@ -1251,7 +1207,7 @@
of_object_attach(obj, %(m_name)s, offset, cur_len);
of_object_wire_init(%(m_name)s, OF_OXM, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
- elif m_type == "of_bsn_vport_header_t":
+ elif m_type == "of_bsn_vport_t":
out.write("""
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
@@ -1575,10 +1531,6 @@
@param cls The class name for the function
@param out The file to which to write
"""
- if type_maps.class_is_inheritance_root(cls):
- param = "obj_p"
- else:
- param = "obj"
out.write("""
/**
@@ -1599,33 +1551,20 @@
*/
void
-%(cls)s_init(%(cls)s_t *%(param)s,
+%(cls)s_init(of_object_t *obj,
of_version_t version, int bytes, int clean_wire)
{
-""" % dict(cls=cls, param=param))
-
- # Use an extra pointer to deal with inheritance classes
- if type_maps.class_is_inheritance_root(cls):
- out.write("""\
- %s_header_t *obj;
-
- obj = &obj_p->header; /* Need instantiable subclass */
-""" % cls)
-
- out.write("""
LOCI_ASSERT(of_object_fixed_len[version][%(enum)s] >= 0);
if (clean_wire) {
MEMSET(obj, 0, sizeof(*obj));
}
if (bytes < 0) {
- bytes = of_object_fixed_len[version][%(enum)s] + of_object_extra_len[version][%(enum)s];
+ bytes = of_object_fixed_len[version][%(enum)s];
}
obj->version = version;
obj->length = bytes;
obj->object_id = %(enum)s;
-""" % dict(cls=cls, enum=enum_name(cls)))
- out.write("""
/* Grow the wire buffer */
if (obj->wbuf != NULL) {
int tot_bytes;
@@ -1634,66 +1573,7 @@
of_wire_buffer_grow(obj->wbuf, tot_bytes);
}
}
-
-""")
-
-## @fixme This should also be updated once there is a map from
-# class instance to wire length/type accessors
-def gen_wire_push_fn(cls, out):
- """
- Generate the calls to push values into the wire buffer
- """
- if type_maps.class_is_virtual(cls):
- print "Push fn gen called for virtual class " + cls
- return
-
- out.write("""
-/**
- * Helper function to push values into the wire buffer
- */
-static inline int
-%(cls)s_push_wire_values(%(cls)s_t *obj)
-{
-""" % dict(cls=cls))
-
- import loxi_globals
- uclass = loxi_globals.unified.class_by_name(cls)
- if uclass and not uclass.virtual and uclass.has_type_members:
- out.write("""
- %(cls)s_push_wire_types(obj);
-""" % dict(cls=cls))
-
- if loxi_utils.class_is_message(cls):
- out.write("""
- /* Message obj; set length */
- of_message_t msg;
-
- if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
- of_message_length_set(msg, obj->length);
- }
-""" % dict(name = enum_name(cls)))
-
- else: # Not a message
- if loxi_utils.class_is_tlv16(cls):
- out.write("""
- /* TLV obj; set length */
- of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
-""" % dict(enum=enum_name(cls)))
-
- if loxi_utils.class_is_u16_len(cls) or cls == "of_packet_queue":
- out.write("""
- of_object_wire_length_set((of_object_t *)obj, obj->length);
-""")
-
- if cls == "of_meter_stats":
- out.write("""
- of_meter_stats_wire_length_set((of_object_t *)obj, obj->length);
-""" % dict(enum=enum_name(cls)))
-
- out.write("""
- return OF_ERROR_NONE;
-}
-""")
+""" % dict(cls=cls, enum=enum_name(cls)))
def gen_new_fn_body(cls, out):
"""
@@ -1708,9 +1588,6 @@
*/
""" % dict(cls=cls))
- if not type_maps.class_is_virtual(cls):
- gen_wire_push_fn(cls, out)
-
uclass = loxi_globals.unified.class_by_name(cls)
is_fixed_length = uclass and uclass.is_fixed_length
max_length = is_fixed_length and "bytes" or "OF_WIRE_BUFFER_MAX_LENGTH"
@@ -1728,35 +1605,40 @@
* \\ingroup %(cls)s
*/
-%(cls)s_t *
+of_object_t *
%(cls)s_new(of_version_t version)
{
- %(cls)s_t *obj;
+ of_object_t *obj;
int bytes;
- bytes = of_object_fixed_len[version][%(enum)s] + of_object_extra_len[version][%(enum)s];
+ bytes = of_object_fixed_len[version][%(enum)s];
- if ((obj = (%(cls)s_t *)of_object_new(%(max_length)s)) == NULL) {
+ if ((obj = of_object_new(%(max_length)s)) == NULL) {
return NULL;
}
%(cls)s_init(obj, version, bytes, 0);
""" % dict(cls=cls, enum=enum_name(cls), max_length=max_length))
if not type_maps.class_is_virtual(cls):
- out.write("""
- if (%(cls)s_push_wire_values(obj) < 0) {
- FREE(obj);
- return NULL;
- }
-""" % dict(cls=cls))
+ from codegen import class_metadata_dict
+ metadata = class_metadata_dict[cls]
+
+ if metadata.wire_type_set != 'NULL':
+ out.write("""\
+ %s(obj);
+""" % metadata.wire_type_set)
+
+ if metadata.wire_length_set != 'NULL':
+ out.write("""\
+ %s(obj, obj->length);
+""" % metadata.wire_length_set)
match_offset = v3_match_offset_get(cls)
if match_offset >= 0:
# Init length field for match object
out.write("""
/* Initialize match TLV for 1.2 */
- /* FIXME: Check 1.3 below */
- if ((version == OF_VERSION_1_2) || (version == OF_VERSION_1_3)) {
+ if ((version >= OF_VERSION_1_2)) {
of_object_u16_set((of_object_t *)obj, %(match_offset)d + 2, 4);
}
""" % dict(match_offset=match_offset))
@@ -1792,11 +1674,11 @@
for cls in of_g.standard_class_order:
out.write("""
-extern %(cls)s_t *
+extern of_object_t *
%(cls)s_new(of_version_t version);
""" % dict(cls=cls))
out.write("""extern void %(cls)s_init(
- %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
+ of_object_t *obj, of_version_t version, int bytes, int clean_wire);
""" % dict(cls=cls))
out.write("""
@@ -1808,8 +1690,6 @@
****************************************************************/
""")
for cls in of_g.standard_class_order:
-# if type_maps.class_is_inheritance_root(cls):
-# continue
out.write("""
/**
* Delete an object of type %(cls)s_t
@@ -1818,8 +1698,8 @@
* \ingroup %(cls)s
*/
static inline void
-%(cls)s_delete(%(cls)s_t *obj) {
- of_object_delete((of_object_t *)(obj));
+%(cls)s_delete(of_object_t *obj) {
+ of_object_delete(obj);
}
""" % dict(cls=cls))
@@ -1867,8 +1747,8 @@
out.write("/* DOCUMENTATION ONLY */\n")
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
- pass # Check this
+ if type_maps.class_is_virtual(cls):
+ pass
out.write("""
/**
diff --git a/c_gen/c_dump_gen.py b/c_gen/c_dump_gen.py
index 2f41c35..799dc09 100644
--- a/c_gen/c_dump_gen.py
+++ b/c_gen/c_dump_gen.py
@@ -90,10 +90,10 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""\
-int %(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
+int %(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, of_object_t *obj);
""" % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
out.write("""
@@ -129,11 +129,11 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""
int
-%(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
+%(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, of_object_t *obj)
{
int out = 0;
""" % dict(cls=cls, ver_name=ver_name))
@@ -150,7 +150,7 @@
""" % dict(m_type=m_type, v_name=var_name_map(m_type)))
if loxi_utils.class_is_list(m_type):
base_type = loxi_utils.list_to_entry_type(m_type)
- out.write(" %s elt;\n int rv;\n" % base_type)
+ out.write(" of_object_t elt;\n int rv;\n")
out.write("""
out += writer(cookie, "Object of type %(cls)s\\n");
""" % dict(cls=cls))
@@ -184,7 +184,7 @@
sub_cls = m_type[:-2] # Trim _t
out.write("""
%(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
- out += %(sub_cls)s_%(ver_name)s_dump(writer, cookie, &%(v_name)s);
+ out += of_object_dump(writer, cookie, &%(v_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name,
v_name=var_name_map(m_type), ver_name=ver_name))
@@ -234,7 +234,7 @@
comma = ","
if (not loxi_utils.class_in_version(cls, version) or
- type_maps.class_is_inheritance_root(cls)):
+ type_maps.class_is_virtual(cls)):
out.write(" unknown_dump%s\n" % comma);
else:
out.write(" %s_%s_dump%s\n" %
@@ -242,20 +242,20 @@
out.write("};\n\n")
out.write("""
-static const loci_obj_dump_f *const dump_funs[5] = {
- NULL,
- dump_funs_v1,
- dump_funs_v2,
- dump_funs_v3,
- dump_funs_v4
+static const loci_obj_dump_f *const dump_funs[] = {
+""")
+
+ for version in of_g.of_version_range:
+ out.write(" [%(v)d] = dump_funs_v%(v)d,\n" % dict(v=version))
+
+ out.write("""\
};
int
of_object_dump(loci_writer_f writer, void* cookie, of_object_t *obj)
{
if ((obj->object_id > 0) && (obj->object_id < OF_OBJECT_COUNT)) {
- if (((obj)->version > 0) && ((obj)->version <= OF_VERSION_1_3)) {
- /* @fixme VERSION */
+ if (OF_VERSION_OKAY(obj->version)) {
return dump_funs[obj->version][obj->object_id](writer, cookie, (of_object_t *)obj);
} else {
return writer(cookie, "Bad version %d\\n", obj->version);
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index 3afc99c..a703e4f 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -104,6 +104,13 @@
#define of_match_v4_to_match of_match_v3_to_match
#define of_match_to_wire_match_v4 of_match_to_wire_match_v3
#define of_match_v4_delete of_match_v3_delete
+
+#define of_match_v5_t of_match_v3_t
+#define of_match_v5_init of_match_v3_init
+#define of_match_v5_new of_match_v3_new
+#define of_match_v5_to_match of_match_v3_to_match
+#define of_match_to_wire_match_v5 of_match_to_wire_match_v3
+#define of_match_v5_delete of_match_v3_delete
""")
def gen_match_macros(out):
@@ -451,7 +458,7 @@
static int
populate_oxm_list(of_match_t *src, of_list_oxm_t *oxm_list)
{
- of_oxm_t oxm_entry;
+ of_object_t elt;
/* For each active member, add an OXM entry to the list */
""")
@@ -459,23 +466,18 @@
out.write("""\
if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
if (!OF_MATCH_MASK_%(ku)s_EXACT_TEST(src)) {
- of_oxm_%(key)s_masked_t *elt;
- elt = &oxm_entry.%(key)s_masked;
-
- of_oxm_%(key)s_masked_init(elt,
+ of_oxm_%(key)s_masked_init(&elt,
oxm_list->version, -1, 1);
- of_list_oxm_append_bind(oxm_list, &oxm_entry);
- of_oxm_%(key)s_masked_value_set(elt,
+ of_list_oxm_append_bind(oxm_list, &elt);
+ of_oxm_%(key)s_masked_value_set(&elt,
src->fields.%(key)s);
- of_oxm_%(key)s_masked_value_mask_set(elt,
+ of_oxm_%(key)s_masked_value_mask_set(&elt,
src->masks.%(key)s);
} else { /* Active, but not masked */
- of_oxm_%(key)s_t *elt;
- elt = &oxm_entry.%(key)s;
- of_oxm_%(key)s_init(elt,
+ of_oxm_%(key)s_init(&elt,
oxm_list->version, -1, 1);
- of_list_oxm_append_bind(oxm_list, &oxm_entry);
- of_oxm_%(key)s_value_set(elt, src->fields.%(key)s);
+ of_list_oxm_append_bind(oxm_list, &elt);
+ of_oxm_%(key)s_value_set(&elt, src->fields.%(key)s);
}
}
""" % dict(key=key, ku=key.upper()))
@@ -622,7 +624,7 @@
{
int rv;
of_list_oxm_t oxm_list;
- of_oxm_t oxm_entry;
+ of_object_t oxm_entry;
""")
# for key in match.of_match_members:
# out.write(" of_oxm_%s_t *%s;\n" % (key, key))
@@ -636,23 +638,23 @@
rv = of_list_oxm_first(&oxm_list, &oxm_entry);
while (rv == OF_ERROR_NONE) {
- switch (oxm_entry.header.object_id) { /* What kind of entry is this */
+ switch (oxm_entry.object_id) { /* What kind of entry is this */
""")
for key in match.of_match_members:
out.write("""
case OF_OXM_%(ku)s_MASKED:
of_oxm_%(key)s_masked_value_mask_get(
- &oxm_entry.%(key)s_masked,
+ &oxm_entry,
&dst->masks.%(key)s);
of_oxm_%(key)s_masked_value_get(
- &oxm_entry.%(key)s,
+ &oxm_entry,
&dst->fields.%(key)s);
of_memmask(&dst->fields.%(key)s, &dst->masks.%(key)s, sizeof(&dst->fields.%(key)s));
break;
case OF_OXM_%(ku)s:
OF_MATCH_MASK_%(ku)s_EXACT_SET(dst);
of_oxm_%(key)s_value_get(
- &oxm_entry.%(key)s,
+ &oxm_entry,
&dst->fields.%(key)s);
break;
""" % (dict(ku=key.upper(), key=key)))
diff --git a/c_gen/c_show_gen.py b/c_gen/c_show_gen.py
index f4d7945..d1cbbdb 100644
--- a/c_gen/c_show_gen.py
+++ b/c_gen/c_show_gen.py
@@ -89,7 +89,6 @@
('uint64_t', 'generation_id'),
('uint16_t', 'value_mask'),
('uint32_t', 'value_mask'),
- ('uint32_t', 'oxm_header'),
('uint8_t', 'value_mask'),
('uint64_t', 'value_mask'),
('uint64_t', 'write_setfields'),
@@ -104,6 +103,7 @@
('uint32_t', 'flow_removed_mask_slave'),
('uint32_t', 'band_types'),
('uint16_t', 'bsn_tcp_flags'),
+ ('uint8_t', 'bsn_l2_cache_hit'),
])
def gen_emitter(cls, m_name, m_type):
@@ -163,10 +163,10 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""\
-int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
+int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, of_object_t *obj);
""" % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
out.write("""
@@ -202,11 +202,11 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
out.write("""
int
-%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
+%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, of_object_t *obj)
{
int out = 0;
""" % dict(cls=cls, ver_name=ver_name))
@@ -222,8 +222,7 @@
%(m_type)s %(v_name)s;
""" % dict(m_type=m_type, v_name=var_name_map(m_type)))
if loxi_utils.class_is_list(m_type):
- base_type = loxi_utils.list_to_entry_type(m_type)
- out.write(" %s elt;\n int rv;\n" % base_type)
+ out.write(" of_object_t elt;\n int rv;\n")
for member in members:
m_type = member["m_type"]
m_name = member["name"]
@@ -255,7 +254,7 @@
sub_cls = m_type[:-2] # Trim _t
out.write("""
%(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
- out += %(sub_cls)s_%(ver_name)s_show(writer, cookie, &%(v_name)s);
+ out += of_object_show(writer, cookie, &%(v_name)s);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name,
v_name=var_name_map(m_type), ver_name=ver_name))
@@ -303,7 +302,7 @@
comma = ","
if (not loxi_utils.class_in_version(cls, version) or
- type_maps.class_is_inheritance_root(cls)):
+ type_maps.class_is_virtual(cls)):
out.write(" unknown_show%s\n" % comma);
else:
out.write(" %s_%s_show%s\n" %
@@ -311,20 +310,20 @@
out.write("};\n\n")
out.write("""
-static const loci_obj_show_f *const show_funs[5] = {
- NULL,
- show_funs_v1,
- show_funs_v2,
- show_funs_v3,
- show_funs_v4
+static const loci_obj_show_f *const show_funs[] = {
+""")
+
+ for version in of_g.of_version_range:
+ out.write(" [%(v)d] = show_funs_v%(v)d,\n" % dict(v=version))
+
+ out.write("""\
};
int
of_object_show(loci_writer_f writer, void* cookie, of_object_t *obj)
{
if ((obj->object_id > 0) && (obj->object_id < OF_OBJECT_COUNT)) {
- if (((obj)->version > 0) && ((obj)->version <= OF_VERSION_1_2)) {
- /* @fixme VERSION */
+ if (OF_VERSION_OKAY(obj->version)) {
return show_funs[obj->version][obj->object_id](writer, cookie, (of_object_t *)obj);
} else {
return writer(cookie, "Bad version %d\\n", obj->version);
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 41fe122..109ab9b 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -99,8 +99,9 @@
of_octets_t="octets",
of_meter_features_t="features",
of_match_t="match",
- of_oxm_header_t="oxm",
- of_bsn_vport_header_t="bsn_vport",
+ of_oxm_t="oxm",
+ of_bsn_vport_t="bsn_vport",
+ of_table_desc_t="table_desc",
# BSN extensions
of_bsn_vport_q_in_q_t="vport",
of_bitmap_128_t="bitmap_128",
@@ -127,8 +128,8 @@
# When embedding an object inside of another object we have to pick a single
# subclass to use, unlike lists where we use all subclasses.
embedded_subclasses = {
- 'of_oxm_header_t': 'of_oxm_eth_type',
- 'of_bsn_vport_header_t': 'of_bsn_vport_q_in_q',
+ 'of_oxm_t': 'of_oxm_eth_type',
+ 'of_bsn_vport_t': 'of_bsn_vport_q_in_q',
}
def ignore_member(cls, version, m_name, m_type):
@@ -379,7 +380,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls) and not loxi_utils.class_is_list(cls):
continue
out.write("""
extern int %(cls)s_%(v_name)s_populate(
@@ -514,7 +515,7 @@
*/
""" % v_name)
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if version in of_g.unified[cls]:
message_scalar_test(out, version, cls)
@@ -527,7 +528,7 @@
for version in of_g.of_version_range:
v_name = loxi_utils.version_to_name(version)
for cls in of_g.standard_class_order:
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if version in of_g.unified[cls]:
test_name = "%s_%s" % (cls, v_name)
@@ -541,7 +542,7 @@
"""
members, member_types = scalar_member_types_get(cls, version)
- length = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
+ length = of_g.base_length[(cls, version)]
v_name = loxi_utils.version_to_name(version)
out.write("""
@@ -700,6 +701,8 @@
"""
for version in of_g.of_version_range:
for cls in of_g.standard_class_order:
+ if type_maps.class_is_virtual(cls):
+ continue
(members, member_types) = scalar_member_types_get(cls, version)
scalar_funs_instance(out, cls, version, members, member_types)
@@ -709,8 +712,7 @@
base_type = loxi_utils.list_to_entry_type(cls)
setup_template = """
%(subcls)s_init(%(inst)s, %(v_name)s, -1, 1);
- %(cls)s_append_bind(list,
- (%(base_type)s_t *)%(inst)s);
+ %(cls)s_append_bind(list, %(inst)s);
value = %(subcls)s_%(v_name)s_populate(
%(inst)s, value);
cur_len += %(inst)s->length;
@@ -771,15 +773,17 @@
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
base_type = loxi_utils.list_to_entry_type(cls)
out.write("""
- %(base_type)s_t elt;
+ of_object_t elt;
int cur_len = 0;
+ (void) elt;
+ (void) cur_len;
""" % dict(cls=cls, base_type=base_type))
sub_classes = type_maps.sub_class_map(base_type, version)
sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
v_name = loxi_utils.version_to_name(version)
- if len(sub_classes) == 0:
+ if not type_maps.class_is_virtual(base_type):
out.write(" /* No subclasses for %s */\n"% base_type)
out.write(" %s_t *elt_p;\n" % base_type)
out.write("\n elt_p = &elt;\n")
@@ -789,9 +793,9 @@
out.write(" %s_t *%s;\n" % (subcls, instance))
out.write("\n /* Instantiate pointers for each subclass */\n")
for instance, subcls in sub_classes:
- out.write(" %s = &elt.%s;\n" % (instance, instance))
+ out.write(" %s = &elt;\n" % (instance))
- if len(sub_classes) == 0: # No inheritance case
+ if not type_maps.class_is_virtual(base_type): # No inheritance case
setup_instance(out, cls, base_type, "elt_p", v_name, version)
else:
for instance, subcls in sub_classes:
@@ -818,14 +822,15 @@
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
base_type = loxi_utils.list_to_entry_type(cls)
out.write("""
- %(base_type)s_t elt;
+ of_object_t elt;
+ (void) elt;
""" % dict(cls=cls, base_type=base_type))
sub_classes = type_maps.sub_class_map(base_type, version)
sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
v_name = loxi_utils.version_to_name(version)
- if len(sub_classes) == 0:
+ if not type_maps.class_is_virtual(base_type):
out.write(" /* No subclasses for %s */\n"% base_type)
out.write(" %s_t *elt_p;\n" % base_type)
out.write("\n elt_p = &elt;\n")
@@ -835,10 +840,12 @@
out.write(" %s_t *%s;\n" % (subcls, instance))
out.write("\n /* Instantiate pointers for each subclass */\n")
for instance, subcls in sub_classes:
- out.write(" %s = &elt.%s;\n" % (instance, instance))
+ out.write(" %s = &elt;\n" % (instance))
- out.write(" TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
- if len(sub_classes) == 0: # No inheritance case
+ if not type_maps.class_is_virtual(base_type) or sub_classes:
+ out.write(" TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
+
+ if not type_maps.class_is_virtual(base_type): # No inheritance case
check_instance(out, cls, base_type, "elt_p", v_name, version, True)
else:
count = 0
@@ -963,10 +970,12 @@
static int
test_match_1(void)
{
- of_match_v1_t *m_v1;
- of_match_v2_t *m_v2;
- of_match_v3_t *m_v3;
- of_match_v4_t *m_v4;
+""")
+
+ for version in of_g.of_version_range:
+ out.write(" of_match_v%(v)d_t *m_v%(v)d;\n" % dict(v=version))
+
+ out.write("""\
of_match_t match;
int value = 1;
int idx;
@@ -1001,10 +1010,12 @@
static int
test_match_2(void)
{
- of_match_v1_t *m_v1;
- of_match_v2_t *m_v2;
- of_match_v3_t *m_v3;
- of_match_v3_t *m_v4;
+""")
+
+ for version in of_g.of_version_range:
+ out.write(" of_match_v%(v)d_t *m_v%(v)d;\n" % dict(v=version))
+
+ out.write("""\
of_match_t match1;
of_match_t match2;
int value = 1;
@@ -1088,7 +1099,7 @@
continue
if type_maps.class_is_virtual(cls):
continue
- bytes = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
+ bytes = of_g.base_length[(cls, version)]
out.write("""
static int
test_%(cls)s_create_%(v_name)s(void)
@@ -1171,15 +1182,17 @@
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
base_type = loxi_utils.list_to_entry_type(cls)
out.write("""
- %(base_type)s_t elt;
+ of_object_t elt;
int cur_len = 0;
+ (void) elt;
+ (void) cur_len;
""" % dict(cls=cls, base_type=base_type))
sub_classes = type_maps.sub_class_map(base_type, version)
sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
v_name = loxi_utils.version_to_name(version)
- if len(sub_classes) == 0:
+ if not type_maps.class_is_virtual(base_type):
out.write(" /* No subclasses for %s */\n"% base_type)
out.write(" %s_t *elt_p;\n" % base_type)
out.write("\n elt_p = &elt;\n")
@@ -1189,9 +1202,9 @@
out.write(" %s_t *%s;\n" % (subcls, instance))
out.write("\n /* Instantiate pointers for each subclass */\n")
for instance, subcls in sub_classes:
- out.write(" %s = &elt.%s;\n" % (instance, instance))
+ out.write(" %s = &elt;\n" % (instance))
- if len(sub_classes) == 0: # No inheritance case
+ if not type_maps.class_is_virtual(base_type): # No inheritance case
setup_instance(out, cls, base_type, "elt_p", v_name, version)
else:
for instance, subcls in sub_classes:
@@ -1215,7 +1228,7 @@
""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
base_type = loxi_utils.list_to_entry_type(cls)
out.write("""
- %(base_type)s_t elt;
+ of_object_t elt;
int count = 0;
int rv;
""" % dict(cls=cls, base_type=base_type))
@@ -1225,7 +1238,7 @@
sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
v_name = loxi_utils.version_to_name(version)
- if len(sub_classes) == 0:
+ if not type_maps.class_is_virtual(base_type):
entry_count = 2
out.write(" /* No subclasses for %s */\n"% base_type)
out.write(" %s_t *elt_p;\n" % base_type)
@@ -1237,10 +1250,12 @@
out.write(" %s_t *%s;\n" % (subcls, instance))
out.write("\n /* Instantiate pointers for each subclass */\n")
for instance, subcls in sub_classes:
- out.write(" %s = &elt.%s;\n" % (instance, instance))
+ out.write(" %s = &elt;\n" % (instance))
- out.write(" TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
- if len(sub_classes) == 0: # No inheritance case
+ if not type_maps.class_is_virtual(base_type) or sub_classes:
+ out.write(" TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
+
+ if not type_maps.class_is_virtual(base_type): # No inheritance case
check_instance(out, cls, base_type, "elt_p", v_name,
version, True)
else:
@@ -1518,7 +1533,7 @@
"""
members, member_types = scalar_member_types_get(cls, version)
- length = of_g.base_length[(cls, version)] + of_g.extra_length.get((cls, version), 0)
+ length = of_g.base_length[(cls, version)]
v_name = loxi_utils.version_to_name(version)
out.write("""
@@ -1573,11 +1588,9 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
- continue
elif loxi_utils.class_is_list(cls):
gen_list_setup_check(out, cls, version)
- else:
+ elif not type_maps.class_is_virtual(cls):
gen_class_setup_check(out, cls, version)
def gen_unified_accessor_tests(out, name):
@@ -1596,7 +1609,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
unified_accessor_test_case(out, cls, version)
@@ -1610,7 +1623,7 @@
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
test_name = "%s_%s" % (cls, v_name)
out.write(" RUN_TEST(%s);\n" % test_name)
@@ -1647,8 +1660,8 @@
%(cls)s_%(ver_name)s_dup(
%(cls)s_t *src)
{
- %(elt_type)s_t src_elt;
- %(elt_type)s_t *dst_elt;
+ of_object_t src_elt;
+ of_object_t *dst_elt;
int rv;
%(cls)s_t *dst;
@@ -1683,9 +1696,9 @@
*
* The caller is responsible for deleting the returned value
*/
-%(cls)s_t *
+of_object_t *
%(cls)s_%(ver_name)s_dup(
- %(cls)s_t *src)
+ of_object_t *src)
{
""" % dict(cls=cls, ver_name=ver_name))
@@ -1693,10 +1706,11 @@
sub_classes = type_maps.sub_class_map(cls, version)
for (_, sub_cls) in sub_classes:
sub_enum = sub_cls.upper()
+ if type_maps.class_is_virtual(sub_cls):
+ continue
out.write("""
- if (src->header.object_id == %(sub_enum)s) {
- return (%(cls)s_t *)%(sub_cls)s_%(ver_name)s_dup(
- (of_object_t *)src);
+ if (src->object_id == %(sub_enum)s) {
+ return %(sub_cls)s_%(ver_name)s_dup(src);
}
""" % dict(sub_cls=sub_cls, ver_name=ver_name, sub_enum=sub_enum, cls=cls))
@@ -1827,7 +1841,7 @@
gen_dup_inheritance(out, cls, version)
elif loxi_utils.class_is_list(cls):
gen_dup_list(out, cls, version)
- else:
+ elif not type_maps.class_is_virtual(cls):
gen_dup_cls(out, cls, version)
def gen_dup(out=sys.stdout):
@@ -1837,22 +1851,26 @@
for cls in of_g.standard_class_order:
out.write("""
-%(cls)s_t *
+of_object_t *
%(cls)s_dup(
- %(cls)s_t *src)
+ of_object_t *src)
{
""" % dict(cls=cls))
for version in of_g.of_version_range:
if not loxi_utils.class_in_version(cls, version):
continue
- hdr = "header." if type_maps.class_is_inheritance_root(cls) else ""
-
+ elif type_maps.class_is_inheritance_root(cls):
+ pass
+ elif loxi_utils.class_is_list(cls):
+ pass
+ elif type_maps.class_is_virtual(cls):
+ continue
ver_name = loxi_utils.version_to_name(version)
out.write("""
- if (src->%(hdr)sversion == %(ver_name)s) {
+ if (src->version == %(ver_name)s) {
return %(cls)s_%(ver_name)s_dup(src);
}
-""" % dict(cls=cls, ver_name=ver_name, hdr=hdr))
+""" % dict(cls=cls, ver_name=ver_name))
out.write("""
/* Class not supported in given version */
@@ -1906,20 +1924,26 @@
for cls in of_g.standard_class_order:
out.write("""
-extern %(cls)s_t *
+extern of_object_t *
%(cls)s_dup(
- %(cls)s_t *src);
+ of_object_t *src);
""" % dict(cls=cls))
for version in of_g.of_version_range:
for cls in of_g.standard_class_order:
if not loxi_utils.class_in_version(cls, version):
continue
+ elif type_maps.class_is_inheritance_root(cls):
+ pass
+ elif loxi_utils.class_is_list(cls):
+ pass
+ elif type_maps.class_is_virtual(cls):
+ continue
ver_name = loxi_utils.version_to_name(version)
out.write("""
-extern %(cls)s_t *
+extern of_object_t *
%(cls)s_%(ver_name)s_dup(
- %(cls)s_t *src);
+ of_object_t *src);
""" % dict(cls=cls, ver_name=ver_name))
out.write("\n#endif /* _OF_DUP_H_ */\n")
@@ -1949,7 +1973,7 @@
for j, cls in enumerate(of_g.all_class_order):
if not loxi_utils.class_in_version(cls, version):
continue
- if type_maps.class_is_inheritance_root(cls):
+ if type_maps.class_is_virtual(cls):
continue
if cls == "of_bsn_virtual_port_create_request": # test q_in_q
out.write("""
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 6c45d4d..36ad5f6 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -64,6 +64,18 @@
extern void of_meter_stats_wire_length_get(of_object_t *obj, int *bytes);
extern void of_meter_stats_wire_length_set(of_object_t *obj, int bytes);
+extern void of_port_desc_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_port_desc_wire_length_set(of_object_t *obj, int bytes);
+
+extern void of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes);
+
+extern void of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes);
+
+extern void of_queue_desc_wire_length_get(of_object_t *obj, int *bytes);
+extern void of_queue_desc_wire_length_set(of_object_t *obj, int bytes);
+
""")
@@ -106,44 +118,3 @@
out.write("""
};
""")
-
-
-def gen_extra_length_array(out):
- """
- Generate an array giving the extra lengths of all objects/versions
- @param out The file handle to which to write
- """
- out.write("""
-/**
- * An array with the number of bytes in the extra length part
- * of each OF object
- */
-""")
-
- for version in of_g.of_version_range:
- out.write("""
-static const int\nof_object_extra_len_v%d[OF_OBJECT_COUNT] = {
- -1, /* of_object is not instantiable */
-""" % version)
- for i, cls in enumerate(of_g.all_class_order):
- comma = ","
- if i == len(of_g.all_class_order) - 1:
- comma = ""
- val = "-1" + comma
- if (cls, version) in of_g.base_length:
- val = str(of_g.extra_length.get((cls, version), 0)) + comma
- out.write(" %-5s /* %d: %s */\n" % (val, i + 1, cls))
- out.write("};\n")
-
- out.write("""
-/**
- * Unified map of extra length part of each object
- */
-const int *const of_object_extra_len[OF_VERSION_ARRAY_MAX] = {
- NULL,
-""")
- for version in of_g.of_version_range:
- out.write(" of_object_extra_len_v%d,\n" % version)
- out.write("""
-};
-""")
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index c1b00ad..f052950 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -121,26 +121,12 @@
c_code_gen.gen_new_function_definitions(out, uclass.name)
c_code_gen.gen_accessor_definitions(out, uclass.name)
-# TODO remove header classes and use the corresponding class instead
-def generate_header_classes(install_dir):
- for cls in of_g.standard_class_order:
- if not cls.endswith("_header") or cls in ["of_header", "of_bsn_header", "of_nicira_header"]:
- continue
- with template_utils.open_output(install_dir, "loci/src/%s.c" % cls) as out:
- util.render_template(out, "class.c",
- push_wire_types_data=None,
- parse_wire_types_data=None)
- # Append legacy generated code
- c_code_gen.gen_new_function_definitions(out, cls)
- c_code_gen.gen_accessor_definitions(out, cls)
-
def generate_classes_header(install_dir):
# Collect legacy code
tmp = StringIO()
c_code_gen.gen_struct_typedefs(tmp)
c_code_gen.gen_new_function_declarations(tmp)
c_code_gen.gen_accessor_declarations(tmp)
- c_code_gen.gen_generics(tmp)
with template_utils.open_output(install_dir, "loci/inc/loci/loci_classes.h") as out:
util.render_template(out, "loci_classes.h",
@@ -186,7 +172,6 @@
# Collect legacy code
tmp = StringIO()
c_type_maps.gen_length_array(tmp)
- c_type_maps.gen_extra_length_array(tmp)
with template_utils.open_output(install_dir, "loci/src/of_type_maps.c") as out:
util.render_template(out, "of_type_maps.c", legacy_code=tmp.getvalue())
@@ -197,6 +182,14 @@
class_metadata = []
class_metadata_dict = {}
+# These classes have handwritten C code to get/set their length fields
+# See templates/of_type_maps.c
+special_length_classes = set([
+ 'of_packet_queue', 'of_meter_stats', 'of_port_desc',
+ 'of_port_stats_entry', 'of_queue_stats_entry',
+ 'of_queue_desc',
+])
+
def build_class_metadata():
for uclass in loxi_globals.unified.classes:
wire_length_get = 'NULL'
@@ -216,14 +209,9 @@
wire_length_set = 'of_object_message_wire_length_set'
elif uclass.is_oxm:
wire_length_get = 'of_oxm_wire_length_get'
- elif uclass.name == "of_packet_queue":
- # u16 len, but at offset 4
- wire_length_get = 'of_packet_queue_wire_length_get'
- wire_length_set = 'of_packet_queue_wire_length_set'
- elif uclass.name == "of_meter_stats":
- # u16 len, but at offset 4
- wire_length_get = 'of_meter_stats_wire_length_get'
- wire_length_set = 'of_meter_stats_wire_length_set'
+ elif uclass.name in special_length_classes:
+ wire_length_get = '%s_wire_length_get' % uclass.name
+ wire_length_set = '%s_wire_length_set' % uclass.name
elif loxi_utils_legacy.class_is_tlv16(uclass.name):
wire_length_set = 'of_tlv16_wire_length_set'
wire_length_get = 'of_tlv16_wire_length_get'
@@ -238,16 +226,6 @@
wire_type_get=wire_type_get,
wire_type_set=wire_type_set))
- # If this is the root of an inheritance hierachy, add metadata
- # for the corresponding header class
- if uclass.name in type_maps.inheritance_map:
- class_metadata.append(ClassMetadata(
- name=uclass.name + '_header',
- wire_length_get=wire_length_get,
- wire_length_set=wire_length_set,
- wire_type_get=wire_type_get,
- wire_type_set=wire_type_set))
-
for metadata in class_metadata:
class_metadata_dict[metadata.name] = metadata
diff --git a/c_gen/match.py b/c_gen/match.py
index 7b7dcce..c6459d4 100644
--- a/c_gen/match.py
+++ b/c_gen/match.py
@@ -131,6 +131,7 @@
2: of_v2_keys,
3: [],
4: [],
+ 5: [],
}
# Complete list of match keys, sorted by the standard order
@@ -196,8 +197,7 @@
# Generate list of OXM names from the unified classes
oxm_names = [x[7:] for x in of_g.unified.keys() if
x.startswith('of_oxm_') and
- x.find('masked') < 0 and
- x.find('header') < 0]
+ x.find('masked') < 0]
# Check that all OXMs are in the match members
for key in oxm_names:
diff --git a/c_gen/of_g_legacy.py b/c_gen/of_g_legacy.py
index 2372b31..87e0680 100644
--- a/c_gen/of_g_legacy.py
+++ b/c_gen/of_g_legacy.py
@@ -111,6 +111,7 @@
2: "uint32_t",
3: "uint32_t",
4: "uint32_t",
+ 5: "uint32_t",
"short_name":"port_no"
},
of_port_desc_t = {
@@ -118,6 +119,7 @@
2: "of_port_desc_t",
3: "of_port_desc_t",
4: "of_port_desc_t",
+ 5: "of_port_desc_t",
"short_name":"port_desc"
},
of_bsn_vport_t = {
@@ -125,6 +127,7 @@
2: "of_bsn_vport_t",
3: "of_bsn_vport_t",
4: "of_bsn_vport_t",
+ 5: "of_bsn_vport_t",
"short_name":"bsn_vport"
},
of_fm_cmd_t = { # Flow mod command went from u16 to u8
@@ -132,6 +135,7 @@
2: "uint8_t",
3: "uint8_t",
4: "uint8_t",
+ 5: "uint8_t",
"short_name":"fm_cmd"
},
of_wc_bmap_t = { # Wildcard bitmap
@@ -139,6 +143,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"wc_bmap"
},
of_match_bmap_t = { # Match bitmap
@@ -146,6 +151,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"match_bmap"
},
of_match_t = { # Match object
@@ -153,6 +159,7 @@
2: "of_match_v2_t",
3: "of_match_v3_t",
4: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
+ 5: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
"short_name":"match"
},
)
@@ -266,12 +273,6 @@
## Map from class, wire_version to size of fixed part of class
base_length = {}
-## Map from class, wire_version to size of variable-offset, fixed length part of class
-extra_length = {
- ("of_packet_in", 3): 2,
- ("of_packet_in", 4): 2,
-}
-
## Boolean indication of variable length, per class, wire_version,
is_fixed_length = set()
diff --git a/c_gen/templates/README b/c_gen/templates/README
index 71c4a48..44eedab 100644
--- a/c_gen/templates/README
+++ b/c_gen/templates/README
@@ -60,7 +60,7 @@
for (i = 1; i <= 4; i++) {
of_action_output_t action;
of_action_output_init(&action, flow_add->version, -1, 1);
- of_list_action_append_bind(&actions, (of_action_t *)&action);
+ of_list_action_append_bind(&actions, &action);
of_action_output_port_set(&action, i);
}
diff --git a/c_gen/templates/list.c b/c_gen/templates/list.c
index 9ff6e42..5eb45c6 100644
--- a/c_gen/templates/list.c
+++ b/c_gen/templates/list.c
@@ -42,12 +42,11 @@
*/
int
-${cls}_first(${cls}_t *list, ${e_cls}_t *_obj)
+${cls}_first(${cls}_t *list, of_object_t *obj)
{
int rv;
- of_object_t *obj = (of_object_t *)_obj;
- ${e_cls}_init(_obj, list->version, -1, 1);
+ ${e_cls}_init(obj, list->version, -1, 1);
if ((rv = of_list_first(list, obj)) < 0) {
return rv;
@@ -73,10 +72,9 @@
*/
int
-${cls}_next(${cls}_t *list, ${e_cls}_t *_obj)
+${cls}_next(${cls}_t *list, of_object_t *obj)
{
int rv;
- of_object_t *obj = (of_object_t *)_obj;
if ((rv = of_list_next(list, obj)) < 0) {
return rv;
@@ -105,9 +103,9 @@
*/
int
-${cls}_append_bind(${cls}_t *list, ${e_cls}_t *obj)
+${cls}_append_bind(${cls}_t *list, of_object_t *obj)
{
- return of_list_append_bind(list, (of_object_t *)obj);
+ return of_list_append_bind(list, obj);
}
/**
@@ -119,7 +117,7 @@
*/
int
-${cls}_append(${cls}_t *list, ${e_cls}_t *obj)
+${cls}_append(${cls}_t *list, of_object_t *obj)
{
- return of_list_append(list, (of_object_t *)obj);
+ return of_list_append(list, obj);
}
diff --git a/c_gen/templates/loci_int.h b/c_gen/templates/loci_int.h
index 1ea9eeb..eb1c923 100644
--- a/c_gen/templates/loci_int.h
+++ b/c_gen/templates/loci_int.h
@@ -30,6 +30,8 @@
:: flow_mod = of_g.base_length[("of_flow_modify",of_g.VERSION_1_2)]
:: packet_in = of_g.base_length[("of_packet_in",of_g.VERSION_1_2)]
:: packet_in_1_3 = of_g.base_length[("of_packet_in",of_g.VERSION_1_3)]
+:: packet_in_1_4 = of_g.base_length[("of_packet_in",of_g.VERSION_1_4)]
+:: assert packet_in_1_3 == packet_in_1_4
:: flow_stats = of_g.base_length[("of_flow_stats_entry", of_g.VERSION_1_2)]
:: match1 = of_g.base_length[("of_match_v1",of_g.VERSION_1_0)]
:: match2 = of_g.base_length[("of_match_v2",of_g.VERSION_1_1)]
@@ -239,13 +241,16 @@
* @param obj An object of type of_packet_in_t
*
* Get length of preceding match object and add to fixed length
- * Applies only to version 1.2 and 1.3
- * The +2 comes from the 2 bytes of padding between the match and packet data.
+ * Applies only to version 1.2+
+ * There are 2 bytes of padding between the match and data. The
+ * _OFFSET_FOLLOWING_MATCH_V3 macro assumes the match is at the end of the
+ * fixed length, so we need to subtract 2 from the fixed length we pass and
+ * then add 2 to the resulting offset.
*/
#define _PACKET_IN_DATA_OFFSET(obj) \
(_OFFSET_FOLLOWING_MATCH_V3((obj), (obj)->version == OF_VERSION_1_2 ? \
-${packet_in} : ${packet_in_1_3}) + 2)
+(${packet_in} - 2) : (${packet_in_1_3} - 2)) + 2)
/**
* Macro to calculate variable offset of data (packet) member in packet_out
diff --git a/c_gen/templates/loci_validator.c b/c_gen/templates/loci_validator.c
index 1f98b21..c4e8b5c 100644
--- a/c_gen/templates/loci_validator.c
+++ b/c_gen/templates/loci_validator.c
@@ -199,7 +199,7 @@
return ${validator_name(proto.class_by_name('of_header'))}(msg, len, &out_len);
:: #endfor
default:
- VALIDATOR_LOG("Bad version %d", OF_VERSION_1_3);
+ VALIDATOR_LOG("Bad version %d", version);
return -1;
}
}
diff --git a/c_gen/templates/locitest/test_utils.c b/c_gen/templates/locitest/test_utils.c
index 10a6b3d..d078a59 100644
--- a/c_gen/templates/locitest/test_utils.c
+++ b/c_gen/templates/locitest/test_utils.c
@@ -43,12 +43,8 @@
test_has_outport(void)
{
of_list_action_t *list;
- of_action_t elt;
- of_action_set_dl_src_t *set_dl_src;
- of_action_output_t *output;
-
- set_dl_src = &elt.set_dl_src;
- output = &elt.output;
+ of_object_t set_dl_src;
+ of_object_t output;
list = of_list_action_new(OF_VERSION_1_0);
TEST_ASSERT(list != NULL);
@@ -57,25 +53,25 @@
TEST_ASSERT(!of_action_list_has_out_port(list, 1));
/* Add some other action */
- of_action_set_dl_src_init(set_dl_src, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)set_dl_src));
+ of_action_set_dl_src_init(&set_dl_src, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &set_dl_src));
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(!of_action_list_has_out_port(list, 1));
/* Add port 2 */
- of_action_output_init(output, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
- of_action_output_port_set(output, 2);
+ of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &output));
+ of_action_output_port_set(&output, 2);
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(!of_action_list_has_out_port(list, 1));
TEST_ASSERT(of_action_list_has_out_port(list, 2));
/* Add port 1 */
- of_action_output_init(output, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
- of_action_output_port_set(output, 1);
+ of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &output));
+ of_action_output_port_set(&output, 1);
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(of_action_list_has_out_port(list, 1));
@@ -88,26 +84,26 @@
TEST_ASSERT(list != NULL);
/* Add port 2 */
- of_action_output_init(output, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
- of_action_output_port_set(output, 2);
+ of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &output));
+ of_action_output_port_set(&output, 2);
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(!of_action_list_has_out_port(list, 1));
TEST_ASSERT(of_action_list_has_out_port(list, 2));
/* Add some other action */
- of_action_set_dl_src_init(set_dl_src, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)set_dl_src));
+ of_action_set_dl_src_init(&set_dl_src, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &set_dl_src));
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(!of_action_list_has_out_port(list, 1));
TEST_ASSERT(of_action_list_has_out_port(list, 2));
/* Add port 1 */
- of_action_output_init(output, OF_VERSION_1_0, -1, 1);
- TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
- of_action_output_port_set(output, 1);
+ of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+ TEST_OK(of_list_action_append_bind(list, &output));
+ of_action_output_port_set(&output, 1);
TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
TEST_ASSERT(of_action_list_has_out_port(list, 1));
diff --git a/c_gen/templates/locitest/test_validator.c b/c_gen/templates/locitest/test_validator.c
index a4b55eb..fde5cba 100644
--- a/c_gen/templates/locitest/test_validator.c
+++ b/c_gen/templates/locitest/test_validator.c
@@ -88,9 +88,9 @@
of_message_t msg;
of_flow_modify_actions_bind(obj, &list);
of_action_set_tp_dst_init(&element1, OF_VERSION_1_0, -1, 1);
- of_list_action_append_bind(&list, (of_action_t *)&element1);
+ of_list_action_append_bind(&list, &element1);
of_action_output_init(&element2, OF_VERSION_1_0, -1, 1);
- of_list_action_append_bind(&list, (of_action_t *)&element2);
+ of_list_action_append_bind(&list, &element2);
msg = OF_OBJECT_TO_MESSAGE(obj);
TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 9fa59e0..3fcf024 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -305,3 +305,173 @@
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
}
+
+/**
+ * Get the wire length for a port desc object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_port_desc_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a port desc object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_port_desc_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}
+
+/**
+ * Get the wire length for a port stats_entry object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a port stats_entry object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}
+
+/**
+ * Get the wire length for a queue stats_entry object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ *
+ * The length is only present for OF 1.4+.
+ */
+void
+of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ &u16);
+ *bytes = u16;
+ } else {
+ *bytes = OF_OBJECT_FIXED_LENGTH(obj);
+ }
+}
+
+/**
+ * Set the wire length for a queue stats_entry object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ *
+ * The length is only present for OF 1.4+.
+ */
+
+void
+of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ if (obj->version >= OF_VERSION_1_4) {
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
+ bytes);
+ } else {
+ LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
+ }
+}
+
+/**
+ * Get the wire length for a queue_desc object
+ * @param obj The object being referenced
+ * @param bytes Pointer to location to store length
+ */
+void
+of_queue_desc_wire_length_get(of_object_t *obj, int *bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ uint16_t u16;
+
+ LOCI_ASSERT(wbuf != NULL);
+
+ of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), &u16);
+ *bytes = u16;
+}
+
+/**
+ * Set the wire length for a queue_desc object
+ * @param obj The object being referenced
+ * @param bytes The length of the object
+ */
+
+void
+of_queue_desc_wire_length_set(of_object_t *obj, int bytes)
+{
+ of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
+ LOCI_ASSERT(wbuf != NULL);
+
+ of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), bytes);
+}
diff --git a/c_gen/templates/of_utils.c b/c_gen/templates/of_utils.c
index 373ad59..bddbc8d 100644
--- a/c_gen/templates/of_utils.c
+++ b/c_gen/templates/of_utils.c
@@ -54,7 +54,7 @@
int
of_action_list_has_out_port(of_list_action_t *actions, of_port_no_t outport)
{
- of_action_t elt;
+ of_object_t elt;
of_action_output_t *output;
int loop_rv;
of_port_no_t port_no;
@@ -64,7 +64,7 @@
return 1;
}
- output = &elt.output;
+ output = &elt;
OF_LIST_ACTION_ITER(actions, &elt, loop_rv) {
if (output->object_id == OF_ACTION_OUTPUT) {
of_action_output_port_get(output, &port_no);
diff --git a/c_gen/templates/of_wire_buf.h b/c_gen/templates/of_wire_buf.h
index 0922a69..3d38f53 100644
--- a/c_gen/templates/of_wire_buf.h
+++ b/c_gen/templates/of_wire_buf.h
@@ -469,14 +469,10 @@
of_wire_buffer_u16_get(wbuf, offset, &v16);
*value = v16;
break;
- case OF_VERSION_1_1:
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u32_get(wbuf, offset, &v32);
*value = v32;
break;
- default:
- LOCI_ASSERT(0);
}
}
@@ -498,13 +494,9 @@
case OF_VERSION_1_0:
of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
break;
- case OF_VERSION_1_1:
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
break;
- default:
- LOCI_ASSERT(0);
}
}
@@ -527,14 +519,10 @@
of_wire_buffer_u16_get(wbuf, offset, &v16);
*value = v16;
break;
- case OF_VERSION_1_1:
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u8_get(wbuf, offset, &v8);
*value = v8;
break;
- default:
- LOCI_ASSERT(0);
}
}
@@ -553,13 +541,9 @@
case OF_VERSION_1_0:
of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
break;
- case OF_VERSION_1_1:
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u8_set(wbuf, offset, (uint8_t)value);
break;
- default:
- LOCI_ASSERT(0);
}
}
@@ -583,13 +567,10 @@
of_wire_buffer_u32_get(wbuf, offset, &v32);
*value = v32;
break;
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u64_get(wbuf, offset, &v64);
*value = v64;
break;
- default:
- LOCI_ASSERT(0);
}
}
@@ -609,12 +590,9 @@
case OF_VERSION_1_1:
of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
break;
- case OF_VERSION_1_2:
- case OF_VERSION_1_3:
+ default:
of_wire_buffer_u64_set(wbuf, offset, (uint64_t)value);
break;
- default:
- LOCI_ASSERT(0);
}
}
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index 3544d80..607814c 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -36,8 +36,6 @@
"""
Returns True if cls is a virtual class
"""
- if cls.endswith("header"):
- return True
if loxi_utils.class_is_list(cls):
return True
return loxi_globals.unified.class_by_name(cls).virtual
@@ -46,6 +44,10 @@
return cls in inheritance_map
def generate_maps():
+ for ofclass in loxi_globals.unified.classes:
+ if ofclass.virtual and not ofclass.superclass:
+ inheritance_map[ofclass.name] = set()
+
for version, protocol in loxi_globals.ir.items():
wire_version = version.wire_version
for ofclass in protocol.classes:
@@ -53,8 +55,6 @@
if not root or root == ofclass or root.name == "of_header":
continue
- if root.name not in inheritance_map:
- inheritance_map[root.name] = set()
inheritance_map[root.name].add(ofclass.name)
def sub_class_map(base_type, version):
diff --git a/cmdline.py b/cmdline.py
index 6395fff..de7070a 100644
--- a/cmdline.py
+++ b/cmdline.py
@@ -33,7 +33,7 @@
# The default configuration dictionary for LOXI code generation
options_default = {
"lang" : "c",
- "version-list" : "1.0 1.1 1.2 1.3",
+ "version-list" : "1.0 1.1 1.2 1.3 1.4",
"install-dir" : "loxi_output",
}
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index fc64f80..b3c3df0 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -826,7 +826,7 @@
entry = enum.entry_by_version_value(self.msg.version, self.value)
return "%s.%s" % ( enum.name, entry.name)
except KeyError, e:
- logger.debug("No enum found", e)
+ logger.debug("No enum found for type %s version %s value %s", java_type, self.msg.version, self.value)
return self.value
@property
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 427de95..79a1db3 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -528,6 +528,10 @@
generic_t = JType("T")
+table_desc = JType('OFTableDesc') \
+ .op(read='OFTableDescVer$version.READER.readFrom(bb)', \
+ write='$name.writeTo(bb)')
+
default_mtype_to_jtype_convert_map = {
'uint8_t' : u8,
@@ -564,6 +568,7 @@
'of_bitmap_128_t': port_bitmap,
'of_checksum_128_t': u128,
'of_bsn_vport_t': bsn_vport,
+ 'of_table_desc_t': table_desc,
}
## Map that defines exceptions from the standard loxi->java mapping scheme
@@ -619,6 +624,10 @@
'of_oxm_mpls_tc_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
'of_oxm_mpls_bos' : { 'value' : boolean_value },
'of_oxm_mpls_bos_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
+ 'of_oxm_ipv6_exthdr' : { 'value' : u16obj },
+ 'of_oxm_ipv6_exthdr_masked' : { 'value' : u16obj, 'value_mask' : u16obj },
+ 'of_oxm_pbb_uca' : { 'value' : boolean_value },
+ 'of_oxm_pbb_uca_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap },
'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap, 'value_mask': port_bitmap },
@@ -674,6 +683,9 @@
'of_oxm_bsn_vlan_xlate_port_group_id' : { 'value' : class_id },
'of_oxm_bsn_vlan_xlate_port_group_id_masked' : { 'value' : class_id, 'value_mask' : class_id },
+ 'of_oxm_bsn_l2_cache_hit' : { 'value' : boolean_value },
+ 'of_oxm_bsn_l2_cache_hit_masked' : { 'value' : boolean_value, 'value_mask' : boolean_value },
+
'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index 6b60fd1..58ddab3 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -10,7 +10,7 @@
<groupId>org.projectfloodlight</groupId>
<artifactId>openflowj</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.9.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>OpenFlowJ-Loxi</name>
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
index 6f54e5f..0c54fdc 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFVersion.java
@@ -1,7 +1,7 @@
package org.projectfloodlight.openflow.protocol;
public enum OFVersion {
- OF_10(1), OF_11(2), OF_12(3), OF_13(4);
+ OF_10(1), OF_11(2), OF_12(3), OF_13(4), OF_14(5);
public final int wireVersion;
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index 2fb58b7..39c15fd 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -185,6 +185,12 @@
public final static MatchField<U64> TUNNEL_ID =
new MatchField<U64>("tunnel_id", MatchFields.TUNNEL_ID);
+ public final static MatchField<U16> IPV6_EXTHDR =
+ new MatchField<U16>("ipv6_exthdr", MatchFields.IPV6_EXTHDR);
+
+ public final static MatchField<OFBooleanValue> PBB_UCA =
+ new MatchField<OFBooleanValue>("pbb_uca", MatchFields.PBB_UCA);
+
public final static MatchField<OFBitMask128> BSN_IN_PORTS_128 =
new MatchField<OFBitMask128>("bsn_in_ports_128", MatchFields.BSN_IN_PORTS_128);
@@ -239,6 +245,9 @@
public final static MatchField<ClassId> BSN_VLAN_XLATE_PORT_GROUP_ID =
new MatchField<ClassId>("bsn_vlan_xlate_port_group_id", MatchFields.BSN_VLAN_XLATE_PORT_GROUP_ID);
+ public final static MatchField<OFBooleanValue> BSN_L2_CACHE_HIT =
+ new MatchField<OFBooleanValue>("bsn_l2_cache_hit", MatchFields.BSN_L2_CACHE_HIT);
+
public String getName() {
return name;
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index 77494cb..aaf3576 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -40,6 +40,8 @@
MPLS_TC,
MPLS_BOS,
TUNNEL_ID,
+ IPV6_EXTHDR,
+ PBB_UCA,
BSN_IN_PORTS_128,
BSN_LAG_ID,
BSN_VRF,
@@ -58,4 +60,5 @@
BSN_UDF7,
BSN_TCP_FLAGS,
BSN_VLAN_XLATE_PORT_GROUP_ID,
+ BSN_L2_CACHE_HIT,
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
new file mode 100644
index 0000000..c893cab
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/ver14/ChannelUtilsVer14.java
@@ -0,0 +1,26 @@
+package org.projectfloodlight.openflow.protocol.ver14;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.projectfloodlight.openflow.protocol.OFMatchBmap;
+import org.projectfloodlight.openflow.protocol.match.Match;
+
+/**
+ * Collection of helper functions for reading and writing into ChannelBuffers
+ *
+ * @author capveg
+ */
+
+public class ChannelUtilsVer14 {
+ public static Match readOFMatch(final ChannelBuffer bb) throws OFParseError {
+ return OFMatchV3Ver14.READER.readFrom(bb);
+ }
+
+ public static OFMatchBmap readOFMatchBmap(ChannelBuffer bb) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public static void writeOFMatchBmap(ChannelBuffer bb, OFMatchBmap match) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/java_gen/templates/custom/OFMatchV3.Builder.java b/java_gen/templates/custom/OFMatchV3.Builder.java
new file mode 100644
index 0000000..54b35ba
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.Builder.java
@@ -0,0 +1,106 @@
+
+ private OFOxmList.Builder oxmListBuilder;
+
+ private void initBuilder() {
+ if (oxmListBuilder != null)
+ return;
+ oxmListBuilder = new OFOxmList.Builder();
+ }
+
+ private void updateOxmList() {
+ this.oxmList = this.oxmListBuilder.build();
+ this.oxmListSet = true;
+ }
+
+ private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
+//:: if has_parent:
+ return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
+//:: else:
+ return this.oxmListSet ? this.oxmList.get(field) : null;
+//:: #endif
+ }
+
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null)
+ return null;
+ return value.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ OFOxm<F> value = getOxm(field);
+ if (value == null || !value.isMasked())
+ return null;
+ // TODO: If changing OXMs to extend Masked, then use it here
+ return Masked.of(value.getValue(), value.getMask());
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && !value.isMasked());
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value == null);
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ OFOxm<?> value = getOxm(field);
+ return (value != null && value.isMasked());
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setExact(
+ MatchField<F> field, F value) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValue(value, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, F value, F mask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromValueAndMask(value, mask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder setMasked(
+ MatchField<F> field, Masked<F> valueWithMask) {
+ initBuilder();
+ OFOxm<F> oxm = OFFactories.getFactory(OFVersion.${version.constant_version}).oxms().fromMasked(valueWithMask, field);
+ this.oxmListBuilder.set(oxm);
+ updateOxmList();
+ return this;
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
+ initBuilder();
+ this.oxmListBuilder.unset(field);
+ updateOxmList();
+ return this;
+ }
diff --git a/java_gen/templates/custom/OFMatchV3.java b/java_gen/templates/custom/OFMatchV3.java
new file mode 100644
index 0000000..799135c
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3.java
@@ -0,0 +1,112 @@
+//:: from generic_utils import OrderedSet
+//:: from java_gen.java_model import model
+ @Override
+ public <F extends OFValueType<F>> F get(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ return oxm.getValue();
+ }
+
+ @Override
+ public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
+ throws UnsupportedOperationException {
+ if (!supportsMasked(field))
+ throw new UnsupportedOperationException("${msg.name} does not support masked matching on field " + field.getName());
+
+ OFOxm<F> oxm = this.oxmList.get(field);
+
+ if (oxm == null || !field.arePrerequisitesOK(this))
+ return null;
+
+ if (oxm.getMask() == null)
+ return null;
+
+ // TODO: Make OfOxm extend Masked and just return the OXM?
+ return Masked.of(oxm.getValue(), oxm.getMask());
+ }
+
+ private static boolean supportsField(MatchField<?> field) {
+ switch (field.id) {
+ //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
+ case ${id_constant}:
+ //:: #endfor
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean supports(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean supportsMasked(MatchField<?> field) {
+ return supportsField(field);
+ }
+
+ @Override
+ public boolean isExact(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && !oxm.isMasked();
+ }
+
+ @Override
+ public boolean isFullyWildcarded(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm == null;
+ }
+
+ @Override
+ public boolean isPartiallyMasked(MatchField<?> field) {
+ if (!supports(field))
+ throw new UnsupportedOperationException("${msg.name} does not support matching on field " + field.getName());
+
+ OFOxm<?> oxm = this.oxmList.get(field);
+
+ return oxm != null && oxm.isMasked();
+ }
+
+ private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
+ private Iterator<OFOxm<?>> oxmIterator;
+
+ MatchFieldIterator() {
+ oxmIterator = oxmList.iterator();
+ }
+
+ @Override
+ protected MatchField<?> computeNext() {
+ while(oxmIterator.hasNext()) {
+ OFOxm<?> oxm = oxmIterator.next();
+ if(oxm.getMatchField().arePrerequisitesOK(${msg.name}.this))
+ return oxm.getMatchField();
+ }
+ endOfData();
+ return null;
+ }
+ }
+
+ @Override
+ public Iterable<MatchField<?>> getMatchFields() {
+ return new Iterable<MatchField<?>>() {
+ public Iterator<MatchField<?>> iterator() {
+ return new MatchFieldIterator();
+ }
+ };
+ }
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
index 3fae367..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.Builder.java
@@ -1,106 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private synchronized void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private synchronized void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public synchronized boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public synchronized boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public synchronized boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public synchronized <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12.java b/java_gen/templates/custom/OFMatchV3Ver12.java
index 81092c1..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver12.java
+++ b/java_gen/templates/custom/OFMatchV3Ver12.java
@@ -1,114 +1 @@
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- case IN_PORT:
- case IN_PHY_PORT:
- case METADATA:
- case ETH_DST:
- case ETH_SRC:
- case ETH_TYPE:
- case VLAN_VID:
- case VLAN_PCP:
- case IP_DSCP:
- case IP_ECN:
- case IP_PROTO:
- case IPV4_SRC:
- case IPV4_DST:
- case TCP_SRC:
- case TCP_DST:
- case UDP_SRC:
- case UDP_DST:
- case SCTP_SRC:
- case SCTP_DST:
- case ICMPV4_TYPE:
- case ICMPV4_CODE:
- case ARP_OP:
- case ARP_SPA:
- case ARP_TPA:
- case ARP_SHA:
- case ARP_THA:
- case IPV6_SRC:
- case IPV6_DST:
- case IPV6_FLABEL:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- throw new UnsupportedOperationException();
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver12_toString.java b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver12_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
index 79cbdbc..ae2ecaa 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.Builder.java
@@ -1,107 +1 @@
-
- private OFOxmList.Builder oxmListBuilder;
-
- private void initBuilder() {
- if (oxmListBuilder != null)
- return;
- oxmListBuilder = new OFOxmList.Builder();
- }
-
- private void updateOxmList() {
- this.oxmList = this.oxmListBuilder.build();
- this.oxmListSet = true;
- }
-
- private <F extends OFValueType<F>> OFOxm<F> getOxm(MatchField<F> field) {
-//:: if has_parent:
- return this.oxmListSet ? this.oxmList.get(field) : parentMessage.oxmList.get(field);
-//:: else:
- return this.oxmListSet ? this.oxmList.get(field) : null;
-//:: #endif
- }
-
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null)
- return null;
- return value.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- OFOxm<F> value = getOxm(field);
- if (value == null || !value.isMasked())
- return null;
- // TODO: If changing OXMs to extend Masked, then use it here
- return Masked.of(value.getValue(), value.getMask());
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && !value.isMasked());
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value == null);
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- OFOxm<?> value = getOxm(field);
- return (value != null && value.isMasked());
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setExact(
- MatchField<F> field, F value) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValue(value, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, F value, F mask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromValueAndMask(value, mask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder setMasked(
- MatchField<F> field, Masked<F> valueWithMask) {
- initBuilder();
- OFOxm<F> oxm = OFFactories.getFactory(OFVersion.OF_13).oxms().fromMasked(valueWithMask, field);
- this.oxmListBuilder.set(oxm);
- updateOxmList();
- return this;
- }
-
- @Override
- public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
- initBuilder();
- this.oxmListBuilder.unset(field);
- updateOxmList();
- return this;
- }
-
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.java b/java_gen/templates/custom/OFMatchV3Ver13.java
index dc8e637..225b0dc 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.java
@@ -1,112 +1 @@
-//:: from generic_utils import OrderedSet
-//:: from java_gen.java_model import model
- @Override
- public <F extends OFValueType<F>> F get(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- return oxm.getValue();
- }
-
- @Override
- public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
- throws UnsupportedOperationException {
- if (!supportsMasked(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support masked matching on field " + field.getName());
-
- OFOxm<F> oxm = this.oxmList.get(field);
-
- if (oxm == null || !field.arePrerequisitesOK(this))
- return null;
-
- if (oxm.getMask() == null)
- return null;
-
- // TODO: Make OfOxm extend Masked and just return the OXM?
- return Masked.of(oxm.getValue(), oxm.getMask());
- }
-
- private static boolean supportsField(MatchField<?> field) {
- switch (field.id) {
- //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
- case ${id_constant}:
- //:: #endfor
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean supports(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean supportsMasked(MatchField<?> field) {
- return supportsField(field);
- }
-
- @Override
- public boolean isExact(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && !oxm.isMasked();
- }
-
- @Override
- public boolean isFullyWildcarded(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm == null;
- }
-
- @Override
- public boolean isPartiallyMasked(MatchField<?> field) {
- if (!supports(field))
- throw new UnsupportedOperationException("OFMatchV3Ver13 does not support matching on field " + field.getName());
-
- OFOxm<?> oxm = this.oxmList.get(field);
-
- return oxm != null && oxm.isMasked();
- }
-
- private class MatchFieldIterator extends AbstractIterator<MatchField<?>> {
- private Iterator<OFOxm<?>> oxmIterator;
-
- MatchFieldIterator() {
- oxmIterator = oxmList.iterator();
- }
-
- @Override
- protected MatchField<?> computeNext() {
- while(oxmIterator.hasNext()) {
- OFOxm<?> oxm = oxmIterator.next();
- if(oxm.getMatchField().arePrerequisitesOK(OFMatchV3Ver13.this))
- return oxm.getMatchField();
- }
- endOfData();
- return null;
- }
- }
-
- @Override
- public Iterable<MatchField<?>> getMatchFields() {
- return new Iterable<MatchField<?>>() {
- public Iterator<MatchField<?>> iterator() {
- return new MatchFieldIterator();
- }
- };
- }
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.Builder.java b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
new file mode 100644
index 0000000..ae2ecaa
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.Builder.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.Builder.java", msg=msg, version=version, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14.java b/java_gen/templates/custom/OFMatchV3Ver14.java
new file mode 100644
index 0000000..225b0dc
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatchV3.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/custom/OFMatchV3Ver14_toString.java b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
new file mode 100644
index 0000000..3b2783b
--- /dev/null
+++ b/java_gen/templates/custom/OFMatchV3Ver14_toString.java
@@ -0,0 +1 @@
+//:: include("custom/OFMatch_toString.java", msg=msg, has_parent=False)
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index f1d72b2..071f177 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -88,7 +88,7 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False, has_parent=False)
//:: if os.path.exists("%s/custom/%s.java" % (template_dir, msg.name)):
- //:: include("custom/%s.java" % msg.name, msg=msg)
+ //:: include("custom/%s.java" % msg.name, msg=msg, version=version)
//:: #endif
//:: if msg.data_members:
@@ -124,7 +124,7 @@
//
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
//:: for i, prop in enumerate(msg.data_members):
@@ -134,7 +134,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=True)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=True)
//:: #endif
}
@@ -164,7 +164,7 @@
//:: #endfor
//:: if os.path.exists("%s/custom/%s.Builder_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
return new ${impl_class}(
@@ -175,7 +175,7 @@
);
}
//:: if os.path.exists("%s/custom/%s.Builder.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Builder.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Builder.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
}
@@ -249,7 +249,7 @@
//:: if msg.data_members:
//:: if os.path.exists("%s/custom/%s.Reader_normalize_stanza.java" % (template_dir, msg.name)):
- //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: #endif
${impl_class} ${msg.variable_name} = new ${impl_class}(
${",\n ".join(
@@ -364,7 +364,7 @@
}
//:: if os.path.exists("%s/custom/%s_toString.java" % (template_dir, msg.name)):
- //:: include("custom/%s_toString.java" % msg.name, msg=msg, has_parent=False)
+ //:: include("custom/%s_toString.java" % msg.name, msg=msg, version=version, has_parent=False)
//:: else:
@Override
public String toString() {
diff --git a/lang_c.py b/lang_c.py
index c7b68f7..bec4a65 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -125,7 +125,6 @@
fn(outfile, os.path.basename(name))
c_gen.codegen.build_class_metadata()
c_gen.codegen.generate_classes(install_dir)
- c_gen.codegen.generate_header_classes(install_dir)
c_gen.codegen.generate_classes_header(install_dir)
c_gen.codegen.generate_lists(install_dir)
c_gen.codegen.generate_strings(install_dir)
diff --git a/loxi_globals.py b/loxi_globals.py
index e8b21bd..b4662cb 100644
--- a/loxi_globals.py
+++ b/loxi_globals.py
@@ -37,12 +37,14 @@
VERSION_1_1 = OFVersion("1.1", 2)
VERSION_1_2 = OFVersion("1.2", 3)
VERSION_1_3 = OFVersion("1.3", 4)
+ VERSION_1_4 = OFVersion("1.4", 5)
all_supported = (
VERSION_1_0,
VERSION_1_1,
VERSION_1_2,
VERSION_1_3,
+ VERSION_1_4,
)
wire_version_map = { v.wire_version : v for v in all_supported }
diff --git a/loxi_ir/ir_offset.py b/loxi_ir/ir_offset.py
index 9c6a5c1..db55f24 100644
--- a/loxi_ir/ir_offset.py
+++ b/loxi_ir/ir_offset.py
@@ -35,6 +35,7 @@
2: "uint32_t",
3: "uint32_t",
4: "uint32_t",
+ 5: "uint32_t",
"short_name":"port_no"
},
of_port_desc_t = {
@@ -42,6 +43,7 @@
2: "of_port_desc_t",
3: "of_port_desc_t",
4: "of_port_desc_t",
+ 5: "of_port_desc_t",
"short_name":"port_desc"
},
of_bsn_vport_t = {
@@ -49,6 +51,7 @@
2: "of_bsn_vport_t",
3: "of_bsn_vport_t",
4: "of_bsn_vport_t",
+ 5: "of_bsn_vport_t",
"short_name":"bsn_vport"
},
of_fm_cmd_t = { # Flow mod command went from u16 to u8
@@ -56,6 +59,7 @@
2: "uint8_t",
3: "uint8_t",
4: "uint8_t",
+ 5: "uint8_t",
"short_name":"fm_cmd"
},
of_wc_bmap_t = { # Wildcard bitmap
@@ -63,6 +67,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"wc_bmap"
},
of_match_bmap_t = { # Match bitmap
@@ -70,6 +75,7 @@
2: "uint32_t",
3: "uint64_t",
4: "uint64_t",
+ 5: "uint64_t",
"short_name":"match_bmap"
},
of_match_t = { # Match object
@@ -77,6 +83,7 @@
2: "of_match_v2_t",
3: "of_match_v3_t",
4: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
+ 5: "of_match_v3_t", # Currently uses same match as 1.2 (v3).
"short_name":"match"
},
)
@@ -180,6 +187,8 @@
member_ir_class = existing_classes[base_class]
bytes = member_ir_class.base_length
length_fixed = member_ir_class.is_fixed_length
+ if member_ir_class.has_external_alignment:
+ bytes = (bytes + 7) & ~7
else:
if base_type in existing_enums:
enum = existing_enums[base_type]
diff --git a/openflow_input/bsn-1.3 b/openflow_input/bsn-1.3
index f9340b4..5ad480c 100644
--- a/openflow_input/bsn-1.3
+++ b/openflow_input/bsn-1.3
@@ -26,6 +26,7 @@
// under the EPL.
#version 4
+#version 5
// BSN extension instruction
struct of_instruction_bsn : of_instruction_experimenter {
diff --git a/openflow_input/bsn_acl b/openflow_input/bsn_acl
index 4035904..bcca842 100644
--- a/openflow_input/bsn_acl
+++ b/openflow_input/bsn_acl
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
// Instructions to express control flow in ACL tables
diff --git a/openflow_input/bsn_arp_idle b/openflow_input/bsn_arp_idle
index 26cea92..16a1782 100644
--- a/openflow_input/bsn_arp_idle
+++ b/openflow_input/bsn_arp_idle
@@ -35,6 +35,7 @@
// not remove the table entry on its own.
#version 4
+#version 5
struct of_bsn_arp_idle : of_bsn_header {
uint8_t version;
diff --git a/openflow_input/bsn_arp_offload b/openflow_input/bsn_arp_offload
index 5a229b1..f13f6ac 100644
--- a/openflow_input/bsn_arp_offload
+++ b/openflow_input/bsn_arp_offload
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_arp_offload : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_aux_cxns b/openflow_input/bsn_aux_cxns
index 247f81b..8ceaa72 100644
--- a/openflow_input/bsn_aux_cxns
+++ b/openflow_input/bsn_aux_cxns
@@ -28,6 +28,8 @@
// Request that the switch spawn and configure auxiliary OF connections.
//
#version 4
+#version 5
+
// Set the number of desired aux connections num_aux=(0-16) accompanying this main connection
// This message is only allowed on the main connection.
struct of_bsn_set_aux_cxns_request : of_bsn_header {
diff --git a/openflow_input/bsn_controller_connections b/openflow_input/bsn_controller_connections
index eae315e..845d3b8 100644
--- a/openflow_input/bsn_controller_connections
+++ b/openflow_input/bsn_controller_connections
@@ -37,6 +37,7 @@
// The URIs are of the form tcp://1.2.3.4:6553
#version 4
+#version 5
enum ofp_bsn_controller_connection_state(wire_type=uint8_t) {
OFP_BSN_CONTROLLER_CONNECTION_STATE_DISCONNECTED = 0,
diff --git a/openflow_input/bsn_debug_counter b/openflow_input/bsn_debug_counter
index 75cafcc..6c28b87 100644
--- a/openflow_input/bsn_debug_counter
+++ b/openflow_input/bsn_debug_counter
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
// Switches have many non-dataplane counters that are mainly useful for
// debugging. An example is the number of packet-ins dropped due to
diff --git a/openflow_input/bsn_dhcp_offload b/openflow_input/bsn_dhcp_offload
index b21b036..5352754 100644
--- a/openflow_input/bsn_dhcp_offload
+++ b/openflow_input/bsn_dhcp_offload
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_dhcp_offload : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_disable_src_mac_check b/openflow_input/bsn_disable_src_mac_check
index f75c237..6b095ca 100644
--- a/openflow_input/bsn_disable_src_mac_check
+++ b/openflow_input/bsn_disable_src_mac_check
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_disable_src_mac_check : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_disable_vlan_counters b/openflow_input/bsn_disable_vlan_counters
index 068db64..e586917 100644
--- a/openflow_input/bsn_disable_vlan_counters
+++ b/openflow_input/bsn_disable_vlan_counters
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_disable_vlan_counters : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_egr_port_group_id b/openflow_input/bsn_egr_port_group_id
index a237b49..3ba5462 100644
--- a/openflow_input/bsn_egr_port_group_id
+++ b/openflow_input/bsn_egr_port_group_id
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* Egress port group ID for SwitchLight
diff --git a/openflow_input/bsn_flow_checksum b/openflow_input/bsn_flow_checksum
index bfa5f3c..35b658f 100644
--- a/openflow_input/bsn_flow_checksum
+++ b/openflow_input/bsn_flow_checksum
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
// Retrieves the checksum for every bucket in a table. The entries are ordered
// by bucket index.
diff --git a/openflow_input/bsn_flow_idle b/openflow_input/bsn_flow_idle
index 40a95d8..e0139e2 100644
--- a/openflow_input/bsn_flow_idle
+++ b/openflow_input/bsn_flow_idle
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
/*
* Notification of idle flows
diff --git a/openflow_input/bsn_gentable b/openflow_input/bsn_gentable
index 6ccaac5..556ae0b 100644
--- a/openflow_input/bsn_gentable
+++ b/openflow_input/bsn_gentable
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
// We have a number of switch agents that need to be configured by the
// controller and report stats. Some of them will have large tables (1000+
diff --git a/openflow_input/bsn_image b/openflow_input/bsn_image
index 05a1a97..fafe8d8 100644
--- a/openflow_input/bsn_image
+++ b/openflow_input/bsn_image
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
struct of_bsn_image_desc_stats_request : of_bsn_stats_request {
uint8_t version;
diff --git a/openflow_input/bsn_in_ports b/openflow_input/bsn_in_ports
index b23df63..819bdde 100644
--- a/openflow_input/bsn_in_ports
+++ b/openflow_input/bsn_in_ports
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* Bitmap of input ports
diff --git a/openflow_input/bsn_l2_cache_hit b/openflow_input/bsn_l2_cache_hit
new file mode 100644
index 0000000..694bc65
--- /dev/null
+++ b/openflow_input/bsn_l2_cache_hit
@@ -0,0 +1,47 @@
+// Copyright 2014, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 3
+#version 4
+
+/*
+ * L2 Cache Hit
+ */
+
+struct of_oxm_bsn_l2_cache_hit : of_oxm {
+ uint32_t type_len == 0x00032401;
+ uint8_t value;
+};
+
+struct of_oxm_bsn_l2_cache_hit_masked : of_oxm {
+ uint32_t type_len == 0x00032502;
+ uint8_t value;
+ uint8_t value_mask;
+};
diff --git a/openflow_input/bsn_l3_interface_class_id b/openflow_input/bsn_l3_interface_class_id
index 80d1e37..f16d333 100644
--- a/openflow_input/bsn_l3_interface_class_id
+++ b/openflow_input/bsn_l3_interface_class_id
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* L3 interface class ID for SwitchLight
diff --git a/openflow_input/bsn_l3_src_class_id b/openflow_input/bsn_l3_src_class_id
index 58f60c6..7e2569e 100644
--- a/openflow_input/bsn_l3_src_class_id
+++ b/openflow_input/bsn_l3_src_class_id
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* L3 source class ID for SwitchLight
diff --git a/openflow_input/bsn_lacp b/openflow_input/bsn_lacp
index 2a63b17..ed36b0d 100644
--- a/openflow_input/bsn_lacp
+++ b/openflow_input/bsn_lacp
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
// LACP Convergence Status set in of_bsn_lacp_convergence_notif message
enum of_bsn_lacp_convergence_status(wire_type=uint8_t, complete=False) {
diff --git a/openflow_input/bsn_lag_id b/openflow_input/bsn_lag_id
index 63645a3..d428933 100644
--- a/openflow_input/bsn_lag_id
+++ b/openflow_input/bsn_lag_id
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* Ingress LAG ID for SwitchLight
diff --git a/openflow_input/bsn_log b/openflow_input/bsn_log
index b2a9758..e636d6e 100644
--- a/openflow_input/bsn_log
+++ b/openflow_input/bsn_log
@@ -29,6 +29,7 @@
// the receiver's configured loglevel is lower than the message's loglevel.
#version 4
+#version 5
enum ofp_bsn_loglevel(wire_type=uint8_t) {
OFP_BSN_LOGLEVEL_MSG = 0,
diff --git a/openflow_input/bsn_packet_of_death b/openflow_input/bsn_packet_of_death
index e8679f0..c1ac28d 100644
--- a/openflow_input/bsn_packet_of_death
+++ b/openflow_input/bsn_packet_of_death
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_packet_of_death : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_pktin_flag b/openflow_input/bsn_pktin_flag
index fd94a49..71a4be1 100644
--- a/openflow_input/bsn_pktin_flag
+++ b/openflow_input/bsn_pktin_flag
@@ -26,6 +26,7 @@
// under the EPL.
#version 4
+#version 5
// In a realistic switch pipeline there are multiple reasons a given packet
// should be sent to the controller. The packet-in reason field is only 8 bits,
diff --git a/openflow_input/bsn_port_counter b/openflow_input/bsn_port_counter
index 83cd1c8..6cf5e10 100644
--- a/openflow_input/bsn_port_counter
+++ b/openflow_input/bsn_port_counter
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
enum ofp_bsn_port_counter(wire_type=uint8_t, complete=False, stable=True) {
OFP_BSN_PORT_COUNTER_RX_BYTES = 0,
diff --git a/openflow_input/bsn_prioritize_pdus b/openflow_input/bsn_prioritize_pdus
index fbec0a0..7a179a9 100644
--- a/openflow_input/bsn_prioritize_pdus
+++ b/openflow_input/bsn_prioritize_pdus
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_prioritize_pdus : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_require_vlan_xlate b/openflow_input/bsn_require_vlan_xlate
index 24cf137..32fc55c 100644
--- a/openflow_input/bsn_require_vlan_xlate
+++ b/openflow_input/bsn_require_vlan_xlate
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_require_vlan_xlate : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_span_destination b/openflow_input/bsn_span_destination
index 7fd900d..fd4f677 100644
--- a/openflow_input/bsn_span_destination
+++ b/openflow_input/bsn_span_destination
@@ -30,6 +30,7 @@
// Copyright (c) 2011, 2012 Open Networking Foundation
#version 4
+#version 5
struct of_instruction_bsn_span_destination : of_instruction_bsn {
uint16_t type == 65535;
diff --git a/openflow_input/bsn_switch_pipeline b/openflow_input/bsn_switch_pipeline
index ff2213f..d42532b 100644
--- a/openflow_input/bsn_switch_pipeline
+++ b/openflow_input/bsn_switch_pipeline
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
struct of_bsn_get_switch_pipeline_request : of_bsn_header {
uint8_t version;
diff --git a/openflow_input/bsn_tcp_flags b/openflow_input/bsn_tcp_flags
index e8ef2e9..1a84a90 100644
--- a/openflow_input/bsn_tcp_flags
+++ b/openflow_input/bsn_tcp_flags
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* TCP flags
diff --git a/openflow_input/bsn_time b/openflow_input/bsn_time
index 0a955be..d69e538 100644
--- a/openflow_input/bsn_time
+++ b/openflow_input/bsn_time
@@ -33,6 +33,7 @@
// The timestamp must be monotonic (not affected by system time updates).
#version 4
+#version 5
struct of_bsn_time_request : of_bsn_header {
uint8_t version;
diff --git a/openflow_input/bsn_tlv b/openflow_input/bsn_tlv
index 9f8da04..4e12a2b 100644
--- a/openflow_input/bsn_tlv
+++ b/openflow_input/bsn_tlv
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
struct of_bsn_tlv_port : of_bsn_tlv {
uint16_t type == 0;
@@ -346,3 +347,44 @@
uint16_t length;
of_octets_t value; /* UTF-8 encoded. Not null terminated. */
};
+
+enum ofp_bsn_lacp_state(wire_type=uint8_t, bitmask=True) {
+ OFP_BSN_LACP_STATE_ACTIVITY = 0x01,
+ OFP_BSN_LACP_STATE_TIMEOUT = 0x02,
+ OFP_BSN_LACP_STATE_AGGREGATION = 0x04,
+ OFP_BSN_LACP_STATE_SYNCHRONIZATION = 0x08,
+ OFP_BSN_LACP_STATE_COLLECTING = 0x10,
+ OFP_BSN_LACP_STATE_DISTRIBUTING = 0x20,
+ OFP_BSN_LACP_STATE_DEFAULTED = 0x40,
+ OFP_BSN_LACP_STATE_EXPIRED = 0x80,
+};
+
+struct of_bsn_tlv_actor_state: of_bsn_tlv {
+ uint16_t type == 53;
+ uint16_t length;
+ enum ofp_bsn_lacp_state value;
+};
+
+struct of_bsn_tlv_partner_state: of_bsn_tlv {
+ uint16_t type == 54;
+ uint16_t length;
+ enum ofp_bsn_lacp_state value;
+};
+
+struct of_bsn_tlv_data : of_bsn_tlv {
+ uint16_t type == 55;
+ uint16_t length;
+ of_octets_t value;
+};
+
+struct of_bsn_tlv_mac_mask : of_bsn_tlv {
+ uint16_t type == 56;
+ uint16_t length;
+ of_mac_addr_t value;
+};
+
+struct of_bsn_tlv_priority : of_bsn_tlv {
+ uint16_t type == 57;
+ uint16_t length;
+ uint32_t value;
+};
diff --git a/openflow_input/bsn_udf b/openflow_input/bsn_udf
index f7ce9a6..12ad1cb 100644
--- a/openflow_input/bsn_udf
+++ b/openflow_input/bsn_udf
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* User Defined Fields
diff --git a/openflow_input/bsn_vlan_counter b/openflow_input/bsn_vlan_counter
index c5814f4..d39d35f 100644
--- a/openflow_input/bsn_vlan_counter
+++ b/openflow_input/bsn_vlan_counter
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
enum ofp_bsn_vlan_counter_constants {
OFP_BSN_VLAN_ALL = 0xffff,
diff --git a/openflow_input/bsn_vlan_xlate_port_group_id b/openflow_input/bsn_vlan_xlate_port_group_id
index c8e5a25..986dc0e 100644
--- a/openflow_input/bsn_vlan_xlate_port_group_id
+++ b/openflow_input/bsn_vlan_xlate_port_group_id
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* VLAN xlate port group ID for SwitchLight
diff --git a/openflow_input/bsn_vrf b/openflow_input/bsn_vrf
index 26959bd..c61c313 100644
--- a/openflow_input/bsn_vrf
+++ b/openflow_input/bsn_vrf
@@ -30,6 +30,7 @@
#version 3
#version 4
+#version 5
/*
* Virtual Routing/Forwarding ID for SwitchLight
diff --git a/openflow_input/bsn_vrf_counter b/openflow_input/bsn_vrf_counter
index b638ff7..012d728 100644
--- a/openflow_input/bsn_vrf_counter
+++ b/openflow_input/bsn_vrf_counter
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
enum ofp_bsn_vrf_counter_constants(wire_type=uint32_t) {
OFP_BSN_VRF_ALL = 0xffffffff,
diff --git a/openflow_input/oxm-1.2 b/openflow_input/oxm-1.2
index 5006cff..dd596bd 100644
--- a/openflow_input/oxm-1.2
+++ b/openflow_input/oxm-1.2
@@ -31,6 +31,7 @@
#version 3
#version 4
+#version 5
struct of_oxm {
uint32_t type_len == ?;
diff --git a/openflow_input/oxm-1.3 b/openflow_input/oxm-1.3
index 8574236..4bb55a1 100644
--- a/openflow_input/oxm-1.3
+++ b/openflow_input/oxm-1.3
@@ -29,6 +29,7 @@
// governing permissions and limitations under the EPL.
#version 4
+#version 5
struct of_oxm_tunnel_id : of_oxm {
uint32_t type_len == 0x80004c08;
@@ -51,3 +52,16 @@
uint8_t value;
uint8_t value_mask;
};
+
+/* Not supporting pbb_isid at the moment, requires a 3-byte field */
+
+struct of_oxm_ipv6_exthdr : of_oxm {
+ uint32_t type_len == 0x80004e02;
+ uint16_t value;
+};
+
+struct of_oxm_ipv6_exthdr_masked : of_oxm {
+ uint32_t type_len == 0x80004f04;
+ uint16_t value;
+ uint16_t value_mask;
+};
diff --git a/openflow_input/oxm-1.4 b/openflow_input/oxm-1.4
new file mode 100644
index 0000000..0fd96ec
--- /dev/null
+++ b/openflow_input/oxm-1.4
@@ -0,0 +1,42 @@
+// Copyright 2014, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License,
+// version 1.0 (EPL), with the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may
+// distribute libraries generated by LoxiGen (LoxiGen Libraries)
+// under the terms of your choice, provided that copyright and
+// licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i)
+// included in the LoxiGen Libraries, if distributed in source code
+// form and (ii) included in any documentation for the LoxiGen
+// Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc.
+// This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or
+// LOXI Exception. You may obtain a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an "AS
+// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the EPL for the specific language
+// governing permissions and limitations under the EPL.
+
+#version 5
+
+struct of_oxm_pbb_uca : of_oxm {
+ uint32_t type_len == 0x80005201;
+ uint8_t value;
+};
+
+struct of_oxm_pbb_uca_masked : of_oxm {
+ uint32_t type_len == 0x80005302;
+ uint8_t value;
+ uint8_t value_mask;
+};
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 1146414..fa1a967 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -1701,7 +1701,7 @@
struct of_table_feature_prop_experimenter : of_table_feature_prop {
uint16_t type == 65534;
uint16_t length;
- uint32_t experimenter;
+ uint32_t experimenter == ?;
uint32_t subtype;
of_octets_t experimenter_data;
};
@@ -1709,7 +1709,7 @@
struct of_table_feature_prop_experimenter_miss : of_table_feature_prop {
uint16_t type == 65535;
uint16_t length;
- uint32_t experimenter;
+ uint32_t experimenter == ?;
uint32_t subtype;
of_octets_t experimenter_data;
};
diff --git a/openflow_input/standard-1.4 b/openflow_input/standard-1.4
new file mode 100644
index 0000000..54fce4a
--- /dev/null
+++ b/openflow_input/standard-1.4
@@ -0,0 +1,2674 @@
+// 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.
+//
+// Also derived from the OpenFlow header files which have these copyrights:
+// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+// Copyright (c) 2011, 2012 Open Networking Foundation
+
+#version 5
+
+enum macro_definitions {
+ OFP_MAX_TABLE_NAME_LEN = 32,
+ OFP_MAX_PORT_NAME_LEN = 16,
+
+ OFP_TCP_PORT = 6653,
+ OFP_SSL_PORT = 6653,
+
+ OFP_ETH_ALEN = 6,
+
+ OFP_DEFAULT_MISS_SEND_LEN = 128,
+
+ OFP_VLAN_NONE = 0,
+
+ OFP_FLOW_PERMANENT = 0,
+
+ OFP_DEFAULT_PRIORITY = 0x8000,
+
+ OFP_NO_BUFFER = 0xffffffff,
+
+ DESC_STR_LEN = 256,
+ SERIAL_NUM_LEN = 32,
+
+ OFPQ_ALL = 0xffffffff,
+ OFPQ_MAX_RATE_UNCFG = 0xffff,
+ OFPQ_MIN_RATE_UNCFG = 0xffff,
+};
+
+enum ofp_port(wire_type=uint32_t) {
+ OFPP_MAX = 0xffffff00,
+ OFPP_IN_PORT = 0xfffffff8,
+ OFPP_TABLE = 0xfffffff9,
+ OFPP_NORMAL = 0xfffffffa,
+ OFPP_FLOOD = 0xfffffffb,
+ OFPP_ALL = 0xfffffffc,
+ OFPP_CONTROLLER = 0xfffffffd,
+ OFPP_LOCAL = 0xfffffffe,
+ OFPP_ANY = 0xffffffff,
+};
+
+enum ofp_type(wire_type=uint8_t) {
+ OFPT_HELLO = 0,
+ OFPT_ERROR = 1,
+ OFPT_ECHO_REQUEST = 2,
+ OFPT_ECHO_REPLY = 3,
+ OFPT_EXPERIMENTER = 4,
+ OFPT_FEATURES_REQUEST = 5,
+ OFPT_FEATURES_REPLY = 6,
+ OFPT_GET_CONFIG_REQUEST = 7,
+ OFPT_GET_CONFIG_REPLY = 8,
+ OFPT_SET_CONFIG = 9,
+ OFPT_PACKET_IN = 10,
+ OFPT_FLOW_REMOVED = 11,
+ OFPT_PORT_STATUS = 12,
+ OFPT_PACKET_OUT = 13,
+ OFPT_FLOW_MOD = 14,
+ OFPT_GROUP_MOD = 15,
+ OFPT_PORT_MOD = 16,
+ OFPT_TABLE_MOD = 17,
+ OFPT_STATS_REQUEST = 18,
+ OFPT_STATS_REPLY = 19,
+ OFPT_BARRIER_REQUEST = 20,
+ OFPT_BARRIER_REPLY = 21,
+ OFPT_ROLE_REQUEST = 24,
+ OFPT_ROLE_REPLY = 25,
+ OFPT_GET_ASYNC_REQUEST = 26,
+ OFPT_GET_ASYNC_REPLY = 27,
+ OFPT_SET_ASYNC = 28,
+ OFPT_METER_MOD = 29,
+ OFPT_ROLE_STATUS = 30,
+ OFPT_TABLE_STATUS = 31,
+ OFPT_REQUESTFORWARD = 32,
+ OFPT_BUNDLE_CONTROL = 33,
+ OFPT_BUNDLE_ADD_MESSAGE = 34,
+};
+
+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(wire_type=uint32_t, bitmask=True) {
+ OFPTC_DEPRECATED_MASK = 0x3,
+ OFPTC_EVICTION = 0x4,
+ OFPTC_VACANCY_EVENTS = 0x8,
+};
+
+enum ofp_table(wire_type=uint8_t, complete=False) {
+ OFPTT_MAX = 0xfe,
+ OFPTT_ALL = 0xff,
+};
+
+enum ofp_capabilities(wire_type=uint32_t, bitmask=True) {
+ OFPC_FLOW_STATS = 0x1,
+ OFPC_TABLE_STATS = 0x2,
+ OFPC_PORT_STATS = 0x4,
+ OFPC_GROUP_STATS = 0x8,
+ OFPC_IP_REASM = 0x20,
+ OFPC_QUEUE_STATS = 0x40,
+ OFPC_PORT_BLOCKED = 0x100,
+};
+
+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,
+ OFPPC_BSN_MIRROR_DEST = 0x80000000,
+};
+
+enum ofp_port_state(wire_type=uint32_t, bitmask=True) {
+ OFPPS_LINK_DOWN = 0x1,
+ OFPPS_BLOCKED = 0x2,
+ OFPPS_LIVE = 0x4,
+};
+
+enum ofp_port_features(wire_type=uint32_t, bitmask=True) {
+ OFPPF_10MB_HD = 0x1,
+ OFPPF_10MB_FD = 0x2,
+ OFPPF_100MB_HD = 0x4,
+ OFPPF_100MB_FD = 0x8,
+ OFPPF_1GB_HD = 0x10,
+ OFPPF_1GB_FD = 0x20,
+ OFPPF_10GB_FD = 0x40,
+ OFPPF_40GB_FD = 0x80,
+ OFPPF_100GB_FD = 0x100,
+ OFPPF_1TB_FD = 0x200,
+ OFPPF_OTHER = 0x400,
+ OFPPF_COPPER = 0x800,
+ OFPPF_FIBER = 0x1000,
+ OFPPF_AUTONEG = 0x2000,
+ OFPPF_PAUSE = 0x4000,
+ OFPPF_PAUSE_ASYM = 0x8000,
+};
+
+enum ofp_port_reason(wire_type=uint8_t) {
+ OFPPR_ADD = 0,
+ OFPPR_DELETE = 1,
+ OFPPR_MODIFY = 2,
+};
+
+enum ofp_match_type(wire_type=uint16_t) {
+ OFPMT_STANDARD = 0,
+ OFPMT_OXM = 1,
+};
+
+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(wire_type=uint16_t) {
+ OFPVID_NONE = 0,
+ OFPVID_PRESENT = 0x1000,
+};
+
+// 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,
+ OFPIEH_DEST = 0x8,
+ OFPIEH_FRAG = 0x10,
+ OFPIEH_ROUTER = 0x20,
+ OFPIEH_HOP = 0x40,
+ OFPIEH_UNREP = 0x80,
+ OFPIEH_UNSEQ = 0x100,
+};
+
+enum ofp_action_type(wire_type=uint16_t) {
+ OFPAT_OUTPUT = 0,
+ OFPAT_COPY_TTL_OUT = 0xb,
+ OFPAT_COPY_TTL_IN = 0xc,
+ OFPAT_SET_MPLS_TTL = 0xf,
+ OFPAT_DEC_MPLS_TTL = 0x10,
+ OFPAT_PUSH_VLAN = 0x11,
+ OFPAT_POP_VLAN = 0x12,
+ OFPAT_PUSH_MPLS = 0x13,
+ OFPAT_POP_MPLS = 0x14,
+ OFPAT_SET_QUEUE = 0x15,
+ OFPAT_GROUP = 0x16,
+ OFPAT_SET_NW_TTL = 0x17,
+ OFPAT_DEC_NW_TTL = 0x18,
+ OFPAT_SET_FIELD = 0x19,
+ OFPAT_PUSH_PBB = 0x1a,
+ OFPAT_POP_PBB = 0x1b,
+ OFPAT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_controller_max_len(wire_type=uint16_t, complete=False) {
+ OFPCML_MAX = 0xffe5,
+ OFPCML_NO_BUFFER = 0xffff,
+};
+
+enum ofp_instruction_type(wire_type=uint16_t, bitmask=True) {
+ OFPIT_GOTO_TABLE = 0x1,
+ OFPIT_WRITE_METADATA = 0x2,
+ OFPIT_WRITE_ACTIONS = 0x3,
+ OFPIT_APPLY_ACTIONS = 0x4,
+ OFPIT_CLEAR_ACTIONS = 0x5,
+ OFPIT_METER = 0x6,
+ OFPIT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_flow_mod_command(wire_type=uint8_t) {
+ OFPFC_ADD = 0,
+ OFPFC_MODIFY = 1,
+ OFPFC_MODIFY_STRICT = 2,
+ OFPFC_DELETE = 3,
+ OFPFC_DELETE_STRICT = 4,
+};
+
+enum ofp_flow_mod_flags(wire_type=uint16_t, bitmask=True) {
+ OFPFF_SEND_FLOW_REM = 0x1,
+ OFPFF_CHECK_OVERLAP = 0x2,
+ OFPFF_RESET_COUNTS = 0x4,
+ OFPFF_NO_PKT_COUNTS = 0x8,
+ OFPFF_NO_BYT_COUNTS = 0x10,
+
+ /* Non-standard, enabled by an experimenter message */
+ /* See the bsn_flow_idle input file */
+ OFPFF_BSN_SEND_IDLE = 0x80,
+};
+
+enum ofp_group(wire_type=uint32_t, complete=False) {
+ OFPG_MAX = 0xffffff00,
+ OFPG_ALL = 0xfffffffc,
+ OFPG_ANY = 0xffffffff,
+};
+
+enum ofp_group_mod_command(wire_type=uint16_t) {
+ OFPGC_ADD = 0,
+ OFPGC_MODIFY = 1,
+ OFPGC_DELETE = 2,
+};
+
+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(wire_type=uint8_t) {
+ OFPR_NO_MATCH = 0,
+ OFPR_ACTION = 1,
+ OFPR_INVALID_TTL = 2,
+ OFPR_ACTION_SET = 3,
+ OFPR_GROUP = 4,
+ OFPR_PACKET_OUT = 5,
+
+ // non-standard BSN extensions. OF does not have a standard-conformant
+ // way to extend the set of packet_in reasons
+ OFPR_BSN_NEW_HOST = 128,
+ OFPR_BSN_STATION_MOVE = 129,
+ OFPR_BSN_BAD_VLAN = 130,
+ OFPR_BSN_DESTINATION_LOOKUP_FAILURE = 131,
+ OFPR_BSN_NO_ROUTE = 132,
+ OFPR_BSN_ICMP_ECHO_REQUEST = 133,
+ OFPR_BSN_DEST_NETWORK_UNREACHABLE = 134,
+ OFPR_BSN_DEST_HOST_UNREACHABLE = 135,
+ OFPR_BSN_DEST_PORT_UNREACHABLE = 136,
+ OFPR_BSN_FRAGMENTATION_REQUIRED = 137,
+ OFPR_BSN_ARP = 139,
+ OFPR_BSN_DHCP = 140,
+ OFPR_BSN_DEBUG = 141,
+ OFPR_BSN_PACKET_OF_DEATH = 142,
+};
+
+enum ofp_flow_removed_reason(wire_type=uint8_t) {
+ OFPRR_IDLE_TIMEOUT = 0,
+ OFPRR_HARD_TIMEOUT = 1,
+ OFPRR_DELETE = 2,
+ OFPRR_GROUP_DELETE = 3,
+ OFPRR_METER_DELETE = 4,
+ OFPRR_EVICTION = 5,
+};
+
+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(wire_type=uint16_t) {
+ OFPMBT_DROP = 0x1,
+ OFPMBT_DSCP_REMARK = 0x2,
+ OFPMBT_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_meter_mod_command(wire_type=uint16_t) {
+ OFPMC_ADD = 0,
+ OFPMC_MODIFY = 1,
+ OFPMC_DELETE = 2,
+};
+
+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(wire_type=uint16_t) {
+ OFPET_HELLO_FAILED = 0,
+ OFPET_BAD_REQUEST = 1,
+ OFPET_BAD_ACTION = 2,
+ OFPET_BAD_INSTRUCTION = 3,
+ OFPET_BAD_MATCH = 4,
+ OFPET_FLOW_MOD_FAILED = 5,
+ OFPET_GROUP_MOD_FAILED = 6,
+ OFPET_PORT_MOD_FAILED = 7,
+ OFPET_TABLE_MOD_FAILED = 8,
+ OFPET_QUEUE_OP_FAILED = 9,
+ OFPET_SWITCH_CONFIG_FAILED = 10,
+ OFPET_ROLE_REQUEST_FAILED = 11,
+ OFPET_METER_MOD_FAILED = 12,
+ OFPET_TABLE_FEATURES_FAILED = 13,
+ OFPET_BAD_PROPERTY = 14,
+ OFPET_ASYNC_CONFIG_FAILED = 15,
+ OFPET_FLOW_MONITOR_FAILED = 16,
+ OFPET_BUNDLE_FAILED = 17,
+ OFPET_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_hello_failed_code(wire_type=uint16_t) {
+ OFPHFC_INCOMPATIBLE = 0,
+ OFPHFC_EPERM = 1,
+};
+
+enum ofp_bad_request_code(wire_type=uint16_t) {
+ OFPBRC_BAD_VERSION = 0,
+ OFPBRC_BAD_TYPE = 1,
+ OFPBRC_BAD_STAT = 2,
+ OFPBRC_BAD_EXPERIMENTER = 3,
+ OFPBRC_BAD_EXPERIMENTER_TYPE = 4,
+ OFPBRC_EPERM = 5,
+ OFPBRC_BAD_LEN = 6,
+ OFPBRC_BUFFER_EMPTY = 7,
+ OFPBRC_BUFFER_UNKNOWN = 8,
+ OFPBRC_BAD_TABLE_ID = 9,
+ OFPBRC_IS_SLAVE = 10,
+ OFPBRC_BAD_PORT = 11,
+ OFPBRC_BAD_PACKET = 12,
+ OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13,
+ OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14,
+ OFPBRC_MULTIPART_REPLY_TIMEOUT = 15,
+};
+
+enum ofp_bad_action_code(wire_type=uint16_t) {
+ OFPBAC_BAD_TYPE = 0,
+ OFPBAC_BAD_LEN = 1,
+ OFPBAC_BAD_EXPERIMENTER = 2,
+ OFPBAC_BAD_EXPERIMENTER_TYPE = 3,
+ OFPBAC_BAD_OUT_PORT = 4,
+ OFPBAC_BAD_ARGUMENT = 5,
+ OFPBAC_EPERM = 6,
+ OFPBAC_TOO_MANY = 7,
+ OFPBAC_BAD_QUEUE = 8,
+ OFPBAC_BAD_OUT_GROUP = 9,
+ OFPBAC_MATCH_INCONSISTENT = 10,
+ OFPBAC_UNSUPPORTED_ORDER = 11,
+ OFPBAC_BAD_TAG = 12,
+ OFPBAC_BAD_SET_TYPE = 13,
+ OFPBAC_BAD_SET_LEN = 14,
+ OFPBAC_BAD_SET_ARGUMENT = 15,
+};
+
+enum ofp_bad_instruction_code(wire_type=uint16_t) {
+ OFPBIC_UNKNOWN_INST = 0,
+ OFPBIC_UNSUP_INST = 1,
+ OFPBIC_BAD_TABLE_ID = 2,
+ OFPBIC_UNSUP_METADATA = 3,
+ OFPBIC_UNSUP_METADATA_MASK = 4,
+ OFPBIC_BAD_EXPERIMENTER = 5,
+ OFPBIC_BAD_EXPERIMENTER_TYPE = 6,
+ OFPBIC_BAD_LEN = 7,
+ OFPBIC_EPERM = 8,
+ OFPBIC_DUP_INST = 9,
+};
+
+enum ofp_bad_match_code(wire_type=uint16_t) {
+ OFPBMC_BAD_TYPE = 0,
+ OFPBMC_BAD_LEN = 1,
+ OFPBMC_BAD_TAG = 2,
+ OFPBMC_BAD_DL_ADDR_MASK = 3,
+ OFPBMC_BAD_NW_ADDR_MASK = 4,
+ OFPBMC_BAD_WILDCARDS = 5,
+ OFPBMC_BAD_FIELD = 6,
+ OFPBMC_BAD_VALUE = 7,
+ OFPBMC_BAD_MASK = 8,
+ OFPBMC_BAD_PREREQ = 9,
+ OFPBMC_DUP_FIELD = 10,
+ OFPBMC_EPERM = 11,
+};
+
+enum ofp_flow_mod_failed_code(wire_type=uint16_t) {
+ OFPFMFC_UNKNOWN = 0,
+ OFPFMFC_TABLE_FULL = 1,
+ OFPFMFC_BAD_TABLE_ID = 2,
+ OFPFMFC_OVERLAP = 3,
+ OFPFMFC_EPERM = 4,
+ OFPFMFC_BAD_TIMEOUT = 5,
+ OFPFMFC_BAD_COMMAND = 6,
+ OFPFMFC_BAD_FLAGS = 7,
+ OFPFMFC_CANT_SYNC = 8,
+ OFPFMFC_BAD_PRIORITY = 9,
+};
+
+enum ofp_group_mod_failed_code(wire_type=uint16_t) {
+ OFPGMFC_GROUP_EXISTS = 0,
+ OFPGMFC_INVALID_GROUP = 1,
+ OFPGMFC_WEIGHT_UNSUPPORTED = 2,
+ OFPGMFC_OUT_OF_GROUPS = 3,
+ OFPGMFC_OUT_OF_BUCKETS = 4,
+ OFPGMFC_CHAINING_UNSUPPORTED = 5,
+ OFPGMFC_WATCH_UNSUPPORTED = 6,
+ OFPGMFC_LOOP = 7,
+ OFPGMFC_UNKNOWN_GROUP = 8,
+ OFPGMFC_CHAINED_GROUP = 9,
+ OFPGMFC_BAD_TYPE = 10,
+ OFPGMFC_BAD_COMMAND = 11,
+ OFPGMFC_BAD_BUCKET = 12,
+ OFPGMFC_BAD_WATCH = 13,
+ OFPGMFC_EPERM = 14,
+};
+
+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,
+ OFPPMFC_EPERM = 4,
+};
+
+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(wire_type=uint16_t) {
+ OFPQOFC_BAD_PORT = 0,
+ OFPQOFC_BAD_QUEUE = 1,
+ OFPQOFC_EPERM = 2,
+};
+
+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(wire_type=uint16_t){
+ OFPRRFC_STALE = 0,
+ OFPRRFC_UNSUP = 1,
+ OFPRRFC_BAD_ROLE = 2,
+};
+
+enum ofp_meter_mod_failed_code(wire_type=uint16_t) {
+ OFPMMFC_UNKNOWN = 0,
+ OFPMMFC_METER_EXISTS = 1,
+ OFPMMFC_INVALID_METER = 2,
+ OFPMMFC_UNKNOWN_METER = 3,
+ OFPMMFC_BAD_COMMAND = 4,
+ OFPMMFC_BAD_FLAGS = 5,
+ OFPMMFC_BAD_RATE = 6,
+ OFPMMFC_BAD_BURST = 7,
+ OFPMMFC_BAD_BAND = 8,
+ OFPMMFC_BAD_BAND_VALUE = 9,
+ OFPMMFC_OUT_OF_METERS = 10,
+ OFPMMFC_OUT_OF_BANDS = 11,
+};
+
+enum ofp_table_features_failed_code(wire_type=uint16_t) {
+ OFPTFFC_BAD_TABLE = 0,
+ OFPTFFC_BAD_METADATA = 1,
+ OFPTFFC_EPERM = 5,
+};
+
+enum ofp_bad_property_code(wire_type=uint16_t) {
+ OFPBPC_BAD_TYPE = 0, /* Unknown property type. */
+ OFPBPC_BAD_LEN = 1, /* Length problem in property. */
+ OFPBPC_BAD_VALUE = 2, /* Unsupported property value. */
+ OFPBPC_TOO_MANY = 3, /* Can’t handle this many properties. */
+ OFPBPC_DUP_TYPE = 4, /* A property type was duplicated. */
+ OFPBPC_BAD_EXPERIMENTER = 5, /* Unknown experimenter id specified. */
+ OFPBPC_BAD_EXP_TYPE = 6, /* Unknown exp_type for experimenter id. */
+ OFPBPC_BAD_EXP_VALUE = 7, /* Unknown value for experimenter id. */
+ OFPBPC_EPERM = 8, /* Permissions error. */
+};
+
+
+enum ofp_async_config_failed_code(wire_type=uint16_t) {
+ OFPACFC_INVALID = 0, /* One mask is invalid. */
+ OFPACFC_UNSUPPORTED = 1, /* Requested configuration not supported. */
+ OFPACFC_EPERM = 2, /* Permissions error. */
+};
+
+enum ofp_flow_monitor_failed_code(wire_type=uint16_t) {
+ OFPMOFC_UNKNOWN = 0, /* Unspecified error. */
+ OFPMOFC_MONITOR_EXISTS = 1, /* Monitor not added because a Monitor ADD
+ * attempted to replace an existing Monitor. */
+ OFPMOFC_INVALID_MONITOR = 2, /* Monitor not added because Monitor specified
+ * is invalid. */
+ OFPMOFC_UNKNOWN_MONITOR = 3, /* Monitor not modified because a Monitor
+ MODIFY attempted to modify a non-existent
+ Monitor. */
+ OFPMOFC_BAD_COMMAND = 4, /* Unsupported or unknown command. */
+ OFPMOFC_BAD_FLAGS = 5, /* Flag configuration unsupported. */
+ OFPMOFC_BAD_TABLE_ID = 6, /* Specified table does not exist. */
+ OFPMOFC_BAD_OUT = 7, /* Error in output port/group. */
+};
+
+enum ofp_bundle_failed_code(wire_type=uint16_t) {
+ OFPBFC_UNKNOWN = 0, /* Unspecified error. */
+ OFPBFC_EPERM = 1, /* Permissions error. */
+ OFPBFC_BAD_ID = 2, /* Bundle ID doesn’t exist. */
+ OFPBFC_BUNDLE_EXIST = 3, /* Bundle ID already exist. */
+ OFPBFC_BUNDLE_CLOSED = 4, /* Bundle ID is closed. */
+ OFPBFC_OUT_OF_BUNDLES = 5, /* Too many bundles IDs. */
+ OFPBFC_BAD_TYPE = 6, /* Unsupported or unknown message control type. */
+ OFPBFC_BAD_FLAGS = 7, /* Unsupported, unknown, or inconsistent flags. */
+ OFPBFC_MSG_BAD_LEN = 8, /* Length problem in included message. */
+ OFPBFC_MSG_BAD_XID = 9, /* Inconsistent or duplicate XID. */
+ OFPBFC_MSG_UNSUP = 10, /* Unsupported message in this bundle. */
+ OFPBFC_MSG_CONFLICT = 11, /* Unsupported message combination in this bundle. */
+ OFPBFC_MSG_TOO_MANY = 12, /* Cant handle this many messages in bundle. */
+ OFPBFC_MSG_FAILED = 13, /* One message in bundle failed. */
+ OFPBFC_TIMEOUT = 14, /* Bundle is taking too long. */
+ OFPBFC_BUNDLE_IN_PROGRESS = 15, /* Bundle is locking the resource. */
+};
+
+/* Port stats property types.
+ */
+enum ofp_port_stats_prop_type(wire_type=uint16_t) {
+ OFPPSPT_ETHERNET = 0, /* Ethernet property. */
+ OFPPSPT_OPTICAL = 1, /* Optical property. */
+ OFPPSPT_EXPERIMENTER = 0xFFFF, /* Experimenter property. */
+};
+
+
+enum ofp_stats_type(wire_type=uint16_t) {
+ OFPST_DESC = 0,
+ OFPST_FLOW = 1,
+ OFPST_AGGREGATE = 2,
+ OFPST_TABLE = 3,
+ OFPST_PORT = 4,
+ OFPST_QUEUE = 5,
+ OFPST_GROUP = 6,
+ OFPST_GROUP_DESC = 7,
+ OFPST_GROUP_FEATURES = 8,
+ OFPST_METER = 9,
+ OFPST_METER_CONFIG = 10,
+ OFPST_METER_FEATURES = 11,
+ OFPST_TABLE_FEATURES = 12,
+ OFPST_PORT_DESC = 13,
+ OFPMP_TABLE_DESC = 14,
+ OFPMP_QUEUE_DESC = 15,
+ OFPMP_FLOW_MONITOR = 16,
+ OFPST_EXPERIMENTER = 0xffff,
+};
+
+enum ofp_stats_request_flags(wire_type=uint16_t, bitmask=True) {
+ OFPSF_REQ_MORE = 0x1,
+};
+
+enum ofp_stats_reply_flags(wire_type=uint16_t, bitmask=True) {
+ OFPSF_REPLY_MORE = 0x1,
+};
+
+enum ofp_table_feature_prop_type(wire_type=uint16_t) {
+ OFPTFPT_INSTRUCTIONS = 0,
+ OFPTFPT_INSTRUCTIONS_MISS = 1,
+ OFPTFPT_NEXT_TABLES = 2,
+ OFPTFPT_NEXT_TABLES_MISS = 3,
+ OFPTFPT_WRITE_ACTIONS = 4,
+ OFPTFPT_WRITE_ACTIONS_MISS = 5,
+ OFPTFPT_APPLY_ACTIONS = 6,
+ OFPTFPT_APPLY_ACTIONS_MISS = 7,
+ OFPTFPT_MATCH = 8,
+ OFPTFPT_WILDCARDS = 0xa,
+ OFPTFPT_WRITE_SETFIELD = 0xc,
+ OFPTFPT_WRITE_SETFIELD_MISS = 0xd,
+ OFPTFPT_APPLY_SETFIELD = 0xe,
+ OFPTFPT_APPLY_SETFIELD_MISS = 0xf,
+ OFPTFPT_TABLE_SYNC_FROM = 0x10,
+ OFPTFPT_EXPERIMENTER = 0xfffe,
+ OFPTFPT_EXPERIMENTER_MISS = 0xffff,
+};
+
+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_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(wire_type=uint16_t) {
+ OFPHET_VERSIONBITMAP = 1,
+};
+
+enum ofp_optical_port_features(wire_type=uint32_t, bitmask=True) {
+ OFPOPF_RX_TUNE = 0x1,
+ OFPOPF_TX_TUNE = 0x2,
+ OFPOPF_TX_PWR = 0x4,
+ OFPOPF_USE_FREQ = 0x8,
+};
+
+enum ofp_table_mod_prop_eviction_flag(wire_type=uint32_t, bitmask=True) {
+ OFPTMPEF_OTHER = 0x1,
+ OFPTMPEF_IMPORTANCE = 0x2,
+ OFPTMPEF_LIFETIME = 0x4,
+};
+
+enum ofp_port_stats_optical_flags(wire_type=uint32_t, bitmask=True) {
+ OFPOSF_RX_TUNE = 0x1,
+ OFPOSF_TX_TUNE = 0x2,
+ OFPOSF_TX_PWR = 0x4,
+ OFPOSF_RX_PWR = 0x10,
+ OFPOSF_TX_BIAS = 0x20,
+ OFPOSF_TX_TEMP = 0x40,
+};
+
+enum ofp_bundle_ctrl_type(wire_type=uint16_t) {
+ OFPBCT_OPEN_REQUEST = 0,
+ OFPBCT_OPEN_REPLY = 1,
+ OFPBCT_CLOSE_REQUEST = 2,
+ OFPBCT_CLOSE_REPLY = 3,
+ OFPBCT_COMMIT_REQUEST = 4,
+ OFPBCT_COMMIT_REPLY = 5,
+ OFPBCT_DISCARD_REQUEST = 6,
+ OFPBCT_DISCARD_REPLY = 7,
+};
+
+enum ofp_bundle_flags(wire_type=uint16_t, bitmask=True) {
+ OFPBF_ATOMIC = 1,
+ OFPBF_ORDERED = 2,
+};
+
+enum ofp_controller_role_reason(wire_type=uint8_t) {
+ OFPCRR_MASTER_REQUEST = 0,
+ OFPCRR_CONFIG = 1,
+ OFPCRR_EXPERIMENTER = 2,
+};
+
+enum ofp_table_reason(wire_type=uint8_t) {
+ OFPTR_VACANCY_DOWN = 3,
+ OFPTR_VACANCY_UP = 4,
+};
+
+enum ofp_requestforward_reason {
+ OFPRFR_GROUP_MOD = 0,
+ OFPRFR_METER_MOD = 1,
+};
+
+/* XXX rename to of_message */
+struct of_header {
+ uint8_t version;
+ uint8_t type == ?;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_uint64 {
+ uint64_t value;
+};
+
+// Special structures used for managing scalar list elements
+struct of_uint32 {
+ uint32_t value;
+};
+
+// Special structures used for managing scalar list elements
+struct of_uint8 {
+ uint8_t value;
+};
+
+struct of_hello_elem {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_hello_elem_versionbitmap : of_hello_elem {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_uint32_t) bitmaps;
+};
+
+struct of_hello : of_header {
+ uint8_t version;
+ uint8_t type == 0;
+ uint16_t length;
+ uint32_t xid;
+ list(of_hello_elem_t) elements;
+};
+
+struct of_echo_request : of_header {
+ uint8_t version;
+ uint8_t type == 2;
+ uint16_t length;
+ uint32_t xid;
+ of_octets_t data;
+};
+
+struct of_echo_reply : of_header {
+ uint8_t version;
+ uint8_t type == 3;
+ uint16_t length;
+ uint32_t xid;
+ of_octets_t data;
+};
+
+struct of_experimenter : of_header {
+ uint8_t version;
+ uint8_t type == 4;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t data;
+};
+
+struct of_barrier_request : of_header {
+ uint8_t version;
+ uint8_t type == 20;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_barrier_reply : of_header {
+ uint8_t version;
+ uint8_t type == 21;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_get_config_request : of_header {
+ uint8_t version;
+ uint8_t type == 7;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_get_config_reply : of_header {
+ uint8_t version;
+ uint8_t type == 8;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_config_flags flags;
+ uint16_t miss_send_len;
+};
+
+struct of_set_config : of_header {
+ uint8_t version;
+ uint8_t type == 9;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_config_flags flags;
+ uint16_t miss_send_len;
+};
+
+struct of_table_mod_prop {
+ uint16_t type == ?; /* One of OFPTMPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_table_mod_prop_eviction {
+ uint16_t type == 2;
+ uint16_t length;
+ enum ofp_table_mod_prop_eviction_flag flags;
+};
+
+struct of_table_mod_prop_vacancy {
+ uint16_t type == 3;
+ uint16_t length;
+ uint8_t vacancy_down;
+ uint8_t vacancy_up;
+ uint8_t vacancy;
+ pad(1);
+};
+
+struct of_table_mod_prop_experimenter {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_table_mod : of_header {
+ uint8_t version;
+ uint8_t type == 17;
+ uint16_t length;
+ uint32_t xid;
+ uint8_t table_id;
+ pad(3);
+ uint32_t config;
+ list(of_table_mod_prop_t) properties;
+};
+
+struct of_port_desc_prop {
+ uint16_t type == ?; /* One of OFPPDPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_port_desc_prop_ethernet : of_port_desc_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ pad(4);
+ uint32_t curr;
+ uint32_t advertised;
+ uint32_t supported;
+ uint32_t peer;
+ uint32_t curr_speed;
+ uint32_t max_speed;
+};
+
+struct of_port_desc_prop_optical : of_port_desc_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ pad(4);
+ uint32_t supported;
+ uint32_t tx_min_freq_lmda;
+ uint32_t tx_max_freq_lmda;
+ uint32_t tx_grid_freq_lmda;
+ uint32_t rx_min_freq_lmda;
+ uint32_t rx_max_freq_lmda;
+ uint32_t rx_grid_freq_lmda;
+ uint32_t tx_pwr_min;
+ uint32_t tx_pwr_max;
+};
+
+struct of_port_desc_prop_experimenter : of_port_desc_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_port_desc {
+ of_port_no_t port_no;
+ uint16_t length;
+ pad(2);
+ of_mac_addr_t hw_addr;
+ pad(2);
+ of_port_name_t name;
+ enum ofp_port_config config; /* Bitmap of OFPPC_* flags. */
+ enum ofp_port_state state; /* Bitmap of OFPPS_* flags. */
+ list(of_port_desc_prop_t) properties;
+};
+
+struct of_features_request : of_header {
+ uint8_t version;
+ uint8_t type == 5;
+ uint16_t length;
+ uint32_t xid;
+};
+
+struct of_features_reply : of_header {
+ uint8_t version;
+ uint8_t type == 6;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t datapath_id;
+ uint32_t n_buffers;
+ uint8_t n_tables;
+ uint8_t auxiliary_id;
+ pad(2);
+ enum ofp_capabilities capabilities;
+ uint32_t reserved;
+};
+
+struct of_port_status : of_header {
+ uint8_t version;
+ uint8_t type == 12;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_port_reason reason;
+ pad(7);
+ of_port_desc_t desc;
+};
+
+struct of_port_mod_prop {
+ uint16_t type == ?; /* One of OFPPMPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+struct of_port_mod_prop_ethernet : of_port_mod_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ uint32_t advertise;
+};
+
+struct of_port_mod_prop_optical : of_port_mod_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ uint32_t configure;
+ uint32_t freq_ldma;
+ uint32_t fl_offset; /* TODO signed */
+ uint32_t grid_span;
+ uint32_t tx_pwr;
+};
+
+struct of_port_mod_prop_experimenter : of_port_mod_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_port_mod : of_header {
+ uint8_t version;
+ uint8_t type == 16;
+ uint16_t length;
+ uint32_t xid;
+ of_port_no_t port_no;
+ pad(4);
+ of_mac_addr_t hw_addr;
+ pad(2);
+ uint32_t config;
+ uint32_t mask;
+ list(of_port_mod_prop_t) properties;
+};
+
+struct of_match_v3(align=8, length_includes_align=False) {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_oxm_t) oxm_list;
+};
+
+// This looks like an action header, but is standalone. See
+// ofp_table_features_prop_actions
+struct of_action_id {
+ uint16_t type;
+ uint16_t len;
+ of_octets_t exp_data;
+};
+
+struct of_action_output : of_action {
+ uint16_t type == 0;
+ uint16_t len;
+ of_port_no_t port;
+ uint16_t max_len;
+ pad(6);
+};
+
+struct of_action_copy_ttl_out : of_action {
+ uint16_t type == 11;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_copy_ttl_in : of_action {
+ uint16_t type == 12;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_set_mpls_ttl : of_action {
+ uint16_t type == 15;
+ uint16_t len;
+ uint8_t mpls_ttl;
+ pad(3);
+};
+
+struct of_action_dec_mpls_ttl : of_action {
+ uint16_t type == 16;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_vlan : of_action {
+ uint16_t type == 17;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_pop_vlan : of_action {
+ uint16_t type == 18;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_mpls : of_action {
+ uint16_t type == 19;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_pop_mpls : of_action {
+ uint16_t type == 20;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action_set_queue : of_action {
+ uint16_t type == 21;
+ uint16_t len;
+ uint32_t queue_id;
+};
+
+struct of_action_group : of_action {
+ uint16_t type == 22;
+ uint16_t len;
+ uint32_t group_id;
+};
+
+struct of_action_set_nw_ttl : of_action {
+ uint16_t type == 23;
+ uint16_t len;
+ uint8_t nw_ttl;
+ pad(3);
+};
+
+struct of_action_dec_nw_ttl : of_action {
+ uint16_t type == 24;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_set_field(align=8, length_includes_align=True) : of_action {
+ uint16_t type == 25;
+ uint16_t len;
+ of_oxm_t field;
+};
+
+struct of_action_experimenter(align=8, length_includes_align=True): of_action {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == ?;
+ of_octets_t data;
+};
+
+struct of_action_pop_pbb : of_action {
+ uint16_t type == 27;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_action_push_pbb : of_action {
+ uint16_t type == 26;
+ uint16_t len;
+ uint16_t ethertype;
+ pad(2);
+};
+
+struct of_action {
+ uint16_t type == ?;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_instruction_id {
+ uint16_t type;
+ uint16_t len;
+};
+
+struct of_instruction {
+ uint16_t type == ?;
+ uint16_t len;
+};
+
+struct of_instruction_goto_table : of_instruction {
+ uint16_t type == 1;
+ uint16_t len;
+ uint8_t table_id;
+ pad(3);
+};
+
+struct of_instruction_write_metadata : of_instruction {
+ uint16_t type == 2;
+ uint16_t len;
+ pad(4);
+ uint64_t metadata;
+ uint64_t metadata_mask;
+};
+
+struct of_instruction_write_actions : of_instruction {
+ uint16_t type == 3;
+ uint16_t len;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_instruction_apply_actions : of_instruction {
+ uint16_t type == 4;
+ uint16_t len;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_instruction_clear_actions : of_instruction {
+ uint16_t type == 5;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_instruction_meter : of_instruction {
+ uint16_t type == 6;
+ uint16_t len;
+ uint32_t meter_id;
+};
+
+struct of_instruction_experimenter : of_instruction {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t experimenter == ?;
+ of_octets_t data;
+};
+
+struct of_flow_mod : of_header {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == ?;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ pad(2);
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_add : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 0;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_modify : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 1;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_modify_strict : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 2;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_delete : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 3;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_flow_delete_strict : of_flow_mod {
+ uint8_t version;
+ uint8_t type == 14;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ uint8_t table_id;
+ of_fm_cmd_t _command == 4;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint16_t priority;
+ uint32_t buffer_id;
+ of_port_no_t out_port;
+ uint32_t out_group;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+struct of_bucket {
+ uint16_t len;
+ uint16_t weight;
+ of_port_no_t watch_port;
+ uint32_t watch_group;
+ pad(4);
+ list(of_action_t) actions;
+};
+
+struct of_group_mod : of_header {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == ?;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_add : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 0;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_modify : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 1;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_group_delete : of_group_mod {
+ uint8_t version;
+ uint8_t type == 15;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_group_mod_command command == 2;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+struct of_packet_out : of_header {
+ uint8_t version;
+ uint8_t type == 13;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t buffer_id;
+ of_port_no_t in_port;
+ uint16_t actions_len;
+ pad(6);
+ list(of_action_t) actions;
+ of_octets_t data;
+};
+
+struct of_packet_in : of_header {
+ uint8_t version;
+ uint8_t type == 10;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t buffer_id;
+ uint16_t total_len;
+ uint8_t reason;
+ uint8_t table_id;
+ uint64_t cookie;
+ of_match_t match;
+ pad(2);
+ of_octets_t data;
+};
+
+struct of_flow_removed : of_header {
+ uint8_t version;
+ uint8_t type == 11;
+ uint16_t length;
+ uint32_t xid;
+ uint64_t cookie;
+ uint16_t priority;
+ uint8_t reason;
+ uint8_t table_id;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ uint64_t packet_count;
+ uint64_t byte_count;
+ of_match_t match;
+};
+
+struct of_meter_band {
+ uint16_t type == ?;
+ uint16_t len;
+// uint32_t rate; // These are excluded b/c this is the header
+// uint32_t burst_size; // These are excluded b/c this is the header
+};
+
+struct of_meter_band_drop : of_meter_band {
+ uint16_t type == 1;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ pad(4);
+};
+
+struct of_meter_band_dscp_remark : of_meter_band {
+ uint16_t type == 2;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ uint8_t prec_level;
+ pad(3);
+};
+
+struct of_meter_band_experimenter : of_meter_band {
+ uint16_t type == 65535;
+ uint16_t len;
+ uint32_t rate;
+ uint32_t burst_size;
+ uint32_t experimenter;
+};
+
+struct of_meter_mod : of_header {
+ uint8_t version;
+ uint8_t type == 29;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t command;
+ uint16_t flags;
+ uint32_t meter_id;
+ list(of_meter_band_t) bands;
+};
+
+struct of_error_msg : of_header {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == ?;
+};
+
+struct of_hello_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 0;
+ enum ofp_hello_failed_code code;
+ of_octets_t data;
+};
+
+struct of_bad_request_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 1;
+ enum ofp_bad_request_code code;
+ of_octets_t data;
+};
+
+struct of_bad_action_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 2;
+ enum ofp_bad_action_code code;
+ of_octets_t data;
+};
+
+struct of_bad_instruction_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 3;
+ enum ofp_bad_instruction_code code;
+ of_octets_t data;
+};
+
+struct of_bad_match_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 4;
+ enum ofp_bad_match_code code;
+ of_octets_t data;
+};
+
+struct of_flow_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 5;
+ enum ofp_flow_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_group_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 6;
+ enum ofp_group_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_port_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 7;
+ enum ofp_port_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_table_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 8;
+ enum ofp_table_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_queue_op_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 9;
+ enum ofp_queue_op_failed_code code;
+ of_octets_t data;
+};
+
+struct of_switch_config_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 10;
+ enum ofp_switch_config_failed_code code;
+ of_octets_t data;
+};
+
+struct of_role_request_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 11;
+ enum ofp_role_request_failed_code code;
+ of_octets_t data;
+};
+
+struct of_meter_mod_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 12;
+ enum ofp_meter_mod_failed_code code;
+ of_octets_t data;
+};
+
+struct of_table_features_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 13;
+ enum ofp_table_features_failed_code code;
+ of_octets_t data;
+};
+
+struct of_bad_property_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 14;
+ enum ofp_bad_property_code code;
+ of_octets_t data;
+};
+
+struct of_async_config_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 15;
+ enum ofp_async_config_failed_code code;
+ of_octets_t data;
+};
+
+struct of_flow_monitor_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 16;
+ enum ofp_flow_monitor_failed_code code;
+ of_octets_t data;
+};
+
+struct of_bundle_failed_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 17;
+ enum ofp_bundle_failed_code code;
+ of_octets_t data;
+};
+
+struct of_experimenter_error_msg : of_error_msg {
+ uint8_t version;
+ uint8_t type == 1;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t err_type == 0xffff;
+ uint16_t subtype;
+ uint32_t experimenter;
+ of_octets_t data;
+};
+
+// STATS ENTRIES: flow, table, port, queue, group stats, group desc stats
+
+struct of_flow_stats_entry {
+ uint16_t length;
+ uint8_t table_id;
+ pad(1);
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint16_t priority;
+ uint16_t idle_timeout;
+ uint16_t hard_timeout;
+ enum ofp_flow_mod_flags flags;
+ uint16_t importance;
+ pad(2);
+ uint64_t cookie;
+ uint64_t packet_count;
+ uint64_t byte_count;
+ of_match_t match;
+ list(of_instruction_t) instructions;
+};
+
+
+struct of_table_stats_entry {
+ uint8_t table_id;
+ pad(3);
+ uint32_t active_count;
+ uint64_t lookup_count;
+ uint64_t matched_count;
+};
+
+/* Common header for all port stats properties. */
+struct of_port_stats_prop {
+ uint16_t type == ?; /* One of OFPPSPT_*. */
+ uint16_t length; /* Length in bytes of this property. */
+};
+
+/* Ethernet port stats property. */
+struct of_port_stats_prop_ethernet : of_port_stats_prop {
+ uint16_t type == 0; /* OFPPSPT_ETHERNET. */
+ uint16_t length; /* Length in bytes of this property. */
+ pad(4);
+
+ uint64_t rx_frame_err; /* Number of frame alignment errors. */
+ uint64_t rx_over_err; /* Number of packets with RX overrun. */
+ uint64_t rx_crc_err; /* Number of CRC errors. */
+ uint64_t collisions; /* Number of collisions. */
+};
+
+/* Optical port stats property. */
+struct of_port_stats_prop_optical : of_port_stats_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ pad(4);
+
+ uint32_t flags;
+ uint32_t tx_freq_lmda;
+ uint32_t tx_offset;
+ uint32_t tx_grid_span;
+ uint32_t rx_freq_lmda;
+ uint32_t rx_offset;
+ uint32_t rx_grid_span;
+ uint16_t tx_pwr;
+ uint16_t rx_pwr;
+ uint16_t bias_current;
+ uint16_t temperature;
+};
+
+/* Experimenter port stats property. */
+struct of_port_stats_prop_experimenter : of_port_stats_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+ of_octets_t experimenter_data;
+};
+
+struct of_port_stats_entry {
+ uint16_t length;
+ pad(2);
+ of_port_no_t port_no;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ uint64_t rx_packets;
+ uint64_t tx_packets;
+ uint64_t rx_bytes;
+ uint64_t tx_bytes;
+ uint64_t rx_dropped;
+ uint64_t tx_dropped;
+ uint64_t rx_errors;
+ uint64_t tx_errors;
+ list(of_port_stats_prop_t) properties;
+};
+
+struct of_queue_stats_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_queue_stats_prop_experimenter : of_queue_stats_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_queue_stats_entry {
+ uint16_t length;
+ pad(6);
+ of_port_no_t port_no;
+ uint32_t queue_id;
+ uint64_t tx_bytes;
+ uint64_t tx_packets;
+ uint64_t tx_errors;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ list(of_queue_stats_prop_t) properties;
+};
+
+struct of_bucket_counter {
+ uint64_t packet_count;
+ uint64_t byte_count;
+};
+
+struct of_group_stats_entry {
+ uint16_t length;
+ pad(2);
+ uint32_t group_id;
+ uint32_t ref_count;
+ pad(4);
+ uint64_t packet_count;
+ uint64_t byte_count;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ list(of_bucket_counter_t) bucket_stats;
+};
+
+struct of_group_desc_stats_entry {
+ uint16_t length;
+ enum ofp_group_type group_type;
+ pad(1);
+ uint32_t group_id;
+ list(of_bucket_t) buckets;
+};
+
+// STATS:
+// Desc, flow, agg, table, port, queue, group, group_desc, group_feat, experi
+
+struct of_stats_request : of_header {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == ?;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_stats_reply : of_header {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == ?;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+};
+
+struct of_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ of_desc_str_t mfr_desc;
+ of_desc_str_t hw_desc;
+ of_desc_str_t sw_desc;
+ of_serial_num_t serial_num;
+ of_desc_str_t dp_desc;
+};
+
+struct of_flow_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 1;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint8_t table_id;
+ pad(3);
+ of_port_no_t out_port;
+ uint32_t out_group;
+ pad(4);
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ of_match_t match;
+};
+
+struct of_flow_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 1;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_flow_stats_entry_t) entries;
+};
+
+struct of_aggregate_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 2;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint8_t table_id;
+ pad(3);
+ of_port_no_t out_port;
+ uint32_t out_group;
+ pad(4);
+ uint64_t cookie;
+ uint64_t cookie_mask;
+ of_match_t match;
+};
+
+struct of_aggregate_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 2;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint64_t packet_count;
+ uint64_t byte_count;
+ uint32_t flow_count;
+ pad(4);
+};
+
+struct of_table_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 3;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_table_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 3;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_table_stats_entry_t) entries;
+};
+
+struct of_experimenter_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0xffff;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+};
+
+struct of_experimenter_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 0xffff;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+};
+
+// FIXME: These are padded to 8 byte align beyond the length indicated
+
+struct of_table_feature_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_table_feature_prop_instructions : of_table_feature_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ // FIXME Check if instruction_t is right for ids here
+ list(of_instruction_id_t) instruction_ids;
+};
+
+struct of_table_feature_prop_instructions_miss : of_table_feature_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ list(of_instruction_id_t) instruction_ids;
+};
+
+struct of_table_feature_prop_next_tables : of_table_feature_prop {
+ uint16_t type == 2;
+ uint16_t length;
+ list(of_uint8_t) next_table_ids;
+};
+
+struct of_table_feature_prop_next_tables_miss : of_table_feature_prop {
+ uint16_t type == 3;
+ uint16_t length;
+ list(of_uint8_t) next_table_ids;
+};
+
+struct of_table_feature_prop_write_actions : of_table_feature_prop {
+ uint16_t type == 4;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_write_actions_miss : of_table_feature_prop {
+ uint16_t type == 5;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_apply_actions : of_table_feature_prop {
+ uint16_t type == 6;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_apply_actions_miss : of_table_feature_prop {
+ uint16_t type == 7;
+ uint16_t length;
+ list(of_action_id_t) action_ids;
+};
+
+struct of_table_feature_prop_match : of_table_feature_prop {
+ uint16_t type == 8;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_wildcards : of_table_feature_prop {
+ uint16_t type == 10;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_write_setfield : of_table_feature_prop {
+ uint16_t type == 12;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_write_setfield_miss : of_table_feature_prop {
+ uint16_t type == 13;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_apply_setfield : of_table_feature_prop {
+ uint16_t type == 14;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_apply_setfield_miss : of_table_feature_prop {
+ uint16_t type == 15;
+ uint16_t length;
+ list(of_uint32_t) oxm_ids;
+};
+
+struct of_table_feature_prop_table_sync_from : of_table_feature_prop {
+ uint16_t type == 16;
+ uint16_t length;
+ list(of_uint8_t) table_ids;
+};
+
+struct of_table_feature_prop_experimenter : of_table_feature_prop {
+ uint16_t type == 65534;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t experimenter_data;
+};
+
+struct of_table_feature_prop_experimenter_miss : of_table_feature_prop {
+ uint16_t type == 65535;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t subtype;
+ of_octets_t experimenter_data;
+};
+
+struct of_table_features {
+ uint16_t length;
+ uint8_t table_id;
+ pad(5);
+ of_table_name_t name;
+ uint64_t metadata_match;
+ uint64_t metadata_write;
+ uint32_t config;
+ uint32_t max_entries;
+ list(of_table_feature_prop_t) properties;
+};
+
+struct of_meter_features {
+ uint32_t max_meter;
+ uint32_t band_types;
+ uint32_t capabilities;
+ uint8_t max_bands;
+ uint8_t max_color;
+ pad(2);
+};
+
+struct of_port_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 4;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ of_port_no_t port_no;
+ pad(4);
+};
+
+struct of_port_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 4;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_port_stats_entry_t) entries;
+};
+
+struct of_queue_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 5;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ of_port_no_t port_no;
+ uint32_t queue_id;
+};
+
+struct of_queue_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 5;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_queue_stats_entry_t) entries;
+};
+
+struct of_group_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 6;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t group_id;
+ pad(4);
+};
+
+struct of_group_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 6;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_group_stats_entry_t) entries;
+};
+
+struct of_group_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 7;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_group_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 7;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_group_desc_stats_entry_t) entries;
+};
+
+struct of_group_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 8;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_group_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 8;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ uint32_t types;
+ uint32_t capabilities;
+ uint32_t max_groups_all;
+ uint32_t max_groups_select;
+ uint32_t max_groups_indirect;
+ uint32_t max_groups_ff;
+ uint32_t actions_all;
+ uint32_t actions_select;
+ uint32_t actions_indirect;
+ uint32_t actions_ff;
+};
+
+struct of_meter_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 9;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t meter_id;
+ pad(4);
+};
+
+struct of_meter_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 9;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_meter_stats_t) entries;
+};
+
+struct of_meter_config_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 10;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ uint32_t meter_id;
+ pad(4);
+};
+
+struct of_meter_config_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 10;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_meter_band_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_meter_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 11;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+// FIXME stats added to get things working
+struct of_meter_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 11;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ of_meter_features_t features;
+};
+
+// FIXME stats added to get things working
+struct of_table_features_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 12;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+ list(of_table_features_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_table_features_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 12;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_table_features_t) entries;
+};
+
+// FIXME stats added to get things working
+struct of_port_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 13;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+// FIXME stats added to get things working
+struct of_port_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 13;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_port_desc_t) entries;
+};
+
+struct of_table_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 14;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_table_desc {
+ uint16_t length;
+ uint8_t table_id;
+ pad(1);
+ enum ofp_table_config config;
+};
+
+struct of_table_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 14;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_table_desc_t) entries;
+};
+
+struct of_queue_desc_stats_request : of_stats_request {
+ uint8_t version;
+ uint8_t type == 18;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 15;
+ enum ofp_stats_request_flags flags;
+ pad(4);
+};
+
+struct of_queue_desc_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_queue_desc_prop_min_rate : of_queue_desc_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ uint16_t rate;
+ pad(2);
+};
+
+struct of_queue_desc_prop_max_rate : of_queue_desc_prop {
+ uint16_t type == 2;
+ uint16_t length;
+ uint16_t rate;
+ pad(2);
+};
+
+struct of_queue_desc_prop_experimenter : of_queue_desc_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_queue_desc {
+ uint32_t port_no;
+ uint32_t queue_id;
+ uint16_t length;
+ pad(6);
+ list(of_queue_desc_prop_t) properties;
+};
+
+struct of_queue_desc_stats_reply : of_stats_reply {
+ uint8_t version;
+ uint8_t type == 19;
+ uint16_t length;
+ uint32_t xid;
+ uint16_t stats_type == 15;
+ enum ofp_stats_reply_flags flags;
+ pad(4);
+ list(of_queue_desc_t) entries;
+};
+
+/*
+ * Not supporting the flow monitor multipart messages. This message is
+ * poorly designed because it includes a variable length match inside a
+ * struct (ofp_flow_monitor_request) with no explicit length member.
+ * I'm not writing the special case code to figure out the total length.
+ */
+
+struct of_meter_band_stats {
+ uint64_t packet_band_count;
+ uint64_t byte_band_count;
+};
+
+struct of_meter_stats {
+ uint32_t meter_id;
+ uint16_t len;
+ pad(6);
+ uint32_t flow_count;
+ uint64_t packet_in_count;
+ uint64_t byte_in_count;
+ uint32_t duration_sec;
+ uint32_t duration_nsec;
+ list(of_meter_band_stats_t) band_stats;
+};
+
+struct of_meter_config {
+ uint16_t length;
+ uint16_t flags;
+ uint32_t meter_id;
+ list(of_meter_band_t) entries;
+};
+
+// END OF STATS OBJECTS
+
+struct of_queue_prop {
+ uint16_t type == ?;
+ uint16_t len;
+ pad(4);
+};
+
+struct of_queue_prop_min_rate : of_queue_prop {
+ uint16_t type == 1;
+ uint16_t len;
+ pad(4);
+ uint16_t rate;
+ pad(6);
+};
+
+struct of_queue_prop_max_rate : of_queue_prop {
+ uint16_t type == 2;
+ uint16_t len;
+ pad(4);
+ uint16_t rate;
+ pad(6);
+};
+
+struct of_queue_prop_experimenter : of_queue_prop {
+ uint16_t type == 65535;
+ uint16_t len;
+ pad(4);
+ uint32_t experimenter == ?;
+ pad(4);
+ of_octets_t data;
+};
+
+struct of_packet_queue {
+ uint32_t queue_id;
+ of_port_no_t port;
+ uint16_t len;
+ pad(6);
+ list(of_queue_prop_t) properties;
+};
+
+struct of_role_request : of_header {
+ uint8_t version;
+ uint8_t type == 24;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_controller_role role;
+ pad(4);
+ uint64_t generation_id;
+};
+
+struct of_role_reply : of_header {
+ uint8_t version;
+ uint8_t type == 25;
+ uint16_t length;
+ uint32_t xid;
+ enum ofp_controller_role role;
+ pad(4);
+ uint64_t generation_id;
+};
+
+/* Bundle messages */
+
+struct of_bundle_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_bundle_prop_experimenter : of_bundle_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_bundle_ctrl_msg : of_header {
+ uint8_t version;
+ uint8_t type == 33;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t bundle_id;
+ enum ofp_bundle_ctrl_type bundle_ctrl_type;
+ enum ofp_bundle_flags flags;
+ list(of_bundle_prop_t) properties;
+};
+
+struct of_bundle_add_msg : of_header {
+ uint8_t version;
+ uint8_t type == 34;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t bundle_id;
+ pad(2);
+ enum ofp_bundle_flags flags;
+ // TODO support embedding of_header
+ of_octets_t data;
+ // TODO support trailing properties
+};
+
+/* Async config messages */
+
+struct of_async_config_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_async_config_prop_packet_in_slave : of_async_config_prop {
+ uint16_t type == 0;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_packet_in_master : of_async_config_prop {
+ uint16_t type == 1;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_port_status_slave : of_async_config_prop {
+ uint16_t type == 2;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_port_status_master : of_async_config_prop {
+ uint16_t type == 3;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_flow_removed_slave : of_async_config_prop {
+ uint16_t type == 4;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_flow_removed_master : of_async_config_prop {
+ uint16_t type == 5;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_role_status_slave : of_async_config_prop {
+ uint16_t type == 6;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_role_status_master : of_async_config_prop {
+ uint16_t type == 7;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_table_status_slave : of_async_config_prop {
+ uint16_t type == 8;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_table_status_master : of_async_config_prop {
+ uint16_t type == 9;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_requestforward_slave : of_async_config_prop {
+ uint16_t type == 10;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_requestforward_master : of_async_config_prop {
+ uint16_t type == 11;
+ uint16_t length;
+ uint32_t mask;
+};
+
+struct of_async_config_prop_experimenter_slave : of_async_config_prop {
+ uint16_t type == 0xfffe;
+ uint16_t length;
+};
+
+struct of_async_config_prop_experimenter_master : of_async_config_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+};
+
+struct of_async_get_request : of_header {
+ uint8_t version;
+ uint8_t type == 26;
+ uint16_t length;
+ uint32_t xid;
+ list(of_async_config_prop_t) properties;
+};
+
+struct of_async_get_reply : of_header {
+ uint8_t version;
+ uint8_t type == 27;
+ uint16_t length;
+ uint32_t xid;
+ list(of_async_config_prop_t) properties;
+};
+
+struct of_async_set : of_header {
+ uint8_t version;
+ uint8_t type == 28;
+ uint16_t length;
+ uint32_t xid;
+ list(of_async_config_prop_t) properties;
+};
+
+/* Role status message */
+
+struct of_role_prop {
+ uint16_t type == ?;
+ uint16_t length;
+};
+
+struct of_role_prop_experimenter : of_role_prop {
+ uint16_t type == 0xffff;
+ uint16_t length;
+ uint32_t experimenter == ?;
+ uint32_t exp_type;
+};
+
+struct of_role_status : of_header {
+ uint8_t version;
+ uint8_t type == 30;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t role;
+ enum ofp_controller_role_reason reason;
+ pad(3);
+ uint64_t generation_id;
+ list(of_role_prop_t) properties;
+};
+
+/* Table status messages */
+
+struct of_table_status : of_header {
+ uint8_t version;
+ uint8_t type == 31;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t role;
+ enum ofp_table_reason reason;
+ pad(7);
+ of_table_desc_t table;
+};
+
+/* Request forward message */
+
+struct of_requestforward : of_header {
+ uint8_t version;
+ uint8_t type == 32;
+ uint16_t length;
+ uint32_t xid;
+ uint32_t role;
+ // TODO support embedding of_header
+ of_octets_t data;
+};
diff --git a/py_gen/codegen.py b/py_gen/codegen.py
index 3b0988e..f8a7211 100644
--- a/py_gen/codegen.py
+++ b/py_gen/codegen.py
@@ -43,6 +43,18 @@
'of_instruction_id': 'instruction_id',
'of_meter_band': 'meter_band',
'of_bsn_tlv': 'bsn_tlv',
+ 'of_port_desc_prop': 'port_desc_prop',
+ 'of_port_stats_prop': 'port_stats_prop',
+ 'of_port_mod_prop': 'port_mod_prop',
+ 'of_table_mod_prop': 'table_mod_prop',
+ 'of_queue_desc_prop': 'queue_desc_prop',
+ 'of_queue_stats_prop': 'queue_stats_prop',
+ 'of_async_config_prop': 'async_config_prop',
+ 'of_bundle_prop': 'bundle_prop',
+ #'of_queue_prop': 'queue_prop',
+ 'of_role_prop': 'role_prop',
+ #'of_table_feature_prop': 'table_feature_prop',
+ 'of_table_mod_prop': 'table_mod_prop',
}
# Return the module and class names for the generated Python class
diff --git a/py_gen/oftype.py b/py_gen/oftype.py
index 7bd242e..51b8e13 100644
--- a/py_gen/oftype.py
+++ b/py_gen/oftype.py
@@ -143,6 +143,7 @@
'of_port_desc_t': 'common.port_desc',
'of_meter_features_t': 'common.meter_features',
'of_bsn_vport_t': 'common.bsn_vport',
+ 'of_table_desc_t': 'common.table_desc',
}
for (cls, pyclass) in embedded_structs.items():
@@ -190,6 +191,7 @@
elif oftype_is_list(oftype):
ofproto = loxi_globals.ir[version]
ofclass = ofproto.class_by_name(oftype_list_elem(oftype))
+ assert ofclass, "No class named %r" % oftype_list_elem(oftype)
module_name, class_name = py_gen.codegen.generate_pyname(ofclass)
return 'loxi.generic_util.unpack_list(%s, %s.%s.unpack)' % \
(reader_expr, module_name, class_name)
diff --git a/py_gen/templates/_common_extra.py b/py_gen/templates/_common_extra.py
index 8639dc4..f801965 100644
--- a/py_gen/templates/_common_extra.py
+++ b/py_gen/templates/_common_extra.py
@@ -35,4 +35,7 @@
:: elif version == OFVersions.VERSION_1_3:
:: # HACK
match = match_v3
+:: elif version == OFVersions.VERSION_1_4:
+:: # HACK
+match = match_v3
:: #endif
diff --git a/py_gen/templates/toplevel_init.py b/py_gen/templates/toplevel_init.py
index e5493a5..0393169 100644
--- a/py_gen/templates/toplevel_init.py
+++ b/py_gen/templates/toplevel_init.py
@@ -39,20 +39,13 @@
"""
Import and return the protocol module for the given wire version.
"""
- if ver == 1:
- import of10
- return of10
- elif ver == 2:
- import of11
- return of11
- elif ver == 3:
- import of12
- return of12
- elif ver == 4:
- import of13
- return of13
- else:
- raise ValueError
+:: for v in loxi_globals.OFVersions.all_supported:
+ if ver == ${v.wire_version}:
+ import of${v.version.replace('.', '')}
+ return of${v.version.replace('.', '')}
+
+:: #endfor
+ raise ValueError
class ProtocolError(Exception):
"""
diff --git a/py_gen/tests/of14.py b/py_gen/tests/of14.py
new file mode 100644
index 0000000..3fdfb8e
--- /dev/null
+++ b/py_gen/tests/of14.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# Copyright 2014, 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 2014, 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 unittest
+from testutil import test_serialization
+from testutil import add_datafiles_tests
+
+try:
+ import loxi
+ import loxi.of14 as ofp
+ from loxi.generic_util import OFReader
+except ImportError:
+ exit("loxi package not found. Try setting PYTHONPATH.")
+
+class TestImports(unittest.TestCase):
+ def test_toplevel(self):
+ import loxi
+ self.assertTrue(hasattr(loxi, "ProtocolError"))
+ self.assertEquals(loxi.version_names[5], "1.4")
+ ofp = loxi.protocol(5)
+ self.assertEquals(ofp.OFP_VERSION, 5)
+ self.assertTrue(hasattr(ofp, "action"))
+ self.assertTrue(hasattr(ofp, "common"))
+ self.assertTrue(hasattr(ofp, "const"))
+ self.assertTrue(hasattr(ofp, "message"))
+ self.assertTrue(hasattr(ofp, "oxm"))
+
+ def test_version(self):
+ import loxi
+ self.assertTrue(hasattr(loxi.of14, "ProtocolError"))
+ self.assertTrue(hasattr(loxi.of14, "OFP_VERSION"))
+ self.assertEquals(loxi.of14.OFP_VERSION, 5)
+ self.assertTrue(hasattr(loxi.of14, "action"))
+ self.assertTrue(hasattr(loxi.of14, "common"))
+ self.assertTrue(hasattr(loxi.of14, "const"))
+ self.assertTrue(hasattr(loxi.of14, "message"))
+ self.assertTrue(hasattr(loxi.of14, "oxm"))
+
+# The majority of the serialization tests are created here using the files in
+# the test_data directory.
+class TestDataFiles(unittest.TestCase):
+ pass
+add_datafiles_tests(TestDataFiles, 'of14/', ofp)
+
+class TestAllof14(unittest.TestCase):
+ """
+ Round-trips every class through serialization/deserialization.
+ Not a replacement for handcoded tests because it only uses the
+ default member values.
+ """
+
+ def setUp(self):
+ mods = [ofp.action,ofp.message,ofp.common,ofp.oxm]
+ self.klasses = [klass for mod in mods
+ for klass in mod.__dict__.values()
+ if isinstance(klass, type) and
+ issubclass(klass, loxi.OFObject) and
+ not hasattr(klass, 'subtypes')]
+ self.klasses.sort(key=lambda x: str(x))
+
+ def test_serialization(self):
+ expected_failures = [
+ ofp.action.set_field, # field defaults to None
+ ]
+ for klass in self.klasses:
+ def fn():
+ obj = klass()
+ if hasattr(obj, "xid"): obj.xid = 42
+ buf = obj.pack()
+ obj2 = klass.unpack(OFReader(buf))
+ self.assertEquals(obj, obj2)
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+ def test_parse_message(self):
+ expected_failures = [
+ ]
+ for klass in self.klasses:
+ if not issubclass(klass, ofp.message.message):
+ continue
+ def fn():
+ obj = klass(xid=42)
+ buf = obj.pack()
+ obj2 = ofp.message.parse_message(buf)
+ self.assertEquals(obj, obj2)
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+ def test_show(self):
+ expected_failures = []
+ for klass in self.klasses:
+ def fn():
+ obj = klass()
+ if hasattr(obj, "xid"): obj.xid = 42
+ obj.show()
+ if klass in expected_failures:
+ self.assertRaises(Exception, fn)
+ else:
+ fn()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test_data/of10/flow_add.data b/test_data/of10/flow_add.data
index 60fd780..275a40e 100644
--- a/test_data/of10/flow_add.data
+++ b/test_data/of10/flow_add.data
@@ -117,19 +117,19 @@
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_object_t action;
+ of_action_output_init(&action, 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_output_port_set(&action, 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_object_t action;
+ of_action_nicira_dec_ttl_init(&action, 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_object_t action;
+ of_action_bsn_set_tunnel_dst_init(&action, OF_VERSION_1_0, -1, 1);
of_list_action_append_bind(&actions, &action);
}
}
diff --git a/test_data/of13/port_status.data b/test_data/of13/port_status.data
index 10f7c16..e56705f 100644
--- a/test_data/of13/port_status.data
+++ b/test_data/of13/port_status.data
@@ -34,3 +34,24 @@
peer=ofp.OFPPF_100MB_FD,
curr_speed=10,
max_speed=20))
+-- c
+obj = of_port_status_new(OF_VERSION_1_3);
+of_port_status_xid_set(obj, 0x12345678);
+of_port_status_reason_set(obj, OF_PORT_CHANGE_REASON_MODIFY);
+{
+ of_object_t desc;
+ of_port_status_desc_bind(obj, &desc);
+ of_port_desc_port_no_set(&desc, 4);
+ 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_config_set(&desc, OF_PORT_CONFIG_FLAG_NO_FWD|OF_PORT_CONFIG_FLAG_NO_RECV);
+ of_port_desc_state_set(&desc, OF_PORT_STATE_FLAG_BLOCKED);
+ of_port_desc_curr_set(&desc, OF_PORT_FEATURE_FLAG_10MB_HD);
+ of_port_desc_advertised_set(&desc, OF_PORT_FEATURE_FLAG_10MB_FD);
+ of_port_desc_supported_set(&desc, OF_PORT_FEATURE_FLAG_100MB_HD);
+ of_port_desc_peer_set(&desc, OF_PORT_FEATURE_FLAG_100MB_FD);
+ of_port_desc_curr_speed_set(&desc, 10);
+ of_port_desc_max_speed_set(&desc, 20);
+}
diff --git a/test_data/of14/flow_add.data b/test_data/of14/flow_add.data
new file mode 100644
index 0000000..88cf939
--- /dev/null
+++ b/test_data/of14/flow_add.data
@@ -0,0 +1,104 @@
+-- binary
+05 0e # version, type
+00 80 # length
+12 34 56 78 # xid
+
+fe dc ba 98 76 54 32 10 # cookie
+
+ff 00 ff 00 ff 00 ff 00 # cookie_mask
+
+03 # table_id
+00 # _command
+00 05 # idle_timeout
+00 0a # hard_timeout
+17 70 # priority
+
+00 00 00 32 # buffer_id
+00 00 00 06 # out_port
+
+00 00 00 08 # out_group
+00 00 # flags
+aa bb # importance
+
+00 01 # match.type
+00 3F # match.length # 59 bytes OXMs + 4 bytes match header
+
+80 00 01 08 # match.oxm_list[0].type_len - IN_PORT
+00 00 00 04 # match.oxm_list[0].value
+00 00 00 05 # match.oxm_list[0].mask
+
+80 00 0A 02 # match.oxm_list[1].type_len - ETH_TYPE
+86 DD # match.oxm_list[1].value - ETH_TYPE = IPv6
+
+80 00 14 01 # match.oxm_list[2].type_len - IP Proto
+06 # match.oxm_list[2].value = IP_PROTO = TCP
+
+80 00 35 20 # match.oxm_list[3].type_len - IPV6_SRC
+1C CA FE 1C B1 10 1C 00 00 28 00 00 00 00 00 00 # match.oxm_list[3].value
+FF FF FF FF FF F0 FF FF 1C 2C 3C 00 00 00 00 00 # match.oxm_list[3].mask
+
+00 # match.pad
+
+00 01 # instructions[0].type
+00 08 # instructions[0].length
+04 # instructions[0].table_id
+00 00 00 # pad
+
+00 01 # instructions[1].type
+00 08 # instructions[1].length
+07 # instructions[1].table_id
+00 00 00 # pad
+-- python
+ofp.message.flow_add(
+ xid=0x12345678,
+ cookie=0xFEDCBA9876543210,
+ cookie_mask=0xFF00FF00FF00FF00,
+ table_id=3,
+ idle_timeout=5,
+ hard_timeout=10,
+ priority=6000,
+ buffer_id=50,
+ out_port=6,
+ out_group=8,
+ flags=0,
+ importance=0xaabb,
+ match=ofp.match(oxm_list=[
+ ofp.oxm.in_port_masked(value=4, value_mask=5),
+ ofp.oxm.eth_type(value=0x86dd),
+ ofp.oxm.ip_proto(value=6),
+ ofp.oxm.ipv6_src_masked(
+ value ='\x1C\xCA\xFE\x1C\xB1\x10\x1C\x00\x00\x28\x00\x00\x00\x00\x00\x00',
+ value_mask='\xFF\xFF\xFF\xFF\xFF\xF0\xFF\xFF\x1C\x2C\x3C\x00\x00\x00\x00\x00')
+ ]),
+ instructions=[
+ ofp.instruction.goto_table(table_id=4),
+ ofp.instruction.goto_table(table_id=7)])
+-- java
+builder.setXid(0x12345678)
+ .setCookie(U64.parseHex("FEDCBA9876543210"))
+ .setCookieMask(U64.parseHex("FF00FF00FF00FF00"))
+ .setTableId(TableId.of(3))
+ .setIdleTimeout(5)
+ .setHardTimeout(10)
+ .setPriority(6000)
+ .setBufferId(OFBufferId.of(50))
+ .setOutPort(OFPort.of(6))
+ .setOutGroup(OFGroup.of(8))
+ .setFlags(ImmutableSet.<OFFlowModFlags>of())
+ .setImportance(0xaabb)
+ .setMatch(
+ factory.buildMatch()
+ .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
+ .setExact(MatchField.ETH_TYPE, EthType.IPv6)
+ .setExact(MatchField.IP_PROTO, IpProtocol.TCP)
+ .setMasked(MatchField.IPV6_SRC,
+ IPv6Address.of(0x1CCAFE1CB1101C00l, 0x0028000000000000l),
+ IPv6Address.of(0xFFFFFFFFFFF0FFFFl, 0x1C2C3C0000000000l))
+ .build()
+ )
+ .setInstructions(
+ ImmutableList.<OFInstruction>of(
+ factory.instructions().gotoTable(TableId.of(4)),
+ factory.instructions().gotoTable(TableId.of(7))
+ )
+ );
diff --git a/test_data/of14/port_desc_stats_reply.data b/test_data/of14/port_desc_stats_reply.data
new file mode 100644
index 0000000..8e38975
--- /dev/null
+++ b/test_data/of14/port_desc_stats_reply.data
@@ -0,0 +1,54 @@
+-- binary
+05 13 # version/type
+00 58 # length
+00 00 00 05 # xid
+00 0d # stats_type
+00 00 # flags
+00 00 00 00 # pad
+00 00 00 01 # entries[0].port_no
+00 48 # entries[0].length
+00 00 # pad
+01 02 03 04 05 06 # entries[0].hw_addr
+00 00 # pad
+69 6e 74 65 72 66 61 63 65 31 32 33 34 35 36 37 # entries[0].name
+00 00 00 60 # entries[0].config
+00 00 00 03 # entries[0].state
+00 00 # entries[0].properties[0].type (ethernet)
+00 20 # entries[0].properties[0].length
+00 00 00 00 # pad
+00 00 00 70 # entries[0].properties[0].curr
+00 00 00 00 # entries[0].properties[0].advertised
+00 00 00 00 # entries[0].properties[0].supported
+00 00 00 00 # entries[0].properties[0].peer
+00 00 00 00 # entries[0].properties[0].curr_speed
+00 00 00 80 # entries[0].properties[0].max_speed
+-- python
+ofp.message.port_desc_stats_reply(
+ xid=5, flags=0, entries=[
+ ofp.port_desc(
+ port_no=1,
+ hw_addr=[1,2,3,4,5,6],
+ name="interface1234567",
+ config=0x60,
+ state=0x03,
+ properties=[
+ ofp.port_desc_prop.ethernet(
+ curr=0x70,
+ max_speed=0x80)])])
+-- java
+builder
+ .setXid(5)
+ .setFlags(ImmutableSet.<OFStatsReplyFlags>of())
+ .setEntries(ImmutableList.of(
+ factory.buildPortDesc()
+ .setPortNo(OFPort.of(1))
+ .setHwAddr(MacAddress.of("01:02:03:04:05:06"))
+ .setName("interface1234567")
+ .setConfig(Sets.immutableEnumSet(OFPortConfig.NO_FWD, OFPortConfig.NO_PACKET_IN))
+ .setState(Sets.immutableEnumSet(OFPortState.LINK_DOWN, OFPortState.BLOCKED))
+ .setProperties(ImmutableList.<OFPortDescProp>of(factory.buildPortDescPropEthernet()
+ .setCurr(0x70)
+ .setMaxSpeed(0x80)
+ .build()))
+ .build())
+ );
diff --git a/test_data/of14/port_stats_reply.data b/test_data/of14/port_stats_reply.data
new file mode 100644
index 0000000..0ff4902
--- /dev/null
+++ b/test_data/of14/port_stats_reply.data
@@ -0,0 +1,104 @@
+-- binary
+05 13 # version/type
+00 d8 # length
+00 00 00 05 # xid
+00 04 # stats_type
+00 00 # flags
+00 00 00 00 # pad
+00 78 # entries[0].length
+00 00 # pad
+00 00 00 01 # entries[0].port_no
+00 00 00 00 # entries[0].duration_sec
+00 00 00 00 # entries[0].duration_nsec
+00 00 00 00 00 00 00 01 # entries[0].rx_packets
+00 00 00 00 00 00 00 00 # entries[0].tx_packets
+00 00 00 00 00 00 00 00 # entries[0].rx_bytes
+00 00 00 00 00 00 00 00 # entries[0].tx_bytes
+00 00 00 00 00 00 00 00 # entries[0].rx_dropped
+00 00 00 00 00 00 00 00 # entries[0].tx_dropped
+00 00 00 00 00 00 00 00 # entries[0].rx_errors
+00 00 00 00 00 00 00 02 # entries[0].tx_errors
+00 00 # entries[0].properties[0].type (ethernet)
+00 28 # entries[0].properties[0].length
+00 00 00 00 # pad
+00 00 00 00 00 00 00 01 # entries[0].properties[0].rx_frame_err
+00 00 00 00 00 00 00 02 # entries[0].properties[0].rx_over_err
+00 00 00 00 00 00 00 03 # entries[0].properties[0].rx_crc_err
+00 00 00 00 00 00 00 04 # entries[0].properties[0].collisions
+00 50 # entries[1].length
+00 00 # pad
+ff ff ff fe # entries[1].port_no
+00 00 00 00 # entries[1].duration_sec
+00 00 00 00 # entries[1].duration_nsec
+00 00 00 00 00 00 00 03 # entries[1].rx_packets
+00 00 00 00 00 00 00 00 # entries[1].tx_packets
+00 00 00 00 00 00 00 00 # entries[1].rx_bytes
+00 00 00 00 00 00 00 00 # entries[1].tx_bytes
+00 00 00 00 00 00 00 00 # entries[1].rx_dropped
+00 00 00 00 00 00 00 00 # entries[1].tx_dropped
+00 00 00 00 00 00 00 00 # entries[1].rx_errors
+00 00 00 00 00 00 00 04 # entries[1].tx_errors
+-- python
+ofp.message.port_stats_reply(
+ xid=5, flags=0, entries=[
+ ofp.port_stats_entry(port_no=1, rx_packets=1, tx_errors=2,
+ properties=[
+ ofp.port_stats_prop.ethernet(
+ rx_frame_err=1,
+ rx_over_err=2,
+ rx_crc_err=3,
+ collisions=4)]),
+ ofp.port_stats_entry(port_no=ofp.OFPP_LOCAL, rx_packets=3, tx_errors=4)])
+-- c
+obj = of_port_stats_reply_new(OF_VERSION_1_4);
+{
+ of_object_t list;
+ of_port_stats_reply_entries_bind(obj, &list);
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_4);
+ of_port_stats_entry_port_no_set(obj, 1);
+ of_port_stats_entry_rx_packets_set(obj, 1);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 2);
+
+ /* Append property */
+ {
+ of_object_t list;
+ of_port_stats_entry_properties_bind(obj, &list);
+ {
+ of_object_t *obj = of_port_stats_prop_ethernet_new(OF_VERSION_1_4);
+ of_port_stats_prop_ethernet_rx_frame_err_set(obj, 1);
+ of_port_stats_prop_ethernet_rx_over_err_set(obj, 2);
+ of_port_stats_prop_ethernet_rx_crc_err_set(obj, 3);
+ of_port_stats_prop_ethernet_collisions_set(obj, 4);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ }
+
+
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ {
+ of_object_t *obj = of_port_stats_entry_new(OF_VERSION_1_4);
+ of_port_stats_entry_port_no_set(obj, OF_PORT_DEST_LOCAL);
+ of_port_stats_entry_rx_packets_set(obj, 3);
+ of_port_stats_entry_tx_packets_set(obj, 0);
+ of_port_stats_entry_rx_bytes_set(obj, 0);
+ of_port_stats_entry_tx_bytes_set(obj, 0);
+ of_port_stats_entry_rx_dropped_set(obj, 0);
+ of_port_stats_entry_tx_dropped_set(obj, 0);
+ of_port_stats_entry_rx_errors_set(obj, 0);
+ of_port_stats_entry_tx_errors_set(obj, 4);
+ 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/of14/port_status.data b/test_data/of14/port_status.data
new file mode 100644
index 0000000..9fb5bde
--- /dev/null
+++ b/test_data/of14/port_status.data
@@ -0,0 +1,72 @@
+-- binary
+05 0c # version, type
+00 58 # length
+12 34 56 78 # xid
+02 # reason
+00 00 00 00 00 00 00 # pad
+00 00 00 04 # port_no
+00 48 # length
+00 00 # pad
+01 02 03 04 05 06 # hw_addr
+00 00 # pad
+66 6f 6f 00 00 00 00 00 # name
+00 00 00 00 00 00 00 00 # ...
+00 00 00 24 # config
+00 00 00 02 # state
+00 00 # properties[0].type (ethernet)
+00 20 # properties[0].length
+00 00 00 00 # pad
+00 00 00 01 # properties[0].curr
+00 00 00 02 # properties[0].advertised
+00 00 00 04 # properties[0].supported
+00 00 00 08 # properties[0].peer
+00 00 00 0a # properties[0].curr_speed
+00 00 00 14 # properties[0].max_speed
+-- python
+ofp.message.port_status(
+ xid=0x12345678,
+ reason=ofp.OFPPR_MODIFY,
+ desc=ofp.port_desc(
+ port_no=4,
+ hw_addr=[1,2,3,4,5,6],
+ name="foo",
+ config=ofp.OFPPC_NO_FWD|ofp.OFPPC_NO_RECV,
+ state=ofp.OFPPS_BLOCKED,
+ properties=[
+ ofp.port_desc_prop.ethernet(
+ curr=ofp.OFPPF_10MB_HD,
+ advertised=ofp.OFPPF_10MB_FD,
+ supported=ofp.OFPPF_100MB_HD,
+ peer=ofp.OFPPF_100MB_FD,
+ curr_speed=10,
+ max_speed=20)]))
+-- c
+obj = of_port_status_new(OF_VERSION_1_4);
+of_port_status_xid_set(obj, 0x12345678);
+of_port_status_reason_set(obj, OF_PORT_CHANGE_REASON_MODIFY);
+{
+ of_object_t desc;
+ of_port_status_desc_bind(obj, &desc);
+ of_port_desc_port_no_set(&desc, 4);
+ 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_config_set(&desc, OF_PORT_CONFIG_FLAG_NO_FWD|OF_PORT_CONFIG_FLAG_NO_RECV);
+ of_port_desc_state_set(&desc, OF_PORT_STATE_FLAG_BLOCKED);
+ {
+ of_list_port_desc_prop_t list;
+ of_port_desc_properties_bind(&desc, &list);
+ {
+ of_object_t *obj = of_port_desc_prop_ethernet_new(OF_VERSION_1_4);
+ of_port_desc_prop_ethernet_curr_set(obj, OF_PORT_FEATURE_FLAG_10MB_HD);
+ of_port_desc_prop_ethernet_advertised_set(obj, OF_PORT_FEATURE_FLAG_10MB_FD);
+ of_port_desc_prop_ethernet_supported_set(obj, OF_PORT_FEATURE_FLAG_100MB_HD);
+ of_port_desc_prop_ethernet_peer_set(obj, OF_PORT_FEATURE_FLAG_100MB_FD);
+ of_port_desc_prop_ethernet_curr_speed_set(obj, 10);
+ of_port_desc_prop_ethernet_max_speed_set(obj, 20);
+ of_list_append(&list, obj);
+ of_object_delete(obj);
+ }
+ }
+}
diff --git a/wireshark_gen/__init__.py b/wireshark_gen/__init__.py
index a610f3f..75918f8 100644
--- a/wireshark_gen/__init__.py
+++ b/wireshark_gen/__init__.py
@@ -38,7 +38,7 @@
DissectorField = namedtuple("DissectorField", ["fullname", "name", "type", "base", "enum_table"])
-proto_names = { 1: 'of10', 2: 'of11', 3: 'of12', 4: 'of13' }
+proto_names = { 1: 'of10', 2: 'of11', 3: 'of12', 4: 'of13', 5: 'of14' }
def make_field_name(version, ofclass_name, member_name):
return "%s.%s.%s" % (proto_names[version.wire_version],
ofclass_name[3:],