Hi Douglas,

Excuse me for cutting in.

Just for getting flow statistics, how about running your app and ofctl_rest
together as Fujimoto said.
e.g.)
 $ ryu-manager your_app.py ryu.app.ofctl_rest


If you want to implement your own REST APIs on your app, Ryu-Book is the
most helpful as far as I know.
(You might already be aware of this though...)
  http://osrg.github.io/ryu-book/en/html/rest_api.html


FYI, here is an sample implementation on simple_switch_13.py for getting
flow statistics.
The usage of "WSGI" framework is described on Ryu-Book.


$ git diff
diff --git a/ryu/app/simple_switch_13.py b/ryu/app/simple_switch_13.py
index 3e7c598..f33e474 100644
--- a/ryu/app/simple_switch_13.py
+++ b/ryu/app/simple_switch_13.py
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
+
 from ryu.base import app_manager
 from ryu.controller import ofp_event
 from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
@@ -21,14 +23,26 @@ from ryu.ofproto import ofproto_v1_3
 from ryu.lib.packet import packet
 from ryu.lib.packet import ethernet
 from ryu.lib.packet import ether_types
+from ryu.app.ofctl import api as ofctl_api
+from ryu.app.wsgi import ControllerBase
+from ryu.app.wsgi import Response
+from ryu.app.wsgi import route
+from ryu.app.wsgi import WSGIApplication
+
+
+_URI_PREFIX = '/simpleswitch/stats/{dpid}'
 
 
 class SimpleSwitch13(app_manager.RyuApp):
     OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
+    _CONTEXTS = {'wsgi': WSGIApplication}
 
     def __init__(self, *args, **kwargs):
         super(SimpleSwitch13, self).__init__(*args, **kwargs)
         self.mac_to_port = {}
+        wsgi = kwargs['wsgi']
+        wsgi.register(SimpleSwitchController,
+                      {SimpleSwitch13.__name__: self})
 
     @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
     def switch_features_handler(self, ev):
@@ -117,3 +131,32 @@ class SimpleSwitch13(app_manager.RyuApp):
         out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                   in_port=in_port, actions=actions, data=data)
         datapath.send_msg(out)
+
+    def get_flow_stats(self, dpid):
+        datapath = ofctl_api.get_datapath(self, dpid)
+        if datapath is None:
+            return None
+
+        parser = datapath.ofproto_parser
+        req = parser.OFPFlowStatsRequest(datapath)
+
+        rep = ofctl_api.send_msg(
+            app=self, msg=req,
+            reply_cls=parser.OFPFlowStatsReply, reply_multi=True)
+        return [r.to_jsondict() for r in rep]
+
+
+class SimpleSwitchController(ControllerBase):
+
+    def __init__(self, req, link, data, **config):
+        super(SimpleSwitchController, self).__init__(req, link, data, **config)
+        self.simple_switch_app = data[SimpleSwitch13.__name__]
+
+    @route('simpleswitch', _URI_PREFIX, methods=['GET'])
+    def list_mac_table(self, req, **kwargs):
+        dpid = int(str(kwargs['dpid']))
+        ret = self.simple_switch_app.get_flow_stats(dpid)
+        if ret is None:
+            return Response(status=404)
+
+        return Response(content_type='application/json', body=json.dumps(ret))


$ ryu-manager ryu/app/simple_switch_13.py 
Registered VCS backend: git
Registered VCS backend: hg
Registered VCS backend: svn
Registered VCS backend: bzr
loading app ryu/app/simple_switch_13.py
loading app ryu.controller.ofp_handler
loading app ryu.app.ofctl.service
loading app ryu.controller.ofp_handler
creating context wsgi
instantiating app ryu.app.ofctl.service of OfctlService
instantiating app ryu/app/simple_switch_13.py of SimpleSwitch13
instantiating app ryu.controller.ofp_handler of OFPHandler
(10332) wsgi starting up on http://0.0.0.0:8080
...


$ curl -X GET http://localhost:8080/simpleswitch/stats/1 | python -m json.tool
[
    {
        "OFPFlowStatsReply": {
            "body": [
                {
                    "OFPFlowStats": {
                        "byte_count": 140,
                        "cookie": 0,
                        "duration_nsec": 771000000,
                        "duration_sec": 1,
                        "flags": 0,
                        "hard_timeout": 0,
                        "idle_timeout": 0,
                        "instructions": [
                            {
                                "OFPInstructionActions": {
                                    "actions": [
                                        {
                                            "OFPActionOutput": {
                                                "len": 16,
                                                "max_len": 65535,
                                                "port": 4294967293,
                                                "type": 0
                                            }
                                        }
                                    ],
                                    "len": 24,
                                    "type": 4
                                }
                            }
                        ],
                        "length": 80,
                        "match": {
                            "OFPMatch": {
                                "length": 4,
                                "oxm_fields": [],
                                "type": 1
                            }
                        },
                        "packet_count": 2,
                        "priority": 0,
                        "table_id": 0
                    }
                }
            ],
            "flags": 0,
            "type": 1
        }
    }
]


