Statistics
| Branch: | Tag: | Revision:

mininet / mininet / nodelib.py @ 8014a702

History | View | Annotate | Download (5.09 KB)

1 3878c000 Bob Lantz
"""
2
Node Library for Mininet
3

4 4015e066 Brian O'Connor
This contains additional Node types which you may find to be useful.
5 3878c000 Bob Lantz
"""
6
7 4015e066 Brian O'Connor
from mininet.node import Node, Switch
8 af1ccf93 Brian O'Connor
from mininet.log import info, warn
9 f0f9907b Bob Lantz
from mininet.moduledeps import pathCheck
10
11 af1ccf93 Brian O'Connor
import re
12 3878c000 Bob Lantz
13
class LinuxBridge( Switch ):
14
    "Linux Bridge (with optional spanning tree)"
15
16
    nextPrio = 100  # next bridge priority for spanning tree
17
18
    def __init__( self, name, stp=False, prio=None, **kwargs ):
19
        """stp: use spanning tree protocol? (default False)
20
           prio: optional explicit bridge priority for STP"""
21
        self.stp = stp
22
        if prio:
23
            self.prio = prio
24
        else:
25
            self.prio = LinuxBridge.nextPrio
26
            LinuxBridge.nextPrio += 1
27
        Switch.__init__( self, name, **kwargs )
28
29 ece509d5 Bob Lantz
    def connected( self ):
30
        "Are we forwarding yet?"
31
        if self.stp:
32
            return 'forwarding' in self.cmd( 'brctl showstp', self )
33
        else:
34
            return True
35 5a530af1 Bob Lantz
36 b1ec912d Bob Lantz
    def start( self, _controllers ):
37 f0f9907b Bob Lantz
        "Start Linux bridge"
38 3878c000 Bob Lantz
        self.cmd( 'ifconfig', self, 'down' )
39
        self.cmd( 'brctl delbr', self )
40
        self.cmd( 'brctl addbr', self )
41
        if self.stp:
42
            self.cmd( 'brctl setbridgeprio', self.prio )
43
            self.cmd( 'brctl stp', self, 'on' )
44
        for i in self.intfList():
45
            if self.name in i.name:
46
                self.cmd( 'brctl addif', self, i )
47
        self.cmd( 'ifconfig', self, 'up' )
48
49 d754a7ce Bob Lantz
    def stop( self, deleteIntfs=True ):
50
        """Stop Linux bridge
51
           deleteIntfs: delete interfaces? (True)"""
52 3878c000 Bob Lantz
        self.cmd( 'ifconfig', self, 'down' )
53
        self.cmd( 'brctl delbr', self )
54 d754a7ce Bob Lantz
        super( LinuxBridge, self ).stop( deleteIntfs )
55 3878c000 Bob Lantz
56 f0f9907b Bob Lantz
    def dpctl( self, *args ):
57
        "Run brctl command"
58
        return self.cmd( 'brctl', *args )
59
60
    @classmethod
61
    def setup( cls ):
62
        "Make sure our class dependencies are available"
63
        pathCheck( 'brctl', moduleName='bridge-utils' )
64
65
66 4015e066 Brian O'Connor
class NAT( Node ):
67 b1ec912d Bob Lantz
    "NAT: Provides connectivity to external network"
68 4015e066 Brian O'Connor
69 b1ec912d Bob Lantz
    def __init__( self, name, inetIntf=None, subnet='10.0/8',
70
                  localIntf=None, **params):
71
        """Start NAT/forwarding between Mininet and external network
72
           inetIntf: interface for internet access
73
           subnet: Mininet subnet (default 10.0/8)="""
74 4015e066 Brian O'Connor
        super( NAT, self ).__init__( name, **params )
75
76 af1ccf93 Brian O'Connor
        self.inetIntf = inetIntf if inetIntf else self.getGatewayIntf()
77 4015e066 Brian O'Connor
        self.subnet = subnet
78
        self.localIntf = localIntf
79
80
    def config( self, **params ):
81
        """Configure the NAT and iptables"""
82 b1ec912d Bob Lantz
        super( NAT, self).config( **params )
83 4015e066 Brian O'Connor
84
        if not self.localIntf:
85 7a3159c9 Bob Lantz
            self.localIntf = self.defaultIntf()
86 4015e066 Brian O'Connor
87
        self.cmd( 'sysctl net.ipv4.ip_forward=0' )
88
89
        # Flush any currently active rules
90
        # TODO: is this safe?
91
        self.cmd( 'iptables -F' )
92
        self.cmd( 'iptables -t nat -F' )
93
94
        # Create default entries for unmatched traffic
95
        self.cmd( 'iptables -P INPUT ACCEPT' )
96
        self.cmd( 'iptables -P OUTPUT ACCEPT' )
97
        self.cmd( 'iptables -P FORWARD DROP' )
98
99
        # Configure NAT
100 b1ec912d Bob Lantz
        self.cmd( 'iptables -I FORWARD',
101
                  '-i', self.localIntf, '-d', self.subnet, '-j DROP' )
102
        self.cmd( 'iptables -A FORWARD',
103
                  '-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
104
        self.cmd( 'iptables -A FORWARD',
105
                  '-i', self.inetIntf, '-d', self.subnet, '-j ACCEPT' )
106
        self.cmd( 'iptables -t nat -A POSTROUTING',
107
                  '-o', self.inetIntf, '-s', self.subnet, '-j MASQUERADE' )
108 4015e066 Brian O'Connor
109
        # Instruct the kernel to perform forwarding
110
        self.cmd( 'sysctl net.ipv4.ip_forward=1' )
111
112
        # Prevent network-manager from messing with our interface
113
        # by specifying manual configuration in /etc/network/interfaces
114
        intf = self.localIntf
115
        cfile = '/etc/network/interfaces'
116
        line = '\niface %s inet manual\n' % intf
117
        config = open( cfile ).read()
118
        if ( line ) not in config:
119 af1ccf93 Brian O'Connor
            info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
120 4015e066 Brian O'Connor
            with open( cfile, 'a' ) as f:
121
                f.write( line )
122
        # Probably need to restart network-manager to be safe -
123
        # hopefully this won't disconnect you
124
        self.cmd( 'service network-manager restart' )
125
126 b1ec912d Bob Lantz
    def getGatewayIntf( self, fallback='eth0' ):
127
        """Return gateway interface name
128
           fallback: default device to fall back to"""
129 af1ccf93 Brian O'Connor
        routes = self.cmd( 'ip route show' )
130 b1ec912d Bob Lantz
        match = re.search( r'default via \S+ dev (\S+)', routes )
131 af1ccf93 Brian O'Connor
        if match:
132
            return match.group( 1 )
133
        else:
134 b1ec912d Bob Lantz
            warn( 'There is no default route set.',
135
                  'Using', fallback, 'as gateway interface...\n' )
136
            return fallback
137 af1ccf93 Brian O'Connor
138 4015e066 Brian O'Connor
    def terminate( self ):
139
        """Stop NAT/forwarding between Mininet and external network"""
140
        # Flush any currently active rules
141
        # TODO: is this safe?
142
        self.cmd( 'iptables -F' )
143
        self.cmd( 'iptables -t nat -F' )
144
145
        # Instruct the kernel to stop forwarding
146
        self.cmd( 'sysctl net.ipv4.ip_forward=0' )
147
148
        super( NAT, self ).terminate()