split multicore - all tests pass
authorimarom <[email protected]>
Sun, 25 Sep 2016 11:58:51 +0000 (14:58 +0300)
committerimarom <[email protected]>
Sun, 25 Sep 2016 12:08:09 +0000 (15:08 +0300)
scripts/automation/regression/functional_tests/stl_basic_tests.py
scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py
scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
scripts/stl/tests/multi_core_test.py
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/stateless/cp/trex_stream_vm.cpp
src/stateless/cp/trex_stream_vm.h

index 2817832..bc5bc4d 100644 (file)
@@ -340,11 +340,13 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test):
         seed = time.time()
 
         # test with simple vars
+        print(format_text("\nTesting multiple flow vars for multicore\n", 'underline'))
         rc = self.run_sim('stl/tests/multi_core_test.py', output = None, options = '--test_multi_core --limit=840 -t test_type=plain#seed={0} -m 27kpps'.format(seed), silent = True)
         assert_equal(rc, True)
 
 
         # test with tuple
+        print(format_text("\nTesting multiple tuple generators for multicore\n", 'underline'))
         rc = self.run_sim('stl/tests/multi_core_test.py', output = None, options = '--test_multi_core --limit=840 -t test_type=tuple#seed={0} -m 27kpps'.format(seed), silent = True)
         assert_equal(rc, True)
 
@@ -356,6 +358,7 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test):
                    ]
 
         for mc_test in mc_tests:
+            print(format_text("\ntesting {0} for multicore...\n".format(mc_test), 'underline'))
             rc = self.run_sim(mc_test, output = None, options = '--test_multi_core --limit=840 -m 27kpps', silent = True)
             assert_equal(rc, True)
 
index 63a1232..54ec2da 100644 (file)
@@ -558,25 +558,13 @@ def test_multi_core (r, options):
 
     print("")
 
-    print(format_text("comparing 2 cores to 1 core:\n", 'underline'))
-    rc = compare_caps_strict('1.cap', '2.cap')
-    if rc:
-        print("[Passed]\n")
-
-    print(format_text("comparing 4 cores to 1 core:\n", 'underline'))
-    rc = compare_caps('1.cap', '4.cap')
-    if rc:
-        print("[Passed]\n")
-
-    print(format_text("comparing 6 cores to 1 core:\n", 'underline'))
-    rc = compare_caps('1.cap', '6.cap')
-    if rc:
-        print("[Passed]\n")
-
-    print(format_text("comparing 8 cores to 1 core:\n", 'underline'))
-    rc = compare_caps('1.cap', '8.cap')
-    if rc:
-        print("[Passed]\n")
+    for core_count in range(1, 9):
+        print(format_text("comparing {0} cores to 1 core:\n".format(core_count), 'underline'))
+        rc = compare_caps_strict('1.cap', '{0}.cap'.format(core_count))
+        if rc:
+            print("[Passed]\n")
+
+    return
 
 
 def main (args = None):
index 65333e0..b42b56a 100755 (executable)
@@ -222,7 +222,6 @@ def decode_tunables (tunable_str):
 
     # each token is of form X=Y
     for token in tokens:
-        print(token)
         m = re.search('(.*)=(.*)', token)
         if not m:
             raise argparse.ArgumentTypeError("bad syntax for tunables: {0}".format(token))
index 918a30b..ccb66cb 100644 (file)
@@ -68,9 +68,13 @@ class STLMultiCore(object):
         port_min = rng.randint(0, port_bound - 1)
         port_max = rng.randint(port_min, port_bound - 1)
 
+        # 840 is the least common multiple
+        limit_flows = 840 * rng.randint(1, 1000)
         vm += [STLVmTupleGen(ip_min = ip_min, ip_max = ip_max, 
                              port_min = port_min, port_max = port_max,
-                             name = name),
+                             name = name,
+                             limit_flows = limit_flows),
+
                STLVmWrFlowVar (fv_name = name + ".ip", pkt_offset = pkt_offset ), # write ip to packet IP.src]
                STLVmWrFlowVar (fv_name = name + ".port", pkt_offset = (pkt_offset + 4) ),
                ]
