summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-02-16 16:08:23 +0200
committerHanoh Haim <hhaim@cisco.com>2016-02-16 16:08:23 +0200
commit47c865838678444c0075aab94267972a3a3cbfff (patch)
tree3551714c2b6e2f3c71374754732ab0e01c7d83f1 /src
parent75c84998813a359cb8619e80507e04f21d71de89 (diff)
step instruction support
Diffstat (limited to 'src')
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp11
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp321
-rw-r--r--src/stateless/cp/trex_stream_vm.h195
-rw-r--r--src/stateless/cp/trex_vm_splitter.cpp5
4 files changed, 452 insertions, 80 deletions
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();