P4編程環境搭建+實現tutorials中basic的案例

前言

最近由於科研的需要,安裝了這個SDN的P4環境,不得不說這個過程真的是異常多的bug,裝了一週才裝好,總結這一週以來的錯誤,下面告訴大家如何一次性的安裝好。(特別提醒,希望你是直接看到這篇文章後來安裝的,因爲在自己安裝的過程中如果出現版本錯誤而沒有把配置好的環境刪除乾淨的話,安裝過程基本就卒了啊!
所以推薦安裝前滿足以下條件之一:

  • 剛開始裝P4,沒有自己先搗鼓然後報各種錯
  • 重裝後的系統
  • 能把之前安裝錯的文件徹底刪除乾淨

安裝過程

話不多說,直接進入安裝整體把。安裝過程大家可能會參考各種網上的文檔,這裏強烈建議大家安裝官網github給的安裝流程https://github.com/p4lang/tutorials/blob/master/vm/user-bootstrap.sh,然後結合SDNLAB的一篇命令改進後的優秀文章P4編程理論與實踐(2)—快速上手一起來看,保證整個過程儘量只有Ctrl+C和Ctrl+V的操作。
這裏我使用的版本是:

  • Ubuntu 16.04 Desktop LTS
  • Python 2.7

希望大家版本儘量和我保持一致,接下來就開始進入正題。我們一共主要需要安裝5個組件:

  • bmv2
  • p4c
  • mininet
  • p4-tutorial
  • PI

1.環境依賴配置

在搭建之前爲了不破壞原環境的整潔性,我們還是在home目錄下創建一個P4的工作目錄,並且加入環境變量:

mkdir ~/P4
cd ~/P4
echo "P4_HOME=$(pwd)" >> ~/.bashrc
source ~/.bashrc

先安裝一些依賴項:(依賴項的安裝很重要,不然等會會出各種問題)

sudo apt-get update
 
sudo apt-get install automake cmake libjudy-dev libpcap-dev libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libboost-thread-dev libevent-dev libtool flex bison pkg-config g++ libssl-dev  -y
 
sudo apt-get install cmake g++ git automake libtool libgc-dev bison flex libfl-dev libgmp-dev libboost-dev libboost-iostreams-dev libboost-graph-dev llvm pkg-config python python-scapy python-ipaddr python-ply tcpdump curl  -y
 
sudo apt-get install libreadline6 libreadline6-dev  python-pip  -y 
 
sudo pip install psutil
sudo pip install crcmod

接下來就是結合上面的兩篇文章開始搭建了

2. 路徑和版本

在我寫這篇文章時,P4的官網github的安裝流程給的Bmv2,PI,P4C,PROTOBUF,GRPC版本如下:

# 打印腳本命令.
set -x
# 在有錯誤輸出時停止.
set -e
 
# 設置相關路徑和版本變量
P4_HOME=$HOME/P4
BMV2_COMMIT="884e01b531c6fd078cc2438a40258ecae011a65b"  # Apr 24, 2019
PI_COMMIT="19de33e83bae7b737a3f8a1c9507c6e84173d96f"    # Apr 24, 2019
P4C_COMMIT="61409c890c58d14ec7d6790f263eb44f393e542a"   # Apr 24, 2019
PROTOBUF_COMMIT="v3.2.0"
GRPC_COMMIT="v1.3.2"
#獲得cpu核數,與某些軟件的編譯選項相關
NUM_CORES=`grep -c ^processor /proc/cpuinfo`

大家自己安裝的時候一定要時刻關注版本的變化,要按照官網github給的版本安裝才儘量不會出現問題(朋友們,我就是因爲設置的版本路徑是舊版的,在P4環境搭建後無法運行最新版的tutorials中的basic實例

3. Mininet安裝

首先是Mininet的安裝:mininet的功能是構建一個虛擬的網絡拓撲。 它通過linux內核的一些特性(net命名空間),在一個主機上劃分出多個虛擬網絡空間,各個網絡空間之間相互隔離,有自己的端口, ip等等。mininet讓一個或者多個vhost(虛擬主機), 軟件交換機(如ovs, bmv2)等 以進程的狀態分別綁定在這些網絡空間之中,共同構成一個進程級別的虛擬網絡拓撲。需要注意的是這些進程級別的主機和交換機他們只是網絡上的隔離,而文件系統則是共享主機的文件系統。
命令行如下:

cd $P4_HOME
# 安裝Mininet
git clone git://github.com/mininet/mininet mininet
cd mininet
sudo ./util/install.sh -nwv
cd ..

很easy就可以實現這一步。

4. Protobuf安裝

這個組件是重點安裝的對象,一定要仔細,它一旦安裝錯誤就會導致後面組件安裝各種報錯。

 安裝Protobuf
git clone https://github.com/google/protobuf.git
cd protobuf
git checkout ${PROTOBUF_COMMIT}
export CFLAGS="-Os"
export CXXFLAGS="-Os"
export LDFLAGS="-Wl,-s"
./autogen.sh
./configure --prefix=/usr
make -j${NUM_CORES}
make check -j${NUM_CORES}
sudo make install
sudo ldconfig
unset CFLAGS CXXFLAGS LDFLAGS
# force install python module
cd python
sudo python setup.py install
cd ../..

要注意這裏的git checkout ,一定要checkout,不然它會默認下載最新版的protobuf,在最後運行實例的時候會報如下的錯:No module named protobuf.internal,這就是版本的問題(我在下載的時候爲3.9.0,但是python2.7目前只支持最高3.8.0的),由於P4的測試都是基於3.2.0版本的,所以建議大家還是安裝老版本的。
在這裏插入圖片描述
make check -j這條命令也很重要,它會檢測安裝的protobuf是否通過所有的測試,如果沒有100% 通過務必要找到原因再繼續往下安裝。

5. grpc安裝

gRPC使客戶端和服務器應用程序能夠透明地進行通信,並簡化了連接系統的構建。關於它的解釋自己在命令行中找到github網址去查看吧:

git clone https://github.com/grpc/grpc.git
cd grpc
git checkout ${GRPC_COMMIT}
git submodule update --init --recursive
export LDFLAGS="-Wl,-s"
make -j${NUM_CORES}
sudo make install
sudo ldconfig
unset LDFLAGS
cd ..
# Install gRPC Python Package
sudo pip install grpcio

這裏一般會比較順利,除了下載速度。

6. Bmv2依賴安裝

這一步沒有完全安裝bmv2,一切都是按照github上的指示來操作的,先安裝BMv2的依賴,下面PI編譯時會用到。behavioral-model又叫bmv2交換機模塊,安裝命令如下:

# 安裝BMv2的依賴,下面PI編譯時會用到。
git clone https://github.com/p4lang/behavioral-model.git
cd behavioral-model
git checkout ${BMV2_COMMIT}
# From bmv2's install_deps.sh, we can skip apt-get install.
# Nanomsg is required by p4runtime, p4runtime is needed by BMv2...
tmpdir=`mktemp -d -p .`
cd ${tmpdir}
bash ../travis/install-thrift.sh
bash ../travis/install-nanomsg.sh
sudo ldconfig
bash ../travis/install-nnpy.sh
cd ..
sudo rm -rf $tmpdir
cd ..

這裏在運行install-thrift.sh和nanomsg.sh文件時會出現一些問題:無法連接到下載thrift源碼包的網址,http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz, 這裏給大家提供下載的鏈接鏈接:https://pan.baidu.com/s/1t5YUm79PtoLkzFt91UDTgw
提取碼:55sl
對應的,將install-thrift.sh文件中的這兩行註釋掉:

#wget http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz
#tar -xzvf thrift-0.9.2.tar.gz

然後插入如下一行代碼,也就是thrift-0.9.2的絕對路徑,也就是behavioral-model下的thrift-0.9.2目錄的位置,修改後保存文件。參考P4使用Ubuntu中安裝教程這篇文章中的圖來給大家一個直觀的感受:
在這裏插入圖片描述
nanomsg.sh文件的修改方式和thrift文件一樣,nnpy文件不需要修改可以直接用。至此,依賴項已完成。

7. PI安裝

PI是P4 runtime的實現,用於Control Plane對數據平面的控制。

# PI/P4Runtime
git clone https://github.com/p4lang/PI.git
cd PI
git checkout ${PI_COMMIT}
git submodule update --init --recursive
./autogen.sh
./configure --with-proto
make -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..

8. Bmv2安裝

剛剛只是安裝了bmv2的依賴,現在開始纔是正式安裝:

# 安裝Bmv2  
cd behavioral-model
./autogen.sh
./configure --enable-debugger --with-pi
make -j${NUM_CORES}
make check  -j${NUM_CORES}
sudo make install
sudo ldconfig

# Simple_switch_grpc target
cd targets/simple_switch_grpc
./autogen.sh
./configure --with-thrift
make -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
cd ..
cd ..

這裏多了個Simple_switch_grpc的安裝,它是支持P4 Runtime的SimpleSwitch版本,這個東西的安裝很關鍵,否則最後的示例也是無法運行的,不過只要你前面安裝的都沒有問題,這裏也不會有啥問題,如果除了問題,推薦github上的Simple_switch_grpc來看是否依賴項出了問題。至此,你已經無限接近最後的成功了,就差最後一個組件了!

9. P4C安裝

這個組件非常關鍵,它是p4語言的編譯器,而且對於它一定要注意版本的問題,因爲目前github上p4lang官網的人還在一直維護更新,所以語法經常有變化,如果你不下載最新的版本,那麼很有可能最後實例測試的時候就會因爲語法問題而game over,所以每一步的git checkout的版本很關鍵。

# 安裝P4C
git clone https://github.com/p4lang/p4c
cd p4c
git checkout ${P4C_COMMIT}
git submodule update --init --recursive
mkdir -p build
cd build
cmake ..
make -j${NUM_CORES}
make check  -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
cd ..

這裏在安裝cmake的時候會報一個錯誤:(如果一切順利當然就不用管下面的了)

-- Found LLVM 3.8.0
-- Added 14 tests to 'ebpf-bcc' (0 xfails)
-- Added 14 tests to 'ebpf' (0 xfails)
-- Added 5 tests to 'p4' (0 xfails)
-- Added 533 tests to 'p4' (5 xfails)
-- Added 5 tests to 'err' (0 xfails)
-- Added 160 tests to 'err' (0 xfails)
-- Added 207 tests to 'p14_to_16' (0 xfails)
-- CTest parallel: -j 4
-- Configuring incomplete, errors occurred!
See also "/home/ilya/p4/p4c/build/CMakeFiles/CMakeOutput.log".
See also "/home/ilya/p4/p4c/build/CMakeFiles/CMakeError.log".

若出現以上類似錯誤,參考github中的issue,具體的命令爲:

cmake .. -DENABLE_EBPF=OFF

就可以順利通過,這裏如果make check -j沒有全部通過也沒關係,也可以順利安裝。當然你也可以檢查去p4c的github上看看還有啥依賴項遺落了。至此,如果你全部安裝成功了,那麼恭喜你,下面就是你的驗收了!!

10. Tutorials 安裝

沒啥好說的。

# 最後獲得p4 tutorials
git clone https://github.com/p4lang/tutorials

至此安裝完成之後,現在P4目錄下面應該是這個樣子:

P4
├── behavioral-model  ## BMv2 軟件交換機
├── grpc              ## 作爲BMv2的依賴
├── mininet           ## mininet 網絡仿真
├── p4c			      ## p4c 編譯器
├── PI                ## PI P4 runtime庫
├── protobuf          ## 作爲依賴
└── tutorials         #### 教程目錄,以及以後主要的學習,實驗

我們主要的工作目錄時tutorials,其餘的都是被使用的工具組件。細看tutorials:

tutorials/
├── exercises   # 存放各種練習
├── utils       # 工具腳本目錄
└── vm          # 用於vagrant構建虛擬機的目錄,可以無視

其中utils裏面存放了一些用於調用各個組件(mininet, bmv2, PI, p4c)的腳本,有了這些腳本,我們可以專注於p4代碼的開發,控制面的編寫,以及拓撲的構建,而不需要費神去了解bmv2的啓動命令,p4c的調用選項等等。具體如何使用,也是非常的簡單,我們進入一個具體的例子查看:

# 我們切換進入 exercises/basic 這個例子
basic
├── basic.p4   # 要編寫的p4代碼
├── build      # 生成文件的目錄
├── logs       # 日誌文件, 在調試的時候真的非常重要!
├── Makefile   ### 通過Makefile 來調用utils下的腳本!
├── pcaps      # 生成的pcap包,可以使用wireshark等工具來分析
├── README.md  # 詳細的指導
├── receive.py ## 利用scapy寫的抓取和分析數據包的工具
├── s1-runtime.json  #
├── s2-runtime.json  # 在運行同時加載入交換機的控制面代碼,這裏有爭議,稍後再談
├── s3-runtime.json  #
├── send.py    ## 利用scapy寫的構建和發送數據包的工具
├── solution   # 這裏有這個例子的示例代碼(答案)
└── topology.json  # 描述拓撲的json文件

可以看到,通過Makefile,我們可以調用utils下的腳本,讓我們的p4代碼跑起來,具體的操作步驟參看github網址https://github.com/p4lang/tutorials/tree/master/exercises/basic::

#
#This will:
#compile basic.p4, and
#start a Mininet instance with three switches (s1, s2, s3) configured in a triangle, each connected to one host (h1, h2, and h3).
#The hosts are assigned IPs of 10.0.1.1, 10.0.2.2, and 10.0.3.3.
#
make run
#you should now see a Mininet command prompt. Open two terminals for h1 and h2, respectively:
mininet> xterm h1 h2
#Each host includes a small Python-based messaging client and server. In h2's xterm, start the server:
./receive.py
#In h1's xterm, send a message to h2:
./send.py 10.0.2.2 "P4 is cool"
#Type exit to leave each xterm and the Mininet command line. Then, to stop mininet:
make stop
#And to delete all pcaps, build files, and logs:
make clean

那麼恭喜你成功運行!!

後話

建議大家遇到問題在官網github中各自的組件安裝的issue裏面去查找解決問題的方法!此外就是不要放棄,即使反覆的失敗也不要灰心,這玩意就是這麼麻煩!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章