this patch makes ofctl_rest enable use of OFPQueueGetConfig message.

Get queues config:

  usage)

    URI:    /stats/queueconfig/<dpid>/<port>
    method: GET

  e.g.)

    $ curl -X GET http://localhost:8080/stats/queueconfig/1/1
    {
      "1": [
        {
          "port": 1,
          "queues": [
            {
              "properties": [
                {
                  "property": "MIN_RATE",
                  "rate": 80
                }
              ],
              "port": 0,
              "queue_id": 1
            },
            {
              "properties": [
                {
                  "property": "MAX_RATE",
                  "rate": 120
                }
              ],
              "port": 2,
              "queue_id": 2
            },
            {
              "properties": [
                {
                  "property": "EXPERIMENTER",
                  "data": [],
                  "experimenter": 999
                }
              ],
              "port": 3,
              "queue_id": 3
            }
          ]
        }
      ]
    }

Signed-off-by: Minoru TAKAHASHI <[email protected]>
---
 ryu/app/ofctl_rest.py | 40 +++++++++++++++++++++++++++++++++++++++-
 ryu/lib/ofctl_v1_2.py | 37 +++++++++++++++++++++++++++++++++++++
 ryu/lib/ofctl_v1_3.py | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/ryu/app/ofctl_rest.py b/ryu/app/ofctl_rest.py
index e459b79..e41d7d6 100644
--- a/ryu/app/ofctl_rest.py
+++ b/ryu/app/ofctl_rest.py
@@ -77,6 +77,9 @@ supported_ofctl = {
 # get queues stats of the switch
 # GET /stats/queue/<dpid>
 #
+# get queues config stats of the switch
+# GET /stats/queueconfig/<dpid>/<port>
+#
 # get meter features stats of the switch
 # GET /stats/meterfeatures/<dpid>
 #
@@ -345,6 +348,35 @@ class StatsController(ControllerBase):
         body = json.dumps(queues)
         return Response(content_type='application/json', body=body)
 
+    def get_queue_config(self, req, dpid, port, **_kwargs):
+
+        if type(dpid) == str and not dpid.isdigit():
+            LOG.debug('invalid dpid %s', dpid)
+            return Response(status=400)
+
+        if type(port) == str and not port.isdigit():
+            LOG.debug('invalid port %s', port)
+            return Response(status=400)
+
+        dp = self.dpset.get(int(dpid))
+        port = int(port)
+
+        if dp is None:
+            return Response(status=404)
+
+        _ofp_version = dp.ofproto.OFP_VERSION
+
+        _ofctl = supported_ofctl.get(_ofp_version, None)
+        if _ofctl is not None:
+            queues = _ofctl.get_queue_config(dp, port, self.waiters)
+
+        else:
+            LOG.debug('Unsupported OF protocol')
+            return Response(status=501)
+
+        body = json.dumps(queues)
+        return Response(content_type='application/json', body=body)
+
     def get_meter_features(self, req, dpid, **_kwargs):
 
         if type(dpid) == str and not dpid.isdigit():
@@ -815,6 +847,11 @@ class RestStatsApi(app_manager.RyuApp):
                        controller=StatsController, action='get_queue_stats',
                        conditions=dict(method=['GET']))
 
+        uri = path + '/queueconfig/{dpid}/{port}'
+        mapper.connect('stats', uri,
+                       controller=StatsController, action='get_queue_config',
+                       conditions=dict(method=['GET']))
+
         uri = path + '/meterfeatures/{dpid}'
         mapper.connect('stats', uri,
                        controller=StatsController, action='get_meter_features',
@@ -920,7 +957,8 @@ class RestStatsApi(app_manager.RyuApp):
         del self.waiters[dp.id][msg.xid]
         lock.set()
 
-    @set_ev_cls([ofp_event.EventOFPSwitchFeatures], MAIN_DISPATCHER)
+    @set_ev_cls([ofp_event.EventOFPSwitchFeatures,
+                 ofp_event.EventOFPQueueGetConfigReply], MAIN_DISPATCHER)
     def features_reply_handler(self, ev):
         msg = ev.msg
         dp = msg.datapath
diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
index 2f2c91f..dcac557 100644
--- a/ryu/lib/ofctl_v1_2.py
+++ b/ryu/lib/ofctl_v1_2.py
@@ -453,6 +453,43 @@ def get_queue_stats(dp, waiters):
     return desc
 
 
+def get_queue_config(dp, port, waiters):
+    ofp = dp.ofproto
+    stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port)
+    msgs = []
+    send_stats_request(dp, stats, waiters, msgs)
+
+    prop_type = {dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE',
+                 dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE',
+                 dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER',
+                 }
+
+    configs = []
+    for config in msgs:
+        queue_list = []
+        for queue in config.queues:
+            prop_list = []
+            for prop in queue.properties:
+                p = {'property': prop_type.get(prop.property, 'UNKNOWN')}
+                if prop.property == dp.ofproto.OFPQT_MIN_RATE or \
+                   prop.property == dp.ofproto.OFPQT_MAX_RATE:
+                    p['rate'] = prop.rate
+                elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER:
+                    p['experimenter'] = prop.experimenter
+                    p['data'] = prop.data
+                prop_list.append(p)
+            q = {'port': queue.port,
+                 'properties': prop_list,
+                 'queue_id': queue.queue_id}
+            queue_list.append(q)
+        c = {'port': config.port,
+             'queues': queue_list}
+        configs.append(c)
+    configs = {str(dp.id): configs}
+
+    return configs
+
+
 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))
diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index a3eae1f..81f9f70 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
@@ -478,6 +478,43 @@ def get_queue_stats(dp, waiters):
     return desc
 
 
+def get_queue_config(dp, port, waiters):
+    ofp = dp.ofproto
+    stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port)
+    msgs = []
+    send_stats_request(dp, stats, waiters, msgs)
+
+    prop_type = {dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE',
+                 dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE',
+                 dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER',
+                 }
+
+    configs = []
+    for config in msgs:
+        queue_list = []
+        for queue in config.queues:
+            prop_list = []
+            for prop in queue.properties:
+                p = {'property': prop_type.get(prop.property, 'UNKNOWN')}
+                if prop.property == dp.ofproto.OFPQT_MIN_RATE or \
+                   prop.property == dp.ofproto.OFPQT_MAX_RATE:
+                    p['rate'] = prop.rate
+                elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER:
+                    p['experimenter'] = prop.experimenter
+                    p['data'] = prop.data
+                prop_list.append(p)
+            q = {'port': queue.port,
+                 'properties': prop_list,
+                 'queue_id': queue.queue_id}
+            queue_list.append(q)
+        c = {'port': config.port,
+             'queues': queue_list}
+        configs.append(c)
+    configs = {str(dp.id): configs}
+
+    return configs
+
+
 def get_flow_stats(dp, waiters, flow={}):
     table_id = int(flow.get('table_id', dp.ofproto.OFPTT_ALL))
     flags = int(flow.get('flags', 0))
-- 
1.9.1


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to