SDN實驗2:Open vSwitch虛擬交換機實踐
實驗目的
- 能夠對Open vSwitch進行基本操作;
- 能夠通過命令行終端使用OVS命令操作Open vSwitch交換機,管理流表;
- 能夠通過Mininet的Python代碼運行OVS命令,控制網絡拓撲中的Open vSwitch交換機
實驗要求
(一)基本要求
- 創建OVS交換機,並以ovs-switchxxx命名,其中xxx為本人在選課班級中的序號,例如ovs-switch001, ovs-switch088等。在創建的交換機上增加端口p0和p1,設置p0的端口號為100,p1的端口號為101,類型均為internal;為了避免網絡接口上的地址和本機已有網絡地址沖突,需要創建虛擬網絡空間(參考命令netns)ns0和ns1,分別將p0和p1移入,並分別配置p0和p1端口的ip地址為190.168.0.100、192.168.0.101,子網掩碼為255.255.255.0;最后測試p0和p1的連通性。
#創建ovs交換機,命名為ovs-switch016
sudo ovs-vsctl add-br ovs-switch016
#創建端口p0和p1,設置編號為100和101,類型均為"internal"
sudo ovs-vsctl add-port ovs-switch016 p0
sudo ovs-vsctl set Interface p0 ofport_request=100 type=internal
sudo ovs-vsctl add-port ovs-switch016 p1
sudo ovs-vsctl set Interface p1 ofport_request=101 type=internal
#查詢網口的相關信息
sudo ethtool -i p0
sudo ethtool -i p1
#配置虛擬網絡空間,並把接口移入網絡空間和配置ip地址
sudo ip netns add ns0
sudo ip link set p0 netns ns0
sudo ip netns exec ns0 ip addr add 192.168.0.100/24 dev p0
sudo ip netns exec ns0 ifconfig p0 promisc up
sudo ip netns add ns1
sudo ip link set p1 netns ns1
sudo ip netns exec ns1 ip addr add 192.168.0.101/24 dev p1
sudo ip netns exec ns1 ifconfig p1 promisc up
#測試p0和p1的連通性
sudo ip netns exec ns0 ping 192.168.0.101
測試結果:p0和p1之間可以ping通
用sudo ovs-vsctl show
查看網絡狀態
- 使用Mininet搭建的SDN拓撲,如下圖所示,要求支持OpenFlow 1.3協議,主機名、交換機名以及端口對應正確
打開mininet可視化工具:
sudo ./../mininet/examples/miniedit.py #在lab2下執行
放置拓撲並設置協議為openflow1.3
另存為python文件,並將對應代碼修改為:
net.addLink(h1, s1, 1, 1)
net.addLink(h2, s1, 1, 2)
net.addLink(h3, s2, 1, 1)
net.addLink(h4, s2, 1, 2)
net.addLink(s1, s2, 3, 3)
並運行sudo python3 topo1.py
可得:
- 通過命令行終端輸入“ovs-ofctl”命令,直接在s1和s2上添加流表,划分出所要求的VLAN。
- 主機連通性要求:h1 – h3互通,h2 – h4互通,其余主機不通
在另一個終端下執行下列指令:
#對s1下發流表:將主機1,2發送來的包打上vlan標記,將主機3,4發送來的包取出vlan標記
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=0,actions=pop_vlan,output:1
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=1,actions=pop_vlan,output:2
#對s2下發流表:將主機3,4發送來的包打上vlan標記,將主機1,2發送來的包取出vlan標記
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=0,actions=pop_vlan,output:1
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=1,actions=pop_vlan,output:2
連通性測試:
因為h1和h2,h3和h4不在同一個vlan里,即使連在同一個交換機上,也無法連通:
輸入下列命令,查看下發流表:
sudo ovs-ofctl -O OpenFlow13 dump-flows s1
sudo ovs-ofctl -O OpenFlow13 dump-flows s2
使用sudo wireshark
運行wireshark,使其抓取s1上的3端口,同時mininet進行h1 ping h3
觀察到h1 ping h3的vlan標記為0,h2 ping h4的vlan標記為1,符合預期的結果
(二)進階要求
閱讀SDNLAB實驗使用Mininet,編寫Python代碼,生成(一)中的SDN拓撲,並在代碼中直接使用OVS命令,做到可以直接運行Python程序完成和(一)相同的VLAN划分。
編寫mytopo.py
代碼並執行:
from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSController
from mininet.node import CPULimitedHost, Host, Node
from mininet.node import OVSKernelSwitch, UserSwitch
from mininet.node import IVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import TCLink, Intf
from subprocess import call
def mynetwork():
net = Mininet( topo=None,build=False,ipBase='192.168.0.0/24')
info( '*** Adding controller\n' )
c0=net.addController(name='c0',
controller=Controller,
protocol='tcp',
port=6633)
info( '*** Add switches\n')
s1 = net.addSwitch('s1', cls=OVSKernelSwitch)
s2 = net.addSwitch('s2', cls=OVSKernelSwitch)
info( '*** Add hosts\n')
h1 = net.addHost('h1', cls=Host, ip='192.168.0.1', defaultRoute=None)
h2 = net.addHost('h2', cls=Host, ip='192.168.0.2', defaultRoute=None)
h3 = net.addHost('h3', cls=Host, ip='192.168.0.3', defaultRoute=None)
h4 = net.addHost('h4', cls=Host, ip='192.168.0.4', defaultRoute=None)
info( '*** Add links\n')
net.addLink(h1, s1, 1, 1)
net.addLink(s1, h2, 2, 1)
net.addLink(s1, s2, 3, 3)
net.addLink(s2, h3, 1, 1)
net.addLink(s2, h4, 2, 1)
info( '*** Starting network\n')
net.build()
info( '*** Starting controllers\n')
for controller in net.controllers:
controller.start()
info( '*** Starting switches\n')
net.get('s1').start([c0])
net.get('s2').start([c0])
info( '*** Post configure switches and hosts\n')
#s1、s2分別調用cmd()實現添加流表和划分vlan的操作
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=0,actions=pop_vlan,output:1')
s1.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=1,actions=pop_vlan,output:2')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:3')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:3')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=0,actions=pop_vlan,output:1')
s2.cmd('sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=1,actions=pop_vlan,output:2')
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
mynetwork()
進行連通性測試,實驗結果與(一)中的要求一致
個人總結
實驗過程中的問題及部分解決方法
(一)使用sudo ovs-vsctl show
查看網絡狀態時,出現了非常多的信息,里面有包括剛剛創建的ovs-switch016網橋,但還包括了很多其他網橋的信息,用sudo ovs-vsctl list-br
命令查看后發現確實有很多個網橋,但目前還不知道為什么會把這些網橋都顯示出來
(二)使用pingall語句時,執行過sudo LANG=en_US mn --test pingall
之后,雖然可以從每一條的結果中看到正確的結果(相同vlan的可以ping通,不同vlan的顯示目標主機不可達),但是最后的result里還是寫着100% dropped(執行alias sudo='sudo '
和alias mn='LANG=en_US mn'
也一樣),暫時還沒找到特別的解決方法
(三)使用wireshark抓包時,一開始默認抓取的端口是s1-eth1,所以一直看不到所抓到的數據包的vlan tag,而且執行h2 ping h4時沒有任何抓到包的消息。后來才知道應該設置抓取的端口為s1-eth3(在捕獲--選項中選中希望抓取的端口,開始進行抓包即可),才可以看到h1 ping h3對應的vlan tag,希望看到h2 ping h4的vlan tag同理,在s2-th3端口進行
(四)這個問題也是之前比較常出現的問題,在試圖運行mininet時出現報錯Exception: Please shut down the controller which is running on port 6633:
,之前知道重啟可以解決這個問題,但有可以不用重啟的方法,直接執行sudo mn -c
即可
個人感想
在這次實驗過程中,學習了Open vSwitch虛擬交換機的一些相關知識與概念,中間遇到過一些比較奇怪的小bug(例如在虛擬機power off菜單處掛起后再試圖打開,會一直黑屏,所以只能重啟),把文件刪除后只能從前幾個步驟重新再做一遍,所以消耗的時間也比較久。雖然之后的實驗中可能也還會遇到這樣的可能性,但是做實驗的時間還是很寶貴的,所以還是需要避免類似的情況反復出現。之前只了解過一些Vlan的概念,這次實驗加深了對Vlan的實現方式的理解,但是實驗過程中涉及到的一些原理還是不夠了解,還需要繼續學習。