Merge pull request #452 from mininet/nat-cmd
Updating NAT class to use gateway interface
This commit is contained in:
@@ -32,7 +32,7 @@ from mininet.nodelib import LinuxBridge
|
|||||||
from mininet.link import Link, TCLink
|
from mininet.link import Link, TCLink
|
||||||
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
||||||
from mininet.topolib import TreeTopo, TorusTopo
|
from mininet.topolib import TreeTopo, TorusTopo
|
||||||
from mininet.util import customConstructor
|
from mininet.util import customConstructor, splitArgs
|
||||||
from mininet.util import buildTopo
|
from mininet.util import buildTopo
|
||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@@ -168,6 +168,17 @@ class MininetRunner( object ):
|
|||||||
# Add or modify global variable or class
|
# Add or modify global variable or class
|
||||||
globals()[ name ] = value
|
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 ):
|
def parseArgs( self ):
|
||||||
"""Parse command-line args and return options object.
|
"""Parse command-line args and return options object.
|
||||||
returns: opts parse options dict"""
|
returns: opts parse options dict"""
|
||||||
@@ -219,9 +230,12 @@ class MininetRunner( object ):
|
|||||||
opts.add_option( '--pin', action='store_true',
|
opts.add_option( '--pin', action='store_true',
|
||||||
default=False, help="pin hosts to CPU cores "
|
default=False, help="pin hosts to CPU cores "
|
||||||
"(requires --host cfs or --host rt)" )
|
"(requires --host cfs or --host rt)" )
|
||||||
opts.add_option( '--nat', action='store_true',
|
opts.add_option( '--nat', action='callback', callback=self.setNat,
|
||||||
default=False, help="adds a NAT to the topology "
|
help="adds a NAT to the topology that connects Mininet hosts"
|
||||||
"that connects Mininet to the physical network" )
|
" 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,
|
opts.add_option( '--version', action='callback', callback=version,
|
||||||
help='prints the version and exits' )
|
help='prints the version and exits' )
|
||||||
opts.add_option( '--cluster', type='string', default=None,
|
opts.add_option( '--cluster', type='string', default=None,
|
||||||
@@ -318,8 +332,8 @@ class MininetRunner( object ):
|
|||||||
autoStaticArp=arp, autoPinCpus=pin,
|
autoStaticArp=arp, autoPinCpus=pin,
|
||||||
listenPort=listenPort )
|
listenPort=listenPort )
|
||||||
|
|
||||||
if self.options.nat:
|
if self.options.ensure_value( 'nat', False ):
|
||||||
nat = mn.addNAT()
|
nat = mn.addNAT( *self.options.nat_args, **self.options.nat_kwargs )
|
||||||
nat.configDefault()
|
nat.configDefault()
|
||||||
|
|
||||||
if self.options.pre:
|
if self.options.pre:
|
||||||
|
|||||||
+15
-5
@@ -5,9 +5,10 @@ This contains additional Node types which you may find to be useful.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from mininet.node import Node, Switch
|
from mininet.node import Node, Switch
|
||||||
from mininet.log import info
|
from mininet.log import info, warn
|
||||||
from mininet.moduledeps import pathCheck
|
from mininet.moduledeps import pathCheck
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
class LinuxBridge( Switch ):
|
class LinuxBridge( Switch ):
|
||||||
"Linux Bridge (with optional spanning tree)"
|
"Linux Bridge (with optional spanning tree)"
|
||||||
@@ -63,13 +64,13 @@ class LinuxBridge( Switch ):
|
|||||||
class NAT( Node ):
|
class NAT( Node ):
|
||||||
"""NAT: Provides connectivity to external network"""
|
"""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 )
|
super( NAT, self ).__init__( name, **params )
|
||||||
|
|
||||||
"""Start NAT/forwarding between Mininet and external network
|
"""Start NAT/forwarding between Mininet and external network
|
||||||
inetIntf: interface for internet access
|
inetIntf: interface for internet access
|
||||||
subnet: Mininet subnet (default 10.0/8)="""
|
subnet: Mininet subnet (default 10.0/8)="""
|
||||||
self.inetIntf = inetIntf
|
self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
|
||||||
self.subnet = subnet
|
self.subnet = subnet
|
||||||
self.localIntf = localIntf
|
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 -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.localIntf, '-s', self.subnet, '-j ACCEPT' )
|
||||||
self.cmd( 'iptables -A FORWARD -i', self.inetIntf, '-d', 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
|
# Instruct the kernel to perform forwarding
|
||||||
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
||||||
@@ -108,13 +109,22 @@ class NAT( Node ):
|
|||||||
line = '\niface %s inet manual\n' % intf
|
line = '\niface %s inet manual\n' % intf
|
||||||
config = open( cfile ).read()
|
config = open( cfile ).read()
|
||||||
if ( line ) not in config:
|
if ( line ) not in config:
|
||||||
info( '*** Adding "' + line.strip() + '" to ' + cfile )
|
info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
|
||||||
with open( cfile, 'a' ) as f:
|
with open( cfile, 'a' ) as f:
|
||||||
f.write( line )
|
f.write( line )
|
||||||
# Probably need to restart network-manager to be safe -
|
# Probably need to restart network-manager to be safe -
|
||||||
# hopefully this won't disconnect you
|
# hopefully this won't disconnect you
|
||||||
self.cmd( 'service network-manager restart' )
|
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 ):
|
def terminate( self ):
|
||||||
"""Stop NAT/forwarding between Mininet and external network"""
|
"""Stop NAT/forwarding between Mininet and external network"""
|
||||||
# Flush any currently active rules
|
# Flush any currently active rules
|
||||||
|
|||||||
Reference in New Issue
Block a user