Exemple #1
0
def match_sanity_check():
    count = 0
    for match_v in ["of_match_v1", "of_match_v2"]:
        count += 1
        for mm in of_g.unified[match_v][count]["members"]:
            key = mm["name"]
            if key.find("_mask") >= 0:
                continue
            if loxi_utils.skip_member_name(key):
                continue
            if key == "wildcards":
                continue
            if not key in of_match_members:
                print "Key %s not found in match struct, v %s" % (key, match_v)
                sys.exit(1)

    # Check oxm list and the list above
    for key in oxm.oxm_types:
        if not key in of_match_members:
            if not (key.find("_masked") > 0):
                debug("Key %s in oxm.oxm_types, not of_match_members" % key)
                sys.exit(1)
            if not key[:-7] in of_match_members:
                debug("Key %s in oxm.oxm_types, but %s not in of_match_members"
                      % (key, key[:-7]))
                sys.exit(1)

    for key in of_match_members:
        if not key in oxm.oxm_types:
            debug("Key %s in of_match_members, not in oxm.oxm_types" % key)
            sys.exit(1)
        if of_match_members[key]["m_type"] != oxm.oxm_types[key]:
            debug("Type mismatch for key %s in oxm data: %s vs %s" %
                  (key, of_match_members[key]["m_type"], oxm.oxm_types[key]))
            sys.exit(1)
