OpenFlow1.3 and ryu controller in GNS3

Posted on 2013/11/16(Sat) 22:42 in technical

冒頭

逆立ちするOPで一時停止しようとする奴は信用できる。

コホン、さて。

先日、openvswitch-2.0.0のインストールが出来た ので、やっぱり流行に流されてOpenFlow 1.3が動きそうな雰囲気位は味わっておこうと思う。

そこで、可視化部分をGNS3にお願いして、簡単な構成でOpenFlow Controllerを使った通信をしてみようと思う。

構成はこんな感じ。

l3_hairpin_topology.png

では、れっつごー。

状況説明

  • Router : BSDRP 1.4 on VirtualBox
  • node-01 : BSDRP 1.4 on VirtualBox
  • node-02 : BSDRP 1.4 on VirtualBox
  • ovs-01 : Ubuntu-12.04.3 + openvswitch-2.0.0 on VirtualBox
  • SDN_Controller : Ubuntu-12.04.3 + ryu-3.3 on VirtualBox

RouterはVLANインタフェース10と20を切って、node-01とnode-02間をVLAN間ルーティングする感じ。

通報

VirtualBoxでe1000インタフェースとVLANの組み合わせが必要な場合は、VirtualBox 4.2以上にしましょう。

参考: https://blogs.oracle.com/fatbloke/entry/what_s_new_in_oracle

通報

VirtualBox 4.3以降は、vbox APIが変更になったので、GNS3のバージョンも上げる必要があります。

本記事中では、VirtualBox 4.3.2 + GNS 0.8.6の組み合わせで進行します。

全てのノードは、GNS3でVirtualBox設定画面で「Enable console support」「Start in headless mode(without GUI)」にチェックを入れておこう。

コピペするのが面倒だからね!

あとNICの数もとりあえず4個位に増やしておこうね!

BSDRPはほぼ素体のまま。今は最新で1.5が手に入ると思うが今回扱う範囲では同じだろう。

Ubuntuを使用する ovs-01, SDN_Controller の2つは、先ほどチェックしたシリアルサポートが無効になっているので、GNS3で起動する前にVirtualBoxを使ってUbuntuのヘルプページの通りに以下の設定を入れておきます。

https://help.ubuntu.com/community/SerialConsoleHowto

$ sudo vi /etc/init/ttyS0.conf
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc or RUNLEVEL=[12345]
stop on runlevel [!12345]

respawn
exec /sbin/getty -L 115200 ttyS0 vt102
$ sudo start ttyS0

それでは、GNS3で構成を組んで起動します。

設定

node-01

アドレスとDGWを設定するだけ。

# ifconfig em1 192.168.10.10/24
# route add default 192.168.10.1

node-02

アドレスとDGWを設定するだけ。

# ifconfig em1 192.168.20.10/24
# route add default 192.168.20.1

Router

VLANインタフェースを2個、IP Routingは最初からONになってる。あと、pingの違いを見分けるために、遅延を20ms程追加しておく。

# ifconfig vlan10 create
# ifconfig vlan10 vlan 10 vlandev em1
# ifconfig vlan10 192.168.10.1/24
# ifconfig vlan20 create
# ifconfig vlan20 vlan 20 vlandev em1
# ifconfig vlan20 192.168.20.1/24
# kldload ipfw
# kldload dummynet
# ipfw add 10 pipe 1 ip from any to any
# ipfw pipe 1 config delay 20ms
# ipfw add 65534 pass ip from any to any
# ipfw list
00010 pipe 1 ip from any to any
65534 allow ip from any to any
65535 deny ip from any to any
# ipfw pipe show
00001: unlimited        20 ms burst 0
q131073  50 sl. 0 flows (1 buckets) sched 65537 weight 0 lmax 0 pri 0 droptail
 sched 65537 type FIFO flags 0x0 0 buckets 0 active

SDN_Controller

Ubuntu-12.04.3をインストールしてシリアルサポートの設定を入れた後からスタートですよ、っと。

ryuのインストールもサクッとやりましょう。

後々ryuのバージョンを変えることもあるかもしれないので、virtualenvで環境を分けてしまいましょう。

$ sudo ip add add 192.168.56.11/24 dev eth1
$ sudo apt-get install python-virtualenv
$ virtualenv ryu
$ source ryu/bin/activate
(ryu)$ sudo apt-get install gcc python-dev
(ryu)$ pip install ryu
(ryu)$ ryu-manager ./ryu/lib/python2.7/site-packages/ryu/app/simple_switch_13.py

ovs-01

前回インストール した後、Serialサポートの設定を入れた後からスタートですよ、っと。

$ sudo ip add add 192.168.56.31/24 dev eth1
$ sudo ovs-vsctl add-br ovs-01
$ sudo ovs-vsctl add-port ovs-01 eth2
$ sudo ovs-vsctl add-port ovs-01 eth3
$ sudo ip link set up eth2
$ sudo ip link set up eth3
$ sudo ovs-vsctl get bridge ovs-01 datapath-id
$ sudo ovs-vsctl set bridge ovs-01 protocols=OpenFlow13
$ sudo ovs-vsctl set-controller ovs-01 tcp:192.168.56.11
$ sudo ovs-vsctl show
cf7b4728-6c31-4e90-af6d-6b7ac60b0844
    Bridge "ovs-01"
        Controller "tcp:192.168.56.11"
            is_connected: true
        Port "ovs-01"
            Interface "ovs-01"
                type: internal
        Port "eth2"
            Interface "eth2"
        Port "eth3"
            Interface "eth3"
    ovs_version: "2.0.0"

