an example:
msg = parser.OFPEchoRequest(datapath=datapath)
result = ofctl.api.send_msg(self, msg, reply_cls=parser.OFPEchoReply)
assert isinstance(result, parser.OFPEchoReply)
Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
ryu/app/ofctl/api.py | 5 +++--
ryu/app/ofctl/event.py | 3 ++-
ryu/app/ofctl/service.py | 36 +++++++++++++++++++++++++++++++++++-
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/ryu/app/ofctl/api.py b/ryu/app/ofctl/api.py
index e49a001..476543e 100644
--- a/ryu/app/ofctl/api.py
+++ b/ryu/app/ofctl/api.py
@@ -29,11 +29,12 @@ def get_datapath(app, dpid):
return app.send_request(event.GetDatapathRequest(dpid=dpid))()
-def send_msg(app, msg):
+def send_msg(app, msg, reply_cls=None):
"""
Send an openflow message.
"""
- return app.send_request(event.SendMsgRequest(msg=msg))()
+ return app.send_request(event.SendMsgRequest(msg=msg,
+ reply_cls=reply_cls))()
app_manager.require_app('ryu.app.ofctl.service')
diff --git a/ryu/app/ofctl/event.py b/ryu/app/ofctl/event.py
index 9920833..9dfefcd 100644
--- a/ryu/app/ofctl/event.py
+++ b/ryu/app/ofctl/event.py
@@ -40,9 +40,10 @@ class GetDatapathRequest(_RequestBase):
# send msg
class SendMsgRequest(_RequestBase):
- def __init__(self, msg):
+ def __init__(self, msg, reply_cls=None):
super(SendMsgRequest, self).__init__()
self.msg = msg
+ self.reply_cls = reply_cls
# generic reply
diff --git a/ryu/app/ofctl/service.py b/ryu/app/ofctl/service.py
index 3e24170..183cc6c 100644
--- a/ryu/app/ofctl/service.py
+++ b/ryu/app/ofctl/service.py
@@ -39,6 +39,26 @@ class OfctlService(app_manager.RyuApp):
super(OfctlService, self).__init__(*args, **kwargs)
self.name = 'ofctl_service'
self._switches = {}
+ self._observing_events = {}
+
+ def _observe_msg(self, msg_cls):
+ assert msg_cls is not None
+ ev_cls = ofp_event.ofp_msg_to_ev_cls(msg_cls)
+ self._observing_events.setdefault(ev_cls, 0)
+ if self._observing_events[ev_cls] == 0:
+ self.logger.debug('ofctl: start observing %s' % (ev_cls,))
+ self.observe_event(ev_cls)
+ self._observing_events[ev_cls] += 1
+ self.register_handler(ev_cls, self._handle_reply)
+
+ def _unobserve_msg(self, msg_cls):
+ assert msg_cls is not None
+ ev_cls = ofp_event.ofp_msg_to_ev_cls(msg_cls)
+ assert self._observing_events[ev_cls] > 0
+ self._observing_events[ev_cls] -= 1
+ if self._observing_events[ev_cls] == 0:
+ self.unobserve_event(ev_cls)
+ self.logger.debug('ofctl: stop observing %s' % (ev_cls,))
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def _switch_features_handler(self, ev):
@@ -80,6 +100,8 @@ class OfctlService(app_manager.RyuApp):
@set_ev_cls(event.SendMsgRequest, MAIN_DISPATCHER)
def _handle_send_msg(self, req):
+ if not req.reply_cls is None:
+ self._observe_msg(req.reply_cls)
msg = req.msg
datapath = msg.datapath
datapath.set_xid(msg)
@@ -112,11 +134,13 @@ class OfctlService(app_manager.RyuApp):
except KeyError:
result = None
req = si.xids.pop(xid)
+ if not req.reply_cls is None:
+ self._unobserve_msg(req.reply_cls)
rep = event.Reply(result=result)
self.reply_to_request(req, rep)
@set_ev_cls(ofp_event.EventOFPErrorMsg, MAIN_DISPATCHER)
- def _handle_error(self, ev):
+ def _handle_reply(self, ev):
msg = ev.msg
datapath = msg.datapath
try:
@@ -125,6 +149,16 @@ class OfctlService(app_manager.RyuApp):
self.logger.error('unknown dpid %s' % (datapath.id,))
return
try:
+ req = si.xids[msg.xid]
+ except KeyError:
+ self.logger.error('unknown error xid %s' % (msg.xid,))
+ return
+ if ((not isinstance(ev, ofp_event.EventOFPErrorMsg)) and
+ (req.reply_cls is None or not isinstance(ev.msg, req.reply_cls))):
+ self.logger.error('unexpected reply %s for xid %s' %
+ (ev, msg.xid,))
+ return
+ try:
si.results[msg.xid] = ev.msg
except KeyError:
self.logger.error('unknown error xid %s' % (msg.xid,))
--
1.8.3.1
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel