+class TrexDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
+ APP_NAME = "t-rex-64"
+ CFG_CONFIG = ""
+ CFG_SCRIPT = ""
+ PIPELINE_COMMAND = ""
+ VNF_TYPE = "TG"
+
+
+class TrexResourceHelper(ClientResourceHelper):
+
+ CONF_FILE = '/tmp/trex_cfg.yaml'
+ QUEUE_WAIT_TIME = 1
+ RESOURCE_WORD = 'trex'
+ RUN_DURATION = 0
+
+ ASYNC_PORT = 4500
+ SYNC_PORT = 4501
+
+ def generate_cfg(self):
+ port_names = self.vnfd_helper.port_pairs.all_ports
+ vpci_list = []
+ port_list = []
+
+ port_nums = sorted(self.vnfd_helper.port_nums(port_names))
+ for port_num in port_nums:
+ interface = self.vnfd_helper.find_interface_by_port(port_num)
+ virtual_interface = interface['virtual-interface']
+ dst_mac = virtual_interface["dst_mac"]
+
+ # why skip?, ordering is based on DPDK port number so we can't skip
+ if not dst_mac:
+ continue
+ # TRex ports must be in DPDK port number, so order of append matters
+ vpci_list.append(virtual_interface["vpci"])
+ local_mac = virtual_interface["local_mac"]
+ port_list.append({
+ "src_mac": mac_address_to_hex_list(local_mac),
+ "dest_mac": mac_address_to_hex_list(dst_mac),
+ })
+ trex_cfg = {
+ 'interfaces': vpci_list,
+ 'port_info': port_list,
+ "port_limit": len(port_names),
+ "version": '2',
+ }
+ cfg_file = [trex_cfg]
+
+ cfg_str = yaml.safe_dump(cfg_file, default_flow_style=False, explicit_start=True)
+ self.ssh_helper.upload_config_file(os.path.basename(self.CONF_FILE), cfg_str)
+
+ def check_status(self):
+ status, _, _ = self.ssh_helper.execute("sudo lsof -i:%s" % self.SYNC_PORT)
+ return status
+
+ # temp disable
+ DISABLE_DEPLOY = True
+
+ def setup(self):
+ super(TrexResourceHelper, self).setup()
+ if self.DISABLE_DEPLOY:
+ return
+
+ trex_path = self.ssh_helper.join_bin_path('trex')
+
+ err = self.ssh_helper.execute("which {}".format(trex_path))[0]
+ if err == 0:
+ return
+
+ LOG.info("Copying %s to destination...", self.RESOURCE_WORD)
+ self.ssh_helper.run("sudo mkdir -p '{}'".format(os.path.dirname(trex_path)))
+ self.ssh_helper.put("~/.bash_profile", "~/.bash_profile")
+ self.ssh_helper.put(trex_path, trex_path, True)
+ ko_src = os.path.join(trex_path, "scripts/ko/src/")
+ self.ssh_helper.execute(self.MAKE_INSTALL.format(ko_src))
+
+ def start(self, ports=None, *args, **kwargs):
+ cmd = "sudo fuser -n tcp {0.SYNC_PORT} {0.ASYNC_PORT} -k > /dev/null 2>&1"
+ self.ssh_helper.execute(cmd.format(self))
+
+ self.ssh_helper.execute("sudo pkill -9 rex > /dev/null 2>&1")
+
+ # We MUST default to 1 because TRex won't work on single-queue devices with
+ # more than one core per port
+ # We really should be trying to find the number of queues in the driver,
+ # but there doesn't seem to be a way to do this
+ # TRex Error: the number of cores should be 1 when the driver
+ # support only one tx queue and one rx queue. Please use -c 1
+ threads_per_port = try_int(self.scenario_helper.options.get("queues_per_port"), 1)
+
+ trex_path = self.ssh_helper.join_bin_path("trex", "scripts")
+ path = get_nsb_option("trex_path", trex_path)
+
+ cmd = "./t-rex-64 --no-scapy-server -i -c {} --cfg '{}'".format(threads_per_port,
+ self.CONF_FILE)
+
+ if self.scenario_helper.options.get("trex_server_debug"):
+ # if there are errors we want to see them
+ redir = ""
+ else:
+ redir = ">/dev/null"
+ # we have to sudo cd because the path might be owned by root
+ trex_cmd = """sudo bash -c "cd '{}' ; {}" {}""".format(path, cmd, redir)
+ LOG.debug(trex_cmd)
+ self.ssh_helper.execute(trex_cmd)
+
+ def terminate(self):
+ super(TrexResourceHelper, self).terminate()
+ cmd = "sudo fuser -n tcp %s %s -k > /dev/null 2>&1"
+ self.ssh_helper.execute(cmd % (self.SYNC_PORT, self.ASYNC_PORT))
+
+
+class TrexTrafficGen(SampleVNFTrafficGen):