P4-16 系列 – Header/Parser

由於近期 P4 官方釋出了 P416(1.2) 的規格,絕大部分的語法與 P4 1.0 都有些落差,所以在這邊打算在寫一系列的文章說明相關語法。

由於正式的 P416(1.2) 規格還沒有釋出,本系列教學會以 pre-release 版本為主。


Header

在 1.0 版中,我們必須先定義 header type 才可以定義 header,header type 裡面使用的單位則是以 bit 為主。

P4 在 1.1 版之後加入了型態,這樣能夠更方便的計算長度,也可以節省一些開發時間。

Header 定義方式如下:

header HeaderName {

    fields.......

}

例如今天我們定義 Ethernet 標頭可以這樣做:

header EthernetHeader {

    bit<48> dst;
    bit<48> src;
    bit<16> etherType;

}

接者在使用這一個 header 去產生實體即可:

EthernetHeader ethernetHeader;

 

相對於 1.0 與 1.1 版,1.2 版少了 field 與 header_type 這類型的關鍵字,簡化開發上的需要去記得東西。

資料型態的部份,在目前 P4 的規格中有定義的基本型態(Base types)如下:

  • void
  • error
  • match_kind
  • bool
  • bit<>
  • int<>
  • varbit<>

除了基本型態以外,還有一些是以資料結構為主的形態,例如 Set、Tuple 等等,之後會再寫一篇說明。


Parser

與 1.0/1.1 版不同的是,原先的版本需要定義出很多個 parser,並在不同的 parser 間切換,而新版的則是定義一個 parser,並在 parser 中撰寫很多不同的狀態(state),並透過 accept 與 reject 決定 parser 是否成功解析一個封包。

表面上看起來 1.2 版與 1.0/1.1 版只是語法上不同,但是實作上面沒有什麼不同,但是實際上若深入研究 1.0/1.1 的設計會發現他有許多限制,舉例來說 1.0/1.1 版不能跳回已經用過的 parser,相同的標頭型態不能夠再被解析一次(例如 VXLAN 的外部封包內部封包)。

而 1.2 版的設計讓相同的狀態執行到多次,且 1.2 版開始將 parser 與 deparser 拆開,原先 1.0/1.1 版的 deparser 是在編譯階段時就產生好的東西,開發者無法決定 deparsing 的順序以及內容。

Parser 的寫法如下:

parser ParserName(packet_in pkt, ...) {

    state start {
        ....
    }

    state state_name {
        ....
    }
}

parser 所帶入的參數主要有:

  • packet_in:執行期間所要解析的封包
  • 其他輸出內容:可以是 struct 或是一般封包參照

不同的 state 切換可以透過 transition 這個關鍵字去做切換,而 transition 後面可以接 state 名稱或是 select 語法,我們以 Ethernet + IPv4 為例子。

parser MyParser(packet_in pkt, out eth, out ipv4) {

    state start {
        transition eth;
    }

    state eth {
        pkt.extract(eth);
        transition select(eth.ethType) {
            0x800: ip;
            _: reject;
        }
    }

    state ip {
        pkt.extract(ipv4);
        transition accept;
    }

}

除了使用 transition, select 以及 extract 以外,Parser 還有提供 verify 語法,透過 verify 檢查,決定 parser 是否要丟出 error 並跳至 reject 狀態,使用方法如下:

verify(判斷式, 錯誤類別);

 

另外,還有一些進階的用法會再寫一篇文章說明,像是:

  • 提供 sub-parser 的寫法:可以在 parser 中建立 sub-parser去進行解析
  • 提供類似迭代的方式去解析封包

 

以上就是 P416 有關於 Header 以及 Parser 的說明,下一篇會簡短的說明各種新增的形態(Types)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料