The current get async reply and get async implementations follows that of of_protocol and OpenFlow 1.3. However, OpenFlow 1.4 defines a rather different format. This patch updates the implementation to follow the OpenFlow 1.4 specification.
Signed-off-by: Simon Horman <[email protected]> --- v3 * First Post --- ryu/ofproto/ofproto_v1_4_parser.py | 109 +++++------------- .../of14/5-41-ofp_get_async_reply.packet | Bin 32 -> 160 bytes .../packet_data/of14/5-42-ofp_set_async.packet | Bin 32 -> 160 bytes ryu/tests/packet_data_generator/rebar.config | 7 +- ryu/tests/packet_data_generator/src/x5.erl | 119 +++++++++++++++++--- .../json/of14/5-41-ofp_get_async_reply.packet.json | 123 +++++++++++++++++++-- .../json/of14/5-42-ofp_set_async.packet.json | 123 +++++++++++++++++++-- 7 files changed, 362 insertions(+), 119 deletions(-) diff --git a/ryu/ofproto/ofproto_v1_4_parser.py b/ryu/ofproto/ofproto_v1_4_parser.py index 42dfcd8..1edc9b1 100644 --- a/ryu/ofproto/ofproto_v1_4_parser.py +++ b/ryu/ofproto/ofproto_v1_4_parser.py @@ -5680,7 +5680,7 @@ class OFPAsyncConfigPropReasons(StringifyMixin): @OFPAsyncConfigProp.register_type(ofproto.OFPTFPT_EXPERIMENTER_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPTFPT_EXPERIMENTER_MASTER) -class OFPQueueDescPropExperimenter(OFPPropCommonExperimenter4ByteData): +class OFPAsyncConfigPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @@ -5715,24 +5715,7 @@ class OFPGetAsyncReply(MsgBase): ================== ==================================================== Attribute Description ================== ==================================================== - packet_in_mask 2-element array: element 0, when the controller has a - OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER role. element 1, - OFPCR_ROLE_SLAVE role controller. - Bitmasks of following values. - OFPR_NO_MATCH - OFPR_ACTION - OFPR_INVALID_TTL - port_status_mask 2-element array. - Bitmasks of following values. - OFPPR_ADD - OFPPR_DELETE - OFPPR_MODIFY - flow_removed_mask 2-element array. - Bitmasks of following values. - OFPRR_IDLE_TIMEOUT - OFPRR_HARD_TIMEOUT - OFPRR_DELETE - OFPRR_GROUP_DELETE + properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: @@ -5742,36 +5725,24 @@ class OFPGetAsyncReply(MsgBase): msg = ev.msg self.logger.debug('OFPGetAsyncReply received: ' - 'packet_in_mask=0x%08x:0x%08x ' - 'port_status_mask=0x%08x:0x%08x ' - 'flow_removed_mask=0x%08x:0x%08x', - msg.packet_in_mask[0], - msg.packet_in_mask[1], - msg.port_status_mask[0], - msg.port_status_mask[1], - msg.flow_removed_mask[0], - msg.flow_removed_mask[1]) - """ - def __init__(self, datapath, packet_in_mask=None, port_status_mask=None, - flow_removed_mask=None): + 'properties=%s', repr(msg.properties)) + """ + def __init__(self, datapath, properties=None): super(OFPGetAsyncReply, self).__init__(datapath) - self.packet_in_mask = packet_in_mask - self.port_status_mask = port_status_mask - self.flow_removed_mask = flow_removed_mask + self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetAsyncReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) - (packet_in_mask_m, packet_in_mask_s, - port_status_mask_m, port_status_mask_s, - flow_removed_mask_m, flow_removed_mask_s) = struct.unpack_from( - ofproto.OFP_ASYNC_CONFIG_PACK_STR, msg.buf, - ofproto.OFP_HEADER_SIZE) - msg.packet_in_mask = [packet_in_mask_m, packet_in_mask_s] - msg.port_status_mask = [port_status_mask_m, port_status_mask_s] - msg.flow_removed_mask = [flow_removed_mask_m, flow_removed_mask_s] + + msg.properties = [] + rest = msg.buf[ofproto.OFP_HEADER_SIZE:] + while rest: + p, rest = OFPAsyncConfigProp.parse(rest) + msg.properties.append(p) + return msg @@ -5786,24 +5757,7 @@ class OFPSetAsync(MsgBase): ================== ==================================================== Attribute Description ================== ==================================================== - packet_in_mask 2-element array: element 0, when the controller has a - OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER role. element 1, - OFPCR_ROLE_SLAVE role controller. - Bitmasks of following values. - OFPR_NO_MATCH - OFPR_ACTION - OFPR_INVALID_TTL - port_status_mask 2-element array. - Bitmasks of following values. - OFPPR_ADD - OFPPR_DELETE - OFPPR_MODIFY - flow_removed_mask 2-element array. - Bitmasks of following values. - OFPRR_IDLE_TIMEOUT - OFPRR_HARD_TIMEOUT - OFPRR_DELETE - OFPRR_GROUP_DELETE + properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: @@ -5812,28 +5766,23 @@ class OFPSetAsync(MsgBase): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser - packet_in_mask = ofp.OFPR_ACTION | ofp.OFPR_INVALID_TTL - port_status_mask = (ofp.OFPPR_ADD | ofp.OFPPR_DELETE | - ofp.OFPPR_MODIFY) - flow_removed_mask = (ofp.OFPRR_IDLE_TIMEOUT | - ofp.OFPRR_HARD_TIMEOUT | - ofp.OFPRR_DELETE) - req = ofp_parser.OFPSetAsync(datapath, - [packet_in_mask, 0], - [port_status_mask, 0], - [flow_removed_mask, 0]) + properties = [ofp_parser.OFPAsyncConfigPropReasons( + 8, ofp_parser.OFPACPT_PACKET_IN_SLAVE, + (ofp_parser.OFPR_APPLY_ACTION | + ofp_parser.OFPR_INVALID_TTL)), + ofp_parser.OFPAsyncConfigPropExperimenter( + ofproto.OFPTFPT_EXPERIMENTER_MASTER, + 16, 100, 2, bytearray())] + req = ofp_parser.OFPSetAsync(datapath, properties) datapath.send_msg(req) """ - def __init__(self, datapath, - packet_in_mask, port_status_mask, flow_removed_mask): + def __init__(self, datapath, properties=None): super(OFPSetAsync, self).__init__(datapath) - self.packet_in_mask = packet_in_mask - self.port_status_mask = port_status_mask - self.flow_removed_mask = flow_removed_mask + self.properties = properties def _serialize_body(self): - msg_pack_into(ofproto.OFP_ASYNC_CONFIG_PACK_STR, self.buf, - ofproto.OFP_HEADER_SIZE, - self.packet_in_mask[0], self.packet_in_mask[1], - self.port_status_mask[0], self.port_status_mask[1], - self.flow_removed_mask[0], self.flow_removed_mask[1]) + bin_props = bytearray() + for p in self.properties: + bin_props += p.serialize() + + self.buf += bin_props diff --git a/ryu/tests/packet_data/of14/5-41-ofp_get_async_reply.packet b/ryu/tests/packet_data/of14/5-41-ofp_get_async_reply.packet index de941ea043b350c32b50838bb8ee20754f1f8e6f..01ad90f63ea8c0ca56e38f738a31e2af9e691857 100644 GIT binary patch literal 160 zcmXZVOAde_3`Nmb5XH~HfddoQ=e}I2SnMTfPHqRKTzV9*I$5SLVa5RqjyPfcJvHOP Yehu5J&F|m*rPj35=9>3Gr`|qYed)#t5C8xG literal 32 acmZRTW>8>&09GKy2*m6_%nZc*AQ}J&;{am- diff --git a/ryu/tests/packet_data/of14/5-42-ofp_set_async.packet b/ryu/tests/packet_data/of14/5-42-ofp_set_async.packet index 7ce57a1b0ee9887c392e99ccb01f66d53640d44d..0b3facf7844b83eea4aabdbc11d3f51145a84a12 100644 GIT binary patch literal 160 zcmXZVI}(5(3`Nlw5XDbnVPWC++?OjAgSpIP&fFBCTzV9*I$5SLVa5RqjyPfcJvHOP Yehu5J&F|m*rPj35=9>3Gr`|qYed=Wi5dZ)H literal 32 acmZRTVNhUz09GKy2*m6_%nZc*AQ}J(0sv$H diff --git a/ryu/tests/packet_data_generator/rebar.config b/ryu/tests/packet_data_generator/rebar.config index efcf2b1..e060319 100644 --- a/ryu/tests/packet_data_generator/rebar.config +++ b/ryu/tests/packet_data_generator/rebar.config @@ -18,9 +18,12 @@ [{of_protocol, ".*", % {git, "https://github.com/FlowForwarding/of_protocol.git", % "5d6a938bcac91d03e4542845bc014a271bab363a"}}, -% use local branch for merge of v5 branch and pull/66 +% use local branch for merge of upstream v5 branch with pull 66 and 71 +% https://github.com/FlowForwarding/of_protocol/tree/v5 +% https://github.com/FlowForwarding/of_protocol/pull/66 +% https://github.com/FlowForwarding/of_protocol/pull/71 {git, "https://github.com/horms/of_protocol.git", - "36f81a2390586c4298c34b8a6dd7c929edbac707"}}, + "6764e8f0ed5c4dee913310bf2bd908ab1768603e"}}, {flower, ".*", {git, "http://github.com/travelping/flower.git", "d783d8f722cb1eb2fa598d4521b309cfcc703fdb"}}]}. diff --git a/ryu/tests/packet_data_generator/src/x5.erl b/ryu/tests/packet_data_generator/src/x5.erl index 74debf1..4490ac7 100644 --- a/ryu/tests/packet_data_generator/src/x5.erl +++ b/ryu/tests/packet_data_generator/src/x5.erl @@ -701,22 +701,111 @@ x() -> }, #ofp_get_async_request{}, #ofp_get_async_reply{ - packet_in_mask = {[table_miss, invalid_ttl], [table_miss]}, - port_status_mask = {[add, delete, modify], [add, delete]}, - flow_removed_mask = { - [idle_timeout, hard_timeout, delete, group_delete], - [idle_timeout, hard_timeout] - } - }, + properties = + [#ofp_async_config_prop_reasons{ + type = packet_in_slave, + mask = [table_miss, apply_action]}, + #ofp_async_config_prop_reasons{ + type = packet_in_master, + mask = [table_miss, apply_action]}, + #ofp_async_config_prop_reasons{ + type = port_status_slave, + mask = [add, delete]}, + #ofp_async_config_prop_reasons{ + type = port_status_master, + mask = [add, delete]}, + #ofp_async_config_prop_reasons{ + type = flow_removed_slave, + mask = [idle_timeout, hard_timeout]}, + #ofp_async_config_prop_reasons{ + type = flow_removed_master, + mask = [idle_timeout, hard_timeout]}, + #ofp_async_config_prop_reasons{ + type = role_status_slave, + mask = [master_request, config]}, + #ofp_async_config_prop_reasons{ + type = role_status_master, + mask = [master_request, config]}, + #ofp_async_config_prop_reasons{ + type = table_status_slave, + mask = [vacancy_down, vacancy_up]}, + #ofp_async_config_prop_reasons{ + type = table_status_master, + mask = [vacancy_down, vacancy_up]}, + #ofp_async_config_prop_reasons{ + type = requestforward_slave, + mask = [group_mod, meter_mod]}, + #ofp_async_config_prop_reasons{ + type = requestforward_master, + mask = [group_mod, meter_mod]}, + #ofp_async_config_prop_experimenter{ + type = experimenter_slave, + experimenter = 101, + exp_type = 0, + data = <<>>}, + #ofp_async_config_prop_experimenter{ + type = experimenter_master, + experimenter = 101, + exp_type = 1, + data = <<1:32>>}, + #ofp_async_config_prop_experimenter{ + type = experimenter_master, + experimenter = 101, + exp_type = 2, + data = <<1:32, 2:32>>}]}, #ofp_set_async{ - packet_in_mask = {[table_miss, invalid_ttl], [table_miss]}, - port_status_mask = {[add, delete, modify], [add, delete]}, - flow_removed_mask = { - [idle_timeout, hard_timeout, delete, group_delete], - [idle_timeout, hard_timeout] - } - }, - + properties = + [#ofp_async_config_prop_reasons{ + type = packet_in_slave, + mask = [table_miss, apply_action]}, + #ofp_async_config_prop_reasons{ + type = packet_in_master, + mask = [table_miss, apply_action]}, + #ofp_async_config_prop_reasons{ + type = port_status_slave, + mask = [add, delete]}, + #ofp_async_config_prop_reasons{ + type = port_status_master, + mask = [add, delete]}, + #ofp_async_config_prop_reasons{ + type = flow_removed_slave, + mask = [idle_timeout, hard_timeout]}, + #ofp_async_config_prop_reasons{ + type = flow_removed_master, + mask = [idle_timeout, hard_timeout]}, + #ofp_async_config_prop_reasons{ + type = role_status_slave, + mask = [master_request, config]}, + #ofp_async_config_prop_reasons{ + type = role_status_master, + mask = [master_request, config]}, + #ofp_async_config_prop_reasons{ + type = table_status_slave, + mask = [vacancy_down, vacancy_up]}, + #ofp_async_config_prop_reasons{ + type = table_status_master, + mask = [vacancy_down, vacancy_up]}, + #ofp_async_config_prop_reasons{ + type = requestforward_slave, + mask = [group_mod, meter_mod]}, + #ofp_async_config_prop_reasons{ + type = requestforward_master, + mask = [group_mod, meter_mod]}, + #ofp_async_config_prop_experimenter{ + type = experimenter_slave, + experimenter = 101, + exp_type = 0, + data = <<>>}, + #ofp_async_config_prop_experimenter{ + type = experimenter_master, + experimenter = 101, + exp_type = 1, + data = <<1:32>>}, + #ofp_async_config_prop_experimenter{ + type = experimenter_master, + experimenter = 101, + exp_type = 2, + data = <<1:32, 2:32>>}]}, #ofp_meter_mod{ command = add, flags = [pktps, burst, stats], diff --git a/ryu/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json b/ryu/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json index abccf04..35e6ce1 100644 --- a/ryu/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json +++ b/ryu/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json @@ -1,16 +1,117 @@ { "OFPGetAsyncReply": { - "flow_removed_mask": [ - 15, - 3 - ], - "packet_in_mask": [ - 5, - 1 - ], - "port_status_mask": [ - 7, - 3 + "properties": [ + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 0 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 1 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 2 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 3 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 4 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 5 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 6 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 7 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 24, + "type": 8 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 24, + "type": 9 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 10 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 11 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "", + "exp_type": 0, + "experimenter": 101, + "length": 12, + "type": 65534 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "AAAAAQ==", + "exp_type": 1, + "experimenter": 101, + "length": 16, + "type": 65535 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "AAAAAQAAAAI=", + "exp_type": 2, + "experimenter": 101, + "length": 20, + "type": 65535 + } + } ] } } diff --git a/ryu/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json b/ryu/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json index da85b88..aa0aa5f 100644 --- a/ryu/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json +++ b/ryu/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json @@ -1,16 +1,117 @@ { "OFPSetAsync": { - "flow_removed_mask": [ - 15, - 3 - ], - "packet_in_mask": [ - 5, - 1 - ], - "port_status_mask": [ - 7, - 3 + "properties": [ + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 0 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 1 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 2 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 3 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 4 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 5 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 6 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 7 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 24, + "type": 8 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 24, + "type": 9 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 10 + } + }, + { + "OFPAsyncConfigPropReasons": { + "length": 8, + "mask": 3, + "type": 11 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "", + "exp_type": 0, + "experimenter": 101, + "length": 12, + "type": 65534 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "AAAAAQ==", + "exp_type": 1, + "experimenter": 101, + "length": 16, + "type": 65535 + } + }, + { + "OFPAsyncConfigPropExperimenter": { + "data": "AAAAAQAAAAI=", + "exp_type": 2, + "experimenter": 101, + "length": 20, + "type": 65535 + } + } ] } } -- 1.8.5.2 ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
