Currently, the error message event log which is output by ofp_handler.py
is difficult to understand what is wrong in the previous OpenFlow request
message.
This patch improves the readability of this output to find out errors.

*** Output Example ***
EventOFPErrorMsg received.
version=0x4, msg_type=0x1, msg_len=0x4c, xid=0xecc7f07b
 `-- msg_type: OFPT_ERROR(1)
OFPErrorMsg(type=0x4, code=0x9, data=b'\x04\x0e\x00\x58\xec\xc7\xf0\x7b\x00\x0
0\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x2b\x67\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x0
0\x01\x00\x0c\x80\x00\x18\x04\xc0\xa8\x00\x01\x00\x00\x00\x00')
 |-- type: OFPET_BAD_MATCH(4)
 |-- code: OFPBMC_BAD_PREREQ(9)
 `-- data: version=0x4, msg_type=0xe, msg_len=0x58, xid=0xecc7f07b
     `-- msg_type: OFPT_FLOW_MOD(14)

Signed-off-by: IWASE Yusuke <[email protected]>
---
 ryu/controller/ofp_handler.py |  23 +++++++-
 ryu/ofproto/ofproto_utils.py  | 123 ++++++++++++++++++++++++++++++++++++++++++
 ryu/ofproto/ofproto_v1_0.py   |   5 ++
 ryu/ofproto/ofproto_v1_2.py   |   3 ++
 ryu/ofproto/ofproto_v1_3.py   |   4 ++
 ryu/ofproto/ofproto_v1_4.py   |   4 ++
 ryu/ofproto/ofproto_v1_5.py   |   4 ++
 7 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100644 ryu/ofproto/ofproto_utils.py

diff --git a/ryu/controller/ofp_handler.py b/ryu/controller/ofp_handler.py
index 553e9f4..cc64b1f 100644
--- a/ryu/controller/ofp_handler.py
+++ b/ryu/controller/ofp_handler.py
@@ -31,6 +31,7 @@ from ryu.controller.controller import OpenFlowController
 from ryu.controller.handler import set_ev_handler
 from ryu.controller.handler import HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER,\
     MAIN_DISPATCHER
+from ryu.ofproto import ofproto_parser
 
 
 # The state transition: HANDSHAKE -> CONFIG -> MAIN
@@ -249,5 +250,23 @@ class OFPHandler(ryu.base.app_manager.RyuApp):
                     [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER])
     def error_msg_handler(self, ev):
         msg = ev.msg
-        self.logger.debug('error msg ev %s type 0x%x code 0x%x %s',
-                          msg, msg.type, msg.code, utils.hex_array(msg.data))
+        ofp = msg.datapath.ofproto
+        (version, msg_type, msg_len, xid) = ofproto_parser.header(msg.data)
+        self.logger.debug('EventOFPErrorMsg received.')
+        self.logger.debug(
+            'version=%s, msg_type=%s, msg_len=%s, xid=%s', hex(msg.version),
+            hex(msg.msg_type), hex(msg.msg_len), hex(msg.xid))
+        self.logger.debug(
+            ' `-- msg_type: %s', ofp.ofp_msg_type_to_str(msg.msg_type))
+        self.logger.debug(
+            "OFPErrorMsg(type=%s, code=%s, data=b'%s')", hex(msg.type),
+            hex(msg.code), utils.binary_str(msg.data))
+        self.logger.debug(
+            ' |-- type: %s', ofp.ofp_error_type_to_str(msg.type))
+        self.logger.debug(
+            ' |-- code: %s', ofp.ofp_error_code_to_str(msg.type, msg.code))
+        self.logger.debug(
+            ' `-- data: version=%s, msg_type=%s, msg_len=%s, xid=%s',
+            hex(version), hex(msg_type), hex(msg_len), hex(xid))
+        self.logger.debug(
+            '     `-- msg_type: %s', ofp.ofp_msg_type_to_str(msg_type))
diff --git a/ryu/ofproto/ofproto_utils.py b/ryu/ofproto/ofproto_utils.py
new file mode 100644
index 0000000..939a2ff
--- /dev/null
+++ b/ryu/ofproto/ofproto_utils.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import re
+
+
+def generate(modname):
+    import sys
+    import functools
+
+    mod = sys.modules[modname]
+
+    def add_attr(k, v):
+        setattr(mod, k, v)
+
+    add_attr('ofp_msg_type_to_str',
+             functools.partial(_msg_type_to_str, mod))
+    add_attr('ofp_error_type_to_str',
+             functools.partial(_error_type_to_str, mod))
+    add_attr('ofp_error_code_to_str',
+             functools.partial(_error_code_to_str, mod))
+    add_attr('ofp_error_to_jsondict',
+             functools.partial(_error_to_jsondict, mod))
+
+
+def _get_value_name(mod, value, pattern):
+    for k, v in mod.__dict__.items():
+        if k.startswith(pattern):
+            if v == value:
+                return k
+    return 'Unknown'
+
+
+def _msg_type_to_str(mod, type_):
+    """
+    This method is registered as ofp_msg_type_to_str(type_) method
+    into ryu.ofproto.ofproto_v1_* modules.
+    And this method returns the message type as a string value for given
+    'type' defined in ofp_type enum.
+
+    Example::
+
+        >>> ofproto.ofp_msg_type_to_str(14)
+        'OFPT_FLOW_MOD(14)'
+    """
+    return '%s(%d)' % (_get_value_name(mod, type_, 'OFPT_'), type_)
+
+
+def _error_type_to_str(mod, type_):
+    """
+    This method is registered as ofp_error_type_to_str(type_) method
+    into ryu.ofproto.ofproto_v1_* modules.
+    And this method returns the error type as a string value for given
+    'type' defined in ofp_error_msg structure.
+
+    Example::
+
+        >>> ofproto.ofp_error_type_to_str(4)
+        'OFPET_BAD_MATCH(4)'
+    """
+    return '%s(%d)' % (_get_value_name(mod, type_, 'OFPET_'), type_)
+
+
+def _get_error_names(mod, type_, code):
+    t_name = _get_value_name(mod, type_, 'OFPET_')
+    if t_name == 'Unknown':
+        return 'Unknown', 'Unknown'
+    # Construct error code name pattern
+    # e.g.) "OFPET_BAD_MATCH" -> "OFPBMC_"
+    if t_name == 'OFPET_FLOW_MONITOR_FAILED':
+        c_name_p = 'OFPMOFC_'
+    else:
+        c_name_p = 'OFP'
+        for m in re.findall("_(.)", t_name):
+            c_name_p += m.upper()
+        c_name_p += 'C_'
+    c_name = _get_value_name(mod, code, c_name_p)
+    return t_name, c_name
+
+
+def _error_code_to_str(mod, type_, code):
+    """
+    This method is registered as ofp_error_code_to_str(type_, code) method
+    into ryu.ofproto.ofproto_v1_* modules.
+    And this method returns the error code as a string value for given
+    'type' and 'code' defined in ofp_error_msg structure.
+
+    Example::
+
+        >>> ofproto.ofp_error_code_to_str(4, 9)
+        'OFPBMC_BAD_PREREQ(9)'
+    """
+    (_, c_name) = _get_error_names(mod, type_, code)
+    return '%s(%d)' % (c_name, code)
+
+
+def _error_to_jsondict(mod, type_, code):
+    """
+    This method is registered as ofp_error_to_jsondict(type_, code) method
+    into ryu.ofproto.ofproto_v1_* modules.
+    And this method returns ofp_error_msg as a json format for given
+    'type' and 'code' defined in ofp_error_msg structure.
+
+    Example::
+
+        >>> ofproto.ofp_error_to_jsondict(4, 9)
+        {'code': 'OFPBMC_BAD_PREREQ(9)', 'type': 'OFPET_BAD_MATCH(4)'}
+    """
+    (t_name, c_name) = _get_error_names(mod, type_, code)
+    return {'type': '%s(%d)' % (t_name, type_),
+            'code': '%s(%d)' % (c_name, code)}
diff --git a/ryu/ofproto/ofproto_v1_0.py b/ryu/ofproto/ofproto_v1_0.py
index c4499ef..4cac262 100644
--- a/ryu/ofproto/ofproto_v1_0.py
+++ b/ryu/ofproto/ofproto_v1_0.py
@@ -20,6 +20,8 @@ OpenFlow 1.0 definitions.
 
 from struct import calcsize
 
