一、實驗內容
搭建如下網絡拓撲,並熟悉相關指令。

二、搭建開發環境
2.1 開發環境搭建
2.1.1下載ubuntu鏡像文件
鏡像下載地址 https://www.ubuntu.com/download/desktop
下載后的文件:ubuntu-18.04.2-desktop-amd64.iso
2.1.2安裝虛擬機
打開VMware,創建新的虛擬機,選擇自定義,點擊下一步
選擇自定義硬件,應用鏡像文件
選擇已下載好的鏡像文件
點擊關閉后完成,VMware就會生成剛才安裝的Ubuntu虛擬機:
2.2 應用軟件安裝
2.2.1安裝mininet
安裝mininet的方法具體有很多種,由於本地采用的是VM和Ubuntu虛擬機的環境,所以本次實驗采用源碼安裝的方式。
要從源代碼本地安裝,首先需要獲取源代碼:
sudo apt-get update sudo apt-get install git sudo git clone git://github.com/mininet/mininet
下載源代碼后,安裝Mininet的命令是:
sudo ./mininet/util/install.sh -a
(-a:安裝Mininet VM中包含的所有內容,包括Open vSwitch等依賴項以及OpenFlow wireshark dissector和POX等附加項。默認情況下,這些工具將構建在主目錄中創建的目錄中。)
安裝完成后,測試基本的Mininet功能:
sudo apt install net-tools(不安裝net-tools會提示找不到所需要的可執行的ifconfig)
sudo mn --test pingall
2.2.2安裝ryu
使用pip命令安裝:
sudo apt install python-pip
pip install ryu
2.2.3獲取Open vSwitch源代碼
Open vSwitch源代碼的規范位置是它的Git存儲庫,您可以將其克隆到名為“ovs”的目錄中:
sudo git clone https://github.com/openvswitch/ovs.git
三、搭建網絡環境
3.1 啟動ryu控制器
ryu-manager --verbose ryu.app.simple_switch_13
3.2 啟動mininet搭建網絡拓撲
搭建網絡topo,由於所要求的網絡拓撲結構為比較簡單的線性拓撲,可以直接使用--topo linear,x構建,選用Open vSwitch交換機:--switch ovsk。啟動mininet:
mn --topo linear,2 --mac --switch ovsk --controller remote
這時候就可以看到mininet已經連接到ryu控制器了:
至此,所要求的網絡環境已經搭建完成,對其進行簡單的測試,在mininet的控制命令行里執行pingall:
四、實驗步驟
4.1 使用wireshark抓取OpenFlow消息
(1)在安裝mininet時已經安裝了wireshark,於是只需要在主機啟動wireshark:
sudo wireshark
等待一會wireshark便會啟動:
(2)在mininet的控制命令行中執行:
h1 ping -c 4 h2
(2)wireshark中選擇監聽any,過濾器filter中輸入openflow_v4即可抓取交換機s1與控制器c0之間的openflow消息:
4.2 OpenFlow報文分析
4.2.1 packet-in消息
(1) 當交換機收到一個數據包后,並未與流表中匹配成功,那么交換機就會將數據封裝在Packer-in消息中,發送給控制器處理。此時數據包會被緩存在交換機中等待處理。
交換機流表所指示的action列表中包含轉發給控制器的動作(Output=Controller),此時數據不會被緩存在控制器中。
(2)In_port數據包進入交換機的入端口號
Reason為packet-in事件的產生原因
同時,從reason的消息格式也可以看出觸發packet-in的兩種情況:OFPR_NO_MATCH和OFPR_ACTION。
4.2.2 packet-out消息
(1)當控制器希望交換機發送某個數據包,其使用Packet_out消息。例子:arp報文在廣播的時候,在交換機中不能直接將arp廣播,而是,將其封裝在Packet_out里面,交換機泛洪的是Packet_out。
(2)控制器向一個交換機發送packet-out消息,buffer_id=-1,data段為某種特殊數據包,actions為從交換機的某個端口進行轉發,如果發出這個數據包的端口另一端也連接一個Open vSwitch交換機,對端的交換機會產生一個packet-in消息將這個特殊的數據包包上交給控制器,從而控制器他側到一條鏈路的存在(控制器實現鏈路發現,就是依靠packet-out消息)。
(3)當控制器斷電或者交換機與控制器之間的連接斷開,則交換機會尋找備用控制器,當無法找到備用控制器時便會進入緊急模式(交換機初始化時也是在這個模式下),在緊急模式下,交換機默認將所有接受到的數據包丟棄。
4.2.3 echo-request消息,echo-reply消息
echo消息為對稱的消息,作用譬如心跳機制,定期給另一方發送echo-request消息,另一方需要給予echo-reply消息回應,確保控制器與交換機的連接狀態。雙方發送的echo消息只有OpenFlow報文頭部,每一個request和reply的請求transcation的ID相同。
4.2.4 flow-mod消息
Flow-Mod消息用開添加、刪除、修改openflow交換機的消息; Flow-Mod消息共有5種類型:ADD、DEKETE、DELETE-STRICT、MODIFY、MODIFY-STRICT。Flow_mod這個消息是OpenFlow中最重要的消息,用來添加、刪除、修改OpenFlow交換機的流表信息。當交換機收到一個無法處理的數據包,封裝到Packet_in消息轉發給控制器后,控制器可以發送一個Flow_mod消息下發一個流表到交換機,並且指定該數據包按照此流表項的action處理。
Flow_mod消息包含四個部分:OpenFlow報文頭、Flow_mod固定字段、Match字段和Instruction字段。分別用來標識該消息的類型、流表項的內容等。
4.3 測試主機連通性
先使主機1可以ping 通主機2,主機2也可以ping 通主機1。
4.4 操作流表項
然后對流表進行操作,使主機1不能ping 通主機2,主機2也不能ping 通主機1。
查看s1中已經存在的流表項:
ovs-ofctl dump-flows s1
4.4.1刪除流表項
執行刪除命令:
ovs-ofctl del-flows s1 in_port='s1-eth2'"
可見交換機s1流表中in_port='s1-eth2'的流表項已經刪除,再執行:h1 ping h2
在刪除流表項之后,h1已無法ping通h2。
4.4.2修改流表項
執行添加流表項命令:(注意add-flow后面不加s)
ovs-ofctl add-flow s1 'in_port="s1-eth1",dl_src=00:00:00:00:00:01, dl_dst=00:00:00:00:00:02 actions=drop'
修改流表項之后,h1 ping h2
4.5 修改流表項
限制該主機1一定時間(比如一分鍾)內再次與主機2通信。限制時間過后,主機1可以與主機2通信。
由於流表具有存活時間,設置錯誤的流表使其無法通信,再通過hard_timeout定期刪除流表,刪除流表后又可以通信。
idle_timeout,空閑時間,如值為 10,表示若某條流表在最近 10s 內沒有被匹配過則刪除。
hard_timeout,存活時間,如值為 10,則從該流表被安裝經過 10s 后無論被使用情況如何,立即被刪除。
idle_age,未命中時間,如值為 10,表示已經有 10s 沒有匹配到過這條流表了。當這個值等於 idle_timeout 時,這條流表就真的失效了。
duration,流表年齡,指的是流表自從安裝到交換機上總共所經過的時間。
因此可以通過修改流表設置,使主機1和主機2無法通信,具體實施的是以下三種方法。
4.5.1將接收到的數據包丟棄
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=drop"
4.5.2設置一個錯誤端口
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=output:100"
4.5.3設置錯誤ip地址
sudo ovs-ofctl add-flow s1 "hard_timeout=60,actions=mod_nw_src: 192.168.1.111"
設置hard_timeout=60
一分鍾后,主機1和主機2又可以實現通信
五、問題與分析
問題1:執行mn命令構建網絡拓撲時出現:“Unable to contact the remote cotroller at 127.0.0.1:6633”。
分析:在搭建網絡拓撲之前沒有啟動ryu控制器,導致無法連接到控制器。
問題2:利用在mininet的控制命令行里執行Python腳本添加host、link、swtich之后原來的主機與新增的主機無法ping通。
分析:(1)在增加一個host之后,需要給它配置IP以及虛擬網卡信息;(2)新增的switch與控制器之間沒有添加網橋,需要在xterm c0中執行添加網橋的命令“ovs-vsctl add-br s3”以及添加相應的端口“ovs-vsctl add-port s3 s3-eth0”等。
問題3:刪除有三個端口的交換機流表項之后只能添加三條流表項。
分析:(1)添加流表項時執行的命令
ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth2”
ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth3”
(2)在in_port相同的情況下,流表里面只會保存最新的一條流表項,解決方法就是修改命令為ovs-ofctl add-flow s1“in_port=s1-eth1,actions=output:s1-eth2,s1-eth3” 。