« 2013年4月 | トップページ | 2013年6月 »

2013年5月

2013年5月12日 (日)

◆ 【TremaでOpenFlowプログラミング】VLAN ID コンバータ

OpenFlow フレームワーク Trema を使って OpenFlow スイッチで VLAN ID を変換する機能を実装してみました。
テスト用の仮想ネットワークは、前回の記事で作った共通ファイル vnetcommon.sh を利用して Open vSwitch を VLAN スイッチと OpenFlow スイッチの両方で使った構成としています。

使用した環境: (前回の記事と同じです)
  OS: Lubuntu 12.04 Desktop (i386) (※ 13.04 ではありません)
  Trema: Trema 0.3.19

補足:
Open vSwitch のインストール方法は以下の記事の「■ステップ3. OpenVSwitch のインストール」を参照ください:
記事: 「2万円で OpenFlow スイッチを自作しよう」
http://ranosgrant.cocolog-nifty.com/blog/2013/02/2-openflow-4b98.html

■今回の仮想ネットワークの構成図
こんなストーリーを想定しています:
・2つの拠点があって、拠点ごとに別々に VLAN ID を管理していた。
・拠点1の VLAN ID 10, 20 の L2 ネットワークを拠点2 にも延ばす必要が生じた。
・しかし、拠点2 では VLAN ID 10, 20 は使えず、代わりに 拠点2 では LAN ID 30, 40 を割り当て、拠点間で VLAN ID を変換することにした。
・拠点1 の VLAN ID: 10 と 拠点2 の VLAN ID: 30 を接続する。
・拠点1 の VLAN ID: 20 と 拠点2 の VLAN ID: 40 を接続する。

Photo
■ 構成の確認
後述するシェルスクリプトで仮想ネットワークを作成したら OpenFlow ポートの1番が拠点1側、ポートの2番が拠点2側との接続となっていることを確認します。

$ sudo ovs-ofctl show ofs1
OFPT_FEATURES_REPLY (xid=0x1): ver:0x1, dpid:0000a67c7e48d940
n_tables:255, n_buffers:256
features: capabilities:0xc7, actions:0xfff
 1(vlinkSW1-1): addr:c6:9c:ee:c6:c9:15
     config:	 0
     state:	 0
     current:	 10GB-FD COPPER
 2(vlinkSW2-1): addr:46:d6:29:cd:8d:3f
     config:	 0
     state:	 0
     current:	 10GB-FD COPPER
 LOCAL(ofs1): addr:a6:7c:7e:48:d9:40
     config:	 PORT_DOWN
     state:	 LINK_DOWN
OFPT_GET_CONFIG_REPLY (xid=0x3): frags=normal miss_send_len=0

■ OpenFlow コントローラ
OpenFlow フレームワーク Trema を用いて VLAN ID コンバータを実装しています。ソースコードは以下:

class VLANIDConverter < Controller
  @conversion_table

  def start
    @convesion_table = [
      [ { :port => 1, :tag => 10 }, { :port => 2, :tag => 30 } ],
      [ { :port => 1, :tag => 20 }, { :port => 2, :tag => 40 } ]
    ]
  end

  def switch_ready( datapath_id )
    puts "switch #{ datapath_id.to_hex } is connected."
    @convesion_table.each do | each |
      flow_mod( datapath_id, each[0], each[1] )
      flow_mod( datapath_id, each[1], each[0] )
    end
    send_flow_mod_add( datapath_id, :priority => 100, :actions => [ ] )
  end

  def flow_mod( datapath_id, e1, e2 )
    send_flow_mod_add(
      datapath_id,
      :match => Match.new( :in_port => e1[ :port ] , :dl_vlan => e1[ :tag ] ),
      :actions => [
        SetVlanVid.new( e2[ :tag ] ),
        SendOutPort.new( e2[ :port ] )
      ]
    )
  end
end

