ofproto 函式庫¶
本章介紹 Ryu ofproto 函式庫。
簡單說明¶
ofproto 函式庫是用來產生及解析 OpenFlow 訊息的函式庫。
相關模組¶
每個 OpenFlow( 版本 X.Y )都有相對應的常數模組( ofproto_vX_Y )和解析模組( ofproto_vX_Y_parser )每個 OpenFlow 版本的實作基本上是獨立的。
OpenFlow 版本 | 常數模組 | 解析模組 |
---|---|---|
1.0.x | ryu.ofproto.ofproto_v1_0 | ryu.ofproto.ofproto_v1_0_parser |
1.2.x | ryu.ofproto.ofproto_v1_2 | ryu.ofproto.ofproto_v1_2_parser |
1.3.x | ryu.ofproto.ofproto_v1_3 | ryu.ofproto.ofproto_v1_3_parser |
1.4.x | ryu.ofproto.ofproto_v1_4 | ryu.ofproto.ofproto_v1_4_parser |
常數模組¶
常數模組是用來做為通訊協定中的常數設定使用,下面列出幾個例子。
常數 | 說明 |
---|---|
OFP_VERSION | 通訊協定版本編號 |
OFPP_xxxx | 連接埠號 |
OFPCML_NO_BUFFER | 無緩衝區間,直接對全體發送訊息 |
OFP_NO_BUFFER | 無效的緩衝編號 |
解析器模組¶
解析模組提供各個 OpenFlow 訊息的對應類別,下面列出幾個例子。 為了更好的說明類別的實體,接下來的描述將用”訊息物件”取代”訊息類別”。
類別( Class ) | 說明 |
---|---|
OFPHello | OFPT_HELLO 訊息 |
OFPPacketOut | OFPT_PACKET_OUT 訊息 |
OFPFlowMod | OFPT_FLOW_MOD 訊息 |
解析模組對應了 OpenFlow 訊息的 Payload 結構中所需的定義,例如下面的例子。 為了更好的說明類別的實體,今後將用結構物件( structure object )取代結構類別( structure class )。
類別( Class ) | 結構 |
---|---|
OFPMatch | ofp_match |
OFPInstructionGotoTable | ofp_instruction_goto_table |
OFPActionOutput | ofp_action_output |
基本使用方法¶
ProtocolDesc 類別¶
這是為了 OpenFlow 協定所必需存在的類別。 使用訊息類別的 __init__ 作為 datapath 的參數,指定該類別的物件。
from ryu.ofproto import ofproto_protocol
from ryu.ofproto import ofproto_v1_3
dp = ofproto_protocol.ProtocolDesc(version=ofproto_v1_3.OFP_VERSION)
網路位址( Network Address )¶
Ryu ofproto 函式庫的 API 使用最基本的文字表現網路位址,請看下面的例子。
備註
但是 OpenFlow 1.0 和這樣的標示方法不同。 ( 2014年2月更新 )
位址( Address )種類 | python文字表示 |
---|---|
MAC 位址 | ‘00:03:47:8c:a1:b3’ |
IPv4 位址 | ‘192.0.2.1’ |
IPv6 位址 | ‘2001:db8::2’ |
訊息物件( Message Object )的產生¶
每個訊息類別( message class ),結構類別( structure class )都需要適當的參數以用來產生。
參數的名稱跟 OpenFlow 協定所定義的欄位名稱基本上是一致的。
在有衝突的情況下會在最後加入「_」,例如:「type_
」就是。
from ryu.ofproto import ofproto_protocol
from ryu.ofproto import ofproto_v1_3
dp = ofproto_protocol.ProtocolDesc(version=ofproto_v1_3.OFP_VERSION)
ofp = dp.ofproto
ofpp = dp.ofproto_parser
actions = [parser.OFPActionOutput(port=ofp.OFPP_CONTROLLER,
max_len=ofp.OFPCML_NO_BUFFER)]
inst = [parser.OFPInstructionActions(type_=ofp.OFPIT_APPLY_ACTIONS,
actions=actions)]
fm = ofpp.OFPFlowMod(datapath=dp,
priority=0,
match=ofpp.OFPMatch(in_port=1,
eth_src='00:50:56:c0:00:08'),
instructions=inst)
備註
常數模組、解析模組最好是在 import 的時候就直接標明。 如此一來在 OpenFlow 版本變更的時候,可以將修正的程度將到最低。 另外儘量使用 ProtocolDesc 物件的 ofproto 和 ofproto_parser 屬性。
訊息物件( Message Object )的解析¶
訊息物件( message object )的內容是可以查詢的。
例如 OFPPacketIn 物件中 pid 的 match field 用查詢 pin.match 即可得到相關的訊息。
OFPMatch 物件中 TLV 的各部分可以使用下列的名稱取得相關的資料。
print pin.match['in_port']
JSON¶
訊息物件( message object )轉換成為 json.dump 的功能是存在的,反之亦然。
備註
但是目前 OpenFlow 1.0 相關的實作並不完全。 ( 2014年2月更新 )
import json
print json.dumps(msg.to_jsondict())
訊息( message )的解析( parse )¶
該功能是為了把訊息的原始資料轉換成訊息物件。 對於從交換器收到的訊息,框架( Framwork )會自動地進行處理,Ryu 應用程式( Application )是不需要特別處理的。
具體來說如下:
- ryu.ofproto.ofproto_parser.header 用來處理版本相依的解析
- 上面處理過的結果可以用 ryu.ofproto.ofproto_parser.msg 功能來解析剩餘的部分
訊息的產生( 序列化,Serialize )¶
將訊息物件轉換並產生對應的訊息 Byte 。 同樣的,來自交換器的訊息將由框架自動處理,Ryu 應用程式無需額外的動作。
具體來說如下:
- 呼叫訊息物件的序列化方法
- 從訊息物件中將 buf 的屬性讀取出來
有些欄位,例如“len”即使不指定,在序列化的同時也會自動被計算出來。