diff options
-rw-r--r-- | ryu/ofproto/ofproto_v1_5_parser.py | 140 |
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 |