はじめに
今回はこれまでのOpen Networking(オープンネットワーキング)について取り上げた記事とは少し方向性を変えて、P4というネットワークデータプレーンを記述することができる言語とその実装例について紹介します。
他にもOpen Networkingに関わる記事がありますので、以下「記事一覧はこちら」からご興味のある記事をご覧ください。
P4とは??
P4(Programming Protocol-Independent Packet Processors)とはネットワークデータプレーンを記述するためのプログラミング言語です。既存のネットワークプロトコルに依存しないため、ユーザが独自に定義したプロトコル及びプロトコルスタックを組むことが可能となっています。
また、様々なハードウェアを使用することができるため、ユーザーの要求に合わせて最適なプラットフォームを選択できます。従来だとユーザー側でデータプレーンを気軽に変更することはできませんでしたが、P4ではプログラムの編集によって素早い開発サイクルでデータプレーンを自由に変更できます。
P4のターゲットとなるハードウェア
P4のユースケース
P4には様々なユースケースが考えられますが、いくつか代表的なものを紹介します。
P4ユースケース
P4でNATを実装
今回はP4に対応しているハードウェアとしてFPGAが搭載されているインテル® PAC N3000を使用してNAT機能を実装してみましたので簡単に解説します。
インテル® PAC N3000
NATの実装イメージ
今回は以下の図のようなイメージのNAT機能をP4を使用してFPGA Smart NICに実装しました。
入ってきたパケットのIPアドレス、ポート番号の条件に応じて、それぞれを書き換えるマッチ&アクションテーブルをP4で記述していきます。
NAT機能実装イメージ
P4コードの記述
今回はすべてのP4記述を解説することはできませんが、ポイントとなる部分を紹介します。
まず解説してくのはマッチ&アクションテーブルの記述です。テーブル記述の上部readsで記載されているのは条件として読み込むパラメーターとなります。今回の記述ではIPアドレス、TCP/UDPのポート番号を条件とするように記述しています。
続いてテーブル記述下部のactionsでは条件が一致した際に実行するアクションをリストしています。このような記述をすることによって入ってきたパケットのヘッダーの条件でどのアクションを実行するかを指定することが可能となります。
条件が一致した際に実行されるアクションは別途記述することが必要です。詳しく解説はしませんが、今回はNATを実装するということでアドレスとポート番号を変換するよう記述をしています。
記述が完了したらP4コードはFPGA Smart NIC用のコンパイラーを使用してコンパイルし、バイナリーイメージをFPGAに書き込みます。
テーブルの記述
アクションの記述
マッチ&アクションルールの設定
先ほどの記述でFPGA内にNAT用のマッチ&アクションテーブルが実装されましたが、それだけではNATとして動作しません。デフォルトではテーブルは空の状態となっているので、ユーザー側でルールを投入してあげることが必要となります。
インテル® PAC N3000ではサーバーからコマンドラインでルールが投入できるようなSDKが提供されています。
以下の例のようにルールを設定した場合、ソースアドレスが1.1.1.1でデスティネーションアドレスが2.2.2.2、TCPのソースポートが1000、デスティネーションポートが2000の条件に一致するパケットが入力されると、デスティネーションアドレスとポートがそれぞれ10.10.10.10:1111と書き換えられるようになります。
必要に応じてルールの追加/変更/削除をおこなうことで意図した動作となるようにコントロールが可能です。
# table_nat keys ( ipv4.srcAddr 1.1.1.1 ipv4.dstAddr 2.2.2.2 tcp true tcp.srcPort 1000 tcp.dstPort 2000 udp false udp.srcPort 0 udp.dstPort 0 ) action dstnat_tcp params ( ipaddr 10.10.10.10 port 1111 )
実動作検証
最後に実際に動作させた際の結果も載せておきます。
以下のようなルール設定をおこない、パケット入力後に出力されたものをキャプチャーしました。
パケットをフィルターすることもできるのでFirewallとして使うこともできます。
# table_nat keys ( ipv4.srcAddr 10.10.10.10 ipv4.dstAddr 20.20.20.20 tcp true tcp.srcPort 1000 tcp.dstPort 2000 udp false udp.srcPort 0 udp.dstPort 0 ) action dstnat_tcp params ( ipaddr 2.2.2.2 port 2222 )
# table_nat keys ( ipv4.srcAddr 10.10.10.10 ipv4.dstAddr 20.20.20.20 tcp false tcp.srcPort 0 tcp.dstPort 0 udp true udp.srcPort 1000 udp.dstPort 2000 ) action drop_act
# table_nat keys ( ipv4.srcAddr 30.30.30.30 ipv4.dstAddr 40.40.40.40 tcp true tcp.srcPort 3000 tcp.dstPort 4000 udp false udp.srcPort 0 udp.dstPort 0 ) action drop_act
# table_nat keys ( ipv4.srcAddr 30.30.30.30 ipv4.dstAddr 40.40.40.40 tcp false tcp.srcPort 0 tcp.dstPort 0 udp true udp.srcPort 3000 udp.dstPort 4000 ) action srcnat_udp params ( ipaddr 3.3.3.3 port 3333 )
入力と出力のパケットをキャプチャーしたものが以下になります。
きちんとルール通りにパケットの処理がされているのがお分かりいただけるかと思います。
インプットのパケット
アウトプットのパケット
最後に
今回の記事ではP4の概要とNATの実装例を紹介しました。
通常FPGAを使って同じような機能をP4を使わずに実現すると、HDLのコード量が多く検証にもかなりの時間がかかりますが、今回はP4を使って開発することでコード数も400行程度で動作検証までは2日程度でできました。また、FPGA開発のスキルがなくてもP4のみで開発できる点もメリットです。
もしP4コードのご要望がございましたら下にあるお問合せボタンから必要事項を入力の上お問い合わせください。
関連する情報
資料一覧はこちら
マクニカが取り扱う製品のご紹介のほか、
BGPクロスネットワーク自動構築ファイルやネットワーク運用試験評価レポートなど、オープンネットワーキングに関する資料を掲載しております。
詳細はこちら
製品ページTopへ
お問い合わせ
本記事に関してご質問などありましたら、以下より問い合わせください。