diff options
author | 2016-05-03 14:57:34 +0300 | |
---|---|---|
committer | 2016-05-09 16:48:14 +0300 | |
commit | 8691f4019dc2123c1aa7413cf3666138756c2f66 (patch) | |
tree | 4b09f137d266471b51a4e5270e8d113806c97c93 /scripts/automation/trex_control_plane | |
parent | 64847bb6d182c73f7489a821ea5724687dab1bc1 (diff) |
first remote PCAP push - draft
Diffstat (limited to 'scripts/automation/trex_control_plane')
5 files changed, 114 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 f8161dcb..ab70d357 100755 --- a/scripts/automation/trex_control_plane/stl/console/trex_console.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py @@ -319,9 +319,13 @@ class TRexConsole(TRexGeneralCmd): return self.do_history(line) def do_push (self, line): - '''Push a PCAP file\n''' + '''Push a local PCAP file\n''' return self.stateless_client.push_line(line) + #def do_push_remote (self, line): + # '''Push a remote accessible PCAP file\n''' + # return self.stateless_client.push_remote_line(line) + def help_push (self): return self.do_push("-h") 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 862a9979..c7d59690 100755 --- 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 @@ -313,6 +313,10 @@ class EventsHandler(object): if session_id != self.client.session_id: self.__async_event_port_released(port_id) + elif (type == 7): + port_id = int(data['port_id']) + ev = "port {0} job failed".format(port_id) + show_event = True # server stopped elif (type == 100): @@ -711,6 +715,17 @@ class STLClient(object): return rc + def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count): + + port_id_list = self.__ports(port_id_list) + rc = RC() + + for port_id in port_id_list: + rc.add(self.ports[port_id].push_remote(pcap_filename, ipg_usec, speedup, count)) + + return rc + + def __validate (self, port_id_list = None): port_id_list = self.__ports(port_id_list) @@ -1852,6 +1867,49 @@ class STLClient(object): @__api_check(True) + def push_remote (self, pcap_filename, ports = None, ipg_usec = None, speedup = 1.0, count = 1): + """ + Push a remote reachable PCAP file + the path must be fullpath accessible to the server + + :parameters: + pcap_filename : str + PCAP file name in full path and accessible to the server + + ports : list + Ports on which to execute the command + + ipg_usec : float + Inter-packet gap in microseconds + + speedup : float + A factor to adjust IPG. effectively IPG = IPG / speedup + + count: int + How many times to transmit the cap + + + :raises: + + :exc:`STLError` + + """ + ports = ports if ports is not None else self.get_acquired_ports() + ports = self._validate_port_list(ports) + + validate_type('pcap_filename', pcap_filename, str) + validate_type('ipg_usec', ipg_usec, (float, int, type(None))) + validate_type('speedup', speedup, float) + validate_type('count', count, int) + + self.logger.pre_cmd("Pushing remote pcap on port(s) {0}:".format(ports)) + rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count) + self.logger.post_cmd(rc) + + if not rc: + raise STLError(rc) + + + @__api_check(True) def validate (self, ports = None, mult = "1", duration = "-1", total = False): """ Validate port(s) configuration @@ -2519,6 +2577,7 @@ class STLClient(object): "push", self.push_line.__doc__, parsing_opts.FILE_PATH, + parsing_opts.REMOTE_FILE, parsing_opts.PORT_LIST_WITH_ALL, parsing_opts.COUNT, parsing_opts.DURATION, @@ -2541,15 +2600,23 @@ class STLClient(object): self.stop(active_ports) # pcap injection removes all previous streams from the ports - self.remove_all_streams(ports = opts.ports) + if opts.remote: + self.push_remote(opts.file[0], + ports = opts.ports, + ipg_usec = opts.ipg_usec, + speedup = opts.speedup, + count = opts.count) + + else: + self.remove_all_streams(ports = opts.ports) - profile = STLProfile.load_pcap(opts.file[0], - opts.ipg_usec, - opts.speedup, - opts.count) + profile = STLProfile.load_pcap(opts.file[0], + opts.ipg_usec, + opts.speedup, + opts.count) - id_list = self.add_streams(profile.get_streams(), opts.ports) - self.start(ports = opts.ports, duration = opts.duration, force = opts.force) + id_list = self.add_streams(profile.get_streams(), opts.ports) + self.start(ports = opts.ports, duration = opts.duration, force = opts.force) return True diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index e8f89b27..986cb3c6 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -148,6 +148,7 @@ class Port(object): return self.owner def sync(self): + params = {"port_id": self.port_id} rc = self.transmit("get_port_status", params) @@ -553,6 +554,28 @@ class Port(object): return self.ok() + def push_remote (self, pcap_filename, ipg_usec, speedup, count): + if not self.is_acquired(): + return self.err("port is not owned") + + if (self.state == self.STATE_DOWN): + return self.err("port is down") + + params = {"handler": self.handler, + "port_id": self.port_id, + "pcap_filename": pcap_filename, + "ipg_usec": ipg_usec if ipg_usec is not None else -1, + "speedup": speedup, + "count": count} + + rc = self.transmit("push_remote", params) + if rc.bad(): + return self.err(rc.err()) + + self.state = self.STATE_TX + return self.ok() + + def get_profile (self): return self.profile 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 165942d8..6ee587c3 100755 --- 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 @@ -7,6 +7,7 @@ from .trex_stl_packet_builder_scapy import STLPktBuilder, Ether, IP, UDP, TCP, R from collections import OrderedDict, namedtuple from scapy.utils import ltoa +from scapy.error import Scapy_Exception import random import yaml import base64 @@ -967,7 +968,11 @@ class STLProfile(object): streams = [] last_ts_usec = 0 - pkts = RawPcapReader(pcap_file).read_all() + try: + pkts = RawPcapReader(pcap_file).read_all() + except Scapy_Exception as e: + raise STLError("failed to open PCAP file '{0}'".format(pcap_file)) + for i, (cap, meta) in enumerate(pkts, start = 1): # IPG - if not provided, take from cap 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 ad46625b..98e3ca6a 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 @@ -32,6 +32,7 @@ PROMISCUOUS = 19 NO_PROMISCUOUS = 20 PROMISCUOUS_SWITCH = 21 TUNABLES = 22 +REMOTE_FILE = 23 GLOBAL_STATS = 50 PORT_STATS = 51 @@ -290,6 +291,11 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'default': False, 'help': "Set if you want to stop active ports before appyling command."}), + REMOTE_FILE: ArgumentPack(['-r', '--remote'], + {"action": "store_true", + 'default': False, + 'help': "file path should be interpeted by the server (remote file)"}), + FILE_PATH: ArgumentPack(['-f'], {'metavar': 'FILE', 'dest': 'file', |