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 do_bgIperf(self, line): args = line.split() if not args: output("Provide a list of hosts.\n") # Try to parse the '-t' argument as the number of seconds seconds = 10 for i, arg in enumerate(args): if arg == "-t": if i + 1 < len(args): try: seconds = int(args[i + 1]) except ValueError: error("Could not parse number of seconds: %s", args[i + 1]) del (args[i + 1]) del args[i] hosts = [] err = False for arg in args: if arg not in self.mn: err = True error("node '%s' not in network\n" % arg) else: hosts.append(self.mn[arg]) if "bgIperf" in dir(self.mn) and not err: self.mn.bgIperf(hosts, seconds=seconds)
def do_placement(self, _line): "Describe node placement" mn = self.mn nodes = mn.hosts + mn.switches + mn.controllers for server in mn.servers: names = [n.name for n in nodes if hasattr(n, "server") and n.server == server] output("%s: %s\n" % (server, " ".join(names)))
def do_px( self, line ): """Execute a Python statement. Node names may be used, e.g.: px print h1.cmd('ls')""" try: exec( line, globals(), self.getLocals() ) except Exception, e: output( str( e ) + '\n' )
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 ping(self, hosts=None): """Ping between all specified hosts. hosts: list of hosts returns: ploss packet loss percentage""" # should we check if running? packets = 0 lost = 0 ploss = None if not hosts: hosts = self.hosts output("*** Ping: testing ping reachability\n") for node in hosts: # print "node:" ,node # only test~lol output("%s -> " % node.name) for dest in hosts: if node != dest: result = node.cmd("ping -c1 " + dest.IP()) sent, received = self._parsePing(result) packets += sent if received > sent: error("*** Error: received too many packets") error("%s" % result) node.cmdPrint("route") exit(1) lost += sent - received output(("%s " % dest.name) if received else "X ") output("\n") ploss = 100 * lost / packets output("*** Results: %i%% dropped (%d/%d lost)\n" % (ploss, lost, packets)) return ploss
def PMUPingPDC(net, pmu, pdc, timeout): time.sleep(5) pmu_host = net.getNodeByName(pmu) pdc_host = net.getNodeByName(pdc) output('%s(%s) ping -c1 %s(%s)' % (pmu, pmu_host.IP(), pdc, pdc_host.IP())) result = pmu_host.cmd('ping -W %d -c1 %s' % (timeout, pdc_host.IP())) output(result)
def errRun( *cmd, **kwargs ): """Run a command and return stdout, stderr and return code cmd: string or list of command and args stderr: STDOUT to merge stderr with stdout shell: run command using shell echo: monitor output to console""" # By default we separate stderr, don't run in a shell, and don't echo stderr = kwargs.get( 'stderr', PIPE ) shell = kwargs.get( 'shell', False ) echo = kwargs.get( 'echo', False ) if echo: # cmd goes to stderr, output goes to stdout info( cmd, '\n' ) if len( cmd ) == 1: cmd = cmd[ 0 ] # Allow passing in a list or a string if isinstance( cmd, str ) and not shell: cmd = cmd.split( ' ' ) cmd = [ str( arg ) for arg in cmd ] elif isinstance( cmd, list ) and shell: cmd = " ".join( arg for arg in cmd ) debug( '*** errRun:', cmd, '\n' ) popen = Popen( cmd, stdout=PIPE, stderr=stderr, shell=shell ) # We use poll() because select() doesn't work with large fd numbers, # and thus communicate() doesn't work either out, err = '', '' poller = poll() poller.register( popen.stdout, POLLIN ) fdtofile = { popen.stdout.fileno(): popen.stdout } outDone, errDone = False, True if popen.stderr: fdtofile[ popen.stderr.fileno() ] = popen.stderr poller.register( popen.stderr, POLLIN ) errDone = False while not outDone or not errDone: readable = poller.poll() for fd, event in readable: f = fdtofile[ fd ] if event & POLLIN: data = f.read( 1024 ) if echo: output( data ) if f == popen.stdout: out += data if data == '': outDone = True elif f == popen.stderr: err += data if data == '': errDone = True else: # POLLHUP or something unexpected if f == popen.stdout: outDone = True elif f == popen.stderr: errDone = True poller.unregister( fd ) returncode = popen.wait() debug( out, err, returncode ) return out, err, returncode
def ping( self, hosts=None, timeout=None ): """Ping between all specified hosts. hosts: list of hosts timeout: time to wait for a response, as string returns: ploss packet loss percentage""" # should we check if running? packets = 0 lost = 0 ploss = None if not hosts: hosts = self.hosts[1:] output( '*** Ping: testing ping reachability\n' ) for node in hosts: output( '%s -> ' % node.name ) for dest in hosts: if node != dest: opts = '' if timeout: opts = '-W %s' % timeout result = node.cmd( 'ping -c1 %s %s' % (opts, dest.IP()) ) sent, received = self._parsePing( result ) packets += sent if received > sent: error( '*** Error: received too many packets' ) error( '%s' % result ) node.cmdPrint( 'route' ) exit( 1 ) lost += sent - received output( ( '%s ' % dest.name ) if received else 'X ' ) output( '\n' ) ploss = 100 * lost / packets output( "*** Results: %i%% dropped (%d/%d lost)\n" % ( ploss, lost, packets ) ) return ploss
def runCpuLimitTest(self, cpu, duration=5): """run CPU limit test with 'while true' processes. cpu: desired CPU fraction of each host duration: test duration in seconds returns a single list of measured CPU fractions as floats. """ pct = cpu * 100 info("*** Testing CPU %.0f%% bandwidth limit\n" % pct) hosts = self.hosts for h in hosts: h.cmd("while true; do a=1; done &") pids = [h.cmd("echo $!").strip() for h in hosts] pids_str = ",".join(["%s" % pid for pid in pids]) cmd = "ps -p %s -o pid,%%cpu,args" % pids_str # It's a shame that this is what pylint prefers outputs = [] for _ in range(duration): sleep(1) outputs.append(quietRun(cmd).strip()) for h in hosts: h.cmd("kill $!") cpu_fractions = [] for test_output in outputs: # Split by line. Ignore first line, which looks like this: # PID %CPU COMMAND\n for line in test_output.split("\n")[1:]: r = r"\d+\s*(\d+\.\d+)" m = re.search(r, line) if m is None: error("*** Error: could not extract CPU fraction: %s\n" % line) return None cpu_fractions.append(float(m.group(1))) output("*** Results: %s\n" % cpu_fractions) return cpu_fractions
def build(self, ovs_type, ports_sock, test_name, dpids, n_tagged=0, tagged_vid=100, n_untagged=0, links_per_host=0, n_extended=0, e_cls=None, tmpdir=None, hw_dpid=None, host_namespace=None): if not host_namespace: host_namespace = {} for dpid in dpids: serialno = mininet_test_util.get_serialno( ports_sock, test_name) sid_prefix = self._get_sid_prefix(serialno) for host_n in range(n_tagged): self._add_tagged_host(sid_prefix, tagged_vid, host_n) for host_n in range(n_untagged): self._add_untagged_host(sid_prefix, host_n, host_namespace.get(host_n, True)) for host_n in range(n_extended): self._add_extended_host(sid_prefix, host_n, e_cls, tmpdir) switch_cls = FaucetSwitch if hw_dpid and hw_dpid == dpid: remap_dpid = str(int(dpid) + 1) output('bridging hardware switch DPID %s (%x) dataplane via OVS DPID %s (%x)' % ( dpid, int(dpid), remap_dpid, int(remap_dpid))) dpid = remap_dpid switch_cls = NoControllerFaucetSwitch switch = self._add_faucet_switch(sid_prefix, dpid, ovs_type, switch_cls) self._add_links(switch, self.hosts(), links_per_host)
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 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 ) bothPoller.register( node.stdout ) 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 hostPing(self, rate, duration_time=10): # rate is the arp request per secend per host rate = float(rate) host_numb = len(self.hosts) output("host_numb:%d\n" % host_numb) net_rate = int(host_numb * rate) self.netPing(net_rate, duration_time)
def waitListening(client, server, port): "Wait until server is listening on port" if not "telnet" in client.cmd("which telnet"): raise Exception("Could not find telnet") cmd = 'sh -c "echo A | telnet -e A %s %s"' % (server.IP(), port) while "Connected" not in client.cmd(cmd): output("waiting for", server, "to listen on port", port, "\n") sleep(0.5)
def do_placement( self ): "Describe node placement" mn = self.mn nodes = mn.hosts + mn.switches + mn.controllers for server in mn.servers: names = [ n.name for n in nodes if hasattr( n, 'server' ) and n.server == server ] output( '%s: %s\n' % ( server, ' '.join( names ) ) )
def waitListening(client, server, port): "Wait until server is listening on port" if not 'telnet' in client.cmd('which telnet'): raise Exception('Could not find telnet') cmd = ('sh -c "echo A | telnet -e A %s %s"' % (server.IP(), port)) while 'Connected' not in client.cmd(cmd): output('waiting for', server, 'to listen on port', port, '\n') sleep(.5)
def startIperf( host, hostsDST ): output( '\n\n' ) for dst in hostsDST: if dst.IP() != host.IP(): hostsAux = [] hostsAux.append(host) hostsAux.append(dst) iperf(hosts = hostsAux )
def do_dpctl(self, line): "Run dpctl (or ovs-ofctl) command on all switches." args = line.split() if len(args) < 1: error("usage: dpctl command [arg1] [arg2] ...\n") return for sw in self.mn.switches: output("*** " + sw.name + " " + ("-" * 72) + "\n") output(sw.dpctl(*args))
def show_topology(): output("------- Topology -------\n") for s in net.switches: output(s.name, '<->') for intf in s.intfs.values(): name = s.connection.get(intf, (None, 'Unknown ') ) [ 1 ] output( ' %s' % name ) output('\n') output('\n')
def do_dpctl( self, line ): "Run dpctl (or ovs-ofctl) command on all switches." args = line.split() if len(args) < 1: error( 'usage: dpctl command [arg1] [arg2] ...\n' ) return for sw in self.mn.switches: output( '*** ' + sw.name + ' ' + ('-' * 72) + '\n' ) output( sw.dpctl( *args ) )
def start(ip="127.0.0.1",port=6633): #def start(ip="127.0.0.1",port=6653): ctrlr = lambda n: RemoteController(n, ip=ip, port=port, inNamespace=False) net = Mininet(switch=OVSSwitch, controller=ctrlr, autoStaticArp=False) c1 = net.addController('c1') gates_agraph = pgv.AGraph("simplified_gates_topology.dot") for sw in gates_agraph.nodes(): net.addSwitch(sw, dpid = hex( int(sw.attr['dpid']) )[2:]) for link in gates_agraph.edges(): (src_switch, dst_switch) = link net.addLink(src_switch, dst_switch, int(link.attr['src_port']), int(link.attr['dport']) ) # Only one host and an Internet Router disguised as a host for now (because it's not part of the OF network) h0 = net.addHost('h0', cls=VLANHost, mac='d4:c9:ef:b2:1b:80', ip='128.253.154.1', vlan=1356) net.addLink("s_bdf", h0, 1, 0) # To test DHCP functionality, ucnomment this line and comment out the fixed IP line. Then when mininet # starts you issue: # mininet> h1 dhclient -v -d -1 h1-eth0.1356 # and make sure it gets its IP by going through all protocol steps. #h1 = net.addHost('h1', cls=VLANHost, mac='00:00:01:00:00:11', ip='0.0.0.0', vlan=1356) h1 = net.addHost('h1', cls=VLANHost, mac='00:00:01:00:00:11', ip='128.253.154.100', vlan=1356) net.addLink("s_f3a", h1, 32, 0) # h4{a,b,c} are wireless nodes supposedly hooked up to a dumb AP. You can't just hook them up # to the same mininet port. Y h4a = net.addHost('h4a', cls=VLANHost, mac='00:00:01:00:00:14', ip='128.253.154.104', vlan=1356) net.addLink("s_f3a", h4a, 33, 0) #net.addHost('h4b', cls=VLANHost, mac='00:00:01:00:00:14', ip='128.253.154.104', vlan=1356) #net.addHost('h4c', cls=VLANHost, mac='00:00:01:00:00:14', ip='128.253.154.104', vlan=1356) # h2 is a syslab PC h2 = net.addHost('h2', cls=VLANHost, mac='00:00:01:00:00:13', ip='128.253.154.102', vlan=1356) net.addLink("s_lab_r6", h2, 1, 0) # MAC spoofing attempt of h2 h3 = net.addHost('h3', cls=VLANHost, mac='00:00:01:00:00:13', ip='128.253.154.102', vlan=1356) net.addLink("s_lab_r6", h3, 2, 0) ###### Start of static Mininet epilogue ###### # Set up logging etc. lg.setLogLevel('info') lg.setLogLevel('output') # Start the network net.start() # Start the DHCP server on Internet Router. This will actually be a DHCP proxy in the real setup. #startDHCPserver( h0, gw='128.253.154.1', dns='8.8.8.8') # Enter CLI mode output("Network ready\n") output("Press Ctrl-d or type exit to quit\n") CLI(net)
def parseIperf(iperfOutput): r = r'([\d\.]+ \w+/sec)' m = re.findall(r, iperfOutput) if m: return m[-1] else: # was: raise Exception(...) output(iperfOutput) return ''
def dhcp(self, hosts=None): """Ping between all specified hosts. hosts: list of hosts returns: ploss packet loss percentage""" if not hosts: hosts = self.hosts output("*** Dhclient: Based on pingall test\n") for node in hosts: result = node.cmd("dhclient") return
def do_status(self, _line): "Report on node shell status" nodes = self.mn.hosts + self.mn.switches for node in nodes: node.shell.poll() exited = [node for node in nodes if node.shell.returncode is not None] if exited: for node in exited: output("%s has exited with code %d\n" % (node, node.shell.returncode)) else: output("All nodes are still running.\n")
def interract(net): if len(args.simulations) > 0: lg.output("Start automatic multiple interaction process\n") interract_mul(net) return if args.watcher_start_event or args.watcher_post_event or args.watcher_probe: lg.output('Started automatic interaction process\n') interract_once(net) return return CLI(net)
def do_dpctl(self, line): "Run dpctl command on all switches." args = line.split() if len(args) == 0: error("usage: dpctl command [arg1] [arg2] ...\n") return if not self.mn.listenPort: error("can't run dpctl w/no passive listening port\n") return for sw in self.mn.switches: output("*** " + sw.name + " " + ("-" * 72) + "\n") output(sw.cmd("dpctl " + " ".join(args) + " tcp:127.0.0.1:%i" % sw.listenPort))
def stopEvents(cls): output("Stopping events\n") for event in cls.events: try: event.timerRun.cancel() event.timerReset.cancel() except: pass stopEvent(cls.network.get(event.target), event) # event.timerReset.finished.set() # event.timerReset.join() cls._newEvent(event)
def do_dpctl( self, line ): "Run dpctl command on all switches." args = line.split() if len(args) == 0: error( 'usage: dpctl command [arg1] [arg2] ...\n' ) return if not self.mn.listenPort: error( "can't run dpctl w/no passive listening port\n") return for sw in self.mn.switches: output( '*** ' + sw.name + ' ' + ('-' * 72) + '\n' ) output( sw.cmd( 'dpctl ' + ' '.join(args) + ' tcp:127.0.0.1:%i' % sw.listenPort ) )
def do_bw( self, line ): "bw: show last reported iperf server ingress bandwidth" output( "Last reported iperf UDP server input bandwidth:\n" ) for h in self.mn.hosts: lastout, lasttime = self.lastbw.get( h, ( '', 0 ) ) out = h.cmd( 'tail -1 /tmp/%s.iperf' % h ) if '---' in out or ( out == lastout and time() - lasttime > 1.5 ): # Stale update - don't display out = '\n' else: self.lastbw[ h ] = ( out, time() ) output( '%s:' % h, out )
def start(ip="127.0.0.1", port=6633): dc1_intfName = 'eth1' dc2_intfName = 'eth2' dc3_intfName = 'eth3' dc3_2_intfName = 'eth4' #sff1_intfName = 'eth3' #sff2_intfName = 'eth4' # Set up logging etc. lg.setLogLevel('info') lg.setLogLevel('output') print("Adding controller") ctrlr = lambda n: RemoteController(n, ip=ip, port=port, inNamespace=False) #ctrlr2 = RemoteController('2', ip='192.168.137.111', port=port, inNamespace=False) net = LINCNet(switch=OVSSwitch, link=LINCLink, controller=ctrlr, autoStaticArp=True, listenPort=6634) c1 = net.addController('c1') #c2 = net.addController('c2',controller=RemoteController, ip='192.168.137.62',port=6633) #c2 = net.addController(ctrlr2) # Add hosts #h1 = net.addHost('h1') #h2 = net.addHost('h2') #h101 = net.addHost('h101') #h102 = net.addHost('h102') # Add packet switches to connect hosts to the optical network s1 = net.addSwitch('s1', dpid='00:00:00:00:00:00:00:01', protocols='OpenFlow10') s2 = net.addSwitch('s2', dpid='00:00:00:00:00:00:00:02', protocols='OpenFlow10') s3 = net.addSwitch('s3', dpid='00:00:00:00:00:00:00:03', protocols='OpenFlow10') # Add optical switches r1 = net.addSwitch('r1', dpid='00:00:00:00:00:00:00:11', cls=LINCSwitch) r2 = net.addSwitch('r2', dpid='00:00:00:00:00:00:00:12', cls=LINCSwitch) r3 = net.addSwitch('r3', dpid='00:00:00:00:00:00:00:13', cls=LINCSwitch) r4 = net.addSwitch('r4', dpid='00:00:00:00:00:00:00:14', cls=LINCSwitch) r5 = net.addSwitch('r5', dpid='00:00:00:00:00:00:00:15', cls=LINCSwitch) r6 = net.addSwitch('r6', dpid='00:00:00:00:00:00:00:16', cls=LINCSwitch) r7 = net.addSwitch('r7', dpid='00:00:00:00:00:00:00:17', cls=LINCSwitch) # Connect hosts to packet switches print("Adding physical hosts to mininet network...") _intf1 = Intf(dc1_intfName, node=s1, port=1) _intf2 = Intf(dc2_intfName, node=s2, port=1) _intf3 = Intf(dc3_intfName, node=s3, port=1) _intf3 = Intf(dc3_2_intfName, node=s3, port=6) #net.addLink(h1, s1) #net.addLink(h2, s2) #linkopts = dict(bw=1, delay='1ms', max_queue_size=500,loss=10,use_htb=True) # Connect packet switches to optical switches net.addLink( s1, r1, 2, 1, cls=LINCLink ) #, bw=10, delay='5ms', loss=10, max_queue_size=1000, use_htb=True net.addLink(s1, r1, 3, 2, cls=LINCLink) net.addLink(s2, r3, 2, 1, cls=LINCLink) net.addLink(s2, r3, 3, 2, cls=LINCLink) net.addLink(s3, r5, 2, 3, cls=LINCLink) net.addLink(s3, r5, 3, 4, cls=LINCLink) net.addLink(s3, r5, 4, 5, cls=LINCLink) net.addLink(s3, r5, 5, 6, cls=LINCLink) # Connect optical switches to each other net.addLink(r1, r2, 3, 1, cls=LINCLink) net.addLink(r1, r7, 4, 1, cls=LINCLink) net.addLink(r2, r3, 2, 3, cls=LINCLink) net.addLink(r3, r4, 4, 1, cls=LINCLink) net.addLink(r3, r6, 5, 2, cls=LINCLink) net.addLink(r4, r7, 3, 2, cls=LINCLink) net.addLink(r4, r5, 2, 1, cls=LINCLink) net.addLink(r5, r6, 2, 3, cls=LINCLink) net.addLink(r6, r7, 1, 3, cls=LINCLink) # Start the network and prime other ARP caches net.start() # Uncomment below if using virtual hosts #net.staticArp() #Uncomment below if using physical hosts print "Configuring ARP entries..." arp.setStaticArp() os.system("./setup_links.sh") # Enter CLI mode output("Network ready\n") output("Press Ctrl-d or type exit to quit\n") CLI(net) net.stop()
def ping(self, hosts=None, timeout=None): """Ping between all specified hosts. hosts: list of hosts timeout: time to wait for a response, as string returns: ploss packet loss percentage""" # should we check if running? packets = 0 lost = 0 ploss = None if not hosts: hosts = self.hosts output('*** Ping: testing ping reachability\n') for node in hosts: output('%s -> ' % node.name) for dest in hosts: if node != dest: opts = '' if timeout: opts = '-W %s' % timeout if dest.intfs: result = node.cmd('ping -c1 %s %s' % (opts, dest.IP())) sent, received = self._parsePing(result) else: sent, received = 0, 0 packets += sent if received > sent: error('*** Error: received too many packets') error('%s' % result) node.cmdPrint('route') exit(1) lost += sent - received output(('%s ' % dest.name) if received else 'X ') output('\n') if packets > 0: ploss = 100.0 * lost / packets received = packets - lost output("*** Results: %i%% dropped (%d/%d received)\n" % (ploss, received, packets)) else: ploss = 0 output("*** Warning: No packets sent\n") return ploss
def do_EOF(self, line): "Exit" output('\n') return self.do_exit(line)
def do_intfs(self, _line): "List interfaces." for node in self.mn.values(): output('%s: %s\n' % (node.name, ','.join(node.intfNames())))
def do_help(self, line): # pylint: disable=arguments-differ "Describe available CLI commands." Cmd.do_help(self, line) if line == '': output(self.helpStr)
def errRun(*cmd, **kwargs): """Run a command and return stdout, stderr and return code cmd: string or list of command and args stderr: STDOUT to merge stderr with stdout shell: run command using shell echo: monitor output to console""" # By default we separate stderr, don't run in a shell, and don't echo stderr = kwargs.get('stderr', PIPE) shell = kwargs.get('shell', False) echo = kwargs.get('echo', False) if echo: # cmd goes to stderr, output goes to stdout info(cmd, '\n') if len(cmd) == 1: cmd = cmd[0] # Allow passing in a list or a string if isinstance(cmd, BaseString) and not shell: cmd = cmd.split(' ') cmd = [str(arg) for arg in cmd] elif isinstance(cmd, list) and shell: cmd = " ".join(arg for arg in cmd) debug('*** errRun:', cmd, '\n') popen = Popen(cmd, stdout=PIPE, stderr=stderr, shell=shell) # We use poll() because select() doesn't work with large fd numbers, # and thus communicate() doesn't work either out, err = '', '' poller = poll() poller.register(popen.stdout, POLLIN) fdtofile = {popen.stdout.fileno(): popen.stdout} outDone, errDone = False, True if popen.stderr: fdtofile[popen.stderr.fileno()] = popen.stderr poller.register(popen.stderr, POLLIN) errDone = False while not outDone or not errDone: readable = poller.poll() for fd, event in readable: f = fdtofile[fd] if event & POLLIN: data = f.read(1024) if Python3: data = data.decode(Encoding) if echo: output(data) if f == popen.stdout: out += data if data == '': outDone = True elif f == popen.stderr: err += data if data == '': errDone = True else: # POLLHUP or something unexpected if f == popen.stdout: outDone = True elif f == popen.stderr: errDone = True poller.unregister(fd) returncode = popen.wait() # Python 3 complains if we don't explicitly close these popen.stdout.close() if stderr == PIPE: popen.stderr.close() debug(out, err, returncode) return out, err, returncode
root = Host('root', inNamespace=False) info("*** Creating link\n") h1.linkTo(root) info(h1) info("*** Configuring nodes\n") h1.setIP('10.0.0.1', 8) root.setIP('10.0.0.2', 8) info("*** Creating banner file\n") f = open('/tmp/%s.banner' % h1.name, 'w') f.write('Welcome to %s at %s\n' % (h1.name, h1.IP())) f.close() info("*** Running sshd\n") cmd = '/usr/sbin/sshd -o UseDNS=no -u0 -o "Banner /tmp/%s.banner"' % h1.name # add arguments from the command line if len(sys.argv) > 1: cmd += ' ' + ' '.join(sys.argv[1:]) h1.cmd(cmd) listening = waitListening(server=h1, port=22, timeout=timeout) if listening: output("*** You may now ssh into", h1.name, "at", h1.IP(), '\n') else: warn( "*** Warning: after %s seconds, %s is not listening on port 22" % (timeout, h1.name), '\n')
def do_appcontainers(self, _): """List deployed app containers.""" appcontainers = " ".join(self.mn._appcontainers) output("deployed app containers are: \n%s\n" % appcontainers)
def do_jobs( self, line ): "jobs: List iperf jobs" output( "Currently running jobs:\n" ) for h in self.mn.hosts: output( '%s:' % h, h.cmd( 'jobs' ).strip(), '\n' )
def to_console(self, message): output(message)
def terminate( self ): cmd_proc = self.cmd_proc if is_some( cmd_proc ): output( newline( '<', 'Terminating shell command', "'" + self.cmd + "'", '>' ) ) cmd_proc.terminate()
def run_cmd(daemon, node, op, dargs=None): if dargs: output(node.cmd(daemon, op, *dargs)) else: output(node.cmd(daemon, op))
def buildFromTopo(self, topo=None): """Build mininet from a topology object At the end of this function, everything should be connected and up.""" # Possibly we should clean up here and/or validate # the topo if self.cleanup: pass info('*** Creating network\n') bastion = self.jump waitStart = False _ip = "{}/{}".format( ipAdd(self.adminNextIP, ipBaseNum=self.adminIpBaseNum, prefixLen=self.adminPrefixLen), self.adminPrefixLen) self.adminNextIP += 1 self.host.createMasterAdminNetwork(self.masterSsh, brname="admin-br", ip=_ip) _info(" admin network created on {}\n".format(self.masterhost)) assert (isinstance(self.controllers, list)) if not self.controllers and self.controller: # Add a default controller info('*** Adding controller\n') classes = self.controller if not isinstance(classes, list): classes = [classes] for i, cls in enumerate(classes): # Allow Controller objects because nobody understands partial() if isinstance(cls, Controller): self.addController(cls) else: self.addController('c%d' % i, cls) # from assh import ASsh # prepare SSH connection to the master info('*** Adding hosts:\n') # == Hosts =========================================================== for hostName in topo.hosts(): _ip = "{}/{}".format( ipAdd(self.adminNextIP, ipBaseNum=self.adminIpBaseNum, prefixLen=self.adminPrefixLen), self.adminPrefixLen) self.adminNextIP += 1 # __ip= newAdminIp(admin_ip) self.addHost(name=hostName, admin_ip=_ip, loop=self.loop, master=self.masterSsh, username=self.user, bastion=bastion, client_keys=self.client_keys, waitStart=waitStart, **topo.nodeInfo(hostName)) info(hostName + ' ') info('\n*** Adding switches:\n') for switchName in topo.switches(): _ip = "{}/{}".format( ipAdd(self.adminNextIP, ipBaseNum=self.adminIpBaseNum, prefixLen=self.adminPrefixLen), self.adminPrefixLen) self.adminNextIP += 1 self.addSwitch(name=switchName, admin_ip=_ip, loop=self.loop, master=self.masterSsh, username=self.user, bastion=bastion, client_keys=self.client_keys, waitStart=waitStart, **topo.nodeInfo(switchName)) info(switchName + ' ') if not waitStart: nodes = self.hosts + self.switches _info("[starting\n") for node in nodes: _info("connectTarget {} ".format(node.name)) node.connectTarget() for node in nodes: node.waitConnectedTarget() _info("connectedTarget {} ".format(node.name)) count = 0 reset = 50 for node in nodes: _info("createContainer {} ".format(node.name)) node.createContainer() count += 1 if count > reset: output("{} nodes created...\n".format(reset)) sleep(10) count = 0 for node in nodes: node.waitCreated() _info("createdContainer {} ".format(node.name)) for node in nodes: _info("create admin interface {} ".format(node.name)) node.addContainerInterface(intfName="admin", brname="admin-br", wait=False) for node in nodes: node.targetSshWaitOutput() _info("admin interface created on {} ".format(node.name)) _info("\n") cmds = [] for node in nodes: cmds = cmds + node.connectToAdminNetwork( master=node.masternode.host, target=node.target, link_id=CloudLink.newLinkId(), admin_br="admin-br", wait=False) if len(cmds) > 0: cmd = ';'.join(cmds) self.masterSsh.cmd(cmd) for node in nodes: node.configureContainer(wait=False) for node in nodes: node.targetSshWaitOutput() for node in nodes: _info("connecting {} ".format(node.name)) node.connect() for node in nodes: node.waitConnected() _info("connected {} ".format(node.name)) for node in nodes: _info("startshell {} ".format(node.name)) node.asyncStartShell() for node in nodes: node.waitStarted() _info("startedshell {}".format(node.name)) for node in nodes: _info("finalize {}".format(node.name)) node.finalizeStartShell() _info("\n") info('\n*** Adding links:\n') for srcName, dstName, params in topo.links(sort=True, withInfo=True): self.addLink(**params) info('(%s, %s) ' % (srcName, dstName)) info('\n')
def waitForNode(self, node): "Wait for a node to finish, and print its output." while node.waiting: v = node.monitor(timeoutms=1) output(v)
def do_nodes(self, _line): "List all nodes." nodes = ' '.join(sorted(self.mn)) output('available nodes are: \n%s\n' % nodes)
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 do_dump(self, _line): "Dump node info." for node in self.mn.values(): output('%s\n' % repr(node))
def pingFull(self, hosts=None, timeout=None): """Ping between all specified hosts and return all data. hosts: list of hosts timeout: time to wait for a response, as string returns: all ping data; see function body.""" # should we check if running? # Each value is a tuple: (src, dsd, [all ping outputs]) all_outputs = [] if not hosts: hosts = self.hosts output('*** Ping: testing ping reachability\n') for node in hosts: output('%s -> ' % node.name) for dest in hosts: if node != dest: opts = '' if timeout: opts = '-W %s' % timeout result = node.cmd('ping -c1 %s %s' % (opts, dest.IP())) outputs = self._parsePingFull(result) sent, received, rttmin, rttavg, rttmax, rttdev = outputs all_outputs.append((node, dest, outputs)) output(('%s ' % dest.name) if received else 'X ') output('\n') output("*** Results: \n") for outputs in all_outputs: src, dest, ping_outputs = outputs sent, received, rttmin, rttavg, rttmax, rttdev = ping_outputs output(" %s->%s: %s/%s, " % (src, dest, sent, received)) output("rtt min/avg/max/mdev %0.3f/%0.3f/%0.3f/%0.3f ms\n" % (rttmin, rttavg, rttmax, rttdev)) return all_outputs
def do_links(self, _line): "Report on links" for link in self.mn.links: output(link, link.status(), '\n')
def mycmd(self, line): "mycmd is an example command to extend the Mininet CLI" net = self.mn output('mycmd invoked for', net, 'with line', line, '\n')
def myNetwork(with_windows=False): net = Mininet(topo=None, build=False, ipBase='10.0.0.0/8') info('*** Adding controller\n') c0 = net.addController(name='c0', controller=Controller, protocol='tcp', port=6633) info('*** Add switches\n') s1 = net.addSwitch('s1', cls=OVSKernelSwitch) s2 = net.addSwitch('s2', cls=OVSKernelSwitch) s3 = net.addSwitch('s3', cls=OVSKernelSwitch) s4 = net.addSwitch('s4', cls=OVSKernelSwitch) info('*** Add hosts\n') h1 = net.addHost('h1', cls=Host, ip='10.0.0.1', defaultRoute=None) hc1 = net.addHost('hc1', cls=Host, ip='10.0.0.5', defaultRoute=None) h2 = net.addHost('h2', cls=Host, ip='10.0.0.2', defaultRoute=None) h3 = net.addHost('h3', cls=Host, ip='10.0.0.3', defaultRoute=None) hc4 = net.addHost('hc4', cls=Host, ip='10.0.0.6', defaultRoute=None) h4 = net.addHost('h4', cls=Host, ip='10.0.0.4', defaultRoute=None) info('*** Add links\n') net.addLink(h1, s1) net.addLink(s1, hc1) net.addLink(s1, s2) net.addLink(s2, h2) net.addLink(s2, s3) net.addLink(s3, h3) net.addLink(s3, s4) net.addLink(s4, hc4) net.addLink(s4, h4) info('*** Starting network\n') net.build() info('*** Starting controllers\n') for controller in net.controllers: controller.start() info('*** Starting switches\n') net.get('s1').start([c0]) net.get('s2').start([c0]) net.get('s3').start([c0]) net.get('s4').start([c0]) info('*** Post configure switches and hosts\n') net.pingAll() mac_h1 = (h1.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] mac_hc1 = (hc1.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] mac_h2 = (h2.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] mac_h3 = (h3.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] mac_hc4 = (hc4.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] mac_h4 = (h4.cmd("ifconfig | grep HWaddr | awk '{print $5}'"))[:17] print("mac_h1(" + mac_h1 + ")") print("mac_hc1(" + mac_hc1 + ")") print("mac_h2(" + mac_h2 + ")") print("mac_h3(" + mac_h3 + ")") print("mac_hc4(" + mac_hc4 + ")") print("mac_h4(" + mac_h4 + ")") ## h1-h4 -> hc1-h4 -> h4-hc1 -> hc1-h4 -> h1-h4 ## h4-h1 <- hc4-h1 <- h1-hc4 <- hc4-h1 <- h4-h1 # s1 (mac) flow_1_2_mac = 'priority=255,in_port=1,dl_src=' + mac_h1 + ',dl_dst=' + mac_h4 + ',actions=output:2' flow_2_3_mac = 'priority=255,in_port=2,dl_src=' + mac_hc1 + ',dl_dst=' + mac_h4 + ',actions=output:3' flow_3_2_mac = 'priority=255,in_port=3,dl_src=' + mac_hc4 + ',dl_dst=' + mac_h1 + ',actions=output:2' flow_2_1_mac = 'priority=255,in_port=2,dl_src=' + mac_h4 + ',dl_dst=' + mac_h1 + ',,actions=output:1' ##???s1.dpctl('add-flow', flow_1_2_mac, '') s1.dpctl('add-flow', flow_2_3_mac, '') s1.dpctl('add-flow', flow_3_2_mac, '') s1.dpctl('add-flow', flow_2_1_mac, '') # s2 (mac) flow_1_2_mac = 'priority=255,in_port=1,dl_src=' + mac_hc1 + ',dl_dst=' + mac_h4 + ',actions=output:2' flow_2_3_mac = 'priority=255,in_port=2,dl_src=' + mac_h4 + ',dl_dst=' + mac_hc1 + ',actions=output:3' flow_3_2_mac = 'priority=255,in_port=3,dl_src=' + mac_h1 + ',dl_dst=' + mac_hc4 + ',actions=output:2' flow_2_1_mac = 'priority=255,in_port=2,dl_src=' + mac_hc4 + ',dl_dst=' + mac_h1 + ',,actions=output:1' s2.dpctl('add-flow', flow_1_2_mac, '') s2.dpctl('add-flow', flow_2_3_mac, '') s2.dpctl('add-flow', flow_3_2_mac, '') s2.dpctl('add-flow', flow_2_1_mac, '') # s3 (mac) flow_1_2_mac = 'priority=255,in_port=1,dl_src=' + mac_h4 + ',dl_dst=' + mac_hc1 + ',actions=output:2' flow_2_3_mac = 'priority=255,in_port=2,dl_src=' + mac_h1 + ',dl_dst=' + mac_h4 + ',actions=output:3' flow_3_2_mac = 'priority=255,in_port=3,dl_src=' + mac_hc4 + ',dl_dst=' + mac_h1 + ',actions=output:2' flow_2_1_mac = 'priority=255,in_port=2,dl_src=' + mac_h1 + ',dl_dst=' + mac_hc4 + ',,actions=output:1' s3.dpctl('add-flow', flow_1_2_mac, '') s3.dpctl('add-flow', flow_2_3_mac, '') s3.dpctl('add-flow', flow_3_2_mac, '') s3.dpctl('add-flow', flow_2_1_mac, '') # s4 (mac) flow_1_2_mac = 'priority=255,in_port=1,dl_src=' + mac_hc1 + ',dl_dst=' + mac_h4 + ',actions=output:2' flow_2_3_mac = 'priority=255,in_port=2,dl_src=' + mac_h1 + ',dl_dst=' + mac_h4 + ',actions=output:3' flow_3_2_mac = 'priority=255,in_port=3,dl_src=' + mac_h4 + ',dl_dst=' + mac_h1 + ',actions=output:2' flow_2_1_mac = 'priority=255,in_port=2,dl_src=' + mac_hc4 + ',dl_dst=' + mac_h1 + ',,actions=output:1' s4.dpctl('add-flow', flow_1_2_mac, '') s4.dpctl('add-flow', flow_2_3_mac, '') s4.dpctl('add-flow', flow_3_2_mac, '') s4.dpctl('add-flow', flow_2_1_mac, '') # s1, s2, s3, s4 (ip) flow_1_2 = 'priority=255,ip,in_port=1,nw_src=10.0.0.1,nw_dst=10.0.0.4,actions=output:2' flow_2_3 = 'priority=255,ip,in_port=2,nw_src=10.0.0.1,nw_dst=10.0.0.4,actions=output:3' flow_3_2 = 'priority=255,ip,in_port=3,nw_src=10.0.0.4,nw_dst=10.0.0.1,actions=output:2' flow_2_1 = 'priority=255,ip,in_port=2,nw_src=10.0.0.4,nw_dst=10.0.0.1,actions=output:1' s1.dpctl('add-flow', flow_1_2, '') s1.dpctl('add-flow', flow_2_3, '') s1.dpctl('add-flow', flow_3_2, '') s1.dpctl('add-flow', flow_2_1, '') s2.dpctl('add-flow', flow_1_2, '') s2.dpctl('add-flow', flow_2_3, '') s2.dpctl('add-flow', flow_3_2, '') s2.dpctl('add-flow', flow_2_1, '') s3.dpctl('add-flow', flow_1_2, '') s3.dpctl('add-flow', flow_2_3, '') s3.dpctl('add-flow', flow_3_2, '') s3.dpctl('add-flow', flow_2_1, '') s2.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.1,actions=output:1', '') s2.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.2,actions=output:2', '') s2.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.3,actions=output:3', '') s2.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.4,actions=output:3', '') s3.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.1,actions=output:1', '') s3.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.2,actions=output:1', '') s3.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.3,actions=output:2', '') s3.dpctl('add-flow', 'priority=65535,arp,arp_tpa=10.0.0.4,actions=output:3', '') info('flows s1: ' + s1.dpctl('dump-flows', '', '')) info('flows s2: ' + s1.dpctl('dump-flows', '', '')) info('flows s3: ' + s1.dpctl('dump-flows', '', '')) info('flows s4: ' + s1.dpctl('dump-flows', '', '')) # net.pingAll() if (with_windows): cleanUpScreens() execInXterm([h2, h3], './sf_hhe.sh; read') execInXterm([hc1, hc4], './sf_eth_nsh.sh; read') execInXterm([h4], './server.sh') execInXterm([h4], './tcp_dump.sh') execInXterm([h1, hc1, h2, h3, hc4, h4], './tcp_dump.sh') execInXterm([h1], 'xterm') ## wireshark cmd = 'wireshark' opts = '-i h1-eth0 -k' h1.cmd(cmd + ' ' + opts + '&') opts = '-i hc1-eth0 -k' hc1.cmd(cmd + ' ' + opts + '&') opts = '-i h2-eth0 -k' h2.cmd(cmd + ' ' + opts + '&') opts = '-i h3-eth0 -k' h3.cmd(cmd + ' ' + opts + '&') opts = '-i hc4-eth0 -k' hc4.cmd(cmd + ' ' + opts + '&') opts = '-i h4-eth0 -k' h4.cmd(cmd + ' ' + opts + '&') time.sleep(1) else: h4.sendCmd('./server.sh') time.sleep(1) hc4.sendCmd('./sf_eth_nsh.sh') time.sleep(1) h3.sendCmd('./sf_hhe.sh') time.sleep(1) h2.sendCmd('./sf_hhe.sh') time.sleep(1) hc1.sendCmd('./sf_eth_nsh.sh') time.sleep(1) #h1.sendCmd('./tcp_dump.sh > h1_tcp_dump.txt') h1.cmd('./client.sh') time.sleep(1) h1.sendCmd('python3 ../sf_hhe/HttpClient.py -ip 10.0.0.4') output(h1.waitOutput()) if (with_windows): execInXterm([h1], './client.sh ; read') CLI(net) cleanUpScreens() else: h1.cleanup() hc1.cleanup() h2.cleanup() h3.cleanup() hc4.cleanup() h4.cleanup() net.stop()
def build(self, ovs_type, ports_sock, test_name, dpids, n_tagged=0, tagged_vid=100, n_untagged=0, links_per_host=0, switch_to_switch_links=1, hw_dpid=None, stack_ring=False): """ Hosts |||| |||| +----+ +----+ +----+ ---+1 | |1234| | 1+--- Hosts ---+2 | | | | 2+--- Hosts ---+3 | | | | 3+--- ---+4 5+-------+5 6+-------+5 4+--- +----+ +----+ +----+ Faucet-1 Faucet-2 Faucet-3 | | | | | | +-------- controller -----+ * s switches (above S = 3; for S > 3, switches are added to the chain) * (n_tagged + n_untagged) hosts per switch * (n_tagged + n_untagged + 1) links on switches 0 and s-1, with final link being inter-switch * (n_tagged + n_untagged + 2) links on switches 0 < n < s-1, with final two links being inter-switch """ def addLinks(src, dst): for _ in range(self.switch_to_switch_links): self.addLink(src, dst) first_switch = None last_switch = None self.switch_to_switch_links = switch_to_switch_links for dpid in dpids: serialno = mininet_test_util.get_serialno(ports_sock, test_name) sid_prefix = self._get_sid_prefix(serialno) hosts = [] for host_n in range(n_tagged): hosts.append( self._add_tagged_host(sid_prefix, tagged_vid, host_n)) for host_n in range(n_untagged): hosts.append(self._add_untagged_host(sid_prefix, host_n)) switch_cls = FaucetSwitch if hw_dpid and hw_dpid == dpid: remap_dpid = str(int(dpid) + 1) output( 'bridging hardware switch DPID %s (%x) dataplane via OVS DPID %s (%x)' % (dpid, int(dpid), remap_dpid, int(remap_dpid))) dpid = remap_dpid switch_cls = NoControllerFaucetSwitch switch = self._add_faucet_switch(sid_prefix, dpid, ovs_type, switch_cls) self._add_links(switch, hosts, links_per_host) if first_switch is None: first_switch = switch if last_switch is not None: # Add a switch-to-switch link with the previous switch, # if this isn't the first switch in the topology. addLinks(last_switch, switch) last_switch = switch if stack_ring: addLinks(first_switch, last_switch)
response = pexpect.run(jsonCurlCmd) if (response.find("Successfully Inserted") != -1): info("Executed %s" % jsonCurlCmd) else: error("Exiting on error %s for cmd %s" % (response, jsonCurlCmd)) sys.exit() info("Reading input from %s file\n" % mainArgs.input) # Read the mcast configuration from JSON input file json_file = open(mainArgs.input, 'r') try: mcast_json = json.load(json_file) except (ValueError, KeyError, TypeError): error("Error from %s failed...exiting\n" % mainArgs.input) sys.exit() output("Load from %s is successful\n" % mainArgs.input) info('Creating mininet topology\n') controller = mainArgs.controller "Create network and test multicast packet delivery" net = Mininet(topo=FourSwMeshTopo(1), switch=OVSSwitch, controller=lambda a: RemoteController(a, ip=controller)) net.start() output("\nCreated Mininet topology\n") # Scan the input json to populate senders and receivers info("\nParsing 'mcastgroup' JSON input\n") try: for i in range(0, len(mcast_json['mcastgroup'])): # Need to strip off netmask for src and grp
def tcptest( self, hosts=None, timeout=2 ): """TCP reachability test hosts: list of hosts. timeout: TCP connection and read timeout in seconds returns: percentage of unsuccessful connections""" # We use custom TCP server and clients. We don't use netcat since # netcat lacks the ability to fine-tune timeouts and to have # time-outs < 1sec. We want both so we can fail-fast. # # We also use a new TCP port for each test. This way we are really sure # we are talking to the right endpoint. Alternatively we could also # send a magic number / token in the TCP payload.... # # TODO: We use fairly low timeouts at the moment. If we find # intermittant errors we might have to use long timeouts # should we check if running? total = 0 success = 0 if not hosts: hosts = self.hosts output( '*** TCP: testing TCP reachability\n' ) for node in hosts: output( '%s -> ' % node.name ) for dest in hosts: if node != dest: total += 1 # # Use a larger timeout for the server, as we do not want # the server to timeout before the client gets a chance # send the packets. # srvResult = dest.sendCmd("mn-tcptest-srv.py %f %d" % (timeout * 10, self.curTcpPort)) dest.waitOutput(pattern = self._listenRegex) cliResult = node.cmd( 'mn-tcptest-cli.py %f %s %d' % (timeout, dest.IP(), self.curTcpPort) ) sleep(0.01) # Make sure server process is done. Need the sleep to give the # server time to terminate dest.sendInt() if dest.waiting: # could be false if the early waitOutput call # retunred an error srvResult = dest.waitOutput() cliResult = self._parseTcpOutput(cliResult) srvResult = self._parseTcpOutput(srvResult) if cliResult == "OK" and srvResult == "OK": # everything ok resCode = dest.name success += 1 elif cliResult != "OK" and srvResult != "OK": # error from both. That's what we expect resCode = cliResult else: # Weird. Only one error? resCode = cliResult + srvResult resCode = resCode.replace("OK","O") output( '%s ' % resCode ) self.curTcpPort += 1 if (self.curTcpPort > self.maxTcpPort): self.curTcpPort = self.minTcpPort output( '\n' ) ploss = 100 * (total-success) / total output( "*** Results: %i%% unsuccessful (%d/%d lost)\n" % ( ploss, (total-success), total ) ) return ploss
def start(ip="192.168.137.110",port=6633): classifier1_intfName = 'eth1' classifier2_intfName = 'eth2' sff1_intfName = 'eth3' sff2_intfName = 'eth4' # Set up logging etc. lg.setLogLevel('info') lg.setLogLevel('output') ctrlr = lambda n: RemoteController(n, ip=ip, port=port, inNamespace=False) ctrlr2 = RemoteController('2', ip='192.168.137.62', port=port, inNamespace=False) net = LINCNet(switch=OVSSwitch, controller=ctrlr, autoStaticArp=True, listenPort=6634) c1 = net.addController('c1') #c2 = net.addController('c2',controller=RemoteController, ip='192.168.137.62',port=6633) c2 = net.addController(ctrlr2) # Add hosts #h1 = net.addHost('h1') #h2 = net.addHost('h2') #h101 = net.addHost('h101') #h102 = net.addHost('h102') # Add packet switches to connect hosts to the optical network s1 = net.addSwitch('s1', dpid='00:00:00:00:00:00:00:01', protocols='OpenFlow10') s2 = net.addSwitch('s2', dpid='00:00:00:00:00:00:00:02', protocols='OpenFlow10') linkopts = dict(bw=1) # Add optical switches r1 = net.addSwitch('r1', dpid='00:00:00:00:00:00:00:11', cls=LINCSwitch) r2 = net.addSwitch('r2', dpid='00:00:00:00:00:00:00:12', cls=LINCSwitch) r3 = net.addSwitch('r3', dpid='00:00:00:00:00:00:00:13', cls=LINCSwitch) r4 = net.addSwitch('r4', dpid='00:00:00:00:00:00:00:14', cls=LINCSwitch) r5 = net.addSwitch('r5', dpid='00:00:00:00:00:00:00:15', cls=LINCSwitch) r6 = net.addSwitch('r6', dpid='00:00:00:00:00:00:00:16', cls=LINCSwitch) r7 = net.addSwitch('r7', dpid='00:00:00:00:00:00:00:17', cls=LINCSwitch) r8 = net.addSwitch('r8', dpid='00:00:00:00:00:00:00:18', cls=LINCSwitch) # Connect hosts to packet switches #print "Adding physical hosts to mininet network..." _intf1 = Intf( classifier1_intfName, node=s1, port=1 ) _intf2 = Intf( sff1_intfName, node=s1, port=2 ) _intf3 = Intf( classifier2_intfName, node=s2, port=1 ) _intf4 = Intf( sff2_intfName, node=s2, port=2 ) #net.addLink(h1, s1) #net.addLink(h2, s2) #net.addLink(h101, s1) #net.addLink(h102, s2) # Connect packet switches to optical switches net.addLink(s1, r1, 3, 1, cls=LINCLink, **linkopts) net.addLink(s1, r1, 4, 2, cls=LINCLink, **linkopts) net.addLink(s2, r2, 3, 1, cls=LINCLink, **linkopts) net.addLink(s2, r2, 4, 2, cls=LINCLink, **linkopts) # Connect optical switches to each other net.addLink(r1, r3, 3, 1, cls=LINCLink) net.addLink(r1, r5, 4, 1, cls=LINCLink) net.addLink(r1, r6, 5, 1, cls=LINCLink) net.addLink(r1, r7, 6, 1, cls=LINCLink) net.addLink(r2, r4, 3, 2, cls=LINCLink) net.addLink(r2, r5, 4, 2, cls=LINCLink) net.addLink(r2, r6, 5, 2, cls=LINCLink) net.addLink(r2, r8, 6, 2, cls=LINCLink) net.addLink(r3, r4, 2, 1, cls=LINCLink) net.addLink(r7, r8, 2, 1, cls=LINCLink) # Start the network and prime other ARP caches net.start() # Uncomment below if using virtal hosts #net.staticArp() #Uncomment below if using physical hosts print "Configuring ARP entries..." utils.setStaticArp() # Enter CLI mode output("Network ready\n") output("Press Ctrl-d or type exit to quit\n") CLI(net) net.stop()
def runTopo(topoFile, simParams, hostOptions, checkLevel, controller, switch): topo = CustomTopo(topoFilePath=topoFile, simParams=simParams, hostOptions=hostOptions) if checkLevel > 1: topo.setNetOption('link', TCLink) # net = CustomMininet(topo = topo, controller = Beacon, autoSetMacs = True, **topo.getNetOptions()) # net = CustomMininet(topo = topo, controller = Beacon, **topo.getNetOptions()) net = CustomMininet(topo=topo, controller=controller, switch=switch, **topo.getNetOptions()) global netprobes netprobes = collections.OrderedDict() try: lg.output('Constructing virtual network..\n') start(net) check(net, checkLevel) lg.output("Starting hosts") lg.info(": ") for host in net.hosts: lg.info("%s " % host.name) if host.monitor_rules is not None: monitor.start(host, host.monitor_rules) if host.command is not None: lg.info("cmd ") host.command = host.command.format( commandOpts=host.commandOpts, name=host.name).format(name=host.name) if host.isXHost: t = makeTerm(host, cmd=host.command) if len(t) < 1: lg.error( "Error while starting terminal for host %s\n" % host.name) continue if len(t) == 2: tunnel, term = t else: term = t try: if term.poll() is not None: lg.error( "Terminal with command %s ended early for host %s : %s\n" % (host.command, host.name, repr(term.communicate()))) except: pass netprobes[host.name] = term else: netprobes[host.name] = runCommand(host) # print(netprobes[host.name].communicate()) else: if host.isXHost: makeTerm(host) lg.info("term ") lg.info("done ") lg.output("\n") EventsManager.startClock(net) interract(net) mon = False counter = monitor.Counter() for host in net.hosts: if host.monitor_rules is not None: monitor.collect(host, monitor_file, counter) monitor.stop(host, host.monitor_rules) mon = True for name, probe in netprobes.iteritems(): lg.info("Send sigint to probe %s\n" % name) import signal try: probe.send_signal(signal.SIGINT) time.sleep(0.05) except OSError as e: lg.error("Failed to send SIGINT to %s : %s\n" % (name, e)) if mon: monitor.writeSummary(monitor_file, counter) finally: stop(net) # cleanup ! lg.info("Stopping remaining processes...\n") kill = 0 for name, probe in netprobes.iteritems(): if probe.poll() is None: kill += 1 if kill > 0: lg.info("Found %s process(es) to kill\n" % kill) time.sleep(3) for name, probe in netprobes.iteritems(): if probe.poll() is None: try: lg.info("Send terminate signal to %s\n" % name) probe.terminate() time.sleep(0.001) except OSError as e: lg.error("Failed to terminate %s : %s\n" % (name, e)) time.sleep(3) for name, probe in netprobes.iteritems(): if probe.poll() is None: try: lg.info("Send kill signal to %s\n" % name) probe.kill() except OSError as e: lg.error("Failed to kill %s : %s\n" % (name, e)) lg.output("\nAll done\n")
def do_help( self, line ): "Describe available CLI commands." Cmd.do_help( self, line ) if line is '': output( self.helpStr )
def myiperf(self, hosts=None, iterations=10, seconds=1, port=5001): client = [] server = [] a = server port = [] r = r'([\d\.]+ \w+/sec)' """Run iperf between two hosts. hosts: list of hosts; if None, uses first and last hosts l4Type: string, one of [ TCP, UDP ] udpBw: bandwidth target for UDP test fmt: iperf format argument if any seconds: iperf time to transmit port: iperf port returns: two-element array of [ server, client ] speeds note: send() is buffered, so client rate can be much higher than the actual transmission rate; on an unloaded system, server rate should be much closer to the actual receive rate""" print "hello" hosts = hosts or [self.hosts] for n in range(len(self.hosts) / 2): client.append(self.hosts[2 * (n)]) server.append(self.hosts[2 * (n) + 1]) port.append(5001) for i in range(len(server)): iperfArgs = 'iperf -p %d ' % port[i] server[i].sendCmd(iperfArgs + '-s -D') for l in range(iterations): a = server[:] b = port[:] for i in range(len(client)): print time.time() start_time = time.time() x = random.randint(0, len(a) - 1) print x bwArgs = '' output('*** Iperf: testing', 'bandwidth between', client[i], 'and', a[x], '\n') if not waitListening(client[i], a[x].IP(), b[x], 20): raise Exception('Could not connect to iperf on port %d' % b[x]) cliout = client[i].cmd('iperf -p %d ' % b[x] + ' -t %d -c ' % seconds + a[x].IP() + ' ' + bwArgs) debug('Client output: %s\n' % cliout) servout = '' # We want the last *b/sec from the iperf server output # for TCP, there are two of them because of waitListening count = 2 while len(re.findall('/sec', servout)) < count: servout += a[x].monitor(timeoutms=1000) print servout print cliout a[x].sendInt() servout = a[x].waitOutput() debug('Server output: %s\n' % servout) m1 = re.findall(r, servout) m2 = re.findall(r, cliout) if m1: print "lololo" if m2: print "lalala" "result = [ m1[-1], m2[-1], time.time() ]" print time.time() result = time.time() - start_time output('*** Results: %s\n' % result) print a print a[x] print b print b[x] del a[x] del b[x] print a print b return result
def iperf(self, hosts=None, l4Type='TCP', udpBw='10M', fmt=None, seconds=5, port=5001): """Run iperf between two hosts. hosts: list of hosts; if None, uses first and last hosts l4Type: string, one of [ TCP, UDP ] udpBw: bandwidth target for UDP test fmt: iperf format argument if any seconds: iperf time to transmit port: iperf port returns: two-element array of [ server, client ] speeds note: send() is buffered, so client rate can be much higher than the actual transmission rate; on an unloaded system, server rate should be much closer to the actual receive rate""" sleep(3) nodes = self.hosts + self.stations hosts = hosts or [nodes[0], nodes[-1]] assert len(hosts) is 2 client, server = hosts conn1 = 0 conn2 = 0 if isinstance(client, Station) or isinstance(server, Station): if isinstance(client, Station): while conn1 is 0: conn1 = int( client.cmd('iw dev %s link ' '| grep -ic \'Connected\'' % client.params['wlan'][0])) if isinstance(server, Station): while conn2 is 0: conn2 = int( server.cmd('iw dev %s link | grep -ic ' '\'Connected\'' % server.params['wlan'][0])) output('*** Iperf: testing', l4Type, 'bandwidth between', client, 'and', server, '\n') server.cmd('killall -9 iperf') iperfArgs = 'iperf -p %d ' % port bwArgs = '' if l4Type is 'UDP': iperfArgs += '-u ' bwArgs = '-b ' + udpBw + ' ' elif l4Type != 'TCP': raise Exception('Unexpected l4 type: %s' % l4Type) if fmt: iperfArgs += '-f %s ' % fmt server.sendCmd(iperfArgs + '-s') if l4Type is 'TCP': if not waitListening(client, server.IP(), port): raise Exception('Could not connect to iperf on port %d' % port) cliout = client.cmd(iperfArgs + '-t %d -c ' % seconds + server.IP() + ' ' + bwArgs) debug('Client output: %s\n' % cliout) servout = '' # We want the last *b/sec from the iperf server output # for TCP, there are two of them because of waitListening count = 2 if l4Type is 'TCP' else 1 while len(re.findall('/sec', servout)) < count: servout += server.monitor(timeoutms=5000) server.sendInt() servout += server.waitOutput() debug('Server output: %s\n' % servout) result = [self._parseIperf(servout), self._parseIperf(cliout)] if l4Type is 'UDP': result.insert(0, udpBw) output('*** Results: %s\n' % result) return result
def stop_custom( self, cmd ): output( newline( '<', 'Stopping shell command', "'" + self.cmd + "'", 'by executing', "'" + cmd + "'", '>' ) ) NodeUtils.run_cmd( self.node, cmd )