diff options
Diffstat (limited to 'src/stateless/cp/trex_stream_vm.h')
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 854 |
1 files changed, 850 insertions, 4 deletions
diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 56edbcaf..e65a87e3 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -24,6 +24,526 @@ limitations under the License. #include <string> #include <stdint.h> #include <vector> +#include <unordered_map> +#include <assert.h> +#include <common/Network/Packet/IPHeader.h> +#include "pal_utl.h" +#include "mbuf.h" + + + + +class StreamVm; + + +/* in memory program */ + +struct StreamDPOpFlowVar8 { + uint8_t m_op; + uint8_t m_flow_offset; + uint8_t m_min_val; + uint8_t m_max_val; +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=*p+1; + if (*p>m_max_val) { + *p=m_min_val; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint8_t * p=(flow_var+m_flow_offset); + *p=*p-1; + if (*p<m_min_val) { + *p=m_max_val; + } + } + + inline void run_rand(uint8_t * flow_var) { + uint8_t * p=(flow_var+m_flow_offset); + *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + } + + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar16 { + uint8_t m_op; + uint8_t m_flow_offset; + uint16_t m_min_val; + uint16_t m_max_val; +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=*p+1; + if (*p>m_max_val) { + *p=m_min_val; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint16_t * p=(uint16_t *)(flow_var+m_flow_offset); + *p=*p-1; + if (*p<m_min_val) { + *p=m_max_val; + } + } + + inline void run_rand(uint8_t * flow_var) { + uint16_t * p=(uint16_t *)(flow_var+m_flow_offset); + *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + } + + + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar32 { + uint8_t m_op; + uint8_t m_flow_offset; + uint32_t m_min_val; + uint32_t m_max_val; +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=*p+1; + if (*p>m_max_val) { + *p=m_min_val; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint32_t * p=(uint32_t *)(flow_var+m_flow_offset); + *p=*p-1; + if (*p<m_min_val) { + *p=m_max_val; + } + } + + inline void run_rand(uint8_t * flow_var) { + uint32_t * p=(uint32_t *)(flow_var+m_flow_offset); + *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + } + +} __attribute__((packed)) ; + +struct StreamDPOpFlowVar64 { + uint8_t m_op; + uint8_t m_flow_offset; + uint64_t m_min_val; + uint64_t m_max_val; +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=*p+1; + if (*p>m_max_val) { + *p=m_min_val; + } + } + + inline void run_dec(uint8_t * flow_var) { + uint64_t * p=(uint64_t *)(flow_var+m_flow_offset); + *p=*p-1; + if (*p<m_min_val) { + *p=m_max_val; + } + } + + inline void run_rand(uint8_t * flow_var) { + uint64_t * p=(uint64_t *)(flow_var+m_flow_offset); + *p= m_min_val + (rand() % (int)(m_max_val - m_min_val + 1)); + } + + +} __attribute__((packed)) ; + + +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)) ; + + +struct StreamDPOpPktWr8 : public StreamDPOpPktWrBase { + int8_t m_val_offset; + uint16_t m_pkt_offset; + +public: + void dump(FILE *fd,std::string opt); + + inline void wr(uint8_t * flow_var_base,uint8_t * pkt_base) { + 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); + + } + + +} __attribute__((packed)) ; + + +struct StreamDPOpPktWr16 : public StreamDPOpPktWrBase { + uint16_t m_pkt_offset; + int16_t m_val_offset; +public: + void dump(FILE *fd,std::string opt); + + 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); + + 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 { + uint16_t m_pkt_offset; + int32_t m_val_offset; +public: + void dump(FILE *fd,std::string opt); + + 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); + 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 { + uint16_t m_pkt_offset; + int64_t m_val_offset; + +public: + void dump(FILE *fd,std::string opt); + + 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); + if ( likely(is_big())){ + *p_pkt=pal_ntohl64((*p_flow_var+m_val_offset)); + }else{ + *p_pkt=(*p_flow_var+m_val_offset); + } + } + + +} __attribute__((packed)); + +struct StreamDPOpIpv4Fix { + uint8_t m_op; + uint16_t m_offset; +public: + void dump(FILE *fd,std::string opt); + void run(uint8_t * pkt_base){ + IPHeader * ipv4= (IPHeader *)(pkt_base+m_offset); + ipv4->updateCheckSum(); + } + +} __attribute__((packed)); + + +/* flow varible of Client command */ +struct StreamDPFlowClient { + uint32_t cur_ip; + uint16_t cur_port; + uint32_t cur_flow_id; +} __attribute__((packed)); + + +struct StreamDPOpClientsLimit { + uint8_t m_op; + uint8_t m_flow_offset; /* offset into the flow var bytes */ + uint8_t m_flags; + uint8_t m_pad; + uint16_t m_min_port; + uint16_t m_max_port; + + uint32_t m_min_ip; + uint32_t m_max_ip; + uint32_t m_limit_flows; /* limit the number of flows */ + +public: + void dump(FILE *fd,std::string opt); + inline void run(uint8_t * flow_var_base) { + StreamDPFlowClient * lp= (StreamDPFlowClient *)(flow_var_base+m_flow_offset); + lp->cur_ip++; + if (lp->cur_ip > m_max_ip ) { + lp->cur_ip= m_min_ip; + lp->cur_port++; + if (lp->cur_port > m_max_port) { + lp->cur_port = m_min_port; + } + } + + 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; + } + } + } + + +} __attribute__((packed)); + +struct StreamDPOpClientsUnLimit { + enum __MIN_PORT { + CLIENT_UNLIMITED_MIN_PORT = 1025 + }; + + uint8_t m_op; + uint8_t m_flow_offset; /* offset into the flow var bytes */ + uint8_t m_flags; + uint8_t m_pad; + uint32_t m_min_ip; + uint32_t m_max_ip; + +public: + void dump(FILE *fd,std::string opt); + inline void run(uint8_t * flow_var_base) { + StreamDPFlowClient * lp= (StreamDPFlowClient *)(flow_var_base+m_flow_offset); + lp->cur_ip++; + if (lp->cur_ip > m_max_ip ) { + lp->cur_ip= m_min_ip; + lp->cur_port++; + if (lp->cur_port == 0) { + lp->cur_port = StreamDPOpClientsUnLimit::CLIENT_UNLIMITED_MIN_PORT; + } + } + } + +} __attribute__((packed)); + + +/* datapath instructions */ +class StreamDPVmInstructions { +public: + enum INS_TYPE { + ditINC8 , + ditINC16 , + ditINC32 , + ditINC64 , + + ditDEC8 , + ditDEC16 , + ditDEC32 , + ditDEC64 , + + ditRANDOM8 , + ditRANDOM16 , + ditRANDOM32 , + ditRANDOM64 , + + ditFIX_IPV4_CS , + + itPKT_WR8 , + itPKT_WR16 , + itPKT_WR32 , + itPKT_WR64 , + itCLIENT_VAR , + itCLIENT_VAR_UNLIMIT + }; + + +public: + void clear(); + void add_command(void *buffer,uint16_t size); + uint8_t * get_program(); + uint32_t get_program_size(); + + + void Dump(FILE *fd); + + +private: + std::vector<uint8_t> m_inst_list; +}; + + +class StreamDPVmInstructionsRunner { +public: + inline void run(uint32_t program_size, + uint8_t * program, /* program */ + uint8_t * flow_var, /* flow var */ + uint8_t * pkt); /* pkt */ + +}; + + +inline void StreamDPVmInstructionsRunner::run(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_ { + StreamDPOpFlowVar8 *lpv8; + StreamDPOpFlowVar16 *lpv16; + StreamDPOpFlowVar32 *lpv32; + StreamDPOpFlowVar64 *lpv64; + StreamDPOpIpv4Fix *lpIpv4Fix; + StreamDPOpPktWr8 *lpw8; + StreamDPOpPktWr16 *lpw16; + StreamDPOpPktWr32 *lpw32; + StreamDPOpPktWr64 *lpw64; + StreamDPOpClientsLimit *lpcl; + StreamDPOpClientsUnLimit *lpclu; + } ua ; + + while ( p < p_end) { + uint8_t op_code=*p; + switch (op_code) { + + case StreamDPVmInstructions::itCLIENT_VAR : + ua.lpcl =(StreamDPOpClientsLimit *)p; + ua.lpcl->run(flow_var); + p+=sizeof(StreamDPOpClientsLimit); + break; + + case StreamDPVmInstructions::itCLIENT_VAR_UNLIMIT : + ua.lpclu =(StreamDPOpClientsUnLimit *)p; + ua.lpclu->run(flow_var); + p+=sizeof(StreamDPOpClientsUnLimit); + break; + + case StreamDPVmInstructions::ditINC8 : + ua.lpv8 =(StreamDPOpFlowVar8 *)p; + ua.lpv8->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar8); + break; + + case StreamDPVmInstructions::ditINC16 : + ua.lpv16 =(StreamDPOpFlowVar16 *)p; + ua.lpv16->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar16); + break; + case StreamDPVmInstructions::ditINC32 : + ua.lpv32 =(StreamDPOpFlowVar32 *)p; + ua.lpv32->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar32); + break; + case StreamDPVmInstructions::ditINC64 : + ua.lpv64 =(StreamDPOpFlowVar64 *)p; + ua.lpv64->run_inc(flow_var); + p+=sizeof(StreamDPOpFlowVar64); + break; + + case StreamDPVmInstructions::ditDEC8 : + ua.lpv8 =(StreamDPOpFlowVar8 *)p; + ua.lpv8->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar8); + break; + case StreamDPVmInstructions::ditDEC16 : + ua.lpv16 =(StreamDPOpFlowVar16 *)p; + ua.lpv16->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar16); + break; + case StreamDPVmInstructions::ditDEC32 : + ua.lpv32 =(StreamDPOpFlowVar32 *)p; + ua.lpv32->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar32); + break; + case StreamDPVmInstructions::ditDEC64 : + ua.lpv64 =(StreamDPOpFlowVar64 *)p; + ua.lpv64->run_dec(flow_var); + p+=sizeof(StreamDPOpFlowVar64); + break; + + case StreamDPVmInstructions::ditRANDOM8 : + ua.lpv8 =(StreamDPOpFlowVar8 *)p; + ua.lpv8->run_rand(flow_var); + p+=sizeof(StreamDPOpFlowVar8); + break; + case StreamDPVmInstructions::ditRANDOM16 : + ua.lpv16 =(StreamDPOpFlowVar16 *)p; + ua.lpv16->run_rand(flow_var); + p+=sizeof(StreamDPOpFlowVar16); + break; + case StreamDPVmInstructions::ditRANDOM32 : + ua.lpv32 =(StreamDPOpFlowVar32 *)p; + ua.lpv32->run_rand(flow_var); + p+=sizeof(StreamDPOpFlowVar32); + break; + case StreamDPVmInstructions::ditRANDOM64 : + ua.lpv64 =(StreamDPOpFlowVar64 *)p; + ua.lpv64->run_rand(flow_var); + p+=sizeof(StreamDPOpFlowVar64); + break; + + case StreamDPVmInstructions::ditFIX_IPV4_CS : + ua.lpIpv4Fix =(StreamDPOpIpv4Fix *)p; + ua.lpIpv4Fix->run(pkt); + p+=sizeof(StreamDPOpIpv4Fix); + break; + + case StreamDPVmInstructions::itPKT_WR8 : + ua.lpw8 =(StreamDPOpPktWr8 *)p; + ua.lpw8->wr(flow_var,pkt); + p+=sizeof(StreamDPOpPktWr8); + break; + + case StreamDPVmInstructions::itPKT_WR16 : + ua.lpw16 =(StreamDPOpPktWr16 *)p; + ua.lpw16->wr(flow_var,pkt); + p+=sizeof(StreamDPOpPktWr16); + break; + + case StreamDPVmInstructions::itPKT_WR32 : + ua.lpw32 =(StreamDPOpPktWr32 *)p; + ua.lpw32->wr(flow_var,pkt); + p+=sizeof(StreamDPOpPktWr32); + break; + + case StreamDPVmInstructions::itPKT_WR64 : + ua.lpw64 =(StreamDPOpPktWr64 *)p; + ua.lpw64->wr(flow_var,pkt); + p+=sizeof(StreamDPOpPktWr64); + break; + default: + assert(0); + } + }; +}; + + + /** * interface for stream VM instruction @@ -32,8 +552,24 @@ limitations under the License. class StreamVmInstruction { public: + enum INS_TYPE { + itNONE = 0, + itFIX_IPV4_CS = 4, + itFLOW_MAN = 5, + itPKT_WR = 6, + itFLOW_CLIENT = 7 + + }; + + typedef uint8_t instruction_type_t ; + + virtual instruction_type_t get_instruction_type()=0; + virtual ~StreamVmInstruction(); + virtual void Dump(FILE *fd)=0; + + private: static const std::string m_name; }; @@ -48,8 +584,14 @@ public: } -private: - uint16_t m_pkt_offset; + virtual instruction_type_t get_instruction_type(){ + return ( StreamVmInstruction::itFIX_IPV4_CS); + } + + virtual void Dump(FILE *fd); + +public: + uint16_t m_pkt_offset; /* the offset of IPv4 header from the start of the packet */ }; /** @@ -61,6 +603,10 @@ class StreamVmInstructionFlowMan : public StreamVmInstruction { public: + virtual instruction_type_t get_instruction_type(){ + return ( StreamVmInstruction::itFLOW_MAN); + } + /** * different types of operations on the object */ @@ -85,7 +631,16 @@ public: } + virtual void Dump(FILE *fd); + + void sanity_check(uint32_t ins_id,StreamVm *lp); + private: + void sanity_check_valid_range(uint32_t ins_id,StreamVm *lp); + void sanity_check_valid_size(uint32_t ins_id,StreamVm *lp); + void sanity_check_valid_opt(uint32_t ins_id,StreamVm *lp); + +public: /* flow var name */ @@ -105,6 +660,83 @@ private: }; + +/** + * flow client instruction - save state for client range and port range + * + * @author hhaim + */ +class StreamVmInstructionFlowClient : public StreamVmInstruction { + +public: + enum client_flags_e { + CLIENT_F_UNLIMITED_FLOWS=1, /* unlimited number of flow, don't care about ports */ + }; + + + virtual instruction_type_t get_instruction_type(){ + return ( StreamVmInstruction::itFLOW_CLIENT); + } + + + StreamVmInstructionFlowClient(const std::string &var_name, + uint32_t client_min_value, + uint32_t client_max_value, + uint16_t port_min, + uint16_t port_max, + uint32_t limit_num_flows, /* zero means don't limit */ + uint16_t flags + ) { + m_var_name = var_name; + m_client_min = client_min_value; + m_client_max = client_max_value; + + m_port_min = port_min; + m_port_max = port_max; + + m_limit_num_flows = limit_num_flows; + m_flags = flags; + } + + virtual void Dump(FILE *fd); + + static uint8_t get_flow_var_size(){ + return (4+2+4); + } + + bool is_unlimited_flows(){ + return ( (m_flags & StreamVmInstructionFlowClient::CLIENT_F_UNLIMITED_FLOWS ) == + StreamVmInstructionFlowClient::CLIENT_F_UNLIMITED_FLOWS ); + } +public: + + + /* flow var name */ + std::string m_var_name; + + uint32_t m_client_min; // min ip + uint32_t m_client_max; // max ip + uint16_t m_port_min; // start port + uint16_t m_port_max; // start port + uint32_t m_limit_num_flows; // number of flows + uint16_t m_flags; +}; + + + +class VmFlowVarRec { +public: + uint32_t m_offset; + union { + StreamVmInstructionFlowMan * m_ins_flowv; + StreamVmInstructionFlowClient * m_ins_flow_client; + } m_ins; + uint8_t m_size_bytes; +}; + + + + /** * write flow var to packet * @@ -121,7 +753,14 @@ public: m_pkt_offset(pkt_offset), m_add_value(add_value), m_is_big_endian(is_big_endian) {} -private: + + virtual instruction_type_t get_instruction_type(){ + return ( StreamVmInstruction::itPKT_WR); + } + + virtual void Dump(FILE *fd); + +public: /* flow var name to write */ std::string m_flow_var_name; @@ -136,12 +775,161 @@ private: bool m_is_big_endian; }; + +/** + * describes a VM program for DP + * + */ + +class StreamVmDp { +public: + StreamVmDp(){ + m_bss_ptr=NULL; + m_program_ptr =NULL ; + m_bss_size=0; + m_program_size=0; + m_max_pkt_offset_change=0; + } + + StreamVmDp( uint8_t * bss, + uint16_t bss_size, + uint8_t * prog, + uint16_t prog_size, + uint16_t max_pkt_offset + ){ + + if (bss) { + assert(bss_size); + m_bss_ptr=(uint8_t*)malloc(bss_size); + assert(m_bss_ptr); + memcpy(m_bss_ptr,bss,bss_size); + m_bss_size=bss_size; + }else{ + m_bss_ptr=NULL; + m_bss_size=0; + } + + if (prog) { + assert(prog_size); + m_program_ptr=(uint8_t*)malloc(prog_size); + memcpy(m_program_ptr,prog,prog_size); + m_program_size = prog_size; + }else{ + m_program_ptr = NULL; + m_program_size=0; + } + m_max_pkt_offset_change =max_pkt_offset; + } + + ~StreamVmDp(){ + if (m_bss_ptr) { + free(m_bss_ptr); + m_bss_ptr=0; + m_bss_size=0; + } + if (m_program_ptr) { + free(m_program_ptr); + m_program_size=0; + m_program_ptr=0; + } + } + + StreamVmDp * clone() const { + StreamVmDp * lp= new StreamVmDp(m_bss_ptr, + m_bss_size, + m_program_ptr, + m_program_size, + m_max_pkt_offset_change + ); + assert(lp); + return (lp); + } + + uint8_t* clone_bss(){ + assert(m_bss_size>0); + uint8_t *p=(uint8_t *)malloc(m_bss_size); + assert(p); + memcpy(p,m_bss_ptr,m_bss_size); + return (p); + } + + uint16_t get_bss_size(){ + return(m_bss_size); + } + + uint8_t* get_bss(){ + return (m_bss_ptr); + } + + uint8_t* get_program(){ + return (m_program_ptr); + } + + uint16_t get_program_size(){ + return (m_program_size); + } + + uint16_t get_max_packet_update_offset(){ + return (m_max_pkt_offset_change); + } + +private: + uint8_t * m_bss_ptr; /* pointer to the data section */ + uint8_t * m_program_ptr; /* pointer to the program */ + uint16_t m_bss_size; + uint16_t m_program_size; /* program size*/ + uint16_t m_max_pkt_offset_change; + +}; + + /** * describes a VM program * */ class StreamVm { + public: + enum STREAM_VM { + svMAX_FLOW_VAR = 64, /* maximum flow varible */ + svMAX_PACKET_OFFSET_CHANGE = 512 + }; + + + + StreamVm(){ + m_bss=0; + m_pkt_size=0; + m_cur_var_offset=0; + } + + + /* set packet size */ + void set_packet_size(uint16_t pkt_size){ + m_pkt_size = pkt_size; + } + + uint16_t get_packet_size(){ + return ( m_pkt_size); + } + + + StreamVmDp * cloneAsVmDp(){ + + StreamVmDp * lp= new StreamVmDp(get_bss_ptr(), + get_bss_size(), + get_dp_instruction_buffer()->get_program(), + get_dp_instruction_buffer()->get_program_size(), + get_max_packet_update_offset() + ); + assert(lp); + return (lp); + + } + + bool is_vm_empty() { + return (m_inst_list.size() == 0); + } /** * add new instruction to the VM @@ -155,17 +943,75 @@ public: */ const std::vector<StreamVmInstruction *> & get_instruction_list(); + 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 * */ - bool compile(); + void compile(); ~StreamVm(); + void Dump(FILE *fd); + + /* raise exception */ + void err(const std::string &err); + private: + + /* lookup for varible offset, */ + bool var_lookup(const std::string &var_name,VmFlowVarRec & var); + + 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() ; + + void build_bss(); + + void build_program(); + + void alloc_bss(); + + 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; + }; #endif /* __TREX_STREAM_VM_API_H__ */ |