原項目位於:https://github.com/simula/P4-OvS/tree/p4/tests
配置步驟見:基於P4的OpenVSwitch環境配置 - 鎮魚 - 博客園 (cnblogs.com)
本文翻譯其項目設計架構與原理。
P4-OvS是開放式虛擬交換機的一個新版本,它支持用戶可配置的、獨立於協議的(P4)數據路徑。
P4操作系統主要基於OVS。出於以下原因,項目決定利用開放式虛擬交換機作為新P4軟件交換機的基礎:
-
開放式虛擬交換機已經支持快速內核旁路解決方案,如DPDK或AF_XDP。因此,這部分代碼可以重復使用。
-
Open vSwitch實現了一個輕量級的成熟數據庫,叫做OVSDB。同樣,OVSDB可以重新用於存儲和同步P4軟件交換機的狀態。
-
經社區驗證的使用模式。
一個懸而未決的問題是,P4開放源碼軟件應該成為開放軟件項目的一部分,還是發展成為一個新的開源項目。在做出這個決定之前,P4-OVS被認為是一個混合(OpenFlow + P4Runtime)解決方案,影響本文檔中描述的設計選擇。
預備知識
如果您不熟悉開放式虛擬交換機的設計和實現,強烈建議您閱讀OVS文檔。https://docs.openvswitch.org/en/latest/
設計假設
-
向后兼容和與OpenFlow的無縫集成——用戶應該仍然能夠使用開放虛擬交換機的眾所周知的現有功能。P4的支持應該是一種選擇。
-
每個橋的P4程序——開放的虛擬交換機允許運行由同一個OVS實例創建的多個OVS橋。P4橋引入了一種新的橋型,叫做“P4橋”。每個P4橋都有自己的P4程序,描述大橋的數據平面特征。
-
保持OVS的模塊化——開放虛擬交換機的架構是模塊化的,允許輕松集成新的開放流數據路徑。P4操作系統的設計和實施也應遵循模塊化方法。
-
支持便攜式交換機架構(PSA)——P4-OvS不會提出另一個P4架構模型。相反,項目利用已經存在且記錄良好的PSA體系結構。
-
P4Runtime作為控制接口——OpenFlow不可擴展,不能支持P4。項目設計者不相信P4和OpenFlow之間的翻譯是可能的。因此,P4-OvS(確切地說是P4橋)將向外部應用程序(控制器)公開基於P4Runtime的控制接口。
架構
如前所述,P4-OvS的想法是通過支持P4的數據路徑和P4Runtime接口來擴展開放虛擬交換機,但保留(至少在第一個版本中)開放虛擬交換機和開放流編程模型的眾所周知的特性。因此,P4-OVS的架構在很大程度上是基於OvS的抽象。從功能的角度來看,P4開放式虛擬交換機擴展了一個基礎開放式虛擬交換機,增加了四個新模塊:
-
可重新配置的(或P4)數據路徑——新的大組件負責處理進入P4橋相關端口的數據包。它應該允許在運行時注入新的數據包處理管道(由P4程序生成)。可重新配置的數據路徑公開了管理P4程序和控制P4對象(如P4表、寄存器等)的接口。).可重配置數據路徑的例子可以是eBPF、XDP或uBPF。
-
P4Runtime接口——這個功能塊在可重構數據路徑和外部控制器之間提供了一個抽象層。特別是,它實現了gRPC服務器(P4Runtime協議定義),並允許用戶控制P4數據路徑。
-
P4編譯器——盡管P4編譯器將在一個單獨的庫中實現,但它也是功能架構的一部分。用戶利用P4編譯器從P4程序和P4運行時接口的P4Info元數據文件中生成特定於數據路徑的二進制文件。
-
ovs-p4ctl——P4大橋的管理工具。它管理P4程序並控制P4對象。其他管理任務(如添加新端口)仍由其他OVS實用工具(如ovs-vsctl)執行。
可重構數據路徑
到目前為止,考慮了以下兩個數據路徑:
-
用戶空間伯克利包過濾器(UBPF)——eBPF的用戶空間再實現。它提供了uBPF虛擬機,在那里可以在運行時注入任意的BPF字節碼。uBPF與用戶空間數據路徑和內核旁路解決方案(如DPDK/AF_XDP)配合良好。
-
eXpress DataPath(XDP)——XDP提供的內核快速路徑也可以作為P4 OvS的可重構數據路徑。還有p4c-xdp編譯器,它可以將P4代碼翻譯成與xdp兼容的BPF字節碼。
由於模塊化設計,應該可以集成一個新的可重構數據路徑(如現場可編程門陣列)。
uBPF數據路徑
P4-OvS的PoC版本實現了uBPF數據路徑。盡管它有一些實現上的怪癖,但它展示了使用uBPF作為默認P4數據路徑的一般思想。
PoC實施基於netdev數據路徑。netdev數據路徑依賴於分組處理和PMD線程來輪詢來自網絡接口的分組。
uBPF遵循同樣的方法。然而,在uBPF包分類的情況下,對包的其他操作是在uBPF程序內部執行的(對每個傳入的包調用)。這對實施有一些影響。首先,netdev利用緩存架構(EMC、SMC緩存)來加速數據包分類。
相反,uBPF數據路徑不能重用基於緩存的分類器,而是依賴p4c-ubpf生成的包分類器。此外,netdev創建每個流的數據包批次。在uBPF的情況下,應該按照每個動作構造包批次。關於uBPF的數據包處理的一般觀點如下。
與OpenFlow橋的互操作性
P4-OvS的設計是為了保持開放虛擬開關的眾所周知的功能。因此,項目也致力於提供具有OpenFlow橋的互操作性模型。
上圖展示了一個場景,其中有一個異構部署,即P4Runtime和OpenFlow橋都是為開放虛擬交換機的實例配置的。在右側,有兩個OpenFlow橋通過一個補丁(patch)端口連接。
補丁端口是OVS的一個眾所周知的概念,它提供了連接兩個OpenFlow橋的輕量級方法,而不需要使用vEth對。它也比vEth更有效。對於P4Runtime橋,項目使用相同的概念。P4-OvS將實現對補丁端口的支持,因此不需要使用vEth來連接兩個P4Runtime橋。該圖還展示了OpenFlow和P4Runtime橋如何相互連接。在這種情況下,需要使用vEth對來連接它們,因為br-p41和br-of1使用不同的數據路徑類型(例如“ubpf”和“netdev”)。
實現架構
OVS提供了分層的、可擴展的架構。說到OpenFlow抽象的實現,有兩個主要的“接口”:ofproto-provider.h和dpif-provider.h。前者指定OpenFlow開關抽象。后者指定了OpenFlow數據路徑接口——OpenFlow數據路徑應該實現的一組動作。
P4-OVS應該有類似的設計。然而,為了避免代碼重復,P4-OvS使用了dpifprovider.h,並用P4特有的函數對其進行了擴展,這些函數不應該由OpenFlow數據路徑來實現。P4-OvS只實現了一個新的p4rt-provider.h,它提供了P4Runtime開關抽象。
執行決策
端口分配
OpenFlow版本的OpenVSSwitch區分了數據路徑級端口號和OpenFlow級端口號。
ofproto-dpif提供OpenFlow端口和數據路徑級端口之間的映射。在P4的情況下,不能進行這樣的映射,因為端口號可以在P4程序中明確使用,該程序在數據路徑級別使用端口號。因此:
-
如果用戶在使用ofport_request添加端口號時沒有指定端口號,端口號將由數據路徑自動分配。
-
如果用戶指定了一個端口號,P4-OvS將嘗試在數據路徑中分配給定的端口號。
上面的自然結果是,端口號在開放虛擬交換機中必須是唯一的。對於傳統的開放式虛擬交換機,端口號對於給定的網橋必須是唯一的。對於P4-OvS,用戶必須請求端口號,任何P4橋都不使用該端口號。
注意!如果用戶指定一個已經在使用的端口號,P4-OvS將返回一個錯誤並分配一個新的端口號。
支持多個P4項目
根據要求,每座P4大橋都應有其獨特的、獨立的P4規划。P4Runtime規范使用設備標識字段來區分由同一P4Runtime服務器控制的不同P4設備。在P4-OvS的情況下,每個P4橋由設備標識來標識。這種方法使P4操作系統符合P4Runtime規范。
注意!PoC版本也使用device_id在數據路徑級別識別P4程序。只要只使用一個P4數據路徑,它就能工作。對於進一步的版本,應該有所提供的數據路徑所使用的device_id和program_id之間的映射。
使用
P4-OvS遵循開放式虛擬交換機的使用模式。網橋和端口配置有ovsvsctl。為了使用新的“p4橋”,新的P4標志、數據路徑類型(PoC中只允許ubpf)和目標二進制文件的路徑必須傳遞給add-br命令。
ovs-vsctl add-br br0 -- set bridge p4=true datapath_type=ubpf other_config:program=" <PATH-TO-P4-PROGRAM>"
上面的命令將使用uBPF數據路徑創建“P4”類型的OVS橋,並將目標二進制(uBPF字節碼)注入uBPF數據路徑,以便數據包可以由用戶配置的管道處理。然后,用戶可以簡單地向網橋添加端口。對於P4橋,應禁用ovs-ofctl工具,例如:
ovs-ofctl dump-flows br0 ERROR: OpenFlow tools are disabled for P4-capable bridge br0
注意!如果ovs-ofctl用於P4橋,當前版本通過返回以下消息通知用戶。對於P4橋來說,ovs-ofctl將無法工作,因為P4橋沒有公開OpenFlow接口。
ovs-ofctl: br0 is not an OpenFlow bridge or a socket
ovs-p4ctl應該用於管理和配置基於P4Runtime的ovs橋。示例命令可能如下所示:
ovs-p4ctl --help
ovs-p4ctl: P4Runtime switch management utility
For P4Runtime switches:
show SWITCH show P4Runtime information
dump-tables SWITCH print table stats
dump-table SWITCH TABLE print table information
add-pipe SWITCH inserts P4 program to the switch
set-pipe SWITCH inserts and activates P4 program
get-pipe SWITCH gets current P4 program
add-entry SWITCH TABLE <ENTRY> adds table entry
del-entry SWITCH TABLE <MATCH> deletes table entries with given
MATCH
dump-entry SWITCH TABLE prints table entries of TABLE
試驗結果
P4-OVS的性能已經過初步測試,結果如下所示。使用原型版本的uBPF數據路徑,它能夠實現比OVS-DPDK稍差的吞吐量。請注意,DPDK配置可能不是最佳的,性能可以調整,但OVS-DPDK和P4-OvS使用了相同的環境。
用例
我在哪里可以看到高性能P4軟件交換機的應用?
-
可擴展、可定制的虛擬機管理程序交換機——開放式虛擬交換機被廣泛用作虛擬機管理程序交換機(例如,用於開放式堆棧)。用戶可配置的版本也可以用作虛擬機管理程序交換機,它將允許雲提供商按需定制網絡並更快地創新。
-
商品服務器上的低成本、可編程“裸機”交換機——隨着用戶需求的不斷變化,網絡結構必須定制,新的網絡功能必須按需部署。P4-OvS可能是DC結構的低成本、可編程網絡交換機的基礎。
-
虛擬網絡文件系統的數據平面組件——VNF提供商可以使用P4虛擬網絡文件系統來構建虛擬網絡文件系統的高性能數據平面(例如5G UPF)。
附錄一——實施
在本節中,將描述特定於實現的方面。
以下修改已應用於原始OVS代碼,以啟用P4數據路徑:
-
新參數(p4,布爾類型)已添加到OVS大橋的數據庫模型中。
-
新增目錄(p4rt/)。它包含與P4和P4Runtime相關的文件(例如P4Runtime抽象的實現和P4Runtime提供程序)。
-
bridge.c中的struct橋已經用新的field struct p4rt *p4rt進行了擴展,它代表P4Runtime開關抽象(類似於struct of port和OpenFlow開關抽象)。
-
這座橋可以是“P4”或“開放流”兩種類型中的一種。因此,在bridge.c中有if-else語句,用於檢查橋是否屬於P4類型。P4大橋的特定於開放流的功能被“阻止”。
-
dpif-netdev . c/create_dp_netdev()-內存分配已移出create _ DP _ net dev()函數(to construct_dp_netdev()),以允許dpif-ubpf重用dpif-net dev的一部分。基本上,為了快速原型化,一些dpif-netdev.c的結構和功能已經轉移到dpif-netdev.h,這可能不是最好的想法,也不是目標解決方案。
-
dpif-provider在OpenFlow數據路徑接口和P4Runtime數據路徑接口之間共享。struct dpif_class已經擴展了僅用於P4(可重配置)數據路徑的函數。這些功能不應該由OpenFlow數據路徑接口實現。