diff --git a/mininet/nodelib.py b/mininet/nodelib.py index 3212e58..84f39b1 100644 --- a/mininet/nodelib.py +++ b/mininet/nodelib.py @@ -73,18 +73,17 @@ class LinuxBridge( Switch ): class NAT( Node ): "NAT: Provides connectivity to external network" - def __init__( self, name, inetIntf=None, subnet='10.0/8', + 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) 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""" @@ -93,9 +92,9 @@ 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 @@ -109,9 +108,9 @@ class NAT( Node ): 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' ) @@ -130,18 +129,6 @@ 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" # Remote NAT rules @@ -150,9 +137,9 @@ class NAT( Node ): self.cmd( 'iptables -D FORWARD', '-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' ) self.cmd( 'iptables -D FORWARD', - '-i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' ) + '-o', self.localIntf, '-d', self.subnet,'-j ACCEPT' ) self.cmd( 'iptables -t nat -D POSTROUTING', - '-o', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' ) - # Instruct the kernel to stop forwarding - self.cmd( 'sysctl net.ipv4.ip_forward=0' ) + '-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()