Revision 55dd9368

View differences:

INSTALL
1 1
Preliminary Mininet Installation/Configuration Notes
2
---
2 3

  
3 4
- Mininet is not currently 'installed.' If you want to install it,
4 5
  so that you can 'import mininet', place it somewhere in your
......
17 18
  does; Ubuntu doesn't. If your kernel doesn't support it, you will need
18 19
  to build and install a kernel that does!
19 20

  
20
- To run the iPerf test, you need to install iperf:
21
- Mininet should probably be run either on a machine with
22
  no other important processes, or on a virtual machine
23
  
24
- To run the iperf test, you need to install iperf:
21 25

  
22 26
    sudo aptitude/yum install iperf
23 27

  
......
30 34
  Consult the appropriate example file for details.
31 35
  
32 36
- To switch to the most recent OpenFlow 0.8.9 release branch (the most
33
  recent one with NOX support):
37
  recent one with full NOX support):
34 38

  
35 39
  git checkout -b release/0.8.9 remotes/origin/release/0.8.9
36 40

  
......
41 45
    insmod /home/openflow/openflow/datapath/linux-2.6/ofdatapath.ko 
42 46
    modprobe tun
43 47

  
44
- The default OpenFlow controller (controller(8)) only supports 16
45
  switches! If you wish to run a network with more than 16 switches,
46
  please recompile controller(8) with larger limits, or use a different
