summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl/trex_stl_lib
diff options
context:
space:
mode:
authorYaroslav Brustinov <ybrustin@cisco.com>2016-12-11 19:06:13 +0200
committerYaroslav Brustinov <ybrustin@cisco.com>2016-12-19 11:23:46 +0200
commite4c8e44b0842093ce2a245e863a8db7f4c2ae9ff (patch)
treef1c92ff366088eb5250d56d22058cb6db7f41aeb /scripts/automation/trex_control_plane/stl/trex_stl_lib
parent057a1ec1e70584f3598e9980bb44f70f73065bac (diff)
add min_ipg to push_pcaps
Change-Id: I353f8903c40963517fd2fed721cc0671d9f6dc4b Signed-off-by: Yaroslav Brustinov <ybrustin@cisco.com>
Diffstat (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py30
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py5
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py63
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py147
4 files changed, 154 insertions, 91 deletions
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 743ff27c..964acce7 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
@@ -777,7 +777,7 @@ class STLClient(object):
return rc
- def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count, duration, is_dual):
+ def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count, duration, is_dual, min_ipg_usec):
port_id_list = self.__ports(port_id_list)
rc = RC()
@@ -793,7 +793,8 @@ class STLClient(object):
count,
duration,
is_dual,
- slave_handler))
+ slave_handler,
+ min_ipg_usec))
return rc
@@ -2494,7 +2495,8 @@ class STLClient(object):
speedup = 1.0,
count = 1,
duration = -1,
- is_dual = False):
+ is_dual = False,
+ min_ipg_usec = None):
"""
Push a remote server-reachable PCAP file
the path must be fullpath accessible to the server
@@ -2524,6 +2526,9 @@ class STLClient(object):
also requires that all the ports will be in master mode
with their adjacent ports as slaves
+ min_ipg_usec : float
+ Minimum inter-packet gap in microseconds to guard from too small ipg.
+
:raises:
+ :exc:`STLError`
@@ -2537,6 +2542,7 @@ class STLClient(object):
validate_type('count', count, int)
validate_type('duration', duration, (float, int))
validate_type('is_dual', is_dual, bool)
+ validate_type('min_ipg_usec', min_ipg_usec, (float, int, type(None)))
# for dual mode check that all are masters
if is_dual:
@@ -2555,7 +2561,7 @@ class STLClient(object):
self.logger.pre_cmd("Pushing remote PCAP on port(s) {0}:".format(ports))
- rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count, duration, is_dual)
+ rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count, duration, is_dual, min_ipg_usec)
self.logger.post_cmd(rc)
if not rc:
@@ -2573,7 +2579,8 @@ class STLClient(object):
force = False,
vm = None,
packet_hook = None,
- is_dual = False):
+ is_dual = False,
+ min_ipg_usec = None):
"""
Push a local PCAP to the server
This is equivalent to loading a PCAP file to a profile
@@ -2615,6 +2622,9 @@ class STLClient(object):
also requires that all the ports will be in master mode
with their adjacent ports as slaves
+ min_ipg_usec : float
+ Minimum inter-packet gap in microseconds to guard from too small ipg.
+
:raises:
+ :exc:`STLError`
@@ -2629,6 +2639,7 @@ class STLClient(object):
validate_type('duration', duration, (float, int))
validate_type('vm', vm, (list, type(None)))
validate_type('is_dual', is_dual, bool)
+ validate_type('min_ipg_usec', min_ipg_usec, (float, int, type(None)))
# no support for > 1MB PCAP - use push remote
@@ -2657,7 +2668,8 @@ class STLClient(object):
speedup,
count,
vm = vm,
- packet_hook = packet_hook)
+ packet_hook = packet_hook,
+ min_ipg_usec = min_ipg_usec)
self.logger.post_cmd(RC_OK)
except STLError as e:
self.logger.post_cmd(RC_ERR(e))
@@ -2682,7 +2694,8 @@ class STLClient(object):
count,
vm = vm,
packet_hook = packet_hook,
- split_mode = split_mode)
+ split_mode = split_mode,
+ min_ipg_usec = min_ipg_usec)
self.logger.post_cmd(RC_OK())
@@ -3653,6 +3666,7 @@ class STLClient(object):
parsing_opts.COUNT,
parsing_opts.DURATION,
parsing_opts.IPG,
+ parsing_opts.MIN_IPG,
parsing_opts.SPEEDUP,
parsing_opts.FORCE,
parsing_opts.DUAL]
@@ -3685,6 +3699,7 @@ class STLClient(object):
self.push_remote(opts.file[0],
ports = opts.ports,
ipg_usec = opts.ipg_usec,
+ min_ipg_usec = opts.min_ipg_usec,
speedup = opts.speedup,
count = opts.count,
duration = opts.duration,
@@ -3694,6 +3709,7 @@ class STLClient(object):
self.push_pcap(opts.file[0],
ports = opts.ports,
ipg_usec = opts.ipg_usec,
+ min_ipg_usec = opts.min_ipg_usec,
speedup = opts.speedup,
count = opts.count,
duration = opts.duration,
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 66d8be2b..9eefc177 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
@@ -735,7 +735,7 @@ class Port(object):
return self.get_rx_filter_mode() == 'all'
@writeable
- def push_remote (self, pcap_filename, ipg_usec, speedup, count, duration, is_dual, slave_handler):
+ def push_remote (self, pcap_filename, ipg_usec, speedup, count, duration, is_dual, slave_handler, min_ipg_usec):
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -745,7 +745,8 @@ class Port(object):
"count": count,
"duration": duration,
"is_dual": is_dual,
- "slave_handler": slave_handler}
+ "slave_handler": slave_handler,
+ "min_ipg_usec": min_ipg_usec if min_ipg_usec else 0}
rc = self.transmit("push_remote", params)
if rc.bad():
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 aa797773..3bce671a 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
@@ -987,7 +987,8 @@ class STLProfile(object):
loop_count = 1,
vm = None,
packet_hook = None,
- split_mode = None):
+ split_mode = None,
+ min_ipg_usec = None):
""" Convert a pcap file with a number of packets to a list of connected streams.
packet1->packet2->packet3 etc
@@ -1017,6 +1018,9 @@ class STLProfile(object):
used for dual mode
can be 'MAC' or 'IP'
+ min_ipg_usec : float
+ Minumum inter packet gap in usec. Used to guard from too small IPGs.
+
:return: STLProfile
"""
@@ -1025,8 +1029,9 @@ class STLProfile(object):
if not os.path.isfile(pcap_file):
raise STLError("file '{0}' does not exists".format(pcap_file))
- # make sure IPG is not less than 1 usec
- if ipg_usec is not None and ipg_usec < 0.001:
+ # make sure IPG is not less than 0.001 usec
+ if (ipg_usec is not None and (ipg_usec < 0.001 * speedup) and
+ (min_ipg_usec is None or min_ipg_usec < 0.001)):
raise STLError("ipg_usec cannot be less than 0.001 usec: '{0}'".format(ipg_usec))
if loop_count < 0:
@@ -1039,6 +1044,7 @@ class STLProfile(object):
pkts = PCAPReader(pcap_file).read_all()
return STLProfile.__pkts_to_streams(pkts,
ipg_usec,
+ min_ipg_usec,
speedup,
loop_count,
vm,
@@ -1059,6 +1065,7 @@ class STLProfile(object):
profile_a = STLProfile.__pkts_to_streams(pkts_a,
ipg_usec,
+ min_ipg_usec,
speedup,
loop_count,
vm,
@@ -1067,6 +1074,7 @@ class STLProfile(object):
profile_b = STLProfile.__pkts_to_streams(pkts_b,
ipg_usec,
+ min_ipg_usec,
speedup,
loop_count,
vm,
@@ -1081,28 +1089,37 @@ class STLProfile(object):
@staticmethod
- def __pkts_to_streams (pkts, ipg_usec, speedup, loop_count, vm, packet_hook, start_delay_usec = 0):
+ def __pkts_to_streams (pkts, ipg_usec, min_ipg_usec, speedup, loop_count, vm, packet_hook, start_delay_usec = 0):
streams = []
if speedup == 0:
raise STLError('Speedup should not be 0')
-
- # 10 ms delay before starting the PCAP
- last_ts_usec = -(start_delay_usec)
+ if min_ipg_usec and min_ipg_usec < 0:
+ raise STLError('min_ipg_usec should not be negative.')
if packet_hook:
pkts = [(packet_hook(cap), meta) for (cap, meta) in pkts]
+ if ipg_usec == None:
+ constant_diff = None
+ else:
+ constant_diff = ipg_usec / float(speedup)
+ if min_ipg_usec is not None:
+ constant_diff = max(constant_diff, min_ipg_usec)
for i, (cap, meta) in enumerate(pkts, start = 1):
# IPG - if not provided, take from cap
- if ipg_usec == None:
+ if constant_diff is None:
packet_time = meta[0] * 1e6 + meta[1]
if i == 1:
- base_time = packet_time
- ts_usec = (packet_time - base_time) / float(speedup)
+ isg = min_ipg_usec if min_ipg_usec else 0
+ else:
+ isg = (packet_time - prev_time) / float(speedup)
+ if min_ipg_usec:
+ isg = max(isg, min_ipg_usec)
+ prev_time = packet_time
else:
- ts_usec = (ipg_usec * i) / float(speedup)
+ isg = constant_diff
# handle last packet
if i == len(pkts):
@@ -1111,18 +1128,32 @@ class STLProfile(object):
else:
next = i + 1
action_count = 0
+ self_start = False if i != 1 else True
+
+ # add stream with delay that will not be part of loop: "delayed_start" -> 1 -> 2 -> 3 -> ... -> 1 -> 2
+ if start_delay_usec and i == 1:
+ if loop_count == 1: # no loop actually
+ isg = start_delay_usec
+ else:
+ streams.append(STLStream(name = 'delayed_start',
+ packet = STLPktBuilder(pkt_buffer = cap, vm = vm),
+ mode = STLTXSingleBurst(total_pkts = 1, percentage = 100),
+ self_start = True,
+ isg = start_delay_usec,
+ action_count = action_count,
+ next = next))
+ action_count = max(0, action_count - 1)
+ self_start = False
streams.append(STLStream(name = i,
packet = STLPktBuilder(pkt_buffer = cap, vm = vm),
mode = STLTXSingleBurst(total_pkts = 1, percentage = 100),
- self_start = True if (i == 1) else False,
- isg = (ts_usec - last_ts_usec), # seconds to usec
+ self_start = self_start,
+ isg = isg,
action_count = action_count,
next = next))
-
- last_ts_usec = ts_usec
-
+
profile = STLProfile(streams)
profile.meta = {'type': 'pcap'}
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 0a7b510f..f5dab30c 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
@@ -14,75 +14,85 @@ ArgumentGroup = namedtuple('ArgumentGroup', ['type', 'args', 'options'])
# list of available parsing options
-MULTIPLIER = 1
-MULTIPLIER_STRICT = 2
-PORT_LIST = 3
-ALL_PORTS = 4
-PORT_LIST_WITH_ALL = 5
-FILE_PATH = 6
-FILE_FROM_DB = 7
-SERVER_IP = 8
-STREAM_FROM_PATH_OR_FILE = 9
-DURATION = 10
-FORCE = 11
-DRY_RUN = 12
-XTERM = 13
-TOTAL = 14
-FULL_OUTPUT = 15
-IPG = 16
-SPEEDUP = 17
-COUNT = 18
-PROMISCUOUS = 19
-LINK_STATUS = 20
-LED_STATUS = 21
-TUNABLES = 22
-REMOTE_FILE = 23
-LOCKED = 24
-PIN_CORES = 25
-CORE_MASK = 26
-DUAL = 27
-FLOW_CTRL = 28
-SUPPORTED = 29
-FILE_PATH_NO_CHECK = 30
-
-OUTPUT_FILENAME = 31
-LIMIT = 33
-PORT_RESTART = 34
-
-RETRIES = 37
-
-SINGLE_PORT = 38
-DST_MAC = 39
-
-PING_IPV4 = 40
-PING_COUNT = 41
-PKT_SIZE = 42
-
-SERVICE_OFF = 43
-
-SRC_IPV4 = 44
-DST_IPV4 = 45
-
-GLOBAL_STATS = 50
-PORT_STATS = 51
-PORT_STATUS = 52
-STREAMS_STATS = 53
-STATS_MASK = 54
-CPU_STATS = 55
-MBUF_STATS = 56
-EXTENDED_STATS = 57
-EXTENDED_INC_ZERO_STATS = 58
-
-STREAMS_MASK = 60
-CORE_MASK_GROUP = 61
-
-# ALL_STREAMS = 61
-# STREAM_LIST_WITH_ALL = 62
+_constants = '''
+
+MULTIPLIER
+MULTIPLIER_STRICT
+PORT_LIST
+ALL_PORTS
+PORT_LIST_WITH_ALL
+FILE_PATH
+FILE_FROM_DB
+SERVER_IP
+STREAM_FROM_PATH_OR_FILE
+DURATION
+FORCE
+DRY_RUN
+XTERM
+TOTAL
+FULL_OUTPUT
+IPG
+MIN_IPG
+SPEEDUP
+COUNT
+PROMISCUOUS
+LINK_STATUS
+LED_STATUS
+TUNABLES
+REMOTE_FILE
+LOCKED
+PIN_CORES
+CORE_MASK
+DUAL
+FLOW_CTRL
+SUPPORTED
+FILE_PATH_NO_CHECK
+
+OUTPUT_FILENAME
+LIMIT
+PORT_RESTART
+
+RETRIES
+
+SINGLE_PORT
+DST_MAC
+
+PING_IPV4
+PING_COUNT
+PKT_SIZE
+
+SERVICE_OFF
+
+SRC_IPV4
+DST_IPV4
+
+GLOBAL_STATS
+PORT_STATS
+PORT_STATUS
+STREAMS_STATS
+STATS_MASK
+CPU_STATS
+MBUF_STATS
+EXTENDED_STATS
+EXTENDED_INC_ZERO_STATS
+
+STREAMS_MASK
+CORE_MASK_GROUP
+
+# ALL_STREAMS
+# STREAM_LIST_WITH_ALL
+# list of ArgumentGroup types
+MUTEX
+'''
+
+for index, line in enumerate(_constants.splitlines()):
+ var = line.strip().split()
+ if not var or '#' in var[0]:
+ continue
+ exec('%s = %s' % (var[0], index))
-# list of ArgumentGroup types
-MUTEX = 1
def check_negative(value):
ivalue = int(value)
@@ -314,6 +324,11 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'default': None,
'type': float}),
+ MIN_IPG: ArgumentPack(['--min-ipg'],
+ {'help': "Minimal IPG value in usec between packets. Used to guard from too small IPGs.",
+ 'dest': "min_ipg_usec",
+ 'default': None,
+ 'type': float}),
SPEEDUP: ArgumentPack(['-s', '--speedup'],
{'help': "Factor to accelerate the injection. effectively means IPG = IPG / SPEEDUP",