Exemplo n.º 1
0
 def gen_unpack_expr(self, reader_expr):
     pack_fmt = self._pack_fmt()
     if pack_fmt and not self.is_array:
         return "%s.read('!%s')[0]" % (reader_expr, pack_fmt)
     elif pack_fmt and self.is_array:
         return "list(%s.read('!%d%s'))" % (self.array_length, pack_fmt)
     elif self.base == 'of_octets_t':
         return "str(%s.read_all())" % (reader_expr)
     elif self.base == 'of_mac_addr_t':
         return "list(%s.read('!6B'))" % (reader_expr)
     elif self.base == 'of_ipv6_t':
         return "%s.read('!16s')[0]" % (reader_expr)
     elif self.base == 'of_match_t':
         return 'common.match.unpack(%s)' % (reader_expr)
     elif self.base == 'of_port_desc_t':
         return 'common.port_desc.unpack(%s)' % (reader_expr)
     elif self.base == 'of_list_action_t':
         return 'action.unpack_list(%s)' % (reader_expr)
     elif self.base == 'of_list_flow_stats_entry_t':
         return 'common.unpack_list_flow_stats_entry(%s)' % (reader_expr)
     elif self.base == 'of_list_queue_prop_t':
         return 'common.unpack_list_queue_prop(%s)' % (reader_expr)
     elif self.base == 'of_list_packet_queue_t':
         return 'common.unpack_list_packet_queue(%s)' % (reader_expr)
     elif self.base == 'of_list_hello_elem_t':
         return 'common.unpack_list_hello_elem(%s)' % (reader_expr)
     elif self.base == 'of_list_oxm_t':
         # HACK need the match_v3 length field
         return 'oxm.unpack_list(%s.slice(_length-4))' % (reader_expr)
     elif self.base == 'of_list_bucket_t':
         return 'common.unpack_list_bucket(%s)' % (reader_expr)
     elif self.base == 'of_list_group_desc_stats_entry_t':
         return 'common.unpack_list_group_desc_stats_entry(%s)' % (reader_expr)
     elif self.base == 'of_list_group_stats_entry_t':
         return 'common.unpack_list_group_stats_entry(%s)' % (reader_expr)
     elif self.base == 'of_list_meter_band_t':
         return 'meter_band.unpack_list(%s)' % (reader_expr)
     elif self.base == 'of_list_meter_stats_t':
         return 'common.unpack_list_meter_stats(%s)' % (reader_expr)
     elif self.base == 'of_port_name_t':
         return self._gen_string_unpack_expr(reader_expr, 16)
     elif self.base == 'of_table_name_t' or self.base == 'of_serial_num_t':
         return self._gen_string_unpack_expr(reader_expr, 32)
     elif self.base == 'of_desc_str_t':
         return self._gen_string_unpack_expr(reader_expr, 256)
     elif self.base == 'of_meter_features_t':
         return 'common.meter_features.unpack(%s)' % (reader_expr)
     elif self.base == 'of_list_instruction_t':
         return 'instruction.unpack_list(%s)' % (reader_expr)
     elif utils.class_is_list(self.base):
         element_cls = utils.list_to_entry_type(self.base)[:-2]
         if ((element_cls, self.version) in of_g.is_fixed_length) \
            and not element_cls in loxi_front_end.type_maps.inheritance_map:
             klass_name = self.base[8:-2]
             element_size, = of_g.base_length[(element_cls, self.version)],
             return 'loxi.generic_util.unpack_list(%s, common.%s.unpack)' % (reader_expr, klass_name)
         else:
             return "loxi.unimplemented('unpack list %s')" % self.base
     else:
         return "loxi.unimplemented('unpack %s')" % self.base
Exemplo n.º 2
0
def generate_common(out, name, version):
    ofclasses = [x for x in build_ofclasses(version)
                 if not utils.class_is_message(x.name)
                    and not utils.class_is_action(x.name)
                    and not utils.class_is_oxm(x.name)
                    and not utils.class_is_list(x.name)]
    util.render_template(out, 'common.py', ofclasses=ofclasses, version=version)
