summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-01-05 20:51:47 +0200
committerHanoh Haim <hhaim@cisco.com>2016-01-05 20:51:47 +0200
commit5f07d1062309eea31e47a6d9ab23bb1c94de5c83 (patch)
tree667326ce482b79d9626badb80d8562a9ecf7551b /src/stateless
parentc905d6b0845e79dbc5d5d37eee560d1dbc58b6ff (diff)
parentd6be4b0e8a2cd92b5e6c455532431897f76331fe (diff)
Merge branch 'random_pkt'
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stream.h6
-rw-r--r--src/stateless/cp/trex_stream_vm.cpp94
-rw-r--r--src/stateless/cp/trex_stream_vm.h100
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp34
-rw-r--r--src/stateless/dp/trex_stream_node.h12
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;