やっていることを文字にすると以下の通り:
・ポート1(拠点1) から来た VLAN ID: 10 のパケットなら、VLAN ID を 30 にすげかえてポート2(拠点2)へ出力。
・ポート2(拠点2) から来た VLAN ID: 30 のパケットなら、VLAN ID を 10 にすげかえてポート1(拠点1)へ出力。
・ポート1(拠点1) から来た VLAN ID: 20 のパケットなら、VLAN ID を 40 にすげかえてポート2(拠点2)へ出力。
・ポート2(拠点2) から来た VLAN ID: 40 のパケットなら、VLAN ID を 20 にすげかえてポート1(拠点1)へ出力。
・上記に当てはまらないパケットが来たら破棄する。(すべてのパケットに合致するフローエントリですが優先度 priority を他のフローエントリより下げることで「上記に当てはまらない」という動きにしています。)

ソース中の @conversion_table を変更すれば異なる変換ルールにできます。

コントローラは仮想ネットワークを作成した後に、以下で起動します:
  trema run コントローラのソースコードのファイル

■ OpenFlow スイッチのフローテーブルの確認

$ sudo ovs-ofctl dump-flows ofs1
NXST_FLOW reply (xid=0x4):
 cookie=0x4, duration=22.022s, table=0, n_packets=0, n_bytes=0, priority=65535,in_port=2,dl_vlan=40 actions=mod_vlan_vid:20,output:1
 cookie=0x1, duration=22.022s, table=0, n_packets=0, n_bytes=0, priority=65535,in_port=1,dl_vlan=10 actions=mod_vlan_vid:30,output:2
 cookie=0x3, duration=22.022s, table=0, n_packets=0, n_bytes=0, priority=65535,in_port=1,dl_vlan=20 actions=mod_vlan_vid:40,output:2
 cookie=0x2, duration=22.022s, table=0, n_packets=0, n_bytes=0, priority=65535,in_port=2,dl_vlan=30 actions=mod_vlan_vid:10,output:1
 cookie=0x5, duration=22.022s, table=0, n_packets=0, n_bytes=0, priority=100 actions=drop

■ 動作確認
vhost1(192.168.0.1, 拠点1, VLAN ID: 10) から ping で vhost3(192.168.0.3, 拠点2, VLAN ID: 30) とのみ通信できることを確認:

$ sudo ip netns exec vhost1 ping -c2 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
From 192.168.0.1 icmp_seq=1 Destination Host Unreachable
From 192.168.0.1 icmp_seq=2 Destination Host Unreachable

--- 192.168.0.2 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1008ms
pipe 2

$ sudo ip netns exec vhost1 ping -c2 192.168.0.3 PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data. 64 bytes from 192.168.0.3: icmp_req=1 ttl=64 time=1.13 ms 64 bytes from 192.168.0.3: icmp_req=2 ttl=64 time=0.160 ms --- 192.168.0.3 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.160/0.649/1.138/0.489 ms $ sudo ip netns exec vhost1 ping -c2 192.168.0.4 PING 192.168.0.4 (192.168.0.4) 56(84) bytes of data. From 192.168.0.1 icmp_seq=1 Destination Host Unreachable From 192.168.0.1 icmp_seq=2 Destination Host Unreachable --- 192.168.0.4 ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1007ms pipe 2

vhost2(192.168.0.2, 拠点1, VLAN ID: 20) から ping で vhost4(192.168.0.4, 拠点2, VLAN ID: 40) とのみ通信できることを確認:

$ sudo ip netns exec vhost2 ping -c2 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
From 192.168.0.2 icmp_seq=1 Destination Host Unreachable
From 192.168.0.2 icmp_seq=2 Destination Host Unreachable

--- 192.168.0.1 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1008ms
pipe 2

$ sudo ip netns exec vhost2 ping -c2 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
From 192.168.0.2 icmp_seq=1 Destination Host Unreachable
From 192.168.0.2 icmp_seq=2 Destination Host Unreachable

--- 192.168.0.3 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1008ms
pipe 2

$ sudo ip netns exec vhost2 ping -c2 192.168.0.4
PING 192.168.0.4 (192.168.0.4) 56(84) bytes of data.
64 bytes from 192.168.0.4: icmp_req=1 ttl=64 time=1.05 ms
64 bytes from 192.168.0.4: icmp_req=2 ttl=64 time=0.153 ms

--- 192.168.0.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.153/0.605/1.058/0.453 ms

