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
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()
def is_virtual(self): return type_maps.class_is_virtual(self.c_name)
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