summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-11-30 14:31:39 +0200
committerHanoh Haim <hhaim@cisco.com>2015-11-30 14:31:39 +0200
commit2e51cea370c6c401453d77b23f552811a669d86a (patch)
treeac5b02efa7a18f255f63fca007b35036fa8a56bc
parent7f07d43ec534562ea274839c8996c9e79e747801 (diff)
vm mode works - first test
-rwxr-xr-xsrc/bp_gtest.cpp2
-rwxr-xr-xsrc/bp_sim.cpp19
-rwxr-xr-xsrc/bp_sim.h6
-rw-r--r--src/gtest/trex_stateless_gtest.cpp54
-rwxr-xr-xsrc/main_dpdk.cpp19
-rw-r--r--src/stateless/cp/trex_stream.cpp2
-rw-r--r--src/stateless/cp/trex_stream.h6
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp98
-rw-r--r--src/stateless/dp/trex_stream_node.h54
9 files changed, 229 insertions, 31 deletions
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp
index a94c2d37..f24464e3 100755
--- a/src/bp_gtest.cpp
+++ b/src/bp_gtest.cpp
@@ -2020,7 +2020,7 @@ public:
virtual int send_node(CGenNode * node);
- virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m){
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){
return (0);
}
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index a61fbb8f..ed729c75 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -4657,13 +4657,24 @@ int CErfIFStl::send_node(CGenNode * _no_to_use){
if ( m_preview_mode->getFileWrite() ){
CGenNodeStateless * node_sl=(CGenNodeStateless *) _no_to_use;
-
+
+ pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
+
/* check that we have mbuf */
rte_mbuf_t * m=node_sl->get_cache_mbuf();
- assert( m );
- pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
+ if (m) {
+ /* cache packet */
+ fill_raw_packet(m,_no_to_use,dir);
+ /* can't free the m, it is cached*/
+ }else{
+
+ m=node_sl->alloc_node_with_vm();
+ assert(m);
+ fill_raw_packet(m,_no_to_use,dir);
+ rte_pktmbuf_free(m);
+
+ }
- fill_raw_packet(m,_no_to_use,dir);
BP_ASSERT(m_writer);
bool res=m_writer->write_packet(m_raw);
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 0da7fb99..b71cb3ff 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -380,7 +380,7 @@ public:
*
* @return
*/
- virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m)=0;
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p)=0;
/**
* translate a port_id to the correct dir on the core
@@ -1799,7 +1799,7 @@ public:
virtual int write_pkt(CCapPktRaw *pkt_raw);
virtual int close_file(void);
- virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m){
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){
return (0);
}
@@ -1878,7 +1878,7 @@ public:
return (0);
}
- virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m){
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){
return (0);
}
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index ea54a935..e236a63d 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -1246,6 +1246,60 @@ TEST_F(basic_stl, multi_pkt1) {
+TEST_F(basic_stl, vm_enable0) {
+
+ CBasicStl t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(7);
+ po->preview.setFileWrite(true);
+ po->out_file ="exp/stl_vm_enable0";
+
+ TrexStreamsCompiler compile;
+
+ uint8_t port_id=0;
+
+ std::vector<TrexStream *> streams;
+
+ TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
+ stream1->m_has_vm = true;
+ stream1->m_vm_prefix_size =64;
+ stream1->set_pps(1.0);
+
+
+ stream1->m_enabled = true;
+ stream1->m_self_start = true;
+ stream1->m_port_id= port_id;
+
+
+ CPcapLoader pcap;
+ pcap.load_pcap_file("cap2/udp_64B.pcap",0);
+ pcap.update_ip_src(0x10000001);
+ pcap.clone_packet_into_stream(stream1);
+
+ streams.push_back(stream1);
+
+ // stream - clean
+
+ TrexStreamsCompiledObj comp_obj(port_id, 1.0 /*mul*/);
+
+ assert(compile.compile(streams, comp_obj) );
+
+ TrexStatelessDpStart * lpstart = new TrexStatelessDpStart(port_id, 0, comp_obj.clone(), 10.0 /*sec */ );
+
+
+ t1.m_msg = lpstart;
+
+ bool res=t1.init();
+
+ delete stream1 ;
+
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+
+
+
/* check disabled stream with multiplier of 5*/
TEST_F(basic_stl, multi_pkt2) {
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 3e5418b9..c17f32f3 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -1875,7 +1875,7 @@ public:
bool process_rx_pkt(pkt_dir_t dir,rte_mbuf_t * m);
- virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, rte_mbuf_t *m);
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p);
virtual pkt_dir_t port_id_to_dir(uint8_t port_id);
@@ -2186,12 +2186,18 @@ int CCoreEthIFStateless::send_node(CGenNode * no){
/* check that we have mbuf */
rte_mbuf_t * m=node_sl->get_cache_mbuf();
- assert( m );
pkt_dir_t dir=(pkt_dir_t)node_sl->get_mbuf_cache_dir();
CCorePerPort * lp_port=&m_ports[dir];
CVirtualIFPerSideStats * lp_stats = &m_stats[dir];
- rte_pktmbuf_refcnt_update(m,1);
+ if (m) {
+ /* cache case */
+ rte_pktmbuf_refcnt_update(m,1);
+ }else{
+ m=node_sl->alloc_node_with_vm();
+ assert(m);
+ }
send_pkt(lp_port,m,lp_stats);
+
return (0);
};
@@ -2290,14 +2296,11 @@ int CCoreEthIF::send_node(CGenNode * node){
}
-int CCoreEthIF::update_mac_addr_from_global_cfg(pkt_dir_t dir,
- rte_mbuf_t *m){
- assert(m);
+int CCoreEthIF::update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t * p){
+ assert(p);
assert(dir<2);
CCorePerPort * lp_port=&m_ports[dir];
- uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*);
uint8_t p_id=lp_port->m_port->get_port_id();
-
memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12);
return (0);
}
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index cad603e2..8ea0c011 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -103,6 +103,8 @@ TrexStream::TrexStream(uint8_t type,
m_pkt.binary = NULL;
m_pkt.len = 0;
+ m_has_vm = false;
+ m_vm_prefix_size = 0;
m_rx_check.m_enable = false;
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index 3e48d7e4..c42d0985 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -133,6 +133,9 @@ public:
TrexStream * dp=new TrexStream(m_type,m_port_id,m_stream_id);
+ dp->m_has_vm = m_has_vm;
+ dp->m_vm_prefix_size = m_vm_prefix_size;
+
dp->m_isg_usec = m_isg_usec;
dp->m_next_stream_id = m_next_stream_id;
@@ -165,6 +168,7 @@ public:
/* basic */
uint8_t m_type;
uint8_t m_port_id;
+ uint16_t m_vm_prefix_size;
uint32_t m_stream_id; /* id from RPC can be anything */
@@ -175,6 +179,8 @@ public:
/* indicators */
bool m_enabled;
bool m_self_start;
+ bool m_has_vm; /* do we have instructions to run */
+
CStreamPktData m_pkt;
/* pkt */
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index 9b62fabd..c7bb7636 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -106,13 +106,45 @@ std::string CGenNodeStateless::get_stream_state_str(stream_state_t stream_state)
}
+rte_mbuf_t * CGenNodeStateless::alloc_node_with_vm(){
+
+ rte_mbuf_t * m;
+ /* alloc small packet buffer*/
+ uint16_t prefix_size = prefix_header_size();
+ m = CGlobalInfo::pktmbuf_alloc( get_socket_id(), prefix_size );
+ if (m==0) {
+ return (m);
+ }
+ /* TBD remove this, should handle cases of error */
+ assert(m);
+ char *p=rte_pktmbuf_append(m, prefix_size);
+ memcpy( p ,m_original_packet_data_prefix, prefix_size);
+
+ /* TBD run VM on the pointer p */
+
+ rte_mbuf_t * m_const = get_const_mbuf();
+ if ( m_const != NULL) {
+ utl_rte_pktmbuf_add_after(m,m_const);
+ }
+ return (m);
+}
+
+
void CGenNodeStateless::free_stl_node(){
/* if we have cache mbuf free it */
rte_mbuf_t * m=get_cache_mbuf();
if (m) {
rte_pktmbuf_free(m);
m_cache_mbuf=0;
+ }else{
+ /* non cache - must have an header */
+ m=get_const_mbuf();
+ if (m) {
+ rte_pktmbuf_free(m); /* reduce the ref counter */
+ }
+ free_prefix_header();
}
+
}
@@ -442,6 +474,10 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port,
pkt_dir_t dir = m_core->m_node_gen.m_v_if->port_id_to_dir(stream->m_port_id);
node->m_flags = 0;
+ node->m_src_port =0;
+ node->m_original_packet_data_prefix = 0;
+
+
/* set socket id */
node->set_socket_id(m_core->m_node_gen.m_socket_id);
@@ -486,23 +522,59 @@ TrexStatelessDpCore::add_stream(TrexStatelessDpPerPort * lp_port,
node->m_port_id = stream->m_port_id;
- /* allocate const mbuf */
- rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size);
- assert(m);
-
- char *p = rte_pktmbuf_append(m, pkt_size);
- assert(p);
- /* copy the packet */
- memcpy(p,stream_pkt,pkt_size);
-
/* set dir 0 or 1 client or server */
node->set_mbuf_cache_dir(dir);
- /* TBD repace the mac if req we should add flag */
- m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, m);
- /* set the packet as a readonly */
- node->set_cache_mbuf(m);
+ if (stream->m_has_vm == false ) {
+ /* allocate const mbuf */
+ rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size);
+ assert(m);
+
+ char *p = rte_pktmbuf_append(m, pkt_size);
+ assert(p);
+ /* copy the packet */
+ memcpy(p,stream_pkt,pkt_size);
+
+ /* TBD repace the mac if req we should add flag */
+ m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir,(uint8_t*) p);
+
+ /* set the packet as a readonly */
+ node->set_cache_mbuf(m);
+ }else{
+ /* we need to copy the object */
+
+ if ( pkt_size > stream->m_vm_prefix_size ) {
+ /* we need const packet */
+ uint16_t const_pkt_size = pkt_size - stream->m_vm_prefix_size ;
+ rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), const_pkt_size );
+ assert(m);
+
+ char *p = rte_pktmbuf_append(m, const_pkt_size);
+ assert(p);
+
+ /* copy packet data */
+ memcpy(p,(stream_pkt+ stream->m_vm_prefix_size),const_pkt_size);
+
+ node->set_const_mbuf(m);
+ }
+
+
+ if (stream->m_vm_prefix_size > pkt_size ) {
+ stream->m_vm_prefix_size = pkt_size;
+ }
+ /* copy the headr */
+ uint16_t header_size = stream->m_vm_prefix_size;
+ assert(header_size);
+ node->alloc_prefix_header(header_size);
+ uint8_t *p=node->m_original_packet_data_prefix;
+ assert(p);
+
+ memcpy(p,stream_pkt , header_size);
+ /* TBD repace the mac if req we should add flag */
+ m_core->m_node_gen.m_v_if->update_mac_addr_from_global_cfg(dir, p);
+ }
+
CDpOneStream one_stream;
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index 111af845..1ae8cbbc 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -54,6 +54,16 @@ struct CGenNodeStateless : public CGenNodeBase {
friend class TrexStatelessDpCore;
public:
+
+ /* flags MASKS*/
+ enum {
+ SL_NODE_FLAGS_DIR =1, //USED by master
+ SL_NODE_FLAGS_MBUF_CACHE =2, //USED by master
+
+ SL_NODE_CONST_MBUF =4
+
+ };
+
enum {
ss_FREE_RESUSE =1, /* should be free by scheduler */
ss_INACTIVE =2, /* will be active by other stream or stopped */
@@ -86,8 +96,10 @@ private:
TrexStream * m_ref_stream_info; /* the stream info */
CGenNodeStateless * m_next_stream;
+ uint8_t * m_original_packet_data_prefix; /* pointer to the original first pointer 64/128/512 */
+
/* pad to match the size of CGenNode */
- uint8_t m_pad_end[56];
+ uint8_t m_pad_end[48];
@@ -256,13 +268,51 @@ public:
}
inline rte_mbuf_t * get_cache_mbuf(){
- if ( m_flags &NODE_FLAGS_MBUF_CACHE ) {
+ if ( m_flags & NODE_FLAGS_MBUF_CACHE ) {
+ return ((rte_mbuf_t *)m_cache_mbuf);
+ }else{
+ return ((rte_mbuf_t *)0);
+ }
+ }
+
+ inline void set_const_mbuf(rte_mbuf_t * m){
+ m_cache_mbuf=(void *)m;
+ m_flags |= SL_NODE_CONST_MBUF;
+ }
+
+ inline rte_mbuf_t * get_const_mbuf(){
+ if ( m_flags &SL_NODE_CONST_MBUF ) {
return ((rte_mbuf_t *)m_cache_mbuf);
}else{
return ((rte_mbuf_t *)0);
}
}
+ /* prefix header exits only in non cache mode size is 64/128/512 other are not possible right now */
+ inline void alloc_prefix_header(uint8_t size){
+ set_prefix_header_size(size);
+ m_original_packet_data_prefix = (uint8_t *)malloc(size);
+ assert(m_original_packet_data_prefix);
+ }
+
+ inline void free_prefix_header(){
+ if (m_original_packet_data_prefix) {
+ free(m_original_packet_data_prefix);
+ }
+ }
+
+ /* prefix headr could be 64/128/512 */
+ inline void set_prefix_header_size(uint16_t size){
+ m_src_port=size;
+ }
+
+ inline uint16_t prefix_header_size(){
+ return (m_src_port);
+ }
+
+
+ rte_mbuf_t * alloc_node_with_vm();
+
void free_stl_node();
public: