[Linux][Network] mininet内のスイッチをループさせてみよう

技術のお話し

今度は何するの?

前回の記事で、少し複雑なL2ネットワークを構成しました。

今回、少々いじってこんなトポロジーを組んでみようと思います。

ネットワークかじってる人はだいたい察しがつくと思うんですが、これまでryu-manager側で動かしてたsimple_switch.pyでは、フレームのループが発生し、ブロードキャストストームが発生するのではないかなと考えました。で、実際にやってみたと。

どういう風にしたのか

前回の投稿で作成したpyファイルのAdd links部分の「★」箇所です。コレを追加しました。これにより、「Switch1->Switch2->Swtich3->Switch4->Switch1」と言うスクウェア型のループが出来上がります。

このファイルを「topo-4sw-10host-loop.py」として保存します。

   # Add links
   self.addLink( Switch1, Switch2 )
   self.addLink( Switch2, Switch3 )
   self.addLink( Switch3, Switch4 )
 ★self.addLink( Switch4, Switch1 )  ←こいつを追加した
   self.addLink( Host1, Switch1 )
   self.addLink( Host2, Switch1 )
   self.addLink( Host3, Switch2 )
   self.addLink( Host4, Switch2 )
   self.addLink( Host5, Switch2 )
   self.addLink( Host6, Switch2 )
   self.addLink( Host7, Switch3 )
   self.addLink( Host8, Switch3 )
   self.addLink( Host9, Switch4 )
   self.addLink( Host10, Switch4 )

simple_switch.pyでこの構成を実行してみる

mininet側はこうなりました。

root@mininet:~/mininet/custom# mn --controller=remote,ip=192.168.100.138,port=6633 --custom ~/mininet/custom/topo-4sw-10host-loop.py --topo mytopo
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 
*** Adding switches:
s1 s2 s3 s4 
*** Adding links:
(h1, s1) (h2, s1) (h3, s2) (h4, s2) (h5, s2) (h6, s2) (h7, s3) (h8, s3) (h9, s4) (h10, s4) (s1, s2) (s2, s3) (s3, s4) (s4, s1) 
*** Configuring hosts
h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 
*** Starting controller
c0 
*** Starting 4 switches
s1 s2 s3 s4 ...
*** Starting CLI:

お、起動したみたい。しかし、ryu-manager側の標準出力には

packet in 2 00:00:00:00:00:05 33:33:ff:00:00:05 5
packet in 1 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 3 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 4 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 4 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 3 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 3 00:00:00:00:00:07 33:33:00:00:00:16 3
packet in 1 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 4 00:00:00:00:00:07 33:33:00:00:00:16 1
packet in 2 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 2 00:00:00:00:00:07 33:33:00:00:00:16 2
packet in 2 00:00:00:00:00:04 33:33:ff:00:00:04 4
packet in 2 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 1 00:00:00:00:00:07 33:33:00:00:00:16 2
packet in 1 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 3 00:00:00:00:00:04 33:33:ff:00:00:04 1
packet in 3 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 1 00:00:00:00:00:07 33:33:00:00:00:16 1
packet in 1 00:00:00:00:00:04 33:33:ff:00:00:04 1
packet in 2 00:00:00:00:00:07 33:33:00:00:00:16 1
packet in 4 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 4 00:00:00:00:00:07 33:33:00:00:00:16 2
packet in 4 00:00:00:00:00:04 33:33:ff:00:00:04 2
packet in 4 00:00:00:00:00:04 33:33:ff:00:00:04 1
packet in 4 00:00:00:00:00:05 33:33:ff:00:00:05 1
packet in 3 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 3 00:00:00:00:00:07 33:33:00:00:00:16 1
packet in 3 00:00:00:00:00:07 33:33:00:00:00:16 2
packet in 1 00:00:00:00:00:04 33:33:ff:00:00:04 2
packet in 1 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 2 00:00:00:00:00:05 33:33:ff:00:00:05 2
packet in 3 00:00:00:00:00:04 33:33:ff:00:00:04 2
packet in 4 00:00:00:00:00:07 33:33:00:00:00:16 1
(以下略)

と言う感じの出力が延々と行われます。そう、フレームがグルグルループしてブロードキャストストームが発生しています。

実際、VM側のパフォーマンスグラフを見ると、1vCPUの負荷がフルになってました。(いずれも2vCPU構成なので、CPU負荷としては50%になっています)

ブロードキャストストームが発生すると、ネットワークインタフェースを所有して接続している機器は皆さん揃って成仏してしまうことになる・・のでコレはマズイっすね。

mininet用VMのCPU負荷

