# SDN P4 的那些事 - by Zephyr Huang 這裡會將學習 P4 過程記錄下來,如果內容有任何錯誤歡迎糾正 ## 基礎環境問題 ### BMv2 BMv2 是一個軟體包,用於模擬和測試基於 P4 語言設計的可編程網路設備的行為。它提供了一個靈活的框架,允許用戶定義和測試各種網路數據平面行為。 #### 監看當前 BMv2 中有哪些 Table Entries 1. simple_switch_CLI --thrift-port <port_number> - port_number: 通常從 9090 開始,或是可以從 P4RuntimeSwitch 的 init 中透過斷點查看指定的 switch 是哪個 port 2. table_dump <table_name> - table_name: 此處填寫要查看的 table 名稱,對應的就是在 P4 中撰寫的 table - Ex: table_dump ipv4_lpm ### simple_switch simple_switch 是 BMv2 中的一個具體的數據平面實現。它是基於 P4 語言的簡單交換機模型,通常用於學術研究和開發環境中來測試和驗證 P4 程式。 ### V1Switch 基於 simple_switch 的 Data plane 資料處理 pipeline,決定一個封包要經過的流程以及每個流程會帶入的參數。 ## Pipeline 過程 以下會使用 V1Switch 作為代表 ### Parser #### 參數 1. packet_in (型態固定) - 封包本人 2. headers (型態自訂) - 可以自訂想要的 header 資料型態 3. metadata (型態自訂) - 可以自訂想要的 metadata 型態 4. standard_metadata_t (型態固定) - 系統定義型態,存放系統所需 metadata - 參數的順序是固定的無法自行更動,同時參數量也是固定的就這幾個欄位而已 #### 會使用到的方法 1. packet.extract(header) - 將封包根據指定的 header 類型提取 header - extract 會直接根據給定的 header 內部的變數提取指定的 bit 數量,不會管當前正常來說某個欄位應該是 x bit 但是我們卻指定 y bit,同時是根據 header 聲明變數時的順序進行提取的,所以在 header 中定義的順序也很重要。 2. packet.lookahead\<header>() - lookahead 可以偷看下一個部分的 header 內容 - 需要在 <> 中說明要偷看的 header 類型,後面的 () 表示 lookahead 是一個 function 所以需要使用 () 執行。 - 可以用在 transition select 當中,先偷看如果用某種 header 是否可以正常解析,如果可以在跳到指定的 state 當中使用 packet.extract(header) 完整解析。 - 如果發生使用 lookahead 時指定的 header 無法正常解析會直接跳到 transition 的 default。 3. extract v.s. lookahead - 上面有提到如果在進行 lookahead 時發生解析失敗會直接到 default 執行,那可能就會有疑問,為何不直接使用 extract 反正解析失敗也會到 default。 - 當解析失敗時還需要解析其他 header 時就會需要使用 lookahead 因為即使解析失敗也不會導致當前的解析頭位置錯誤,如果使用 extract 則解析失敗時解析頭也已經移動到錯誤的位置了。 ### Ingress && Egress #### 參數 1. headers (型態自訂) 2. metadata (型態自訂) 3. standard_metadata_t (型態固定) #### 會用到的方法 1. table - 在 Data plane 中主要控制封包要怎麼傳送的方法 - 主要內容 key, actions - key: 提供 Control plane 添加 match 的規則 - actions: 提供 Control plane 添加 action 的規則 - 其他內容 - default_action: 在沒有指定 match 到時需要執行的 action 時默認執行的內容 - entries: 可以在 Data plane 創建時直接添加 table entries 不依靠 control plane(多數情況下不會使用,只有在測試的時候使用) - table.apply.hit() - 如果有 match 到該 table 的某個 entry 會是 true 反之 false ## V1Model V1Model 是基於 P4 官方提供基於 BMv2 實現的 switch 包含兩種(simple_switch, simple_switch_grpc)。 同時提供最常使用的 Pipeline 框架 V1Switch。 ### 一些細節的內容 1. 到底是誰定義每個模組當中帶入的參數 - 哪些是模組 1. parser 2. control - 定義模組有哪些參數以及順序的是交換機 2. Pipeline 的順序是怎麼定義的 - Ex: V1Switch 為什麼一定是以下的順序 1. Parser 2. VerifyChecksum 3. Ingress 4. Egress 5. ComputeChecksum 6. Deparser - Pipeline 的順序是根據最終的交換機決定,如果最終的交換機不是 P4 官方提供的 simple_switch 系列就會使用不同的 pipeline 3. extern 相關的東西 1. extern 的聲明方法 ```c++ extern <module_name> { <function_name>(<function_parameters>) } ``` - 當硬體提供的函數是放在某個指定的模塊時使用 - 只需將該模塊中會使用到的函數引入即可 ```c++ extern <function_name>(<function_parameters>) ``` - 當硬體提供的函數是全局類型的時候使用 2. module_name - 模塊的名稱須根據實際的交換機決定 3. function_name - 外部函數名稱須根據實際交換機決定 4. function_parameters - 函數帶入的參數須根據實際交換機決定 ## Tofino ## 將封包從 CPU port 發送出去並且可以收到 1. 在 onl 的機器上透過 `ip a` 檢查所有的網卡 - 基本上會找到 enp4s0f0, enp4s0f1 這兩個網卡 - 在 10.30.3.67 的機器上 - enp4s0f0 對應上 port 66 - enp4s0f1 對應上 port 64 2. 將需要的網卡開啟 - 將網卡啟用 - ip link set dev enp4s0f0 up - 設定 ipv4 (不確定是否真的需要,但是如果開啟後他沒有自動給要記得設定,否則走 ipv4 的封包會收不到) - sudo ip addr add 192.168.1.100/24 dev eth0 - 設定 ipv6 - sudo ip -6 addr add 2001:db8::1/64 dev eth0 3. 啟動 tofino 4. 將對應到 server 的 port 開啟以及對應到 CPU port 開啟 - port 64: 應該會是 33/0 - port 66: 應該會是 33/2 - 同時 CPU port 的也是 10G 5. 透過 server 發送 ICMP 或是使用 scapy (但需要指定 mac address) 發送封包 6. 確認在 onl 系統中有收到對應的封包 ### P4 內容 直接將所有的封包不進行任何處理只設定 egress port 是 CPU port 就可以
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up