Statistics
| Branch: | Tag: | Revision:

mininet / mininet / nodelib.py @ master

History | View | Annotate | Download (5.38 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 ba05fd36 Bob Lantz
from mininet.util import quietRun
11 f0f9907b Bob Lantz
12 af1ccf93 Brian O'Connor
import re
13 3878c000 Bob Lantz
14
class LinuxBridge( Switch ):
15
    "Linux Bridge (with optional spanning tree)"
16
17
    nextPrio = 100  # next bridge priority for spanning tree
18
19
    def __init__( self, name, stp=False, prio=None, **kwargs ):
20
        """stp: use spanning tree protocol? (default False)
21
           prio: optional explicit bridge priority for STP"""
22
        self.stp = stp
23
        if prio:
24
            self.prio = prio
25
        else:
26
            self.prio = LinuxBridge.nextPrio
27
            LinuxBridge.nextPrio += 1
28
        Switch.__init__( self, name, **kwargs )
29
30 ece509d5 Bob Lantz
    def connected( self ):
31
        "Are we forwarding yet?"
32
        if self.stp:
33
            return 'forwarding' in self.cmd( 'brctl showstp', self )
34
        else:
35
            return True
36 5a530af1 Bob Lantz
37 b1ec912d Bob Lantz
    def start( self, _controllers ):
38 f0f9907b Bob Lantz
        "Start Linux bridge"
39 3878c000 Bob Lantz
        self.cmd( 'ifconfig', self, 'down' )
40
        self.cmd( 'brctl delbr', self )
41
        self.cmd( 'brctl addbr', self )
42
        if self.stp:
43
            self.cmd( 'brctl setbridgeprio', self.prio )
44
            self.cmd( 'brctl stp', self, 'on' )
45
        for i in self.intfList():
46
            if self.name in i.name:
47
                self.cmd( 'brctl addif', self, i )
48
        self.cmd( 'ifconfig', self, 'up' )
49
50 d754a7ce Bob Lantz
    def stop( self, deleteIntfs=True ):
51
        """Stop Linux bridge
52
           deleteIntfs: delete interfaces? (True)"""
53 3878c000 Bob Lantz
        self.cmd( 'ifconfig', self, 'down' )
54
        self.cmd( 'brctl delbr', self )
55 d754a7ce Bob Lantz
        super( LinuxBridge, self ).stop( deleteIntfs )
56 3878c000 Bob Lantz
57 f0f9907b Bob Lantz
    def dpctl( self, *args ):
58
        "Run brctl command"
59
        return self.cmd( 'brctl', *args )
60
61
    @classmethod
62
    def setup( cls ):
63 ba05fd36 Bob Lantz
        "Check dependencies and warn about firewalling"
64 f0f9907b Bob Lantz
        pathCheck( 'brctl', moduleName='bridge-utils' )
65 ba05fd36 Bob Lantz
        # Disable Linux bridge firewalling so that traffic can flow!
66
        for table in 'arp', 'ip', 'ip6':
67
            cmd = 'sysctl net.bridge.bridge-nf-call-%stables' % table
68
            out = quietRun( cmd ).strip()
69
            if out.endswith( '1' ):
70
                warn( 'Warning: Linux bridge may not work with', out, '\n' )
71 f0f9907b Bob Lantz
72
73 4015e066 Brian O'Connor
class NAT( Node ):
74 b1ec912d Bob Lantz
    "NAT: Provides connectivity to external network"
75 4015e066 Brian O'Connor
76 90d50dcb Jonathan Hart
    def __init__( self, name, subnet='10.0/8',
77 c4a85ab1 Bob Lantz
                  localIntf=None, flush=False, **params):
78 b1ec912d Bob Lantz
        """Start NAT/forwarding between Mininet and external network
79 c4a85ab1 Bob Lantz
           subnet: Mininet subnet (default 10.0/8)
80
           flush: flush iptables before installing NAT rules"""
81 4015e066 Brian O'Connor
        super( NAT, self ).__init__( name, **params )
82
83
        self.subnet = subnet
84
        self.localIntf = localIntf
85 c4a85ab1 Bob Lantz
        self.flush = flush
86 90d50dcb Jonathan Hart
        self.forwardState = self.cmd( 'sysctl -n net.ipv4.ip_forward' ).strip()
87 4015e066 Brian O'Connor
88
    def config( self, **params ):
89
        """Configure the NAT and iptables"""
90 b1ec912d Bob Lantz
        super( NAT, self).config( **params )
91 4015e066 Brian O'Connor
92
        if not self.localIntf:
93 7a3159c9 Bob Lantz
            self.localIntf = self.defaultIntf()
94 4015e066 Brian O'Connor
95 c4a85ab1 Bob Lantz
        if self.flush:
96 90d50dcb Jonathan Hart
            self.cmd( 'sysctl net.ipv4.ip_forward=0' )
97 c4a85ab1 Bob Lantz
            self.cmd( 'iptables -F' )
98
            self.cmd( 'iptables -t nat -F' )
99
            # Create default entries for unmatched traffic
100
            self.cmd( 'iptables -P INPUT ACCEPT' )
101
            self.cmd( 'iptables -P OUTPUT ACCEPT' )
102
            self.cmd( 'iptables -P FORWARD DROP' )
103 4015e066 Brian O'Connor
104 c4a85ab1 Bob Lantz
        # Install NAT rules
105 b1ec912d Bob Lantz
        self.cmd( 'iptables -I FORWARD',
106
                  '-i', self.localIntf, '-d', self.subnet, '-j DROP' )
107
        self.cmd( 'iptables -A FORWARD',
108
                  '-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
109
        self.cmd( 'iptables -A FORWARD',
110 90d50dcb Jonathan Hart
                  '-o', self.localIntf, '-d', self.subnet,'-j ACCEPT' )
111 b1ec912d Bob Lantz
        self.cmd( 'iptables -t nat -A POSTROUTING',
112 f7601da0 Bob Lantz
                  '-s', self.subnet, "'!'", '-d', self.subnet, '-j MASQUERADE' )
113 4015e066 Brian O'Connor
114
        # Instruct the kernel to perform forwarding
115
        self.cmd( 'sysctl net.ipv4.ip_forward=1' )
116
117
        # Prevent network-manager from messing with our interface
118
        # by specifying manual configuration in /etc/network/interfaces
119
        intf = self.localIntf
120
        cfile = '/etc/network/interfaces'
121
        line = '\niface %s inet manual\n' % intf
122
        config = open( cfile ).read()
123
        if ( line ) not in config:
124 af1ccf93 Brian O'Connor
            info( '*** Adding "' + line.strip() + '" to ' + cfile + '\n' )
125 4015e066 Brian O'Connor
            with open( cfile, 'a' ) as f:
126
                f.write( line )
127
        # Probably need to restart network-manager to be safe -
128
        # hopefully this won't disconnect you
129
        self.cmd( 'service network-manager restart' )
130
131
    def terminate( self ):
132 c4a85ab1 Bob Lantz
        "Stop NAT/forwarding between Mininet and external network"
133
        # Remote NAT rules
134
        self.cmd( 'iptables -D FORWARD',
135
                   '-i', self.localIntf, '-d', self.subnet, '-j DROP' )
136
        self.cmd( 'iptables -D FORWARD',
137
                  '-i', self.localIntf, '-s', self.subnet, '-j ACCEPT' )
138
        self.cmd( 'iptables -D FORWARD',
139 90d50dcb Jonathan Hart
                  '-o', self.localIntf, '-d', self.subnet,'-j ACCEPT' )
140 c4a85ab1 Bob Lantz
        self.cmd( 'iptables -t nat -D POSTROUTING',
141 90d50dcb Jonathan Hart
                  '-s', self.subnet, '\'!\'', '-d', self.subnet, '-j MASQUERADE' )
142
        # Put the forwarding state back to what it was
143
        self.cmd( 'sysctl net.ipv4.ip_forward=%s' % self.forwardState )
144 4015e066 Brian O'Connor
        super( NAT, self ).terminate()