ryu-manager用VMのCPU負荷この状態でpingを打ってみるわけですが、当然応答は返ってきませんでした。

mininet> pingall
*** Ping: testing ping reachability
h1 -> ^C
Interrupt
stopping h1 
mininet>

コンソール応答も怪しくなってきたので取り敢えずmininetを終了・・・・

mininet> exit
*** Stopping 1 controllers
c0 
*** Stopping 14 links
..............
*** Stopping 4 switches
s1 s2 s3 s4 
*** Stopping 10 hosts
h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 
*** Done
completed in 13.810 seconds
root@mininet:~/mininet/custom#

ryu-manager側のログ爆発もここで停止しました。

OpenFlowコントローラから、STP機能を付与したコンフィグを実行させる

simple_switch.pyではこのループした構成での正常な通信は望めませんで、代わりに同じディレクトリにある「simple_switch_stp.py」と言うファイルで立ち上げてみることにしました。RyuってこうしたサンプルPythonファイルが沢山あるので、動きを見極めるにはちょうどよいですね。

[root@OpenFlow app]# ryu-manager ~/ryu/app/simple_switch_stp.py
loading app /root/ryu/app/simple_switch_stp.py
loading app ryu.controller.ofp_handler
instantiating app None of Stp
creating context stplib
instantiating app /root/ryu/app/simple_switch_stp.py of SimpleSwitchStp
instantiating app ryu.controller.ofp_handler of OFPHandler

この状態でmininetを起動します。

root@mininet:~/mininet/custom# mn --controller=remote,ip=192.168.100.138,port=6633 --custom ~/mininet/custom/topo-4sw-10host-loop.py --topo mytopo
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 
*** Adding switches:
s1 s2 s3 s4 
*** Adding links:
(h1, s1) (h2, s1) (h3, s2) (h4, s2) (h5, s2) (h6, s2) (h7, s3) (h8, s3) (h9, s4) (h10, s4) (s1, s2) (s2, s3) (s3, s4) (s4, s1) 
*** Configuring hosts
h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 
*** Starting controller
c0 
*** Starting 4 switches
s1 s2 s3 s4 ...
*** Starting CLI:
mininet>

すると、ryu-manager側で以下のような応答が返ってきました。

[STP][INFO] dpid=0000000000000004: Join as stp bridge.
[STP][INFO] dpid=0000000000000004: [port=1] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000004: [port=2] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000004: [port=3] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: Join as stp bridge.
[STP][INFO] dpid=0000000000000004: [port=4] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=1] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=2] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=3] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=4] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=5] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000003: Join as stp bridge.
[STP][INFO] dpid=0000000000000002: [port=6] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000003: [port=1] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000003: [port=2] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000003: [port=3] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000001: Join as stp bridge.
[STP][INFO] dpid=0000000000000003: [port=4] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000001: [port=1] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000001: [port=2] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000001: [port=3] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000001: [port=4] DESIGNATED_PORT / LISTEN
[STP][INFO] dpid=0000000000000002: [port=1] Receive superior BPDU.
(以下略)

この時点ではまだpingallを実行しても到達性は確認できません。

mininet> pingall
*** Ping: testing ping reachability
h1 -> X X ^C
Interrupt
stopping h1

しばらくすると、STPのコンバージェンスが始まったようです。LEARNING状態に入りました。

[STP][INFO] dpid=0000000000000001: [port=1] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000001: [port=2] ROOT_PORT / LEARN
[STP][INFO] dpid=0000000000000001: [port=3] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000001: [port=4] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000004: [port=1] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000004: [port=2] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000004: [port=3] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000004: [port=4] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000003: [port=1] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000003: [port=2] ROOT_PORT / LEARN
[STP][INFO] dpid=0000000000000003: [port=3] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000003: [port=4] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=1] ROOT_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=2] NON_DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=3] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=4] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=5] DESIGNATED_PORT / LEARN
[STP][INFO] dpid=0000000000000002: [port=6] DESIGNATED_PORT / LEARN

その後、FORWARD/DISCARDが決定されたようです。

[STP][INFO] dpid=0000000000000001: [port=1] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000001: [port=2] ROOT_PORT / FORWARD
[STP][INFO] dpid=0000000000000001: [port=3] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000001: [port=4] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000004: [port=1] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000004: [port=2] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000004: [port=3] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000004: [port=4] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000003: [port=1] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000003: [port=2] ROOT_PORT / FORWARD
[STP][INFO] dpid=0000000000000003: [port=3] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000003: [port=4] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000002: [port=1] ROOT_PORT / FORWARD
[STP][INFO] dpid=0000000000000002: [port=2] NON_DESIGNATED_PORT / BLOCK
[STP][INFO] dpid=0000000000000002: [port=3] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000002: [port=4] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000002: [port=5] DESIGNATED_PORT / FORWARD
[STP][INFO] dpid=0000000000000002: [port=6] DESIGNATED_PORT / FORWARD

