Skip to content

Commit 1517027

Browse files
committed
Updated.
1 parent b77ec38 commit 1517027

File tree

1 file changed

+24
-24
lines changed

1 file changed

+24
-24
lines changed

part2.ja.md

+24-24
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ OpenFlow の動作を現実世界にたとえると,製品の電話サポー
1818

1919
## 電話サポートの業務手順
2020

21-
友太郎 ゆうたろう 君は,エアコンが故障したので修理に出そうと考えました (図1)。電話サポートに問い合わせると,サポート係の葵 (あおい) さんはエアコンの症状を聞き,手元のマニュアルに対処方法が載っている場合にはこれをすぐに教えてくれます。問題は,マニュアルに対処法が載っていない場合です。このようなときは少し時間がかかりますが,上司の宮坂主任にどうしたらよいか聞きます。そして,宮坂主任からの回答が得られたら,葵さんは友太郎君に折り返し電話をします。また,次からの同じ問い合わせにはすばやく答えられるようにするため,葵さんは教わった対処法を手元のマニュアルに追加しておきます。
21+
友太郎 (ゆうたろう) 君は,エアコンが故障したので修理に出そうと考えました (図1)。電話サポートに問い合わせると,サポート係の葵 (あおい) さんはエアコンの症状を聞き,手元のマニュアルに対処方法が載っている場合にはこれをすぐに教えてくれます。問題は,マニュアルに対処法が載っていない場合です。このようなときは少し時間がかかりますが,上司の宮坂主任にどうしたらよいか聞きます。そして,宮坂主任からの回答が得られたら,葵さんは友太郎君に折り返し電話をします。また,次からの同じ問い合わせにはすばやく答えられるようにするため,葵さんは教わった対処法を手元のマニュアルに追加しておきます。
2222

2323
簡単ですね? 信じられないかもしれませんが,あなたはすでに OpenFlow の 95% を理解したも同然なのです。
2424

@@ -28,13 +28,13 @@ OpenFlow の動作を現実世界にたとえると,製品の電話サポー
2828

2929
## OpenFlowに置き換えると……
3030

31-
OpenFlow では,お客さんがパケットを発生させるホスト,電話サポート係がスイッチ,上司がコントローラ,マニュアルがスイッチのフローテーブル (後述) に対応します (図2)。
31+
OpenFlow では,お客さんがパケットを発生させるホスト,電話サポート係がスイッチ,上司がコントローラ,マニュアルがスイッチのフローテーブル (後述) に対応します (図2)。
3232

