Mininet with different network subnet
Introduction
我們使用 mn --topo single,3 --mac
創造一個有不同subnet的拓墣,使用--mac
使得所有host的MAC Address更加簡單,能夠使得此實驗變得容易。
我們目標是要讓這三個不同subnet的host都能夠互相溝通。
網路架構如下圖
在此實驗中,我們並不採用任何controller來控制所有封包,單純就手動下flow entry來處理所有的封包,一旦了解了這中間的道理,要自己撰寫APP處裏此情況就不會太難了。
Solutions
首先,mininet創造出來網路後,預設會讓所有的host都屬於相同的network subnet 10.0.0.0/24,因此在實驗開始前,我們要先修改其餘host的設定,改變其network subnet。
- 在mininet的環境中執行下列指令
- h2 ifconfig h2-eth0 20.0.0.1
- h3 ifconfig h3-eth0 30.0.0.1
接下來,我們先執行h1 ping h3,這時候我們會看到有錯誤訊息 connect: Network is unreachable。這個原因是因為對於host1來說,host2是不一樣的network subnet,此時會將該封包轉送到本身subnet的gateway來處理,但是該host不知道gateway在哪裡,因此我們要幫他們加上route for default gateway。
- 在mininet的環境中執行下列指令
- h1 route add default gw 10.0.0.254 h1-eth0
- h2 route add default gw 20.0.0.254 h2-eth0
- h3 route add default gw 30.0.0.254 h3-eth0
接下來,我們繼續執行h1 ping h3
,此時會得到下列的訊息
mininet> h1 ping h3
PING 30.0.0.1 (30.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
From 10.0.0.1 icmp_seq=3 Destination Host Unreachable
From 10.0.0.1 icmp_seq=4 Destination Host Unreachable
到這步驟後,因為我們還沒有寫入任何的flow entry,所以網路不通是正常的。在處理ICMP 封包前,我們必須要先處理ARP的封包。 這邊我們先在mininet那邊持續的執行h1 ping h3。同時,我們開啟第二個視窗,執行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
20:07:04.639862 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28
20:07:05.639859 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28
20:07:06.639895 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28
20:07:07.639856 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 10.0.0.254 tell 10.0.0.1, length 28
由這邊可以發現,Host 1透過arp在詢問其gateway相關資訊,但是麻煩的是,在此網路中,我們並沒有真的一個Device的ip是該gateway,為了解決這個問題,我們有兩個選擇
- 弄一個Host出來,當作gateway去處理
- 弄個arp proxy來處理,這部分在OpenDayLight中預設有提供此module,讓controller假裝自己是gateway來處理此問題。
由於本實驗並沒有採用任何controller,因此我們要手動修改switch,讓她覺得自己是gateway,能夠回arp reply給Host。
- 在mininet的環境中執行下列指令
- s1 ifconfig s1:0 10.0.0.254
- s1 ifconfig s1:1 20.0.0.254
- s1 ifconfig s1:2 30.0.0.254
我們令s1這個interface擁有三個ip,這些ip都代表每個network subnet的gatewayip,接下來為了讓switch自己幫我們處理所有arp request for gateway,我們加入下列flow entry到s1中
- 在mininet的環境中執行下列指令
- sh ovs-ofctl add-flow s1 "table=0,priority=65535,arp,arp_tpa=10.0.0.254 actions=LOCAL"
- sh ovs-ofctl add-flow s1 "table=0,priority=65535,arp,arp_tpa=20.0.0.254 actions=LOCAL"
- sh ovs-ofctl add-flow s1 "table=0,priority=65535,arp,arp_tpa=30.0.0.254 actions=LOCAL"
上面這三個flow entry會把所有arp request for gateway的封包都導入本地的OS去處理,因此這些封包就會進入到 s1:0,s1:1,s1:2去處理,並且回覆一個arp reply。這些arp reply都會再度的進到OVS內,為了處理這些封包,我們要根據他的destination ip address把它給送回去對應的Host。
- sh ovs-ofctl add-flow s1 "table=0,priority=1,arp,nw_dst=10.0.0.1,actions=output:1"
- sh ovs-ofctl add-flow s1 "table=0,priority=1,arp,nw_dst=20.0.0.1,actions=output:2"
- sh ovs-ofctl add-flow s1 "table=0,priority=1,arp,nw_dst=30.0.0.1,actions=output:3"
這些完畢後,arp封包就能夠正常處理了,接下來為了處理ICMP,我們要再做一些設定,在此實驗中,我們同時測試multiple table的功用,因此我們決定把ICMP routing的部分放到第二個table去處理。 首先,我們先在table 0加入一個flow entry,把剛剛沒有被arp處理掉的封包都送到table 1去處理。
- sh ovs-ofctl add-flow s1 "table=0,priority=0,actions=resubmit(,1)"
接者,在table 1,因為switch的身份很類似router,因此我們要修改所有封包的destination MAC Address。
- 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"
- 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"
- sh ovs-ofctl add-flow s1 "table=1,icmp,nw_dst=30.0.0.1,actions=mod_dl_dst=00:00:00:00:00:03,output:3"
最後執行h1 ping h3
,就會順利的通了,以下整理一下flow table中的所有flow entry
#Those two flow will handle the arp-request for the gateway, it will send the arp-request to s1
table=0,priority=65535,arp,arp_tpa=10.0.0.254 actions=LOCAL
table=0,priority=65535,arp,arp_tpa=20.0.0.254 actions=LOCAL
table=0,priority=65535,arp,arp_tpa=30.0.0.254 actions=LOCAL
table=0,priority=1,arp,nw_dst=10.0.0.1,actions=output:1
table=0,priority=1,arp,nw_dst=20.0.0.1,actions=output:2
table=0,priority=1,arp,nw_dst=30.0.0.1,actions=output:3
table=0,priority=0,actions=resubmit(,1)
#table1 - forward/route
table=1,icmp,nw_dst=10.0.0.1,actions=mod_dl_dst=00:00:00:00:00:01,output:1
table=1,icmp,nw_dst=20.0.0.1,actions=mod_dl_dst=00:00:00:00:00:02,output:2
table=1,icmp,nw_dst=30.0.0.1,actions=mod_dl_dst=00:00:00:00:00:03,output:3