Statistics
| Branch: | Tag: | Revision:

mininet / bin / mn_run.py @ ee007363

History | View | Annotate | Download (6.16 KB)

1
#!/usr/bin/env python
2
'''Mininet runner
3

4
@author Brandon Heller (brandonh@stanford.edu)
5
'''
6

    
7
from optparse import OptionParser
8
import time
9

    
10
try:
11
    from ripcord.dctopo import TreeTopo, FatTreeTopo, VL2Topo
12
    USE_RIPCORD = True
13
except ImportError:
14
    USE_RIPCORD = False
15

    
16
from mininet.logging_mod import lg, set_loglevel, LEVELS
17
from mininet.net import Mininet, init
18
from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
19
from mininet.node import RemoteController
20
from mininet.topo import SingleSwitchTopo, LinearTopo
21

    
22
# built in topologies, created only when run
23
TOPO_DEF = 'minimal'
24
TOPOS = {'minimal' :   (lambda: SingleSwitchTopo(k = 2)),
25
         'single4' :   (lambda: SingleSwitchTopo(k = 4)),
26
         'single100' : (lambda: SingleSwitchTopo(k = 100)),
27
         'linear2' :   (lambda: LinearTopo(k = 2)),
28
         'linear100' : (lambda: LinearTopo(k = 100))}
29
if USE_RIPCORD:
30
    TOPOS_RIPCORD = {
31
         'tree16' :   (lambda: TreeTopo(depth = 3, fanout = 4)),
32
         'tree64' :   (lambda: TreeTopo(depth = 4, fanout = 4)),
33
         'tree1024' : (lambda: TreeTopo(depth = 3, fanout = 32)),
34
         'fattree4' : (lambda: FatTreeTopo(k = 4)),
35
         'fattree6' : (lambda: FatTreeTopo(k = 6)),
36
         'vl2'      : (lambda: VL2Topo(da = 4, di = 4))}
37
    TOPOS.update(TOPOS_RIPCORD)
38

    
39
SWITCH_DEF = 'kernel'
40
SWITCHES = {'kernel' : KernelSwitch}
41

    
42
HOST_DEF = 'process'
43
HOSTS = {'process' : Host}
44

    
45
CONTROLLER_DEF = 'ref'
46
# a and b are the name and inNamespace params.
47
CONTROLLERS = {'ref' : Controller,
48
               'nox_dump' : lambda a, b: NOX(a, b, 'packetdump'),
49
               'nox_pysw' : lambda a, b: NOX(a, b, 'pyswitch'),
50
               'remote' : lambda a, b: None,
51
               'none' :     lambda a, b: None}
52

    
53
# optional tests to run
54
TESTS = ['cli', 'build', 'ping_all', 'ping_pair', 'iperf', 'all', 'iperf_udp']
55

    
56
def add_dict_option(opts, choices_dict, default, name, help_str = None):
57
    '''Convenience function to add choices dicts to OptionParser.
58
    
59
    @param opts OptionParser instance
60
    @param choices_dict dictionary of valid choices, must include default
61
    @param default default choice key
62
    @param name long option name
63
    @param help string
64
    '''
65
    if default not in choices_dict:
66
        raise Exception('Invalid  default %s for choices dict: %s' %
67
                        (default, name))
68
    if not help_str:
69
        help_str = '[' + ' '.join(choices_dict.keys()) + ']'
70
    opts.add_option('--' + name,
71
                    type = 'choice',
72
                    choices = choices_dict.keys(),
73
                    default = default,
74
                    help = help_str)
75

    
76

    
77
class MininetRunner(object):
78
    '''Build, setup, and run Mininet.'''
79

    
80
    def __init__(self):
81
        '''Init.'''
82
        self.options = None
83
        
84
        self.parse_args()
85
        self.setup()
86
        self.begin()
87

    
88
    def parse_args(self):
89
        '''Parse command-line args and return options object.
90
        
91
        @return opts parse options dict
92
        '''
93
        opts = OptionParser()
94
        add_dict_option(opts, TOPOS, TOPO_DEF, 'topo')
95
        add_dict_option(opts, SWITCHES, SWITCH_DEF, 'switch')
96
        add_dict_option(opts, HOSTS, HOST_DEF, 'host')
97
        add_dict_option(opts, CONTROLLERS, CONTROLLER_DEF, 'controller')
98

    
99
        opts.add_option('--test', type = 'choice', choices = TESTS,
100
                        default = TESTS[0],
101
                        help = '[' + ' '.join(TESTS) + ']')
102
        opts.add_option('--xterms', '-x', action = 'store_true',
103
                        default = False, help = 'spawn xterms for each node')
104
        opts.add_option('--mac', action = 'store_true',
105
                        default = False, help = 'set MACs equal to DPIDs')
106
        opts.add_option('--arp', action = 'store_true',
107
                        default = False, help = 'set all-pairs ARP entries')
108
        opts.add_option('--verbosity', '-v', type = 'choice',
109
                        choices = LEVELS.keys(), default = 'info',
110
                        help = '[' + ' '.join(LEVELS.keys()) + ']')
111
        opts.add_option('--ip', type = 'string', default = '127.0.0.1',
112
                        help = '[ip address as a dotted decimal string for a'
113
                        'remote controller]')
114
        opts.add_option('--port', type = 'string', default = 6633,
115
                        help = '[port integer for a listening remote'
116
                        ' controller]')
117
        self.options = opts.parse_args()[0]
118

    
119
    def setup(self):
120
        '''Setup and validate environment.'''
121

    
122
        # set logging verbosity
123
        set_loglevel(self.options.verbosity)
124

    
125
        # validate environment setup
126
        init()
127

    
128
        # check for invalid combinations
129
        if self.options.controller == 'ref' and \
130
            (('fattree' in self.options.topo) or ('vl2' in self.options.topo)):
131
            raise Exception('multipath topos require multipath-capable '
132
                            'controller.')
133

    
134
    def begin(self):
135
        '''Create and run mininet.'''
136

    
137
        start = time.time()
138

    
139
        topo = TOPOS[self.options.topo]() # build topology object
140
        switch = SWITCHES[self.options.switch]
141
        host = HOSTS[self.options.host]
142
        controller = CONTROLLERS[self.options.controller]
143
        if self.options.controller == 'remote':
144
            controller = lambda a, b: RemoteController(a, b,
145
                             ip_address = self.options.ip,
146
                             port = self.options.port)
147

    
148
        controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
149
        xterms = self.options.xterms
150
        mac = self.options.mac
151
        arp = self.options.arp
152
        mn = Mininet(topo, switch, host, controller, controller_params,
153
                     xterms = xterms, auto_set_macs = mac,
154
                     auto_static_arp = arp)
155

    
156
        test = self.options.test
157
        if test != 'build':
158
            if test == 'cli':
159
                mn.interact()
160
            elif test == 'all':
161
                mn.start()
162
                mn.ping()
163
                mn.iperf()
164
                mn.stop()
165
            else:
166
                mn.run(test)
167

    
168
        elapsed = float(time.time() - start)
169
        print ('completed in %0.3f seconds' % elapsed)
170

    
171

    
172
if __name__ == "__main__":
173
    MininetRunner()