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_factory

     datapath.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_cls

     return _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
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

>From 34881421a13987d5eb78d6711c81b7b28b22d9d3 Mon Sep 17 00:00:00 2001
From: IWASE Yusuke <iwase.yusu...@gmail.com>
Date: Tue, 18 Jul 2017 11:45:43 +0900
Subject: [PATCH] [WIP] ofproto: Support OFPErrorExperimenterMsg

Signed-off-by: IWASE Yusuke <iwase.yusu...@gmail.com>
---
 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
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to