« ◆ 【Open vSwitchのみで OpenFlowプログラミング】VLAN ID コンバータ 改 | トップページ | ◆ OpenFlowフレームワーク Trema 0.4 のインストール »

2013年8月10日 (土)

◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク: STP(Spanning Tree Protocol)

Open vSwitch のスパニングツリープロトコル(Spanning Tree Protocol, STP)を有効にして動かしてみました。

動作確認環境:
   OS: Lubuntu 13.04 Desktop (i386)
   Open vSwitch: 1.9.0

■今回作成した仮想ネットワークの構成図

2台のスイッチが2本の線でつながっており、ループしている状態にしています。

Photo
念のため、ovs-vsctl show で確認してみます:

$ sudo ovs-vsctl show
dc50ed1a-4dd2-4169-89d3-fbe717480a70
    Bridge "vswitch1"
        Port "vlink1"
            Interface "vlink1"
        Port "vlinkSW1-0"
            Interface "vlinkSW1-0"
        Port "vlinkSW2-1"
            Interface "vlinkSW2-1"
        Port "vswitch1"
            Interface "vswitch1"
                type: internal
    Bridge "vswitch2"
        Port "vlinkSW2-0"
            Interface "vlinkSW2-0"
        Port "vlink2"
            Interface "vlink2"
        Port "vswitch2"
            Interface "vswitch2"
                type: internal
        Port "vlinkSW1-1"
            Interface "vlinkSW1-1"
    ovs_version: "1.9.0"

■動作テスト

(1) ネットワークを作成後、すぐに、vhost1 から vhost2(192.168.0.2) へ ping

ping に -D オプションをつけてタイムスタンプを出力するようにしてみました。最初に通信ができるようになるまで30秒弱かかっています。

$ sudo ip netns exec vhost1 ping -D 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
[1376076296.379297] From 192.168.0.1 icmp_seq=1 Destination Host Unreachable
[1376076296.379366] From 192.168.0.1 icmp_seq=2 Destination Host Unreachable
[1376076296.379376] From 192.168.0.1 icmp_seq=3 Destination Host Unreachable
[1376076299.379759] From 192.168.0.1 icmp_seq=4 Destination Host Unreachable
[1376076299.379797] From 192.168.0.1 icmp_seq=5 Destination Host Unreachable
[1376076299.379806] From 192.168.0.1 icmp_seq=6 Destination Host Unreachable
[1376076302.391493] From 192.168.0.1 icmp_seq=7 Destination Host Unreachable
[1376076302.391527] From 192.168.0.1 icmp_seq=8 Destination Host Unreachable
[1376076302.391535] From 192.168.0.1 icmp_seq=9 Destination Host Unreachable
   略
[1376076317.404299] From 192.168.0.1 icmp_seq=22 Destination Host Unreachable
[1376076317.404333] From 192.168.0.1 icmp_seq=23 Destination Host Unreachable
[1376076317.404342] From 192.168.0.1 icmp_seq=24 Destination Host Unreachable
[1376076320.404558] From 192.168.0.1 icmp_seq=25 Destination Host Unreachable
[1376076320.404599] From 192.168.0.1 icmp_seq=26 Destination Host Unreachable
[1376076320.404613] From 192.168.0.1 icmp_seq=27 Destination Host Unreachable
[1376076322.405310] 64 bytes from 192.168.0.2: icmp_req=28 ttl=64 time=2000 ms
[1376076322.405340] 64 bytes from 192.168.0.2: icmp_req=29 ttl=64 time=1000 ms
[1376076322.405348] 64 bytes from 192.168.0.2: icmp_req=30 ttl=64 time=0.664 ms
[1376076323.404743] 64 bytes from 192.168.0.2: icmp_req=31 ttl=64 time=0.068 ms
[1376076324.404754] 64 bytes from 192.168.0.2: icmp_req=32 ttl=64 time=0.073 ms
^C
--- 192.168.0.2 ping statistics ---
32 packets transmitted, 5 received, +27 errors, 84% packet loss, time 31023ms
rtt min/avg/max/mdev = 0.068/600.459/2000.704/800.205 ms, pipe 4

(2) ブロックされているポートの確認

Open vSwitch の Port テーブルのカラム status で状態が確認できます。出力カラムを name と status だけに絞ると出力したの以下の結果です。
今回のテストでは、vlinkSW1-0 のポートがブロックされていることが確認できます。

$ sudo ovs-vsctl -- --columns=name,status list Port
name                : "vlinkSW2-0"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="433", stp_state=forwarding}

name                : "vlink1"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="433", stp_state=forwarding}

name                : "vlinkSW2-1"
status              : {stp_port_id="8002", stp_role=root, stp_sec_in_state="433", stp_state=forwarding}

