Hi Hu, It seems a bug of Ryu. When Ryu receives OFPT_ERROR messages with OFPET_EXPERIMENTER type, Ryu will successfully parse OFPT_ERROR messages, but will fail to convert messages into events for Ryu applications.
The attached patch should fix this problem on only OF 1.3. Could you try this? Thanks, Iwase On 2017年07月11日 11:07, Hu Dingyuan wrote:
Hi, When I use ryu to send a apply actions message, a error occurred.match=OFPMatch(oxm_fields={'in_port': 7, 'eth_type': 2048, 'ipv4_src': '192.0.2.129', 'ipv4_dst': '10.0.2.104'}), instructions=[OFPInstructionActions(actions=[OFPActionSetField(eth_src='b6:9f:5d:cf:64:a8'), OFPActionSetField(eth_dst='b6:9f:5d:cf:64:a8'), OFPActionSetField(ipv4_src='10.18.0.1/32'), OFPActionSetField(ip_dscp=4), OFPActionSetField(ip_ecn=2), OFPActionDecNwTtl(len=8,type=24), OFPActionOutput(len=16,max_len=65509,port=7,type=0)],type=4), OFPInstructionGotoTable(len=8,table_id=<FlowTable.transit_counter: 110>,type=1)]This error only occurred few times, I am not sure about why it happened. It should be a bug of ryu? Error in the datapath 000000ecaccde88b from ('2001:da8:215:8f2:2ec:acff:fecd:e890', 41324, 0, 0) hub: uncaught exception: Traceback (most recent call last): File "/usr/local/lib/python3.6/site-packages/ryu/lib/hub.py", line 60, in _launch return func(*args, **kwargs)File "/usr/local/lib/python3.6/site-packages/ryu/controller/controller.py", line 460, in datapath_connection_factorydatapath.serve() File "/usr/local/lib/python3.6/site-packages/ryu/controller/controller.py", line 378, in serve self._recv_loop() File "/usr/local/lib/python3.6/site-packages/ryu/controller/controller.py", line 132, in deactivate method(self) File "/usr/local/lib/python3.6/site-packages/ryu/controller/controller.py", line 273, in _recv_loop ev = ofp_event.ofp_msg_to_ev(msg) File "/usr/local/lib/python3.6/site-packages/ryu/controller/ofp_event.py", line 66, in ofp_msg_to_ev return ofp_msg_to_ev_cls(msg.__class__)(msg)File "/usr/local/lib/python3.6/site-packages/ryu/controller/ofp_event.py", line 71, in ofp_msg_to_ev_clsreturn _OFP_MSG_EVENTS[name] KeyError: 'EventOFPErrorExperimenterMsg' ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
>From 34881421a13987d5eb78d6711c81b7b28b22d9d3 Mon Sep 17 00:00:00 2001 From: IWASE Yusuke <[email protected]> Date: Tue, 18 Jul 2017 11:45:43 +0900 Subject: [PATCH] [WIP] ofproto: Support OFPErrorExperimenterMsg Signed-off-by: IWASE Yusuke <[email protected]> --- ryu/controller/ofp_handler.py | 38 ++++++++++++------ ryu/ofproto/ofproto_v1_3_parser.py | 81 ++++++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 46 deletions(-) diff --git a/ryu/controller/ofp_handler.py b/ryu/controller/ofp_handler.py index 70ffc8c..deb2ed3 100644 --- a/ryu/controller/ofp_handler.py +++ b/ryu/controller/ofp_handler.py @@ -268,18 +268,32 @@ class OFPHandler(ryu.base.app_manager.RyuApp): def error_msg_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto - self.logger.debug( - "EventOFPErrorMsg received.\n" - "version=%s, msg_type=%s, msg_len=%s, xid=%s\n" - " `-- msg_type: %s\n" - "OFPErrorMsg(type=%s, code=%s, data=b'%s')\n" - " |-- type: %s\n" - " |-- code: %s", - hex(msg.version), hex(msg.msg_type), hex(msg.msg_len), - hex(msg.xid), ofp.ofp_msg_type_to_str(msg.msg_type), - hex(msg.type), hex(msg.code), utils.binary_str(msg.data), - ofp.ofp_error_type_to_str(msg.type), - ofp.ofp_error_code_to_str(msg.type, msg.code)) + if msg.type == ofp.OFPET_EXPERIMENTER: + self.logger.debug( + "EventOFPErrorMsg received.\n" + "version=%s, msg_type=%s, msg_len=%s, xid=%s\n" + " `-- msg_type: %s\n" + "OFPErrorExperimenterMsg(type=%s, exp_type=%s," + " experimenter=%s, data=b'%s')", + hex(msg.version), hex(msg.msg_type), hex(msg.msg_len), + hex(msg.xid), + ofp.ofp_msg_type_to_str(msg.msg_type), + hex(msg.type), hex(msg.exp_type), + hex(msg.experimenter), utils.binary_str(msg.data)) + else: + self.logger.debug( + "EventOFPErrorMsg received.\n" + "version=%s, msg_type=%s, msg_len=%s, xid=%s\n" + " `-- msg_type: %s\n" + "OFPErrorMsg(type=%s, code=%s, data=b'%s')\n" + " |-- type: %s\n" + " |-- code: %s", + hex(msg.version), hex(msg.msg_type), hex(msg.msg_len), + hex(msg.xid), + ofp.ofp_msg_type_to_str(msg.msg_type), + hex(msg.type), hex(msg.code), utils.binary_str(msg.data), + ofp.ofp_error_type_to_str(msg.type), + ofp.ofp_error_code_to_str(msg.type, msg.code)) if msg.type == ofp.OFPET_HELLO_FAILED: self.logger.debug( " `-- data: %s", msg.data.decode('ascii')) diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py index c298c99..19c36d6 100644 --- a/ryu/ofproto/ofproto_v1_3_parser.py +++ b/ryu/ofproto/ofproto_v1_3_parser.py @@ -214,6 +214,16 @@ class OFPErrorMsg(MsgBase): OFPET_EXPERIMENTER N/A ============================= =========== + If ``type == OFPET_EXPERIMENTER``, this message has also the following + attributes. + + ============= ====================================================== + Attribute Description + ============= ====================================================== + exp_type Experimenter defined type + experimenter Experimenter ID + ============= ====================================================== + Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, @@ -235,50 +245,53 @@ class OFPErrorMsg(MsgBase): def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, = struct.unpack_from('!H', six.binary_type(buf), ofproto.OFP_HEADER_SIZE) - if type_ == ofproto.OFPET_EXPERIMENTER: - return OFPErrorExperimenterMsg.parser(datapath, version, msg_type, - msg_len, xid, buf) msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) - msg.type, msg.code = struct.unpack_from( - ofproto.OFP_ERROR_MSG_PACK_STR, msg.buf, - ofproto.OFP_HEADER_SIZE) - msg.data = msg.buf[ofproto.OFP_ERROR_MSG_SIZE:] + if type_ == ofproto.OFPET_EXPERIMENTER: + (msg.type, msg.exp_type, msg.experimenter, + msg.data) = cls.parse_experimenter_body(buf) + else: + (msg.type, msg.code, + msg.data) = cls.parse_body(buf) return msg - def _serialize_body(self): - assert self.data is not None - msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, - ofproto.OFP_HEADER_SIZE, self.type, self.code) - self.buf += self.data - - -class OFPErrorExperimenterMsg(MsgBase): - def __init__(self, datapath, type_=None, exp_type=None, experimenter=None, - data=None): - super(OFPErrorExperimenterMsg, self).__init__(datapath) - self.type = ofproto.OFPET_EXPERIMENTER - self.exp_type = exp_type - self.experimenter = experimenter - self.data = data + @classmethod + def parse_body(cls, buf): + type_, code = struct.unpack_from( + ofproto.OFP_ERROR_MSG_PACK_STR, buf, + ofproto.OFP_HEADER_SIZE) + data = buf[ofproto.OFP_ERROR_MSG_SIZE:] + return type_, code, data @classmethod - def parser(cls, datapath, version, msg_type, msg_len, xid, buf): - cls.cls_msg_type = msg_type - msg = super(OFPErrorExperimenterMsg, cls).parser( - datapath, version, msg_type, msg_len, xid, buf) - msg.type, msg.exp_type, msg.experimenter = struct.unpack_from( - ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, msg.buf, + def parse_experimenter_body(cls, buf): + type_, exp_type, experimenter = struct.unpack_from( + ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) - msg.data = msg.buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] - return msg + data = buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] + return type_, exp_type, experimenter, data def _serialize_body(self): assert self.data is not None - msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, - self.buf, ofproto.OFP_HEADER_SIZE, - self.type, self.exp_type, self.experimenter) - self.buf += self.data + if self.type == ofproto.OFPET_EXPERIMENTER: + msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, + self.buf, ofproto.OFP_HEADER_SIZE, + self.type, self.exp_type, self.experimenter) + self.buf += self.data + else: + msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, + self.buf, ofproto.OFP_HEADER_SIZE, + self.type, self.code) + self.buf += self.data + + +# For the backward compatibility +def OFPErrorExperimenterMsg(datapath, type_=None, exp_type=None, + experimenter=None, data=None): + msg = OFPErrorMsg(datapath, data=data) + msg.type = ofproto.OFPET_EXPERIMENTER + msg.exp_type = exp_type + msg.experimenter = experimenter @_register_parser -- 2.7.4
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