Exemplo n.º 3
0
    def gen_init_expr(self):
        if utils.class_is_list(self.base):
            v = "[]"
        elif self.base.find("uint") == 0 or self.base in ["char", "of_port_no_t"]:
            v = "0"
        elif self.base == 'of_mac_addr_t':
            v = '[0,0,0,0,0,0]'
        elif self.base == 'of_ipv6_t':
            v = repr('\x00' * 16)
        elif self.base == 'of_wc_bmap_t':
            if self.version in [1,2]:
                v = 'const.OFPFW_ALL'
            else:
                v = 0
        elif self.base == "of_match_bmap_t":
            if self.version in [1,2]:
                v = 'const.OFPFW_ALL'
            else:
                v = 0
        elif self.base in ['of_octets_t', 'of_port_name_t', 'of_table_name_t',
                           'of_desc_str_t', 'of_serial_num_t']:
            v = '""'
        elif self.base == 'of_match_t':
            v = 'common.match()'
        elif self.base == 'of_port_desc_t':
            v = 'common.port_desc()'
        elif self.base == 'of_meter_features_t':
            v = 'common.meter_features()'
        else:
            v = "None"

        if self.is_array:
            return "[" + ','.join([v] * self.array_length) + "]"
        else:
            return v
Exemplo n.º 4
0
def class_is_virtual(cls):
    """
    Returns True if cls is a virtual class
    """
    if cls.find("header") > 0:
        return True
    if loxi_utils.class_is_list(cls):
        return True
    return loxi_globals.unified.class_by_name(cls).virtual
Exemplo n.º 5
0
def class_is_virtual(cls):
    """
    Returns True if cls is a virtual class
    """
    if cls.find("header") > 0:
        return True
    if loxi_utils.class_is_list(cls):
        return True
    return loxi_globals.unified.class_by_name(cls).virtual
Exemplo n.º 6
0
def gen_all_java(out, name):
    """ Generate all of the java files

    @param out is an open file handle to a file called README
    @param name should be 'README' and is ignored for the java
        driver
    """
    messages = list()
    actions = list()
    instructions = list()
    matches = list()
    stat_types = list()
    queue_prop = list()
    lists = list()
    for cls in of_g.unified:
        print "! Classifying %s" % cls
        if cls in ["of_stats_reply", "of_flow_mod", "of_stats_request"]:
            continue  # doesn't work?!
        if loxi_utils.class_is_stats_message(cls):
            stat_types.append(cls)
        elif loxi_utils.class_is_message(cls):
            messages.append(cls)
        elif loxi_utils.class_is_action(cls):
            actions.append(cls)
        elif loxi_utils.class_is_instruction(cls):
            instructions.append(cls)
        elif loxi_utils.class_is_oxm(cls):
            matches.append(cls)
        elif loxi_utils.class_is_queue_prop(cls):
            queue_prop.append(cls)
        elif loxi_utils.class_is_list(cls):
            lists.append(cls)
        else:
            print "Skipping Unknown class object %s" % str(cls)
    print "Parsed "
    print "  Messages: %d" % len(messages)
    print "  Actions: %d" % len(actions)
    print "  Instructions: %d" % len(instructions)
    print "  OXM matches: %d" % len(matches)
    print "  Stat types: %d" % len(stat_types)
    print "  Queue properties: %d" % len(queue_prop)
    print "  Lists: %d" % len(lists)
    target_dir = "loxi_output/openflowj"
    basedir = "%s/%s/" % (target_dir, lang_java.file_to_subdir_map["base_java"])
    srcdir = "%s/src/main/java/org/openflow/protocol" % basedir
    print "Outputting to %s" % basedir
    if not os.path.exists(basedir):
        os.makedirs(basedir)
    java_utils.copy_prewrite_tree(basedir)
    msgs.create_message_interfaces(messages, srcdir)
    msgs.create_message_by_version(messages, srcdir)
    msgs.create_of_type_enum(messages, srcdir)
    with open("README.java-lang") as readme_src:
        out.writelines(readme_src.readlines())
    out.close()
