Пример #1
0
def gen_class(t, parent, obj_type, template=None):
    if not parent in class_to_members_map.keys():
        doc_info = "Unknown parent action/instruction class: " + parent
    else:
        doc_info = "Data members inherited from " + parent + ":\n"
    for var in class_to_members_map[parent]:
        doc_info += "    @arg " + var + "\n"
    if obj_type == "action":
        name = "OFPAT_" + t.upper()
    else:
        name = "OFPIT_" + t.upper()
    if template is None:
        template = template_no_list
    to_print = re.sub('--TYPE--', t, template)
    to_print = re.sub('--OBJ_TYPE--', obj_type, to_print)
    to_print = re.sub('--PARENT_TYPE--', parent, to_print)
    to_print = re.sub('--ACT_INST_NAME--', name, to_print)
    to_print = re.sub('--DOC_INFO--', doc_info, to_print)
    print to_print
Пример #2
0
def gen_class(t, parent, obj_type, template=None):
    if not parent in class_to_members_map.keys():
        doc_info = "Unknown parent action/instruction class: " + parent
    else:
        doc_info = "Data members inherited from " + parent + ":\n"
    for var in class_to_members_map[parent]:
        doc_info += "    @arg " + var + "\n"
    if obj_type == "action":
        name = "OFPAT_" + t.upper()
    else:
        name = "OFPIT_" + t.upper()
    if template is None:
        template = template_no_list
    to_print = re.sub('--TYPE--', t, template)
    to_print = re.sub('--OBJ_TYPE--', obj_type, to_print)
    to_print = re.sub('--PARENT_TYPE--', parent, to_print)
    to_print = re.sub('--ACT_INST_NAME--', name, to_print)
    to_print = re.sub('--DOC_INFO--', doc_info, to_print)
    print to_print
Пример #3
0
    --DOC_INFO--
    \"""
    def __init__(self):
        --PARENT_TYPE--.__init__(self)
        self.type = --ACTION_NAME--
        self.len = self.__len__()
    def show(self, prefix=''):
        outstr = prefix + "action_--TYPE--\\n"
        outstr += --PARENT_TYPE--.show(self, prefix)
        return outstr
"""

if __name__ == '__main__':
    for (t, parent) in action_class_map.items():
        if not parent in class_to_members_map.keys():
            doc_info = "Unknown parent action class: " + parent
        else:
            doc_info = "Data members inherited from " + parent + ":\n"
            for var in class_to_members_map[parent]:
                doc_info += "    @arg " + var + "\n"
        action_name = "OFPAT_" + t.upper()
        to_print = re.sub('--TYPE--', t, template)
        to_print = re.sub('--PARENT_TYPE--', parent, to_print)
        to_print = re.sub('--ACTION_NAME--', action_name, to_print)
        to_print = re.sub('--DOC_INFO--', doc_info, to_print)
        print to_print

    # Generate a list of action classes
    print "action_class_list = ("
    prev = None
