Ryu SDN Frameworkを活用した簡易ルータ機能の作成(6) 〜疎通診断編〜
最近、OpenFlowもだいぶ認知度が高まってきた気がします。通常、OpenFlowは、通信経路の自動設定に活用されることが多いと思います。今回は、ちょっと応用編として、OpenFlow監視機能の実現を目指して、REST-IFから疎通診断が可能になるようなping機能に着手したいと思います。
◆疎通診断機能
OpenFlowスイッチとつながるネットワーク機器との相互接続性の監視を、OpenFlow機能(Packet-In, Packet-Out)を活用して実現します。実際の機能構成イメージは、概ね、こんな感じです。
実装コードは、こちらになります。
前回のRESTインタフェース(openflowRouter)の実装コード拡張
前回までのSimpleRouterの実装コード拡張
[実装における課題]
疎通診断先のアドレス情報を特定するには、OpenflowRouter内部でもルーティングテーブル,ARPテーブルとMACテーブルを保持することが必須となりますが、まだ、これらテーブルの実装までには至っていません。今回は、REST-IF上で疎通診断で必要になるアドレス情報をすべて指定する方式としました。
◆実際に動かしてみた
疎通診断の代表的なユースケースを確認するために、今回からネットワーク構成を変更しております。
前回までは、「HOST1 <-> OpenvSwitch <-> HOST2 」という構成でした。
今回は、「HOST1 <-> vyatta <-> OpenvSwitch <-> HOST2 」という構成としております。
TestCase1:
正しく動作しているvyattaルータ向けに疎通診断を実施した場合
REST-Clientから疎通診断を実施した結果です。vyattaルータからのICMP Echo Replyを受信できております。
$ curl -s -X PUT -d '{"ping": {"hostIp": "192.168.0.1", "data": "Created by Openflow Router", "hostMac": "52:54:00:b2:55:2c", "routerMac": "00:00:00:00:00:01", "routerIp": "192.168.0.10", "outPort": "1"}}' http://localhost:8080/openflow/0000000000000001/ping | python -mjson.tool { "id": "0000000000000001", "ping": [ "PING 192.168.0.1 : 26 data bytes", "ping ok ( 34 bytes from 192.168.0.1: icmp_req=1 ttl=64 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 192.168.0.1: icmp_req=2 ttl=64 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 192.168.0.1: icmp_req=3 ttl=64 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 192.168.0.1: icmp_req=4 ttl=64 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 192.168.0.1: icmp_req=5 ttl=64 data=[Created by Openflow Router] )" ] }
通常のPingであれば、RTT計測結果も確認できるところですが、今回の機能構成上では、OpenFlowチャネルを介した ICMPパケット送受信が行われるため、正確なRTT計測が実施できません。よって、RTT計測は対応しておりません。
TestCase2:
NIC故障などで、正しく動作していないvyattaルータ向けに疎通診断を実施した場合
REST-Clientから疎通診断を実施した結果です。vyattaルータ向けのICMP Echo Reply受信タイムアウトを検出できております。
$ curl -s -X PUT -d '{"ping": {"hostIp": "192.168.0.1", "data": "Created by Openflow Router", "hostMac": "52:54:00:b2:55:2c", "routerMac": "00:00:00:00:00:01", "routerIp": "192.168.0.10", "outPort": "1"}}' http://localhost:8080/openflow/0000000000000001/ping | python -mjson.tool { "id": "0000000000000001", "ping": [ "PING 192.168.0.1 : 26 data bytes", "ping ng ( Request Timeout for icmp_seq 1 )", "ping ng ( Request Timeout for icmp_seq 2 )", "ping ng ( Request Timeout for icmp_seq 3 )", "ping ng ( Request Timeout for icmp_seq 4 )", "ping ng ( Request Timeout for icmp_seq 5 )" ] }
TestCase3:
正しく動作しているHOST1向けに疎通診断を実施した場合
REST-Clientから疎通診断を実施した結果です。HOST1からのICMP Echo Replyを受信できております。
$ curl -s -X PUT -d '{"ping": {"hostIp": "172.16.100.101", "data": "Created by Openflow Router", "hostMac": "52:54:00:b2:55:2c", "routerMac": "00:00:00:00:00:01", "routerIp": "192.168.0.10", "outPort": "1"}}' http://localhost:8080/openflow/0000000000000001/ping | python -mjson.tool { "id": "0000000000000001", "ping": [ "PING 172.16.100.101 : 26 data bytes", "ping ok ( 34 bytes from 172.16.100.101: icmp_req=1 ttl=63 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 172.16.100.101: icmp_req=2 ttl=63 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 172.16.100.101: icmp_req=3 ttl=63 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 172.16.100.101: icmp_req=4 ttl=63 data=[Created by Openflow Router] )", "ping ok ( 34 bytes from 172.16.100.101: icmp_req=5 ttl=63 data=[Created by Openflow Router] )" ] }
TestCase4:
NIC故障などで、正しく動作していないHOST1向けに疎通診断を実施した場合
REST-Clientから疎通診断を実施した結果です。vyattaルータからのICMP Echo Reply受信によりHOST1への到達性NGを検出できております。
$ curl -s -X PUT -d '{"ping": {"hostIp": "172.16.100.101", "data": "Created by Openflow Router", "hostMac": "52:54:00:b2:55:2c", "routerMac": "00:00:00:00:00:01", "routerIp": "192.168.0.10", "outPort": "1"}}' http://localhost:8080/openflow/0000000000000001/ping | python -mjson.tool { "id": "0000000000000001", "ping": [ "PING 172.16.100.101 : 26 data bytes", "ping ok (ping ng ( Detination Unreachable ))", "ping ok (ping ng ( Detination Unreachable ))", "ping ok (ping ng ( Detination Unreachable ))", "ping ok (ping ng ( Detination Unreachable ))", "ping ok (ping ng ( Detination Unreachable ))" ] }
◆終わりに
今回、疎通診断機能の実装を通じて、いろいろ学ぶことができました。
一般的なルータ機器には、疎通診断なping機能がひととおり備わっているので、その存在価値を意識することは少ないと思います。すなわち、使えて当たり前という意識ですよね。OpenFlowプログラミングで疎通診断を実装する場合には、Echo Reply受信タイムアウト等のエラー判定を盛り込まなければなりません。
よく、OpenFlowプロトコルによるネットワーク制御のオープン化をメリットとして取り上げられる雑誌記事を見掛けますが、『OpenFlowプログラミングで実装すれば、なんでもできるようになる。』けど、『OpenFlowプログラミングで実装しなければ、何もできない。』ということを再認識できました。
次回は、OpenFlow簡易ルータのルーティング管理の拡張を図りたいと思います。