def load_module(cls, n_radios, nodes, alt_module, **params): """Load WiFi Module :param n_radios: number of wifi radios :param alt_module: dir of a mac80211_hwsim alternative module""" debug('Loading %s virtual wifi interfaces\n' % n_radios) if not cls.externally_managed: if alt_module: output_ = os.system('insmod %s radios=0 >/dev/null 2>&1' % alt_module) else: output_ = os.system('modprobe mac80211_hwsim radios=0 ' '>/dev/null 2>&1') """output_ is different of zero in Kernel 3.13.x. radios=0 doesn't work in such kernel version""" if output_ == 0: cls.__create_hwsim_mgmt_devices(n_radios, nodes, **params) else: # Useful for kernel <= 3.13.x if n_radios == 0: n_radios = 1 if alt_module: os.system('insmod %s radios=%s' % (alt_module, n_radios)) else: os.system('modprobe mac80211_hwsim radios=%s' % n_radios) else: cls.devices_created_dynamically = True cls.__create_hwsim_mgmt_devices(n_radios, nodes, **params)
def addNodeLoopbackIntf(self, loIntf, loNum): """Adds a loopback interface (called on instantiation an interface). loIntf: loopback interface.""" self.nameToIntf[loIntf.name] = loIntf self.loIntfs[loIntf.name] = loNum debug('\n') debug('added intf %s to node %s\n' % (loIntf, self.name))
def config(self, **kwargs): Host.config(self, **kwargs) debug("configuring route %s" % self.route) self.cmd('ip addr add %s dev %s-eth0' % (self.ip, self.name)) self.cmd('ip route add default via %s' % self.route)
def fixLimits(): "Fix ridiculously small resource limits." debug( "*** Setting resource limits\n" ) try: rlimitTestAndSet( RLIMIT_NPROC, 8192 ) rlimitTestAndSet( RLIMIT_NOFILE, 16384 ) #Increase open file limit sysctlTestAndSet( 'fs.file-max', 10000 ) #Increase network buffer space sysctlTestAndSet( 'net.core.wmem_max', 16777216 ) sysctlTestAndSet( 'net.core.rmem_max', 16777216 ) sysctlTestAndSet( 'net.ipv4.tcp_rmem', '10240 87380 16777216' ) sysctlTestAndSet( 'net.ipv4.tcp_wmem', '10240 87380 16777216' ) sysctlTestAndSet( 'net.core.netdev_max_backlog', 5000 ) #Increase arp cache size sysctlTestAndSet( 'net.ipv4.neigh.default.gc_thresh1', 4096 ) sysctlTestAndSet( 'net.ipv4.neigh.default.gc_thresh2', 8192 ) sysctlTestAndSet( 'net.ipv4.neigh.default.gc_thresh3', 16384 ) #Increase routing table size sysctlTestAndSet( 'net.ipv4.route.max_size', 32768 ) #Increase number of PTYs for nodes sysctlTestAndSet( 'kernel.pty.max', 20000 ) except: warn( "*** Error setting resource limits. " "Mininet's performance may be affected.\n" )
def moduleDeps( subtract=None, add=None ): """Handle module dependencies. subtract: string or list of module names to remove, if already loaded add: string or list of module names to add, if not already loaded""" subtract = subtract if subtract is not None else [] add = add if add is not None else [] if type( subtract ) is str: subtract = [ subtract ] if type( add ) is str: add = [ add ] for mod in subtract: if mod in lsmod(): info( '*** Removing ' + mod + '\n' ) rmmodOutput = rmmod( mod ) if rmmodOutput: error( 'Error removing ' + mod + ': "%s">\n' % rmmodOutput ) exit( 1 ) if mod in lsmod(): error( 'Failed to remove ' + mod + '; still there!\n' ) exit( 1 ) for mod in add: if mod not in lsmod(): info( '*** Loading ' + mod + '\n' ) modprobeOutput = modprobe( mod ) if modprobeOutput: error( 'Error inserting ' + mod + ' - is it installed and available via modprobe?\n' + 'Error was: "%s"\n' % modprobeOutput ) if mod not in lsmod(): error( 'Failed to insert ' + mod + ' - quitting.\n' ) exit( 1 ) else: debug( '*** ' + mod + ' already loaded\n' )
def waitListening( client=None, server='127.0.0.1', port=80, timeout=None ): """Wait until server is listening on port. returns True if server is listening""" runCmd = ( client.cmd if client else partial( quietRun, shell=True ) ) if not runCmd( 'which telnet' ): raise Exception('Could not find telnet' ) # pylint: disable=maybe-no-member serverIP = server if isinstance( server, basestring ) else server.IP() cmd = ( 'echo A | telnet -e A %s %s' % ( serverIP, port ) ) time = 0 result = runCmd( cmd ) while 'Connected' not in result: if 'No route' in result: rtable = runCmd( 'route' ) error( 'no route to %s:\n%s' % ( server, rtable ) ) return False if timeout and time >= timeout: error( 'could not connect to %s on port %d\n' % ( server, port ) ) return False debug( 'waiting for', server, 'to listen on port', port, '\n' ) info( '.' ) sleep( .5 ) time += .5 result = runCmd( cmd ) return True
def assign_iface(cls, nodes, phys, **params): """Assign virtual interfaces for all nodes :param nodes: list of wireless nodes :param phys: list of phys :param **params: ifb - Intermediate Functional Block device""" log_filename = '/tmp/mininetwifi-fakelb.log' cls.logging_to_file("%s" % log_filename) try: debug("\n*** Configuring interfaces with appropriated network" "-namespaces...\n") for node in nodes: for wlan in range(0, len(node.params['wpan'])): node.wpanPhyID[wlan] = cls.wpanPhyID cls.wpanPhyID += 1 phy = cls.getPhy(phys[0]) os.system('iwpan phy phy%s set netns %s' % (phy, node.pid)) node.cmd('ip link set %s down' % cls.wlan_list[0]) node.cmd('ip link set %s name %s' % (cls.wlan_list[0], node.params['wpan'][wlan])) cls.wlan_list.pop(0) except: logging.exception("Warning:") info("Warning! Error when loading fakelb. " "Please run sudo 'mn -c' before running your code.\n") info("Further information available at %s.\n" % log_filename) exit(1)
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 precheck( self ): """Pre-check to make sure connection works and that we can call sudo without a password""" result = 0 info( '*** Checking servers\n' ) for server in self.servers: ip = self.serverIP[ server ] if not server or server == 'localhost': continue info( server, '' ) dest = '%s@%s' % ( self.user, ip ) cmd = [ 'sudo', '-E', '-u', self.user ] cmd += self.sshcmd + [ '-n', dest, 'sudo true' ] debug( ' '.join( cmd ), '\n' ) _out, _err, code = errRun( cmd ) if code != 0: error( '\nstartConnection: server connection check failed ' 'to %s using command:\n%s\n' % ( server, ' '.join( cmd ) ) ) result |= code if result: error( '*** Server precheck failed.\n' '*** Make sure that the above ssh command works' ' correctly.\n' '*** You may also need to run mn -c on all nodes, and/or\n' '*** use sudo -E.\n' ) sys.exit( 1 ) info( '\n' )
def waitListening( client=None, server='127.0.0.1', port=80, timeout=None, callback=None, sleepSecs=.5 ): "Modified mininet.util.waitListening with callback, sleepSecs" runCmd = ( client.cmd if client else partial( quietRun, shell=True ) ) if not runCmd( 'which telnet' ): raise Exception('Could not find telnet' ) # pylint: disable=maybe-no-member serverIP = server if isinstance( server, basestring ) else server.IP() cmd = ( 'echo A | telnet -e A %s %s' % ( serverIP, port ) ) elapsed = 0 result = runCmd( cmd ) while 'Connected' not in result: if 'No route' in result: rtable = runCmd( 'route' ) error( 'no route to %s:\n%s' % ( server, rtable ) ) return False if timeout and elapsed >= timeout: error( 'could not connect to %s on port %d\n' % ( server, port ) ) return False debug( 'waiting for', server, 'to listen on port', port, '\n' ) info( '.' ) if callback: callback() time.sleep( sleepSecs ) elapsed += sleepSecs result = runCmd( cmd ) return True
def makeTunnel(self, node1, node2, intfname1, intfname2, addr1=None, addr2=None): "Make a tunnel across switches on different servers" # We should never try to create a tunnel to ourselves! assert node1.server != node2.server if node2.server == 'localhost': return self.makeTunnel( node2, node1, intfname2, intfname1, addr2, addr1 ) IP1, IP2 = node1.serverIP, node2.serverIP # GRE tunnel needs to be set up with the IP of the local interface # that connects the remote node, NOT '127.0.0.1' of localhost if node1.server == 'localhost': output = quietRun('ip route get %s' % node2.serverIP) IP1 = output.split(' src ')[1].split()[0] debug( '\n*** Make GRE tunnel ' + node1.server + ':' + intfname1 + ' == ' + node2.server + ':' + intfname2 ) tun1 = 'local ' + IP1 + ' remote ' + IP2 tun2 = 'local ' + IP2 + ' remote ' + IP1 self.__class__.GRE_KEY += 1 for (node, intfname, addr, tun) in [(node1, intfname1, addr1, tun1), (node2, intfname2, addr2, tun2)]: node.rcmd('ip link delete ' + intfname) result = node.rcmd('ip link add name ' + intfname + ' type gretap ' + tun + ' ttl 64 key ' + str( self.__class__.GRE_KEY) ) if result: raise Exception('error creating gretap on %s: %s' % (node, result)) if addr: node.rcmd('ip link set %s address %s' % (intfname, addr)) node.rcmd('ip link set dev %s up' % intfname) node.rcmd('ip link set dev %s mtu 1450' % intfname) if not self.moveIntf(intfname, node): raise Exception('interface move failed on node %s' % node)
def _popen( self, cmd, sudo=True, tt=True, **params): """Spawn a process on a remote node cmd: remote command to run (list) **params: parameters to Popen() returns: Popen() object""" if type( cmd ) is str: cmd = cmd.split() if self.isRemote: if sudo: cmd = [ 'sudo', '-E' ] + cmd if tt: cmd = self.sshcmd + cmd else: # Hack: remove -tt sshcmd = list( self.sshcmd ) sshcmd.remove( '-tt' ) cmd = sshcmd + cmd else: if self.user and not sudo: # Drop privileges cmd = [ 'sudo', '-E', '-u', self.user ] + cmd params.update( preexec_fn=self._ignoreSignal ) debug( '_popen', cmd, '\n' ) popen = super( RemoteMixin, self )._popen( cmd, **params ) return popen
def start(self, controllers): "Start up a new P4 switch" info("Starting P4 switch {}.\n".format(self.name)) args = [self.sw_path] for port, intf in self.intfs.items(): if not intf.IP(): args.extend(['-i', str(port) + "@" + intf.name]) if self.pcap_dump: args.append("--pcap") # args.append("--useFiles") if self.thrift_port: args.extend(['--thrift-port', str(self.thrift_port)]) if self.nanomsg: args.extend(['--nanolog', self.nanomsg]) args.extend(['--device-id', str(self.device_id)]) P4Switch.device_id += 1 args.append(self.json_path) if self.enable_debugger: args.append("--debugger") if self.log_console: args.append("--log-console") logfile = "/tmp/p4s.{}.log".format(self.name) info(' '.join(args) + "\n") pid = None with tempfile.NamedTemporaryFile() as f: # self.cmd(' '.join(args) + ' > /dev/null 2>&1 &') self.cmd(' '.join(args) + ' >' + logfile + ' 2>&1 & echo $! >> ' + f.name) pid = int(f.read()) debug("P4 switch {} PID is {}.\n".format(self.name, pid)) if not self.check_switch_started(pid): error("P4 switch {} did not start correctly.\n".format(self.name)) exit(1) info("P4 switch {} has been started.\n".format(self.name))
def __init__(self, tcpdump_host, tcpdump_filter, funcs=None, vflags='-v', timeout=10, packets=2, root_intf=False, pcap_out=None, intf_name=None, blocking=True): self.intf_name = intf_name if intf_name else tcpdump_host.intf().name self.funcs = funcs if root_intf: self.intf_name = self.intf_name.split('.')[0] tcpdump_flags = vflags tcpdump_flags += ' -c %u' % packets if packets else '' tcpdump_flags += ' -w %s' % pcap_out if pcap_out else '' tcpdump_cmd = 'tcpdump -i %s %s -e -n -U %s' % ( self.intf_name, tcpdump_flags, tcpdump_filter) pipe_cmd = tcpdump_cmd if timeout: pipe_cmd = mininet_test_util.timeout_soft_cmd(tcpdump_cmd, timeout) debug(pipe_cmd) self.pipe = tcpdump_host.popen( pipe_cmd, stdin=mininet_test_util.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, shell=False) if self.stream(): debug('tcpdump_helper stream fd %s %s' % ( self.stream().fileno(), self.intf_name)) self.readbuf = '' self.set_blocking(blocking)
def load_ifb(cls, wlans): """ Loads IFB :param wlans: Number of wireless interfaces """ debug('\nLoading IFB: modprobe ifb numifbs=%s' % wlans) os.system('modprobe ifb numifbs=%s' % wlans)
def test_ping_with_background_traffice(network, round_count=1, round_duration=5, ping_interval=1.0, background=True): """ h1 执行 ping 测试延时 h2 执行 netperf 测试带宽利用率 :param background: :param network: mininet class :param round_count: 循环次数 :param round_duration: 循环时间每轮 :param ping_interval: ping包采样间隔 :return: """ result = "" h1 = network.get("h1") popens = {} if background: # backgroud traffice, 每轮增加10秒时延 h1.cmd("netperf -H h3 -l %s &" % (round_count * (round_duration + 5))) sleep(3) # wait 2 second to reach tcp max output for r in range(round_count): print ("*** ROUND %s" % r) for h in [h1]: ping_cmd = "ping -c%s -i%s h3 " % (int(round_duration / ping_interval), ping_interval) info("<%s>: popen cmd: %s \n" % (h.name, ping_cmd)) popens[h] = h.popen(ping_cmd) # Monitor them and print output for host, line in pmonitor(popens): if host: if line.find("icmp_seq") != -1: debug("<%s>: %s\n" % (host.name, line.strip())) # suppressed ping output to debug level else: info("<%s>: %s\n" % (host.name, line.strip())) result += "<%s>: %s\n" % (host.name, line.strip()) debug("\n".join(os.popen('tc -s -d qdisc show dev s1-eth3').readlines())) return result
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 createUniqueFloodlightPropertiesFile(self): """ Creates a unique properties file for the particular Floodlight instance. Each file is put in the 'properties' folder in the floodlight directory. Static class attributes keep track of the current port number to use. :return: None """ # The path to the properties file to be copied and the name of the file old_path = Floodlight.fl_root_dir + 'src/main/resources/' old_file = 'floodlightdefault.properties' # The path where the new properties file will be located and the name of the file new_path = Floodlight.fl_root_dir + 'properties/' new_file = 'floodlight' + str(Floodlight.controller_number) + '.properties' # Set the instance attributes so that the instance can know where its associated properties file is self.properties_path = new_path self.properties_file = new_file # Check if the new path already exists. If not, then create it if not path.exists(new_path): makedirs(new_path) # Copy the old properties file to the new location with the new name shutil.copy(old_path + old_file, new_path + new_file) # Open the new properties file and scan it for the ports that need to be changed with open(new_path + new_file) as fp: properties = jprops.load_properties(fp) http = [key for key, value in properties.items() if key.endswith('httpPort')][0] https = [key for key, value in properties.items() if key.endswith('httpsPort')][0] openflow = [key for key, value in properties.items() if key.endswith('openFlowPort')][0] syncmanager = [key for key, value in properties.items() if key.endswith('SyncManager.port')][0] properties[http] = str(Floodlight.http_port + 10) properties[https] = str(Floodlight.https_port + 10) properties[openflow] = str(Floodlight.openflow_port + 10) properties[syncmanager] = str(Floodlight.sync_manager_port + 10) # Update the class attributes so that everyone knows what ports are available now Floodlight.http_port += 10 Floodlight.https_port += 10 Floodlight.openflow_port += 10 Floodlight.sync_manager_port += 10 log.debug('Ports being used in controller ' + self.name + ' property file...\n') log.debug(http + ' = ' + properties[http] + '\n') log.debug(https + ' = ' + properties[https] + '\n') log.debug(openflow + ' = ' + properties[openflow] + '\n') log.debug(syncmanager + ' = ' + properties[syncmanager] + '\n') # Write the updated ports to the new properties file with open(new_path + new_file, 'w') as fp: # print 'Writing to file ' + new_file jprops.store_properties(fp, properties)
def config(self, **kwargs): Host.config(self, **kwargs) debug("configuring route %s" % self.gateway) self.cmd('ip addr flush dev %s' % self.defaultIntf()) for ip in self.ips: self.cmd('ip addr add %s dev %s' % (ip, self.defaultIntf())) self.cmd('ip route add default via %s' % self.gateway)
def makeTunnel( self, node1, node2, intfname1, intfname2, addr1=None, addr2=None ): "Make a tunnel across switches on different servers" # We should never try to create a tunnel to ourselves! assert node1.server != 'localhost' or node2.server != 'localhost' # And we can't ssh into this server remotely as 'localhost', # so try again swappping node1 and node2 if node2.server == 'localhost': return self.makeTunnel( node2, node1, intfname2, intfname1, addr2, addr1 ) # 1. Create tap interfaces for node in node1, node2: # For now we are hard-wiring tap9, which we will rename node.rcmd( 'ip link delete tap9', stderr=PIPE ) cmd = 'ip tuntap add dev tap9 mode tap user ' + node.user node.rcmd( cmd ) links = node.rcmd( 'ip link show' ) # print 'after add, links =', links assert 'tap9' in links # 2. Create ssh tunnel between tap interfaces # -n: close stdin dest = '%s@%s' % ( node2.user, node2.serverIP ) cmd = [ 'ssh', '-n', '-o', 'Tunnel=Ethernet', '-w', '9:9', dest, 'echo @' ] self.cmd = cmd tunnel = node1.rpopen( cmd, sudo=False ) # When we receive the character '@', it means that our # tunnel should be set up debug( 'Waiting for tunnel to come up...\n' ) ch = tunnel.stdout.read( 1 ) if ch != '@': error( 'makeTunnel:\n', 'Tunnel setup failed for', '%s:%s' % ( node1, node1.dest ), 'to', '%s:%s\n' % ( node2, node2.dest ), 'command was:', cmd, '\n' ) tunnel.terminate() tunnel.wait() error( ch + tunnel.stdout.read() ) error( tunnel.stderr.read() ) sys.exit( 1 ) # 3. Move interfaces if necessary for node in node1, node2: if node.inNamespace: retry( 3, .01, RemoteLink.moveIntf, 'tap9', node ) # 4. Rename tap interfaces to desired names for node, intf, addr in ( ( node1, intfname1, addr1 ), ( node2, intfname2, addr2 ) ): if not addr: node.cmd( 'ip link set tap9 name', intf ) else: node.cmd( 'ip link set tap9 name', intf, 'address', addr ) for node, intf in ( ( node1, intfname1 ), ( node2, intfname2 ) ): assert intf in node.cmd( 'ip link show' ) return tunnel
def execute(self): """Run the helper and accumulate tcpdump output.""" tcpdump_txt = '' if self.stream(): while True: line = self.next_line() if not line: break debug('tcpdump_helper fd %d line "%s"' % (self.stream().fileno(), line)) tcpdump_txt += line.strip() return tcpdump_txt
def load_module(cls, n_radios, alt_module=''): """ Load WiFi Module :param n_radios: number of radios :param alt_module: dir of a fakelb alternative module""" debug('Loading %s virtual interfaces\n' % n_radios) if not cls.externally_managed: if alt_module: os.system('insmod %s numlbs=0' % alt_module) else: os.system('modprobe fakelb numlbs=%s' % n_radios)
def cfsInfo( self, f): "Internal method: return parameters for CFS bandwidth" pstr, qstr = 'cfs_period_us', 'cfs_quota_us' # CFS uses wall clock time for period and CPU time for quota. quota = int( self.period_us * f * numCores() ) period = self.period_us if f > 0 and quota < 1000: debug( '(cfsInfo: increasing default period) ' ) quota = 1000 period = int( quota / f / numCores() ) return pstr, qstr, period, quota
def isFloodlightInstalled(): """ This is a helper function to determine whether floodlight has been installed. :return: true or false """ if not path.isdir(Floodlight.fl_root_dir): log.debug('Floodlight is not installed.\n') return False else: log.debug('Floodlight has been installed.\n') return True
def ssf(self, sta, ap, wlan): #ssf: Strongest signal first distance = sta.get_distance_to(sta.params['associatedTo'][wlan]) rssi = sta.get_rssi(sta.params['associatedTo'][wlan], wlan, distance) ref_dist = sta.get_distance_to(ap) ref_rssi = sta.get_rssi(ap, wlan, ref_dist) if float(ref_rssi) > float(rssi + 0.1): debug('iw dev %s disconnect\n' % sta.params['wlan'][wlan]) sta.pexec('iw dev %s disconnect' % sta.params['wlan'][wlan]) self.changeAP = True return self.changeAP
def myiperf(self, hosts=None, l4Type='TCP', udpBw='10M', fmt=None, seconds=2, 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""" hosts = hosts or [self.hosts[0], self.hosts[-1]] assert len(hosts) == 2 client, server = hosts output('*** Iperf: testing', l4Type, 'bandwidth between', client, 'and', server, '\n') server.cmd('killall -9 iperf') iperfArgs = 'iperf3 -p %d ' % port bwArgs = '' if l4Type == '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 == 'TCP': if not waitListening(client, server.IP(), port): raise Exception('Could not connect to iperf on port %d' % port) time1 = time.time() ttt=2 for coun in range(3): cliout = client.cmd(iperfArgs + '-P 20 -l 42 -n %d -c ' % ttt + server.IP() + ' ' + bwArgs) # time.sleep(.01) time2 = time.time() output('this took %0.3f ms \n' % ( (time2 - time1) * 1000.0)) 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 llf(self, sta, ap, wlan): #llf: Least loaded first apref = sta.params['associatedTo'][wlan] if apref != '': ref_llf = len(apref.params['associatedStations']) if len(ap.params['associatedStations']) + 2 < ref_llf: debug('iw dev %s disconnect\n' % sta.params['wlan'][wlan]) sta.pexec('iw dev %s disconnect' % sta.params['wlan'][wlan]) self.changeAP = True else: self.changeAP = True return self.changeAP
def iperf( self, hosts=None, l4Type='TCP', udpBw='10M', format=None, seconds=5): """Run iperf between two hosts. hosts: list of hosts; if None, uses opposite hosts l4Type: string, one of [ TCP, UDP ] udpBw: bandwidth target for UDP test format: iperf format argument if any seconds: iperf time to transmit 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""" if not quietRun( 'which telnet' ): error( 'Cannot find telnet 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 ) if format: iperfArgs += '-f %s ' %format server.sendCmd( iperfArgs + '-s', printPid=True ) servout = '' while server.lastPid is None: servout += server.monitor() if l4Type == 'TCP': while 'Connected' not in client.cmd( 'sh -c "echo A | telnet -e A %s 5001"' % server.IP()): info( 'Waiting for iperf to start up...' ) sleep(.5) cliout = client.cmd( iperfArgs + '-t %d -c ' % seconds + 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 makeTunnel( self, node1, node2, intfname1, intfname2, addr1=None, addr2=None ): "Make a tunnel across switches on different servers" # We should never try to create a tunnel to ourselves! assert node1.server != node2.server # And we can't ssh into this server remotely as 'localhost', # so try again swappping node1 and node2 if node2.server == 'localhost': return self.makeTunnel( node2, node1, intfname2, intfname1, addr2, addr1 ) print( '\n*** Make SSH tunnel ' + node1.server + ':' + intfname1 + ' == ' + node2.server + ':' + intfname2 ) # 1. Create tap interfaces for node in node1, node2: # For now we are hard-wiring tap9, which we will rename cmd = 'ip tuntap add dev tap9 mode tap user ' + node.user result = node.rcmd( cmd ) if result: raise Exception( 'error creating tap9 on %s: %s' % ( node, result ) ) # 2. Create ssh tunnel between tap interfaces # -n: close stdin dest = '%s@%s' % ( node2.user, node2.serverIP ) cmd = [ 'ssh', '-n', '-o', 'Tunnel=Ethernet', '-w', '9:9', dest, 'echo @' ] self.cmd = cmd tunnel = node1.rpopen( cmd, sudo=False ) # When we receive the character '@', it means that our # tunnel should be set up debug( 'Waiting for tunnel to come up...\n' ) ch = tunnel.stdout.read( 1 ) if ch != '@': raise Exception( 'makeTunnel:\n', 'Tunnel setup failed for', '%s:%s' % ( node1, node1.dest ), 'to', '%s:%s\n' % ( node2, node2.dest ), 'command was:', cmd, '\n' ) # 3. Move interfaces if necessary for node in node1, node2: if not self.moveIntf( 'tap9', node ): raise Exception( 'interface move failed on node %s' % node ) # 4. Rename tap interfaces to desired names for node, intf, addr in ( ( node1, intfname1, addr1 ), ( node2, intfname2, addr2 ) ): if not addr: result = node.cmd( 'ip link set tap9 name', intf ) else: result = node.cmd( 'ip link set tap9 name', intf, 'address', addr ) if result: raise Exception( 'error renaming %s: %s' % ( intf, result ) ) return tunnel
def moveIntfFrom( self, intf, intf_node, port=None ): """Move an interface. intf: interface intf_node: original node containing interface port: port number (optional, typically OpenFlow port number)""" if port is None: port = self.newPort() self.intfs[ port ] = intf self.ports[ intf ] = port self.nameToIntf[ intf.name ] = intf debug( '\nmoving intf %s:%d to node %s\n' % ( intf, port, self.name )) debug( 'moving', intf, 'into namespace for', self.name, '\n' ) moveIntf( intf.name, self, intf_node )
def computeDijkastra(self): """ Dijkstra computation: Compute all the shortest paths from nodes to the destinations. And fills the distance matrix with the corresponding source to destination cost """ distanceMatrix = self.getNestedDictionary() nodeNames = self.getNodeNames() for node in nodeNames: others = [x for x in nodeNames if x not in [node]] for destinationNode in others: cost, path = dijkstra(self.adjacenctMatrix, node, destinationNode) viaNeighbor = path[1] distanceMatrix[node][destinationNode][viaNeighbor] = cost debug("Shortest Distance Matrix: {}".format( json.dumps(distanceMatrix))) return distanceMatrix
def create_hwsim(self, n): self.get_phys() p = subprocess.Popen( ["hwsim_mgmt", "-c", "-n", self.prefix + ("%02d" % n)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1) output, err_out = p.communicate() if p.returncode == 0: m = re.search("ID (\d+)", output.decode()) debug("Created mac80211_hwsim device with ID %s\n" % m.group(1)) Mac80211Hwsim.hwsim_ids.append(m.group(1)) else: error("\nError on creating mac80211_hwsim device with name %s" % (self.prefix + ("%02d" % n))) error("\nOutput: %s" % output) error("\nError: %s" % err_out)
def computeHyperbolic(self): paths = self.getNestedDictionary() nodeNames = self.getNodeNames() for node in self.nodeDict: neighbors = [k for k in self.adjacenctMatrix[node]] for viaNeighbor in neighbors: others = [x for x in nodeNames if x not in [viaNeighbor, node]] paths[node][viaNeighbor][viaNeighbor] = 0 # Compute distance from neighbors to no-neighbors for destinationNode in others: hyperbolicDistance = getHyperbolicDistance( self.nodeDict[viaNeighbor], self.nodeDict[destinationNode]) hyperbolicCost = int(HYPERBOLIC_COST_ADJUSTMENT_FACTOR \ * round(hyperbolicDistance, 6)) paths[node][destinationNode][viaNeighbor] = hyperbolicCost debug("Shortest Distance Matrix: {}".format(json.dumps(paths))) return paths
def terminate(self): if not self.pipe: return -1 try: debug('tcpdump_helper terminate fd %s' % self.stream().fileno()) self.pipe.kill() result = self.pipe.wait() if result == 124: # Mask valid result from timeout command. result = 0 self.pipe.stdout.close() self.pipe = None return result except Exception as e: error('Error closing tcpdump_helper fd %d: %s' % (self.pipe.stdout.fileno(), e)) return -2
def registerRoute(node, namePrefix, remoteNodeAddress, protocol=PROTOCOL_UDP, origin=255, cost=0, inheritFlag=True, captureFlag=False, expirationInMillis=None): cmd = ('nfdc route add {} {}://{} origin {} cost {} {}{}').format( namePrefix, protocol, remoteNodeAddress, origin, cost, 'no-inherit ' if not inheritFlag else '', 'capture ' if captureFlag else '', 'expires {}'.format(expirationInMillis) if expirationInMillis else '') debug(node.cmd(cmd)) Minindn.sleep(SLEEP_TIME)
def kill(self, purge=False): """Kill a container.""" debug('killing container %s.' % self.container) if purge: kill_cmd = ["docker", "rm", "-f", self.container] else: kill_cmd = ["docker", "kill", self.container] try: kill_pipe = self._popen(kill_cmd, stdin=DEVNULL, stdout=PIPE, stderr=STDOUT) kill_pipe.stdout.readlines() kill_pipe.stdout.close() except: if kill_pipe: kill_pipe.poll() raise
def setChannelParameters(self, sta, ap, dist, wlan): """ Wifi Parameters """ associated = True time = abs(sta.params['speed']) staList = self.staList if ap == sta.associatedAp[wlan]: if dist > ap.range + sta.range: debug( '\niw dev %s disconnect' % sta.params['wlan'][wlan] ) sta.pexec('iw dev %s disconnect' % sta.params['wlan'][wlan]) sta.associatedAp[wlan] = 'NoAssociated' sta.params['rssi'][wlan] = 0 sta.params['snr'][wlan] = 0 self.numberOfAssociatedStations(ap) else: channelParameters(sta, ap, wlan, dist, staList, time) else: if dist < ap.range + sta.range: aps = 0 for n in range(0,len(sta.associatedAp)): if str(sta.associatedAp[n]) != 'NoAssociated': aps+=1 if len(sta.associatedAp) == aps: associated = True else: associated = False else: associated = False if ap == sta.associatedAp[wlan] or dist < (ap.range + sta.range): #Only if it is a mobility environment changeAP = False association_Control = dict () """Association Control: mechanisms that optimize the use of the APs""" if self.associationControlMethod != False: ac = self.associationControlMethod value = associationControl(sta, ap, wlan, ac) changeAP = value.changeAP association_Control.setdefault( 'ac', ac ) #Go to handover if associated == False or changeAP == True: self.handover(sta, ap, wlan, dist, changeAP, **association_Control) channelParameters(sta, ap, wlan, dist, staList, time)
def start(self, controllers): "Start up a new P4 switch" info("Starting P4 switch {}.\n".format(self.name)) args = [self.sw_path] for port, intf in self.intfs.items(): if not intf.IP(): args.extend(['-i', str(port) + "@" + intf.name]) if self.pcap_dump: args.append("--pcap") # args.append("--useFiles") if self.thrift_port: args.extend(['--thrift-port', str(self.thrift_port)]) if self.nanomsg: args.extend(['--nanolog', self.nanomsg]) args.extend(['--device-id', str(self.device_id)]) P4Switch.device_id += 1 #"changes to burn different p4 json files to different switches" if self.device_id == 0 or self.device_id == 1: args.append("int_source.p4.json") elif self.device_id == no_of_switches.no_of_switches - 1: args.append("int_sink.p4.json") else: args.append("int_transit.p4.json") if self.enable_debugger: args.append("--debugger") if self.log_console: args.append("--log-console") info(' '.join(args) + "\n") pid = None with tempfile.NamedTemporaryFile() as f: # self.cmd(' '.join(args) + ' > /dev/null 2>&1 &') self.cmd(' '.join(args) + ' >' + self.log_file + ' 2>&1 & echo $! >> ' + f.name) pid = int(f.read()) debug("P4 switch {} PID is {}.\n".format(self.name, pid)) sleep(1) if not self.check_switch_started(pid): error("P4 switch {} did not start correctly." "Check the switch log file.\n".format(self.name)) exit(1) info("P4 switch {} has been started.\n".format(self.name))
def mobilityPositionDefined(self, initial_time, final_time, staMov): """ ongoing Mobility """ t_end = time.time() + final_time t_initial = time.time() + initial_time currentTime = time.time() i = 1 if self.DRAW == True: debug('Enabling Graph...\n') plot.instantiateGraph(self.MAX_X, self.MAX_Y) for sta in self.staList: self.graphInstantiateNodes(sta) if sta not in staMov: plot.pltNode[sta].set_data(sta.params['position'][0], sta.params['position'][1]) plot.drawTxt(sta) plot.drawCircle(sta) for ap in mobility.apList: self.graphInstantiateNodes(ap) for c in ap.connections: line = plot.plotLine2d([ap.connections[c].params['position'][0], ap.params['position'][0]], \ [ap.connections[c].params['position'][1], ap.params['position'][1]], 'b') plot.plotLine(line) for wall in mobility.wallList: line = plot.plotLine2d([wall.params['initPos'][0], wall.params['finalPos'][0]], \ [wall.params['initPos'][1], wall.params['finalPos'][1]], 'r', 10) plot.plotLine(line) try: while time.time() < t_end and time.time() > t_initial: if self.continue_: if time.time() - currentTime >= i: for sta in staMov: if time.time() - currentTime >= sta.startTime and time.time() - currentTime <= sta.endTime: x = float(sta.params['position'][0]) + float(self.moveFac[sta][0]) y = float(sta.params['position'][1]) + float(self.moveFac[sta][1]) z = float(sta.params['position'][2]) + float(self.moveFac[sta][2]) sta.params['position'] = x, y, z for wlan in range(0, len(sta.params['wlan'])): self.nodeParameter(sta, wlan) if self.DRAW: plot.graphPause() plot.graphUpdate(sta) i += 1 except: print 'Error! Mobility stopped!'
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""" hosts = hosts or [ self.hosts[ 0 ], self.hosts[ -1 ] ] assert len( hosts ) == 2 client, server = hosts output( '*** Iperf: testing', l4Type, 'bandwidth between', client, 'and', server, '\n' ) server.cmd( 'killall -9 iperf' ) iperfArgs = 'iperf -p %d ' % port bwArgs = '' if l4Type == '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 == '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 ) 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 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""" if not quietRun('which telnet'): error('Cannot find telnet 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 '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) 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 __create_hwsim_mgmt_devices(cls, n_radios): # generate prefix if py_version_info < (3, 0): phys = subprocess.check_output("find /sys/kernel/debug/ieee80211 -name " "hwsim | cut -d/ -f 6 | sort", shell=True).split("\n") else: phys = subprocess.check_output("find /sys/kernel/debug/ieee80211 -name " "hwsim | cut -d/ -f 6 | sort", shell=True).decode('utf-8').split("\n") num = 0 numokay = False cls.prefix = "" while not numokay: cls.prefix = "mn%02ds" % num numokay = True for phy in phys: if phy.startswith(cls.prefix): num += 1 numokay = False break try: for i in range(0, n_radios): p = subprocess.Popen(["hwsim_mgmt", "-c", "-n", cls.prefix + ("%02d" % i)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1) output, err_out = p.communicate() if p.returncode == 0: if py_version_info < (3, 0): m = re.search("ID (\d+)", output) else: m = re.search("ID (\d+)", output.decode()) debug("Created mac80211_hwsim device with ID %s\n" % m.group(1)) cls.hwsim_ids.append(m.group(1)) else: error("\nError on creating mac80211_hwsim device with name %s" % (cls.prefix + ("%02d" % i))) error("\nOutput: %s" % output) error("\nError: %s" % err_out) except: info("Warning! If you already had Mininet-WiFi installed " "please run util/install.sh -W and then sudo make install.\n")
def terminate(self): """Terminate the helper.""" if not self.pipe or not self.stream(): return -1 try: debug('tcpdump_helper terminate fd %s' % self.stream().fileno()) self.pipe.terminate() result = self.pipe.wait() if result == 124: # Mask valid result from timeout command. result = 0 self.pipe.stdout.close() self.pipe = None return result except EnvironmentError as err: error('Error closing tcpdump_helper fd %d: %s' % (self.pipe.stdout.fileno(), err)) return -2
def associate_noEncrypt(cls, sta, ap, wlan): """ Association when there is no encrypt :param sta: station :param ap: access point :param wlan: wlan ID """ #debug('iw dev %s connect %s %s\n' # % (sta.params['wlan'][wlan], ap.params['ssid'][0], ap.params['mac'][0])) #sta.pexec('iw dev %s connect %s %s' # % (sta.params['wlan'][wlan], ap.params['ssid'][0], ap.params['mac'][0])) #iwconfig is still necessary, since iw doesn't include essid like iwconfig does. debug('iwconfig %s essid %s ap %s\n' % (sta.params['wlan'][wlan], ap.params['ssid'][0], ap.params['mac'][0])) sta.pexec('iwconfig %s essid %s ap %s' % (sta.params['wlan'][wlan], ap.params['ssid'][0], ap.params['mac'][0]))
def __init__(self, nSpines, nLeaves, nHosts, numlinks, **params): Topo.__init__(self, **params) self.spines = {} self.leaves = {} self.numlinks = numlinks self.numhosts = nHosts h = {} # Add switches sc = 0 hc = 1 for i in range(0, nSpines): self.spines[i] = self.addSwitch('s%d' % (sc + 1)) sc += 1 for i in range(0, nLeaves): self.leaves[i] = self.addSwitch('s%d' % (sc + 1)) for s in self.spines: for l in range(0, self.numlinks): self.addLink(self.leaves[i], self.spines[s]) for j in range(0, nHosts): name = 'h%d' % hc ip = '10.0.%d.%d/24' % (i + 1, j + 2) defaultRoute = 'via 10.0.%d.254' % (i + 1) hc += 1 h[name] = self.addHost(name, ip=ip, defaultRoute=defaultRoute, startCommand='foo') debug('*** Add host %s as %s\n' % (name, ip)) self.addLink(h[name], self.leaves[i]) sc += 1 generate = params['generate'].lower() in [ 'y', 'yes', 't', 'true' ] if 'generate' in params else False self.driver = 'ofdpa-ovs' self.onos = 'http://*****:*****@localhost:8181' post = params['post'].lower() in ['y', 'yes', 't', 'true' ] if 'post' in params else False if generate or post: do_post_internal(self)
def handover(self, sta, ap, wlan, distance, changeAP, ac=None): """handover""" if ac == 'llf' or ac == 'ssf' and sta.params['associatedTo'][wlan] != ap: if sta.params['associatedTo'][wlan] != '': sta.params['associatedTo'][wlan].associatedStations.remove(sta) sta.pexec('iw dev %s disconnect' % sta.params['wlan'][wlan]) debug ('\niwconfig %s essid %s ap %s' % (sta.params['wlan'][wlan], ap.ssid[0], ap.params['mac'])) sta.pexec('iwconfig %s essid %s ap %s' % (sta.params['wlan'][wlan], ap.ssid[0], ap.params['mac'])) sta.params['associatedTo'][wlan] = ap sta.params['frequency'][wlan] = channelParameters.frequency(ap, 0) ap.associatedStations.append(sta) elif ap not in sta.params['associatedTo']: # Useful for stations with more than one wifi iface if sta.params['associatedTo'][wlan] == '': debug('\niwconfig %s essid %s ap %s' % (sta.params['wlan'][wlan], ap.ssid[0], ap.params['mac'])) sta.pexec('iwconfig %s essid %s ap %s' % (sta.params['wlan'][wlan], ap.ssid[0], ap.params['mac'])) sta.params['frequency'][wlan] = channelParameters.frequency(ap, 0) ap.associatedStations.append(sta) sta.params['associatedTo'][wlan] = ap
def plotGraph(self, wifiNodes=[], srcConn=[], dstConn=[]): """ Plot Graph """ debug('Enabling Graph...\n') for node in wifiNodes: x = '%.2f' % float(node.params['position'][0]) y = '%.2f' % float(node.params['position'][1]) self.graphInstantiateNodes(node) node.pltNode.set_data(x, y) self.text(node) self.circle(node) for c in range(0, len(srcConn)): src_x = '%.2f' % float(srcConn[c].params['position'][0]) src_y = '%.2f' % float(srcConn[c].params['position'][1]) dst_x = '%.2f' % float(dstConn[c].params['position'][0]) dst_y = '%.2f' % float(dstConn[c].params['position'][1]) line = self.plotLine2d([src_x, dst_x], \ [src_y, dst_y], 'b') self.plotLine(line)
def start(self, controllers): info("Starting P4 grpc switch {}.\n".format(self.name)) args = [self.sw_path] for port, intf in self.intfs.items(): if not intf.IP(): args.extend(['-i', str(port) + "@" + intf.name]) if self.pcap_dump: args.append("--pcap") if self.nanomsg: args.extend(['--nanolog', self.nanomsg]) args.extend(['--device-id', str(self.device_id)]) P4Switch.device_id += 1 if self.json_path: args.append(self.json_path) else: args.append("--no-p4") if self.enable_debugger: args.append("--debugger") if self.log_console: args.append("--log-console") args.extend(['--log-level', 'trace']) if self.grpc_port: args.append("-- --grpc-server-addr 0.0.0.0:" + str(self.grpc_port)) if self.cpu_port: args.extend(['--cpu-port', str(self.cpu_port)]) cmd = ' '.join(args) info(cmd + "\n") logfile = "/tmp/p4s.{}.log".format(self.name) pid = None for i in range(0, 3): with tempfile.NamedTemporaryFile() as f: self.cmd(cmd + ' >' + logfile + ' 2>&1 & echo $! >> ' + f.name) pid = int(f.read()) debug("P4 switch {} PID is {}.\n".format(self.name, pid)) if not self.check_switch_started(pid): error("P4 switch {} did not start correctly on {}. attempt.\n". format(self.name, i + 1)) else: info("P4 Switch {} did start correctly.\n".format(self.name)) break info("P4 switch {} has been started.\n".format(self.name))
def start(self, controllers): if not self.stopped: warn("*** %s is already running!\n" % self.name) return # Remove files from previous executions (if we are restarting) self.cleanupTmpFiles() if self.grpcPort: writeToFile("/tmp/bmv2-%s-grpc-port" % self.name, self.grpcPort) if self.thriftPort: writeToFile("/tmp/bmv2-%s-thrift-port" % self.name, self.thriftPort) cmdString = self.getBmv2CmdString() if self.dryrun: info("\n*** DRY RUN (not executing %s)\n" % self.targetName) debug("\n%s\n" % cmdString) try: if not self.dryrun: # Start the switch self.stopped = False self.logfd = open(self.logfile, "w") self.logfd.write(cmdString + "\n\n" + "-" * 80 + "\n\n") self.logfd.flush() self.bmv2popen = self.popen(cmdString, stdout=self.logfd, stderr=self.logfd) self.waitBmv2Start() # We want to be notified if BMv2/Stratum dies... threading.Thread(target=watchDog, args=[self]).start() if self.netcfg: self.doOnosNetcfg() except Exception: ONOSBmv2Switch.mininet_exception = 1 self.killBmv2() self.printBmv2Log() raise
def apOutOfRange(self, sta, ap, wlan, dist): """ When ap is out of range :param sta: station :param ap: access point :param wlan: wlan ID :param dist: distance between source and destination """ if ap == sta.params['associatedTo'][wlan]: debug('iw dev %s disconnect\n' % sta.params['wlan'][wlan]) if 'encrypt' in ap.params: if ap.params['encrypt'][0] == 'wpa' or ap.params['encrypt'][ 0] == 'wpa2': if sta.passwd != ap.params['passwd'][0]: os.system('rm %s.staconf' % sta) pidfile = "mn%d_%s_%s_wpa.pid" % (os.getpid(), sta.name, wlan) os.system( 'pkill -f \'wpa_supplicant -B -Dnl80211 -P %s -i %s\'' % (pidfile, sta.params['wlan'][wlan])) os.system('rm /var/run/wpa_supplicant/%s' % sta.params['wlan'][wlan]) else: pass sta.pexec('iw dev %s disconnect' % sta.params['wlan'][wlan]) if WmediumdServerConn.connected and WmediumdServerConn.interference_enabled and dist >= 0.01: """do nothing""" elif WmediumdServerConn.connected and dist >= 0.01: cls = Association cls.setSNRWmediumd(sta, ap, snr=-10) sta.params['associatedTo'][wlan] = '' sta.params['rssi'][wlan] = 0 sta.params['snr'][wlan] = 0 sta.params['channel'][wlan] = 0 # sta.params['frequency'][wlan] = 0 if sta in ap.params['associatedStations']: ap.params['associatedStations'].remove(sta) if ap in sta.params['apsInRange']: sta.params['apsInRange'].remove(ap) ap.params['stationsInRange'].pop(sta, None) setChannelParams.recordParams(sta, ap)
def start(self, controllers): #print "switch start" #print self.name #print "grpc_port:" + str(self.grpc_port) #print "device_id:" + str(self.device_id) info("Starting P4 switch {}.\n".format(self.name)) logfile = "/home/shengliu/Workspace/log/p4s.{}.log".format(self.name) args = [self.sw_path] for port, intf in self.intfs.items(): if not intf.IP(): args.extend(['-i', str(port) + "@" + intf.name]) if self.pcap_dump: pcapfile = "/home/shengliu/Workspace/pcap/" args.append("--pcap " + pcapfile) if self.nanomsg: args.extend(['--nanolog', self.nanomsg]) args.extend(['--device-id', str(self.device_id)]) P4Switch.device_id += 1 if self.json_path: args.append(self.json_path) else: args.append("--no-p4") if self.enable_debugger: args.append("--debugger") if self.log_console: args.append("--log-file " + logfile) args.append("--log-level debug --log-flush") if self.grpc_port: args.append("-- --grpc-server-addr 0.0.0.0:" + str(self.grpc_port)) cmd = ' '.join(args) #print cmd info(cmd + "\n") pid = None with tempfile.NamedTemporaryFile() as f: self.cmd(cmd + ' >' + logfile + ' 2>&1 & echo $! >> ' + f.name) pid = int(f.read()) debug("P4 switch {} PID is {}.\n".format(self.name, pid)) if not self.check_switch_started(pid): error("P4 switch {} did not start correctly.\n".format(self.name)) exit(1) info("P4 switch {} has been started.\n".format(self.name))
def boostKubeCluster(self): # Get cluster infomaiton info("** Bootstrapping Kind Cluster **\n") info("Number of workers %s\nNumber of control-plane %s\n" % (self.numWorker, self.numController)) if self.numController == 0: error("No control plane for kubernetes cluster!") # TODO: enforce certain resource limits configPath = self.generateKindConfig(self.clusterName, self.kubeCluster) debug( self.pexec([ "kind", "create", "cluster", "--name", self.clusterName, "--config", configPath ])) # TODO: need to parse the output of kind to make sure it's created info("**Cluster created successfully!**")
def removeHost( self, name, **params): """ Remove a host from the network at runtime. """ if not isinstance( name, BaseString ) and name is not None: name = name.name # if we get a host object try: h = self.get(name) except: error("Host: %s not found. Cannot remove it.\n" % name) return False if h is not None: if h in self.hosts: self.hosts.remove(h) if name in self.nameToNode: del self.nameToNode[name] h.stop( deleteIntfs=True ) debug("Removed: %s\n" % name) return True return False
def plotGraph(self, wifiNodes=[], srcConn=[], dstConn=[], MAX_X=0, MAX_Y=0): """ Plot Graph """ debug('Enabling Graph...\n') for node in wifiNodes: self.graphInstantiateNodes(node, MAX_X, MAX_Y) node.pltNode.set_data(node.params['position'][0], node.params['position'][1]) self.text(node) self.circle(node) self.graphUpdate(node) for c in range(0, len(srcConn)): line = self.plotLine2d([srcConn[c].params['position'][0], dstConn[c].params['position'][0]], \ [srcConn[c].params['position'][1], dstConn[c].params['position'][1]], 'b') self.plotLine(line)
def load_module(cls, n_radios, alternativeModule=''): """ Load WiFi Module :param n_radios: number of radios :param alternativeModule: dir of a fakelb alternative module""" debug('Loading %s virtual interfaces\n' % n_radios) if not cls.externally_managed: if alternativeModule == '': output_ = os.system('modprobe fakelb numlbs=%s' % n_radios) else: output_ = os.system('insmod %s numlbs=0' % alternativeModule) # Useful for tests in Kernels like Kernel 3.13.x if n_radios == 0: n_radios = 1 if alternativeModule == '': os.system('modprobe fakelb numlbs=%s' % n_radios) else: os.system('insmod %s numlbs=%s' % (alternativeModule, n_radios))
def start(self): """Start <bcnode> <args> on node. Log to /tmp/bc_<name>.log""" if self.server: pathCheck(self.server) cout = '/tmp/bc_' + self.name + '.log' if self.sdir is not None: import os self.cmd('cd ' + self.sdir) sdir = '%s/%s' % (self.sdir, self.IP()) try: os.stat(sdir) except: os.mkdir(sdir) self.sargs += ' -datadir=' + sdir debug(self.server + ' ' + self.sargs + ' 1>' + cout + ' 2>' + cout + ' &') self.cmd(self.server + ' ' + self.sargs + ' 1>' + cout + ' 2>' + cout + ' &') self.execed = False
def plotGraph(cls, nodes, conn): "Plot Graph" debug('Enabling Graph...\n') for node in nodes: x, y = cls.getxy(node) cls.instantiateNodes(node) node.pltNode.set_data(x, y) cls.text(node) cls.circle(node) if 'src' in conn: for c in range(0, len(conn['src'])): ls = conn['ls'][c] src_x = '%.2f' % float(conn['src'][c].params['position'][0]) src_y = '%.2f' % float(conn['src'][c].params['position'][1]) dst_x = '%.2f' % float(conn['dst'][c].params['position'][0]) dst_y = '%.2f' % float(conn['dst'][c].params['position'][1]) line = cls.plotLine2d([float(src_x), float(dst_x)], \ [float(src_y), float(dst_y)], 'b', ls=ls) cls.plotLine(line)
def start(self): # Start capturing traffic with Tshark. Create one logfile for every interface debug("[{0}] Starting tshark logging\n".format(self.node.name)) ip_addresses = [self.node.intfs[intf].ip for intf in self.node.intfs] self.node.cmd("ifconfig &> {}/ifconfig.out".format(self.logFolder)) self.node.cmd("echo {} > {}/ip-adresses.txt".format( ",".join(ip_addresses), self.logFolder)) if self.singleLogFile: interfaces = ["-i " + intf for intf in self.node.intfNames()] ndnDumpOutputFile = "{}{}-interfaces.pcap".format( self.logFolder, self.node.name) self.node.cmd("tshark {} -w {} &> /dev/null &".format( " ".join(interfaces), ndnDumpOutputFile)) else: for intf in self.node.intfNames(): ndnDumpOutputFile = "{}{}.pcap".format(self.logFolder, intf) self.node.cmd("tshark -i {} -w {} &> /dev/null &".format( intf, ndnDumpOutputFile))
def __init__(self, tcpdump_host, tcpdump_filter, funcs=None, vflags='-v', timeout=10, packets=2, root_intf=False, pcap_out=None, intf_name=None, blocking=True): self.intf_name = intf_name if intf_name else tcpdump_host.intf().name self.funcs = funcs if root_intf: self.intf_name = self.intf_name.split('.')[0] tcpdump_flags = vflags tcpdump_flags += ' -Z root' tcpdump_flags += ' -c %u' % packets if packets else '' tcpdump_flags += ' -w %s' % pcap_out if pcap_out else '' tcpdump_cmd = 'tcpdump -i %s %s --immediate-mode -e -n -U %s' % ( self.intf_name, tcpdump_flags, tcpdump_filter) pipe_cmd = tcpdump_cmd if timeout: pipe_cmd = mininet_test_util.timeout_soft_cmd(tcpdump_cmd, timeout) debug(pipe_cmd) self.pipe = tcpdump_host.popen(pipe_cmd, stdin=mininet_test_util.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, shell=False) if self.stream(): debug( f'tcpdump_helper stream fd {self.stream().fileno()} {self.intf_name}' ) self.readbuf = '' self.set_blocking(blocking)
def start(self, controllers): info("Starting P4 switch {}.\n".format(self.name)) args = [self.sw_path] for port, intf in self.intfs.items(): print "P4 Runtime switch Start..." print "port ...", port print "intf ...", intf if not intf.IP(): print "Args extend.. " print "port .. ", str(port) print "interface .. ", str(intf.name) args.extend(['-i', str(port) + "@" + intf.name]) if self.pcap_dump: args.append("--pcap") if self.nanomsg: args.extend(['--nanolog', self.nanomsg]) args.extend(['--device-id', str(self.device_id)]) P4Switch.device_id += 1 if self.json_path: args.append(self.json_path) else: args.append("--no-p4") if self.enable_debugger: args.append("--debugger") if self.log_console: args.append("--log-console") if self.grpc_port: args.append("-- --grpc-server-addr 0.0.0.0:" + str(self.grpc_port)) cmd = ' '.join(args) info(cmd + "\n") logfile = "/tmp/p4s.{}.log".format(self.name) pid = None with tempfile.NamedTemporaryFile() as f: self.cmd(cmd + ' >' + logfile + ' 2>&1 & echo $! >> ' + f.name) pid = int(f.read()) debug("P4 switch {} PID is {}.\n".format(self.name, pid)) if not self.check_switch_started(pid): error("P4 switch {} did not start correctly.\n".format(self.name)) exit(1) info("P4 switch {} has been started.\n".format(self.name))