Skip to content

Commit

Permalink
openflow_input: changed syntax for openflow input parsing of enums
Browse files Browse the repository at this point in the history
  • Loading branch information
andi-bigswitch committed Sep 19, 2013
1 parent 938f326 commit dfeb594
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 64 deletions.
32 changes: 24 additions & 8 deletions loxi_front_end/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
# EPL for the specific language governing permissions and limitations
# under the EPL.

from generic_utils import find
from collections import namedtuple
import copy
import of_g
import loxi_front_end.type_maps as type_maps
Expand All @@ -33,33 +35,43 @@
class InputError(Exception):
pass

def create_member(m_ast):

FrontendCtx = namedtuple("FrontendCtx", ("used_enums"))

def get_type(t_ast, ctx):
if t_ast[0] == "enum":
ctx.used_enums.add(t_ast[1])

return t_ast[1]

def create_member(m_ast, ctx):
if m_ast[0] == 'pad':
return OFPadMember(length=m_ast[1])
elif m_ast[0] == 'type':
return OFTypeMember(name=m_ast[2], oftype=m_ast[1], value=m_ast[3])
return OFTypeMember(name=m_ast[2], oftype=get_type(m_ast[1], ctx), value=m_ast[3])
elif m_ast[0] == 'data':
if m_ast[2] == 'length' or m_ast[2] == 'len': # Should be moved to parser
return OFLengthMember(name=m_ast[2], oftype=m_ast[1])
return OFLengthMember(name=m_ast[2], oftype=get_type(m_ast[1], ctx))
elif m_ast[2] == 'actions_len':
# HACK only usage so far
return OFFieldLengthMember(name=m_ast[2], oftype=m_ast[1], field_name='actions')
return OFFieldLengthMember(name=m_ast[2], oftype=get_type(m_ast[1], ctx), field_name='actions')
else:
return OFDataMember(name=m_ast[2], oftype=m_ast[1])
return OFDataMember(name=m_ast[2], oftype=get_type(m_ast[1], ctx))
elif m_ast[0] == 'discriminator':
return OFDiscriminatorMember(name=m_ast[2], oftype=m_ast[1])
return OFDiscriminatorMember(name=m_ast[2], oftype=get_type(m_ast[1], ctx))
else:
raise InputError("Dont know how to create member: %s" % m_ast[0])

def create_ofinput(ast):

"""
Create an OFInput from an AST
@param ast An AST as returned by loxi_front_end.parser.parse
@returns An OFInput object
"""

ctx = FrontendCtx(set())
ofinput = OFInput(wire_versions=set(), classes=[], enums=[])

for decl_ast in ast:
Expand All @@ -70,7 +82,7 @@ def create_ofinput(ast):
# 3: super_class or None
# 4: list of members
superclass = decl_ast[3]
members = [create_member(m_ast) for m_ast in decl_ast[4]]
members = [create_member(m_ast, ctx) for m_ast in decl_ast[4]]

discriminators = [ m for m in members if isinstance(m, OFDiscriminatorMember) ]
if len(discriminators) > 1:
Expand Down Expand Up @@ -103,4 +115,8 @@ def create_ofinput(ast):
if not ofinput.wire_versions:
raise InputError("Missing #version metadata")

for used_enum in ctx.used_enums:
if not find(lambda e: e.name == used_enum, ofinput.enums):
raise Exception("Undeclared enum used in OFInput: {}".format(used_enum))

return ofinput
15 changes: 8 additions & 7 deletions loxi_front_end/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@
identifier = word.copy().setName("identifier")

# Type names
scalar_type = word
array_type = P.Combine(word + lit('[') - P.Word(P.alphanums + '_') - lit(']'))
list_type = P.Combine(kw('list') - lit('(') - identifier - lit(')'))
any_type = (array_type | list_type | scalar_type).setName("type name")
enum_type = kw("enum") - word
scalar_type = tag("scalar") + word
array_type = tag("array") + P.Combine(word + lit('[') - P.Word(P.alphanums + '_') - lit(']'))
list_type = tag("list") + P.Combine(kw('list') - lit('(') - identifier - lit(')'))
any_type = P.Group(enum_type | array_type | list_type | scalar_type).setName("type name")

# Structs
pad_member = P.Group(kw('pad') - s('(') - integer - s(')'))
Expand All @@ -56,7 +57,7 @@
data_member = P.Group(tag('data') + any_type - identifier)

struct_param_name = kw("align")
struct_param = P.Group(struct_param_name - s('=') - any_type)
struct_param = P.Group(struct_param_name - s('=') - word)
struct_param_list = P.Forward()
struct_param_list << struct_param + P.Optional(s(',') - P.Optional(struct_param_list))

