Changes v2 -> v3:

- correct the following description


this patch implements a REST API for OFPMeterConfigStats.

e.g., when you send a MeterMod message as:

    curl -X POST -d '{"dpid": 1,
                      "meter_id": 1,
                      "flags": "KBPS",
                      "bands": [{"type": "DROP", "rate": 1000},
                                {"type": "REMARK", "rate": 2000},
                                {"type": "EXPERIMENTER", "rate": 3000}
                      ]}' http://localhost:8080/stats/meterentry/add

and you do the following command:

    curl http://localhost:8080/stats/meterconfig/1

then you will get the configuration as:

    {"1": [{"bands": [{"burst_size": 0, "rate": 1000, "type": "DROP"},
                      {"prec_level": 0, "burst_size": 0, "rate": 2000, "type": 
"REMARK"},
                      {"burst_size": 0, "rate": 3000, "experimenter": 0, 
"type": "EXPERIMENTER"}],
            "flags": "KBPS",
            "meter_id": 1}]}

Signed-off-by: Yuichi Ito <[email protected]>
---
 ryu/app/ofctl_rest.py |   28 ++++++++++++++++++++++++++--
 ryu/lib/ofctl_v1_3.py |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/ryu/app/ofctl_rest.py b/ryu/app/ofctl_rest.py
index 788714d..61e99ed 100644
--- a/ryu/app/ofctl_rest.py
+++ b/ryu/app/ofctl_rest.py
@@ -51,6 +51,9 @@ LOG = logging.getLogger('ryu.app.ofctl_rest')
 # get meter features stats of the switch
 # GET /stats/meterfeatures/<dpid>
 #
+# get meter config stats of the switch
+# GET /stats/meterconfig/<dpid>
+#
 # get meters stats of the switch
 # GET /stats/meter/<dpid>
 #
@@ -77,8 +80,6 @@ LOG = logging.getLogger('ryu.app.ofctl_rest')
 # delete a meter entry
 # POST /stats/meterentry/delete

-# TODO: support OFPMeterConfigStats
-

 class StatsController(ControllerBase):
     def __init__(self, req, link, data, **config):
@@ -153,6 +154,20 @@ class StatsController(ControllerBase):
         body = json.dumps(meters)
         return (Response(content_type='application/json', body=body))

+    def get_meter_config(self, req, dpid, **_kwargs):
+        dp = self.dpset.get(int(dpid))
+        if dp is None:
+            return Response(status=404)
+
+        if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION:
+            meters = ofctl_v1_3.get_meter_config(dp, self.waiters)
+        else:
+            LOG.debug('Unsupported OF protocol')
+            return Response(status=501)
+
+        body = json.dumps(meters)
+        return (Response(content_type='application/json', body=body))
+
     def get_meter_stats(self, req, dpid, **_kwargs):
         dp = self.dpset.get(int(dpid))
         if dp is None:
@@ -288,6 +303,11 @@ class RestStatsApi(app_manager.RyuApp):
                        controller=StatsController, action='get_meter_features',
                        conditions=dict(method=['GET']))

+        uri = path + '/meterconfig/{dpid}'
+        mapper.connect('stats', uri,
+                       controller=StatsController, action='get_meter_config',
+                       conditions=dict(method=['GET']))
+
         uri = path + '/meter/{dpid}'
         mapper.connect('stats', uri,
                        controller=StatsController, action='get_meter_stats',
@@ -349,3 +369,7 @@ class RestStatsApi(app_manager.RyuApp):
     @set_ev_cls(ofp_event.EventOFPMeterFeaturesStatsReply, MAIN_DISPATCHER)
     def meter_features_stats_reply_handler(self, ev):
         self.stats_reply_handler(ev)
+
+    @set_ev_cls(ofp_event.EventOFPMeterConfigStatsReply, MAIN_DISPATCHER)
+    def meter_config_stats_reply_handler(self, ev):
+        self.stats_reply_handler(ev)
diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
index 37f67d0..7e538b6 100644
--- a/ryu/lib/ofctl_v1_3.py
+++ b/ryu/lib/ofctl_v1_3.py
@@ -479,6 +479,42 @@ def get_meter_features(dp, waiters):
     return features


+def get_meter_config(dp, waiters):
+    flags = {dp.ofproto.OFPMF_KBPS: 'KBPS',
+             dp.ofproto.OFPMF_PKTPS: 'PKTPS',
+             dp.ofproto.OFPMF_BURST: 'BURST',
+             dp.ofproto.OFPMF_STATS: 'STATS'}
+
+    band_type = {dp.ofproto.OFPMBT_DROP: 'DROP',
+                 dp.ofproto.OFPMBT_DSCP_REMARK: 'REMARK',
+                 dp.ofproto.OFPMBT_EXPERIMENTER: 'EXPERIMENTER'}
+
+    stats = dp.ofproto_parser.OFPMeterConfigStatsRequest(
+        dp, 0, dp.ofproto.OFPM_ALL)
+    msgs = []
+    send_stats_request(dp, stats, waiters, msgs)
+
+    configs = []
+    for msg in msgs:
+        for config in msg.body:
+            bands = []
+            for band in config.bands:
+                b = {'type': band_type.get(band.type, ''),
+                     'rate': band.rate,
+                     'burst_size': band.burst_size}
+                if band.type == dp.ofproto.OFPMBT_DSCP_REMARK:
+                    b['prec_level'] = band.prec_level
+                elif band.type == dp.ofproto.OFPMBT_EXPERIMENTER:
+                    b['experimenter'] = band.experimenter
+                bands.append(b)
+            c = {'flags': flags.get(config.flags, 0),
+                 'meter_id': config.meter_id,
+                 'bands': bands}
+            configs.append(c)
+    configs = {str(dp.id): configs}
+    return configs
+
+
 def mod_flow_entry(dp, flow, cmd):
     cookie = int(flow.get('cookie', 0))
     cookie_mask = int(flow.get('cookie_mask', 0))
--
1.7.10.4


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to