Ryu+Lagopusで
OpenFlowの動きを見てみよう
Mar 10, 2016
Masaru OKI @masaru0714
OpenFlowおさらい
● コントローラとスイッチが連係して動作する
● コントローラがパケット処理のルール(フローエントリ)をスイッチに登録する
● スイッチは登録されたルールに従って受信パケットを処理する
スイッチ
コントローラ TCP or SSL
flow table
フローエントリ登録
「1からきたパケットは2へ」
パケット
パケット
1
2
3
LagopusとRyu
● Lagopus
○ https://lagopus.github.io/
○ オープンソースのOpenFlowソフトウェアスイッチ。
○ 単一プロセスで動作する。
● Ryu
○ https://osrg.github.io/ryu/
○ オープンソースのSDNコントローラフレームワーク。
○ Pythonで書かれている。
○ 提供されるクラスを使ったアプリケーションを記述して利用。
■ OpenFlowコントローラを記述することができる。
Ryu certification
ryu-manager /usr/local/lib/python2.7/dist-packages/ryu/tests/switch/tester.py
● テスト対象のスイッチにOpenFlowのルールを入れて、パケットを流す
● ルールに従って処理されたパケットが出力されることを検証する
● 送受信のための補助スイッチもOpenFlowで制御する
テスト対象スイッチ
Device Under Test
(DUT)
補助スイッチ
tester.py
1.フロー投入
2.Packet-out
3.Packet-in
テストケース
JSON
4.Packet-in結果がテスト
ケースに書かれた内容と
一致するかチェック
JSONで記述する。
[
“テスト内容の説明”,
{
“description”: “テストの細かい説明”,
“prerequisite”:[フロー登録などの内容],
“tests”:
[
{
“ingress”:[DUTに送るパケットの内容],
“egress”:[DUTから送られてくるべきパケットの内容]
}
]
}
]
Ryu certificationのテストケース
{ … }, { … } と
複数記述できる
{ … }, { … } と
複数記述できる
prerequisiteの例
"prerequisite":[
{
"OFPFlowMod":{
"table_id":0,
"match":{
"OFPMatch":{
"oxm_fields":[
{
"OXMTlv":{
"field":"in_port",
"value":1
}
}
]
}
},
"instructions":[
{
"OFPInstructionActions":{
"actions":[
{
"OFPActionOutput":{
"port":2
}
}
],
"type":4
}
}
]
}
}
],
in_port=1,actions=output:2
testsの例
"tests":[
{
"ingress":[
"ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)",
"ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)",
"tcp(dst_port=2222, option=bytes(b'x00' * 4), src_port=11111)",
"b'x01x02x03x04x05x06x07x08tnx0bx0crx0ex0fx10x11x12x13x14”
],
"egress":[
"ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)",
"ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)",
"tcp(dst_port=2222, option=bytes(b'x00' * 4), src_port=11111)",
"b'x01x02x03x04x05x06x07x08tnx0bx0crx0ex0fx10x11x12x13x14”
]
}
]
受信パケットがそのまま出力
される想定
テストケースを別の見方で考えると
● 自分が考えたOpenFlowのフローエントリを書いて
● どういうパケットを受信したら
● どういう結果になると思うかを記述する
正しく動作するOpenFlowスイッチに対してこれをやると、
OpenFlowの動作について確認することができる!
● OpenFlowについての理解を深めることができる。あるいは、
● スイッチのバグを見つけることができるかも?
Ryu certificationのためのLagopusの設定
misc/examples/2x3port.dsl
● Ryu添付テストケースで3ポート使うものがあるため3ポートを結線する想定。
● ひとつのLagopusで二つのスイッチを扱います
テスト対象スイッチ
bridge0 dpid=1
補助スイッチ
bridge1 dpid=2
127.0.0.1:6667
127.0.0.1:6667
コントローラ
Ryu certificationのためのLagopus起動コマンドライン
● DPDK版。hugepageの利用ができるよう準備願います。
● 8コアのマシンの例。下記を一行で入力してください。
● -d を省いてバックグラウンド動作させてもOKです。
● コア数が少ないときは -c の値を調整してください(-c 3など)
● eth_pipeはLagopus内蔵のドライバで、2つポートを用意しその間をつなぎます
sudo lagopus -d -C ./misc/examples/2x3port.dsl -- -cff -n2
--vdev eth_pipe0 --vdev eth_pipe1 --vdev eth_pipe2 -- -p3f
自分で書いたJSONを走らせてみる
● 下記を1行で入力してください。
● --test-switch-dirはディレクトリ名指定ですが、ファイル名指定もできます。
ryu-manager /usr/local/lib/python2.7/dist-packages/ryu/tests/switch/tester.py
--test-switch-dir YOUR_TEST.json
実行例
$ ryu-manager ./ryu/tests/switch/tester.py --test-switch-dir ./ryu/tests/switch/of13/tunnel/09_DECAP_GTPU.json
(中略)
--- Test start ---
waiting for switches connection…
dpid=0000000000000001 : Join target SW.
dpid=0000000000000002 : Join tester SW.
action: 09_DECAP_GTPU
ethernet/ipv4/udp/gtpu/ipv4/tcp-->'eth_type=0x0800,ip_proto=17,udp_dst=2125,actions=decap:ethrenet,decap:ip,
decap:udp,decap:gtpu,encap:ethernet,set_eth_src:12:22:22:22:22:22,set_eth_dst:22:33:33:33:33:33,output:2' OK
--- Test end ---
--- Test report ---
OK(1) / ERROR(0)
Terminated
テストケースの書き方のキモ
● ingressは1番ポートで受信するパケットの内容。
● egressは2番ポートに送信されるパケットの内容。
● 「キーワードがわからない」
○ 現時点では、OpenFlow仕様書を参照するか Ryuのソースを読むか
○ 既存テストケースの内容からコピペするのもありです
○ /usr/local/lib/python2.7/dist-packages/ryu/tests/switch/of13/ の下にたくさんあります
リファレンス
● Ryu book “OpenFlowスイッチテストツール”
○ https://osrg.github.io/ryu-book/ja/html/switch_test_tool.html
○ mininetを使ったテストの方法についても書かれています
● Open Networking Foundation
○ https://opennetworking.org/
○ OpenFlow仕様書などが入手できます
● Lagopus
○ https://lagopus.github.io/
○ バグを見つけたらgithubのissueなどでご報告いただければ。

Ryu+Lagopusで OpenFlowの動きを見てみよう