I am having trouble connecting the switch to the controller in mininet. I use python script.
My script is the following.
The file name is test.py.
#!/usr/bin/python
from mininet.cli import CLI
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.node import Controller, OVSSwitch, RemoteController, OVSBridge
from mininet.log import setLogLevel
class test_Topo(Topo):
def build(self):
s1 = self.addSwitch( 's1')
s2 = self.addSwitch( 's2')
h1 = self.addHost( 'h1' )
h2 = self.addHost( 'h2' )
n1 = self.addHost( 'n1' )
self.addLink( s1, s2 )
self.addLink( s1, h1 )
self.addLink( s1, h2 )
self.addLink( s2, n1 )
def test():
topo = test_Topo()
net = Mininet(topo, build=False, waitConnected=True, switch=OVSSwitch, controller=Controller)
c0 = net.addController( 'c0', port=6633 )
c1 = net.addController('c1', port=6634)
net.build()
s1 = net.get('s1')
s2 = net.get('s2')
c0.start()
c1.start()
s1.start([c0])
s2.start([c1])
net.start()
net.pingAll()
CLI( net )
net.stop()
if __name__ == '__main__':
setLogLevel('info')
test()
I want to have each switch connected to a different controller.
I ran the script with the following command.
sudo python3 test.py
The result is the following.
*** Creating network
*** Adding hosts:
h1 h2 n1
*** Adding switches:
s1 s2
*** Adding links:
(s1, h1) (s1, h2) (s1, s2) (s2, n1)
*** Configuring hosts
h1 h2 n1
*** Starting controller
c0 c1
*** Starting 2 switches
s1 s2 ...
*** Waiting for switches to connect
The connection does not end permanently after the message
*** Waiting for switches to connect
is displayed.
I referred to this code.
https://github.com/mininet/mininet/blob/master/examples/controllers.py
https://github.com/mininet/mininet/blob/master/examples/controllers2.py
I can't understand why switch can't connect the controller in my code.
I apologize for my poor English.
Related
I am recently studying Mininet.And I watched a video about "How to Streaming Video in Mininet"
this is its python code
def myNetwork():
"Create a network."
net = Mininet( topo=None, build=False )
info('*** Adding Controller\n')
net.addController(name='c0')
print( "*** Add Access Points\n")
s1=net.addSwitch('s1')
# Intf('eth0',node=s1) # Some Problem
info('*** Add hosts\n')
h1 = net.addHost('h1',ip='10.0.0.1')
h2 = net.addHost('h2',ip='10.0.0.2')
info('*** Add links\n')
net.addLink(h1,s1,cls=TCLink,bw=10,delay='1ms',loss=0)
net.addLink(h2,s1,cls=TCLink,bw=10,delay='1ms',loss=50)
print ("*** Starting network")
net.start()
os.popen('ovs-vsctl add-port s1 eth0')
h1.cmdPrint('dhclient '+h1.defaultIntf().name)
h2.cmdPrint('dhclient '+h2.defaultIntf().name)
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
myNetwork()
after running this code , the bug ocuurs as below:
*** h1 : ('dhclient h1-eth0',)
ovs-vsctl: Error detected while setting up 'eth0'. See ovs-vswitchd log for details
How can I fix this
Why the error occurs and how can I fix this error to make it works
I have this code that I am trying to use to connect three routers r1,r2,r3 together. I think I have to use switches to connect host nodes to the routers so each router is connected to a switch that is connected to a host. I have it working for 2 routers but I can't get it to work for three routers
I am using mininet to run the python script. Is there a way to add the ip addresses to the routing tables for the host. I am new to mininet so I am not familiar with connecting routers. I have to do this for 7 routers not just three but I am starting with 3 for now. Is there a better way to do this ?
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
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 2 routers in two 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')
# Add 2 switches
s1 = self.addSwitch('s1')
s2 = self.addSwitch('s2')
s3 = self.addSwitch('s3')
# 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'})
# Add router-router link in a new subnet for the router-router connection
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,
r2,
intfName1='r1-eth3',
intfName2='r2-eth3',
params1={'ip': '10.101.0.1/24'},
params2={'ip': '10.101.0.2/24'})
# Adding hosts specifying the default route
d1 = self.addHost(name='d1',
ip='10.0.0.251/24',
defaultRoute='via 10.0.0.1')
d2 = self.addHost(name='d2',
ip='10.1.0.252/24',
defaultRoute='via 10.1.0.1')
d3 = self.addHost(name='d3',
ip='10.1.0.253/24',
defaultRoute='via 10.1.0.1')
# Add host-switch links
self.addLink(d1, s1)
self.addLink(d2, s2)
self.addLink(d3, s2)
def run():
topo = NetworkTopo()
net = Mininet(topo=topo)
# Add routing for reaching networks that aren't directly connected
print info(net['r1'].cmd("ip route add 10.1.0.0/24 via 10.100.0.2 dev r1-eth2"))
print info(net['r2'].cmd("ip route add 10.0.0.0/24 via 10.100.0.1 dev r2-eth2"))
net.start()
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
run()
The reason why router 3 is not working is because you have not connected it! So instead of
self.addLink(r1,
r2,
intfName1='r1-eth3',
intfName2='r2-eth3',
params1={'ip': '10.101.0.1/24'},
params2={'ip': '10.101.0.2/24'})
Use
self.addLink(r1,
r2,
intfName1='r1-eth0',
intfName2='r3-eth0',
params1={'ip': '10.101.0.1/24'},
params2={'ip': '10.101.0.2/24'})
I want to run instances of Quagga on each of my hosts in a Mininet setting. As implemented in the code below, I am able to mount /tmp/<host>/etc/quagga as /etc/quagga for each host, isolating configuration files inside the directory per host (private directories). But when I start Quagga service in each host (last lines in ipconf file below), they all share the same PID number, effectively creating the same process for all of them, although each one has its own Quagga configuration file.
I want to have separate Quagga instances, each with its own PID. How can I achieve this?
Custom topology file my_topo.py:
from mininet.topo import Topo
class my_topo(Topo):
"My custom topology settings"
def __init__(self, enable_all=True):
"Create custom topo."
Topo.__init__(self)
private_dirs = [("/etc/quagga", "/tmp/%(name)s/etc/quagga")]
h1 = self.addHost("h1",
ip="172.31.1.100/24",
privateDirs=private_dirs)
h2 = self.addHost("h2",
ip="172.31.2.100/24",
privateDirs=private_dirs)
h3 = self.addHost("h3",
ip="172.31.3.100/24",
privateDirs=private_dirs)
h4 = self.addHost("h4",
ip="172.31.4.100/24",
privateDirs=private_dirs)
h5 = self.addHost("h5",
ip="172.32.1.2/30",
privateDirs=private_dirs)
sA = self.addSwitch("s5")
sB = self.addSwitch("s6")
sC = self.addSwitch("s7")
sD = self.addSwitch("s8")
self.addLink(h1, sA)
self.addLink(h2, sB)
self.addLink(h3, sC)
self.addLink(h4, sD)
self.addLink(sA, sB)
self.addLink(sB, sD)
self.addLink(sD, sC)
self.addLink(sC, sA)
self.addLink(sA, sD)
self.addLink(h2, h5, 1, 0)
self.addLink(h4, h5, 1, 1)
topos = { "my_topo": ( lambda: my_topo() ) }
Commands file ipconf:
h1 /etc/init.d/quagga restart
h2 /etc/init.d/quagga restart
h3 /etc/init.d/quagga restart
h4 /etc/init.d/quagga restart
h5 /etc/init.d/quagga restart
Command to run Mininet:
sudo mn --custom mininet/custom/my_topo.py --topo=my_topo --controller=remote,ip=192.168.56.101,port=6633 --pre=ipconf
I figured out myself how to isolate processes from each host using Mininext, an expansion for Mininet which provides greater isolation between the hosts. Since Mininext is not compatible with recent versions of Mininet, I had to downgrade the latter to version 2.1.0, as instructed in the Mininext repository. Now I can run distinct Quagga instances in each host nicely.
Here is the adapted topology code using Mininext library, in case anyone faces the same situation:
import inspect
import os
from mininext.topo import Topo
from mininext.services.quagga import QuaggaService
from collections import namedtuple
QuaggaHost = namedtuple('QuaggaHost', 'name ip lo gw')
class my_topo(Topo):
'My custom topology settings'
def __init__(self):
Topo.__init__(self)
self_path = os.path.dirname(os.path.abspath(
inspect.getfile(inspect.currentframe())
))
quagga_svc = QuaggaService(autoStop=False)
quagga_base_config_path = self_path + '/configs/'
quagga_hosts = []
quagga_hosts.append(QuaggaHost(name='h1',
ip='172.31.1.100/24',
lo='10.0.1.1/24',
gw='gw 172.31.1.1'))
quagga_hosts.append(QuaggaHost(name='h2',
ip='172.31.2.100/24',
lo='10.0.2.1/24',
gw='gw 172.31.2.1'))
quagga_hosts.append(QuaggaHost(name='h3',
ip='172.31.3.100/24',
lo='10.0.3.1/24',
gw='gw 172.31.3.1'))
quagga_hosts.append(QuaggaHost(name='h4',
ip='172.31.4.100/24',
lo='10.0.4.1/24',
gw='gw 172.31.4.1'))
quagga_hosts.append(QuaggaHost(name='h5',
ip='172.32.1.2/30',
lo='10.0.5.1/24',
gw='gw 172.32.1.1'))
hosts = {}
for host in quagga_hosts:
quagga_container = self.addHost(name=host.name,
ip=host.ip,
defaultRoute=host.gw,
hostname=host.name,
privateLogDir=True,
privateRunDir=True,
inMountNamespace=True,
inPIDNamespace=True,
inUTSNamespace=True)
hosts[host.name] = quagga_container
self.addNodeLoopbackIntf(node=host.name, ip=host.lo)
quagga_svc_config = \
{'quaggaConfigPath': quagga_base_config_path + host.name}
self.addNodeService(node=host.name, service=quagga_svc,
nodeConfig=quagga_svc_config)
sA = self.addSwitch('s5')
sB = self.addSwitch('s6')
sC = self.addSwitch('s7')
sD = self.addSwitch('s8')
self.addLink(hosts['h1'], sA)
self.addLink(hosts['h2'], sB)
self.addLink(hosts['h3'], sC)
self.addLink(hosts['h4'], sD)
self.addLink(sA, sB)
self.addLink(sB, sD)
self.addLink(sD, sC)
self.addLink(sC, sA)
self.addLink(sA, sD)
self.addLink(hosts['h2'], hosts['h5'], 1, 0)
self.addLink(hosts['h4'], hosts['h5'], 1, 1)
topos = {'my_topo': (lambda: my_topo())}
Quagga configuration files must be placed inside configs directory, which lies in the same directory as the topology file. configs has directories for each host, as if each one was a /etc/quagga directory.
I am attempting to set up a network in which 3 hosts (h1, h2, h3, on different networks) can ping each other through the 2 routers (r1, r2) that separate them.
h1 -> r1 -> h2 -> r2 -> h3 -> r3 -> internet
I found this, to guide me through 2 hosts and 1 router but when I add r2 on the other side of h2, r2 doesn't response to anything, and it isn't able to ping anything OR I can get the following bidirectional pairs:
(h1, r1) (h2, r2)
This code gives me a non-responsive/mute r2:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.log import setLogLevel, info
from mininet.cli import CLI
class LinuxRouter( Node ):
"A Node with IP forwarding enabled."
def config( self, **params ):
super( LinuxRouter, self).config( **params )
# Enable forwarding on the router
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 ):
"A LinuxRouter connecting three IP subnets"
def build( self, **_opts ):
robIP = '10.1.1.14/24' # IP address for r0-eth1
richIP = '10.4.4.46/24'
robert = self.addNode( 'r0', cls=LinuxRouter, ip=robIP, defaultRoute='via 10.4.4.14' )
richard = self.addNode( 'r1', cls=LinuxRouter, ip=richIP, defaultRoute='via 10.6.6.46' )
alice = self.addHost( 'h1', ip='10.1.1.17/24', defaultRoute='via 10.1.1.14' )
bob = self.addHost( 'h2', ip='10.4.4.48/24', defaultRoute='via 10.4.4.14' )
self.addLink( alice, robert, intfName2='r0-eth1', params2={ 'ip' : '10.1.1.14/24' } )
self.addLink( bob, robert, intfName2='r1-eth1', params2={ 'ip' : '10.4.4.14/24' } )
self.addLink( bob, richard, intfName2='r0-eth2', params2={ 'ip' : '10.4.4.46/24' } )
def run():
"Test linux router"
topo = NetworkTopo()
net = Mininet( topo=topo ) # controller is used by s1-s3
net.start()
info( '*** Routing Table on Router:\n' )
print net[ 'r0' ].cmd( 'route' )
CLI( net )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
run()
If I transpose these 2 lines I get the 2 bidirectional pairs.
self.addLink( bob, richard, intfName2='r1-eth1', params2={ 'ip' : '10.4.4.46/24' } )
self.addLink( bob, robert, intfName2='r0-eth2', params2={ 'ip' : '10.4.4.14/24' } )
I don't even know if this problem is my bad code, or if it's a configuration I haven't done on the routers that's causing it.
I just need to be able to pingall with no loss.
I'm a newer in Mininet, I started my topology with CLI command: "sudo mn", after that, I'm adding some hosts and switches... but I want to save it for the next time.
How can I do it?
Example:
http://i1360.photobucket.com/albums/r653/HKati/Capture%20drsquoeacutecran%202016-04-23%20agrave%2007.08.02_zpsxcmh4u6s.png
I'm not sure if I got your question correctly but you can define your topology within a script:
Example my_topology.py
from mininet.topo import Topo
class MyTopo( Topo ):
def __init__( self ):
Topo.__init__( self )
# Add hosts and switches
left_host = self.addHost( 'h1' )
right_host = self.addHost( 'h2' )
left_switch = self.addSwitch( 's0' )
right_switch = self.addSwitch( 's2' )
# Add links
self.addLink( leftHost, left_switch, bw=10, delay='10ms', loss=0, max_queue_size=1000 )
self.addLink( left_switch, right_switch, bw=10, delay='10ms', loss=0, max_queue_size=1000 )
self.addLink( right_switch, rightHost, bw=10, delay='10ms', loss=0, max_queue_size=1000 )
topos = { 'mytopo': ( lambda: MyTopo() ) }
Then you can start it with
mn --custom my_topology.py --topo mytopo --link tc,bw=10,delay=10ms