3333
![OpenFlowの動作モデル](https://github.com/trema/Programming-Trema/raw/master/images/2_002.png)
3434

3535
図2 OpenFlowの動作モデル
3636

37-
スイッチはホストからのパケットを受信すると,最初はその処理方法がわかりません。そこで,上司にあたるコントローラに問い合わせます。この問い合わせを `packet_in` メッセージと呼びます。コントローラはこれを受け取ると,同様のパケットが届いた場合にスイッチでどう処理すべきか パケットを転送する,書き換えるなど を決めます。これをアクションと呼びます。そして 「スイッチで処理すべきパケットの特徴」+「アクション」 の組 (フローと呼びます) をスイッチのマニュアルに追加します。この命令を `flow_mod` メッセージと呼び,スイッチのマニュアルをフローテーブルと呼びます。処理すべきパケットの特徴とアクションをフローテーブルに書いておくことで,以後,これに当てはまるパケットはスイッチ側だけですばやく処理できます。忘れてはならないのが,`packet_in` メッセージで上がってきた最初のパケットです。これはコントローラに上がってきて処理待ちの状態になっているので,`packet_out` メッセージで適切な宛先に転送してあげます。
37+
スイッチはホストからのパケットを受信すると,最初はその処理方法がわかりません。そこで,上司にあたるコントローラに問い合わせます。この問い合わせを `packet_in` メッセージと呼びます。コントローラはこれを受け取ると,同様のパケットが届いた場合にスイッチでどう処理すべきか (パケットを転送する,書き換えるなど) を決めます。これをアクションと呼びます。そして 「スイッチで処理すべきパケットの特徴」+「アクション」 の組 (フローと呼びます) をスイッチのマニュアルに追加します。この命令を `flow_mod` メッセージと呼び,スイッチのマニュアルをフローテーブルと呼びます。処理すべきパケットの特徴とアクションをフローテーブルに書いておくことで,以後,これに当てはまるパケットはスイッチ側だけですばやく処理できます。忘れてはならないのが,`packet_in` メッセージで上がってきた最初のパケットです。これはコントローラに上がってきて処理待ちの状態になっているので,`packet_out` メッセージで適切な宛先に転送してあげます。
3838

3939
電話サポートとの大きな違いは,フローテーブルに書かれたフローには期限があり,これを過ぎると消えてしまうということです。これは,「マニュアルに書かれた内容は徐々に古くなるので,古くなった項目は消す必要がある」 と考えるとわかりやすいかもしれません。フローが消えるタイミングでコントローラには `flow_removed` メッセージが送信されます。これには,あるフローに従ってパケットがどれだけ転送されたか -- 電話サポートの例で言うと,マニュアルのある項目が何回参照されたか -- つまり,トラフィックの集計情報が記録されています。
4040

@@ -47,18 +47,18 @@ OpenFlow では,お客さんがパケットを発生させるホスト,電
4747

4848
## 設計と実装
4949

50-
「L2 スイッチ機能」と「トラフィックの集計機能」のためにはどんな部品が必要でしょうか? まずは,スイッチに指示を出す上司にあたるコントローラクラスが必要です。これを `TrafficMonitor` クラスと名付けましょう。また,パケットを宛先のスイッチポートへ届けるための `FDB` クラス (注1),あとはトラフィックを集計するための `Counter` クラスの 3 つが最低限必要です。
50+
「L2 スイッチ機能」と「トラフィックの集計機能」のためにはどんな部品が必要でしょうか? まずは,スイッチに指示を出す上司にあたるコントローラクラスが必要です。これを `TrafficMonitor` クラスと名付けましょう。また,パケットを宛先のスイッチポートへ届けるための `FDB` クラス (注1),あとはトラフィックを集計するための `Counter` クラスの 3 つが最低限必要です。
5151

52-
注1 FDB とは Forwarding DataBase の略で,スイッチの一般的な機能です。詳しくは続く実装で説明します。
52+
注1) FDB とは Forwarding DataBase の略で,スイッチの一般的な機能です。詳しくは続く実装で説明します。
5353

5454
### FDBクラス
5555

56-
`FDB` クラス リスト1 は,ホストの MAC アドレスとホストが接続しているスイッチポートの対応を学習するデータベースです。このデータベースを参照することで,`packet_in` メッセージで入ってきたパケットの宛先 MAC アドレスからパケット送信先のスイッチポートを決定できます。
56+
`FDB` クラス (リスト1) は,ホストの MAC アドレスとホストが接続しているスイッチポートの対応を学習するデータベースです。このデータベースを参照することで,`packet_in` メッセージで入ってきたパケットの宛先 MAC アドレスからパケット送信先のスイッチポートを決定できます。
5757

5858
```ruby
5959
class FDB
6060
def initialize
61-
@db = {} # <- 連想配列MACアドレス→スイッチポート番号
61+
@db = {} # <- 連想配列(MACアドレス→スイッチポート番号)
6262
end
6363

6464
def lookup mac # <- MACアドレスからスイッチポート番号を引く
@@ -71,19 +71,19 @@ class FDB
7171
end
7272
```
7373

74-
リスト1 MACアドレス→スイッチポートのデータベースFDBクラスfdb.rb
74+
リスト1 MACアドレス→スイッチポートのデータベースFDBクラス(fdb.rb)
7575

7676
### Counter クラス
7777

78-
`Counter` クラス リスト2 は,ホスト (MAC アドレスで区別します) ごとの送信パケット数およびバイト数をカウントします。また,カウントした集計情報を表示するためのヘルパメソッドを提供します。
78+
`Counter` クラス (リスト2) は,ホスト (MAC アドレスで区別します) ごとの送信パケット数およびバイト数をカウントします。また,カウントした集計情報を表示するためのヘルパメソッドを提供します。
7979

