diff options
author | Yusuke Iwase <iwase.yusuke0@gmail.com> | 2014-08-20 14:27:19 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-08-20 05:25:10 -0700 |
commit | 04766aaa93c211d6245e2740046ee8e2e013fad5 (patch) | |
tree | f3570f06ef9dd1d4696ead68a6f037d7f3ad0d16 | |
parent | 7cc538a01afc696b19bcbf4cf6bc059a72c068bd (diff) |
ofctl_rest: support OFPFlowStats filtered by fields
this patch enables ofctl_rest to get OFPFlowStats messages
filtered by the OFPFlowStatsRequest fields in OpenFlow specification.
usage)
URI: /stats/flow/<dpid>
method: POST
the message body is as follows:
table_id ID of table.
out_port Require matching entries to include this as an output port.
out_group Require matching entries to include this as an output group.
(Not supported in of1.0)
cookie Require matching entries to contain this cookie value.
(Not supported in of1.0)
cookie_mask Mask used to restrict the cookie bits that must match.
(Not supported in of1.0)
match Fields to match.
e.g.)
curl -X POST -d '{"table_id": 0,
"out_port": 2,
"cookie": 1,
"cookie_mask": 1,
"match":{"in_port":1}}'
http://localhost:8080/stats/flow/1
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/app/ofctl_rest.py | 20 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_0.py | 11 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_2.py | 14 | ||||
-rw-r--r-- | ryu/lib/ofctl_v1_3.py | 16 |
4 files changed, 38 insertions, 23 deletions
diff --git a/ryu/app/ofctl_rest.py b/ryu/app/ofctl_rest.py index 89e8fbc3..0dcdbaa3 100644 --- a/ryu/app/ofctl_rest.py +++ b/ryu/app/ofctl_rest.py @@ -48,6 +48,9 @@ LOG = logging.getLogger('ryu.app.ofctl_rest') # get flows stats of the switch # GET /stats/flow/<dpid> # +# get flows stats of the switch filtered by the fields +# POST /stats/flow/<dpid> +# # get ports stats of the switch # GET /stats/port/<dpid> # @@ -148,16 +151,25 @@ class StatsController(ControllerBase): return (Response(content_type='application/json', body=body)) def get_flow_stats(self, req, dpid, **_kwargs): + if req.body == '': + flow = {} + else: + try: + flow = eval(req.body) + except SyntaxError: + LOG.debug('invalid syntax %s', req.body) + return Response(status=400) + dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: - flows = ofctl_v1_0.get_flow_stats(dp, self.waiters) + flows = ofctl_v1_0.get_flow_stats(dp, self.waiters, flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: - flows = ofctl_v1_2.get_flow_stats(dp, self.waiters) + flows = ofctl_v1_2.get_flow_stats(dp, self.waiters, flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: - flows = ofctl_v1_3.get_flow_stats(dp, self.waiters) + flows = ofctl_v1_3.get_flow_stats(dp, self.waiters, flow) else: LOG.debug('Unsupported OF protocol') return Response(status=501) @@ -511,7 +523,7 @@ class RestStatsApi(app_manager.RyuApp): uri = path + '/flow/{dpid}' mapper.connect('stats', uri, controller=StatsController, action='get_flow_stats', - conditions=dict(method=['GET'])) + conditions=dict(method=['GET', 'POST'])) uri = path + '/port/{dpid}' mapper.connect('stats', uri, diff --git a/ryu/lib/ofctl_v1_0.py b/ryu/lib/ofctl_v1_0.py index 06e9b04d..f9b563df 100644 --- a/ryu/lib/ofctl_v1_0.py +++ b/ryu/lib/ofctl_v1_0.py @@ -223,11 +223,14 @@ def get_desc_stats(dp, waiters): return desc -def get_flow_stats(dp, waiters): - match = dp.ofproto_parser.OFPMatch( - dp.ofproto.OFPFW_ALL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +def get_flow_stats(dp, waiters, flow={}): + match = to_match(dp, flow.get('match', {})) + table_id = int(flow.get('table_id', 0xff)) + out_port = int(flow.get('out_port', dp.ofproto.OFPP_NONE)) + stats = dp.ofproto_parser.OFPFlowStatsRequest( - dp, 0, match, 0xff, dp.ofproto.OFPP_NONE) + dp, 0, match, table_id, out_port) + msgs = [] send_stats_request(dp, stats, waiters, msgs) diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py index 0f767cda..dec8c7e2 100644 --- a/ryu/lib/ofctl_v1_2.py +++ b/ryu/lib/ofctl_v1_2.py @@ -588,13 +588,13 @@ def get_queue_stats(dp, waiters): return desc -def get_flow_stats(dp, waiters): - table_id = dp.ofproto.OFPTT_ALL - out_port = dp.ofproto.OFPP_ANY - out_group = dp.ofproto.OFPG_ANY - cookie = 0 - cookie_mask = 0 - match = dp.ofproto_parser.OFPMatch() +def get_flow_stats(dp, waiters, flow={}): + table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) + out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + cookie = int(flow.get('cookie', 0)) + cookie_mask = int(flow.get('cookie_mask', 0)) + match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, table_id, out_port, out_group, cookie, cookie_mask, match) diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py index b81a8ee3..23692162 100644 --- a/ryu/lib/ofctl_v1_3.py +++ b/ryu/lib/ofctl_v1_3.py @@ -616,14 +616,14 @@ def get_queue_stats(dp, waiters): return desc -def get_flow_stats(dp, waiters): - table_id = dp.ofproto.OFPTT_ALL - flags = 0 - out_port = dp.ofproto.OFPP_ANY - out_group = dp.ofproto.OFPG_ANY - cookie = 0 - cookie_mask = 0 - match = dp.ofproto_parser.OFPMatch() +def get_flow_stats(dp, waiters, flow={}): + table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL)) + flags = int(flow.get('flags', 0)) + out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY)) + out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY)) + cookie = int(flow.get('cookie', 0)) + cookie_mask = int(flow.get('cookie_mask', 0)) + match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, |