Committed by
Bob Lantz
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
Showing
1 changed file
with
32 additions
and
10 deletions
... | @@ -20,7 +20,7 @@ Or with the user switch (or CPqD if installed): | ... | @@ -20,7 +20,7 @@ Or with the user switch (or CPqD if installed): |
20 | mn --custom onos.py --controller onos,3 \ | 20 | mn --custom onos.py --controller onos,3 \ |
21 | --switch onosuser --topo torus,4,4 | 21 | --switch onosuser --topo torus,4,4 |
22 | 22 | ||
23 | -Currently you meed to specify a custom switch class | 23 | +Currently you meed to use a custom switch class |
24 | because Mininet's Switch() class does't (yet?) handle | 24 | because Mininet's Switch() class does't (yet?) handle |
25 | controllers with multiple IP addresses directly. | 25 | controllers with multiple IP addresses directly. |
26 | 26 | ||
... | @@ -59,7 +59,9 @@ import time | ... | @@ -59,7 +59,9 @@ import time |
59 | 59 | ||
60 | ### ONOS Environment | 60 | ### ONOS Environment |
61 | 61 | ||
62 | -KarafPort = 8101 # ssh port indicating karaf is running | 62 | +KarafPort = 8101 # ssh port indicating karaf is running |
63 | +GUIPort = 8181 # GUI/REST port | ||
64 | +OpenFlowPort = 6653 # OpenFlow port | ||
63 | 65 | ||
64 | def defaultUser(): | 66 | def defaultUser(): |
65 | "Return a reasonable default user" | 67 | "Return a reasonable default user" |
... | @@ -71,7 +73,6 @@ def defaultUser(): | ... | @@ -71,7 +73,6 @@ def defaultUser(): |
71 | user = 'nobody' | 73 | user = 'nobody' |
72 | return user | 74 | return user |
73 | 75 | ||
74 | - | ||
75 | # Module vars, initialized below | 76 | # Module vars, initialized below |
76 | HOME = ONOS_ROOT = KARAF_ROOT = ONOS_HOME = ONOS_USER = None | 77 | HOME = ONOS_ROOT = KARAF_ROOT = ONOS_HOME = ONOS_USER = None |
77 | ONOS_APPS = ONOS_WEB_USER = ONOS_WEB_PASS = ONOS_TAR = None | 78 | ONOS_APPS = ONOS_WEB_USER = ONOS_WEB_PASS = ONOS_TAR = None |
... | @@ -239,13 +240,13 @@ class ONOSNode( Controller ): | ... | @@ -239,13 +240,13 @@ class ONOSNode( Controller ): |
239 | info( '.' ) | 240 | info( '.' ) |
240 | time.sleep( 1 ) | 241 | time.sleep( 1 ) |
241 | info( ' ssh-port' ) | 242 | info( ' ssh-port' ) |
242 | - waitListening( client=self, server=self, port=8101 ) | 243 | + waitListening( server=self, port=KarafPort ) |
243 | info( ' openflow-port' ) | 244 | info( ' openflow-port' ) |
244 | - waitListening( server=self, port=6653 ) | 245 | + waitListening( server=self, port=OpenFlowPort ) |
245 | info( ' client' ) | 246 | info( ' client' ) |
246 | while True: | 247 | while True: |
247 | - result = quietRun( 'echo apps -a | %s -h %s' % ( self.client, self.IP() ), | 248 | + result = quietRun( 'echo apps -a | %s -h %s' % |
248 | - shell=True ) | 249 | + ( self.client, self.IP() ), shell=True ) |
249 | if 'openflow' in result: | 250 | if 'openflow' in result: |
250 | break | 251 | break |
251 | info( '.' ) | 252 | info( '.' ) |
... | @@ -265,6 +266,7 @@ class ONOSCluster( Controller ): | ... | @@ -265,6 +266,7 @@ class ONOSCluster( Controller ): |
265 | """name: (first parameter) | 266 | """name: (first parameter) |
266 | *args: topology class parameters | 267 | *args: topology class parameters |
267 | ipBase: IP range for ONOS nodes | 268 | ipBase: IP range for ONOS nodes |
269 | + forward: default port forwarding list, | ||
268 | topo: topology class or instance | 270 | topo: topology class or instance |
269 | **kwargs: additional topology parameters""" | 271 | **kwargs: additional topology parameters""" |
270 | args = list( args ) | 272 | args = list( args ) |
... | @@ -277,11 +279,13 @@ class ONOSCluster( Controller ): | ... | @@ -277,11 +279,13 @@ class ONOSCluster( Controller ): |
277 | args = ( 1, ) | 279 | args = ( 1, ) |
278 | if not isinstance( topo, Topo ): | 280 | if not isinstance( topo, Topo ): |
279 | topo = RenamedTopo( topo, *args, hnew='onos', **kwargs ) | 281 | topo = RenamedTopo( topo, *args, hnew='onos', **kwargs ) |
280 | - ipBase = kwargs.pop( 'ipBase', '192.168.123.0/24' ) | 282 | + self.ipBase = kwargs.pop( 'ipBase', '192.168.123.0/24' ) |
283 | + self.forward = kwargs.pop( 'forward', | ||
284 | + [ KarafPort, GUIPort, OpenFlowPort ] ) | ||
281 | super( ONOSCluster, self ).__init__( name, inNamespace=False ) | 285 | super( ONOSCluster, self ).__init__( name, inNamespace=False ) |
282 | fixIPTables() | 286 | fixIPTables() |
283 | self.env = initONOSEnv() | 287 | self.env = initONOSEnv() |
284 | - self.net = Mininet( topo=topo, ipBase=ipBase, | 288 | + self.net = Mininet( topo=topo, ipBase=self.ipBase, |
285 | host=ONOSNode, switch=LinuxBridge, | 289 | host=ONOSNode, switch=LinuxBridge, |
286 | controller=None ) | 290 | controller=None ) |
287 | self.net.addNAT().configDefault() | 291 | self.net.addNAT().configDefault() |
... | @@ -296,6 +300,7 @@ class ONOSCluster( Controller ): | ... | @@ -296,6 +300,7 @@ class ONOSCluster( Controller ): |
296 | for node in self.nodes(): | 300 | for node in self.nodes(): |
297 | node.start( self.env ) | 301 | node.start( self.env ) |
298 | info( '\n' ) | 302 | info( '\n' ) |
303 | + self.configPortForwarding( ports=self.forward, action='A' ) | ||
299 | self.waitStarted() | 304 | self.waitStarted() |
300 | return | 305 | return |
301 | 306 | ||
... | @@ -305,10 +310,12 @@ class ONOSCluster( Controller ): | ... | @@ -305,10 +310,12 @@ class ONOSCluster( Controller ): |
305 | for node in self.nodes(): | 310 | for node in self.nodes(): |
306 | info( node ) | 311 | info( node ) |
307 | node.waitStarted() | 312 | node.waitStarted() |
308 | - info( '*** Waited %.2f seconds for ONOS startup' % ( time.time() - startTime ) ) | 313 | + info( '*** Waited %.2f seconds for ONOS startup' % |
314 | + ( time.time() - startTime ) ) | ||
309 | 315 | ||
310 | def stop( self ): | 316 | def stop( self ): |
311 | "Shut down ONOS cluster" | 317 | "Shut down ONOS cluster" |
318 | + self.configPortForwarding( ports=self.forward, action='D' ) | ||
312 | for node in self.nodes(): | 319 | for node in self.nodes(): |
313 | node.stop() | 320 | node.stop() |
314 | self.net.stop() | 321 | self.net.stop() |
... | @@ -317,6 +324,18 @@ class ONOSCluster( Controller ): | ... | @@ -317,6 +324,18 @@ class ONOSCluster( Controller ): |
317 | "Return list of ONOS nodes" | 324 | "Return list of ONOS nodes" |
318 | return [ h for h in self.net.hosts if isinstance( h, ONOSNode ) ] | 325 | return [ h for h in self.net.hosts if isinstance( h, ONOSNode ) ] |
319 | 326 | ||
327 | + def configPortForwarding( self, ports=[], intf='eth0', action='A' ): | ||
328 | + """Start or stop ports on intf to all nodes | ||
329 | + action: A=add/start, D=delete/stop (default: A)""" | ||
330 | + for port in ports: | ||
331 | + for index, node in enumerate( self.nodes() ): | ||
332 | + ip, inport = node.IP(), port + index | ||
333 | + # Configure a destination NAT rule | ||
334 | + cmd = ( 'iptables -t nat -{action} PREROUTING -t nat ' | ||
335 | + '-i {intf} -p tcp --dport {inport} ' | ||
336 | + '-j DNAT --to-destination {ip}:{port}' ) | ||
337 | + self.cmd( cmd.format( **locals() ) ) | ||
338 | + | ||
320 | 339 | ||
321 | class ONOSSwitchMixin( object ): | 340 | class ONOSSwitchMixin( object ): |
322 | "Mixin for switches that connect to an ONOSCluster" | 341 | "Mixin for switches that connect to an ONOSCluster" |
... | @@ -413,6 +432,9 @@ switches = { 'onos': ONOSOVSSwitch, | ... | @@ -413,6 +432,9 @@ switches = { 'onos': ONOSOVSSwitch, |
413 | 'onosuser': ONOSUserSwitch, | 432 | 'onosuser': ONOSUserSwitch, |
414 | 'default': ONOSOVSSwitch } | 433 | 'default': ONOSOVSSwitch } |
415 | 434 | ||
435 | +# Null topology so we can control an external/hardware network | ||
436 | +topos = { 'none': Topo } | ||
437 | + | ||
416 | if __name__ == '__main__': | 438 | if __name__ == '__main__': |
417 | if len( argv ) != 2: | 439 | if len( argv ) != 2: |
418 | test( 3 ) | 440 | test( 3 ) | ... | ... |
-
Please register or login to post a comment