At Mon, 3 Oct 2016 18:32:34 +0900,
Takashi YAMAMOTO wrote:
> 
> 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?

Done.

> 
> > +            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

Reply via email to