Last active
May 15, 2024 12:25
-
-
Save lantz/5640610 to your computer and use it in GitHub Desktop.
Script to set up NAT with Mininet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
Example to create a Mininet topology and connect it to the internet via NAT | |
through eth0 on the host. | |
Glen Gibb, February 2011 | |
(slight modifications by BL, 5/13) | |
""" | |
from mininet.cli import CLI | |
from mininet.log import lg, info | |
from mininet.node import Node | |
from mininet.topolib import TreeNet | |
from mininet.util import quietRun | |
################################# | |
def startNAT( root, inetIntf='eth0', subnet='10.0/8' ): | |
"""Start NAT/forwarding between Mininet and external network | |
root: node to access iptables from | |
inetIntf: interface for internet access | |
subnet: Mininet subnet (default 10.0/8)=""" | |
# Identify the interface connecting to the mininet network | |
localIntf = root.defaultIntf() | |
# Flush any currently active rules | |
root.cmd( 'iptables -F' ) | |
root.cmd( 'iptables -t nat -F' ) | |
# Create default entries for unmatched traffic | |
root.cmd( 'iptables -P INPUT ACCEPT' ) | |
root.cmd( 'iptables -P OUTPUT ACCEPT' ) | |
root.cmd( 'iptables -P FORWARD DROP' ) | |
# Configure NAT | |
root.cmd( 'iptables -I FORWARD -i', localIntf, '-d', subnet, '-j DROP' ) | |
root.cmd( 'iptables -A FORWARD -i', localIntf, '-s', subnet, '-j ACCEPT' ) | |
root.cmd( 'iptables -A FORWARD -i', inetIntf, '-d', subnet, '-j ACCEPT' ) | |
root.cmd( 'iptables -t nat -A POSTROUTING -o ', inetIntf, '-j MASQUERADE' ) | |
# Instruct the kernel to perform forwarding | |
root.cmd( 'sysctl net.ipv4.ip_forward=1' ) | |
def stopNAT( root ): | |
"""Stop NAT/forwarding between Mininet and external network""" | |
# Flush any currently active rules | |
root.cmd( 'iptables -F' ) | |
root.cmd( 'iptables -t nat -F' ) | |
# Instruct the kernel to stop forwarding | |
root.cmd( 'sysctl net.ipv4.ip_forward=0' ) | |
def fixNetworkManager( root, intf ): | |
"""Prevent network-manager from messing with our interface, | |
by specifying manual configuration in /etc/network/interfaces | |
root: a node in the root namespace (for running commands) | |
intf: interface name""" | |
cfile = '/etc/network/interfaces' | |
line = '\niface %s inet manual\n' % intf | |
config = open( cfile ).read() | |
if ( line ) not in config: | |
print '*** Adding', line.strip(), 'to', cfile | |
with open( cfile, 'a' ) as f: | |
f.write( line ) | |
# Probably need to restart network-manager to be safe - | |
# hopefully this won't disconnect you | |
root.cmd( 'service network-manager restart' ) | |
def connectToInternet( network, switch='s1', rootip='10.254', subnet='10.0/8'): | |
"""Connect the network to the internet | |
switch: switch to connect to root namespace | |
rootip: address for interface in root namespace | |
subnet: Mininet subnet""" | |
switch = network.get( switch ) | |
prefixLen = subnet.split( '/' )[ 1 ] | |
routes = [ subnet ] # host networks to route to | |
# Create a node in root namespace | |
root = Node( 'root', inNamespace=False ) | |
# Prevent network-manager from interfering with our interface | |
fixNetworkManager( root, 'root-eth0' ) | |
# Create link between root NS and switch | |
link = network.addLink( root, switch ) | |
link.intf1.setIP( rootip, prefixLen ) | |
# Start network that now includes link to root namespace | |
network.start() | |
# Start NAT and establish forwarding | |
startNAT( root ) | |
# Establish routes from end hosts | |
for host in network.hosts: | |
host.cmd( 'ip route flush root 0/0' ) | |
host.cmd( 'route add -net', subnet, 'dev', host.defaultIntf() ) | |
host.cmd( 'route add default gw', rootip ) | |
return root | |
if __name__ == '__main__': | |
lg.setLogLevel( 'info') | |
net = TreeNet( depth=1, fanout=4 ) | |
# Configure and start NATted connectivity | |
rootnode = connectToInternet( net ) | |
print "*** Hosts are running and should have internet connectivity" | |
print "*** Type 'exit' or control-D to shut down network" | |
CLI( net ) | |
# Shut down NAT | |
stopNAT( rootnode ) | |
net.stop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment