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
