Thomas Vachuska
Committed by Gerrit Code Review

Enhancing ONOS mininet topology approach to remove boilerplate and simplify testing and demos.

Change-Id: Id8ab2bfa74254560714f4c27a9342693d1dc9788
...@@ -34,13 +34,7 @@ ...@@ -34,13 +34,7 @@
34 <step name="Wait-For-Mininet" requires="Start-Mininet" 34 <step name="Wait-For-Mininet" requires="Start-Mininet"
35 exec="onos-mininet wait 10"/> 35 exec="onos-mininet wait 10"/>
36 36
37 - <step name="Show-Network" requires="Wait-For-Mininet" 37 + <step name="Check-Summary" requires="~Wait-For-Mininet"
38 - exec="onos-mininet sendAndExpect net --expect ."/>
39 -
40 - <step name="Discover-Hosts" requires="Show-Network"
41 - exec="onos-mininet sendAndExpect py [ h.cmd('arping -U -c 1 ' + h.IP()) for h in net.hosts ] --expect ."/>
42 -
43 - <step name="Check-Summary" requires="Discover-Hosts"
44 exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/> 38 exec="onos-check-summary ${OC1} [0-9]* 25 140 25"/>
45 39
46 <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}" 40 <step name="Balance-Masters" requires="~Check-Summary" if="${OC2}"
......
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 -import sys 3 +from onosnet import run
4 -
5 -from mininet.net import Mininet
6 -from mininet.cli import CLI
7 -from mininet.log import setLogLevel
8 -from mininet.node import RemoteController
9 -from mininet.link import TCLink
10 -
11 from attmpls import AttMplsTopo 4 from attmpls import AttMplsTopo
12 5
13 -setLogLevel( 'info' ) 6 +run( AttMplsTopo() )
14 -
15 -def pingloop( net ):
16 - setLogLevel( 'error' )
17 - try:
18 - while True:
19 - net.ping()
20 - finally:
21 - setLogLevel( 'info' )
22 -
23 -def run(controllers=[ '127.0.0.1' ]):
24 - Mininet.pingloop = pingloop
25 - net = Mininet( topo=AttMplsTopo(), link=TCLink, build=False, autoSetMacs=True )
26 - ctrl_count = 0
27 - for controllerIP in controllers:
28 - net.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP )
29 - ctrl_count = ctrl_count + 1
30 - net.build()
31 - net.start()
32 - CLI( net )
33 - net.stop()
34 -
35 -if __name__ == '__main__':
36 - if len( sys.argv ) > 1:
37 - controllers = sys.argv[ 1: ]
38 - else:
39 - print 'Usage: att-onos.py <c0 IP> <c1 IP> ...'
40 - exit( 1 )
41 - run( controllers )
......
...@@ -175,3 +175,7 @@ class AttMplsTopo( Topo ): ...@@ -175,3 +175,7 @@ class AttMplsTopo( Topo ):
175 self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') 175 self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms')
176 176
177 topos = { 'att': ( lambda: AttMplsTopo() ) } 177 topos = { 'att': ( lambda: AttMplsTopo() ) }
178 +
179 +if __name__ == '__main__':
180 + from onosnet import run
181 + run( AttMplsTopo() )
......
1 +#!/usr/bin/python
2 +
3 +import sys
4 +from threading import Thread
5 +
6 +from mininet.net import Mininet
7 +from mininet.log import setLogLevel
8 +from mininet.node import RemoteController
9 +from mininet.log import info, debug
10 +from mininet.util import quietRun
11 +from mininet.link import TCLink
12 +from mininet.cli import CLI
13 +
14 +class ONOSMininet( Mininet ):
15 +
16 + @classmethod
17 + def setup( cls ):
18 + cls.useArping = True if quietRun( 'which arping' ) else False
19 +
20 + def __init__( self, controllers=[], gratuitousArp=True, build=True, *args, **kwargs ):
21 + """Create Mininet object for ONOS.
22 + controllers: List of controller IP addresses
23 + gratuitousArp: Send an ARP from each host to aid controller's host discovery"""
24 + # discarding provided controller (if any),
25 + # using list of remote controller IPs instead
26 + kwargs[ 'controller' ] = None
27 +
28 + # delay building for a second
29 + kwargs[ 'build' ] = False
30 +
31 + Mininet.__init__(self, *args, **kwargs )
32 +
33 + self.gratArp = gratuitousArp
34 + self.useArping = ONOSMininet.useArping
35 +
36 + info ( '*** Adding controllers\n' )
37 + ctrl_count = 0
38 + for controllerIP in controllers:
39 + self.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP )
40 + info( ' c%d (%s)\n' % ( ctrl_count, controllerIP ) )
41 + ctrl_count = ctrl_count + 1
42 +
43 + if self.topo and build:
44 + self.build()
45 +
46 + def start( self ):
47 + Mininet.start( self )
48 + if self.gratArp:
49 + self.waitConnected()
50 + info ( '*** Sending a gratuitious ARP from each host\n' )
51 + self.gratuitousArp()
52 +
53 +
54 + def gratuitousArp( self ):
55 + "Send an ARP from each host to aid controller's host discovery; fallback to ping if necessary"
56 + if self.useArping:
57 + for host in self.hosts:
58 + info( '%s ' % host.name )
59 + debug( host.cmd( 'arping -U -c 1 ' + host.IP() ) )
60 + info ( '\n' )
61 + else:
62 + info( '\nWARNING: arping is not found, using ping instead.\n'
63 + 'For higher performance, install arping: sudo apt-get install iputils-arping\n\n' )
64 +
65 + threads = [ self.threadPing(s, d) for (s, d) in zip( self.hosts, self.hosts[1:] + self.hosts[0:1] ) ]
66 + for t in threads:
67 + t.join()
68 + info ( '\n' )
69 +
70 + def threadPing( self, src, dst ):
71 + "Ping from src to dst in a thread"
72 + def p():
73 + src.cmd( 'ping -w 0.1 -W 0.1 -c1 ' + dst.IP() )
74 + t = Thread( target=p )
75 + info ( '%s ' % src.name )
76 + t.start()
77 + return t
78 +
79 + def pingloop( self ):
80 + "Loop forever pinging the full mesh of hosts"
81 + setLogLevel( 'error' )
82 + try:
83 + while True:
84 + self.ping()
85 + finally:
86 + setLogLevel( 'info' )
87 +
88 +# Initialize ONOSMininet the first time that the class is loaded
89 +ONOSMininet.setup()
90 +
91 +def run( topo, controllers=None, link=TCLink, autoSetMacs=True ):
92 + if not controllers and len( sys.argv ) > 1:
93 + controllers = sys.argv[ 1: ]
94 + else:
95 + print 'Need to provide a topology and list of controllers'
96 + exit( 1 )
97 +
98 + setLogLevel( 'info' )
99 +
100 + net = ONOSMininet( topo=topo, controllers=controllers, link=link, autoSetMacs=autoSetMacs )
101 + net.start()
102 + CLI( net )
103 + net.stop()
...@@ -81,3 +81,7 @@ class UkTopo( Topo ): ...@@ -81,3 +81,7 @@ class UkTopo( Topo ):
81 self.addLink( YORK, NRWICH, bw=10, delay='1.0ms') 81 self.addLink( YORK, NRWICH, bw=10, delay='1.0ms')
82 82
83 topos = { 'uk': ( lambda: UkTopo() ) } 83 topos = { 'uk': ( lambda: UkTopo() ) }
84 +
85 +if __name__ == '__main__':
86 + from onosnet import run
87 + run( UkTopo() )
......