Updating NAT class to use gateway interface

Also, passing CLI args to NAT constructor

fixes #437
This commit is contained in:
Brian O'Connor
2014-11-24 18:16:57 -08:00
parent 015cd9e776
commit af1ccf93a5
2 changed files with 34 additions and 10 deletions
+19 -5
View File
@@ -32,7 +32,7 @@ from mininet.nodelib import LinuxBridge
from mininet.link import Link, TCLink
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
from mininet.topolib import TreeTopo, TorusTopo
from mininet.util import customConstructor
from mininet.util import customConstructor, splitArgs
from mininet.util import buildTopo
from functools import partial
@@ -168,6 +168,17 @@ class MininetRunner( object ):
# Add or modify global variable or class
globals()[ name ] = value
def setNat( self, option, opt_str, value, parser ):
parser.values.nat = True
if parser.rargs and parser.rargs[ 0 ][ 0 ] != '-': #first arg, first char != '-'
value = parser.rargs.pop( 0 )
_, args, kwargs = splitArgs( opt_str + ',' + value )
parser.values.nat_args = args
parser.values.nat_kwargs = kwargs
else:
parser.values.nat_args = []
parser.values.nat_kwargs = {}
def parseArgs( self ):
"""Parse command-line args and return options object.
returns: opts parse options dict"""
@@ -219,9 +230,12 @@ class MininetRunner( object ):
opts.add_option( '--pin', action='store_true',
default=False, help="pin hosts to CPU cores "
"(requires --host cfs or --host rt)" )
opts.add_option( '--nat', action='store_true',
default=False, help="adds a NAT to the topology "
"that connects Mininet to the physical network" )
opts.add_option( '--nat', action='callback', callback=self.setNat,
help="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"
" IP subnet into the Mininet network. If you need to change"
" Mininet's IP subnet, see the --ipbase option." )
opts.add_option( '--version', action='callback', callback=version,
help='prints the version and exits' )
opts.add_option( '--cluster', type='string', default=None,
@@ -319,7 +333,7 @@ class MininetRunner( object ):
listenPort=listenPort )
if self.options.nat:
nat = mn.addNAT()
nat = mn.addNAT( *self.options.nat_args, **self.options.nat_kwargs )
nat.configDefault()
if self.options.pre:
+15 -5
View File
@@ -5,9 +5,10 @@ This contains additional Node types which you may find to be useful.
"""
from mininet.node import Node, Switch
from mininet.log import info
from mininet.log import info, warn
from mininet.moduledeps import pathCheck
import re
class LinuxBridge( Switch ):
"Linux Bridge (with optional spanning tree)"
@@ -63,13 +64,13 @@ class LinuxBridge( Switch ):
class NAT( Node ):
"""NAT: Provides connectivity to external network"""
def __init__( self, name, inetIntf='eth0', subnet='10.0/8', localIntf=None, **params):
def __init__( self, name, inetIntf=None, subnet='10.0/8', localIntf=None, **params):
super( NAT, self ).__init__( name, **params )
"""Start NAT/forwarding between Mininet and external network
inetIntf: interface for internet access
subnet: Mininet subnet (default 10.0/8)="""
self.inetIntf = inetIntf
self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
self.subnet = subnet
self.localIntf = localIntf
@@ -96,7 +97,7 @@ class NAT( Node ):
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' )
self.cmd( 'iptables -t nat -A POSTROUTING -o ', self.inetIntf, '-j MASQUERADE' )
self.cmd( 'iptables -t nat -A POSTROUTING -o ', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' )
# Instruct the kernel to perform forwarding
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
@@ -108,13 +109,22 @@ class NAT( Node ):
line = '\niface %s inet manual\n' % intf
config = open( cfile ).read()
if ( line ) not in config:
info( '*** Adding "' + line.strip() + '" to ' + cfile )
info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
with open( cfile, 'a' ) as f:
f.write( line )
# Probably need to restart network-manager to be safe -
# hopefully this won't disconnect you
self.cmd( 'service network-manager restart' )
def getGatewayIntf( self ):
routes = self.cmd( 'ip route show' )
match = re.search('default via \S+ dev (\S+)', routes )
if match:
return match.group( 1 )
else:
warn( 'There is no default route set. Using eth0 as gateway interface...\n' )
return 'eth0'
def terminate( self ):
"""Stop NAT/forwarding between Mininet and external network"""
# Flush any currently active rules