Example #1
0
def process_input_file(filename):
    """
    Process an input file

    Does not modify global state.

    @param filename The input filename

    @returns An OFInput object
    """

    # Parse the input file
    try:
        with open(filename, 'r') as f:
            ast = parser.parse(f.read())
    except pyparsing.ParseBaseException as e:
        print "Parse error in %s: %s" % (os.path.basename(filename), str(e))
        sys.exit(1)

    # Create the OFInput from the AST
    try:
        ofinput = frontend.create_ofinput(ast)
    except frontend.InputError as e:
        print "Error in %s: %s" % (os.path.basename(filename), str(e))
        sys.exit(1)

    return ofinput
Example #2
0
    def test_inheritance(self):
        ast = parser.parse("""
#version 1

struct of_queue_prop {
    uint16_t type == ?;
    uint16_t len;
    pad(4);
};

struct of_queue_prop_min_rate : of_queue_prop {
    uint16_t type == 1;
    uint16_t len;
    pad(4);
    uint16_t rate;
    pad(6);
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            [
                'struct', 'of_queue_prop', [], None,
                [['discriminator', ['scalar', 'uint16_t'], 'type'],
                 ['data', ['scalar', 'uint16_t'], 'len'], ['pad', 4]]
            ],
            [
                'struct', 'of_queue_prop_min_rate', [], 'of_queue_prop',
                [['type', ['scalar', 'uint16_t'], 'type', 1],
                 ['data', ['scalar', 'uint16_t'], 'len'], ['pad', 4],
                 ['data', ['scalar', 'uint16_t'], 'rate'], ['pad', 6]]
            ],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        expected_classes = [
            OFClass(name='of_queue_prop',
                    superclass=None,
                    members=[
                        OFDiscriminatorMember('type', 'uint16_t'),
                        OFLengthMember('len', 'uint16_t'),
                        OFPadMember(4)
                    ],
                    virtual=True,
                    params={}),
            OFClass(name='of_queue_prop_min_rate',
                    superclass='of_queue_prop',
                    members=[
                        OFTypeMember('type', 'uint16_t', 1),
                        OFLengthMember('len', 'uint16_t'),
                        OFPadMember(4),
                        OFDataMember('rate', 'uint16_t'),
                        OFPadMember(6)
                    ],
                    virtual=False,
                    params={}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
Example #3
0
    def test_inheritance(self):
        ast = parser.parse("""
#version 1

struct of_queue_prop {
    uint16_t type == ?;
    uint16_t len;
    pad(4);
};

struct of_queue_prop_min_rate : of_queue_prop {
    uint16_t type == 1;
    uint16_t len;
    pad(4);
    uint16_t rate;
    pad(6);
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],

            ['struct', 'of_queue_prop', [], None, [
                ['discriminator', ['scalar', 'uint16_t'], 'type'],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 4]]],

            ['struct', 'of_queue_prop_min_rate', [], 'of_queue_prop', [
                ['type', ['scalar', 'uint16_t'], 'type', 1],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 4],
                ['data', ['scalar', 'uint16_t'], 'rate'],
                ['pad', 6]]],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        expected_classes = [
            OFClass(name='of_queue_prop', superclass=None, members=[
                OFDiscriminatorMember('type', 'uint16_t'),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(4)], virtual=True, params={}),
            OFClass(name='of_queue_prop_min_rate', superclass='of_queue_prop', members= [
                OFTypeMember('type', 'uint16_t', 1),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(4),
                OFDataMember('rate', 'uint16_t'),
                OFPadMember(6)], virtual=False, params= {}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
Example #4
0
    def test_field_length(self):
        ast = parser.parse("""
#version 1

struct of_test_entry {
    uint32_t x;
};

struct of_test {
    uint16_t list_len == length(list);
    list(of_test_entry_t) list;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            [
                'struct', 'of_test_entry', [], None,
                [['data', ['scalar', 'uint32_t'], 'x']]
            ],
            [
                'struct', 'of_test', [], None,
                [['field_length', ['scalar', 'uint16_t'], 'list_len', 'list'],
                 ['data', ['list', 'list(of_test_entry_t)'], 'list']]
            ]
        ]
        self.assertEqual(expected_ast, ast)

        ofinput = frontend.create_ofinput("standard-1.0", ast)
        expected_classes = [
            OFClass(name='of_test_entry',
                    superclass=None,
                    virtual=False,
                    params={},
                    members=[OFDataMember('x', 'uint32_t')]),
            OFClass(name='of_test',
                    superclass=None,
                    virtual=False,
                    params={},
                    members=[
                        OFFieldLengthMember('list_len', 'uint16_t', 'list'),
                        OFDataMember('list', 'list(of_test_entry_t)')
                    ])
        ]
        self.assertEqual(expected_classes, ofinput.classes)
Example #5
0
    def test_field_length(self):
        ast = parser.parse("""
#version 1

struct of_test_entry {
    uint32_t x;
};

struct of_test {
    uint16_t list_len == length(list);
    list(of_test_entry_t) list;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],

            ['struct', 'of_test_entry', [], None, [
                ['data', ['scalar', 'uint32_t'], 'x']]],

            ['struct', 'of_test', [], None, [
                ['field_length', ['scalar', 'uint16_t'], 'list_len', 'list'],
                ['data', ['list', 'list(of_test_entry_t)'], 'list']]]
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput("standard-1.0", ast)
        expected_classes = [
            OFClass(name='of_test_entry', superclass=None, virtual=False, params={},
                members=[
                    OFDataMember('x', 'uint32_t')]),
            OFClass(name='of_test', superclass=None, virtual=False, params={},
                members=[
                    OFFieldLengthMember('list_len', 'uint16_t', 'list'),
                    OFDataMember('list', 'list(of_test_entry_t)')])
        ]
        self.assertEquals(expected_classes, ofinput.classes)
Example #6
0
    def test_simple(self):
        ast = parser.parse("""
#version 1

enum ofp_port_config {
    OFPPC_PORT_DOWN = 0x1,
    OFPPC_NO_STP = 0x2,
    OFPPC_NO_RECV = 0x4,
    OFPPC_NO_RECV_STP = 0x8,
    OFPPC_NO_FLOOD = 0x10,
    OFPPC_NO_FWD = 0x20,
    OFPPC_NO_PACKET_IN = 0x40,
};

#version 2

struct of_echo_reply(align=8) {
    uint8_t version;
    uint8_t type == 3;
    uint16_t length;
    uint32_t xid;
    of_octets_t data;
};

enum ofp_queue_op_failed_code(wire_type=uint32, bitmask=False, complete=True) {
    OFPQOFC_BAD_PORT = 0,
    OFPQOFC_BAD_QUEUE = 1,
    OFPQOFC_EPERM = 2,
};

struct of_packet_queue {
    uint32_t queue_id;
    uint16_t len;
    pad(2);
    list(of_queue_prop_t) properties;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            ['enum', 'ofp_port_config', [], [
                ['OFPPC_PORT_DOWN', [], 1],
                ['OFPPC_NO_STP', [], 2],
                ['OFPPC_NO_RECV', [], 4],
                ['OFPPC_NO_RECV_STP', [], 8],
                ['OFPPC_NO_FLOOD', [], 16],
                ['OFPPC_NO_FWD', [], 32],
                ['OFPPC_NO_PACKET_IN', [], 64]]],
            ['metadata', 'version', '2'],
            ['struct', 'of_echo_reply', [['align', '8']], None, [
                ['data', ['scalar', 'uint8_t'], 'version'],
                ['type', ['scalar', 'uint8_t'], 'type', 3],
                ['data', ['scalar', 'uint16_t'], 'length'],
                ['data', ['scalar', 'uint32_t'], 'xid'],
                ['data', ['scalar', 'of_octets_t'], 'data']]],
            ['enum', 'ofp_queue_op_failed_code',
                [['wire_type', 'uint32'], ['bitmask','False'], ['complete', 'True']], [
                ['OFPQOFC_BAD_PORT', [], 0],
                ['OFPQOFC_BAD_QUEUE', [], 1],
                ['OFPQOFC_EPERM', [], 2]]],
            ['struct', 'of_packet_queue', [], None, [
                ['data', ['scalar', 'uint32_t'], 'queue_id'],
                ['data', ['scalar', 'uint16_t'], 'len'],
                ['pad', 2],
                ['data', ['list', 'list(of_queue_prop_t)'], 'properties']]],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        self.assertEquals(set([1, 2]), ofinput.wire_versions)
        expected_classes = [
            OFClass(name='of_echo_reply', superclass=None, members=[
                OFDataMember('version', 'uint8_t'), # XXX
                OFTypeMember('type', 'uint8_t', 3),
                OFLengthMember('length', 'uint16_t'),
                OFDataMember('xid', 'uint32_t'),
                OFDataMember('data', 'of_octets_t')], virtual=False,
                params={'align': '8'}),
            OFClass(name='of_packet_queue', superclass=None, members=[
                OFDataMember('queue_id', 'uint32_t'),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(2),
                OFDataMember('properties', 'list(of_queue_prop_t)')], virtual=False, params={}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
        expected_enums = [
            OFEnum(name='ofp_port_config', entries=[
                OFEnumEntry('OFPPC_PORT_DOWN', 1, {}),
                OFEnumEntry('OFPPC_NO_STP', 2, {}),
                OFEnumEntry('OFPPC_NO_RECV', 4, {}),
                OFEnumEntry('OFPPC_NO_RECV_STP', 8, {}),
                OFEnumEntry('OFPPC_NO_FLOOD', 16, {}),
                OFEnumEntry('OFPPC_NO_FWD', 32, {}),
                OFEnumEntry('OFPPC_NO_PACKET_IN', 64, {})], params={}),
            OFEnum(name='ofp_queue_op_failed_code', entries=[
                OFEnumEntry('OFPQOFC_BAD_PORT', 0, {}),
                OFEnumEntry('OFPQOFC_BAD_QUEUE', 1, {}),
                OFEnumEntry('OFPQOFC_EPERM', 2, {})],
                params={'wire_type': 'uint32', 'bitmask': 'False', 'complete': 'True'}),
        ]
        self.assertEquals(expected_enums, ofinput.enums)
Example #7
0
    def test_simple(self):
        ast = parser.parse("""
#version 1

enum ofp_port_config {
    OFPPC_PORT_DOWN = 0x1,
    OFPPC_NO_STP = 0x2,
    OFPPC_NO_RECV = 0x4,
    OFPPC_NO_RECV_STP = 0x8,
    OFPPC_NO_FLOOD = 0x10,
    OFPPC_NO_FWD = 0x20,
    OFPPC_NO_PACKET_IN = 0x40,
};

#version 2

struct of_echo_reply(align=8) {
    uint8_t version;
    uint8_t type == 3;
    uint16_t length;
    uint32_t xid;
    of_octets_t data;
};

enum ofp_queue_op_failed_code(wire_type=uint32, bitmask=False, complete=True) {
    OFPQOFC_BAD_PORT = 0,
    OFPQOFC_BAD_QUEUE = 1,
    OFPQOFC_EPERM = 2,
};

struct of_packet_queue {
    uint32_t queue_id;
    uint16_t len;
    pad(2);
    list(of_queue_prop_t) properties;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            [
                'enum', 'ofp_port_config', [],
                [['OFPPC_PORT_DOWN', [], 1], ['OFPPC_NO_STP', [], 2],
                 ['OFPPC_NO_RECV', [], 4], ['OFPPC_NO_RECV_STP', [], 8],
                 ['OFPPC_NO_FLOOD', [], 16], ['OFPPC_NO_FWD', [], 32],
                 ['OFPPC_NO_PACKET_IN', [], 64]]
            ],
            ['metadata', 'version', '2'],
            [
                'struct', 'of_echo_reply', [['align', '8']], None,
                [['data', ['scalar', 'uint8_t'], 'version'],
                 ['type', ['scalar', 'uint8_t'], 'type', 3],
                 ['data', ['scalar', 'uint16_t'], 'length'],
                 ['data', ['scalar', 'uint32_t'], 'xid'],
                 ['data', ['scalar', 'of_octets_t'], 'data']]
            ],
            [
                'enum', 'ofp_queue_op_failed_code',
                [['wire_type', 'uint32'], ['bitmask', 'False'],
                 ['complete', 'True']],
                [['OFPQOFC_BAD_PORT', [], 0], ['OFPQOFC_BAD_QUEUE', [], 1],
                 ['OFPQOFC_EPERM', [], 2]]
            ],
            [
                'struct', 'of_packet_queue', [], None,
                [['data', ['scalar', 'uint32_t'], 'queue_id'],
                 ['data', ['scalar', 'uint16_t'], 'len'], ['pad', 2],
                 ['data', ['list', 'list(of_queue_prop_t)'], 'properties']]
            ],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        self.assertEquals(set([1, 2]), ofinput.wire_versions)
        expected_classes = [
            OFClass(
                name='of_echo_reply',
                superclass=None,
                members=[
                    OFDataMember('version', 'uint8_t'),  # XXX
                    OFTypeMember('type', 'uint8_t', 3),
                    OFLengthMember('length', 'uint16_t'),
                    OFDataMember('xid', 'uint32_t'),
                    OFDataMember('data', 'of_octets_t')
                ],
                virtual=False,
                params={'align': '8'}),
            OFClass(name='of_packet_queue',
                    superclass=None,
                    members=[
                        OFDataMember('queue_id', 'uint32_t'),
                        OFLengthMember('len', 'uint16_t'),
                        OFPadMember(2),
                        OFDataMember('properties', 'list(of_queue_prop_t)')
                    ],
                    virtual=False,
                    params={}),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
        expected_enums = [
            OFEnum(name='ofp_port_config',
                   entries=[
                       OFEnumEntry('OFPPC_PORT_DOWN', 1, {}),
                       OFEnumEntry('OFPPC_NO_STP', 2, {}),
                       OFEnumEntry('OFPPC_NO_RECV', 4, {}),
                       OFEnumEntry('OFPPC_NO_RECV_STP', 8, {}),
                       OFEnumEntry('OFPPC_NO_FLOOD', 16, {}),
                       OFEnumEntry('OFPPC_NO_FWD', 32, {}),
                       OFEnumEntry('OFPPC_NO_PACKET_IN', 64, {})
                   ],
                   params={}),
            OFEnum(name='ofp_queue_op_failed_code',
                   entries=[
                       OFEnumEntry('OFPQOFC_BAD_PORT', 0, {}),
                       OFEnumEntry('OFPQOFC_BAD_QUEUE', 1, {}),
                       OFEnumEntry('OFPQOFC_EPERM', 2, {})
                   ],
                   params={
                       'wire_type': 'uint32',
                       'bitmask': 'False',
                       'complete': 'True'
                   }),
        ]
        self.assertEquals(expected_enums, ofinput.enums)
Example #8
0
    def test_simple(self):
        ast = parser.parse("""
#version 1

enum ofp_port_config {
    OFPPC_PORT_DOWN = 0x1,
    OFPPC_NO_STP = 0x2,
    OFPPC_NO_RECV = 0x4,
    OFPPC_NO_RECV_STP = 0x8,
    OFPPC_NO_FLOOD = 0x10,
    OFPPC_NO_FWD = 0x20,
    OFPPC_NO_PACKET_IN = 0x40,
};

#version 2

struct of_echo_reply {
    uint8_t version;
    uint8_t type == 3;
    uint16_t length;
    uint32_t xid;
    of_octets_t data;
};

enum ofp_queue_op_failed_code {
    OFPQOFC_BAD_PORT = 0,
    OFPQOFC_BAD_QUEUE = 1,
    OFPQOFC_EPERM = 2,
};

struct of_packet_queue {
    uint32_t queue_id;
    uint16_t len;
    pad(2);
    list(of_queue_prop_t) properties;
};
""")

        # Not testing the parser, just making sure the AST is what we expect
        expected_ast = [
            ['metadata', 'version', '1'],
            ['enum', 'ofp_port_config', [
                ['OFPPC_PORT_DOWN', 1],
                ['OFPPC_NO_STP', 2],
                ['OFPPC_NO_RECV', 4],
                ['OFPPC_NO_RECV_STP', 8],
                ['OFPPC_NO_FLOOD', 16],
                ['OFPPC_NO_FWD', 32],
                ['OFPPC_NO_PACKET_IN', 64]]],
            ['metadata', 'version', '2'],
            ['struct', 'of_echo_reply', [
                ['data', 'uint8_t', 'version'],
                ['type', 'uint8_t', 'type', 3],
                ['data', 'uint16_t', 'length'],
                ['data', 'uint32_t', 'xid'],
                ['data', 'of_octets_t', 'data']]],
            ['enum', 'ofp_queue_op_failed_code', [
                ['OFPQOFC_BAD_PORT', 0],
                ['OFPQOFC_BAD_QUEUE', 1],
                ['OFPQOFC_EPERM', 2]]],
            ['struct', 'of_packet_queue', [
                ['data', 'uint32_t', 'queue_id'],
                ['data', 'uint16_t', 'len'],
                ['pad', 2],
                ['data', 'list(of_queue_prop_t)', 'properties']]],
        ]
        self.assertEquals(expected_ast, ast)

        ofinput = frontend.create_ofinput(ast)
        self.assertEquals(set([1, 2]), ofinput.wire_versions)
        expected_classes = [
            OFClass('of_echo_reply', [
                OFDataMember('version', 'uint8_t'), # XXX
                OFTypeMember('type', 'uint8_t', 3),
                OFLengthMember('length', 'uint16_t'),
                OFDataMember('xid', 'uint32_t'),
                OFDataMember('data', 'of_octets_t')]),
            OFClass('of_packet_queue', [
                OFDataMember('queue_id', 'uint32_t'),
                OFLengthMember('len', 'uint16_t'),
                OFPadMember(2),
                OFDataMember('properties', 'list(of_queue_prop_t)')]),
        ]
        self.assertEquals(expected_classes, ofinput.classes)
        expected_enums = [
            OFEnum('ofp_port_config', [
                ('OFPPC_PORT_DOWN', 1),
                ('OFPPC_NO_STP', 2),
                ('OFPPC_NO_RECV', 4),
                ('OFPPC_NO_RECV_STP', 8),
                ('OFPPC_NO_FLOOD', 16),
                ('OFPPC_NO_FWD', 32),
                ('OFPPC_NO_PACKET_IN', 64)]),
            OFEnum('ofp_queue_op_failed_code', [
                ('OFPQOFC_BAD_PORT', 0),
                ('OFPQOFC_BAD_QUEUE', 1),
                ('OFPQOFC_EPERM', 2)]),
        ]
        self.assertEquals(expected_enums, ofinput.enums)