Sliceable Switch を使う (その1)

今回は Trema Apps にある Sliceable Switch について紹介します。このアプリを使うと、OpenFlow ネットワーク全体をスライスに分割し,複数の L2 ネットワークとして動かすことができます。ちょうど,L2 スイッチを複数の VLAN に分けて使うイメージです。マルチテナントを収容するデータセンターで、テナント毎に独立したネットワークを実現するなどの用途を想定したものです。

準備

Sliceable Switch のソースコードhttps://github.com/trema/apps/ にて公開されています。ソースコードをまだ取得していない場合は、git で取得してください。ここでは、以下のようなディレクトリ構成になっていることが前提です。

% ls -F
apps/   trema/

Sliceable Switch は、topology や flow_manager とも連動して動作するようになっていますので、これらのモジュールも合わせて make してください。

% (cd apps/topology/; make)
% (cd apps/flow_manager/; make)
% (cd apps/sliceable_switch; make)

動作させる

まずは以下の内容のファイルを、network.conf という名前で用意してください。

vswitch {
  datapath_id "0xe0"
}

vhost ("host1") {
  ip "192.168.0.1"
  netmask "255.255.0.0"
  mac "00:00:00:00:00:01"
}

vhost ("host2") {
  ip "192.168.0.2"
  netmask "255.255.0.0"
  mac "00:00:00:00:00:02"
}

vhost ("host3") {
  ip "192.168.0.3"
  netmask "255.255.0.0"
  mac "00:00:00:00:00:03"
}

vhost ("host4") {
  ip "192.168.0.4"
  netmask "255.255.0.0"
  mac "00:00:00:00:00:04"
}

link "0xe0", "host1"
link "0xe0", "host2"
link "0xe0", "host3"
link "0xe0", "host4"

run {
  path "../apps/topology/topology"
}

run {
  path "../apps/topology/topology_discovery"
}

run {
  path "../apps/flow_manager/flow_manager"
}

run {
  path "../apps/sliceable_switch/sliceable_switch"
  options "-s", "../apps/sliceable_switch/slice.db", "-f", "../apps/sliceable_switch/filter.db"
}

event :port_status => "topology", :packet_in => "filter", :state_notify => "topology"
filter :lldp => "topology_discovery", :packet_in => "sliceable_switch"

trema のディレクトリに移動し、Sliceable Switch を起動します。
Siceable Switch の起動には、ルート権限が必要です。sudo を使って、以下のように起動してください。

% cd ../../trema
% sudo ./trema run -c ./network.conf

このように起動しただけでは、スライス機能つきスイッチは動作しません。スライスの設定が必要です。今回は二つのスライスを作ってみましょう。
スライスの作成には、同梱されている slice コマンドを使用します。このコマンドを使って、以下のように、二つのスライス slice1, slice2 を作ってみましょう。

% cd ../apps/sliceable_switch
% ./slice create slice1
A new slice is created successfully.
% ./slice create slice2
A new slice is created successfully.

次は作成したそれぞれのスライスにホストを所属させます。その方法には、ホストが接続しているポートの指定と、ホストの MAC アドレスの登録の二通りがあります。今回は後者の方法で試してみましょう。以下のように host1, host2 の MAC アドレスを slice1 に、host3, host4 の MAC アドレスを slice2 に、それぞれ登録を行います。

% ./slice add-mac slice1 00:00:00:00:00:01
A MAC-based binding is added successfully.
% ./slice add-mac slice1 00:00:00:00:00:02
A MAC-based binding is added successfully.
% ./slice add-mac slice2 00:00:00:00:00:03
A MAC-based binding is added successfully.
% ./slice add-mac slice2 00:00:00:00:00:04
A MAC-based binding is added successfully.

ここまでで準備は完了です。それではまず同じスライスに所属するホスト同士が通信できることを確認してみましょう。
MAC アドレスをスライスに登録する方法では、コントローラは起動直後に、登録した MAC アドレスを持つホストがどこにいるのかを知りません。そのため、host1 の位置をコントローラに学習させるために、はじめに host1 から host2 へとパケットを送ります。その後、host2 から host1 へパケットを送り、host1 の受信カウンタを見てみましょう。host2 からのパケットが受信できていることが確認できます。

% cd ../../trema
% ./trema send_packet --source host1 --dest host2
% ./trema send_packet --source host2 --dest host1
% ./trema show_stats host1 --rx
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.0.1,1,192.168.0.2,1,1,50

次に、異なるスライスに所属するホスト同士は通信できないことを確認してみます。slice2 に所属する host4 から slice1 に所属するhost1 へとパケットを送ってみましょう。host1 の受信カウンタを見ても、host4 からのパケットが届いていないことがわかります。

% ./trema send_packet --source host4 --dest host1
% ./trema show_stats host1 --rx
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.0.1,1,192.168.0.2,1,1,50

おわりに

Sliceable Switch を動作させ、同一スライスに所属するホスト同士のみが通信できることを確認してみました。今回はスライスの設定は、 slice コマンドを用いて行いましたが、REST API 経由でもできるようなしくみが用意されています。次回は REST API を使う方法について紹介したいと思います。