Merge branch 'of1.0' into testing
Conflicts: bin/mn mininet/cli.py mininet/moduledeps.py mininet/node.py mininet/topo.py util/install.sh
This commit is contained in:
@@ -1,31 +1,71 @@
|
|||||||
|
|
||||||
Preliminary Mininet Installation/Configuration Notes
|
Preliminary Mininet Installation/Configuration Notes
|
||||||
|
|
||||||
Alpha release, March 2010
|
Pre-Beta version, August 2010
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
(Disclaimer: this is an early alpha release; things may be broken!)
|
(Disclaimer: we're still pre-beta - things may be broken!)
|
||||||
|
|
||||||
The easiest way to get Mininet running is to start with one of our pre-built virtual machine images from:
|
The supported installation methods for Mininet Pre-Beta are 1) using
|
||||||
|
a pre-built VM image, and 2) native installation on Ubuntu or Debian.
|
||||||
|
(Other distributions may be supported in the future - if you would
|
||||||
|
like to contribute an installation script, we would welcome it!)
|
||||||
|
|
||||||
http://www.openflowswitch.org/foswiki/bin/view/OpenFlow/MininetGettingStarted
|
1. Easiest "install" - use our pre-built VM image!
|
||||||
|
|
||||||
Once you have booted up the VM image, all you need to do to install
|
The easiest way to get Mininet running is to start with one of our pre-built
|
||||||
Mininet into it is:
|
virtual machine images from:
|
||||||
|
|
||||||
git clone git://yuba.stanford.edu/mininet.git
|
http://openflow.org/foswiki/bin/view/OpenFlow/MininetGettingStarted
|
||||||
cd mininet
|
|
||||||
sudo make install
|
|
||||||
|
|
||||||
At this point, it should be possible to run a simple Mininet configuration
|
Boot up the VM image, log in, and follow the instructions on the wiki page.
|
||||||
from the command line:
|
|
||||||
|
|
||||||
sudo mn
|
An additional advantage of using the VM image is that it doesn't mess with
|
||||||
|
your native OS install or damage it in any way.
|
||||||
|
|
||||||
As an alternative, if you are Linux-savvy, do not wish to use the VM
|
2. Native installation for Ubuntu and Debian 5 (NEW for pre-beta!)
|
||||||
image, and wish to take on the challenge of installing Mininet and its
|
|
||||||
dependencies from scratch, the requirements are described below.
|
If you are running Ubuntu or Debian 5, you may be able to use our handy
|
||||||
|
install.sh script, which is in mininet/util.
|
||||||
|
|
||||||
|
WARNING: install.sh is a bit intrusive and may possibly damage your OS
|
||||||
|
and/or home directory. Although we hope it won't do anything completely
|
||||||
|
terrible, you may want to look at the script before you run it, and you
|
||||||
|
should make sure your system and home directory are backed up just in case!
|
||||||
|
|
||||||
|
To install ALL of the software which we use for OpenFlow tutorials, you may
|
||||||
|
use
|
||||||
|
|
||||||
|
$ mininet/util/install.sh
|
||||||
|
|
||||||
|
This takes about 20-30 minutes.
|
||||||
|
|
||||||
|
Alternately, you can install just the pieces you need.
|
||||||
|
|
||||||
|
We recommend the following steps, in order:
|
||||||
|
|
||||||
|
a) On Debian 5, first install a Mininet-compatible kernel:
|
||||||
|
$ mininet/util/install.sh -k
|
||||||
|
Reboot and run 'uname -r' to make sure you're running the new kernel.
|
||||||
|
|
||||||
|
b) Install mininet and its dependencies:
|
||||||
|
$ mininet/util/install.sh -n
|
||||||
|
|
||||||
|
c) Install OpenFlow 1.0 and associated useful software
|
||||||
|
$ mininet/util/install.sh -f
|
||||||
|
|
||||||
|
d) Install Open vSwitch and its kernel module
|
||||||
|
$ mininet/util/install.sh -vm
|
||||||
|
|
||||||
|
e) If you wish to install the version of NOX we use in the tutorial:
|
||||||
|
$ mininet/util/install.sh -x
|
||||||
|
|
||||||
|
Good luck! Some additional installation notes are provided below, for
|
||||||
|
the brave and/or Linux-savvy, or those who are trying to understand what
|
||||||
|
is installed and why.
|
||||||
|
|
||||||
|
p.s. Note that only one instance of Mininet is currently supported on a single
|
||||||
|
machine - that's one reason we recommend using a VM to run it.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -36,47 +76,94 @@ compile kernels, apply patches, configure networks, write code, etc.. If
|
|||||||
this is unfamiliar territory, or if you run into trouble, we recommend
|
this is unfamiliar territory, or if you run into trouble, we recommend
|
||||||
using one of our pre-built virtual machine images (see above.)
|
using one of our pre-built virtual machine images (see above.)
|
||||||
|
|
||||||
|
If you wish to try to create a VM to run Mininet, you may also wish
|
||||||
|
to look at the Wiki page:
|
||||||
|
|
||||||
|
http://openflow.org/foswiki/bin/view/OpenFlow/MininetVMCreationNotes
|
||||||
|
|
||||||
|
0. Obtaining Mininet
|
||||||
|
|
||||||
|
If you're reading this, you've already done it, but the command to
|
||||||
|
download mininet is:
|
||||||
|
|
||||||
|
git clone git://openflow.org/mininet.git
|
||||||
|
|
||||||
1. Core Mininet installation
|
1. Core Mininet installation
|
||||||
|
|
||||||
The core Mininet installation requires gcc, make, python,
|
The core Mininet installation requires gcc, make, python,
|
||||||
and setuptools.
|
and setuptools. On Ubuntu and Debian you may install them with:
|
||||||
|
|
||||||
|
# aptitude install gcc make python setuptools
|
||||||
|
|
||||||
To install Mininet itself, with root privileges:
|
To install Mininet itself, with root privileges:
|
||||||
|
|
||||||
|
# cd mininet
|
||||||
# make install
|
# make install
|
||||||
|
|
||||||
This places the mininet package in /usr/lib/python-2.5/site-packages/,
|
This places the mininet package in /usr/lib/python-*/site-packages/,
|
||||||
so that 'import mininet' will work, and installs the primary mn
|
so that 'import mininet' will work, and installs the primary mn
|
||||||
script (mn) as well as its helper utility (mnexec.)
|
script (mn) as well as its helper utility (mnexec.)
|
||||||
|
|
||||||
2. Script-based kernel and OpenFlow installation for Debian
|
On Ubuntu and Debian, Mininet's dependencies and core files may also be
|
||||||
|
installed using mininet/util/install.sh -n
|
||||||
|
|
||||||
If you are running debian-stable, you may be able to use the
|
2. Installation script for Ubuntu/Debian Lenny
|
||||||
|
|
||||||
|
If you are running Ubuntu 10.04 or Debian Lenny, you may be able to use the
|
||||||
util/install.sh script to install a compatible Linux kernel as well as
|
util/install.sh script to install a compatible Linux kernel as well as
|
||||||
other software including the OpenFlow reference implementation, the Open
|
other software including the OpenFlow reference implementation, the Open
|
||||||
vSwitch switch implementation, and the NOX OpenFlow controller. Assuming
|
vSwitch switch implementation, and the NOX OpenFlow controller.
|
||||||
the mininet source tree is installed in ~/mininet, the steps to run
|
|
||||||
install.sh are as follows:
|
Many different installation options are possible by passing different
|
||||||
|
options to install.sh; install.sh -h lists them all.
|
||||||
|
|
||||||
|
Assuming the mininet source tree is installed in ~/mininet, the steps to run
|
||||||
|
install.sh to install EVERYTHING we use for OpenFlow tutorials are:
|
||||||
|
|
||||||
% cd
|
% cd
|
||||||
% time ~/mininet/util/install.sh
|
% time ~/mininet/util/install.sh # installs tons of stuff
|
||||||
% sudo reboot # to load new kernel
|
% sudo reboot # to load new kernel
|
||||||
% ~/mininet/util/install.sh -c # to clean out unneeded kernel stuff
|
% ~/mininet/util/install.sh -c # to clean out unneeded kernel stuff
|
||||||
|
|
||||||
If install.sh cannot be used for some reason, the kernel and
|
This installs a lot of useful software, but it will take a while (30
|
||||||
OpenFlow software requirements are descibed in steps [3] and [4],
|
minutes or more, depending on your network connection, computer, etc..)
|
||||||
|
|
||||||
|
Probably the minimal semi-useful configuration would be to install
|
||||||
|
Mininet itself, kernel support if necessary, and either the
|
||||||
|
reference OpenFlow switch or Open vSwitch. This could be installed
|
||||||
|
as follows:
|
||||||
|
|
||||||
|
% sudo ~/mininet/util/install.sh -knvm
|
||||||
|
|
||||||
|
Respectively, this installs kernel support, core mininet dependencies,
|
||||||
|
Open vSwitch, and the Open vSwitch kernel module. If a new kernel was
|
||||||
|
installed, then a reboot may be required.
|
||||||
|
|
||||||
|
If install.sh cannot be used for some reason (e.g. you're on Fedora
|
||||||
|
or some other Linux - please don't say CentOS) or if you don't want to
|
||||||
|
install all of these components (they're useful!), the kernel and
|
||||||
|
OpenFlow software requirements are described in steps [3] and [4],
|
||||||
which follow.
|
which follow.
|
||||||
|
|
||||||
If you successfully used install.sh, proceed to step [5].
|
If you successfully used install.sh, congratulations! You're basically
|
||||||
|
done. Proceed to step [6] for additional advice.
|
||||||
|
|
||||||
3. Linux Kernel requirements
|
3. Linux Kernel requirements
|
||||||
|
|
||||||
Mininet requires a kernel built with network namespace support enabled,
|
Mininet requires a kernel built with network namespace support enabled,
|
||||||
i.e. with CONFIG_NET_NS=Y
|
i.e. with CONFIG_NET_NS=Y, such as the kernel shipped with
|
||||||
|
Ubuntu 10.04 LTS, currently 2.6.32. On Ubuntu 10.04, you should not need
|
||||||
|
to install or build a custom kernel, although 2.6.33+ is faster at
|
||||||
|
tearing down virtual ethernet pairs.
|
||||||
|
|
||||||
If your kernel doesn't support it, you will need to build and install a
|
For Ubuntu and Debian, we provide a 2.6.33 kernel package which you may be
|
||||||
kernel that does! >= 2.6.33 works better, but may be harder to get
|
able to install using "util/install.sh -k". Note our kernel package
|
||||||
working, depending on your Linux distribution.
|
requires an ext2 or ext3 root file system, so it won't work if you have
|
||||||
|
a default Ubuntu install, which uses ext4.
|
||||||
|
|
||||||
|
If your kernel wasn't compiled with CONFIG_NET_NS=Y, you will need to
|
||||||
|
build and install a kernel that does! >= 2.6.33 works better, but may
|
||||||
|
be harder to get working, depending on your Linux distribution.
|
||||||
|
|
||||||
A script for building Debian packages for 2.6.33.1 is provided in
|
A script for building Debian packages for 2.6.33.1 is provided in
|
||||||
mininet/util/kbuild. You may wish to read it, as it applies patches
|
mininet/util/kbuild. You may wish to read it, as it applies patches
|
||||||
@@ -102,23 +189,19 @@ using one of our pre-built virtual machine images (see above.)
|
|||||||
|
|
||||||
Mininet requires either the reference OpenFlow switch implementation
|
Mininet requires either the reference OpenFlow switch implementation
|
||||||
(from openflowswitch.org) or Open vSwitch (openvswitch.org) to be
|
(from openflowswitch.org) or Open vSwitch (openvswitch.org) to be
|
||||||
installed. "make test" requires the reference user and kernel space
|
installed. "make test" requires the reference user space
|
||||||
implementations as well as Open vSwitch. Note the kernel implementation
|
implementations as well as Open vSwitch. Note the reference kernel
|
||||||
is not currently included in OpenFlow 1.0.
|
implementation is not currently included in OpenFlow 1.0.
|
||||||
|
|
||||||
To switch to the most recent OpenFlow 0.8.9 release branch (the most
|
On Ubuntu and Debian, the install.sh script may be used with the '-f'
|
||||||
recent one with full NOX support and kernel datapath support) in your
|
option to install the OpenFlow reference implementation, the '-v' option
|
||||||
OpenFlow git tree:
|
to build Open vSwitch, and the '-m' option to install the Open vSwitch
|
||||||
|
kernel module into /lib/modules (note: you must build Open vSwitch first!)
|
||||||
git checkout -b release/0.8.9 remotes/origin/release/0.8.9
|
|
||||||
|
|
||||||
A patch to enable datapath.c to compile with recent kernels
|
|
||||||
is included in util/openflow-patches/datapath.patch.
|
|
||||||
|
|
||||||
Mininet will automatically load and remove kernel module dependencies
|
Mininet will automatically load and remove kernel module dependencies
|
||||||
for supported switch types, using modprobe and rmmod - but these
|
for supported switch types, using modprobe and rmmod - but these
|
||||||
modules must be in a location where modprobe can find them (i.e.
|
modules must be in a location where modprobe can find them (e.g.
|
||||||
/lib/modules/...)
|
something like /lib/modules/`uname -r`/kernel/drivers/net/)
|
||||||
|
|
||||||
The reference OpenFlow controller (controller(8)) only supports 16
|
The reference OpenFlow controller (controller(8)) only supports 16
|
||||||
switches by default! If you wish to run a network with more than 16
|
switches by default! If you wish to run a network with more than 16
|
||||||
@@ -128,6 +211,9 @@ using one of our pre-built virtual machine images (see above.)
|
|||||||
|
|
||||||
5. Other software dependencies
|
5. Other software dependencies
|
||||||
|
|
||||||
|
On Ubuntu and Debian, other Mininet dependencies may be installed using
|
||||||
|
the '-n' option of the install.sh script.
|
||||||
|
|
||||||
To run the iperf test, you need to install iperf:
|
To run the iperf test, you need to install iperf:
|
||||||
|
|
||||||
sudo aptitude/yum install iperf
|
sudo aptitude/yum install iperf
|
||||||
@@ -141,8 +227,14 @@ using one of our pre-built virtual machine images (see above.)
|
|||||||
Some examples may have additional requirements - consult the specific
|
Some examples may have additional requirements - consult the specific
|
||||||
example file for details.
|
example file for details.
|
||||||
|
|
||||||
|
The install.sh script has an '-x' option to install the version of
|
||||||
|
NOX from the OpenFlow tutorial.
|
||||||
|
|
||||||
6. Other notes and recommendations
|
6. Other notes and recommendations
|
||||||
|
|
||||||
|
If you did not install certain useful packages and you wish to later,
|
||||||
|
it may be possible to install them using install.sh.
|
||||||
|
|
||||||
Mininet should be run either on a machine with
|
Mininet should be run either on a machine with
|
||||||
no other important processes, or on a virtual machine (recommended!)
|
no other important processes, or on a virtual machine (recommended!)
|
||||||
|
|
||||||
@@ -151,3 +243,26 @@ using one of our pre-built virtual machine images (see above.)
|
|||||||
Good luck!
|
Good luck!
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Historical information on OpenFlow 0.8.9 and the reference kernel module:
|
||||||
|
|
||||||
|
The kernel reference implementation has been deprecated, but it may
|
||||||
|
be possible to get it work with Mininet.
|
||||||
|
|
||||||
|
To switch to the most recent OpenFlow 0.8.9 release branch (the most
|
||||||
|
recent one with full NOX support and kernel datapath support) in your
|
||||||
|
OpenFlow git tree:
|
||||||
|
|
||||||
|
git checkout -b release/0.8.9 remotes/origin/release/0.8.9
|
||||||
|
|
||||||
|
A patch to enable datapath.c to compile with recent kernels
|
||||||
|
is included in util/openflow-patches/datapath.patch.
|
||||||
|
|
||||||
|
In OpenFlow 1.0, switch port numbering starts at 1 (for better or for worse.)
|
||||||
|
To run with previous versions of OpenFlow, it may be necessary
|
||||||
|
to change SWITCH_PORT_BASE from 1 to 0 in node.py.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ TESTS = [ 'cli', 'build', 'pingall', 'pingpair', 'iperf', 'all', 'iperfudp',
|
|||||||
'none' ]
|
'none' ]
|
||||||
|
|
||||||
ALTSPELLING = { 'pingall': 'pingAll', 'pingpair': 'pingPair',
|
ALTSPELLING = { 'pingall': 'pingAll', 'pingpair': 'pingPair',
|
||||||
'iperfudp': 'iperfUdp', 'iperfUDP': 'iperfUdp' }
|
'iperfudp': 'iperfUdp', 'iperfUDP': 'iperfUdp', 'prefixlen': 'prefixLen' }
|
||||||
|
|
||||||
def buildTopo( topo ):
|
def buildTopo( topo ):
|
||||||
"Create topology from string with format (object, arg1, arg2,...)."
|
"Create topology from string with format (object, arg1, arg2,...)."
|
||||||
@@ -176,11 +176,25 @@ class MininetRunner( object ):
|
|||||||
' controller]' )
|
' controller]' )
|
||||||
opts.add_option( '--innamespace', action='store_true',
|
opts.add_option( '--innamespace', action='store_true',
|
||||||
default=False, help='sw and ctrl in namespace?' )
|
default=False, help='sw and ctrl in namespace?' )
|
||||||
|
<<<<<<< HEAD:bin/mn
|
||||||
|
=======
|
||||||
|
opts.add_option( '--listenport', type='int', default=6634,
|
||||||
|
help='[base port for passive switch listening'
|
||||||
|
' controller]' )
|
||||||
|
opts.add_option( '--nolistenport', action='store_true',
|
||||||
|
default=False, help="don't use passive listening port")
|
||||||
|
>>>>>>> of1.0:bin/mn
|
||||||
opts.add_option( '--pre', type='string', default=None,
|
opts.add_option( '--pre', type='string', default=None,
|
||||||
help='[CLI script to run before tests]' )
|
help='[CLI script to run before tests]' )
|
||||||
opts.add_option( '--post', type='string', default=None,
|
opts.add_option( '--post', type='string', default=None,
|
||||||
help='[CLI script to run after tests]' )
|
help='[CLI script to run after tests]' )
|
||||||
|
<<<<<<< HEAD:bin/mn
|
||||||
|
|
||||||
|
=======
|
||||||
|
opts.add_option( '--prefixlen', type='int', default=8,
|
||||||
|
help='[prefix length (e.g. /8) for automatic '
|
||||||
|
'network configuration]' )
|
||||||
|
>>>>>>> of1.0:bin/mn
|
||||||
self.options, self.args = opts.parse_args()
|
self.options, self.args = opts.parse_args()
|
||||||
|
|
||||||
def setup( self ):
|
def setup( self ):
|
||||||
@@ -217,15 +231,31 @@ class MininetRunner( object ):
|
|||||||
if self.validate:
|
if self.validate:
|
||||||
self.validate( self.options )
|
self.validate( self.options )
|
||||||
|
|
||||||
|
<<<<<<< HEAD:bin/mn
|
||||||
controllerParams = ControllerParams( '10.0.0.0', 8 )
|
controllerParams = ControllerParams( '10.0.0.0', 8 )
|
||||||
|
=======
|
||||||
|
# We should clarify what this is actually for...
|
||||||
|
# It seems like it should be default values for the
|
||||||
|
# *data* network, so it may be misnamed.
|
||||||
|
controllerParams = ControllerParams( '10.0.0.0',
|
||||||
|
self.options.prefixlen)
|
||||||
|
|
||||||
|
>>>>>>> of1.0:bin/mn
|
||||||
inNamespace = self.options.innamespace
|
inNamespace = self.options.innamespace
|
||||||
xterms = self.options.xterms
|
xterms = self.options.xterms
|
||||||
mac = self.options.mac
|
mac = self.options.mac
|
||||||
arp = self.options.arp
|
arp = self.options.arp
|
||||||
|
listenPort = None
|
||||||
|
if not self.options.nolistenport:
|
||||||
|
listenPort = self.options.listenport
|
||||||
mn = Mininet( topo, switch, host, controller, controllerParams,
|
mn = Mininet( topo, switch, host, controller, controllerParams,
|
||||||
inNamespace=inNamespace,
|
inNamespace=inNamespace,
|
||||||
xterms=xterms, autoSetMacs=mac,
|
xterms=xterms, autoSetMacs=mac,
|
||||||
|
<<<<<<< HEAD:bin/mn
|
||||||
autoStaticArp=arp )
|
autoStaticArp=arp )
|
||||||
|
=======
|
||||||
|
autoStaticArp=arp, listenPort=listenPort )
|
||||||
|
>>>>>>> of1.0:bin/mn
|
||||||
if self.options.pre:
|
if self.options.pre:
|
||||||
CLI( mn, script=self.options.pre )
|
CLI( mn, script=self.options.pre )
|
||||||
|
|
||||||
|
|||||||
Executable
+26
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"This example doesn't use OpenFlow, but attempts to run sshd in a namespace."
|
||||||
|
|
||||||
|
from mininet.node import Host
|
||||||
|
|
||||||
|
print "*** Creating nodes"
|
||||||
|
h1 = Host( 'h1' )
|
||||||
|
root = Host( 'root', inNamespace=False )
|
||||||
|
|
||||||
|
print "*** Creating links"
|
||||||
|
h1.linkTo( root )
|
||||||
|
|
||||||
|
print "*** Configuring nodes"
|
||||||
|
h1.setIP( h1.intfs[ 0 ], '10.0.0.1', 8 )
|
||||||
|
root.setIP( root.intfs[ 0 ], '10.0.0.2', 8 )
|
||||||
|
|
||||||
|
print "*** Creating banner file"
|
||||||
|
f = open( '/tmp/%s.banner' % h1.name, 'w' )
|
||||||
|
f.write( 'Welcome to %s at %s\n' % ( h1.name, h1.IP() ) )
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
print "*** Running sshd"
|
||||||
|
h1.cmd( '/usr/sbin/sshd -o "Banner /tmp/%s.banner"' % h1.name )
|
||||||
|
|
||||||
|
print "*** You may now ssh into", h1.name, "at", h1.IP()
|
||||||
@@ -448,8 +448,7 @@ class ConsoleApp( Frame ):
|
|||||||
|
|
||||||
def assign( obj, **kwargs ):
|
def assign( obj, **kwargs ):
|
||||||
"Set a bunch of fields in an object."
|
"Set a bunch of fields in an object."
|
||||||
for name, value in kwargs.items():
|
obj.__dict__.update( kwargs )
|
||||||
setattr( obj, name, value )
|
|
||||||
|
|
||||||
class Object( object ):
|
class Object( object ):
|
||||||
"Generic object you can stuff junk into."
|
"Generic object you can stuff junk into."
|
||||||
|
|||||||
Executable
+64
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""
|
||||||
|
This example creates a multi-controller network from
|
||||||
|
semi-scratch; note a topo object could also be used and
|
||||||
|
would be passed into the Mininet() constructor.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from mininet.net import Mininet
|
||||||
|
from mininet.node import Controller, OVSKernelSwitch
|
||||||
|
from mininet.cli import CLI
|
||||||
|
from mininet.log import setLogLevel
|
||||||
|
|
||||||
|
Switch = OVSKernelSwitch
|
||||||
|
|
||||||
|
def addHost( net, N ):
|
||||||
|
"Create host hN and add to net."
|
||||||
|
name = 'h%d' % N
|
||||||
|
ip = '10.0.0.%d' % N
|
||||||
|
return net.addHost( name, ip=ip )
|
||||||
|
|
||||||
|
def multiControllerNet():
|
||||||
|
"Create a network with multiple controllers."
|
||||||
|
|
||||||
|
net = Mininet( controller=Controller, switch=Switch)
|
||||||
|
|
||||||
|
print "*** Creating controllers"
|
||||||
|
c1 = net.addController( 'c1', port=6633 )
|
||||||
|
c2 = net.addController( 'c2', port=6634 )
|
||||||
|
|
||||||
|
print "*** Creating switches"
|
||||||
|
s1 = net.addSwitch( 's1' )
|
||||||
|
s2 = net.addSwitch( 's2' )
|
||||||
|
|
||||||
|
print "*** Creating hosts"
|
||||||
|
hosts1 = [ addHost( net, n ) for n in 3, 4 ]
|
||||||
|
hosts2 = [ addHost( net, n ) for n in 5, 6 ]
|
||||||
|
|
||||||
|
print "*** Creating links"
|
||||||
|
for h in hosts1:
|
||||||
|
s1.linkTo( h )
|
||||||
|
for h in hosts2:
|
||||||
|
s2.linkTo( h )
|
||||||
|
s1.linkTo( s2 )
|
||||||
|
|
||||||
|
print "*** Starting network"
|
||||||
|
net.build()
|
||||||
|
c1.start()
|
||||||
|
c2.start()
|
||||||
|
s1.start( [ c1 ] )
|
||||||
|
s2.start( [ c2 ] )
|
||||||
|
|
||||||
|
print "*** Testing network"
|
||||||
|
net.pingAll()
|
||||||
|
|
||||||
|
print "*** Running CLI"
|
||||||
|
CLI( net )
|
||||||
|
|
||||||
|
print "*** Stopping network"
|
||||||
|
net.stop()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
setLogLevel( 'info' ) # for CLI output
|
||||||
|
multiControllerNet()
|
||||||
+16
-1
@@ -272,6 +272,20 @@ class CLI( Cmd ):
|
|||||||
error( 'error reading file %s\n' % args[ 0 ] )
|
error( 'error reading file %s\n' % args[ 0 ] )
|
||||||
self.inputFile = None
|
self.inputFile = None
|
||||||
|
|
||||||
|
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 default( self, line ):
|
def default( self, line ):
|
||||||
"""Called on an input line when the command prefix is not recognized.
|
"""Called on an input line when the command prefix is not recognized.
|
||||||
Overridden to run shell commands when a node is the first CLI argument.
|
Overridden to run shell commands when a node is the first CLI argument.
|
||||||
@@ -314,7 +328,8 @@ class CLI( Cmd ):
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
bothPoller.poll()
|
bothPoller.poll()
|
||||||
if self.inputFile:
|
# XXX BL: this doesn't quite do what we want.
|
||||||
|
if False and self.inputFile:
|
||||||
key = self.inputFile.read( 1 )
|
key = self.inputFile.read( 1 )
|
||||||
if key is not '':
|
if key is not '':
|
||||||
node.write(key)
|
node.write(key)
|
||||||
|
|||||||
+11
-9
@@ -37,7 +37,7 @@ def moduleDeps( subtract=None, add=None ):
|
|||||||
info( '*** Removing ' + mod + '\n' )
|
info( '*** Removing ' + mod + '\n' )
|
||||||
rmmodOutput = rmmod( mod )
|
rmmodOutput = rmmod( mod )
|
||||||
if rmmodOutput:
|
if rmmodOutput:
|
||||||
error( 'Error removing ' + mod + '\n%s' % rmmodOutput )
|
error( 'Error removing ' + mod + ': "%s">\n' % rmmodOutput )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
if mod in lsmod():
|
if mod in lsmod():
|
||||||
error( 'Failed to remove ' + mod + '; still there!\n' )
|
error( 'Failed to remove ' + mod + '; still there!\n' )
|
||||||
@@ -47,20 +47,22 @@ def moduleDeps( subtract=None, add=None ):
|
|||||||
info( '*** Loading ' + mod + '\n' )
|
info( '*** Loading ' + mod + '\n' )
|
||||||
modprobeOutput = modprobe( mod )
|
modprobeOutput = modprobe( mod )
|
||||||
if modprobeOutput:
|
if modprobeOutput:
|
||||||
error( 'Error inserting ' + mod + ';\n See INSTALL.\n%s' %
|
error( 'Error inserting ' + mod +
|
||||||
modprobeOutput )
|
' - is it installed and available via modprobe?\n' +
|
||||||
exit( 1 )
|
'Error was: "%s"\n' % modprobeOutput )
|
||||||
if mod not in lsmod():
|
if mod not in lsmod():
|
||||||
error( 'Failed to insert ' + mod + '\n' )
|
error( 'Failed to insert ' + mod + ' - quitting.\n' )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
else:
|
else:
|
||||||
debug( '*** ' + mod + ' already loaded\n' )
|
debug( '*** ' + mod + ' already loaded\n' )
|
||||||
|
|
||||||
def pathCheck( *args ):
|
|
||||||
|
def pathCheck( *args, **kwargs ):
|
||||||
"Make sure each program in *args can be found in $PATH."
|
"Make sure each program in *args can be found in $PATH."
|
||||||
|
moduleName = kwargs.get( 'moduleName', 'it' )
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if not quietRun( 'which ' + arg ):
|
if not quietRun( 'which ' + arg ):
|
||||||
error( 'Cannot find required executable %s -'
|
error( 'Cannot find required executable %s.\n' % arg +
|
||||||
' is it installed somewhere in your $PATH?\n(%s)\n' %
|
'Please make sure that %s is installed ' % moduleName +
|
||||||
( arg, environ[ 'PATH' ] ) )
|
'and available in your $PATH:\n(%s)\n' % environ[ 'PATH' ] )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
|
|||||||
+20
-10
@@ -94,7 +94,7 @@ from time import sleep
|
|||||||
|
|
||||||
from mininet.cli import CLI
|
from mininet.cli import CLI
|
||||||
from mininet.log import info, error, debug, output
|
from mininet.log import info, error, debug, output
|
||||||
from mininet.node import Host, UserSwitch, KernelSwitch, Controller
|
from mininet.node import Host, UserSwitch, OVSKernelSwitch, Controller
|
||||||
from mininet.node import ControllerParams
|
from mininet.node import ControllerParams
|
||||||
from mininet.util import quietRun, fixLimits
|
from mininet.util import quietRun, fixLimits
|
||||||
from mininet.util import createLink, macColonHex, ipStr, ipParse
|
from mininet.util import createLink, macColonHex, ipStr, ipParse
|
||||||
@@ -103,12 +103,12 @@ from mininet.term import cleanUpScreens, makeTerms
|
|||||||
class Mininet( object ):
|
class Mininet( object ):
|
||||||
"Network emulation with hosts spawned in network namespaces."
|
"Network emulation with hosts spawned in network namespaces."
|
||||||
|
|
||||||
def __init__( self, topo=None, switch=KernelSwitch, host=Host,
|
def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
|
||||||
controller=Controller,
|
controller=Controller,
|
||||||
cparams=ControllerParams( '10.0.0.0', 8 ),
|
cparams=ControllerParams( '10.0.0.0', 8 ),
|
||||||
build=True, xterms=False, cleanup=False,
|
build=True, xterms=False, cleanup=False,
|
||||||
inNamespace=False,
|
inNamespace=False,
|
||||||
autoSetMacs=False, autoStaticArp=False ):
|
autoSetMacs=False, autoStaticArp=False, listenPort=None ):
|
||||||
"""Create Mininet object.
|
"""Create Mininet object.
|
||||||
topo: Topo (topology) object or None
|
topo: Topo (topology) object or None
|
||||||
switch: Switch class
|
switch: Switch class
|
||||||
@@ -120,7 +120,9 @@ class Mininet( object ):
|
|||||||
cleanup: if build now, cleanup before creating?
|
cleanup: if build now, cleanup before creating?
|
||||||
inNamespace: spawn switches and controller in net namespaces?
|
inNamespace: spawn switches and controller in net namespaces?
|
||||||
autoSetMacs: set MAC addrs from topo?
|
autoSetMacs: set MAC addrs from topo?
|
||||||
autoStaticArp: set all-pairs static MAC addrs?"""
|
autoStaticArp: set all-pairs static MAC addrs?
|
||||||
|
listenPort: base listening port to open; will be incremented for
|
||||||
|
each additional switch in the net if inNamespace=False"""
|
||||||
self.switch = switch
|
self.switch = switch
|
||||||
self.host = host
|
self.host = host
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
@@ -131,6 +133,7 @@ class Mininet( object ):
|
|||||||
self.cleanup = cleanup
|
self.cleanup = cleanup
|
||||||
self.autoSetMacs = autoSetMacs
|
self.autoSetMacs = autoSetMacs
|
||||||
self.autoStaticArp = autoStaticArp
|
self.autoStaticArp = autoStaticArp
|
||||||
|
self.listenPort = listenPort
|
||||||
|
|
||||||
self.hosts = []
|
self.hosts = []
|
||||||
self.switches = []
|
self.switches = []
|
||||||
@@ -162,25 +165,32 @@ class Mininet( object ):
|
|||||||
"""Add switch.
|
"""Add switch.
|
||||||
name: name of switch to add
|
name: name of switch to add
|
||||||
mac: default MAC address for kernel/OVS switch intf 0
|
mac: default MAC address for kernel/OVS switch intf 0
|
||||||
returns: added switch"""
|
returns: added switch
|
||||||
|
side effect: increments the listenPort member variable."""
|
||||||
if self.switch == UserSwitch:
|
if self.switch == UserSwitch:
|
||||||
sw = self.switch( name, defaultMAC=mac, defaultIP=ip,
|
sw = self.switch( name, listenPort=self.listenPort,
|
||||||
inNamespace=self.inNamespace )
|
defaultMAC=mac, defaultIP=ip, inNamespace=self.inNamespace )
|
||||||
else:
|
else:
|
||||||
sw = self.switch( name, defaultMAC=mac, defaultIP=ip, dp=self.dps,
|
sw = self.switch( name, listenPort=self.listenPort,
|
||||||
|
defaultMAC=mac, defaultIP=ip, dp=self.dps,
|
||||||
inNamespace=self.inNamespace )
|
inNamespace=self.inNamespace )
|
||||||
|
if not self.inNamespace and self.listenPort:
|
||||||
|
self.listenPort += 1
|
||||||
self.dps += 1
|
self.dps += 1
|
||||||
self.switches.append( sw )
|
self.switches.append( sw )
|
||||||
self.nameToNode[ name ] = sw
|
self.nameToNode[ name ] = sw
|
||||||
return sw
|
return sw
|
||||||
|
|
||||||
def addController( self, name='c0', **kwargs ):
|
def addController( self, name='c0', controller=None, **kwargs ):
|
||||||
"""Add controller.
|
"""Add controller.
|
||||||
controller: Controller class"""
|
controller: Controller class"""
|
||||||
controller_new = self.controller( name, **kwargs )
|
if not controller:
|
||||||
|
controller = self.controller
|
||||||
|
controller_new = controller( name, **kwargs )
|
||||||
if controller_new: # allow controller-less setups
|
if controller_new: # allow controller-less setups
|
||||||
self.controllers.append( controller_new )
|
self.controllers.append( controller_new )
|
||||||
self.nameToNode[ name ] = controller_new
|
self.nameToNode[ name ] = controller_new
|
||||||
|
return controller_new
|
||||||
|
|
||||||
# Control network support:
|
# Control network support:
|
||||||
#
|
#
|
||||||
|
|||||||
+33
-18
@@ -200,7 +200,6 @@ class Node( object ):
|
|||||||
"""Monitor and return the output of a command.
|
"""Monitor and return the output of a command.
|
||||||
Set self.waiting to False if command has completed.
|
Set self.waiting to False if command has completed.
|
||||||
timeoutms: timeout in ms or None to wait indefinitely."""
|
timeoutms: timeout in ms or None to wait indefinitely."""
|
||||||
assert self.waiting
|
|
||||||
self.waitReadable( timeoutms )
|
self.waitReadable( timeoutms )
|
||||||
data = self.read( 1024 )
|
data = self.read( 1024 )
|
||||||
# Look for PID
|
# Look for PID
|
||||||
@@ -434,9 +433,19 @@ class Switch( Node ):
|
|||||||
|
|
||||||
portBase = SWITCH_PORT_BASE # 0 for OF < 1.0, 1 for OF >= 1.0
|
portBase = SWITCH_PORT_BASE # 0 for OF < 1.0, 1 for OF >= 1.0
|
||||||
|
|
||||||
def __init__( self, name, opts='', **kwargs):
|
def __init__( self, name, opts='', listenPort=None, **kwargs):
|
||||||
Node.__init__( self, name, **kwargs )
|
Node.__init__( self, name, **kwargs )
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
|
self.listenPort = listenPort
|
||||||
|
if self.listenPort:
|
||||||
|
self.opts += ' --listen=ptcp:%i ' % self.listenPort
|
||||||
|
|
||||||
|
def defaultIntf( self ):
|
||||||
|
"Return interface for HIGHEST port"
|
||||||
|
ports = self.intfs.keys()
|
||||||
|
if ports:
|
||||||
|
intf = self.intfs[ max( ports ) ]
|
||||||
|
return intf
|
||||||
|
|
||||||
def sendCmd( self, *cmd, **kwargs ):
|
def sendCmd( self, *cmd, **kwargs ):
|
||||||
"""Send command to Node.
|
"""Send command to Node.
|
||||||
@@ -455,12 +464,15 @@ class UserSwitch( Switch ):
|
|||||||
"""Init.
|
"""Init.
|
||||||
name: name for the switch"""
|
name: name for the switch"""
|
||||||
Switch.__init__( self, name, **kwargs )
|
Switch.__init__( self, name, **kwargs )
|
||||||
pathCheck( 'ofdatapath', 'ofprotocol' )
|
pathCheck( 'ofdatapath', 'ofprotocol',
|
||||||
|
moduleName='the OpenFlow reference user switch (openflow.org)' )
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup():
|
def setup():
|
||||||
"Ensure any dependencies are loaded; if not, try to load them."
|
"Ensure any dependencies are loaded; if not, try to load them."
|
||||||
moduleDeps( add=TUN )
|
if not os.path.exists( '/dev/net/tun' ):
|
||||||
|
moduleDeps( add=TUN )
|
||||||
|
|
||||||
def start( self, controllers ):
|
def start( self, controllers ):
|
||||||
"""Start OpenFlow reference user datapath.
|
"""Start OpenFlow reference user datapath.
|
||||||
@@ -478,7 +490,7 @@ class UserSwitch( Switch ):
|
|||||||
if self.inNamespace:
|
if self.inNamespace:
|
||||||
intfs = intfs[ :-1 ]
|
intfs = intfs[ :-1 ]
|
||||||
self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
|
self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
|
||||||
' punix:/tmp/' + self.name + mac_str +
|
' punix:/tmp/' + self.name + mac_str + ' --no-slicing ' +
|
||||||
' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
|
' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
|
||||||
self.cmd( 'ofprotocol unix:/tmp/' + self.name +
|
self.cmd( 'ofprotocol unix:/tmp/' + self.name +
|
||||||
' tcp:%s:%d' % ( controller.IP(), controller.port ) +
|
' tcp:%s:%d' % ( controller.IP(), controller.port ) +
|
||||||
@@ -511,8 +523,10 @@ class KernelSwitch( Switch ):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def setup():
|
def setup():
|
||||||
"Ensure any dependencies are loaded; if not, try to load them."
|
"Ensure any dependencies are loaded; if not, try to load them."
|
||||||
moduleDeps( subtract = OVS_KMOD, add = OF_KMOD )
|
pathCheck( 'ofprotocol',
|
||||||
pathCheck( 'ofprotocol' )
|
moduleName='the OpenFlow reference kernel switch'
|
||||||
|
' (openflow.org) (NOTE: not available in OpenFlow 1.0!)' )
|
||||||
|
moduleDeps( subtract=OVS_KMOD, add=OF_KMOD )
|
||||||
|
|
||||||
def start( self, controllers ):
|
def start( self, controllers ):
|
||||||
"Start up reference kernel datapath."
|
"Start up reference kernel datapath."
|
||||||
@@ -559,14 +573,15 @@ class OVSKernelSwitch( Switch ):
|
|||||||
self.intf = self.dp
|
self.intf = self.dp
|
||||||
if self.inNamespace:
|
if self.inNamespace:
|
||||||
error( "OVSKernelSwitch currently only works"
|
error( "OVSKernelSwitch currently only works"
|
||||||
" in the root namespace." )
|
" in the root namespace.\n" )
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup():
|
def setup():
|
||||||
"Ensure any dependencies are loaded; if not, try to load them."
|
"Ensure any dependencies are loaded; if not, try to load them."
|
||||||
moduleDeps( subtract = OF_KMOD, add = OVS_KMOD )
|
pathCheck( 'ovs-dpctl', 'ovs-openflowd',
|
||||||
pathCheck( 'ovs-dpctl', 'ovs-openflowd' )
|
moduleName='Open vSwitch (openvswitch.org)')
|
||||||
|
moduleDeps( subtract=OF_KMOD, add=OVS_KMOD )
|
||||||
|
|
||||||
def start( self, controllers ):
|
def start( self, controllers ):
|
||||||
"Start up kernel datapath."
|
"Start up kernel datapath."
|
||||||
@@ -607,10 +622,10 @@ class Controller( Node ):
|
|||||||
"""A Controller is a Node that is running (or has execed?) an
|
"""A Controller is a Node that is running (or has execed?) an
|
||||||
OpenFlow controller."""
|
OpenFlow controller."""
|
||||||
|
|
||||||
def __init__( self, name, inNamespace=False, controller='controller',
|
def __init__( self, name, inNamespace=False, command='controller',
|
||||||
cargs='-v ptcp:', cdir=None, defaultIP="127.0.0.1",
|
cargs='-v ptcp:%d', cdir=None, defaultIP="127.0.0.1",
|
||||||
port=6633 ):
|
port=6633 ):
|
||||||
self.controller = controller
|
self.command = command
|
||||||
self.cargs = cargs
|
self.cargs = cargs
|
||||||
self.cdir = cdir
|
self.cdir = cdir
|
||||||
self.port = port
|
self.port = port
|
||||||
@@ -620,17 +635,17 @@ class Controller( Node ):
|
|||||||
def start( self ):
|
def start( self ):
|
||||||
"""Start <controller> <args> on controller.
|
"""Start <controller> <args> on controller.
|
||||||
Log to /tmp/cN.log"""
|
Log to /tmp/cN.log"""
|
||||||
pathCheck( self.controller )
|
pathCheck( self.command )
|
||||||
cout = '/tmp/' + self.name + '.log'
|
cout = '/tmp/' + self.name + '.log'
|
||||||
if self.cdir is not None:
|
if self.cdir is not None:
|
||||||
self.cmd( 'cd ' + self.cdir )
|
self.cmd( 'cd ' + self.cdir )
|
||||||
self.cmd( self.controller + ' ' + self.cargs +
|
self.cmd( self.command + ' ' + self.cargs % self.port +
|
||||||
' 1>' + cout + ' 2>' + cout + '&' )
|
' 1>' + cout + ' 2>' + cout + '&' )
|
||||||
self.execed = False
|
self.execed = False
|
||||||
|
|
||||||
def stop( self ):
|
def stop( self ):
|
||||||
"Stop controller."
|
"Stop controller."
|
||||||
self.cmd( 'kill %' + self.controller )
|
self.cmd( 'kill %' + self.command )
|
||||||
self.terminate()
|
self.terminate()
|
||||||
|
|
||||||
def IP( self, intf=None ):
|
def IP( self, intf=None ):
|
||||||
@@ -668,8 +683,8 @@ class NOX( Controller ):
|
|||||||
noxCoreDir = os.environ[ 'NOX_CORE_DIR' ]
|
noxCoreDir = os.environ[ 'NOX_CORE_DIR' ]
|
||||||
|
|
||||||
Controller.__init__( self, name,
|
Controller.__init__( self, name,
|
||||||
controller=noxCoreDir + '/nox_core',
|
command=noxCoreDir + '/nox_core',
|
||||||
cargs='--libdir=/usr/local/lib -v -i ptcp: ' +
|
cargs='--libdir=/usr/local/lib -v -i ptcp:%s ' % self.port +
|
||||||
' '.join( noxArgs ),
|
' '.join( noxArgs ),
|
||||||
cdir=noxCoreDir, **kwargs )
|
cdir=noxCoreDir, **kwargs )
|
||||||
|
|
||||||
|
|||||||
+140
-24
@@ -9,19 +9,38 @@ set -e
|
|||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
# Location of CONFIG_NET_NS-enabled kernel(s)
|
# Location of CONFIG_NET_NS-enabled kernel(s)
|
||||||
KERNEL_LOC=http://www.stanford.edu/~brandonh
|
KERNEL_LOC=http://www.openflow.org/downloads/mininet
|
||||||
|
|
||||||
|
test -e /etc/debian_version && DIST="Debian"
|
||||||
|
grep Ubuntu /etc/lsb-release &> /dev/null && DIST="Ubuntu"
|
||||||
|
|
||||||
# Kernel params
|
# Kernel params
|
||||||
# These kernels have been tried:
|
# These kernels have been tried:
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
KERNEL_NAME=2.6.33.1-mininet
|
KERNEL_NAME=2.6.33.1-mininet
|
||||||
#KERNEL_NAME=`uname -r`
|
#KERNEL_NAME=`uname -r`
|
||||||
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
KERNEL_IMAGE=linux-image-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
KERNEL_IMAGE=linux-image-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
|
=======
|
||||||
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
KERNEL_NAME=2.6.33.1-mininet
|
||||||
|
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
|
KERNEL_IMAGE=linux-image-${KERNEL_NAME}_${KERNEL_NAME}-10.00.Custom_i386.deb
|
||||||
|
elif [ "$DIST" = "Ubuntu" ]; then
|
||||||
|
KERNEL_NAME=`uname -r`
|
||||||
|
KERNEL_HEADERS=linux-headers-${KERNEL_NAME}
|
||||||
|
else
|
||||||
|
echo "Install.sh currently only supports Ubuntu and Debian."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Detected Linux distribution: $DIST"
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
|
|
||||||
# Kernel Deb pkg to be removed:
|
# Kernel Deb pkg to be removed:
|
||||||
KERNEL_IMAGE_OLD=linux-image-2.6.26-2-686
|
KERNEL_IMAGE_OLD=linux-image-2.6.26-2-686
|
||||||
|
|
||||||
DRIVERS_DIR=/lib/modules/${KERNEL_NAME}/kernel/drivers
|
DRIVERS_DIR=/lib/modules/${KERNEL_NAME}/kernel/drivers/net
|
||||||
|
|
||||||
#OVS_RELEASE=openvswitch-1.0.1
|
#OVS_RELEASE=openvswitch-1.0.1
|
||||||
OVS_RELEASE=openvswitch # release 1.0.1 doesn't work with veth pairs.
|
OVS_RELEASE=openvswitch # release 1.0.1 doesn't work with veth pairs.
|
||||||
@@ -29,12 +48,14 @@ OVS_DIR=~/$OVS_RELEASE
|
|||||||
OVS_KMOD=openvswitch_mod.ko
|
OVS_KMOD=openvswitch_mod.ko
|
||||||
|
|
||||||
function kernel {
|
function kernel {
|
||||||
echo "Install new kernel..."
|
echo "Install Mininet-compatible kernel"
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
|
|
||||||
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
|
||||||
# The easy approach: download pre-built linux-image and linux-headers packages:
|
# The easy approach: download pre-built linux-image and linux-headers packages:
|
||||||
wget $KERNEL_LOC/$KERNEL_HEADERS
|
wget -c $KERNEL_LOC/$KERNEL_HEADERS
|
||||||
wget $KERNEL_LOC/$KERNEL_IMAGE
|
wget -c $KERNEL_LOC/$KERNEL_IMAGE
|
||||||
|
|
||||||
#Install custom linux headers and image:
|
#Install custom linux headers and image:
|
||||||
sudo dpkg -i $KERNEL_IMAGE $KERNEL_HEADERS
|
sudo dpkg -i $KERNEL_IMAGE $KERNEL_HEADERS
|
||||||
@@ -51,6 +72,8 @@ function kernel {
|
|||||||
sudo update-grub
|
sudo update-grub
|
||||||
|
|
||||||
# The default should be the new kernel. Otherwise, you may need to modify /boot/grub/menu.lst to set the default to the entry corresponding to the kernel you just installed.
|
# The default should be the new kernel. Otherwise, you may need to modify /boot/grub/menu.lst to set the default to the entry corresponding to the kernel you just installed.
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function kernel_clean {
|
function kernel_clean {
|
||||||
@@ -65,14 +88,20 @@ function kernel_clean {
|
|||||||
|
|
||||||
# Install Mininet deps
|
# Install Mininet deps
|
||||||
function mn_deps {
|
function mn_deps {
|
||||||
#Install dependencies:
|
echo "Installing Mininet dependencies"
|
||||||
sudo apt-get install -y screen psmisc xterm ssh iperf iproute python-setuptools
|
sudo aptitude install -y gcc make screen psmisc xterm ssh iperf iproute \
|
||||||
|
python-setuptools python-networkx
|
||||||
|
|
||||||
#Add sysctl parameters as noted in the INSTALL file to increase kernel limits to support larger setups:
|
#Add sysctl parameters as noted in the INSTALL file to increase kernel limits to support larger setups:
|
||||||
sudo su -c "cat /home/mininet/mininet/util/sysctl_addon >> /etc/sysctl.conf"
|
sudo su -c "cat $HOME/mininet/util/sysctl_addon >> /etc/sysctl.conf"
|
||||||
|
|
||||||
#Load new sysctl settings:
|
#Load new sysctl settings:
|
||||||
sudo sysctl -p
|
sudo sysctl -p
|
||||||
|
|
||||||
|
echo "Installing Mininet core"
|
||||||
|
pushd ~/mininet
|
||||||
|
sudo make install
|
||||||
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
# The following will cause a full OF install, covering:
|
# The following will cause a full OF install, covering:
|
||||||
@@ -109,7 +138,12 @@ function of {
|
|||||||
sudo apt-get remove -y avahi-daemon
|
sudo apt-get remove -y avahi-daemon
|
||||||
|
|
||||||
# Disable IPv6. Add to /etc/modprobe.d/blacklist:
|
# Disable IPv6. Add to /etc/modprobe.d/blacklist:
|
||||||
sudo sh -c "echo -e 'blacklist net-pf-10\nblacklist ipv6' >> /etc/modprobe.d/blacklist"
|
if [ "$DIST" = "Ubuntu" ]; then
|
||||||
|
BLACKLIST=/etc/modprobe.d/blacklist.conf
|
||||||
|
else
|
||||||
|
BLACKLIST=/etc/modprobe.d/blacklist
|
||||||
|
fi
|
||||||
|
sudo sh -c "echo 'blacklist net-pf-10\nblacklist ipv6' >> $BLACKLIST"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install OpenVSwitch
|
# Install OpenVSwitch
|
||||||
@@ -117,13 +151,23 @@ function of {
|
|||||||
function ovs {
|
function ovs {
|
||||||
echo "Installing OpenVSwitch..."
|
echo "Installing OpenVSwitch..."
|
||||||
|
|
||||||
#Install Autoconf 2.63+ backport from Debian Backports repo:
|
if [ "$DIST" = "Debian" ]; then
|
||||||
#Instructions from http://backports.org/dokuwiki/doku.php?id=instructions
|
sudo aptitude -y install pkg-config gcc make git-core python-dev libssl-dev
|
||||||
sudo su -c "echo 'deb http://www.backports.org/debian lenny-backports main contrib non-free' >> /etc/apt/sources.list"
|
#Install Autoconf 2.63+ backport from Debian Backports repo:
|
||||||
sudo apt-get update
|
#Instructions from http://backports.org/dokuwiki/doku.php?id=instructions
|
||||||
sudo apt-get -y --force-yes install debian-backports-keyring
|
sudo su -c "echo 'deb http://www.backports.org/debian lenny-backports main contrib non-free' >> /etc/apt/sources.list"
|
||||||
sudo apt-get -y --force-yes -t lenny-backports install autoconf
|
sudo apt-get update
|
||||||
|
sudo apt-get -y --force-yes install debian-backports-keyring
|
||||||
|
sudo apt-get -y --force-yes -t lenny-backports install autoconf
|
||||||
|
fi
|
||||||
|
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
|
=======
|
||||||
|
if [ "$DIST" = "Ubuntu" ]; then
|
||||||
|
sudo apt-get -y install $KERNEL_HEADERS
|
||||||
|
fi
|
||||||
|
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
#Install OVS from release
|
#Install OVS from release
|
||||||
cd ~/
|
cd ~/
|
||||||
#wget http://openvswitch.org/releases/${OVS_RELEASE}.tar.gz
|
#wget http://openvswitch.org/releases/${OVS_RELEASE}.tar.gz
|
||||||
@@ -132,7 +176,17 @@ function ovs {
|
|||||||
git clone git://openvswitch.org/openvswitch
|
git clone git://openvswitch.org/openvswitch
|
||||||
cd $OVS_RELEASE
|
cd $OVS_RELEASE
|
||||||
./boot.sh
|
./boot.sh
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
./configure --with-l26=/lib/modules/${KERNEL_NAME}/build
|
./configure --with-l26=/lib/modules/${KERNEL_NAME}/build
|
||||||
|
=======
|
||||||
|
BUILDDIR=/lib/modules/${KERNEL_NAME}/build
|
||||||
|
if [ ! -e $BUILDDIR ]; then
|
||||||
|
echo "Creating build directory $BUILDDIR"
|
||||||
|
sudo mkdir -p $BUILDDIR
|
||||||
|
fi
|
||||||
|
opts="--with-l26=$BUILDDIR"
|
||||||
|
./configure $opts
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
}
|
}
|
||||||
@@ -142,8 +196,14 @@ function nox {
|
|||||||
echo "Installing NOX w/tutorial files..."
|
echo "Installing NOX w/tutorial files..."
|
||||||
|
|
||||||
#Install NOX deps:
|
#Install NOX deps:
|
||||||
sudo apt-get -y install autoconf automake g++ libtool python python-twisted swig libboost1.35-dev libxerces-c2-dev libssl-dev make
|
sudo apt-get -y install autoconf automake g++ libtool python python-twisted swig libxerces-c2-dev libssl-dev make
|
||||||
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
sudo apt-get -y install libboost1.35-dev
|
||||||
|
elif [ "$DIST" = "Ubuntu" ]; then
|
||||||
|
sudo apt-get -y install python-dev libboost-dev
|
||||||
|
sudo apt-get -y install libboost-filesystem-dev
|
||||||
|
sudo apt-get -y install libboost-test-dev
|
||||||
|
fi
|
||||||
#Install NOX optional deps:
|
#Install NOX optional deps:
|
||||||
sudo apt-get install -y libsqlite3-dev python-simplejson
|
sudo apt-get install -y libsqlite3-dev python-simplejson
|
||||||
|
|
||||||
@@ -154,12 +214,19 @@ function nox {
|
|||||||
|
|
||||||
# With later autoconf versions this doesn't quite work:
|
# With later autoconf versions this doesn't quite work:
|
||||||
./boot.sh --apps-core || true
|
./boot.sh --apps-core || true
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
# So use this instead:
|
# So use this instead:
|
||||||
autoreconf --install --force
|
autoreconf --install --force
|
||||||
|
=======
|
||||||
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
# So use this instead:
|
||||||
|
autoreconf --install --force
|
||||||
|
fi
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
../configure --with-python=yes
|
../configure --with-python=yes
|
||||||
make
|
make
|
||||||
#make check
|
#make check
|
||||||
|
|
||||||
# Add NOX_CORE_DIR env var:
|
# Add NOX_CORE_DIR env var:
|
||||||
@@ -194,7 +261,11 @@ function cbench {
|
|||||||
git clone git://www.openflow.org/oflops.git
|
git clone git://www.openflow.org/oflops.git
|
||||||
cd oflops
|
cd oflops
|
||||||
sh boot.sh
|
sh boot.sh
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
./configure --with-openflow-src-dir=/home/mininet/openflow
|
./configure --with-openflow-src-dir=/home/mininet/openflow
|
||||||
|
=======
|
||||||
|
./configure --with-openflow-src-dir=$HOME/openflow
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
make
|
make
|
||||||
sudo make install || true # make install fails; force past this
|
sudo make install || true # make install fails; force past this
|
||||||
}
|
}
|
||||||
@@ -221,12 +292,23 @@ function other {
|
|||||||
git config --global color.branch auto
|
git config --global color.branch auto
|
||||||
|
|
||||||
#Reduce boot screen opt-out delay. Modify timeout in /boot/grub/menu.lst to 1:
|
#Reduce boot screen opt-out delay. Modify timeout in /boot/grub/menu.lst to 1:
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
sudo sed -i -e 's/^timeout.*$/timeout 1/' /boot/grub/menu.lst
|
sudo sed -i -e 's/^timeout.*$/timeout 1/' /boot/grub/menu.lst
|
||||||
|
|
||||||
# Clean unneeded debs:
|
# Clean unneeded debs:
|
||||||
rm -f ~/linux-headers-* ~/linux-image-*
|
rm -f ~/linux-headers-* ~/linux-image-*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
if [ "$DIST" = "Debian" ]; then
|
||||||
|
sudo sed -i -e 's/^timeout.*$/timeout 1/' /boot/grub/menu.lst
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean unneeded debs:
|
||||||
|
rm -f ~/linux-headers-* ~/linux-image-*
|
||||||
|
}
|
||||||
|
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
# Script to copy built OVS kernel module to where modprobe will
|
# Script to copy built OVS kernel module to where modprobe will
|
||||||
# find them automatically. Removes the need to keep an environment variable
|
# find them automatically. Removes the need to keep an environment variable
|
||||||
# for insmod usage, and works nicely with multiple kernel versions.
|
# for insmod usage, and works nicely with multiple kernel versions.
|
||||||
@@ -243,11 +325,14 @@ function modprobe {
|
|||||||
|
|
||||||
function all {
|
function all {
|
||||||
echo "Running all commands..."
|
echo "Running all commands..."
|
||||||
kernel
|
if [ "$DIST" != "Ubuntu" ]; then
|
||||||
|
# Ubuntu ships with Mininet-compatible kernel
|
||||||
|
kernel
|
||||||
|
fi
|
||||||
mn_deps
|
mn_deps
|
||||||
of
|
of
|
||||||
ovs
|
ovs
|
||||||
modprobe
|
modprobe
|
||||||
nox
|
nox
|
||||||
oftest
|
oftest
|
||||||
cbench
|
cbench
|
||||||
@@ -264,27 +349,58 @@ function vm_clean {
|
|||||||
sudo rm -rf openvswitch*.tar.gz
|
sudo rm -rf openvswitch*.tar.gz
|
||||||
|
|
||||||
# Remove sensistive files
|
# Remove sensistive files
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
history -c
|
history -c
|
||||||
rm ~/.bash_history # history -c doesn't seem to work for some reason
|
rm ~/.bash_history # history -c doesn't seem to work for some reason
|
||||||
|
=======
|
||||||
|
history -c # note this won't work if you have multiple bash sessions
|
||||||
|
rm -f ~/.bash_history # need to clear in memory and remove on disk
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
rm -f ~/.ssh/id_rsa* ~/.ssh/known_hosts
|
rm -f ~/.ssh/id_rsa* ~/.ssh/known_hosts
|
||||||
sudo rm ~/.ssh/authorized_keys2
|
sudo rm -f ~/.ssh/authorized_keys2
|
||||||
|
|
||||||
# Remove Mininet files
|
# Remove Mininet files
|
||||||
#sudo rm -f /lib/modules/python2.5/site-packages/mininet*
|
#sudo rm -f /lib/modules/python2.5/site-packages/mininet*
|
||||||
#sudo rm -f /usr/bin/mnexec
|
#sudo rm -f /usr/bin/mnexec
|
||||||
|
|
||||||
# Clear optional dev script for SSH keychain load on boot
|
# Clear optional dev script for SSH keychain load on boot
|
||||||
|
<<<<<<< HEAD:util/install.sh
|
||||||
rm ~/.bash_profile
|
rm ~/.bash_profile
|
||||||
|
=======
|
||||||
|
rm -f ~/.bash_profile
|
||||||
|
>>>>>>> of1.0:util/install.sh
|
||||||
|
|
||||||
# Clear git changes
|
# Clear git changes
|
||||||
git config --global user.name "None"
|
git config --global user.name "None"
|
||||||
git config --global user.email "None"
|
git config --global user.email "None"
|
||||||
|
|
||||||
#sudo rm -rf ~/mininet
|
# Remove mininet install script
|
||||||
|
rm -f install-mininet.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
function usage {
|
function usage {
|
||||||
printf "Usage: %s: [-acdfhkmntvxy] args\n" $(basename $0) >&2
|
printf 'Usage: %s [-acdfhkmntvxy]\n\n' $(basename $0) >&2
|
||||||
|
|
||||||
|
printf 'This install script attempts to install useful packages\n' >&2
|
||||||
|
printf 'for Mininet. It should (hopefully) work on Ubuntu 10.04 and\n' >&2
|
||||||
|
printf 'Debian 5.0 (Lenny). If you run into trouble, try\n' >&2
|
||||||
|
printf 'installing one thing at a time, and looking at the \n' >&2
|
||||||
|
printf 'specific installation function in this script.\n\n' >&2
|
||||||
|
|
||||||
|
printf 'options:\n' >&2
|
||||||
|
printf -- ' -a: (default) install (A)ll packages - good luck!\n' >&2
|
||||||
|
printf -- ' -c: (C)lean up after kernel install\n' >&2
|
||||||
|
printf -- ' -d: (D)elete some sensitive files from a VM image\n' >&2
|
||||||
|
printf -- ' -f: install open(F)low\n' >&2
|
||||||
|
printf -- ' -h: print this (H)elp message\n' >&2
|
||||||
|
printf -- ' -k: install new (K)ernel\n' >&2
|
||||||
|
printf -- ' -m: install Open vSwitch kernel (M)odule\n' >&2
|
||||||
|
printf -- ' -n: install mini(N)et dependencies + core files\n' >&2
|
||||||
|
printf -- ' -t: install o(T)her stuff\n' >&2
|
||||||
|
printf -- ' -v: install open (V)switch\n' >&2
|
||||||
|
printf -- ' -x: install NO(X) OpenFlow controller\n' >&2
|
||||||
|
printf -- ' -y: install (A)ll packages\n' >&2
|
||||||
|
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +411,7 @@ else
|
|||||||
while getopts 'acdfhkmntvx' OPTION
|
while getopts 'acdfhkmntvx' OPTION
|
||||||
do
|
do
|
||||||
case $OPTION in
|
case $OPTION in
|
||||||
a) all;;
|
a) all;;
|
||||||
c) kernel_clean;;
|
c) kernel_clean;;
|
||||||
d) vm_clean;;
|
d) vm_clean;;
|
||||||
f) of;;
|
f) of;;
|
||||||
|
|||||||
Reference in New Issue
Block a user