summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-12-13 16:26:36 +0200
committerHanoh Haim <hhaim@cisco.com>2015-12-13 16:26:36 +0200
commitbc6ecb17ed3cce705f08d9b7f676de9e6fbf8c77 (patch)
tree4daa908b7dd6b712f92e1dcfcdc0d069b73f5890 /src
parent6a38f90c1bc6ac63897356c60ad29a7e513e8ad2 (diff)
compile a program
Diffstat (limited to 'src')
-rw-r--r--src/gtest/trex_stateless_gtest.cpp11
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp382
-rw-r--r--src/stateless/cp/trex_stream_vm.h81
3 files changed, 427 insertions, 47 deletions
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index 1ad03c63..02e84c0f 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -55,30 +55,27 @@ TEST_F(basic_vm, vm0) {
);
vm.Dump(stdout);
-
-
}
TEST_F(basic_vm, vm1) {
StreamVm vm;
- vm.set_packet_size(512);
-
- vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(20) );
+ vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1,
StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 )
);
- vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",14, 0,true)
+ vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
);
- vm.Dump(stdout);
+ vm.set_packet_size(128);
vm.compile_next();
}
+
//////////////////////////////////////////////////////
diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp
index 09a49111..82ba8bc5 100644
--- a/src/stateless/cp/trex_stream_vm.cpp
+++ b/src/stateless/cp/trex_stream_vm.cpp
@@ -24,6 +24,8 @@ limitations under the License.
#include <assert.h>
#include <iostream>
#include <trex_stateless.h>
+#include <common/Network/Packet/IPHeader.h>
+#include <common/basic_utils.h>
@@ -129,6 +131,12 @@ void StreamVm::add_instruction(StreamVmInstruction *inst) {
m_inst_list.push_back(inst);
}
+const StreamDPVmInstructions &
+StreamVm::get_dp_instruction_buffer(){
+ return m_instructions;
+}
+
+
const std::vector<StreamVmInstruction *> &
StreamVm::get_instruction_list() {
return m_inst_list;
@@ -144,6 +152,14 @@ bool StreamVm::var_add(const std::string &var_name,VmFlowVarRec & var){
}
+uint16_t StreamVm::get_var_offset(const std::string &var_name){
+ VmFlowVarRec var;
+ bool res=var_lookup(var_name,var);
+ assert(res);
+ return (var.m_offset);
+}
+
+
bool StreamVm::var_lookup(const std::string &var_name,VmFlowVarRec & var){
auto search = m_flow_var_offset.find(var_name);
@@ -206,6 +222,18 @@ void StreamVm::alloc_bss(){
m_bss=(uint8_t *)malloc(m_cur_var_offset);
}
+void StreamVm::clean_max_field_cnt(){
+ m_max_field_update=0;
+}
+
+void StreamVm::add_field_cnt(uint16_t new_cnt){
+
+ if ( new_cnt > m_max_field_update) {
+ m_max_field_update = new_cnt;
+ }
+}
+
+
void StreamVm::free_bss(){
if (m_bss) {
free(m_bss);
@@ -216,6 +244,199 @@ void StreamVm::free_bss(){
void StreamVm::build_program(){
+ /* build the commands into a buffer */
+ m_instructions.clear();
+ clean_max_field_cnt();
+ uint32_t ins_id=0;
+
+ for (auto inst : m_inst_list) {
+ StreamVmInstruction::instruction_type_t ins_type=inst->get_instruction_type();
+
+ /* itFIX_IPV4_CS */
+ 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;
+ ss << "instruction id '" << ins_id << "' fix ipv4 command offset " << lpFix->m_pkt_offset << " is too high relative to packet size "<< m_pkt_size;
+ err(ss.str());
+ }
+
+ StreamDPOpIpv4Fix ipv_fix;
+ ipv_fix.m_offset = lpFix->m_pkt_offset;
+ ipv_fix.m_op = StreamDPVmInstructions::ditFIX_IPV4_CS;
+ m_instructions.add_command(&ipv_fix,sizeof(ipv_fix));
+ }
+
+
+ /* flow man */
+ if (ins_type == StreamVmInstruction::itFLOW_MAN) {
+ StreamVmInstructionFlowMan *lpMan =(StreamVmInstructionFlowMan *)inst;
+
+
+ if (lpMan->m_size_bytes == 1 ){
+
+ uint8_t op;
+
+ 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));
+ }
+
+ if (lpMan->m_size_bytes == 2 ){
+ uint8_t op;
+
+ if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_INC ){
+ op = StreamDPVmInstructions::ditINC16 ;
+ }
+
+ if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ){
+ op = StreamDPVmInstructions::ditDEC16 ;
+ }
+
+ if ( lpMan->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM ){
+ op = StreamDPVmInstructions::ditRANDOM16 ;
+ }
+
+ StreamDPOpFlowVar16 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));
+ }
+
+ if (lpMan->m_size_bytes == 4 ){
+ uint8_t op;
+
+ 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));
+ }
+
+ if (lpMan->m_size_bytes == 8 ){
+ uint8_t op;
+
+ 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 ;
+ }
+
+ StreamDPOpFlowVar32 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));
+ }
+ }
+
+ if (ins_type == StreamVmInstruction::itPKT_WR) {
+ StreamVmInstructionWriteToPkt *lpPkt =(StreamVmInstructionWriteToPkt *)inst;
+
+ VmFlowVarRec var;
+ if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){
+
+ std::stringstream ss;
+ ss << "instruction id '" << ins_id << "' packet write with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ;
+ err(ss.str());
+ }
+
+ if (lpPkt->m_pkt_offset + var.m_instruction->m_size_bytes > m_pkt_size ) {
+ std::stringstream ss;
+ ss << "instruction id '" << ins_id << "' packet write with packet_offset " << lpPkt->m_pkt_offset + var.m_instruction->m_size_bytes << " bigger than packet size "<< m_pkt_size;
+ err(ss.str());
+ }
+ add_field_cnt(lpPkt->m_pkt_offset + var.m_instruction->m_size_bytes);
+
+
+ uint8_t op_size=var.m_instruction->m_size_bytes;
+ 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_offset =flow_offset;
+ pw8.m_pkt_offset = lpPkt->m_pkt_offset;
+ pw8.m_val_offset = (int8_t)lpPkt->m_add_value;
+ m_instructions.add_command(&pw8,sizeof(pw8));
+ }
+
+ if (op_size == 2) {
+ StreamDPOpPktWr16 pw16;
+ pw16.m_op = StreamDPVmInstructions::itPKT_WR16;
+ pw16.m_flags =0;
+ pw16.m_offset =flow_offset;
+ pw16.m_pkt_offset = lpPkt->m_pkt_offset;
+ pw16.m_val_offset = (int16_t)lpPkt->m_add_value;
+ m_instructions.add_command(&pw16,sizeof(pw16));
+ }
+
+ if (op_size == 4) {
+ StreamDPOpPktWr32 pw32;
+ pw32.m_op = StreamDPVmInstructions::itPKT_WR32;
+ pw32.m_flags =0;
+ pw32.m_offset =flow_offset;
+ pw32.m_pkt_offset = lpPkt->m_pkt_offset;
+ pw32.m_val_offset = (int32_t)lpPkt->m_add_value;
+ m_instructions.add_command(&pw32,sizeof(pw32));
+ }
+
+ if (op_size == 8) {
+ StreamDPOpPktWr64 pw64;
+ pw64.m_op = StreamDPVmInstructions::itPKT_WR64;
+ pw64.m_flags =0;
+ pw64.m_offset =flow_offset;
+ pw64.m_pkt_offset = lpPkt->m_pkt_offset;
+ pw64.m_val_offset = (int64_t)lpPkt->m_add_value;
+ m_instructions.add_command(&pw64,sizeof(pw64));
+ }
+
+ }
+
+ ins_id++;
+ }
}
@@ -265,14 +486,16 @@ void StreamVm::compile_next() {
build_program();
-
+ if ( get_max_packet_update_offset() >svMAX_PACKET_OFFSET_CHANGE ){
+ std::stringstream ss;
+ ss << "maximum offset is" << get_max_packet_update_offset() << " bigger than maximum " <<svMAX_PACKET_OFFSET_CHANGE;
+ err(ss.str());
+ }
}
bool StreamVm::compile() {
- //m_flow_var_offset
-
return (false);
}
@@ -285,12 +508,28 @@ StreamVm::~StreamVm() {
void StreamVm::Dump(FILE *fd){
+ fprintf(fd," instructions \n");
uint32_t cnt=0;
for (auto inst : m_inst_list) {
fprintf(fd," [%04lu] : ",(ulong)cnt);
inst->Dump(fd);
cnt++;
}
+
+ if ( get_bss_size() ) {
+ fprintf(fd," BSS \n");
+ utl_DumpBuffer(fd,get_bss_ptr(),get_bss_size(),0);
+ }
+
+ if ( m_instructions.get_program_size() > 0 ){
+ fprintf(fd," RAW instructions \n");
+ m_instructions.Dump(fd);
+ }
+}
+
+
+void StreamDPVmInstructions::clear(){
+ m_inst_list.clear();
}
@@ -314,46 +553,159 @@ uint32_t StreamDPVmInstructions::get_program_size(){
void StreamDPVmInstructions::Dump(FILE *fd){
- //uint8_t * p=get_program();
-
-
+ uint8_t * p=get_program();
+
+
+ uint32_t program_size = get_program_size();
+ uint8_t * p_end=p+program_size;
+
+ StreamDPOpFlowVar8 *lpv8;
+ StreamDPOpFlowVar16 *lpv16;
+ StreamDPOpFlowVar32 *lpv32;
+ StreamDPOpFlowVar64 *lpv64;
+ StreamDPOpIpv4Fix *lpIpv4Fix;
+ StreamDPOpPktWr8 *lpw8;
+ StreamDPOpPktWr16 *lpw16;
+ StreamDPOpPktWr32 *lpw32;
+ StreamDPOpPktWr64 *lpw64;
+
+ while ( p < p_end) {
+ 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);
+ break;
+ case ditRANDOM16 :
+ lpv16 =(StreamDPOpFlowVar16 *)p;
+ lpv16->dump(fd,"RAND16");
+ p+=sizeof(StreamDPOpFlowVar16);
+ break;
+ case ditRANDOM32 :
+ lpv32 =(StreamDPOpFlowVar32 *)p;
+ lpv32->dump(fd,"RAND32");
+ p+=sizeof(StreamDPOpFlowVar32);
+ break;
+ case ditRANDOM64 :
+ lpv64 =(StreamDPOpFlowVar64 *)p;
+ lpv64->dump(fd,"RAND64");
+ p+=sizeof(StreamDPOpFlowVar64);
+ break;
+
+ case ditFIX_IPV4_CS :
+ lpIpv4Fix =(StreamDPOpIpv4Fix *)p;
+ lpIpv4Fix->dump(fd,"Ipv4Fix");
+ p+=sizeof(StreamDPOpIpv4Fix);
+ break;
+
+ case itPKT_WR8 :
+ lpw8 =(StreamDPOpPktWr8 *)p;
+ lpw8->dump(fd,"Wr8");
+ p+=sizeof(StreamDPOpPktWr8);
+ break;
+
+ case itPKT_WR16 :
+ lpw16 =(StreamDPOpPktWr16 *)p;
+ lpw16->dump(fd,"Wr16");
+ p+=sizeof(StreamDPOpPktWr16);
+ break;
+
+ case itPKT_WR32 :
+ lpw32 =(StreamDPOpPktWr32 *)p;
+ lpw32->dump(fd,"Wr32");
+ p+=sizeof(StreamDPOpPktWr32);
+ break;
+
+ case itPKT_WR64 :
+ lpw64 =(StreamDPOpPktWr64 *)p;
+ lpw64->dump(fd,"Wr64");
+ p+=sizeof(StreamDPOpPktWr64);
+ break;
+ default:
+ assert(0);
+ }
+ };
}
-void StreamDPOpFlowVar8::dump(FILE *fd){
+void StreamDPOpFlowVar8::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val);
}
-void StreamDPOpFlowVar16::dump(FILE *fd){
+void StreamDPOpFlowVar16::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val);
}
-void StreamDPOpFlowVar32::dump(FILE *fd){
+void StreamDPOpFlowVar32::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val);
}
-void StreamDPOpFlowVar64::dump(FILE *fd){
+void StreamDPOpFlowVar64::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flow_offset,(ulong)m_min_val,(ulong)m_max_val);
}
-void StreamDPOpPktWr8::dump(FILE *fd){
+void StreamDPOpPktWr8::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flags,(ulong)m_pkt_offset,(ulong)m_offset);
}
-void StreamDPOpPktWr16::dump(FILE *fd){
+void StreamDPOpPktWr16::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flags,(ulong)m_pkt_offset,(ulong)m_offset);
}
-void StreamDPOpPktWr32::dump(FILE *fd){
+void StreamDPOpPktWr32::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flags,(ulong)m_pkt_offset,(ulong)m_offset);
}
-void StreamDPOpPktWr64::dump(FILE *fd){
+void StreamDPOpPktWr64::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu, %lu , %lu \n", (ulong)m_op,(ulong)m_flags,(ulong)m_pkt_offset,(ulong)m_offset);
}
-void StreamDPOpIpv4Fix::dump(FILE *fd){
+void StreamDPOpIpv4Fix::dump(FILE *fd,std::string opt){
fprintf(fd," %lu, %lu \n", (ulong)m_op,(ulong)m_offset);
}
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h
index ed0e2087..795f5aa1 100644
--- a/src/stateless/cp/trex_stream_vm.h
+++ b/src/stateless/cp/trex_stream_vm.h
@@ -39,7 +39,7 @@ struct StreamDPOpFlowVar8 {
uint8_t m_min_val;
uint8_t m_max_val;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed)) ;
@@ -49,7 +49,7 @@ struct StreamDPOpFlowVar16 {
uint16_t m_min_val;
uint16_t m_max_val;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed)) ;
@@ -59,7 +59,7 @@ struct StreamDPOpFlowVar32 {
uint32_t m_min_val;
uint32_t m_max_val;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed)) ;
@@ -69,49 +69,50 @@ struct StreamDPOpFlowVar64 {
uint64_t m_min_val;
uint64_t m_max_val;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed)) ;
-struct StreamDPOpPktWr8 {
+struct StreamDPOpPktWrBase {
uint8_t m_op;
uint8_t m_flags;
- uint8_t m_offset;
+ uint8_t m_offset;
+} __attribute__((packed)) ;
+
+
+struct StreamDPOpPktWr8 : public StreamDPOpPktWrBase {
+ int8_t m_val_offset;
uint16_t m_pkt_offset;
+
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed)) ;
-struct StreamDPOpPktWr16 {
- uint8_t m_op;
- uint8_t m_flags;
+struct StreamDPOpPktWr16 : public StreamDPOpPktWrBase {
uint16_t m_pkt_offset;
- uint16_t m_offset;
+ int16_t m_val_offset;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed));
-struct StreamDPOpPktWr32 {
- uint8_t m_op;
- uint8_t m_flags;
+struct StreamDPOpPktWr32 : public StreamDPOpPktWrBase {
uint16_t m_pkt_offset;
- uint32_t m_offset;
+ int32_t m_val_offset;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed));
-struct StreamDPOpPktWr64 {
- uint8_t m_op;
- uint8_t m_flags;
+struct StreamDPOpPktWr64 : public StreamDPOpPktWrBase {
uint16_t m_pkt_offset;
- uint32_t m_offset;
+ int64_t m_val_offset;
+
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed));
@@ -119,7 +120,7 @@ struct StreamDPOpIpv4Fix {
uint8_t m_op;
uint32_t m_offset;
public:
- void dump(FILE *fd);
+ void dump(FILE *fd,std::string opt);
} __attribute__((packed));
@@ -153,6 +154,7 @@ public:
public:
+ void clear();
void add_command(void *buffer,uint16_t size);
uint8_t * get_program();
uint32_t get_program_size();
@@ -211,7 +213,7 @@ public:
virtual void Dump(FILE *fd);
public:
- uint16_t m_pkt_offset;
+ uint16_t m_pkt_offset; /* the offset of IPv4 header from the start of the packet */
};
/**
@@ -335,7 +337,8 @@ public:
class StreamVm {
public:
enum STREAM_VM {
- svMAX_FLOW_VAR = 64 /* maximum flow varible */
+ svMAX_FLOW_VAR = 64, /* maximum flow varible */
+ svMAX_PACKET_OFFSET_CHANGE = 512
};
@@ -370,6 +373,23 @@ public:
*/
const std::vector<StreamVmInstruction *> & get_instruction_list();
+ const StreamDPVmInstructions & get_dp_instruction_buffer();
+
+ uint16_t get_bss_size(){
+ return (m_cur_var_offset );
+ }
+
+ uint8_t * get_bss_ptr(){
+ return (m_bss );
+ }
+
+
+ uint16_t get_max_packet_update_offset(){
+ return ( m_max_field_update );
+ }
+
+
+
/**
* compile the VM
* return true of success, o.w false
@@ -396,6 +416,8 @@ private:
void var_clear_table();
bool var_add(const std::string &var_name,VmFlowVarRec & var);
+
+ uint16_t get_var_offset(const std::string &var_name);
void build_flow_var_table() ;
@@ -407,13 +429,22 @@ private:
void free_bss();
+private:
+
+ void clean_max_field_cnt();
+
+ void add_field_cnt(uint16_t new_cnt);
private:
uint16_t m_pkt_size;
uint16_t m_cur_var_offset;
+ uint16_t m_max_field_update; /* the location of the last byte that is going to be changed in the packet */
+
std::vector<StreamVmInstruction *> m_inst_list;
std::unordered_map<std::string, VmFlowVarRec> m_flow_var_offset;
uint8_t * m_bss;
+
+ StreamDPVmInstructions m_instructions;
};