はじめに
そんなに長くもなければややこしくもないネタないかなーと思って、ふとまだやってなかったなと思い、書いてみます。
P4Runtime?
まずP4言語というものがありまして、これはデータプレーンをプログラミングするための言語です。プログラマブルASICだとかFPGAだとかSmartNICだとかeBPF/XDPだとかDPDKだとかで、パケットをどう処理するかを記述するとその通りに動くというものです。たとえばルーティングテーブルを定義して、パケットのdstipを参照し、テーブルのdestination IP addressとLongest Prefix Matchして、というルックアップ処理などをP4言語で思うままにプログラムとして書けます。P4言語のコンパイラを通すと、ターゲットに合わせたアウトプットが得られるのでそれを組み込んだりします。
では、テーブルに値を書き込むにはどうすればいいのでしょう?
このテーブルへのアクセスを実現するのがP4Runtimeです。
P4言語で定義された、あるいはP4言語(のテーブル定義)で操作できるデータプレーンに対する、ベンダ非依存のAPI仕様となります。P4Runtime Specificationできっちり定義されています。protobufで定義されます。リファレンス実装ではトランスポートは大抵のものと同じようにgRPCが使われます。
SONiCのP4Runtime実装
SONiC-P4RTというのが、SONiC向けP4Runtimeアプリケーションの実装です。Googleの方がやられてるそうですが、Googleの公式プロダクトではないとのことです。
PINS (P4 Integrated Network Stack)というプロジェクトのアーキテクチャに沿った実装 SONiC-PINSとして組み込まれます。
PINSについては上記ページから辿れるスライド(PDF)がわかりやすいと思います。
スライドに書かれている内部動作について軽くまとめると、
- SAIに沿ったP4テーブル定義
- P4Runtime Appがコントロールプレーンと通信し、APPL_DB(P4RTテーブル)に書き込む
-
orchagent
はP4RT
テーブルを読んで、ASIC_DBに書き込む - あとは通常のSONiCと同様にASIC操作
基本構造はTofinoとか関係なく、どのASICのスイッチでも動くもの、と言えそうです。P4プログラミングによるデータプレーン拡張はさすがにTofinoじゃないと無理な気がします。
組み込んだらどうなるのか
SONiC上でp4rt dockerが起動され、P4Runtime serverとしてRPCを受け付けるようになります。それにより、P4Runtime仕様に沿ったAPIが提供され、外部(コントロールプレーン)から操作できるようになります。なるはずです。
コントロールプレーンはどうやって用意するの? テーブル情報は?
Google P4 ProgramsにprotobufやC++ライブラリがまとめられてるので、これを使ってくださいということのようです。少し眺めてみるとactionsとかも定義されてるのですが、データプレーン定義として使われるわけではないようです。
組み込み方
git clone https://github.com/sonic-net/sonic-buildimage
cd sonic-buildiamge
echo INCLUDE_P4RT=yes > rules/config.user
- ビルド
なのですが、手元の都合でビルドにかなり時間がかかっていて、実際に動かしてみるのはまた後日、ということにさせてください。
構造上、CLIやREST API(management framework)とは併用しない前提だと思います。(整合性がとれなくなる)
おわりに
半端な紹介になってしまってすみませんが、理解の一助になれば幸いです。