summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gtest/trex_stateless_gtest.cpp171
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp12
-rw-r--r--src/stateless/cp/trex_stream_vm.h33
3 files changed, 206 insertions, 10 deletions
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index 191bae00..126d28af 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -160,6 +160,177 @@ TEST_F(basic_vm, vm2) {
}
+TEST_F(basic_vm, vm3) {
+
+ StreamVm vm;
+
+ vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
+ StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 )
+ );
+ vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
+ );
+ //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
+
+ vm.set_packet_size(128);
+
+ vm.compile_next();
+
+
+ uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
+
+ printf (" program size : %lu \n",(ulong)program_size);
+
+
+ vm.Dump(stdout);
+
+ #define PKT_TEST_SIZE (14+20+4+4)
+ uint8_t test_udp_pkt[PKT_TEST_SIZE]={
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x08,0x00,
+
+ 0x45,0x00,0x00,0x81, /*14 */
+ 0xaf,0x7e,0x00,0x00, /*18 */
+ 0x12,0x11,0xd9,0x23, /*22 */
+ 0x01,0x01,0x01,0x01, /*26 */
+ 0x3d,0xad,0x72,0x1b, /*30 */
+
+ 0x11,0x11,
+ 0x11,0x11,
+
+ 0x00,0x6d,
+ 0x00,0x00,
+ };
+
+
+
+ StreamDPVmInstructionsRunner runner;
+
+ uint8_t ex[]={5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3};
+
+ int i;
+ for (i=0; i<20; i++) {
+ runner.run(program_size,
+ vm.get_dp_instruction_buffer()->get_program(),
+ vm.get_bss_ptr(),
+ test_udp_pkt);
+
+ fprintf(stdout," %d \n",i);
+ //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
+ /* big */
+ EXPECT_EQ(test_udp_pkt[29],ex[i]);
+ EXPECT_EQ(test_udp_pkt[28],0);
+ EXPECT_EQ(test_udp_pkt[27],0);
+ EXPECT_EQ(test_udp_pkt[26],0);
+ }
+
+}
+
+TEST_F(basic_vm, vm4) {
+
+ StreamVm vm;
+
+ vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
+ StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,4,1,7 )
+ );
+ vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
+ );
+ //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
+
+ vm.set_packet_size(128);
+
+ vm.compile_next();
+
+
+ uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
+
+ printf (" program size : %lu \n",(ulong)program_size);
+
+
+ vm.Dump(stdout);
+
+ #define PKT_TEST_SIZE (14+20+4+4)
+ uint8_t test_udp_pkt[PKT_TEST_SIZE]={
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x08,0x00,
+
+ 0x45,0x00,0x00,0x81, /*14 */
+ 0xaf,0x7e,0x00,0x00, /*18 */
+ 0x12,0x11,0xd9,0x23, /*22 */
+ 0x01,0x01,0x01,0x01, /*26 */
+ 0x3d,0xad,0x72,0x1b, /*30 */
+
+ 0x11,0x11,
+ 0x11,0x11,
+
+ 0x00,0x6d,
+ 0x00,0x00,
+ };
+
+
+
+ StreamDPVmInstructionsRunner runner;
+
+ uint8_t ex[]={5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 1,
+ 2,
+ 3};
+
+ int i;
+ for (i=0; i<20; i++) {
+ runner.run(program_size,
+ vm.get_dp_instruction_buffer()->get_program(),
+ vm.get_bss_ptr(),
+ test_udp_pkt);
+
+ fprintf(stdout," %d \n",i);
+ //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
+ /* big */
+ EXPECT_EQ(test_udp_pkt[29],ex[i]);
+ EXPECT_EQ(test_udp_pkt[28],0);
+ EXPECT_EQ(test_udp_pkt[27],0);
+ EXPECT_EQ(test_udp_pkt[26],0);
+ }
+
+}
+
+
//////////////////////////////////////////////////////
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp
index 68021970..9fc2f049 100644
--- a/src/stateless/cp/trex_stream_vm.cpp
+++ b/src/stateless/cp/trex_stream_vm.cpp
@@ -391,12 +391,14 @@ void StreamVm::build_program(){
uint8_t op_size=var.m_instruction->m_size_bytes;
- uint8_t flow_offset=get_var_offset(lpPkt->m_flow_var_name);
+ bool is_big = lpPkt->m_is_big_endian;
+ uint8_t flags = (is_big?StreamDPOpPktWrBase::PKT_WR_IS_BIG:0);
+ uint8_t flow_offset = get_var_offset(lpPkt->m_flow_var_name);
if (op_size == 1) {
StreamDPOpPktWr8 pw8;
pw8.m_op = StreamDPVmInstructions::itPKT_WR8;
- pw8.m_flags =0;
+ pw8.m_flags =flags;
pw8.m_offset =flow_offset;
pw8.m_pkt_offset = lpPkt->m_pkt_offset;
pw8.m_val_offset = (int8_t)lpPkt->m_add_value;
@@ -406,7 +408,7 @@ void StreamVm::build_program(){
if (op_size == 2) {
StreamDPOpPktWr16 pw16;
pw16.m_op = StreamDPVmInstructions::itPKT_WR16;
- pw16.m_flags =0;
+ pw16.m_flags =flags;
pw16.m_offset =flow_offset;
pw16.m_pkt_offset = lpPkt->m_pkt_offset;
pw16.m_val_offset = (int16_t)lpPkt->m_add_value;
@@ -416,7 +418,7 @@ void StreamVm::build_program(){
if (op_size == 4) {
StreamDPOpPktWr32 pw32;
pw32.m_op = StreamDPVmInstructions::itPKT_WR32;
- pw32.m_flags =0;
+ pw32.m_flags =flags;
pw32.m_offset =flow_offset;
pw32.m_pkt_offset = lpPkt->m_pkt_offset;
pw32.m_val_offset = (int32_t)lpPkt->m_add_value;
@@ -426,7 +428,7 @@ void StreamVm::build_program(){
if (op_size == 8) {
StreamDPOpPktWr64 pw64;
pw64.m_op = StreamDPVmInstructions::itPKT_WR64;
- pw64.m_flags =0;
+ pw64.m_flags =flags;
pw64.m_offset =flow_offset;
pw64.m_pkt_offset = lpPkt->m_pkt_offset;
pw64.m_val_offset = (int64_t)lpPkt->m_add_value;
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index 1a4ca95f..843ec726 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -29,6 +29,7 @@ limitations under the License.
#include <common/Network/Packet/IPHeader.h>
+
class StreamVm;
@@ -164,9 +165,19 @@ public:
struct StreamDPOpPktWrBase {
+ enum {
+ PKT_WR_IS_BIG = 1
+ }; /* for flags */
+
uint8_t m_op;
uint8_t m_flags;
uint8_t m_offset;
+
+public:
+ bool is_big(){
+ return ( (m_flags &StreamDPOpPktWrBase::PKT_WR_IS_BIG) == StreamDPOpPktWrBase::PKT_WR_IS_BIG ?true:false);
+ }
+
} __attribute__((packed)) ;
@@ -181,6 +192,7 @@ public:
uint8_t * p_pkt = (pkt_base+m_pkt_offset);
uint8_t * p_flow_var = (flow_var_base+m_offset);
*p_pkt=(*p_flow_var+m_val_offset);
+
}
@@ -196,10 +208,14 @@ public:
inline void wr(uint8_t * flow_var_base,uint8_t * pkt_base) {
uint16_t * p_pkt = (uint16_t*)(pkt_base+m_pkt_offset);
uint16_t * p_flow_var = (uint16_t*)(flow_var_base+m_offset);
- *p_pkt=(*p_flow_var+m_val_offset);
- }
+ if ( likely(is_big())){
+ *p_pkt=PKT_HTONS((*p_flow_var+m_val_offset));
+ }else{
+ *p_pkt=(*p_flow_var+m_val_offset);
+ }
+ }
} __attribute__((packed));
struct StreamDPOpPktWr32 : public StreamDPOpPktWrBase {
@@ -211,10 +227,13 @@ public:
inline void wr(uint8_t * flow_var_base,uint8_t * pkt_base) {
uint32_t * p_pkt = (uint32_t*)(pkt_base+m_pkt_offset);
uint32_t * p_flow_var = (uint32_t*)(flow_var_base+m_offset);
- *p_pkt=(*p_flow_var+m_val_offset);
+ if ( likely(is_big())){
+ *p_pkt=PKT_HTONL((*p_flow_var+m_val_offset));
+ }else{
+ *p_pkt=(*p_flow_var+m_val_offset);
+ }
}
-
} __attribute__((packed));
struct StreamDPOpPktWr64 : public StreamDPOpPktWrBase {
@@ -227,7 +246,11 @@ public:
inline void wr(uint8_t * flow_var_base,uint8_t * pkt_base) {
uint64_t * p_pkt = (uint64_t*)(pkt_base+m_pkt_offset);
uint64_t * p_flow_var = (uint64_t*)(flow_var_base+m_offset);
- *p_pkt=(*p_flow_var+m_val_offset);
+ if ( likely(is_big())){
+ *p_pkt=pal_ntohl64((*p_flow_var+m_val_offset));
+ }else{
+ *p_pkt=(*p_flow_var+m_val_offset);
+ }
}