Пример #4
0
def gen_message_wrapper(msg):
    """
    Generate a wrapper for the given message based on above info
    @param msg String identifying the message name for the class
    """

    msg_name = "OFPT_" + msg.upper()
    parent = message_class_map[msg]
    has_match = False
    has_list = False    # Has trailing list
    has_core_members = False
    has_string = False  # Has trailing string
    if parent != 'ofp_header':
        has_core_members = True
    if msg in match_members:
        has_match = True
    if msg in list_members.keys():
        (list_var, list_type) = list_members[msg]
        has_list = True
    if msg in string_members:
        has_string = True
    if has_core_members:
        print "class " + msg + "(" + parent + "):"
    else:
        print "class " + msg + "(object):"
    _p1('"""')
    _p1("Wrapper class for " + msg)
    print
    _p1("OpenFlow message header: length, version, xid, type")
    _p1("@arg length: The total length of the message")
    _p1("@arg version: The OpenFlow version (" + str(OFP_VERSION) + ")")
    _p1("@arg xid: The transaction ID")
    _p1("@arg type: The message type (" + msg_name + "=" + 
        str(eval(msg_name)) + ")")
    print
    if has_core_members and parent in class_to_members_map.keys():
        _p1("Data members inherited from " + parent + ":")
        for var in class_to_members_map[parent]:
            _p1("@arg " + var)
    if has_list:
        if list_type == None:
            _p1("@arg " + list_var + ": Variable length array of TBD")
        else:
            _p1("@arg " + list_var + ": Object of type " + list_type);
    if has_string:
        _p1("@arg data: Binary string following message members")
    print
    _p1('"""')

    print
    _p1("def __init__(self):")
    if has_core_members:
        _p2(parent + ".__init__(self)")
    _p2("self.header = ofp_header()")
    _p2("self.header.type = " + msg_name)
    if has_match:
        _p2("self.match_fields = match_list()")
    if has_list:
        if list_type == None:
            _p2('self.' + list_var + ' = []')
        else:
            _p2('self.' + list_var + ' = ' + list_type + '()')
    if has_string:
        _p2('self.data = ""')

    print """

    def pack(self):
        \"""
        Pack object into string

        @return The packed string which can go on the wire

        \"""
        self.header.length = len(self)
        packed = self.header.pack()
"""

    # Have to special case the action length calculation for pkt out
    if msg == 'packet_out':
        _p2('self.actions_len = len(self.actions)')
    if has_core_members:
        _p2("packed += " + parent + ".pack(self)")
    if has_match:
        _p2('packed += self.match_fields.pack()')
        _p2('self.match.length = len(self.match_fields)')
    if has_list:
        if list_type == None:
            _p2('for obj in self.' + list_var + ':')
            _p3('packed += obj.pack()')
        else:
            _p2('packed += self.' + list_var + '.pack()')
    if has_string:
        _p2('packed += self.data')
    _p2("return packed")

    print """
    def unpack(self, binary_string):
        \"""
        Unpack object from a binary string

        @param binary_string The wire protocol byte string holding the object
        represented as an array of bytes.
        @return The remainder of binary_string that was not parsed.

        \"""
        binary_string = self.header.unpack(binary_string)
"""
    if has_core_members:
        _p2("binary_string = " + parent + ".unpack(self, binary_string)")
    if has_list:
        if msg == "features_reply":  # Special case port parsing
            # For now, cheat and assume the rest of the message is port list
            _p2("while len(binary_string) >= OFP_PORT_BYTES:")
            _p3("new_port = ofp_port()")
            _p3("binary_string = new_port.unpack(binary_string)")
            _p3("self.ports.append(new_port)")
        elif list_type == None:
            _p2("for obj in self." + list_var + ":")
            _p3("binary_string = obj.unpack(binary_string)")
        elif msg == "packet_out":  # Special case this
            _p2('binary_string = self.actions.unpack(' + 
                'binary_string, bytes=self.actions_len)')
        else:
            _p2("binary_string = self." + list_var + ".unpack(binary_string)")
    if has_string:
        _p2("self.data = binary_string")
        _p2("binary_string = ''")
    else:
        _p2("# Fixme: If no self.data, add check for data remaining")
    _p2("return binary_string")

    print """
    def __len__(self):
        \"""
        Return the length of this object once packed into a string

        @return An integer representing the number bytes in the packed
        string.

        \"""
        length = OFP_HEADER_BYTES
"""
    if has_core_members:
        _p2("length += " + parent + ".__len__(self)")
    if has_list:
        if list_type == None:
            _p2("for obj in self." + list_var + ":")
            _p3("length += len(obj)")
        else:
            _p2("length += len(self." + list_var + ")")
    if has_string:
        _p2("length += len(self.data)")
    _p2("return length")

    print """
    def show(self, prefix=''):
        \"""
        Generate a string (with multiple lines) describing the contents
        of the object in a readable manner

        @param prefix Pre-pended at the beginning of each line.

        \"""
"""
    _p2("outstr = prefix + '" + msg + " (" + msg_name + ")\\n'")
    _p2("prefix += '  '")
    _p2("outstr += prefix + 'ofp header\\n'")
    _p2("outstr += self.header.show(prefix + '  ')")
    if has_core_members:
        _p2("outstr += " + parent + ".show(self, prefix)")
    if has_list:
        if list_type == None:
            _p2('outstr += prefix + "Array ' + list_var + '\\n"')
            _p2('for obj in self.' + list_var +':')
            _p3("outstr += obj.show(prefix + '  ')")
        else:
            _p2('outstr += prefix + "List ' + list_var + '\\n"')
            _p2('outstr += self.' + list_var + ".show(prefix + '  ')")
    if has_string:
        _p2("outstr += prefix + 'data is of length ' + str(len(self.data)) + '\\n'")
        _p2("##@todo Fix this circular reference")
        _p2("# if len(self.data) > 0:")
        _p3("# obj = of_message_parse(self.data)")
        _p3("# if obj != None:")
        _p4("# outstr += obj.show(prefix)")
        _p3("# else:")
        _p4('# outstr += prefix + "Unable to parse data\\n"')
    _p2('return outstr')

    print """
    def __eq__(self, other):
        \"""
        Return True if self and other hold the same data

        @param other Other object in comparison

        \"""
        if type(self) != type(other): return False
        if not self.header.__eq__(other.header): return False
"""
    if has_core_members:
        _p2("if not " + parent + ".__eq__(self, other): return False")
    if has_string:
        _p2("if self.data != other.data: return False")
    if has_list:
        _p2("if self." + list_var + " != other." + list_var + ": return False")
    _p2("return True")

    print """
Пример #5
0
    --DOC_INFO--
    \"""
    def __init__(self):
        --PARENT_TYPE--.__init__(self)
        self.type = --ACTION_NAME--
        self.len = self.__len__()
    def show(self, prefix=''):
        outstr = prefix + "action_--TYPE--\\n"
        outstr += --PARENT_TYPE--.show(self, prefix)
        return outstr
"""

