Revision 3484389d

View differences:

examples/README
68 68

  
69 69
This example creates a network and runs multiple tests on it.
70 70

  
71
nat.py:
72

  
73
This example shows how to connect a Mininet network to the Internet
74
using NAT. It also answers the eternal question "why can't I ping
75
google?"
76

  
71 77
popen.py:
72 78

  
73 79
This example monitors a number of hosts using host.popen() and
examples/nat.py
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, info
14
from mininet.node import Node
15
from mininet.topolib import TreeNet
16
from mininet.util import quietRun
17

  
18
#################################
19
def startNAT( root, inetIntf='eth0', subnet='10.0/8' ):
20
    """Start NAT/forwarding between Mininet and external network
21
    root: node to access iptables from
22
    inetIntf: interface for internet access
23
    subnet: Mininet subnet (default 10.0/8)="""
24

  
25
    # Identify the interface connecting to the mininet network
26
    localIntf =  root.defaultIntf()
27

  
28
    # Flush any currently active rules
29
    root.cmd( 'iptables -F' )
30
    root.cmd( 'iptables -t nat -F' )
31

  
32
    # Create default entries for unmatched traffic
33
    root.cmd( 'iptables -P INPUT ACCEPT' )
34
    root.cmd( 'iptables -P OUTPUT ACCEPT' )
35
    root.cmd( 'iptables -P FORWARD DROP' )
36

  
37
    # Configure NAT
38
    root.cmd( 'iptables -I FORWARD -i', localIntf, '-d', subnet, '-j DROP' )
39
    root.cmd( 'iptables -A FORWARD -i', localIntf, '-s', subnet, '-j ACCEPT' )
40
    root.cmd( 'iptables -A FORWARD -i', inetIntf, '-d', subnet, '-j ACCEPT' )
41
    root.cmd( 'iptables -t nat -A POSTROUTING -o ', inetIntf, '-j MASQUERADE' )
42

  
43
    # Instruct the kernel to perform forwarding
44
    root.cmd( 'sysctl net.ipv4.ip_forward=1' )
45

  
46
def stopNAT( root ):
47
    """Stop NAT/forwarding between Mininet and external network"""
48
    # Flush any currently active rules
49
    root.cmd( 'iptables -F' )
50
    root.cmd( 'iptables -t nat -F' )
51

  
52
    # Instruct the kernel to stop forwarding
53
    root.cmd( 'sysctl net.ipv4.ip_forward=0' )
54

  
55
def fixNetworkManager( root, intf ):
56
    """Prevent network-manager from messing with our interface,
57
       by specifying manual configuration in /etc/network/interfaces
58
       root: a node in the root namespace (for running commands)
59
       intf: interface name"""
60
    cfile = '/etc/network/interfaces'
61
    line = '\niface %s inet manual\n' % intf
62
    config = open( cfile ).read()
63
    if ( line ) not in config:
64
        print '*** Adding', line.strip(), 'to', cfile
65
        with open( cfile, 'a' ) as f:
66
            f.write( line )
67
    # Probably need to restart network-manager to be safe -
68
    # hopefully this won't disconnect you
69
    root.cmd( 'service network-manager restart' )
70

  
71
def connectToInternet( network, switch='s1', rootip='10.254', subnet='10.0/8'):
72
    """Connect the network to the internet
73
       switch: switch to connect to root namespace
74
       rootip: address for interface in root namespace
75
       subnet: Mininet subnet"""
76
    switch = network.get( switch )
77
    prefixLen = subnet.split( '/' )[ 1 ]
78
    routes = [ subnet ]  # host networks to route to
79

  
80
    # Create a node in root namespace
81
    root = Node( 'root', inNamespace=False )
82

  
83
    # Prevent network-manager from interfering with our interface
84
    fixNetworkManager( root, 'root-eth0' )
85

  
86
    # Create link between root NS and switch
87
    link = network.addLink( root, switch )
88
    link.intf1.setIP( rootip, prefixLen )
89

  
90
    # Start network that now includes link to root namespace
91
    network.start()
92

  
93
    # Start NAT and establish forwarding
94
    startNAT( root )
95

  
96
    # Establish routes from end hosts
97
    for host in network.hosts:
98
        host.cmd( 'ip route flush root 0/0' )
99
        host.cmd( 'route add -net', subnet, 'dev', host.defaultIntf() )
100
        host.cmd( 'route add default gw', rootip )
101

  
102
    return root
103

  
104
if __name__ == '__main__':
105
    lg.setLogLevel( 'info')
106
    net = TreeNet( depth=1, fanout=4 )
107
    # Configure and start NATted connectivity
108
    rootnode = connectToInternet( net )
109
    print "*** Hosts are running and should have internet connectivity"
110
    print "*** Type 'exit' or control-D to shut down network"
111
    CLI( net )
112
    # Shut down NAT
113
    stopNAT( rootnode )
114
    net.stop()

Also available in: Unified diff