diff options
author | Hanoh Haim <hhaim@cisco.com> | 2016-02-16 16:08:23 +0200 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2016-02-16 16:08:23 +0200 |
commit | 47c865838678444c0075aab94267972a3a3cbfff (patch) | |
tree | 3551714c2b6e2f3c71374754732ab0e01c7d83f1 | |
parent | 75c84998813a359cb8619e80507e04f21d71de89 (diff) |
step instruction support
-rw-r--r-- | scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py | 4 | ||||
-rw-r--r-- | scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py | 9 | ||||
-rw-r--r-- | scripts/exp/udp_1pkt_mac_step.pcap | bin | 0 -> 1544 bytes | |||
-rw-r--r-- | scripts/stl/udp_1pkt_mac_step.py | 35 | ||||
-rw-r--r-- | scripts/stl/yaml/burst_1pkt_vm.yaml | 1 | ||||
-rw-r--r-- | scripts/stl/yaml/imix_1pkt_vm.yaml | 1 | ||||
-rw-r--r-- | scripts/stl/yaml/imix_3pkt_vm.yaml | 3 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 11 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 321 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 195 | ||||
-rw-r--r-- | src/stateless/cp/trex_vm_splitter.cpp | 5 |
11 files changed, 500 insertions, 85 deletions
diff --git a/scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py b/scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py index f4b67f05..1f07b6e4 100644 --- a/scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py +++ b/scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py @@ -139,7 +139,7 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test): def test_stl_profiles (self): - p = [ + p1 = [ ["udp_1pkt_1mac_override.py","-m 1 -l 50",True], ["syn_attack.py","-m 1 -l 50",False], # can't compare random now ["udp_1pkt_1mac.py","-m 1 -l 50",True], @@ -180,7 +180,7 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test): ]; - p1 = [ ["burst_3st_loop_x_times.py","-m 1 -l 20 ",True] ] + p = [ ["udp_1pkt_mac_step.py","-m 1 -l 20 ",True] ] for obj in p: diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py index 88efe265..c788e277 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py @@ -207,7 +207,7 @@ class CTRexVmInsFlowVar(CTRexVmInsBase): OPERATIONS =['inc', 'dec', 'random'] VALID_SIZES =[1, 2, 4, 8] - def __init__(self, fv_name, size, op, init_value, min_value, max_value): + def __init__(self, fv_name, size, op, init_value, min_value, max_value,step): super(CTRexVmInsFlowVar, self).__init__("flow_var") self.name = fv_name; assert type(fv_name)==str, 'type of fv_name is not str' @@ -219,6 +219,8 @@ class CTRexVmInsFlowVar(CTRexVmInsBase): assert type(min_value)==int, 'type of min_value is not int' self.max_value=max_value assert type(max_value)==int, 'type of min_value is not int' + self.step=step + assert type(step)==int, 'type of step should be int' class CTRexVmInsWrFlowVar(CTRexVmInsBase): def __init__(self, fv_name, pkt_offset, add_value=0, is_big_endian=True): @@ -496,7 +498,7 @@ def check_for_int (val): class CTRexVmDescFlowVar(CTRexVmDescBase): - def __init__(self, name, init_value=None, min_value=0, max_value=255, size=4, op="inc"): + def __init__(self, name, init_value=None, min_value=0, max_value=255, size=4, step=1,op="inc"): super(CTRexVmDescFlowVar, self).__init__() self.name = name; assert type(name)==str, 'type of name is not str' @@ -512,12 +514,13 @@ class CTRexVmDescFlowVar(CTRexVmDescBase): self.init_value = convert_val (init_value) self.min_value = convert_val (min_value); self.max_value = convert_val (max_value) + self.step = convert_val (step) if self.min_value > self.max_value : raise CTRexPacketBuildException(-11,("max %d is lower than min %d ") % (self.max_value,self.min_value) ); def get_obj (self): - return CTRexVmInsFlowVar(self.name,self.size,self.op,self.init_value,self.min_value,self.max_value); + return CTRexVmInsFlowVar(self.name,self.size,self.op,self.init_value,self.min_value,self.max_value,self.step); def get_var_name(self): return [self.name] diff --git a/scripts/exp/udp_1pkt_mac_step.pcap b/scripts/exp/udp_1pkt_mac_step.pcap Binary files differnew file mode 100644 index 00000000..0377567b --- /dev/null +++ b/scripts/exp/udp_1pkt_mac_step.pcap diff --git a/scripts/stl/udp_1pkt_mac_step.py b/scripts/stl/udp_1pkt_mac_step.py new file mode 100644 index 00000000..077a162b --- /dev/null +++ b/scripts/stl/udp_1pkt_mac_step.py @@ -0,0 +1,35 @@ +from trex_stl_lib.api import * + + +# step is not 1. +class STLS1(object): + + def __init__ (self): + self.fsize =64; # the size of the packet + + def create_stream (self): + + # create a base packet and pad it to size + size = self.fsize - 4; # no FCS + base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) + pad = max(0, size - len(base_pkt)) * 'x' + + vm = CTRexScRaw( [ STLVmFlowVar(name="mac_src", min_value=1, max_value=100, size=1,step=2, op="inc"), + STLVmWrFlowVar(fv_name="mac_src", pkt_offset= 11) # write it to LSB of SRC offset it 11 + ] + ) + + return STLStream(packet = STLPktBuilder(pkt = base_pkt/pad,vm = vm), + mode = STLTXCont( pps=10 )) + + def get_streams (self, direction = 0): + # create 1 stream + return [ self.create_stream() ] + + +# dynamic load - used for trex console or simulator +def register(): + return STLS1() + + + diff --git a/scripts/stl/yaml/burst_1pkt_vm.yaml b/scripts/stl/yaml/burst_1pkt_vm.yaml index 246b8813..fed39488 100644 --- a/scripts/stl/yaml/burst_1pkt_vm.yaml +++ b/scripts/stl/yaml/burst_1pkt_vm.yaml @@ -19,6 +19,7 @@ "name" : "l3_src", "op" : "inc", "size" : 2, + "step" : 1, "type" : "flow_var" }, { diff --git a/scripts/stl/yaml/imix_1pkt_vm.yaml b/scripts/stl/yaml/imix_1pkt_vm.yaml index 05443a6c..698d3e60 100644 --- a/scripts/stl/yaml/imix_1pkt_vm.yaml +++ b/scripts/stl/yaml/imix_1pkt_vm.yaml @@ -19,6 +19,7 @@ "name" : "l3_src", "op" : "inc", "size" : 4, + "step" : 1, "type" : "flow_var" }, { diff --git a/scripts/stl/yaml/imix_3pkt_vm.yaml b/scripts/stl/yaml/imix_3pkt_vm.yaml index 6ba2c40c..3e7cd0ed 100644 --- a/scripts/stl/yaml/imix_3pkt_vm.yaml +++ b/scripts/stl/yaml/imix_3pkt_vm.yaml @@ -19,6 +19,7 @@ "name" : "l3_src", "op" : "inc", "size" : 2, + "step" : 1, "type" : "flow_var" }, { @@ -49,6 +50,7 @@ "name" : "l3_src", "op" : "inc", "size" : 2, + "step" : 1, "type" : "flow_var" }, { @@ -80,6 +82,7 @@ "name" : "l3_src", "op" : "inc", "size" : 2, + "step" : 1, "type" : "flow_var" }, { diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 0262fd7c..508967b9 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -249,6 +249,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream uint64_t init_value = parse_uint64(inst, "init_value", result); uint64_t min_value = parse_uint64(inst, "min_value", result); uint64_t max_value = parse_uint64(inst, "max_value", result); + uint64_t step = parse_uint64(inst, "step", result); if (max_value < min_value ) { std::stringstream ss; @@ -257,7 +258,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 1 ) { - if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX)) { + if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX) || (step >UINT8_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT8_MAX; generate_parse_err(result, ss.str()); @@ -265,7 +266,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 2 ) { - if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX)) { + if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX) || (step > UINT16_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT16_MAX; generate_parse_err(result, ss.str()); @@ -273,7 +274,7 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream } if (flow_var_size == 4 ) { - if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX)) { + if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX) || (step > UINT32_MAX) ) { std::stringstream ss; ss << "VM: request val is bigger than " << UINT32_MAX; generate_parse_err(result, ss.str()); @@ -286,7 +287,9 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, TrexStream op_type, init_value, min_value, - max_value)); + max_value, + step) + ); } void diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index b91f0fb5..f99c3c9c 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -102,7 +102,7 @@ void StreamVmInstructionFlowMan::Dump(FILE *fd){ break; }; - fprintf(fd," (%lu:%lu:%lu) \n",m_init_value,m_min_value,m_max_value); + fprintf(fd," (%lu:%lu:%lu:%lu) \n",m_init_value,m_min_value,m_max_value,m_step); } @@ -412,31 +412,52 @@ void StreamVm::build_program(){ if (lpMan->m_size_bytes == 1 ){ - - uint8_t op=StreamDPVmInstructions::ditINC8; - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC8 ; - } - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC8 ; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + uint8_t op=StreamDPVmInstructions::ditINC8; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC8 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC8 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM8 ; + } + + StreamDPOpFlowVar8 fv8; + fv8.m_op = op; + fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv8.m_min_val = (uint8_t)lpMan->m_min_value; + fv8.m_max_val = (uint8_t)lpMan->m_max_value; + m_instructions.add_command(&fv8,sizeof(fv8)); + }else{ + uint8_t op=StreamDPVmInstructions::ditINC8_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC8_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC8_STEP ; + } + + StreamDPOpFlowVar8Step fv8; + fv8.m_op = op; + fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv8.m_min_val = (uint8_t)lpMan->m_min_value; + fv8.m_max_val = (uint8_t)lpMan->m_max_value; + fv8.m_step = (uint8_t)lpMan->m_step; + m_instructions.add_command(&fv8,sizeof(fv8)); } - - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM8 ; - } - - StreamDPOpFlowVar8 fv8; - fv8.m_op = op; - fv8.m_flow_offset = get_var_offset(lpMan->m_var_name); - fv8.m_min_val = (uint8_t)lpMan->m_min_value; - fv8.m_max_val = (uint8_t)lpMan->m_max_value; - m_instructions.add_command(&fv8,sizeof(fv8)); } if (lpMan->m_size_bytes == 2 ){ uint8_t op; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + op = StreamDPVmInstructions::ditINC16; @@ -458,56 +479,119 @@ void StreamVm::build_program(){ fv16.m_min_val = (uint16_t)lpMan->m_min_value; fv16.m_max_val = (uint16_t)lpMan->m_max_value; m_instructions.add_command(&fv16,sizeof(fv16)); - } + }else{ - if (lpMan->m_size_bytes == 4 ){ - uint8_t op; + op = StreamDPVmInstructions::ditINC16_STEP; - op = StreamDPVmInstructions::ditINC32; + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC16_STEP ; + } - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC32 ; - } + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC16_STEP ; + } - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC32 ; - } + StreamDPOpFlowVar16Step fv16; + fv16.m_op = op; + fv16.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv16.m_min_val = (uint16_t)lpMan->m_min_value; + fv16.m_max_val = (uint16_t)lpMan->m_max_value; + fv16.m_step = (uint16_t)lpMan->m_step; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM32 ; - } - - StreamDPOpFlowVar32 fv32; - fv32.m_op = op; - fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); - fv32.m_min_val = (uint32_t)lpMan->m_min_value; - fv32.m_max_val = (uint32_t)lpMan->m_max_value; - m_instructions.add_command(&fv32,sizeof(fv32)); + m_instructions.add_command(&fv16,sizeof(fv16)); + } } - if (lpMan->m_size_bytes == 8 ){ + if (lpMan->m_size_bytes == 4 ){ uint8_t op; + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ + op = StreamDPVmInstructions::ditINC32; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC32 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC32 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM32 ; + } + + StreamDPOpFlowVar32 fv32; + fv32.m_op = op; + fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv32.m_min_val = (uint32_t)lpMan->m_min_value; + fv32.m_max_val = (uint32_t)lpMan->m_max_value; + m_instructions.add_command(&fv32,sizeof(fv32)); + }else{ + op = StreamDPVmInstructions::ditINC32_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC32_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC32_STEP ; + } + + StreamDPOpFlowVar32Step fv32; + fv32.m_op = op; + fv32.m_flow_offset = get_var_offset(lpMan->m_var_name); + fv32.m_min_val = (uint32_t)lpMan->m_min_value; + fv32.m_max_val = (uint32_t)lpMan->m_max_value; + fv32.m_step = (uint32_t)lpMan->m_step; + m_instructions.add_command(&fv32,sizeof(fv32)); + } + } - op = StreamDPVmInstructions::ditINC64; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ - op = StreamDPVmInstructions::ditINC64 ; - } + if (lpMan->m_size_bytes == 8 ){ + uint8_t op; - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ - op = StreamDPVmInstructions::ditDEC64 ; - } + if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){ - if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ - op = StreamDPVmInstructions::ditRANDOM64 ; + op = StreamDPVmInstructions::ditINC64; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC64 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC64 ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){ + op = StreamDPVmInstructions::ditRANDOM64 ; + } + + 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; + fv64.m_max_val = (uint64_t)lpMan->m_max_value; + m_instructions.add_command(&fv64,sizeof(fv64)); + }else{ + + op = StreamDPVmInstructions::ditINC64_STEP; + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){ + op = StreamDPVmInstructions::ditINC64_STEP ; + } + + if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){ + op = StreamDPVmInstructions::ditDEC64_STEP ; + } + + StreamDPOpFlowVar64Step 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; + fv64.m_max_val = (uint64_t)lpMan->m_max_value; + fv64.m_step = (uint64_t)lpMan->m_step; + m_instructions.add_command(&fv64,sizeof(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; - fv64.m_max_val = (uint64_t)lpMan->m_max_value; - m_instructions.add_command(&fv64,sizeof(fv64)); } } @@ -890,6 +974,12 @@ void StreamDPVmInstructions::Dump(FILE *fd){ StreamDPOpFlowVar16 *lpv16; StreamDPOpFlowVar32 *lpv32; StreamDPOpFlowVar64 *lpv64; + + StreamDPOpFlowVar8Step *lpv8s; + StreamDPOpFlowVar16Step *lpv16s; + StreamDPOpFlowVar32Step *lpv32s; + StreamDPOpFlowVar64Step *lpv64s; + StreamDPOpIpv4Fix *lpIpv4Fix; StreamDPOpPktWr8 *lpw8; StreamDPOpPktWr16 *lpw16; @@ -1016,6 +1106,47 @@ void StreamDPVmInstructions::Dump(FILE *fd){ p+=sizeof(StreamDPOpPktSizeChange); break; + case ditINC8_STEP : + lpv8s =(StreamDPOpFlowVar8Step *)p; + lpv8s->dump(fd,"INC8_STEP"); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case ditINC16_STEP : + lpv16s =(StreamDPOpFlowVar16Step *)p; + lpv16s->dump(fd,"INC16_STEP"); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case ditINC32_STEP : + lpv32s =(StreamDPOpFlowVar32Step *)p; + lpv32s->dump(fd,"INC32_STEP"); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case ditINC64_STEP : + lpv64s =(StreamDPOpFlowVar64Step *)p; + lpv64s->dump(fd,"INC64_STEP"); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + + case ditDEC8_STEP : + lpv8s =(StreamDPOpFlowVar8Step *)p; + lpv8s->dump(fd,"DEC8_DEC"); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case ditDEC16_STEP : + lpv16s =(StreamDPOpFlowVar16Step *)p; + lpv16s->dump(fd,"DEC16_STEP"); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case ditDEC32_STEP : + lpv32s =(StreamDPOpFlowVar32Step *)p; + lpv32s->dump(fd,"DEC32_STEP"); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case ditDEC64_STEP : + lpv64s =(StreamDPOpFlowVar64Step *)p; + lpv64s->dump(fd,"DEC64_STEP"); + p+=sizeof(StreamDPOpFlowVar64Step); + break; default: assert(0); @@ -1024,6 +1155,23 @@ void StreamDPVmInstructions::Dump(FILE *fd){ } +void StreamDPOpFlowVar8Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar16Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar32Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + +void StreamDPOpFlowVar64Step::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, of:%lu, (%lu-%lu-%lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val,(ulong)m_step); +} + + void StreamDPOpFlowVar8::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, of:%lu, (%lu- %lu) \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val); } @@ -1074,3 +1222,60 @@ void StreamDPOpPktSizeChange::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, flow_offset: %lu \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset); } + + +void StreamDPVmInstructionsRunner::slow_commands(uint8_t op_code, + uint8_t * flow_var, /* flow var */ + uint8_t * pkt, + uint8_t * & p){ + ua_t ua; + + switch (op_code) { + + case StreamDPVmInstructions::ditINC8_STEP : + ua.lpv8s =(StreamDPOpFlowVar8Step *)p; + ua.lpv8s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + + case StreamDPVmInstructions::ditINC16_STEP : + ua.lpv16s =(StreamDPOpFlowVar16Step *)p; + ua.lpv16s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case StreamDPVmInstructions::ditINC32_STEP : + ua.lpv32s =(StreamDPOpFlowVar32Step *)p; + ua.lpv32s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case StreamDPVmInstructions::ditINC64_STEP : + ua.lpv64s =(StreamDPOpFlowVar64Step *)p; + ua.lpv64s->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + + case StreamDPVmInstructions::ditDEC8_STEP : + ua.lpv8s =(StreamDPOpFlowVar8Step *)p; + ua.lpv8s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar8Step); + break; + case StreamDPVmInstructions::ditDEC16_STEP : + ua.lpv16s =(StreamDPOpFlowVar16Step *)p; + ua.lpv16s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar16Step); + break; + case StreamDPVmInstructions::ditDEC32_STEP : + ua.lpv32s =(StreamDPOpFlowVar32Step *)p; + ua.lpv32s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar32Step); + break; + case StreamDPVmInstructions::ditDEC64_STEP : + ua.lpv64s =(StreamDPOpFlowVar64Step *)p; + ua.lpv64s->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar64Step); + break; + default: + assert(0); + } +} + diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index dabc502c..fd685b24 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -215,6 +215,128 @@ public: } __attribute__((packed)) ; + +struct StreamDPOpFlowVar8Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint8_t m_min_val; + uint8_t m_max_val; + uint8_t m_step; +public: + void dump(FILE *fd,std::string opt); + + inline void run_inc(uint8_t * flow_var) { + uint8_t *p = (flow_var + m_flow_offset); + if (*p >= (m_max_val-m_step)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint8_t *p = (flow_var + m_flow_offset); + if (*p <= (m_min_val+m_step)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar16Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint16_t m_min_val; + uint16_t m_max_val; + uint16_t m_step; + +public: + void dump(FILE *fd,std::string opt); + + 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)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + 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)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar32Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint32_t m_min_val; + uint32_t m_max_val; + uint32_t m_step; +public: + void dump(FILE *fd,std::string opt); + + 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)) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + 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)) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar64Step { + uint8_t m_op; + uint8_t m_flow_offset; + uint64_t m_min_val; + uint64_t m_max_val; + uint64_t m_step; +public: + void dump(FILE *fd,std::string opt); + + 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) ) { + *p = m_min_val; + } else { + *p = *p + m_step; + } + } + + 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) { + *p = m_max_val; + } else { + *p = *p - m_step; + } + } + + +} __attribute__((packed)) ; + +/////////////////////////////////////////////////////////////////////// + + struct StreamDPOpPktWrBase { enum { PKT_WR_IS_BIG = 1 @@ -440,6 +562,18 @@ public: itCLIENT_VAR_UNLIMIT , itPKT_SIZE_CHANGE , + /* inc/dec with step*/ + ditINC8_STEP , + ditINC16_STEP , + ditINC32_STEP , + ditINC64_STEP , + + ditDEC8_STEP , + ditDEC16_STEP , + ditDEC32_STEP , + ditDEC64_STEP , + + }; @@ -462,7 +596,14 @@ class StreamDPVmInstructionsRunner { public: StreamDPVmInstructionsRunner(){ m_new_pkt_size=0;; + } + + void slow_commands(uint8_t op_code, + uint8_t * flow_var, /* flow var */ + uint8_t * pkt, + uint8_t * & p); + inline void run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ @@ -477,19 +618,7 @@ private: }; -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 - ){ - - - uint8_t * p=program; - uint8_t * p_end=p+program_size; - - - union ua_ { +typedef union ua_ { StreamDPOpFlowVar8 *lpv8; StreamDPOpFlowVar16 *lpv16; StreamDPOpFlowVar32 *lpv32; @@ -503,7 +632,26 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, StreamDPOpClientsLimit *lpcl; StreamDPOpClientsUnLimit *lpclu; - } ua ; + + StreamDPOpFlowVar8Step *lpv8s; + StreamDPOpFlowVar16Step *lpv16s; + StreamDPOpFlowVar32Step *lpv32s; + StreamDPOpFlowVar64Step *lpv64s; +} ua_t ; + + + +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 + ){ + + uint8_t * p=program; + uint8_t * p_end=p+program_size; + + ua_t ua; while ( p < p_end) { uint8_t op_code=*p; @@ -620,9 +768,10 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, ua.lpw_pkt_size->run(flow_var,m_new_pkt_size); p+=sizeof(StreamDPOpPktSizeChange); break; - + default: - assert(0); + slow_commands(op_code,flow_var,pkt,p); + break; } }; }; @@ -736,6 +885,11 @@ public: return ( StreamVmInstruction::itFLOW_MAN); } + virtual bool is_valid_for_split() const { + return (m_step==1?true:false); + } + + virtual uint64_t get_splitable_range() const { return (m_max_value - m_min_value + 1); } @@ -777,13 +931,16 @@ public: flow_var_op_e op, uint64_t init_value, uint64_t min_value, - uint64_t max_value) : StreamVmInstructionVar(var_name) { + uint64_t max_value, + uint64_t step=1) : StreamVmInstructionVar(var_name) { m_op = op; m_size_bytes = size; m_init_value = init_value; m_min_value = min_value; m_max_value = max_value; + m_step = step; + } virtual void Dump(FILE *fd); @@ -796,7 +953,8 @@ public: m_op, m_init_value, m_min_value, - m_max_value); + m_max_value, + m_step); } private: @@ -817,6 +975,7 @@ public: uint64_t m_min_value; uint64_t m_max_value; + uint64_t m_step; }; diff --git a/src/stateless/cp/trex_vm_splitter.cpp b/src/stateless/cp/trex_vm_splitter.cpp index 9465718f..5e6d4fbd 100644 --- a/src/stateless/cp/trex_vm_splitter.cpp +++ b/src/stateless/cp/trex_vm_splitter.cpp @@ -101,6 +101,11 @@ TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) { return false; } + /* split only step of 1 */ + if (!instr->is_valid_for_split() ){ + return false; + } + /* we need to split - duplicate VM now */ duplicate_vm(); |