ofp_handler: Output human readable error msg ev log
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 <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
f5932480c5
commit
b6e280172a
@ -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))
|
||||
|
123
ryu/ofproto/ofproto_utils.py
Normal file
123
ryu/ofproto/ofproto_utils.py
Normal file
@ -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)}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user