if __name__ == '__main__':
    for (t, parent) in action_class_map.items():
        if not parent in class_to_members_map.keys():
            doc_info = "Unknown parent action class: " + parent
        else:
            doc_info = "Data members inherited from " + parent + ":\n"
            for var in class_to_members_map[parent]:
                doc_info += "    @arg " + var + "\n"
        action_name = "OFPAT_" + t.upper()
        to_print = re.sub('--TYPE--', t, template)
        to_print = re.sub('--PARENT_TYPE--', parent, to_print)
        to_print = re.sub('--ACTION_NAME--', action_name, to_print)
        to_print = re.sub('--DOC_INFO--', doc_info, to_print)
        print to_print

    # Generate a list of action classes
    print "action_class_list = ("
    prev = None
Пример #6
0
def gen_message_wrapper(msg):
    """
    Generate a wrapper for the given message based on above info
    @param msg String identifying the message name for the class
    """

    msg_name = "OFPT_" + msg.upper()
    parent = message_class_map[msg]

    has_list = False  # Has trailing list
    has_core_members = False
    has_string = False  # Has trailing string
    if parent != 'ofp_header':
        has_core_members = True
    if msg in list_members.keys():
        (list_var, list_type) = list_members[msg]
        has_list = True
    if msg in string_members:
        has_string = True

    if has_core_members:
        print "class " + msg + "(" + parent + "):"
    else:
        print "class " + msg + ":"
    _p1('"""')
    _p1("Wrapper class for " + msg)
    print
    _p1("OpenFlow message header: length, version, xid, type")
    _p1("@arg length: The total length of the message")
    _p1("@arg version: The OpenFlow version (" + str(OFP_VERSION) + ")")
    _p1("@arg xid: The transaction ID")
    _p1("@arg type: The message type (" + msg_name + "=" +
        str(eval(msg_name)) + ")")
    print
    if has_core_members and parent in class_to_members_map.keys():
        _p1("Data members inherited from " + parent + ":")
        for var in class_to_members_map[parent]:
            _p1("@arg " + var)
    if has_list:
        if list_type == None:
            _p1("@arg " + list_var + ": Variable length array of TBD")
        else:
            _p1("@arg " + list_var + ": Object of type " + list_type)
    if has_string:
        _p1("@arg data: Binary string following message members")
    print
    _p1('"""')

    print
    _p1("def __init__(self):")
    if has_core_members:
        _p2(parent + ".__init__(self)")
    _p2("self.header = ofp_header()")
    _p2("self.header.type = " + msg_name)
    if has_list:
        if list_type == None:
            _p2('self.' + list_var + ' = []')
        else:
            _p2('self.' + list_var + ' = ' + list_type + '()')
    if has_string:
        _p2('self.data = ""')

    print """

    def pack(self):
        \"""
        Pack object into string

        @return The packed string which can go on the wire

        \"""
        self.header.length = len(self)
        packed = self.header.pack()
"""

    # Have to special case the action length calculation for pkt out
    if msg == 'packet_out':
        _p2('self.actions_len = len(self.actions)')
    if has_core_members:
        _p2("packed += " + parent + ".pack(self)")
    if has_list:
        if list_type == None:
            _p2('for obj in self.' + list_var + ':')
            _p3('packed += obj.pack()')
        else:
            _p2('packed += self.' + list_var + '.pack()')
    if has_string:
        _p2('packed += self.data')
    _p2("return packed")

    print """
    def unpack(self, binary_string):
        \"""
        Unpack object from a binary string

        @param binary_string The wire protocol byte string holding the object
        represented as an array of bytes.
        @return The remainder of binary_string that was not parsed.

        \"""
        binary_string = self.header.unpack(binary_string)
"""
    if has_core_members:
        _p2("binary_string = " + parent + ".unpack(self, binary_string)")
    if has_list:
        if msg == "features_reply":  # Special case port parsing
            # For now, cheat and assume the rest of the message is port list
            _p2("while len(binary_string) >= OFP_PHY_PORT_BYTES:")
            _p3("new_port = ofp_phy_port()")
            _p3("binary_string = new_port.unpack(binary_string)")
            _p3("self.ports.append(new_port)")
        elif list_type == None:
            _p2("for obj in self." + list_var + ":")
            _p3("binary_string = obj.unpack(binary_string)")
        elif msg == "packet_out":  # Special case this
            _p2('binary_string = self.actions.unpack(' +
                'binary_string, bytes=self.actions_len)')
        elif msg == "flow_mod":  # Special case this
            _p2("ai_len = self.header.length - (OFP_FLOW_MOD_BYTES + " +
                "OFP_HEADER_BYTES)")
            _p2("binary_string = self.actions.unpack(binary_string, " +
                "bytes=ai_len)")
        else:
            _p2("binary_string = self." + list_var + ".unpack(binary_string)")
    if has_string:
        _p2("self.data = binary_string")
        _p2("binary_string = ''")
    else:
        _p2("# Fixme: If no self.data, add check for data remaining")
    _p2("return binary_string")

    print """
    def __len__(self):
        \"""
        Return the length of this object once packed into a string

        @return An integer representing the number bytes in the packed
        string.

        \"""
        length = OFP_HEADER_BYTES
"""
    if has_core_members:
        _p2("length += " + parent + ".__len__(self)")
    if has_list:
        if list_type == None:
            _p2("for obj in self." + list_var + ":")
            _p3("length += len(obj)")
        else:
            _p2("length += len(self." + list_var + ")")
    if has_string:
        _p2("length += len(self.data)")
    _p2("return length")

    print """
    def show(self, prefix=''):
        \"""
        Generate a string (with multiple lines) describing the contents
        of the object in a readable manner

        @param prefix Pre-pended at the beginning of each line.

        \"""
"""
    _p2("outstr = prefix + '" + msg + " (" + msg_name + ")\\n'")
    _p2("prefix += '  '")
    _p2("outstr += prefix + 'ofp header\\n'")
    _p2("outstr += self.header.show(prefix + '  ')")
    if has_core_members:
        _p2("outstr += " + parent + ".show(self, prefix)")
    if has_list:
        if list_type == None:
            _p2('outstr += prefix + "Array ' + list_var + '\\n"')
            _p2('for obj in self.' + list_var + ':')
            _p3("outstr += obj.show(prefix + '  ')")
        else:
            _p2('outstr += prefix + "List ' + list_var + '\\n"')
            _p2('outstr += self.' + list_var + ".show(prefix + '  ')")
    if has_string:
        _p2("outstr += prefix + 'data is of length ' + str(len(self.data)) + '\\n'"
            )
        _p2("##@todo Fix this circular reference")
        _p2("# if len(self.data) > 0:")
        _p3("# obj = of_message_parse(self.data)")
        _p3("# if obj != None:")
        _p4("# outstr += obj.show(prefix)")
        _p3("# else:")
        _p4('# outstr += prefix + "Unable to parse data\\n"')
    _p2('return outstr')

    print """
    def __eq__(self, other):
        \"""
        Return True if self and other hold the same data

        @param other Other object in comparison

        \"""
        if type(self) != type(other): return False
        if not self.header.__eq__(other.header): return False
"""
    if has_core_members:
        _p2("if not " + parent + ".__eq__(self, other): return False")
    if has_string:
        _p2("if self.data != other.data: return False")
    if has_list:
        _p2("if self." + list_var + " != other." + list_var + ": return False")
    _p2("return True")

    print """