每一個封包在處理時,都會夾帶一個獨立的 metadata,我們可以把 metadata 視同為區域變數,以方便我們在判斷封包時使用。

自定義 Metadata


有關於 meatadata,在 P4 當中,開發者可以自定數個不同的 metadata,定義方式跟 header 一樣,如下:

header_type my_metadata_t {
    fields {
        field1: 8; // size, bits
        field2: 4;
        field3: 2;
        /* ... */
    }
}

header my_metadata_t my_metadata;

如此一來就可以直接在 action 或是 control 之中直接使用。

Standard Metadata


這一個 metadata 比較特別,當每一個封包進來時就會自動產生好該封包的基礎元素,例如 ingress port、packet length 等;這一個 metadata 也可以用來設定 out port。

使用他的方法很簡單,只需要使用:

standard_metadata.some_field

下面說明他所包含的欄位:

  1. ingress_port:封包進來的 port,唯讀
  2. packet_length:封包長度(byte),不包含 ethernet header CRC。如果 switch 開啟 cut-length 模式,則不能用在 match 中,也不能在 action 被參考;唯讀。
  3. egress_spec:在 ingress control flow 中可以被設定,可以是實體 port、或是虛擬 port,或是 multicast 群組。
  4. egress_port:真正實際要出去的實體 port,若 egress_spec 指向實體 port 就會相同,若是虛擬 port 則會轉換後寫在這邊,ingress 階段沒有讀取的意義。唯讀。
  5. egress_instance:僅在 egress 中有意義,跟 egress_port 一樣是在中間的 buffer/queue 階段產生的資料。
    有這一份資料的目的是,當封包被複製(flood、multicast),則每一個封包都會有一個不同的 ID 以方便辨認。
  6. instance_type:這一個資料表示了該封包是「一般的」、「被複製的」或是重新再送的,有以下幾種可能:
    1. normal:一般的
    2. ingress clone:透過 clone_i2i 或 clone_i2e 的方式產生的封包
    3. egress clone:透過 clone_e2i 或 c;one_e2e 的方式產生的封包
    4. recirculated:透過 resubmit 跟 recirculate 重送的封包

    註:這部份官方還在討論當中

  7. parser_status:0 表示 parser 沒有問題,否則就會是錯誤代碼。
    註:這部份官方還在討論當中
  8. parser_error_location:詳細的 parser 錯誤位置。
    註:這部份官方還在討論當中

 

下一篇將會說明 Counter 以及 Meter。

Share Your Thought