diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 208 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 10 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 25 | ||||
-rw-r--r-- | src/stateless/cp/trex_vm_splitter.cpp | 7 |
4 files changed, 172 insertions, 78 deletions
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index e7564350..cb02a80a 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -161,7 +161,7 @@ TEST_F(basic_vm, vm0) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(20) ); - vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1, + vm.add_instruction( new StreamVmInstructionFlowMan( "var1",8, StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",14, 0,true) @@ -198,7 +198,7 @@ TEST_F(basic_vm, vm2) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) ); @@ -274,7 +274,7 @@ TEST_F(basic_vm, vm3) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) ); @@ -356,8 +356,8 @@ TEST_F(basic_vm, vm4) { StreamVm vm; - vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 ) + vm.add_instruction( new StreamVmInstructionFlowMan( "var1", 8 /* size */, + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,false) ); @@ -425,8 +425,12 @@ TEST_F(basic_vm, vm4) { test_udp_pkt); fprintf(stdout," %d \n",i); - //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0); + utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0); /* not big */ + EXPECT_EQ(test_udp_pkt[33],0); + EXPECT_EQ(test_udp_pkt[32],0); + EXPECT_EQ(test_udp_pkt[31],0); + EXPECT_EQ(test_udp_pkt[30],0); EXPECT_EQ(test_udp_pkt[29],0); EXPECT_EQ(test_udp_pkt[28],0); EXPECT_EQ(test_udp_pkt[27],0); @@ -442,11 +446,11 @@ TEST_F(basic_vm, vm5) { StreamVm vm; vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 ) + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 ) ); vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,25,23,27 ) ); + StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) ); /* src ip */ vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) @@ -586,7 +590,7 @@ TEST_F(basic_vm, vm6) { ); vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */, - StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,25,23,27 ) ); + StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) ); /* src ip */ vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true) @@ -2618,86 +2622,154 @@ TEST_F(basic_stl, graph_generator2) { delete obj; } -static -void vm_split_test(const char *erf_filename, - TrexStream::STREAM_TYPE stream_type, - double pps, - StreamVmInstructionFlowMan::flow_var_op_e op, - uint8_t dp_core_count, - uint8_t dp_core_to_check) { +class VmSplitTest { - TrexStreamsCompiler compile; - std::vector<TrexStreamsCompiledObj *> objs; - std::vector<TrexStream *> streams; +public: - TrexStream *stream = new TrexStream(stream_type, 0, 1); + VmSplitTest(const char *erf_filename) { + m_erf_filename = erf_filename; + m_stream = NULL; - stream->set_single_burst(pps); - stream->set_pps(pps); + pcap.load_pcap_file("cap2/udp_64B.pcap",0); + pcap.update_ip_src(0x10000001); - stream->m_enabled = true; - stream->m_self_start = true; + m_split_instr = new StreamVmInstructionFlowMan("var1", + 8, + StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, + 0, + 0, + 1000 + ); + } - CPcapLoader pcap; - pcap.load_pcap_file("cap2/udp_64B.pcap",0); - pcap.update_ip_src(0x10000001); - pcap.clone_packet_into_stream(stream); - + ~VmSplitTest() { + if (m_split_instr) { + delete m_split_instr; + } + } - StreamVm &vm = stream->m_vm; + void set_stream(TrexStream *stream) { - StreamVmInstruction *flow_var = new StreamVmInstructionFlowMan("var1", - 1, - op, - 0, - 0, - 255); + if (m_stream) { + delete m_stream; + m_stream = NULL; + } - vm.add_instruction(flow_var); - vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1", 59, 0,true)); - vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14)); + m_stream = stream; + m_stream->m_enabled = true; + m_stream->m_self_start = true; + + pcap.clone_packet_into_stream(stream); + } - vm.set_split_instruction(flow_var); - streams.push_back(stream); + void set_flow_var_as_split(StreamVmInstructionFlowMan::flow_var_op_e op, + uint64_t start, + uint64_t end, + uint64_t init) { - /* compiling for 8 cores */ - assert(compile.compile(0, streams, objs, dp_core_count)); - for (auto stream : streams) { - delete stream; + if (m_split_instr) { + delete m_split_instr; + m_split_instr = NULL; + } + + m_split_instr = new StreamVmInstructionFlowMan("var1", + 8, + op, + init, + start, + end); } - /* choose one DP object */ - TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(0, 0, objs[dp_core_to_check], 1 /*sec */ ); - objs[dp_core_to_check] = NULL; - /* free all the non used DP objects */ - for (auto obj : objs) { - if (obj) { - delete obj; + void run(uint8_t dp_core_count, uint8_t dp_core_to_check) { + TrexStreamsCompiler compile; + std::vector<TrexStreamsCompiledObj *> objs; + std::vector<TrexStream *> streams; + + StreamVm &vm = m_stream->m_vm; + + vm.add_instruction(m_split_instr); + + vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1", 60 - 8 - 4, 0,true)); + + vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14)); + + vm.set_split_instruction(m_split_instr); + + streams.push_back(m_stream); + + /* compiling for 8 cores */ + assert(compile.compile(0, streams, objs, dp_core_count)); + + m_split_instr = NULL; + + /* choose one DP object */ + TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(0, 0, objs[dp_core_to_check], 1 /*sec */ ); + objs[dp_core_to_check] = NULL; + /* free all the non used DP objects */ + for (auto obj : objs) { + if (obj) { + delete obj; + } } + + + CParserOption * po =&CGlobalInfo::m_options; + po->preview.setVMode(7); + po->preview.setFileWrite(true); + po->out_file = m_erf_filename; + + CBasicStl t1; + t1.m_msg = lpStartCmd; + bool res=t1.init(); + EXPECT_EQ_UINT32(1, res?1:0); + } +private: + const char *m_erf_filename; + TrexStream *m_stream; + StreamVmInstruction *m_split_instr; + CPcapLoader pcap; +}; - CParserOption * po =&CGlobalInfo::m_options; - po->preview.setVMode(7); - po->preview.setFileWrite(true); - po->out_file = erf_filename; - CBasicStl t1; - t1.m_msg = lpStartCmd; - bool res=t1.init(); - EXPECT_EQ_UINT32(1, res?1:0); + +TEST_F(basic_stl, vm_split_flow_var_inc) { + + VmSplitTest split("exp/stl_vm_split_flow_var_inc.erf"); + + TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); + stream.set_pps(1000); + + split.set_stream(&stream); + split.run(8, 4); + } -TEST_F(basic_stl, vm_split_flow_var_1) { +TEST_F(basic_stl, vm_split_flow_var_small_range) { + /* small range */ + VmSplitTest split("exp/stl_vm_split_flow_var_small_range.erf"); + + TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); + stream.set_pps(1000); + + split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0); + split.set_stream(&stream); + split.run(8, 4); - vm_split_test("exp/stl_vm_split_flow_var_1.erf", - TrexStream::stSINGLE_BURST, - 1000, - StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, - 8, - 4); - } +TEST_F(basic_stl, vm_split_flow_var_big_range) { + VmSplitTest split("exp/stl_vm_split_flow_var_big_range.erf"); + + TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0); + stream.set_pps(1000); + + split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC, 1, 1000, 1000); + split.set_stream(&stream); + split.run(8, 7); + + +} /********************************************* Itay Tests End *************************************/ diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index b086e21b..cbd2ce7c 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -426,7 +426,7 @@ void StreamVm::build_program(){ op = StreamDPVmInstructions::ditRANDOM64 ; } - StreamDPOpFlowVar32 fv64; + StreamDPOpFlowVar64 fv64; fv64.m_op = op; fv64.m_flow_offset = get_var_offset(lpMan->m_var_name); fv64.m_min_val = (uint64_t)lpMan->m_min_value; @@ -549,19 +549,19 @@ void StreamVm::build_bss() { switch (ins_man->m_size_bytes) { case 1: - *p=(uint8_t)ins_man->m_init_value; + *p=(uint8_t)ins_man->get_bss_init_value(); p+=1; break; case 2: - *((uint16_t*)p)=(uint16_t)ins_man->m_init_value; + *((uint16_t*)p)=(uint16_t)ins_man->get_bss_init_value(); p+=2; break; case 4: - *((uint32_t*)p)=(uint32_t)ins_man->m_init_value; + *((uint32_t*)p)=(uint32_t)ins_man->get_bss_init_value(); p+=4; break; case 8: - *((uint64_t*)p)=(uint64_t)ins_man->m_init_value; + *((uint64_t*)p)=(uint64_t)ins_man->get_bss_init_value(); p+=8; break; default: diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index cd78dbd1..a0e8b6b5 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -352,7 +352,7 @@ public: class StreamDPVmInstructions { public: enum INS_TYPE { - ditINC8 , + ditINC8 =7 , ditINC16 , ditINC32 , ditINC64 , @@ -636,6 +636,29 @@ public: FLOW_VAR_OP_RANDOM }; + + /** + * for BSS we take one previous value + * because the VM will be executed before writing to pkt + * so the init value is one step's advanced + * + */ + uint64_t get_bss_init_value() const { + uint64_t init = m_init_value; + + switch (m_op) { + case FLOW_VAR_OP_INC: + return (init == m_min_value ? m_max_value : (init - 1)); + + case FLOW_VAR_OP_DEC: + return (init == m_max_value ? m_min_value : (init + 1)); + + default: + return init; + } + + } + StreamVmInstructionFlowMan(const std::string &var_name, uint8_t size, flow_var_op_e op, diff --git a/src/stateless/cp/trex_vm_splitter.cpp b/src/stateless/cp/trex_vm_splitter.cpp index 489e3b75..8aae8c76 100644 --- a/src/stateless/cp/trex_vm_splitter.cpp +++ b/src/stateless/cp/trex_vm_splitter.cpp @@ -89,9 +89,8 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { return false; } - /* if the range is too small - multiply */ + /* if the range is too small - it is unsplitable */ if (instr->get_range() < m_dp_core_count) { - // FIXME return false; } @@ -118,8 +117,8 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { per_core_instr->m_min_value = start; per_core_instr->m_max_value = end; - /* init value is the max value because the VM program's first iteration */ - per_core_instr->m_init_value = end; + /* after split this has no meaning - choose it as we see fit */ + per_core_instr->m_init_value = (per_core_instr->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ? end : start); core_stream->vm_compile(); |