読者です 読者をやめる 読者になる 読者になる

SDN開発エンジニアを目指した活動ブログ

〜SDNなオープンソース製品を実際に使って試してみる〜

Ryu SDN Frameworkを活用した簡易ルータ機能の作成(2) 〜IPルーティングの初歩編〜

通信プロトコル動作をOpenFlowプログラミングで制御するテーマ素材として、今回は、「IPルーティング編」です。異なるサブネット間を相互接続する役割のIPルータにおけるパケット転送機能を、OpenFlowプロトコルを活用して実現したいと思います。今後は、OpenFlowルータとて説明を進めます。
前回は、「双方のPC端末間では、各々が属しているサブネットワークが異なるため、自側のPC端末が対向側PC端末と相互通信を始める際に、自側PC端末に直接繋がったOpenFlowルータのMACアドレスを把握できるように、PC端末からOpenFlowルータ間でのARP Request/Replyの通信シーケンスの実装」に取り組みました。
これにより、PC端末では、OpenFlowルータに関するARP学習が完了している状態になるので、IPパケットを送出することが可能になるのです。

◆Ryuアプリ「簡易ルータ(コード名;simpleForward)」の実装

simpleForwardとして実装する機能は、前回のARP Request/Reply編でのOpenFlowルータに対する機能拡張を前提とします。
実際の機能概要は、概ね、こんな感じです。
(1) OpenFlowコントローラでは、双方のPC端末に関わるARP情報を管理する。←前回、対応済
(2) OpenFlowコントローラでは、双方のPC端末のIPパケット転送に関わる転送ルールをIPルーティングTBLとしてを管理する。
(3) OpenFlowコントローラでは、双方のPC端末のIPパケット転送ルールに対応したFlowエントリをOpenFlowスイッチに設定する。
(4) OpenFlowスイッチ上でFlowエントリを保持し、実際のIPルーティングの転送処理を実施する。

双方のPC端末(HOST1とHOST2)間は、各々異なるサブネットに属しており、これらをOpenFlowルータが相互接続することによりHOST1〜HOST2間の通信が実現できるようにIPパケット転送に関わる通信シーケンスの実装を行いました。
f:id:ttsubo:20140113134817j:plain

◆実装コード

簡易ルータ(コード名;simpleForward)実装コードは、こちらになります。
simpleRouter/ryu-app/blog/article_02/simpleForward.py at master · ttsubo/simpleRouter · GitHub

◆実際に動かしてみた

OpenFlowコントローラ上でのRyuアプリ「simpleForward」を動作させた上で、HOST1からHOST2にICMP通信を行いました。
最近、Ryu SDN Frameworkも3.5にバージョンアップされたみたいなので、今回の動作環境も、Ryu3.5で実施しております。

PC端末(HOST1)

自PC端末(HOST1)から対向PC端末(HOST2)へのICMP通信は、正しく動作できました。

tsubo@Host1:~$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=1.01 ms
64 bytes from 192.168.1.1: icmp_req=2 ttl=64 time=0.679 ms
64 bytes from 192.168.1.1: icmp_req=3 ttl=64 time=0.927 ms
64 bytes from 192.168.1.1: icmp_req=4 ttl=64 time=0.821 ms
64 bytes from 192.168.1.1: icmp_req=5 ttl=64 time=0.891 ms
64 bytes from 192.168.1.1: icmp_req=6 ttl=64 time=1.11 ms
64 bytes from 192.168.1.1: icmp_req=7 ttl=64 time=1.00 ms
64 bytes from 192.168.1.1: icmp_req=8 ttl=64 time=0.646 ms
64 bytes from 192.168.1.1: icmp_req=9 ttl=64 time=1.08 ms
64 bytes from 192.168.1.1: icmp_req=10 ttl=64 time=1.10 ms
^C
--- 192.168.1.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9004ms
rtt min/avg/max/mdev = 0.646/0.928/1.114/0.165 ms

OpenFlowスイッチ

