From 268c7f125a8d51fa46a48de7104a3cfd7c50397e Mon Sep 17 00:00:00 2001 From: imarom Date: Thu, 11 Feb 2016 08:15:33 -0500 Subject: push support --- .../trex_control_plane/stl/console/trex_console.py | 11 +++++- .../stl/trex_stl_lib/trex_stl_client.py | 46 +++++++++++++++++++++- .../stl/trex_stl_lib/trex_stl_streams.py | 19 +++++++-- .../stl/trex_stl_lib/utils/parsing_opts.py | 22 +++++++++-- 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py index 789ad4ab..9e9dcf62 100755 --- a/scripts/automation/trex_control_plane/stl/console/trex_console.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py @@ -325,6 +325,13 @@ class TRexConsole(TRexGeneralCmd): def do_shell (self, line): return self.do_history(line) + def do_push (self, line): + '''Push a PCAP file\n''' + return self.stateless_client.push_line(line) + + def help_push (self): + return self.do_push("-h") + def do_history (self, line): '''Manage the command history\n''' @@ -385,6 +392,7 @@ class TRexConsole(TRexGeneralCmd): if (l > 2) and (s[l - 2] in file_flags): return TRexConsole.tree_autocomplete(s[l - 1]) + @verify_connected_and_rw def do_start(self, line): '''Start selected traffic in specified port(s) on TRex\n''' @@ -566,8 +574,9 @@ class TRexConsole(TRexGeneralCmd): print "----------------------------\n" cmds = [x[3:] for x in self.get_names() if x.startswith("do_")] + hidden = ['EOF', 'q', 'exit', 'h', 'shell'] for cmd in cmds: - if ( (cmd == "EOF") or (cmd == "q") or (cmd == "exit") or (cmd == "h")): + if cmd in hidden: continue try: diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index c8049bf9..5096e33d 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -1724,7 +1724,7 @@ class STLClient(object): parsing_opts.PORT_LIST_WITH_ALL, parsing_opts.TOTAL, parsing_opts.FORCE, - parsing_opts.STREAM_FROM_PATH_OR_FILE, + parsing_opts.FILE_PATH, parsing_opts.DURATION, parsing_opts.MULTIPLIER_STRICT, parsing_opts.DRY_RUN) @@ -1975,3 +1975,47 @@ class STLClient(object): + @__console + def push_line (self, line): + '''Push a PCAP file ''' + + parser = parsing_opts.gen_parser(self, + "push", + self.push_line.__doc__, + parsing_opts.FILE_PATH, + parsing_opts.PORT_LIST_WITH_ALL, + parsing_opts.DURATION, + parsing_opts.IPG, + parsing_opts.SPEEDUP, + parsing_opts.FORCE) + + opts = parser.parse_args(line.split()) + if opts is None: + return + + active_ports = list(set(self.get_active_ports()).intersection(opts.ports)) + + if active_ports: + if not opts.force: + msg = "Port(s) {0} are active - please stop them or add '--force'\n".format(active_ports) + self.logger.log(format_text(msg, 'bold')) + return + else: + self.stop(active_ports) + + try: + # pcap injection removes all previous streams from the ports + self.remove_all_streams(ports = opts.ports) + profile = STLProfile.load_pcap(opts.file[0], + opts.ipg_usec, + opts.speedup, + loop = True if opts.duration != -1 else False) + + id_list = self.add_streams(profile.get_streams(), opts.ports) + self.start(ports = opts.ports, duration = opts.duration, force = opts.force) + + except STLError as e: + print e.brief() + return + + diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py index c9c34e4b..91a554ff 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py @@ -365,7 +365,7 @@ class STLProfile(object): sys.path.remove(basedir) @staticmethod - def load_pcap (pcap_file): + def load_pcap (pcap_file, ipg_usec = None, speedup = 1.0, loop = False): # check filename if not os.path.isfile(pcap_file): raise STLError("file '{0}' does not exists".format(pcap_file)) @@ -376,13 +376,24 @@ class STLProfile(object): pkts = RawPcapReader(pcap_file).read_all() for i, (cap, meta) in enumerate(pkts, start = 1): - ts_usec = meta[0] * 1e6 + meta[1] + # IPG - if not provided, take from cap + if ipg_usec == None: + ts_usec = (meta[0] * 1e6 + meta[1]) / float(speedup) + else: + ts_usec = (ipg_usec * i) / float(speedup) + + # handle last packet + if i == len(pkts): + next = 1 if loop else None + else: + next = i + 1 + streams.append(STLStream(name = i, packet = CScapyTRexPktBuilder(pkt_buffer = cap), mode = STLTXSingleBurst(total_pkts = 1), self_start = True if (i == 1) else False, isg = (ts_usec - last_ts_usec), # seconds to usec - next = (i + 1) if i != len(pkts) else None)) + next = next)) last_ts_usec = ts_usec return STLProfile(streams) @@ -401,7 +412,7 @@ class STLProfile(object): profile = STLProfile.load_yaml(filename) elif suffix in ['cap', 'pcap']: - profile = STLProfile.load_pcap(filename) + profile = STLProfile.load_pcap(filename, speedup = 1, ipg_usec = 1e6) else: raise STLError("unknown profile file type: '{0}'".format(suffix)) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 968bbb7e..77970c75 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -24,6 +24,8 @@ DRY_RUN = 12 XTERM = 13 TOTAL = 14 FULL_OUTPUT = 15 +IPG = 16 +SPEEDUP = 17 GLOBAL_STATS = 50 PORT_STATS = 51 @@ -197,6 +199,19 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'default': False, 'action': "store_true"}), + IPG: ArgumentPack(['-i', '--ipg'], + {'help': "IPG value in usec between packets. default will be from the pcap", + 'dest': "ipg_usec", + 'default': None, + 'type': float}), + + + SPEEDUP: ArgumentPack(['-s', '--speedup'], + {'help': "Factor to accelerate the injection. effectively means IPG = IPG / SPEEDUP", + 'dest': "speedup", + 'default': 1.0, + 'type': float}), + PORT_LIST: ArgumentPack(['--port'], {"nargs": '+', 'dest':'ports', @@ -217,19 +232,20 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'dest': 'duration', 'type': match_time_unit, 'default': -1.0, - 'help': "Set duration time for TRex."}), + 'help': "Set duration time for job."}), FORCE: ArgumentPack(['--force'], {"action": "store_true", 'default': False, - 'help': "Set if you want to stop active ports before applying new TRex run on them."}), + 'help': "Set if you want to stop active ports before appyling command."}), FILE_PATH: ArgumentPack(['-f'], {'metavar': 'FILE', 'dest': 'file', 'nargs': 1, + 'required': True, 'type': is_valid_file, - 'help': "File path to YAML file that describes a stream pack. "}), + 'help': "File path to load"}), FILE_FROM_DB: ArgumentPack(['--db'], {'metavar': 'LOADED_STREAM_PACK', -- cgit 1.2.3-korg