paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

mininetのちょっとした外部Controller連携

正月休みに止まっていたSDN(openflow)の勉強をやろうと思いmininetと外部コントローラーの連携を行いました。

本当はryuを使って試してみたかったのですが、私のubuntuデスクトップ環境とは相性が良くないようで起動できず疲れて止めてしまっていました。
今は動くものを見ることが優先だと思いコントローラーの連携をやってみました。

mininet

SDNのシミュレータです。
お手軽に環境が作れて便利。私はVM版を使ってます。

Mininet: An Instant Virtual Network on Your Laptop (or Other PC) - Mininet

コントローラー(OpenDaylight)

今は沢山の種類がありますが今回は導入が簡単そうなOpenDaylightを使います。 openflowのテーブルを管理するコンポーネントです。

Home - OpenDaylight

環境

今回は旅行用に新しいノートPCを新調したのでこちらでちょっと試しました。

Windows10 + Virtualboxです。

VM

Virtualbox環境上です。

  • mininet
    • 公式配布のVM
  • コントローラー用ubuntu22.04
    • Vagrantで公式のboxをインストール
    • OpenDaylightインストール

どちらもホストオンリーアダプタで相互に接続できるネットワークになってます。

OpenDaylightのインストール

VMのバージョン。

vagrant@ubuntu-jammy:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
Codename:       jammy

OpenDaylightインストールは公式に沿って進めるだけ。
https://docs.opendaylight.org/en/latest/index.html#opendaylight-contributor-guides

しかし最新のものだとEquinoxのストレージがどうので起動しなかったので、ナレッジ記事を見てバージョンを落としました。
JAVA製アプリは意外と使った経験がないので勉強になります。

Install OpenDaylight on Ubuntu 22.04 LTS (All Features, Any Version)

OpenDaylight起動

インストール完了後は以下のコマンドで起動します。

vagrant@ubuntu-jammy:~$ cd karaf-0.8.4/
vagrant@ubuntu-jammy:~/karaf-0.8.4$
vagrant@ubuntu-jammy:~/karaf-0.8.4$ ./bin/karaf

Apache karafというプラットフォームを使っているらしいです。(詳しくは調べてません)
Apache Karaf - The Modulith Runtime

起動するとバナーが出てきます。
この時点でブラウザでアクセスできます。

