I'm new to Mininet and POX controller to simulate SDN. I want to create the following network, using Mininet Python API:
My objective is to let each host/router send packets to all the other hosts/routers. To do that, I used ip route command. This is my Python code for creating the network:
#!/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()
This is the output of net command on Mininet CLI:
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
I have two issues:
1- Running pingall on mininet CLI, gives this output:
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)
Why can't routers send packet to "opposite" routers and hosts ? I do not understand why hosts can send packet to router instead.
2- Using two entries with same destination in the "routing table", for example:
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"))
produces this warning in the output:
RTNETLINK answers: File exists
and alternative route paths can't be used. I want to let h1 send packets to host h4 by passing through router r2, but also by passing through router r3. How can I fix "multiple paths" with ip route command?