On Thu, Sep 29, 2016 at 4:44 PM, IWAMOTO Toshihiro <[email protected]>
wrote:
> OFPT_ERROR_MSG can return truncated messages. Some users want to
> see them in human-friendly format [1]. Catch exceptions caused
> by such truncated messages and reraise as OFPTruncatedMessage
> with incomplete ofpmsg in the exception class.
>
> Not every exceptions are captured, and we should deal with other
> OpenFlow versions, too.
>
> [1] https://bugs.launchpad.net/dragonflow/+bug/1624826
>
> Signed-off-by: IWAMOTO Toshihiro <[email protected]>
> ---
> ryu/exception.py | 13 +++++++
> ryu/ofproto/ofproto_v1_3_parser.py | 71 +++++++++++++++++++++++++++++-
> --------
> 2 files changed, 67 insertions(+), 17 deletions(-)
>
> diff --git a/ryu/exception.py b/ryu/exception.py
> index 0a1e72c..1be4ba1 100644
> --- a/ryu/exception.py
> +++ b/ryu/exception.py
> @@ -39,6 +39,19 @@ class OFPMalformedMessage(RyuException):
> message = 'malformed message'
>
>
> +class OFPTruncatedMessage(RyuException):
> + message = 'truncated message: %(orig_ex)s'
> +
> + def __init__(self, ofpmsg, residue, original_exception,
> + msg=None, **kwargs):
> + self.ofpmsg = ofpmsg
> + self.residue = residue
> + self.original_exception = original_exception
> + kwargs['orig_ex'] = str(original_exception)
> +
> + super(OFPTruncatedMessage, self).__init__(msg, **kwargs)
> +
> +
> class NetworkNotFound(RyuException):
> message = 'no such network id %(network_id)s'
>
> diff --git a/ryu/ofproto/ofproto_v1_3_parser.py
> b/ryu/ofproto/ofproto_v1_3_parser.py
> index 99c4a47..ab07f75 100644
> --- a/ryu/ofproto/ofproto_v1_3_parser.py
> +++ b/ryu/ofproto/ofproto_v1_3_parser.py
> @@ -49,6 +49,7 @@ from ryu.lib import addrconv
> from ryu.lib import mac
> from ryu.lib.pack_utils import msg_pack_into
> from ryu.lib.packet import packet
> +from ryu import exception
> from ryu import utils
> from ryu.ofproto.ofproto_parser import StringifyMixin, MsgBase
> from ryu.ofproto import ether
> @@ -1269,17 +1270,28 @@ class OFPMatch(StringifyMixin):
> offset += 4
> length -= 4
>
> + exc = None
> + residue = None
> # XXXcompat
> - cls.parser_old(match, buf, offset, length)
> + try:
> + cls.parser_old(match, buf, offset, length)
> + except Exception as e:
> + exc = e
>
> fields = []
> - while length > 0:
> - n, value, mask, field_len = ofproto.oxm_parse(buf, offset)
> - k, uv = ofproto.oxm_to_user(n, value, mask)
> - fields.append((k, uv))
> - offset += field_len
> - length -= field_len
> + try:
> + while length > 0:
> + n, value, mask, field_len = ofproto.oxm_parse(buf, offset)
> + k, uv = ofproto.oxm_to_user(n, value, mask)
> + fields.append((k, uv))
> + offset += field_len
> + length -= field_len
> + except Exception as e:
>
Exception looks too broad to me.
most of exceptions came from unpack_from, don't they?
> + exc = e
> + residue = buf[offset:]
> match._fields2 = fields
> + if exc is not None:
> + raise exception.OFPTruncatedMessage(match, residue, exc)
> return match
>
> @staticmethod
> @@ -2696,14 +2708,31 @@ class OFPFlowMod(MsgBase):
> ofproto.OFP_HEADER_SIZE)
> offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE
>
> - msg.match = OFPMatch.parser(buf, offset)
> + try:
> + msg.match = OFPMatch.parser(buf, offset)
> + except exception.OFPTruncatedMessage as e:
> + msg.match = e.ofpmsg
> + e.ofpmsg = msg
> + raise e
> +
> offset += utils.round_up(msg.match.length, 8)
>
> instructions = []
> - while offset < msg_len:
> - i = OFPInstruction.parser(buf, offset)
> - instructions.append(i)
> - offset += i.len
> + try:
> + while offset < msg_len:
> + i = OFPInstruction.parser(buf, offset)
> + instructions.append(i)
> + offset += i.len
> + except exception.OFPTruncatedMessage as e:
> + instructions.append(e.ofpmsg)
> + msg.instructions = instructions
> + e.ofpmsg = msg
> + raise e
> + except Exception as e:
> + msg.instructions = instructions
> + raise exception.OFPTruncatedMessage(ofpmsg=msg,
> + residue=buf[offset:],
> + original_exception=e)
> msg.instructions = instructions
>
> return msg
> @@ -2830,14 +2859,22 @@ class OFPInstructionActions(OFPInstruction):
> offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE
> actions = []
> actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE
> - while actions_len > 0:
> - a = OFPAction.parser(buf, offset)
> - actions.append(a)
> - actions_len -= a.len
> - offset += a.len
> + exc = None
> + try:
> + while actions_len > 0:
> + a = OFPAction.parser(buf, offset)
> + actions.append(a)
> + actions_len -= a.len
> + offset += a.len
> + except Exception as e:
> + exc = e
>
> inst = cls(type_, actions)
> inst.len = len_
> + if exc is not None:
> + raise exception.OFPTruncatedMessage(ofpmsg=inst,
> + residue=buf[offset:],
> + original_exception=exc)
> return inst
>
> def serialize(self, buf, offset):
> --
> 2.1.4
>
>
> ------------------------------------------------------------
> ------------------
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
>
------------------------------------------------------------------------------
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