fix ipv4 checksum error in case of pkt_size>128 and field offset less than ip-header...
authorHanoh Haim <[email protected]>
Tue, 23 Feb 2016 13:30:41 +0000 (15:30 +0200)
committerHanoh Haim <[email protected]>
Tue, 23 Feb 2016 13:30:41 +0000 (15:30 +0200)
scripts/automation/regression/unit_tests/functional_tests/stl_basic_tests.py
scripts/exp/udp_1pkt_simple_test.pcap [new file with mode: 0644]
scripts/exp/udp_1pkt_simple_test2.pcap [new file with mode: 0644]
scripts/stl/udp_1pkt_simple_test.py [new file with mode: 0644]
scripts/stl/udp_1pkt_simple_test2.py [new file with mode: 0644]
src/stateless/cp/trex_stream.cpp
src/stateless/cp/trex_stream.h
src/stateless/cp/trex_stream_vm.cpp
src/stateless/cp/trex_stream_vm.h

index e6a82cf..6fb012c 100644 (file)
@@ -181,13 +181,15 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test):
             ["udp_1pkt_mac_step.py","-m 1 -l 20 ",True],
             ["udp_1pkt_mac_mask1.py","-m 1 -l 20 ",True] ,
             ["udp_1pkt_mac_mask2.py","-m 1 -l 20 ",True],
-            ["udp_1pkt_mac_mask3.py","-m 1 -l 20 ",True]
+            ["udp_1pkt_mac_mask3.py","-m 1 -l 20 ",True],
+            ["udp_1pkt_simple_test2.py","-m 1 -l 10 ",True], # test split of packet with ip option
+            ["udp_1pkt_simple_test.py","-m 1 -l 10 ",True]
 
 
           ];
 
 
-        p1  = [ ["udp_1pkt_mpls_vm.py","-m 1 ",True] ]
+        p1  = [ ["udp_1pkt_simple_test.py","-m 1 -l 10 ",True] ]
         
 
         for obj in p:
diff --git a/scripts/exp/udp_1pkt_simple_test.pcap b/scripts/exp/udp_1pkt_simple_test.pcap
new file mode 100644 (file)
index 0000000..2eeec46
Binary files /dev/null and b/scripts/exp/udp_1pkt_simple_test.pcap differ
diff --git a/scripts/exp/udp_1pkt_simple_test2.pcap b/scripts/exp/udp_1pkt_simple_test2.pcap
new file mode 100644 (file)
index 0000000..002d77d
Binary files /dev/null and b/scripts/exp/udp_1pkt_simple_test2.pcap differ
diff --git a/scripts/stl/udp_1pkt_simple_test.py b/scripts/stl/udp_1pkt_simple_test.py
new file mode 100644 (file)
index 0000000..eb11d4e
--- /dev/null
@@ -0,0 +1,43 @@
+from trex_stl_lib.api import *
+
+def generate_payload(length):
+      word = ''
+      alphabet_size = len(string.letters)
+      for i in range(length):
+          word += string.letters[(i % alphabet_size)]
+      return word
+
+
+class STLS1(object):
+
+    def create_stream (self):
+        fsize_no_fcs = 129
+        base_pkt_a = Ether()/IP(dst="48.0.0.1",options=IPOption('\x01\x01\x01\x00'))/UDP(dport=12,sport=1025)
+
+        vm1 = CTRexScRaw([
+                          STLVmFlowVar(name="src",min_value="10.0.0.1",max_value="10.0.0.10",size=4,op="inc"),
+                          STLVmWrFlowVar(fv_name="src",pkt_offset= "IP.src"),
+                           # checksum
+                         STLVmFixIpv4(offset = "IP")
+
+                         ]
+                         ) # split to cores base on the tuple generator
+
+        #
+        pkt_a = STLPktBuilder(pkt=base_pkt_a/generate_payload(fsize_no_fcs-len(base_pkt_a)), vm=vm1)
+
+
+        return STLStream( packet = pkt_a ,
+                          mode = STLTXCont() )
+
+    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/udp_1pkt_simple_test2.py b/scripts/stl/udp_1pkt_simple_test2.py
new file mode 100644 (file)
index 0000000..c8da758
--- /dev/null
@@ -0,0 +1,43 @@
+from trex_stl_lib.api import *
+
+def generate_payload(length):
+      word = ''
+      alphabet_size = len(string.letters)
+      for i in range(length):
+          word += string.letters[(i % alphabet_size)]
+      return word
+
+
+class STLS1(object):
+
+    def create_stream (self):
+        fsize_no_fcs = 129
+        base_pkt_a = Ether()/IP()/IPv6()/IP(dst="48.0.0.1",options=IPOption('\x01\x01\x01\x00'))/UDP(dport=12,sport=1025)
+
+        vm1 = CTRexScRaw([
+                          STLVmFlowVar(name="src",min_value="10.0.0.1",max_value="10.0.0.10",size=4,op="inc"),
+                          STLVmWrFlowVar(fv_name="src",pkt_offset= "IP:1.src"),
+                           # checksum
+                          STLVmFixIpv4(offset = "IP:1")
+
+                         ]
+                         ) # split to cores base on the tuple generator
+
+        #
+        pkt_a = STLPktBuilder(pkt=base_pkt_a/generate_payload(fsize_no_fcs-len(base_pkt_a)), vm=vm1)
+
+
+        return STLStream( packet = pkt_a ,
+                          mode = STLTXCont() )
+
+    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()
+
+
+
index fb0b35d..05c14cb 100644 (file)
@@ -62,7 +62,9 @@ TrexStream::vm_compile() {
     }
 
     /* compile */