def gen_validator(out, cls, version):
    fixed_len = of_g.base_length[(cls, version)]
    ver_name = loxi_utils.version_to_name(version)
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
    if (len < %(fixed_len)s) {
        VALIDATOR_LOG("Class %(cls)s.  Len %%d too small, < %%d", len, %(fixed_len)s);
        return -1;
    }
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(),
           fixed_len=fixed_len))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        m_offset = member['offset']
        m_cls = m_type[:-2]  # Trim _t
        if loxi_utils.skip_member_name(m_name):
            continue
        if not loxi_utils.type_is_of_object(m_type):
            continue
        if not loxi_utils.class_is_var_len(m_cls, version):
            continue
        if cls == "of_packet_out" and m_name == "actions":
            # See _PACKET_OUT_ACTION_LEN
            out.write("""
    {
        uint16_t %(m_name)s_len;
        buf_u16_get(buf + %(m_offset)s - 2, &%(m_name)s_len);
        if (%(m_name)s_len + %(m_offset)s > len) {
            VALIDATOR_LOG("Class %(cls)s, member %(m_name)s.  "
                          "Len %%d and offset %%d too big for %%d",
                          %(m_name)s_len, %(m_offset)s, len);
            return -1;
        }
""" % dict(m_name=m_name, m_offset=m_offset, cls=cls))
        else:
            out.write("""
    
    {    int %(m_name)s_len = len - %(m_offset)s;
   
""" % dict(m_name=m_name, m_offset=m_offset))
        out.write("""
        if (%(m_cls)s_%(ver_name)s_validate(buf + %(m_offset)s, %(m_name)s_len) < 0) {
            return -1;
        }
    }
""" % dict(m_name=m_name, m_cls=m_cls, ver_name=ver_name, m_offset=m_offset))
    out.write("""
    return 0;
}
""")
Exemple #3
0
def gen_validator(out, cls, version):
    fixed_len = of_g.base_length[(cls, version)];
    ver_name = loxi_utils.version_to_name(version)
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
    if (len < %(fixed_len)s) {
        VALIDATOR_LOG("Class %(cls)s.  Len %%d too small, < %%d", len, %(fixed_len)s);
        return -1;
    }
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(), fixed_len=fixed_len))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        m_offset = member['offset']
        m_cls = m_type[:-2] # Trim _t
        if loxi_utils.skip_member_name(m_name):
            continue
        if not loxi_utils.type_is_of_object(m_type):
            continue
        if not loxi_utils.class_is_var_len(m_cls, version):
            continue
        if cls == "of_packet_out" and m_name == "actions":
            # See _PACKET_OUT_ACTION_LEN
            out.write("""
    {
        uint16_t %(m_name)s_len;
        buf_u16_get(buf + %(m_offset)s - 2, &%(m_name)s_len);
        if (%(m_name)s_len + %(m_offset)s > len) {
            VALIDATOR_LOG("Class %(cls)s, member %(m_name)s.  "
                          "Len %%d and offset %%d too big for %%d",
                          %(m_name)s_len, %(m_offset)s, len);
            return -1;
        }
""" % dict(m_name=m_name, m_offset=m_offset, cls=cls))
        else:
            out.write("""

    {    int %(m_name)s_len = len - %(m_offset)s;

"""  % dict(m_name=m_name, m_offset=m_offset))
        out.write("""
        if (%(m_cls)s_%(ver_name)s_validate(buf + %(m_offset)s, %(m_name)s_len) < 0) {
            return -1;
        }
    }
""" % dict(m_name=m_name, m_cls=m_cls, ver_name=ver_name, m_offset=m_offset))
    out.write("""
    return 0;
}
""")
Exemple #4
0
def match_sanity_check():
    count = 0
    for match_v in ["of_match_v1", "of_match_v2"]:
        count += 1
        for mm in of_g.unified[match_v][count]["members"]:
            key = mm["name"]
            if key.find("_mask") >= 0:
                continue
            if loxi_utils.skip_member_name(key):
                continue
            if key == "wildcards":
                continue
            if not key in of_match_members:
                print "Key %s not found in match struct, v %s" % (key, match_v)
                sys.exit(1)

    # Generate list of OXM names from the unified classes
    oxm_names = [x[7:] for x in of_g.unified.keys() if
                 x.startswith('of_oxm_') and
                 x.find('masked') < 0 and
                 x.find('header') < 0]

    # Check that all OXMs are in the match members
    for key in oxm_names:
        if not key in of_match_members:
            if not (key.find("_masked") > 0):
                debug("Key %s in OXM, not of_match_members" % key)
                sys.exit(1)
            if not key[:-7] in of_match_members:
                debug("Key %s in OXM, but %s not in of_match_members"
                      % (key, key[:-7]))
                sys.exit(1)

    # Check that all match members are in the OXMs
    for key in of_match_members:
        if not key in oxm_names:
            debug("Key %s in of_match_members, not in OXM" % key)
            sys.exit(1)
        oxm_type = of_g.unified['of_oxm_%s' % key]['union']['value']['m_type']
        if of_match_members[key]["m_type"] != oxm_type:
            debug("Type mismatch for key %s in oxm data: %s vs %s" %
                  (key, of_match_members[key]["m_type"], oxm_type))
            sys.exit(1)
Exemple #5
0
def match_sanity_check():
    count = 0
    for match_v in ["of_match_v1", "of_match_v2"]:
        count += 1
        for mm in of_g.unified[match_v][count]["members"]:
            key = mm["name"]
            if key.find("_mask") >= 0:
                continue
            if loxi_utils.skip_member_name(key):
                continue
            if key == "wildcards":
                continue
            if not key in of_match_members:
                print "Key %s not found in match struct, v %s" % (key, match_v)
                sys.exit(1)

    # Generate list of OXM names from the unified classes
    oxm_names = [
        x[7:] for x in of_g.unified.keys() if x.startswith('of_oxm_')
        and x.find('masked') < 0 and x.find('header') < 0
    ]

    # Check that all OXMs are in the match members
    for key in oxm_names:
        if not key in of_match_members:
            if not (key.find("_masked") > 0):
                debug("Key %s in OXM, not of_match_members" % key)
                sys.exit(1)
            if not key[:-7] in of_match_members:
                debug("Key %s in OXM, but %s not in of_match_members" %
                      (key, key[:-7]))
                sys.exit(1)

    # Check that all match members are in the OXMs
    for key in of_match_members:
        if not key in oxm_names:
            debug("Key %s in of_match_members, not in OXM" % key)
            sys.exit(1)
        oxm_type = of_g.unified['of_oxm_%s' % key]['union']['value']['m_type']
        if of_match_members[key]["m_type"] != oxm_type:
            debug("Type mismatch for key %s in oxm data: %s vs %s" %
                  (key, of_match_members[key]["m_type"], oxm_type))
            sys.exit(1)
