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 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:] else: pyname = cls[3:] type_values = get_type_values(cls, version) members = [] length_member = None type_members = [] pad_count = 0 for member in unified_class['members']: if member['name'] in ['length', 'len']: length_member = LengthMember(name=member['name'], offset=member['offset'], oftype=oftype.OFType(member['m_type'], version)) elif member['name'] in type_values: type_members.append(TypeMember(name=member['name'], offset=member['offset'], oftype=oftype.OFType(member['m_type'], version), value=type_values[member['name']])) else: # HACK ensure member names are unique if member['name'].startswith("pad"): if pad_count == 0: m_name = 'pad' else: m_name = "pad%d" % pad_count pad_count += 1 else: m_name = member['name'] members.append(Member(name=m_name, oftype=oftype.OFType(member['m_type'], version), offset=member['offset'], skip=member['name'] in of_g.skip_members)) ofclasses.append( OFClass(name=cls, pyname=pyname, members=members, length_member=length_member, 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 generate_common(out, name, version): ofclasses = [x for x in build_ofclasses(version) if not utils.class_is_message(x.name) and not utils.class_is_action(x.name) and not utils.class_is_oxm(x.name) and not utils.class_is_list(x.name)] util.render_template(out, 'common.py', ofclasses=ofclasses, version=version)
def class_info(self): """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface""" # FIXME: This code could be cleaned up further. Maybe some of the exceptions # here could be folded into ir, or the type arithmetic specified in a more general # fashion def calc_package(i): if i.is_subclassof("of_error_msg"): return "errormsg" elif i.is_instanceof("of_action"): return "action" elif i.is_instanceof("of_action_id"): return "actionid" elif i.is_instanceof("of_instruction"): return "instruction" elif i.is_instanceof("of_instruction_id"): return "instructionid" elif i.is_instanceof("of_oxm"): return "oxm" elif i.is_instanceof("of_meter_band"): return "meterband" elif i.is_instanceof("of_queue_prop"): return "queueprop" elif i.is_instanceof("of_bsn_tlv"): return "bsntlv" else: return "" def calc_super_name(i): if re.match('of_match_.*', i.name): return "Match" else: ir_super_class = self.ir_class.superclass return java_class_name(ir_super_class.name) if ir_super_class else "" package = calc_package(self.ir_class) super_name = calc_super_name(self.ir_class) if self.name == "OFStatsRequest": # stats_requests are special because of their type annotation return (package, "OFMessage", "T extends OFStatsReply") elif self.ir_class.is_subclassof('of_stats_request'): # stats_request subclasses are special because of their type annotation reply_name = re.sub(r'Request$', 'Reply', self.name) super_type_annotation = "T" if self.ir_class.virtual else reply_name type_annotation = "T extends {}".format(reply_name) if self.ir_class.virtual \ else "" return (package, "{}<{}>".format(super_name, super_type_annotation), type_annotation) elif self.name == "OFOxm": return (package, None, "T extends OFValueType<T>") elif loxi_utils.class_is_oxm(self.c_name): # look up type from member value for OFValueType type annotation if self.member_by_name("value") is not None: return (package, "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None) else: return (package, "OFOxm", None) else: return (package, super_name, None)
def gen_all_java(out, name): """ Generate all of the java files @param out is an open file handle to a file called README @param name should be 'README' and is ignored for the java driver """ messages = list() actions = list() instructions = list() matches = list() stat_types = list() queue_prop = list() lists = list() for cls in of_g.unified: print "! Classifying %s" % cls if cls in ["of_stats_reply", "of_flow_mod", "of_stats_request"]: continue # doesn't work?! if loxi_utils.class_is_stats_message(cls): stat_types.append(cls) elif loxi_utils.class_is_message(cls): messages.append(cls) elif loxi_utils.class_is_action(cls): actions.append(cls) elif loxi_utils.class_is_instruction(cls): instructions.append(cls) elif loxi_utils.class_is_oxm(cls): matches.append(cls) elif loxi_utils.class_is_queue_prop(cls): queue_prop.append(cls) elif loxi_utils.class_is_list(cls): lists.append(cls) else: print "Skipping Unknown class object %s" % str(cls) print "Parsed " print " Messages: %d" % len(messages) print " Actions: %d" % len(actions) print " Instructions: %d" % len(instructions) print " OXM matches: %d" % len(matches) print " Stat types: %d" % len(stat_types) print " Queue properties: %d" % len(queue_prop) print " Lists: %d" % len(lists) target_dir = "loxi_output/openflowj" basedir = "%s/%s/" % (target_dir, lang_java.file_to_subdir_map["base_java"]) srcdir = "%s/src/main/java/org/openflow/protocol" % basedir print "Outputting to %s" % basedir if not os.path.exists(basedir): os.makedirs(basedir) java_utils.copy_prewrite_tree(basedir) msgs.create_message_interfaces(messages, srcdir) msgs.create_message_by_version(messages, srcdir) msgs.create_of_type_enum(messages, srcdir) with open("README.java-lang") as readme_src: out.writelines(readme_src.readlines()) out.close()
def class_info(self): """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface""" # FIXME: This duplicates inheritance information that is now available in the loxi_ir # model (note, that the loxi model is on versioned classes). Should check/infer the # inheritance information from the versioned lox_ir classes. if re.match(r'OFStatsRequest$', self.name): return ("", "OFMessage", "T extends OFStatsReply") elif re.match(r'OF.+StatsRequest$', self.name): return ("", "OFStatsRequest<{}>".format(re.sub(r'Request$', 'Reply', self.name)), None) elif re.match(r'OF.+StatsReply$', self.name): return ("", "OFStatsReply", None) elif re.match(r'OF.+ErrorMsg$', self.name): return ("", "OFErrorMsg", None) elif re.match(r'OFFlow(Add|Modify(Strict)?|Delete(Strict)?)$', self.name): return ("", "OFFlowMod", None) elif loxi_utils.class_is_message(self.c_name) and re.match(r'OFBsn.+$', self.name) and self.name != "OFBsnHeader": return ("", "OFBsnHeader", None) elif loxi_utils.class_is_message(self.c_name) and re.match(r'OFNicira.+$', self.name) and self.name != "OFNiciraHeader": return ("", "OFNiciraHeader", None) elif self.name == "OFBsnHeader" or self.name =="OFNiciraHeader": return ("", "OFExperimenter", None) elif re.match(r'OFMatch.*', self.name): return ("", "Match", None) elif loxi_utils.class_is_message(self.c_name): return ("", "OFMessage", None) elif loxi_utils.class_is_action(self.c_name): if re.match(r'OFActionBsn.+', self.name): return ("action", "OFActionBsn", None) elif re.match(r'OFActionNicira.+', self.name): return ("action", "OFActionNicira", None) elif self.name == "OFActionBsn" or self.name == "OFActionNicira": return ("action", "OFActionExperimenter", None) else: return ("action", "OFAction", None) elif re.match(r'OFBsnVport.+$', self.name): return ("", "OFBsnVport", None) elif self.name == "OFOxm": return ("oxm", None, "T extends OFValueType<T>") elif loxi_utils.class_is_oxm(self.c_name): if self.name in model.oxm_map: return ("oxm", "OFOxm<%s>" % model.oxm_map[self.name].type_name, None) else: return ("oxm", "OFOxm", None) elif loxi_utils.class_is_instruction(self.c_name): return ("instruction", "OFInstruction", None) elif loxi_utils.class_is_meter_band(self.c_name): return ("meterband", "OFMeterBand", None) elif loxi_utils.class_is_queue_prop(self.c_name): return ("queueprop", "OFQueueProp", None) elif loxi_utils.class_is_hello_elem(self.c_name): return ("", "OFHelloElem", None) elif loxi_utils.class_is_table_feature_prop(self.c_name): return ("", "OFTableFeatureProp", None) else: return ("", None, None)
def generate_pyname(cls): if utils.class_is_action(cls): return cls[10:] elif utils.class_is_oxm(cls): return cls[7:] elif utils.class_is_meter_band(cls): return cls[14:] elif utils.class_is_instruction(cls): return cls[15:] else: return cls[3:]
def generate_common(out, name, version): ofclasses = [ x for x in build_ofclasses(version) if not utils.class_is_message(x.name) and not utils.class_is_action( x.name) and not utils.class_is_instruction(x.name) and not utils.class_is_meter_band(x.name) and not utils.class_is_oxm(x.name) and not utils.class_is_list(x.name) ] util.render_template(out, 'common.py', ofclasses=ofclasses, version=version)
def get_type_values(cls, version): """ Returns a map from the name of the type member to its value. """ type_values = {} # Primary wire type if utils.class_is_message(cls): type_values['version'] = 'const.OFP_VERSION' type_values['type'] = util.constant_for_value(version, "ofp_type", util.primary_wire_type(cls, version)) if cls in type_maps.flow_mod_list: type_values['_command'] = util.constant_for_value(version, "ofp_flow_mod_command", type_maps.flow_mod_types[version][cls[8:]]) if cls in type_maps.stats_request_list: type_values['stats_type'] = util.constant_for_value(version, "ofp_stats_types", type_maps.stats_types[version][cls[3:-14]]) if cls in type_maps.stats_reply_list: type_values['stats_type'] = util.constant_for_value(version, "ofp_stats_types", type_maps.stats_types[version][cls[3:-12]]) if type_maps.message_is_extension(cls, version): type_values['experimenter'] = '%#x' % type_maps.extension_to_experimenter_id(cls) type_values['subtype'] = type_maps.extension_message_to_subtype(cls, version) elif utils.class_is_action(cls): type_values['type'] = util.constant_for_value(version, "ofp_action_type", util.primary_wire_type(cls, version)) if type_maps.action_is_extension(cls, version): type_values['experimenter'] = '%#x' % type_maps.extension_to_experimenter_id(cls) type_values['subtype'] = type_maps.extension_action_to_subtype(cls, version) elif utils.class_is_queue_prop(cls): type_values['type'] = util.constant_for_value(version, "ofp_queue_properties", util.primary_wire_type(cls, version)) elif utils.class_is_hello_elem(cls): type_values['type'] = util.constant_for_value(version, "ofp_hello_elem_type", util.primary_wire_type(cls, version)) elif utils.class_is_oxm(cls): oxm_class = 0x8000 oxm_type = util.primary_wire_type(cls, version) oxm_masked = cls.find('masked') != -1 and 1 or 0 oxm_len = of_g.base_length[(cls, version)] - 4 type_values['type_len'] = '%#x' % (oxm_class << 16 | oxm_type << 8 | \ oxm_masked << 8 | oxm_len) elif cls == "of_match_v2": type_values['type'] = 0 elif cls == "of_match_v3": type_values['type'] = 1 elif utils.class_is_meter_band(cls): type_values['type'] = util.constant_for_value(version, "ofp_meter_band_type", util.primary_wire_type(cls, version)) elif utils.class_is_instruction(cls): type_values['type'] = util.constant_for_value(version, "ofp_instruction_type", util.primary_wire_type(cls, version)) return type_values
def generate_class(self, clazz): """ return wether or not to generate implementation class clazz. Now true for everything except OFTableModVer10. @param clazz JavaOFClass instance """ if clazz.interface.name.startswith("OFMatchV"): return True elif clazz.name == "OFTableModVer10": # tablemod ver 10 is a hack and has no oftype defined return False if loxi_utils.class_is_message(clazz.interface.c_name): return True if loxi_utils.class_is_oxm(clazz.interface.c_name): return True if loxi_utils.class_is_action(clazz.interface.c_name): return True if loxi_utils.class_is_instruction(clazz.interface.c_name): return True else: return True
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 generate_oxm(out, name, version): ofclasses = [x for x in build_ofclasses(version) if utils.class_is_oxm(x.name)] util.render_template(out, 'oxm.py', ofclasses=ofclasses, version=version)
def class_info(self): """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface""" # FIXME: This code could be cleaned up further. Maybe some of the exceptions # here could be folded into ir, or the type arithmetic specified in a more general # fashion def calc_package(i): if i.is_subclassof("of_error_msg"): return "errormsg" elif i.is_instanceof("of_action"): return "action" elif i.is_instanceof("of_action_id"): return "actionid" elif i.is_instanceof("of_instruction"): return "instruction" elif i.is_instanceof("of_instruction_id"): return "instructionid" elif i.is_instanceof("of_oxm"): return "oxm" elif i.is_instanceof("of_meter_band"): return "meterband" elif i.is_instanceof("of_queue_prop"): return "queueprop" elif i.is_instanceof("of_bsn_tlv"): return "bsntlv" else: return "" def calc_super_name(i): if re.match('of_match_.*', i.name): return "Match" else: ir_super_class = self.ir_class.superclass return java_class_name( ir_super_class.name) if ir_super_class else "" package = calc_package(self.ir_class) super_name = calc_super_name(self.ir_class) if self.name == "OFStatsRequest": # stats_requests are special because of their type annotation return (package, "OFMessage", "T extends OFStatsReply") elif self.ir_class.is_subclassof('of_stats_request'): # stats_request subclasses are special because of their type annotation reply_name = re.sub(r'Request$', 'Reply', self.name) super_type_annotation = "T" if self.ir_class.virtual else reply_name type_annotation = "T extends {}".format(reply_name) if self.ir_class.virtual \ else "" return (package, "{}<{}>".format(super_name, super_type_annotation), type_annotation) elif self.name == "OFOxm": return (package, None, "T extends OFValueType<T>") elif loxi_utils.class_is_oxm(self.c_name): # look up type from member value for OFValueType type annotation if self.member_by_name("value") is not None: return (package, "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None) else: return (package, "OFOxm", None) else: return (package, super_name, None)
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 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
def generate_oxm(out, name, version): ofclasses = [ x for x in build_ofclasses(version) if utils.class_is_oxm(x.name) ] util.render_template(out, 'oxm.py', ofclasses=ofclasses, version=version)
def class_info(self): """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface""" # FIXME: This duplicates inheritance information that is now available in the loxi_ir # model (note, that the loxi model is on versioned classes). Should check/infer the # inheritance information from the versioned lox_ir classes. if re.match(r'OFStatsRequest$', self.name): return ("", "OFMessage", "T extends OFStatsReply") elif self.ir_class.is_subclassof('of_stats_request'): if self.ir_class.is_subclassof('of_bsn_stats_request'): return ("", "OFBsnStatsRequest", None) elif self.ir_class.is_subclassof('of_experimenter_stats_request'): return ("", "OFExperimenterStatsRequest", None) else: return ("", "OFStatsRequest<{}>".format(re.sub(r'Request$', 'Reply', self.name)), None) elif self.ir_class.is_subclassof('of_stats_reply'): if self.ir_class.is_subclassof('of_bsn_stats_reply'): return ("", "OFBsnStatsReply", None) elif self.ir_class.is_subclassof('of_experimenter_stats_reply'): return ("", "OFExperimenterStatsReply", None) else: return ("", "OFStatsReply", None) elif self.ir_class.is_subclassof('of_error_msg'): return ("errormsg", "OFErrorMsg", None) elif self.ir_class.is_subclassof('of_flow_mod'): return ("", "OFFlowMod", None) elif self.ir_class.is_subclassof('of_group_mod'): return ("", "OFGroupMod", None) elif self.ir_class.is_subclassof('of_bsn_header'): return ("", "OFBsnHeader", None) elif self.ir_class.is_subclassof('of_nicira_header'): return ("", "OFNiciraHeader", None) elif self.ir_class.is_subclassof('of_experimenter'): return ("", "OFExperimenter", None) elif re.match(r'OFMatch.*', self.name): return ("", "Match", None) elif self.ir_class.is_message: return ("", "OFMessage", None) elif self.ir_class.is_action: if self.ir_class.is_subclassof('of_action_bsn'): return ("action", "OFActionBsn", None) elif self.ir_class.is_subclassof('of_action_nicira'): return ("action", "OFActionNicira", None) elif self.ir_class.is_subclassof('of_action_experimenter'): return ("action", "OFActionExperimenter", None) else: return ("action", "OFAction", None) elif self.ir_class.is_instanceof("of_action_id"): if self.ir_class.is_subclassof('of_action_id_bsn'): return ("actionid", "OFActionIdBsn", None) elif self.ir_class.is_subclassof('of_action_id_nicira'): return ("actionid", "OFActionIdNicira", None) elif self.ir_class.is_subclassof('of_action_id_experimenter'): return ("actionid", "OFActionIdExperimenter", None) else: return ("actionid", "OFActionId", None) elif self.ir_class.is_instruction: if self.ir_class.is_subclassof('of_instruction_bsn'): return ("instruction", "OFInstructionBsn", None) elif self.ir_class.is_subclassof('of_instruction_experimenter'): return ("instruction", "OFInstructionExperimenter", None) else: return ("instruction", "OFInstruction", None) elif self.ir_class.is_instanceof('of_instruction_id'): if self.ir_class.is_subclassof('of_instruction_id_bsn'): return ("instructionid", "OFInstructionIdBsn", None) elif self.ir_class.is_subclassof('of_instruction_id_experimenter'): return ("instructionid", "OFInstructionIdExperimenter", None) else: return ("instructionid", "OFInstructionId", None) elif re.match(r'OFBsnVport.+$', self.name): return ("", "OFBsnVport", None) elif self.name == "OFOxm": return ("oxm", None, "T extends OFValueType<T>") elif loxi_utils.class_is_oxm(self.c_name): if self.member_by_name("value") is not None: return ("oxm", "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None) else: return ("oxm", "OFOxm", None) elif loxi_utils.class_is_instruction(self.c_name): return ("instruction", "OFInstruction", None) elif loxi_utils.class_is_meter_band(self.c_name): return ("meterband", "OFMeterBand", None) elif loxi_utils.class_is_queue_prop(self.c_name): return ("queueprop", "OFQueueProp", None) elif loxi_utils.class_is_hello_elem(self.c_name): return ("", "OFHelloElem", None) elif loxi_utils.class_is_table_feature_prop(self.c_name): return ("", "OFTableFeatureProp", None) elif loxi_utils.class_is_bsn_tlv(self.c_name): return ("bsntlv", "OFBsnTlv", None) else: return ("", None, None)