Statistics
| Branch: | Tag: | Revision:

mininet / mininet / nodelib.py @ f0f9907b

History | View | Annotate | Download (4.35 KB)

1
"""
2
Node Library for Mininet
3

4
This contains additional Node types which you may find to be useful.
5
"""
6

    
7
from mininet.node import Node, Switch
8
from mininet.log import setLogLevel, info
9
from mininet.moduledeps import pathCheck
10

    
11

    
12
class LinuxBridge( Switch ):
13
    "Linux Bridge (with optional spanning tree)"
14

    
15
    nextPrio = 100  # next bridge priority for spanning tree
16

    
17
    def __init__( self, name, stp=False, prio=None, **kwargs ):
18
        """stp: use spanning tree protocol? (default False)
19
           prio: optional explicit bridge priority for STP"""
20
        self.stp = stp
21
        if prio:
22
            self.prio = prio
23
        else:
24
            self.prio = LinuxBridge.nextPrio
25
            LinuxBridge.nextPrio += 1
26
        Switch.__init__( self, name, **kwargs )
27

    
28
    def connected( self ):
29
        "Are we forwarding yet?"
30
        if self.stp:
31
            return 'forwarding' in self.cmd( 'brctl showstp', self )
32
        else:
33
            return True
34
    
35
    def start( self, controllers ):
36
        "Start Linux bridge"
37
        self.cmd( 'ifconfig', self, 'down' )
38
        self.cmd( 'brctl delbr', self )
39
        self.cmd( 'brctl addbr', self )
40
        if self.stp:
41
            self.cmd( 'brctl setbridgeprio', self.prio )
42
            self.cmd( 'brctl stp', self, 'on' )
43
        for i in self.intfList():
44
            if self.name in i.name:
45
                self.cmd( 'brctl addif', self, i )
46
        self.cmd( 'ifconfig', self, 'up' )
47

    
48
    def stop( self ):
49
        "Stop Linux bridge"
50
        self.cmd( 'ifconfig', self, 'down' )
51
        self.cmd( 'brctl delbr', self )
52

    
53
    def dpctl( self, *args ):
54
        "Run brctl command"
55
        return self.cmd( 'brctl', *args )
56

    
57
    @classmethod
58
    def setup( cls ):
59
        "Make sure our class dependencies are available"
60
        pathCheck( 'brctl', moduleName='bridge-utils' )
61

    
62

    
63
class NAT( Node ):
64
    """NAT: Provides connectivity to external network"""
65

    
66
    def __init__( self, name, inetIntf='eth0', subnet='10.0/8', localIntf=None, **params):
67
        super( NAT, self ).__init__( name, **params )
68

    
69
        """Start NAT/forwarding between Mininet and external network
70
        inetIntf: interface for internet access
71
        subnet: Mininet subnet (default 10.0/8)="""
72
        self.inetIntf = inetIntf
73
        self.subnet = subnet
74
        self.localIntf = localIntf
75

    
76
    def config( self, **params ):
77
        super( NAT, self).config( **params )
78
        """Configure the NAT and iptables"""
79

    
80
        if not self.localIntf:
81
            self.localIntf =  self.defaultIntf()
82

    
83
        self.cmd( 'sysctl net.ipv4.ip_forward=0' )
84

    
85
        # Flush any currently active rules
86
        # TODO: is this safe?
87
        self.cmd( 'iptables -F' )
88
        self.cmd( 'iptables -t nat -F' )
89

    
90
        # Create default entries for unmatched traffic
91
        self.cmd( 'iptables -P INPUT ACCEPT' )
92
        self.cmd( 'iptables -P OUTPUT ACCEPT' )
93
        self.cmd( 'iptables -P FORWARD DROP' )
94

    
95
        # Configure NAT
96
        self.cmd( 'iptables -I FORWARD -i', self.localIntf, '-d', self.subnet, '-j DROP' )
97
        self.cmd( 'iptables -A FORWARD -i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
98
        self.cmd( 'iptables -A FORWARD -i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' )
99
        self.cmd( 'iptables -t nat -A POSTROUTING -o ', self.inetIntf, '-j MASQUERADE' )
100

    
101
        # Instruct the kernel to perform forwarding
102
        self.cmd( 'sysctl net.ipv4.ip_forward=1' )
103

    
104
        # Prevent network-manager from messing with our interface
105
        # by specifying manual configuration in /etc/network/interfaces
106
        intf = self.localIntf
107
        cfile = '/etc/network/interfaces'
108
        line = '\niface %s inet manual\n' % intf
109
        config = open( cfile ).read()
110
        if ( line ) not in config:
111
            info( '*** Adding "' + line.strip() + '" to ' + cfile )
112
            with open( cfile, 'a' ) as f:
113
                f.write( line )
114
        # Probably need to restart network-manager to be safe -
115
        # hopefully this won't disconnect you
116
        self.cmd( 'service network-manager restart' )
117

    
118
    def terminate( self ):
119
        """Stop NAT/forwarding between Mininet and external network"""
120
        # Flush any currently active rules
121
        # TODO: is this safe?
122
        self.cmd( 'iptables -F' )
123
        self.cmd( 'iptables -t nat -F' )
124

    
125
        # Instruct the kernel to stop forwarding
126
        self.cmd( 'sysctl net.ipv4.ip_forward=0' )
127

    
128
        super( NAT, self ).terminate()
129