+from ryu.ofproto import ofproto_utils
+
 
 MAX_XID = 0xffffffff
 
@@ -492,6 +494,9 @@ OFP_QUEUE_PROP_MIN_RATE_SIZE = 16
 assert (calcsize(OFP_QUEUE_PROP_MIN_RATE_PACK_STR) +
         OFP_QUEUE_PROP_HEADER_SIZE == OFP_QUEUE_PROP_MIN_RATE_SIZE)
 
+# generate utility methods
+ofproto_utils.generate(__name__)
+
 
 def nxm_header__(vendor, field, hasmask, length):
     return (vendor << 16) | (field << 9) | (hasmask << 8) | length
diff --git a/ryu/ofproto/ofproto_v1_2.py b/ryu/ofproto/ofproto_v1_2.py
index 9f6c26a..a53b4bf 100644
--- a/ryu/ofproto/ofproto_v1_2.py
+++ b/ryu/ofproto/ofproto_v1_2.py
@@ -19,6 +19,7 @@ OpenFlow 1.2 definitions.
 """
 
 from ryu.lib import type_desc
+from ryu.ofproto import ofproto_utils
 from ryu.ofproto import oxm_fields
 
 from struct import calcsize
@@ -831,6 +832,8 @@ oxm_types = [
 
 oxm_fields.generate(__name__)
 
+# generate utility methods
+ofproto_utils.generate(__name__)
 
 # define constants
 OFP_VERSION = 0x03
diff --git a/ryu/ofproto/ofproto_v1_3.py b/ryu/ofproto/ofproto_v1_3.py
index c3adc61..cf7a48d 100644
--- a/ryu/ofproto/ofproto_v1_3.py
+++ b/ryu/ofproto/ofproto_v1_3.py
@@ -19,6 +19,7 @@ OpenFlow 1.3 definitions.
 """
 
 from ryu.lib import type_desc
