個人的なメモであり,私の考えと教えていただいたことがごちゃまぜになっています.
誰の役に立つのか分かりませんが,備忘録も兼ねてここに残します.
座学
P4とは
データプレーンをプログラマブルにする目的
ユースケースに合わせたリソースの配分
1種類のHWで複数のユースケースに対応
新しいアプリケーション,機能の実装
パケットへの情報の埋め込み
独自ヘッダの定義(Telemetry, OAM)
新しいプロトコルのサポート(VXLAN)
新しい領域への適応(GTP, SFC)
ASICの改修には1,5~2年程度必要
トップダウンからボトムアップへ
ASICの機能→SWが実現可能な機能
SWで実現したい機能→ASICの機能
利点
新しい機能,複雑さを削減,リソースの有効活用,優れた視認性
ターゲット
SW ASIC xx Tbps
Eth SW
FPGA xxxGbps
Smart NIC
NPU xx Gbps
Smart NIC
CPU x Gbps (BMv2, eBPF | p4lang, p4c)
Server, VM, CT
何ができる?
SilkRoad, NDP, INT, NetCache/NetChain, Blink, ...
2015 - 2019年の論文
P4コードの書き方
PISA, Protocol-Independent Switch Architecture
- Parser
- Match-Action Pipeline
- Deparser
V1Model
ingress_port: 物理ポート
egress_spec: どのポートで出したいのか,ingressパイプライン中で決める
egress_port: パイプライン中で読み取ることができ,パケットがどのポートから出力されるかを示す
テーブルの中のデータはjsonファイルとして別で持っておく
isValid, setValid, setInvalidを用いてヘッダの有効性の記述が可能
ipヘッダなど,プラットフォームによっては予め用意されている場合もある
特殊なデータ型
struct: メンバは順序付けられない
Header Stack: ヘッダの配列
Header Union: ヘッダの共用
VLANなど,入ったり入らなかったりするものはetherTypeで条件分岐をつけて表せる
テーブルを使う書き方,使わない書き方(逐次実行 or actionを使用),両方できる
プラットフォーム側でJSONファイルの場所を制御している
プログラムで制御するものではない
「このエントリは入れておきたい」ものがあれば,プログラムにハードコードすることもできる
テーブルのデータを書き換えることで挙動を変える動作も想定されている.
match_kindというP4特有の型がある
core.p4にexact, lpm(longest prefix match), ternalyがある
プラットフォームごとに追加の実装があったりなかったり
action drop(){
mark_to_drop();
}
packet_outがcore.p4にある.
これを使って,packet_out型のpacketを引数として受け,
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
...
と示すと,チェックを経て問題なければ挿入される.
パーサを通すと,ヘッダ情報がバラされる(パイプライン部にはペイロードしか通らない)
そのため,デパーサで組み立て直す必要がある
meta, std_metaは全く別物
std_metaは決まっている
metaはユーザ定義のものなど (?)
ペイロードは触らない
フラグメントしたいときとか,どうするといい?
→ できない
ペイロードの先頭にあるなら,それをヘッダとして書いて読み書きすることは可能
→ アプリケーションレイヤまで見ることもできなくはないが,可変長の領域に対応できないので,現実的に難しいケースが多い
ハンズオン
OSSのパケットジェネレーター
機能のテスト:scapy
https://github.com/secdev/scapy
性能測定:TRex(Cisco)
https://github.com/cisco-system-traffic-generator/trex-core
https://github.com/cisco-system-traffic-generator/trex-stateless-gui
https://github.com/cisco-system-traffic-generator/trex-emu
- DPDKによりKernelをバイパスするので,ホスト内でpcapしても見えない
- DPDKでNICを専有するので,SSH他用のNICが別途必要
詳細:https://qiita.com/Shakapon/items/128f8d39cdacb8f1fc0a
P4関連の出版物
https://p4.org/publications/
eBPFなど,CPU上で動かす状況で動的にテーブルを変更したい,どうすれば?
P4Runtimeを使おう
gRPC準拠のAPIで操作できる
参考:https://github.com/yyasuda/P4Runtime-firstbite/blob/master/docs_ja/README.md
参考:https://qiita.com/yyasuda/items/99d96895d43eb49cee15
ubpfなどの実行環境側でgRPCに準拠して動作を変更できるようにすれば,P4Runtimeで制御できる
※SWでgRPCサーバが動作している必要がある
実行環境にハードコードしてしまうことで初期値を無理やり設定することはできるはず
tofinoなどであれば,それ用のコマンドが用意されている
tableのsize
テーブルエントリのサイズ
例:1024とセットすると,1024行
書かないとコンパイラが勝手に決める
tofinoなど,制約の厳しい環境では無駄が生じやすい.手動で指定したほうがよいかも
P4動向(IPDK, SONiC DASH)
IPDKに加え,SONiCによるDASHもP4を使用して開発中
https://github.com/sonic-net/DASH
IPDK
VXLANのカプセル化やFWなどの機能をスマートNICにオフロード
infrap4d:P4デバイスをTDIを通して制御するソフトウェア
p4rt-ctl - (gNMI/p4runtime) - infrap4d (tdi) - P4
Linux Networkingの構成
a) DPDKベース (SWベース)
linux_networking.p4を読もう
b) ES2Kベース (HWベース, Intel IPU E2000)
SONiC
IP CLOSファブリックを実現可能
ホワイトボックスSWにインストールするNW-OS
SONiC DASH
SONiCのアーキテクチャを流用して,スマートNICやスマートSWで動かすプロジェクト
Microsoftがこれを使っている模様
opencompute.org 2023-icp-global-summit
Alibabaも
opencompute.org 2023-icp-global-summit
SDNコントローラからgNMIによる制御が可能
SONiCのアーキテクチャからの主な変更点
1. SWデバイス→P4デバイス
2. デバイスドライバ→DASHドライバ