summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYusuke Iwase <iwase.yusuke0@gmail.com>2015-05-28 11:52:48 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-06-18 18:24:07 +0900
commit05984d0c04e5d0ad871563b14df0dd3dc6f046f6 (patch)
tree227bfc768866a1b322084b448326a007c0e50a98
parent7510d10a3ee6bebfe7152d50d8e65bdeb2160770 (diff)
ofproto_v1_5_parser: Add OPFStats parser for Flow Stats Structures
This patch adds OPFStats class which has simpler API with OFPMatch class. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/ofproto/ofproto_v1_5_parser.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/ryu/ofproto/ofproto_v1_5_parser.py b/ryu/ofproto/ofproto_v1_5_parser.py
index 7d15bc62..d9ea7190 100644
--- a/ryu/ofproto/ofproto_v1_5_parser.py
+++ b/ryu/ofproto/ofproto_v1_5_parser.py
@@ -812,6 +812,146 @@ 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()
+ # No mask
+ self.fields = [ofproto.oxs_to_user(n, v, None) 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, None) # No mask
+ 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:
+ # No mask
+ field_offset += ofproto.oxs_serialize(n, value, None, 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