diff options
author | Hanoh Haim <hhaim@cisco.com> | 2016-01-05 20:51:47 +0200 |
---|---|---|
committer | Hanoh Haim <hhaim@cisco.com> | 2016-01-05 20:51:47 +0200 |
commit | 5f07d1062309eea31e47a6d9ab23bb1c94de5c83 (patch) | |
tree | 667326ce482b79d9626badb80d8562a9ecf7551b /src/stateless | |
parent | c905d6b0845e79dbc5d5d37eee560d1dbc58b6ff (diff) | |
parent | d6be4b0e8a2cd92b5e6c455532431897f76331fe (diff) |
Merge branch 'random_pkt'
Diffstat (limited to 'src/stateless')
-rw-r--r-- | src/stateless/cp/trex_stream.h | 6 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.cpp | 94 | ||||
-rw-r--r-- | src/stateless/cp/trex_stream_vm.h | 100 | ||||
-rw-r--r-- | src/stateless/dp/trex_stateless_dp_core.cpp | 34 | ||||
-rw-r--r-- | src/stateless/dp/trex_stream_node.h | 12 |
5 files changed, 233 insertions, 13 deletions
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index b4f19111..a164f266 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -32,6 +32,8 @@ limitations under the License. #include <trex_stream_vm.h> #include <stdio.h> #include <string.h> +#include <common/captureFile.h> + class TrexRpcCmdAddStream; @@ -123,8 +125,8 @@ public: virtual ~TrexStream(); /* defines the min max per packet supported */ - static const uint32_t MIN_PKT_SIZE_BYTES = 1; - static const uint32_t MAX_PKT_SIZE_BYTES = 9000; + static const uint32_t MIN_PKT_SIZE_BYTES = 60; + static const uint32_t MAX_PKT_SIZE_BYTES = MAX_PKT_SIZE; /* provides storage for the stream json*/ void store_stream_json(const Json::Value &stream_json); diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index a3f585ad..b992d1ab 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -107,11 +107,14 @@ void StreamVmInstructionFlowMan::Dump(FILE *fd){ void StreamVmInstructionWriteToPkt::Dump(FILE *fd){ - fprintf(fd," write_pkt , %s ,%lu, add, %ld, big, %lu \n",m_flow_var_name.c_str(),(ulong)m_pkt_offset,(long)m_add_value,(ulong)(m_is_big_endian?1:0)); } +void StreamVmInstructionChangePktSize::Dump(FILE *fd){ + fprintf(fd," pkt_size_change , %s \n",m_flow_var_name.c_str() ); +} + void StreamVmInstructionFlowClient::Dump(FILE *fd){ @@ -192,6 +195,7 @@ void StreamVm::build_flow_var_table() { m_cur_var_offset=0; uint32_t ins_id=0; m_is_random_var=false; + m_is_change_pkt_size=false; /* scan all flow var instruction and build */ for (auto inst : m_inst_list) { @@ -201,6 +205,10 @@ void StreamVm::build_flow_var_table() { m_is_random_var =true; } } + + if ( inst->get_instruction_type() == StreamVmInstruction::itPKT_SIZE_CHANGE ){ + m_is_change_pkt_size=true; + } } /* if we found allocate BSS +4 bytes */ @@ -296,6 +304,51 @@ void StreamVm::build_flow_var_table() { ins_id++; } + + ins_id=0; + + /* second interation for sanity check and fixups*/ + for (auto inst : m_inst_list) { + + + if (inst->get_instruction_type() == StreamVmInstruction::itPKT_SIZE_CHANGE ) { + StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst; + + VmFlowVarRec var; + if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){ + + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ; + err(ss.str()); + } + + if ( var.m_size_bytes != 2 ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2 "; + err(ss.str()); + } + + if ( var.m_ins.m_ins_flowv->m_max_value > m_pkt_size) { + var.m_ins.m_ins_flowv->m_max_value =m_pkt_size; + } + + if (var.m_ins.m_ins_flowv->m_min_value > m_pkt_size) { + var.m_ins.m_ins_flowv->m_min_value = m_pkt_size; + } + + + if ( var.m_ins.m_ins_flowv->m_min_value >= var.m_ins.m_ins_flowv->m_max_value ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' min packet size " << var.m_ins.m_ins_flowv->m_min_value << " is bigger or eq to max packet size " << var.m_ins.m_ins_flowv->m_max_value; + err(ss.str()); + } + + if ( var.m_ins.m_ins_flowv->m_min_value < 60) { + var.m_ins.m_ins_flowv->m_min_value =60; + } + } + }/* for */ + } void StreamVm::alloc_bss(){ @@ -474,6 +527,8 @@ void StreamVm::build_program(){ ss << "instruction id '" << ins_id << "' packet write with packet_offset " << lpPkt->m_pkt_offset + var.m_size_bytes << " bigger than packet size "<< m_pkt_size; err(ss.str()); } + + add_field_cnt(lpPkt->m_pkt_offset + var.m_size_bytes); @@ -555,6 +610,32 @@ void StreamVm::build_program(){ } } + + if (ins_type == StreamVmInstruction::itPKT_SIZE_CHANGE ) { + StreamVmInstructionChangePktSize *lpPkt =(StreamVmInstructionChangePktSize *)inst; + + VmFlowVarRec var; + if ( var_lookup(lpPkt->m_flow_var_name ,var) == false){ + + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size with no valid flow varible name '" << lpPkt->m_flow_var_name << "'" ; + err(ss.str()); + } + + if ( var.m_size_bytes != 2 ) { + std::stringstream ss; + ss << "instruction id '" << ins_id << "' packet size change should point to a flow varible with size 2 "; + err(ss.str()); + } + + uint8_t flow_offset = get_var_offset(lpPkt->m_flow_var_name); + + StreamDPOpPktSizeChange pkt_size_ch; + pkt_size_ch.m_op =StreamDPVmInstructions::itPKT_SIZE_CHANGE; + pkt_size_ch.m_flow_offset = flow_offset; + m_instructions.add_command(&pkt_size_ch,sizeof(pkt_size_ch)); + } + ins_id++; } } @@ -790,6 +871,8 @@ void StreamDPVmInstructions::Dump(FILE *fd){ StreamDPOpPktWr64 *lpw64; StreamDPOpClientsLimit *lp_client; StreamDPOpClientsUnLimit *lp_client_unlimited; + StreamDPOpPktSizeChange *lp_pkt_size_change; + while ( p < p_end) { @@ -901,6 +984,12 @@ void StreamDPVmInstructions::Dump(FILE *fd){ p+=sizeof(StreamDPOpClientsUnLimit); break; + case itPKT_SIZE_CHANGE : + lp_pkt_size_change =(StreamDPOpPktSizeChange *)p; + lp_pkt_size_change->dump(fd,"pkt_size_c"); + p+=sizeof(StreamDPOpPktSizeChange); + break; + default: assert(0); @@ -955,4 +1044,7 @@ void StreamDPOpClientsUnLimit::dump(FILE *fd,std::string opt){ fprintf(fd," %10s op:%lu, flow_offset: %lu (%x-%x) flags:%x \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset,m_min_ip,m_max_ip,m_flags); } +void StreamDPOpPktSizeChange::dump(FILE *fd,std::string opt){ + fprintf(fd," %10s op:%lu, flow_offset: %lu \n", opt.c_str(),(ulong)m_op,(ulong)m_flow_offset); +} diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 891e5b51..edc4f730 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -396,6 +396,21 @@ public: } __attribute__((packed)); +struct StreamDPOpPktSizeChange { + uint8_t m_op; + uint8_t m_flow_offset; /* offset to the flow var */ + + inline void run(uint8_t * flow_var_base,uint16_t & new_size) { + uint16_t * p_flow_var = (uint16_t*)(flow_var_base+m_flow_offset); + new_size = (*p_flow_var); + } + + void dump(FILE *fd,std::string opt); + + +} __attribute__((packed)); ; + + /* datapath instructions */ class StreamDPVmInstructions { public: @@ -422,7 +437,9 @@ public: itPKT_WR32 , itPKT_WR64 , itCLIENT_VAR , - itCLIENT_VAR_UNLIMIT + itCLIENT_VAR_UNLIMIT , + itPKT_SIZE_CHANGE , + }; @@ -443,12 +460,20 @@ private: class StreamDPVmInstructionsRunner { public: + StreamDPVmInstructionsRunner(){ + m_new_pkt_size=0;; + } inline void run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ uint8_t * pkt); /* pkt */ + inline uint16_t get_new_pkt_size(){ + return (m_new_pkt_size); + } +private: + uint16_t m_new_pkt_size; }; @@ -456,7 +481,8 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, uint32_t program_size, uint8_t * program, /* program */ uint8_t * flow_var, /* flow var */ - uint8_t * pkt){ + uint8_t * pkt + ){ uint8_t * p=program; @@ -473,6 +499,8 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, StreamDPOpPktWr16 *lpw16; StreamDPOpPktWr32 *lpw32; StreamDPOpPktWr64 *lpw64; + StreamDPOpPktSizeChange *lpw_pkt_size; + StreamDPOpClientsLimit *lpcl; StreamDPOpClientsUnLimit *lpclu; } ua ; @@ -586,6 +614,13 @@ inline void StreamDPVmInstructionsRunner::run(uint32_t * per_thread_random, ua.lpw64->wr(flow_var,pkt); p+=sizeof(StreamDPOpPktWr64); break; + + case StreamDPVmInstructions::itPKT_SIZE_CHANGE : + ua.lpw_pkt_size =(StreamDPOpPktSizeChange *)p; + ua.lpw_pkt_size->run(flow_var,m_new_pkt_size); + p+=sizeof(StreamDPOpPktSizeChange); + break; + default: assert(0); } @@ -607,7 +642,8 @@ public: itFIX_IPV4_CS = 4, itFLOW_MAN = 5, itPKT_WR = 6, - itFLOW_CLIENT = 7 + itFLOW_CLIENT = 7 , + itPKT_SIZE_CHANGE = 8 }; @@ -880,7 +916,7 @@ public: /** - * write flow var to packet + * write flow var to packet, hhaim * */ class StreamVmInstructionWriteToPkt : public StreamVmInstruction { @@ -925,6 +961,36 @@ public: }; + +/** + * change packet size, + * + */ +class StreamVmInstructionChangePktSize : public StreamVmInstruction { +public: + + StreamVmInstructionChangePktSize(const std::string &flow_var_name) : + + m_flow_var_name(flow_var_name) + {} + + virtual instruction_type_t get_instruction_type() const { + return ( StreamVmInstruction::itPKT_SIZE_CHANGE ); + } + + virtual void Dump(FILE *fd); + + virtual StreamVmInstruction * clone() { + return new StreamVmInstructionChangePktSize(m_flow_var_name); + } + +public: + + /* flow var name to write */ + std::string m_flow_var_name; +}; + + /** * describes a VM program for DP * @@ -939,6 +1005,7 @@ public: m_program_size=0; m_max_pkt_offset_change=0; m_prefix_size = 0; + m_is_pkt_size_var=false; } StreamVmDp( uint8_t * bss, @@ -946,7 +1013,8 @@ public: uint8_t * prog, uint16_t prog_size, uint16_t max_pkt_offset, - uint16_t prefix_size + uint16_t prefix_size, + bool a_is_pkt_size_var ){ if (bss) { @@ -972,6 +1040,7 @@ public: m_max_pkt_offset_change = max_pkt_offset; m_prefix_size = prefix_size; + m_is_pkt_size_var=a_is_pkt_size_var; } ~StreamVmDp(){ @@ -993,7 +1062,8 @@ public: m_program_ptr, m_program_size, m_max_pkt_offset_change, - m_prefix_size + m_prefix_size, + m_is_pkt_size_var ); assert(lp); return (lp); @@ -1035,6 +1105,14 @@ public: m_prefix_size = prefix_size; } + void set_pkt_size_is_var(bool pkt_size_var){ + m_is_pkt_size_var=pkt_size_var; + } + bool is_pkt_size_var(){ + return (m_is_pkt_size_var); + } + + private: uint8_t * m_bss_ptr; /* pointer to the data section */ uint8_t * m_program_ptr; /* pointer to the program */ @@ -1042,6 +1120,7 @@ private: uint16_t m_program_size; /* program size*/ uint16_t m_max_pkt_offset_change; uint16_t m_prefix_size; + bool m_is_pkt_size_var; }; @@ -1093,7 +1172,8 @@ public: get_dp_instruction_buffer()->get_program(), get_dp_instruction_buffer()->get_program_size(), get_max_packet_update_offset(), - get_prefix_size() + get_prefix_size(), + is_var_pkt_size() ); assert(lp); return (lp); @@ -1142,6 +1222,11 @@ public: return m_prefix_size; } + bool is_var_pkt_size(){ + return (m_is_change_pkt_size); + } + + bool is_compiled() { return m_is_compiled; } @@ -1197,6 +1282,7 @@ private: private: bool m_is_random_var; + bool m_is_change_pkt_size; bool m_is_compiled; uint16_t m_prefix_size; uint16_t m_pkt_size; diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp index 0a9a88ab..a80efc08 100644 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ b/src/stateless/dp/trex_stateless_dp_core.cpp @@ -149,10 +149,34 @@ rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){ m_vm_flow_var, (uint8_t*)p); + uint16_t pkt_new_size=runner.get_new_pkt_size(); + if ( likely( pkt_new_size == 0) ) { + /* no packet size change */ + rte_mbuf_t * m_const = get_const_mbuf(); + if ( m_const != NULL) { + utl_rte_pktmbuf_add_after(m,m_const); + } + return (m); + } + /* packet size change there are a few changes */ rte_mbuf_t * m_const = get_const_mbuf(); - if ( m_const != NULL) { - utl_rte_pktmbuf_add_after(m,m_const); + if ( (m_const == 0 ) || (pkt_new_size<=prefix_size) ) { + /* one mbuf , just trim it */ + m->data_len = pkt_new_size; + m->pkt_len = pkt_new_size; + return (m); + } + + rte_mbuf_t * mi= CGlobalInfo::pktmbuf_alloc_small(get_socket_id()); + assert(mi); + rte_pktmbuf_attach(mi,m_const); + utl_rte_pktmbuf_add_after2(m,mi); + + if ( pkt_new_size < m->pkt_len) { + /* need to trim it */ + mi->data_len = (pkt_new_size - prefix_size); + m->pkt_len = pkt_new_size; } return (m); } @@ -617,6 +641,12 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port, } + if ( lpDpVm->is_pkt_size_var() ) { + // mark the node as varible size + node->set_var_pkt_size(); + } + + if (lpDpVm->get_prefix_size() > pkt_size ) { lpDpVm->set_prefix_size(pkt_size); } diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h index 70a66e6a..dfa4cc13 100644 --- a/src/stateless/dp/trex_stream_node.h +++ b/src/stateless/dp/trex_stream_node.h @@ -60,7 +60,9 @@ public: SL_NODE_FLAGS_DIR =1, //USED by master SL_NODE_FLAGS_MBUF_CACHE =2, //USED by master - SL_NODE_CONST_MBUF =4 + SL_NODE_CONST_MBUF =4, + + SL_NODE_VAR_PKT_SIZE =8 }; @@ -282,6 +284,14 @@ public: } } + inline void set_var_pkt_size(){ + m_flags |= SL_NODE_VAR_PKT_SIZE; + } + + inline bool is_var_pkt_size(){ + return ( ( m_flags &SL_NODE_VAR_PKT_SIZE )?true:false); + } + inline void set_const_mbuf(rte_mbuf_t * m){ m_cache_mbuf=(void *)m; m_flags |= SL_NODE_CONST_MBUF; |