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 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)) return type_values
def convert_to_jtype(obj_name, field_name, c_type): """ Convert from a C type ("uint_32") to a java type ("U32") and return a JType object with the size, internal type, and marshalling functions""" if obj_name in exceptions and field_name in exceptions[obj_name]: return exceptions[obj_name][field_name] elif ( obj_name == "of_header" or loxi_utils.class_is_message(obj_name)) and field_name == "type" and c_type == "uint8_t": return JType("OFType", 'byte') \ .op(read='bb.readByte()', write='bb.writeByte($name)') elif field_name == "type" and re.match(r'of_action.*', obj_name): return JType("OFActionType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)\ .op(read="OFActionTypeSerializerVer$version.readFrom(bb)", write="OFActionTypeSerializerVer$version.writeTo(bb, $name)", pub_type=True) elif field_name == "version" and c_type == "uint8_t": return JType("OFVersion", 'byte') \ .op(read='bb.readByte()', write='bb.writeByte($name)') elif c_type in default_mtype_to_jtype_convert_map: return default_mtype_to_jtype_convert_map[c_type] elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type): return make_standard_list_jtype(c_type) elif c_type in enum_java_types(): return enum_java_types()[c_type] else: print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name) jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type)) return JType(jtype)
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 generate_message(out, name, version): ofclasses = [ x for x in build_ofclasses(version) if utils.class_is_message(x.name) ] util.render_template(out, 'message.py', ofclasses=ofclasses, version=version)
def additional_parent_interfaces(self): if loxi_utils.class_is_message(self.c_name) and not self.is_virtual: m = re.match(r'(.*)Request$', self.name) if m: reply_name = m.group(1) + "Reply" if model.interface_by_name(reply_name): return ["OFRequest<%s>" % reply_name ] return []
def convert_to_jtype(obj_name, field_name, c_type): """ Convert from a C type ("uint_32") to a java type ("U32") and return a JType object with the size, internal type, and marshalling functions""" if obj_name in exceptions and field_name in exceptions[obj_name]: return exceptions[obj_name][field_name] elif (obj_name == "of_header" or loxi_utils.class_is_message(obj_name) ) and field_name == "type" and c_type == "uint8_t": return of_type elif field_name == "type" and re.match(r'of_action.*', obj_name): return action_type elif field_name == "err_type": return JType("OFErrorType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif loxi_utils.class_is(obj_name, "of_error_msg") and field_name == "data": return error_cause_data elif field_name == "stats_type": return JType("OFStatsType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif field_name == "type" and re.match(r'of_instruction.*', obj_name): return instruction_type elif loxi_utils.class_is( obj_name, "of_flow_mod" ) and field_name == "table_id" and c_type == "uint8_t": return table_id_default_zero elif loxi_utils.class_is( obj_name, "of_flow_mod" ) and field_name == "out_group" and c_type == "uint32_t": return of_group_default_any elif field_name == "table_id" and c_type == "uint8_t": return table_id elif field_name == "version" and c_type == "uint8_t": return of_version elif field_name == "buffer_id" and c_type == "uint32_t": return buffer_id elif field_name == "group_id" and c_type == "uint32_t": return of_group elif field_name == 'datapath_id': return datapath_id elif field_name == 'actions' and obj_name == 'of_features_reply': return action_type_set elif field_name == "table_id" and re.match(r'of_bsn_gentable.*', obj_name): return gen_table_id elif field_name == "bundle_id" and re.match(r'of_bundle_.*', obj_name): return bundle_id elif c_type in default_mtype_to_jtype_convert_map: return default_mtype_to_jtype_convert_map[c_type] elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type): return gen_list_jtype(list_cname_to_java_name(c_type)) elif c_type in enum_java_types(): return enum_java_types()[c_type] else: print("WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name)) jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type)) return JType(jtype)
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 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 order_and_assign_object_ids(): """ Order all classes and assign object ids to all classes. This is done to promote a reasonable order of the objects, putting messages first followed by non-messages. No assumptions should be made about the order, nor about contiguous numbering. However, the numbers should all be reasonably small allowing arrays indexed by these enum values to be defined. """ # Generate separate message and non-message ordered lists for cls in of_g.unified: if loxi_utils.class_is_message(cls): of_g.ordered_messages.append(cls) elif loxi_utils.class_is_list(cls): of_g.ordered_list_objects.append(cls) else: of_g.ordered_non_messages.append(cls) of_g.ordered_pseudo_objects.append("of_stats_request") of_g.ordered_pseudo_objects.append("of_stats_reply") of_g.ordered_pseudo_objects.append("of_flow_mod") of_g.ordered_messages.sort() of_g.ordered_pseudo_objects.sort() of_g.ordered_non_messages.sort() of_g.ordered_list_objects.sort() of_g.standard_class_order.extend(of_g.ordered_messages) of_g.standard_class_order.extend(of_g.ordered_non_messages) of_g.standard_class_order.extend(of_g.ordered_list_objects) # This includes pseudo classes for which most code is not generated of_g.all_class_order.extend(of_g.ordered_messages) of_g.all_class_order.extend(of_g.ordered_non_messages) of_g.all_class_order.extend(of_g.ordered_list_objects) of_g.all_class_order.extend(of_g.ordered_pseudo_objects) # Assign object IDs for cls in of_g.ordered_messages: of_g.unified[cls]["object_id"] = of_g.object_id of_g.object_id += 1 for cls in of_g.ordered_non_messages: of_g.unified[cls]["object_id"] = of_g.object_id of_g.object_id += 1 for cls in of_g.ordered_list_objects: of_g.unified[cls]["object_id"] = of_g.object_id of_g.object_id += 1 for cls in of_g.ordered_pseudo_objects: of_g.unified[cls] = {} of_g.unified[cls]["object_id"] = of_g.object_id of_g.object_id += 1
def convert_to_jtype(obj_name, field_name, c_type): """ Convert from a C type ("uint_32") to a java type ("U32") and return a JType object with the size, internal type, and marshalling functions""" if obj_name in exceptions and field_name in exceptions[obj_name]: return exceptions[obj_name][field_name] elif ( (obj_name == "of_header" or loxi_utils.class_is_message(obj_name)) and field_name == "type" and c_type == "uint8_t" ): return of_type elif field_name == "type" and re.match(r"of_action.*", obj_name): return action_type elif field_name == "err_type": return JType("OFErrorType", "short").op(read="bb.readShort()", write="bb.writeShort($name)") elif field_name == "stats_type": return JType("OFStatsType", "short").op(read="bb.readShort()", write="bb.writeShort($name)") elif field_name == "type" and re.match(r"of_instruction.*", obj_name): return instruction_type elif ( obj_name in ("of_flow_add", "of_flow_modify", "of_flow_modify_strict", "of_delete_strict") and field_name == "table_id" and c_type == "uint8_t" ): return table_id_default_zero elif field_name == "table_id" and c_type == "uint8_t": return table_id elif field_name == "version" and c_type == "uint8_t": return of_version elif field_name == "buffer_id" and c_type == "uint32_t": return buffer_id elif field_name == "group_id" and c_type == "uint32_t": return of_group elif field_name == "datapath_id": return datapath_id elif field_name == "actions" and obj_name == "of_features_reply": return action_type_set elif field_name == "table_id" and re.match(r"of_bsn_gentable.*", obj_name): return gen_table_id elif c_type in default_mtype_to_jtype_convert_map: return default_mtype_to_jtype_convert_map[c_type] elif re.match(r"list\(of_([a-zA-Z_]+)_t\)", c_type): return gen_list_jtype(list_cname_to_java_name(c_type)) elif c_type in enum_java_types(): return enum_java_types()[c_type] else: print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name) jtype = name_c_to_caps_camel(re.sub(r"_t$", "", c_type)) return JType(jtype)
def convert_to_jtype(obj_name, field_name, c_type): """ Convert from a C type ("uint_32") to a java type ("U32") and return a JType object with the size, internal type, and marshalling functions""" if obj_name in exceptions and field_name in exceptions[obj_name]: return exceptions[obj_name][field_name] elif ( obj_name == "of_header" or loxi_utils.class_is_message(obj_name)) and field_name == "type" and c_type == "uint8_t": return of_type elif field_name == "type" and re.match(r'of_action.*', obj_name): return action_type elif field_name == "err_type": return JType("OFErrorType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif loxi_utils.class_is(obj_name, "of_error_msg") and field_name == "data": return error_cause_data elif field_name == "stats_type": return JType("OFStatsType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif field_name == "type" and re.match(r'of_instruction.*', obj_name): return instruction_type elif loxi_utils.class_is(obj_name, "of_flow_mod") and field_name == "table_id" and c_type == "uint8_t": return table_id_default_zero elif loxi_utils.class_is(obj_name, "of_flow_mod") and field_name == "out_group" and c_type == "uint32_t": return of_group_default_any elif field_name == "table_id" and c_type == "uint8_t": return table_id elif field_name == "version" and c_type == "uint8_t": return of_version elif field_name == "buffer_id" and c_type == "uint32_t": return buffer_id elif field_name == "group_id" and c_type == "uint32_t": return of_group elif field_name == 'datapath_id': return datapath_id elif field_name == 'actions' and obj_name == 'of_features_reply': return action_type_set elif field_name == "table_id" and re.match(r'of_bsn_gentable.*', obj_name): return gen_table_id elif field_name == "bundle_id" and re.match(r'of_bundle_.*', obj_name): return bundle_id elif c_type in default_mtype_to_jtype_convert_map: return default_mtype_to_jtype_convert_map[c_type] elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type): return gen_list_jtype(list_cname_to_java_name(c_type)) elif c_type in enum_java_types(): return enum_java_types()[c_type] else: print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name) jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type)) return JType(jtype)
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 convert_to_jtype(obj_name, field_name, c_type): """ Convert from a C type ("uint_32") to a java type ("U32") and return a JType object with the size, internal type, and marshalling functions""" if obj_name in exceptions and field_name in exceptions[obj_name]: return exceptions[obj_name][field_name] elif ( obj_name == "of_header" or loxi_utils.class_is_message(obj_name)) and field_name == "type" and c_type == "uint8_t": return JType("OFType", 'byte') \ .op(read='bb.readByte()', write='bb.writeByte($name)') elif field_name == "type" and re.match(r'of_action.*', obj_name): return JType("OFActionType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)\ .op(read="OFActionTypeSerializerVer$version.readFrom(bb)", write="OFActionTypeSerializerVer$version.writeTo(bb, $name)", pub_type=True) elif field_name == "err_type": return JType("OFErrorType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif field_name == "stats_type": return JType("OFStatsType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)') elif field_name == "type" and re.match(r'of_instruction.*', obj_name): return JType("OFInstructionType", 'short') \ .op(read='bb.readShort()', write='bb.writeShort($name)', pub_type=False)\ .op(read="OFInstructionTypeSerializerVer$version.readFrom(bb)", write="OFInstructionTypeSerializerVer$version.writeTo(bb, $name)", pub_type=True) elif obj_name in ("of_flow_add", "of_flow_modify", "of_flow_modify_strict", "of_delete_strict") and field_name == "table_id" and c_type == "uint8_t": return table_id_default_zero elif field_name == "table_id" and c_type == "uint8_t": return table_id elif field_name == "version" and c_type == "uint8_t": return of_version elif field_name == "buffer_id" and c_type == "uint32_t": return JType("OFBufferId") \ .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER") elif field_name == 'datapath_id': return datapath_id elif field_name == 'actions' and obj_name == 'of_features_reply': return JType("Set<OFActionType>") \ .op(read='ChannelUtilsVer10.readSupportedActions(bb)', write='ChannelUtilsVer10.writeSupportedActions(bb, $name)', default='ImmutableSet.<OFActionType>of()') elif c_type in default_mtype_to_jtype_convert_map: return default_mtype_to_jtype_convert_map[c_type] elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type): return make_standard_list_jtype(c_type) elif c_type in enum_java_types(): return enum_java_types()[c_type] else: print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name) jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type)) return JType(jtype)
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 build_ofclasses(version): ofclasses = [] for ofclass in of_g.ir[version].classes: cls = ofclass.name if ofclass.virtual: 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, has_internal_alignment=cls == 'of_action_set_field', has_external_alignment=cls == 'of_match_v3')) return ofclasses
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 build_ofclasses(version): ofclasses = [] for ofclass in of_g.ir[version].classes: cls = ofclass.name if ofclass.virtual: 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, has_internal_alignment=cls == 'of_action_set_field', has_external_alignment=cls == 'of_match_v3')) return ofclasses
def gen_c(out, name): loxi_utils.gen_c_copy_license(out) out.write(""" /** * * AUTOMATICALLY GENERATED FILE. Edits will be lost on regen. * * Source file for OpenFlow message validation. * */ #include "loci_log.h" #include <loci/loci.h> #include <loci/loci_validator.h> #define VALIDATOR_LOG(...) LOCI_LOG_ERROR("Validator Error: " __VA_ARGS__) """) # Declarations for version in of_g.of_version_range: ver_name = loxi_utils.version_to_name(version) for cls in reversed(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(""" static inline int %(cls)s_%(ver_name)s_validate(uint8_t *buf, int len);\ """ % dict(cls=cls, ver_name=ver_name)) out.write("\n") # Definitions for version in of_g.of_version_range: ver_name = loxi_utils.version_to_name(version) for cls in reversed(of_g.standard_class_order): if not loxi_utils.class_in_version(cls, version): continue if cls in type_maps.inheritance_map: continue if loxi_utils.class_is_list(cls): gen_list_validator(out, cls, version) else: gen_validator(out, cls, version) out.write(""" int of_validate_message_%(ver_name)s(of_message_t msg, int len) { of_object_id_t object_id = of_message_to_object_id(msg, len); uint8_t *buf = OF_MESSAGE_TO_BUFFER(msg); switch (object_id) { """ % dict(ver_name=ver_name)) for cls in reversed(of_g.standard_class_order): if not loxi_utils.class_in_version(cls, version): continue if cls in type_maps.inheritance_map: continue if loxi_utils.class_is_message(cls): out.write("""\ case %(cls_id)s: return %(cls)s_%(ver_name)s_validate(buf, len); """ % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper())) out.write("""\ default: VALIDATOR_LOG("%(cls)s: could not map %(cls_id)s"); return -1; } } """ % dict(ver_name=ver_name, cls=cls, cls_id=cls.upper())) out.write(""" int of_validate_message(of_message_t msg, int len) { of_version_t version; if (len < OF_MESSAGE_MIN_LENGTH || len != of_message_length_get(msg)) { VALIDATOR_LOG("message length %d != %d", len, of_message_length_get(msg)); return -1; } version = of_message_version_get(msg); switch (version) { """) for version in of_g.of_version_range: ver_name = loxi_utils.version_to_name(version) out.write("""\ case %(ver_name)s: return of_validate_message_%(ver_name)s(msg, len); """ % dict(ver_name=ver_name)) out.write("""\ default: VALIDATOR_LOG("Bad version %%d", %(ver_name)s); return -1; } } """ % dict(ver_name=ver_name))
def generate_message(out, name, version): ofclasses = [x for x in build_ofclasses(version) if utils.class_is_message(x.name)] util.render_template(out, 'message.py', ofclasses=ofclasses, version=version)