blob: d6f96b156d11a2bd425fd1dc1f1470f6fcec45f1 [file] [log] [blame]
Carmelo Cascone977ae3f2016-06-23 19:28:28 -07001import socket
2
Carmelo Cascone785fada2016-06-16 18:34:16 -07003from mininet.log import error, info
4from mininet.node import Switch
Carmelo Cascone785fada2016-06-16 18:34:16 -07005
Carmelo Cascone75e97992017-06-05 02:32:47 -04006BMV2_TARGET = 'simple_switch_grpc'
Carmelo Cascone785fada2016-06-16 18:34:16 -07007
8class ONOSBmv2Switch(Switch):
9 """BMv2 software switch """
10
Carmelo Cascone785fada2016-06-16 18:34:16 -070011 deviceId = 0
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070012 instanceCount = 0
Carmelo Cascone785fada2016-06-16 18:34:16 -070013
Carmelo Cascone75e97992017-06-05 02:32:47 -040014 def __init__(self, name, debugger=False, loglevel="warn", elogger=False, persistent=False,
15 logflush=False, **kwargs):
Carmelo Cascone785fada2016-06-16 18:34:16 -070016 Switch.__init__(self, name, **kwargs)
Carmelo Cascone75e97992017-06-05 02:32:47 -040017 self.thriftPort = ONOSBmv2Switch.pickUnusedPort()
18 self.grpcPort = ONOSBmv2Switch.pickUnusedPort()
19 if self.dpid:
20 self.deviceId = int(self.dpid, 0 if 'x' in self.dpid else 16)
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070021 else:
Carmelo Cascone75e97992017-06-05 02:32:47 -040022 self.deviceId = ONOSBmv2Switch.deviceId
23 ONOSBmv2Switch.deviceId += 1
Carmelo Cascone785fada2016-06-16 18:34:16 -070024 self.debugger = debugger
25 self.loglevel = loglevel
26 self.logfile = '/tmp/bmv2-%d.log' % self.deviceId
Carmelo Cascone785fada2016-06-16 18:34:16 -070027 self.elogger = elogger
28 self.persistent = persistent
Carmelo Cascone75e97992017-06-05 02:32:47 -040029 self.logflush = logflush
Carmelo Cascone785fada2016-06-16 18:34:16 -070030 if persistent:
31 self.exectoken = "/tmp/bmv2-%d-exec-token" % self.deviceId
32 self.cmd("touch %s" % self.exectoken)
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070033 # Store thrift port for future uses.
34 self.cmd("echo %d > /tmp/bmv2-%d-thrift-port" % (self.thriftPort, self.deviceId))
Carmelo Cascone75e97992017-06-05 02:32:47 -040035 self.cmd("echo %d > /tmp/bmv2-%d-grpc-port" % (self.grpcPort, self.deviceId))
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070036
37 @classmethod
38 def pickUnusedPort(cls):
39 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
40 s.bind(('localhost', 0))
41 addr, port = s.getsockname()
42 s.close()
43 return port
Carmelo Cascone785fada2016-06-16 18:34:16 -070044
Carmelo Cascone785fada2016-06-16 18:34:16 -070045 def start(self, controllers):
Carmelo Cascone75e97992017-06-05 02:32:47 -040046 args = [BMV2_TARGET, '--device-id %s' % str(self.deviceId)]
Carmelo Cascone785fada2016-06-16 18:34:16 -070047 for port, intf in self.intfs.items():
48 if not intf.IP():
49 args.append('-i %d@%s' % (port, intf.name))
50 if self.thriftPort:
51 args.append('--thrift-port %d' % self.thriftPort)
52 if self.elogger:
53 nanomsg = 'ipc:///tmp/bmv2-%d-log.ipc' % self.deviceId
54 args.append('--nanolog %s' % nanomsg)
55 if self.debugger:
56 args.append('--debugger')
Carmelo Cascone75e97992017-06-05 02:32:47 -040057 args.append('--log-file %s -L%s' % (self.logfile, self.loglevel))
58 if self.logflush:
59 args.append('--log-flush')
60 args.append('--no-p4')
Carmelo Cascone785fada2016-06-16 18:34:16 -070061 args.append('--')
Carmelo Cascone75e97992017-06-05 02:32:47 -040062 args.append('--enable-swap')
63 if self.grpcPort:
64 args.append('--grpc-server-addr 0.0.0.0:%d' % self.grpcPort)
Carmelo Cascone785fada2016-06-16 18:34:16 -070065
66 bmv2cmd = " ".join(args)
Carmelo Cascone785fada2016-06-16 18:34:16 -070067 info("\nStarting BMv2 target: %s\n" % bmv2cmd)
Carmelo Cascone785fada2016-06-16 18:34:16 -070068 if self.persistent:
69 # Re-exec the switch if it crashes.
70 cmdStr = "(while [ -e {} ]; " \
71 "do {} ; " \
72 "sleep 1; " \
Carmelo Cascone75e97992017-06-05 02:32:47 -040073 "done;) &".format(self.exectoken, bmv2cmd)
Carmelo Cascone785fada2016-06-16 18:34:16 -070074 else:
Carmelo Cascone75e97992017-06-05 02:32:47 -040075 cmdStr = "{} &".format(bmv2cmd)
Carmelo Cascone785fada2016-06-16 18:34:16 -070076 self.cmd(cmdStr)
77
78 def stop(self):
79 "Terminate switch."
Carmelo Cascone977ae3f2016-06-23 19:28:28 -070080 self.cmd("rm -f /tmp/bmv2-%d-*" % self.deviceId)
Carmelo Cascone75e97992017-06-05 02:32:47 -040081 # wildcard end as BMv2 might create log files with .txt extension
82 self.cmd("rm -f /tmp/bmv2-%d.log*" % self.deviceId)
83 self.cmd('kill %' + BMV2_TARGET)
Carmelo Cascone785fada2016-06-16 18:34:16 -070084 self.deleteIntfs()
85
86
87### Exports for bin/mn
Carmelo Cascone785fada2016-06-16 18:34:16 -070088switches = {'onosbmv2': ONOSBmv2Switch}