Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NPLによるデータプレーンプログラミング
Search
Masaru OKI
January 29, 2020
Technology
8
2.3k
NPLによるデータプレーンプログラミング
2019年6月にBroadcomより公開された、データプレーン用プログラミング言語NPL(Network Programming Language)について、概要や文法および実装の現状を紹介します。
Masaru OKI
January 29, 2020
Tweet
Share
More Decks by Masaru OKI
See All by Masaru OKI
SONiCを自前でビルドする話
imasaruoki
1
950
Ansible把握した 1日目
imasaruoki
0
270
SONiC近況報告 2019/Fall
imasaruoki
1
1.2k
ホワイトボックススイッチをAnsibleで操る話
imasaruoki
2
2.3k
ホワイトボックススイッチとNOSを取り巻く状況について
imasaruoki
3
2.2k
SONICイントロダクション
imasaruoki
1
440
SONiCをはじめてみよう
imasaruoki
4
1.7k
SONiCで設定するFRRouting
imasaruoki
0
1.5k
SONiCトラブルシューティング
imasaruoki
4
470
Other Decks in Technology
See All in Technology
[CV勉強会@関東 ECCV2024 読み会] オンラインマッピング x トラッキング MapTracker: Tracking with Strided Memory Fusion for Consistent Vector HD Mapping (Chen+, ECCV24)
abemii
0
220
Incident Response Practices: Waroom's Features and Future Challenges
rrreeeyyy
0
160
【Pycon mini 東海 2024】Google Colaboratoryで試すVLM
kazuhitotakahashi
2
520
TanStack Routerに移行するのかい しないのかい、どっちなんだい! / Are you going to migrate to TanStack Router or not? Which one is it?
kaminashi
0
590
社内で最大の技術的負債のリファクタリングに取り組んだお話し
kidooonn
1
550
OCI Network Firewall 概要
oracle4engineer
PRO
0
4.1k
New Relicを活用したSREの最初のステップ / NRUG OKINAWA VOL.3
isaoshimizu
2
610
誰も全体を知らない ~ ロールの垣根を超えて引き上げる開発生産性 / Boosting Development Productivity Across Roles
kakehashi
1
230
初心者向けAWS Securityの勉強会mini Security-JAWSを9ヶ月ぐらい実施してきての近況
cmusudakeisuke
0
120
The Rise of LLMOps
asei
7
1.6k
これまでの計測・開発・デプロイ方法全部見せます! / Findy ISUCON 2024-11-14
tohutohu
3
370
AWS Lambdaと歩んだ“サーバーレス”と今後 #lambda_10years
yoshidashingo
1
170
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
The Pragmatic Product Professional
lauravandoore
31
6.3k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Speed Design
sergeychernyshev
25
620
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
What's new in Ruby 2.0
geeforr
343
31k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Transcript
NPLによる データプレーンプログラミング ネットワークプログラマビリティ勉強会 #19 Jan 29, 2020 Masaru OKI
[email protected]
Contents • 自己紹介 • スイッチ機器の構造 • データプレーンのプログラミング • NPL概説 •
まとめ • Appendix NPL詳解 • Appendix 2 他言語との比較 2
自己紹介 名前: 沖 勝 (おき まさる) 所属: 株式会社インターネットイニシアティブ プロダクト本部 SDN開発部 ネットワーク基盤開発課
主な業務: ホワイトボックススイッチを用いた、サービス基盤向け データプレーンの開発 3
調査の動機 一般のスイッチ製品でできないことを、実現したい。 ソフトウェア処理よりも高速に。 データプレーンのプログラミングで実現できるか調査する。 4 単なるパケット転送ではなく、 通常のスイッチ製品にない機能を 実現したい
スイッチ機器の構造 5
スイッチ機器のハードウェア構造 高速パケット転送のためスイッチASICを搭載し モニターやキーボード接続を排して ストレージやメモリサイズを小さめにした サーバーPCのような構造。 6 CPU Module (CPU+Mem+Storage) スイッチASIC
(Application Specific Integrated Circuit) PSU (Power Supply Unit) FAN SFP (Small Form-factor Pluggable)
実際に天板を開けてみた 7 スイッチASIC (Application Specific Integrated Circuit) PSU (Power Supply
Unit) FAN SFP (Small Form-factor Pluggable) CPU Module (CPU+Mem+Storage)
CPU ModuleとBMC 8 CPU Memory (8GB DDR4 SO-DIMM) Storage (M.2
SSD 64GB) BMC (Board Management Controller)
コントロールプレーンとデータプレーン スコープによってどこをそう呼ぶかが変わるので注意 9 サーバー = コントロールプレーン スイッチ = データプレーン CPU
Module = コントロールプレーン スイッチASIC = データプレーン
SDNの文脈だと通常はこちら OpenFlowなどでおなじみ 10 サーバー = コントロールプレーン スイッチ = データプレーン
今回の対象はこちら 11 CPU Module = コントロールプレーン スイッチASIC = データプレーン
データプレーンのプログラミング 12
スイッチASICによるパケット処理 • 通常のスイッチASICにおけるパケット処理の内部ブロック(概略) • ブロックはあらかじめ用意されていて処理順(パイプライン)は固定 • 各ブロック用のテーブルの種類や最大サイズも基本的に固定 • できることがあらかじめはっきりしていて機能追加はできない 13
packet in packet out parser match drop copy forward edit TCAM, SRAM ACL, LPM, etc. VLAN, IPv4, IPv6 TCP, etc. dst mac書換 VLAN変更 トンネル処理, etc. multicast, ACL, etc.
一般のスイッチ製品でできないことは? • どうやれば実現できる? • スイッチASICに機能が用意されていれば、コントロールプレーン次第 ◦ たとえばホワイトボックススイッチ用 OS • なかったら、無理?
◦ ソフトウェアで頑張ると遅い 14 単なるパケット転送ではなく、 通常のスイッチ製品にない機能を 実現したい ???
プログラマブルASIC • 従来のスイッチASICと比較して、 柔軟に構成変更ができ、ブロックの組み合わせやテーブルの内容、 サイズをカスタマイズできるASICが考案され、市場に出始めた。 • プログラマブルASICと呼ばれる。有名なのはBarefoot Tofino。 • FPGAのように回路を組むのではなく、パケット処理に特化した
プログラミング言語を用いてブロック、テーブル、処理内容を記述する。 • 従来のASIC制御(C言語によるSDKのAPI呼び出し)が用意される製品も。 15
プログラマブルASICを使うと • パイプラインに処理ブロックを追加し、独自の処理を加えられる • parserで処理できるパケットヘッダも自由に定義できる • テーブルも自由に定義し、サイズも変更できる 16 packet in
packet out parser match drop copy forward edit special action
プログラマブルASIC 製品あれこれ • Merchant Silicon ◦ 2014 Cavium XPliant ◦
2016 Barefoot (Intel) Tofino ◦ 2017 Broadcom Trident 3 ◦ 2017 Mellanox Spectrum-2 ◦ 2019 Broadcom Jericho2 ◦ 2019 Broadcom Trident 4 ◦ 2019 Marvell Prestera CX • Custom Silicon ◦ Juniper Trio ◦ Cisco UADP 17
プログラマブルASICの開発手段 • Cavium XPliant ◦ 独自言語によるparserおよびテーブル定義、Excelシートによるヘッダ定義、C言語によるアクション定義 ◦ NDAベースで、開発環境が一般公開されることはないままチップがdiscon • Barefoot
Tofino ◦ P4言語でparser、ヘッダ、テーブル、アクションを定義 • Mellanox Spectrum-2 ◦ P4(予定) • Marvell Prestera CX ◦ 不明 (SDKのAPIによる制御?) • Broadcom Trident 3 ◦ ソフトウェア開発者にはファームウェアバイナリが支給されるのみ ◦ 実質的にプログラマブルではなく機能が固定されたASICの扱い • Broadcom Trident 4 ◦ NPLでparser、ヘッダ、テーブル、アクションを定義(予定) 18
NPL概説 19
NPL • Network Programming Language • https://nplang.org/ ◦ 単に ‘NPL’
で検索すると、同名の別言語が引っ掛かるので注意 • Broadcomが開発した、オープンなデータプレーンプログラミング言語。 • 2019年6月に公開。仕様の最新バージョンは1.3 • 仕様書は表紙・目次含め80ページ。 • ターゲットはプログラマブルASIC、NIC、FPGA、ソフトウェアスイッチ。 • Broadcom Trident 4とJericho 2が対応予定。 20
イベント https://nplang.org/npl/events-list/ • OnCon Asia 2019: SDKLT and NPL •
SIGCOMM 2019: Building Efficient Packet Processing Flows with NPL • ONF CONNECT 2019: Building Efficient Network Stack with SDKLT and NPL 21
NPLの特徴 公式ページに記載されている特徴 • Customized table pipelines • Intelligent action processing
• Parallelism • Advanced logical table capabilities • An integrated instrumentation plane • Simple, intuitive control flow 22
NPLソースプログラム(例) program l2_switch { ing.usage_mode_create(...); ing.execute(); parse_begin(start); port_table_lookup(0); l2_host_table_lookup(0); resolve_destination();
do_packet_modif(); egr.usage_mode_create(...); egr.execute(); } struct l2_t { } parser_node start { extract_fields(ing_pkt.l2); } bus cmdbus_t cmdbus; logical_table port_table { keys { … } fields { … } } logical_table l2_host_table { } function resolve_destination() { } function do_packet_modif() { } パケットヘッダを定義。 パケットヘッダ 解析ツリーを定義。 key-fieldテーブルを定義。 処理を定義。 ・解析結果を変数に代入 ・パケットヘッダの変更 変数(メタデータ)を定義。 プログラムを定義。 受信パケットの一連の処理を記述。 パケット処理の起点。 23
l2_switchサンプルプログラム https://github.com/nplang/NPL-Example-Applications/tree/master/Layer-2 24
NPLによるデータプレーン開発の流れ NPLソース プログラム (*.npl) コンパイラ ツールチェイン (nlc, g++) バイナリ イメージ
ASIC あるいはエミュレータ 25
NPLを実際に試せる環境 • https://github.com/nplang/NPL-Tutorials • VirtualBox用のVMイメージ(NCSC_June_2019.ova)が配布されている。 ◦ インポートして使う。 ◦ Ubuntu 16.04LTSにNPL開発環境、エミュレータ、サンプルがインストールされている。
◦ NPLツール類はMITライセンス。 ◦ ユーザnpl、パスワードnplでログインする。 ◦ VMイメージ内に用意されているサンプル NPLプログラム ▪ npl_tidbits (NPLの構成要素を一通り並べたもの ) ▪ l2_switch ▪ l3_app • Trident4搭載スイッチ製品は、2020年に出荷される模様。 26
VM環境でl2_switchをビルドする export NPL_EXAMPLES=/home/npl/ncsc-1.3.3rc4/examples cd $NPL_EXAMPLES/l2_switch make fe_nplsim make nplsim_comp C++ソースコードを生成する。
生成されたコードはSystemCを呼び出す。 NPLコンパイラは nlc C++ソースコードをコンパイルし、 ネイティブ実行ファイルを生成。 fe_output/bmodel/bin/bmodel.sim 27
l2_switchを実行する make nplsim_run • 実行するとターミナルウィンドウが2つ開く。BMODELとBMCLI。 ◦ BMODELでは、ビルドしたバイナリ bmodel.simが起動する。 ◦ BMCLIではPythonで作られたシェルbmif_cli.pyが起動する。bmodel.simとsocket通信する。
• BMCLIで下記を実行すると、テーブルエントリ情報をBMODELに流し込む。 rcload /home/npl/ncsc-1.3.3rc4/examples/l2_switch/bm_tests/l2_test/tbl_cfg.txt • makeを実行したターミナルで下記を実行すると、 BMODELにパケットを送り込み、動作を確認できる。 python bm_tests/l2_test/test.py 28
l2_switch実行画面 BMCLI bmif_cli.py BMODEL bmodel.sim 29 test.py
l2_switchソースコード /home/npl/ncsc-1.3.3rc4/examples/l2_switch/npl の下にある。 config.iniにはコンパイラに渡すパラメータ(warning許容数など)が書かれている。 ~/ncsc-1.3.3rc4/examples/l2_switch$ ls -l npl total 28
-r--r--r-- 1 npl npl 284 Jun 7 13:51 config.ini -r-xr-xr-x 1 npl npl 2598 Jun 7 13:51 l2_bus.npl -r--r--r-- 1 npl npl 496 Jun 7 13:51 l2_header_format.npl -r-xr-xr-x 1 npl npl 2684 Jun 7 13:51 l2_parser.npl -r-xr-xr-x 1 npl npl 789 Jun 7 13:51 l2_sf_defines.npl -r-xr-xr-x 1 npl npl 7851 Jun 7 13:51 l2_switch.npl 30
l2_switch通信の実際 • ip linkなどで確認するとわかるが、vethは作られていない。 ◦ test.pyは9090/tcpでbmodel.simと接続していた。 • つまり、実通信をさばくデータプレーンとして素直には使えない。 ◦ これはl3_appなど他のサンプルも同様。
• 現状提供されている環境は、単体テスト用と割り切って使うしかない。 ◦ mininetで動かせるといいのだが …… • NPLソースコードの問題ではない。ツールチェインとライブラリ次第。 • 9090/tcpで通信し、vethとの間でパケットを橋渡しするプログラムを書けば仮想環 境でパケット転送を含め動作確認できるかもしれない。 31
NPLでできないこと • NPLの言語仕様の範囲で記述できない機能がある。たとえば ◦ パケットとは独立して保持する情報 (カウンターなど) ◦ キュー ◦ 優先制御
◦ 送出ポート選択 • NPLでは、外部にこれらを処理する機能ブロックが用意されていれば special_functionを定義して、NPLプログラムから呼び出すことができる。 実際にはベンダーがspecial_functionの情報を開発者に提供するだろう。 • special_functionは実装依存な点に注意。 32
special_functionの例 program l2_switch { ing.usage_mode_create(...); ing.execute(); parse_begin(start); port_table_lookup(0); l2_host_table_lookup(0); resolve_destination();
do_packet_modif(); egr.usage_mode_create(...); egr.execute(); } struct l2_t { } parser_node start { extract_fields(ing_pkt.l2); } bus cmdbus_t cmdbus; logical_table port_table { keys { … } fields { … } } logical_table l2_host_table { } function resolve_destination() { } function do_packet_modif() { } 33 program l2_switchの中で太字の部分が special_functionであり、 この例では示されていないが special_functionの宣言が必要。 用意されたサンプルにも存在する。
NPLはP4と何が違うのか • 開発の経緯 ◦ P4はスタンフォード大学の学術研究を発端として産学共同で開発・発展している。 ◦ NPLは(P4を参考にしつつ)企業(Broadcom)によって開発された。 • モデル ◦
P4で想定されるPISAはmatch-actionをつないでいくモデル。 ◦ NPLは複数テーブルを同時に lookupし並列処理できるよう設計されている。 • 言語仕様 ◦ P4はP4-16で仕様が大幅に拡張され、よりソフトウェア的になっている。 (154ページ) ◦ 一方NPLは言語仕様がコンパクト。 (80ページ) • 周辺環境 ◦ P4は言語としてだけでなく P4Runtimeなど周辺環境も整備されつつある。 ◦ NPLは現在、言語仕様および仮想実行環境のみ公開されている。 34
まとめ 35
まとめ • 2019年6月に、BroadcomからNPLが公開された。 • NPLはデータプレーン用プログラミング言語。 • 適用できるハードウェアはまだ市場にはない。 • 提供されるソフトウェア実装はテスト用のみだが、単体テストには十分。 •
P4_16と比べると仕様はシンプル。(といっても80ページ) • 競争が生まれることによる市場の活性化・健全化を期待したい。 36
リファレンス • NPL https://nplang.org/ • NPL github https://github.com/nplang/ • BCM56880
(Broadcom Trident 4) https://jp.broadcom.com/products/ethernet-connectivity/switching/strataxgs/bcm56880-series • P4 https://p4.org/ 37
Appendix: NPL詳解 38
NPLが想定するブロックダイヤグラム NPL v1.3仕様書 12ページより 39
NPLプログラムの構造 1. struct(パケットヘッダ)を定義する 2. ヘッダグループ用structとpacketを定義する 3. parser_nodeを定義する 4. logical_busを定義する 5.
logical_tableを定義する 6. 複雑さなど必要に応じてfunctionを定義する 7. programを定義する 40
struct(パケットヘッダ) • パケットヘッダを定義する。 • fieldsの内側にヘッダフィールドを並べる。 • bit(1bit)、bit[](固定長bit列), varbit(可変長bit列) • varbitを使う場合ヘッダ長計算式を別途指定。
• overlays指定でunionのようなことができる。 struct ipv4_t { fields { bit[8] vh: bit[8] tos; bit[32] sa; bit[32] da; varbit[320] option; } overlays { version: vh[7:4]; hdr_len: vh[3:0]; } header_length_exp: hdr_len*4; } struct vlan_t { fields { bit[3] pcp; bit cfi; bit[12] vid; bit[16] ethertype; } } 41
ヘッダグループとpacket • 複数のstructをまとめたものをヘッダグループと呼ぶ。ヘッダグループの定義も struct。 • ipv4とipv6など、一方のみ有効となるヘッダもまとめる。 (選択はparserにより実行) • ヘッダグループのfieldに書けるのはstructのみ。bitやvarbitを書くことはできない。 •
parseする最初のヘッダグループを指定し、 packetを定義する。 struct l2_t { fields { macs_t macs; vlan_t ctag; ethertype_t etype; } } struct l3_t { fields { ipv4_t ipv4; ipv6_t ipv6; } } struct ingress_packet_t { fields { l2_t l2; vlan_t vlan; l3_t l3; } } packet ingress_packet_t ing_pkt; 42 ヘッダグループ packet
header, header groupとpacketの関係 • NPL v1.3仕様書 21ページより。 • この場合、Header Groupをまとめたstructをpacketとして定義する。
43
parser_node • root_node: 1を指定したノードから順に解析していく。 • extract_fields(packet.header)でパケットヘッダの値を参照できるようにする。 • メンバーの値を参照し、 if else、switchで分岐する。
• next_nodeで次のノードの解析。 end_nodeで解析終了。 • parse_break, parse_continue parser_node start { root_node: 1; next_node ethernet; } parser_node ethernet { extract_fields(ing_pkt.l2); switch (latest.ethertype) { 0x8100 : {next_node ctag}; default: {next_node ingress}; } } parser_node ctag { extract_fields(ing_pkt.vlan); next_node ingress; } parser_node ingress { end_node : 1; } 44
logical_bus • フィールドの集まり、すなわち変数を定義する。 • structを指定することで作成できる。 • parser_nodeの中で参照でき、logical_tableやfunction(後述)の中で代入できる。 struct obj_bus_t {
fields { bit[16] port; bit[16] dst; bit dst_discard; bit[16] src; bit src_discard; bit[16] vid; } } bus obj_bus_t objbus; 45
logical_table • match actionテーブルを定義する。テーブルタイプは index, tcam, hash, alpm。(拡張可能) • キー(keys)はbitあるいはbit配列で指定。(structは書けない)
• 値(fields)はbit、bit配列あるいはauto_enumで定義する。(structは書けない) • key_construct()でパケットヘッダからキーを作る式を指定。 • field_assignment()でフィールドの値をlogical busに代入できる。 • 同一テーブルを2種の用途で使い分けできる。 lookup(0)とlookup(1)。 logical_table my_station_hit { table_type : tcam; maxsize : 512; minsize : 512; keys { bit[48] macda; bit[12] vid; } fields { bit[2] mpls_tunnel_type; bit local_l3_host; } key_construct() { macda = ing_pkt.l2.macs.macda; vid = obj_bus.vlan_id; } } 46
function, program • 処理のかたまりを定義する。パラメータを与えることはできない。 • 全ての演算を記述でき、全ての logical busを操作できる(パラメータ相当はlogical bus経由)。 •
parser, logical table lookup, editorなどを呼び出せる。 • programは最初に呼び出されるロジック。 parse_begin()でヘッダ解析開始。 function push_vlan_tag() { egr_pkt.vlan.vid = 100; egr_pkt.vlan.tpid = 0x8100; add_header(egr_pkt.vlan); } program app { parse_begin(start); my_station_hit.lookup(0); if (ing_pkt.l3.ipv4._PRESENT) { push_vlan_tag(); } } 47
special_function • ターゲットデバイス依存の機能を呼び出す。ベンダにより提供される。 ◦ チップの内蔵回路で実現される機能、既存の実装済みパケット処理ロジック ◦ パケットに含まれない (しかしパケット処理に必要な )情報の取得、設定 •
たとえばポート番号の情報をspecial_functionを用いて取得する。 special_function iarb { usage_mode_create(in const eindex, out bit[4] otpid_enable, out bit[1] ts_enable, out bit[7] port_num, out bit[2] port_type_cfg, out bit[16] currenttime ); usage_mode_select(in bit[1] eindex); } program app { iarb.usage_mode_create( 0, control_id.otpid_enable, control_id.ts_enable, obj_bus.port_num, obj_bus.port_type_cfg, time_bus.currenttime ); iarb.execute(); ... 48
extern • special_functionと似ている。外部機能をfunctionとして呼ぶ。 • Cのexternのように外部にあることを宣言する。 • 繰り返し何度も呼ばれる機能で使用される。 • 例 ◦
パケットのdrop ◦ CPUあるいは他ポートへのパケットのコピー ◦ パケットカウンタ 49 extern packet_drop(in bit[1] trigger, in const value, in const drop_code);
Editor パケットの編集機能。functionから呼び出す。 • add_header • delete_header • replace_header_field • create_checksum
• update_packet_length 50
その他の構文 • コメントはC++同様の /* … */ および // • C言語ライクなプリプロセッサ
◦ #include ◦ #ifdef …#else … #endif ◦ #define 51
NPLにないもの • 統計情報収集 • キュー制御 • メーター制御 • ポート制御 externやspecial_functionで機能が提供されるか、
あるいはNPLで書ける範囲外のところで制御すると思われる。 52
Appendix 2: 他言語との比較 53
値の表現 NPLは10進数と16進数のみでシンプル。負数がない。 NPL P4-14 P4-16 (参考)C 10進数 42 42 42
42 2進数 0b101010 0b101010 8進数 0o52 052 16進数 0x2a 0x2a 0x2a 0x2a ビット幅指定 (fieldに合わせる) 8’42 8w42 (fieldに合わせる) マイナス値 -42 -42 -42 54
型 NPLにはtypedefがなく、整数や文字列は定数のみ。 NPL P4-14 P4-16 (参考)C ビット bit var; var:
1; bit var; int var: 1; ビット列 bit[16] var; var: 16; bit<16> var; int var:16; 可変長ビット列 varbit[32] var; var: *; varbit<16> var; 32bit符号なし整数 constのみ uint32_t var; int<32> var; uint32_t var; 文字列 print(即値);のみ string var; char [] var; 型名定義 (#define) typedef typedef typedef 55
演算子 P4-14には除算がない。 NPL P4-14 P4-16 (参考)C 四則演算+剰余 +, *, -,
/, % +, *, - +, *, -, /, % +, *, -, /, % ビット演算 &, |, ^ &, |, ^ &, |, ^ &, |, ^ ブール演算 ||, && or, and or, and, ||, && ||, && 比較演算 !=, ==, <. >, <=, >= !=, ==, <. >, <=, >= !=, ==, <. >, <=, >= ne, eq, le, ge !=, ==, <. >, <=, >= 56
制御構文 for, whileなどの繰り返し構文はNPL, P4ともに用意されていない。 NPL P4-14 P4-16 (参考)C 条件分岐 if
(expr) { func; } else { func; } if (expr) { func; } else { func; } if (expr) { func; } else { func; } if (expr) { func; } else { func; } 値による分岐 switch (expr) { 値1: { … } default: { … } } (parser内のみ) return select (expr) { 値1: name; default: ... } switch (expr) { 値1: { … } default: { … } } switch (expr) { case 値1: …; break; default: …; } 57
パケットヘッダ定義 どれもほぼ似通っている。 struct ipv4_t { fields { bit[4] version; bit[4]
hdr_len; bit[8] tos; bit[32] sa; bit[32] da; varbit[320] option; } header_length_exp:hdr_len*4; } header_type ipv4_t { fields { version : 4; hdr_len : 4; tos : 8; sa : 32; da : 32; option : *; } length: hdr_len*4; } header ipv4_t { bit<4> version; bit<4> hdr_len; bit<8> tos; bit<32> sa; bit<32> da; varbit<320> option; } NPL P4-14 P4-16 58
parser parser_node start { root_node: 1; next_node ethernet; } parser_node
ethernet { extract_fields(ing_pkt.l2); switch (latest.ethertype) { 0x8100 : {next_node ctag}; default : {next_node ingress}; } } parser_node ctag { extract_fields(ing_pkt.vlan); next_node ingress; } parser_node ingress { end_node : 1; } NPL P4-14 P4-16 parser ethernet { extract(l2); return select (latest.ethertype) { 0x8100 : ctag; default : ingress; } } parser ctag { extract(vlan); return ingress; } parser GenericParser(packet_in b, out Packet_header p) { state start { b.extract(p.l2); transition select (p.l2.ethertype) { 16w0x8100 : ctag; } } state ctag { b.extract(p.vlan); accept; } 59
テーブル定義 P4はmatchと組にする選択可能なactionを書く。NPLは値。 logical_table my_station_hit { table_type : tcam; maxsize :
512; minsize : 512; keys { bit[48] macda; bit[12] vid; } fields { bit[2] mpls_tunnel_type; bit local_l3_host; } key_construct() { macda = ing_pkt.l2.macda; vid = obj_bus.vlan_id; } } NPL P4-14 P4-16 table my_station_hit { reads { l2.macs.macda: exact; l2.vlan.vlan_id: exact; } actions { add_mTag; common_copy_pkt_to_cpu; no_op; } min_size : 512; max_size : 512; } table my_station_hit { key - { l2.macs.macda: exact; l2.vlan.vlan_id: exact; } actions - { add_mTag; common_copy_pkt_to_cpu; no_op; } default_action - no_op; } 60