Exemplo n.º 7
0
def class_is_virtual(cls):
    """
    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
    return False
Exemplo n.º 8
0
def class_is_virtual(cls):
    """
    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
    return False
Exemplo n.º 9
0
def generate_common(out, name, version):
    ofclasses = [
        x for x in build_ofclasses(version)
        if not utils.class_is_message(x.name) and not utils.class_is_action(
            x.name) and not utils.class_is_instruction(x.name)
        and not utils.class_is_meter_band(x.name)
        and not utils.class_is_oxm(x.name) and not utils.class_is_list(x.name)
    ]
    util.render_template(out,
                         'common.py',
                         ofclasses=ofclasses,
                         version=version)
Exemplo n.º 10
0
def order_and_assign_object_ids():
    """
    Order all classes and assign object ids to all classes.

    This is done to promote a reasonable order of the objects, putting
    messages first followed by non-messages.  No assumptions should be
    made about the order, nor about contiguous numbering.  However, the
    numbers should all be reasonably small allowing arrays indexed by
    these enum values to be defined.
    """

    # Generate separate message and non-message ordered lists
    for cls in of_g.unified:
        if loxi_utils.class_is_message(cls):
            of_g.ordered_messages.append(cls)
        elif loxi_utils.class_is_list(cls):
            of_g.ordered_list_objects.append(cls)
        else:
            of_g.ordered_non_messages.append(cls)

    of_g.ordered_pseudo_objects.append("of_stats_request")
    of_g.ordered_pseudo_objects.append("of_stats_reply")
    of_g.ordered_pseudo_objects.append("of_flow_mod")

    of_g.ordered_messages.sort()
    of_g.ordered_pseudo_objects.sort()
    of_g.ordered_non_messages.sort()
    of_g.ordered_list_objects.sort()
    of_g.standard_class_order.extend(of_g.ordered_messages)
    of_g.standard_class_order.extend(of_g.ordered_non_messages)
    of_g.standard_class_order.extend(of_g.ordered_list_objects)

    # This includes pseudo classes for which most code is not generated
    of_g.all_class_order.extend(of_g.ordered_messages)
    of_g.all_class_order.extend(of_g.ordered_non_messages)
    of_g.all_class_order.extend(of_g.ordered_list_objects)
    of_g.all_class_order.extend(of_g.ordered_pseudo_objects)

    # Assign object IDs
    for cls in of_g.ordered_messages:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_non_messages:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_list_objects:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_pseudo_objects:
        of_g.unified[cls] = {}
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
Exemplo n.º 11
0
def order_and_assign_object_ids():
    """
    Order all classes and assign object ids to all classes.

    This is done to promote a reasonable order of the objects, putting
    messages first followed by non-messages.  No assumptions should be
    made about the order, nor about contiguous numbering.  However, the
    numbers should all be reasonably small allowing arrays indexed by 
    these enum values to be defined.
    """

    # Generate separate message and non-message ordered lists
    for cls in of_g.unified:
        if loxi_utils.class_is_message(cls):
            of_g.ordered_messages.append(cls)
        elif loxi_utils.class_is_list(cls):
            of_g.ordered_list_objects.append(cls)
        else:
            of_g.ordered_non_messages.append(cls)

    of_g.ordered_pseudo_objects.append("of_stats_request")
    of_g.ordered_pseudo_objects.append("of_stats_reply")
    of_g.ordered_pseudo_objects.append("of_flow_mod")

    of_g.ordered_messages.sort()
    of_g.ordered_pseudo_objects.sort()
    of_g.ordered_non_messages.sort()
    of_g.ordered_list_objects.sort()
    of_g.standard_class_order.extend(of_g.ordered_messages)
    of_g.standard_class_order.extend(of_g.ordered_non_messages)
    of_g.standard_class_order.extend(of_g.ordered_list_objects)

    # This includes pseudo classes for which most code is not generated
    of_g.all_class_order.extend(of_g.ordered_messages)
    of_g.all_class_order.extend(of_g.ordered_non_messages)
    of_g.all_class_order.extend(of_g.ordered_list_objects)
    of_g.all_class_order.extend(of_g.ordered_pseudo_objects)

    # Assign object IDs
    for cls in of_g.ordered_messages:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_non_messages:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_list_objects:
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
    for cls in of_g.ordered_pseudo_objects:
        of_g.unified[cls] = {}
        of_g.unified[cls]["object_id"] = of_g.object_id
        of_g.object_id += 1