+    m_vm.set_pkt(m_pkt.binary);
     m_vm.compile(m_pkt.len);
+    m_vm.set_pkt(0);
 
     /* create DP object */
     m_vm_dp = m_vm.generate_dp_object();
index 2ab90c9..5240e96 100644 (file)
@@ -68,22 +68,26 @@ static inline uint16_t get_log2_size(uint16_t size){
  *        ==>62
  * 
  */
+
 static inline uint16_t calc_writable_mbuf_size(uint16_t max_offset_writable,
                                                uint16_t pkt_size){
 
-    if ( pkt_size<=64 ){
-        return (pkt_size);
-    }
     if (pkt_size<=128) {
         return (pkt_size);
     }
 
     //pkt_size> 128
+    // if reside is less than 64 keep it as a single packet
     uint16_t non_writable = pkt_size - (max_offset_writable +1) ;
     if ( non_writable<64 ) {
         return (pkt_size);
     }
-    return(max_offset_writable+1);
+
+    // keep the r/w at least 60 byte
+    if ((max_offset_writable+1)<=60) {
+        return 60;
+    }
+    return max_offset_writable+1;
 }
 
 
index f83025d..b0cadfb 100644 (file)
@@ -396,8 +396,6 @@ void StreamVm::build_program(){
         if (ins_type == StreamVmInstruction::itFIX_IPV4_CS) {
             StreamVmInstructionFixChecksumIpv4 *lpFix =(StreamVmInstructionFixChecksumIpv4 *)inst;
 
-            add_field_cnt(lpFix->m_pkt_offset +12);
-
             if ( (lpFix->m_pkt_offset + IPV4_HDR_LEN) > m_pkt_size  ) {
 
                 std::stringstream ss;
@@ -405,6 +403,26 @@ void StreamVm::build_program(){
                 err(ss.str());
             }
 
+            uint16_t offset_next_layer = IPV4_HDR_LEN;
+
+            if ( m_pkt ){
+                IPHeader * ipv4= (IPHeader *)(m_pkt+lpFix->m_pkt_offset);
+                offset_next_layer = ipv4->getSize();
+            }
+
+            if (offset_next_layer<IPV4_HDR_LEN) {
+                offset_next_layer=IPV4_HDR_LEN;
+            }
+
+            if ( (lpFix->m_pkt_offset + offset_next_layer) > m_pkt_size  ) {
+
+                std::stringstream ss;
+                ss << "instruction id '" << ins_id << "' fix ipv4 command offset  " << lpFix->m_pkt_offset << "plus "<<offset_next_layer<< " is too high relative to packet size  "<< m_pkt_size;
+                err(ss.str());
+            }
+            /* calculate this offset from the packet */
+            add_field_cnt(lpFix->m_pkt_offset + offset_next_layer);
+
             StreamDPOpIpv4Fix ipv_fix;
             ipv_fix.m_offset = lpFix->m_pkt_offset;
             ipv_fix.m_op = StreamDPVmInstructions::ditFIX_IPV4_CS;
index 1350470..c16545d 100644 (file)
@@ -1408,6 +1408,7 @@ public:
 
         m_split_instr=NULL;
         m_is_compiled = false;
+        m_pkt=0;
     }
 
 
@@ -1511,6 +1512,10 @@ public:
     /* raise exception */
     void  err(const std::string &err);
 
+    void set_pkt(uint8_t *pkt){
+        m_pkt=pkt;
+    }
+
 
     /**
      * return a pointer to a flow var / client var 
@@ -1565,6 +1570,7 @@ private:
     StreamDPVmInstructions             m_instructions;
     
     StreamVmInstructionVar             *m_split_instr;
+    uint8_t                            *m_pkt;