Exemple #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
Exemple #2
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
Exemple #3
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);
}
""")
def gen_list_validator(out, cls, version):
    ver_name = loxi_utils.version_to_name(version)
    e_cls = loxi_utils.list_to_entry_type(cls)
    fixed_len = of_g.base_length[(e_cls, version)]
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(), e_cls=e_cls))

    # TLV16
    if loxi_utils.class_is_tlv16(e_cls):
        subclasses = type_maps.inheritance_map[e_cls]
        out.write("""\
    while (len >= %(fixed_len)s) {
        of_object_id_t e_id;
        uint16_t e_type, e_len;
        buf_u16_get(buf, &e_type);
        buf_u16_get(buf+2, &e_len);
        e_id = %(e_cls)s_to_object_id(e_type, %(ver_name)s);
        switch (e_id) {
""" % dict(fixed_len=fixed_len, ver_name=ver_name, e_cls=e_cls))
        for subcls in subclasses:
            subcls = e_cls + '_' + subcls
            if not loxi_utils.class_in_version(subcls, version):
                continue
            out.write("""\
        case %(subcls_enum)s:
            if (%(subcls)s_%(ver_name)s_validate(buf, e_len) < 0) {
                return -1;
            }
            break;
""" % dict(ver_name=ver_name,
            subcls=subcls,
            subcls_enum=loxi_utils.enum_name(subcls)))
        out.write("""\
        default:
            return -1;
        }
        buf += e_len;
        len -= e_len;
    }
    if (len != 0) {
        return -1;
    }
""" % dict(e_cls=e_cls, ver_name=ver_name))

    # U16 len
    elif loxi_utils.class_is_u16_len(e_cls) or loxi_utils.class_is_action(
            e_cls):
        out.write("""\
    /* TODO verify U16 len elements */
""" % dict())

    # OXM
    elif loxi_utils.class_is_oxm(e_cls):
        out.write("""\
    /* TODO verify OXM elements */
""" % dict())

    # Fixed length
    elif not loxi_utils.class_is_var_len(e_cls, version):
        out.write("""\
    if ((len / %(fixed_len)s) * %(fixed_len)s != len) {
        return -1;
    }
""" % dict(fixed_len=fixed_len))

    # ???
    else:
        out.write("""\
    /* XXX unknown element format */
""" % dict())

    out.write("""
    return 0;
}
""")
Exemple #5
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);
}
""")
Exemple #6
0
def gen_list_validator(out, cls, version):
    ver_name = loxi_utils.version_to_name(version)
    e_cls = loxi_utils.list_to_entry_type(cls)
    fixed_len = of_g.base_length[(e_cls, version)];
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(), e_cls=e_cls))

    # TLV16
    if loxi_utils.class_is_tlv16(e_cls):
        subclasses = type_maps.inheritance_map[e_cls]
        out.write("""\
    while (len >= %(fixed_len)s) {
        of_object_id_t e_id;
        uint16_t e_type, e_len;
        buf_u16_get(buf, &e_type);
        buf_u16_get(buf+2, &e_len);
        e_id = %(e_cls)s_to_object_id(e_type, %(ver_name)s);
        switch (e_id) {
""" % dict(fixed_len=fixed_len, ver_name=ver_name, e_cls=e_cls))
        for subcls in subclasses:
            subcls = e_cls + '_' + subcls
            if not loxi_utils.class_in_version(subcls, version):
                continue
            out.write("""\
        case %(subcls_enum)s:
            if (%(subcls)s_%(ver_name)s_validate(buf, e_len) < 0) {
                return -1;
            }
            break;
""" % dict(ver_name=ver_name, subcls=subcls, subcls_enum=loxi_utils.enum_name(subcls)))
        out.write("""\
        default:
            return -1;
        }
        buf += e_len;
        len -= e_len;
    }
    if (len != 0) {
        return -1;
    }
""" % dict(e_cls=e_cls, ver_name=ver_name))

    # U16 len
    elif loxi_utils.class_is_u16_len(e_cls) or loxi_utils.class_is_action(e_cls):
        out.write("""\
    /* TODO verify U16 len elements */
""" % dict())

    # OXM
    elif loxi_utils.class_is_oxm(e_cls):
        out.write("""\
    /* TODO verify OXM elements */
""" % dict())

    # Fixed length
    elif not loxi_utils.class_is_var_len(e_cls, version):
        out.write("""\
    if ((len / %(fixed_len)s) * %(fixed_len)s != len) {
        return -1;
    }
""" % dict(fixed_len=fixed_len))

    # ???
    else:
        out.write("""\
    /* XXX unknown element format */
""" % dict())

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