name                : "vlink2"
status              : {stp_port_id="8003", stp_role=designated, stp_sec_in_state="433", stp_state=forwarding}

name                : "vswitch1"
status              : {}

name                : "vlinkSW1-0"
status              : {stp_port_id="8003", stp_role=alternate, stp_sec_in_state="462", stp_state=blocking}

name                : "vlinkSW1-1"
status              : {stp_port_id="8002", stp_role=designated, stp_sec_in_state="433", stp_state=forwarding}

name                : "vswitch2"
status              : {}

(3) 切断してみる

上記で確認した結果から、vlinkSW2-0 と vlinkSW2-1 の間で通信がされていることが分かるのでこの通信を切断し、vlinkSW1-0 のブロックが解除されて vlinkSW1-0 と vlinkSW1-1 の間の通信が回復することを確認してみます。

ping を実行中に以下のコマンドでインタフェースをダウンさせて通信を切断します:

$ sudo ifconfig vlinkSW2-0 down

以下、ping の結果。回復までに約50秒かかっています。

$ sudo ip netns exec vhost1 ping -D 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
[1376077074.541945] 64 bytes from 192.168.0.2: icmp_req=1 ttl=64 time=0.714 ms
[1376077075.543771] 64 bytes from 192.168.0.2: icmp_req=2 ttl=64 time=0.071 ms
[1376077076.543824] 64 bytes from 192.168.0.2: icmp_req=3 ttl=64 time=0.063 ms
[1376077125.551195] From 192.168.0.1 icmp_seq=49 Destination Host Unreachable
[1376077125.551250] From 192.168.0.1 icmp_seq=50 Destination Host Unreachable
[1376077125.551258] From 192.168.0.1 icmp_seq=51 Destination Host Unreachable
[1376077125.552571] 64 bytes from 192.168.0.2: icmp_req=52 ttl=64 time=0.664 ms
[1376077126.555236] 64 bytes from 192.168.0.2: icmp_req=53 ttl=64 time=0.060 ms
[1376077127.555274] 64 bytes from 192.168.0.2: icmp_req=54 ttl=64 time=0.060 ms
[1376077128.555355] 64 bytes from 192.168.0.2: icmp_req=55 ttl=64 time=0.074 ms
[1376077129.555414] 64 bytes from 192.168.0.2: icmp_req=56 ttl=64 time=0.058 ms
^C
--- 192.168.0.2 ping statistics ---
56 packets transmitted, 8 received, +3 errors, 85% packet loss, time 55015ms
rtt min/avg/max/mdev = 0.058/0.220/0.714/0.271 ms, pipe 3

(4) ポートのステータス確認

vlinkSW1-0 のブロック状態が解除されていることが確認できます:

$ sudo ip netns exec vsudo ovs-vsctl -- --columns=name,status list Port
name                : "vlinkSW2-0"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="1175", stp_state=forwarding}

name                : "vlink1"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="1175", stp_state=forwarding}

name                : "vlinkSW2-1"
status              : {stp_port_id="8002", stp_role=designated, stp_sec_in_state="1175", stp_state=forwarding}

name                : "vlink2"
status              : {stp_port_id="8003", stp_role=designated, stp_sec_in_state="1175", stp_state=forwarding}

name                : "vswitch1"
status              : {}

name                : "vlinkSW1-0"
status              : {stp_port_id="8003", stp_role=root, stp_sec_in_state="372", stp_state=forwarding}

name                : "vlinkSW1-1"
status              : {stp_port_id="8002", stp_role=designated, stp_sec_in_state="1175", stp_state=forwarding}

name                : "vswitch2"
status              : {}

(5) 停止したインタフェースを回復させる

先ほど停止したインタフェースを回復させるとどうなるでしょう?
ping 実行中に以下のコマンドで復活させます:

$ sudo ifconfig vlinkSW2-0 up

回復したときに、少しもたつきます:

$ sudo ip netns exec vhost1 ping -D 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
[1376077760.643086] 64 bytes from 192.168.0.2: icmp_req=1 ttl=64 time=0.049 ms
[1376077761.642098] 64 bytes from 192.168.0.2: icmp_req=2 ttl=64 time=0.057 ms
[1376077762.643821] 64 bytes from 192.168.0.2: icmp_req=3 ttl=64 time=0.057 ms
[1376077763.645079] 64 bytes from 192.168.0.2: icmp_req=4 ttl=64 time=0.076 ms
[1376077764.645113] 64 bytes from 192.168.0.2: icmp_req=5 ttl=64 time=0.078 ms
[1376077765.645305] 64 bytes from 192.168.0.2: icmp_req=6 ttl=64 time=0.072 ms
[1376077766.689862] 64 bytes from 192.168.0.2: icmp_req=7 ttl=64 time=9.23 ms
[1376077767.853087] 64 bytes from 192.168.0.2: icmp_req=8 ttl=64 time=10.1 ms