この状態でpingallを実行すると、ちゃんと疎通できました。

mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3 h4 h5 h6 h7 h8 h9 h10 
h2 -> h1 h3 h4 h5 h6 h7 h8 h9 h10 
h3 -> h1 h2 h4 h5 h6 h7 h8 h9 h10 
h4 -> h1 h2 h3 h5 h6 h7 h8 h9 h10 
h5 -> h1 h2 h3 h4 h6 h7 h8 h9 h10 
h6 -> h1 h2 h3 h4 h5 h7 h8 h9 h10 
h7 -> h1 h2 h3 h4 h5 h6 h8 h9 h10 
h8 -> h1 h2 h3 h4 h5 h6 h7 h9 h10 
h9 -> h1 h2 h3 h4 h5 h6 h7 h8 h10 
h10 -> h1 h2 h3 h4 h5 h6 h7 h8 h9 
*** Results: 0% dropped (90/90 received)
mininet>

まとめ

このように、ryu-manager側で呼び出すpyファイルを変えることで、スイッチに持たせる機能を変化させることができそうです。つまり、単一規格のスイッチにOpenFlowコントローラによる制御を実装することで、物理的にはおんなじスイッチが違う機能を有する・・・と言う真似ができるということを理解しました。

他にも色々サンプルがあるので遊んでみようかなとは思ってます。

-rw-r--r-- 1 root root 0 5月 9 15:36 __init__.py
-rw-r--r-- 1 root root 3647 5月 9 15:36 bmpstation.py
-rw-r--r-- 1 root root 1787 5月 9 15:36 cbench.py
-rw-r--r-- 1 root root 817 5月 9 15:36 conf_switch_key.py
-rw-r--r-- 1 root root 3903 5月 9 15:36 example_switch_13.py
-rw-r--r-- 1 root root 27324 5月 9 15:36 ofctl_rest.py
-rw-r--r-- 1 root root 5936 5月 9 15:36 rest_conf_switch.py
-rw-r--r-- 1 root root 38647 5月 9 15:36 rest_firewall.py
-rw-r--r-- 1 root root 40143 8月 30 05:42 rest_qos.py
-rw-r--r-- 1 root root 70965 5月 9 15:36 rest_router.py
-rw-r--r-- 1 root root 3967 5月 9 15:36 rest_topology.py
-rw-r--r-- 1 root root 55673 5月 9 15:36 rest_vtep.py
-rw-r--r-- 1 root root 4027 5月 9 15:36 simple_monitor_13.py
-rw-r--r-- 1 root root 3755 5月 9 15:36 simple_switch.py
-rw-r--r-- 1 root root 3294 5月 9 15:36 simple_switch_12.py
-rw-r--r-- 1 root root 4742 5月 9 15:36 simple_switch_13.py
-rw-r--r-- 1 root root 3916 5月 9 15:36 simple_switch_14.py
-rw-r--r-- 1 root root 3889 5月 9 15:36 simple_switch_igmp.py
-rw-r--r-- 1 root root 3350 5月 9 15:36 simple_switch_igmp_13.py
-rw-r--r-- 1 root root 4328 5月 9 15:36 simple_switch_lacp.py
-rw-r--r-- 1 root root 3877 5月 9 15:36 simple_switch_lacp_13.py
-rw-r--r-- 1 root root 4265 5月 9 15:36 simple_switch_rest_13.py
-rw-r--r-- 1 root root 4954 5月 9 15:36 simple_switch_snort.py
-rw-r--r-- 1 root root 4979 5月 9 15:36 simple_switch_stp.py
-rw-r--r-- 1 root root 4591 5月 9 15:36 simple_switch_stp_13.py
-rw-r--r-- 1 root root 3793 5月 9 15:36 simple_switch_websocket_13.py
-rw-r--r-- 1 root root 4384 5月 9 15:36 ws_topology.py
-rw-r--r-- 1 root root 10137 5月 9 15:36 wsgi.py

それにしてもコードが全然分からんす。開発なんて15年ぐらい前から全くやってないっすからね・・・・とほほ。もう少し直感的に理解できる仕組みに触れてみようかなと思っていて、その一つのOpenDaylightを触ってみようかなとか考えています。

徐々に理解深めていって、運用イメージを膨らませてみようかなーと思っています。

取り敢えず言えることは「OpenFlowって面白い!」ってことかなぁ。

Tags:

Comments are closed

PAGE TOP