透過 ONOS 來控制 bmv2 witch:Pipeconf 開發流程

5 月 5, 2018

如果需要透過 P4 來定義自己的 Pipeline,並透過 ONOS 去控制的話,則會需要製作一個 pipeconf (pipeline config) 來讓 ONOS 知道要傳送什麼樣的 pipeline 到裝置上,以及該如何去操作裝置上的 table。

撰寫一個 Pipeconf 需要的東西如下:

  • 編譯好的 pipeline config (bmv2 json, Tofino binary….)
  • p4info
  • PipeconfLoader(進入點)
  • Interpreter(可有可無)
  • Pipeliner(可有可無)

上述前三個為必須,後兩個可有可無,但是會建議加上以支援更多功能,舉例來說,若沒有 Interpreter,則無法使用 ONOS 所提供的基本功能,例如 Packet In/Out,使用預設的程式

Pipeliner 的部份,目前 ONOS 預設會用到 Pipeliner 的有像是 Host 以及 Link 偵測等等的程式可能會需要用 Pipeliner 將預期的 Flow 裝至裝置中,但若沒有想要使用這些功能也可以不用撰寫。

在之前的說明當中, Pipeconf 可以是一個獨立的外部程式(oar),本文會以此為主進行說明。

要建立一個獨立的外部程式,首先是需要安裝 ONOS,安裝完之後使用下方指令產生本地端的 maven 函式庫:

onos-buck-publish-local

這個指令會將 ONOS 編譯並且產生相關的 jar 供這個外部獨立的程式使用。
目前這部份還需要依賴 maven,Buck 支援可能是之後的事情。

函式庫建立完之後透過以下指令產生一個空的 ONOS bundle 專案:

onos-create-app

此時會有一支程式引導並產生我們需要的檔案

建立好的 bundle 長這樣:
Screen Shot 2018-05-06 at 1.16.45 AM.png

裡面僅有 3 個檔案:
pom.xml: Bundle 編譯用的資訊
AppComponent: 這一個 Bundle 的主程式
AppComponentTest: 測試程式

接下來個會有幾個步驟:建立置需要的檔案、編輯 pom 檔案、撰寫 PipeconfLoader、Interpreter、Pipeliner

建立需要的檔案

第一件事情就是把 AppComponent 換成 Pipeconf Loader,可以直接更改 class 以及檔案名稱
接著吧該放置的東西寫好,例如 Interpreter, Pipeliner 等等

放置好之後目錄會長這樣:
Screen Shot 2018-05-06 at 1.28.29 AM

由於不需要解釋 Unit test,所以這個範例中把 Unit test 移除了,當然實際在撰寫 Pipeconf 時一樣可以加一些 Unit test 去測試 Interpreter 或是 Pipeliner 等等的功能(請參考 FabricPipeliner)

而在 resources 中的則是已經編譯好的 pipeline config,這邊使用 bmv2 json + p4info 作為例子。

編輯 pom 檔案

接著,由於預設 bundle 並不會自動啟動程式進入點(Activate Pipeconf loader),這時就需要更改 pom.xml 讓 ONOS 知道說他是一個 ONOS App 且需要啟用主要的 Component。

在 pom.xml 檔案中會看到下列區塊:

<!-- Uncomment to generate ONOS app from this module.
<onos.app.name>org.foo.app</onos.app.name>
<onos.app.title>Foo App</onos.app.title>
<onos.app.origin>Foo, Inc.</onos.app.origin>
<onos.app.category>default</onos.app.category>
<onos.app.url>http://onosproject.org</onos.app.url>
<onos.app.readme>ONOS OSGi bundle archetype.</onos.app.readme>
-->

將這一個區塊註解取消並填上相對應的資訊即可,例如:

<onos.app.name>org.p4tw.testpipeline</onos.app.name>
<onos.app.title>My Test Pipeline</onos.app.title>
<onos.app.origin>P4TW</onos.app.origin>
<onos.app.category>pipeconf</onos.app.category>
<onos.app.url>http://onosproject.org</onos.app.url>
<onos.app.readme>My test pipeline</onos.app.readme>

撰寫 PipeconfLoader

基本上 PipeconfLoader 就是一個 ONOS 的 App,當 ONOS 啟動這一個 App 時,會透過 PiPipeconfService 去註冊 Pipeconf。

