Open vSwith模擬網關實現不同子網的互通
一.實驗目的
本實驗通過Mininet構建子網,并使得OVS作為網關,來模擬子網間的互通。在實驗的過程中,我們來學習一下內容:OVS構建子網過程。
OVS設置網關過程。
OVS配置流表過程。
二.實驗準備
實驗環境我們使用Mininet進行構建,建議到Mininet官方下載***的Mininet虛擬機,本實驗中虛擬機版本是mininet-2.2.1-150420-ubuntu-14.04-server-amd64,或者參考官方文檔中介紹的Native Installation from Source進行安裝。
實驗拓撲圖如下:
三.實驗步驟
1.構建網絡拓撲。
我們的目標是要讓兩個不同子網的主機能相互通信,可以先構建出兩個主機,然后給主機設置不同子網。由于Mininet虛擬的主機默認屬于10.0.0.0/24,需要對主機網絡進行設置。
說明:
$> 表示Linux命令行的輸入,權限為root。
mininet> 表示Mininet命令行模式。
創建拓撲
$> mn --topo single,2 --mac
說明:參數--mac是為了創建的host有更簡單的MAC地址,為后面流表創建提供方便。
查詢狀態
mininet> dump
可以看出,默認的h1和h2是在同一網段,而且可以相互ping通。
mininet> h1 ping h2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.96 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.412 ms
修改網絡設置
mininet> h1 ifconfig h1-eth0 10.0.0.1/24 netmask 255.0.0.0 mininet> h2 ifconfig h2-eth0 20.0.0.1/24 netmask 255.0.0.0
測試網絡狀態如下:
mininet> h1 ping h2 connect: Network is unreachable
由于通過配置,h1和h2已經不在同一網段,當h1 ping h2時,包會轉發到子網的網關來處理,但是由于當前環境中沒有針對兩個網段設置網關,最終狀態為不可達。此時我們可以為主機設置網關。
設置網關
mininet> h1 route add default gw 10.0.0.254 h1-eth0 mininet> h2 route add default gw 20.0.0.254 h2-eth0
測試網絡狀態如下:
mininet> h1 ping h2 PING 20.0.0.1 (20.0.0.1) 56(84) bytes of data. From 10.0.0.1 icmp_seq=1 Destination Host Unreachable From 10.0.0.1 icmp_seq=2 Destination Host Unreachable
#p#
為了更直觀的觀察當前網絡狀態,在新的Linux窗口使用tcpdump來查看h1 ping h2過程中包的信息。如下:
$>tcpdump -vvv -i s1-eth1 tcpdump: WARNING: s1-eth1: no IPv4 address assigned tcpdump: listening on s1-eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 05:38:06.917012 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28 05:38:07.917134 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28
當h1-eth0發送ARP包請求s1-eth1網關,而當前環境中沒有網關設備,OVS無法進行轉發;另外,如果OVS連接了控制器,如OpenDaylight,這可以利用它預設的ARP Proxy,讓控制器來提供目標地址信息。因此ICMP封包前,由于獲取不到目標地址信息,而導致網絡不可達。
2. 設置OVS為網關
如果實驗連接了控制器,這可以通過控制器獲得目標地址的信息,這部分可以單獨通過另外的實驗進行驗證。由于試驗中沒有任何控制器,因此需要對OVS進行配置,使得其具有gateway的功能,能夠對ARP進行回復。
mininet> s1 ifconfig s1:0 10.0.0.254 mininet> s1 ifconfig s1:1 20.0.0.254
測試網絡狀態,發現h1與網關可以ping通了。
mininet> h1 ping 10.0.0.254 PING 10.0.0.254 (10.0.0.254) 56(84) bytes of data. 64 bytes from 10.0.0.254: icmp_seq=1 ttl=64 time=3.35 ms 64 bytes from 10.0.0.254: icmp_seq=2 ttl=64 time=0.669 ms
從tcpdump窗口觀察到的信息也顯示相關信息如下:
10.0.0.1 > 10.0.0.254: ICMP echo request, id 4284, seq 3, length 64 06:01:43.104097 IP (tos 0x0, ttl 64, id 3241, offset 0, flags [none], proto ICMP (1), length 84) 10.0.0.254 > 10.0.0.1: ICMP echo reply, id 4284, seq 3, length 64 06:01:46.114482 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.1 tell 10.0.0.254, length 28
但是,此時h1 ping h2還是不會通的。因為當前轉發平面沒有任何流對發過來的ICMP包做轉發。因此,我們需要添加一些流,使得整個網絡最終運作起來。
3. 配置流表
處理ARP請求
當網管的ARP流到來后,將其交給本地的OVS處理。
mininet> sh ovs-ofctl add-flow s1 "table=0,priority=65535,arp,arp_tpa=10.0.0.254 actions=LOCAL" mininet> sh ovs-ofctl add-flow s1 "table=0,priority=65535,arp,arp_tpa=20.0.0.254 actions=LOCAL"
處理ARP應答
該應答回復目標地址的出口,比如將目標網絡10.0.0.1的包通過出口端口1抓發出去。端口信息可以查詢如下:
mininet> sh ovs-vsctl -- --columns=name,ofport list Interface name : "s1-eth2" ofport : 2 name : "s1-eth1" ofport : 1 name : "s1" ofport : 65534
處理應答的流表如下:
mininet> sh ovs-ofctl add-flow s1 "table=0,priority=1,arp,nw_dst=10.0.0.1,actions=output:1" mininet> sh ovs-ofctl add-flow s1 "table=0,priority=1,arp,nw_dst=20.0.0.1,actions=output:2"
處理了應答包后,實際上網絡還是不能通。到目前為止,僅對ARP的包做了相應的處理,而ICMP的包為處理。
10.0.0.1 > 20.0.0.1: ICMP echo request, id 5004, seq 1, length 64 06:28:06.932565 IP (tos 0x0, ttl 64, id 52645, offset 0, flags [DF], proto ICMP (1), length 84) 10.0.0.1 > 20.0.0.1: ICMP echo request, id 5004, seq 2, length 64 06:28:07.932469 IP (tos 0x0, ttl 64, id 52646, offset 0, flags [DF], proto ICMP (1), length 84)
ICMP應答處理
接下來需要對ICMP的請求進行處理。為了使得流表表達更清晰,我們將ICMP路由的處理放在另外一個table處理。 也就是在table(1)中設置一個***優先級的流,將非ARP的包丟給下一個流表處理。
mininet> sh ovs-ofctl add-flow s1 "table=0,priority=0,actions=resubmit(,1)"
在table(1)中,OVS的角色有點像router,我們需要修改ICMP封包的目標MAC地址。
mininet> sh ovs-ofctl add-flow s1 "table=1,icmp,nw_dst=10.0.0.1,actions=mod_dl_dst=00:00:00:00:00:01,output:1" mininet> sh ovs-ofctl add-flow s1 "table=1,icmp,nw_dst=20.0.0.1,actions=mod_dl_dst=00:00:00:00:00:02,output:2"
***,執行h1 ping h2,兩個子網的主機能順利ping通。
mininet> h1 ping h2 PING 20.0.0.1 (20.0.0.1) 56(84) bytes of data. 64 bytes from 20.0.0.1: icmp_seq=1 ttl=64 time=1.29 ms 64 bytes from 20.0.0.1: icmp_seq=2 ttl=64 time=0.080 ms 64 bytes from 20.0.0.1: icmp_seq=3 ttl=64 time=0.089 ms