動作チェック

ovs-01

$ sudo tcpdump -n -i eth1 -s 1600 -w ovs-01_eth1.pcap

node-01

# ping -c 10 192.168.20.10
PING 192.168.20.10 (192.168.20.10): 56 data bytes
64 bytes from 192.168.20.10: icmp_seq=0 ttl=63 time=171.512 ms
64 bytes from 192.168.20.10: icmp_seq=1 ttl=63 time=72.741 ms
64 bytes from 192.168.20.10: icmp_seq=2 ttl=63 time=73.386 ms
64 bytes from 192.168.20.10: icmp_seq=3 ttl=63 time=72.073 ms
64 bytes from 192.168.20.10: icmp_seq=4 ttl=63 time=72.223 ms
64 bytes from 192.168.20.10: icmp_seq=5 ttl=63 time=71.912 ms
64 bytes from 192.168.20.10: icmp_seq=6 ttl=63 time=72.251 ms
64 bytes from 192.168.20.10: icmp_seq=7 ttl=63 time=72.152 ms
64 bytes from 192.168.20.10: icmp_seq=8 ttl=63 time=72.172 ms
64 bytes from 192.168.20.10: icmp_seq=9 ttl=63 time=72.958 ms

--- 192.168.20.10 ping statistics ---
10 packets transmitted, 10 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 71.912/82.338/171.512/29.728 ms

で、ovs-01のtcpdumpは止めてしまって、フローエントリを確認してみましょう。

$ sudo ovs-ofctl dump-flows ovs-01 --protocol=OpenFlow13
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x0, duration=148.046s, table=0, n_packets=14, n_bytes=1314, priority=0 actions=CONTROLLER:65535
 cookie=0x0, duration=105.104s, table=0, n_packets=10, n_bytes=984, priority=1,in_port=2,dl_dst=08:00:27:09:97:35 actions=output:1
 cookie=0x0, duration=105.062s, table=0, n_packets=20, n_bytes=1934, priority=1,in_port=1,dl_dst=08:00:27:2d:12:0b actions=output:2
$ sudo ovs-ofctl dump-ports-desc ovs-01 --protocol=OpenFlow13
OFPST_PORT_DESC reply (OF1.3) (xid=0x2):
 1(eth2): addr:08:00:27:83:fe:03
     config:     0
     state:      0
     current:    1GB-FD COPPER AUTO_NEG
     advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     supported:  10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     speed: 1000 Mbps now, 1000 Mbps max
 2(eth3): addr:08:00:27:36:f4:3e
     config:     0
     state:      0
     current:    1GB-FD COPPER AUTO_NEG
     advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     supported:  10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG
     speed: 1000 Mbps now, 1000 Mbps max
 LOCAL(ovs-01): addr:08:00:27:36:f4:3e
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max

OpenFlow 1.3から、どのエントリにも一致しなかったパケットはpacket-inしないで破棄される、ということなので、一番上の"actions=CONTROLLER:65535"が追加されている。

下の2行は、宛先MACアドレスと出力ポートの関係を設定して、一般的なL2SWの処理をしている。

ちなみに、pingが流れている状態でそのパケットがどういうエントリと関連があったか、ということも見ることが出来る。

$ sudo ovs-appctl dpif/dump-flows ovs-01
skb_priority(0),in_port(2),eth(src=08:00:27:ae:5f:d5,dst=08:00:27:2d:12:0b),eth_type(0x8100),encap(eth_type(0x0800),ipv4(src=192.168.20.10/255.255.255.255,dst=192.168.10.10/255.255.255.255,proto=1/0xff,tos=0/0,ttl=64/0,frag=no/0xff),icmp(type=0,code=0)), packets:0, bytes:0, used:0.839s, actions:3
skb_priority(0),in_port(2),eth(src=08:00:27:09:97:35,dst=08:00:27:2d:12:0b),eth_type(0x8100),encap(eth_type(0x0800),ipv4(src=192.168.10.10/255.255.255.255,dst=192.168.20.10/255.255.255.255,proto=1/0xff,tos=0/0,ttl=64/0,frag=no/0xff),icmp(type=8,code=0)), packets:0, bytes:0, used:0.883s, actions:3
skb_priority(0),in_port(3),eth(src=08:00:27:2d:12:0b,dst=08:00:27:09:97:35),eth_type(0x8100),encap(eth_type(0x0800),ipv4(src=192.168.20.10/255.255.255.255,dst=192.168.10.10/255.255.255.255,proto=1/0xff,tos=0/0,ttl=63/0,frag=no/0xff),icmp(type=0,code=0)), packets:0, bytes:0, used:0.800s, actions:2
skb_priority(0),in_port(3),eth(src=08:00:27:2d:12:0b,dst=08:00:27:ae:5f:d5),eth_type(0x8100),encap(eth_type(0x0800),ipv4(src=192.168.10.10/255.255.255.255,dst=192.168.20.10/255.255.255.255,proto=1/0xff,tos=0/0,ttl=63/0,frag=no/0xff),icmp(type=8,code=0)), packets:0, bytes:0, used:0.849s, actions:userspace(pid=4294963133,slow_path(controller))

おしまい

とりあえずOpenFlow 1.3での動作もできそうだ、と言うところで一旦おしまい。

今回取得したキャプチャファイルは https://www.ainoniwa.net/data/pcap/GNS3_openflow13_01/ovs-01_eth1.pcap からダウンロードできたりします。

おわり。