P4: Programming Protocol-Independent Packet Processors
P4: Programming Protocol-Independent Packet Processors
摘要
P4是一門高級語言,用于編程與協議無關的數據包處理器。P4與SDN控制協議相關聯,類似與OpenFlow。當前,OpenFlow明確指定了運行的協議頭。這個設置在幾年內,從12個字段增長到41個字段,并且增加了協議頭的復雜性,卻沒有提供應有的靈活性。本文提出P4作為OpenFlow將來演化發展的目標。我們有三個目標:(1)字段可重配性(2)協議獨立性(3)目標無關性。
1 引言
SDN使得操作人員可編程化的控制他們的網絡,在SDN中,控制平面與轉發平面分離,控制平面控制多個轉發設備,同時,轉發設備可以通過共有的,開放的,廠商無關的接口(比如OpenFlow),使得控制平面可以對不同的軟件、硬件服務商進行控制。
OpenFlow接口開始是很簡單的,簡單的表匹配規則概念可以在多個頭字段進行匹配(比如MAC地址,IP地址,協議,TCP/UDP端口數字等)。在過去五年,隨著多個階段的規則表和更多的頭字段,配置變得愈加的復雜(表1所示)。頭字段增加的現象并沒有停止,為了取代這種不斷擴展OpenFlow配置的現象,我們認為將來的交換機應該提供靈活的機制,以支持解析數據包和匹配頭字段。控制器通過接口,可以利用這些優勢。
最近,芯片設計證明這樣的靈活性可以通過傳統的ASICs以Tb/s的速度實現。對這種新一代的交換機芯片實現編程并不容易。圖1顯示了P4(告知交換機如何配置交換機、處理數據包)和現在的APIs(用于在固定功能交換機上填充轉發表)之間的關系。P4為可編程網絡的概念提出抽象的級別,P4可以作為控制器和交換機之間的通常的接口。關鍵的挑戰是找到一個“最佳位置”,以平衡表現力的需求與各種硬件和軟件交換機的易于實施。
P4四個主要目標如下:
- 1.可重配性,控制器可以定義數據解析和處理的字段。
- 2.協議獨立性,交換機不會限定于明確的數據包格式。相反,控制器可以配置,(1)數據包解析器可以以特別的名字和類型提取數據包頭字段(ii)有匹配+動作表集合可以對這些數據包頭進行處理。
- 3.目標獨立性。這就類似C程序的運行不必關心底層的硬件。P4程序寫好的配置不必關心底層設備,但是在將P4程序編寫的配置,對交換機進行配置時,需要對交換機的能力進行考慮。
本文大綱如下。首先介紹交換機轉發模型的概念,接下來,闡明用于描述協議獨立數據包處理的新語言需求。然后提出一個簡單的示例,示例中支持有新的數據包頭字段以及在多個階段對數據包進行處理。我們用這個示例探索P4程序如何配置頭,數據包解析器,多個匹配+動作表,以及對這些表控制的控制流。最后,討論編譯器如何將P4映射到目標交換機。
2 抽象轉發模型
圖2顯示了我們的抽象模型,交換機通過可編程解析器轉發數據包,然后是多個匹配+動作階段,按串行,并行或兩者的組合排列。首先,OpenFlow假定的是固定的解析器,而我們的模型支持可編程解析器允許定義新的頭字段。第二,OpenFlow假定match+action階段是串行的,而我們的模型則可以并行的或者串行。第三,我們的模型假定,所有的動作由交換機支持的數據獨立協議原語組成。
我們的概念模型總結了數據包如何通過不同的技術進行處理。這讓我們設計了一個更通用的語言(P4)來體現數據包是如何通過抽象模型處理的。因此,程序員可以創建目標無關的程序,通過編譯器映射到不同的轉發設備。
轉發模型由兩種操作控制:配置和填充。配置操作編程解析器,設置匹配+動作階段的順序,并且配置每個階段如何處理頭字段。填充操作,在匹配+動作表中添加(刪除)流表項,這個表在配置操作進行時,就配置好。填充確定在任何給定時間應用到數據包的策略。
為了本文的目的,我們假定配置和填充是處于兩個不同的階段。交換機在配置階段不需要處理數據包,但是,我們仍然希望,在重配、升級的時間里,仍然可以進行數據包處理。
首先是解析器對到來的數據包進行處理。數據包數據部分假定為分別緩存,并且不能夠進行匹配。解析器從頭部識別、解析出字段,并且因此定義交換機支持的協議。模型未對協議頭的含義進行假定,僅僅是解析的表示(解析到的東西)定義了匹配+動作的集合。
接下來,解析出來的頭字段通過匹配+動作表,匹配+動作表被分在進入和出去兩部分之間,兩者可能修改數據包頭,進入的匹配+動作決定了出去的端口,以及決定了數據包放置的隊列。基于進入口處理,數據包可能被轉發、復制(組播或者控制平面)、丟棄,或者觸發流控制。出口匹配+動作對每一個數據包頭實例進行修改。動作表可以與流關聯,以追蹤幀到幀的數據狀態。
數據包在多個階段之間可以攜帶額外的信息(數據包處理時產生),我們將這些信息稱之為元數據,可以類似數據包頭字段那樣被識別。元數據例子比如,進入端口、傳輸目的、和隊列,時間戳可以用于數據包調度,有些數據(比如虛擬網標識符)在表與表之間傳輸是不會改變的。
排隊原則的處理與現在的OpenFlow協議一樣:一個動作映射一個數據包到一個隊列,這個隊列配置為接收特殊服務規則。服務規則作為交換機配置的一部分。通過添加動作原語可以允許程序員實現新的或者現存的擁塞控制協議。
3 可編程語言
我們使用抽象的轉發模型來表達交換機是如何配置以及處理數據包的。TTL字段必須減小并且測試,隧道頭字段可能需要添加,總和可能需要計算,這促使P4使用指令控制流編程來表述頭字段的處理(通過聲明的頭類型和原語動作集合)。
數據包處理語言必須能夠讓開發者表達在頭字段之間的(明確的或隱式的)依賴關系,依賴關系決定了數據包在;哪些表中可以并行運行。比如,由于在IP路由表和ARP表之間的依賴關系,順序執行要求一個IP路由表和一個ARP表。依賴關系可以通過分析TDGs(依賴關系表)進行識別。這些圖表(TDGs)描述了字段的輸入,動作,表之間的控制流。圖3顯示了L2/L3層交換機之間的依賴圖例子。TDG節點直接映射動作表和在管道的依賴分析識別。不幸的是,TDGs對大多數程序員來說是不可取的,因為他們趨向于認為使用命令構建而不是圖表表達數據包處理算法。
這促使我們提出兩步編譯處理。在最高級別層,編程人員使用命令語言表達數據包處理程序來代表控制流(P4),這種情況下,編譯器將P4語言表示部分翻譯到TDG上,進行依賴關系分析,接著匹配TDG到具體的目標交換機。P4的設計是為了更方便的將一個P4程序翻譯到TDG上
4 P4語言舉例
我們通過深度研究一些例子以探索P4。在核心和邊緣的網絡部署是有區別的。終端主機直接與邊緣設備相連,邊緣設備再通過高帶寬的核心進行互連。所有的協議都是設計以支持這個結構(比如MPLS,PortLand),目的是簡化核心部分的轉發。
考慮使用top-of-rack(ToR)交換機通過兩層核心連接部署2級網絡。我們假設終端主機的數量不斷增長,L2核心交換機不斷溢出。MPLS是簡化核心的一個選項,但是使用多個標簽進行實現分發控制協議是艱難的任務。PortLand協議看起來很有趣,但是需要重寫MAC地址,可能會破壞現有的網絡調試工具,并且需要新的代理來response請求。
P4讓我們能夠使用傳統的解決方法,并且對現在的網絡架構只需做微小的改變。我們將用于學習的樣例稱之為mTag(可以認為是一種機制,用來P4進行描述):它結合了攜帶簡單MPLS類似的標簽的PortLand多級路由協議。通過核心的路由由32bit的標簽編碼而成,一個32bit的標簽由四個單字節的字段組成。32bit的標簽可以攜帶源路由或者目的定位信息(比如PortLand的PseudoMac)。每個核心交換機只要檢測標簽的一個bit并且檢驗信息。我們的例子中,標簽是通過 第一個ToR交換機添加的,盡管,這同樣會在終端機NIC上進行添加。mTag的例子是為了將我們的注意放在P4語言上。在實踐中,P4程序對于整個交換機來說會更加復雜。
4.1 P4概念
P4程序的定義包含以下組件的定義:
- 1.首部Headers:首部的定義描述了一系列首部區域的順序和結構。它包含區域長度的規范,約束了區域數據的取值。
- 2.解析器Parsers:解析器的定義描述了如何識別數據包內的首部和有效的首部順序。
- 3.表Tables:“匹配–動作”表是執行數據包處理的機制。P4程序定義的首部區域可能會用于匹配,或者在其上執行特定的動作。
- 4.動作Actions:P4支持通過更簡單的協議無關的原語構造復雜的執行動作。這些復雜的動作可以在“匹配 – 動作”表中使用。
- 5.控制程序Control Programs:控制程序決定了“匹配 – 動作”表處理數據包的順序。一個簡單又必要的程序描述了“匹配 – 動作”表之間的控制流。
接下來,我們將展示,在P4中,這些組件是如何幫助的mTag實現理想的處理器。
4.2 首部格式
從首部格式的規范開始設計。通常,每一個頭部的配置是通過聲明字段名字和寬度的集合組成。可選的字段聲明允許我們對不同大小的字段約束值的范圍和最大長度。比如,標準以太網和VLAN的頭配置如下所示:
header ethernet {fields {dst_addr: 48; // width in bitssrc_addr: 48;ethertype: 16;} } header vlan {fields {pcp: 3;cfi: 1;vid: 12;ethertype: 16;} }mTag首部可以不修改現有的聲明而進行添加。字段名表名核心層有兩層匯聚。每一個核心交換機都被編寫了一些規則來檢查這些字節中的某一個。具體檢查哪一個字節,是由字節在交換機所處層次位置和數據流的方向(上或下)決定的。
header mTag {fields {up1: 8;up2: 8;down1: 8;down2: 8;ethertype: 16;} }4.3 數據包解析器
P4假設底層交換機可以實現一個狀態機,這個狀態機能夠自頭至尾橫貫數據包的各個首部,隨著狀態機的行進提取首部區域的值。提取出來的首部區域值被送入“匹配–動作”表進行處理。P4把狀態機直接描述成從一個首部到下一個首部的過渡轉移的集合。每一個過渡轉移可能會被當前首部中的值觸發。
parser start {ethernet; } parser ethernet {switch (ethertype) {case 0x8100:vlan;case 0x9100:vlan;case 0x800:ipv4;// Other cases} } parser vlan {switch (ethertype) {case 0xaaaa:mTag;case 0x800:ipv4;// Other cases} } parser mTag {switch (ethertype) {case 0x800:ipv4;// Other cases} }數據包的解析從start狀態開始,一直行進直到到達了明確的stop狀態或是遭遇到無法處理的情況(這可能被標記成錯誤)。在到達了對應下一個首部的狀態時,狀態機根據首部的規范描述提取出首部,然后根據狀態機的下一個過渡轉移繼續向前行進。提取出來的首部被送往交換機流水線后半部分的“匹配+動作”的處理過程。
4.4 表的規范
接下來,開發者需要描述定義首部區域(字段)如何在“匹配– 動作”階段進行匹配(比如它們應該被精確匹配,范圍匹配還是通配符匹配),以及當成功匹配之后將執行什么動作。
在我們簡單的mTag例子中,邊緣交換機匹配二層目的地和VLAN ID,然后選擇一個mTag添加到首部中。開發者定義一張表來匹配這些區域(字段),以及執行一個添加mTag首部的動作(見后文)。其中的reads屬性聲明了要匹配哪些首部區域(字段),同時限定了匹配類型(精確匹配、三重匹配等)。actions屬性列出了“匹配–動作”表可能會對數據包執行的動作。動作將會在本文后續部分講解。max_size屬性指明了“匹配–動作”表需要能夠支持多少條表項。
表的規范允許P4編譯器決定存儲表需要多大的存儲空間,以及在什么樣的存儲器(比如TCAM或SRAM)上實現這個表。
table mTag_table {reads {ethernet.dst_addr: exact;vlan.vid: exact;}actions {// At runtime, entries are programmed with params// for the mTag action. See below.add_mTag;}max_size: 20000; }為了展示的完整性和后續討論的便利,我們在此展示其他表的簡短定義,這些表將在控制程序一節中引用。
table source_check {// Verify mtag only on ports to the corereads {mtag: valid; // Was mtag parsed? metadata.ingress_port: exact;}actions { // Each table entry specifies *one* action// If inappropriate mTag, send to CPUfault_to_cpu;// If mtag found, strip and record in metadata//剝離和記錄元數據strip_mtag;// Otherwise, allow the packet to continuepass;}max_size: 64; // One rule per port } table local_switching {// Reads destination and checks if local// If miss occurs, goto mtag table. } table egress_check {// Verify egress is resolved// Do not retag packets received with tag// Reads egress and whether packet was mTagged }4.5 動作規范
P4定義了一個基本動作的集合,可以利用它們構造復雜的動作。每個P4程序都聲明了一個動作功能的集合,動作功能由動作原語編寫而成;這些動作功能簡化了表的規范和下發。P4假設一個動作功能中的原語是并行執行的。(沒有并行執行能力的交換設備可能會模擬并行的過程。)
適用于上述的add_mTag動作的實現如下:
action add_mTag(up1, up2, down1, down2, egr_spec) {add_header(mTag);// Copy VLAN ethertype to mTagcopy_field(mTag.ethertype, vlan.ethertype);// Set VLAN’s ethertype to signal mTagset_field(vlan.ethertype, 0xaaaa);set_field(mTag.up1, up1);set_field(mTag.up2, up2);set_field(mTag.down1, down1);set_field(mTag.down2, down2);// Set the destination egress port as wellset_field(metadata.egress_spec, egr_spec); }如果某個動作需要有輸入參數(例如mTag中的up1值),參數將會在運行時由匹配表提供。
在這個例子中,交換機將mTag標簽插入在VLAN標簽之后,復制VLAN標簽的Ethertype字段到mTag中,以指明后續類型為mTag,然后設置VLAN標簽的Ethertype字段為0xaaaa,表明其后跟隨的是mTag標簽。在邊緣交換機上執行的相反動作沒有展示出來,這些動作將會從數據包中剝去mTag標簽。
P4的基本動作包括:
1.Set_field:將首部中的某一特定區域設置為特定的值,支持帶掩碼的設置;
2.Copy_field:將一個首部區域的值拷貝到另一首部區域中;
3.Add_header:添加一個有效的特定的首部(以及它所有的首部區域);
4.Remove_header:從數據包中刪除(pop取出)一個首部(以及它所有的首部區域);
5.Increment:遞增或遞減一個首部區域的值;
6.Checksum:計算首部區域的一些集合的校驗和(比如IPv4校驗和)。
我們期望大多數交換設備上的實現將會約束動作的處理,只允許與特定的數據包格式相一致的首部進行修改操作。
4.6 控制程序
一旦表和動作被定義好,接下來僅剩的任務就是指定從一個表轉移到下一個表的控制流。控制流作為一個程序通過一個函數、條件和表的引用組成的集合進行指定。
圖4-1為邊緣交換機上的mTag實現展示了一個期望的控制流的圖形化表示。在包解析之后,source_check表確認接收到的數據包和入端口是否一致。例如,mTag只應該存在于連接到核心交換機的端口上。source_check也會從數據包中剝去mTag標簽,同時在元數據中記錄數據包是否擁有mTag標簽。流水線中后續的表可能會匹配這個元數據以避免再次往數據包中添加標簽。
local_switching表稍后將會被運行。如果沒有匹配上,就意味著這個數據包的目的地不是連接在同一個交換機上的主機。在這種情況下,mTag_table表(上述定義的)將會用來匹配這個數據包。本地和送往核心層的轉發控制都可以被egress_check表處理。這個表將會在轉發目的地未知的情況下,上送一個通知到SDN控制層。
這一包處理流水線的必要描述如下:
control main() { // Verify mTag state and port are consistent //驗證mTag 是否合法,端口與連接到核心交換機的端口是否一致。 table(source_check);// If no error from source_check, continue if (!defined(metadata.ingress_error)) { // Attempt to switch to end hosts table(local_switching);if (!defined(metadata.egress_spec)) { // Not a known local host; try mtagging table(mTag_table); }// Check for unknown egress state or // bad retagging with mTag. table(egress_check); } }5 編譯P4程序
為了讓網絡能夠實現我們的P4程序,我們需要編譯器來把目標無關的描述映射到目標交換機的特定硬件或軟件平臺上。完成這個工作涉及分配目標的資源并且為設備生成合適的配置。
5.1 編譯包解析器
對于有可編程包解析器的設備,編譯器將解析器描述翻譯成解析狀態機。對于固定的解析器,編譯器僅僅確認解析器描述與目標設備的解析器是一致的。生成一個狀態機的細節和有關狀態表項的細節,可以在[16]中找到。
表2展示了上述解析器中vlan和mTag部分的狀態表項。每一條表項指明了當前的狀態、用于匹配的區域的值以及即將跳轉的下一狀態。為了展示的簡潔性,其他行被忽略。
5.2 編譯控制程序
§4.6中必要的控制流描述是一種方便的指定交換機的邏輯轉發行為的方法,但它不能明確地表示出表之間的依賴和并發執行的機會。因此我們部署一個編譯器來分析控制程序,幫助我們識別依賴以及尋找能夠并發處理首部區域的機會。最終,編譯器為交換設備生成目標配置。目標設備有很多種可能,例如軟件交換機[17]、多核軟件交換機[18]、NPU[19]、固定功能的交換機[20],或是可重配置的匹配表(RMT)流水線[2]。
轉載于:https://www.cnblogs.com/Pan-xi-yi/p/9813402.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的P4: Programming Protocol-Independent Packet Processors的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java BIO、NIO、AIO 学习
- 下一篇: Intel格式和ATT格式汇编区别