Exemple #6
0
def match_sanity_check():
    count = 0
    for match_v in ["of_match_v1", "of_match_v2"]:
        count += 1
        for mm in of_g.unified[match_v][count]["members"]:
            key = mm["name"]
            if key.find("_mask") >= 0:
                continue
            if loxi_utils.skip_member_name(key):
                continue
            if key == "wildcards":
                continue
            if not key in of_match_members:
                print "Key %s not found in match struct, v %s" % (key, match_v)
                sys.exit(1)

    # Check oxm list and the list above
    for key in oxm.oxm_types:
        if not key in of_match_members:
            if not (key.find("_masked") > 0):
                debug("Key %s in oxm.oxm_types, not of_match_members" % key)
                sys.exit(1)
            if not key[:-7] in of_match_members:
                debug(
                    "Key %s in oxm.oxm_types, but %s not in of_match_members" %
                    (key, key[:-7]))
                sys.exit(1)

    for key in of_match_members:
        if not key in oxm.oxm_types:
            debug("Key %s in of_match_members, not in oxm.oxm_types" % key)
            sys.exit(1)
        if of_match_members[key]["m_type"] != oxm.oxm_types[key]:
            debug("Type mismatch for key %s in oxm data: %s vs %s" %
                  (key, of_match_members[key]["m_type"], oxm.oxm_types[key]))
            sys.exit(1)
