作者簡介:鄭浩,東南大學本科生,研究方向:OpenFlow,P4。郵箱: zenhox@163.com
本文首先向大家簡單介紹在學習P4過程中需要用到的工具。本文的主要特色是讓對P4感興趣的大家不費吹灰之力的在工作,學習之餘,快速搭建完善的P4實驗環境並開始第一個P4實驗。本文的更新日期是2018年10月8日,使用相對於大多數教程來說較新的P4環境,本文提供兩種搭建環境的方法,它們的特點如下:
優點: 方便,快捷,對作業系統沒什麼要求。
缺點:運行較慢。
如果工作環境沒有Linux系統,建議使用VM。
優點:運行速率快,環境較新。
缺點:可能會遇到錯誤,需要一個ubuntu系統。
不用擔心費神的環境搭建,本文將提供一個一鍵搭建環境的腳本。這個腳本通過了我多次測試。
主要需要安裝5個組件:
bmv2
p4c
mininet
p4-tutorial
PI
首先要明白他們各自的作用【圖片來源於p4.org】:
如圖,我們寫好xxx.p4代碼,通過 p4c 這個 p4 compiler 將p4代碼編譯成為p4交換機可以理解的各種」機器代碼」。如果目標交換機是 bmv2 , 那麼p4c將生成 .json文件。
p4c是一款 p4編譯器。
BMv2是支持P4編程的軟體交換機。
PI是P4 runtime的實現,用於Control Plane對數據平面的控制。
mininet的功能是構建一個虛擬的網絡拓撲。 它通過linux內核的一些特性(net命名空間),在一個主機上劃分出多個虛擬網絡空間,各個網絡空間之間相互隔離,有自己的埠, ip等等。mininet讓一個或者多個vhost(虛擬主機), 軟體交換機(如ovs, bmv2)等 以進程的狀態分別綁定在這些網絡空間之中,共同構成一個進程級別的虛擬網絡拓撲。需要注意的是這些進程級別的主機和交換機他們只是網絡上的隔離,而文件系統則是共享主機的文件系統。
p4 tutorials 提供了用於學習的實例代碼,它提供了很多個帶有方向性的實際場景,例如負載均衡,簡單的隧道機制,源路由等。並且它事先寫好了控制面代碼,讓p4的初學者可以集中注意力在數據面編程的學習之上。
scapy是一個python庫,提供構建數據包,抓包,解析包等功能。它功能強大,但是效率很低。由於P4編程中經常會引入各種各樣的數據包,有些甚至是開發者自定義的數據包格式。所以我們可以利用scapy進行便捷的組包,發包。如果需要高速率的發包和解析包就不能使用scapy了。
搭建環境有兩條路可以走:
官方提供了用於學習的虛擬機,裡面有完整的環境。可以嘗試訪問官網連結。如果不能訪問外網,可以嘗試訪問我這個1Core, 1M帶寬的伺服器資源
官方的環境似乎比較陳舊,我利用方法二在虛擬機中搭建了一個環境,並且導出供大家使用,下面是下載連結:
1.FTP伺服器下載, 這個是一個雲主機,如果過期或者伺服器崩潰, 聯繫我去修復。
2.如果FTP伺服器崩潰,建議自己裝一個Ubuntu16.04的虛擬機,然後調用方法二,其實也很簡單。
3.這裡還有一個騰訊微雲的連結: https://share.weiyun.com/581m3WN
真機搭建需要獲得各個組件的源碼,然後編譯安裝,可能遇到各個組件之間的版本兼容性,依賴性等問題。
本來打算一步一步寫出手動搭建的步驟,但過程比較痛苦,為了防止讓大家陷入搭建環境這種苦澀且收益不大的環節,本文按照p4 tutorials中vagrant用於構建虛擬機環境的腳本,進行了適當修改後,最終改成一個搭建真機P4實驗環境的腳本。通過這個腳本,可以方便的讓大家搭建好P4學習環境,該腳本通過了本人多次測試。
建議在網絡環境較好的環境下執行腳本,如果能使用國外的代理就更好了,如果網速較慢,建議晚上睡覺前執行,然後天亮後再瞅瞅,畢竟國內訪問github有時真的太慢了。
相關腳本已經上傳至p4-quick 。
在搭建之前
為了不破壞原環境的整潔性,我們還是在home目錄下創建一個P4的工作目錄,並且加入環境變量:
在運行腳本之前,先核實一下必要的環境和依賴:
發行版: Ubuntu 16.04 Desktop LTS , 通過 lsb_release -a查看。
Python: 2.7.12, 通過 python --version查看。
內核: 4.15.0-29-generic , 通過 uanme -a查看,差不多即可。
開始搭建
先安裝一些依賴:
然後創建一個文件,用於存放搭建環境的腳本:
然後將以下內容,複製到 env_up.sh文件當中:
保存退出腳本,然後執行這個腳本:
腳本開始自動為你搭建環境,如果中途遇到錯誤,腳本會中斷,如果腳本順利執行,那麼腳本結束後,環境便搭建好了。
進行實驗之前
如果你下載的是本文提供的第二種虛擬機,或者通過腳本安裝了P4環境,現在P4目錄下面應該是這個樣子:
我們主要的工作目錄時tutorials,其餘的都是被使用的工具組件。細看tutorials:
其中utils裡面存放了一些用於調用各個組件(mininet, bmv2, PI, p4c)的腳本,有了這些腳本,我們可以專注於p4代碼的開發,控制面的編寫,以及拓撲的構建,而不需要費神去了解bmv2的啟動命令,p4c的調用選項等等。具體如何使用,也是非常的簡單,我們進入一個具體的例子查看:
可以看到,通過Makefile,我們可以調用utils下的腳本,讓我們的p4代碼跑起來:
調用make run,我們可以運行當前目錄下(以basic目錄為例)的代碼,它將執行以下幾個步驟:
編譯basic.p4 代碼,生成basic.json
解析topology.json, 並且構建相應的mininet仿真拓撲,按照該拓撲啟動一臺或者多臺BMv2交換機,以及一些host
啟動BMv2的同時會將p4代碼編譯產生的json文件導入
啟動BMv2後會解析 sN-runtime.json 文件,將其載入 交換機sN流表之中
進入mininet命令行,同時開始記錄log以及搜集pcap文件
在新版本的tutorials中,載入靜態流表項時採用了runtime方法,而非之前的CLI方法,我們查看一下s1-runtime.json的部分
這是一個json文件,可以看到,其作用是定義一個個具體的流表項,標明了流表項所處的位置,匹配域,匹配模式,動作名,以及動作參數。這些欄位都依賴於我們P4代碼中所自定義的流表,匹配域和動作。
查看要實現的功能
查看README,裡面這樣介紹這個實驗:
可以看到這是一個實現轉發功能的P4實例,文件剩餘部分是進行實驗具體的思路和指令,建議大家多多查閱README,以後就可以自己學習啦~
查看網絡拓撲結構 topology.json:
清晰明了:這個拓撲中有3個switch,3個host,構成一個三角形的拓撲,注意到定義switches的時候,會定義載入到交換機的流表項文件」sN-runtime.json」。
了解大概之後,我們開始編寫basic.p4代碼:
回憶代碼要實現的功能:ip_v4轉發。我們需要完成的是tutorials中的TODO部分。
在代碼的開頭, 我們得知該代碼是P4_16版本,使用的是我們之前談到的v1_model。
通過查看main回顧v1_model:
我們要需要完成以下幾個基本的步驟,其餘部分可以暫時省略。
定義數據結構:
Parser 解析數據包
parser是一個有限狀態機。從 start 狀態開始,每一個狀態便解析一種協議,然後根據低層協議的類型欄位,選擇解析高一層協議的狀態,然後transition到該狀態解析上層協議,最後transition到accept。具體如下:
Ingress
Checksum 和 Deparser
這兩個部分都有高度抽象的內置函數直接完成:
寫好控制面代碼
雖然說官方為了讓大家專注於數據面編程,已經給好了控制面指令,但是我們有必要查看一下他們,從而有了更深入的理解, 查看 s[1,2,3]-runtime.json, 裡面定義了很多流表項。以s1-runtime.json為例, 具體的一條流表項為:
回想,table name 就是我們在p4代碼中自定義的轉發表。匹配域也依照了我們自定義的代碼。而動作也按照我們編寫的動作代碼傳入了相應的參數。將所有的流表項匯總一下, 我繪製了下面的圖片:
看到這一步,我們便瞭然了。數據面定義了轉發表,而控制面下發了具體匹配轉發的流表項,使得這三個主機可以互通。而在控制面下發的流表項與我們p4代碼中定義的流表結構息息相關。
運行代碼
丟包率為0,說明轉發功能實現了。這樣我們完成了第一個實驗。
一點建議
本文提供給大家最快捷的方式去體驗,學習和使用P4。其中有方便的虛擬機直接使用,也有真機搭建的腳本。搭建好環境並且開始第一個實驗後,大家可以自己專注於P4的學習啦。
第一次寫文章,而且限於本人能力有限。難免有紕漏或者理解不當,還望各位諒解,如果能夠給予批評指點,不勝感激!聯繫郵箱: zenhox@163.com,鄭。
【培訓】
長按識別下方二維碼,立即報名
【活動】
長按識別下方二維碼,立即報名