diff options
author | Yusuke Iwase <iwase.yusuke0@gmail.com> | 2015-08-03 16:06:06 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-03 21:32:50 +0900 |
commit | 317d3c4634da9b92663625286d767494394ea2d2 (patch) | |
tree | 7b5476cb9555b1893e15016f4f4ef67518311fb1 | |
parent | c7df2ef4fbb08d7bd6e7d2c65b6aeb976c13435f (diff) |
ofproto_v1_5_parser: Add OFPFlowDesc support
OpenFlow Spec 1.5 introduce lightweight flow statistics multipart,
rename existing flow statistics as flow description.
This patch add flow description multipart support.
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.py | 2 | ||||
-rw-r--r-- | ryu/ofproto/ofproto_v1_5_parser.py | 137 |
2 files changed, 138 insertions, 1 deletions
diff --git a/ryu/ofproto/ofproto_v1_5.py b/ryu/ofproto/ofproto_v1_5.py index 2cc4ebf3..e55eea33 100644 --- a/ryu/ofproto/ofproto_v1_5.py +++ b/ryu/ofproto/ofproto_v1_5.py @@ -1197,7 +1197,7 @@ assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) == OFP_FLOW_STATS_REQUEST_SIZE) # struct ofp_flow_desc -_OFP_FLOW_DESC_0_PACK_STR = 'H2xBBHHHHHQ' +_OFP_FLOW_DESC_0_PACK_STR = 'H2xBxHHHHHQ' OFP_FLOW_DESC_0_PACK_STR = '!' + _OFP_FLOW_DESC_0_PACK_STR OFP_FLOW_DESC_0_SIZE = 24 assert calcsize(OFP_FLOW_DESC_0_PACK_STR) == OFP_FLOW_DESC_0_SIZE diff --git a/ryu/ofproto/ofproto_v1_5_parser.py b/ryu/ofproto/ofproto_v1_5_parser.py index ca0a7bf5..066ace2b 100644 --- a/ryu/ofproto/ofproto_v1_5_parser.py +++ b/ryu/ofproto/ofproto_v1_5_parser.py @@ -4070,6 +4070,57 @@ class OFPExperimenterStatsReply(OFPMultipartReply): super(OFPExperimenterStatsReply, self).__init__(datapath, **kwargs) +class OFPFlowDesc(StringifyMixin): + def __init__(self, table_id=None, priority=None, + idle_timeout=None, hard_timeout=None, flags=None, + importance=None, cookie=None, match=None, stats=None, + instructions=None, length=None): + super(OFPFlowDesc, self).__init__() + self.length = length + self.table_id = table_id + self.priority = priority + self.idle_timeout = idle_timeout + self.hard_timeout = hard_timeout + self.flags = flags + self.importance = importance + self.cookie = cookie + self.match = match + self.stats = stats + self.instructions = instructions + + @classmethod + def parser(cls, buf, offset): + flow_desc = cls() + + (flow_desc.length, flow_desc.table_id, + flow_desc.priority, flow_desc.idle_timeout, + flow_desc.hard_timeout, flow_desc.flags, + flow_desc.importance, + flow_desc.cookie) = struct.unpack_from( + ofproto.OFP_FLOW_DESC_0_PACK_STR, buf, offset) + offset += ofproto.OFP_FLOW_DESC_0_SIZE + + flow_desc.match = OFPMatch.parser(buf, offset) + match_length = utils.round_up(flow_desc.match.length, 8) + offset += match_length + + flow_desc.stats = OFPStats.parser(buf, offset) + stats_length = utils.round_up(flow_desc.stats.length, 8) + offset += stats_length + + instructions = [] + inst_length = (flow_desc.length - (ofproto.OFP_FLOW_DESC_0_SIZE + + match_length + stats_length)) + while inst_length > 0: + inst = OFPInstruction.parser(buf, offset) + instructions.append(inst) + offset += inst.len + inst_length -= inst.len + + flow_desc.instructions = instructions + return flow_desc + + class OFPFlowStats(StringifyMixin): def __init__(self, table_id=None, reason=None, priority=None, match=None, stats=None, length=0): @@ -4123,6 +4174,92 @@ class OFPFlowStatsRequestBase(OFPMultipartRequest): self.match.serialize(self.buf, offset) +@_set_stats_type(ofproto.OFPMP_FLOW_DESC, OFPFlowDesc) +@_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) +class OFPFlowDescStatsRequest(OFPFlowStatsRequestBase): + """ + Individual flow descriptions request message + + The controller uses this message to query individual flow descriptions. + + ================ ====================================================== + Attribute Description + ================ ====================================================== + flags Zero or ``OFPMPF_REQ_MORE`` + table_id ID of table to read + out_port Require matching entries to include this as an output + port + out_group Require matching entries to include this as an output + group + cookie Require matching entries to contain this cookie value + cookie_mask Mask used to restrict the cookie bits that must match + match Instance of ``OFPMatch`` + ================ ====================================================== + + Example:: + + def send_flow_desc_request(self, datapath): + ofp = datapath.ofproto + ofp_parser = datapath.ofproto_parser + + cookie = cookie_mask = 0 + match = ofp_parser.OFPMatch(in_port=1) + req = ofp_parser.OFPFlowDescStatsRequest(datapath, 0, + ofp.OFPTT_ALL, + ofp.OFPP_ANY, + ofp.OFPG_ANY, + cookie, cookie_mask, + match) + datapath.send_msg(req) + """ + def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL, + out_port=ofproto.OFPP_ANY, + out_group=ofproto.OFPG_ANY, + cookie=0, cookie_mask=0, match=None, type_=None): + if match is None: + match = OFPMatch() + super(OFPFlowDescStatsRequest, self).__init__( + datapath, flags, table_id, out_port, out_group, cookie, + cookie_mask, match) + + +@OFPMultipartReply.register_stats_type() +@_set_stats_type(ofproto.OFPMP_FLOW_DESC, OFPFlowDesc) +@_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) +class OFPFlowDescStatsReply(OFPMultipartReply): + """ + Individual flow descriptions reply message + + The switch responds with this message to an individual flow descriptions + request. + + ================ ====================================================== + Attribute Description + ================ ====================================================== + body List of ``OFPFlowDesc`` instance + ================ ====================================================== + + Example:: + + @set_ev_cls(ofp_event.EventOFPFlowDescStatsReply, MAIN_DISPATCHER) + def flow_desc_reply_handler(self, ev): + flows = [] + for stat in ev.msg.body: + flows.append('table_id=%s priority=%d ' + 'idle_timeout=%d hard_timeout=%d flags=0x%04x ' + 'importance=%d cookie=%d match=%s ' + 'stats=%s instructions=%s' % + (stat.table_id, stat.priority, + stat.idle_timeout, stat.hard_timeout, + stat.flags, stat.importance, + stat.cookie, stat.match, + stat.stats, stat.instructions)) + self.logger.debug('FlowDesc: %s', flows) + """ + def __init__(self, datapath, type_=None, **kwargs): + super(OFPFlowDescStatsReply, self).__init__(datapath, **kwargs) + + @_set_stats_type(ofproto.OFPMP_FLOW_STATS, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowStatsRequest(OFPFlowStatsRequestBase): |