summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-12-22 08:12:16 -0500
committerimarom <imarom@cisco.com>2015-12-23 09:59:40 -0500
commit16130b77af4f966b1f794f27b75265d76ee96dea (patch)
tree15378997c61a480e94093f5af658404885763e74
parent0901331fc21088307fc4a264d5b38089a1ce7f1a (diff)
some fixes to the VM and the splitter
-rw-r--r--scripts/exp/stl_vm_split_flow_var_1.erf-0-ex.erfbin11000 -> 0 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_1.erf-0.erfbin11000 -> 0 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_big_range.erf-0-ex.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_big_range.erf-0.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_inc.erf-0-ex.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_inc.erf-0.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_small_range.erf-0-ex.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/stl_vm_split_flow_var_small_range.erf-0.erfbin0 -> 11000 bytes
-rw-r--r--scripts/exp/udp_64B_vm6-ex.pcapbin1544 -> 1544 bytes
-rw-r--r--src/gtest/trex_stateless_gtest.cpp208
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp10
-rw-r--r--src/stateless/cp/trex_stream_vm.h25
-rw-r--r--src/stateless/cp/trex_vm_splitter.cpp7
13 files changed, 172 insertions, 78 deletions
diff --git a/scripts/exp/stl_vm_split_flow_var_1.erf-0-ex.erf b/scripts/exp/stl_vm_split_flow_var_1.erf-0-ex.erf
deleted file mode 100644
index cc612d1d..00000000
--- a/scripts/exp/stl_vm_split_flow_var_1.erf-0-ex.erf
+++ /dev/null
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_1.erf-0.erf b/scripts/exp/stl_vm_split_flow_var_1.erf-0.erf
deleted file mode 100644
index cc612d1d..00000000
--- a/scripts/exp/stl_vm_split_flow_var_1.erf-0.erf
+++ /dev/null
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_big_range.erf-0-ex.erf b/scripts/exp/stl_vm_split_flow_var_big_range.erf-0-ex.erf
new file mode 100644
index 00000000..8f4fe297
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_big_range.erf-0-ex.erf
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_big_range.erf-0.erf b/scripts/exp/stl_vm_split_flow_var_big_range.erf-0.erf
new file mode 100644
index 00000000..8f4fe297
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_big_range.erf-0.erf
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_inc.erf-0-ex.erf b/scripts/exp/stl_vm_split_flow_var_inc.erf-0-ex.erf
new file mode 100644
index 00000000..82025972
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_inc.erf-0-ex.erf
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_inc.erf-0.erf b/scripts/exp/stl_vm_split_flow_var_inc.erf-0.erf
new file mode 100644
index 00000000..82025972
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_inc.erf-0.erf
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_small_range.erf-0-ex.erf b/scripts/exp/stl_vm_split_flow_var_small_range.erf-0-ex.erf
new file mode 100644
index 00000000..5dac9893
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_small_range.erf-0-ex.erf
Binary files differ
diff --git a/scripts/exp/stl_vm_split_flow_var_small_range.erf-0.erf b/scripts/exp/stl_vm_split_flow_var_small_range.erf-0.erf
new file mode 100644
index 00000000..5dac9893
--- /dev/null
+++ b/scripts/exp/stl_vm_split_flow_var_small_range.erf-0.erf
Binary files differ
diff --git a/scripts/exp/udp_64B_vm6-ex.pcap b/scripts/exp/udp_64B_vm6-ex.pcap
index 68588302..dd55c0e7 100644
--- a/scripts/exp/udp_64B_vm6-ex.pcap
+++ b/scripts/exp/udp_64B_vm6-ex.pcap
Binary files differ
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();