Exemple #7
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_validator(out, cls, version):
    fixed_len = of_g.base_length[(cls, version)]
    ver_name = loxi_utils.version_to_name(version)
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
    if (len < %(fixed_len)s) {
        VALIDATOR_LOG("Class %(cls)s.  Len %%d too small, < %%d", len, %(fixed_len)s);
        return -1;
    }
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(),
           fixed_len=fixed_len))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        m_offset = member['offset']
        m_cls = m_type[:-2]  # Trim _t
        if loxi_utils.skip_member_name(m_name):
            continue
        if not loxi_utils.type_is_of_object(m_type):
            continue
        if not loxi_utils.class_is_var_len(m_cls, version):
            continue
        if cls == "of_packet_out" and m_name == "actions":
            # See _PACKET_OUT_ACTION_LEN
            out.write("""
    {
        uint16_t %(m_name)s_len;
        buf_u16_get(buf + %(m_offset)s - 2, &%(m_name)s_len);
        if (%(m_name)s_len + %(m_offset)s > len) {
            VALIDATOR_LOG("Class %(cls)s, member %(m_name)s.  "
                          "Len %%d and offset %%d too big for %%d",
                          %(m_name)s_len, %(m_offset)s, len);
            return -1;
        }
""" % dict(m_name=m_name, m_offset=m_offset, cls=cls))
        elif version >= of_g.VERSION_1_2 and loxi_utils.cls_is_flow_mod(
                cls) and m_name == "instructions":
            # See _FLOW_MOD_INSTRUCTIONS_OFFSET
            match_offset = v3_match_offset_get(cls)
            m_offset = '%s_offset' % m_name
            out.write("""
    {
        uint16_t %(m_name)s_len, %(m_name)s_offset;
        uint16_t match_len;
        buf_u16_get(buf + %(match_offset)s + 2, &match_len);
        %(m_name)s_offset = %(match_offset)s + OF_MATCH_BYTES(match_len);
        %(m_name)s_len = len - %(m_name)s_offset;
""" % dict(m_name=m_name, cls=cls, match_offset=match_offset))
        elif cls == "of_bsn_gentable_entry_add" and m_name == "value":
            continue
        elif cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "value":
            continue
        elif cls == "of_bsn_gentable_entry_stats_entry" and m_name == "stats":
            continue
        else:
            out.write("""

    {    int %(m_name)s_len = len - %(m_offset)s;

""" % dict(m_name=m_name, m_offset=m_offset))
        out.write("""
        if (%(m_cls)s_%(ver_name)s_validate(buf + %(m_offset)s, %(m_name)s_len) < 0) {
            return -1;
        }
    }
""" % dict(m_name=m_name, m_cls=m_cls, ver_name=ver_name, m_offset=m_offset))
    out.write("""
    return 0;
}
""")
Exemple #9
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 #10
0
def gen_validator(out, cls, version):
    fixed_len = of_g.base_length[(cls, version)];
    ver_name = loxi_utils.version_to_name(version)
    out.write("""
static inline int
%(cls)s_%(ver_name)s_validate(uint8_t *buf, int len)
{
    if (len < %(fixed_len)s) {
        VALIDATOR_LOG("Class %(cls)s.  Len %%d too small, < %%d", len, %(fixed_len)s);
        return -1;
    }
""" % dict(cls=cls, ver_name=ver_name, cls_id=cls.upper(), fixed_len=fixed_len))
    members, member_types = loxi_utils.all_member_types_get(cls, version)
    for member in members:
        m_type = member["m_type"]
        m_name = member["name"]
        m_offset = member['offset']
        m_cls = m_type[:-2] # Trim _t
        if loxi_utils.skip_member_name(m_name):
            continue
        if not loxi_utils.type_is_of_object(m_type):
            continue
        if not loxi_utils.class_is_var_len(m_cls, version):
            continue
        if cls == "of_packet_out" and m_name == "actions":
            # See _PACKET_OUT_ACTION_LEN
            out.write("""
    {
        uint16_t %(m_name)s_len;
        buf_u16_get(buf + %(m_offset)s - 2, &%(m_name)s_len);
        if (%(m_name)s_len + %(m_offset)s > len) {
            VALIDATOR_LOG("Class %(cls)s, member %(m_name)s.  "
                          "Len %%d and offset %%d too big for %%d",
                          %(m_name)s_len, %(m_offset)s, len);
            return -1;
        }
""" % dict(m_name=m_name, m_offset=m_offset, cls=cls))
        elif version >= of_g.VERSION_1_2 and loxi_utils.cls_is_flow_mod(cls) and m_name == "instructions":
            # See _FLOW_MOD_INSTRUCTIONS_OFFSET
            match_offset = v3_match_offset_get(cls)
            m_offset = '%s_offset' % m_name
            out.write("""
    {
        uint16_t %(m_name)s_len, %(m_name)s_offset;
        uint16_t match_len;
        buf_u16_get(buf + %(match_offset)s + 2, &match_len);
        %(m_name)s_offset = %(match_offset)s + OF_MATCH_BYTES(match_len);
        %(m_name)s_len = len - %(m_name)s_offset;
""" % dict(m_name=m_name, cls=cls, match_offset=match_offset))
        elif cls == "of_bsn_gentable_entry_add" and m_name == "value":
            continue;
        elif cls == "of_bsn_gentable_entry_desc_stats_entry" and m_name == "value":
            continue;
        elif cls == "of_bsn_gentable_entry_stats_entry" and m_name == "stats":
            continue;
        else:
            out.write("""

    {    int %(m_name)s_len = len - %(m_offset)s;

"""  % dict(m_name=m_name, m_offset=m_offset))
        out.write("""
        if (%(m_cls)s_%(ver_name)s_validate(buf + %(m_offset)s, %(m_name)s_len) < 0) {
            return -1;
        }
    }
""" % dict(m_name=m_name, m_cls=m_cls, ver_name=ver_name, m_offset=m_offset))
    out.write("""
    return 0;
}
""")