Add port forwarding using iptables
By default, we now forward the following ports from
port on eth0 to port+N on onosN:
8101 (KarafPort)
8181 (GUIPort) (also REST)
6643 (OpenFlowPort)
Note: this will not work if your default interface is
called something other than eth0.
Also: added null topology so we can use onos.py to control
an external/hardware network.
Bugs: it seems that iptables isn't cleaned up completely -
Mininet's NAT element may be to blame.
Change-Id: I2197194100a77ebfddd0d38ad5194ad7569ceba3
diff --git a/tools/dev/mininet/onos.py b/tools/dev/mininet/onos.py
index 9640837..6e66f26 100755
--- a/tools/dev/mininet/onos.py
+++ b/tools/dev/mininet/onos.py
@@ -20,7 +20,7 @@
mn --custom onos.py --controller onos,3 \
--switch onosuser --topo torus,4,4
-Currently you meed to specify a custom switch class
+Currently you meed to use a custom switch class
because Mininet's Switch() class does't (yet?) handle
controllers with multiple IP addresses directly.
@@ -59,7 +59,9 @@
### ONOS Environment
-KarafPort = 8101 # ssh port indicating karaf is running
+KarafPort = 8101 # ssh port indicating karaf is running
+GUIPort = 8181 # GUI/REST port
+OpenFlowPort = 6653 # OpenFlow port
def defaultUser():
"Return a reasonable default user"
@@ -71,7 +73,6 @@
user = 'nobody'
return user
-
# Module vars, initialized below
HOME = ONOS_ROOT = KARAF_ROOT = ONOS_HOME = ONOS_USER = None
ONOS_APPS = ONOS_WEB_USER = ONOS_WEB_PASS = ONOS_TAR = None
@@ -239,13 +240,13 @@
info( '.' )
time.sleep( 1 )
info( ' ssh-port' )
- waitListening( client=self, server=self, port=8101 )
+ waitListening( server=self, port=KarafPort )
info( ' openflow-port' )
- waitListening( server=self, port=6653 )
+ waitListening( server=self, port=OpenFlowPort )
info( ' client' )
while True:
- result = quietRun( 'echo apps -a | %s -h %s' % ( self.client, self.IP() ),
- shell=True )
+ result = quietRun( 'echo apps -a | %s -h %s' %
+ ( self.client, self.IP() ), shell=True )
if 'openflow' in result:
break
info( '.' )
@@ -265,6 +266,7 @@
"""name: (first parameter)
*args: topology class parameters
ipBase: IP range for ONOS nodes
+ forward: default port forwarding list,
topo: topology class or instance
**kwargs: additional topology parameters"""
args = list( args )
@@ -277,11 +279,13 @@
args = ( 1, )
if not isinstance( topo, Topo ):
topo = RenamedTopo( topo, *args, hnew='onos', **kwargs )
- ipBase = kwargs.pop( 'ipBase', '192.168.123.0/24' )
+ self.ipBase = kwargs.pop( 'ipBase', '192.168.123.0/24' )
+ self.forward = kwargs.pop( 'forward',
+ [ KarafPort, GUIPort, OpenFlowPort ] )
super( ONOSCluster, self ).__init__( name, inNamespace=False )
fixIPTables()
self.env = initONOSEnv()
- self.net = Mininet( topo=topo, ipBase=ipBase,
+ self.net = Mininet( topo=topo, ipBase=self.ipBase,
host=ONOSNode, switch=LinuxBridge,
controller=None )
self.net.addNAT().configDefault()
@@ -296,6 +300,7 @@
for node in self.nodes():
node.start( self.env )
info( '\n' )
+ self.configPortForwarding( ports=self.forward, action='A' )
self.waitStarted()
return
@@ -305,10 +310,12 @@
for node in self.nodes():
info( node )
node.waitStarted()
- info( '*** Waited %.2f seconds for ONOS startup' % ( time.time() - startTime ) )
+ info( '*** Waited %.2f seconds for ONOS startup' %
+ ( time.time() - startTime ) )
def stop( self ):
"Shut down ONOS cluster"
+ self.configPortForwarding( ports=self.forward, action='D' )
for node in self.nodes():
node.stop()
self.net.stop()
@@ -317,6 +324,18 @@
"Return list of ONOS nodes"
return [ h for h in self.net.hosts if isinstance( h, ONOSNode ) ]
+ def configPortForwarding( self, ports=[], intf='eth0', action='A' ):
+ """Start or stop ports on intf to all nodes
+ action: A=add/start, D=delete/stop (default: A)"""
+ for port in ports:
+ for index, node in enumerate( self.nodes() ):
+ ip, inport = node.IP(), port + index
+ # Configure a destination NAT rule
+ cmd = ( 'iptables -t nat -{action} PREROUTING -t nat '
+ '-i {intf} -p tcp --dport {inport} '
+ '-j DNAT --to-destination {ip}:{port}' )
+ self.cmd( cmd.format( **locals() ) )
+
class ONOSSwitchMixin( object ):
"Mixin for switches that connect to an ONOSCluster"
@@ -413,6 +432,9 @@
'onosuser': ONOSUserSwitch,
'default': ONOSOVSSwitch }
+# Null topology so we can control an external/hardware network
+topos = { 'none': Topo }
+
if __name__ == '__main__':
if len( argv ) != 2:
test( 3 )