diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gtest/trex_stateless_gtest.cpp | 150 | ||||
-rwxr-xr-x | src/main.cpp | 1 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 28 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 72 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 8 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 4 |
6 files changed, 237 insertions, 26 deletions
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp index 1626ac25..2718dead 100644 --- a/src/gtest/trex_stateless_gtest.cpp +++ b/src/gtest/trex_stateless_gtest.cpp @@ -261,9 +261,11 @@ TEST_F(basic_vm, vm2) { 2, 3}; + uint32_t random_per_thread=0; int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -340,9 +342,12 @@ TEST_F(basic_vm, vm3) { 2, 3}; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -425,9 +430,12 @@ TEST_F(basic_vm, vm4) { 2, 3}; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -564,9 +572,12 @@ TEST_F(basic_vm, vm5) { 0x17, }; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), test_udp_pkt); @@ -631,9 +642,12 @@ TEST_F(basic_vm, vm6) { StreamDPVmInstructionsRunner runner; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -699,9 +713,12 @@ TEST_F(basic_vm, vm7) { StreamDPVmInstructionsRunner runner; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -765,9 +782,12 @@ TEST_F(basic_vm, vm8) { StreamDPVmInstructionsRunner runner; + uint32_t random_per_thread=0; + int i; for (i=0; i<20; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -843,9 +863,12 @@ TEST_F(basic_vm, vm9) { StreamDPVmInstructionsRunner runner; + uint32_t random_per_thread=0; + int i; for (i=0; i<30; i++) { - runner.run(program_size, + runner.run(&random_per_thread, + program_size, vm.get_dp_instruction_buffer()->get_program(), vm.get_bss_ptr(), (uint8_t*)pcap.m_raw.raw); @@ -895,10 +918,13 @@ TEST_F(basic_vm, vm10) { StreamDPVmInstructionsRunner runner; + uint32_t random_per_thread=0; + int i; for (i=0; i<30; i++) { - runner.run(lpDpVm->get_program_size(), + runner.run(&random_per_thread, + lpDpVm->get_program_size(), lpDpVm->get_program(), lpDpVm->get_bss(), (uint8_t*)pcap.m_raw.raw); @@ -916,6 +942,112 @@ TEST_F(basic_vm, vm10) { } +/* test vmDP object */ +TEST_F(basic_vm, vm_syn_attack) { + + StreamVm vm; + srand(0x1234); + + vm.add_instruction( new StreamVmInstructionFlowMan( "ip_src", + 4, + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 0, + 1000000)); + + vm.add_instruction( new StreamVmInstructionFlowMan( "ip_dst", + 4, + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 0, + 1000000)); + + vm.add_instruction( new StreamVmInstructionFlowMan( "src_port", + 2, + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 1025, + 65000)); + + vm.add_instruction( new StreamVmInstructionFlowMan( "dst_port", + 2, + StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM, + 0, + 1025, + 65000)); + + /* src ip */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_src",26, 0x10000000,true) + ); + + vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_dst",26+4, 0x40000000,true) + ); + + vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) ); + + /* src port */ + vm.add_instruction( new StreamVmInstructionWriteToPkt( "src_port",34, 0,true) + ); + vm.add_instruction( new StreamVmInstructionWriteToPkt( "dst_port",34+2, 0,true) + ); + + + vm.set_packet_size(128); + + vm.compile(); + + printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset()); + + EXPECT_EQ(38,vm.get_max_packet_update_offset()); + + StreamVmDp * lpDpVm =vm.cloneAsVmDp(); + + EXPECT_EQ(lpDpVm->get_bss_size(),vm.get_bss_size()); + + uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size(); + + printf (" program size : %lu \n",(ulong)program_size); + + + vm.Dump(stdout); + + CPcapLoader pcap; + pcap.load_pcap_file("stl/syn_packet.pcap",0); + + + + CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/stl_syn_attack.pcap"); + assert(lpWriter); + + + StreamDPVmInstructionsRunner runner; + + uint32_t random_per_thread=0; + + int i; + for (i=0; i<30; i++) { + + runner.run(&random_per_thread, + lpDpVm->get_program_size(), + lpDpVm->get_program(), + lpDpVm->get_bss(), + (uint8_t*)pcap.m_raw.raw); + + assert(lpWriter->write_packet(&pcap.m_raw)); + } + + delete lpWriter; + + CErfCmp cmp; + delete lpDpVm; + + bool res1=cmp.compare("exp/stl_syn_attack.pcap","exp/stl_syn_attack-ex.pcap"); + EXPECT_EQ(1, res1?1:0); +} + + + + ////////////////////////////////////////////////////// diff --git a/src/main.cpp b/src/main.cpp index b633fce6..1b219a8c 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -769,6 +769,7 @@ extern "C" const char * get_build_time(void){ int main(int argc , char * argv[]){ + int res=0; time_init(); CGlobalInfo::m_socket.Create(0); diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index e10e1a81..2984b896 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -191,7 +191,29 @@ void StreamVm::build_flow_var_table() { var_clear_table(); m_cur_var_offset=0; uint32_t ins_id=0; + m_is_random_var=false; /* scan all flow var instruction and build */ + + for (auto inst : m_inst_list) { + if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){ + StreamVmInstructionFlowMan * ins_man=(StreamVmInstructionFlowMan *)inst; + if (ins_man->m_op ==StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM){ + m_is_random_var =true; + } + } + } + + /* if we found allocate BSS +4 bytes */ + if ( m_is_random_var ){ + VmFlowVarRec var; + + var.m_offset = m_cur_var_offset; + var.m_ins.m_ins_flowv = NULL; + var.m_size_bytes = sizeof(uint32_t); + var_add("___random___",var); + m_cur_var_offset += sizeof(uint32_t); + } + for (auto inst : m_inst_list) { if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){ @@ -207,6 +229,7 @@ void StreamVm::build_flow_var_table() { ss << "instruction id '" << ins_id << "' flow variable name " << ins_man->m_var_name << " already exists"; err(ss.str()); }else{ + var.m_offset=m_cur_var_offset; var.m_ins.m_ins_flowv = ins_man; var.m_size_bytes = ins_man->m_size_bytes; @@ -541,6 +564,11 @@ void StreamVm::build_bss() { alloc_bss(); uint8_t * p=(uint8_t *)m_bss; + if ( m_is_random_var ){ + *((uint32_t*)p)=rand(); + p+=sizeof(uint32_t); + } + for (auto inst : m_inst_list) { if ( inst->get_instruction_type() == StreamVmInstruction::itFLOW_MAN ){ diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index e65a87e3..9023c6b7 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -32,6 +32,46 @@ limitations under the License. +//https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/ + +//Used to seed the generator. +inline void fast_srand(uint32_t &g_seed, int seed ){ + g_seed = seed; +} + + +//fastrand routine returns one integer, similar output value range as C lib. + +inline int fastrand(uint32_t &g_seed) +{ + g_seed = (214013*g_seed+2531011); + return (g_seed>>16)&0x7FFF; +} + +static inline void vm_srand(uint32_t * per_thread_seed,uint64_t seedval) +{ + fast_srand( *per_thread_seed,seedval ); +} + +static inline uint32_t vm_rand16(uint32_t * per_thread_seed) +{ + return ( fastrand(*per_thread_seed)); +} + +static inline uint32_t vm_rand32(uint32_t * per_thread_seed) +{ + return ( (vm_rand16(per_thread_seed)<<16)+vm_rand16(per_thread_seed)); +} + +static inline uint64_t vm_rand64(uint32_t * per_thread_seed) +{ + uint64_t res; + + res=((uint64_t)vm_rand32(per_thread_seed)<<32)+vm_rand32(per_thread_seed); + + return (res); +} + class StreamVm; @@ -62,9 +102,9 @@ public: } } - inline void run_rand(uint8_t * flow_var) { + inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) { uint8_t * p=(flow_var+m_flow_offset); - *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + *p= m_min_val + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1)); } @@ -94,9 +134,9 @@ public: } } - inline void run_rand(uint8_t * flow_var) { + inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) { uint16_t * p=(uint16_t *)(flow_var+m_flow_offset); - *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + *p= m_min_val + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1)); } @@ -127,9 +167,9 @@ public: } } - inline void run_rand(uint8_t * flow_var) { + inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) { uint32_t * p=(uint32_t *)(flow_var+m_flow_offset); - *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + *p= m_min_val + (vm_rand32(per_thread_random) % (int)(m_max_val - m_min_val + 1)); } } __attribute__((packed)) ; @@ -158,9 +198,9 @@ public: } } - inline void run_rand(uint8_t * flow_var) { + inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) { uint64_t * p=(uint64_t *)(flow_var+m_flow_offset); - *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + *p= m_min_val + ( vm_rand64(per_thread_random) % (int)(m_max_val - m_min_val + 1)); } @@ -395,7 +435,8 @@ private: class StreamDPVmInstructionsRunner { public: - inline void run(uint32_t program_size, + inline void run(uint32_t * per_thread_random, + uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ uint8_t * pkt); /* pkt */ @@ -403,7 +444,8 @@ public: }; -inline void StreamDPVmInstructionsRunner::run(uint32_t program_size, +inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, + uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ uint8_t * pkt){ @@ -488,22 +530,22 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t program_size, case StreamDPVmInstructions::ditRANDOM8 : ua.lpv8 =(StreamDPOpFlowVar8 *)p; - ua.lpv8->run_rand(flow_var); + ua.lpv8->run_rand(flow_var,per_thread_random); p+=sizeof(StreamDPOpFlowVar8); break; case StreamDPVmInstructions::ditRANDOM16 : ua.lpv16 =(StreamDPOpFlowVar16 *)p; - ua.lpv16->run_rand(flow_var); + ua.lpv16->run_rand(flow_var,per_thread_random); p+=sizeof(StreamDPOpFlowVar16); break; case StreamDPVmInstructions::ditRANDOM32 : ua.lpv32 =(StreamDPOpFlowVar32 *)p; - ua.lpv32->run_rand(flow_var); + ua.lpv32->run_rand(flow_var,per_thread_random); p+=sizeof(StreamDPOpFlowVar32); break; case StreamDPVmInstructions::ditRANDOM64 : ua.lpv64 =(StreamDPOpFlowVar64 *)p; - ua.lpv64->run_rand(flow_var); + ua.lpv64->run_rand(flow_var,per_thread_random); p+=sizeof(StreamDPOpFlowVar64); break; @@ -901,6 +943,7 @@ public: m_bss=0; m_pkt_size=0; m_cur_var_offset=0; + m_is_random_var=false; } @@ -1002,6 +1045,7 @@ private: void add_field_cnt(uint16_t new_cnt); private: + bool m_is_random_var; uint16_t m_pkt_size; uint16_t m_cur_var_offset; uint16_t m_max_field_update; /* the location of the last byte that is going to be changed in the packet */ diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 585ff2c7..f43f0d3a 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -69,6 +69,9 @@ void CGenNodeStateless::Dump(FILE *fd){ } +/** + * this function called when stream restart after it was inactive + */ void CGenNodeStateless::refresh(){ /* refill the stream info */ @@ -124,7 +127,8 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ /* run the VM program */ StreamDPVmInstructionsRunner runner; - runner.run( m_vm_program_size, + runner.run( (uint32_t*)m_vm_flow_var, + m_vm_program_size, m_vm_program, m_vm_flow_var, (uint8_t*)p); @@ -302,7 +306,7 @@ bool TrexStatelessDpCore::set_stateless_next_node(CGenNodeStateless * cur_node, /* can't be FREE_RESUSE */ assert(state != CGenNodeStateless::ss_FREE_RESUSE); - if (next_node->get_state() == CGenNodeStateless::ss_INACTIVE ) { + if (state == CGenNodeStateless::ss_INACTIVE ) { /* refill start info and scedule, no update in active streams */ next_node->refresh(); diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index d33785fe..c9c0de43 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -102,11 +102,13 @@ private: uint8_t * m_vm_flow_var; /* pointer to the vm flow var */ uint8_t * m_vm_program; /* pointer to the program */ uint16_t m_vm_program_size; /* up to 64K op codes */ + uint16_t m_pad2; + uint32_t m_pad3; /* End Fast Field VM Section */ /* pad to match the size of CGenNode */ - uint8_t m_pad_end[30]; + uint8_t m_pad_end[20]; public: |