def gen_conf (args): parser = argparse.ArgumentParser() add_args_from_schema(parser, args.get('name', 'mgw')) set_defaults(parser, **args) args = parser.parse_args([]) pl_class = find_mod.find_class('GenConf', args.name) conf = pl_class(args).create_conf() return conf
def gen_pcap(*defaults): args = parse_args(defaults) conf = json_load(args.conf, object_hook=ObjectView) if args.random_seed: random.seed(args.random_seed) in_que = multiprocessing.Queue() out_que = multiprocessing.Queue() gen_pkt_class = find_mod.find_class('GenPkt', conf.name) gen_pkt_obj = gen_pkt_class(args, conf, in_que, out_que) worker_num = max(1, args.thread) job_size = 1024 if args.ascii: print("Dumping packets:") else: args.pcap_file = PcapWriter(args.output.name) processes = [] for i in range(worker_num): p = multiprocessing.Process(target=gen_pkt_obj.do_work) p.start() processes.append(p) num_jobs = 0 for item in gen_pkt_obj.create_work_items(job_size): in_que.put(item) num_jobs += 1 results = [] next_idx = 0 while next_idx < num_jobs: result = out_que.get() if 'exception' in result: print('Exception: %s' % result['exception']) print(''.join(result['traceback'])) exit() # print('idx: %s' % result['job_idx']) results.append(result) results.sort(key=lambda x: x['job_idx']) # print([x['job_idx'] for x in results]) while len(results) > 0 and results[0]['job_idx'] == next_idx: # print('w: %s' % results[0]['job_idx']) pkts = [PicklablePacket.__call__(p) for p in results[0]['pkts']] output_pkts(args, pkts) results.pop(0) next_idx += 1 # stop workers for i in range(worker_num): in_que.put(None) for p in processes: p.join() if not args.ascii: args.pcap_file.close()
def parse_cli_args (): parser = argparse.ArgumentParser() parser2 = argparse.ArgumentParser() for args, kw in [ (['--json', '-j'], { 'type': argparse.FileType('r'), 'help': 'Override default settings from config file'}), (['--output', '-o'], { 'type': argparse.FileType('w'), 'help': 'Output file', 'default': '/dev/stdout'}), (['--pipeline', '-p'], { 'dest': 'name', 'type': str, 'choices': list_pipelines(), 'help': 'Name of the pipeline', 'default': 'mgw'}), (['--name'], { 'dest': 'name', 'type': str, 'choices': list_pipelines(), 'help': argparse.SUPPRESS, 'default': 'mgw'}), (['--info', '-i'], { 'action': 'store_true', 'help': 'Show detailed info of a pipeline and exit'}), ]: parser.add_argument(*args, **kw) parser2.add_argument(*args, **kw) parser.set_defaults(info=False) parser2.add_argument('dummy', metavar='pipeline specific args ...', nargs='?', type=str, help='see -i for details') args, _ = parser2.parse_known_args() if args.json: # Set the default pipeline from the json file new_defaults = json.load(args.json) set_defaults(parser, **new_defaults) (args, _) = parser.parse_known_args() add_args_from_schema(parser, args.name) if args.json: # Override the defaults for the given pipeline set_defaults(parser, **new_defaults) args = parser.parse_args() if args.info: parser = argparse.ArgumentParser() parser.formatter_class = argparse.ArgumentDefaultsHelpFormatter pl = find_mod.find_class('GenConf', args.name)({}) parser.usage = "\n\n%s (%s)" % (pl.__doc__, args.name) add_args_from_schema(parser, args.name) parser.parse_args(['-h']) return args
def run_in_cwd(): cwd = Path().cwd() conf = json_load(cwd / 'plot.json') data = [] for res in sorted((cwd.parent.parent / 'measurements').glob('*.json')): print(res) data += json_load(res) data = filter_data(conf, data) data = mongo_pipeline(conf.aggregate, data) #print('mongo', json.dumps(data, indent=2, sort_keys=True)) plt_class = find_mod.find_class('Plot', conf.type) plt_obj = plt_class(conf) plot_points = plt_obj.plot(data) plt_obj.write_preamble() with open('out.json', 'w') as f: json.dump(plot_points, f, indent=1)
def instantiate_pipeline(self): pl_class = None pl_name = self.pl_conf.name for switch_type in self.switch_type: try: backend = 'SUT_%s' % switch_type pl_class = find_mod.find_class(backend, pl_name) self.logger.info('pipeline: %s_%s', backend, pl_name) break except KeyError as e: pass if pl_class is None: self.signal_fauilure('Pipeline (%s) not found for %s', pl_name, self.switch_type) return self.pl = pl_class(self, self.pl_conf)
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from ryu.lib.packet.ether_types import ETH_TYPE_IP import os import sys fdir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(fdir, '..', '..', 'lib')) import find_mod Base = find_mod.find_class('SUT_openflow', 'base') class SUT_openflow(Base): """Firewall (ACL) pipeline """ def __init__(self, parent, conf): super(SUT_openflow, self).__init__(parent, conf) self.tables = { 'selector': 0, 'upstream': 1, 'downstream': 2, 'drop': 3, } def config_switch(self, parser):
# TIPSY: Telco pIPeline benchmarking SYstem # # Copyright (C) 2017-2018 by its authors (See AUTHORS) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import find_mod BaseLago = find_mod.find_class('SUT_lagopus', 'mgw') BaseErfs = find_mod.find_class('SUT_erfs', 'bng') class SUT_lagopus(BaseLago, BaseErfs): pass # TODO: this inheritance should be carefully tested
# General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from ryu.lib.packet import in_proto from ryu.lib.packet.ether_types import ETH_TYPE_IP import os import sys fdir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(fdir, '..', '..', 'lib')) import find_mod Base = find_mod.find_class('SUT_ovs', 'mgw') class SUT_ovs(Base): def __init__(self, parent, conf): super(SUT_ovs, self).__init__(parent, conf) self.tables = { 'ingress': 0, 'dl_nat': 1, 'dl_fw': 2, 'downlink': 3, 'uplink': 4, 'ul_fw': 5, 'ul_nat': 6, 'l3_lookup': 7, 'drop': 250
# You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os import subprocess import sys import time from ryu.lib import hub fdir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(fdir, '..', '..', 'lib')) import find_mod RyuAppOpenflow = find_mod.find_class('RyuApp', 'openflow') class RyuApp(RyuAppOpenflow): def __init__(self, *args, **kwargs): if 'switch_type' not in kwargs: kwargs['switch_type'] = ['lagopus', 'openflow'] self.core_idx = 0 # next core to allocate in the core_list super(RyuApp, self).__init__(*args, **kwargs) def get_cores(self, num_cores): coremask = self.bm_conf.sut.coremask cpum = int(coremask, 16) core_list = [i for i in range(32) if (cpum >> i) & 1 == 1] ## lcore 0 is reserved for the controller #core_list = [i for i in core_list if i != 0]
# TIPSY: Telco pIPeline benchmarking SYstem # # Copyright (C) 2018 by its authors (See AUTHORS) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from pathlib import Path import find_mod Base = find_mod.find_class('SUT', 'openflow') class SUT(Base): pass
# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from ryu.lib.packet import in_proto from ryu.lib.packet.ether_types import ETH_TYPE_IP import find_mod Base = find_mod.find_class('SUT_erfs', 'mgw') class SUT_lagopus(Base): def init_backend(self): # Backend specific initialization pass def get_vxlan_encap_actions(self, vxlan_vni, tun_ip_src, tun_ip_dst): # https://github.com/lagopus/lagopus/issues/92 ofp = self.parent.dp.ofproto parser = self.parent.dp.ofproto_parser type_eth = (ofp.OFPHTN_ONF << 16) | ofp.OFPHTO_ETHERNET type_ip = (ofp.OFPHTN_ETHERTYPE << 16) | 0x0800 type_udp = (ofp.OFPHTN_IP_PROTO << 16) | 17
# TIPSY: Telco pIPeline benchmarking SYstem # # Copyright (C) 2018 by its authors (See AUTHORS) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import subprocess from pathlib import Path import find_mod OpenFlow = find_mod.find_class('SUT', 'openflow') class SUT(OpenFlow): def _query_version(self): v = self.run_ssh_cmd(['ovs-vsctl', '--version'], stdout=subprocess.PIPE) first_line = v.stdout.decode('utf8').split("\n")[0] self.result['version'] = first_line.split(' ')[-1]
default=benchmark_conf, help='configuration of the whole benchmark (in json)'), cfg.StrOpt('webhook_configured', default='http://localhost:8888/configured', help='URL to request when the sw is configured'), cfg.StrOpt('webhook_failed', default='http://localhost:8888/failed', help='URL to request when the configuration is unsuccessful'), ], group='tipsy') CONF = cfg.CONF['tipsy'] def eprint(*args, **kw): print(*args, file=sys.stderr, **kw) try: with open(CONF['benchmark_conf'], 'r') as f: bm = json.load(f) except IOError as e: eprint('Failed to load cfg file (%s): %s' % (fname, e)) raise e except ValueError as e: eprint('Failed to parse cfg file (%s): %s' % (fname, e)) raise e App = find_mod.find_class('RyuApp', bm["sut"]["type"]) App.__module__ = 'tipsy' App.__name__ = 'Tipsy'
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from pathlib import Path, PosixPath import find_mod Base = find_mod.find_class('SUT', 'base') class SUT(Base): def __init__(self, conf): super(SUT, self).__init__(conf) self.remote_dir = Path(self.conf.sut.tipsy_dir) / 'module' / 'openflow' self.virtualenv = None def _start(self): self.upload_conf_files('/tmp') cmd = ['sudo', str(self.remote_dir / 'start-ryu')] if self.virtualenv: cmd.append(self.virtualenv) self.run_async_ssh_cmd(cmd)