diff options
author | Simon Horman <horms@verge.net.au> | 2014-03-11 10:41:58 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-03-16 21:42:04 +0900 |
commit | fbd51b60f7310426619f5cf78cd92d5812778917 (patch) | |
tree | 03b0e3fa84c165d1d0dacc357194637ed69e7a0f | |
parent | 08f7517234a181d133e9397866e383322761d5be (diff) |
of14: Add OFPFlowUpdate
This will be used by flow monitor reply messages
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/ofproto/ofproto_v1_4.py | 6 | ||||
-rw-r--r-- | ryu/ofproto/ofproto_v1_4_parser.py | 116 |
2 files changed, 121 insertions, 1 deletions
diff --git a/ryu/ofproto/ofproto_v1_4.py b/ryu/ofproto/ofproto_v1_4.py index f566c73f..0d8efb63 100644 --- a/ryu/ofproto/ofproto_v1_4.py +++ b/ryu/ofproto/ofproto_v1_4.py @@ -1299,7 +1299,11 @@ OFPFME_PAUSED = 5 # Monitoring paused (out of buffer space). OFPFME_RESUMED = 6 # Monitoring resumed. # struct ofp_flow_update_full -OFP_FLOW_UPDATE_FULL_PACK_STR = '!HHBBHHH4xQ' + _OFP_MATCH_PACK_STR +_OFP_FLOW_UPDATE_FULL_0_PACK_STR = 'HHBBHHH4xQ' +OFP_FLOW_UPDATE_FULL_0_PACK_STR = '!' + _OFP_FLOW_UPDATE_FULL_0_PACK_STR +OFP_FLOW_UPDATE_FULL_0_SIZE = 24 +OFP_FLOW_UPDATE_FULL_PACK_STR = (OFP_FLOW_UPDATE_FULL_0_PACK_STR + + _OFP_MATCH_PACK_STR) OFP_FLOW_UPDATE_FULL_SIZE = 32 assert (calcsize(OFP_FLOW_UPDATE_FULL_PACK_STR) == OFP_FLOW_UPDATE_FULL_SIZE) diff --git a/ryu/ofproto/ofproto_v1_4_parser.py b/ryu/ofproto/ofproto_v1_4_parser.py index 40910723..21f5fe60 100644 --- a/ryu/ofproto/ofproto_v1_4_parser.py +++ b/ryu/ofproto/ofproto_v1_4_parser.py @@ -3400,6 +3400,122 @@ class OFPMeterFeaturesStatsReply(OFPMultipartReply): super(OFPMeterFeaturesStatsReply, self).__init__(datapath, **kwargs) +class OFPFlowUpdate(StringifyMixin): + def __init__(self, length, event): + super(OFPFlowUpdate, self).__init__() + self.length = length + self.event = event + + +class OFPFlowUpdateHeader(OFPFlowUpdate): + _EVENT = {} + + @staticmethod + def register_flow_update_event(event, length): + def _register_flow_update_event(cls): + OFPFlowUpdateHeader._EVENT[event] = cls + cls.cls_flow_update_event = event + cls.cls_flow_update_length = length + return cls + return _register_flow_update_event + + def __init__(self, length=None, event=None): + cls = self.__class__ + super(OFPFlowUpdateHeader, self).__init__(length, + cls.cls_flow_update_event) + self.length = length + + @classmethod + def parser(cls, buf, offset): + length, event = struct.unpack_from( + ofproto.OFP_FLOW_UPDATE_HEADER_PACK_STR, buf, offset) + cls_ = cls._EVENT[event] + return cls_.parser(buf, offset) + + +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_INITIAL, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_ADDED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_REMOVED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_MODIFIED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) +class OFPFlowUpdateFull(OFPFlowUpdateHeader): + def __init__(self, length=None, event=None, table_id=None, reason=None, + idle_timeout=None, hard_timeout=None, priority=None, + cookie=None, match=None, instructions=[]): + super(OFPFlowUpdateFull, self).__init__(length, event) + self.table_id = table_id + self.reason = reason + self.idle_timeout = idle_timeout + self.hard_timeout = hard_timeout + self.priority = priority + self.cookie = cookie + self.match = match + assert (event != ofproto.OFPFME_REMOVED or len(instructions) == 0) + for i in instructions: + assert isinstance(i, OFPInstruction) + self.instructions = instructions + + @classmethod + def parser(cls, buf, offset): + (length, event, table_id, reason, idle_timeout, hard_timeout, priority, + cookie) = struct.unpack_from(ofproto.OFP_FLOW_UPDATE_FULL_0_PACK_STR, + buf, offset) + offset += ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE + assert cls.cls_flow_update_length <= length + assert cls.cls_flow_update_event == event + + match = OFPMatch.parser(buf, offset) + match_length = utils.round_up(match.length, 8) + offset += match_length + + inst_length = (length - ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE - + match_length) + instructions = [] + while inst_length > 0: + inst = OFPInstruction.parser(buf, offset) + instructions.append(inst) + offset += inst.len + inst_length -= inst.len + + return cls(length, event, table_id, reason, idle_timeout, + hard_timeout, priority, cookie, match, instructions) + + +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_ABBREV, ofproto.OFP_FLOW_UPDATE_ABBREV_SIZE) +class OFPFlowUpdateAbbrev(OFPFlowUpdateHeader): + def __init__(self, length=None, event=None, xid=None): + super(OFPFlowUpdateAbbrev, self).__init__(length, event) + self.xid = xid + + @classmethod + def parser(cls, buf, offset): + length, event, xid = struct.unpack_from( + ofproto.OFP_FLOW_UPDATE_ABBREV_PACK_STR, buf, offset) + assert cls.cls_flow_update_length == length + assert cls.cls_flow_update_event == event + + return cls(length, event, xid) + + +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_PAUSED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) +@OFPFlowUpdateHeader.register_flow_update_event( + ofproto.OFPFME_RESUMED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) +class OFPFlowUpdatePaused(OFPFlowUpdateHeader): + @classmethod + def parser(cls, buf, offset): + length, event = struct.unpack_from( + ofproto.OFP_FLOW_UPDATE_PAUSED_PACK_STR, buf, offset) + assert cls.cls_flow_update_length == length + assert cls.cls_flow_update_event == event + + return cls(length, event) + + class OFPExperimenterMultipart(ofproto_parser.namedtuple( 'OFPExperimenterMultipart', ('experimenter', 'exp_type', 'data'))): |