OpenFlow
ネットワークの制御とデータ転送を分離するSDNで、コントローラーがスイッチのパケット処理を指示するためのプロトコル。スイッチはコントローラーから受け取ったルール(フローエントリ)に従って、転送や破棄などを行う。
イマシルちゃんの解説
ネットワークの通信経路を変えるとき、機器ごとに設定を直すのは大変だよ。
OpenFlowは、ネットワークを制御するコントローラーからスイッチへ、通信データのまとまりであるパケットの扱い方を指示するためのプロトコルなんだ。
たとえば「この宛先へのパケットはこのポートへ送る」というルールを登録できるよ。
スイッチは受け取ったパケットをルールと照らし合わせ、転送したり破棄したりするんだ。
ルールにないパケットの扱いも設定で決まり、必ずコントローラーへ問い合わせるわけではないよ。
指示を決める仕事と実際に転送する仕事を分けることで、ソフトウェアから通信の流れをまとめて変えられるんだ。
この解説はわかりやすかったですか?
より深い解説
定義
OpenFlowは、ONF(Open Networking Foundation)が仕様を定めた、SDNを実現するためのプロトコルである。ネットワークの経路を考える機能(制御)をOpenFlowコントローラーに、パケットを転送する機能(データ転送)をOpenFlowスイッチに分け、両者の間のやり取りをOpenFlowで行う。コントローラーとスイッチの間の通信には、TCPのポート6653番を使い、TLSで暗号化することもできる。
パケット処理のルール
OpenFlowスイッチは、フローテーブルに登録されたフローエントリに従ってパケットを処理する。
| 項目 | 内容 |
|---|---|
| マッチフィールド | 対象のパケットの条件(受信ポート、MACアドレス、IPアドレス、ポート番号など) |
| 優先度 | 複数のエントリに当てはまるときの優先順位 |
| カウンタ | 当てはまったパケットの数やバイト数 |
| インストラクション | アクションの適用や、次のテーブルへの移動などを指定する |
| タイムアウト | 最後に一致してからの時間や、登録してからの時間を基にエントリを失効させる |
OpenFlowではレイヤ2からレイヤ4までのさまざまな条件を組み合わせ、転送の仕方を細かく決められる。例えばETH_TYPEはイーサネットのEtherType、ETH_DSTは宛先MACアドレスを照合するフィールドである。識別条件をMatch Field、略してMFと表すこともある。
主なメッセージ
| メッセージ | 向き | 内容 |
|---|---|---|
| Packet-In | スイッチ → コントローラー | 受信パケットの全体または一部と、入力ポートなどの情報を通知する。コントローラーへの送信を指示する処理などで使う |
| Packet-Out | コントローラー → スイッチ | 指定したパケットへアクションを適用する。出力アクションとポートを指定すれば、そこから送出させられる |
| Flow-Mod | コントローラー → スイッチ | フローエントリの追加、変更、削除を指示する |
| Echo(Request / Reply) | 双方向 | 接続が生きているかを確かめる |
| Hello | 双方向 | 接続の開始時に、使うバージョンを取り決める |
| Port-Status | スイッチ → コントローラー | ポートの状態の変化を知らせる |
スイッチをOFS、コントローラーをOFCと略すことがある。Packet-Outは個々のパケットの処理を指示し、Flow-Modはフローテーブルのルールを変更する。この二つの役割を区別する。なお、バッファIDを指定したFlow-Modで保留中のパケットも処理できるため、両者を必ず一組で送るわけではない。
パケットへ適用する処理
| 処理の名称 | 働き |
|---|---|
| Output | 指定した出力先へパケットを送る |
| Drop | パケットを破棄するという動作を表す |
| Set-Field | 指定したヘッダーフィールドの値を書き換える |
| Push-VLAN | 外側にVLANヘッダーを付加する |
| Pop-VLAN | 外側のVLANヘッダーを取り除く |
例えばSet-FieldでETH_DSTの値を変更すると、イーサネットフレームの宛先MACアドレスが変わる。VLANヘッダーがないパケットにVLAN IDを設定する場合は、まずヘッダーを追加してから値を書き込む。
OpenFlow 1.3ではDropという独立したアクションコードがあるわけではない。パイプラインで別途出力していないパケットについて、最終的なアクションセットに出力やグループ処理を指定しなければ破棄される。設定画面や説明表の名称と、仕様上の表現を区別する。
コントローラーを出力先にする
Outputの出力先には物理ポートの番号だけでなく、予約された特殊なポートも指定できる。controllerはコントローラーへ送るための指定で、仕様上はOFPP_CONTROLLERという予約ポートに対応する。通常のケーブルを挿す物理ポートを意味しない。
例えばETH_TYPEが0x88CC、すなわちLLDPのフレームに一致するルールへ、この出力先を設定する。スイッチは該当フレームをPacket-Inとしてコントローラーへ通知する。コントローラーは受信スイッチと入力ポート、通知された隣接情報を使って接続構成を把握できる。
典型的な流れ(リアクティブ型)
- スイッチが、通常のフローエントリに当てはまらないパケットを受け取る。ここではテーブルミス時にコントローラーへ送るルールをあらかじめ設定しておく
- スイッチが、そのパケットをPacket-Inでコントローラーに送る
- コントローラーが転送先を決め、Flow-Modで同じ種類のパケットのためのエントリをスイッチに登録する
- 最初のパケットを別途処理する場合は、コントローラーがPacket-Outで送出させる
- 以降の同じ種類のパケットは、スイッチがエントリに従って自分で転送する
このように、パケットが来てからエントリを登録する方式をリアクティブ型、あらかじめエントリを登録しておく方式をプロアクティブ型という。
参考資料
- ONF OpenFlow Switch Specification 1.3.5の第4・5・7章に予約ポート、フローテーブル、アクション、制御メッセージが定められている。