index becd51c..3afa245 100644 (file)
@@ -241,14 +241,21 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std:
     uint32_t limit_flows  = parse_uint32(inst, "limit_flows", result);
     uint16_t flags        = parse_uint16(inst, "flags", result);
 
+    /* archiecture limitation - limit_flows must be greater or equal to DP core count */
+    if (limit_flows < get_stateless_obj()->get_dp_core_count()) {
+        std::stringstream ss;
+        ss << "cannot limit flows to less than " << (uint32_t)get_stateless_obj()->get_dp_core_count();
+        generate_execute_err(result, ss.str());
+    }
+
     stream->m_vm.add_instruction(new StreamVmInstructionFlowClient(flow_var_name,
-                                                                ip_min,
-                                                                ip_max,
-                                                                port_min,
-                                                                port_max,
-                                                                limit_flows,
-                                                                flags
-                                                                ));
+                                                                   ip_min,
+                                                                   ip_max,
+                                                                   port_min,
+                                                                   port_max,
+                                                                   limit_flows,
+                                                                   flags
+                                                                   ));
 }
 
 
index 594e9cf..106b5ea 100644 (file)
@@ -731,188 +731,118 @@ void StreamVm::build_program(){
 
             var_cnt++;
 
-            if (lpMan->m_size_bytes == 1 ){
-                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_size_bytes == 2 ){
-                uint8_t op;
-                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){
-
-
-                op = StreamDPVmInstructions::ditINC16;
-
-                if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
-                    op = StreamDPVmInstructions::ditINC16 ;
+            /* flow var size 1 */
+            if (lpMan->m_size_bytes == 1 ) {
+                uint8_t op = StreamDPVmInstructions::ditINC8_STEP;
+
+                switch (lpMan->m_op) {
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_INC:
+                    op = StreamDPVmInstructions::ditINC8_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC:
+                    op = StreamDPVmInstructions::ditDEC8_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM:
+                    op = StreamDPVmInstructions::ditRANDOM8;
+                    break;
+                default:
+                    assert(0);
                 }
 
-                if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
-                    op = StreamDPVmInstructions::ditDEC16 ;
-                }
+                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::ditRANDOM16 ;
+            /* flow var size 2 */
+            if (lpMan->m_size_bytes == 2) {
+                uint8_t op = StreamDPVmInstructions::ditINC16_STEP;
+
+                switch (lpMan->m_op) {
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_INC:
+                    op = StreamDPVmInstructions::ditINC16_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC:
+                    op = StreamDPVmInstructions::ditDEC16_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM:
+                    op = StreamDPVmInstructions::ditRANDOM16;
+                    break;
+                default:
+                    assert(0);
                 }
 
-                StreamDPOpFlowVar16 fv16;
+                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;
-                m_instructions.add_command(&fv16,sizeof(fv16));
-              }else{
-
-                  op = StreamDPVmInstructions::ditINC16_STEP;
-
-                  if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
-                      op = StreamDPVmInstructions::ditINC16_STEP ;
-                  }
+                fv16.m_step        = (uint16_t)lpMan->m_step;
 
-                  if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
-                      op = StreamDPVmInstructions::ditDEC16_STEP ;
-                  }
+                m_instructions.add_command(&fv16,sizeof(fv16));
+            }
 
-                  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;
 
-                  m_instructions.add_command(&fv16,sizeof(fv16));
-              }
-            }
+            /* flow var size 4 */
+            if (lpMan->m_size_bytes == 4) {
+                uint8_t op = StreamDPVmInstructions::ditINC32_STEP;
 
-            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{
+                switch (lpMan->m_op) {
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_INC:
                     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));
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC:
+                    op = StreamDPVmInstructions::ditDEC32_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM:
+                    op = StreamDPVmInstructions::ditRANDOM32;
+                    break;
+                default:
+                    assert(0);
                 }
-            }
 
+                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));
 
