A Simple L2 lerning switch development tutorial on P4Runtime
このチュートリアルは、P4Runtime の Packet-In/Out 機能を使って簡単なスイッチを構築するものです。P4Runtime Shell をベースとした、簡易なコントローラを試作するとともに、今後あなたが継続的に機能を拡張するのが容易な環境を提供します。
このチュートリアルでは、以下の四つのことを試します。最終的には非常に簡素な MAC Learning Switch が出来上がります。
- Multicast Group の設定と、それを利用した Flooding 処理
- Packet-In 処理を利用した、コントローラへの処理依頼
- Packet-Out 処理を利用した、スイッチのテーブルへのエントリ追加
- そうした実験を行うための P4Runtime Shell への機能追加
これらの実験は、以下の環境で行います。
- コントローラ役には P4Runtime Shell を用いる
- スイッチ役には P4Runtime に対応した Mininet を用いる
- P4 コンパイルにはオープンソースの p4c を用いる
もしチュートリアルをスキップしたい人には 近道 があります。
以下に一つずつ手順を示します。順番に試していくのが良いでしょう。
Tutorial 0: 実験環境の準備
Mininetを起動し、そこにコントローラ代わりとなる、P4 Runtime Shell を接続させます。
Tutorial 1: NanoSwitch01
届いたパケットのすべてを全ポートにリピートします
- Multicast Group を設定し、そこに出力する
Tutorial 2: NanoSwitch02
Ingress port をリピートの対象としないよう工夫します
- Multicast されたパケットのうち、Ingress port と同じ番号のポートだったら drop する
Tutorial 3: NanoSwitch03
スイッチ側にフロー・テーブルを作って未知のホストに対応します
- Unknown なものは Packet-In する
- Packet-In されたパケットは全ポートにリピートするよう Packet-Out する
Tutorial 4: NanoSwitch04
コントローラ側にホスト・テーブルを作って既知のホストに対応します
- 既知のホスト・ペアの通信についてはフローテーブルに往復ぶんのエントリを追加する
- これ以降はコントローラを介さず、スイッチだけで往復パケットの転送が行われる
Tutorial 5: NanoSwitch05
nanosw04では無視していたブロードキャスト処理を追加します
- ブロードキャストが出たらフローテーブルに対応したエントリを追加する
- ARP に対応し、普通のスイッチらしい挙動をするようになる
Tutorial 6: NanoSwitch06
フローテーブルへのエントリ追加が間に合わない場合にエラーになることに対応します
- 二重登録になった場合、そのエラーを無視する
今回作成した Switch は、P4Runtime を分かりやすく試せることを優先しています。そのため機能的にはかなり不完全で、ぱっと思いつくだけでも以下の問題などがあります。これらについては、あなた自身で追加してみてはどうでしょう。
-
実際のスイッチ運用の場面では、ホスト X を、同じスイッチの port 1 から port 2 に差し替えることがよく起きます。しかしこのスイッチはそのようなことを考慮しておらず、差し替えるとパケットが往復できなくなります。
-
登録できるエントリ数には限りがありますから、しばらくパケットが流れなかったフローエントリについては削除すべきです。
-
そもそも通常の L2 Learning Switch では、destination host が何番ポートに居るかだけを記憶し、フローごとにエントリを記憶する必要がありません。しかしP4 でそれを実現するには、source MAC でマッチングするものと、destination MAC + port でマッチングするものの、二つのテーブルが必要です。二つのテーブルを順にマッチしていくスイッチを作ってみませんか?
今回のチュートリアルは P4Runtime Shell に機能を追加しながら行いました。私の手元で使っていた改造版 P4Runtime Shell を公開しています。Dockerfile.dev をオリジナル・バージョンと見比べれば、どこを改造したか分かると思います。これを Tutorial0: 実験環境の準備 で示した方法で作成した Docker Image も公開しています。
そこには今回のチュートリアルで利用した機能がすべて含まれている上に、ここでは紹介しなかった機能もあります。興味のある方は以下のリンクを見て下さい。
Mininet では ping などのツールがあり、ARP などを生じさせずに簡単にパケットを送信できますが、たとえば Wedge Switch など実機を使った実験などでは、Wedge 自身 (OpenNetworkLinux) あるいは Wedge のポートに接続した Windows/Mac などから任意のパケットを送信したくなるでしょう。そうした場合のツールを置いておきます。
CPU port の情報は nanoswXX.p4 の冒頭にあります。必要に応じて以下の記述を変更して再コンパイルしてください。
#define CPU_PORT 255
もしあなたが試そうとするスイッチの CPU port 番号が分からない場合は、P4Runtime-CPUport-finder が役に立つかも知れません。