已這個例子來說,我們希望 Pipeconf 擁有 Interpreter 以及 Pipeliner 兩種 Driver Behavior,以及使用 bmv2 json + p4info,則 Pipeconf 可以這樣寫:

PiPipeconfId id = new PiPipeconfId("my-test-pipeconf");
URL bmv2ConfigPath = TestPipeconfLoader.class.getResource("/test-pipeline.json");
URL p4infoPath = TestPipeconfLoader.class.getResource("/test-pipeline.p4info");

pipeconf = DefaultPiPipeconf.builder()
    .withId(id)
    .addBehaviour(Pipeliner.class, TestPipeliner.class)
    .addBehaviour(PiPipelineInterpreter.class, TestInterpreter.class)
    .addExtension(PiPipeconf.ExtensionType.BMV2_JSON, bmv2ConfigPath)
    .addExtension(PiPipeconf.ExtensionType.P4_INFO_TEXT, p4infoPath)
    .build();

piPipeconfService.register(pipeconf);

Pipeconf ID 的部份則是會用在 devide config 當中。

上述的程式僅需放至於 PipeconfLoader 中的 activate function 中即可在 ONOS 載入這個 App(oar)時就將 Pipeconf 載好了。

而 deavtivate 的部份僅需使用 Pipeconf service 中的 remove 即可。

撰寫 Interpreter

Interpreter 著要是處理一些將 ONOS 一般的 API 轉換至 PI API 的工作,下面解說每一個需要實作的函式的功能:

  • mapCriterionType: 將 ONOS 一般的 Criterion 轉換成 PI match 欄位,舉例來說,如果一個 ONOS App 使用普通的 Criterion 像是 ETH_DST,則會透過這個方法進行轉換。
  • mapPiMatchFieldId: 跟前一個相反,這是將 PI match 欄位轉換成普通的 Criterion。
  • mapFlowRuleTableId: 將數字 Id 轉換成像是 P4 一樣使用字串的 Id,例如 ONOS 許多孤能都會使用 table 0,而自行定義的 Pipeline 若需要支援一些常用的 ONOS service,則可能會需要這個轉換的功能。
  • mapPiTableId: 與前一個相反,將字串 Id 轉換回數字 Id。
  • mapTreatment: 將 ONOS 的 TrafficTreatment 加上 TableId 轉換成 PiAction,這主要是要解決多個 Action 對到單一個 Action 的問題。OpenFlow 允許一個 Match 執行多個 Action,但是 P4 僅允許單一個,因此需要這樣的轉換。
  • mapOutboundPacket: 將 ONOS PacketOut 轉換成 PI 格式,即 metadata + paylad,這部份是因為開發者可以透過 P4 語言定義接收端接收的 metadata 格式,因此需要另外定義。
  • mapInboundPacket: 同理,因為開發者可以定義 metadata,以及可以定義非正規網路協定,因此需要另外轉寫轉換用的函式。

撰寫 Pipeliner

Pipeliner 是專門將 FlowObjective 轉換成 Flow+Group 的一個組件,詳細的 Flow Objective 介紹可以參考去年 ONOS Build 演講:
https://youtu.be/c3OESLdAgQk

Pipeliner 主要是需要處理三種不同的 FlowObjective:

FilteringObjective:用來表示允許或是擋掉封包進入 Pipeliner 的規則,有時候還會有附帶一些處理的 Action 像是 packet-in 到 ONOS,或是更改 header 等等的。

ForwardingObjective:用來描述封包在 Pipeliner 中需要如何去處理,可能是送至 ONOS,或是將封包傳給特定某些 egress table 處理等等的。

NextObjective:用來描述 Egress table 裡面需要放置什麼樣的東西,每一個 NextObjecgive 都會有一個獨立的 Id,ForwardingObjective 可以透過此 Id 來決定該封包要給哪一個 Egress 規則處理。

編譯成 oar

撰寫完成後,即可於它的根目錄直接執行mvn clean install指令,執行完後會產生一些編譯好的檔案如下:
Screen Shot 2018-05-06 at 2.29.07 AM

testpipeline-1.0-SNAPSHOT.oar 即為我們需要的檔案,於 ONOS 執行時可透過 onos-app載入到 ONOS 當中。

參考資料

以上就是 Pipeconf 轉寫教學,這邊會建議直接參考 ONOS Basic pipeline 這一個範例去學習會更加容易。若是希望能夠了解 Pipeliner 的話,則可以去看看 ONOS Fabric pipeline

發佈留言

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

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