![](/img/trans.png)
[英]How to check which ports are connected to host in Mininet using open vswitch and a Pox controller?
[英]Simulate a network with routers using Mininet/POX
我是 Mininet 和 POX 控制器來模擬 SDN 的新手。 我想使用 Mininet Python API 創建以下網絡:
我的目標是讓每個主機/路由器向所有其他主機/路由器發送數據包。 為此,我使用了ip route命令。 這是我用於創建網絡的 Python 代碼:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.node import RemoteController
from mininet.log import setLogLevel, info
from mininet.cli import CLI
class LinuxRouter(Node):
def config(self, **params):
super(LinuxRouter, self).config(**params)
self.cmd('sysctl net.ipv4.ip_forward=1')
def terminate(self):
self.cmd('sysctl net.ipv4.ip_forward=0')
super(LinuxRouter, self).terminate()
class NetworkTopo(Topo):
def build(self, **_opts):
# Add 4 routers in four different subnets
r1 = self.addHost('r1', cls=LinuxRouter, ip='10.0.0.1/24')
r2 = self.addHost('r2', cls=LinuxRouter, ip='10.1.0.1/24')
r3 = self.addHost('r3', cls=LinuxRouter, ip='10.2.0.1/24')
r4 = self.addHost('r4', cls=LinuxRouter, ip='10.3.0.1/24')
# Add 2 switches
s1 = self.addSwitch('s1')
s2 = self.addSwitch('s2')
s3 = self.addSwitch('s3')
s4 = self.addSwitch('s4')
# Add host-switch links in the same subnet
self.addLink(s1,
r1,
intfName2='r1-eth1',
params2={'ip': '10.0.0.1/24'})
self.addLink(s2,
r2,
intfName2='r2-eth1',
params2={'ip': '10.1.0.1/24'})
self.addLink(s3,
r3,
intfName2='r3-eth1',
params2={'ip': '10.2.0.1/24'})
self.addLink(s4,
r4,
intfName2='r4-eth1',
params2={'ip': '10.3.0.1/24'})
# Add router-router links in new subnets for the router-router connections
self.addLink(r1,
r2,
intfName1='r1-eth2',
intfName2='r2-eth2',
params1={'ip': '10.100.0.1/24'},
params2={'ip': '10.100.0.2/24'})
self.addLink(r1,
r3,
intfName1='r1-eth3',
intfName2='r3-eth2',
params1={'ip': '10.101.0.1/24'},
params2={'ip': '10.101.0.2/24'})
self.addLink(r3,
r4,
intfName1='r3-eth3',
intfName2='r4-eth2',
params1={'ip': '10.102.0.1/24'},
params2={'ip': '10.102.0.2/24'})
self.addLink(r2,
r4,
intfName1='r2-eth3',
intfName2='r4-eth3',
params1={'ip': '10.103.0.1/24'},
params2={'ip': '10.103.0.2/24'})
# Adding hosts specifying the default route
h1 = self.addHost(name='h1',
ip='10.0.0.10/24',
defaultRoute='via 10.0.0.1')
h2 = self.addHost(name='h2',
ip='10.1.0.10/24',
defaultRoute='via 10.1.0.1')
h3 = self.addHost(name='h3',
ip='10.2.0.10/24',
defaultRoute='via 10.2.0.1')
h4 = self.addHost(name='h4',
ip='10.3.0.10/24',
defaultRoute='via 10.3.0.1')
# Add host-switch links
self.addLink(h1, s1)
self.addLink(h2, s2)
self.addLink(h3, s3)
self.addLink(h4, s4)
def run():
topo = NetworkTopo()
net = Mininet(topo=topo, controller=RemoteController)
# Add routing for reaching networks that aren't directly connected
info(net['r1'].cmd("ip route add 10.1.0.0/24 via 10.100.0.2 dev r1-eth2"))
info(net['r1'].cmd("ip route add 10.2.0.0/24 via 10.101.0.2 dev r1-eth3"))
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.101.0.2 dev r1-eth3"))
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.100.0.2 dev r1-eth2"))
info(net['r2'].cmd("ip route add 10.0.0.0/24 via 10.100.0.1 dev r2-eth2"))
info(net['r2'].cmd("ip route add 10.3.0.0/24 via 10.103.0.2 dev r2-eth3"))
info(net['r2'].cmd("ip route add 10.2.0.0/24 via 10.103.0.2 dev r2-eth3"))
info(net['r2'].cmd("ip route add 10.2.0.0/24 via 10.100.0.1 dev r2-eth2"))
info(net['r3'].cmd("ip route add 10.0.0.0/24 via 10.101.0.1 dev r3-eth2"))
info(net['r3'].cmd("ip route add 10.3.0.0/24 via 10.102.0.2 dev r3-eth3"))
info(net['r3'].cmd("ip route add 10.1.0.0/24 via 10.102.0.2 dev r3-eth3"))
info(net['r3'].cmd("ip route add 10.1.0.0/24 via 10.101.0.1 dev r3-eth2"))
info(net['r4'].cmd("ip route add 10.1.0.0/24 via 10.103.0.1 dev r4-eth3"))
info(net['r4'].cmd("ip route add 10.2.0.0/24 via 10.102.0.1 dev r4-eth2"))
info(net['r4'].cmd("ip route add 10.0.0.0/24 via 10.102.0.1 dev r4-eth2"))
info(net['r4'].cmd("ip route add 10.0.0.0/24 via 10.103.0.1 dev r4-eth3"))
net.start()
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
run()
這是 Mininet CLI 上net命令的輸出:
h1 h1-eth0:s1-eth2
h2 h2-eth0:s2-eth2
h3 h3-eth0:s3-eth2
h4 h4-eth0:s4-eth2
r1 r1-eth1:s1-eth1 r1-eth2:r2-eth2 r1-eth3:r3-eth2
r2 r2-eth1:s2-eth1 r2-eth2:r1-eth2 r2-eth3:r4-eth3
r3 r3-eth1:s3-eth1 r3-eth2:r1-eth3 r3-eth3:r4-eth2
r4 r4-eth1:s4-eth1 r4-eth2:r3-eth3 r4-eth3:r2-eth3
s1 lo: s1-eth1:r1-eth1 s1-eth2:h1-eth0
s2 lo: s2-eth1:r2-eth1 s2-eth2:h2-eth0
s3 lo: s3-eth1:r3-eth1 s3-eth2:h3-eth0
s4 lo: s4-eth1:r4-eth1 s4-eth2:h4-eth0
c0
我有兩個問題:
1- 在 mininet CLI 上運行 pingall,給出以下輸出:
mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3 h4 r1 r2 r3 r4
h2 -> h1 h3 h4 r1 r2 r3 r4
h3 -> h1 h2 h4 r1 r2 r3 r4
h4 -> h1 h2 h3 r1 r2 r3 r4
r1 -> h1 h2 h3 X r2 r3 X
r2 -> h1 h2 X h4 r1 X r4
r3 -> h1 X h3 h4 r1 X r4
r4 -> X h2 h3 h4 X r2 r3
*** Results: 14% dropped (48/56 received)
為什么路由器不能將數據包發送到“相反的”路由器和主機? 我不明白為什么主機可以將數據包發送到路由器。
2-在“路由表”中使用兩個具有相同目的地的條目,例如:
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.101.0.2 dev r1-eth3"))
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.100.0.2 dev r1-eth2"))
在輸出中產生此警告:
RTNETLINK answers: File exists
並且不能使用替代路由路徑。 我想讓 h1 通過路由器 r2 向主機 h4 發送數據包,但也通過路由器 r3。 如何使用 ip route 命令修復“多路徑”?
讓我們從這個開始:
r1 -> h1 h2 h3 X r2 r3 X
為什么r1
不能 ping h4
? h4
是10.3.0.10
。 r1
具有以下路由表:
mininet> r1 ip route
10.0.0.0/24 dev r1-eth1 proto kernel scope link src 10.0.0.1
10.1.0.0/24 via 10.100.0.2 dev r1-eth2
10.2.0.0/24 via 10.101.0.2 dev r1-eth3
10.3.0.0/24 via 10.101.0.2 dev r1-eth3 metric 100
10.3.0.0/24 via 10.100.0.2 dev r1-eth2 metric 200
10.100.0.0/24 dev r1-eth2 proto kernel scope link src 10.100.0.1
10.101.0.0/24 dev r1-eth3 proto kernel scope link src 10.101.0.1
對10.3.0.10
的h4
的請求將通過10.101.0.2
( r3
) 路由,源地址為10.101.0.1
。
r3
具有以下路由表:
mininet> r3 ip route
10.0.0.0/24 via 10.101.0.1 dev r3-eth2
10.1.0.0/24 via 10.102.0.2 dev r3-eth3 metric 100
10.1.0.0/24 via 10.101.0.1 dev r3-eth2 metric 200
10.2.0.0/24 dev r3-eth1 proto kernel scope link src 10.2.0.1
10.3.0.0/24 via 10.102.0.2 dev r3-eth3
10.101.0.0/24 dev r3-eth2 proto kernel scope link src 10.101.0.2
10.102.0.0/24 dev r3-eth3 proto kernel scope link src 10.102.0.1
所以r3
將通過10.102.0.2
10.3.0.10
那是r4
,它有這個路由表:
mininet> r4 ip route
10.0.0.0/24 via 10.102.0.1 dev r4-eth2 metric 100
10.0.0.0/24 via 10.103.0.1 dev r4-eth3 metric 200
10.1.0.0/24 via 10.103.0.1 dev r4-eth3
10.2.0.0/24 via 10.102.0.1 dev r4-eth2
10.3.0.0/24 dev r4-eth1 proto kernel scope link src 10.3.0.1
10.102.0.0/24 dev r4-eth2 proto kernel scope link src 10.102.0.2
10.103.0.0/24 dev r4-eth3 proto kernel scope link src 10.103.0.2
這里我們有一個問題: r4
沒有返回10.101.0.0/24
的路由,也沒有默認網關。 這會導致兩個問題:
r4
將無法回復那些 ICMP 回顯請求數據包。 嘗試聯系10.101.0.0/24
網絡上的任何系統都將失敗:
mininet> r4 ping 10.101.0.1 ping: connect: Network is unreachable
由於r4
上的rp_filter
設置...
mininet> r4 sysctl -a -r rp_filter net.ipv4.conf.all.arp_filter = 0 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.arp_filter = 0 net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.lo.arp_filter = 0 net.ipv4.conf.lo.rp_filter = 2 net.ipv4.conf.r4-eth1.arp_filter = 0 net.ipv4.conf.r4-eth1.rp_filter = 2 net.ipv4.conf.r4-eth2.arp_filter = 0 net.ipv4.conf.r4-eth2.rp_filter = 2 net.ipv4.conf.r4-eth3.arp_filter = 0 net.ipv4.conf.r4-eth3.rp_filter = 2
...來自無法訪問的網絡的傳入數據包將被簡單地丟棄,因此請求在r4
停止並且永遠不會傳遞到h4
。
這里的解決方案是給r4
一條返回10.101.0.0/24
主機的路由。 顯而易見的選擇似乎是通過r3
,所以:
mininet> r4 ip route add 10.101.0.0/24 via 10.102.0.1
有了這條新路由,我們可以從r1
ping h4
:
mininet> r1 ping -c3 h4
PING 10.3.0.10 (10.3.0.10) 56(84) bytes of data.
64 bytes from 10.3.0.10: icmp_seq=1 ttl=62 time=1.15 ms
64 bytes from 10.3.0.10: icmp_seq=2 ttl=62 time=0.160 ms
64 bytes from 10.3.0.10: icmp_seq=3 ttl=62 time=0.048 ms
--- 10.3.0.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.048/0.451/1.147/0.493 ms
在“路由表”中使用具有相同目標的兩個條目...在輸出中產生此警告:
RTNETLINK answers: File exists
在做出路由決策時,內核希望找到一個匹配的路由。 如果沒有某種方式來區分兩者,您就不能使用不同的網關有多個路由到同一個目的地。 首先,您希望這兩條路線有什么行為? 一個典型的解決方案是為路由分配不同的權重,以便優先使用一個,但它變得不可用(例如,接口關閉),將選擇輔助路由。 例如:
info(net['r1'].cmd("ip route add 10.1.0.0/24 via 10.100.0.2 dev r1-eth2"))
info(net['r1'].cmd("ip route add 10.2.0.0/24 via 10.101.0.2 dev r1-eth3"))
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.101.0.2 dev r1-eth3 metric 100"))
info(net['r1'].cmd("ip route add 10.3.0.0/24 via 10.100.0.2 dev r1-eth2 metric 200"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.