+from ryu.ofproto import ofproto_utils
 from ryu.ofproto import oxm_fields
 
 from struct import calcsize
@@ -1229,6 +1230,9 @@ OFP_PROP_EXPERIMENTER_SIZE = 12
 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) ==
         OFP_PROP_EXPERIMENTER_SIZE)
 
+# generate utility methods
+ofproto_utils.generate(__name__)
+
 # define constants
 OFP_VERSION = 0x04
 OFP_TCP_PORT = 6633
diff --git a/ryu/ofproto/ofproto_v1_4.py b/ryu/ofproto/ofproto_v1_4.py
index 345846e..250c0e1 100644
--- a/ryu/ofproto/ofproto_v1_4.py
+++ b/ryu/ofproto/ofproto_v1_4.py
@@ -19,6 +19,7 @@ OpenFlow 1.4 definitions.
 """
 
 from ryu.lib import type_desc
+from ryu.ofproto import ofproto_utils
 from ryu.ofproto import oxm_fields
 
 from struct import calcsize
@@ -1482,6 +1483,9 @@ OFP_PROP_EXPERIMENTER_SIZE = 12
 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) ==
         OFP_PROP_EXPERIMENTER_SIZE)
 
+# generate utility methods
+ofproto_utils.generate(__name__)
+
 # define constants
 OFP_VERSION = 0x05
 OFP_TCP_PORT = 6653
diff --git a/ryu/ofproto/ofproto_v1_5.py b/ryu/ofproto/ofproto_v1_5.py
index 31e5cc0..be5bd14 100644
--- a/ryu/ofproto/ofproto_v1_5.py
+++ b/ryu/ofproto/ofproto_v1_5.py
@@ -19,6 +19,7 @@ OpenFlow 1.5 definitions.
 """
 
 from ryu.lib import type_desc
+from ryu.ofproto import ofproto_utils
 from ryu.ofproto import oxm_fields
 from ryu.ofproto import oxs_fields
 
@@ -1818,6 +1819,9 @@ OFP_PROP_EXPERIMENTER_SIZE = 12
 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) ==
         OFP_PROP_EXPERIMENTER_SIZE)
 
+# generate utility methods
+ofproto_utils.generate(__name__)
+
 # define constants
 OFP_VERSION = 0x06
 OFP_TCP_PORT = 6653
-- 
1.9.1



------------------------------------------------------------------------------
Monitor Your Dynamic Infrastructure at Any Scale With Datadog!
Get real-time metrics from all of your servers, apps and tools
in one place.
SourceForge users - Click here to start your Free Trial of Datadog now!
http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to