8080
```ruby
8181
class Counter
8282
def initialize
8383
@db = {} # <- ホストごとの集計情報を記録する連想配列
8484
end
8585

86-
def add mac, packet_count, byte_count # <- ホスト MAC アドレス = mac の送信パケット数、バイト数を追加
86+
def add mac, packet_count, byte_count # <- ホスト (MAC アドレス = mac) の送信パケット数、バイト数を追加
8787
@db[ mac ] ||= { :packet_count => 0, :byte_count => 0 }
8888
@db[ mac ][ :packet_count ] += packet_count
8989
@db[ mac ][ :byte_count ] += byte_count
@@ -95,15 +95,15 @@ class Counter
9595
end
9696
```
9797

98-
リスト2 トラフィックを記録し集計する `Counter` クラス `counter.rb`
98+
リスト2 トラフィックを記録し集計する `Counter` クラス (`counter.rb`)
9999

100100
### TrafficMonitor クラス
101101

102-
`TrafficMonitor` クラスはコントローラの本体です リスト3。メインの処理はリスト 3 1-3 の 3 つになります。
102+
`TrafficMonitor` クラスはコントローラの本体です (リスト3)。メインの処理はリスト 3 1-3 の 3 つになります。
103103

104-
`packet_in` メッセージが到着したとき,パケットを宛先のスイッチポートに転送し,フローテーブルを更新する部分
105-
`flow_removed` メッセージが到着したとき,トラフィック集計情報を更新する部分
106-
タイマーで 10 秒ごとにトラフィックの集計情報を表示する部分
104+
1. `packet_in` メッセージが到着したとき,パケットを宛先のスイッチポートに転送し,フローテーブルを更新する部分
105+
2. `flow_removed` メッセージが到着したとき,トラフィック集計情報を更新する部分
106+
3. タイマーで 10 秒ごとにトラフィックの集計情報を表示する部分
107107

108108

109109
```ruby
@@ -169,7 +169,7 @@ class TrafficMonitor < Controller
169169
end
170170
```
171171

172-
リスト3 本体 `TrafficMonitor` クラス `traffic-monitor.rb`
172+
リスト3 本体 `TrafficMonitor` クラス (`traffic-monitor.rb`)
173173

174174
それでは,とくに重要な (1) の処理を詳しく見ていきましょう。なお,リスト 3 中で使われているメソッドの引数など API の詳細については,「Trema Ruby API ドキュメント」 を参照してください。
175175

@@ -186,21 +186,21 @@ end
186186

187187
1. `host1` から `host2` を宛先としてパケットを送信すると,まずはスイッチにパケットが届く
188188
2. スイッチのフローテーブルは最初はまっさらで,どう処理すればよいかわからない状態なので,コントローラである `TrafficMonitor``packet_in` メッセージを送る
189-
3. `TrafficMonitor``packet_in` メッセージハンドラでは,`packet_in` メッセージの `in_port` `host1` のつながるスイッチポート`host1` の MAC アドレスを FDB に記録する
189+
3. `TrafficMonitor``packet_in` メッセージハンドラでは,`packet_in` メッセージの `in_port` (`host1` のつながるスイッチポート)`host1` の MAC アドレスを FDB に記録する
190190
4. また,`Counter` に記録された `host1` の送信トラフィックを 1 パケット分増やす
191191
5. `packet_in` メッセージの宛先 MAC アドレスから転送先のスイッチポート番号を FDB に問い合わせる。この時点では `host2` のスイッチポートは学習していないので,結果は 「不明」
192-
6. そこで,パケットを `in_port` 以外のすべてのスイッチポートに出力する `packet_out` メッセージ FLOOD と呼ばれる をスイッチに送り,`host2` が受信してくれることを期待する
192+
6. そこで,パケットを `in_port` 以外のすべてのスイッチポートに出力する `packet_out` メッセージ (FLOOD と呼ばれる) をスイッチに送り,`host2` が受信してくれることを期待する
193193
7. スイッチは,パケットを `in_port` 以外のすべてのポートに出す
194194

