summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYusuke Iwase <iwase.yusuke0@gmail.com>2014-08-20 14:27:19 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-08-20 05:25:10 -0700
commit04766aaa93c211d6245e2740046ee8e2e013fad5 (patch)
treef3570f06ef9dd1d4696ead68a6f037d7f3ad0d16
parent7cc538a01afc696b19bcbf4cf6bc059a72c068bd (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.py20
-rw-r--r--ryu/lib/ofctl_v1_0.py11
-rw-r--r--ryu/lib/ofctl_v1_2.py14
-rw-r--r--ryu/lib/ofctl_v1_3.py16
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,