-            if (lpMan->m_size_bytes == 8 ){
-                uint8_t op;
-
-                if ( (lpMan->m_step == 1) || (lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ) ){
+            }
 
-                    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{
+            /* flow var size 8 */
+            if (lpMan->m_size_bytes == 8) {
+                uint8_t op = StreamDPVmInstructions::ditINC64_STEP;
 
+                switch (lpMan->m_op) {
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_INC:
                     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));
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC:
+                    op = StreamDPVmInstructions::ditDEC64_STEP;
+                    break;
+                case StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM:
+                    op = StreamDPVmInstructions::ditRANDOM64;
+                    break;
+                default:
+                    assert(0);
                 }
+
+                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));
+
             }
+
         }
 
         if (ins_type == StreamVmInstruction::itPKT_WR) {
@@ -1065,11 +995,14 @@ void StreamVm::build_program(){
 
                 client_cmd.m_min_port    = lpMan->m_port.m_min_value;
                 client_cmd.m_max_port    = lpMan->m_port.m_max_value;
-                client_cmd.m_port_step   = lpMan->m_port.m_step;
-
+                client_cmd.m_step_port   = lpMan->m_port.m_step;
+                
                 client_cmd.m_min_ip      = lpMan->m_ip.m_min_value;
                 client_cmd.m_max_ip      = lpMan->m_ip.m_max_value;
-                client_cmd.m_ip_step     = lpMan->m_ip.m_step;
+                client_cmd.m_step_ip     = lpMan->m_ip.m_step;
+
+                client_cmd.m_init_ip     = lpMan->m_ip.m_init_value;
+                client_cmd.m_init_port   = lpMan->m_port.m_init_value;
 
                 client_cmd.m_limit_flows = lpMan->m_limit_num_flows;
                 m_instructions.add_command(&client_cmd,sizeof(client_cmd));
@@ -1299,11 +1232,6 @@ void StreamDPVmInstructions::Dump(FILE *fd){
     uint32_t program_size = get_program_size();
     uint8_t * p_end=p+program_size;
 
-    StreamDPOpFlowVar8  *lpv8;
-    StreamDPOpFlowVar16 *lpv16;
-    StreamDPOpFlowVar32 *lpv32;
-    StreamDPOpFlowVar64 *lpv64;
-
     StreamDPOpFlowVar8Step  *lpv8s;
     StreamDPOpFlowVar16Step *lpv16s;
     StreamDPOpFlowVar32Step *lpv32s;
@@ -1328,67 +1256,25 @@ void StreamDPVmInstructions::Dump(FILE *fd){
         uint8_t op_code=*p;
         switch (op_code) {
 
-        case   ditINC8  :
-            lpv8 =(StreamDPOpFlowVar8 *)p;
-            lpv8->dump(fd,"INC8");
-            p+=sizeof(StreamDPOpFlowVar8);
-            break;
-        case  ditINC16  :
-            lpv16 =(StreamDPOpFlowVar16 *)p;
-            lpv16->dump(fd,"INC16");
-            p+=sizeof(StreamDPOpFlowVar16);
-            break;
-        case  ditINC32 :
-            lpv32 =(StreamDPOpFlowVar32 *)p;
-            lpv32->dump(fd,"INC32");
-            p+=sizeof(StreamDPOpFlowVar32);
-             break;
-        case  ditINC64 :
-            lpv64 =(StreamDPOpFlowVar64 *)p;
-            lpv64->dump(fd,"INC64");
-            p+=sizeof(StreamDPOpFlowVar64);
-            break;
-
-        case  ditDEC8 :
-            lpv8 =(StreamDPOpFlowVar8 *)p;
-            lpv8->dump(fd,"DEC8");
-            p+=sizeof(StreamDPOpFlowVar8);
-            break;
-        case  ditDEC16 :
-            lpv16 =(StreamDPOpFlowVar16 *)p;
-            lpv16->dump(fd,"DEC16");
-            p+=sizeof(StreamDPOpFlowVar16);
-            break;
-        case  ditDEC32 :
-            lpv32 =(StreamDPOpFlowVar32 *)p;
-            lpv32->dump(fd,"DEC32");
-            p+=sizeof(StreamDPOpFlowVar32);
-            break;
-        case  ditDEC64 :
-            lpv64 =(StreamDPOpFlowVar64 *)p;
-            lpv64->dump(fd,"DEC64");
-            p+=sizeof(StreamDPOpFlowVar64);
-            break;
-
         case  ditRANDOM8 :
-            lpv8 =(StreamDPOpFlowVar8 *)p;
-            lpv8->dump(fd,"RAND8");
-            p+=sizeof(StreamDPOpFlowVar8);
+            lpv8s =(StreamDPOpFlowVar8Step *)p;
+            lpv8s->dump(fd,"RAND8");
+            p+=sizeof(StreamDPOpFlowVar8Step);
             break;
         case  ditRANDOM16 :
-            lpv16 =(StreamDPOpFlowVar16 *)p;
-            lpv16->dump(fd,"RAND16");
-            p+=sizeof(StreamDPOpFlowVar16);
+            lpv16s =(StreamDPOpFlowVar16Step *)p;
+            lpv16s->dump(fd,"RAND16");
+            p+=sizeof(StreamDPOpFlowVar16Step);
             break;
         case  ditRANDOM32 :
-            lpv32 =(StreamDPOpFlowVar32 *)p;
-            lpv32->dump(fd,"RAND32");
-            p+=sizeof(StreamDPOpFlowVar32);
+            lpv32s =(StreamDPOpFlowVar32Step *)p;
+            lpv32s->dump(fd,"RAND32");
+            p+=sizeof(StreamDPOpFlowVar32Step);
             break;
         case  ditRANDOM64 :
-            lpv64 =(StreamDPOpFlowVar64 *)p;
-            lpv64->dump(fd,"RAND64");
-            p+=sizeof(StreamDPOpFlowVar64);
+            lpv64s =(StreamDPOpFlowVar64Step *)p;
+            lpv64s->dump(fd,"RAND64");
+            p+=sizeof(StreamDPOpFlowVar64Step);
             break;
 
         case  ditFIX_IPV4_CS :
@@ -1535,22 +1421,6 @@ void StreamDPOpFlowVar64Step::dump(FILE *fd,std::string opt){
 }
 
 
-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);
-}
-
-void StreamDPOpFlowVar16::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);
-}
-
-void StreamDPOpFlowVar32::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);
-}
-
-void StreamDPOpFlowVar64::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);
-}
-
 void StreamDPOpPktWr8::dump(FILE *fd,std::string opt){
     fprintf(fd," %10s  op:%lu, flags:%lu, pkt_of:%lu,  f_of:%lu \n",  opt.c_str(),(ulong)m_op,(ulong)m_flags,(ulong)m_pkt_offset,(ulong)m_offset);
 }
