Merge into master from pull request #154:
java_gen: dedicated factories for (action|instruction)_id, erromsg (https://github.com/floodlight/loxigen/pull/154)
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index e2bb467..640687f 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -37,6 +37,7 @@
from c_gen import flags, type_maps, c_type_maps
import c_gen.loxi_utils_legacy as loxi_utils
from c_gen.loxi_utils_legacy import config_check
+import loxi_globals
import c_gen.identifiers as identifiers
@@ -425,7 +426,6 @@
of_match_t *match);
extern int of_wire_buffer_of_match_set(of_object_t *obj, int offset,
of_match_t *match, int cur_len);
-extern void of_extension_object_id_set(of_object_t *obj, of_object_id_t id);
""")
# gen_base_types(out)
@@ -785,6 +785,7 @@
#include <loci/loci.h>
#include <loci/of_object.h>
#include "loci_log.h"
+#include "loci_push_wire_types.h"
""")
gen_object_enum_str(out)
@@ -2501,7 +2502,7 @@
typedef void (*of_wire_length_get_f)(of_object_t *obj, int *bytes);
typedef void (*of_wire_length_set_f)(of_object_t *obj, int bytes);
typedef void (*of_wire_type_get_f)(of_object_t *obj, of_object_id_t *id);
-typedef void (*of_wire_type_set_f)(of_object_t *obj, of_object_id_t id);
+typedef void (*of_wire_type_set_f)(of_object_t *obj);
""")
# If not using function pointers in classes, don't gen typedefs below
if not config_check("gen_fn_ptrs"):
@@ -2687,62 +2688,30 @@
{
""" % 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; push version, length and type to wire */
+ /* Message obj; set length */
of_message_t msg;
if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
- of_message_version_set(msg, obj->version);
of_message_length_set(msg, obj->length);
- OF_TRY(of_wire_message_object_id_set(OF_OBJECT_TO_WBUF(obj),
- %(name)s));
}
""" % dict(name = enum_name(cls)))
- for version in of_g.of_version_range:
- if type_maps.class_is_extension(cls, version):
- exp_name = type_maps.extension_to_experimenter_macro_name(cls)
- subtype = type_maps.extension_message_to_subtype(cls, version)
- if subtype is None or exp_name is None:
- print "Error in mapping extension message"
- print cls, version
- sys.exit(1)
- out.write("""
- if (obj->version == %(version)s) {
- of_message_experimenter_id_set(OF_OBJECT_TO_MESSAGE(obj),
- %(exp_name)s);
- of_message_experimenter_subtype_set(OF_OBJECT_TO_MESSAGE(obj),
- %(subtype)s);
- }
-""" % dict(exp_name=exp_name, version=of_g.wire_ver_map[version],
- subtype=str(subtype)))
-
else: # Not a message
if loxi_utils.class_is_tlv16(cls):
out.write("""
- /* TLV obj; set length and type */
+ /* TLV obj; set length */
of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
- of_tlv16_wire_object_id_set((of_object_t *)obj,
- %(enum)s);
""" % dict(enum=enum_name(cls)))
- # Some tlv16 types may be extensions requiring more work
- if cls in ["of_action_bsn_mirror", "of_action_id_bsn_mirror",
- "of_action_bsn_set_tunnel_dst", "of_action_id_bsn_set_tunnel_dst",
- "of_action_nicira_dec_ttl", "of_action_id_nicira_dec_ttl",
- "of_instruction_bsn_disable_src_mac_check"]:
- out.write("""
- /* Extended TLV obj; Call specific accessor */
- of_extension_object_id_set(obj, %(enum)s);
-""" % dict(cls=cls, enum=enum_name(cls)))
-
- if loxi_utils.class_is_oxm(cls):
- out.write("""\
- /* OXM obj; set length and type */
- of_oxm_wire_length_set((of_object_t *)obj, obj->length);
- of_oxm_wire_object_id_set((of_object_t *)obj, %(enum)s);
-""" % dict(enum=enum_name(cls)))
if loxi_utils.class_is_u16_len(cls) or cls == "of_packet_queue":
out.write("""
obj->wire_length_set((of_object_t *)obj, obj->length);
@@ -3050,6 +3019,12 @@
/* Set up the object's function pointers */
""")
+ uclass = loxi_globals.unified.class_by_name(cls)
+ if uclass and not uclass.virtual and uclass.has_type_members:
+ out.write("""
+ obj->wire_type_set = %(cls)s_push_wire_types;
+""" % dict(cls=cls))
+
if loxi_utils.class_is_message(cls):
out.write("""
obj->wire_length_get = of_object_message_wire_length_get;
@@ -3060,7 +3035,6 @@
if not (cls in type_maps.inheritance_map): # Don't set for super
out.write("""
obj->wire_length_set = of_tlv16_wire_length_set;
- obj->wire_type_set = of_tlv16_wire_object_id_set;\
""")
out.write("""
obj->wire_length_get = of_tlv16_wire_length_get;
@@ -3096,9 +3070,7 @@
if loxi_utils.class_is_oxm(cls):
out.write("""
obj->wire_length_get = of_oxm_wire_length_get;
- obj->wire_length_set = of_oxm_wire_length_set;
obj->wire_type_get = of_oxm_wire_object_id_get;
- obj->wire_type_set = of_oxm_wire_object_id_set;
""")
if loxi_utils.class_is_u16_len(cls):
out.write("""
diff --git a/c_gen/c_type_maps.py b/c_gen/c_type_maps.py
index 09ee486..b0775d1 100644
--- a/c_gen/c_type_maps.py
+++ b/c_gen/c_type_maps.py
@@ -1094,92 +1094,6 @@
""")
- # Generate the function that sets the object type fields
- out.write("""
-
-/**
- * Map a message in a wire buffer object to its OF object id.
- * @param wbuf Pointer to a wire buffer object, populated with an OF message
- * @returns The object ID of the message
- * @returns OF_OBJECT_INVALID if unable to parse the message type
- *
- * Version must be set in the buffer prior to calling this routine
- */
-
-static inline int
-of_wire_message_object_id_set(of_wire_buffer_t *wbuf, of_object_id_t id)
-{
- int type;
- of_version_t ver;
- of_message_t msg;
-
- msg = (of_message_t)WBUF_BUF(wbuf);
-
- ver = of_message_version_get(msg);
-
- /* ASSERT(id is a message object) */
-
- if ((type = of_object_to_wire_type(id, ver)) < 0) {
- return OF_ERROR_PARAM;
- }
- of_message_type_set(msg, type);
-
- if ((type = of_object_to_stats_type(id, ver)) >= 0) {
- /* It's a stats obj */
- of_message_stats_type_set(msg, type);
- if (type == OF_STATS_TYPE_EXPERIMENTER) {
- switch (id) {
- case OF_BSN_LACP_STATS_REQUEST:
- case OF_BSN_LACP_STATS_REPLY:
- of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
- of_message_stats_experimenter_subtype_set(msg, 1);
- break;
- case OF_BSN_SWITCH_PIPELINE_STATS_REQUEST:
- case OF_BSN_SWITCH_PIPELINE_STATS_REPLY:
- of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
- of_message_stats_experimenter_subtype_set(msg, 6);
- break;
- case OF_BSN_PORT_COUNTER_STATS_REQUEST:
- case OF_BSN_PORT_COUNTER_STATS_REPLY:
- of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
- of_message_stats_experimenter_subtype_set(msg, 8);
- break;
- case OF_BSN_VLAN_COUNTER_STATS_REQUEST:
- case OF_BSN_VLAN_COUNTER_STATS_REPLY:
- of_message_stats_experimenter_id_set(msg, OF_EXPERIMENTER_ID_BSN);
- of_message_stats_experimenter_subtype_set(msg, 9);
- break;
- default:
- break;
- }
- }
- }
- if ((type = of_object_to_error_type(id, ver)) >= 0) {
- /* It's an error obj */
- of_message_error_type_set(msg, type);
- }
- if ((type = of_object_to_flow_mod_command(id, ver)) >= 0) {
- /* It's a flow mod obj */
- of_message_flow_mod_command_set(msg, ver, type);
- }
- if ((type = of_object_to_group_mod_command(id, ver)) >= 0) {
- /* It's a group mod obj */
- of_message_group_mod_command_set(msg, type);
- }
- if (of_object_id_is_extension(id, ver)) {
- uint32_t val32;
-
- /* Set the experimenter and subtype codes */
- val32 = of_extension_to_experimenter_id(id, ver);
- of_message_experimenter_id_set(msg, val32);
- val32 = of_extension_to_experimenter_subtype(id, ver);
- of_message_experimenter_subtype_set(msg, val32);
- }
-
- return OF_ERROR_NONE;
-}
-""")
-
def gen_type_data_header(out):
out.write("""
@@ -1249,15 +1163,11 @@
extern void of_object_message_wire_length_set(of_object_t *obj, int bytes);
extern void of_oxm_wire_length_get(of_object_t *obj, int *bytes);
-extern void of_oxm_wire_length_set(of_object_t *obj, int bytes);
extern void of_oxm_wire_object_id_get(of_object_t *obj, of_object_id_t *id);
-extern void of_oxm_wire_object_id_set(of_object_t *obj, of_object_id_t id);
extern void of_tlv16_wire_length_get(of_object_t *obj, int *bytes);
extern void of_tlv16_wire_length_set(of_object_t *obj, int bytes);
-extern void of_tlv16_wire_object_id_set(of_object_t *obj, of_object_id_t id);
-
/* Wire length is uint16 at front of structure */
extern void of_u16_len_wire_length_get(of_object_t *obj, int *bytes);
extern void of_u16_len_wire_length_set(of_object_t *obj, int bytes);
diff --git a/c_gen/codegen.py b/c_gen/codegen.py
new file mode 100644
index 0000000..0d7832a
--- /dev/null
+++ b/c_gen/codegen.py
@@ -0,0 +1,79 @@
+# 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.
+
+"""
+Code generation
+
+These functions extract data from the IR and render templates with it.
+"""
+
+from collections import namedtuple
+from itertools import groupby
+import template_utils
+import loxi_globals
+import loxi_ir.ir as ir
+import util
+
+PushWireTypesFn = namedtuple('PushWireTypesFn',
+ ['class_name', 'versioned_type_members'])
+PushWireTypesMember = namedtuple('PushWireTypesMember',
+ ['name', 'offset', 'length', 'value'])
+
+def gen_push_wire_types(install_dir):
+ fns = []
+ for uclass in loxi_globals.unified.classes:
+ if uclass.virtual or not uclass.has_type_members:
+ continue
+
+ # Generate a dict of version -> list of PushWireTypesMember
+ type_members_by_version = {}
+ for version, ofclass in sorted(uclass.version_classes.items()):
+ pwtms = []
+ for m in ofclass.members:
+ if isinstance(m, ir.OFTypeMember):
+ if m.name == "version" and m.value == version.wire_version:
+ # Special case for version
+ pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, "obj->version"))
+ else:
+ pwtms.append(PushWireTypesMember(m.name, m.offset, m.length, m.value))
+ type_members_by_version[version] = pwtms
+
+ # Merge versions with identical type members
+ all_versions = sorted(type_members_by_version.keys())
+ versioned_type_members = []
+ for pwtms, versions in groupby(all_versions, type_members_by_version.get):
+ versioned_type_members.append((pwtms, list(versions)))
+
+ fns.append(PushWireTypesFn(
+ class_name=uclass.name,
+ versioned_type_members=versioned_type_members))
+
+ with template_utils.open_output(install_dir, "loci/src/loci_push_wire_types.c") as out:
+ util.render_template(out, "loci_push_wire_types.c", fns=fns)
+
+ with template_utils.open_output(install_dir, "loci/src/loci_push_wire_types.h") as out:
+ util.render_template(out, "loci_push_wire_types.h", fns=fns)
diff --git a/c_gen/templates/loci_push_wire_types.c b/c_gen/templates/loci_push_wire_types.c
new file mode 100644
index 0000000..2103aad
--- /dev/null
+++ b/c_gen/templates/loci_push_wire_types.c
@@ -0,0 +1,83 @@
+:: # 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.
+::
+:: include('_copyright.c')
+
+/****************************************************************
+ *
+ * Functions for each concrete class that set the type fields
+ *
+ ****************************************************************/
+
+#include <loci/loci.h>
+#include <loci/of_message.h>
+#include <endian.h>
+
+#ifdef __GNUC__
+#define UNREACHABLE() __builtin_unreachable()
+#else
+#define UNREACHABLE()
+#endif
+
+/*
+ * In a separate function to give the compiler the choice of whether to inline.
+ */
+static unsigned char *
+loci_object_to_buffer(of_object_t *obj)
+{
+ return OF_OBJECT_BUFFER_INDEX(obj, 0);
+}
+
+:: for fn in fns:
+
+void
+${fn.class_name}_push_wire_types(of_object_t *obj)
+{
+ unsigned char *buf = loci_object_to_buffer(obj);
+ switch (obj->version) {
+:: for ms, versions in fn.versioned_type_members:
+:: for version in versions:
+ case ${version.constant_version(prefix='OF_VERSION_')}:
+:: #endfor
+:: for m in ms:
+:: if m.length == 1:
+ *(uint8_t *)(buf + ${m.offset}) = ${m.value}; /* ${m.name} */
+:: elif m.length == 2:
+ *(uint16_t *)(buf + ${m.offset}) = htobe16(${m.value}); /* ${m.name} */
+:: elif m.length == 4:
+ *(uint32_t *)(buf + ${m.offset}) = htobe32(${m.value}); /* ${m.name} */
+:: else:
+:: raise("unsupported push_wire_types length %d" % m.length)
+:: #endif
+:: #endfor
+ break;
+:: #endfor
+ default:
+ UNREACHABLE();
+ }
+}
+:: #endfor
diff --git a/c_gen/templates/loci_push_wire_types.h b/c_gen/templates/loci_push_wire_types.h
new file mode 100644
index 0000000..5b2c1e8
--- /dev/null
+++ b/c_gen/templates/loci_push_wire_types.h
@@ -0,0 +1,40 @@
+:: # 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.
+::
+:: include('_copyright.c')
+#ifndef LOCI_PUSH_WIRE_TYPES_H
+#define LOCI_PUSH_WIRE_TYPES_H
+
+#include <loci/loci.h>
+
+/* Declarations of public functions from loci_push_wire_types.c */
+
+:: for fn in fns:
+void ${fn.class_name}_push_wire_types(of_object_t *obj);
+:: #endfor
+
+#endif
diff --git a/c_gen/templates/of_message.h b/c_gen/templates/of_message.h
index befda2f..df74231 100644
--- a/c_gen/templates/of_message.h
+++ b/c_gen/templates/of_message.h
@@ -105,11 +105,6 @@
return (of_version_t)msg[OF_MESSAGE_VERSION_OFFSET];
}
-static inline void
-of_message_version_set(of_message_t msg, of_version_t version) {
- buf_u8_set(msg, (uint8_t)version);
-}
-
/**
* @brief Get/set OpenFlow type of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -122,11 +117,6 @@
return msg[OF_MESSAGE_TYPE_OFFSET];
}
-static inline void
-of_message_type_set(of_message_t msg, uint8_t value) {
- buf_u8_set(msg + OF_MESSAGE_TYPE_OFFSET, value);
-}
-
/**
* @brief Get/set in-buffer length of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -161,11 +151,6 @@
return val;
}
-static inline void
-of_message_xid_set(of_message_t msg, uint32_t xid) {
- buf_u32_set(msg + OF_MESSAGE_XID_OFFSET, xid);
-}
-
/**
* @brief Get/set stats type of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -180,11 +165,6 @@
return val;
}
-static inline void
-of_message_stats_type_set(of_message_t msg, uint16_t type) {
- buf_u16_set(msg + OF_MESSAGE_STATS_TYPE_OFFSET, type);
-}
-
/**
* @brief Get/set error type of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -199,11 +179,6 @@
return val;
}
-static inline void
-of_message_error_type_set(of_message_t msg, uint16_t type) {
- buf_u16_set(msg + OF_MESSAGE_ERROR_TYPE_OFFSET, type);
-}
-
/**
* @brief Get/set experimenter ID of a message
@@ -219,11 +194,6 @@
return val;
}
-static inline void
-of_message_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) {
- buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_ID_OFFSET, experimenter_id);
-}
-
/**
* @brief Get/set experimenter message type (subtype) of a message
@@ -239,13 +209,6 @@
return val;
}
-static inline void
-of_message_experimenter_subtype_set(of_message_t msg,
- uint32_t subtype) {
- buf_u32_set(msg + OF_MESSAGE_EXPERIMENTER_SUBTYPE_OFFSET,
- subtype);
-}
-
/**
* Flow mod command changed from 16 to 8 bits on the wire from 1.0 to 1.1
*/
@@ -263,19 +226,6 @@
return val8;
}
-static inline void
-of_message_flow_mod_command_set(of_message_t msg, of_version_t version,
- uint8_t command) {
- uint16_t val16;
-
- if (version == OF_VERSION_1_0) {
- val16 = command;
- buf_u16_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), val16);
- } else {
- buf_u8_set(msg + OF_MESSAGE_FLOW_MOD_COMMAND_OFFSET(version), command);
- }
-}
-
/**
* @brief Get/set stats request/reply experimenter ID of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -290,11 +240,6 @@
return val;
}
-static inline void
-of_message_stats_experimenter_id_set(of_message_t msg, uint32_t experimenter_id) {
- buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_ID_OFFSET, experimenter_id);
-}
-
/**
* @brief Get/set stats request/reply experimenter subtype of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -309,11 +254,6 @@
return val;
}
-static inline void
-of_message_stats_experimenter_subtype_set(of_message_t msg, uint32_t subtype) {
- buf_u32_set(msg + OF_MESSAGE_STATS_EXPERIMENTER_SUBTYPE_OFFSET, subtype);
-}
-
/**
* @brief Get/set group mod command of a message
* @param msg Pointer to the message buffer of sufficient length
@@ -328,9 +268,4 @@
return val;
}
-static inline void
-of_message_group_mod_command_set(of_message_t msg, uint16_t command) {
- buf_u16_set(msg + OF_MESSAGE_GROUP_MOD_COMMAND_OFFSET, command);
-}
-
#endif /* _OF_MESSAGE_H_ */
diff --git a/c_gen/templates/of_object.c b/c_gen/templates/of_object.c
index 0b3ec3a..ae22f64 100644
--- a/c_gen/templates/of_object.c
+++ b/c_gen/templates/of_object.c
@@ -510,7 +510,7 @@
}
if (child->wire_type_set) {
- child->wire_type_set(child, child->object_id);
+ child->wire_type_set(child);
}
/* Update the parent's length */
diff --git a/c_gen/templates/of_type_maps.c b/c_gen/templates/of_type_maps.c
index 2314d67..4b35dcc 100644
--- a/c_gen/templates/of_type_maps.c
+++ b/c_gen/templates/of_type_maps.c
@@ -139,30 +139,6 @@
}
/**
- * Set the object ID based on the wire buffer for any TLV object
- * @param obj The object being referenced
- * @param id The ID value representing what should be stored.
- */
-
-void
-of_tlv16_wire_object_id_set(of_object_t *obj, of_object_id_t id)
-{
- int wire_type;
- of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
- ASSERT(wbuf != NULL);
-
- wire_type = of_object_to_type_map[obj->version][id];
- ASSERT(wire_type >= 0);
-
- of_wire_buffer_u16_set(wbuf,
- OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_TYPE_OFFSET), wire_type);
-
- if (wire_type == OF_EXPERIMENTER_TYPE) {
- of_extension_object_id_set(obj, id);
- }
-}
-
-/**
* Get the object ID of an extended action
* @param obj The object being referenced
* @param id Where to store the object ID
@@ -209,44 +185,6 @@
}
/**
- * Set wire data for extension objects, not messages.
- */
-
-void
-of_extension_object_id_set(of_object_t *obj, of_object_id_t id)
-{
- uint8_t *buf = OF_OBJECT_BUFFER_INDEX(obj, 0);
-
- switch (id) {
- case OF_ACTION_BSN_MIRROR:
- case OF_ACTION_ID_BSN_MIRROR:
- buf_u32_set(buf + OF_ACTION_EXPERIMENTER_ID_OFFSET,
- OF_EXPERIMENTER_ID_BSN);
- buf_u32_set(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, 1);
- break;
- case OF_ACTION_BSN_SET_TUNNEL_DST:
- case OF_ACTION_ID_BSN_SET_TUNNEL_DST:
- buf_u32_set(buf + OF_ACTION_EXPERIMENTER_ID_OFFSET,
- OF_EXPERIMENTER_ID_BSN);
- buf_u32_set(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, 2);
- break;
- case OF_ACTION_NICIRA_DEC_TTL:
- case OF_ACTION_ID_NICIRA_DEC_TTL:
- buf_u32_set(buf + OF_ACTION_EXPERIMENTER_ID_OFFSET,
- OF_EXPERIMENTER_ID_NICIRA);
- buf_u16_set(buf + OF_ACTION_EXPERIMENTER_SUBTYPE_OFFSET, 18);
- break;
- case OF_INSTRUCTION_BSN_DISABLE_SRC_MAC_CHECK:
- buf_u32_set(buf + OF_INSTRUCTION_EXPERIMENTER_ID_OFFSET,
- OF_EXPERIMENTER_ID_BSN);
- buf_u32_set(buf + OF_INSTRUCTION_EXPERIMENTER_SUBTYPE_OFFSET, 0);
- break;
- default:
- break;
- }
-}
-
-/**
* Get the object ID of an extended action
* @param obj The object being referenced
* @param id Where to store the object ID
@@ -551,27 +489,6 @@
}
/**
- * Set the length of an OXM object in the wire buffer
- * @param obj The object whose wire buffer is an OXM type
- * @param bytes Value to store in wire buffer
- */
-
-void
-of_oxm_wire_length_set(of_object_t *obj, int bytes)
-{
- uint32_t type_len;
- of_wire_buffer_t *wbuf;
-
- ASSERT(bytes >= 0 && bytes < 256);
-
- /* Read-modify-write */
- _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
- OF_OXM_LENGTH_SET(type_len, bytes);
- of_wire_buffer_u32_set(wbuf,
- OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), type_len);
-}
-
-/**
* Get the object ID of an OXM object based on the wire buffer type
* @param obj The object whose wire buffer is an OXM type
* @param id (out) Where the ID is stored
@@ -587,80 +504,6 @@
*id = of_oxm_to_object_id(type_len, obj->version);
}
-/**
- * Set the wire type of an OXM object based on the object ID passed
- * @param obj The object whose wire buffer is an OXM type
- * @param id The object ID mapped to an OXM wire type which is stored
- */
-
-void
-of_oxm_wire_object_id_set(of_object_t *obj, of_object_id_t id)
-{
- uint32_t type_len;
- int wire_type;
- of_wire_buffer_t *wbuf;
-
- ASSERT(OF_OXM_VALID_ID(id));
-
- /* Read-modify-write */
- _GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
-
- switch (id) {
- case OF_OXM_BSN_IN_PORTS_128:
- type_len = 0x00030000 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_IN_PORTS_128_MASKED:
- type_len = 0x00030100 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_LAG_ID:
- type_len = 0x00030200 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_LAG_ID_MASKED:
- type_len = 0x00030300 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_VRF:
- type_len = 0x00030400 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_VRF_MASKED:
- type_len = 0x00030500 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_GLOBAL_VRF_ALLOWED:
- type_len = 0x00030600 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_GLOBAL_VRF_ALLOWED_MASKED:
- type_len = 0x00030700 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_INTERFACE_CLASS_ID:
- type_len = 0x00030800 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_INTERFACE_CLASS_ID_MASKED:
- type_len = 0x00030900 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_SRC_CLASS_ID:
- type_len = 0x00030a00 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_SRC_CLASS_ID_MASKED:
- type_len = 0x00030b00 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_DST_CLASS_ID:
- type_len = 0x00030c00 | (type_len & 0xff);
- break;
- case OF_OXM_BSN_L3_DST_CLASS_ID_MASKED:
- type_len = 0x00030d00 | (type_len & 0xff);
- break;
- default:
- wire_type = of_object_to_wire_type(id, obj->version);
- ASSERT(wire_type >= 0);
- type_len = 0x80000000 | (wire_type << 8) | (type_len & 0xff);
- break;
- }
-
- of_wire_buffer_u32_set(wbuf,
- OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), type_len);
-}
-
-
-
#define OF_U16_LEN_LENGTH_OFFSET 0
/**
diff --git a/c_gen/type_maps.py b/c_gen/type_maps.py
index e709b70..f285a33 100644
--- a/c_gen/type_maps.py
+++ b/c_gen/type_maps.py
@@ -38,6 +38,7 @@
from generic_utils import *
import loxi_utils.loxi_utils as loxi_utils
import c_gen.loxi_utils_legacy as loxi_utils
+import loxi_globals
invalid_type = "invalid_type"
invalid_value = "0xeeee" # Note, as a string
@@ -154,16 +155,11 @@
"""
Returns True if cls is a virtual class
"""
- if cls in inheritance_map:
- return True
if cls.find("header") > 0:
return True
if loxi_utils.class_is_list(cls):
return True
- # TODO get this from the input file when we have virtual class syntax
- if cls in ["of_flow_mod", "of_stats_request", "of_stats_reply", "of_error_msg", "of_bsn_header", "of_nicira_header", "of_action_bsn", "of_action_nicira", "of_action_id_bsn", "of_action_id_nicira", "of_bsn_stats_request", "of_bsn_stats_reply", "of_experimenter_stats_request", "of_experimenter_stats_reply", "of_instruction_experimenter", "of_instruction_bsn", "of_group_mod"]:
- return True
- return False
+ return loxi_globals.unified.class_by_name(cls).virtual
################################################################
#
diff --git a/lang_c.py b/lang_c.py
index 762f82c..7718d48 100644
--- a/lang_c.py
+++ b/lang_c.py
@@ -41,6 +41,7 @@
import c_gen.c_show_gen as c_show_gen
import c_gen.c_validator_gen as c_validator_gen
import c_gen.util
+import c_gen.codegen
import loxi_utils.loxi_utils as loxi_utils
import template_utils
@@ -173,3 +174,4 @@
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.gen_push_wire_types(install_dir)
diff --git a/loxi_ir/ir.py b/loxi_ir/ir.py
index ebd4f85..6fae92b 100644
--- a/loxi_ir/ir.py
+++ b/loxi_ir/ir.py
@@ -183,6 +183,10 @@
def has_external_alignment(self):
return self.params.get('length_includes_align') == 'False'
+ @property
+ def has_type_members(self):
+ return find(lambda m: isinstance(m, OFTypeMember), self.members) is not None
+
""" one class unified across openflow versions. Keeps around a map version->versioned_class """
class OFUnifiedClass(OFClass):
def __new__(cls, version_classes, *a, **kw):
diff --git a/openflow_input/bsn_global_vrf_allowed b/openflow_input/bsn_global_vrf_allowed
index 543c6fd..ee26308 100644
--- a/openflow_input/bsn_global_vrf_allowed
+++ b/openflow_input/bsn_global_vrf_allowed
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_global_vrf_allowed_masked : of_oxm {
- uint32_t type_len == 0x00030701;
+ uint32_t type_len == 0x00030702;
uint8_t value;
uint8_t value_mask;
};
diff --git a/openflow_input/bsn_in_ports b/openflow_input/bsn_in_ports
index 05003b9..b23df63 100644
--- a/openflow_input/bsn_in_ports
+++ b/openflow_input/bsn_in_ports
@@ -50,7 +50,7 @@
*/
struct of_oxm_bsn_in_ports_128 : of_oxm {
- uint32_t type_len == 0x00030020;
+ uint32_t type_len == 0x00030010;
of_bitmap_128_t value;
};
diff --git a/openflow_input/bsn_l3_dst_class_id b/openflow_input/bsn_l3_dst_class_id
index 385add7..8d324a1 100644
--- a/openflow_input/bsn_l3_dst_class_id
+++ b/openflow_input/bsn_l3_dst_class_id
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_l3_dst_class_id_masked : of_oxm {
- uint32_t type_len == 0x00030d04;
+ uint32_t type_len == 0x00030d08;
uint32_t value;
uint32_t value_mask;
};
diff --git a/openflow_input/bsn_l3_interface_class_id b/openflow_input/bsn_l3_interface_class_id
index efeb949..80d1e37 100644
--- a/openflow_input/bsn_l3_interface_class_id
+++ b/openflow_input/bsn_l3_interface_class_id
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_l3_interface_class_id_masked : of_oxm {
- uint32_t type_len == 0x00030904;
+ uint32_t type_len == 0x00030908;
uint32_t value;
uint32_t value_mask;
};
diff --git a/openflow_input/bsn_l3_src_class_id b/openflow_input/bsn_l3_src_class_id
index f18aab9..58f60c6 100644
--- a/openflow_input/bsn_l3_src_class_id
+++ b/openflow_input/bsn_l3_src_class_id
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_l3_src_class_id_masked : of_oxm {
- uint32_t type_len == 0x00030b04;
+ uint32_t type_len == 0x00030b08;
uint32_t value;
uint32_t value_mask;
};
diff --git a/openflow_input/bsn_lag_id b/openflow_input/bsn_lag_id
index c96c1d6..63645a3 100644
--- a/openflow_input/bsn_lag_id
+++ b/openflow_input/bsn_lag_id
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_lag_id_masked : of_oxm {
- uint32_t type_len == 0x00030304;
+ uint32_t type_len == 0x00030308;
uint32_t value;
uint32_t value_mask;
};
diff --git a/openflow_input/bsn_vrf b/openflow_input/bsn_vrf
index 3641faa..26959bd 100644
--- a/openflow_input/bsn_vrf
+++ b/openflow_input/bsn_vrf
@@ -41,7 +41,7 @@
};
struct of_oxm_bsn_vrf_masked : of_oxm {
- uint32_t type_len == 0x00030504;
+ uint32_t type_len == 0x00030508;
uint32_t value;
uint32_t value_mask;
};
diff --git a/wireshark_gen/templates/_oftype_readers.lua b/wireshark_gen/templates/_oftype_readers.lua
index 9a5e4fa..10f13ca 100644
--- a/wireshark_gen/templates/_oftype_readers.lua
+++ b/wireshark_gen/templates/_oftype_readers.lua
@@ -135,7 +135,7 @@
local action_len = reader2.peek(2, 2):uint()
local child_reader = reader2.slice(action_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_action(child_reader, child_subtree, version)
+ local info = of_action_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
list:set_text("List of actions")
@@ -151,7 +151,7 @@
local port_desc_len = 64
local child_reader = reader.slice(port_desc_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_port_desc(child_reader, child_subtree, version)
+ local info = of_port_desc_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -166,7 +166,7 @@
local stats_len = reader.peek(0,2):uint()
local child_reader = reader.slice(stats_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_flow_stats_entry(child_reader, child_subtree, version)
+ local info = of_flow_stats_entry_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -181,7 +181,7 @@
local stats_len = 112
local child_reader = reader.slice(stats_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_port_stats_entry(child_reader, child_subtree, version)
+ local info = of_port_stats_entry_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -196,7 +196,7 @@
local stats_len = 24
local child_reader = reader.slice(stats_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_table_stats_entry(child_reader, child_subtree, version)
+ local info = of_table_stats_entry_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -211,7 +211,7 @@
local stats_len = 40
local child_reader = reader.slice(stats_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_queue_stats_entry(child_reader, child_subtree, version)
+ local info = of_queue_stats_entry_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -244,7 +244,7 @@
local match_len = 4 + reader2.peek(3,1):uint()
local child_reader = reader2.slice(match_len)
local child_subtree = list:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_oxm(child_reader, child_subtree, version)
+ local info = of_oxm_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
subtree:set_text("OXM")
@@ -256,7 +256,7 @@
return
end
local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
- local info = dissect_of_instruction(reader, child_subtree, version)
+ local info = of_instruction_dissectors[version](reader, child_subtree)
child_subtree:set_text("Instructions")
end
@@ -270,7 +270,7 @@
local bucket_len = reader.peek(0,2):uint()
local child_reader = reader.slice(bucket_len)
local child_subtree = bucket_list_subtree:add(fields[field_name], child_reader.peek_all(0))
- local info = dissect_of_bucket(child_reader, child_subtree, version)
+ local info = of_bucket_dissectors[version](child_reader, child_subtree)
child_subtree:set_text(info)
end
end
@@ -280,6 +280,6 @@
return
end
local child_subtree = subtree:add(fields[field_name], reader.peek_all(0))
- local info = dissect_of_oxm(reader, child_subtree, version)
+ local info = of_oxm_dissectors[version](reader, child_subtree)
child_subtree:set_text(info)
end
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index 931843d..bdbe2ec 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -39,8 +39,6 @@
:: include('_ofreader.lua')
-:: include('_oftype_readers.lua')
-
p_of = Proto ("of", "OpenFlow")
local openflow_versions = {
@@ -104,25 +102,25 @@
local of_message_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_header_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_header_v${version.wire_version},
:: #endfor
}
local of_oxm_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_oxm_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_oxm_v${version.wire_version},
:: #endfor
}
local of_action_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_action_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_action_v${version.wire_version},
:: #endfor
}
local of_instruction_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_instruction_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_instruction_v${version.wire_version},
:: #endfor
}
@@ -140,13 +138,13 @@
local of_stats_reply_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_stats_reply_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_stats_reply_v${version.wire_version},
:: #endfor
}
local of_stats_request_dissectors = {
:: for version in ir:
- [${version.wire_version}] = of_stats_request_v${version.wire_version}_dissectors,
+ [${version.wire_version}] = dissect_of_stats_request_v${version.wire_version},
:: #endfor
}
@@ -174,6 +172,8 @@
:: #endfor
}
+:: include('_oftype_readers.lua')
+
function dissect_of_message(buf, root)
local reader = OFReader.new(buf)
local subtree = root:add(p_of, buf(0))
@@ -186,95 +186,11 @@
end
local info = "unknown"
- info = of_message_dissectors[version_val][type_val](reader, subtree)
+ info = of_message_dissectors[version_val](reader, subtree)
return protocol, info
end
-function dissect_of_oxm(reader, subtree, version_val)
- local type_val = reader.peek(0,4):uint()
- local info = "unknown"
- if of_oxm_dissectors[version_val] and of_oxm_dissectors[version_val][type_val] then
- info = of_oxm_dissectors[version_val][type_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_action(reader, subtree, version_val)
- local type_val = reader.peek(0,2):uint()
- local info = "unknown"
- if of_action_dissectors[version_val] and of_action_dissectors[version_val][type_val] then
- info = of_action_dissectors[version_val][type_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_instruction(reader, subtree, version_val)
- local type_val = reader.peek(0,2):uint()
- local info = "unknown"
- if of_instruction_dissectors[version_val] and of_instruction_dissectors[version_val][type_val] then
- info = of_instruction_dissectors[version_val][type_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_bucket(reader, subtree, version_val)
- local info = "unknown"
- if of_bucket_dissectors[version_val] then
- info = of_bucket_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_port_desc(reader, subtree, version_val)
- local info = "unknown"
- if of_port_desc_dissectors[version_val] then
- info = of_port_desc_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_flow_stats_entry(reader, subtree, version_val)
- local info = "unknown"
- if of_flow_stats_entry_dissectors[version_val] then
- info = of_flow_stats_entry_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_port_stats_entry(reader, subtree, version_val)
- local info = "unknown"
- if of_port_stats_entry_dissectors[version_val] then
- info = of_port_stats_entry_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_table_stats_entry(reader, subtree, version_val)
- local info = "unknown"
- if of_table_stats_entry_dissectors[version_val] then
- info = of_table_stats_entry_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-function dissect_of_queue_stats_entry(reader, subtree, version_val)
- local info = "unknown"
- if of_queue_stats_entry_dissectors[version_val] then
- info = of_queue_stats_entry_dissectors[version_val](reader, subtree)
- end
-
- return info
-end
-
-- of dissector function
function p_of.dissector (buf, pkt, root)
local offset = 0