vagrant@ubuntu-jammy:~$ cd karaf-0.8.4/
vagrant@ubuntu-jammy:~/karaf-0.8.4$
vagrant@ubuntu-jammy:~/karaf-0.8.4$ ./bin/karaf
Apache Karaf starting up. Press Enter to open the shell now...
 99% [=======================================================================>]                                         
    ________                       ________                .__  .__       .__     __
    \_____  \ ______   ____   ____ \______ \ _____  ___.__.|  | |__| ____ |  |___/  |_
     /   |   \\____ \_/ __ \ /    \ |    |  \\__  \<   |  ||  | |  |/ ___\|  |  \   __\
    /    |    \  |_> >  ___/|   |  \|    `   \/ __ \\___  ||  |_|  / /_/  >   Y  \  |
    \_______  /   __/ \___  >___|  /_______  (____  / ____||____/__\___  /|___|  /__|
            \/|__|        \/     \/        \/     \/\/            /_____/      \/


Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown OpenDaylight.

opendaylight-user@root>
opendaylight-user@root>version
4.1.6

このバージョンだとDLUXというモジュールが内包されていて管理画面として閲覧できるようです。

まだ真っ白。

mininet起動

mininetのVM情報は割愛します。
mininetからコントローラーを指定してmnで仮想ネットワークを起動します。

mininet@mininet-vm:~$ sudo mn --controller=remote,ip=192.168.56.10
*** Creating network
*** Adding controller
Connecting to remote controller at 192.168.56.10:6653
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
c0
*** Starting 1 switches
s1 ...
*** Starting CLI:

pingallで通信を発生させて、OpenDaylightを更新するとトポロジが表示されました。
自動で構成図作られて見れるの便利ですね。

テーブル、フロー確認

今回もコントローラーはデフォルトのままですが、通信が発生したのでmininet側でフロー等確認してみます。
h1 -> h2へのpingとhttpアクセス(HEAD)も合わせて実行しています。

  • dump-tables

OpenDaylightもデフォだと全て転送です。

mininet> dpctl dump-tables
*** s1 ------------------------------------------------------------------------
OFPST_TABLE reply (xid=0x2):
  table 0:
    active=4, lookup=8, matched=8
    max_entries=1000000
    matching:
      exact match or wildcard: in_port eth_{src,,type} vlan_{vid,pcp} ip_{src,dst} nw_{proto,tos} tcp_{src,dst}

  table 1:
    active=0, lookup=0, matched=0
    (same features)

  tables 2...253: ditto
  • dump-flow

mininetのコントローラーとは出力が違いますね。 ポート80番のアクセスログも出力されていません。
この辺はコントローラーの書き方の違いでしょうか。(こちらも中身は未チェック)

mininet> pingall
*** Ping: testing ping reachability
h1 -> X
h2 -> X
*** Results: 100% dropped (0/2 received)
mininet>
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2
h2 -> h1
*** Results: 0% dropped (2/2 received)
mininet>
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
 cookie=0x2b00000000000000, duration=11.569s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2a00000000000000, duration=2.945s, table=0, n_packets=0, n_bytes=0, idle_timeout=600, hard_timeout=300, priority=10,dl_src=7a:da:b8:bf:4a:dd,dl_dst=0e:93:63:fe:44:64 actions=output:"s1-eth2"
 cookie=0x2a00000000000001, duration=2.895s, table=0, n_packets=0, n_bytes=0, idle_timeout=600, hard_timeout=300, priority=10,dl_src=0e:93:63:fe:44:64,dl_dst=7a:da:b8:bf:4a:dd actions=output:"s1-eth1"
 cookie=0x2b00000000000000, duration=9.879s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth1" actions=output:"s1-eth2",CONTROLLER:65535
 cookie=0x2b00000000000001, duration=9.866s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth2" actions=output:"s1-eth1",CONTROLLER:65535
 cookie=0x2b00000000000000, duration=11.569s, table=0, n_packets=1, n_bytes=42, priority=0 actions=drop
mininet>
mininet> ping h1 h2
*** Unknown command: ping h1 h2
mininet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.527 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.071 ms
^C
--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3032ms
rtt min/avg/max/mdev = 0.064/0.186/0.527/0.196 ms
mininet>
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
 cookie=0x2b00000000000000, duration=32.569s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2a00000000000000, duration=23.945s, table=0, n_packets=5, n_bytes=434, idle_timeout=600, hard_timeout=300, priority=10,dl_src=7a:da:b8:bf:4a:dd,dl_dst=0e:93:63:fe:44:64 actions=output:"s1-eth2"
 cookie=0x2a00000000000001, duration=23.895s, table=0, n_packets=5, n_bytes=434, idle_timeout=600, hard_timeout=300, priority=10,dl_src=0e:93:63:fe:44:64,dl_dst=7a:da:b8:bf:4a:dd actions=output:"s1-eth1"
 cookie=0x2b00000000000000, duration=30.879s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth1" actions=output:"s1-eth2",CONTROLLER:65535
 cookie=0x2b00000000000001, duration=30.866s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth2" actions=output:"s1-eth1",CONTROLLER:65535
 cookie=0x2b00000000000000, duration=32.569s, table=0, n_packets=1, n_bytes=42, priority=0 actions=drop
mininet>
mininet> h2 python3 -m http.server 80 &
mininet>
mininet> h1 curl --spider h2
bash: curl: command not found
mininet> h1 wget --spider h2
Spider mode enabled. Check if remote file exists.
--2023-01-06 15:25:14--  http://10.0.0.2/
Connecting to 10.0.0.2:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1050 (1.0K) [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.

mininet>
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
 cookie=0x2b00000000000000, duration=76.878s, table=0, n_packets=0, n_bytes=0, priority=100,dl_type=0x88cc actions=CONTROLLER:65535
 cookie=0x2a00000000000000, duration=68.254s, table=0, n_packets=12, n_bytes=1016, idle_timeout=600, hard_timeout=300, priority=10,dl_src=7a:da:b8:bf:4a:dd,dl_dst=0e:93:63:fe:44:64 actions=output:"s1-eth2"
 cookie=0x2a00000000000001, duration=68.204s, table=0, n_packets=10, n_bytes=907, idle_timeout=600, hard_timeout=300, priority=10,dl_src=0e:93:63:fe:44:64,dl_dst=7a:da:b8:bf:4a:dd actions=output:"s1-eth1"
 cookie=0x2b00000000000000, duration=75.188s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth1" actions=output:"s1-eth2",CONTROLLER:65535
 cookie=0x2b00000000000001, duration=75.175s, table=0, n_packets=3, n_bytes=238, priority=2,in_port="s1-eth2" actions=output:"s1-eth1",CONTROLLER:65535
 cookie=0x2b00000000000000, duration=76.878s, table=0, n_packets=1, n_bytes=42, priority=0 actions=drop
mininet>

まとめ

今回はmininetのコントローラーを外部のものに指定して通信内容を見てみました。
パケットの転送は同じくできるもののflowsの出力結果が変わっているのが面白いですね。
コントローラーでどう処理するかの書き方でログの出し方も変わるのでしょうか。

次回はコントローラーの書き方を勉強しつつ少しいじってみたいと思います。