自PC端末(HOST1)から対向PC端末(HOST2)へのICMP通信が動作できることを確認した上で、OpenFlowスイッチ上のFlowテーブルに保管されたFlowエントリを出力しました。
想定とおりのFlowエントリが確認できました。

tsubo@OpenFlowSwitch:~$ sudo ovs-ofctl dump-flows br0 --protocols=OpenFlow13
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x0, duration=20.900s, table=0, n_packets=20, n_bytes=1960, priority=255,ip,in_port=2,dl_src=52:54:00:0b:d0:48,dl_dst=00:00:00:00:00:02,nw_dst=192.168.0.1 actions=set_field:00:00:00:00:00:01->eth_src,set_field:52:54:00:75:4e:57->eth_dst,output:1
 cookie=0x0, duration=20.900s, table=0, n_packets=20, n_bytes=1960, priority=255,ip,in_port=1,dl_src=52:54:00:75:4e:57,dl_dst=00:00:00:00:00:01,nw_dst=192.168.1.1 actions=set_field:00:00:00:00:00:02->eth_src,set_field:52:54:00:0b:d0:48->eth_dst,output:2
 cookie=0x0, duration=21.690s, table=0, n_packets=11, n_bytes=774, priority=0 actions=CONTROLLER:65535

OpenFlowコントローラ

現状のRyuアプリ「simpleForward」では、UIの実装を行っておりません。
ですので、ここでは、OpenvSwitch〜OpenFlowContoller間のOpenFlowチャネルでのOpenFlowプロトコルの通信シーケンスをパケットキャプチャしました。想定どおりのOpenFlowプロトコルの通信シーケンスが確認できました。
f:id:ttsubo:20140113142034j:plain

◆その他、補足

さきほどの動作説明では、PC端末(HOST1)では、自側PC端末に直接繋がったOpenFlowルータのMACアドレスを把握していない状態(=ARP学習していない状態)から、PC端末の動作を開始する前提としておりました。
ただ、OpenFlowコントローラ再起動のような事象が発生した場合には、次のような状態も想定する必要があります。
(1) PC端末では、ARP学習済であり、ICMP通信をすぐにでも開始可能である。(ARP Request/Replyの通信シーケンス不要のため)
(2) OpenFlowコントローラでは、双方のPC端末に関わるARP情報が管理できていない。再学習です必要がある。
(3) OpenFlowコントローラでは、双方のPC端末のIPパケット転送ルールに対応したFlowエントリをOpenFlowスイッチに設定する。
(4) OpenFlowスイッチ上でFlowエントリを保持し、実際のIPルーティングの転送処理を実施する。

f:id:ttsubo:20140113143756j:plain

PC端末(HOST1)でARP学習済の時に、再度、自PC端末(HOST1)から対向PC端末(HOST2)へのICMP通信を行いました。その時の、OpenvSwitch〜OpenFlowContoller間のOpenFlowチャネルでのOpenFlowプロトコルの通信シーケンスをパケットキャプチャしました。想定どおりのOpenFlowプロトコルの通信シーケンスが確認できました。
f:id:ttsubo:20140113145101j:plain

実際のパケットキャプチャの内容を、よくよく確認してみると、双方のPC端末(HOST1,HOST2)から"91.189.89.22"宛にTCPコネクション開設している箇所が、気になります。
開発用OpenFlowネットワーク環境として、mininetが活用されるケースが多いと思いますが、実際のPC端末でやりとりされている通信シーケンスを想定した上で、OpenFlowプログラミングを実施しないと、「開発環境では、ちゃんとうまく動作するのに、本番環境では想定外の挙動が発生してしまう...」みたいな運用課題が懸念されます。よって、このような運用課題の事例を低減するためにも、最近の継続インテグレーション的な開発手法をOpenFlowプログラミングに活用することが重要かもしれません。

◆終わりに

今回、Ryu SDN Frameworkを活用して、IPルーティングの初歩レベルのOpenFlowプログラミングを実施してみました。
次回は、Ryuアプリ開発を目的としたOpenFlowテスト環境について、少し考えてみたいと思います。