Thanks,
Iwase


On 2017年06月07日 20:21, Douglas Harewood-Gill wrote:
> Hi there. That is fantastic. Sounds exactly like what I am looking for so 
> thank you.
> 
> One last question for the minute. I know you provided a link but how do you 
> implement this with custom Ryu controller code?
> 
> My apologies if I am asking something really obvious.
> 
> Cheers
> 
> Douglas
> 
> On 7 June 2017 at 01:15, Fujimoto Satoshi <satoshi.fujimo...@gmail.com 
> <mailto:satoshi.fujimo...@gmail.com>> wrote:
> 
>     Hi, Douglas
> 
>     Ryu has ofctl_rest.py, which is a sample application and provides REST 
> API to get flow statistics.
>             http://ryu.readthedocs.io/en/latest/app/ofctl_rest.html 
> <http://ryu.readthedocs.io/en/latest/app/ofctl_rest.html>
> 
>     I think it is better to use ofctl_rest.py than to implement your own REST 
> API in your app.
> 
>     Thanks,
>     Fujimoto
> 
> 
>     On 2017年06月06日 21:18, Douglas Harewood-Gill wrote:
>>
>>     Greetings  I am a PhD student new to both Python and Ryu and I was 
>> wondering if anyone could give me some advice.
>>
>>
>>     I am using the Ryu controller program (L2DestForwardStaticRyu.py) 
>> provided by Dr Grey Bernstein 
>> (https://www.grotto-networking.com/SDNfun.html#programming-switches-with-ryu 
>> <https://www.grotto-networking.com/SDNfun.html#programming-switches-with-ryu>)
>>  for shortest path computation for a full Mesh network in Mininet but the 
>> example provided does not include REST which I require to be able to collect 
>> flow statistics such as the flows in each router, bandwidth, latency, etc. 
>>
>>
>>     Unfortunately I have been looking and with the exception of 
>> (https://osrg.github.io/ryu-book/en/html/rest_api.html 
>> <https://osrg.github.io/ryu-book/en/html/rest_api.html>) which seems overly 
>> specific, I am unable to find a good example that would allow me to work out 
>> how to integrate REST into the above Ryu control program.  
>>
>>     So if anyone can point me in the right direction or can provide some 
>> examples, I would be most grateful.
>>
>>
>>     Thank you for your time.
>>
>>
>>     Best Regards
>>
>>
>>     Douglas
>>
>>
>>
>>     -- 
>>     *Douglas Harewood-Gill MSc MIET*
>>     CDT Student in Communications (PhD), University of Bristol
>>     Post-Graduate Student (Taught and Research)
>>     e-mail: douglas.harewood-g...@bristol.ac.uk 
>> <mailto:douglas.harewood-g...@bristol.ac.uk>
>>
>>     *
>>     CDT Communications*
>>
>>     University of Bristol, Merchant Venturers' Building, Woodland Road, 
>> Clifton, Bristol. BS8 1UB
>>
>>     http://www.bristol.ac.uk/
>>
>>
>>
>>
>>     
>> ------------------------------------------------------------------------------
>>     Check out the vibrant tech community on one of the world's most
>>     engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>>
>>
>>     _______________________________________________
>>     Ryu-devel mailing list
>>     Ryu-devel@lists.sourceforge.net <mailto:Ryu-devel@lists.sourceforge.net>
>>     https://lists.sourceforge.net/lists/listinfo/ryu-devel 
>> <https://lists.sourceforge.net/lists/listinfo/ryu-devel>
> 
> 
> 
> 
> -- 
> *Douglas Harewood-Gill MSc MIET*
> CDT Student in Communications (PhD), University of Bristol
> Post-Graduate Student (Taught and Research)
> e-mail: douglas.harewood-g...@bristol.ac.uk 
> <mailto:douglas.harewood-g...@bristol.ac.uk>
> 
> *
> CDT Communications*
> 
> University of Bristol, Merchant Venturers' Building, Woodland Road, Clifton, 
> Bristol. BS8 1UB
> 
> http://www.bristol.ac.uk/
> 
> 
> 
> 
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> 
> 
> 
> _______________________________________________
> Ryu-devel mailing list
> Ryu-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
> 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to