#!/usr/bin/python """ ############################################################################## # Topology with one router and two hosts with static routes # # 172.16.101.0/24 172.16.102.0/24 # h1 ------------------- r1 ------------------ h2 # .1 .2 .3 .1 # ############################################################################## Here r1 acts as a Linux router. There are two veth-pairs in our topology as following. h1-eth0-------r1-eth2 r1-eth3-----h2eth0 Packets received on r1-eth2 is being transmitted to r1-eth3 using XDP fast path. Packets are generated on h1 towards h2 using iperf. """ from mininet.topo import Topo from mininet.net import Mininet from mininet.link import TCLink from mininet.node import Node, CPULimitedHost from mininet.log import setLogLevel, info from mininet.util import custom, waitListening from mininet.cli import CLI import sys import time class LinuxRouter( Node ): "A Node with IP forwarding enabled." def config( self, **params ): super( LinuxRouter, self).config( **params ) # Enable forwarding on the router self.cmd( 'sysctl net.ipv4.ip_forward=1' ) def terminate( self ): self.cmd( 'sysctl net.ipv4.ip_forward=0' ) super( LinuxRouter, self ).terminate() class NetworkTopo( Topo ): def build( self, **_opts ): h1 = self.addHost( 'h1', ip='172.16.101.1/24', defaultRoute='via 172.16.101.2' ) h2 = self.addHost( 'h2', ip='172.16.102.1/24', defaultRoute='via 172.16.102.3' ) r1 = self.addNode( 'r1', cls=LinuxRouter, ip='172.16.101.2/24' ) self.addLink( h1, r1, intfName2='r1-eth2', params2={ 'ip' : '172.16.101.2/24' }) self.addLink( h2, r1, intfName2='r1-eth3', params2={ 'ip' : '172.16.102.3/24' }) def main(cli=0): "Test linux router" topo = NetworkTopo() net = Mininet( topo=topo, controller = None ) net.start() # testing using port 45678, TCP window size 20MB and 10 connection. res = net['h2'].cmd('iperf -s -p 45678 -w 20MB &') #Anyhing that blocks shouldn't be used in cmd(). Use popen() instead. It will create a new process. Now monitor the output of the process proc = net['h1'].popen('iperf -c 172.16.102.1 -p 45678 -t 30 -w 20MB -P 10') # print res #Don't uncomment this. Strange things happen :-( #Parse the res to find out the PID of iperf server. The program can crash if res isn't formatted properly. Try again pid = res.split(" ") iperf_s_pid = pid[1] iperf_c_pid = int(pid[1]) + 1 print pid[1], int(pid[1]) + 1 #Pin iperf server and client to core 0 and 1 respectively. Note that throughput you get depends on other applications running on a CPU. So if you get bad throughput, try restatring. Even though you close some applications, the process can sit in the backgroud net['h2'].cmd('sudo taskset -pc 0 {0}'.format(iperf_s_pid)) net['h1'].cmd('sudo taskset -pc 1 {0}'.format(iperf_c_pid)) for line in iter(proc.stdout.readline, b''): print line net['h2'].cmd('sudo kill -9 {0}'.format(iperf_s_pid)) net['h1'].cmd('sudo kill -9 {0}'.format(iperf_c_pid)) CLI( net ) net.stop() if __name__ == '__main__': args = sys.argv setLogLevel( 'info' ) main()