SDN P4 的那些事 - by Zephyr Huang
這裡會將學習 P4 過程記錄下來,如果內容有任何錯誤歡迎糾正
基礎環境問題
BMv2
BMv2 是一個軟體包,用於模擬和測試基於 P4 語言設計的可編程網路設備的行為。它提供了一個靈活的框架,允許用戶定義和測試各種網路數據平面行為。
監看當前 BMv2 中有哪些 Table Entries
- simple_switch_CLI –thrift-port <port_number>
- port_number: 通常從 9090 開始,或是可以從 P4RuntimeSwitch 的 init 中透過斷點查看指定的 switch 是哪個 port
- 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
參數
- packet_in (型態固定)
- headers (型態自訂)
- metadata (型態自訂)
- standard_metadata_t (型態固定)
- 參數的順序是固定的無法自行更動,同時參數量也是固定的就這幾個欄位而已
會使用到的方法
- packet.extract(header)
- 將封包根據指定的 header 類型提取 header
- extract 會直接根據給定的 header 內部的變數提取指定的 bit 數量,不會管當前正常來說某個欄位應該是 x bit 但是我們卻指定 y bit,同時是根據 header 聲明變數時的順序進行提取的,所以在 header 中定義的順序也很重要。
- packet.lookahead<header>()
- lookahead 可以偷看下一個部分的 header 內容
- 需要在 <> 中說明要偷看的 header 類型,後面的 () 表示 lookahead 是一個 function 所以需要使用 () 執行。
- 可以用在 transition select 當中,先偷看如果用某種 header 是否可以正常解析,如果可以在跳到指定的 state 當中使用 packet.extract(header) 完整解析。
- 如果發生使用 lookahead 時指定的 header 無法正常解析會直接跳到 transition 的 default。
- extract v.s. lookahead
- 上面有提到如果在進行 lookahead 時發生解析失敗會直接到 default 執行,那可能就會有疑問,為何不直接使用 extract 反正解析失敗也會到 default。
- 當解析失敗時還需要解析其他 header 時就會需要使用 lookahead 因為即使解析失敗也不會導致當前的解析頭位置錯誤,如果使用 extract 則解析失敗時解析頭也已經移動到錯誤的位置了。
Ingress && Egress
參數
- headers (型態自訂)
- metadata (型態自訂)
- standard_metadata_t (型態固定)
會用到的方法
- 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。
一些細節的內容
- 到底是誰定義每個模組當中帶入的參數
- 哪些是模組
- parser
- control
- 定義模組有哪些參數以及順序的是交換機
- Pipeline 的順序是怎麼定義的
- Ex: V1Switch 為什麼一定是以下的順序
- Parser
- VerifyChecksum
- Ingress
- Egress
- ComputeChecksum
- Deparser
- Pipeline 的順序是根據最終的交換機決定,如果最終的交換機不是 P4 官方提供的 simple_switch 系列就會使用不同的 pipeline
- extern 相關的東西
- extern 的聲明方法
- 當硬體提供的函數是放在某個指定的模塊時使用
- 只需將該模塊中會使用到的函數引入即可
- module_name
- function_name
- function_parameters
Tofino
將封包從 CPU port 發送出去並且可以收到
- 在 onl 的機器上透過
ip a
檢查所有的網卡
- 基本上會找到 enp4s0f0, enp4s0f1 這兩個網卡
- 在 10.30.3.67 的機器上
- enp4s0f0 對應上 port 66
- enp4s0f1 對應上 port 64
- 將需要的網卡開啟
- 將網卡啟用
- 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
- 啟動 tofino
- 將對應到 server 的 port 開啟以及對應到 CPU port 開啟
- port 64: 應該會是 33/0
- port 66: 應該會是 33/2
- 同時 CPU port 的也是 10G
- 透過 server 發送 ICMP 或是使用 scapy (但需要指定 mac address) 發送封包
- 確認在 onl 系統中有收到對應的封包
P4 內容
直接將所有的封包不進行任何處理只設定 egress port 是 CPU port 就可以