47
  controller such as nox. (At the moment, unfortunately, it's not
48
  easy to do so without modifying mininet.py. This will be improved
48
- The reference OpenFlow controller (controller(8)) only supports 16
49
  switches by default! If you wish to run a network with more than 16
50
  switches, please recompile controller(8) with larger limits, or use a
51
  different controller such as nox. (At the moment, unfortunately, it's
52
  not easy to do so without modifying mininet.py. This will be improved
49 53
  upon, and an example provided, in the future.)
50 54
  
51 55
- For scalable configurations, you might need to increase some of your
......
75 79
    # Mininet: increase routing table size
76 80
    net.ipv4.route.max_size=32768
77 81

  
82
---
78 83

  
79 84

  
README
21 21
In order to run Mininet, you must have:
22 22

  
23 23
* A Linux 2.6.26 or greater kernel compiled with network namespace support
24
  enabled. (Debian 5.0 or greater should work.)
24
  enabled. (Debian 5.0 or greater should work)
25 25

  
26 26
* The OpenFlow reference implementation (either the user or kernel
27 27
  datapath may be used, and the tun or ofdatapath kernel modules must be
28 28
  loaded, respectively)
29 29

  
30
* Python, Bash, Ping, iPerf, etc.
30
* Python, bash, ping, iperf, etc.
31 31

  
32 32
* Root privileges (required for network device access)
33 33

  
34 34
* The netns program (included as netns.c), or an equivalent program
35
  of the same name, installed in an appropriate path location.
35
  of the same name, installed in an appropriate path location
36 36
  
37
* mininet.py installed in an appropriate Python path location.
37
* mininet.py installed in an appropriate Python path location
38 38

  
39 39
Currently mininet includes:
40 40

  
41 41
- A simple node infrastructure (Host, Switch, Controller classes) for
42
  creating virtual OpenFlow networks.
42
  creating virtual OpenFlow networks
43 43
	
44 44
- A simple network infrastructure (class Network and its descendants
45 45
  TreeNet, GridNet and LinearNet) for creating scalable topologies and
......
52 52

  
53 53
- A 'cleanup' script to get rid of junk (interfaces, processes, etc.)
54 54
  which might be left around by mininet. Try this if things stop
55
  working.
55
  working!
56 56
  
57 57
- Examples (in examples/ directory) to help you get started.
58 58

  
cleanup
1 1
#!/bin/bash
2 2

  
3
# Unfortunately, Mininet and OpenFlow don't always clean up
4
# properly after themselves. Until they do (or until cleanup
5
# functionality is integrated into the python code), this
6
# script may be used to get rid of unwanted garbage. It may
7
# also get rid of "false positives", but hopefully nothing
8
# irreplaceable!
9

  
3 10
echo "Removing all links of the pattern foo-ethX"
4 11

  
5 12
for f in `ip link show | egrep -o '(\w+-eth\w+)' ` ; do  
......
14 21
echo "Removing excess kernel datapath processes"
15 22
ps ax | egrep -o 'dp[0-9]+' | sed 's/dp/nl:/' | xargs -l1 echo dpctl deldp 
16 23

  
17
echo "Removing vconn junk in /tmp"
24
echo "Removing junk in /tmp"
18 25
rm -f /tmp/vconn* /tmp/vlogs* /tmp/*.out /tmp/*.log
19 26

  
20 27
echo "Removing old screen sessions"
examples/cli.py
1
#!/usr/bin/python
2

  
3
"Create a tree network and run the CLI on it."
4

  
5
from mininet import init, TreeNet, Cli
6

  
7
if __name__ == '__main__':
8
   init()
9
   network = TreeNet( depth=2, fanout=4, kernel=True )
10
   network.run( Cli )
examples/linearBandwidth.py
1
#!/usr/bin/python
2

  
3
"""
4
Test bandwidth on linear networks of varying size, using both
5
the kernel and user datapaths.
6

  
7
Each network looks like:
8

  
9
h0 <-> s0 <-> s1 .. sN <-> h1
10

  
11
Note: by default, the reference controller only supports 16
12
switches, so this test WILL NOT WORK unless you have recompiled
13
your controller to support a 100 switches (or more.)
14

  
15
"""
16
   
17
from mininet import init, LinearNet, iperfTest
18

  
19
def linearBandwidthTest():
20

  
21
   datapaths = [ 'kernel', 'user' ]
22
   switchCounts = [ 1, 20, 40, 60, 80, 100 ]
23
   results = {}
24

  
25
   for datapath in datapaths:
26
      k = datapath == 'kernel'
27
      results[ datapath ] = []
28
      for switchCount in switchCounts: 
29
         print "*** Creating linear network of size", switchCount
30
         network = LinearNet( switchCount, k)
31
         bandwidth = network.run( iperfTest )
32
         results[ datapath ] += [ ( switchCount, bandwidth ) ]
33
         
34
   for datapath in datapaths:
35
      print
36
      print "*** Linear network results for", datapath, "datapath:"
37
      print
38
      result = results[ datapath ]  
39
      print "SwitchCount\tiPerf results"
40
      for switchCount, bandwidth in result:
41
         print switchCount, '\t\t', 
42
         print bandwidth[ 0 ], 'server, ', bandwidth[ 1 ], 'client'
43
      print
44
   print
45
      
46
if __name__ == '__main__':
47
   init()
48
   print "*** Running linearBandwidthTest"
49
   linearBandwidthTest()
50
   exit( 1 )
51

  
52
   
examples/linearbandwidth.py
1
#!/usr/bin/python
2

  
3
"""
4
Test bandwidth (using iperf) on linear networks of varying size, 
5
using both kernel and user datapaths.
6

  
7
Each network looks like:
8

  
9
h0 <-> s0 <-> s1 .. sN <-> h1
10

  
11
Note: by default, the reference controller only supports 16
12
switches, so this test WILL NOT WORK unless you have recompiled
13
your controller to support a 100 switches (or more.)
14
"""
15
   
16
from mininet import init, LinearNet, iperfTest
17

  
18
def linearBandwidthTest():
19

  
20
   datapaths = [ 'kernel', 'user' ]
21
   switchCounts = [ 1, 20, 40, 60, 80, 100 ]
22
   results = {}
23

  
24
   for datapath in datapaths:
25
      k = datapath == 'kernel'
26
      results[ datapath ] = []
27
      for switchCount in switchCounts: 
28
         print "*** Creating linear network of size", switchCount
29
         network = LinearNet( switchCount, k)
30
         bandwidth = network.run( iperfTest )
31
         results[ datapath ] += [ ( switchCount, bandwidth ) ]
32
         
33
   for datapath in datapaths:
34
      print
35
      print "*** Linear network results for", datapath, "datapath:"
36
      print
37
      result = results[ datapath ]  
38
      print "SwitchCount\tiperf Results"
39
      for switchCount, bandwidth in result:
40
         print switchCount, '\t\t', 
41
         print bandwidth[ 0 ], 'server, ', bandwidth[ 1 ], 'client'
42
      print
43
   print
44
      
45
if __name__ == '__main__':
46
   init()
47
   print "*** Running linearBandwidthTest"
48
   linearBandwidthTest()
49
   exit( 1 )
50

  
51
   
examples/multitest.py
1
#!/usr/bin/python
2

  
3
"Run multiple tests on a network."
4
   
5
from mininet import init, TreeNet, pingTestVerbose, iperfTest, Cli
6

  
7
if __name__ == '__main__':
8
   init()
9
   network = TreeNet( depth=2, fanout=2, kernel=True )
10
   network.start()
11
   network.runTest( pingTestVerbose )
12
   network.runTest( iperfTest)
13
   network.runTest( Cli )
14
   network.stop()
examples/sshd.py
1 1
#!/usr/bin/python
2 2

  
3
"""Create a network and start sshd(8) on the hosts.
4
   While something like rshd(8) would be lighter and faster,
5
   (and perfectly adequate on an in-machine network)
6
   the advantage of running sshd is that scripts can work
7
   unchanged on mininet and hardware."""
3
"""
4
Create a network and start sshd(8) on the hosts.
8 5

  
6
While something like rshd(8) would be lighter and faster,
7
(and perfectly adequate on an in-machine network)
8
the advantage of running sshd is that scripts can work
9
unchanged on mininet and hardware.
10
"""
11

  
12
import sys ; readline = sys.stdin.readline
9 13
from mininet import init, Node, createLink, TreeNet, Cli
10 14

  
11 15
def nets( hosts ):
......
17 21
      nets[ net ] = True
18 22
   return nets.keys()
19 23
   
20
def addRoutes( node, nets, intf ):
21
   "Add routes from node to nets through intf."
22
   for net in nets:
23
      node.cmdPrint( 'route add -net ' + net + ' dev ' + intf )
24

  
25
def removeRoutes( node, nets ):
26
   "Remove routes to nets from node."
27
   for net in nets:
28
      node.cmdPrint( 'route del -net ' + net )
29
   
30
def sshd( network ):
31
   "Start sshd up on each host, routing appropriately."
32
   controllers, switches, hosts = (
33
      network.controllers, network.switches, network.hosts )
34
   # Create a node in root ns and link to switch 0
24
def connectToRootNS( network, switch ):
25
   "Connect hosts to root namespace via switch. Starts network."
26
   # Create a node in root namespace and link to switch 0
35 27
   root = Node( 'root', inNamespace=False )
36
   createLink( root, switches[ 0 ] )
28
   createLink( root, switch )
37 29
   ip = '10.0.123.1'
38 30
   root.setIP( root.intfs[ 0 ], ip, '/24' )
31
   # Start network that now includes link to root namespace
39 32
   network.start()
40 33
   # Add routes
41
   routes = nets( hosts )
42
   addRoutes( root, routes, root.intfs[ 0 ] )
43
   # Start up sshd on each host
44
   for host in hosts: host.cmdPrint( '/usr/sbin/sshd' )
45
   # Dump out IP addresses and run CLI
34
   routes = nets( network.hosts )
35
   intf = root.intfs[ 0 ]
36
   for net in routes:
37
      root.cmdPrint( 'route add -net ' + net + ' dev ' + intf )
38

  
39
def startServers( network, server ):
40
   "Start network, and servers on each host."
41
   connectToRootNS( network, network.switches[ 0 ] )
42
   for host in network.hosts: host.cmdPrint( server )
43

  
44
if __name__ == '__main__':
45
   init()
46
   network = TreeNet( depth=1, fanout=4, kernel=True )
47
   startServers( network, '/usr/sbin/sshd' )
46 48
   print
47 49
   print "*** Hosts are running sshd at the following addresses:"
48
   for host in hosts: print host.name, host.IP()
49 50
   print
50
   print "*** Starting Mininet CLI - type 'exit' or ^D to exit"
51
   network.runTest( Cli )
51
   for host in network.hosts: print host.name, host.IP()
52
   print
53
   print "*** Press return to shut down network: ",
54
   readline()
52 55
   network.stop()
53
   removeRoutes( root, routes )
54
   
55
if __name__ == '__main__':
56
   init()
57
   network = TreeNet( depth=1, fanout=2, kernel=True )
58
   sshd( network )
examples/treeInteract.py
1
#!/usr/bin/python
2

  
3
"Create a tree network and run the CLI on it."
4

  
5
from mininet import init, TreeNet, Cli
6

  
7
if __name__ == '__main__':
8
   init()
9
   network = TreeNet( depth=2, fanout=4, kernel=True )
10
   network.run( Cli )
examples/treePing64.py
1
#!/usr/bin/python
2

  
3
"Create a 64-node tree network, and test connectivity using ping."
4
   
5
from mininet import init, TreeNet, pingTestVerbose
6

  
7
def treePing64():
8
   results = {}
9
   datapaths = [ 'kernel', 'user' ]
10
   
11
   print "*** Testing Mininet with kernel and user datapaths"
12
   
13
   for datapath in datapaths:
14
      k = datapath == 'kernel'
15
      network = TreeNet( depth=2, fanout=8, kernel=k )
16
      result = network.run( pingTestVerbose )
17
      results[ datapath ] = result
18
   
19
   print  
20
   print "*** TreeNet ping results:"
21
   for datapath in datapaths:
22
      print "%s:" % datapath, results[ datapath ]
23
   print
24
   
25
if __name__ == '__main__':
26
   init()
27
   treePing64()
28

  
examples/treenet1024.py
1
#!/usr/bin/python
2

  
3
"""
4
Create a 1024-host network, and run the CLI on it.
5
If this fails because of kernel limits, you may have
6
to adjust them, e.g. by adding entries to /etc/sysctl.conf
7
and running sysctl -p.
8
"""
9
   
10
from mininet import init, TreeNet
11

  
12
if __name__ == '__main__':
13
   init()
14
   network = TreeNet( depth=2, fanout=32, kernel=True )
15
   network.run( Cli )
examples/treeping64.py
1
#!/usr/bin/python
2

  
3
"Create a 64-node tree network, and test connectivity using ping."
4
   
5
from mininet import init, TreeNet, pingTestVerbose
6

  
7
def treePing64():
8
   results = {}
9
   datapaths = [ 'kernel', 'user' ]
10
   
11
   print "*** Testing Mininet with kernel and user datapaths"
12
   
13
   for datapath in datapaths:
14
      k = datapath == 'kernel'
15
      network = TreeNet( depth=2, fanout=8, kernel=k )
16
      result = network.run( pingTestVerbose )
17
      results[ datapath ] = result
18
   
19
   print  
20
   print "*** TreeNet ping results:"
21
   for datapath in datapaths:
22
      print "%s:" % datapath, results[ datapath ]
23
   print
24
   
25
if __name__ == '__main__':
26
   init()
27
   treePing64()
28

  
examples/xterms.py
1 1
#!/usr/bin/python
2 2

  
3 3
"""
4
Create a network and run an xterm (connected via screen(1) ) on each host.
5
Requires xterm(1) and GNU screen(1).
4
Create a network and run an xterm (connected via screen(1) ) on each
5
host. Requires xterm(1) and GNU screen(1).
6 6
"""
7 7

  
8
import os
8
import os, re
9 9
from subprocess import Popen
10 10
from mininet import init, TreeNet, Cli, quietRun
11 11

  
......
13 13
   "Run screen on a node, and hook up an xterm."
14 14
   node.cmdPrint( 'screen -dmS ' + node.name )
15 15
   title += ': ' + node.name
16
   if not node.inNamespace:
17
      title += ' (root namespace)'
16
   if not node.inNamespace: title += ' (root)'
18 17
   cmd = [ 'xterm', '-title', title ]
19 18
   cmd += [ '-e', 'screen', '-D', '-RR', '-S', node.name ]
20 19
   return Popen( cmd )
21 20

  
22 21
def cleanUpScreens():
23 22
   "Remove moldy old screen sessions."      
24
   # XXX We need to implement this - otherwise those darned
25
   # screen sessions will just accumulate
26
   output = quietRun( 'screen -ls' )
27
   pass
23
   r = r'(\d+.[hsc]\d+)'
24
   output = quietRun( 'screen -ls' ).split( '\n' )
25
   for line in output:
26
      m = re.search( r, line )
27
      if m is not None:
28
         quietRun( 'screen -S ' + m.group( 1 ) + ' -X kill' )
28 29
   
29 30
def makeXterms( nodes, title ):
30 31
   terms = []
......
34 35
   return terms
35 36

  
36 37
def xterms( controllers, switches, hosts ):
38
   cleanUpScreens()
37 39
   terms = []
38 40
   terms += makeXterms( controllers, 'controller' )
39 41
   terms += makeXterms( switches, 'switch' )
40 42
   terms += makeXterms( hosts, 'host' )
41 43
   # Wait for xterms to exit
42
   for term in terms:
44
   for term in terms: 
43 45
      os.waitpid( term.pid, 0 )
46
   cleanUpScreens()
44 47
   
45 48
if __name__ == '__main__':
46 49
   init()
47 50
   print "Running xterms on", os.environ[ 'DISPLAY' ]
48
   cleanUpScreens()
49 51
   network = TreeNet( depth=2, fanout=2, kernel=True )
50 52
   network.run( xterms )
51
   cleanUpScreens()
mininet.py
18 18
Hosts have a network interface which is configured via ifconfig/ip
19 19
link/etc. with data network IP addresses (e.g. 192.168.123.2 )
20 20

  
21
This version supports both the kernel or user space datapaths
21
This version supports both the kernel and user space datapaths
22 22
from the OpenFlow reference implementation.
23 23

  
24 24
In kernel datapath mode, the controller and switches are simply
25 25
processes in the root namespace.
26 26

  
27
Kernel OpenFlow datapaths are instantiated using dpctl(8), and are attached
28
to the one side of a veth pair; the other side resides in the host
29
namespace. In this mode, switch processes can simply connect to the
27
Kernel OpenFlow datapaths are instantiated using dpctl(8), and are
28
attached to the one side of a veth pair; the other side resides in the
29
host namespace. In this mode, switch processes can simply connect to the
30 30
controller via the loopback interface.
31 31

  
32 32
In user datapath mode, the controller and switches are full-service
......
35 35
currently routed although it could be bridged.)
36 36

  
37 37
In addition to a management interface, user mode switches also have
38
several switch interfaces, halves of veth pairs whose other halves reside
39
in the host nodes that the switches are connected to.
38
several switch interfaces, halves of veth pairs whose other halves
39
reside in the host nodes that the switches are connected to.
40 40

  
41 41
Naming:
42 42
   Host nodes are named h1-hN
......
61 61

  
62 62
History:
63 63
11/19/09 Initial revision (user datapath only)
64
11/19/09 Mininet demo at OpenFlow SWAI meeting
64 65
12/08/09 Kernel datapath support complete
65 66
12/09/09 Moved controller and switch routines into classes
66 67
12/12/09 Added subdivided network driver workflow
......
788 789

  
789 790
def init():
790 791
   "Initialize Mininet."
791
   # Note: this script must be run as root 
792
   # Perhaps we should do so automatically!
793 792
   if os.getuid() != 0: 
793
      # Note: this script must be run as root 
794
      # Perhaps we should do so automatically!
794 795
      print "*** Mininet must run as root."; exit( 1 )
795 796
   fixLimits()
796 797

  
797 798
if __name__ == '__main__':
798 799
   init()
799 800
   results = {}
800
   exit( 1 )
801
   print "*** Welcome to Mininet!"
802
   print "*** Look in examples/ for more examples\n"
801 803
   print "*** Testing Mininet with kernel and user datapath"
802 804
   for datapath in [ 'kernel', 'user' ]:
803 805
      k = datapath == 'kernel'
804
      # results += [ TreeNet( depth=2, fanout=2, kernel=k ).
805
      #   run( pingTestVerbose ) ]
806
      results[ datapath ] = []
807
      for switchCount in range( 1, 4 ):
808
         results[ datapath ]  += [ ( switchCount,
809
            LinearNet( switchCount, k).run( iperfTest ) ) ]
810
      # GridNet( 2, 2 ).run( Cli )
811
   print "*** Test results:", results
806
      network = TreeNet( depth=2, fanout=4, kernel=k)
807
      result = network.run( pingTestVerbose )
808
      results[ datapath ] = result
809
   print "*** Test results:", results

Also available in: Unified diff