OpenFlow 1.5 從入門到交報告 (二) - Ryu
支援 OpenFlow 的 Controller 有很多種,Ryu 就是其中一員。Ryu 是一個開源的 OpenFlow Controller 開發框架,主要語言是 Python,由日本 NTT 的實驗室創造。截至目前為止,Ryu 支援到 OpenFlow 1.5。本篇同時是 2019 研究所課程報告下半部,上一篇介紹了 Mininnet 基本概念,有興去可以參照。
安裝 Ryu
|
|
Ryu 部分功能有依賴其他套件,可以一併安裝。
|
|
還有一些是必要的 Dependencies:
|
|
或是,使用 Ryu Container
我很喜歡 Container 超好用,環境單純,不需要煩惱架設環境所踩到的雷,不過要想清楚的是 Container 間的網路怎麼連,目前我想讓 Mininet 容器能夠和 Ryu Controller 容器可以互連,因此使用預設的 bridge mode 即可。為了讓 Ryu 容器可以吃到我之後寫的 Python,所以要 Mount 一個 Volume 對應到主機的某資料夾。
|
|
接著到另一個視窗開 Mininet
|
|
查看 Ryu 的 IP,是172.17.0.2
:
|
|
執行 Simple Switch
運行 Ryu 的 Simple Switch: ryu-manager ryu.app.simple_switch_15
, 測試 Controller 是否可以被 Mininet 連接。
|
|
接著啟動 Mininet,控制器指定到 Ryu 的 IP:
|
|
你會看見 Ryu 輸出一堆封包訊息:
|
|
最後 Pingall 測試 Hosts 之間可以互通。
|
|
Ryu 開發框架結構
下面這個程式還沒有任何功能,不過已經是一個最基本可以運行的 Ryu 程式。ryu.base.app_manager.RyuApp(*_args, **_kwargs)
這個 Class 是 Ryu 的 Base class,我們自己寫的 Class 必須繼承這個 Class。文件中規定,Constructor 中必須呼叫 Parent 的 Constructor,換句話說就是 __init__
中必須呼叫 RyuApp.__init__
,也就是super.__init__
。
|
|
接下來觀察 simple_switch
原始碼,藉此了解如何開發 Ryu Controller。
Code 在官方 Repo 中
指定 OpenFlow 版本
這個例子指定了 OpenFlow 1.5 版本
|
|
Decorator @set_ev_cls(ev_cls, dispatchers=None)
Ryu 讓我們透過 @set_ev_cls
這個 Decorated Method 來定義 Event Handeler 的角色,當該定義的 Event 發生時,就會執行 Decorator 下方的函式。這個 Decorated Method 接收兩個參數: ev_cls
和 dispatcher
。ev_cls
這個 Event Class 參數要放入 OpenFlow 的 Messages and Structures,依照 OpenFlow 標準分為 Controller-to-Switch、Asynchronous 與 Symmetric,以 OpenFlow 1.5 為例,文件中就有列出所有的種類以及他們的作用。 dispatcher
參數用來決定要處理哪個 Negotiation Phase (Switch 與 Controller 交涉的階段),總共有四個階段,取決於你放的 ev_cls
為何。
Negotiation phase | Description |
---|---|
ryu.controller.handler.HANDSHAKE_DISPATCHER |
Sending and waiting for hello message |
ryu.controller.handler.CONFIG_DISPATCHER |
Version negotiated and sent features-request message |
ryu.controller.handler.MAIN_DISPATCHER |
Switch-features message received and sent set-config message |
ryu.controller.handler.DEAD_DISPATCHER |
Disconnect from the peer. Or disconnecting due to some unrecoverable errors. |
例如 simple_switch_15.py
中,就包含兩個 Decorated Method。以下這段程式碼,ofp_event.EventOFPSwitchFeatures
代表函式會在 Switch 回應 Feature Reply 時觸發,對應到的 Negotiation phase 即為 CONFIG_DISPATCHER
。
|
|
ofp_event.EventOFPPacketIn
是 Packet-In Message,意即當 Switch 收到進入的封包時,所發送給 Controller 的訊息。當 Switch 收到封包時觸發,對應到的 Negotiation phase 為 MAIN_DISPATCHER
。
|
|
Add Flow
再來看看 Function 裡面的變數是如何使用的。
|
|
ev.msg.datapath
代表 Switch 物件datapath.ofproto
與datapath.ofproto_parser
代表著 OpenFlow protocol 物件OFPMatch
用來指定 Flow Match,共40種。這裡沒有定義何 Match。OFPActionOutput
用來決定封包要往哪個連接埠送出,主要參數是兩個 Flag,port
就是 Output port,max_len
指送給 Controller 的最大長度。OFPP_CONTROLLER
就是送到 Controller,OFPCML_NO_BUFFER
代表封包完整地給 Controller,這些值都是一個 Flag,可以在原始碼查看。
|
|
OFPInstructionActions
就是 OpenFlow 的 Instruction,種類由第一個參數設定,三選一如下,第二個參數放入OFPInstructionActions
。OFPIT_WRITE_ACTIONS
OFPIT_APPLY_ACTIONS
OFPIT_CLEAR_ACTIONS
OFPFlowMod
用來讓 Controller 改變 Flow Table。table_id
如果有要指定 Table 來放入 Entry 可使用instructions
中用來傳入OFPInstructionActions
- 最後透過
datapath.send_msg(mod)
將 OpenFlow 訊息送到交換器
References
- Getting Started — Ryu 4.30 documentation
- osrg/ryu - Docker Hub
- Install Mininet and Ryu Controller
- osrg/ryu: Ryu component-based software defined networking framework
- openflow-switch-v1.5.1.pdf
- 張衛峰,深度解析SDN:利益、戰略、技術、實踐,台灣:碁峰,2014,第 68 至 83 頁。