我們在使用ryu控制器的時候經常希望可以同步地獲取openflow的信息,而ryu/app/ofctl文件夾下的api.py文件就爲我們提供了這樣一個方便的途徑。
當然最方便的獲取和更新交換機狀態的方法當然是使用REST API接口,我將會在下一篇博客中寫到,關於這部分之前也有不少小夥伴寫過,可以參考李呈同學的博客http://www.sdnlab.com/11552.html。
1.如何啓動
如果你啓動的app中已經導入了ryu.app.ofctl.api,那麼在app啓動的時候已經將ofctl.api模塊導入。如果啓動的app中沒有導入它那麼需要在啓動的app文件中添加並編寫,具體見2中的使用例子。
import ryu.app.ofctl.api
2.api模塊
(附源碼)
源碼中定義了兩個方法,其中一個是get_datapath,它有兩個參數分別爲:app和dpid,其中app爲客戶機中運行的app實例,dpid是其中一條datapath的id號(爲整數)。另一個方法是send_msg,它的參數有四個分別爲:app、msg、reply_cls、reply_multi,其中app爲客戶機中運行的app實例,msg是要發送的openflow controller-to-switch類型的消息,reply_cls是希望返回的openflow的消息類,reply_multi在希望返回多元的消息時爲true默認爲false,最後的兩個參數均爲默認。
使用例子:
import ryu.app.ofctl.api as api #導入ryu.app.ofctl.api並重新命名爲api
msg = parser.OFPPortDescStatsRequest(datapath=datapath)
result = api.send_msg(self, msg,
reply_cls=parser.OFPPortDescStatsReply,
reply_multi=True)
3.異常提示
1)exception ryu.app.ofctl.exception.InvalidDatapath(result)
Datapath is invalid.
這個通常可能是由於bridge沒有連上造成的
2)exception ryu.app.ofctl.exception.OFError(result)
OFPErrorMsg is received.
3)exception ryu.app.ofctl.exception.UnexpectedMultiReply(result)
Two or more replies are received for reply_muiti=False request.
4.源碼
import numbers
from ryu.base import app_manager
from . import event
def get_datapath(app, dpid):
"""
Get datapath object by dpid.
:param app: Client RyuApp instance
:param dpid: Datapath-id (in integer)
Returns None on error.
"""
assert isinstance(dpid, numbers.Integral)
return app.send_request(event.GetDatapathRequest(dpid=dpid))()
def send_msg(app, msg, reply_cls=None, reply_multi=False):
"""
Send an OpenFlow message and wait for reply messages.
:param app: Client RyuApp instance
:param msg: An OpenFlow controller-to-switch message to send
:param reply_cls: OpenFlow message class for expected replies.
None means no replies are expected. The default is None.
:param reply_multi: True if multipart replies are expected.
The default is False.
If no replies, returns None.
If reply_multi=False, returns OpenFlow switch-to-controller message.
If reply_multi=True, returns a list of OpenFlow switch-to-controller
messages.
Raise an exception on error.
Example::
import ryu.app.ofctl.api as api
msg = parser.OFPPortDescStatsRequest(datapath=datapath)
result = api.send_msg(self, msg,
reply_cls=parser.OFPPortDescStatsReply,
reply_multi=True)
"""
return app.send_request(event.SendMsgRequest(msg=msg,
reply_cls=reply_cls,
reply_multi=reply_multi))()
app_manager.require_app('ryu.app.ofctl.service', api_style=True)
參考網頁:
http://ryu.readthedocs.org/en/latest/app/ofctl.html#ryu.app.ofctl.exception.InvalidDatapath
https://github.com/osrg/ryu/blob/master/ryu/app/ofctl/api.py