Beispiel #1
0
def build_ofclasses(version):
    blacklist = ["of_experimenter", "of_action_experimenter"]
    ofclasses = []
    for ofclass in of_g.ir[version].classes:
        cls = ofclass.name
        if type_maps.class_is_virtual(cls):
            continue
        if cls in blacklist:
            continue

        members = []
        type_members = []

        for m in ofclass.members:
            if type(m) == OFTypeMember:
                members.append(m)
                type_members.append(members[-1])
            elif type(m) == OFLengthMember:
                members.append(m)
            elif type(m) == OFFieldLengthMember:
                members.append(m)
            elif type(m) == OFPadMember:
                members.append(m)
            elif type(m) == OFDataMember:
                if utils.class_is_message(ofclass.name) and m.name == 'version':
                    # HACK move to frontend
                    members.append(OFTypeMember(
                        name=m.name,
                        oftype=m.oftype,
                        value=version))
                    type_members.append(members[-1])
                else:
                    members.append(m)

        ofclasses.append(
            PyOFClass(name=cls,
                      pyname=generate_pyname(cls),
                      members=members,
                      type_members=type_members,
                      min_length=of_g.base_length[(cls, version)],
                      is_fixed_length=(cls, version) in of_g.is_fixed_length))
    return ofclasses
Beispiel #2
0
def populate_type_maps():
    """
    Use the type members in the IR to fill out the legacy type_maps.
    """

    def split_inherited_cls(cls):
        if cls == 'of_meter_band_stats': # HACK not a subtype of of_meter_band
            return None, None
        for parent in sorted(type_maps.inheritance_data.keys(), reverse=True):
            if cls.startswith(parent):
                return (parent, cls[len(parent)+1:])
        return None, None

    def find_experimenter(parent, cls):
        for experimenter in sorted(of_g.experimenter_name_to_id.keys(), reverse=True):
            prefix = parent + '_' + experimenter
            if cls.startswith(prefix) and cls != prefix:
                return experimenter
        return None

    def find_type_value(ofclass, m_name):
        for m in ofclass.members:
            if isinstance(m, OFTypeMember) and m.name == m_name:
                return m.value
        raise KeyError("ver=%d, cls=%s, m_name=%s" % (wire_version, cls, m_name))

    # Most inheritance classes: actions, instructions, etc
    for wire_version, protocol in of_g.ir.items():
        for ofclass in protocol.classes:
            cls = ofclass.name
            parent, subcls = split_inherited_cls(cls)
            if not (parent and subcls):
                continue
            if parent == 'of_oxm':
                val = (find_type_value(ofclass, 'type_len') >> 8) & 0xff
            else:
                val = find_type_value(ofclass, 'type')
            type_maps.inheritance_data[parent][wire_version][subcls] = val

            # Extensions (only actions for now)
            experimenter = find_experimenter(parent, cls)
            if parent == 'of_action' and experimenter:
                val = find_type_value(ofclass, 'subtype')
                type_maps.extension_action_subtype[wire_version][experimenter][cls] = val
                if wire_version >= of_g.VERSION_1_3:
                    cls2 = parent + "_id" + cls[len(parent):]
                    type_maps.extension_action_id_subtype[wire_version][experimenter][cls2] = val

    # Messages
    for wire_version, protocol in of_g.ir.items():
        for ofclass in protocol.classes:
            cls = ofclass.name
            # HACK (though this is what loxi_utils.class_is_message() does)
            if not [x for x in ofclass.members if isinstance(x, OFDataMember) and x.name == 'xid']:
                continue
            if type_maps.class_is_virtual(cls):
                continue
            subcls = cls[3:]
            val = find_type_value(ofclass, 'type')
            if not val in type_maps.message_types[wire_version].values():
                type_maps.message_types[wire_version][subcls] = val

            # Extensions
            experimenter = find_experimenter('of', cls)
            if experimenter:
                val = find_type_value(ofclass, 'subtype')
                type_maps.extension_message_subtype[wire_version][experimenter][cls] = val

    type_maps.generate_maps()
Beispiel #3
0
 def is_virtual(self):
     return type_maps.class_is_virtual(self.c_name)
Beispiel #4
0
def build_ofclasses(version):
    blacklist = ["of_action", "of_action_header", "of_header", "of_queue_prop",
                 "of_queue_prop_header", "of_experimenter", "of_action_experimenter",
                 "of_oxm", "of_oxm_header", "of_oxm_experimenter_header",
                 "of_hello_elem", "of_hello_elem_header"]
    ofclasses = []
    for cls in of_g.standard_class_order:
        if type_maps.class_is_virtual(cls):
            continue
        if version not in of_g.unified[cls] or cls in blacklist:
            continue
        unified_class = util.lookup_unified_class(cls, version)

        # Name for the generated Python class
        if utils.class_is_action(cls):
            pyname = cls[10:]
        elif utils.class_is_oxm(cls):
            pyname = cls[7:]
        elif utils.class_is_meter_band(cls):
            pyname = cls[14:]
        elif utils.class_is_instruction(cls):
            pyname = cls[15:]
        else:
            pyname = cls[3:]

        type_values = get_type_values(cls, version)
        members = []
        type_members = []

        pad_count = 0

        for member in unified_class['members']:
            if member['name'] in ['length', 'len']:
                members.append(LengthMember(name=member['name'],
                                            oftype=oftype.OFType(member['m_type'], version)))
            elif (cls, version, member['name']) in field_length_members:
                field_name = field_length_members[(cls, version, member['name'])]
                members.append(FieldLengthMember(name=member['name'],
                                                 oftype=oftype.OFType(member['m_type'], version),
                                                 field_name=field_name))
            elif member['name'] in type_values:
                members.append(TypeMember(name=member['name'],
                                          oftype=oftype.OFType(member['m_type'], version),
                                          value=type_values[member['name']]))
                type_members.append(members[-1])
            elif member['name'].startswith("pad"):
                # HACK this should be moved to the frontend
                pad_oftype = oftype.OFType(member['m_type'], version)
                length = struct.calcsize("!" + pad_oftype._pack_fmt())
                if pad_oftype.is_array: length *= pad_oftype.array_length
                members.append(PadMember(length=length))
            else:
                members.append(Member(name=member['name'],
                                      oftype=oftype.OFType(member['m_type'], version)))

        ofclasses.append(
            OFClass(name=cls,
                    pyname=pyname,
                    members=members,
                    type_members=type_members,
                    min_length=of_g.base_length[(cls, version)],
                    is_fixed_length=(cls, version) in of_g.is_fixed_length))
    return ofclasses