■今回の仮想ネットワークの作成・削除シェルスクリプト
引数 delete で削除、add で追加です。
共通ファイル vnetcommon.sh がカレントディレクトリにおいてあることを前提としています。

#!/bin/sh
. ./vnetcommon.sh

delete() {
    deleteVSwitch "ofs1" "vswitch1" "vswitch2"
    deleteVLink "vlinkSW1" "vlinkSW2"
    deleteVHost "vhost1" "vhost2" "vhost3" "vhost4"
    deleteVLink "vlink1" "vlink2" "vlink3" "vlink4"
}

add() {
    addOFSwitch "ofs1"
    addVSwitch "vswitch1"
    addVSwitch "vswitch2"
    connectVSwitchToVSwitch "vswitch1" "vlinkSW1" "ofs1"
    connectVSwitchToVSwitch "vswitch2" "vlinkSW2" "ofs1"

    addVHost "vhost1"
    connectVHostToVSwitch "vhost1" "vlink1" "vswitch1" tag=10
    vhostExec "vhost1" ifconfig "vlink1" "192.168.0.1"

    addVHost "vhost2"
    connectVHostToVSwitch "vhost2" "vlink2" "vswitch1" tag=20
    vhostExec "vhost2" ifconfig "vlink2" "192.168.0.2"

    addVHost "vhost3"
    connectVHostToVSwitch "vhost3" "vlink3" "vswitch2" tag=30
    vhostExec "vhost3" ifconfig "vlink3" "192.168.0.3"

    addVHost "vhost4"
    connectVHostToVSwitch "vhost4" "vlink4" "vswitch2" tag=40
    vhostExec "vhost4" ifconfig "vlink4" "192.168.0.4"
}

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

vnetcommon.sh のコードは、前回記事の末尾を参照ください。

2013年5月11日 (土)

◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク(OpenFlowスイッチとTrema)

今回は、Open vSwitch を OpenFlow スイッチとして使ってみました。OpenFlow コントローラは、OpenFlow フレームワーク Trema を使い OpenFlow スイッチをリピーターハブとして動かしています。

今回の構成程度だと、Trema の仮想ネットワーク機能を使った方がお手軽です。ですが、このシェルスクリプトを用いた方法では今までの記事で書いてきたように VLAN や仮想ルータ、仮想スイッチを組み合わせることができるのでTrema の仮想ネットワークよりも色々なネットワーク構成が可能です。

使用した環境:
  OS: Lubuntu 12.04 Desktop (i386) (※ 13.04 ではありません)
  Trema: Trema 0.3.19

■今回作成した仮想ネットワークの構成図
2つの OpenFlow スイッチにそれぞれ1つ仮想ホストをつないだだけの簡単な構成です。
図には書いていませんが、各 OpenFlow スイッチはローカルループバック 127.0.0.1 経由で OpenFlow フレームワーク Trema と接続します。
Photo_5

仮想ホストで使うインターフェース名は、仮想スイッチ側のインターフェース名と同じ名前を使うようにしました。仮想ホスト側は独自の名前空間なのでこういうことができます。

■OpenFlowコントローラ

OpenFlow フレームワーク Trema で、OpenFlow スイッチをリピーターハブとして動作させるコントローラを動かします。ソースコードは以下:

class RepetaerHub < Controller
  def switch_ready( datapath_id )
    puts "switch #{ datapath_id.to_hex } is connected."
    send_flow_mod_add( datapath_id, :actions => SendOutPort.new( OFPP_FLOOD ))
  end
end

コントローラは仮想ネットワークを作成した後に、以下で起動します:
  trema run コントローラのソースコードのファイル

■構成の確認
OpenFlow ポートの1番が OpenFlow スイッチ間の接続、2番が仮想マシンとの接続となっていることを確認します。

vswitch1 の OpenFlow スイッチとしての情報:

$ sudo ovs-ofctl show vswitch1
OFPT_FEATURES_REPLY (xid=0x1): ver:0x1, dpid:0000000000000001
n_tables:255, n_buffers:256
features: capabilities:0xc7, actions:0xfff
1(vlinkSW1-0): addr:9a:51:e2:54:c1:69
     config:     0
     state:      0
     current:    10GB-FD COPPER
2(vlink1): addr:86:98:54:0d:32:08
     config:     0
     state:      0
     current:    10GB-FD COPPER
