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;
}
""")
Beispiel #2
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;
}
""")
Beispiel #3
0
def log_all_class_info():
    """
    Log the results of processing the input

    Debug function
    """

    for cls in of_g.unified:
        for v in of_g.unified[cls]:
            if type(v) == type(0):
                log("cls: %s. ver: %d. base len %d. %s" %
                    (str(cls), v, of_g.base_length[(cls, v)],
                     loxi_utils.class_is_var_len(cls,v) and "not fixed"
                     or "fixed"))
                if "use_version" in of_g.unified[cls][v]:
                    log("cls %s: v %d mapped to %d" % (str(cls), v,
                           of_g.unified[cls][v]["use_version"]))
                if "members" in of_g.unified[cls][v]:
                    for member in of_g.unified[cls][v]["members"]:
                        log("   %-20s: type %-20s. offset %3d" %
                            (member["name"], member["m_type"],
                             member["offset"]))
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;
}
""")
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;
}
""")
Beispiel #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;
}
""")
Beispiel #7
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;
}
""")