Statistics
| Branch: | Tag: | Revision:

mininet / bin / mn_run.py @ 376bcba4

History | View | Annotate | Download (5.49 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.topo import SingleSwitchTopo, LinearTopo
20

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

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

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

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

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

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

    
74

    
75
class MininetRunner(object):
76
    '''Build, setup, and run Mininet.'''
77

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

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

    
97
        opts.add_option('--test', type = 'choice', choices = TESTS,
98
                        default = TESTS[0],
99
                        help = '[' + ' '.join(TESTS) + ']')
100
        opts.add_option('--xterms', '-x', action = 'store_true',
101
                        default = False, help = 'spawn xterms for each node')
102
        opts.add_option('--mac', action = 'store_true',
103
                        default = False, help = 'set host MACs equal to DPIDs')
104
        opts.add_option('--arp', action = 'store_true',
105
                        default = False, help = 'set all-pairs ARP entries')
106
        opts.add_option('--verbosity', '-v', type = 'choice',
107
                        choices = LEVELS.keys(), default = 'info',
108
                        help = '[' + ' '.join(LEVELS.keys()) + ']')
109
        self.options = opts.parse_args()[0]
110

    
111
    def setup(self):
112
        '''Setup and validate environment.'''
113

    
114
        # set logging verbosity
115
        set_loglevel(self.options.verbosity)
116

    
117
        # validate environment setup
118
        init()
119

    
120
        # check for invalid combinations
121
        if self.options.controller == 'ref' and \
122
            (('fattree' in self.options.topo) or ('vl2' in self.options.topo)):
123
            raise Exception('multipath topos require multipath-capable '
124
                            'controller.')
125

    
126
    def begin(self):
127
        '''Create and run mininet.'''
128

    
129
        start = time.time()
130

    
131
        topo = TOPOS[self.options.topo]() # build topology object
132
        switch = SWITCHES[self.options.switch]
133
        host = HOSTS[self.options.host]
134
        controller = CONTROLLERS[self.options.controller]
135

    
136
        controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
137
        xterms = self.options.xterms
138
        mac = self.options.mac
139
        arp = self.options.arp
140
        mn = Mininet(topo, switch, host, controller, controller_params,
141
                     xterms = xterms, auto_set_macs = mac,
142
                     auto_static_arp = arp)
143

    
144
        test = self.options.test
145
        if test != 'build':
146
            if test == 'cli':
147
                mn.interact()
148
            elif test == 'all':
149
                mn.start()
150
                mn.ping()
151
                mn.iperf()
152
                mn.stop()
153
            else:
154
                mn.run(test)
155

    
156
        elapsed = float(time.time() - start)
157
        print ('completed in %0.3f seconds' % elapsed)
158

    
159

    
160
if __name__ == "__main__":
161
    MininetRunner()