@@ -1697,49 +1567,6 @@ void   StreamDPVmInstructionsRunner::slow_commands(uint8_t op_code,
     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;
     case  StreamDPVmInstructions::itPKT_WR_MASK:
         ua.lpwr_mask =(StreamDPOpPktWrMask *)p;
         ua.lpwr_mask->wr(flow_var,pkt);
index 0556eaf..92fefbb 100644 (file)
@@ -262,102 +262,106 @@ public:
 
 /* in memory program */
 
-struct StreamDPOpFlowVar8 {
+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);
-        *p = inc_mod(m_min_val, m_max_val, *p, 1);
+        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     inline void run_dec(uint8_t * flow_var) {
         uint8_t *p = (flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *p, 1);
+        *p = dec_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     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 + (vm_rand16(per_thread_random)  % (int)(m_max_val - m_min_val + 1));
+        uint8_t *p=(flow_var+m_flow_offset);
+        *p = m_min_val + (vm_rand16(per_thread_random)  % (int)(m_max_val - m_min_val + 1));
     }
 
-
 } __attribute__((packed)) ;
 
-struct StreamDPOpFlowVar16 {
+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);
-        *p = inc_mod(m_min_val, m_max_val, *p, 1);
+        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     inline void run_dec(uint8_t * flow_var) {
         uint16_t *p = (uint16_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *p, 1);
+        *p = dec_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     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 + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1));
+        uint16_t *p = (uint16_t *)(flow_var+m_flow_offset);
+        *p = m_min_val + (vm_rand16(per_thread_random) % (int)(m_max_val - m_min_val + 1));
     }
 
-
-
 } __attribute__((packed)) ;
 
