summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSimon Horman <horms@verge.net.au>2014-03-11 10:41:58 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-03-16 21:42:04 +0900
commitfbd51b60f7310426619f5cf78cd92d5812778917 (patch)
tree03b0e3fa84c165d1d0dacc357194637ed69e7a0f
parent08f7517234a181d133e9397866e383322761d5be (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.py6
-rw-r--r--ryu/ofproto/ofproto_v1_4_parser.py116
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'))):