From 9ee4979cfc10f16f6c0bc37ffb65fdba1908e997 Mon Sep 17 00:00:00 2001 From: Thomas Vachuska Date: Tue, 1 Mar 2016 16:51:14 -0800 Subject: [PATCH] Enhancing ONOS mininet topology approach to remove boilerplate and simplify testing and demos. Change-Id: Id8ab2bfa74254560714f4c27a9342693d1dc9788 --- tools/test/scenarios/net-setup.xml | 8 +-- tools/test/topos/att-onos.py | 39 +---------- tools/test/topos/attmpls.py | 4 ++ tools/test/topos/onosnet.py | 103 +++++++++++++++++++++++++++++ tools/test/topos/uk.py | 4 ++ 5 files changed, 114 insertions(+), 44 deletions(-) create mode 100644 tools/test/topos/onosnet.py diff --git a/tools/test/scenarios/net-setup.xml b/tools/test/scenarios/net-setup.xml index 702480ed02..6599d390c4 100644 --- a/tools/test/scenarios/net-setup.xml +++ b/tools/test/scenarios/net-setup.xml @@ -34,13 +34,7 @@ - - - - - 1: - controllers = sys.argv[ 1: ] - else: - print 'Usage: att-onos.py ...' - exit( 1 ) - run( controllers ) +run( AttMplsTopo() ) diff --git a/tools/test/topos/attmpls.py b/tools/test/topos/attmpls.py index 4fe711546d..fedcb6c612 100644 --- a/tools/test/topos/attmpls.py +++ b/tools/test/topos/attmpls.py @@ -175,3 +175,7 @@ class AttMplsTopo( Topo ): self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms') topos = { 'att': ( lambda: AttMplsTopo() ) } + +if __name__ == '__main__': + from onosnet import run + run( AttMplsTopo() ) diff --git a/tools/test/topos/onosnet.py b/tools/test/topos/onosnet.py new file mode 100644 index 0000000000..cbf034b087 --- /dev/null +++ b/tools/test/topos/onosnet.py @@ -0,0 +1,103 @@ +#!/usr/bin/python + +import sys +from threading import Thread + +from mininet.net import Mininet +from mininet.log import setLogLevel +from mininet.node import RemoteController +from mininet.log import info, debug +from mininet.util import quietRun +from mininet.link import TCLink +from mininet.cli import CLI + +class ONOSMininet( Mininet ): + + @classmethod + def setup( cls ): + cls.useArping = True if quietRun( 'which arping' ) else False + + def __init__( self, controllers=[], gratuitousArp=True, build=True, *args, **kwargs ): + """Create Mininet object for ONOS. + controllers: List of controller IP addresses + gratuitousArp: Send an ARP from each host to aid controller's host discovery""" + # discarding provided controller (if any), + # using list of remote controller IPs instead + kwargs[ 'controller' ] = None + + # delay building for a second + kwargs[ 'build' ] = False + + Mininet.__init__(self, *args, **kwargs ) + + self.gratArp = gratuitousArp + self.useArping = ONOSMininet.useArping + + info ( '*** Adding controllers\n' ) + ctrl_count = 0 + for controllerIP in controllers: + self.addController( 'c%d' % ctrl_count, RemoteController, ip=controllerIP ) + info( ' c%d (%s)\n' % ( ctrl_count, controllerIP ) ) + ctrl_count = ctrl_count + 1 + + if self.topo and build: + self.build() + + def start( self ): + Mininet.start( self ) + if self.gratArp: + self.waitConnected() + info ( '*** Sending a gratuitious ARP from each host\n' ) + self.gratuitousArp() + + + def gratuitousArp( self ): + "Send an ARP from each host to aid controller's host discovery; fallback to ping if necessary" + if self.useArping: + for host in self.hosts: + info( '%s ' % host.name ) + debug( host.cmd( 'arping -U -c 1 ' + host.IP() ) ) + info ( '\n' ) + else: + info( '\nWARNING: arping is not found, using ping instead.\n' + 'For higher performance, install arping: sudo apt-get install iputils-arping\n\n' ) + + threads = [ self.threadPing(s, d) for (s, d) in zip( self.hosts, self.hosts[1:] + self.hosts[0:1] ) ] + for t in threads: + t.join() + info ( '\n' ) + + def threadPing( self, src, dst ): + "Ping from src to dst in a thread" + def p(): + src.cmd( 'ping -w 0.1 -W 0.1 -c1 ' + dst.IP() ) + t = Thread( target=p ) + info ( '%s ' % src.name ) + t.start() + return t + + def pingloop( self ): + "Loop forever pinging the full mesh of hosts" + setLogLevel( 'error' ) + try: + while True: + self.ping() + finally: + setLogLevel( 'info' ) + +# Initialize ONOSMininet the first time that the class is loaded +ONOSMininet.setup() + +def run( topo, controllers=None, link=TCLink, autoSetMacs=True ): + if not controllers and len( sys.argv ) > 1: + controllers = sys.argv[ 1: ] + else: + print 'Need to provide a topology and list of controllers' + exit( 1 ) + + setLogLevel( 'info' ) + + net = ONOSMininet( topo=topo, controllers=controllers, link=link, autoSetMacs=autoSetMacs ) + net.start() + CLI( net ) + net.stop() diff --git a/tools/test/topos/uk.py b/tools/test/topos/uk.py index 1725d376e9..2ed176573f 100644 --- a/tools/test/topos/uk.py +++ b/tools/test/topos/uk.py @@ -81,3 +81,7 @@ class UkTopo( Topo ): self.addLink( YORK, NRWICH, bw=10, delay='1.0ms') topos = { 'uk': ( lambda: UkTopo() ) } + +if __name__ == '__main__': + from onosnet import run + run( UkTopo() )