Exemplo n.º 12
0
def class_is_virtual(cls):
    """
    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"]:
        return True
    return False
Exemplo n.º 13
0
def class_is_virtual(cls):
    """
    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"
    ]:
        return True
    return False
Exemplo n.º 14
0
 def gen_unpack_expr(self, buf_expr, offset_expr):
     pack_fmt = self._pack_fmt()
     if pack_fmt and not self.is_array:
         return "struct.unpack_from('!%s', %s, %s)[0]" % (pack_fmt, buf_expr, offset_expr)
     elif pack_fmt and self.is_array:
         return "list(struct.unpack_from('!%d%s', %s, %s))" % (self.array_length, pack_fmt, buf_expr, offset_expr)
     elif self.base == "of_octets_t":
         return "%s[%s:]" % (buf_expr, offset_expr)
     elif self.base == "of_mac_addr_t":
         return "list(struct.unpack_from('!6B', %s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_match_t":
         return "common.match.unpack(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_port_desc_t":
         return "common.port_desc.unpack(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_list_action_t":
         return "action.unpack_list(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_list_flow_stats_entry_t":
         return "common.unpack_list_flow_stats_entry(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_list_queue_prop_t":
         return "common.unpack_list_queue_prop(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_list_packet_queue_t":
         return "common.unpack_list_packet_queue(buffer(%s, %s))" % (buf_expr, offset_expr)
     elif self.base == "of_port_name_t":
         return self._gen_string_unpack_expr(16, buf_expr, offset_expr)
     elif self.base == "of_table_name_t" or self.base == "of_serial_num_t":
         return self._gen_string_unpack_expr(32, buf_expr, offset_expr)
     elif self.base == "of_desc_str_t":
         return self._gen_string_unpack_expr(256, buf_expr, offset_expr)
     elif utils.class_is_list(self.base):
         element_cls = utils.list_to_entry_type(self.base)[:-2]
         if (element_cls, self.version) in of_g.is_fixed_length:
             klass_name = self.base[8:-2]
             element_size, = (of_g.base_length[(element_cls, self.version)],)
             return "util.unpack_array(common.%s.unpack, %d, buffer(%s, %s))" % (
                 klass_name,
                 element_size,
                 buf_expr,
                 offset_expr,
             )
         else:
             return "None # TODO unpack list %s" % self.base
     else:
         return "None # TODO unpack %s" % self.base
Exemplo n.º 15
0
    def gen_init_expr(self):
        if utils.class_is_list(self.base):
            v = "[]"
        elif self.base.find("uint") == 0 or self.base in ["char", "of_port_no_t"]:
            v = "0"
        elif self.base == "of_mac_addr_t":
            v = "[0,0,0,0,0,0]"
        elif self.base == "of_wc_bmap_t":
            v = "const.OFPFW_ALL"
        elif self.base in ["of_octets_t", "of_port_name_t", "of_table_name_t", "of_desc_str_t", "of_serial_num_t"]:
            v = '""'
        elif self.base == "of_match_t":
            v = "common.match()"
        elif self.base == "of_port_desc_t":
            v = "common.port_desc()"
        else:
            v = "None"

        if self.is_array:
            return "[" + ",".join([v] * self.array_length) + "]"
        else:
            return v