LOCAL(vswitch1): addr:66:40:c5:44:72:41
     config:     PORT_DOWN
     state:      LINK_DOWN
OFPT_GET_CONFIG_REPLY (xid=0x3): frags=normal miss_send_len=0

vswitch2 の OpenFlow スイッチとしての情報:

$ sudo ovs-ofctl show vswitch2
OFPT_FEATURES_REPLY (xid=0x1): ver:0x1, dpid:00008a25a0cdf842
n_tables:255, n_buffers:256
features: capabilities:0xc7, actions:0xfff
1(vlinkSW1-1): addr:1a:71:45:3a:ec:32
     config:     0
     state:      0
     current:    10GB-FD COPPER
2(vlink2): addr:7a:f8:28:27:67:f7
     config:     0
     state:      0
     current:    10GB-FD COPPER
LOCAL(vswitch2): addr:8a:25:a0:cd:f8:42
     config:     PORT_DOWN
     state:      LINK_DOWN
OFPT_GET_CONFIG_REPLY (xid=0x3): frags=normal miss_send_len=0

■ OpenFlow スイッチのフローテーブルの確認

vswitch1 のフローテーブル:

$ sudo ovs-ofctl dump-flows vswitch1
NXST_FLOW reply (xid=0x4):
cookie=0x1, duration=113.232s, table=0, n_packets=0, n_bytes=0, priority=65535 actions=FLOOD

vswitch2 のフローテーブル:

$ sudo ovs-ofctl dump-flows vswitch2
NXST_FLOW reply (xid=0x4):
cookie=0x1, duration=121.102s, table=0, n_packets=0, n_bytes=0, priority=65535 actions=FLOOD

■動作確認
vhost1 から ping で vhost2(192.168.0.2)へ通信できることを確認:

$ sudo ip netns exec vhost1 ping -c 3 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_req=1 ttl=64 time=3.12 ms
64 bytes from 192.168.0.2: icmp_req=2 ttl=64 time=0.196 ms
64 bytes from 192.168.0.2: icmp_req=3 ttl=64 time=0.096 ms

--- 192.168.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.096/1.140/3.128/1.406 ms

■今回の仮想ネットワークの作成・削除シェルスクリプト
引数 delete で削除、add で追加です。
今までのシェルスクリプトの経験から関数化して他でも使える共通部分を別ファイル vnetcommon.sh に分離しました。共通部分のファイル vnetcommon.sh はカレントディレクトリにおいてあることを前提としています。

#!/bin/sh
. ./vnetcommon.sh

delete() {
    deleteVSwitch "vswitch1" "vswitch2"
    deleteVLink "vlinkSW1"
    deleteVHost "vhost1" "vhost2"
    deleteVLink "vlink1" "vlink2"
}