[1376077768.669838] 64 bytes from 192.168.0.2: icmp_req=9 ttl=64 time=0.328 ms
[1376077769.668223] 64 bytes from 192.168.0.2: icmp_req=10 ttl=64 time=0.122 ms
[1376077770.667189] 64 bytes from 192.168.0.2: icmp_req=11 ttl=64 time=0.092 ms
[1376077771.666140] 64 bytes from 192.168.0.2: icmp_req=12 ttl=64 time=0.054 ms
[1376077772.666320] 64 bytes from 192.168.0.2: icmp_req=13 ttl=64 time=0.113 ms
[1376077773.666751] 64 bytes from 192.168.0.2: icmp_req=14 ttl=64 time=0.065 ms
^C
--- 192.168.0.2 ping statistics ---
14 packets transmitted, 14 received, 0% packet loss, time 13023ms
rtt min/avg/max/mdev = 0.049/1.470/10.194/3.371 ms

(6) ポートのステータス確認

再び vlinkSW1-0 がブロックされていました:

$ sudo ovs-vsctl -- --columns=name,status list Port
name                : "vlinkSW2-0"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="1777", stp_state=forwarding}

name                : "vlink1"
status              : {stp_port_id="8001", stp_role=designated, stp_sec_in_state="1777", stp_state=forwarding}

name                : "vlinkSW2-1"
status              : {stp_port_id="8002", stp_role=root, stp_sec_in_state="1777", stp_state=forwarding}

name                : "vlink2"
status              : {stp_port_id="8003", stp_role=designated, stp_sec_in_state="1777", stp_state=forwarding}

name                : "vswitch1"
status              : {}

name                : "vlinkSW1-0"
status              : {stp_port_id="8003", stp_role=alternate, stp_sec_in_state="331", stp_state=blocking}

name                : "vlinkSW1-1"
status              : {stp_port_id="8002", stp_role=designated, stp_sec_in_state="1777", stp_state=forwarding}

name                : "vswitch2"
status              : {}

■今回の仮想ネットワークの作成・削除用シェルスクリプト

引数 delete で削除、add で追加です。
共通ファイル vnetcommon.sh がカレントディレクトリにおいてあることを前提としています。
赤字にしたところが STP を有効に設定している箇所です。

#!/bin/sh

. ./vnetcommon.sh

delete() {
    deleteVSwitch "vswitch1" "vswitch2"
    deleteVHost "vhost1" "vhost2"
}

add() {
    addVSwitch "vswitch1"
    sudo ovs-vsctl set Bridge "vswitch1" stp_enable=true

    addVSwitch "vswitch2"
    sudo ovs-vsctl set Bridge "vswitch2" stp_enable=true

    connectVSwitchToVSwitch "vswitch1" "vlinkSW1" "vswitch2"
    connectVSwitchToVSwitch "vswitch2" "vlinkSW2" "vswitch1"

    addVHost "vhost1"
    connectVHostToVSwitch "vhost1" "vlink1" "vswitch1"
    vhostExec "vhost1" ifconfig "vlink1" "192.168.0.1"

    addVHost "vhost2"
    connectVHostToVSwitch "vhost2" "vlink2" "vswitch2"
    vhostExec "vhost2" ifconfig "vlink2" "192.168.0.2"
}

case "$1" in
add)
    sudo sh -c exit
    set -x
    add
    ;;
delete)
    sudo sh -c exit
    delete > /dev/null 2>&1
    ;;
*)
    echo "usage: $0 { add | delete }"
esac

現時点の Open vSwitch の FAQ には STP はあまりテストしていないということが書いてあり使用はおすすめしないようです。

FAQ の URL: http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=openvswitch;a=blob_plain;f=FAQ;hb=HEAD

The Open vSwitch implementation of STP is not well tested. Please report any bugs you observe, but if you'd rather avoid acting as a beta tester then another option might be your best shot.

« ◆ 【Open vSwitchのみで OpenFlowプログラミング】VLAN ID コンバータ 改 | トップページ | ◆ OpenFlowフレームワーク Trema 0.4 のインストール »

Open vSwitch」カテゴリの記事

仮想ネットワーク」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1776113/52817017

この記事へのトラックバック一覧です: ◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク: STP(Spanning Tree Protocol):

« ◆ 【Open vSwitchのみで OpenFlowプログラミング】VLAN ID コンバータ 改 | トップページ | ◆ OpenFlowフレームワーク Trema 0.4 のインストール »

最近のトラックバック

無料ブログはココログ