Compare commits

...

21 Commits

Author SHA1 Message Date
Brian O'Connor 8df24304d8 Updating OpenFlow default port to 6653
- Pass 6653 to controllers that Mininet starts
- Try to connect first on 6653 for RemoteController, then fallback to 6633

fixes #545
2015-09-22 17:29:50 -07:00
lantz 93b123761b Merge pull request #541 from thinred/master
don't generate .pyc files on some makefile targets
2015-07-29 13:25:32 -07:00
Tomasz Buchert cdbbb5b7a6 don't generate .pyc files on some makefile targets 2015-07-29 17:13:01 +02:00
Bob Lantz 2cb17590c2 Remove blank line
I'm not sure whether we really need to turn off ip_forward before
flushing iptables, but it might possibly be useful to avoid certain
unexpected behavior.
2015-06-25 15:42:22 -07:00
Bob Lantz f7601da006 Change quoting for '!' 2015-06-25 15:38:50 -07:00
lantz 65a0e5f3b6 Merge pull request #528 from pichuang/cluster
Fixed `whoami` output problem in cluster.py
2015-06-25 13:36:21 -07:00
Roan Huang d5d66f1276 Fixed whoami output problem in cluster.py
Remove the last character when use `whoami`
2015-06-25 05:37:20 +00:00
Bob Lantz 9ed14fa0f4 Remove explicit NAT code and use built-in NAT functionality.
This API isn't great - we should try to improve it in the future.
2015-06-23 15:17:58 -07:00
lantz f24ebc438e Merge pull request #530 from jonohart/master
Enable NAT to use all interfaces.
2015-06-23 15:08:47 -07:00
Jonathan Hart 90d50dcbc4 Enable NAT to use all interfaces.
Also put the net.ipv4.ip_forward option back to what it was before on exit,
rather than always setting back to 0.
2015-06-23 13:57:19 -07:00
Bob Lantz 5f68be2273 Remove debug print 2015-06-11 00:16:55 -07:00
Bob Lantz 68ae67dc58 Support custom links in custom file 2015-06-10 20:35:53 -07:00
Bob Lantz c4a85ab1d1 Add flush option to disable flushing iptables 2015-06-10 20:09:29 -07:00
Bob Lantz ef3c885630 Add help regarding --nat [option=val...] 2015-06-10 20:08:44 -07:00
Bob Lantz bb35d04102 Fix TorusTopo for UserSwitch
UserSwitch requires a 12-digit dpid.
2015-06-07 22:10:18 -07:00
Bob Lantz ba05fd363b Warn if bridge netfilter (firewall) is enabled
Newer linux kernels enable filtering on the linux bridge;
this can prevent it from working in mininet!
2015-06-05 16:10:21 -07:00
Brian O'Connor e988b0f660 Merge pull request #522 from mininet/devel/torus
Adding number of hosts per switch option to torus topo
2015-06-05 01:45:01 -07:00
Brian O'Connor b27cce08af Adding number of hosts per switch option to torus topo 2015-05-27 23:45:19 -07:00
Bob Lantz a38896c254 Avoid expanding a string into a list of chars 2015-05-16 08:24:15 -07:00
Bob Lantz 63ae13fcf9 Fix #520 2015-05-12 23:50:37 -07:00
Bob Lantz c5f6d0ff17 Restore use of self.intf (if present) in addLink
fixes #515
2015-05-02 13:16:48 -07:00
8 changed files with 88 additions and 150 deletions
+3 -2
View File
@@ -2,6 +2,7 @@ MININET = mininet/*.py
TEST = mininet/test/*.py
EXAMPLES = mininet/examples/*.py
MN = bin/mn
PYMN = python -B bin/mn
BIN = $(MN)
PYSRC = $(MININET) $(TEST) $(EXAMPLES) $(BIN)
MNEXEC = mnexec
@@ -43,7 +44,7 @@ slowtest: $(MININET)
mininet/examples/test/runner.py -v
mnexec: mnexec.c $(MN) mininet/net.py
cc $(CFLAGS) $(LDFLAGS) -DVERSION=\"`PYTHONPATH=. $(MN) --version`\" $< -o $@
cc $(CFLAGS) $(LDFLAGS) -DVERSION=\"`PYTHONPATH=. $(PYMN) --version`\" $< -o $@
install: $(MNEXEC) $(MANPAGES)
install $(MNEXEC) $(BINDIR)
@@ -60,7 +61,7 @@ man: $(MANPAGES)
mn.1: $(MN)
PYTHONPATH=. help2man -N -n "create a Mininet network." \
--no-discard-stderr $< -o $@
--no-discard-stderr "$(PYMN)" -o $@
mnexec.1: mnexec
help2man -N -n "execution utility for Mininet." \
+2 -2
View File
@@ -158,7 +158,7 @@ class MininetRunner( object ):
def setCustom( self, name, value ):
"Set custom parameters for MininetRunner."
if name in ( 'topos', 'switches', 'hosts', 'controllers' ):
if name in ( 'topos', 'switches', 'hosts', 'controllers', 'links' ):
# Update dictionaries
param = name.upper()
globals()[ param ].update( value )
@@ -238,7 +238,7 @@ class MininetRunner( object ):
default=False, help="pin hosts to CPU cores "
"(requires --host cfs or --host rt)" )
opts.add_option( '--nat', action='callback', callback=self.setNat,
help="adds a NAT to the topology that"
help="[option=val...] adds a NAT to the topology that"
" connects Mininet hosts to the physical network."
" Warning: This may route any traffic on the machine"
" that uses Mininet's"
+1 -1
View File
@@ -103,7 +103,7 @@ def findUser():
# Logged-in user (if we have a tty)
( quietRun( 'who am i' ).split() or [ False ] )[ 0 ] or
# Give up and return effective user
quietRun( 'whoami' ) )
quietRun( 'whoami' ).strip() )
class ClusterCleanup( object ):
+3 -93
View File
@@ -2,11 +2,6 @@
"""
Example to create a Mininet topology and connect it to the internet via NAT
through eth0 on the host.
Glen Gibb, February 2011
(slight modifications by BL, 5/13)
"""
from mininet.cli import CLI
@@ -14,99 +9,14 @@ from mininet.log import lg
from mininet.node import Node
from mininet.topolib import TreeNet
#################################
def startNAT( root, inetIntf='eth0', subnet='10.0/8' ):
"""Start NAT/forwarding between Mininet and external network
root: node to access iptables from
inetIntf: interface for internet access
subnet: Mininet subnet (default 10.0/8)="""
# Identify the interface connecting to the mininet network
localIntf = root.defaultIntf()
# Flush any currently active rules
root.cmd( 'iptables -F' )
root.cmd( 'iptables -t nat -F' )
# Create default entries for unmatched traffic
root.cmd( 'iptables -P INPUT ACCEPT' )
root.cmd( 'iptables -P OUTPUT ACCEPT' )
root.cmd( 'iptables -P FORWARD DROP' )
# Configure NAT
root.cmd( 'iptables -I FORWARD -i', localIntf, '-d', subnet, '-j DROP' )
root.cmd( 'iptables -A FORWARD -i', localIntf, '-s', subnet, '-j ACCEPT' )
root.cmd( 'iptables -A FORWARD -i', inetIntf, '-d', subnet, '-j ACCEPT' )
root.cmd( 'iptables -t nat -A POSTROUTING -o ', inetIntf, '-j MASQUERADE' )
# Instruct the kernel to perform forwarding
root.cmd( 'sysctl net.ipv4.ip_forward=1' )
def stopNAT( root ):
"""Stop NAT/forwarding between Mininet and external network"""
# Flush any currently active rules
root.cmd( 'iptables -F' )
root.cmd( 'iptables -t nat -F' )
# Instruct the kernel to stop forwarding
root.cmd( 'sysctl net.ipv4.ip_forward=0' )
def fixNetworkManager( root, intf ):
"""Prevent network-manager from messing with our interface,
by specifying manual configuration in /etc/network/interfaces
root: a node in the root namespace (for running commands)
intf: interface name"""
cfile = '/etc/network/interfaces'
line = '\niface %s inet manual\n' % intf
config = open( cfile ).read()
if line not in config:
print '*** Adding', line.strip(), 'to', cfile
with open( cfile, 'a' ) as f:
f.write( line )
# Probably need to restart network-manager to be safe -
# hopefully this won't disconnect you
root.cmd( 'service network-manager restart' )
def connectToInternet( network, switch='s1', rootip='10.254', subnet='10.0/8'):
"""Connect the network to the internet
switch: switch to connect to root namespace
rootip: address for interface in root namespace
subnet: Mininet subnet"""
switch = network.get( switch )
prefixLen = subnet.split( '/' )[ 1 ]
# Create a node in root namespace
root = Node( 'root', inNamespace=False )
# Prevent network-manager from interfering with our interface
fixNetworkManager( root, 'root-eth0' )
# Create link between root NS and switch
link = network.addLink( root, switch )
link.intf1.setIP( rootip, prefixLen )
# Start network that now includes link to root namespace
network.start()
# Start NAT and establish forwarding
startNAT( root )
# Establish routes from end hosts
for host in network.hosts:
host.cmd( 'ip route flush root 0/0' )
host.cmd( 'route add -net', subnet, 'dev', host.defaultIntf() )
host.cmd( 'route add default gw', rootip )
return root
if __name__ == '__main__':
lg.setLogLevel( 'info')
net = TreeNet( depth=1, fanout=4 )
# Configure and start NATted connectivity
rootnode = connectToInternet( net )
# Add NAT connectivity
net.addNAT().configDefault()
net.start()
print "*** Hosts are running and should have internet connectivity"
print "*** Type 'exit' or control-D to shut down network"
CLI( net )
# Shut down NAT
stopNAT( rootnode )
net.stop()
+2
View File
@@ -357,6 +357,8 @@ class Mininet( object ):
options.setdefault( 'port1', port1 )
if port2 is not None:
options.setdefault( 'port2', port2 )
if self.intf is not None:
options.setdefault( 'intf', self.intf )
# Set default MAC - this should probably be in Link
options.setdefault( 'addr1', self.randMac() )
options.setdefault( 'addr2', self.randMac() )
+27 -7
View File
@@ -168,6 +168,8 @@ class Node( object ):
def mountPrivateDirs( self ):
"mount private directories"
# Avoid expanding a string into a list of chars
assert not isinstance( self.privateDirs, basestring )
for directory in self.privateDirs:
if isinstance( directory, tuple ):
# mount given private directory
@@ -1143,7 +1145,7 @@ class OVSSwitch( Switch ):
if self.protocols and not self.isOldOVS():
opts += ' protocols=%s' % self.protocols
if self.stp and self.failMode == 'standalone':
opts += ' stp_enable=true' % self
opts += ' stp_enable=true'
return opts
def start( self, controllers ):
@@ -1344,7 +1346,7 @@ class Controller( Node ):
def __init__( self, name, inNamespace=False, command='controller',
cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1",
port=6633, protocol='tcp', **params ):
port=6653, protocol='tcp', **params ):
self.command = command
self.cargs = cargs
self.cdir = cdir
@@ -1478,7 +1480,7 @@ class RemoteController( Controller ):
"Controller running outside of Mininet's control."
def __init__( self, name, ip='127.0.0.1',
port=6633, **kwargs):
port=None, **kwargs):
"""Init.
name: name to give controller
ip: the IP address where the remote controller is
@@ -1496,12 +1498,30 @@ class RemoteController( Controller ):
def checkListening( self ):
"Warn if remote controller is not accessible"
listening = self.cmd( "echo A | telnet -e A %s %d" %
( self.ip, self.port ) )
if self.port is not None:
self.isListening( self.ip, self.port )
else:
for port in [ 6653, 6633 ]:
if self.isListening( self.ip, port ):
self.port = port
info( "Connecting to remote controller"
" at %s:%d\n" % ( self.ip, self.port ))
break
if self.port is None:
self.port = 6653
warn( "Setting remote controller"
" to %s:%d\n" % ( self.ip, self.port ))
def isListening( self, ip, port ):
"Check if a remote controller is listening at a specific ip and port"
listening = self.cmd( "echo A | telnet -e A %s %d" % ( ip, port ) )
if 'Connected' not in listening:
warn( "Unable to contact the remote controller"
" at %s:%d\n" % ( self.ip, self.port ) )
" at %s:%d\n" % ( ip, port ) )
return False
else:
return True
DefaultControllers = ( Controller, OVSController )
+37 -41
View File
@@ -7,6 +7,7 @@ This contains additional Node types which you may find to be useful.
from mininet.node import Node, Switch
from mininet.log import info, warn
from mininet.moduledeps import pathCheck
from mininet.util import quietRun
import re
@@ -59,23 +60,30 @@ class LinuxBridge( Switch ):
@classmethod
def setup( cls ):
"Make sure our class dependencies are available"
"Check dependencies and warn about firewalling"
pathCheck( 'brctl', moduleName='bridge-utils' )
# Disable Linux bridge firewalling so that traffic can flow!
for table in 'arp', 'ip', 'ip6':
cmd = 'sysctl net.bridge.bridge-nf-call-%stables' % table
out = quietRun( cmd ).strip()
if out.endswith( '1' ):
warn( 'Warning: Linux bridge may not work with', out, '\n' )
class NAT( Node ):
"NAT: Provides connectivity to external network"
def __init__( self, name, inetIntf=None, subnet='10.0/8',
localIntf=None, **params):
def __init__( self, name, subnet='10.0/8',
localIntf=None, flush=False, **params):
"""Start NAT/forwarding between Mininet and external network
inetIntf: interface for internet access
subnet: Mininet subnet (default 10.0/8)="""
subnet: Mininet subnet (default 10.0/8)
flush: flush iptables before installing NAT rules"""
super( NAT, self ).__init__( name, **params )
self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
self.subnet = subnet
self.localIntf = localIntf
self.flush = flush
self.forwardState = self.cmd( 'sysctl -n net.ipv4.ip_forward' ).strip()
def config( self, **params ):
"""Configure the NAT and iptables"""
@@ -84,27 +92,24 @@ class NAT( Node ):
if not self.localIntf:
self.localIntf = self.defaultIntf()
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
if self.flush:
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
self.cmd( 'iptables -F' )
self.cmd( 'iptables -t nat -F' )
# Create default entries for unmatched traffic
self.cmd( 'iptables -P INPUT ACCEPT' )
self.cmd( 'iptables -P OUTPUT ACCEPT' )
self.cmd( 'iptables -P FORWARD DROP' )
# Flush any currently active rules
# TODO: is this safe?
self.cmd( 'iptables -F' )
self.cmd( 'iptables -t nat -F' )
# Create default entries for unmatched traffic
self.cmd( 'iptables -P INPUT ACCEPT' )
self.cmd( 'iptables -P OUTPUT ACCEPT' )
self.cmd( 'iptables -P FORWARD DROP' )
# Configure NAT
# Install NAT rules
self.cmd( 'iptables -I FORWARD',
'-i', self.localIntf, '-d', self.subnet, '-j DROP' )
self.cmd( 'iptables -A FORWARD',
'-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
self.cmd( 'iptables -A FORWARD',
'-i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' )
'-o', self.localIntf, '-d', self.subnet,'-j ACCEPT' )
self.cmd( 'iptables -t nat -A POSTROUTING',
'-o', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' )
'-s', self.subnet, "'!'", '-d', self.subnet, '-j MASQUERADE' )
# Instruct the kernel to perform forwarding
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
@@ -123,26 +128,17 @@ class NAT( Node ):
# hopefully this won't disconnect you
self.cmd( 'service network-manager restart' )
def getGatewayIntf( self, fallback='eth0' ):
"""Return gateway interface name
fallback: default device to fall back to"""
routes = self.cmd( 'ip route show' )
match = re.search( r'default via \S+ dev (\S+)', routes )
if match:
return match.group( 1 )
else:
warn( 'There is no default route set.',
'Using', fallback, 'as gateway interface...\n' )
return fallback
def terminate( self ):
"""Stop NAT/forwarding between Mininet and external network"""
# Flush any currently active rules
# TODO: is this safe?
self.cmd( 'iptables -F' )
self.cmd( 'iptables -t nat -F' )
# Instruct the kernel to stop forwarding
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
"Stop NAT/forwarding between Mininet and external network"
# Remote NAT rules
self.cmd( 'iptables -D FORWARD',
'-i', self.localIntf, '-d', self.subnet, '-j DROP' )
self.cmd( 'iptables -D FORWARD',
'-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
self.cmd( 'iptables -D FORWARD',
'-o', self.localIntf, '-d', self.subnet,'-j ACCEPT' )
self.cmd( 'iptables -t nat -D POSTROUTING',
'-s', self.subnet, '\'!\'', '-d', self.subnet, '-j MASQUERADE' )
# Put the forwarding state back to what it was
self.cmd( 'sysctl net.ipv4.ip_forward=%s' % self.forwardState )
super( NAT, self ).terminate()
+13 -4
View File
@@ -45,10 +45,18 @@ class TorusTopo( Topo ):
without STP turned on! It can be used with STP, e.g.:
# mn --topo torus,3,3 --switch lxbr,stp=1 --test pingall"""
def build( self, x, y ):
def build( self, x, y, n=1 ):
"""x: dimension of torus in x-direction
y: dimension of torus in y-direction
n: number of hosts per switch"""
if x < 3 or y < 3:
raise Exception( 'Please use 3x3 or greater for compatibility '
'with 2.1' )
if n == 1:
genHostName = lambda loc, k: 'h%s' % ( loc )
else:
genHostName = lambda loc, k: 'h%sx%d' % ( loc, k )
hosts, switches, dpid = {}, {}, 0
# Create and wire interior
for i in range( 0, x ):
@@ -57,9 +65,10 @@ class TorusTopo( Topo ):
# dpid cannot be zero for OVS
dpid = ( i + 1 ) * 256 + ( j + 1 )
switch = switches[ i, j ] = self.addSwitch(
's' + loc, dpid='%016x' % dpid )
host = hosts[ i, j ] = self.addHost( 'h' + loc )
self.addLink( host, switch )
's' + loc, dpid='%x' % dpid )
for k in range( 0, n ):
host = hosts[ i, j, k ] = self.addHost( genHostName( loc, k + 1 ) )
self.addLink( host, switch )
# Connect switches
for i in range( 0, x ):
for j in range( 0, y ):