blob: b2213d1e12758c5c49bea98aa9b63c2b41b280ae [file] [log] [blame]
Carmelo Cascone785fada2016-06-16 18:34:16 -07001from mininet.log import error, info
2from mininet.node import Switch
3from os import environ
4from os.path import isfile
5
6
7class ONOSBmv2Switch(Switch):
8 """BMv2 software switch """
9
10 thriftPort = 9090
11 deviceId = 0
12
13 def __init__(self, name, thriftPort=None, deviceId=None, debugger=False,
14 loglevel="warn", elogger=False, persistent=True, **kwargs):
15 Switch.__init__(self, name, **kwargs)
16 self.swPath = environ['BMV2_EXE']
17 self.jsonPath = environ['BMV2_JSON']
18 if not thriftPort:
19 self.thriftPort = ONOSBmv2Switch.thriftPort
20 ONOSBmv2Switch.thriftPort += 1
21 else:
22 self.thriftPort = thriftPort
23 ONOSBmv2Switch.thriftPort = max(thriftPort, ONOSBmv2Switch.thriftPort)
24 if not deviceId:
25 if self.dpid:
26 self.deviceId = int(self.dpid, 0 if 'x' in self.dpid else 16)
27 else:
28 self.deviceId = ONOSBmv2Switch.deviceId
29 ONOSBmv2Switch.deviceId += 1
30 else:
31 self.deviceId = deviceId
32 ONOSBmv2Switch.deviceId = max(deviceId, ONOSBmv2Switch.deviceId)
33 self.debugger = debugger
34 self.loglevel = loglevel
35 self.logfile = '/tmp/bmv2-%d.log' % self.deviceId
36 self.output = open(self.logfile, 'w')
37 self.elogger = elogger
38 self.persistent = persistent
39 if persistent:
40 self.exectoken = "/tmp/bmv2-%d-exec-token" % self.deviceId
41 self.cmd("touch %s" % self.exectoken)
42
43 @classmethod
44 def setup(cls):
45 err = False
46
47 if 'BMV2_EXE' not in environ:
48 error("ERROR! environment var $BMV2_EXE not set\n")
49 err = True
50 elif not isfile(environ['BMV2_EXE']):
51 error("ERROR! BMV2_EXE=%s: no such file\n" % environ['BMV2_EXE'])
52 err = True
53
54 if 'BMV2_JSON' not in environ:
55 error("ERROR! environment var $BMV2_JSON not set\n")
56 err = True
57 elif not isfile(environ['BMV2_JSON']):
58 error("ERROR! BMV2_JSON=%s: no such file\n" % environ['BMV2_JSON'])
59 err = True
60
61 if err:
62 exit(1)
63
64 def start(self, controllers):
65 args = [self.swPath, '--device-id %s' % str(self.deviceId)]
66 for port, intf in self.intfs.items():
67 if not intf.IP():
68 args.append('-i %d@%s' % (port, intf.name))
69 if self.thriftPort:
70 args.append('--thrift-port %d' % self.thriftPort)
71 if self.elogger:
72 nanomsg = 'ipc:///tmp/bmv2-%d-log.ipc' % self.deviceId
73 args.append('--nanolog %s' % nanomsg)
74 if self.debugger:
75 args.append('--debugger')
76 args.append('--log-console -L%s' % self.loglevel)
77 args.append(self.jsonPath)
78
79 assert controllers[0]
80 c = controllers[0]
81 args.append('--')
82 args.append('--controller-ip %s' % c.IP())
83 args.append('--controller-port %d' % c.port)
84
85 bmv2cmd = " ".join(args)
86
87 info("\nStarting BMv2 target: %s\n" % bmv2cmd)
88
89 if self.persistent:
90 # Re-exec the switch if it crashes.
91 cmdStr = "(while [ -e {} ]; " \
92 "do {} ; " \
93 "sleep 1; " \
94 "done;) > {} 2>&1 &".format(self.exectoken, bmv2cmd, self.logfile)
95 else:
96 cmdStr = "{} > {} 2>&1 &".format(bmv2cmd, self.logfile)
97
98 self.cmd(cmdStr)
99
100 def stop(self):
101 "Terminate switch."
102 self.output.flush()
103 if self.persistent:
104 self.cmd("rm -f %s" % self.exectoken)
105 self.cmd('kill %' + self.swPath)
106 self.deleteIntfs()
107
108
109### Exports for bin/mn
110
111switches = {'onosbmv2': ONOSBmv2Switch}