Statistics
| Branch: | Tag: | Revision:

mininet / examples / nat.py @ 824afb84

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()