summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-02-23 15:32:19 +0200
committerHanoh Haim <hhaim@cisco.com>2016-02-23 15:32:19 +0200
commit36cc1ecef32dcee3640e6ddf96422c07d89777b3 (patch)
tree6a9eadb662ad0f98395886077fe32943512fd040
parent68ebd739646a27f1bb92ce8eacb5bb76f6399580 (diff)
parent81059eb5df274efe48ad3914039ddb657c3285ab (diff)
Merge ipv4 checksum issue
-rwxr-xr-xlinux_dpdk/ws_main.py2
-rwxr-xr-xscripts/automation/regression/trex_unit_test.py2
-rwxr-xr-xscripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py169
-rwxr-xr-xscripts/automation/regression/unit_tests/trex_general_test.py11
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py2
-rw-r--r--scripts/automation/trex_control_plane/stl/examples/stl_imix.py2
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py313
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py29
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py16
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py63
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py133
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py11
-rwxr-xr-xsrc/bp_sim.cpp5
-rw-r--r--src/dpdk22/drivers/net/i40e/i40e_ethdev.c13
-rw-r--r--src/dpdk22/lib/librte_ether/rte_ethdev.c15
-rw-r--r--src/dpdk22/lib/librte_ether/rte_ethdev.h2
-rw-r--r--src/gtest/trex_stateless_gtest.cpp96
-rwxr-xr-xsrc/main.cpp9
-rwxr-xr-xsrc/main_dpdk.cpp27
-rwxr-xr-xsrc/msg_manager.cpp15
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp80
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h21
-rw-r--r--src/sim/trex_sim.h62
-rw-r--r--src/sim/trex_sim_stateless.cpp69
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp16
-rw-r--r--src/stateless/cp/trex_stateless_port.h15
-rw-r--r--src/stateless/cp/trex_stream.cpp28
-rw-r--r--src/stateless/cp/trex_stream.h233
-rw-r--r--src/stateless/cp/trex_stream_vm.h16
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp36
-rw-r--r--src/stateless/cp/trex_streams_compiler.h16
31 files changed, 1033 insertions, 494 deletions
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index 19d884cd..b533004a 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -833,6 +833,8 @@ files_list=[
't-rex-debug-gdb',
'stl-sim',
'find_python.sh',
+ 'run_regression',
+ 'run_functional_tests',
'release_notes.pdf',
'dpdk_nic_bind.py',
'dpdk_setup_ports.py',
diff --git a/scripts/automation/regression/trex_unit_test.py b/scripts/automation/regression/trex_unit_test.py
index be063846..fca733ba 100755
--- a/scripts/automation/regression/trex_unit_test.py
+++ b/scripts/automation/regression/trex_unit_test.py
@@ -213,7 +213,7 @@ if __name__ == "__main__":
CTRexScenario.setup_name = os.path.basename(CTRexScenario.setup_dir)
xml_name = 'report_%s.xml' % CTRexScenario.setup_name
- nose_argv = ['-s', '-v', '--exe', '--rednose', '--detailed-errors']
+ nose_argv = ['', '-s', '-v', '--exe', '--rednose', '--detailed-errors']
if '--collect-only' in sys.argv: # this is a user trying simply to view the available tests. no need xunit.
CTRexScenario.is_test_list = True
else:
diff --git a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py
index e76e3bb0..df93aba1 100755
--- a/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py
+++ b/scripts/automation/regression/unit_tests/functional_tests/hltapi_stream_builder_test.py
@@ -38,11 +38,10 @@ class CTRexHltApi_Test(unittest.TestCase):
with self.assertRaises(Exception):
STLHltStream(l2_encap = 'ethernet_sdfgsdfg')
# all default values
- test_stream = STLHltStream(name = 'stream-0')
+ test_stream = STLHltStream()
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
- stream:
+- stream:
action_count: 0
enabled: true
flags: 3
@@ -61,10 +60,10 @@ class CTRexHltApi_Test(unittest.TestCase):
split_by_var: ''
'''
- # Eth/IP/TCP, test L2 fields, wait for masking of variables for MAC
+ # Eth/IP/TCP, test MAC fields VM, wait for masking of variables for MAC
@nottest
- def test_l2_basic(self):
- test_stream = STLHltStream(name = 'stream-0')
+ def test_macs_vm(self):
+ test_stream = STLHltStream(name = 'stream-0', )
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
TBD
@@ -73,16 +72,30 @@ TBD
# Eth/IP/TCP, ip src and dest is changed by VM
def test_ip_ranges(self):
- test_stream = STLHltStream(ip_src_addr = '192.168.1.1',
+ # running on single core not implemented yet
+ with self.assertRaises(Exception):
+ test_stream = STLHltStream(split_by_cores = 'single',
+ ip_src_addr = '192.168.1.1',
+ ip_src_mode = 'increment',
+ ip_src_count = 5,)
+ # wrong type
+ with self.assertRaises(Exception):
+ test_stream = STLHltStream(split_by_cores = 12345,
+ ip_src_addr = '192.168.1.1',
+ ip_src_mode = 'increment',
+ ip_src_count = 5,)
+
+ test_stream = STLHltStream(split_by_cores = 'duplicate',
+ ip_src_addr = '192.168.1.1',
ip_src_mode = 'increment',
ip_src_count = 5,
ip_dst_addr = '5.5.5.5',
ip_dst_count = 2,
ip_dst_mode = 'random',
- name = 'stream-0')
+ name = 'test_ip_ranges')
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_ip_ranges
stream:
action_count: 0
enabled: true
@@ -112,9 +125,9 @@ TBD
name: ip_src
pkt_offset: 26
type: write_flow_var
- - init_value: 84215045
- max_value: 84215046
- min_value: 84215045
+ - init_value: 0
+ max_value: 4294967295
+ min_value: 0
name: ip_dst
op: random
size: 4
@@ -137,10 +150,10 @@ TBD
tcp_dst_port_mode = 'random',
tcp_dst_port_count = 10,
tcp_dst_port = 1234,
- name = 'stream-0')
+ name = 'test_tcp_ranges')
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_tcp_ranges
stream:
action_count: 0
enabled: true
@@ -170,9 +183,9 @@ TBD
name: tcp_src
pkt_offset: 34
type: write_flow_var
- - init_value: 1234
- max_value: 1243
- min_value: 1234
+ - init_value: 0
+ max_value: 65535
+ min_value: 0
name: tcp_dst
op: random
size: 2
@@ -185,7 +198,7 @@ TBD
type: write_flow_var
- pkt_offset: 14
type: fix_checksum_ipv4
- split_by_var: ''
+ split_by_var: tcp_src
'''
# Eth / IP / UDP, udp ports are changed by VM
@@ -214,10 +227,10 @@ TBD
udp_dst_port_mode = 'increment',
udp_dst_port_count = 10,
udp_dst_port = 1234,
- name = 'stream-0')
+ name = 'test_udp_ranges')
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_udp_ranges
stream:
action_count: 0
enabled: true
@@ -262,7 +275,7 @@ TBD
type: write_flow_var
- pkt_offset: 14
type: fix_checksum_ipv4
- split_by_var: ''
+ split_by_var: udp_src
'''
# Eth/IP/TCP, packet length is changed in VM by frame_size
@@ -274,10 +287,10 @@ TBD
test_stream = STLHltStream(length_mode = 'decrement',
frame_size_min = 100,
frame_size_max = 3000,
- name = 'stream-0')
+ name = 'test_pkt_len_by_framesize')
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_pkt_len_by_framesize
stream:
action_count: 0
enabled: true
@@ -311,7 +324,7 @@ TBD
type: write_flow_var
- pkt_offset: 14
type: fix_checksum_ipv4
- split_by_var: ''
+ split_by_var: pkt_len
'''
# Eth/IP/UDP, packet length is changed in VM by l3_length
@@ -320,10 +333,10 @@ TBD
length_mode = 'random',
l3_length_min = 100,
l3_length_max = 400,
- name = 'stream-0')
+ name = 'test_pkt_len_by_l3length')
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_pkt_len_by_l3length
stream:
action_count: 0
enabled: true
@@ -373,11 +386,11 @@ TBD
test_stream = STLHltStream(l2_encap = 'ethernet_ii')
assert ':802.1Q:' not in test_stream.get_pkt_type(), 'Default packet should not include dot1q'
- test_stream = STLHltStream(name = 'stream-0', l2_encap = 'ethernet_ii_vlan')
+ test_stream = STLHltStream(name = 'test_vlan_basic', l2_encap = 'ethernet_ii_vlan')
assert ':802.1Q:' in test_stream.get_pkt_type(), 'No dot1q in packet with encap ethernet_ii_vlan'
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_vlan_basic
stream:
action_count: 0
enabled: true
@@ -402,12 +415,14 @@ TBD
# default frame size should be not enough
with self.assertRaises(Exception):
STLHltStream(vlan_id = [1, 2, 3, 4])
- test_stream = STLHltStream(name = 'stream-0', frame_size = 100, vlan_id = [1, 2, 3, 4], vlan_protocol_tag_id = '8100 0x8100')
+ test_stream = STLHltStream(name = 'test_vlan_multiple', frame_size = 100,
+ vlan_id = [1, 2, 3, 4], # can be either array or string separated by spaces
+ vlan_protocol_tag_id = '8100 0x8100')
pkt_layers = test_stream.get_pkt_type()
- assert ':802.1Q:802.1Q:802.1Q:802.1Q:' in pkt_layers, 'No four dot1q layers in packet: %s' % pkt_layers
+ assert '802.1Q:' * 4 in pkt_layers, 'No four dot1q layers in packet: %s' % pkt_layers
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_vlan_multiple
stream:
action_count: 0
enabled: true
@@ -427,6 +442,84 @@ TBD
split_by_var: ''
'''
+ # Eth/IP/TCP, with 5 vlans and VMs on vlan_id
+ def test_vlan_vm(self):
+ test_stream = STLHltStream(name = 'test_vlan_vm', frame_size = 100,
+ vlan_id = '1 2 1000 4 5', # 5 vlans
+ vlan_id_mode = 'increment fixed decrement random', # 5th vlan will be default fixed
+ vlan_id_step = 2, # 1st vlan step will be 2, others - default 1
+ vlan_id_count = [4, 1, 10], # 4th independent on count, 5th will be fixed
+ )
+ pkt_layers = test_stream.get_pkt_type()
+ self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
+ assert '802.1Q:' * 5 in pkt_layers, 'No five dot1q layers in packet: %s' % pkt_layers
+ self.golden_yaml = '''
+- name: test_vlan_vm
+ stream:
+ action_count: 0
+ enabled: true
+ flags: 3
+ isg: 0.0
+ mode:
+ pps: 1
+ type: continuous
+ packet:
+ binary: AAAAAAAAAAABAAABgQAwAYEAMAKBADPogQAwBIEAMAUIAEUAAEIAAAAAQAa6tQAAAADAAAABBAAAUAAAAAEAAAABUAAP5SzkAAAhISEhISEhISEhISEhISEhISEhISEhISEhIQ==
+ meta: ''
+ rx_stats:
+ enabled: false
+ self_start: true
+ vm:
+ instructions:
+ - init_value: 1
+ max_value: 7
+ min_value: 1
+ name: vlan_id0
+ op: inc
+ size: 2
+ step: 2
+ type: flow_var
+ - is_big_endian: true
+ mask: 4095
+ name: vlan_id0
+ pkt_cast_size: 2
+ pkt_offset: 14
+ shift: 0
+ type: write_mask_flow_var
+ - init_value: 1000
+ max_value: 1000
+ min_value: 991
+ name: vlan_id2
+ op: dec
+ size: 2
+ step: 1
+ type: flow_var
+ - is_big_endian: true
+ mask: 4095
+ name: vlan_id2
+ pkt_cast_size: 2
+ pkt_offset: 22
+ shift: 0
+ type: write_mask_flow_var
+ - init_value: 0
+ max_value: 65535
+ min_value: 0
+ name: vlan_id3
+ op: random
+ size: 2
+ step: 1
+ type: flow_var
+ - is_big_endian: true
+ mask: 4095
+ name: vlan_id3
+ pkt_cast_size: 2
+ pkt_offset: 26
+ shift: 0
+ type: write_mask_flow_var
+ split_by_var: vlan_id2
+'''
+
+
# Eth/IPv6/TCP, no VM
def test_ipv6_basic(self):
# default frame size should be not enough
@@ -437,10 +530,10 @@ TBD
# error should affect
with self.assertRaises(Exception):
STLHltStream(l3_protocol = 'ipv6', ipv6_src_addr = 'asdfasdfasgasdf')
- test_stream = STLHltStream(name = 'stream-0', l3_protocol = 'ipv6', length_mode = 'fixed', l3_length = 150, )
+ test_stream = STLHltStream(name = 'test_ipv6_basic', l3_protocol = 'ipv6', length_mode = 'fixed', l3_length = 150, )
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_ipv6_basic
stream:
action_count: 0
enabled: true
@@ -462,7 +555,7 @@ TBD
# Eth/IPv6/UDP, VM on ipv6 fields
def test_ipv6_src_dst_ranges(self):
- test_stream = STLHltStream(name = 'stream-0', l3_protocol = 'ipv6', l3_length = 150, l4_protocol = 'udp',
+ test_stream = STLHltStream(name = 'test_ipv6_src_dst_ranges', l3_protocol = 'ipv6', l3_length = 150, l4_protocol = 'udp',
ipv6_src_addr = '1111:2222:3333:4444:5555:6666:7777:8888',
ipv6_dst_addr = '1111:1111:1111:1111:1111:1111:1111:1111',
ipv6_src_mode = 'increment', ipv6_src_step = 5, ipv6_src_count = 10,
@@ -470,7 +563,7 @@ TBD
)
self.test_yaml = test_stream.dump_to_yaml(self.yaml_save_location())
self.golden_yaml = '''
-- name: stream-0
+- name: test_ipv6_src_dst_ranges
stream:
action_count: 0
enabled: true
@@ -488,7 +581,7 @@ TBD
vm:
instructions:
- init_value: 2004322440
- max_value: 2004322449
+ max_value: 2004322485
min_value: 2004322440
name: ipv6_src
op: inc
@@ -502,7 +595,7 @@ TBD
type: write_flow_var
- init_value: 286331153
max_value: 286331153
- min_value: 286331004
+ min_value: 286328620
name: ipv6_dst
op: dec
size: 4
@@ -513,7 +606,7 @@ TBD
name: ipv6_dst
pkt_offset: 50
type: write_flow_var
- split_by_var: ''
+ split_by_var: ipv6_dst
'''
diff --git a/scripts/automation/regression/unit_tests/trex_general_test.py b/scripts/automation/regression/unit_tests/trex_general_test.py
index 14af4820..f367a397 100755
--- a/scripts/automation/regression/unit_tests/trex_general_test.py
+++ b/scripts/automation/regression/unit_tests/trex_general_test.py
@@ -243,9 +243,14 @@ class CTRexGeneral_Test(unittest.TestCase):
m_total_alloc_error = trex_res.get_last_value("trex-global.data.m_total_alloc_error")
m_total_queue_full = trex_res.get_last_value("trex-global.data.m_total_queue_full")
m_total_queue_drop = trex_res.get_last_value("trex-global.data.m_total_queue_drop")
- self.assert_gt( 999, m_total_alloc_error, 'Got allocation errors. (%s), please review multiplier and templates configuration.' % m_total_alloc_error)
- self.assert_gt( max(9999, trex_tx_pckt / 1000 ), m_total_queue_full, 'Too much queue_full (%s), please review multiplier.' % m_total_queue_full)
- self.assert_gt( 999, m_total_queue_drop, 'Too much queue_drop (%s), please review multiplier.' % m_total_queue_drop)
+ self.assert_gt(1000, m_total_alloc_error, 'Got allocation errors. (%s), please review multiplier and templates configuration.' % m_total_alloc_error)
+ self.assert_gt(1000, m_total_queue_drop, 'Too much queue_drop (%s), please review multiplier.' % m_total_queue_drop)
+
+ if self.is_VM:
+ allowed_queue_full = 10000 + trex_tx_pckt / 100
+ else:
+ allowed_queue_full = 1000 + trex_tx_pckt / 1000
+ self.assert_gt(allowed_queue_full, m_total_queue_full, 'Too much queue_full (%s), please review multiplier.' % m_total_queue_full)
# # check T-Rex expected counters
#trex_exp_rate = trex_res.get_expected_tx_rate().get('m_tx_expected_bps')
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 9e9dcf62..0beb10df 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -532,7 +532,7 @@ class TRexConsole(TRexGeneralCmd):
info = self.stateless_client.get_connection_info()
exe = './trex-console --top -t -q -s {0} -p {1} --async_port {2}'.format(info['server'], info['sync_port'], info['async_port'])
- cmd = ['xterm', '-geometry', '111x42', '-sl', '0', '-title', 'trex_tui', '-e', exe]
+ cmd = ['xterm', '-geometry', '111x47', '-sl', '0', '-title', 'trex_tui', '-e', exe]
self.terminal = subprocess.Popen(cmd)
return
diff --git a/scripts/automation/trex_control_plane/stl/examples/stl_imix.py b/scripts/automation/trex_control_plane/stl/examples/stl_imix.py
index b9fbbbb6..e3c01ca9 100644
--- a/scripts/automation/trex_control_plane/stl/examples/stl_imix.py
+++ b/scripts/automation/trex_control_plane/stl/examples/stl_imix.py
@@ -35,7 +35,7 @@ def imix_test ():
dir_1 = table['dir'][1]
# load IMIX profile
- profile = STLProfile.load_py('../../../../stl/profiles/imix.py')
+ profile = STLProfile.load_py('../../../../stl/imix.py')
streams = profile.get_streams()
# add both streams to ports
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py
index 5311884d..60654f0a 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_hltapi.py
@@ -22,6 +22,7 @@ cleanup_session_kwargs = {
# traffic_config()
traffic_config_kwargs = {
'mode': None, # ( create | modify | remove | reset )
+ 'split_by_cores': 'split', # ( split | duplicate | single ) TRex extention: split = split traffic by cores, duplicate = duplicate traffic for all cores, single = run only with sinle core (not implemented yet)
'port_handle': None,
'port_handle2': None,
# stream builder parameters
@@ -32,6 +33,7 @@ traffic_config_kwargs = {
'stream_id': None,
'name': None,
'bidirectional': 0,
+ 'direction': 0, # ( 0 | 1 ) TRex extention: 1 = exchange sources and destinations
'pkts_per_burst': 1,
'burst_loop_count': 1,
'inter_burst_gap': 12,
@@ -327,7 +329,7 @@ class CTRexHltApi(object):
# connection successfully created with server, try acquiring ports of TRex
try:
- port_list = self.parse_port_list(kwargs['port_list'])
+ port_list = self._parse_port_list(kwargs['port_list'])
self.trex_client.acquire(ports = port_list, force = kwargs['break_locks'])
except Exception as e:
self.trex_client = None
@@ -358,7 +360,7 @@ class CTRexHltApi(object):
if port_list == 'all':
port_list = self.trex_client.get_acquired_ports()
else:
- port_list = self.parse_port_list(port_list)
+ port_list = self._parse_port_list(port_list)
except Exception as e:
return HLT_ERR('Unable to determine which ports to release: %s' % e if isinstance(e, STLError) else traceback.format_exc())
try:
@@ -412,10 +414,7 @@ class CTRexHltApi(object):
else:
stream_id = stream_id[0]
- port_handle = kwargs['port_handle']
- if type(port_handle) is not list:
- port_handle = [port_handle]
-
+ port_handle = port_list = self._parse_port_list(kwargs['port_handle'])
ALLOWED_MODES = ['create', 'modify', 'remove', 'enable', 'disable', 'reset']
if mode not in ALLOWED_MODES:
return HLT_ERR('Mode must be one of the following values: %s' % ALLOWED_MODES)
@@ -455,13 +454,12 @@ class CTRexHltApi(object):
# if stream_id not in self._streams_history:
# return HLT_ERR('This stream_id (%s) was not used before, please create new.' % stream_id)
# self._streams_history[stream_id].update(kwargs) # <- the modification
-
if mode == 'modify': # we remove stream and create new one with same stream_id
stream_id = kwargs.get('stream_id')
if stream_id is None:
return HLT_ERR('Please specify stream_id to modify.')
-
+
if len(port_handle) > 1:
for port in port_handle:
user_kwargs[port_handle] = port
@@ -502,12 +500,10 @@ class CTRexHltApi(object):
if res1['status'] == 0:
raise STLError('Could not create bidirectional stream 1: %s' % res1['log'])
streams_per_port.add_streams_from_res(res1)
+ kwargs['direction'] = 1 - kwargs['direction'] # not
+ correct_direction(user_kwargs, kwargs)
user_kwargs['mac_src'] = kwargs['mac_src2']
user_kwargs['mac_dst'] = kwargs['mac_dst2']
- user_kwargs['ip_src_addr'] = kwargs['ip_dst_addr']
- user_kwargs['ip_dst_addr'] = kwargs['ip_src_addr']
- user_kwargs['ipv6_src_addr'] = kwargs['ipv6_dst_addr']
- user_kwargs['ipv6_dst_addr'] = kwargs['ipv6_src_addr']
if save_to_yaml and type(save_to_yaml) is str:
user_kwargs['save_to_yaml'] = save_to_yaml.replace('.yaml', '_bi2.yaml')
user_kwargs['port_handle'] = port_handle2
@@ -657,30 +653,15 @@ class CTRexHltApi(object):
# Private functions #
###########################
- # obsolete
@staticmethod
- def process_response(port_list, response):
- log = response.data() if response.good() else response.err()
- if isinstance(port_list, list):
- log = CTRexHltApi.join_batch_response(log)
- return response.good(), log
-
- @staticmethod
- def parse_port_list(port_list):
- if isinstance(port_list, str):
- return [int(port)
- for port in port_list.split()]
- elif isinstance(port_list, list):
- return [int(port)
- for port in port_list]
- else:
- return port_list
-
- @staticmethod
- def join_batch_response(responses):
- if type(responses) is list():
- return '\n'. join([str(response) for response in responses])
- return responses
+ def _parse_port_list(port_list):
+ if type(port_list) is str:
+ return [int(port) for port in port_list.strip().split()]
+ elif type(port_list) is list:
+ return [int(port) for port in port_list]
+ elif type(port) in (int, long):
+ return [int(port_list)]
+ raise STLError('port_list should be string with ports, list, or single number')
def STLHltStream(**user_kwargs):
kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs)
@@ -745,7 +726,6 @@ def STLHltStream(**user_kwargs):
#self_start = True,
mode = transmit_mode_class,
#rx_stats = rx_stats,
- #next_stream_id = -1,
stream_id = kwargs.get('stream_id'),
name = kwargs.get('name'),
)
@@ -761,6 +741,7 @@ def STLHltStream(**user_kwargs):
def generate_packet(**user_kwargs):
correct_macs(user_kwargs)
kwargs = merge_kwargs(traffic_config_kwargs, user_kwargs)
+ correct_direction(kwargs, kwargs)
vm_cmds = []
fix_ipv4_checksum = False
@@ -772,42 +753,70 @@ def generate_packet(**user_kwargs):
# XShortEnumField("type", 0x9000, ETHER_TYPES) ]
l2_layer = Ether(src = kwargs['mac_src'], dst = kwargs['mac_dst'])
- # TODO: add Eth VM once variable masking will be done
+ # Eth VM
+ # WIP!!! Need 8 bytes mask and vars
+ if kwargs['mac_src_mode'] != 'fixed':
+ mac_src_count = kwargs['mac_src_count'] - 1
+ if mac_src_count < 0:
+ raise STLError('mac_src_count has to be at least 1')
+ if mac_src_count > 0:
+ mac_src = mac_str_to_num(mac2str(kwargs['mac_src']))
+ if kwargs['mac_src_mode'] == 'increment':
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'inc', step = kwargs['mac_src_step'],
+ min_value = mac_src,
+ max_value = mac_src + mac_src_count * kwargs['mac_src_step']))
+ elif kwargs['mac_src_mode'] == 'decrement':
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'dec', step = kwargs['mac_src_step'],
+ min_value = mac_src - mac_src_count * kwargs['mac_src_step'],
+ max_value = mac_src))
+ elif kwargs['mac_src_mode'] == 'random':
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'mac_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffffffffffff))
+ else:
+ raise STLError('mac_src_mode %s is not supported' % kwargs['mac_src_mode'])
+ vm_cmds.append(STLVmWrMaskFlowVar(fv_name = 'mac_src', pkt_offset = 'Ethernet.src', pkt_cast_size = 4, mask = 0xffffffff))
+
if kwargs['l2_encap'] == 'ethernet_ii_vlan' or (kwargs['l2_encap'] == 'ethernet_ii' and vlan_in_args(user_kwargs)):
#fields_desc = [ BitField("prio", 0, 3),
# BitField("id", 0, 1),
# BitField("vlan", 1, 12),
# XShortEnumField("type", 0x0000, ETHER_TYPES) ]
for i, vlan_kwargs in enumerate(split_vlan_args(kwargs)):
+ vlan_id = int(vlan_kwargs['vlan_id'])
dot1q_kwargs = {'prio': vlan_kwargs['vlan_user_priority'],
- 'vlan': vlan_kwargs['vlan_id'],
+ 'vlan': vlan_id,
'id': vlan_kwargs['vlan_cfi']}
- if vlan_kwargs['vlan_protocol_tag_id'] is not None:
- dot1q_kwargs['type'] = vlan_kwargs['vlan_protocol_tag_id']
+ vlan_protocol_tag_id = vlan_kwargs['vlan_protocol_tag_id']
+ if vlan_protocol_tag_id is not None:
+ if type(vlan_protocol_tag_id) is str:
+ vlan_protocol_tag_id = int(vlan_protocol_tag_id, 16)
+ dot1q_kwargs['type'] = vlan_protocol_tag_id
l2_layer /= Dot1Q(**dot1q_kwargs)
+
# vlan VM
- if vlan_kwargs['vlan_id_mode'] != 'fixed':
- if vlan_kwargs['vlan_id_count'] < 1:
+ vlan_id_mode = vlan_kwargs['vlan_id_mode']
+ if vlan_id_mode != 'fixed':
+ vlan_id_count = int(vlan_kwargs['vlan_id_count']) - 1
+ if vlan_id_count < 0:
raise STLError('vlan_id_count has to be at least 1')
- if kwargs['vlan_id_count'] > 1:
+ if vlan_id_count > 0 or vlan_id_mode == 'random':
var_name = 'vlan_id%s' % i
- raise STLError('vlan_id VM not supported yet, waiting for bitmask from stateless')
- if kwargs['vlan_id_mode'] == 'increment':
- vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'inc', step = vlan_kwargs['vlan_id_step'],
- min_value = kwargs['vlan_id'],
- max_value = kwargs['vlan_id'] + kwargs['vlan_id_count'] - 1))
- elif kwargs['vlan_id_mode'] == 'decrement':
- vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'dec', step = vlan_kwargs['vlan_id_step'],
- min_value = kwargs['vlan_id'] - kwargs['vlan_id_count'] + 1,
- max_value = kwargs['vlan_id']))
- elif kwargs['vlan_id_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 4, op = 'random',
- min_value = kwargs['vlan_id'],
- max_value = kwargs['vlan_id'] + kwargs['vlan_id_count'] - 1))
+ step = int(vlan_kwargs['vlan_id_step'])
+ if vlan_id_mode == 'increment':
+ vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'inc', step = step,
+ min_value = vlan_id,
+ max_value = vlan_id + vlan_id_count * step))
+ elif vlan_id_mode == 'decrement':
+ vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'dec', step = step,
+ min_value = vlan_id - vlan_id_count * step,
+ max_value = vlan_id))
+ elif vlan_id_mode == 'random':
+ vm_cmds.append(CTRexVmDescFlowVar(name = var_name, size = 2, op = 'random', min_value = 0, max_value = 0xffff))
else:
- raise STLError('vlan_id_mode %s is not supported' % kwargs['vlan_id_mode'])
- vm_cmds.append(CTRexVmDescWrFlowVar(fv_name = var_name, pkt_offset = 'Dot1Q:%s.vlan' % i))
+ raise STLError('vlan_id_mode %s is not supported' % vlan_id_mode)
+ vm_cmds.append(STLVmWrMaskFlowVar(fv_name = var_name, pkt_offset = '802|1Q:%s.vlan' % i,
+ pkt_cast_size = 2, mask = 0xfff))
+
else:
raise NotImplementedError("l2_encap does not support the desired encapsulation '%s'" % kwargs['l2_encap'])
base_pkt = l2_layer
@@ -830,7 +839,7 @@ def generate_packet(**user_kwargs):
ip_tos = get_TOS(user_kwargs, kwargs)
if ip_tos < 0 or ip_tos > 255:
raise STLError('TOS %s is not in range 0-255' % ip_tos)
- l3_layer = IP(tos = get_TOS(user_kwargs, kwargs),
+ l3_layer = IP(tos = ip_tos,
len = kwargs['l3_length'],
id = kwargs['ip_id'],
frag = kwargs['ip_fragment_offset'],
@@ -841,45 +850,53 @@ def generate_packet(**user_kwargs):
)
# IPv4 VM
if kwargs['ip_src_mode'] != 'fixed':
- if kwargs['ip_src_count'] < 1:
+ ip_src_count = kwargs['ip_src_count'] - 1
+ if ip_src_count < 0:
raise STLError('ip_src_count has to be at least 1')
- if kwargs['ip_src_count'] > 1:
+ if ip_src_count > 0:
fix_ipv4_checksum = True
- ip_src_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_src_addr']))
+ ip_src_addr = kwargs['ip_src_addr']
+ if type(ip_src_addr) is str:
+ ip_src_addr = ipv4_str_to_num(is_valid_ipv4(ip_src_addr))
+ ip_src_step = kwargs['ip_src_step']
+ if type(ip_src_step) is str:
+ ip_src_step = ipv4_str_to_num(is_valid_ipv4(ip_src_step))
if kwargs['ip_src_mode'] == 'increment':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = kwargs['ip_src_step'],
- min_value = ip_src_addr_num,
- max_value = ip_src_addr_num + kwargs['ip_src_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'inc', step = ip_src_step,
+ min_value = ip_src_addr,
+ max_value = ip_src_addr + ip_src_count * ip_src_step))
elif kwargs['ip_src_mode'] == 'decrement':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = kwargs['ip_src_step'],
- min_value = ip_src_addr_num - kwargs['ip_src_count'] + 1,
- max_value = ip_src_addr_num))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'dec', step = ip_src_step,
+ min_value = ip_src_addr - ip_src_count * ip_src_step,
+ max_value = ip_src_addr))
elif kwargs['ip_src_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random',
- min_value = ip_src_addr_num,
- max_value = ip_src_addr_num + kwargs['ip_src_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff))
else:
raise STLError('ip_src_mode %s is not supported' % kwargs['ip_src_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ip_src', pkt_offset = 'IP.src'))
if kwargs['ip_dst_mode'] != 'fixed':
- if kwargs['ip_dst_count'] < 1:
+ ip_dst_count = kwargs['ip_dst_count'] - 1
+ if ip_dst_count < 0:
raise STLError('ip_dst_count has to be at least 1')
- if kwargs['ip_dst_count'] > 1:
+ if ip_dst_count > 0:
fix_ipv4_checksum = True
- ip_dst_addr_num = ipv4_str_to_num(is_valid_ipv4(kwargs['ip_dst_addr']))
+ ip_dst_addr = kwargs['ip_dst_addr']
+ if type(ip_dst_addr) is str:
+ ip_dst_addr = ipv4_str_to_num(is_valid_ipv4(ip_dst_addr))
+ ip_dst_step = kwargs['ip_dst_step']
+ if type(ip_dst_step) is str:
+ ip_dst_step = ipv4_str_to_num(is_valid_ipv4(ip_dst_step))
if kwargs['ip_dst_mode'] == 'increment':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = kwargs['ip_dst_step'],
- min_value = ip_dst_addr_num,
- max_value = ip_dst_addr_num + kwargs['ip_dst_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'inc', step = ip_dst_step,
+ min_value = ip_dst_addr,
+ max_value = ip_dst_addr + ip_dst_count * ip_dst_step))
elif kwargs['ip_dst_mode'] == 'decrement':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = kwargs['ip_dst_step'],
- min_value = ip_dst_addr_num - kwargs['ip_dst_count'] + 1,
- max_value = ip_dst_addr_num))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'dec', step = ip_dst_step,
+ min_value = ip_dst_addr - ip_dst_count * ip_dst_step,
+ max_value = ip_dst_addr))
elif kwargs['ip_dst_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random',
- min_value = ip_dst_addr_num,
- max_value = ip_dst_addr_num + kwargs['ip_dst_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ip_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff))
else:
raise STLError('ip_dst_mode %s is not supported' % kwargs['ip_dst_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ip_dst', pkt_offset = 'IP.dst'))
@@ -902,51 +919,50 @@ def generate_packet(**user_kwargs):
if kwargs['ipv6_next_header'] is not None:
ipv6_kwargs['nh'] = kwargs['ipv6_next_header']
l3_layer = IPv6(**ipv6_kwargs)
+
# IPv6 VM
if kwargs['ipv6_src_mode'] != 'fixed':
- if kwargs['ipv6_src_count'] < 1:
+ ipv6_src_count = kwargs['ipv6_src_count'] - 1
+ if ipv6_src_count < 0:
raise STLError('ipv6_src_count has to be at least 1')
- if kwargs['ipv6_src_count'] > 1:
+ if ipv6_src_count > 0:
ipv6_src_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_src_addr'])[-4:])
ipv6_src_step = kwargs['ipv6_src_step']
- if type(kwargs['ipv6_src_step']) is str: # convert ipv6 step to number
+ if type(ipv6_src_step) is str: # convert ipv6 step to number
ipv6_src_step = ipv4_str_to_num(is_valid_ipv6(ipv6_src_step)[-4:])
if kwargs['ipv6_src_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'inc', step = ipv6_src_step,
min_value = ipv6_src_addr_num,
- max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] - 1))
+ max_value = ipv6_src_addr_num + ipv6_src_count * ipv6_src_step))
elif kwargs['ipv6_src_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'dec', step = ipv6_src_step,
- min_value = ipv6_src_addr_num - kwargs['ipv6_src_count'] + 1,
+ min_value = ipv6_src_addr_num - ipv6_src_count * ipv6_src_step,
max_value = ipv6_src_addr_num))
elif kwargs['ipv6_src_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'random',
- min_value = ipv6_src_addr_num,
- max_value = ipv6_src_addr_num + kwargs['ipv6_src_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_src', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff))
else:
raise STLError('ipv6_src_mode %s is not supported' % kwargs['ipv6_src_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ipv6_src', pkt_offset = 'IPv6.src', offset_fixup = 12))
if kwargs['ipv6_dst_mode'] != 'fixed':
- if kwargs['ipv6_dst_count'] < 1:
+ ipv6_dst_count = kwargs['ipv6_dst_count'] - 1
+ if ipv6_dst_count < 0:
raise STLError('ipv6_dst_count has to be at least 1')
- if kwargs['ipv6_dst_count'] > 1:
+ if ipv6_dst_count > 0:
ipv6_dst_addr_num = ipv4_str_to_num(is_valid_ipv6(kwargs['ipv6_dst_addr'])[-4:])
ipv6_dst_step = kwargs['ipv6_dst_step']
- if type(kwargs['ipv6_dst_step']) is str: # convert ipv6 step to number
+ if type(ipv6_dst_step) is str: # convert ipv6 step to number
ipv6_dst_step = ipv4_str_to_num(is_valid_ipv6(ipv6_dst_step)[-4:])
if kwargs['ipv6_dst_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'inc', step = ipv6_dst_step,
min_value = ipv6_dst_addr_num,
- max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] - 1))
+ max_value = ipv6_dst_addr_num + ipv6_dst_count * ipv6_dst_step))
elif kwargs['ipv6_dst_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'dec', step = ipv6_dst_step,
- min_value = ipv6_dst_addr_num - kwargs['ipv6_dst_count'] + 1,
+ min_value = ipv6_dst_addr_num - ipv6_dst_count * ipv6_dst_step,
max_value = ipv6_dst_addr_num))
elif kwargs['ipv6_dst_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'random',
- min_value = ipv6_dst_addr_num,
- max_value = ipv6_dst_addr_num + kwargs['ipv6_dst_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'ipv6_dst', size = 4, op = 'random', min_value = 0, max_value = 0xffffffff))
else:
raise STLError('ipv6_dst_mode %s is not supported' % kwargs['ipv6_dst_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='ipv6_dst', pkt_offset = 'IPv6.dst', offset_fixup = 12))
@@ -986,44 +1002,42 @@ def generate_packet(**user_kwargs):
urgptr = kwargs['tcp_urgent_ptr'],
)
# TCP VM
- if kwargs['tcp_src_port_count'] != 1:
- if kwargs['tcp_src_port_count'] < 1:
+ if kwargs['tcp_src_port_mode'] != 'fixed':
+ tcp_src_port_count = kwargs['tcp_src_port_count'] - 1
+ if tcp_src_port_count < 0:
raise STLError('tcp_src_port_count has to be at least 1')
- if kwargs['tcp_src_port_count'] > 1:
+ if tcp_src_port_count > 0:
fix_ipv4_checksum = True
if kwargs['tcp_src_port_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'inc', step = kwargs['tcp_src_port_step'],
min_value = kwargs['tcp_src_port'],
- max_value = kwargs['tcp_src_port'] + kwargs['tcp_src_port_count'] - 1))
+ max_value = kwargs['tcp_src_port'] + tcp_src_port_count * kwargs['tcp_src_port_step']))
elif kwargs['tcp_src_port_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'dec', step = kwargs['tcp_src_port_step'],
- min_value = kwargs['tcp_src_port'] - kwargs['tcp_src_port_count'] +1,
+ min_value = kwargs['tcp_src_port'] - tcp_src_port_count * kwargs['tcp_src_port_step'],
max_value = kwargs['tcp_src_port']))
elif kwargs['tcp_src_port_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'random',
- min_value = kwargs['tcp_src_port'],
- max_value = kwargs['tcp_src_port'] + kwargs['tcp_src_port_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff))
else:
raise STLError('tcp_src_port_mode %s is not supported' % kwargs['tcp_src_port_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='tcp_src', pkt_offset = 'TCP.sport'))
- if kwargs['tcp_dst_port_count'] != 1:
- if kwargs['tcp_dst_port_count'] < 1:
+ if kwargs['tcp_dst_port_mode'] != 'fixed':
+ tcp_dst_port_count = kwargs['tcp_dst_port_count'] - 1
+ if tcp_dst_port_count < 0:
raise STLError('tcp_dst_port_count has to be at least 1')
- if kwargs['tcp_dst_port_count'] > 1:
+ if tcp_dst_port_count > 0:
fix_ipv4_checksum = True
if kwargs['tcp_dst_port_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'inc', step = kwargs['tcp_dst_port_step'],
min_value = kwargs['tcp_dst_port'],
- max_value = kwargs['tcp_dst_port'] + kwargs['tcp_dst_port_count'] - 1))
+ max_value = kwargs['tcp_dst_port'] + tcp_dst_port_count * kwargs['tcp_dst_port_step']))
elif kwargs['tcp_dst_port_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'dec', step = kwargs['tcp_dst_port_step'],
- min_value = kwargs['tcp_dst_port'] - kwargs['tcp_dst_port_count'] +1,
+ min_value = kwargs['tcp_dst_port'] - tcp_dst_port_count * kwargs['tcp_dst_port_step'],
max_value = kwargs['tcp_dst_port']))
elif kwargs['tcp_dst_port_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'random',
- min_value = kwargs['tcp_dst_port'],
- max_value = kwargs['tcp_dst_port'] + kwargs['tcp_dst_port_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'tcp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff))
else:
raise STLError('tcp_dst_port_mode %s is not supported' % kwargs['tcp_dst_port_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='tcp_dst', pkt_offset = 'TCP.dport'))
@@ -1037,44 +1051,42 @@ def generate_packet(**user_kwargs):
dport = kwargs['udp_dst_port'],
len = kwargs['udp_length'], chksum = None)
# UDP VM
- if kwargs['udp_src_port_count'] != 1:
- if kwargs['udp_src_port_count'] < 1:
+ if kwargs['udp_src_port_mode'] != 'fixed':
+ udp_src_port_count = kwargs['udp_src_port_count'] - 1
+ if udp_src_port_count < 0:
raise STLError('udp_src_port_count has to be at least 1')
- if kwargs['udp_src_port_count'] > 1:
+ if udp_src_port_count > 0:
fix_ipv4_checksum = True
if kwargs['udp_src_port_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'inc', step = kwargs['udp_src_port_step'],
min_value = kwargs['udp_src_port'],
- max_value = kwargs['udp_src_port'] + kwargs['udp_src_port_count'] - 1))
+ max_value = kwargs['udp_src_port'] + udp_src_port_count * kwargs['udp_src_port_step']))
elif kwargs['udp_src_port_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'dec', step = kwargs['udp_src_port_step'],
- min_value = kwargs['udp_src_port'] - kwargs['udp_src_port_count'] +1,
+ min_value = kwargs['udp_src_port'] - udp_src_port_count * kwargs['udp_src_port_step'],
max_value = kwargs['udp_src_port']))
elif kwargs['udp_src_port_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'random',
- min_value = kwargs['udp_src_port'],
- max_value = kwargs['udp_src_port'] + kwargs['udp_src_port_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_src', size = 2, op = 'random', min_value = 0, max_value = 0xffff))
else:
raise STLError('udp_src_port_mode %s is not supported' % kwargs['udp_src_port_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='udp_src', pkt_offset = 'UDP.sport'))
- if kwargs['udp_dst_port_count'] != 1:
- if kwargs['udp_dst_port_count'] < 1:
+ if kwargs['udp_dst_port_mode'] != 'fixed':
+ udp_dst_port_count = kwargs['udp_dst_port_count'] - 1
+ if udp_dst_port_count < 0:
raise STLError('udp_dst_port_count has to be at least 1')
- if kwargs['udp_dst_port_count'] > 1:
+ if udp_dst_port_count > 0:
fix_ipv4_checksum = True
if kwargs['udp_dst_port_mode'] == 'increment':
vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'inc', step = kwargs['udp_dst_port_step'],
min_value = kwargs['udp_dst_port'],
- max_value = kwargs['udp_dst_port'] + kwargs['udp_dst_port_count'] - 1))
+ max_value = kwargs['udp_dst_port'] + udp_dst_port_count * kwargs['udp_dst_port_step']))
elif kwargs['udp_dst_port_mode'] == 'decrement':
vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'dec', step = kwargs['udp_dst_port_step'],
- min_value = kwargs['udp_dst_port'] - kwargs['udp_dst_port_count'] +1,
+ min_value = kwargs['udp_dst_port'] - udp_dst_port_count * kwargs['udp_dst_port_step'],
max_value = kwargs['udp_dst_port']))
elif kwargs['udp_dst_port_mode'] == 'random':
- vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'random',
- min_value = kwargs['udp_dst_port'],
- max_value = kwargs['udp_dst_port'] + kwargs['udp_dst_port_count'] - 1))
+ vm_cmds.append(CTRexVmDescFlowVar(name = 'udp_dst', size = 2, op = 'random', min_value = 0, max_value = 0xffff))
else:
raise STLError('udp_dst_port_mode %s is not supported' % kwargs['udp_dst_port_mode'])
vm_cmds.append(CTRexVmDescWrFlowVar(fv_name='udp_dst', pkt_offset = 'UDP.dport'))
@@ -1138,7 +1150,25 @@ def generate_packet(**user_kwargs):
if fix_ipv4_checksum and l3_layer.name == 'IP' and kwargs['ip_checksum'] is None:
vm_cmds.append(CTRexVmDescFixIpv4(offset = 'IP'))
if vm_cmds:
- pkt.add_command(CTRexScRaw(vm_cmds))
+ split_by_field = None
+ if kwargs['split_by_cores'] == 'single':
+ raise STLError("split_by_cores 'single' not implemented yet")
+ elif kwargs['split_by_cores'] == 'split':
+ max_length = 0
+ for cmd in vm_cmds:
+ if isinstance(cmd, CTRexVmDescFlowVar):
+ if cmd.op not in ('inc', 'dec'):
+ continue
+ length = float(cmd.max_value - cmd.min_value) / cmd.step
+ if cmd.name == 'ip_src' and length > 7: # priority is to split by ip_src
+ split_by_field = 'ip_src'
+ break
+ if length > max_length:
+ max_length = length
+ split_by_field = cmd.name
+ elif kwargs['split_by_cores'] != 'duplicate':
+ raise STLError("split_by_cores '%s' not supported" % kwargs['split_by_cores'])
+ pkt.add_command(CTRexScRaw(vm_cmds, split_by_field))
# debug (only the base packet, without VM)
debug_filename = kwargs.get('save_to_pcap')
@@ -1183,10 +1213,6 @@ def split_vlan_args(kwargs):
for arg, value in kwargs.items():
if arg.startswith('vlan_'):
vlan_args_dict[arg] = split_vlan_arg(value)
- if arg == 'vlan_protocol_tag_id': # special case, can be string of hex
- print vlan_args_dict[arg]
- vlan_args_dict[arg] = [int(x, 16) for x in vlan_args_dict[arg] if type(x) is str]
- print vlan_args_dict[arg]
dot1q_headers_count = max([len(x) for x in vlan_args_dict.values()])
vlan_args_per_header = [{} for _ in range(dot1q_headers_count)]
for arg, value in vlan_args_dict.items():
@@ -1197,4 +1223,17 @@ def split_vlan_args(kwargs):
vlan_args_per_header[i][arg] = traffic_config_kwargs[arg]
return vlan_args_per_header
-
+def correct_direction(user_kwargs, kwargs):
+ if kwargs['direction'] == 0:
+ return
+ user_kwargs['mac_src'], user_kwargs['mac_dst'] = kwargs['mac_dst'], kwargs['mac_src']
+ if kwargs['l3_protocol'] == 'ipv4':
+ for arg in kwargs.keys():
+ if 'ip_src_' in arg:
+ dst_arg = 'ip_dst_' + arg[7:]
+ user_kwargs[arg], user_kwargs[dst_arg] = kwargs[dst_arg], kwargs[arg]
+ elif kwargs['l3_protocol'] == 'ipv6':
+ for arg in kwargs.keys():
+ if 'ipv6_src_' in arg:
+ dst_arg = 'ipv6_dst_' + arg[9:]
+ user_kwargs[arg], user_kwargs[dst_arg] = kwargs[dst_arg], kwargs[arg]
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
index 24a7301b..713769b6 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
@@ -28,17 +28,24 @@ class CTRexPacketBuildException(Exception):
################################################################################################
-def ipv4_str_to_num (ipv4_buffer):
+def _buffer_to_num(str_buffer):
+ assert type(str_buffer)==str, 'type of str_buffer is not str'
+ res=0
+ for i in str_buffer:
+ res = res << 8
+ res += ord(i)
+ return res
+
+def ipv4_str_to_num (ipv4_buffer):
assert type(ipv4_buffer)==str, 'type of ipv4_buffer is not str'
assert len(ipv4_buffer)==4, 'size of ipv4_buffer is not 4'
- res=0
- shift=24
- for i in ipv4_buffer:
- res = res + (ord(i)<<shift);
- shift =shift -8
- return res
+ return _buffer_to_num(ipv4_buffer)
+def mac_str_to_num (mac_buffer):
+ assert type(mac_buffer)==str, 'type of mac_buffer is not str'
+ assert len(mac_buffer)==6, 'size of mac_buffer is not 6'
+ return _buffer_to_num(mac_buffer)
def is_valid_ipv4(ip_addr):
@@ -215,12 +222,16 @@ class CTRexVmInsFlowVar(CTRexVmInsBase):
self.op = op
self.init_value = init_value
assert type(init_value)==int, 'type of init_value is not int'
+ assert init_value >= 0, 'init_value (%s) is negative' % init_value
self.min_value=min_value
assert type(min_value)==int, 'type of min_value is not int'
+ assert min_value >= 0, 'min_value (%s) is negative' % min_value
self.max_value=max_value
- assert type(max_value)==int, 'type of min_value is not int'
+ assert type(max_value)==int, 'type of max_value is not int'
+ assert max_value >= 0, 'max_value (%s) is negative' % max_value
self.step=step
assert type(step)==int, 'type of step should be int'
+ assert step >= 0, 'step (%s) is negative' % step
class CTRexVmInsWrFlowVar(CTRexVmInsBase):
def __init__(self, fv_name, pkt_offset, add_value=0, is_big_endian=True):
@@ -588,7 +599,7 @@ class CTRexVmDescWrMaskFlowVar(CTRexVmDescBase):
self.pkt_offset =pkt_offset
self.pkt_cast_size =pkt_cast_size
assert type(pkt_cast_size)==int,'type of pkt_cast_size is not int'
- if not (pkt_cast_size in [1,2,4]):
+ if not (pkt_cast_size in [1,2,4,8]):
raise CTRexPacketBuildException(-10,"not valid cast size");
self.mask = mask
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 838a49ed..29bad041 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
@@ -4,6 +4,7 @@ from collections import namedtuple, OrderedDict
import trex_stl_stats
from trex_stl_types import *
import time
+import copy
StreamOnPort = namedtuple('StreamOnPort', ['compiled_stream', 'metadata'])
@@ -160,8 +161,8 @@ class Port(object):
return self.err("Please stop port before attempting to add streams")
# listify
- streams_list = streams_list if isinstance(streams_list, list) else [streams_list]
-
+ streams_list = copy.deepcopy(streams_list if isinstance(streams_list, list) else [streams_list])
+
lookup = {}
# allocate IDs
@@ -171,10 +172,12 @@ class Port(object):
lookup[stream.get_name()] = stream.get_id()
- # resolve names
+ batch = []
+
+
for stream in streams_list:
- next_id = -1
+ next_id = -1
next = stream.get_next()
if next:
if not next in lookup:
@@ -183,10 +186,7 @@ class Port(object):
stream.set_next_id(next_id)
-
-
- batch = []
- for stream in streams_list:
+
stream_json = stream.to_json()
stream_json['next_stream_id'] = stream.get_next_id()
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index e5578564..34c7a857 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -117,8 +117,10 @@ class CTRexInfoGenerator(object):
per_field_stats = OrderedDict([("owner", []),
("state", []),
("--", []),
- ("Tx bps", []),
+ ("Tx bps L2", []),
+ ("Tx bps L1", []),
("Tx pps", []),
+ ("Line Util.", []),
("---", []),
("Rx bps", []),
@@ -313,7 +315,15 @@ class CTRexStats(object):
# must be implemented by designated classes (such as port/ global stats)
raise NotImplementedError()
+ def generate_extended_values (self, snapshot):
+ raise NotImplementedError()
+
+
def update(self, snapshot):
+
+ # some extended generated values (from base values)
+ self.generate_extended_values(snapshot)
+
# update
self.latest_stats = snapshot
@@ -326,6 +336,8 @@ class CTRexStats(object):
if (not self.reference_stats) or (diff_time > 3):
self.reference_stats = self.latest_stats
+
+
self.last_update_ts = time.time()
@@ -439,6 +451,20 @@ class CGlobalStats(CTRexStats):
return stats
+ def generate_extended_values (self, snapshot):
+ # L1 bps
+ bps = snapshot.get("m_tx_bps")
+ pps = snapshot.get("m_tx_pps")
+
+ if pps > 0:
+ avg_pkt_size = bps / (pps * 8.0)
+ bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+ else:
+ bps_L1 = 0.0
+
+ snapshot['m_tx_bps_L1'] = bps_L1
+
+
def generate_stats(self):
return OrderedDict([("connection", "{host}, Port {port}".format(host=self.connection_info.get("server"),
port=self.connection_info.get("sync_port"))),
@@ -450,8 +476,11 @@ class CGlobalStats(CTRexStats):
(" ", ""),
- ("total_tx", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
- self.get_trend_gui("m_tx_bps"))),
+ ("total_tx_L2", u"{0} {1}".format( self.get("m_tx_bps", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_tx_bps"))),
+
+ ("total_tx_L1", u"{0} {1}".format( self.get("m_tx_bps_L1", format=True, suffix="b/sec"),
+ self.get_trend_gui("m_tx_bps_L1"))),
("total_rx", u"{0} {1}".format( self.get("m_rx_bps", format=True, suffix="b/sec"),
self.get_trend_gui("m_rx_bps"))),
@@ -532,6 +561,21 @@ class CPortStats(CTRexStats):
return stats
+ def generate_extended_values (self, snapshot):
+ # L1 bps
+ bps = snapshot.get("m_total_tx_bps")
+ pps = snapshot.get("m_total_tx_pps")
+
+ if pps > 0:
+ avg_pkt_size = bps / (pps * 8.0)
+ bps_L1 = bps * ( (avg_pkt_size + 20.0) / avg_pkt_size )
+ else:
+ bps_L1 = 0.0
+
+ snapshot['m_total_tx_bps_L1'] = bps_L1
+ snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100
+
+
def generate_stats(self):
state = self._port_obj.get_port_state_name() if self._port_obj else ""
@@ -542,6 +586,7 @@ class CPortStats(CTRexStats):
else:
state = format_text(state, 'bold')
+
return {"owner": self._port_obj.user if self._port_obj else "",
"state": "{0}".format(state),
@@ -550,8 +595,16 @@ class CPortStats(CTRexStats):
"----": " ",
"-----": " ",
- "Tx bps": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
- self.get("m_total_tx_bps", format = True, suffix = "bps")),
+ "Tx bps L1": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps_L1", show_value = False),
+ self.get("m_total_tx_bps_L1", format = True, suffix = "bps")),
+
+ "Tx bps L2": u"{0} {1}".format(self.get_trend_gui("m_total_tx_bps", show_value = False),
+ self.get("m_total_tx_bps", format = True, suffix = "bps")),
+
+ "Line Util.": u"{0} {1}".format(self.get_trend_gui("m_percentage", show_value = False),
+ format_text(
+ self.get("m_percentage", format = True, suffix = "%") if self._port_obj else "",
+ 'bold')),
"Rx bps": u"{0} {1}".format(self.get_trend_gui("m_total_rx_bps", show_value = False),
self.get("m_total_rx_bps", format = True, suffix = "bps")),
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 b72b5d35..f79d25c3 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
@@ -1,6 +1,7 @@
#!/router/bin/python
from trex_stl_exceptions import *
+from trex_stl_types import verify_exclusive_arg, validate_type
from trex_stl_packet_builder_interface import CTrexPktBuilderInterface
from trex_stl_packet_builder_scapy import CScapyTRexPktBuilder, Ether, IP, UDP, TCP, RawPcapReader
from collections import OrderedDict, namedtuple
@@ -11,15 +12,50 @@ import yaml
import base64
import string
import traceback
-
-def random_name (l):
- return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(l))
+from types import NoneType
+import copy
# base class for TX mode
class STLTXMode(object):
- def __init__ (self):
- self.fields = {}
+ def __init__ (self, pps = None, bps_L1 = None, bps_L2 = None, percentage = None):
+ args = [pps, bps_L1, bps_L2, percentage]
+
+ # default
+ if all([x is None for x in args]):
+ pps = 1.0
+ else:
+ verify_exclusive_arg(args)
+
+ self.fields = {'rate': {}}
+
+ if pps is not None:
+ validate_type('pps', pps, [float, int])
+
+ self.fields['rate']['type'] = 'pps'
+ self.fields['rate']['value'] = pps
+
+ elif bps_L1 is not None:
+ validate_type('bps_L1', bps_L1, [float, int])
+
+ self.fields['rate']['type'] = 'bps_L1'
+ self.fields['rate']['value'] = bps_L1
+
+ elif bps_L2 is not None:
+ validate_type('bps_L2', bps_L2, [float, int])
+
+ self.fields['rate']['type'] = 'bps_L2'
+ self.fields['rate']['value'] = bps_L2
+
+ elif percentage is not None:
+ validate_type('percentage', percentage, [float, int])
+ if not (percentage > 0 and percentage <= 100):
+ raise STLArgumentError('percentage', percentage)
+
+ self.fields['rate']['type'] = 'percentage'
+ self.fields['rate']['value'] = percentage
+
+
def to_json (self):
return self.fields
@@ -28,15 +64,11 @@ class STLTXMode(object):
# continuous mode
class STLTXCont(STLTXMode):
- def __init__ (self, pps = 1):
+ def __init__ (self, pps = None, bps_L1 = None, bps_L2 = None, percentage = None):
- if not isinstance(pps, (int, float)):
- raise STLArgumentError('pps', pps)
-
- super(STLTXCont, self).__init__()
+ super(STLTXCont, self).__init__(pps, bps_L1, bps_L2, percentage)
self.fields['type'] = 'continuous'
- self.fields['pps'] = pps
def __str__ (self):
return "Continuous"
@@ -44,18 +76,14 @@ class STLTXCont(STLTXMode):
# single burst mode
class STLTXSingleBurst(STLTXMode):
- def __init__ (self, pps = 1, total_pkts = 1):
-
- if not isinstance(pps, (int, float)):
- raise STLArgumentError('pps', pps)
+ def __init__ (self, total_pkts = 1, pps = None, bps_L1 = None, bps_L2 = None, percentage = None):
if not isinstance(total_pkts, int):
raise STLArgumentError('total_pkts', total_pkts)
- super(STLTXSingleBurst, self).__init__()
+ super(STLTXSingleBurst, self).__init__(pps, bps_L1, bps_L2, percentage)
self.fields['type'] = 'single_burst'
- self.fields['pps'] = pps
self.fields['total_pkts'] = total_pkts
def __str__ (self):
@@ -65,13 +93,13 @@ class STLTXSingleBurst(STLTXMode):
class STLTXMultiBurst(STLTXMode):
def __init__ (self,
- pps = 1,
pkts_per_burst = 1,
ibg = 0.0, # usec not SEC
- count = 1):
-
- if not isinstance(pps, (int, float)):
- raise STLArgumentError('pps', pps)
+ count = 1,
+ pps = None,
+ bps_L1 = None,
+ bps_L2 = None,
+ percentage = None):
if not isinstance(pkts_per_burst, int):
raise STLArgumentError('pkts_per_burst', pkts_per_burst)
@@ -82,10 +110,9 @@ class STLTXMultiBurst(STLTXMode):
if not isinstance(count, int):
raise STLArgumentError('count', count)
- super(STLTXMultiBurst, self).__init__()
+ super(STLTXMultiBurst, self).__init__(pps, bps_L1, bps_L2, percentage)
self.fields['type'] = 'multi_burst'
- self.fields['pps'] = pps
self.fields['pkts_per_burst'] = pkts_per_burst
self.fields['ibg'] = ibg
self.fields['count'] = count
@@ -104,7 +131,7 @@ class STLStream(object):
def __init__ (self,
name = None,
packet = None,
- mode = STLTXCont(1),
+ mode = STLTXCont(pps = 1),
enabled = True,
self_start = True,
isg = 0.0,
@@ -117,20 +144,12 @@ class STLStream(object):
):
# type checking
- if not isinstance(mode, STLTXMode):
- raise STLArgumentError('mode', mode)
-
- if packet and not isinstance(packet, CTrexPktBuilderInterface):
- raise STLArgumentError('packet', packet)
-
- if not isinstance(enabled, bool):
- raise STLArgumentError('enabled', enabled)
-
- if not isinstance(self_start, bool):
- raise STLArgumentError('self_start', self_start)
-
- if not isinstance(isg, (int, float)):
- raise STLArgumentError('isg', isg)
+ validate_type('mode', mode, STLTXMode)
+ validate_type('packet', packet, (NoneType, CTrexPktBuilderInterface))
+ validate_type('enabled', enabled, bool)
+ validate_type('self_start', self_start, bool)
+ validate_type('isg', isg, (int, float))
+ validate_type('stream_id', stream_id, (NoneType, int))
if (type(mode) == STLTXCont) and (next != None):
raise STLError("continuous stream cannot have a next stream ID")
@@ -181,6 +200,8 @@ class STLStream(object):
self.fields['mode'] = mode.to_json()
self.mode_desc = str(mode)
+
+ # packet
self.fields['packet'] = {}
self.fields['vm'] = {}
@@ -249,8 +270,6 @@ class STLStream(object):
return pkt_len
- def get_pps (self):
- return self.fields['mode']['pps']
def get_mode (self):
return self.mode_desc
@@ -265,7 +284,14 @@ class STLStream(object):
if self.next:
y['next'] = self.next
- y['stream'] = self.fields
+ y['stream'] = copy.deepcopy(self.fields)
+
+ # some shortcuts for YAML
+ rate_type = self.fields['mode']['rate']['type']
+ rate_value = self.fields['mode']['rate']['value']
+
+ y['stream']['mode'][rate_type] = rate_value
+ del y['stream']['mode']['rate']
return y
@@ -313,23 +339,29 @@ class YAMLLoader(object):
def __parse_mode (self, mode_obj):
+ rate_parser = set(mode_obj).intersection(['pps', 'bps_L1', 'bps_L2', 'percentage'])
+ if len(rate_parser) != 1:
+ raise STLError("'rate' must contain exactly one from 'pps', 'bps_L1', 'bps_L2', 'percentage'")
+
+ rate_type = rate_parser.pop()
+ rate = {rate_type : mode_obj[rate_type]}
+
mode_type = mode_obj.get('type')
if mode_type == 'continuous':
- defaults = STLTXCont()
- mode = STLTXCont(pps = mode_obj.get('pps', defaults.fields['pps']))
+ mode = STLTXCont(**rate)
elif mode_type == 'single_burst':
defaults = STLTXSingleBurst()
- mode = STLTXSingleBurst(pps = mode_obj.get('pps', defaults.fields['pps']),
- total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts']))
+ mode = STLTXSingleBurst(total_pkts = mode_obj.get('total_pkts', defaults.fields['total_pkts']),
+ **rate)
elif mode_type == 'multi_burst':
defaults = STLTXMultiBurst()
- mode = STLTXMultiBurst(pps = mode_obj.get('pps', defaults.fields['pps']),
- pkts_per_burst = mode_obj.get('pkts_per_burst', defaults.fields['pkts_per_burst']),
+ mode = STLTXMultiBurst(pkts_per_burst = mode_obj.get('pkts_per_burst', defaults.fields['pkts_per_burst']),
ibg = mode_obj.get('ibg', defaults.fields['ibg']),
- count = mode_obj.get('count', defaults.fields['count']))
+ count = mode_obj.get('count', defaults.fields['count']),
+ **rate)
else:
raise STLError("mode type can be 'continuous', 'single_burst' or 'multi_burst")
@@ -338,6 +370,8 @@ class YAMLLoader(object):
return mode
+
+
def __parse_stream (self, yaml_object):
s_obj = yaml_object['stream']
@@ -536,3 +570,4 @@ class STLProfile(object):
def __len__ (self):
return len(self.streams)
+
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
index 0a6e64fb..d4ad8bd2 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_types.py
@@ -2,6 +2,7 @@
from collections import namedtuple
from utils.text_opts import *
from trex_stl_exceptions import *
+import types
RpcCmdData = namedtuple('RpcCmdData', ['method', 'params'])
TupleRC = namedtuple('RC', ['rc', 'data', 'is_warn'])
@@ -102,9 +103,17 @@ def RC_WARN (warn):
def validate_type(arg_name, arg, valid_types):
if type(valid_types) is list:
valid_types = tuple(valid_types)
- if type(valid_types) is type or type(valid_types) is tuple:
+ if (type(valid_types) is type or # single type, not array of types
+ type(valid_types) is tuple or # several valid types as tuple
+ type(valid_types) is types.ClassType): # old style class
if isinstance(arg, valid_types):
return
raise STLTypeError(arg_name, type(arg), valid_types)
else:
raise STLError('validate_type: valid_types should be type or list or tuple of types')
+
+# throws STLError if not exactly one argument is present
+def verify_exclusive_arg (args_list):
+ if not (len(filter(lambda x: x is not None, args_list)) == 1):
+ raise STLError('exactly one parameter from {0} should be provided'.format(args_list))
+
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index a1851b55..88e2c3ad 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -4137,7 +4137,10 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name,
void CFlowGenList::Delete(){
clean_p_thread_info();
Clean();
- delete CPluginCallback::callback;
+ if (CPluginCallback::callback) {
+ delete CPluginCallback::callback;
+ CPluginCallback::callback = NULL;
+ }
}
diff --git a/src/dpdk22/drivers/net/i40e/i40e_ethdev.c b/src/dpdk22/drivers/net/i40e/i40e_ethdev.c
index 7542ade1..0a1e9efc 100644
--- a/src/dpdk22/drivers/net/i40e/i40e_ethdev.c
+++ b/src/dpdk22/drivers/net/i40e/i40e_ethdev.c
@@ -2071,6 +2071,19 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
i40e_update_vsi_stats(pf->main_vsi);
}
+// TREX_PATCH
+int
+i40e_trex_get_speed(struct rte_eth_dev *dev)
+{
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (i40e_is_40G_device(hw->device_id)) {
+ return 40;
+ } else {
+ return 10;
+ }
+}
+
/* Get all statistics of a port */
static void
i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
diff --git a/src/dpdk22/lib/librte_ether/rte_ethdev.c b/src/dpdk22/lib/librte_ether/rte_ethdev.c
index ed971b49..43ec0265 100644
--- a/src/dpdk22/lib/librte_ether/rte_ethdev.c
+++ b/src/dpdk22/lib/librte_ether/rte_ethdev.c
@@ -1430,6 +1430,21 @@ rte_eth_link_get_nowait(uint8_t port_id, struct rte_eth_link *eth_link)
}
}
+// TREX_PATCH
+int
+rte_eth_get_speed(uint8_t port_id, int *speed)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+
+ dev = &rte_eth_devices[port_id];
+
+ // Only xl710 support this
+ *speed = i40e_trex_get_speed(dev);
+ return 0;
+}
+
int
rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats)
{
diff --git a/src/dpdk22/lib/librte_ether/rte_ethdev.h b/src/dpdk22/lib/librte_ether/rte_ethdev.h
index f8c7c86d..e4bc9742 100644
--- a/src/dpdk22/lib/librte_ether/rte_ethdev.h
+++ b/src/dpdk22/lib/librte_ether/rte_ethdev.h
@@ -2150,6 +2150,8 @@ extern void rte_eth_link_get(uint8_t port_id, struct rte_eth_link *link);
extern void rte_eth_link_get_nowait(uint8_t port_id,
struct rte_eth_link *link);
+extern int rte_eth_get_speed(uint8_t port_id, int *speed);
+
/**
* Retrieve the general I/O statistics of an Ethernet device.
*
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index 3faaedeb..576f7d6e 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -1874,7 +1874,7 @@ TEST_F(basic_stl, basic_pause_resume0) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -1937,7 +1937,7 @@ void CBBStartStopDelay2::call_after_init(CBasicStl * m_obj){
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -1985,7 +1985,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2063,7 +2063,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2114,7 +2114,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop3) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2165,7 +2165,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop2) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2218,7 +2218,7 @@ TEST_F(basic_stl, single_pkt_bb_start_stop) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2270,7 +2270,7 @@ TEST_F(basic_stl, simple_prog4) {
/* stream0 */
TrexStream * stream0 = new TrexStream(TrexStream::stCONTINUOUS, 0,300);
- stream0->set_pps(1.0);
+ stream0->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream0->m_enabled = true;
stream0->m_self_start = true;
@@ -2283,7 +2283,7 @@ TEST_F(basic_stl, simple_prog4) {
/* stream1 */
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(5);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2299,7 +2299,7 @@ TEST_F(basic_stl, simple_prog4) {
/* stream1 */
TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
- stream2->set_pps(1.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
stream2->m_enabled = true;
stream2->m_self_start = false;
@@ -2351,7 +2351,7 @@ TEST_F(basic_stl, simple_prog3) {
/* stream1 */
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(5);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2368,7 +2368,7 @@ TEST_F(basic_stl, simple_prog3) {
/* stream1 */
TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
- stream2->set_pps(1.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
stream2->m_enabled = true;
stream2->m_self_start = false;
@@ -2418,7 +2418,7 @@ TEST_F(basic_stl, simple_prog2) {
/* stream1 */
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(5);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2435,7 +2435,7 @@ TEST_F(basic_stl, simple_prog2) {
/* stream1 */
TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
- stream2->set_pps(1.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream2->set_single_burst(5);
stream2->m_isg_usec = 2000000; /*time betwean stream 1 to stream 2 */
stream2->m_enabled = true;
@@ -2478,7 +2478,7 @@ TEST_F(basic_stl, simple_prog1) {
/* stream1 */
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(5);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2495,7 +2495,7 @@ TEST_F(basic_stl, simple_prog1) {
/* stream1 */
TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
- stream2->set_pps(1.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream2->set_single_burst(5);
stream2->m_enabled = true;
stream2->m_self_start = false;
@@ -2538,7 +2538,7 @@ TEST_F(basic_stl, single_pkt_burst1) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(5);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2583,7 +2583,7 @@ TEST_F(basic_stl, single_pkt) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2633,7 +2633,7 @@ void test_mac_replace(bool replace_src_by_pkt,
stream1->set_override_src_mac_by_pkt_data(replace_src_by_pkt);
stream1->set_override_dst_mac_mode((TrexStream::stream_dst_mac_t)replace_dst_mode);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2707,7 +2707,7 @@ TEST_F(basic_stl, multi_pkt1) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2721,7 +2721,7 @@ TEST_F(basic_stl, multi_pkt1) {
streams.push_back(stream1);
TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
- stream2->set_pps(2.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
stream2->m_enabled = true;
stream2->m_self_start = true;
@@ -2773,7 +2773,7 @@ void CEnableVm::run(bool full_packet,double duration=10.0){
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
stream1->m_self_start = true;
@@ -2862,7 +2862,7 @@ TEST_F(basic_stl, multi_pkt2) {
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->m_enabled = true;
@@ -2877,7 +2877,7 @@ TEST_F(basic_stl, multi_pkt2) {
TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
- stream2->set_pps(2.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
stream2->m_enabled = false;
stream2->m_self_start = false;
@@ -2919,7 +2919,7 @@ TEST_F(basic_stl, multi_burst1) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_multi_burst(5,
3,
2000000.0);
@@ -2962,7 +2962,7 @@ TEST_F(basic_stl, compile_bad_1) {
TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
stream1->m_enabled = true;
- stream1->set_pps(52.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
stream1->m_next_stream_id = 3;
streams.push_back(stream1);
@@ -2987,14 +2987,14 @@ TEST_F(basic_stl, compile_bad_2) {
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,1);
stream1->m_enabled = true;
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(200);
/* non existant next stream */
stream1->m_next_stream_id = 5;
TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
- stream1->set_pps(52.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
streams.push_back(stream1);
streams.push_back(stream2);
@@ -3026,7 +3026,7 @@ TEST_F(basic_stl, compile_bad_3) {
/* stream 1 */
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = 5481;
@@ -3039,7 +3039,7 @@ TEST_F(basic_stl, compile_bad_3) {
stream->m_enabled = true;
stream->m_next_stream_id = -1;
stream->m_self_start = false;
- stream->set_pps(52.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
streams.push_back(stream);
@@ -3047,7 +3047,7 @@ TEST_F(basic_stl, compile_bad_3) {
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = -1;
@@ -3059,7 +3059,7 @@ TEST_F(basic_stl, compile_bad_3) {
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 41231);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = 3928;
@@ -3071,7 +3071,7 @@ TEST_F(basic_stl, compile_bad_3) {
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 3928);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = 41231;
@@ -3100,7 +3100,7 @@ TEST_F(basic_stl, compile_with_warnings) {
/* stream 1 */
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = 1928;
@@ -3113,7 +3113,7 @@ TEST_F(basic_stl, compile_with_warnings) {
stream->m_enabled = true;
stream->m_next_stream_id = 1928;
stream->m_self_start = true;
- stream->set_pps(52.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
streams.push_back(stream);
@@ -3121,7 +3121,7 @@ TEST_F(basic_stl, compile_with_warnings) {
stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
stream->m_enabled = true;
- stream->set_pps(1.0);
+ stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream->set_single_burst(200);
stream->m_next_stream_id = -1;
@@ -3154,7 +3154,7 @@ TEST_F(basic_stl, compile_good_stream_id_compres) {
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,700);
stream1->m_self_start = true;
stream1->m_enabled = true;
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(200);
/* non existant next stream */
@@ -3162,7 +3162,7 @@ TEST_F(basic_stl, compile_good_stream_id_compres) {
TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST,0,800);
- stream2->set_pps(52.0);
+ stream2->set_rate(TrexStreamRate::RATE_PPS,52.0);
stream2->m_enabled = true;
stream2->m_next_stream_id = 700;
stream2->set_single_burst(300);
@@ -3231,7 +3231,7 @@ TEST_F(basic_stl, dp_stop_event) {
std::vector<TrexStream *> streams;
TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0);
- stream1->set_pps(1.0);
+ stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
stream1->set_single_burst(100);
stream1->m_enabled = true;
@@ -3277,7 +3277,7 @@ TEST_F(basic_stl, graph_generator1) {
stream->m_self_start = true;
stream->m_isg_usec = 42;
- stream->set_pps(10);
+ stream->set_rate(TrexStreamRate::RATE_PPS,10);
stream->set_single_burst(43281);
stream->m_pkt.len = 512;
@@ -3291,7 +3291,7 @@ TEST_F(basic_stl, graph_generator1) {
stream->m_enabled = true;
stream->m_self_start = false;
- stream->set_pps(20);
+ stream->set_rate(TrexStreamRate::RATE_PPS,20);
stream->set_multi_burst(4918, 13, 7);
stream->m_next_stream_id = -1;
stream->m_pkt.len = 64;
@@ -3304,7 +3304,7 @@ TEST_F(basic_stl, graph_generator1) {
stream->m_self_start = true;
stream->m_isg_usec = 50;
- stream->set_pps(30);
+ stream->set_rate(TrexStreamRate::RATE_PPS,30);
stream->m_next_stream_id = -1;
stream->m_pkt.len = 1512;
@@ -3334,7 +3334,7 @@ TEST_F(basic_stl, graph_generator2) {
stream->m_self_start = true;
- stream->set_pps(1000);
+ stream->set_rate(TrexStreamRate::RATE_PPS,1000);
/* a burst of 2000 packets with a delay of 1 second */
stream->m_isg_usec = 0;
@@ -3352,7 +3352,7 @@ TEST_F(basic_stl, graph_generator2) {
stream->m_enabled = true;
stream->m_self_start = true;
- stream->set_pps(1000);
+ stream->set_rate(TrexStreamRate::RATE_PPS,1000);
stream->m_isg_usec = 1000 * 1000 + 1000;
stream->set_multi_burst(1000 - 2, 1000, 1000 * 1000 + 2000);
stream->m_pkt.len = 128;
@@ -3517,7 +3517,7 @@ TEST_F(basic_stl, vm_split_flow_var_inc) {
TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
stream.set_single_burst(1000);
- stream.set_pps(100000);
+ stream.set_rate(TrexStreamRate::RATE_PPS,100000);
split.set_stream(&stream);
split.run(8, 4);
@@ -3530,7 +3530,7 @@ TEST_F(basic_stl, vm_split_flow_var_small_range) {
TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
stream.set_single_burst(1000);
- stream.set_pps(100000);
+ stream.set_rate(TrexStreamRate::RATE_PPS,100000);
split.set_stream(&stream);
split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0);
@@ -3544,7 +3544,7 @@ TEST_F(basic_stl, vm_split_flow_var_big_range) {
TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
stream.set_single_burst(1000);
- stream.set_pps(100000);
+ stream.set_rate(TrexStreamRate::RATE_PPS,100000);
split.set_stream(&stream);
split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC, 1, 1000, 1000);
@@ -3559,7 +3559,7 @@ TEST_F(basic_stl, vm_split_client_var) {
TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
stream.set_single_burst(1000);
- stream.set_pps(100000);
+ stream.set_rate(TrexStreamRate::RATE_PPS,100000);
split.set_stream(&stream);
split.set_client_var_as_split(0x10000001, 0x100000fe, 5000, 5050);
diff --git a/src/main.cpp b/src/main.cpp
index 6ee3a03d..6a6b5721 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -82,6 +82,8 @@ static CSimpleOpt::SOption parser_options[] =
SO_END_OF_OPTIONS
};
+static TrexStateless *m_sim_statelss_obj;
+
static int usage(){
printf(" Usage: bp_sim [OPTION] -f cfg.yaml -o outfile.erf \n");
@@ -247,6 +249,13 @@ void set_default_mac_addr(){
}
}
+TrexStateless * get_stateless_obj() {
+ return m_sim_statelss_obj;
+}
+
+void set_stateless_obj(TrexStateless *obj) {
+ m_sim_statelss_obj = obj;
+}
int main(int argc , char * argv[]){
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index d40c4c8b..701ae13e 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -125,7 +125,7 @@ struct port_cfg_t;
class CTRexExtendedDriverBase {
public:
- virtual TrexPlatformApi::driver_speed_e get_driver_speed() = 0;
+ virtual TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) = 0;
virtual int get_min_sample_rate(void)=0;
virtual void update_configuration(port_cfg_t * cfg)=0;
@@ -155,7 +155,7 @@ public:
CTRexExtendedDriverBase1G(){
}
- TrexPlatformApi::driver_speed_e get_driver_speed() {
+ TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) {
return TrexPlatformApi::SPEED_1G;
}
@@ -197,7 +197,7 @@ public:
CGlobalInfo::m_options.preview.set_vm_one_queue_enable(true);
}
- TrexPlatformApi::driver_speed_e get_driver_speed() {
+ TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) {
return TrexPlatformApi::SPEED_1G;
}
@@ -240,7 +240,7 @@ public:
CTRexExtendedDriverBase10G(){
}
- TrexPlatformApi::driver_speed_e get_driver_speed() {
+ TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) {
return TrexPlatformApi::SPEED_10G;
}
@@ -274,8 +274,15 @@ public:
CTRexExtendedDriverBase40G(){
}
- TrexPlatformApi::driver_speed_e get_driver_speed() {
- return TrexPlatformApi::SPEED_40G;
+ TrexPlatformApi::driver_speed_e get_driver_speed(uint8_t port_id) {
+ int speed;
+
+ rte_eth_get_speed(port_id, &speed);
+ if (speed == 10) {
+ return TrexPlatformApi::SPEED_10G;
+ } else {
+ return TrexPlatformApi::SPEED_40G;
+ }
}
static CTRexExtendedDriverBase * create(){
@@ -4277,8 +4284,8 @@ int main_test(int argc , char * argv[]){
if (CGlobalInfo::m_options.m_debug_pkt_proto != 0) {
CTrexDebug debug = CTrexDebug(g_trex.m_ports, g_trex.m_max_ports);
- debug.test_send(CGlobalInfo::m_options.m_debug_pkt_proto);
- exit(1);
+ debug.test_send(CGlobalInfo::m_options.m_debug_pkt_proto);
+ exit(1);
}
if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){
@@ -4918,12 +4925,12 @@ TrexDpdkPlatformApi::port_id_to_cores(uint8_t port_id, std::vector<std::pair<uin
}
void
-TrexDpdkPlatformApi::get_interface_info(uint8_t interface_id,
+TrexDpdkPlatformApi::get_interface_info(uint8_t port_id,
std::string &driver_name,
driver_speed_e &speed) const {
driver_name = CTRexExtendedDriverDb::Ins()->get_driver_name();
- speed = CTRexExtendedDriverDb::Ins()->get_drv()->get_driver_speed();
+ speed = CTRexExtendedDriverDb::Ins()->get_drv()->get_driver_speed(port_id);
}
void
diff --git a/src/msg_manager.cpp b/src/msg_manager.cpp
index 5fe44771..9ade1bfc 100755
--- a/src/msg_manager.cpp
+++ b/src/msg_manager.cpp
@@ -52,8 +52,6 @@ bool CMessagingManager::Create(uint8_t num_dp_threads,std::string a_name){
}
void CMessagingManager::Delete(){
- assert(m_cp_to_dp);
- assert(m_dp_to_cp);
int i;
for (i=0; i<m_num_dp_threads; i++) {
CNodeRing * lp;
@@ -63,8 +61,16 @@ void CMessagingManager::Delete(){
lp->Delete();
}
- delete []m_dp_to_cp;
- delete []m_cp_to_dp;
+ if (m_dp_to_cp) {
+ delete [] m_dp_to_cp;
+ m_dp_to_cp = NULL;
+ }
+
+ if (m_cp_to_dp) {
+ delete [] m_cp_to_dp;
+ m_cp_to_dp = NULL;
+ }
+
}
CNodeRing * CMessagingManager::getRingCpToDp(uint8_t thread_id){
@@ -83,6 +89,7 @@ void CMsgIns::Free(){
if (m_ins) {
m_ins->Delete();
delete m_ins;
+ m_ins = NULL;
}
}
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 920991e2..50295c7c 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -49,7 +49,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
string type = parse_string(mode, "type", result);
/* allocate a new stream based on the type */
- std::unique_ptr<TrexStream> stream( allocate_new_stream(section, port_id, stream_id, result) );
+ std::unique_ptr<TrexStream> stream = allocate_new_stream(section, port_id, stream_id, result);
/* save this for future queries */
stream->store_stream_json(section);
@@ -59,6 +59,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
stream->m_self_start = parse_bool(section, "self_start", result);
stream->m_flags = parse_int(section, "flags", result);
stream->m_action_count = parse_uint16(section, "action_count", result);
+
/* inter stream gap */
stream->m_isg_usec = parse_double(section, "isg", result);
@@ -97,7 +98,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
/* parse VM */
const Json::Value &vm = parse_object(section ,"vm", result);
- parse_vm(vm, stream.get(), result);
+ parse_vm(vm, stream, result);
/* parse RX info */
const Json::Value &rx = parse_object(section, "rx_stats", result);
@@ -112,7 +113,7 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
}
/* make sure this is a valid stream to add */
- validate_stream(stream.get(), result);
+ validate_stream(stream, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
@@ -130,43 +131,34 @@ TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
-TrexStream *
+std::unique_ptr<TrexStream>
TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result) {
- TrexStream *stream = NULL;
+ std::unique_ptr<TrexStream> stream;
const Json::Value &mode = parse_object(section, "mode", result);
std::string type = parse_string(mode, "type", result);
- if (type == "continuous") {
- double pps = parse_double(mode, "pps", result);
- stream = new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id);
- stream->set_pps(pps);
+ if (type == "continuous") {
- if (stream->m_next_stream_id != -1) {
- generate_parse_err(result, "continious stream cannot provide next stream id - only -1 is valid");
- }
+ stream.reset(new TrexStream( TrexStream::stCONTINUOUS, port_id, stream_id));
} else if (type == "single_burst") {
uint32_t total_pkts = parse_int(mode, "total_pkts", result);
- double pps = parse_double(mode, "pps", result);
- stream = new TrexStream(TrexStream::stSINGLE_BURST,port_id, stream_id);
- stream->set_pps(pps);
+ stream.reset(new TrexStream(TrexStream::stSINGLE_BURST, port_id, stream_id));
stream->set_single_burst(total_pkts);
} else if (type == "multi_burst") {
- double pps = parse_double(mode, "pps", result);
double ibg_usec = parse_double(mode, "ibg", result);
uint32_t num_bursts = parse_int(mode, "count", result);
uint32_t pkts_per_burst = parse_int(mode, "pkts_per_burst", result);
- stream = new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id );
- stream->set_pps(pps);
+ stream.reset(new TrexStream(TrexStream::stMULTI_BURST,port_id, stream_id ));
stream->set_multi_burst(pkts_per_burst,num_bursts,ibg_usec);
@@ -174,17 +166,44 @@ TrexRpcCmdAddStream::allocate_new_stream(const Json::Value &section, uint8_t por
generate_parse_err(result, "bad stream type provided: '" + type + "'");
}
- /* make sure we were able to allocate the memory */
- if (!stream) {
- generate_internal_err(result, "unable to allocate memory");
- }
+ /* parse the rate of the stream */
+ const Json::Value &rate = parse_object(mode ,"rate", result);
+ parse_rate(rate, stream, result);
return (stream);
}
void
-TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_rate(const Json::Value &rate, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
+
+ double value = parse_double(rate, "value", result);
+ if (value <= 0) {
+ std::stringstream ss;
+ ss << "rate value must be a positive number - got: '" << value << "'";
+ generate_parse_err(result, ss.str());
+ }
+
+ auto rate_types = {"pps", "bps_L1", "bps_L2", "percentage"};
+ std::string rate_type = parse_choice(rate, "type", rate_types, result);
+
+ if (rate_type == "pps") {
+ stream->set_rate(TrexStreamRate::RATE_PPS, value);
+ } else if (rate_type == "bps_L1") {
+ stream->set_rate(TrexStreamRate::RATE_BPS_L1, value);
+ } else if (rate_type == "bps_L2") {
+ stream->set_rate(TrexStreamRate::RATE_BPS_L2, value);
+ } else if (rate_type == "percentage") {
+ stream->set_rate(TrexStreamRate::RATE_PERCENTAGE, value);
+ } else {
+ /* impossible */
+ assert(0);
+ }
+
+}
+
+void
+TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result);
stream->m_vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(pkt_offset));
@@ -192,7 +211,7 @@ TrexRpcCmdAddStream::parse_vm_instr_checksum(const Json::Value &inst, TrexStream
void
-TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
std::string flow_var_name = parse_string(inst, "name", result);
@@ -201,7 +220,7 @@ TrexRpcCmdAddStream::parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexS
void
-TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result){
+TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result){
std::string flow_var_name = parse_string(inst, "name", result);
@@ -225,7 +244,7 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, Trex
void
-TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
auto sizes = {1, 2, 4, 8};
@@ -294,7 +313,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream
void
-TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result);
uint16_t pkt_cast_size = parse_uint16(inst, "pkt_cast_size", result);
@@ -312,7 +331,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_mask_flow_var(const Json::Value &inst,
void
-TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
uint16_t pkt_offset = parse_uint16(inst, "pkt_offset", result);
int add_value = parse_int(inst, "add_value", result);
@@ -325,7 +344,7 @@ TrexRpcCmdAddStream::parse_vm_instr_write_flow_var(const Json::Value &inst, Trex
}
void
-TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
const Json::Value &instructions = parse_array(vm ,"instructions", result);
@@ -372,7 +391,7 @@ TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::V
}
void
-TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &result) {
+TrexRpcCmdAddStream::validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result) {
/* add the stream to the port's stream table */
TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
@@ -381,7 +400,6 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
if (port->get_stream_by_id(stream->m_stream_id)) {
std::stringstream ss;
ss << "stream " << stream->m_stream_id << " already exists";
- delete stream;
generate_execute_err(result, ss.str());
}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index 3dc2ce0a..d90d880e 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -24,6 +24,7 @@ limitations under the License.
#include <trex_rpc_cmd_api.h>
#include <json/json.h>
+#include <memory>
class TrexStream;
@@ -91,16 +92,16 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdRemoveStream, "remove_stream", 2, tru
TREX_RPC_CMD_DEFINE_EXTENDED(TrexRpcCmdAddStream, "add_stream", 3, true,
/* extended part */
-TrexStream * allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
-void validate_stream(const TrexStream *stream, Json::Value &result);
-void parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_checksum(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_tuple_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_trim_pkt_size(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-
-void parse_vm_instr_write_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
-void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, TrexStream *stream, Json::Value &result);
+std::unique_ptr<TrexStream> allocate_new_stream(const Json::Value &section, uint8_t port_id, uint32_t stream_id, Json::Value &result);
+void validate_stream(const std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm(const Json::Value &vm, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_rate(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
);
diff --git a/src/sim/trex_sim.h b/src/sim/trex_sim.h
index 8feb7bc0..21498978 100644
--- a/src/sim/trex_sim.h
+++ b/src/sim/trex_sim.h
@@ -25,6 +25,7 @@ limitations under the License.
#include <os_time.h>
#include <bp_sim.h>
#include <json/json.h>
+#include <trex_stateless.h>
int gtest_main(int argc, char **argv);
@@ -32,12 +33,49 @@ class TrexStateless;
class TrexPublisher;
class DpToCpHandler;
+void set_stateless_obj(TrexStateless *obj);
static inline bool
in_range(int x, int low, int high) {
return ( (x >= low) && (x <= high) );
}
+/*************** hook for platform API **************/
+class SimPlatformApi : public TrexPlatformApi {
+public:
+ SimPlatformApi(int dp_core_count) {
+ m_dp_core_count = dp_core_count;
+ }
+
+ virtual uint8_t get_dp_core_count() const {
+ return m_dp_core_count;
+ }
+
+ virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
+ }
+
+ virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
+ driver_name = "TEST";
+ speed = TrexPlatformApi::SPEED_10G;
+ }
+
+ virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
+ }
+
+ virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
+ for (int i = 0; i < m_dp_core_count; i++) {
+ cores_id_list.push_back(std::make_pair(i, 0));
+ }
+ }
+
+ virtual void publish_async_data_now(uint32_t key) const {
+
+ }
+
+private:
+ int m_dp_core_count;
+};
+
/**
* interface for a sim target
*
@@ -67,12 +105,28 @@ public:
*
* @author imarom (28-Dec-15)
*/
-class SimGtest : public SimInterface {
+class SimGtest : SimInterface {
public:
int run(int argc, char **argv) {
+ TrexStatelessCfg cfg;
+
+ cfg.m_port_count = 2;
+ cfg.m_rpc_req_resp_cfg = NULL;
+ cfg.m_rpc_async_cfg = NULL;
+ cfg.m_rpc_server_verbose = false;
+ cfg.m_platform_api = new SimPlatformApi(1);
+ cfg.m_publisher = NULL;
+
+ set_stateless_obj(new TrexStateless(cfg));
+
assert( CMsgIns::Ins()->Create(4) );
- return gtest_main(argc, argv);
+ int rc = gtest_main(argc, argv);
+
+ delete get_stateless_obj();
+ set_stateless_obj(NULL);
+
+ return rc;
}
};
@@ -112,9 +166,6 @@ public:
int limit,
bool is_dry_run);
- TrexStateless * get_stateless_obj() {
- return m_trex_stateless;
- }
void set_verbose(bool enable) {
m_verbose = enable;
@@ -149,7 +200,6 @@ private:
return m_verbose;
}
- TrexStateless *m_trex_stateless;
DpToCpHandler *m_dp_to_cp_handler;
TrexPublisher *m_publisher;
CFlowGenList m_fl;
diff --git a/src/sim/trex_sim_stateless.cpp b/src/sim/trex_sim_stateless.cpp
index 897d1fec..a8316034 100644
--- a/src/sim/trex_sim_stateless.cpp
+++ b/src/sim/trex_sim_stateless.cpp
@@ -54,10 +54,6 @@ static string format_num(double num, const string &suffix = "") {
return "NaN";
}
-TrexStateless * get_stateless_obj() {
- return SimStateless::get_instance().get_stateless_obj();
-}
-
class SimRunException : public std::runtime_error
{
@@ -69,41 +65,6 @@ public:
}
};
-/*************** hook for platform API **************/
-class SimPlatformApi : public TrexPlatformApi {
-public:
- SimPlatformApi(int dp_core_count) {
- m_dp_core_count = dp_core_count;
- }
-
- virtual uint8_t get_dp_core_count() const {
- return m_dp_core_count;
- }
-
- virtual void get_global_stats(TrexPlatformGlobalStats &stats) const {
- }
-
- virtual void get_interface_info(uint8_t interface_id, std::string &driver_name, driver_speed_e &speed) const {
- driver_name = "TEST";
- speed = TrexPlatformApi::SPEED_10G;
- }
-
- virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const {
- }
-
- virtual void port_id_to_cores(uint8_t port_id, std::vector<std::pair<uint8_t, uint8_t>> &cores_id_list) const {
- for (int i = 0; i < m_dp_core_count; i++) {
- cores_id_list.push_back(std::make_pair(i, 0));
- }
- }
-
- virtual void publish_async_data_now(uint32_t key) const {
-
- }
-
-private:
- int m_dp_core_count;
-};
/**
* handler for DP to CP messages
@@ -146,7 +107,6 @@ public:
************************/
SimStateless::SimStateless() {
- m_trex_stateless = NULL;
m_publisher = NULL;
m_dp_to_cp_handler = NULL;
m_verbose = false;
@@ -198,9 +158,10 @@ SimStateless::run(const string &json_filename,
SimStateless::~SimStateless() {
- if (m_trex_stateless) {
- delete m_trex_stateless;
- m_trex_stateless = NULL;
+
+ if (get_stateless_obj()) {
+ delete get_stateless_obj();
+ set_stateless_obj(NULL);
}
if (m_publisher) {
@@ -231,11 +192,11 @@ SimStateless::prepare_control_plane() {
cfg.m_platform_api = new SimPlatformApi(m_dp_core_count);
cfg.m_publisher = m_publisher;
- m_trex_stateless = new TrexStateless(cfg);
+ set_stateless_obj(new TrexStateless(cfg));
- m_trex_stateless->launch_control_plane();
+ get_stateless_obj()->launch_control_plane();
- for (auto &port : m_trex_stateless->get_port_list()) {
+ for (auto &port : get_stateless_obj()->get_port_list()) {
port->acquire("test", 0, true);
}
@@ -274,7 +235,7 @@ SimStateless::execute_json(const std::string &json_filename) {
buffer << test.rdbuf();
try {
- rep = m_trex_stateless->get_rpc_server()->test_inject_request(buffer.str());
+ rep = get_stateless_obj()->get_rpc_server()->test_inject_request(buffer.str());
} catch (TrexRpcException &e) {
throw SimRunException(e.what());
}
@@ -321,8 +282,10 @@ static inline bool is_debug() {
void
SimStateless::show_intro(const std::string &out_filename) {
- uint64_t bps = 0;
- uint64_t pps = 0;
+ double pps;
+ double bps_L1;
+ double bps_L2;
+ double percentage;
std::cout << "\nGeneral info:\n";
std::cout << "------------\n\n";
@@ -356,10 +319,12 @@ SimStateless::show_intro(const std::string &out_filename) {
std::cout << "stream count: " << port->get_stream_count() << "\n";
- port->get_port_effective_rate(bps, pps);
+ port->get_port_effective_rate(pps, bps_L1, bps_L2, percentage);
- std::cout << "max BPS: " << format_num(bps, "bps") << "\n";
- std::cout << "max PPS: " << format_num(pps, "pps") << "\n";
+ std::cout << "max PPS : " << format_num(pps, "pps") << "\n";
+ std::cout << "max BPS L1 : " << format_num(bps_L1, "bps") << "\n";
+ std::cout << "max BPS L2 : " << format_num(bps_L2, "bps") << "\n";
+ std::cout << "line util. : " << format_num(percentage, "%") << "\n";
std::cout << "\n\nStarting simulation...\n";
}
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 8ee46d29..99b6565c 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -631,7 +631,10 @@ TrexStatelessPort::validate(void) {
void
-TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
+TrexStatelessPort::get_port_effective_rate(double &pps,
+ double &bps_L1,
+ double &bps_L2,
+ double &percentage) {
if (get_stream_count() == 0) {
return;
@@ -641,8 +644,11 @@ TrexStatelessPort::get_port_effective_rate(uint64_t &bps, uint64_t &pps) {
generate_streams_graph();
}
- bps = m_graph_obj->get_max_bps_l2() * m_factor;
- pps = m_graph_obj->get_max_pps() * m_factor;
+ pps = m_graph_obj->get_max_pps() * m_factor;
+ bps_L1 = m_graph_obj->get_max_bps_l1() * m_factor;
+ bps_L2 = m_graph_obj->get_max_bps_l2() * m_factor;
+ percentage = (bps_L1 / get_port_speed_bps()) * 100.0;
+
}
/************* Trex Port Owner **************/
@@ -651,7 +657,7 @@ TrexPortOwner::TrexPortOwner() {
m_is_free = true;
/* for handlers random generation */
- srand(time(NULL));
+ m_seed = time(NULL);
}
/**
@@ -669,7 +675,7 @@ TrexPortOwner::generate_handler() {
/* generate 8 bytes of random handler */
for (int i = 0; i < 8; ++i) {
- ss << alphanum[rand() % (sizeof(alphanum) - 1)];
+ ss << alphanum[rand_r(&m_seed) % (sizeof(alphanum) - 1)];
}
return (ss.str());
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index b0b0ddf3..49e69757 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -93,6 +93,8 @@ private:
/* handler genereated internally */
std::string m_handler;
+ /* seed for generating random values */
+ unsigned int m_seed;
/* just references defaults... */
static const std::string g_unowned_name;
@@ -316,10 +318,11 @@ public:
*
* @author imarom (07-Jan-16)
*
- * @param bps
- * @param pps
*/
- void get_port_effective_rate(uint64_t &bps, uint64_t &pps);
+ void get_port_effective_rate(double &pps,
+ double &bps_L1,
+ double &bps_L2,
+ double &percentage);
private:
@@ -441,9 +444,9 @@ public:
static const std::initializer_list<std::string> g_types;
static const std::initializer_list<std::string> g_ops;
- mul_type_e m_type;
- mul_op_e m_op;
- double m_value;
+ mul_type_e m_type;
+ mul_op_e m_op;
+ double m_value;
};
#endif /* __TREX_STATELESS_PORT_H__ */
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index 05c14cba..f1c93a11 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -22,6 +22,7 @@ limitations under the License.
#include <cstddef>
#include <string.h>
#include <assert.h>
+#include <trex_stateless.h>
/**************************************
* stream
@@ -93,25 +94,30 @@ void TrexStream::Dump(FILE *fd){
fprintf(fd," type : %s \n",get_stream_type_str(m_type).c_str());
if ( m_type == TrexStream::stCONTINUOUS ) {
- fprintf(fd," pps : %f \n",m_pps);
}
if (m_type == TrexStream::stSINGLE_BURST) {
- fprintf(fd," pps : %f \n",m_pps);
fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts);
}
if (m_type == TrexStream::stMULTI_BURST) {
- fprintf(fd," pps : %f \n",m_pps);
fprintf(fd," burst : %lu \n",(ulong)m_burst_total_pkts);
fprintf(fd," mburst : %lu \n",(ulong)m_num_bursts);
if (m_ibg_usec>0.0) {
fprintf(fd," m_ibg_usec : %f \n",m_ibg_usec);
}
}
+
+ fprintf(fd," rate :\n\n");
+
+ fprintf(fd," pps : %f\n", m_rate.get_pps());
+ fprintf(fd," bps L1 : %f\n", m_rate.get_bps_L1());
+ fprintf(fd," bps L2 : %f\n", m_rate.get_bps_L2());
+ fprintf(fd," percentage : %f\n", m_rate.get_percentage());
+
}
TrexStream::TrexStream(uint8_t type,
- uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) {
+ uint8_t port_id, uint32_t stream_id) : m_port_id(port_id), m_stream_id(stream_id) , m_rate(*this) {
/* default values */
m_type = type;
@@ -127,7 +133,6 @@ TrexStream::TrexStream(uint8_t type,
m_rx_check.m_enable = false;
- m_pps=-1.0;
m_burst_total_pkts=0;
m_num_bursts=1;
m_ibg_usec=0.0;
@@ -238,3 +243,16 @@ int TrexStreamTable::size() {
}
+/**************************************
+ * TrexStreamRate
+ *************************************/
+uint64_t
+TrexStreamRate::get_line_speed_bps() {
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(m_stream.m_port_id);
+ return port->get_port_speed_bps();
+}
+
+double
+TrexStreamRate::get_pkt_size() {
+ return m_stream.get_pkt_size();
+}
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index 5240e96d..cc05c198 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -107,12 +107,184 @@ public:
}
};
+class TrexStream;
+
+/**
+ * describes a stream rate
+ *
+ * @author imarom (18-Feb-16)
+ */
+class TrexStreamRate {
+
+
+public:
+
+ enum rate_type_e {
+ RATE_INVALID,
+ RATE_PPS,
+ RATE_BPS_L1,
+ RATE_BPS_L2,
+ RATE_PERCENTAGE
+ };
+
+ TrexStreamRate(TrexStream &stream) : m_stream(stream) {
+ m_pps = 0;
+ m_bps_L1 = 0;
+ m_bps_L2 = 0;
+ m_percentage = 0;
+ }
+
+
+ TrexStreamRate& operator=(const TrexStreamRate& other) {
+ m_pps = other.m_pps;
+ m_bps_L1 = other.m_bps_L1;
+ m_bps_L2 = other.m_bps_L2;
+ m_percentage = other.m_percentage;
+
+ return (*this);
+ }
+
+ /**
+ * set the base rate
+ * other values will be dervied from this value
+ *
+ */
+ void set_base_rate(rate_type_e type, double value) {
+ m_pps = 0;
+ m_bps_L1 = 0;
+ m_bps_L2 = 0;
+ m_percentage = 0;
+
+ assert(value > 0);
+
+ switch (type) {
+ case RATE_PPS:
+ m_pps = value;
+ break;
+ case RATE_BPS_L1:
+ m_bps_L1 = value;
+ break;
+ case RATE_BPS_L2:
+ m_bps_L2 = value;
+ break;
+ case RATE_PERCENTAGE:
+ m_percentage = value;
+ break;
+
+ default:
+ assert(0);
+
+ }
+ }
+
+ double get_pps() {
+ if (m_pps == 0) {
+ calculate();
+ }
+ return (m_pps);
+ }
+
+ double get_bps_L1() {
+ if (m_bps_L1 == 0) {
+ calculate();
+ }
+ return (m_bps_L1);
+ }
+
+ double get_bps_L2() {
+ if (m_bps_L2 == 0) {
+ calculate();
+ }
+ return m_bps_L2;
+ }
+
+ double get_percentage() {
+ if (m_percentage == 0) {
+ calculate();
+ }
+ return m_percentage;
+ }
+
+
+
+ /* update the rate by a factor */
+ void update_factor(double factor) {
+ /* if all are non zero - it works, if only one (base) is also works */
+ m_pps *= factor;
+ m_bps_L1 *= factor;
+ m_bps_L2 *= factor;
+ m_percentage *= factor;
+ }
+
+
+
+private:
+
+ /**
+ * calculates all the rates from the base rate
+ *
+ */
+ void calculate() {
+
+ if (m_pps != 0) {
+ calculate_from_pps();
+ } else if (m_bps_L1 != 0) {
+ calculate_from_bps_L1();
+ } else if (m_bps_L2 != 0) {
+ calculate_from_bps_L2();
+ } else if (m_percentage != 0) {
+ calculate_from_percentage();
+ } else {
+ assert(0);
+ }
+ }
+
+
+ uint64_t get_line_speed_bps();
+ double get_pkt_size();
+
+ void calculate_from_pps() {
+ m_bps_L1 = m_pps * (get_pkt_size() + 24) * 8;
+ m_bps_L2 = m_pps * (get_pkt_size() + 4) * 8;
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
+ }
+
+
+ void calculate_from_bps_L1() {
+ m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
+ }
+
+
+ void calculate_from_bps_L2() {
+ m_bps_L1 = m_bps_L2 * ( (get_pkt_size() + 24.0) / (get_pkt_size() + 4.0));
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+ m_percentage = (m_bps_L1 / get_line_speed_bps()) * 100.0;
+ }
+
+ void calculate_from_percentage() {
+ m_bps_L1 = (m_percentage / 100.0) * get_line_speed_bps();
+ m_bps_L2 = m_bps_L1 * ( (get_pkt_size() + 4.0) / (get_pkt_size() + 24.0) );
+ m_pps = m_bps_L2 / (8 * (get_pkt_size() + 4));
+
+ }
+
+ double m_pps;
+ double m_bps_L1;
+ double m_bps_L2;
+ double m_percentage;
+
+ /* reference to the owner class */
+ TrexStream &m_stream;
+};
/**
* Stateless Stream
*
*/
class TrexStream {
+friend class TrexStreamRate;
public:
enum STREAM_TYPE {
@@ -155,12 +327,29 @@ public:
m_next_stream_id = next_stream_id;
}
- double get_pps() const {
- return m_pps;
+
+ double get_pps() {
+ return m_rate.get_pps();
+ }
+
+ double get_bps_L1() {
+ return m_rate.get_bps_L1();
}
- void set_pps(double pps){
- m_pps = pps;
+ double get_bps_L2() {
+ return m_rate.get_bps_L2();
+ }
+
+ double get_bw_percentage() {
+ return m_rate.get_percentage();
+ }
+
+ void set_rate(TrexStreamRate::rate_type_e type, double value) {
+ m_rate.set_base_rate(type, value);
+ }
+
+ void update_rate_factor(double factor) {
+ m_rate.update_factor(factor);
}
void set_type(uint8_t type){
@@ -227,13 +416,14 @@ public:
dp->m_expected_pkt_len = m_expected_pkt_len;
dp->m_rx_check = m_rx_check;
- dp->m_pps = m_pps;
dp->m_burst_total_pkts = m_burst_total_pkts;
dp->m_num_bursts = m_num_bursts;
dp->m_ibg_usec = m_ibg_usec;
dp->m_flags = m_flags;
dp->m_action_count = m_action_count;
+ dp->m_rate = m_rate;
+
return(dp);
}
@@ -245,19 +435,11 @@ public:
}
}
- double get_burst_length_usec() const {
- return ( (m_burst_total_pkts / m_pps) * 1000 * 1000);
+ double get_burst_length_usec() {
+ return ( (m_burst_total_pkts / get_pps()) * 1000 * 1000);
}
- double get_bps_l2() {
- return get_bps(false);
- }
-
- double get_bps_l1() {
- return get_bps(true);
- }
-
-
+
void Dump(FILE *fd);
StreamVmDp * getDpVm(){
@@ -325,8 +507,6 @@ public:
} m_rx_check;
- double m_pps;
-
uint32_t m_burst_total_pkts; /* valid in case of burst stSINGLE_BURST,stMULTI_BURST*/
uint32_t m_num_bursts; /* valid in case of stMULTI_BURST */
@@ -338,8 +518,7 @@ public:
private:
- double get_bps(bool layer1) {
-
+ double get_pkt_size() {
/* lazy calculate the expected packet length */
if (m_expected_pkt_len == 0) {
/* if we have a VM - it might have changed the packet (even random) */
@@ -349,17 +528,13 @@ private:
m_expected_pkt_len = m_vm.calc_expected_pkt_size(m_pkt.len);
}
}
-
-
- /* packet length + 4 CRC bytes to bits and multiplied by PPS */
- if (layer1) {
- /* layer one includes preamble, frame delimiter and interpacket gap */
- return (m_pps * (m_expected_pkt_len + 4 + 8 + 12) * 8);
- } else {
- return (m_pps * (m_expected_pkt_len + 4) * 8);
- }
+ return m_expected_pkt_len;
}
+
+
+ /* no access to this without a lazy build method */
+ TrexStreamRate m_rate;
};
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index c16545d9..0bd00711 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -227,7 +227,7 @@ public:
inline void run_inc(uint8_t * flow_var) {
uint8_t *p = (flow_var + m_flow_offset);
- if (*p >= (m_max_val-m_step)) {
+ if (*p > (m_max_val-m_step)) {
*p = m_min_val;
} else {
*p = *p + m_step;
@@ -236,7 +236,7 @@ public:
inline void run_dec(uint8_t * flow_var) {
uint8_t *p = (flow_var + m_flow_offset);
- if (*p <= (m_min_val+m_step)) {
+ if (*p < (m_min_val+m_step)) {
*p = m_max_val;
} else {
*p = *p - m_step;
@@ -257,7 +257,7 @@ public:
inline void run_inc(uint8_t * flow_var) {
uint16_t *p = (uint16_t *)(flow_var + m_flow_offset);
- if (*p >= (m_max_val-m_step)) {
+ if (*p > (m_max_val-m_step)) {
*p = m_min_val;
} else {
*p = *p + m_step;
@@ -266,7 +266,7 @@ public:
inline void run_dec(uint8_t * flow_var) {
uint16_t *p = (uint16_t *)(flow_var + m_flow_offset);
- if (*p <= (m_min_val+m_step)) {
+ if (*p < (m_min_val+m_step)) {
*p = m_max_val;
} else {
*p = *p - m_step;
@@ -286,7 +286,7 @@ public:
inline void run_inc(uint8_t * flow_var) {
uint32_t *p = (uint32_t *)(flow_var + m_flow_offset);
- if (*p >= (m_max_val-m_step)) {
+ if (*p > (m_max_val-m_step)) {
*p = m_min_val;
} else {
*p = *p + m_step;
@@ -295,7 +295,7 @@ public:
inline void run_dec(uint8_t * flow_var) {
uint32_t *p = (uint32_t *)(flow_var + m_flow_offset);
- if (*p <= (m_min_val+m_step)) {
+ if (*p < (m_min_val+m_step)) {
*p = m_max_val;
} else {
*p = *p - m_step;
@@ -315,7 +315,7 @@ public:
inline void run_inc(uint8_t * flow_var) {
uint64_t *p = (uint64_t *)(flow_var + m_flow_offset);
- if (*p >= (m_max_val-m_step) ) {
+ if (*p > (m_max_val-m_step) ) {
*p = m_min_val;
} else {
*p = *p + m_step;
@@ -324,7 +324,7 @@ public:
inline void run_dec(uint8_t * flow_var) {
uint64_t *p = (uint64_t *)(flow_var + m_flow_offset);
- if (*p <= m_min_val+m_step) {
+ if (*p < m_min_val+m_step) {
*p = m_max_val;
} else {
*p = *p - m_step;
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index 9d048dbd..aca74498 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -459,7 +459,7 @@ TrexStreamsCompiler::compile_internal(uint8_t por
*
*/
void
-TrexStreamsCompiler::compile_stream(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -500,7 +500,7 @@ TrexStreamsCompiler::compile_stream(const TrexStream *stream,
*
*/
void
-TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream_on_all_cores(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -509,7 +509,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
std::vector<TrexStream *> core_streams(dp_core_count);
- double per_core_rate = (stream->m_pps * (factor / dp_core_count));
+ double per_core_factor = (factor / dp_core_count);
int per_core_burst_total_pkts = (stream->m_burst_total_pkts / dp_core_count);
/* for each core - creates its own version of the stream */
@@ -521,7 +521,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
/* adjust rate and packets count */
- dp_stream->m_pps = per_core_rate;
+ dp_stream->update_rate_factor(per_core_factor);
dp_stream->m_burst_total_pkts = per_core_burst_total_pkts;
core_streams[i] = dp_stream;
@@ -547,7 +547,7 @@ TrexStreamsCompiler::compile_stream_on_all_cores(const TrexStream *stream,
*
*/
void
-TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
+TrexStreamsCompiler::compile_stream_on_single_core(TrexStream *stream,
double factor,
TrexStreamsCompiledObj *obj,
int new_id,
@@ -560,7 +560,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
/* compile the VM if exists */
if (!stream->m_vm.is_vm_empty()) {
- ((TrexStream *)stream)->vm_compile();
+ stream->vm_compile();
dp_stream->m_vm_dp = stream->m_vm_dp->clone();
}
@@ -581,7 +581,7 @@ TrexStreamsCompiler::compile_stream_on_single_core(const TrexStream *stream,
* @param stream
*/
void
-TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, TrexStream *stream) {
switch (stream->get_type()) {
@@ -604,7 +604,7 @@ TrexStreamsGraph::add_rate_events_for_stream(double &offset_usec, const TrexStre
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
@@ -613,8 +613,8 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre
start_event.time = offset_usec + stream->m_isg_usec;
start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
m_graph_obj->add_rate_event(start_event);
/* no more events after this stream */
@@ -629,7 +629,7 @@ TrexStreamsGraph::add_rate_events_for_stream_cont(double &offset_usec, const Tre
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
TrexStreamsGraphObj::rate_event_st stop_event;
@@ -640,9 +640,9 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c
/* start event */
start_event.time = offset_usec + stream->m_isg_usec;
- start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_pps = stream->get_pps();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
m_graph_obj->add_rate_event(start_event);
/* stop event */
@@ -662,7 +662,7 @@ TrexStreamsGraph::add_rate_events_for_stream_single_burst(double &offset_usec, c
*
*/
void
-TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream) {
+TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream) {
TrexStreamsGraphObj::rate_event_st start_event;
TrexStreamsGraphObj::rate_event_st stop_event;
@@ -672,8 +672,8 @@ TrexStreamsGraph::add_rate_events_for_stream_multi_burst(double &offset_usec, co
/* for debug purposes */
start_event.diff_pps = stream->get_pps();
- start_event.diff_bps_l2 = ((TrexStream *)stream)->get_bps_l2();
- start_event.diff_bps_l1 = ((TrexStream *)stream)->get_bps_l1();
+ start_event.diff_bps_l2 = stream->get_bps_L2();
+ start_event.diff_bps_l1 = stream->get_bps_L1();
start_event.stream_id = stream->m_stream_id;
stop_event.diff_pps = -(start_event.diff_pps);
@@ -714,7 +714,7 @@ TrexStreamsGraph::generate_graph_for_one_root(uint32_t root_stream_id) {
double offset = 0;
while (true) {
- const TrexStream *stream;
+ TrexStream *stream;
/* fetch the stream from the hash - if it is not present, report an error */
try {
diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h
index a3a1f8f7..b8b0be37 100644
--- a/src/stateless/cp/trex_streams_compiler.h
+++ b/src/stateless/cp/trex_streams_compiler.h
@@ -123,19 +123,19 @@ private:
void add_warning(const std::string &warning);
void err(const std::string &err);
- void compile_stream(const TrexStream *stream,
+ void compile_stream(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
GraphNodeMap &nodes);
- void compile_stream_on_single_core(const TrexStream *stream,
+ void compile_stream_on_single_core(TrexStream *stream,
double factor,
TrexStreamsCompiledObj *obj,
int new_id,
int new_next_id);
- void compile_stream_on_all_cores(const TrexStream *stream,
+ void compile_stream_on_all_cores(TrexStream *stream,
double factor,
uint8_t dp_core_count,
std::vector<TrexStreamsCompiledObj *> &objs,
@@ -245,13 +245,13 @@ private:
void generate_graph_for_one_root(uint32_t root_stream_id);
- void add_rate_events_for_stream(double &offset, const TrexStream *stream);
- void add_rate_events_for_stream_cont(double &offset_usec, const TrexStream *stream);
- void add_rate_events_for_stream_single_burst(double &offset_usec, const TrexStream *stream);
- void add_rate_events_for_stream_multi_burst(double &offset_usec, const TrexStream *stream);
+ void add_rate_events_for_stream(double &offset, TrexStream *stream);
+ void add_rate_events_for_stream_cont(double &offset_usec, TrexStream *stream);
+ void add_rate_events_for_stream_single_burst(double &offset_usec, TrexStream *stream);
+ void add_rate_events_for_stream_multi_burst(double &offset_usec, TrexStream *stream);
/* for fast processing of streams */
- std::unordered_map<uint32_t, const TrexStream *> m_streams_hash;
+ std::unordered_map<uint32_t, TrexStream *> m_streams_hash;
/* main object to hold the graph - returned to the user */
TrexStreamsGraphObj *m_graph_obj;