Expand All @@ -68,12 +69,12 @@

# Enums
enum_param_name = kw("wire_type") | kw("bitmask") | kw("complete")
enum_param = P.Group(enum_param_name - s('=') - any_type)
enum_param = P.Group(enum_param_name - s('=') - word)
enum_param_list = P.Forward()
enum_param_list << enum_param + P.Optional(s(',') + P.Optional(enum_param_list))

enum_member_param_name = kw("virtual")
enum_member_param = P.Group(enum_member_param_name - s('=') - any_type)
enum_member_param = P.Group(enum_member_param_name - s('=') - word)
enum_member_param_list = P.Forward()
enum_member_param_list << enum_member_param + P.Optional(s(',') + P.Optional(enum_member_param_list))

Expand Down
14 changes: 7 additions & 7 deletions openflow_input/standard-1.0
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ enum ofp_flow_wildcards(wire_type=uint32_t, bitmask=True) {
OFPFW_NW_DST_MASK = 0xfc000,
OFPFW_DL_VLAN_PCP = 0x100000,
OFPFW_NW_TOS = 0x200000,
OFPFW_ALL = 0x3fffff,
OFPFW_ALL(virtual=True) = 0x3fffff,
};

enum ofp_action_type(wire_type=uint16_t) {
Expand Down Expand Up @@ -586,7 +586,7 @@ struct of_flow_mod : of_header {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand All @@ -603,7 +603,7 @@ struct of_flow_add : of_flow_mod {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand All @@ -620,7 +620,7 @@ struct of_flow_modify : of_flow_mod {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand All @@ -637,7 +637,7 @@ struct of_flow_modify_strict : of_flow_mod {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand All @@ -654,7 +654,7 @@ struct of_flow_delete : of_flow_mod {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand All @@ -671,7 +671,7 @@ struct of_flow_delete_strict : of_flow_mod {
uint16_t priority;
uint32_t buffer_id;
of_port_no_t out_port;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
list(of_action_t) actions;
};

Expand Down
12 changes: 6 additions & 6 deletions openflow_input/standard-1.1
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ struct of_flow_mod : of_header {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -877,7 +877,7 @@ struct of_flow_add : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -898,7 +898,7 @@ struct of_flow_modify : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -919,7 +919,7 @@ struct of_flow_modify_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -940,7 +940,7 @@ struct of_flow_delete : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -961,7 +961,7 @@ struct of_flow_delete_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand Down
12 changes: 6 additions & 6 deletions openflow_input/standard-1.2
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ struct of_flow_mod : of_header {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -793,7 +793,7 @@ struct of_flow_add : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -814,7 +814,7 @@ struct of_flow_modify : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -835,7 +835,7 @@ struct of_flow_modify_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -856,7 +856,7 @@ struct of_flow_delete : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -877,7 +877,7 @@ struct of_flow_delete_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand Down
12 changes: 6 additions & 6 deletions openflow_input/standard-1.3
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ struct of_flow_mod : of_header {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -945,7 +945,7 @@ struct of_flow_add : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -966,7 +966,7 @@ struct of_flow_modify : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -987,7 +987,7 @@ struct of_flow_modify_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -1008,7 +1008,7 @@ struct of_flow_delete : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand All @@ -1029,7 +1029,7 @@ struct of_flow_delete_strict : of_flow_mod {
uint32_t buffer_id;
of_port_no_t out_port;
uint32_t out_group;
ofp_flow_mod_flags flags;
enum ofp_flow_mod_flags flags;
pad(2);
of_match_t match;
list(of_instruction_t) instructions;
Expand Down
26 changes: 13 additions & 13 deletions utest/test_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,21 @@ def test_simple(self):
['OFPPC_NO_PACKET_IN', [], 64]]],
['metadata', 'version', '2'],
['struct', 'of_echo_reply', [['align', '8']], None, [
['data', 'uint8_t', 'version'],
['type', 'uint8_t', 'type', 3],
['data', 'uint16_t', 'length'],
['data', 'uint32_t', 'xid'],
['data', 'of_octets_t', 'data']]],
['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', 'uint32_t', 'queue_id'],
['data', 'uint16_t', 'len'],
['data', ['scalar', 'uint32_t'], 'queue_id'],
['data', ['scalar', 'uint16_t'], 'len'],
['pad', 2],
['data', 'list(of_queue_prop_t)', 'properties']]],
['data', ['list', 'list(of_queue_prop_t)'], 'properties']]],
]
self.assertEquals(expected_ast, ast)

Expand Down Expand Up @@ -167,15 +167,15 @@ def test_inheritance(self):
['metadata', 'version', '1'],

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

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

0 comments on commit dfeb594

Please sign in to comment.