Exemplo n.º 16
0
 def gen_pack_expr(self, expr_expr):
     pack_fmt = self._pack_fmt()
     if pack_fmt and not self.is_array:
         return 'struct.pack("!%s", %s)' % (pack_fmt, expr_expr)
     elif pack_fmt and self.is_array:
         return 'struct.pack("!%s%s", *%s)' % (self.array_length, pack_fmt, expr_expr)
     elif self.base == "of_octets_t":
         return expr_expr
     elif utils.class_is_list(self.base):
         return '"".join([x.pack() for x in %s])' % expr_expr
     elif self.base == "of_mac_addr_t":
         return 'struct.pack("!6B", *%s)' % expr_expr
     elif self.base in ["of_match_t", "of_port_desc_t"]:
         return "%s.pack()" % expr_expr
     elif self.base == "of_port_name_t":
         return self._gen_string_pack_expr(16, expr_expr)
     elif self.base == "of_table_name_t" or self.base == "of_serial_num_t":
         return self._gen_string_pack_expr(32, expr_expr)
     elif self.base == "of_desc_str_t":
         return self._gen_string_pack_expr(256, expr_expr)
     else:
         return "'TODO pack %s'" % self.base
Exemplo n.º 17
0
 def gen_pack_expr(self, expr_expr):
     pack_fmt = self._pack_fmt()
     if pack_fmt and not self.is_array:
         return 'struct.pack("!%s", %s)' % (pack_fmt, expr_expr)
     elif pack_fmt and self.is_array:
         return 'struct.pack("!%s%s", *%s)' % (self.array_length, pack_fmt, expr_expr)
     elif self.base == 'of_octets_t':
         return expr_expr
     elif utils.class_is_list(self.base):
         return '"".join([x.pack() for x in %s])' % expr_expr
     elif self.base == 'of_mac_addr_t':
         return 'struct.pack("!6B", *%s)' % expr_expr
     elif self.base == 'of_ipv6_t':
         return 'struct.pack("!16s", %s)' % expr_expr
     elif self.base in ['of_match_t', 'of_port_desc_t', 'of_meter_features_t']:
         return '%s.pack()' % expr_expr
     elif self.base == 'of_port_name_t':
         return self._gen_string_pack_expr(16, expr_expr)
     elif self.base == 'of_table_name_t' or self.base == 'of_serial_num_t':
         return self._gen_string_pack_expr(32, expr_expr)
     elif self.base == 'of_desc_str_t':
         return self._gen_string_pack_expr(256, expr_expr)
     else:
         return "loxi.unimplemented('pack %s')" % self.base