195-
これで,最終的に `host2` がパケットを受信できます。逆に,この状態で `host1` を宛先として `host2` からパケットを送信したときの動作シーケンスは次のとおりになります (図5)。4 までの動作は図 4 と同じですが,5 からの動作が次のように異なります。
195+
これで,最終的に `host2` がパケットを受信できます。逆に,この状態で `host1` を宛先として `host2` からパケットを送信したときの動作シーケンスは次のとおりになります (図5)。4 までの動作は図 4 と同じですが,5 からの動作が次のように異なります。
196196

197197
![host1 から host2 宛にパケットを送信したときの動作シーケンス](https://github.com/trema/Programming-Trema/raw/master/images/2_005.png)
198198

199199
図5 host1 から host2 宛にパケットを送信したときの動作シーケンス
200200

201201
1. `host1` から `host2` を宛先としてパケットを送信すると,まずはスイッチにパケットが届く
202202
2. スイッチのフローテーブルは最初はまっさらで,どう処理すればよいかわからない状態なので,コントローラである `TrafficMonitor``packet_in` メッセージを送る
203-
3. `TrafficMonitor``packet_in` メッセージハンドラでは,`packet_in` メッセージの `in_port` `host1` のつながるスイッチポート`host1` の MAC アドレスを FDB に記録する
203+
3. `TrafficMonitor``packet_in` メッセージハンドラでは,`packet_in` メッセージの `in_port` (`host1` のつながるスイッチポート)`host1` の MAC アドレスを FDB に記録する
204204
4. また,`Counter` に記録された `host1` の送信トラフィックを 1 パケット分増やす
205205
5. `packet_in` メッセージの宛先 MAC アドレスから,転送先のスイッチポート番号を FDB に問い合わせる。これは,先ほど `host1` から `host2` にパケットを送った時点で FDB に学習させているので,送信先はスイッチポート 1 番ということがわかる
206206
6. そこで,`TrafficMonitor` はパケットをスイッチポート 1 番へ出力する `packet_out` メッセージをスイッチに送る。スイッチはこれを受け取ると,パケットをスイッチポート 1 番に出し,最終的に `host1` がパケットを受信する
@@ -211,7 +211,7 @@ end
211211

212212
# 実行してみよう
213213

214-
それでは,早速実行してみましょう (注2)。リスト 4 の内容の仮想ネットワーク設定を `traffic-monitor.conf` として保存し,次のように実行してください。
214+
それでは,早速実行してみましょう (注2)。リスト 4 の内容の仮想ネットワーク設定を `traffic-monitor.conf` として保存し,次のように実行してください。
215215

216216
% ./trema run ./traffic-monitor.rb -c ./traffic-monitor.conf
217217

@@ -244,7 +244,7 @@ link "0xabc", "host2"
244244

245245
% ./trema send_packets --source host2 --dest host1 --n_pkts 10 --pps 10← host2からhost1宛にパケットを10個送る
246246

247-
`trema run` を実行した元のターミナルに次のような出力が出ていれば成功です(注3)
247+
`trema run` を実行した元のターミナルに次のような出力が出ていれば成功です(注3)
248248

249249
...
250250
00:00:00:00:00:01 10 packets (640 bytes)
@@ -254,9 +254,9 @@ link "0xabc", "host2"
254254
↑host2からパケットが10個送信された
255255
...
256256

257-
注2 Trema のセットアップが済んでいない人は,前回もしくは Trema のドキュメントを参考にセットアップしておいてください。なお,Trema は頻繁に更新されていますので,すでにインストールしている人も最新版にアップデートすることをお勧めします。
257+
注2) Trema のセットアップが済んでいない人は,前回もしくは Trema のドキュメントを参考にセットアップしておいてください。なお,Trema は頻繁に更新されていますので,すでにインストールしている人も最新版にアップデートすることをお勧めします。
258258

259-
注3 その他のトラフィック情報も出るかもしれませんが,これは Linux カーネルが送っている IPv6 のパケットなので,`host1``host2` とは関係ありません。
259+
注3) その他のトラフィック情報も出るかもしれませんが,これは Linux カーネルが送っている IPv6 のパケットなので,`host1``host2` とは関係ありません。
260260

261261

262262
# まとめ

0 commit comments

Comments
 (0)