mininet / examples / nat.py @ 7c5d2771
History | View | Annotate | Download (3.77 KB)
1 |
#!/usr/bin/python
|
---|---|
2 |
|
3 |
"""
|
4 |
Example to create a Mininet topology and connect it to the internet via NAT
|
5 |
through eth0 on the host.
|
6 |
|
7 |
Glen Gibb, February 2011
|
8 |
|
9 |
(slight modifications by BL, 5/13)
|
10 |
"""
|
11 |
|
12 |
from mininet.cli import CLI |
13 |
from mininet.log import lg |
14 |
from mininet.node import Node |
15 |
from mininet.topolib import TreeNet |
16 |
|
17 |
#################################
|
18 |
def startNAT( root, inetIntf='eth0', subnet='10.0/8' ): |
19 |
"""Start NAT/forwarding between Mininet and external network
|
20 |
root: node to access iptables from
|
21 |
inetIntf: interface for internet access
|
22 |
subnet: Mininet subnet (default 10.0/8)="""
|
23 |
|
24 |
# Identify the interface connecting to the mininet network
|
25 |
localIntf = root.defaultIntf() |
26 |
|
27 |
# Flush any currently active rules
|
28 |
root.cmd( 'iptables -F' )
|
29 |
root.cmd( 'iptables -t nat -F' )
|
30 |
|
31 |
# Create default entries for unmatched traffic
|
32 |
root.cmd( 'iptables -P INPUT ACCEPT' )
|
33 |
root.cmd( 'iptables -P OUTPUT ACCEPT' )
|
34 |
root.cmd( 'iptables -P FORWARD DROP' )
|
35 |
|
36 |
# Configure NAT
|
37 |
root.cmd( 'iptables -I FORWARD -i', localIntf, '-d', subnet, '-j DROP' ) |
38 |
root.cmd( 'iptables -A FORWARD -i', localIntf, '-s', subnet, '-j ACCEPT' ) |
39 |
root.cmd( 'iptables -A FORWARD -i', inetIntf, '-d', subnet, '-j ACCEPT' ) |
40 |
root.cmd( 'iptables -t nat -A POSTROUTING -o ', inetIntf, '-j MASQUERADE' ) |
41 |
|
42 |
# Instruct the kernel to perform forwarding
|
43 |
root.cmd( 'sysctl net.ipv4.ip_forward=1' )
|
44 |
|
45 |
def stopNAT( root ): |
46 |
"""Stop NAT/forwarding between Mininet and external network"""
|
47 |
# Flush any currently active rules
|
48 |
root.cmd( 'iptables -F' )
|
49 |
root.cmd( 'iptables -t nat -F' )
|
50 |
|
51 |
# Instruct the kernel to stop forwarding
|
52 |
root.cmd( 'sysctl net.ipv4.ip_forward=0' )
|
53 |
|
54 |
def fixNetworkManager( root, intf ): |
55 |
"""Prevent network-manager from messing with our interface,
|
56 |
by specifying manual configuration in /etc/network/interfaces
|
57 |
root: a node in the root namespace (for running commands)
|
58 |
intf: interface name"""
|
59 |
cfile = '/etc/network/interfaces'
|
60 |
line = '\niface %s inet manual\n' % intf
|
61 |
config = open( cfile ).read()
|
62 |
if line not in config: |
63 |
print '*** Adding', line.strip(), 'to', cfile |
64 |
with open( cfile, 'a' ) as f: |
65 |
f.write( line ) |
66 |
# Probably need to restart network-manager to be safe -
|
67 |
# hopefully this won't disconnect you
|
68 |
root.cmd( 'service network-manager restart' )
|
69 |
|
70 |
def connectToInternet( network, switch='s1', rootip='10.254', subnet='10.0/8'): |
71 |
"""Connect the network to the internet
|
72 |
switch: switch to connect to root namespace
|
73 |
rootip: address for interface in root namespace
|
74 |
subnet: Mininet subnet"""
|
75 |
switch = network.get( switch ) |
76 |
prefixLen = subnet.split( '/' )[ 1 ] |
77 |
|
78 |
# Create a node in root namespace
|
79 |
root = Node( 'root', inNamespace=False ) |
80 |
|
81 |
# Prevent network-manager from interfering with our interface
|
82 |
fixNetworkManager( root, 'root-eth0' )
|
83 |
|
84 |
# Create link between root NS and switch
|
85 |
link = network.addLink( root, switch ) |
86 |
link.intf1.setIP( rootip, prefixLen ) |
87 |
|
88 |
# Start network that now includes link to root namespace
|
89 |
network.start() |
90 |
|
91 |
# Start NAT and establish forwarding
|
92 |
startNAT( root ) |
93 |
|
94 |
# Establish routes from end hosts
|
95 |
for host in network.hosts: |
96 |
host.cmd( 'ip route flush root 0/0' )
|
97 |
host.cmd( 'route add -net', subnet, 'dev', host.defaultIntf() ) |
98 |
host.cmd( 'route add default gw', rootip )
|
99 |
|
100 |
return root
|
101 |
|
102 |
if __name__ == '__main__': |
103 |
lg.setLogLevel( 'info')
|
104 |
net = TreeNet( depth=1, fanout=4 ) |
105 |
# Configure and start NATted connectivity
|
106 |
rootnode = connectToInternet( net ) |
107 |
print "*** Hosts are running and should have internet connectivity" |
108 |
print "*** Type 'exit' or control-D to shut down network" |
109 |
CLI( net ) |
110 |
# Shut down NAT
|
111 |
stopNAT( rootnode ) |
112 |
net.stop() |