Exemplo n.º 18
0
def gen_obj_show_c(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Source file for object showing. 
 * 
 */

#define DISABLE_WARN_UNUSED_RESULT
#include <loci/loci.h>
#include <loci/loci_show.h>
#include <loci/loci_obj_show.h>

static int
unknown_show(loci_writer_f writer, void* cookie, of_object_t *obj)
{
    return writer(cookie, "Unable to print object of type %d, version %d\\n", 
                         obj->object_id, obj->version);
}    
""")

    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            out.write("""
int
%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
{
    int out = 0;
""" % dict(cls=cls, ver_name=ver_name))

            members, member_types = loxi_utils.all_member_types_get(cls, version)
            for m_type in member_types:
                if loxi_utils.type_is_scalar(m_type) or m_type in \
                        ["of_match_t", "of_octets_t"]:
                    # Declare instance of these
                    out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
                else:
                    out.write("""
    %(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)
            for member in members:
                m_type = member["m_type"]
                m_name = member["name"]
                #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
                emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + m_name; 
                if loxi_utils.skip_member_name(m_name):
                    continue
                if (loxi_utils.type_is_scalar(m_type) or
                    m_type in ["of_match_t", "of_octets_t"]):
                    out.write("""
    %(cls)s_%(m_name)s_get(obj, &%(v_name)s);
    out += writer(cookie, "%(m_name)s=");
    out += %(emitter)s(writer, cookie, %(v_name)s);
    out += writer(cookie, " "); 
""" % dict(cls=cls, m_name=m_name, m_type=m_type,
           v_name=var_name_map(m_type), emitter=emitter))
                elif loxi_utils.class_is_list(m_type):
                    sub_cls = m_type[:-2] # Trim _t
                    elt_type = loxi_utils.list_to_entry_type(m_type)
                    out.write("""
    out += writer(cookie, "%(elt_type)s={ ");
    %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
    %(u_type)s_ITER(&%(v_name)s, &elt, rv) {
        of_object_show(writer, cookie, (of_object_t *)&elt);
    }
    out += writer(cookie, "} "); 
""" % dict(sub_cls=sub_cls, u_type=sub_cls.upper(), v_name=var_name_map(m_type),
           elt_type=elt_type, cls=cls, m_name=m_name, m_type=m_type))
                else:
                    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);
""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, 
           v_name=var_name_map(m_type), ver_name=ver_name))

            out.write("""
    return out;
}
""")
    out.write("""
/**
 * Log a match entry
 */
int
loci_show_match(loci_writer_f writer, void* cookie, of_match_t *match)
{
    int out = 0;
""")

    for key, entry in match.of_match_members.items():
        m_type = entry["m_type"]
        #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
        emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + key; 
        out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
        out += writer(cookie, "%(key)s active="); 
        out += %(emitter)s(writer, cookie, match->fields.%(key)s);
        out += writer(cookie, "/"); 
        out += %(emitter)s(writer, cookie, match->masks.%(key)s);
        out += writer(cookie, " ");
    }
""" % dict(key=key, ku=key.upper(), emitter=emitter, m_type=m_type))

    out.write("""
    return out;
}
""")

    # Generate big table indexed by version and object
    for version in of_g.of_version_range:
        out.write("""
static loci_obj_show_f show_funs_v%(version)s[OF_OBJECT_COUNT] = {
""" % dict(version=version))
        out.write("    unknown_show, /* of_object, not a valid specific type */\n")
        for j, cls in enumerate(of_g.all_class_order):
            comma = ""
            if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
                comma = ","

            if (not loxi_utils.class_in_version(cls, version) or 
                    cls in type_maps.inheritance_map):
                out.write("    unknown_show%s\n" % comma);
            else:
                out.write("    %s_%s_show%s\n" % 
                          (cls, loxi_utils.version_to_name(version), comma))
        out.write("};\n\n")

    out.write("""
static loci_obj_show_f *show_funs[5] = {
    NULL,
    show_funs_v1,
    show_funs_v2,
    show_funs_v3,
    show_funs_v4
};

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 */
            return show_funs[obj->version][obj->object_id](writer, cookie, (of_object_t *)obj);
        } else {
            return writer(cookie, "Bad version %d\\n", obj->version);
        }
    }
    return writer(cookie, "Bad object id %d\\n", obj->object_id);
}
""")
Exemplo n.º 19
0
def gen_c(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Source file for OpenFlow message validation.
 *
 */

#include "loci_log.h"
#include <loci/loci.h>
#include <loci/loci_validator.h>

#define VALIDATOR_LOG(...) LOCI_LOG_ERROR("Validator Error: " __VA_ARGS__)

""")

    # Declarations
    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            out.write("""
static inline int %(cls)s_%(ver_name)s_validate(uint8_t *buf, int len);\
""" % dict(cls=cls, ver_name=ver_name))

    out.write("\n")

    # Definitions
    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            if loxi_utils.class_is_list(cls):
                gen_list_validator(out, cls, version)
            else:
                gen_validator(out, cls, version)

        out.write("""
int
of_validate_message_%(ver_name)s(of_message_t msg, int len)
{
    of_object_id_t object_id = of_message_to_object_id(msg, len);
    uint8_t *buf = OF_MESSAGE_TO_BUFFER(msg);
    switch (object_id) {
""" % dict(ver_name=ver_name))
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            if loxi_utils.class_is_message(cls):
                out.write("""\
    case %(cls_id)s:
        return %(cls)s_%(ver_name)s_validate(buf, len);
""" % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper()))
        out.write("""\
    default:
        VALIDATOR_LOG("%(cls)s: could not map %(cls_id)s");
        return -1;
    }
}
""" % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper()))

    out.write("""
int
of_validate_message(of_message_t msg, int len)
{
    of_version_t version;
    if (len < OF_MESSAGE_MIN_LENGTH ||
        len != of_message_length_get(msg)) {
        VALIDATOR_LOG("message length %d != %d", len,
                      of_message_length_get(msg));
        return -1;
    }

    version = of_message_version_get(msg);
    switch (version) {
""")

    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        out.write("""\
    case %(ver_name)s:
        return of_validate_message_%(ver_name)s(msg, len);
""" % dict(ver_name=ver_name))

    out.write("""\
    default:
        VALIDATOR_LOG("Bad version %%d", %(ver_name)s);
        return -1;
    }
}
""" % dict(ver_name=ver_name))
Exemplo n.º 20
0
def gen_obj_show_c(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Source file for object showing.
 *
 */

#define DISABLE_WARN_UNUSED_RESULT
#include <loci/loci.h>
#include <loci/loci_show.h>
#include <loci/loci_obj_show.h>

static int
unknown_show(loci_writer_f writer, void* cookie, of_object_t *obj)
{
    return writer(cookie, "Unable to print object of type %d, version %d\\n",
                         obj->object_id, obj->version);
}
""")

    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in of_g.standard_class_order:
            if not loxi_utils.class_in_version(cls, version):
                continue
            if type_maps.class_is_virtual(cls):
                continue
            out.write("""
int
%(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))

            members, member_types = loxi_utils.all_member_types_get(cls, version)
            for m_type in member_types:
                if loxi_utils.type_is_scalar(m_type) or m_type in \
                        ["of_match_t", "of_octets_t"]:
                    # Declare instance of these
                    out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
                else:
                    out.write("""
    %(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):
                        out.write("    of_object_t elt;\n    int rv;\n")
            for member in members:
                m_type = member["m_type"]
                m_name = member["name"]
                emitter = gen_emitter(cls, m_name, m_type)
                if loxi_utils.skip_member_name(m_name):
                    continue
                if (loxi_utils.type_is_scalar(m_type) or
                    m_type in ["of_match_t", "of_octets_t"]):
                    out.write("""
    %(cls)s_%(m_name)s_get(obj, &%(v_name)s);
    out += writer(cookie, "%(m_name)s=");
    out += %(emitter)s(writer, cookie, %(v_name)s);
    out += writer(cookie, " ");
""" % dict(cls=cls, m_name=m_name, m_type=m_type,
           v_name=var_name_map(m_type), emitter=emitter))
                elif loxi_utils.class_is_list(m_type):
                    sub_cls = m_type[:-2] # Trim _t
                    elt_type = loxi_utils.list_to_entry_type(m_type)
                    out.write("""
    out += writer(cookie, "%(elt_type)s={ ");
    %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
    %(u_type)s_ITER(&%(v_name)s, &elt, rv) {
        of_object_show(writer, cookie, (of_object_t *)&elt);
    }
    out += writer(cookie, "} ");
""" % dict(sub_cls=sub_cls, u_type=sub_cls.upper(), v_name=var_name_map(m_type),
           elt_type=elt_type, cls=cls, m_name=m_name, m_type=m_type))
                else:
                    sub_cls = m_type[:-2] # Trim _t
                    out.write("""
    %(cls)s_%(m_name)s_bind(obj, &%(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))

            out.write("""
    return out;
}
""")
    out.write("""
/**
 * Log a match entry
 */
int
loci_show_match(loci_writer_f writer, void* cookie, of_match_t *match)
{
    int out = 0;
""")

    for key, entry in match.of_match_members.items():
        m_type = entry["m_type"]
        emitter = gen_emitter('of_match', key, m_type)
        out.write("""
    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
        out += writer(cookie, "%(key)s active=");
        out += %(emitter)s(writer, cookie, match->fields.%(key)s);
        out += writer(cookie, "/");
        out += %(emitter)s(writer, cookie, match->masks.%(key)s);
        out += writer(cookie, " ");
    }
""" % dict(key=key, ku=key.upper(), emitter=emitter, m_type=m_type))

    out.write("""
    return out;
}
""")

    # Generate big table indexed by version and object
    for version in of_g.of_version_range:
        out.write("""
static const loci_obj_show_f show_funs_v%(version)s[OF_OBJECT_COUNT] = {
""" % dict(version=version))
        out.write("    unknown_show, /* of_object, not a valid specific type */\n")
        for j, cls in enumerate(of_g.all_class_order):
            comma = ""
            if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
                comma = ","

            if (not loxi_utils.class_in_version(cls, version) or
                    type_maps.class_is_virtual(cls)):
                out.write("    unknown_show%s\n" % comma);
            else:
                out.write("    %s_%s_show%s\n" %
                          (cls, loxi_utils.version_to_name(version), comma))
        out.write("};\n\n")

    out.write("""
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 (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);
        }
    }
    return writer(cookie, "Bad object id %d\\n", obj->object_id);
}
""")
Exemplo n.º 21
0
def gen_c(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""
/**
 *
 * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
 *
 * Source file for OpenFlow message validation.
 *
 */

#include "loci_log.h"
#include <loci/loci.h>
#include <loci/loci_validator.h>

#define VALIDATOR_LOG(...) LOCI_LOG_ERROR("Validator Error: " __VA_ARGS__)

""")

    # Declarations
    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            out.write("""
static inline int %(cls)s_%(ver_name)s_validate(uint8_t *buf, int len);\
""" % dict(cls=cls, ver_name=ver_name))

    out.write("\n")

    # Definitions
    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            if loxi_utils.class_is_list(cls):
                gen_list_validator(out, cls, version)
            else:
                gen_validator(out, cls, version)

        out.write("""
int
of_validate_message_%(ver_name)s(of_message_t msg, int len)
{
    of_object_id_t object_id = of_message_to_object_id(msg, len);
    uint8_t *buf = OF_MESSAGE_TO_BUFFER(msg);
    switch (object_id) {
""" % dict(ver_name=ver_name))
        for cls in reversed(of_g.standard_class_order):
            if not loxi_utils.class_in_version(cls, version):
                continue
            if cls in type_maps.inheritance_map:
                continue
            if loxi_utils.class_is_message(cls):
                out.write("""\
    case %(cls_id)s:
        return %(cls)s_%(ver_name)s_validate(buf, len);
""" % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper()))
        out.write("""\
    default:
        VALIDATOR_LOG("%(cls)s: could not map %(cls_id)s");
        return -1;
    }
}
""" % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper()))

    out.write("""
int
of_validate_message(of_message_t msg, int len)
{
    of_version_t version;
    if (len < OF_MESSAGE_MIN_LENGTH ||
        len != of_message_length_get(msg)) {
        VALIDATOR_LOG("message length %d != %d", len,
                      of_message_length_get(msg));
        return -1;
    }

    version = of_message_version_get(msg);
    switch (version) {
""")

    for version in of_g.of_version_range:
        ver_name = loxi_utils.version_to_name(version)
        out.write("""\
    case %(ver_name)s:
        return of_validate_message_%(ver_name)s(msg, len);
""" % dict(ver_name=ver_name))

    out.write("""\
    default:
        VALIDATOR_LOG("Bad version %%d", %(ver_name)s);
        return -1;
    }
}
""" % dict(ver_name=ver_name))