summaryrefslogtreecommitdiffstats
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
parent057a1ec1e70584f3598e9980bb44f70f73065bac (diff)
add min_ipg to push_pcaps
Change-Id: I353f8903c40963517fd2fed721cc0671d9f6dc4b Signed-off-by: Yaroslav Brustinov <ybrustin@cisco.com>
-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
-rw-r--r--src/gtest/trex_stateless_gtest.cpp4
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp6
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp2
-rw-r--r--src/stateless/cp/trex_stateless_port.h1
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp9
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h2
-rw-r--r--src/stateless/dp/trex_stream_node.h6
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp2
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h3
13 files changed, 184 insertions, 96 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",
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index 09942c57..2593261f 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -4340,6 +4340,7 @@ TEST_F(basic_stl, pcap_remote_basic) {
0,
"exp/remote_test.cap",
10,
+ 0,
1,
1,
-1,
@@ -4363,6 +4364,7 @@ TEST_F(basic_stl, pcap_remote_loop) {
0,
"exp/remote_test.cap",
1,
+ 0,
1,
3,
-1,
@@ -4385,6 +4387,7 @@ TEST_F(basic_stl, pcap_remote_duration) {
0,
"exp/remote_test.cap",
100000,
+ 0,
1,
0,
0.5,
@@ -4407,6 +4410,7 @@ TEST_F(basic_stl, pcap_remote_dual) {
0,
"exp/remote_test_dual.erf",
10000,
+ 0,
1,
0,
0.5,
diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
index f936f946..b3b1b3b4 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp
@@ -631,6 +631,10 @@ TrexRpcCmdPushRemote::_run(const Json::Value &params, Json::Value &result) {
uint8_t port_id = parse_port(params, result);
std::string pcap_filename = parse_string(params, "pcap_filename", result);
double ipg_usec = parse_double(params, "ipg_usec", result);
+ double min_ipg_sec = 0;
+ if (params.isMember("min_ipg_usec")) {
+ min_ipg_sec = usec_to_sec(parse_double(params, "min_ipg_usec", result));
+ }
double speedup = parse_double(params, "speedup", result);
uint32_t count = parse_uint32(params, "count", result);
double duration = parse_double(params, "duration", result);
@@ -649,7 +653,7 @@ TrexRpcCmdPushRemote::_run(const Json::Value &params, Json::Value &result) {
try {
- port->push_remote(pcap_filename, ipg_usec, speedup, count, duration, is_dual);
+ port->push_remote(pcap_filename, ipg_usec, min_ipg_sec, speedup, count, duration, is_dual);
} catch (const TrexException &ex) {
generate_execute_err(result, ex.what());
}
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 3a4db196..97f60dd6 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -511,6 +511,7 @@ TrexStatelessPort::update_traffic(const TrexPortMultiplier &mul, bool force) {
void
TrexStatelessPort::push_remote(const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
double duration,
@@ -550,6 +551,7 @@ TrexStatelessPort::push_remote(const std::string &pcap_filename,
m_pending_async_stop_event,
pcap_filename,
ipg_usec,
+ min_ipg_sec,
speedup,
count,
duration,
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 317f4f70..404e1355 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -221,6 +221,7 @@ public:
*/
void push_remote(const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
double duration,
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index 485e8533..6f9376c2 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -478,6 +478,7 @@ bool TrexStatelessDpPerPort::pause_traffic(uint8_t port_id){
bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
bool is_dual) {
@@ -508,6 +509,7 @@ bool TrexStatelessDpPerPort::push_pcap(uint8_t port_id,
slave_mac_addr,
pcap_filename,
ipg_usec,
+ min_ipg_sec,
speedup,
count,
is_dual);
@@ -1169,6 +1171,7 @@ TrexStatelessDpCore::push_pcap(uint8_t port_id,
int event_id,
const std::string &pcap_filename,
double ipg_usec,
+ double m_min_ipg_sec,
double speedup,
uint32_t count,
double duration,
@@ -1179,7 +1182,7 @@ TrexStatelessDpCore::push_pcap(uint8_t port_id,
lp_port->set_event_id(event_id);
/* delegate the command to the port */
- bool rc = lp_port->push_pcap(port_id, pcap_filename, ipg_usec, speedup, count, is_dual);
+ bool rc = lp_port->push_pcap(port_id, pcap_filename, ipg_usec, m_min_ipg_sec, speedup, count, is_dual);
if (!rc) {
/* report back that we stopped */
CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(m_core->m_thread_id);
@@ -1263,6 +1266,7 @@ bool CGenNodePCAP::create(uint8_t port_id,
const uint8_t *slave_mac_addr,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
bool is_dual) {
@@ -1275,13 +1279,14 @@ bool CGenNodePCAP::create(uint8_t port_id,
m_count = count;
m_is_dual = is_dual;
m_dir = dir;
+ m_min_ipg_sec = min_ipg_sec;
/* mark this node as slow path */
set_slow_path(true);
if (ipg_usec != -1) {
/* fixed IPG */
- m_ipg_sec = usec_to_sec(ipg_usec / speedup);
+ m_ipg_sec = std::max(min_ipg_sec, usec_to_sec(ipg_usec / speedup));
m_speedup = 0;
} else {
/* packet IPG */
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index b386daf7..e880a6eb 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -74,6 +74,7 @@ public:
bool push_pcap(uint8_t port_id,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
bool is_dual);
@@ -183,6 +184,7 @@ public:
int event_id,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
double duration,
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index dda3113a..bc7be057 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -468,6 +468,7 @@ public:
const uint8_t *slave_mac_addr,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
bool is_dual);
@@ -536,7 +537,7 @@ public:
if (m_ipg_sec != -1) {
return m_ipg_sec;
} else {
- return ((m_raw_packet->get_time() - m_last_pkt_time) / m_speedup);
+ return (std::max(m_min_ipg_sec, (m_raw_packet->get_time() - m_last_pkt_time) / m_speedup));
}
}
@@ -632,6 +633,7 @@ private:
double m_last_pkt_time;
double m_speedup;
double m_ipg_sec;
+ double m_min_ipg_sec;
uint32_t m_count;
double m_next_time_offset; /* in sec */
@@ -644,7 +646,7 @@ private:
bool m_is_dual;
/* pad to match the size of CGenNode */
- uint8_t m_pad_end[19];
+ uint8_t m_pad_end[11];
} __rte_cache_aligned;
diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp
index 2b8e93bb..aeb1e677 100644
--- a/src/stateless/messaging/trex_stateless_messaging.cpp
+++ b/src/stateless/messaging/trex_stateless_messaging.cpp
@@ -191,6 +191,7 @@ TrexStatelessDpPushPCAP::handle(TrexStatelessDpCore *dp_core) {
m_event_id,
m_pcap_filename,
m_ipg_usec,
+ m_min_ipg_sec,
m_speedup,
m_count,
m_duration,
@@ -204,6 +205,7 @@ TrexStatelessDpPushPCAP::clone() {
m_event_id,
m_pcap_filename,
m_ipg_usec,
+ m_min_ipg_sec,
m_speedup,
m_count,
m_duration,
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
index dbdd9b56..72b92d11 100644
--- a/src/stateless/messaging/trex_stateless_messaging.h
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -313,6 +313,7 @@ public:
int event_id,
const std::string &pcap_filename,
double ipg_usec,
+ double min_ipg_sec,
double speedup,
uint32_t count,
double duration,
@@ -321,6 +322,7 @@ public:
m_port_id = port_id;
m_event_id = event_id;
m_ipg_usec = ipg_usec;
+ m_min_ipg_sec = min_ipg_sec;
m_speedup = speedup;
m_count = count;
m_duration = duration;
@@ -335,6 +337,7 @@ private:
std::string m_pcap_filename;
int m_event_id;
double m_ipg_usec;
+ double m_min_ipg_sec;
double m_speedup;
double m_duration;
uint32_t m_count;