diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/bp_sim.cpp | 5 | ||||
-rw-r--r-- | src/dpdk22/drivers/net/i40e/i40e_ethdev.c | 13 | ||||
-rw-r--r-- | src/dpdk22/lib/librte_ether/rte_ethdev.c | 15 | ||||
-rw-r--r-- | src/dpdk22/lib/librte_ether/rte_ethdev.h | 2 | ||||
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 96 | ||||
-rwxr-xr-x | src/main.cpp | 9 | ||||
-rwxr-xr-x | src/main_dpdk.cpp | 27 | ||||
-rwxr-xr-x | src/msg_manager.cpp | 15 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 80 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmds.h | 21 | ||||
-rw-r--r-- | src/sim/trex_sim.h | 62 | ||||
-rw-r--r-- | src/sim/trex_sim_stateless.cpp | 69 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 16 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 15 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.cpp | 28 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream.h | 233 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 16 | ||||
-rw-r--r-- | src/stateless/cp/trex_streams_compiler.cpp | 36 | ||||
-rw-r--r-- | src/stateless/cp/trex_streams_compiler.h | 16 |
19 files changed, 533 insertions, 241 deletions
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 ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms, 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 ¶ms, Json::Value &result) { -TrexStream * +std::unique_ptr<TrexStream> TrexRpcCmdAddStream::allocate_new_stream(const Json::Value §ion, 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 §ion, 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 §ion, 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 §ion, 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; |