This patch adds OPFStats class which has simpler API with OFPMatch class.

Signed-off-by: IWASE Yusuke <[email protected]>
---
 ryu/ofproto/ofproto_v1_5_parser.py | 136 +++++++++++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)

diff --git a/ryu/ofproto/ofproto_v1_5_parser.py 
b/ryu/ofproto/ofproto_v1_5_parser.py
index 7d15bc6..8dda2e4 100644
--- a/ryu/ofproto/ofproto_v1_5_parser.py
+++ b/ryu/ofproto/ofproto_v1_5_parser.py
@@ -812,6 +812,142 @@ class OFPMatch(StringifyMixin):
         return OFPMatch(_ordered_fields=fields)
 
 
+class OFPStats(StringifyMixin):
+    """
+    Flow Stats Structure
+
+    This class is implementation of the flow stats structure having
+    compose/query API.
+
+    You can define the flow stats by the keyword arguments.
+    The following arguments are available.
+
+    ============= ================ ============================================
+    Argument      Value            Description
+    ============= ================ ============================================
+    duration      Integer 32bit*2  Time flow entry has been alive. This field
+                                   is a tuple of two Integer 32bit. The first
+                                   value is duration_sec and the second is
+                                   duration_nsec.
+    idle_time     Integer 32bit*2  Time flow entry has been idle.
+    flow_count    Integer 32bit    Number of aggregated flow entries.
+    packet_count  Integer 64bit    Number of packets matched by a flow entry.
+    byte_count    Integer 64bit    Number of bytes matched by a flow entry.
+    ============= ================ ============================================
+
+    Example::
+
+        >>> # compose
+        >>> stats = parser.OFPStats(
+        ...     packet_count=100,
+        ...     duration=(100, 200)
+        >>> # query
+        >>> if 'duration' in stats:
+        ...     print stats['duration']
+        ...
+        (100, 200)
+    """
+
+    def __init__(self, length=None, _ordered_fields=None, **kwargs):
+        super(OFPStats, self).__init__()
+        self.length = length
+
+        if _ordered_fields is not None:
+            assert not kwargs
+            self.fields = _ordered_fields
+        else:
+            fields = [ofproto.oxs_from_user(k, v) for (k, v)
+                      in kwargs.iteritems()]
+            # sort by OXS type values
+            fields.sort()
+            self.fields = [ofproto.oxs_to_user(n, v) for (n, v) in fields]
+
+    @classmethod
+    def parser(cls, buf, offset):
+        """
+        Returns an object which is generated from a buffer including the
+        expression of the wire protocol of the flow stats.
+        """
+        stats = OFPStats()
+        reserved, length = struct.unpack_from('!HH', buf, offset)
+
+        stats.length = length
+
+        # ofp_stats adjustment
+        offset += 4
+        length -= 4
+
+        fields = []
+        while length > 0:
+            n, value, field_len = ofproto.oxs_parse(buf, offset)
+            k, uv = ofproto.oxs_to_user(n, value)
+            fields.append((k, uv))
+            offset += field_len
+            length -= field_len
+        stats.fields = fields
+        return stats
+
+    def serialize(self, buf, offset):
+        """
+        Outputs the expression of the wire protocol of the flow stats into
+        the buf.
+        Returns the output length.
+        """
+        fields = [ofproto.oxs_from_user(k, uv) for (k, uv)
+                  in self.fields]
+
+        hdr_pack_str = '!HH'
+        field_offset = offset + struct.calcsize(hdr_pack_str)
+        for (n, value) in fields:
+            field_offset += ofproto.oxs_serialize(n, value, buf, field_offset)
+
+        reserved = 0
+        length = field_offset - offset
+        msg_pack_into(hdr_pack_str, buf, offset, reserved, length)
+        self.length = length
+
+        pad_len = utils.round_up(length, 8) - length
+        msg_pack_into("%dx" % pad_len, buf, field_offset)
+
+        return length + pad_len
+
+    def __getitem__(self, key):
+        return dict(self.fields)[key]
+
+    def __contains__(self, key):
+        return key in dict(self.fields)
+
+    def iteritems(self):
+        return dict(self.fields).iteritems()
+
+    def get(self, key, default=None):
+        return dict(self.fields).get(key, default)
+
+    def stringify_attrs(self):
+        yield "oxs_fields", dict(self.fields)
+
+    def to_jsondict(self):
+        """
+        Returns a dict expressing the flow stats.
+        """
+        body = {"oxs_fields": [ofproto.oxs_to_jsondict(k, uv) for k, uv
+                               in self.fields],
+                "length": self.length}
+        return {self.__class__.__name__: body}
+
+    @classmethod
+    def from_jsondict(cls, dict_):
+        """
+        Returns an object which is generated from a dict.
+
+        Exception raises:
+        KeyError -- Unknown stats field is defined in dict
+        """
+        fields = [ofproto.oxs_from_jsondict(f) for f
+                  in dict_['oxs_fields']]
+        return OFPStats(_ordered_fields=fields)
+
+
 class OFPPropUnknown(StringifyMixin):
     def __init__(self, type_=None, length=None, buf=None):
         self.buf = buf
-- 
1.9.1



------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to