add() {
    addOFSwitch "vswitch1" "0x1"
    addOFSwitch "vswitch2"
    connectVSwitchToVSwitch "vswitch1" "vlinkSW1" "vswitch2"

    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

上記で、「sudo sh -c exit」と一見無意味なことをしているのは事前に sudo のパスワード入力を済ませたかったからです。

共通ファイル vnetcommon.sh の内容は以下:

deleteVHost() {
   local host
   for host in "$@"; do
       sudo ip netns delete "$host"
   done
}

deleteVSwitch() {
   local switch
   for switch in "$@"; do
       sudo ovs-vsctl del-br "$switch"
   done
}

deleteVLink() {
   local link
   for link in "$@"; do
       sudo ip link delete "$link"
       sudo ip link delete "${link}-0"
       sudo ip link delete "${link}-1"
   done
}

addVHost() {
    local host="$1"
    sudo ip netns add "$host"
    sudo ip netns exec "$host" ifconfig lo 127.0.0.1
}

addVSwitch() {
    local switch="$1"
    sudo ovs-vsctl add-br "$switch"
}

setupVSwitchAsOpenFlowSwitch() {
    local switch="$1"
    local datapath_id="$2"

    if [ "$datapath_id" != "" ]; then
        sudo ovs-vsctl set bridge "$switch" other-config:datapath-id=`printf \"%016x\" $datapath_id`
    fi
    sudo ovs-vsctl set-fail-mode "$switch" secure
    sudo ovs-vsctl set-controller "$switch" tcp:127.0.0.1 -- \
        set controller "$switch" connection-mode=out-of-band -- \
        set controller "$switch" inactivity-probe=180 -- \
        set controller "$switch" controller-rate-limit=40000 -- \
        set controller "$switch" controller-burst-limit=20000
}

addOFSwitch() {
    addVSwitch "$1"
    setupVSwitchAsOpenFlowSwitch "$1" "$2"
}

connectVSwitchToVSwitch() {
    local switch1="$1"
    local link="$2"
    local switch2="$3"

    sudo ip link add name "${link}-0" type veth peer name "${link}-1"

    sudo ip link set "${link}-0" up
    sudo ovs-vsctl add-port "$switch1" "${link}-0"

    sudo ip link set "${link}-1" up
    sudo ovs-vsctl add-port "$switch2" "${link}-1"
}

connectVHostToVSwitch() {
    local host="$1"
    local link="$2"
    local switch="$3"
    local opt="$4"

    sudo ip link add name "${link}" type veth peer name "${link}-1"

    sudo ip link set "${link}-1" netns "$host"
    sudo ip netns exec "$host" ip link set "${link}-1" name "${link}"
    sudo ip netns exec "$host" ifconfig "${link}" up

    sudo ip link set "${link}" up
    sudo ovs-vsctl add-port "$switch" "${link}" $opt
}

vhostExec() {
    sudo ip netns exec "$@"
}

OpenFlow スイッチとしてのオプションは、Trema が内部的に使っているユーザースペース版 Open vSwitch の起動オプションを参考にしています。
『OpenFlow実践入門』(初版 P.195) 「仮想スイッチ」に記載されているコマンドラインオプションを参考にさせていただきました。

addOFSwitch 関数の第2引数は datapath_id ですが、省略可能です。

2013年5月 8日 (水)

◆ OpenFlow 1.0.0 メッセージと Trema API(Ruby) との対応表

OpenFlow 1.0.0 メッセージとOpenFlowフレームワーク Trema の Ruby API との対応をまとめてみました。OpenFlow 1.0.0 の仕様を読んでから Trema で実装したいけどどうすればできるんだろう、とよく悩むことがあったので整理しました。
Trema のメソッド名、クラス名の箇所には Trema API のページへのリンクを埋め込んであります。



本記事の作成においては、http://rubydoc.info/github/trema/trema/master/file/README.md にて gem version 0.3.19 と表示され、かつ、同ページ下部に「Generated on Wed May  1 04:44:45 2013」と出ているものを参照しています。
今後のエンハンスで変更されるかもしれません。

2013年5月 6日 (月)

◆ OpenFlow 1.0.0 メッセージ一覧

『次世代ネットワーク制御技術 OpenFlow入門』(発行 アスキー・メディアワークス)が5月1日に発売されていたのでさっそく買ってみました。「2.4 コントローラ」は、 OpenFlow 1.0.0 仕様書の OpenFlow メッセージの説明箇所を日本語訳したような内容で仕様書を読むうえで便利そうだったのですが、目次の充実度がいまいちなのが残念でした。

ちょうど OpenFlow メッセージについて整理したいと思っていたので、仕様書と対応付ける形で目次のような感じで記載箇所をまとめてみました。

OpenFlow 1.0.0 仕様書においてメッセージについて記載している箇所は本文が "4.1 OpenFlow Protocol Overview"、詳細は "5 Appendix A: The OpenFlow Protocol" です。
以下では基本構成を、"4.1 OpenFlow Protocol Overview" にしています。

ページ番号は、
 ・『OpenFlow入門』と書いた箇所は『次世代ネットワーク制御技術 OpenFlow入門』初版でのページ
  ・その他は、OpenFlow Switch Specification Version 1.0.0 のページ
です。
また、OpenFlow Switch Specification Version 1.0.0 の PDF への各ページへのリンクを設定してあります。


"4.1 OpenFlow Protocol Overview" (P.10)
  OpenFlowでは3つのメッセージのタイプがある:
  ・Controller-to-Switch
      コントローラからスイッチに対して発行されるメッセージ。
    スイッチからの応答があるものとないものがある。
  ・Asynchronous
      スイッチからコントローラに対して発行されるメッセージ。
  ・Symmetric
      スイッチからコントローラ、コントローラからスイッチの双方向で発行されるメッセージ。

"4.1.1 Controller-to-Switch" (P.10)
 □ "Features:" (P.10)
    (『OpenFlow入門』 「・Feature」 P.46) 

    ■ メッセージ OFPT_FEATURES_REQUEST / 応答メッセージ OFPT_FEATURES_REPLY
    "5.3.1 Handshake"  (P.25)
    (『OpenFlow入門』 「Feature」 P.62) 

  □ "Configuration:"  (P.10)
    (『OpenFlow入門』 「・Configuration」 P.47) 

    ■ メッセージ OFPT_GET_CONFIG_REQUEST / 応答メッセージ OFPT_GET_CONFIG_REPLY
    "5.3.2 Switch Configuration" (P.26)
    (『OpenFlow入門』 「Configuration」 P.64) 

    ■ メッセージ OFPT_SET_CONFIG
    "5.3.2 Switch Configuration" (P.26)
    (『OpenFlow入門』 「Configuration」 P.64) 

    ■ メッセージ OFPT_QUEUE_GET_CONFIG_REQUEST / 応答メッセージ OFPT_QUEUE_GET_CONFIG_REPLY
    "5.3.4 Queue Configuration Message" (P.29)

  □ "Modify-State:" (P.10)
    (『OpenFlow入門』 「・Modify-State」 P.49) 

    ■ メッセージ OFPT_FLOW_MOD
    "4.6 Flow Table Modification Message" (P.13)
    "5.3.3 Modify State Messages" "Modify Flow Entry Message" (P.27)
    (『OpenFlow入門』 「Modify-State1(フローエントリ変更メッセージ)」 P.65) 

    メッセージのタイプ:
        OFPFC_ADD
        OFPFC_MODIFTY
        OFPFC_MODIFY_STRICT
        OFPFC_DELTE
        OFPFC_DELETE_STRICT

    ■ メッセージ OFPT_PORT_MOD
    "5.3.3 Modify State Messages" "Port Modification Message" (P.29)
    (『OpenFlow入門』 「Modify-State2 (ポート変更メッセージ)」 P.75) 

  □ "Read-State:" (P.10)
    (『OpenFlow入門』 「・Read-State」 P.50) 

    ■ メッセージ OFPT_STATS_REQUEST / 応答メッセージ OFPT_STATS_REPLY
    "5.3.5 Read State Messages" (P.30)
    (『OpenFlow入門』 「Read-State」 P.75) 

    メッセージのタイプ:
       OFPST_DESC      ("Description Statistics" P.31)
       OFPST_FLOW      ("Individual Flow Statistics" P.31)
       OFPST_AGGREGATE ("Aggregate Flow Statistics" P.33)
       OFPST_TABLE     ("Table Statistics" P.33)
       OFPST_PORT      ("Port Statistics" P.34)
       OFPST_QUEUE     ("Queue Statistics" P.35)
       OFPST_VENDOR    ("Vendor Statistics" P.35)

  □ "Send-Packet:" (P.10)
    (『OpenFlow入門』 「・Send-Packet」 P.50) 

    ■ メッセージ OFPT_PACKET_OUT
    "5.3.6 Send Packet Message" (P.35)
    (『OpenFlow入門』 「Send-Packet」 P.82) 

  □ "Barrier:" (P.10)
    (『OpenFlow入門』 「・Barrier」 P.50) 

    ■ メッセージ OFPT_BARRIER_REQUEST / 応答メッセージ OFPT_BARRIER_REPLY
    "5.3.7 Barrier Message" (P.36)
    (『OpenFlow入門』 「Barrier」 P.82) 

"4.1.2 Asynchronous" (P.10)
  (『OpenFlow入門』「非同期メッセージ」 P.44) 

  □ "Packet-in:" (P.11)
    (『OpenFlow入門』「・Packet-In」 P.44) 

    ■ メッセージ OFPT_PACKET_IN
    "5.4.1 Packet-In Message" (P.36)
    (『OpenFlow入門』「Packet-in」 P.52) 

  □ "Flow-Removed:" (P.11)
    "4.7 Flow Removal" (P.15)
    (『OpenFlow入門』 「・Flow-Removed」 P.45) 

    ■ メッセージ OFPT_FLOW_REMOVED
    "5.4.2 Flow Removed Message" (P.37)
    (『OpenFlow入門』「Flow-Removed」 P.53) 
 
  □ "Port-status:" (P.11)
    (『OpenFlow入門』 「・Port-Status」 P.46) 

    ■ メッセージ OFPT_PORT_STATUS
    "5.4.3 Port Status Message" (P.38)
    (『OpenFlow入門』「Port-Status」 P.55) 
   
  □ "Error:" (P.11)
    (『OpenFlow入門』 「・Error」 P.46) 

    ■ メッセージ OFPT_ERROR_MSG
    "5.4.4 Error Message" (P.38)
    (『OpenFlow入門』 「Error」 P.58) 

"4.1.3 Symmetric" (P.11)
  "5.5 Symmetric Messages" (P.41)

  □ "Hello:" (P.11)
    (『OpenFlow入門』 「・Hello」 P.51) 

    ■ メッセージ OFPT_HELLO
    "5.5.1 Hello" (P.41)
    (『OpenFlow入門』 「Hello」 P.83) 

  □ "Echo:" (P.11)
    (『OpenFlow入門』 「・Echo」 P.51) 

    ■ メッセージ OFPT_ECHO_REQUEST
     "5.5.2 Echo Reqest" (P.41)
    (『OpenFlow入門』 「Echo」 P.83) 

    ■ メッセージ OFPT_ECHO_REPLY
    "5.5.3 Echo Reply" (P.41)

  □ "Vendor:" (P.11)
    (『OpenFlow入門』 「・Echo」 P.52) 

    ■ メッセージ OFPT_VENDOR
    "5.5.4 Vendor" (P.41)
    (『OpenFlow入門』 「Vendor」 P.84) 

 


OpenFlow Switch Specification Version 1.0.0 は以下の Web ページで公開されています:
  http://www.openflow.org/wp/documents/

2013年5月 1日 (水)

◆ Linux のネットワークネームスペース機能と Open vSwitch で仮想ネットワーク(VLANホスト追加)

前々回の記事の仮想ネットワークに、VLANインターフェースを持つ仮想ホストを追加してみました。

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

vhost6 を追加して VLAN ID=10 で接続しています。vlink6-0 のインターフェース対して VLAN インタフェースを vlink6-0.10 という名前で作っています。
※ vhost5 は、ありません。
Photo
■追加した仮想ホストでのインタフェース設定の確認

$ sudo ip netns exec vhost6 ip link show
19: vlink6-0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether aa:df:6d:3b:6c:b1 brd ff:ff:ff:ff:ff:ff 24: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 25: vlink6-0.10@vlink6-0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP     link/ether aa:df:6d:3b:6c:b1 brd ff:ff:ff:ff:ff:ff

■動作確認

vhost6 から ping で通信確認。VLAN ID が異なる vhost2 とは通信できない。

(1) vhost6 から vhost1(192.168.1.1) への ping

$ sudo ip netns exec vhost6 ping 192.168.1.1 -c 3
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=0.703 ms
64 bytes from 192.168.1.1: icmp_req=2 ttl=64 time=0.149 ms
64 bytes from 192.168.1.1: icmp_req=3 ttl=64 time=0.126 ms

--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.126/0.326/0.703/0.266 ms

(2) vhost6 から vhost2(192.168.1.2) への ping

$ sudo ip netns exec vhost6 ping 192.168.1.2 -c 3
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
From 192.168.1.6 icmp_seq=1 Destination Host Unreachable
From 192.168.1.6 icmp_seq=2 Destination Host Unreachable
From 192.168.1.6 icmp_seq=3 Destination Host Unreachable

--- 192.168.1.2 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2001ms
pipe 3

(3) vhost6 から vhost3(192.168.1.3) への ping

$ sudo ip netns exec vhost6 ping 192.168.1.3 -c 3
PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data.
64 bytes from 192.168.1.3: icmp_req=1 ttl=64 time=0.633 ms
64 bytes from 192.168.1.3: icmp_req=2 ttl=64 time=0.103 ms
64 bytes from 192.168.1.3: icmp_req=3 ttl=64 time=0.107 ms

--- 192.168.1.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.103/0.281/0.633/0.248 ms

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

引数 delete で削除、add で追加です。

VLANインタフェースを持つ仮想ホストの追加箇所を赤字にしています。

#!/bin/sh
delete() {
    sudo ovs-vsctl del-br vswitch1
    sudo ovs-vsctl del-br vswitch2
    sudo ip netns delete vhost1
    sudo ip netns delete vhost2
    sudo ip netns delete vhost3
    sudo ip netns delete vhost4
    sudo ip link delete vlink5-0
    sudo ip link delete vlink5-1
    sudo ip netns delete vhost6
}
add() {
    sudo ovs-vsctl add-br vswitch1
    sudo ovs-vsctl add-br vswitch2
   
    sudo ip link add name vlink1-0 type veth peer name vlink1-1
    sudo ip link add name vlink2-0 type veth peer name vlink2-1
    sudo ip link add name vlink3-0 type veth peer name vlink3-1
    sudo ip link add name vlink4-0 type veth peer name vlink4-1
    sudo ip link add name vlink5-0 type veth peer name vlink5-1
    sudo ip link add name vlink6-0 type veth peer name vlink6-1
   
    sudo ip link set vlink1-0 up
    sudo ip link set vlink2-0 up
    sudo ip link set vlink3-0 up
    sudo ip link set vlink4-0 up
   
    sudo ip link set vlink1-1 up
    sudo ip link set vlink2-1 up
    sudo ip link set vlink3-1 up
    sudo ip link set vlink4-1 up
    sudo ip link set vlink6-1 up
   
    sudo ip netns add vhost1
    sudo ip netns add vhost2
    sudo ip netns add vhost3
    sudo ip netns add vhost4
    sudo ip netns add vhost6
   
    sudo ip netns exec vhost1 ifconfig lo 127.0.0.1
    sudo ip netns exec vhost2 ifconfig lo 127.0.0.1
    sudo ip netns exec vhost3 ifconfig lo 127.0.0.1
    sudo ip netns exec vhost4 ifconfig lo 127.0.0.1
    sudo ip netns exec vhost6 ifconfig lo 127.0.0.1

    sudo ip link set vlink1-0 netns vhost1
    sudo ip link set vlink2-0 netns vhost2
    sudo ip link set vlink3-0 netns vhost3
    sudo ip link set vlink4-0 netns vhost4
    sudo ip link set vlink6-0 netns vhost6
    sudo ip netns exec vhost6 ip link add link vlink6-0 name vlink6-0.10 type vlan id 10
    sudo ip netns exec vhost6 ip link set vlink6-0 up

   
    sudo ip netns exec vhost1 ifconfig vlink1-0 192.168.1.1
    sudo ip netns exec vhost2 ifconfig vlink2-0 192.168.1.2
    sudo ip netns exec vhost3 ifconfig vlink3-0 192.168.1.3
    sudo ip netns exec vhost4 ifconfig vlink4-0 192.168.1.4
    sudo ip netns exec vhost6 ifconfig vlink6-0.10 192.168.1.6
   
    sudo ovs-vsctl add-port vswitch1 vlink5-0
    sudo ovs-vsctl add-port vswitch2 vlink5-1
   
    sudo ovs-vsctl add-port vswitch1 vlink1-1 tag=10
    sudo ovs-vsctl add-port vswitch1 vlink2-1 tag=20
    sudo ovs-vsctl add-port vswitch1 vlink6-1
   
    sudo ovs-vsctl add-port vswitch2 vlink3-1 tag=10
    sudo ovs-vsctl add-port vswitch2 vlink4-1 tag=20
    sudo ip link set vlink5-0 up
    sudo ip link set vlink5-1 up
}
case "$1" in
add)
    set -x
    add
    ;;
delete)
    delete > /dev/null 2>&1
    ;;
*)
    echo "usage: $0 (add|delete)"
esac

« 2013年4月 | トップページ | 2013年6月 »

最近のトラックバック

無料ブログはココログ