-struct StreamDPOpFlowVar32 {
+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);
-        *p = inc_mod(m_min_val, m_max_val, *p, 1);
+        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     inline void run_dec(uint8_t * flow_var) {
         uint32_t *p = (uint32_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *p, 1);
+        *p = dec_mod(m_min_val, m_max_val, *p, m_step);
     }
 
+
     inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
-        uint32_t * p=(uint32_t *)(flow_var+m_flow_offset);
+        uint32_t *p = (uint32_t *)(flow_var+m_flow_offset);
         *p = m_min_val + (vm_rand32(per_thread_random) % ((uint64_t)(m_max_val) - m_min_val + 1));
     }
 
 } __attribute__((packed)) ;
 
-struct StreamDPOpFlowVar64 {
+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);
-        *p = inc_mod(m_min_val, m_max_val, *p, 1);
+        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
     }
 
     inline void run_dec(uint8_t * flow_var) {
         uint64_t *p = (uint64_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *p, 1);
+        *p = dec_mod(m_min_val, m_max_val, *p, m_step);
     }
 
+
     inline void run_rand(uint8_t * flow_var,uint32_t *per_thread_random) {
         uint64_t * p=(uint64_t *)(flow_var+m_flow_offset);
 
@@ -368,95 +372,6 @@ 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);
-        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
-    }
-
-    inline void run_dec(uint8_t * flow_var) {
-        uint8_t *p = (flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *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);
-        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
-    }
-
-    inline void run_dec(uint8_t * flow_var) {
-        uint16_t *p = (uint16_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *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);
-        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
-    }
-
-    inline void run_dec(uint8_t * flow_var) {
-        uint32_t *p = (uint32_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *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);
-        *p = inc_mod(m_min_val, m_max_val, *p, m_step);
-    }
-
-    inline void run_dec(uint8_t * flow_var) {
-        uint64_t *p = (uint64_t *)(flow_var + m_flow_offset);
-        *p = dec_mod(m_min_val, m_max_val, *p, m_step);
-    }
-
-
 } __attribute__((packed)) ;
 
 ///////////////////////////////////////////////////////////////////////
@@ -615,11 +530,13 @@ struct StreamDPOpClientsLimit {
 
     uint16_t    m_min_port;
     uint16_t    m_max_port;
-    uint16_t    m_port_step;
+    uint16_t    m_step_port;
+    uint16_t    m_init_port;
 
     uint32_t    m_min_ip;
     uint32_t    m_max_ip;
-    uint32_t    m_ip_step;
+    uint32_t    m_step_ip;
+    uint32_t    m_init_ip;
 
     uint32_t    m_limit_flows; /* limit the number of flows */
 
@@ -631,25 +548,22 @@ public:
         StreamDPFlowClient *lp = (StreamDPFlowClient *)(flow_var_base + m_flow_offset);
 
         /* first advance the outer var (IP) */
-        lp->cur_ip = inc_mod_of(m_min_ip, m_max_ip, lp->cur_ip, m_ip_step, of);
+        lp->cur_ip = inc_mod_of(m_min_ip, m_max_ip, lp->cur_ip, m_step_ip, of);
 
         /* if we had an overflow - advance the port */
         if (of) {
-            lp->cur_port = inc_mod(m_min_port, m_max_port, lp->cur_port, m_port_step);
+            lp->cur_port = inc_mod(m_min_port, m_max_port, lp->cur_port, m_step_port);
         }
 
-        /* TODO: handle limit */
-        #if 0
         if (m_limit_flows) {
             lp->cur_flow_id++;
             if ( lp->cur_flow_id > m_limit_flows ){
                 /* reset to the first flow */
                 lp->cur_flow_id = 1;
-                lp->cur_ip      =  m_min_ip;
-                lp->cur_port    =  m_min_port;
+                lp->cur_ip      = m_init_ip;
+                lp->cur_port    = m_init_port;
             }
         }
-        #endif
     }
 
 
