コンテンツにスキップ

3. 概要

従来のスイッチとプログラマブルスイッチの比較。
図1. 従来のスイッチとプログラマブルスイッチの比較。

P4は、ハードウェア/ソフトウェアスイッチ、ネットワークインターフェースカード、 ルーター、あるいはネットワーク・アプライアンスといった、 プログラマブルな転送要素のデータプレーンによって、 パケットがどのように処理されるかを記述するための言語です。 P4という名称は、この言語を紹介した元の論文である"Programming Protocol-independent Packet Processors"(プロトコル非依存のパケットプロセッサのプログラミング、 https://arxiv.org/pdf/1312.1719.pdf )に由来しています。 P4は当初スイッチのプログラミング用に設計されましたが、 その範囲は多種多様なデバイスをカバーするように拡張されています。 以降、このドキュメントでは、これらすべてのデバイスを指す一般的な用語として「ターゲット」を使用します。

多くのターゲットはコントロールプレーンとデータプレーンの両方を実装しています。 P4は、ターゲットのデータプレーン機能のみを記述するよう設計されています。 P4プログラムは、コントロールプレーンとデータプレーンが通信するインターフェースも部分的に定義しますが、 ターゲットのコントロールプレーン機能を記述するためにP4を使用することはできません。 以降、このドキュメントでは、私達がP4で「ターゲットをプログラミングする」と表現する場合、 それは「ターゲットのデータプレーンをプログラミングする」ことを意味します。

ターゲットの具体的な例として、図1は従来の固定機能スイッチとP4プログラマブルスイッチの違いを示しています。 従来のスイッチでは、製造元がデータプレーンの機能を定義します。 コントロールプレーンはテーブル(例: ルーティングテーブル)のエントリを管理したり、 専用のオブジェクト(例: メーター)を設定したり、 制御パケット(例: ルーティングプロトコルパケット)やリンク状態の変化や学習通知などの非同期イベントを処理したりすることによって、 データプレーンを制御します。

P4プログラマブルスイッチは従来のスイッチとは2つの本質的な点で異なります。

  • データプレーンの機能は事前に固定されておらず、P4プログラムによって定義されます。 データプレーンは初期化時に、P4プログラムで記述された機能を実装するように設定され(長い赤色の矢印で示されています)、 既存のネットワークプロトコルに関する組み込みの知識を一切持っていません。
  • コントロールプレーンは固定機能デバイスと同じチャンネルを用いてデータプレーンと通信します。 しかし、データプレーン内のテーブルやその他のオブジェクトのセットは、P4プログラムによって定義されるため、もはや固定されていません。 コントロールプレーンがデータプレーンとの通信に使うAPIはP4コンパイラによって生成されます。

このように、P4はプロトコル非依存であると言えますが、 これによってプログラマーは豊富なプロトコルのセットや、 その他のデータプレーンの動作を表現することが可能になります。

P4を用いたターゲットのプログラミング。
図2. P4を用いたターゲットのプログラミング。

P4言語によって提供される中核的な抽象化は以下の通りです。

  • ヘッダ型(Header types) はパケット内の各ヘッダのフォーマット(フィールドのセットとそれらのサイズ)を記述します。
  • パーサー(Parsers) は受信パケット内で許可されるヘッダの順序、それらのヘッダの順序を識別する方法、 およびパケットから抽出するヘッダとフィールドを記述します。
  • テーブル(Tables) はユーザー定義のキーとアクションを関連付けます。 P4テーブルは従来のスイッチテーブルを一般化したもので、ルーティングテーブル、フロールックアップテーブル、 アクセスコントロールリスト、その他のユーザー定義のテーブルタイプ(複雑な多変数決定を含む)を実装するために使用できます。
  • アクション(Actions) はパケットのヘッダフィールドとメタデータがどのように操作されるかを記述するコード断片です。 アクションには、実行時にコントロールプレーンから提供されるデータを含めることができます。
  • マッチアクションユニット(Match-action units) は以下の連続した操作を実行します。
    • パケットフィールドまたは計算されたメタデータからルックアップキーを構築する。
    • 構築されたキーを使用してテーブルルックアップを実行し、実行するアクション(関連するデータを含む)を選択する。
    • 最後に、選択されたアクションを実行する。
  • コントロールフロー(Control flow) はターゲット上でのパケット処理を記述する命令型プログラムであり、 データに依存したマッチアクションユニットの呼び出しシーケンスを含みます。デパーシング(パケットの再構築)も、コントロールフローを使用して実行できます。
  • 外部オブジェクト(Extern objects) はアーキテクチャ固有の構成要素であり、明確に定義されたAPIを通じてP4プログラムから操作できますが、 その内部動作はハードワイヤード(固定)であり(例: チェックサムユニット)、したがってP4を用いてプログラムすることはできません。
  • ユーザー定義メタデータ(User-defined metadata) は各パケットに関連付けられる、ユーザーが定義したデータ構造です。
  • 組み込みメタデータ(Intrinsic metadata) は各パケットに関連付けられるアーキテクチャから提供されるメタデータ(例: パケットが受信された入力ポート)です。

2は、P4を用いてターゲットをプログラミングする際の典型的なツールワークフローを示しています。

ターゲットの製造元は、ハードウェアまたはソフトウェアの実装フレームワーク、アーキテクチャ定義、およびそのターゲット用のP4コンパイラを提供します。 P4プログラマーは、特定のアーキテクチャ向けのプログラムを作成します。 このアーキテクチャは、ターゲット上にあるP4でプログラム可能なコンポーネントのセットと、それらの外部データプレーンインターフェースを定義するものです。

P4プログラムのセットをコンパイルすると、以下の2つの成果物が生成されます。

  • 入力プログラムに記述された転送ロジックを実装するデータプレーン設定
  • コントロールプレーンからデータプレーンオブジェクトの状態を管理するためのAPI

P4はプログラマブル・ネットワークインターフェースカード、FPGA、ソフトウェアスイッチ、 ハードウェアASICといった多種多様なターゲット上で実装できるように設計されたドメイン固有言語です。 そのため、P4言語はこれら全てのプラットフォーム上で効率的に実装できる構成要素のみに制限されています。

テーブル検索操作や外部オブジェクトとのやりとりにかかるコストを一定と仮定した場合、 全てのP4プログラム(すなわち、パーサーとコントロールブロック)は受信・解析される入力パケットの各バイトあたりに一定回数の操作を実行します。 パーサーはループを含むことがありますが、各サイクルで何らかのヘッダが抽出される限りにおいて、パケット自体が総実行回数に上限を与えます。 言い換えれば、これらの仮定のもとでは、P4プログラムの計算量は、全ヘッダの合計サイズに対して線形であり、データ処理中に蓄積された状態のサイズ(例: フロー数や処理された総パケット数)には決して依存しません。 これらの保証は、多種多様なターゲットで高速なパケット処理を可能にするための必要条件です(ただし十分条件ではありません)。

ターゲットのP4準拠性(P4 conformance)は、以下のように定義されます。 もし特定のターゲットTがP4プログラミング言語のサブセット(仮にP4Tとします)しかサポートしていない場合、そのターゲット上で実行されるP4Tで書かれたプログラムは、このドキュメントに記述されているものと全く同じ動作を提供しなければなりません。なお、P4に準拠したターゲットは任意のP4言語拡張やextern要素を提供することができます。

Compared to state-of-the-art packet-processing systems (e.g., based on writing microcode on top of custom hardware), P4 provides a number of significant advantages:

  • Flexibility: P4 makes many packet-forwarding policies expressible as programs, in contrast to traditional switches, which expose fixed-function forwarding engines to their users.
  • Expressiveness: P4 can express sophisticated, hardware-independent packet processing algorithms using solely general-purpose operations and table look-ups. Such programs are portable across hardware targets that implement the same architectures (assuming sufficient resources are available).
  • Resource mapping and management: P4 programs describe storage resources abstractly (e.g., IPv4 source address); compilers map such user-defined fields to available hardware resources and manage low-level details such as allocation and scheduling.
  • Software engineering: P4 programs provide important benefits such as type checking, information hiding, and software reuse.
  • Component libraries: Component libraries supplied by manufacturers can be used to wrap hardware-specific functions into portable high-level P4 constructs.
  • Decoupling hardware and software evolution: Target manufacturers may use abstract architectures to further decouple the evolution of low-level architectural details from high-level processing.
  • Debugging: Manufacturers can provide software models of an architecture to aid in the development and debugging of P4 programs.

\~ Figure { #fig-p4transition; caption: “Evolution of the language between versions P414 (versions 1.0 and 1.1) and P416.” } [p4transition] \~ [p4transition]: figs/p4transition.png { width: 100%; page-align: forcehere }

Compared to P414, the earlier version of the language, P416 makes a number of significant, backwards-incompatible changes to the syntax and semantics of the language. The evolution from the previous version (P414) to the current one (P416) is depicted in Figure [#fig-p4transition]. In particular, a large number of language features have been eliminated from the language and moved into libraries including counters, checksum units, meters, etc.

Hence, the language has been transformed from a complex language (more than 70 keywords) into a relatively small core language (less than 40 keywords, shown in Section [#sec-p4-keywords]) accompanied by a library of fundamental constructs that are needed for writing most P4.

The v1.1 version of P4 introduced a language construct called extern that can be used to describe library elements. Many constructs defined in the v1.1 language specification will thus be transformed into such library elements (including constructs that have been eliminated from the language, such as counters and meters). Some of these extern objects are expected to be standardized, and they will be in the scope of a future document describing a standard library of P4 elements. In this document we provide several examples of extern constructs. P416 also introduces and repurposes some v1.1 language constructs for describing the programmable parts of an architecture. These language constructs are: parser, state, control, and package.

One important goal of the P416 language revision is to provide a stable language definition. In other words, we strive to ensure that all programs written in P416 will remain syntactically correct and behave identically when treated as programs for future versions of the language. Moreover, if some future version of the language requires breaking backwards compatibility, we will seek to provide an easy path for migrating P416 programs to the new version.