Merge into master from pull request #288:
add bsn_log extension (https://github.com/floodlight/loxigen/pull/288)
diff --git a/c_gen/build_of_g.py b/c_gen/build_of_g.py
index 4d37b36..9b19af6 100755
--- a/c_gen/build_of_g.py
+++ b/c_gen/build_of_g.py
@@ -242,6 +242,7 @@
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)
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index ee87d0d..191fcd3 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1081,172 +1081,6 @@
################################################################
#
-# List accessor code generation
-#
-# Currently these all implement copy on read semantics
-#
-################################################################
-
-def init_call(e_type, obj, ver, length, cw):
- """
- Generate the init call given the strings for params
- """
- hdr = "" # If inheritance type, coerce to hdr object
- obj_name = obj
- if e_type in type_maps.inheritance_map:
- hdr = "_header"
- obj_name = "(%s_header_t *)" % e_type + obj
-
- return """\
-%(e_type)s%(hdr)s_init(%(obj_name)s,
- %(ver)s, %(length)s, %(cw)s)\
-""" % dict(e_type=e_type, hdr=hdr, obj_name=obj_name, ver=ver,
- length=length, cw=cw)
-
-def gen_list_first(out, cls, e_type):
- """
- Generate the body of a list_first operation
- @param cls The class name for which code is being generated
- @param e_type The element type of the list
- @param out The file to which to write
- """
- i_call = init_call(e_type, "obj", "list->version", "0", "1")
- if e_type in type_maps.inheritance_map:
- len_str = "obj->header.length"
- else:
- len_str = "obj->length"
-
- out.write("""
-/**
- * Associate an iterator with a list
- * @param list The list to iterate over
- * @param obj The list entry iteration pointer
- * @return OF_ERROR_RANGE if the list is empty (end of list)
- *
- * The obj instance is completely initialized. The caller is responsible
- * for cleaning up any wire buffers associated with obj before this call
- */
-
-int
-%(cls)s_first(%(cls)s_t *list,
- %(e_type)s_t *obj)
-{
- int rv;
-
- %(i_call)s;
- if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
- return rv;
- }
-""" % dict(cls=cls, e_type=e_type, i_call=i_call))
-
- # Special case flow_stats_entry lists
-
- out.write("""
- of_object_wire_init((of_object_t *) obj, %(u_type)s,
- list->length);
- if (%(len_str)s == 0) {
- return OF_ERROR_PARSE;
- }
-
- return rv;
-}
-""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))
-
-def gen_list_next(out, cls, e_type):
- """
- Generate the body of a list_next operation
- @param cls The class name for which code is being generated
- @param e_type The element type of the list
- @param out The file to which to write
- """
-
- if e_type in type_maps.inheritance_map:
- len_str = "obj->header.length"
- else:
- len_str = "obj->length"
-
- out.write("""
-/**
- * Advance an iterator to the next element in a list
- * @param list The list being iterated
- * @param obj The list entry iteration pointer
- * @return OF_ERROR_RANGE if already at the last entry on the list
- *
- */
-
-int
-%(cls)s_next(%(cls)s_t *list,
- %(e_type)s_t *obj)
-{
- int rv;
-
- if ((rv = of_list_next((of_object_t *)list, (of_object_t *)obj)) < 0) {
- return rv;
- }
-
- rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
- list->length);
-
- if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
- return OF_ERROR_PARSE;
- }
-
- return rv;
-}
-""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))
-
-def gen_list_append(out, cls, e_type):
- """
- Generate the body of a list append functions
- @param cls The class name for which code is being generated
- @param e_type The element type of the list
- @param out The file to which to write
- """
-
- out.write("""
-/**
- * Set up to append an object of type %(e_type)s to an %(cls)s.
- * @param list The list that is prepared for append
- * @param obj Pointer to object to hold data to append
- *
- * The obj instance is completely initialized. The caller is responsible
- * for cleaning up any wire buffers associated with obj before this call.
- *
- * See the generic documentation for of_list_append_bind.
- */
-
-int
-%(cls)s_append_bind(%(cls)s_t *list,
- %(e_type)s_t *obj)
-{
- return of_list_append_bind((of_object_t *)list, (of_object_t *)obj);
-}
-
-/**
- * Append an item to a %(cls)s list.
- *
- * This copies data from item and leaves item untouched.
- *
- * See the generic documentation for of_list_append.
- */
-
-int
-%(cls)s_append(%(cls)s_t *list,
- %(e_type)s_t *item)
-{
- return of_list_append((of_object_t *)list, (of_object_t *)item);
-}
-
-""" % dict(cls=cls, e_type=e_type))
-
-def gen_list_accessors(out, cls):
- e_type = loxi_utils.list_to_entry_type(cls)
- gen_list_first(out, cls, e_type)
- gen_list_next(out, cls, e_type)
- gen_list_append(out, cls, e_type)
-
-################################################################
-#
# Accessor Functions
#
################################################################
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
index 7cb46db..b8a6757 100644
--- a/c_gen/codegen.py
+++ b/c_gen/codegen.py
@@ -43,6 +43,8 @@
import c_gen.of_g_legacy as of_g
import c_gen.type_maps as type_maps
import c_gen.c_type_maps as c_type_maps
+import loxi_utils.loxi_utils as loxi_utils
+import c_gen.loxi_utils_legacy as loxi_utils_legacy
CLASS_CHUNK_SIZE = 32
@@ -145,14 +147,24 @@
legacy_code=tmp.getvalue())
def generate_lists(install_dir):
- for cls in of_g.ordered_list_objects:
+ # Collect all the lists in use
+ list_oftypes = set()
+ for uclass in loxi_globals.unified.classes:
+ for ofclass in uclass.version_classes.values():
+ for m in ofclass.members:
+ if isinstance(m, ir.OFDataMember) and \
+ loxi_utils.oftype_is_list(m.oftype):
+ list_oftypes.add(m.oftype)
+
+ for oftype in sorted(list(list_oftypes)):
+ cls, e_cls = loxi_utils_legacy.list_name_extract(oftype)
+ e_cls = e_cls[:-2]
+ e_uclass = loxi_globals.unified.class_by_name(e_cls)
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)
+ util.render_template(out, "list.c", cls=cls, e_cls=e_cls, e_uclass=e_uclass,
+ wire_length_get=class_metadata_dict[e_cls].wire_length_get)
# Append legacy generated code
c_code_gen.gen_new_function_definitions(out, cls)
- c_code_gen.gen_list_accessors(out, cls)
def generate_strings(install_dir):
object_id_strs = []
@@ -182,159 +194,165 @@
ClassMetadata = namedtuple('ClassMetadata',
['name', 'wire_length_get', 'wire_length_set', 'wire_type_get', 'wire_type_set'])
+class_metadata = []
+class_metadata_dict = {}
+
+def build_class_metadata():
+ for uclass in loxi_globals.unified.classes:
+ wire_length_get = 'NULL'
+ wire_length_set = 'NULL'
+ wire_type_get = 'NULL'
+ wire_type_set = 'NULL'
+
+ if uclass and not uclass.virtual and uclass.has_type_members:
+ wire_type_set = '%s_push_wire_types' % uclass.name
+
+ if uclass.is_message:
+ wire_length_get = 'of_object_message_wire_length_get'
+ wire_length_set = 'of_object_message_wire_length_set'
+ elif uclass.is_action:
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_action_wire_object_id_get'
+ elif uclass.is_instanceof('of_bsn_vport'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_bsn_vport_wire_object_id_get'
+ elif uclass.is_action_id:
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_action_id_wire_object_id_get'
+ elif uclass.is_instruction:
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_instruction_wire_object_id_get'
+ elif uclass.is_instanceof('of_instruction_id'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_instruction_id_wire_object_id_get'
+ elif uclass.is_instanceof('of_queue_prop'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_queue_prop_wire_object_id_get'
+ elif uclass.is_instanceof('of_table_feature_prop'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_table_feature_prop_wire_object_id_get'
+ elif uclass.is_instanceof('of_meter_band'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_meter_band_wire_object_id_get'
+ elif uclass.is_instanceof('of_hello_elem'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_hello_elem_wire_object_id_get'
+ elif uclass.is_instanceof('of_bsn_tlv'):
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_get = 'of_bsn_tlv_wire_object_id_get'
+ elif uclass.is_oxm:
+ wire_length_get = 'of_oxm_wire_length_get'
+ wire_type_get = 'of_oxm_wire_object_id_get'
+ elif uclass.name == "of_packet_queue":
+ wire_length_get = 'of_packet_queue_wire_length_get'
+ wire_length_set = 'of_packet_queue_wire_length_set'
+ elif uclass.name == "of_meter_stats":
+ wire_length_get = 'of_meter_stats_wire_length_get'
+ wire_length_set = 'of_meter_stats_wire_length_set'
+ elif uclass.name in ["of_group_desc_stats_entry", "of_group_stats_entry",
+ "of_flow_stats_entry", "of_bucket", "of_table_features",
+ "of_bsn_port_counter_stats_entry", "of_bsn_vlan_counter_stats_entry",
+ "of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry",
+ "of_bsn_gentable_desc_stats_entry"]:
+ wire_length_get = "of_u16_len_wire_length_get"
+ wire_length_set = "of_u16_len_wire_length_set"
+ elif uclass.name == 'of_match_v3':
+ wire_length_set = 'of_tlv16_wire_length_set'
+ wire_length_get = 'of_tlv16_wire_length_get'
+ wire_type_set = 'of_match_v3_push_wire_types'
+
+ class_metadata.append(ClassMetadata(
+ name=uclass.name,
+ wire_length_get=wire_length_get,
+ wire_length_set=wire_length_set,
+ wire_type_get=wire_type_get,
+ wire_type_set=wire_type_set))
+
+ class_metadata.extend([
+ ClassMetadata(
+ name="of_action_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_action_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_action_id_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_action_id_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_bsn_vport_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_bsn_vport_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_instruction_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_instruction_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_instruction_id_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_instruction_id_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_queue_prop_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_queue_prop_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_table_feature_prop_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_table_feature_prop_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_meter_band_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_meter_band_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_hello_elem_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_hello_elem_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_bsn_tlv_header",
+ wire_length_set='of_tlv16_wire_length_set',
+ wire_length_get='of_tlv16_wire_length_get',
+ wire_type_get='of_bsn_tlv_wire_object_id_get',
+ wire_type_set='NULL'),
+ ClassMetadata(
+ name="of_oxm_header",
+ wire_length_set='NULL',
+ wire_length_get='of_oxm_wire_length_get',
+ wire_type_get='of_oxm_wire_object_id_get',
+ wire_type_set='NULL'),
+ ])
+
+ for metadata in class_metadata:
+ class_metadata_dict[metadata.name] = metadata
+
def generate_class_metadata(install_dir):
with template_utils.open_output(install_dir, "loci/inc/loci/loci_class_metadata.h") as out:
util.render_template(out, "loci_class_metadata.h")
with template_utils.open_output(install_dir, "loci/src/loci_class_metadata.c") as out:
- class_metadata = []
- for uclass in loxi_globals.unified.classes:
- wire_length_get = 'NULL'
- wire_length_set = 'NULL'
- wire_type_get = 'NULL'
- wire_type_set = 'NULL'
-
- if uclass and not uclass.virtual and uclass.has_type_members:
- wire_type_set = '%s_push_wire_types' % uclass.name
-
- if uclass.is_message and uclass.name != "of_header":
- wire_length_get = 'of_object_message_wire_length_get'
- wire_length_set = 'of_object_message_wire_length_set'
- elif uclass.is_action:
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_action_wire_object_id_get'
- elif uclass.is_instanceof('of_bsn_vport'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_bsn_vport_wire_object_id_get'
- elif uclass.is_action_id:
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_action_id_wire_object_id_get'
- elif uclass.is_instruction:
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_instruction_wire_object_id_get'
- elif uclass.is_instanceof('of_instruction_id'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_instruction_id_wire_object_id_get'
- elif uclass.is_instanceof('of_queue_prop'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_queue_prop_wire_object_id_get'
- elif uclass.is_instanceof('of_table_feature_prop'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_table_feature_prop_wire_object_id_get'
- elif uclass.is_instanceof('of_meter_band'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_meter_band_wire_object_id_get'
- elif uclass.is_instanceof('of_hello_elem'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_hello_elem_wire_object_id_get'
- elif uclass.is_instanceof('of_bsn_tlv'):
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_get = 'of_bsn_tlv_wire_object_id_get'
- elif uclass.is_oxm:
- wire_length_get = 'of_oxm_wire_length_get'
- wire_type_get = 'of_oxm_wire_object_id_get'
- elif uclass.name == "of_packet_queue":
- wire_length_get = 'of_packet_queue_wire_length_get'
- wire_length_set = 'of_packet_queue_wire_length_set'
- elif uclass.name == "of_meter_stats":
- wire_length_get = 'of_meter_stats_wire_length_get'
- wire_length_set = 'of_meter_stats_wire_length_set'
- elif uclass.name in ["of_group_desc_stats_entry", "of_group_stats_entry",
- "of_flow_stats_entry", "of_bucket", "of_table_features",
- "of_bsn_port_counter_stats_entry", "of_bsn_vlan_counter_stats_entry",
- "of_bsn_gentable_entry_desc_stats_entry", "of_bsn_gentable_entry_stats_entry",
- "of_bsn_gentable_desc_stats_entry"]:
- wire_length_get = "of_u16_len_wire_length_get"
- wire_length_set = "of_u16_len_wire_length_set"
- elif uclass.name == 'of_match_v3':
- wire_length_set = 'of_tlv16_wire_length_set'
- wire_length_get = 'of_tlv16_wire_length_get'
- wire_type_set = 'of_match_v3_push_wire_types'
-
- class_metadata.append(ClassMetadata(
- name=uclass.name,
- wire_length_get=wire_length_get,
- wire_length_set=wire_length_set,
- wire_type_get=wire_type_get,
- wire_type_set=wire_type_set))
-
- class_metadata.extend([
- ClassMetadata(
- name="of_action_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_action_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_action_id_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_action_id_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_bsn_vport_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_bsn_vport_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_instruction_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_instruction_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_instruction_id_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_instruction_id_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_queue_prop_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_queue_prop_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_table_feature_prop_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_table_feature_prop_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_meter_band_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_meter_band_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_hello_elem_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_hello_elem_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_bsn_tlv_header",
- wire_length_set='of_tlv16_wire_length_set',
- wire_length_get='of_tlv16_wire_length_get',
- wire_type_get='of_bsn_tlv_wire_object_id_get',
- wire_type_set='NULL'),
- ClassMetadata(
- name="of_oxm_header",
- wire_length_set='NULL',
- wire_length_get='of_oxm_wire_length_get',
- wire_type_get='of_oxm_wire_object_id_get',
- wire_type_set='NULL'),
- ])
-
util.render_template(out, "loci_class_metadata.c", class_metadata=class_metadata)
diff --git a/c_gen/templates/list.c b/c_gen/templates/list.c
new file mode 100644
index 0000000..9ff6e42
--- /dev/null
+++ b/c_gen/templates/list.c
@@ -0,0 +1,125 @@
+:: # 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.
+::
+:: include('_copyright.c')
+:: include('_pragmas.c')
+
+#include "loci_log.h"
+#include "loci_int.h"
+
+/**
+ * Associate an iterator with a list
+ * @param list The list to iterate over
+ * @param obj The list entry iteration pointer
+ * @return OF_ERROR_RANGE if the list is empty (end of list)
+ *
+ * The obj instance is completely initialized. The caller is responsible
+ * for cleaning up any wire buffers associated with obj before this call
+ */
+
+int
+${cls}_first(${cls}_t *list, ${e_cls}_t *_obj)
+{
+ int rv;
+ of_object_t *obj = (of_object_t *)_obj;
+
+ ${e_cls}_init(_obj, list->version, -1, 1);
+
+ if ((rv = of_list_first(list, obj)) < 0) {
+ return rv;
+ }
+
+:: if e_uclass.virtual:
+ ${e_cls}_wire_object_id_get(obj, &obj->object_id);
+:: #endif
+
+:: if wire_length_get != 'NULL':
+ ${wire_length_get}(obj, &obj->length);
+:: #endif
+
+ return rv;
+}
+
+/**
+ * Advance an iterator to the next element in a list
+ * @param list The list being iterated
+ * @param obj The list entry iteration pointer
+ * @return OF_ERROR_RANGE if already at the last entry on the list
+ *
+ */
+
+int
+${cls}_next(${cls}_t *list, ${e_cls}_t *_obj)
+{
+ int rv;
+ of_object_t *obj = (of_object_t *)_obj;
+
+ if ((rv = of_list_next(list, obj)) < 0) {
+ return rv;
+ }
+
+:: if e_uclass.virtual:
+ ${e_cls}_wire_object_id_get(obj, &obj->object_id);
+:: #endif
+
+:: if wire_length_get != 'NULL':
+ ${wire_length_get}(obj, &obj->length);
+:: #endif
+
+ return rv;
+}
+
+/**
+ * Set up to append an object of type ${e_cls} to an ${cls}.
+ * @param list The list that is prepared for append
+ * @param obj Pointer to object to hold data to append
+ *
+ * The obj instance is completely initialized. The caller is responsible
+ * for cleaning up any wire buffers associated with obj before this call.
+ *
+ * See the generic documentation for of_list_append_bind.
+ */
+
+int
+${cls}_append_bind(${cls}_t *list, ${e_cls}_t *obj)
+{
+ return of_list_append_bind(list, (of_object_t *)obj);
+}
+
+/**
+ * Append an object to a ${cls} list.
+ *
+ * This copies data from obj and leaves item untouched.
+ *
+ * See the generic documentation for of_list_append.
+ */
+
+int
+${cls}_append(${cls}_t *list, ${e_cls}_t *obj)
+{
+ return of_list_append(list, (of_object_t *)obj);
+}
diff --git a/c_gen/templates/of_object.c b/c_gen/templates/of_object.c
index b0d3e14..5647d81 100644
--- a/c_gen/templates/of_object.c
+++ b/c_gen/templates/of_object.c
@@ -455,7 +455,7 @@
return OF_ERROR_RANGE;
}
- object_child_attach(parent, child, 0, 0);
+ of_object_attach(parent, child, 0, child->length);
return OF_ERROR_NONE;
}
@@ -508,7 +508,7 @@
/* Offset is relative to parent start */
offset = (child->obj_offset - parent->obj_offset) +
child->length;
- object_child_attach(parent, child, offset, 0);
+ of_object_attach(parent, child, offset, child->length);
return OF_ERROR_NONE;
}
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 13b879a..9fa59e0 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -37,9 +37,6 @@
#include <loci/loci.h>
#include <loci/of_message.h>
-#define OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET 4
-#define OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET 8
-
${legacy_code}
/****************************************************************
@@ -308,53 +305,3 @@
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
}
-
-int
-of_experimenter_stats_request_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
-{
- switch (experimenter) {
- case OF_EXPERIMENTER_ID_BSN:
- switch (subtype) {
- case 1: return OF_BSN_LACP_STATS_REQUEST;
- case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REQUEST;
- case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REQUEST;
- case 4: return OF_BSN_GENTABLE_DESC_STATS_REQUEST;
- case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REQUEST;
- case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REQUEST;
- case 7: return OF_BSN_GENTABLE_STATS_REQUEST;
- case 8: return OF_BSN_PORT_COUNTER_STATS_REQUEST;
- case 9: return OF_BSN_VLAN_COUNTER_STATS_REQUEST;
- case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REQUEST;
- case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REQUEST;
- case 12: return OF_BSN_DEBUG_COUNTER_STATS_REQUEST;
- case 13: return OF_BSN_DEBUG_COUNTER_DESC_STATS_REQUEST;
- case 14: return OF_BSN_IMAGE_DESC_STATS_REQUEST;
- }
- }
- return OF_OBJECT_INVALID;
-}
-
-int
-of_experimenter_stats_reply_to_object_id(uint32_t experimenter, uint32_t subtype, int ver)
-{
- switch (experimenter) {
- case OF_EXPERIMENTER_ID_BSN:
- switch (subtype) {
- case 1: return OF_BSN_LACP_STATS_REPLY;
- case 2: return OF_BSN_GENTABLE_ENTRY_DESC_STATS_REPLY;
- case 3: return OF_BSN_GENTABLE_ENTRY_STATS_REPLY;
- case 4: return OF_BSN_GENTABLE_DESC_STATS_REPLY;
- case 5: return OF_BSN_GENTABLE_BUCKET_STATS_REPLY;
- case 6: return OF_BSN_SWITCH_PIPELINE_STATS_REPLY;
- case 7: return OF_BSN_GENTABLE_STATS_REPLY;
- case 8: return OF_BSN_PORT_COUNTER_STATS_REPLY;
- case 9: return OF_BSN_VLAN_COUNTER_STATS_REPLY;
- case 10: return OF_BSN_FLOW_CHECKSUM_BUCKET_STATS_REPLY;
- case 11: return OF_BSN_TABLE_CHECKSUM_STATS_REPLY;
- case 12: return OF_BSN_DEBUG_COUNTER_STATS_REPLY;
- case 13: return OF_BSN_DEBUG_COUNTER_DESC_STATS_REPLY;
- case 14: return OF_BSN_IMAGE_DESC_STATS_REPLY;
- }
- }
- return OF_OBJECT_INVALID;
-}
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 14878c3..8c06379 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -681,6 +681,7 @@
'of_bucket' : { 'watch_group': of_group },
'of_bsn_tlv_vlan_vid' : { 'value' : vlan_vid },
+ 'of_bsn_table_set_buckets_size' : { 'table_id' : table_id },
'of_bsn_gentable_entry_add' : { 'table_id' : gen_table_id },
'of_features_reply' : { 'auxiliary_id' : of_aux_id},
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index fd595ce..338172f 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -10,7 +10,7 @@
<groupId>org.projectfloodlight</groupId>
<artifactId>openflowj</artifactId>
- <version>0.3.6-SNAPSHOT</version>
+ <version>0.3.7-SNAPSHOT</version>
<packaging>jar</packaging>
<name>OpenFlowJ-Loxi</name>
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
index fb5cd23..18f524e 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
@@ -10,6 +10,8 @@
import static org.junit.Assert.fail;
import org.hamcrest.Matchers;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.Test;
import com.google.common.hash.HashCode;
@@ -27,6 +29,22 @@
}
@Test
+ public void testReadBytes() {
+ ChannelBuffer empty = ChannelBuffers.wrappedBuffer(new byte[16]);
+ U128 uEmpty = U128.read16Bytes(empty);
+ assertThat(uEmpty.getMsb(), equalTo(0L));
+ assertThat(uEmpty.getLsb(), equalTo(0L));
+
+ ChannelBuffer value = ChannelBuffers.wrappedBuffer(
+ new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88,
+ (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd,
+ (byte) 0xee, (byte) 0xff, 0x11 });
+ U128 uValue = U128.read16Bytes(value);
+ assertThat(uValue.getMsb(), equalTo(0x1122334455667788L));
+ assertThat(uValue.getLsb(), equalTo(0x99aabbccddeeff11L));
+ }
+
+ @Test
public void testPutTo() {
U128 h = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
U128 hSame = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
diff --git a/lang_c.py b/lang_c.py
index 8e153fe..c7b68f7 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -123,6 +123,7 @@
for (name, fn) in targets.items():
with template_utils.open_output(install_dir, name) as outfile:
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)
diff --git a/loxi_utils/loxi_utils.py b/loxi_utils/loxi_utils.py
index 865891f..c86c503 100644
--- a/loxi_utils/loxi_utils.py
+++ b/loxi_utils/loxi_utils.py
@@ -177,3 +177,11 @@
return enum.params['wire_type']
else:
return oftype
+
+def oftype_is_list(oftype):
+ return (oftype.find("list(") == 0)
+
+# Converts "list(of_flow_stats_entry_t)" to "of_flow_stats_entry"
+def oftype_list_elem(oftype):
+ assert oftype.find("list(") == 0
+ return oftype[5:-3]
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 19940ac..64a465d 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -1378,7 +1378,7 @@
uint16_t priority;
uint16_t idle_timeout;
uint16_t hard_timeout;
- uint16_t flags;
+ enum ofp_flow_mod_flags flags;
pad(4);
uint64_t cookie;
uint64_t packet_count;