@@ -790,10 +704,6 @@ private:
 
 
 typedef union  ua_ {
-        StreamDPOpFlowVar8  *lpv8;
-        StreamDPOpFlowVar16 *lpv16;
-        StreamDPOpFlowVar32 *lpv32;
-        StreamDPOpFlowVar64 *lpv64;
         StreamDPOpIpv4Fix   *lpIpv4Fix;
         StreamDPOpPktWr8     *lpw8;
         StreamDPOpPktWr16    *lpw16;
@@ -835,80 +745,88 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random,
         uint8_t op_code=*p;
         switch (op_code) {
 
-        case  StreamDPVmInstructions::itCLIENT_VAR :      
+        case StreamDPVmInstructions::itCLIENT_VAR :      
             ua.lpcl =(StreamDPOpClientsLimit *)p;
             ua.lpcl->run(flow_var);
             p+=sizeof(StreamDPOpClientsLimit);
             break;
 
-        case  StreamDPVmInstructions::itCLIENT_VAR_UNLIMIT :      
+        case StreamDPVmInstructions::itCLIENT_VAR_UNLIMIT :      
             ua.lpclu =(StreamDPOpClientsUnLimit *)p;
             ua.lpclu->run(flow_var);
-            p+=sizeof(StreamDPOpClientsUnLimit);
+            p += sizeof(StreamDPOpClientsUnLimit);
             break;
 
-        case   StreamDPVmInstructions::ditINC8  :
-            ua.lpv8 =(StreamDPOpFlowVar8 *)p;
-            ua.lpv8->run_inc(flow_var);
-            p+=sizeof(StreamDPOpFlowVar8);
+        case StreamDPVmInstructions::ditINC8_STEP:
+            ua.lpv8s =(StreamDPOpFlowVar8Step *)p;
+            ua.lpv8s->run_inc(flow_var);
+            p += sizeof(StreamDPOpFlowVar8Step);
             break;
 
-        case  StreamDPVmInstructions::ditINC16  :
-            ua.lpv16 =(StreamDPOpFlowVar16 *)p;
-            ua.lpv16->run_inc(flow_var);
-            p+=sizeof(StreamDPOpFlowVar16);
+        case StreamDPVmInstructions::ditINC16_STEP:
+            ua.lpv16s =(StreamDPOpFlowVar16Step *)p;
+            ua.lpv16s->run_inc(flow_var);
+            p += sizeof(StreamDPOpFlowVar16Step);
             break;
-        case  StreamDPVmInstructions::ditINC32 :
-            ua.lpv32 =(StreamDPOpFlowVar32 *)p;
-            ua.lpv32->run_inc(flow_var);
-            p+=sizeof(StreamDPOpFlowVar32);
+
+        case StreamDPVmInstructions::ditINC32_STEP:
+            ua.lpv32s =(StreamDPOpFlowVar32Step *)p;
+            ua.lpv32s->run_inc(flow_var);
+            p += sizeof(StreamDPOpFlowVar32Step);
              break;
-        case  StreamDPVmInstructions::ditINC64 :
-            ua.lpv64 =(StreamDPOpFlowVar64 *)p;
-            ua.lpv64->run_inc(flow_var);
-            p+=sizeof(StreamDPOpFlowVar64);
+
+        case StreamDPVmInstructions::ditINC64_STEP:
+            ua.lpv64s =(StreamDPOpFlowVar64Step *)p;
+            ua.lpv64s->run_inc(flow_var);
+            p += sizeof(StreamDPOpFlowVar64Step);
             break;
 
-        case  StreamDPVmInstructions::ditDEC8 :
-            ua.lpv8 =(StreamDPOpFlowVar8 *)p;
-            ua.lpv8->run_dec(flow_var);
-            p+=sizeof(StreamDPOpFlowVar8);
+        case StreamDPVmInstructions::ditDEC8_STEP:
+            ua.lpv8s =(StreamDPOpFlowVar8Step *)p;
+            ua.lpv8s->run_dec(flow_var);
+            p += sizeof(StreamDPOpFlowVar8Step);
             break;
-        case  StreamDPVmInstructions::ditDEC16 :
-            ua.lpv16 =(StreamDPOpFlowVar16 *)p;
-            ua.lpv16->run_dec(flow_var);
-            p+=sizeof(StreamDPOpFlowVar16);
+
+        case StreamDPVmInstructions::ditDEC16_STEP:
+            ua.lpv16s =(StreamDPOpFlowVar16Step *)p;
+            ua.lpv16s->run_dec(flow_var);
+            p += sizeof(StreamDPOpFlowVar16Step);
             break;
-        case  StreamDPVmInstructions::ditDEC32 :
-            ua.lpv32 =(StreamDPOpFlowVar32 *)p;
-            ua.lpv32->run_dec(flow_var);
-            p+=sizeof(StreamDPOpFlowVar32);
+
+        case StreamDPVmInstructions::ditDEC32_STEP:
+            ua.lpv32s =(StreamDPOpFlowVar32Step *)p;
+            ua.lpv32s->run_dec(flow_var);
+            p += sizeof(StreamDPOpFlowVar32Step);
             break;
-        case  StreamDPVmInstructions::ditDEC64 :
-            ua.lpv64 =(StreamDPOpFlowVar64 *)p;
-            ua.lpv64->run_dec(flow_var);
-            p+=sizeof(StreamDPOpFlowVar64);
+
+        case StreamDPVmInstructions::ditDEC64_STEP:
+            ua.lpv64s =(StreamDPOpFlowVar64Step *)p;
+            ua.lpv64s->run_dec(flow_var);
+            p += sizeof(StreamDPOpFlowVar64Step);
             break;
 
-        case  StreamDPVmInstructions::ditRANDOM8 :
-            ua.lpv8 =(StreamDPOpFlowVar8 *)p;
-            ua.lpv8->run_rand(flow_var,per_thread_random);
-            p+=sizeof(StreamDPOpFlowVar8);
+        case StreamDPVmInstructions::ditRANDOM8 :
+            ua.lpv8s =(StreamDPOpFlowVar8Step *)p;
+            ua.lpv8s->run_rand(flow_var, per_thread_random);
+            p += sizeof(StreamDPOpFlowVar8Step);
             break;
-        case  StreamDPVmInstructions::ditRANDOM16 :
-            ua.lpv16 =(StreamDPOpFlowVar16 *)p;
-            ua.lpv16->run_rand(flow_var,per_thread_random);
-            p+=sizeof(StreamDPOpFlowVar16);
+
+        case StreamDPVmInstructions::ditRANDOM16:
+            ua.lpv16s =(StreamDPOpFlowVar16Step *)p;
+            ua.lpv16s->run_rand(flow_var, per_thread_random);
+            p += sizeof(StreamDPOpFlowVar16Step);
             break;
-        case  StreamDPVmInstructions::ditRANDOM32 :
-            ua.lpv32 =(StreamDPOpFlowVar32 *)p;
-            ua.lpv32->run_rand(flow_var,per_thread_random);
-            p+=sizeof(StreamDPOpFlowVar32);
+
+        case StreamDPVmInstructions::ditRANDOM32:
+            ua.lpv32s =(StreamDPOpFlowVar32Step *)p;
+            ua.lpv32s->run_rand(flow_var, per_thread_random);
+            p += sizeof(StreamDPOpFlowVar32Step);
             break;
-        case  StreamDPVmInstructions::ditRANDOM64 :
-            ua.lpv64 =(StreamDPOpFlowVar64 *)p;
-            ua.lpv64->run_rand(flow_var,per_thread_random);
-            p+=sizeof(StreamDPOpFlowVar64);
+
+        case StreamDPVmInstructions::ditRANDOM64:
+            ua.lpv64s =(StreamDPOpFlowVar64Step *)p;
+            ua.lpv64s->run_rand(flow_var, per_thread_random);
+            p += sizeof(StreamDPOpFlowVar64Step);
             break;
 
         case  StreamDPVmInstructions::ditFIX_IPV4_CS :
@@ -1441,6 +1359,17 @@ public:
         uint16_t port_step_mul  =  1 + (step_mul / m_ip.get_range());
 
         m_port.update(port_phase, port_step_mul);
+    
+        /* update the limit per core */
+        if (m_limit_num_flows) {
+            uint64_t per_core_limit = m_limit_num_flows / step_mul;
+            if (phase == 0) {
+                per_core_limit += m_limit_num_flows % step_mul;
+            }
+
+            m_limit_num_flows = per_core_limit;
+            assert(per_core_limit > 0);
+        }
         
     }