Compare commits

..

2 Commits

Author SHA1 Message Date
lantz 008f62f6ce Merge branch 'master' into rc-local 2021-02-06 15:55:55 -08:00
Bob Lantz f33a8f0eea rc.local: /usr/bin/bash -> /bin/bash
bash is (and should be) located in /bin

this may have caused ubuntu 18.04 to not execute
/etc/rc.local and regenerate ssh keys
2021-02-01 16:21:43 -08:00
12 changed files with 921 additions and 2056 deletions
+17 -6
View File
@@ -2,7 +2,7 @@
Mininet Installation/Configuration Notes
----------------------------------------
Mininet 2.3.0rc1
Mininet 2.3.0b2
---
The supported installation methods for Mininet are 1) using a
@@ -137,7 +137,9 @@ like to contribute an installation script, we would welcome it!)
This takes about 4 minutes on our test system.
3.2. (Experimental) Native installation from source on Fedora:
3.2. Native installation from source on Fedora 18+.
*This may be out of date.*
As root execute the following operations:
@@ -145,6 +147,18 @@ like to contribute an installation script, we would welcome it!)
yum install git
* create an user account (e.g. mininet) and add it to the wheel group
useradd [...] mininet
usermod -a -G wheel mininet
* change the SElinux setting to permissive. It can be done
temporarily with:
setenforce 0
then login with the new account (e.g. mininet) and do the following:
* clone the Mininet repository
git clone git://github.com/mininet/mininet.git
@@ -163,10 +177,7 @@ like to contribute an installation script, we would welcome it!)
sudo mn --test pingall
Note that `install.sh -fnv `may not install all dependencies on Fedora,
and many tests may still fail.
4. Creating your own Mininet/OpenFlow tutorial VM on Ubuntu/Debian
4. Creating your own Mininet/OpenFlow tutorial VM
Creating your own Ubuntu Mininet VM for use with the OpenFlow tutorial
is easy! First, create a new Ubuntu VM. Next, run two commands in it:
+1 -1
View File
@@ -1,4 +1,4 @@
Mininet 2.3.0rc1 License
Mininet 2.3.0b2 License
Copyright (c) 2013-2020 Open Networking Foundation
Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
-2
View File
@@ -56,8 +56,6 @@ install-manpages: $(MANPAGES)
install -D -t $(MANDIR) $(MANPAGES)
install: install-mnexec install-manpages
# This seems to work on all pip versions
$(PYTHON) -m pip uninstall mininet || true
$(PYTHON) -m pip install .
develop: $(MNEXEC) $(MANPAGES)
+6 -6
View File
@@ -2,7 +2,7 @@ Mininet: Rapid Prototyping for Software Defined Networks
========================================================
*The best way to emulate almost any network on your laptop!*
Mininet 2.3.0rc1
Mininet 2.3.0b2
[![Build Status][1]](https://github.com/mininet/mininet/actions)
@@ -70,7 +70,7 @@ Mininet includes:
### Python 3 Support
- Mininet 2.3.0rc1 supports Python 3 and Python 2!
- Mininet 2.3.0b2 supports Python 3 and Python 2!
- You can install both the Python 3 and Python 2 versions of
Mininet side by side, but the most recent installation will
@@ -84,7 +84,7 @@ determine which Python version is used by default by `mn`.
- More information regarding Python 3 and Python 2 support
may be found in the release notes on http://docs.mininet.org.
### Other Enhancements and Information
- Support for Ubuntu 20.04 LTS (and 18.04 and 16.04)
@@ -117,7 +117,7 @@ Mininet mailing list, `mininet-discuss` at:
### Join Us
Thanks again to all of the Mininet contributors and users!
Thanks again to all of the Mininet contributors!
Mininet is an open source project and is currently hosted
at <https://github.com/mininet>. You are encouraged to download
@@ -129,10 +129,10 @@ hard work that Mininet continues to grow and improve.
### Enjoy Mininet
Have fun! We look forward to seeing what you will do with Mininet
Have fun! We look forward to seeing what you will do with Mininet
to change the networking world.
Bob Lantz,
Bob Lantz
on behalf of the Mininet Contributors
[1]: https://github.com/mininet/mininet/workflows/mininet-tests/badge.svg
-3
View File
@@ -290,9 +290,6 @@ class MininetRunner( object ):
help='prints the version and exits' )
opts.add_option( '--wait', '-w', action='store_true',
default=False, help='wait for switches to connect' )
opts.add_option( '--twait', '-t', action='store', type='int',
dest='wait',
help='timed wait (s) for switches to connect' )
opts.add_option( '--cluster', type='string', default=None,
metavar='server1,server2...',
help=( 'run on multiple servers (experimental!)' ) )
+830 -1936
View File
File diff suppressed because it is too large Load Diff
+31 -57
View File
@@ -89,7 +89,7 @@ from mininet.link import Link, Intf
from mininet.net import Mininet
from mininet.topo import LinearTopo
from mininet.topolib import TreeTopo
from mininet.util import quietRun, errRun, decode
from mininet.util import quietRun, errRun
from mininet.examples.clustercli import CLI
from mininet.log import setLogLevel, debug, info, error
from mininet.clean import addCleanupCallback
@@ -247,7 +247,7 @@ class RemoteMixin( object ):
result = ''
while True:
poll = popen.poll()
result += decode( popen.stdout.read() )
result += popen.stdout.read()
if poll is not None:
break
return result
@@ -440,16 +440,13 @@ class RemoteLink( Link ):
# When we receive the character '@', it means that our
# tunnel should be set up
debug( 'Waiting for tunnel to come up...\n' )
ch = decode( tunnel.stdout.read( 1 ) )
ch = tunnel.stdout.read( 1 )
if ch != '@':
ch += decode( tunnel.stdout.read() )
cmd = ' '.join( cmd )
raise Exception( 'makeTunnel:\n'
'Tunnel setup failed for '
'%s:%s' % ( node1, node1.dest ) + ' to '
'%s:%s\n' % ( node2, node2.dest ) +
'command was: %s' % cmd + '\n' +
'result was: ' + 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 ):
@@ -851,37 +848,27 @@ class MininetCluster( Mininet ):
if cfile:
config.setdefault( 'controlPath', cfile )
@staticmethod
def isLoopback( ipaddr ):
"Is ipaddr an IPv4 loopback address?"
return ipaddr.startswith( '127.' )
# pylint: disable=arguments-differ,signature-differs
def addController( self, *args, **kwargs ):
"Patch to update IP address to global IP address"
controller = Mininet.addController( self, *args, **kwargs )
controllerIP = controller.IP()
loopback = '127.0.0.1'
if ( not isinstance( controller, Controller ) or
not self.isLoopback( controller.IP() ) ):
return controller
controller.IP() != loopback ):
return None
# Find route to a different server IP address
serverIPs = [ ip for ip in self.serverIP.values()
if ip != controllerIP ]
if ip is not controller.IP() ]
if not serverIPs:
return None # no remote servers - loopback is fine
for remoteIP in serverIPs:
# Route should contain 'dev <intfname>'
route = controller.cmd( 'ip route get', remoteIP,
r'| egrep -o "dev\s[^[:space:]]+"' )
if not route:
raise Exception('addController: no route from', controller,
'to', remoteIP )
intf = route.split()[ 1 ].strip()
if intf != 'lo':
break
if intf == 'lo':
raise Exception( 'addController: could not find external '
'interface/IP for %s' % controller )
remoteIP = serverIPs[ 0 ]
# Route should contain 'dev <intfname>'
route = controller.cmd( 'ip route get', remoteIP,
r'| egrep -o "dev\s[^[:space:]]+"' )
if not route:
raise Exception('addController: no route from', controller,
'to', remoteIP )
intf = route.split()[ 1 ].strip()
debug( 'adding', intf, 'to', controller )
Intf( intf, node=controller ).updateIP()
debug( controller, 'IP address updated to', controller.IP() )
@@ -896,10 +883,7 @@ class MininetCluster( Mininet ):
Mininet.buildFromTopo( self, *args, **kwargs )
# Default remote server for tests
remoteServer = 'ubuntu2'
def testNsTunnels( remote=remoteServer, link=RemoteGRELink ):
def testNsTunnels( remote='ubuntu2', link=RemoteGRELink ):
"Test tunnels between nodes in namespaces"
net = Mininet( host=RemoteHost, link=link, waitConnected=True )
h1 = net.addHost( 'h1')
@@ -914,14 +898,14 @@ def testNsTunnels( remote=remoteServer, link=RemoteGRELink ):
# This shows how node options may be used to manage
# cluster placement using the net.add*() API
def testRemoteNet( remote=remoteServer, link=RemoteGRELink ):
def testRemoteNet( remote='ubuntu2', link=RemoteGRELink ):
"Test remote Node classes"
info( '*** Remote Node Test\n' )
net = Mininet( host=RemoteHost, switch=RemoteOVSSwitch,
link=link, controller=ClusterController,
net = Mininet( host=RemoteHost, switch=RemoteOVSSwitch, link=link,
waitConnected=True )
c0 = net.addController( 'c0' )
# Make sure controller knows its non-loopback address
Intf( 'eth0', node=c0 ).updateIP()
info( "*** Creating local h1\n" )
h1 = net.addHost( 'h1' )
info( "*** Creating remote h2\n" )
@@ -953,7 +937,7 @@ def testRemoteNet( remote=remoteServer, link=RemoteGRELink ):
remoteHosts = [ 'h2' ]
remoteSwitches = [ 's2' ]
remoteServer = 'ubuntu2'
def HostPlacer( name, *args, **params ):
"Custom Host() constructor which places hosts on servers"
@@ -970,21 +954,10 @@ def SwitchPlacer( name, *args, **params ):
return RemoteOVSSwitch( name, *args, **params )
def ClusterController( *args, **kwargs):
"Custom Controller() constructor which updates its intf IP address"
intf = kwargs.pop( 'intf', '' )
"Custom Controller() constructor which updates its eth0 IP address"
controller = Controller( *args, **kwargs )
# Find out its IP address so that cluster switches can connect
if not intf:
output = controller.cmd(
r"ip a | egrep -o '\w+:\s\w+'" ).split( '\n' )
for line in output:
intf = line.split()[ -1 ]
if intf != 'lo':
break
if intf == 'lo':
raise Exception( 'Could not find non-loopback interface'
'for %s' % controller )
Intf( intf, node=controller ).updateIP()
Intf( 'eth0', node=controller ).updateIP()
return controller
def testRemoteTopo( link=RemoteGRELink ):
@@ -1001,7 +974,7 @@ def testRemoteTopo( link=RemoteGRELink ):
# do random switch placement rather than completely random
# host placement.
def testRemoteSwitches( remote=remoteServer, link=RemoteGRELink ):
def testRemoteSwitches( remote='ubuntu2', link=RemoteGRELink ):
"Test with local hosts and remote switches"
servers = [ 'localhost', remote]
topo = TreeTopo( depth=4, fanout=2 )
@@ -1019,7 +992,7 @@ def testRemoteSwitches( remote=remoteServer, link=RemoteGRELink ):
# functions, for maximum ease of use. MininetCluster() also
# pre-flights and multiplexes server connections.
def testMininetCluster( remote=remoteServer, link=RemoteGRELink ):
def testMininetCluster( remote='ubuntu2', link=RemoteGRELink ):
"Test MininetCluster()"
servers = [ 'localhost', remote ]
topo = TreeTopo( depth=3, fanout=3 )
@@ -1029,7 +1002,7 @@ def testMininetCluster( remote=remoteServer, link=RemoteGRELink ):
net.pingAll()
net.stop()
def signalTest( remote=remoteServer):
def signalTest( remote='ubuntu2'):
"Make sure hosts are robust to signals"
h = RemoteHost( 'h0', server=remote )
h.shell.send_signal( SIGINT )
@@ -1044,6 +1017,7 @@ def signalTest( remote=remoteServer):
if __name__ == '__main__':
setLogLevel( 'info' )
remoteServer = 'ubuntu2'
remoteLink = RemoteSSHLink
testRemoteTopo(link=remoteLink)
testNsTunnels( remote=remoteServer, link=remoteLink )
+5 -4
View File
@@ -2703,13 +2703,14 @@ class MiniEdit( Frame ):
tags = self.canvas.gettags(item)
if 'Controller' in tags:
# remove from switch controller lists
for searchwidget in self.widgetToItem:
name = searchwidget[ 'text' ]
tags = self.canvas.gettags( self.widgetToItem[ searchwidget ] )
for serachwidget in self.widgetToItem:
name = serachwidget[ 'text' ]
tags = self.canvas.gettags( self.widgetToItem[ serachwidget ] )
if 'Switch' in tags:
if widget['text'] in self.switchOpts[name]['controllers']:
self.switchOpts[name]['controllers'].remove(widget['text'])
for link in tuple( widget.links.values() ):
for link in widget.links.values():
# Delete from view and model
self.deleteItem( link )
del self.itemToWidget[ item ]
+1 -9
View File
@@ -89,15 +89,7 @@ class CLI( Cmd ):
if os.path.isfile( history_path ):
read_history_file( history_path )
set_history_length( 1000 )
def writeHistory():
"Write out history file"
try:
write_history_file( history_path )
except IOError:
# Ignore probably spurious IOError
pass
atexit.register( writeHistory )
atexit.register( lambda: write_history_file( history_path ) )
def run( self ):
"Run our cmdloop(), catching KeyboardInterrupt"
+7 -9
View File
@@ -109,7 +109,7 @@ from mininet.util import ( quietRun, fixLimits, numCores, ensureRoot,
from mininet.term import cleanUpScreens, makeTerms
# Mininet version: should be consistent with README and LICENSE
VERSION = "2.3.0rc1"
VERSION = "2.3.0b2"
class Mininet( object ):
"Network emulation with hosts spawned in network namespaces."
@@ -137,9 +137,7 @@ class Mininet( object ):
autoStaticArp: set all-pairs static MAC addrs?
autoPinCpus: pin hosts to (real) cores (requires CPULimitedHost)?
listenPort: base listening port to open; will be incremented for
each additional switch in the net if inNamespace=False
waitConnected: wait for switches to Connect?
(False; True/None=wait indefinitely; time(s)=timed wait)"""
each additional switch in the net if inNamespace=False"""
self.topo = topo
self.switch = switch
self.host = host
@@ -177,9 +175,10 @@ class Mininet( object ):
if topo and build:
self.build()
def waitConnected( self, timeout=None, delay=.5 ):
"""wait for each switch to connect to a controller
timeout: time to wait, or None or True to wait indefinitely
def waitConnected( self, timeout=5, delay=.5 ):
"""wait for each switch to connect to a controller,
up to 5 seconds
timeout: time to wait, or None to wait indefinitely
delay: seconds to sleep per iteration
returns: True if all switches are connected"""
info( '*** Waiting for switches to connect\n' )
@@ -193,8 +192,7 @@ class Mininet( object ):
if not remaining:
info( '\n' )
return True
# Still allow None to preserve 2.2 behavior
if timeout not in ( None, True ) and time > timeout:
if timeout is not None and time > timeout:
break
sleep( delay )
time += delay
+20 -14
View File
@@ -1505,26 +1505,32 @@ class NOX( Controller ):
Controller.__init__( self, name,
command=noxCoreDir + '/nox_core',
cargs='--libdir=/usr/local/lib -v '
'-i ptcp:%s ' +
cargs='--libdir=/usr/local/lib -v -i ptcp:%s ' +
' '.join( noxArgs ),
cdir=noxCoreDir,
**kwargs )
class Ryu( Controller ):
"Ryu OpenFlow Controller"
def __init__( self, name, ryuArgs='ryu.app.simple_switch',
command='ryu run', **kwargs ):
"Controller to run Ryu application"
def __init__( self, name, *ryuArgs, **kwargs ):
"""Init.
name: name to give controller.
ryuArgs: modules to pass to Ryu (ryu.app.simple_switch)
command: comand to run Ryu ('ryu run')"""
if isinstance( ryuArgs, ( list, tuple ) ):
ryuArgs = ' '.join( ryuArgs )
cargs = kwargs.pop(
'cargs', ryuArgs + ' --ofp-tcp-listen-port %s' )
Controller.__init__( self, name, command=command,
cargs=cargs, **kwargs )
name: name to give controller.
ryuArgs: arguments and modules to pass to Ryu"""
homeDir = quietRun( 'printenv HOME' ).strip( '\r\n' )
ryuCoreDir = '%s/ryu/ryu/app/' % homeDir
if not ryuArgs:
warn( 'warning: no Ryu modules specified; '
'running simple_switch only\n' )
ryuArgs = [ ryuCoreDir + 'simple_switch.py' ]
elif not isinstance( ryuArgs, ( list, tuple ) ):
ryuArgs = [ ryuArgs ]
Controller.__init__( self, name,
command='ryu-manager',
cargs='--ofp-tcp-listen-port %s ' +
' '.join( ryuArgs ),
cdir=ryuCoreDir,
**kwargs )
class RemoteController( Controller ):
+3 -9
View File
@@ -164,9 +164,7 @@ function mn_deps {
if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
$install gcc make socat psmisc xterm openssh-clients iperf \
iproute telnet python-setuptools libcgroup-tools \
ethtool help2man net-tools
$install ${PYPKG}-pyflakes pylint ${PYPKG}-pep8-naming \
${PYPKG}-pexpect
ethtool help2man pyflakes pylint python-pep8 python-pexpect
elif [ "$DIST" = "SUSE LINUX" ]; then
$install gcc make socat psmisc xterm openssh iperf \
iproute telnet ${PYPKG}-setuptools libcgroup-tools \
@@ -207,11 +205,10 @@ function mn_deps {
# Install Mininet documentation dependencies
function mn_doc {
echo "Installing Mininet documentation dependencies"
$install doxygen texlive-fonts-recommended
$install doxygen doxypy texlive-fonts-recommended
if ! $install doxygen-latex; then
echo "doxygen-latex not needed"
fi
sudo pip install doxypy
}
# The following will cause a full OF install, covering:
@@ -410,10 +407,7 @@ function ovs {
echo "Installing Open vSwitch..."
if [ "$DIST" = "Fedora" -o "$DIST" = "RedHatEnterpriseServer" ]; then
$install openvswitch
if ! $install openvswitch-controller; then
echo "openvswitch-controller not installed"
fi
$install openvswitch openvswitch-controller
return
fi