Signed-off-by: Simon Horman <[email protected]>
---
 ryu/ofproto/ofproto_v1_4_parser.py | 94 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/ryu/ofproto/ofproto_v1_4_parser.py 
b/ryu/ofproto/ofproto_v1_4_parser.py
index b5716c9..0fc4ea7 100644
--- a/ryu/ofproto/ofproto_v1_4_parser.py
+++ b/ryu/ofproto/ofproto_v1_4_parser.py
@@ -1455,6 +1455,100 @@ class OFPPacketIn(MsgBase):
         return msg
 
 
+@_register_parser
+@_set_msg_type(ofproto.OFPT_FLOW_REMOVED)
+class OFPFlowRemoved(MsgBase):
+    """
+    Flow removed message
+
+    When flow entries time out or are deleted, the switch notifies controller
+    with this message.
+
+    ================ ======================================================
+    Attribute        Description
+    ================ ======================================================
+    cookie           Opaque controller-issued identifier
+    priority         Priority level of flow entry
+    reason           One of the following values.
+                     OFPRR_IDLE_TIMEOUT
+                     OFPRR_HARD_TIMEOUT
+                     OFPRR_DELETE
+                     OFPRR_GROUP_DELETE
+    table_id         ID of the table
+    duration_sec     Time flow was alive in seconds
+    duration_nsec    Time flow was alive in nanoseconds beyond duration_sec
+    idle_timeout     Idle timeout from original flow mod
+    hard_timeout     Hard timeout from original flow mod
+    packet_count     Number of packets that was associated with the flow
+    byte_count       Number of bytes that was associated with the flow
+    match            Instance of ``OFPMatch``
+    ================ ======================================================
+
+    Example::
+
+        @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER)
+        def flow_removed_handler(self, ev):
+            msg = ev.msg
+            dp = msg.datapath
+            ofp = dp.ofproto
+
+            if msg.reason == ofp.OFPRR_IDLE_TIMEOUT:
+                reason = 'IDLE TIMEOUT'
+            elif msg.reason == ofp.OFPRR_HARD_TIMEOUT:
+                reason = 'HARD TIMEOUT'
+            elif msg.reason == ofp.OFPRR_DELETE:
+                reason = 'DELETE'
+            elif msg.reason == ofp.OFPRR_GROUP_DELETE:
+                reason = 'GROUP DELETE'
+            else:
+                reason = 'unknown'
+
+            self.logger.debug('OFPFlowRemoved received: '
+                              'cookie=%d priority=%d reason=%s table_id=%d '
+                              'duration_sec=%d duration_nsec=%d '
+                              'idle_timeout=%d hard_timeout=%d '
+                              'packet_count=%d byte_count=%d match.fields=%s',
+                              msg.cookie, msg.priority, reason, msg.table_id,
+                              msg.duration_sec, msg.duration_nsec,
+                              msg.idle_timeout, msg.hard_timeout,
+                              msg.packet_count, msg.byte_count, msg.match)
+    """
+    def __init__(self, datapath, cookie=None, priority=None, reason=None,
+                 table_id=None, duration_sec=None, duration_nsec=None,
+                 idle_timeout=None, hard_timeout=None, packet_count=None,
+                 byte_count=None, match=None):
+        super(OFPFlowRemoved, self).__init__(datapath)
+        self.cookie = cookie
+        self.priority = priority
+        self.reason = reason
+        self.table_id = table_id
+        self.duration_sec = duration_sec
+        self.duration_nsec = duration_nsec
+        self.idle_timeout = idle_timeout
+        self.hard_timeout = hard_timeout
+        self.packet_count = packet_count
+        self.byte_count = byte_count
+        self.match = match
+
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type,
+                                                msg_len, xid, buf)
+
+        (msg.cookie, msg.priority, msg.reason,
+         msg.table_id, msg.duration_sec, msg.duration_nsec,
+         msg.idle_timeout, msg.hard_timeout, msg.packet_count,
+         msg.byte_count) = struct.unpack_from(
+            ofproto.OFP_FLOW_REMOVED_PACK_STR0,
+            msg.buf, ofproto.OFP_HEADER_SIZE)
+
+        offset = (ofproto.OFP_FLOW_REMOVED_SIZE - ofproto.OFP_MATCH_SIZE)
+
+        msg.match = OFPMatch.parser(msg.buf, offset)
+
+        return msg
+
+
 class OFPPort(StringifyMixin):
     _TYPE = {
         'ascii': [
-- 
1.8.5.2


------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to