def waitForNode( self, node ): "Wait for a node to finish, and print its output." # Pollers nodePoller = poll() nodePoller.register( node.stdout ) bothPoller = poll() bothPoller.register( self.stdin, POLLIN ) bothPoller.register( node.stdout, POLLIN ) if self.isatty(): # Buffer by character, so that interactive # commands sort of work quietRun( 'stty -icanon min 1' ) while True: try: bothPoller.poll() # XXX BL: this doesn't quite do what we want. if False and self.inputFile: key = self.inputFile.read( 1 ) if key is not '': node.write(key) else: self.inputFile = None if isReadable( self.inPoller ): key = self.stdin.read( 1 ) node.write( key ) if isReadable( nodePoller ): data = node.monitor() output( data ) if not node.waiting: break except KeyboardInterrupt: node.sendInt()
def start( self, controllers ): "Start up kernel datapath." ofplog = '/tmp/' + self.name + '-ofp.log' self.startIntfs() # Delete local datapath if it exists; # then create a new one monitoring the given interfaces quietRun( 'ovs-dpctl del-dp ' + self.dp ) self.cmd( 'ovs-dpctl add-dp ' + self.dp ) mac_str = '' if self.defaultMAC: # ovs-openflowd expects a string of exactly 16 hex digits with no # colons. mac_str = ' --datapath-id=0000' + \ ''.join( self.defaultMAC.split( ':' ) ) + ' ' ports = sorted( self.ports.values() ) if len( ports ) != ports[ -1 ] + 1 - self.portBase: raise Exception( 'only contiguous, one-indexed port ranges ' 'supported: %s' % self.intfs ) intfs = [ self.intfs[ port ] for port in ports ] self.cmd( 'ovs-dpctl', 'add-if', self.dp, ' '.join( intfs ) ) # Run protocol daemon if not self.defVendor: # Mark the switch so controller will send LLDP/BDDP on all ports self.opts += ' --mfr-desc="big switch networks" --dp-desc="bigtest datapath" ' self.cmd( 'ovs-openflowd ' + self.dp + ' '.join( [ ' tcp:%s:%d' % ( c.IP(), c.port ) \ for c in controllers ] ) + ' --fail=secure ' + self.opts + mac_str + ' 1>' + ofplog + ' 2>' + ofplog + '&' ) self.execed = False
def start( self, controllers ): "Start up kernel datapath." ofplog = '/tmp/' + self.name + '-ofp.log' quietRun( 'ifconfig lo up' ) # Delete local datapath if it exists; # then create a new one monitoring the given interfaces quietRun( 'ovs-dpctl del-dp ' + self.dp ) self.cmd( 'ovs-dpctl add-dp ' + self.dp ) mac_str = '' if self.defaultMAC: # ovs-openflowd expects a string of exactly 16 hex digits with no # colons. mac_str = ' --datapath-id=0000' + \ ''.join( self.defaultMAC.split( ':' ) ) + ' ' ports = sorted( self.ports.values() ) if len( ports ) != ports[ -1 ] + 1 - self.portBase: raise Exception( 'only contiguous, one-indexed port ranges ' 'supported: %s' % self.intfs ) intfs = [ self.intfs[ port ] for port in ports ] self.cmd( 'ovs-dpctl', 'add-if', self.dp, ' '.join( intfs ) ) # Run protocol daemon controller = controllers[ 0 ] self.cmd( 'ovs-openflowd ' + self.dp + ' tcp:%s:%d' % ( controller.IP(), controller.port ) + ' --fail=secure ' + self.opts + mac_str + ' 1>' + ofplog + ' 2>' + ofplog + '&' ) self.execed = False
def tunnelX11( node, display=None): """Create an X11 tunnel from node:6000 to the root host display: display on root host (optional) returns: node $DISPLAY, Popen object for tunnel""" if display is None and 'DISPLAY' in environ: display = environ[ 'DISPLAY' ] if display is None: error( "Error: Cannot connect to display\n" ) return None, None host, screen = display.split( ':' ) # Unix sockets should work if not host or host == 'unix': # GDM3 doesn't put credentials in .Xauthority, # so allow root to just connect quietRun( 'xhost +si:localuser:root' ) return display, None else: # Add credentials with new hostname creds = subprocess.check_output( 'xauth list $DISPLAY', shell=True ).split('/', 1) if len( creds ) == 2: newCred = node.name + '/' + creds[ 1 ] node.cmd( 'xauth add ' + newCred ) # Create a tunnel for the TCP connection port = 6000 + int( float( screen ) ) connection = r'TCP\:%s\:%s' % ( host, port ) cmd = [ "socat", "TCP-LISTEN:%d,fork,reuseaddr" % port, "EXEC:'mnexec -a 1 socat STDIO %s'" % connection ] return 'localhost:' + screen, node.popen( cmd )
def do_noecho( self, line ): "Run an interactive command with echoing turned off." if self.isatty(): quietRun( 'stty -echo' ) self.default( line ) if self.isatty(): quietRun( 'stty echo' )
def cleanup( self ): "Help python collect its garbage." if not self.inNamespace: for intfName in self.intfNames(): if self.name in intfName: quietRun( 'ip link del ' + intfName ) self.shell = None
def __init__( self, mininet, stdin=sys.stdin, script=None ): self.mn = mininet self.nodelist = self.mn.controllers + self.mn.switches + self.mn.hosts self.nodemap = {} # map names to Node objects for node in self.nodelist: self.nodemap[ node.name ] = node # Attempt to handle input self.stdin = stdin self.inPoller = poll() self.inPoller.register( stdin ) self.inputFile = script Cmd.__init__( self ) info( '*** Starting CLI:\n' ) if self.inputFile: self.do_source( self.inputFile ) return while True: try: # Make sure no nodes are still waiting for node in self.nodelist: while node.waiting: node.sendInt() node.monitor() if self.isatty(): quietRun( 'stty sane' ) self.cmdloop() break except KeyboardInterrupt: output( '\nInterrupt\n' )
def __init__( self, mininet, stdin=sys.stdin, script=None ): self.mn = mininet # Local variable bindings for py command self.locals = { 'net': mininet } # Attempt to handle input self.stdin = stdin self.inPoller = poll() self.inPoller.register( stdin ) self.inputFile = script Cmd.__init__( self ) info( '*** Starting CLI:\n' ) if self.inputFile: self.do_source( self.inputFile ) return while True: try: # Make sure no nodes are still waiting for node in self.mn.values(): while node.waiting: node.sendInt() node.monitor() if self.isatty(): quietRun( 'stty sane' ) self.cmdloop() break except KeyboardInterrupt: output( '\nInterrupt\n' )
def start(self, controllers): "Start up kernel datapath." ofplog = "/tmp/" + self.name + "-ofp.log" quietRun("ifconfig lo up") # Delete local datapath if it exists; # then create a new one monitoring the given interfaces self.cmd("ovs-dpctl del-dp " + self.dp) self.cmd("ovs-dpctl add-dp " + self.dp) intfs = [str(i) for i in self.intfList() if not i.IP()] self.cmd("ovs-dpctl", "add-if", self.dp, " ".join(intfs)) # Run protocol daemon clist = ",".join(["tcp:%s:%d" % (c.IP(), c.port) for c in controllers]) self.cmd( "ovs-openflowd " + self.dp + " " + clist + " --fail=secure " + self.opts + " --datapath-id=" + self.dpid + " 1>" + ofplog + " 2>" + ofplog + "&" ) self.execed = False
def cleanup( self ): "Help python collect its garbage." # Intfs may end up in root NS for intfName in self.intfNames(): if self.name in intfName: quietRun( 'ip link del ' + intfName ) self.shell = None
def start( self, controllers ): "Start up kernel datapath." self.startIntfs() # Delete local datapath if it exists; # then create a new one monitoring the given interfaces quietRun( self.vsctl_cmd + ' -- --if-exists del-br ' + self.dp ) self.cmd( self.vsctl_cmd + ' add-br ' + self.dp ) self.cmd( self.vsctl_cmd + ' set-fail-mode ' + self.dp + ' secure') mac_str = '' if self.defaultMAC: # ovs-openflowd expects a string of exactly 16 hex digits with no # colons. dpid_str = '0000' + \ ''.join( self.defaultMAC.split( ':' ) ) + ' ' self.cmd(self.vsctl_cmd + ' --no-wait set bridge %s other-config:datapath_type=system other-config:datapath-id=%s' % (self.dp, dpid_str)) ports = sorted( self.ports.values() ) if len( ports ) != ports[ -1 ] + 1 - self.portBase: raise Exception( 'only contiguous, one-indexed port ranges ' 'supported: %s' % self.intfs ) intfs = [ self.intfs[ port ] for port in ports ] for i in intfs: self.cmd( self.vsctl_cmd, 'add-port', self.dp, i ) self.cmd( self.vsctl_cmd + ' set-controller ' + self.dp + ' '.join( [ ' tcp:%s:%d' % ( c.IP(), c.port ) \ for c in controllers ] )) self.execed = False
def stopUDPClient(): '''stop a UDP client ''' info('** Stop UDP client!!') #host.cmd('cd ./%s/; nohup python2.7 ./') quietRun("pkill -9 -f client") quietRun("pkill -9 -f client.py")
def setupInts(intfs): ''' add taps and bring them up. ''' for i in intfs: quietRun('ip tuntap add dev %s mode tap' % i) quietRun('ip link set dev %s up' % i) info('*** Intf %s set\n' % i)
def cgroupSet(self, param, value, resource="cpu"): "Set a cgroup parameter and return its value" cmd = "cgset -r %s.%s=%s /%s" % (resource, param, value, self.name) quietRun(cmd) nvalue = int(self.cgroupGet(param, resource)) if nvalue != value: error("*** error: cgroupSet: %s set to %s instead of %s\n" % (param, nvalue, value)) return nvalue
def cleanUpScreens(): "Remove moldy old screen sessions." r = r'(\d+\.mininet\.[hsc]\d+)' output = quietRun( 'screen -ls' ).split( '\n' ) for line in output: m = re.search( r, line ) if m: quietRun( 'screen -S ' + m.group( 1 ) + ' -X quit' )
def configSFlow(spine, leaf, collector, ifname): sflow = 'ovs-vsctl -- --id=@sflow create sflow agent=%s target=%s sampling=10 polling=20 --' % (ifname, collector) for s in range(1,spine+1): sflow += ' -- set bridge s%s sflow=@sflow' % s for ls in range(1,leaf+1): sflow += ' -- set bridge s%s sflow=@sflow' % (spine+ls) info('*** Configuring sFlow collector=%s \n' % collector) quietRun(sflow)
def setupInts(intfs): """ add taps and bring them up. """ for i in intfs: quietRun("ip tuntap add dev %s mode tap" % i) quietRun("ip link set dev %s up" % i) info("*** Intf %s set\n" % i)
def __init__( self, net, *args, **kwargs ): self.iperfs = {} self.bw = '12k' self.mn = net self.lastbw = {} # last bandwidth reports self.start() quietRun( 'rm /tmp/*.iperf /tmp/*.client' ) CLI.__init__( self, net, *args, **kwargs )
def delete( self ): "Delete interface" self.cmd( 'ip link del ' + self.name ) self.cmd( 'ovs-vsctl del-port ' + self.name.split('-')[0] + ' ' + self.name) ### if self.node.inNamespace: # Link may have been dumped into root NS quietRun( 'ip link del ' + self.name ) quietRun( 'ovs-vsctl del-port ' + self.name.split('-')[0] + ' ' + self.name) ###
def chrt(self): "Set RT scheduling priority" quietRun("chrt -p %s %s" % (self.rtprio, self.pid)) result = quietRun("chrt -p %s" % self.pid) firstline = result.split("\n")[0] lastword = firstline.split(" ")[-1] if lastword != "SCHED_RR": error("*** error: could not assign SCHED_RR to %s\n" % self.name) return lastword
def checkIntf(intf): "Make sure intf exists and is not configured." if (" %s:" % intf) not in quietRun("ip link show"): error("Error:", intf, "does not exist!\n") exit(1) ips = re.findall(r"\d+\.\d+\.\d+\.\d+", quietRun("ifconfig " + intf)) if ips: error("Error:", intf, "has an IP address," "and is probably in use!\n") exit(1)
def linkAs(self, node2, intfName, port1=None, port2=None): """ Link the given node to the switch on the given interface in the Click config file. """ intf1, intf2 = super(ClickKernelSwitch, self).linkTo(node2, port1, port2) self.intfRename(intf1, intfName) quietRun('ifconfig ' + intf1 + ' up') return intf1, intf2
def chrt( self ): "Set RT scheduling priority" quietRun( 'chrt -p %s %s' % ( self.rtprio, self.pid ) ) result = quietRun( 'chrt -p %s' % self.pid ) firstline = result.split( '\n' )[ 0 ] lastword = firstline.split( ' ' )[ -1 ] if lastword != 'SCHED_RR': error( '*** error: could not assign SCHED_RR to %s\n' % self.name ) return lastword
def findUser(): "Try to return logged-in (usually non-root) user" return ( # If we're running sudo os.environ.get( 'SUDO_USER', False ) or # Logged-in user (if we have a tty) ( quietRun( 'who am i' ).split() or [ False ] )[ 0 ] or # Give up and return effective user quietRun( 'whoami' ).strip() )
def checkIntf(intf): if(' %s:'% intf) not in quietRun('ip link show'): error('Error:', intf, 'can not exist\n' ) exit(1) ips = re.findall( r'\d+\.\d+\.\d+\.\d+', quietRun( 'ifconfig ' + intf) ) if ips: error('Error:', intf, 'has an IP address,' 'and is probably in use!\n' ) exit(1)
def deleteIntf(self, intf): del self.connection[intf] port = self.intfToPort(intf) if port is not None: del self.intfs[port] del self.ports[intf] quietRun( 'ip link del ' + intf ) sleep( 0.001 )
def run( sched='cfs', cpu=.05, fastbw=100, lanbw=10, reduce=0): "Run test" quietRun( 'pkill -9 iperf') topo = EmulabTopo( testbw=fastbw, lanbw=lanbw, cpu=cpu) net = Mininet(topo, host=custom( Host, sched=sched, period_us=10000, isIsolated=(sched is not 'none') ) ) net.start() # Set up routes for extra link print [ h.name for h in net.hosts]
def checkRequired(): "Check for required executables" required = [ 'udhcpd', 'udhcpc', 'dnsmasq', 'curl', 'firefox' ] for r in required: if not quietRun( 'which ' + r ): print '* Installing', r print quietRun( 'apt-get install -y ' + r ) if r == 'dnsmasq': # Don't run dnsmasq by default! print quietRun( 'update-rc.d dnsmasq disable' )
def checkIntf( intf ): "Make sure intf exists and is not configured." if ( ' %s:' % intf ) not in quietRun( 'ip link show' ): error( 'Error:', intf, 'does not exist!\n' ) exit( 1 ) ips = re.findall( r'\d+\.\d+\.\d+\.\d+', quietRun( 'ifconfig ' + intf ) ) if ips: error( 'Error:', intf, 'has an IP address,' 'and is probably in use!\n' ) exit( 1 )
def stop( self, wait=True ): "Interrupt all hosts." consoles = self.consoles[ 'hosts' ].consoles for console in consoles: console.handleInt() if wait: for console in consoles: console.waitOutput() self.setOutputHook( None ) # Shut down any iperfs that might still be running quietRun( 'killall -9 iperf' )
def switchJSON(switch): "Returns the json configuration for a packet switch" configDict = {} configDict[ 'uri' ] = 'of:' + switch.dpid configDict[ 'mac' ] = quietRun('cat /sys/class/net/%s/address' % switch.name).strip('\n').translate(None, ':') configDict[ 'hw' ] = 'PK' # FIXME what about OVS? configDict[ 'mfr' ] = 'Linc' # FIXME what about OVS? configDict[ 'type' ] = 'SWITCH' # FIXME what about OVS? annotations = switch.params.get('annotations', {}) annotations.setdefault('name', switch.name) configDict[ 'annotations' ] = annotations ports = [] for port, intf in switch.intfs.items(): if intf.name == 'lo': continue portDict = {} portDict[ 'port' ] = port portDict[ 'type' ] = 'FIBER' if isinstance(intf.link, LINCLink) else 'COPPER' intfList = [ intf.link.intf1, intf.link.intf2 ] intfList.remove(intf) portDict[ 'speed' ] = intfList[ 0 ].speed if isinstance(intf.link, LINCLink) else 0 ports.append(portDict) configDict[ 'ports' ] = ports return configDict
def testSimpleHTTP(self): "Start an HTTP server on h1 and wget from h2" if 'Python 2' in quietRun('python --version'): httpserver = 'SimpleHTTPServer' else: httpserver = 'http.server' p = pexpect.spawn('mn -w', logfile=stdout) p.expect(self.prompt) p.sendline('h1 python -m %s 80 >& /dev/null &' % httpserver) p.expect(self.prompt) # The walkthrough doesn't specify a delay here, and # we also don't read the output (also a possible problem), # but for now let's wait a number of seconds to make # it less likely to fail due to the race condition. p.sendline('px from mininet.util import waitListening;' 'waitListening(h1, port=80, timeout=30)') p.expect(self.prompt) p.sendline(' h2 wget -O - h1') p.expect('200 OK') p.expect(self.prompt) p.sendline('h1 kill %python') p.expect(self.prompt) p.sendline('exit') p.wait()
def do_arp(self, line): "Send gratuitous arps from all data network hosts" startTime = time.time() try: count = int(line) except: count = 1 # Technically this check should be on the host if '-U' not in quietRun('arping -h', shell=True): warn('Please install iputils-arping.\n') return # This is much faster if we do it in parallel for host in self.mn.net.hosts: intf = host.defaultIntf() # -b: keep using broadcasts; -f: quit after 1 reply # -U: gratuitous ARP update host.sendCmd('arping -bf -c', count, '-U -I', intf.name, intf.IP()) for host in self.mn.net.hosts: # We could check the output here if desired host.waitOutput() info('.') info('\n') elapsed = time.time() - startTime debug('Completed in %.2f seconds\n' % elapsed)
def stophttp(): "Stop simple Python web servers" info('*** Shutting down stale SimpleHTTPServers', quietRun("pkill -9 -f SimpleHTTPServer"), '\n') info('*** Shutting down stale webservers', quietRun("pkill -9 -f webserver.py"), '\n')
def setup(argv): domains = [] ctlsets = sys.argv[1:] # the controllers for the optical domain d0 = OpticalDomain() f0 = FabricDomain(1) f1 = FabricDomain(2) domains.extend([d0, f0, f1]) for i in range(len(domains)): ctls = ctlsets[i].split(',') for c in range(len(ctls)): domains[i].addController('c%s%s' % (i, c), controller=RemoteController, ip=ctls[c]) # netcfg for each domains # Note: Separate netcfg for domain0 is created in opticalUtils domainCfgs = [] for i in range(0, len(ctlsets)): cfg = {} cfg['devices'] = {} cfg['ports'] = {} cfg['links'] = {} domainCfgs.append(cfg) # make/setup Mininet object net = Mininet() for d in domains: d.build() d.injectInto(net) # connect COs to core - sort of hard-wired at this moment # adding cross-connect links for i in range(1, len(domains)): # add 10 cross-connect links between domains xcPortNo = 2 ochPortNo = 10 an = {"bandwidth": 10, "durable": "true"} net.addLink(domains[i].getTether(), d0.getSwitches('OE%s' % i), port1=xcPortNo, port2=ochPortNo, speed=10000, annotations=an, cls=LINCLink) xcId = 'of:' + domains[i].getSwitches( name=domains[i].getTether()).dpid + '/' + str(xcPortNo) ochId = 'of:' + d0.getSwitches('OE%s' % i).dpid + '/' + str(ochPortNo) domainCfgs[i]['ports'][xcId] = {'cross-connect': {'remote': ochId}} # fire everything up net.build() map(lambda x: x.start(), domains) # create a minimal copy of the network for configuring LINC. cfgnet = Mininet() cfgnet.switches = net.switches cfgnet.links = net.links cfgnet.controllers = d0.getControllers() LINCSwitch.bootOE(cfgnet, d0.getSwitches()) # send netcfg json to each CO-ONOS for i in range(1, len(domains)): info('*** Pushing Topology.json to CO-ONOS %d\n' % i) filename = 'Topology%d.json' % i with open(filename, 'w') as outfile: json.dump(domainCfgs[i], outfile, indent=4, separators=(',', ': ')) output = quietRun('%s/tools/test/bin/onos-netcfg %s %s &'\ % (LINCSwitch.onosDir, domains[i].getControllers()[0].ip, filename), shell=True) # successful output contains the two characters '{}' # if there is more output than this, there is an issue if output.strip('{}'): warn('***WARNING: Could not push topology file to ONOS: %s\n' % output) CLI(net) net.stop() LINCSwitch.shutdownOE()
import socket from mininet.cli import CLI from mininet.log import setLogLevel, info, error from mininet.net import Mininet from mininet.link import Intf from mininet.topo import Topo, SingleSwitchTopo from mininet.node import OVSSwitch, Controller, RemoteController from mininet.nodelib import LinuxBridge from functools import partial from mininet.util import quietRun if __name__ == '__main__': setLogLevel( 'info' ) print quietRun( 'ovs-vsctl set Open_vSwitch . other_config:vlan-limit={{ .Values.vlanMatchDepth }}' ) OVSSwitch13 = partial( OVSSwitch, protocols='OpenFlow13' ) controllerIp = socket.gethostbyname( '{{ .Values.onosOpenflowSvc }}' ) net = Mininet( topo=None ) info( '*** Adding controllers\n' ) onos = net.addController( name='onos', controller=RemoteController, ip=controllerIp, port=6653 ) info( '*** Adding switches\n' ) s1 = net.addSwitch( name='s1', cls=OVSSwitch13 ) s2 = net.addSwitch( 's2', cls=LinuxBridge ) info( '*** Creating hosts\n' ) h1 = net.addHost( 'h1', ip='10.0.0.1/24') h2 = net.addHost( 'h2', ip='10.1.0.2/24')
def linearBandwidthTest(lengths): "Check bandwidth at various lengths along a switch chain." results = {} switchCount = max(lengths) hostCount = switchCount + 1 switches = { 'reference user': UserSwitch, 'Open vSwitch kernel': OVSKernelSwitch } # UserSwitch is horribly slow with recent kernels. # We can reinstate it once its performance is fixed del switches['reference user'] topo = LinearTestTopo(hostCount) # Select TCP Reno output = quietRun('sysctl -w net.ipv4.tcp_congestion_control=reno') assert 'reno' in output for datapath in switches.keys(): print("*** testing", datapath, "datapath") Switch = switches[datapath] results[datapath] = [] link = partial(TCLink, delay='1ms') net = Mininet(topo=topo, switch=Switch, controller=Controller, waitConnected=True, link=link) net.start() print("*** testing basic connectivity") for n in lengths: net.ping([net.hosts[0], net.hosts[n]]) print("*** testing bandwidth") for n in lengths: src, dst = net.hosts[0], net.hosts[n] # Try to prime the pump to reduce PACKET_INs during test # since the reference controller is reactive src.cmd('telnet', dst.IP(), '5001') print("testing", src.name, "<->", dst.name) bandwidth = net.iperf([src, dst], seconds=10) print(bandwidth) flush() results[datapath] += [(n, bandwidth)] net.stop() for datapath in switches.keys(): print() print("*** Linear network results for", datapath, "datapath:") print() result = results[datapath] print("SwitchCount\tiperf Results") for switchCount, bandwidth in result: print(switchCount, '\t\t') print(bandwidth[0], 'server, ', bandwidth[1], 'client') print() print()
station=Station, controller=Controller, ).addAccessPoint('ap123') self.assertEqual(ap.dpid, self.dpidFrom_(123)) class OVSUser(OVSAP): "OVS User AP convenience class" def __init__(self, *args, **kwargs): kwargs.update(datapath='user') OVSAP.__init__(self, *args, **kwargs) class testSwitchOVSUser(TestSwitchDpidAssignmentOVS): "Test dpid assignnment of OVS User AP." accessPointClass = OVSUser @unittest.skipUnless(quietRun('which ivs-ctl'), 'IVS ap is not installed') class testSwitchIVS(TestSwitchDpidAssignmentOVS): "Test dpid assignment of IVS ap." accessPointClass = IVSSwitch @unittest.skipUnless(quietRun('which ofprotocol'), 'Reference user ap is not installed') class testSwitchUserspace(TestSwitchDpidAssignmentOVS): "Test dpid assignment of Userspace ap." accessPointClass = UserAP if __name__ == '__main__': setLogLevel('warning') unittest.main()
def myNet(cname='controller', cargs='-v ptcp:'): "Create network from scratch using Open vSwitch." info( "*** Creating nodes\n" ) controller = Node( 'c0', inNamespace=False ) s0 = Node( 's0', inNamespace=False ) s1 = Node( 's1', inNamespace=False ) h0 = Node( 'h0' ) h1 = Node( 'h1' ) h2 = Node( 'h2' ) info( "*** Creating links..." ) linkopts0=dict(bw=10, delay='1ms', loss=0) info( '\nLink h0-s0 | ' ) TCLink( h0, s0, **linkopts0) info( '\nLink h1-s0 | ' ) TCLink( h1, s0, **linkopts0) info( '\nLink s0-s1 | ' ) TCLink( s0, s1, **linkopts0) info( '\nLink s1-h2 | ' ) TCLink( s1, h2, **linkopts0) info( '\n' ) info( "*** Configuring hosts...\n" ) h0.setIP( '192.168.1.1/24' ) h1.setIP( '192.168.1.2/24' ) h2.setIP( '192.168.1.3/24' ) info( "*** Starting network using Open vSwitch...\n" ) s0.cmd( 'ovs-vsctl del-br s0' ) s0.cmd( 'ovs-vsctl add-br s0' ) s1.cmd( 'ovs-vsctl del-br s1' ) s1.cmd( 'ovs-vsctl add-br s1' ) controller.cmd( cname + ' ' + cargs + '&' ) for intf in s0.intfs.values(): print intf print s0.cmd( 'ovs-vsctl add-port s0 %s' % intf ) for intf in s1.intfs.values(): print intf print s1.cmd( 'ovs-vsctl add-port s1 %s' % intf ) # Note: controller and switch are in root namespace, and we # can connect via loopback interface info( '*** Connect to controller with tcp port...' ) s0.cmd( 'ovs-vsctl set-controller s0 tcp:127.0.0.1:6633' ) s1.cmd( 'ovs-vsctl set-controller s0 tcp:127.0.0.1:6633' ) info( '\n' ) info( '*** Waiting for switch to connect to controller..' ) while 'is_connected' not in quietRun( 'ovs-vsctl show' ): sleep( 1 ) info( '.' ) info( 'connected!\n' ) #print s0.cmd('ovs-ofctl show dp0') info( "*** Running test...\n" ) info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) h0.cmdPrint( 'ping -c 2 ' + h2.IP() ) info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) h1.cmdPrint( 'ping -c 2 ' + h2.IP() ) info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) info( '*** Starting iperf Server...\n' ) h2.cmdPrint('iperf -s -i 1 > bandwidth_result &') info( '*** Original link bandwidth testing...\n' ) print "iperf: h0--s0--s1--h2" h0.cmdPrint('iperf -c 192.168.1.3 -t 15') info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) print "iperf: h1--s0--s1--h2" h1.cmdPrint('iperf -c 192.168.1.3 -t 15') info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) print "!!! Limiting the bandwidth for flow entry [h0] -> [h2]" s0.cmdPrint('ethtool -K s0-eth2 gro off') s0.cmdPrint('tc qdisc del dev s0-eth2 root') s0.cmdPrint('tc qdisc add dev s0-eth2 root handle 1: cbq avpkt 1000 bandwidth 10Mbit') s0.cmdPrint('tc class add dev s0-eth2 parent 1: classid 1:1 cbq rate 512kbit allot 1500 prio 5 bounded isolated') s0.cmdPrint('tc filter add dev s0-eth2 parent 1: protocol ip prio 16 u32 match ip src 192.168.1.1 flowid 1:1') s0.cmdPrint('tc qdisc add dev s0-eth2 parent 1:1 sfq perturb 10') info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' ) info( '\n*** Limited link bandwidth testing...\n' ) print "iperf: h0--s0--s1--h2" h0.cmdPrint('iperf -c 192.168.1.3 -t 15') info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' ) print "iperf: h1--s0--s1--h2" h1.cmdPrint('iperf -c 192.168.1.3 -t 15') info( '*** Done...\n' ) info( "*** Stopping network...\n" ) controller.cmd( 'kill %' + cname ) s0.cmd( 'ovs-vsctl del-br s0' ) s0.deleteIntfs() s1.cmd( 'ovs-vsctl del-br s1' ) s1.deleteIntfs() info( '\n' )
def cgroupGet( self, param, resource='cpu' ): "Return value of cgroup parameter" cmd = 'cgget -r %s.%s /%s' % ( resource, param, self.name ) return int(quietRun( cmd ).split()[ -1 ] )
def quietRunNs(command, namespace='ns_int', display=True, shell=True): if display: print "Namespace %s: %s" % (namespace, command) quietRun('ip netns exec %s %s' % (namespace, command), shell=shell)
def stop( self ): "Terminate kernel datapath." quietRun( 'ovs-dpctl del-dp ' + self.dp ) self.cmd( 'kill %ovs-openflowd' ) self.deleteIntfs()
def fixIPTables(): "Fix LinuxBridge warning" for s in 'arp', 'ip', 'ip6': quietRun('sysctl net.bridge.bridge-nf-call-%stables=0' % s)
def _quietRun(command): print command quietRun(command, shell=True)
def iperf(self, hosts=None, l4Type='TCP', udpBw='10M'): """Run iperf between two hosts. hosts: list of hosts; if None, uses opposite hosts l4Type: string, one of [ TCP, UDP ] returns: results two-element array of server and client speeds""" """ Currently when the server side iperf service not reachable by the client, the mininet console either hangs forever (not responsive to to any keys Or continuously prints the message "waiting for iperf to startup" Actually there are two issues : 1. when iperf session end point was created in mininet , if connectivity exists client will know in matter of secs . Per per current login client waits forever without yielding. default telnet wait time of 60 secs is good enough. Therefore while loop is not necessary. If statement is good enough. 2. Since client to server connectivity can be verified within few secs, telnet with 60 sec timeout is overkill. You get console full of msgs or console doesnt yield or hangs till telnet timeout. We can accomplish the same verification . It is common practice to use netcat(nc) to accomplish the same. Fix has been verified with iperf between hosts, between unreachable hosts, switches. """ """ commented if not quietRun( 'which telnet' ): error( 'Cannot find telnet in $PATH - required for iperf test' ) return """ if not quietRun('which nc'): error('Cannot find nc in $PATH - required for iperf test') return if not hosts: hosts = [self.hosts[0], self.hosts[-1]] else: assert len(hosts) == 2 client, server = hosts output('*** Iperf: testing ' + l4Type + ' bandwidth between ') output("%s and %s\n" % (client.name, server.name)) server.cmd('killall -9 iperf') iperfArgs = 'iperf ' bwArgs = '' if l4Type == 'UDP': iperfArgs += '-u ' bwArgs = '-b ' + udpBw + ' ' elif l4Type != 'TCP': raise Exception('Unexpected l4 type: %s' % l4Type) server.sendCmd(iperfArgs + '-s', printPid=True) servout = '' while server.lastPid is None: servout += server.monitor() if l4Type == 'TCP': """ While loop is replaced by if block while 'Connected' not in client.cmd( 'sh -c "echo A | telnet -e A %s 5001"' % server.IP()): output('waiting for iperf to start up...') sleep(.5) """ if l4Type == 'TCP': sleep(0.5) ### Changed to handle a. hang issue when one of the hosts not reachable ### b. continuous waiting loop c. reduced waiting verification using Net cat vs telnet if ('succeeded' not in client.cmd('nc -w 3 -v -z %s 5001' % server.IP())): output('waiting for iperf to start up...\n') ## since session has failed, cleanup server end point and server.sendInt() servout += server.waitOutput() error( "\niperf Error: Unable to reach the server %s on port 5001. iperf failed \n\n" % server.IP()) return cliout = client.cmd(iperfArgs + '-t 5 -c ' + server.IP() + ' ' + bwArgs) debug('Client output: %s\n' % cliout) server.sendInt() servout += server.waitOutput() debug('Server output: %s\n' % servout) result = [self._parseIperf(servout), self._parseIperf(cliout)] if l4Type == 'UDP': result.insert(0, udpBw) output('*** Results: %s\n' % result) return result
def stopsshd(): "Stop *all* sshd processes with a custom banner" info('*** Shutting down stale sshd/Banner processes ', quietRun("pkill -9 -f Banner"), '\n')
def defineNetwork(): if len(sys.argv) < 2: print "Missing paramenter: python hotmboxes16-topo-2016-02-05.py <debug=1|0>" sys.exit() #commento debug = sys.argv[1] #print some usefull information net = Mininet(topo=None, build=False, link=TCLink) net.addController(name='c0', controller=RemoteController, # ip='192.168.224.133', port=6633) #net = Mininet(controller=RemoteController, link=TCLink, build=False, xterms=False) info("*** Create an empty network and add nodes and swith to it *** \n") #net = Mininet(controller=RemoteController, link=TCLink, build=False) #MyPOXController info("\n*** Adding Controller: Controller will be external *** \n") #BUILDING CLUSTER 1: s1, s2, s3, s4 and vmu1, vmu2, dpi, wana, tc info("\n*** Creating Switch *** \n") s1 = net.addSwitch('s1') # this should be equivalent to s1 = net.addSwitch('s1', OVSSwitch) s1.cmd( 'ovs-vsctl del-br ' + s1.name ) s1.cmd( 'ovs-vsctl add-br ' + s1.name ) s1.cmd( 'ovs-vsctl set Bridge '+ s1.name + ' stp_enable=false' ) # Disabling STP s2 = net.addSwitch('s2') s2.cmd( 'ovs-vsctl del-br ' + s2.name ) s2.cmd( 'ovs-vsctl add-br ' + s2.name ) s2.cmd( 'ovs-vsctl set Bridge '+ s2.name + ' stp_enable=false' ) # Disabling STP s3 = net.addSwitch('s3') s3.cmd( 'ovs-vsctl del-br ' + s3.name ) s3.cmd( 'ovs-vsctl add-br ' + s3.name ) s3.cmd( 'ovs-vsctl set Bridge '+ s3.name + ' stp_enable=false' ) # Disabling STP s4 = net.addSwitch('s4') s4.cmd( 'ovs-vsctl del-br ' + s4.name ) s4.cmd( 'ovs-vsctl add-br ' + s4.name ) s4.cmd( 'ovs-vsctl set Bridge '+ s4.name + ' stp_enable=false' ) # Disabling STP info("\n*** Creating VM-User 1 *** \n") vmu1 = net.addHost('VMU1') info("\n*** Creating VM-User 2 *** \n") vmu2 = net.addHost('VMU2') info("\n*** Creating DPI *** \n") dpi = net.addHost('DPI') info("\n*** Creating WAN A. *** \n") wana = net.addHost('WANA') info("\n*** Creating TC *** \n") tc = net.addHost('TC') info("\n*** Creating Virtual Router 1 *** \n") vr1 = net.addHost('VR1') info("\n*** Creating Links on Cluster 1 *** \n") net.addLink(vmu1, s1, bw=100) net.addLink(vmu2, s1, bw=100) net.addLink(dpi, s1, bw=100) net.addLink(wana, s1, bw=100) net.addLink(wana, s1, bw=100) net.addLink(tc, s1, bw=100) net.addLink(tc, s1, bw=100) net.addLink(s1, s2, bw=100) net.addLink(s1, s3, bw=100) net.addLink(s2, s4, bw=100) net.addLink(s3, s4, bw=100) net.addLink(vr1, s4, bw=100) #BUILDING CLUSTER 2: s5, s6, s7, s8 and h2, wana2, vr2, vr3 s5 = net.addSwitch('s5') s5.cmd( 'ovs-vsctl del-br ' + s5.name ) s5.cmd( 'ovs-vsctl add-br ' + s5.name ) s5.cmd( 'ovs-vsctl set Bridge '+ s5.name + ' stp_enable=false' ) # Disabling STP s6 = net.addSwitch('s6') s6.cmd( 'ovs-vsctl del-br ' + s6.name ) s6.cmd( 'ovs-vsctl add-br ' + s6.name ) s6.cmd( 'ovs-vsctl set Bridge '+ s6.name + ' stp_enable=false' ) # Disabling STP s7 = net.addSwitch('s7') s7.cmd( 'ovs-vsctl del-br ' + s7.name ) s7.cmd( 'ovs-vsctl add-br ' + s7.name ) s7.cmd( 'ovs-vsctl set Bridge '+ s7.name + ' stp_enable=false' ) # Disabling STP s8 = net.addSwitch('s8') s8.cmd( 'ovs-vsctl del-br ' + s8.name ) s8.cmd( 'ovs-vsctl add-br ' + s8.name ) s8.cmd( 'ovs-vsctl set Bridge '+ s8.name + ' stp_enable=false' ) # Disabling STP info("\n*** Creating Host 2 *** \n") h2 = net.addHost('H2') info("\n*** Creating WAN A. 2 *** \n") wana2 = net.addHost('WANA2') info("\n*** Creating VR2 *** \n") vr2 = net.addHost('VR2') info("\n*** Creating VR3 *** \n") vr3 = net.addHost('VR3') info("\n*** Creating Links on Cluster 2 *** \n") net.addLink(vr1, vr2, bw=100) net.addLink(vr2, s5, bw=100) net.addLink(s5, s6, bw=100) net.addLink(s5, s8, bw=100) net.addLink(h2, s8, bw=100) net.addLink(wana2, s6, bw=100) net.addLink(wana2, s6, bw=100) net.addLink(s6, s7, bw=100) net.addLink(s8, s7, bw=100) net.addLink(s7, vr3, bw=100) #BUILDING CLUSTER 3: s9, s10, s11, s12 and h3, wana3, vr4 s9 = net.addSwitch('s9') s9.cmd( 'ovs-vsctl del-br ' + s9.name ) s9.cmd( 'ovs-vsctl add-br ' + s9.name ) s9.cmd( 'ovs-vsctl set Bridge '+ s9.name + ' stp_enable=false' ) # Disabling STP s10 = net.addSwitch('s10') s10.cmd( 'ovs-vsctl del-br ' + s10.name ) s10.cmd( 'ovs-vsctl add-br ' + s10.name ) s10.cmd( 'ovs-vsctl set Bridge '+ s10.name + ' stp_enable=false' ) # Disabling STP s11 = net.addSwitch('s11') s11.cmd( 'ovs-vsctl del-br ' + s11.name ) s11.cmd( 'ovs-vsctl add-br ' + s11.name ) s11.cmd( 'ovs-vsctl set Bridge '+ s11.name + ' stp_enable=false' ) # Disabling STP s12 = net.addSwitch('s12') s12.cmd( 'ovs-vsctl del-br ' + s12.name ) s12.cmd( 'ovs-vsctl add-br ' + s12.name ) s12.cmd( 'ovs-vsctl set Bridge '+ s12.name + ' stp_enable=false' ) # Disabling STP info("\n*** Creating Host 3 *** \n") h3 = net.addHost('H3') info("\n*** Creating WAN A. 3 *** \n") wana3 = net.addHost('WANA3') info("\n*** Creating VR4 *** \n") vr4 = net.addHost('VR4') info("\n*** Creating Links on Cluster 3 *** \n") net.addLink(vr4, vr3, bw=100) net.addLink(vr4, s9, bw=100) net.addLink(s9, s10, bw=100) net.addLink(s9, s12, bw=100) net.addLink(wana3, s10, bw=100) net.addLink(wana3, s10, bw=100) net.addLink(s10, s11, bw=100) net.addLink(s11, s12, bw=100) net.addLink(s11, h3, bw=100) #Trying to assign MAC address to each node of the cluster 1 vmu1.setMAC("00:00:00:00:00:01", vmu1.name + "-eth0") vmu2.setMAC("00:00:00:00:00:02", vmu2.name + "-eth0") dpi.setMAC("00:00:00:00:00:03", dpi.name + "-eth0") wana.setMAC("00:00:00:00:00:04", wana.name + "-eth0") wana.setMAC("00:00:00:00:00:05", wana.name + "-eth1") tc.setMAC("00:00:00:00:00:06", tc.name + "-eth0") tc.setMAC("00:00:00:00:00:07", tc.name + "-eth1") vr1.setMAC("00:00:00:00:00:08", vr1.name + "-eth0") vr1.setMAC("00:00:00:00:00:09", vr1.name + "-eth1") #Trying to assign MAC address to each node of the cluster 2 vr2.setMAC("00:00:00:00:00:0A", vr2.name + "-eth0") vr2.setMAC("00:00:00:00:00:0B", vr2.name + "-eth1") h2.setMAC("00:00:00:00:00:0C", h2.name + "-eth0") wana2.setMAC("00:00:00:00:00:0D", wana2.name + "-eth0") wana2.setMAC("00:00:00:00:00:0E", wana2.name + "-eth1") vr3.setMAC("00:00:00:00:00:0F", vr3.name + "-eth0") vr3.setMAC("00:00:00:00:00:10", vr3.name + "-eth1") #Trying to assign MAC address to each node of the cluster 3 vr4.setMAC("00:00:00:00:00:11", vr4.name + "-eth0") vr4.setMAC("00:00:00:00:00:12", vr4.name + "-eth1") wana3.setMAC("00:00:00:00:00:13", wana3.name + "-eth0") wana3.setMAC("00:00:00:00:00:14", wana3.name + "-eth1") h3.setMAC("00:00:00:00:00:15", h3.name + "-eth0") #Disabling IPv6 for host in net.hosts: print 'Going to disable IPv6 on ' + host.name host.cmd('sysctl -w net.ipv6.conf.all.disable_ipv6=1') host.cmd('sysctl -w net.ipv6.conf.default.disable_ipv6=1') host.cmd('sysctl -w net.ipv6.conf.lo.disable_ipv6=1') for switch in net.switches: for intf in switch.intfs.values(): switch.cmd( 'ovs-vsctl add-port ' + switch.name + ' %s' % intf ) print "Eseguito comando: ovs-vsctl add-port ", switch.name, " ", intf #info("\n*** Starting Network using Open vSwitch and remote controller*** \n") # Set the controller for the switch for switch in net.switches: switch.cmd('ovs-vsctl set-controller ' + switch.name + ' tcp:127.0.0.1:6633') info( '\n*** Waiting for switch to connect to controller' ) while 'is_connected' not in quietRun( 'ovs-vsctl show' ): sleep( 1 ) info( '.' ) info('\n') # Creating a Linux Bridge on each host nhosts = len(net.hosts) print 'Total number of hosts: ' + str(nhosts) count = 1 net.start() info('\n*** Going to take down default configuration ...\n') info('\n*** ... and creating Linux bridge on WANA and TC, as well as configuring interfaces \n') for host in net.hosts: print 'Deleting ip address on ' + host.name + '-eth0 interface ...' host.cmd('ip addr del ' + host.IP(host.name + '-eth0') + '/8 dev ' + host.name + '-eth0') print 'Deleting entry in IP routing table on ' + host.name host.cmd('ip route del 10.0.0.0/8') print "Going to configure new IP" if host.name == 'WANA' or host.name == 'WANA2' or host.name == 'WANA3' or host.name == 'TC': # VNFs case print "Host with 2 interfaces: " + host.name host.cmd('brctl addbr br-' + host.name) host.cmd('brctl addif br-' + host.name + ' ' + host.name + '-eth0') host.cmd('brctl addif br-' + host.name + ' ' + host.name + '-eth1') if host.name == 'WANA' or host.name == 'TC': host.cmd('ip addr add 192.168.1.' + str(count) + '/24 dev br-' + host.name) elif host.name == 'WANA2': host.cmd('ip addr add 192.168.2.' + str(count) + '/24 dev br-' + host.name) else: host.cmd('ip addr add 192.168.3.' + str(count) + '/24 dev br-' + host.name) host.cmd('ip link set br-' + host.name + ' up') print "LB configured!" host.cmd('sysctl -w net.ipv4.ip_forward=1') print "IP Forwarding enabled!" elif host.name == 'VMU1' or host.name == 'VMU2' or host.name == 'DPI' or host.name == 'H2' or host.name == 'H3': if host.name == 'VMU1' or host.name == 'VMU2' or host.name == 'DPI': # Machine on cluster 1 host.setIP("192.168.1." + str(count), 24, host.name + "-eth0") elif host.name == 'H2': # Machine on cluster 2 host.setIP("192.168.2." + str(count), 24, host.name + "-eth0") else: # Machine on cluster 3 host.setIP("192.168.3." + str(count), 24, host.name + "-eth0") print "[CURRENT-CHECK] IP: " + net.hosts[count - 1].IP(net.hosts[count - 1].name + '-eth0') elif host.name == 'VR1' or host.name == 'VR3': if host.name == 'VR1': host.setIP("192.168.1." + str(count), 24, host.name + "-eth0") elif host.name == 'VR3': host.setIP("192.168.2." + str(count), 24, host.name + "-eth0") net.hosts[count - 1].setIP("10.0.0." + str(count - 5), 30, net.hosts[count - 1].name + "-eth1") net.hosts[count + 2].setIP("10.0.0." + str(count - 4), 30, net.hosts[count + 2].name + "-eth0") # also configuring VR2-eth0 and VR4-eth0 print net.hosts[count - 1].name + "-eth1 interface has been configured!" print "[Checking VR IP] " + net.hosts[count - 1].IP(host.name + '-eth1') net.hosts[count - 1].cmd('sysctl -w net.ipv4.ip_forward=1') # enabled on VR1 print "On VR node: IP Forwarding enabled!" else: # VR2 or VR4 case if host.name == 'VR2': host.setIP("192.168.2." + str(count), 24, host.name + "-eth1") else: # VR4 host.setIP("192.168.3." + str(count), 24, host.name + "-eth1") net.hosts[count - 1].cmd('sysctl -w net.ipv4.ip_forward=1') print "On VR node: IP Forwarding enabled!" count = count + 1 print "\n" # ARP storm avoidance rules # for switch in net.switches: # if switch.name == 's1': # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=4,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=5,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=6,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=7,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # elif switch.name == 's6' or switch.name == 's10': # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=2,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # switch.cmd('ovs-ofctl add-flow ' + switch.name + ' in_port=3,arp,dl_dst=FF:FF:FF:FF:FF:FF,actions=drop') # for switch in net.switches: # print "Rules installed on switch " + switch.name + ": " + switch.cmdPrint('ovs-ofctl dump-flows ' + switch.name) print "Configuring default gw on each host.. TODO" count = 1 for host in net.hosts: print "Adding default gw ..." '''if host.name != 'VR' and host.name != 'H1' and host.name != 'WANA' and host.name != 'TC': host.setDefaultRoute('dev ' + host.name + '-eth0 via ' + net.hosts[nhosts - 2].IP(net.hosts[nhosts - 2].name + '-eth0')) elif host.name == 'TC' or host.name == 'WANA': print "Default GW manually configured" host.cmd('route add default gw ' + net.hosts[nhosts - 2].IP(net.hosts[nhosts - 2].name + '-eth0')) else: #H1 case host.setDefaultRoute('dev ' + host.name + '-eth0 via ' + net.hosts[nhosts - 2].IP(net.hosts[nhosts - 2].name + '-eth1'))''' if host.name == 'VMU1' or host.name == 'VMU2': host.setDefaultRoute('dev ' + host.name + '-eth0 via ' + net.hosts[nhosts - 8].IP(net.hosts[nhosts - 8].name + '-eth0')) elif host.name == 'H2': host.cmd('route add -net 192.168.1.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 5].IP(net.hosts[nhosts - 5].name + '-eth1')) host.cmd('route add -net 192.168.3.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 4].IP(net.hosts[nhosts - 4].name + '-eth0')) elif host.name == 'H3': host.setDefaultRoute('dev ' + host.name + '-eth0 via ' + net.hosts[nhosts - 1].IP(net.hosts[nhosts - 1].name + '-eth1')) elif host.name == 'VR1': host.cmd('route add -net 192.168.2.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 5].IP(net.hosts[nhosts - 5].name + '-eth0')) host.cmd('route add -net 192.168.3.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 5].IP(net.hosts[nhosts - 5].name + '-eth0')) elif host.name == 'VR2': host.cmd('route add -net 192.168.1.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 8].IP(net.hosts[nhosts - 8].name + '-eth1')) host.cmd('route add -net 192.168.3.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 4].IP(net.hosts[nhosts - 4].name + '-eth0')) elif host.name == 'VR3': host.cmd('route add -net 192.168.1.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 5].IP(net.hosts[nhosts - 5].name + '-eth1')) host.cmd('route add -net 192.168.3.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 1].IP(net.hosts[nhosts - 1].name + '-eth0')) elif host.name == 'VR4': host.cmd('route add -net 192.168.1.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 4].IP(net.hosts[nhosts - 4].name + '-eth1')) host.cmd('route add -net 192.168.2.0 netmask 255.255.255.0 gw ' + net.hosts[nhosts - 4].IP(net.hosts[nhosts - 4].name + '-eth1')) else: print "Host " + host.name + ": routing table currently not configured" info('... running CLI \n***') CLI(net) info('\n') info('... stopping Network ***\n') net.stop()
def bootOE(net): "Start the LINC optical emulator within a mininet instance" opticalJSON = {} linkConfig = [] devices = [] #setting up the controllers for LINCSwitch class LINCSwitch.controllers = net.controllers for switch in net.switches: if isinstance(switch, OpticalSwitch): devices.append(switch.json()) else: devices.append(LINCSwitch.switchJSON(switch)) opticalJSON['devices'] = devices for link in net.links: if isinstance(link, LINCLink): linkConfig.append(link.json()) opticalJSON['links'] = linkConfig info('*** Writing Topology.json file\n') with open('Topology.json', 'w') as outfile: json.dump(opticalJSON, outfile, indent=4, separators=(',', ': ')) info( '*** Converting Topology.json to linc-oe format (TopoConfig.json) file\n' ) output = quietRun( '%s/tools/test/bin/onos-oecfg ./Topology.json > TopoConfig.json' % LINCSwitch.onosDir, shell=True) if output: error('***ERROR: Error creating topology file: %s ' % output + '\n') return False info('*** Creating sys.config...\n') output = quietRun( '%s/config_generator TopoConfig.json %s/sys.config.template %s %s' % (LINCSwitch.configGen, LINCSwitch.configGen, LINCSwitch.controllers[0].ip, LINCSwitch.controllers[0].port), shell=True) if output: error('***ERROR: Error creating sys.config file: %s\n' % output) return False info('*** Setting multiple controllers in sys.config...\n') searchStr = '\[{"Switch.*$' ctrlStr = '' for index in range(len(LINCSwitch.controllers)): ctrlStr += '{"Switch%d-Controller","%s",%d,tcp},' % ( index, net.controllers[index].ip, net.controllers[index].port) replaceStr = '[%s]},' % ctrlStr[:-1] # Cut off last comma sedCmd = 'sed -i \'s/%s/%s/\' sys.config' % (searchStr, replaceStr) output = quietRun(sedCmd, shell=True) info('*** Copying sys.config to linc-oe directory: ', output + '\n') output = quietRun('cp -v sys.config %s/rel/linc/releases/1.0/' % LINCSwitch.lincDir, shell=True).strip('\n') info(output + '\n') info('*** Adding taps and bringing them up...\n') LINCSwitch.setupInts(LINCSwitch.getTaps()) info('*** removing pipes if any \n') quietRun('rm /tmp/home/%s/linc-oe/rel/linc/*' % LINCSwitch.user, shell=True) info('*** Starting linc OE...\n') output = quietRun('%s/rel/linc/bin/linc start' % LINCSwitch.lincDir, shell=True) if output: error('***ERROR: LINC-OE: %s' % output + '\n') quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True) return False info('*** Waiting for linc-oe to start...\n') LINCSwitch.waitStarted(net) info( '*** Adding cross-connect (tap) interfaces to packet switches...\n' ) for link in net.links: if isinstance(link, LINCLink): if link.annotations['optical.type'] == 'cross-connect': for intf in [link.intf1, link.intf2]: if not isinstance(intf, LINCIntf): intfList = [intf.link.intf1, intf.link.intf2] intfList.remove(intf) intf2 = intfList[0] intf.node.attach( LINCSwitch.findTap(intf2.node, intf2.node.ports[intf2])) info('*** Waiting for all devices to be available in ONOS...\n') url = 'http://%s:8181/onos/v1/devices' % LINCSwitch.controllers[0].ip time = 0 while True: response = json.load(urllib2.urlopen(url)) devs = response.get('devices') # Wait for all devices to be registered if (len(devices) != len(devs)): continue # Wait for all devices to available available = True for d in devs: available &= d['available'] if available: break if (time >= TIMEOUT): error( '***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT) break time += SLEEP_TIME sleep(SLEEP_TIME) info('*** Pushing Topology.json to ONOS\n') for index in range(len(LINCSwitch.controllers)): output = quietRun( '%s/tools/test/bin/onos-topo-cfg %s Topology.json &' % (LINCSwitch.onosDir, LINCSwitch.controllers[index].ip), shell=True) # successful output contains the two characters '{}' # if there is more output than this, there is an issue if output.strip('{}'): warn('***WARNING: Could not push topology file to ONOS: %s\n' % output)
def modprobe(mod): """Return output of modprobe mod: module string""" return quietRun(['modprobe', mod])
def rmmod(mod): """Return output of lsmod. mod: module string""" return quietRun(['rmmod', mod])
def shutdownOE(): "stop the optical emulator" info('*** Stopping linc OE...\n') quietRun('%s/rel/linc/bin/linc stop' % LINCSwitch.lincDir, shell=True)
def tsharkVersion(): "Return tshark version" versionStr = quietRun('tshark -v') versionMatch = re.findall(r'TShark[^\d]*(\d+.\d+.\d+)', versionStr) return versionMatch[0]
def tsharkVersion(): "Return tshark version" versionStr = quietRun('tshark -v') versionMatch = re.findall(r'TShark \d+.\d+.\d+', versionStr)[0] return versionMatch.split()[ 1 ]
class testWalkthrough(unittest.TestCase): "Test Mininet walkthrough" prompt = 'mininet>' # PART 1 def testHelp(self): "Check the usage message" p = pexpect.spawn('mn -h') index = p.expect(['Usage: mn', pexpect.EOF]) self.assertEqual(index, 0) def testWireshark(self): "Use tshark to test the of dissector" # Satisfy pylint assert self if StrictVersion(tsharkVersion()) < StrictVersion('1.12.0'): tshark = pexpect.spawn('tshark -i lo -R of') else: tshark = pexpect.spawn('tshark -i lo -Y openflow_v1') tshark.expect(['Capturing on lo', "Capturing on 'Loopback'"]) mn = pexpect.spawn('mn --test pingall') mn.expect('0% dropped') tshark.expect(['74 Hello', '74 of_hello', '74 Type: OFPT_HELLO']) tshark.sendintr() def testBasic(self): "Test basic CLI commands (help, nodes, net, dump)" p = pexpect.spawn('mn') p.expect(self.prompt) # help command p.sendline('help') index = p.expect(['commands', self.prompt]) self.assertEqual(index, 0, 'No output for "help" command') # nodes command p.sendline('nodes') p.expect(r'([chs]\d ?){4}') nodes = p.match.group(0).split() self.assertEqual(len(nodes), 4, 'No nodes in "nodes" command') p.expect(self.prompt) # net command p.sendline('net') expected = [x for x in nodes] while len(expected) > 0: index = p.expect(expected) node = p.match.group(0) expected.remove(node) p.expect('\n') self.assertEqual(len(expected), 0, '"nodes" and "net" differ') p.expect(self.prompt) # dump command p.sendline('dump') expected = [r'<\w+ (%s)' % n for n in nodes] actual = [] for _ in nodes: index = p.expect(expected) node = p.match.group(1) actual.append(node) p.expect('\n') self.assertEqual(actual.sort(), nodes.sort(), '"nodes" and "dump" differ') p.expect(self.prompt) p.sendline('exit') p.wait() def testHostCommands(self): "Test ifconfig and ps on h1 and s1" p = pexpect.spawn('mn') p.expect(self.prompt) # Third pattern is a local interface beginning with 'eth' or 'en' interfaces = [ 'h1-eth0', 's1-eth1', '[^-](eth|en)\w*\d', 'lo', self.prompt ] # h1 ifconfig p.sendline('h1 ifconfig -a') ifcount = 0 while True: index = p.expect(interfaces) if index == 0 or index == 3: ifcount += 1 elif index == 1: self.fail('s1 interface displayed in "h1 ifconfig"') elif index == 2: self.fail('eth0 displayed in "h1 ifconfig"') else: break self.assertEqual(ifcount, 2, 'Missing interfaces on h1') # s1 ifconfig p.sendline('s1 ifconfig -a') ifcount = 0 while True: index = p.expect(interfaces) if index == 0: self.fail('h1 interface displayed in "s1 ifconfig"') elif index == 1 or index == 2 or index == 3: ifcount += 1 else: break self.assertTrue(ifcount >= 3, 'Missing interfaces on s1') # h1 ps p.sendline("h1 ps -a | egrep -v 'ps|grep'") p.expect(self.prompt) h1Output = p.before # s1 ps p.sendline("s1 ps -a | egrep -v 'ps|grep'") p.expect(self.prompt) s1Output = p.before # strip command from ps output and compute diffs h1Output = h1Output.split('\n')[1:] s1Output = s1Output.split('\n')[1:] diffs = set(h1Output).difference(set(s1Output)) # allow up to two diffs to account for daemons, etc. self.assertTrue( len(diffs) <= 2, 'h1 and s1 "ps" output differ too much: %s' % diffs) p.sendline('exit') p.wait() def testConnectivity(self): "Test ping and pingall" p = pexpect.spawn('mn') p.expect(self.prompt) p.sendline('h1 ping -c 1 h2') p.expect('1 packets transmitted, 1 received') p.expect(self.prompt) p.sendline('pingall') p.expect('0% dropped') p.expect(self.prompt) p.sendline('exit') p.wait() def testSimpleHTTP(self): "Start an HTTP server on h1 and wget from h2" p = pexpect.spawn('mn') p.expect(self.prompt) p.sendline('h1 python -m SimpleHTTPServer 80 &') p.expect(self.prompt) p.sendline(' h2 wget -O - h1') p.expect('200 OK') p.expect(self.prompt) p.sendline('h1 kill %python') p.expect(self.prompt) p.sendline('exit') p.wait() # PART 2 def testRegressionRun(self): "Test pingpair (0% drop) and iperf (bw > 0) regression tests" # test pingpair p = pexpect.spawn('mn --test pingpair') p.expect('0% dropped') p.expect(pexpect.EOF) # test iperf p = pexpect.spawn('mn --test iperf') p.expect(r"Results: \['([\d\.]+) .bits/sec',") bw = float(p.match.group(1)) self.assertTrue(bw > 0) p.expect(pexpect.EOF) def testTopoChange(self): "Test pingall on single,3 and linear,4 topos" # testing single,3 p = pexpect.spawn('mn --test pingall --topo single,3') p.expect(r'(\d+)/(\d+) received') received = int(p.match.group(1)) sent = int(p.match.group(2)) self.assertEqual(sent, 6, 'Wrong number of pings sent in single,3') self.assertEqual(sent, received, 'Dropped packets in single,3') p.expect(pexpect.EOF) # testing linear,4 p = pexpect.spawn('mn --test pingall --topo linear,4') p.expect(r'(\d+)/(\d+) received') received = int(p.match.group(1)) sent = int(p.match.group(2)) self.assertEqual(sent, 12, 'Wrong number of pings sent in linear,4') self.assertEqual(sent, received, 'Dropped packets in linear,4') p.expect(pexpect.EOF) def testLinkChange(self): "Test TCLink bw and delay" p = pexpect.spawn('mn --link tc,bw=10,delay=10ms') # test bw p.expect(self.prompt) p.sendline('iperf') p.expect(r"Results: \['([\d\.]+) Mbits/sec',") bw = float(p.match.group(1)) self.assertTrue(bw < 10.1, 'Bandwidth > 10 Mb/s') self.assertTrue(bw > 9.0, 'Bandwidth < 9 Mb/s') p.expect(self.prompt) # test delay p.sendline('h1 ping -c 4 h2') p.expect(r'rtt min/avg/max/mdev = ' r'([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+) ms') delay = float(p.match.group(2)) self.assertTrue(delay > 40, 'Delay < 40ms') self.assertTrue(delay < 45, 'Delay > 40ms') p.expect(self.prompt) p.sendline('exit') p.wait() def testVerbosity(self): "Test debug and output verbosity" # test output p = pexpect.spawn('mn -v output') p.expect(self.prompt) self.assertEqual(len(p.before), 0, 'Too much output for "output"') p.sendline('exit') p.wait() # test debug p = pexpect.spawn('mn -v debug --test none') p.expect(pexpect.EOF) lines = p.before.split('\n') self.assertTrue(len(lines) > 70, "Debug output is too short") def testCustomTopo(self): "Start Mininet using a custom topo, then run pingall" # Satisfy pylint assert self custom = os.path.dirname(os.path.realpath(__file__)) custom = os.path.join(custom, '../../custom/topo-2sw-2host.py') custom = os.path.normpath(custom) p = pexpect.spawn('mn --custom %s --topo mytopo --test pingall' % custom) p.expect('0% dropped') p.expect(pexpect.EOF) def testStaticMAC(self): "Verify that MACs are set to easy to read numbers" p = pexpect.spawn('mn --mac') p.expect(self.prompt) for i in range(1, 3): p.sendline('h%d ifconfig' % i) p.expect('HWaddr 00:00:00:00:00:0%d' % i) p.expect(self.prompt) def testSwitches(self): "Run iperf test using user and ovsk switches" switches = ['user', 'ovsk'] for sw in switches: p = pexpect.spawn('mn --switch %s --test iperf' % sw) p.expect(r"Results: \['([\d\.]+) .bits/sec',") bw = float(p.match.group(1)) self.assertTrue(bw > 0) p.expect(pexpect.EOF) def testBenchmark(self): "Run benchmark and verify that it takes less than 2 seconds" p = pexpect.spawn('mn --test none') p.expect(r'completed in ([\d\.]+) seconds') time = float(p.match.group(1)) self.assertTrue(time < 2, 'Benchmark takes more than 2 seconds') def testOwnNamespace(self): "Test running user switch in its own namespace" p = pexpect.spawn('mn --innamespace --switch user') p.expect(self.prompt) interfaces = ['h1-eth0', 's1-eth1', '[^-]eth0', 'lo', self.prompt] p.sendline('s1 ifconfig -a') ifcount = 0 while True: index = p.expect(interfaces) if index == 1 or index == 3: ifcount += 1 elif index == 0: self.fail('h1 interface displayed in "s1 ifconfig"') elif index == 2: self.fail('eth0 displayed in "s1 ifconfig"') else: break self.assertEqual(ifcount, 2, 'Missing interfaces on s1') # verify that all hosts a reachable p.sendline('pingall') p.expect(r'(\d+)% dropped') dropped = int(p.match.group(1)) self.assertEqual(dropped, 0, 'pingall failed') p.expect(self.prompt) p.sendline('exit') p.wait() # PART 3 def testPythonInterpreter(self): "Test py and px by checking IP for h1 and adding h3" p = pexpect.spawn('mn') p.expect(self.prompt) # test host IP p.sendline('py h1.IP()') p.expect('10.0.0.1') p.expect(self.prompt) # test adding host p.sendline("px net.addHost('h3')") p.expect(self.prompt) p.sendline("px net.addLink(s1, h3)") p.expect(self.prompt) p.sendline('net') p.expect('h3') p.expect(self.prompt) p.sendline('py h3.MAC()') p.expect('([a-f0-9]{2}:?){6}') p.expect(self.prompt) p.sendline('exit') p.wait() def testLink(self): "Test link CLI command using ping" p = pexpect.spawn('mn') p.expect(self.prompt) p.sendline('link s1 h1 down') p.expect(self.prompt) p.sendline('h1 ping -c 1 h2') p.expect('unreachable') p.expect(self.prompt) p.sendline('link s1 h1 up') p.expect(self.prompt) p.sendline('h1 ping -c 1 h2') p.expect('0% packet loss') p.expect(self.prompt) p.sendline('exit') p.wait() @unittest.skipUnless( os.path.exists('/tmp/pox') or '1 received' in quietRun('ping -c 1 github.com'), 'Github is not reachable; cannot download Pox') def testRemoteController(self): "Test Mininet using Pox controller" # Satisfy pylint assert self if not os.path.exists('/tmp/pox'): p = pexpect.spawn( 'git clone https://github.com/noxrepo/pox.git /tmp/pox') p.expect(pexpect.EOF) pox = pexpect.spawn('/tmp/pox/pox.py forwarding.l2_learning') net = pexpect.spawn( 'mn --controller=remote,ip=127.0.0.1,port=6633 --test pingall') net.expect('0% dropped') net.expect(pexpect.EOF) pox.sendintr() pox.wait()
def exampleCustomTags(): """Simple example that exercises VLANStarTopo""" net = Mininet( topo=VLANStarTopo() ) net.start() CLI( net ) net.stop() if __name__ == '__main__': import sys from functools import partial from mininet.net import Mininet from mininet.cli import CLI from mininet.topo import SingleSwitchTopo from mininet.log import setLogLevel setLogLevel( 'info' ) if not quietRun( 'which vconfig' ): error( "Cannot find command 'vconfig'\nThe package", "'vlan' is required in Ubuntu or Debian,", "or 'vconfig' in Fedora\n" ) exit() if len( sys.argv ) >= 2: exampleAllHosts( vlan=int( sys.argv[ 1 ] ) ) else: exampleCustomTags()
def stopquagga(): quietRun('sudo pkill -9 -f bgpd') quietRun('sudo pkill -9 -f zebra')
def dumbbell_test(tcp_alg, delay): out = quietRun('mn -c') info('mn -c: {}\n'.format(out)) output = quietRun( 'sysctl -w net.ipv4.tcp_congestion_control={}'.format(tcp_alg)) assert tcp_alg in output trans_len_sec = TRANSMISSION_DURATION_SECS info( "Creating the a dumbell network with delay={} for alg {} for {} secs\n" .format(delay, tcp_alg, trans_len_sec)) dumbbell = Dumbbell(delay) net = Mininet(dumbbell, link=TCLink) file_name = "{}_{}_ms_delay".format(tcp_alg, delay) iperf_file_name1 = "iperf_{}_{}_ms_delay_1.txt".format(tcp_alg, delay) iperf_file_name2 = "iperf_{}_{}_ms_delay_2.txt".format(tcp_alg, delay) info("Starting the topology\n") net.start() dumpNodeConnections(net.hosts) info("Starting tcp probe\n") start_tcp_probe(file_name) src1 = net.hosts[0] src2 = net.hosts[1] dest1 = net.hosts[2] dest2 = net.hosts[3] trans_len_sec = TRANSMISSION_DURATION_SECS q1 = Queue() q2 = Queue() now = str(dt.datetime.now()) # Get a proc pool to transmit src1->dest1, src2->dest2 p1 = Process(target=run_iperf, args=(q1, src1, dest1, trans_len_sec, 5001, tcp_alg, iperf_file_name1)) p2 = Process(target=run_iperf, args=(q2, src2, dest2, trans_len_sec, 5002, tcp_alg, iperf_file_name2)) info("{} Conn 1 started. Waiting for {} secs for conn 2\n".format( now, SECOND_TRANSMISSION_DELAY_SECS)) p1.start() # wait for SECOND_TRANSMISSION_DELAY_SECS before starting the second transmission time.sleep(SECOND_TRANSMISSION_DELAY_SECS) p2.start() now = str(dt.datetime.now()) info("{} Conn 2 started\n".format(now)) # get the popens from each of the 2 iperf runs popens1 = q1.get() popen1 = popens1[0] popen2 = popens1[1] popens2 = q2.get() popen3 = popens2[0] popen4 = popens2[1] # wait until connection 1 is done (output, err) = popen1.communicate() p_status = popen1.wait() now = str(dt.datetime.now()) info('{} Connection 1 Finished. output:{}, err={},status={}'.format( now, output, err, p_status)) popen2.kill() # wait until connection 2 is done (output, err) = popen3.communicate() p_status = popen3.wait() now = str(dt.datetime.now()) info('{} Connection 2 Finished. output:{}, err={},status={}'.format( now, output, err, p_status)) popen4.kill() info("Transmission complete. Shutting down\n") net.stop() stop_tcp_probe()
def lsmod(): "Return output of lsmod." return quietRun('lsmod')
# pylint: enable=E1101 class testSingleSwitchOVSKernel(testSingleSwitchCommon, unittest.TestCase): "Test ping with single switch topology (OVS kernel switch)." switchClass = OVSSwitch class testSingleSwitchOVSUser(testSingleSwitchCommon, unittest.TestCase): "Test ping with single switch topology (OVS user switch)." switchClass = partial(OVSSwitch, datapath='user') @unittest.skipUnless(quietRun('which ivs-ctl'), 'IVS is not installed') class testSingleSwitchIVS(testSingleSwitchCommon, unittest.TestCase): "Test ping with single switch topology (IVS switch)." switchClass = IVSSwitch @unittest.skipUnless(quietRun('which ofprotocol'), 'Reference user switch is not installed') class testSingleSwitchUserspace(testSingleSwitchCommon, unittest.TestCase): "Test ping with single switch topology (Userspace switch)." switchClass = UserSwitch # Tell pylint not to complain about calls to other class # pylint: disable=E1101
def delete( self ): "Delete interface" self.cmd( 'ip link del ' + self.name ) if self.node.inNamespace: # Link may have been dumped into root NS quietRun( 'ip link del ' + self.name )