summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlinux/ws_main.py19
-rwxr-xr-xsrc/bp_gtest.cpp18
-rwxr-xr-xsrc/bp_sim.cpp174
-rwxr-xr-xsrc/bp_sim.h46
-rw-r--r--src/gtest/trex_stateless_gtest.cpp360
-rwxr-xr-xsrc/main.cpp47
-rwxr-xr-xsrc/msg_manager.cpp26
-rwxr-xr-xsrc/msg_manager.h1
-rwxr-xr-xsrc/pal/linux/mbuf.cpp7
-rwxr-xr-xsrc/pal/linux/mbuf.h2
-rwxr-xr-xsrc/pal/linux_dpdk/mbuf.h4
-rw-r--r--src/stateless/cp/trex_stream.h4
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp2
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp44
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h10
-rw-r--r--src/stateless/dp/trex_stream_node.h10
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h1
17 files changed, 426 insertions, 349 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py
index d020411a..65ca4522 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -238,9 +238,15 @@ bp =SrcGroups([
bp_sim_gtest,
main_src,
cmn_src ,
+
net_src ,
yaml_src,
- bp_hack_for_compile,
+ json_src,
+ stateless_src,
+ rpc_server_src
+ #rpc_server_mock_src,
+
+ #bp_hack_for_compile,
]);
@@ -393,10 +399,13 @@ class build_option:
build_types = [
- build_option(name = "bp-sim", src = bp, debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False,
- flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing']),
- build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False,
- flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing']),
+ build_option(name = "bp-sim", src = bp, use = ['zmq'],debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False,
+ flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing'],
+ rpath = ['.']),
+
+ build_option(name = "bp-sim", src = bp, use = ['zmq'],debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False,
+ flags = ['-Wall', '-Werror', '-Wno-sign-compare', '-Wno-strict-aliasing'],
+ rpath = ['.']),
build_option(name = "mock-rpc-server", use = ['zmq'], src = rpc_server_mock, debug_mode= DEBUG_,platform = PLATFORM_64, is_pie = False,
flags = ['-DTREX_RPC_MOCK_SERVER', '-Wall', '-Werror', '-Wno-sign-compare'],
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp
index 03ab74bd..a94c2d37 100755
--- a/src/bp_gtest.cpp
+++ b/src/bp_gtest.cpp
@@ -131,16 +131,6 @@ int test_human_p(){
-static bool was_init=false;
-
-void gtest_init_once(){
-
- if ( !was_init ){
- CGlobalInfo::init_pools(1000);
- time_init();
- was_init=true;
- }
-}
@@ -259,7 +249,6 @@ public:
class basic : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
}
virtual void TearDown() {
}
@@ -269,7 +258,6 @@ public:
class cpu : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
}
virtual void TearDown() {
}
@@ -1199,7 +1187,6 @@ TEST_F(cpu, cpu3) {
class timerwl : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
}
virtual void TearDown() {
}
@@ -1450,7 +1437,6 @@ TEST_F(timerwl, many_timers_with_stop) {
class rx_check : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
m_rx_check.Create();
}
@@ -2142,7 +2128,6 @@ public:
class rx_check_system : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
m_rx_check.m_callback=&m_callback;
m_callback.mg =&m_mg;
@@ -2420,8 +2405,6 @@ public:
class nat_check_system : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
-
m_rx_check.m_callback=&m_callback;
m_callback.mg =&m_mg;
m_mg.Create();
@@ -2467,7 +2450,6 @@ class file_flow_info : public testing::Test {
protected:
virtual void SetUp() {
- gtest_init_once();
assert(m_flow_info.Create());
}
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 0c0cbb75..c63ad1af 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -496,6 +496,26 @@ void CRteMemPool::dump(FILE *fd){
}
////////////////////////////////////////
+
+void CGlobalInfo::free_pools(){
+ CPlatformSocketInfo * lpSocket =&m_socket;
+ CRteMemPool * lpmem;
+ int i;
+ for (i=0; i<(int)MAX_SOCKETS_SUPPORTED; i++) {
+ if (lpSocket->is_sockets_enable((socket_id_t)i)) {
+ lpmem= &m_mem_pool[i];
+ utl_rte_mempool_delete(lpmem->m_big_mbuf_pool);
+ utl_rte_mempool_delete(lpmem->m_small_mbuf_pool);
+ utl_rte_mempool_delete(lpmem->m_mbuf_pool_128);
+ utl_rte_mempool_delete(lpmem->m_mbuf_pool_256);
+ utl_rte_mempool_delete(lpmem->m_mbuf_pool_512);
+ utl_rte_mempool_delete(lpmem->m_mbuf_pool_1024);
+ }
+ utl_rte_mempool_delete(m_mem_pool[0].m_mbuf_global_nodes);
+ }
+}
+
+
void CGlobalInfo::init_pools(uint32_t rx_buffers){
/* this include the pkt from 64- */
CGlobalMemory * lp=&CGlobalInfo::m_memory_cfg;
@@ -748,9 +768,7 @@ int CErfIF::write_pkt(CCapPktRaw *pkt_raw){
int CErfIF::close_file(void){
BP_ASSERT(m_raw);
- m_raw->raw=0;
delete m_raw;
-
if ( m_preview_mode->getFileWrite() ){
BP_ASSERT(m_writer);
delete m_writer;
@@ -3054,6 +3072,16 @@ void CGenNode::DumpHeader(FILE *fd){
fprintf(fd," pkt_id,time,fid,pkt_info,pkt,len,type,is_init,is_last,type,thread_id,src_ip,dest_ip,src_port \n");
}
+
+void CGenNode::free_gen_node(){
+ rte_mbuf_t * m=get_cache_mbuf();
+ if ( unlikely(m != NULL) ) {
+ rte_pktmbuf_free(m);
+ m_plugin_info=0;
+ }
+}
+
+
void CGenNode::Dump(FILE *fd){
fprintf(fd,"%.6f,%llx,%p,%llu,%d,%d,%d,%d,%d,%d,%x,%x,%d\n",
m_time,
@@ -3123,6 +3151,15 @@ int CNodeGenerator::close_file(CFlowGenListPerThread * thread){
return (0);
}
+int CNodeGenerator::update_stl_stats(CGenNodeStateless *node_sl){
+ if ( m_preview_mode.getVMode() >2 ){
+ fprintf(stdout," %llu ,", (unsigned long long)m_cnt);
+ node_sl->Dump(stdout);
+ m_cnt++;
+ }
+ return (0);
+}
+
int CNodeGenerator::update_stats(CGenNode * node){
if ( m_preview_mode.getVMode() >2 ){
@@ -3361,6 +3398,7 @@ void CFlowGenListPerThread::Delete(){
Clean();
m_cpu_cp_u.Delete();
+ utl_rte_mempool_delete(m_node_pool);
}
@@ -3462,9 +3500,9 @@ int CNodeGenerator::flush_file(dsec_t max_time,
}
}
- #ifndef RTE_DPDK
- thread->check_msgs();
- #endif
+ //#ifndef RTE_DPDK
+ //thread->check_msgs();
+ //#endif
uint8_t type=node->m_type;
@@ -3472,9 +3510,14 @@ int CNodeGenerator::flush_file(dsec_t max_time,
m_p_queue.pop();
CGenNodeStateless *node_sl = (CGenNodeStateless *)node;
+ #ifdef _DEBUG
+ update_stl_stats(node_sl);
+ #endif
+
/* if the stream has been deactivated - end */
if (unlikely(!node_sl->is_active())) {
thread->free_node(node);
+
} else {
node_sl->handle(thread);
}
@@ -3899,41 +3942,26 @@ void CFlowGenListPerThread::check_msgs(void) {
}
}
-void delay(int msec);
+//void delay(int msec);
-const uint8_t test_udp_pkt[]={
- 0x00,0x00,0x00,0x01,0x00,0x00,
- 0x00,0x00,0x00,0x01,0x00,0x00,
- 0x08,0x00,
- 0x45,0x00,0x00,0x81,
- 0xaf,0x7e,0x00,0x00,
- 0x12,0x11,0xd9,0x23,
- 0x01,0x01,0x01,0x01,
- 0x3d,0xad,0x72,0x1b,
-
- 0x11,0x11,
- 0x11,0x11,
-
- 0x00,0x6d,
- 0x00,0x00,
-
- 0x64,0x31,0x3a,0x61,
- 0x64,0x32,0x3a,0x69,0x64,
- 0x32,0x30,0x3a,0xd0,0x0e,
- 0xa1,0x4b,0x7b,0xbd,0xbd,
- 0x16,0xc6,0xdb,0xc4,0xbb,0x43,
- 0xf9,0x4b,0x51,0x68,0x33,0x72,
- 0x20,0x39,0x3a,0x69,0x6e,0x66,0x6f,
- 0x5f,0x68,0x61,0x73,0x68,0x32,0x30,0x3a,0xee,0xc6,0xa3,
- 0xd3,0x13,0xa8,0x43,0x06,0x03,0xd8,0x9e,0x3f,0x67,0x6f,
- 0xe7,0x0a,0xfd,0x18,0x13,0x8d,0x65,0x31,0x3a,0x71,0x39,
- 0x3a,0x67,0x65,0x74,0x5f,0x70,0x65,0x65,0x72,0x73,0x31,
- 0x3a,0x74,0x38,0x3a,0x3d,0xeb,0x0c,0xbf,0x0d,0x6a,0x0d,
- 0xa5,0x31,0x3a,0x79,0x31,0x3a,0x71,0x65,0x87,0xa6,0x7d,
- 0xe7
-};
+void CFlowGenListPerThread::start_stateless_simulation_file(std::string erf_file_name,
+ CPreviewMode &preview){
+ m_preview_mode = preview;
+ m_node_gen.open_file(erf_file_name,&m_preview_mode);
+}
+
+void CFlowGenListPerThread::stop_stateless_simulation_file(){
+ m_node_gen.close_file(this);
+}
+
+void CFlowGenListPerThread::start_stateless_daemon_simulation(){
+
+ m_cur_time_sec = 0;
+ m_stateless_dp_info.run_once();
+
+}
void CFlowGenListPerThread::start_stateless_daemon(){
m_cur_time_sec = 0;
@@ -4002,6 +4030,12 @@ void CFlowGenListPerThread::start_generate_stateful(std::string erf_file_name,
m_node_gen.close_file(this);
}
+void CFlowGenList::Delete(){
+ clean_p_thread_info();
+ Clean();
+ delete CPluginCallback::callback;
+}
+
bool CFlowGenList::Create(){
check_objects_sizes();
@@ -4033,10 +4067,6 @@ void CFlowGenList::clean_p_thread_info(void){
}
-void CFlowGenList::Delete(){
- clean_p_thread_info();
- Clean();
-}
int CFlowGenList::load_from_mac_file(std::string file_name) {
if ( !utl_is_file_exists (file_name) ){
@@ -4570,24 +4600,54 @@ int CNullIF::send_node(CGenNode * node){
}
-int CErfIF::send_node(CGenNode * node){
- if ( m_preview_mode->getFileWrite() ){
- CFlowPktInfo * lp=node->m_pkt_info;
- rte_mbuf_t * m=lp->generate_new_mbuf(node);
+void CErfIF::fill_raw_packet(rte_mbuf_t * m,CGenNode * node,pkt_dir_t dir){
fill_pkt(m_raw,m);
+
CPktNsecTimeStamp t_c(node->m_time);
m_raw->time_nsec = t_c.m_time_nsec;
m_raw->time_sec = t_c.m_time_sec;
-
- pkt_dir_t dir=node->cur_interface_dir();
uint8_t p_id = (uint8_t)dir;
-
m_raw->setInterface(p_id);
+}
+
+
+int CErfIFStl::send_node(CGenNode * _no_to_use){
+
+ if ( m_preview_mode->getFileWrite() ){
+
+ CGenNodeStateless * node_sl=(CGenNodeStateless *) _no_to_use;
+
+ /* 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();
+
+ fill_raw_packet(m,_no_to_use,dir);
+ BP_ASSERT(m_writer);
+ bool res=m_writer->write_packet(m_raw);
+
+
+ BP_ASSERT(res);
+ }
+ return (0);
+}
+
+
+int CErfIF::send_node(CGenNode * node){
+
+ if ( m_preview_mode->getFileWrite() ){
+
+ CFlowPktInfo * lp=node->m_pkt_info;
+ rte_mbuf_t * m=lp->generate_new_mbuf(node);
+ pkt_dir_t dir=node->cur_interface_dir();
+
+ fill_raw_packet(m,node,dir);
/* update mac addr dest/src 12 bytes */
uint8_t *p=(uint8_t *)m_raw->raw;
+ int p_id=(int)dir;
memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12);
/* If vlan is enabled, add vlan header */
@@ -6807,6 +6867,24 @@ bool CSimplePacketParser::Parse(){
}
+/* free the right object.
+ it is classic to use virtual function but we can't do it here and we don't even want to use callback function
+ as we want to save space and in most cases there is nothing to free.
+ this might be changed in the future
+ */
+void CGenNodeBase::free_base(){
+ if ( m_type == FLOW_PKT ) {
+ CGenNode* p=(CGenNode*)this;
+ p->free_gen_node();
+ return;
+ }
+ if (m_type==STATELESS_PKT) {
+ CGenNodeStateless* p=(CGenNodeStateless*)this;
+ p->free_stl_node();
+ return;
+ }
+}
+
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 36595581..eef5576b 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -328,6 +328,9 @@ public:
CVirtualIF (){
m_preview_mode =NULL;
}
+
+ virtual ~CVirtualIF(){
+ }
public:
virtual int open_file(std::string file_name)=0;
@@ -1140,6 +1143,9 @@ public:
class CGlobalInfo {
public:
static void init_pools(uint32_t rx_buffers);
+ /* for simulation */
+ static void free_pools();
+
static inline rte_mbuf_t * pktmbuf_alloc_small(socket_id_t socket){
return ( m_mem_pool[socket].pktmbuf_alloc_small() );
@@ -1376,7 +1382,9 @@ public:
FLOW_PKT_NAT =3,
FLOW_SYNC =4, /* called evey 1 msec */
STATELESS_PKT =5,
- EXIT_SCHED =6
+ EXIT_SCHED =6,
+ EXIT_PORT_SCHED =7
+
};
@@ -1432,6 +1440,7 @@ public:
}
+ void free_base();
};
@@ -1466,6 +1475,9 @@ public:
uint32_t m_dest_idx;
uint32_t m_end_of_cache_line[6];
+
+public:
+ void free_gen_node();
public:
void Dump(FILE *fd);
@@ -1652,6 +1664,8 @@ public:
+
+
#if __x86_64__
/* size of 64 bytes */
#define DEFER_CLIENTS_NUM (16)
@@ -1802,11 +1816,24 @@ public:
virtual int flush_tx_queue(void);
-private:
+protected:
+
+ void fill_raw_packet(rte_mbuf_t * m,CGenNode * node,pkt_dir_t dir);
+
CFileWriterBase * m_writer;
CCapPktRaw * m_raw;
};
+/* for stateless we have a small changes in case we send the packets for optimization */
+class CErfIFStl : public CErfIF {
+
+public:
+
+ virtual int send_node(CGenNode * node);
+};
+
+
+
static inline int fill_pkt(CCapPktRaw * raw,rte_mbuf_t * m){
raw->pkt_len = m->pkt_len;
char *p=raw->raw;
@@ -1903,6 +1930,8 @@ private:
return (m_v_if->send_node(node));
}
int update_stats(CGenNode * node);
+ int update_stl_stats(CGenNodeStateless *node_sl);
+
FORCE_NO_INLINE bool handle_slow_messages(uint8_t type,
CGenNode * node,
@@ -3412,6 +3441,14 @@ public:
void start_generate_stateful(std::string erf_file_name,CPreviewMode &preview);
void start_stateless_daemon();
+ void start_stateless_daemon_simulation();
+
+ /* open a file for simulation */
+ void start_stateless_simulation_file(std::string erf_file_name,CPreviewMode &preview);
+ /* close a file for simulation */
+ void stop_stateless_simulation_file();
+
+
void Dump(FILE *fd);
void DumpCsv(FILE *fd);
@@ -3519,7 +3556,10 @@ inline CGenNode * CFlowGenListPerThread::create_node(void){
return (res);
}
+
+
inline void CFlowGenListPerThread::free_node(CGenNode *p){
+ p->free_base();
rte_mempool_sp_put(m_node_pool, p);
}
@@ -4033,6 +4073,8 @@ enum MINVM_PLUGIN_ID{
class CPluginCallback {
public:
+ virtual ~CPluginCallback(){
+ }
virtual void on_node_first(uint8_t plugin_id,CGenNode * node,CFlowYamlInfo * template_info, CTupleTemplateGeneratorSmart * tuple_gen,CFlowGenListPerThread * flow_gen) =0;
virtual void on_node_last(uint8_t plugin_id,CGenNode * node)=0;
virtual rte_mbuf_t * on_node_generate_mbuf(uint8_t plugin_id,CGenNode * node,CFlowPktInfo * pkt_info)=0;
diff --git a/src/gtest/trex_stateless_gtest.cpp b/src/gtest/trex_stateless_gtest.cpp
index 2bab4dff..36e48f6e 100644
--- a/src/gtest/trex_stateless_gtest.cpp
+++ b/src/gtest/trex_stateless_gtest.cpp
@@ -22,332 +22,180 @@ limitations under the License.
#include "bp_sim.h"
#include <common/gtest.h>
#include <common/basic_utils.h>
+#include <trex_stateless_dp_core.h>
+#include <trex_stateless_messaging.h>
+#include <trex_streams_compiler.h>
+#include <trex_stream_node.h>
+#include <trex_stream.h>
+#include <trex_stateless_port.h>
+#include <trex_rpc_server_api.h>
#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
-// one stream info with const packet , no VM
-class CTRexDpStatelessVM {
-};
-
-//- add dump function
-// - check one object
-// create frame work
-class CTRexDpStreamModeContinues{
+/* basic stateless test */
+class basic_stl : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ }
+ virtual void TearDown() {
+ }
public:
- void set_pps(double pps){
- m_pps=pps;
- }
- double get_pps(){
- return (m_pps);
- }
-
- void dump(FILE *fd);
-private:
- double m_pps;
};
-void CTRexDpStreamModeContinues::dump(FILE *fd){
- fprintf (fd," pps : %f \n",m_pps);
-}
+class CBasicStl {
-
-class CTRexDpStreamModeSingleBurst{
public:
- void set_pps(double pps){
- m_pps=pps;
- }
- double get_pps(){
- return (m_pps);
- }
-
- void set_total_packets(uint64_t total_packets){
- m_total_packets =total_packets;
- }
-
- uint64_t get_total_packets(){
- return (m_total_packets);
+ CBasicStl(){
+ m_time_diff=0.001;
+ m_threads=1;
}
- void dump(FILE *fd);
-
-private:
- double m_pps;
- uint64_t m_total_packets;
-};
-
-
-void CTRexDpStreamModeSingleBurst::dump(FILE *fd){
- fprintf (fd," pps : %f \n",m_pps);
- fprintf (fd," total_packets : %llu \n", (unsigned long long)m_total_packets);
-}
-
+ bool init(void){
-class CTRexDpStreamModeMultiBurst{
-public:
- void set_pps(double pps){
- m_pps=pps;
- }
- double get_pps(){
- return (m_pps);
- }
+ CErfIFStl erf_vif;
+ fl.Create();
+ fl.generate_p_thread_info(1);
+ CFlowGenListPerThread * lpt;
- void set_pkts_per_burst(uint64_t pkts_per_burst){
- m_pkts_per_burst =pkts_per_burst;
- }
+ fl.m_threads_info[0]->set_vif(&erf_vif);
- uint64_t get_pkts_per_burst(){
- return (m_pkts_per_burst);
- }
+ CErfCmp cmp;
+ cmp.dump=1;
- void set_ibg(double ibg){
- m_ibg = ibg;
- }
+ CMessagingManager * cp_dp = CMsgIns::Ins()->getCpDp();
- double get_ibg(){
- return ( m_ibg );
- }
+ m_ring_from_cp = cp_dp->getRingCpToDp(0);
- void set_number_of_bursts(uint32_t number_of_bursts){
- m_number_of_bursts = number_of_bursts;
- }
- uint32_t get_number_of_bursts(){
- return (m_number_of_bursts);
- }
+ bool res=true;
- void dump(FILE *fd);
+ lpt=fl.m_threads_info[0];
-private:
- double m_pps;
- double m_ibg; // inter burst gap
- uint64_t m_pkts_per_burst;
- uint32_t m_number_of_bursts;
-};
+ char buf[100];
+ char buf_ex[100];
+ sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),0);
+ sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),0);
-void CTRexDpStreamModeMultiBurst::dump(FILE *fd){
- fprintf (fd," pps : %f \n",m_pps);
- fprintf (fd," total_packets : %llu \n", (unsigned long long)m_pkts_per_burst);
- fprintf (fd," ibg : %f \n",m_ibg);
- fprintf (fd," num_of_bursts : %lu \n", (ulong)m_number_of_bursts);
-}
+ lpt->start_stateless_simulation_file(buf,CGlobalInfo::m_options.preview);
+ /* add stream to the queue */
+ assert(m_msg);
+ assert(m_ring_from_cp->Enqueue((CGenNode *)m_msg)==0);
-class CTRexDpStreamMode {
-public:
- enum MODES {
- moCONTINUES = 0x0,
- moSINGLE_BURST = 0x1,
- moMULTI_BURST = 0x2
- } ;
- typedef uint8_t MODE_TYPE_t;
+ lpt->start_stateless_daemon_simulation();
- void reset();
+ #if 0
+ lpt->m_node_gen.DumpHist(stdout);
- void set_mode(MODE_TYPE_t mode ){
- m_type = mode;
- }
- MODE_TYPE_t get_mode(){
- return (m_type);
- }
+ cmp.d_sec = m_time_diff;
+ if ( cmp.compare(std::string(buf),std::string(buf_ex)) != true ) {
+ res=false;
+ }
- CTRexDpStreamModeContinues & cont(void){
- return (m_data.m_cont);
- }
- CTRexDpStreamModeSingleBurst & single_burst(void){
- return (m_data.m_signle_burst);
- }
+ if ( m_dump_json ){
+ printf(" dump json ...........\n");
+ std::string s;
+ fl.m_threads_info[0]->m_node_gen.dump_json(s);
+ printf(" %s \n",s.c_str());
+ }
+ #endif
- CTRexDpStreamModeMultiBurst & multi_burst(void){
- return (m_data.m_multi_burst);
+ fl.Delete();
+ return (res);
}
- void dump(FILE *fd);
-private:
- uint8_t m_type;
- union Data {
- CTRexDpStreamModeContinues m_cont;
- CTRexDpStreamModeSingleBurst m_signle_burst;
- CTRexDpStreamModeMultiBurst m_multi_burst;
- } m_data;
+public:
+ int m_threads;
+ double m_time_diff;
+ bool m_dump_json;
+ TrexStatelessCpToDpMsgBase * m_msg;
+ CNodeRing *m_ring_from_cp;
+ CFlowGenList fl;
};
-void CTRexDpStreamMode::reset(){
- m_type =CTRexDpStreamMode::moCONTINUES;
- memset(&m_data,0,sizeof(m_data));
-}
-
-void CTRexDpStreamMode::dump(FILE *fd){
- const char * table[3] = {"CONTINUES","SINGLE_BURST","MULTI_BURST"};
-
- fprintf(fd," mode : %s \n", (char*)table[m_type]);
- switch (m_type) {
- case CTRexDpStreamMode::moCONTINUES :
- cont().dump(fd);
- break;
- case CTRexDpStreamMode::moSINGLE_BURST :
- single_burst().dump(fd);
- break;
- case CTRexDpStreamMode::moMULTI_BURST :
- multi_burst().dump(fd);
- break;
- default:
- fprintf(fd," ERROR type if not valid %d \n",m_type);
- break;
- }
-}
+const uint8_t my_test_pkt[]={
+ 0x00,0x04,0x96,0x08,0xe0,0x40,
+ 0x00,0x0e,0x2e,0x24,0x37,0x5f,
+ 0x08,0x00,
+ 0x45,0x02,0x00,0x30,
+ 0x00,0x00,0x40,0x00,
+ 0x40,0x84,0xbd,0x04,
+ 0x9b,0xe6,0x18,0x9b, //sIP
+ 0xcb,0xff,0xfc,0xc2, //DIP
-class CTRexDpStatelessStream {
+ 0x80,0x44,//SPORT
+ 0x00,0x50,//DPORT
-public:
- enum FLAGS_0{
- _ENABLE = 0,
- _SELF_START = 1,
- _VM_ENABLE =2,
- _END_STREAM =-1
- };
-
- CTRexDpStatelessStream(){
- reset();
- }
+ 0x00,0x00,0x00,0x00, //checksum
- void reset(){
- m_packet =0;
- m_vm=0;
- m_flags=0;
- m_isg_sec=0.0;
- m_next_stream = CTRexDpStatelessStream::_END_STREAM ; // END
- m_mode.reset();
- }
+ 0x11,0x22,0x33,0x44, // magic
+ 0x00,0x00,0x00,0x00, //64 bit counter
+ 0x00,0x00,0x00,0x00,
+ 0x00,0x01,0xa0,0x00, //seq
+ 0x00,0x00,0x00,0x00,
+};
- void set_enable(bool enable){
- btSetMaskBit32(m_flags,_ENABLE,_ENABLE,enable?1:0);
- }
- bool get_enabled(){
- return (btGetMaskBit32(m_flags,_ENABLE,_ENABLE)?true:false);
- }
- void set_self_start(bool enable){
- btSetMaskBit32(m_flags,_SELF_START,_SELF_START,enable?1:0);
- }
- bool get_self_start(bool enable){
- return (btGetMaskBit32(m_flags,_SELF_START,_SELF_START)?true:false);
- }
+TEST_F(basic_stl, limit_single_pkt) {
- /* if we don't have VM we could just replicate the mbuf and allocate it once */
- void set_vm_enable(bool enable){
- btSetMaskBit32(m_flags,_VM_ENABLE,_VM_ENABLE,enable?1:0);
- }
+ CBasicStl t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->out_file ="exp/stl_single_sctp_pkt";
- bool get_vm_enabled(bool enable){
- return (btGetMaskBit32(m_flags,_VM_ENABLE,_VM_ENABLE)?true:false);
- }
+ TrexStreamsCompiler compile;
- void set_inter_stream_gap(double isg_sec){
- m_isg_sec =isg_sec;
- }
- double get_inter_stream_gap(){
- return (m_isg_sec);
- }
+ std::vector<TrexStream *> streams;
- CTRexDpStreamMode & get_mode();
+ TrexStream * stream1 = new TrexStreamContinuous(0,0,1.0);
+ stream1->m_enabled = true;
+ stream1->m_self_start = true;
+ uint8_t *binary = new uint8_t[sizeof(my_test_pkt)];
+ memcpy(binary,my_test_pkt,sizeof(my_test_pkt));
- // CTRexDpStatelessStream::_END_STREAM for END
- void set_next_stream(int32_t next_stream){
- m_next_stream =next_stream;
- }
+ stream1->m_pkt.binary = binary;
+ stream1->m_pkt.len = sizeof(my_test_pkt);
- int32_t get_next_stream(void){
- return ( m_next_stream );
- }
- void dump(FILE *fd);
+ streams.push_back(stream1);
-private:
- char * m_packet;
- CTRexDpStatelessVM * m_vm;
- uint32_t m_flags;
- double m_isg_sec; // in second
- CTRexDpStreamMode m_mode;
- int32_t m_next_stream; // next stream id
-};
+ // stream - clean
-//- list of streams info with const packet , no VM
-// - object that include the stream /scheduler/ packet allocation / need to create an object for one thread that works for test
-// generate pcap file and compare it
-
-#if 0
-void CTRexDpStatelessStream::dump(FILE *fd){
-
- fprintf(fd," enabled : %d \n",get_enabled()?1:0);
- fprintf(fd," self_start : %d \n",get_self_start()?1:0);
- fprintf(fd," vm : %d \n",get_vm_enabled()?1:0);
- fprintf(" isg : %f \n",m_isg_sec);
- m_mode.dump(fd);
- if (m_next_stream == CTRexDpStatelessStream::_END_STREAM ) {
- fprintf(fd," action : End of Stream \n");
- }else{
- fprintf(" next : %d \n",m_next_stream);
- }
-}
+ TrexStreamsCompiledObj comp_obj(0,1.0);
+ assert(compile.compile(streams, comp_obj) );
+ TrexStatelessDpStart * lpstart = new TrexStatelessDpStart( comp_obj.clone() );
-class CTRexStatelessBasic {
-
-public:
- CTRexStatelessBasic(){
- m_threads=1;
- }
-
- bool init(void){
- return (true);
- }
-
-public:
- bool m_threads;
-};
+ t1.m_msg = lpstart;
+ bool res=t1.init();
-/* stateless basic */
-class dp_sl_basic : public testing::Test {
- protected:
- virtual void SetUp() {
- }
- virtual void TearDown() {
- }
-public:
-};
-
+ delete stream1 ;
-
-TEST_F(dp_sl_basic, test1) {
- CTRexDpStatelessStream s1;
- s1.set_enable(true);
- s1.set_self_start(true);
- s1.set_inter_stream_gap(0.77);
- s1.get_mode().set_mode(CTRexDpStreamMode::moCONTINUES);
- s1.get_mode().cont().set_pps(100.2);
- s1.dump(stdout);
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
}
+
#endif
diff --git a/src/main.cpp b/src/main.cpp
index df9d8b40..64547d57 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,6 +26,8 @@ limitations under the License.
#include <common/arg/SimpleGlob.h>
#include <common/arg/SimpleOpt.h>
+#include <stateless/cp/trex_stateless.h>
+
// An enum for all the option types
enum { OPT_HELP, OPT_CFG, OPT_NODE_DUMP, OP_STATS,
@@ -94,21 +96,20 @@ static int usage(){
int gtest_main(int argc, char **argv) ;
-static int parse_options(int argc, char *argv[], CParserOption* po ) {
+static int parse_options(int argc, char *argv[], CParserOption* po, bool & is_gtest ) {
CSimpleOpt args(argc, argv, parser_options);
int a=0;
int node_dump=0;
po->preview.clean();
po->preview.setFileWrite(true);
- int res1;
while ( args.Next() ){
if (args.LastError() == SO_SUCCESS) {
switch (args.OptionId()) {
case OPT_UT :
- res1=gtest_main(argc, argv);
- exit(res1);
+ is_gtest=true;
+ return (0);
break;
case OPT_HELP:
usage();
@@ -749,18 +750,50 @@ int merge_2_cap_files_sip() {
return (0);
}
+static TrexStateless *g_trex_stateless;
+
+
+TrexStateless * get_stateless_obj() {
+ return g_trex_stateless;
+}
+
+extern "C" const char * get_build_date(void){
+ return (__DATE__);
+}
+
+extern "C" const char * get_build_time(void){
+ return (__TIME__ );
+}
+
+
int main(int argc , char * argv[]){
+ int res=0;
time_init();
CGlobalInfo::m_socket.Create(0);
-
CGlobalInfo::init_pools(1000);
assert( CMsgIns::Ins()->Create(4) );
- if ( parse_options(argc, argv, &CGlobalInfo::m_options ) != 0){
+
+ bool is_gtest=false;
+
+ if ( parse_options(argc, argv, &CGlobalInfo::m_options , is_gtest) != 0){
exit(-1);
}
- return (load_list_of_cap_files(&CGlobalInfo::m_options));
+
+ if ( is_gtest ) {
+ res = gtest_main(argc, argv);
+ }else{
+ res = load_list_of_cap_files(&CGlobalInfo::m_options);
+ }
+
+ CMsgIns::Ins()->Free();
+ CGlobalInfo::free_pools();
+ CGlobalInfo::m_socket.Delete();
+
+
+ return (res);
+
}
diff --git a/src/msg_manager.cpp b/src/msg_manager.cpp
index 9f41d08c..5fe44771 100755
--- a/src/msg_manager.cpp
+++ b/src/msg_manager.cpp
@@ -51,15 +51,20 @@ bool CMessagingManager::Create(uint8_t num_dp_threads,std::string a_name){
return (true);
}
void CMessagingManager::Delete(){
- if (m_dp_to_cp) {
- m_dp_to_cp->Delete();
- delete []m_dp_to_cp;
- }
- if (m_cp_to_dp) {
- m_cp_to_dp->Delete();
- delete []m_cp_to_dp;
+
+ assert(m_cp_to_dp);
+ assert(m_dp_to_cp);
+ int i;
+ for (i=0; i<m_num_dp_threads; i++) {
+ CNodeRing * lp;
+ lp=getRingCpToDp(i);
+ lp->Delete();
+ lp=getRingDpToCp(i);
+ lp->Delete();
}
+ delete []m_dp_to_cp;
+ delete []m_cp_to_dp;
}
CNodeRing * CMessagingManager::getRingCpToDp(uint8_t thread_id){
@@ -76,6 +81,7 @@ CNodeRing * CMessagingManager::getRingDpToCp(uint8_t thread_id){
void CMsgIns::Free(){
if (m_ins) {
+ m_ins->Delete();
delete m_ins;
}
}
@@ -98,6 +104,12 @@ bool CMsgIns::Create(uint8_t num_threads){
}
+void CMsgIns::Delete(){
+ m_cp_dp.Delete();
+ m_rx_dp.Delete();
+}
+
+
CMsgIns * CMsgIns::m_ins=0;
diff --git a/src/msg_manager.h b/src/msg_manager.h
index 8958f826..0390ce10 100755
--- a/src/msg_manager.h
+++ b/src/msg_manager.h
@@ -98,6 +98,7 @@ public:
static CMsgIns * Ins();
static void Free();
bool Create(uint8_t num_threads);
+ void Delete();
public:
CMessagingManager * getRxDp(){
return (&m_rx_dp);
diff --git a/src/pal/linux/mbuf.cpp b/src/pal/linux/mbuf.cpp
index 7eca8fd5..26a54fe9 100755
--- a/src/pal/linux/mbuf.cpp
+++ b/src/pal/linux/mbuf.cpp
@@ -78,6 +78,13 @@ rte_mempool_t * utl_rte_mempool_create(const char *name,
return p;
}
+void utl_rte_mempool_delete(rte_mempool_t * & pool){
+ if (pool) {
+ delete pool;
+ pool=0;
+ }
+}
+
uint16_t rte_mbuf_refcnt_update(rte_mbuf_t *m, int16_t value)
{
diff --git a/src/pal/linux/mbuf.h b/src/pal/linux/mbuf.h
index 35a442bf..4132f842 100755
--- a/src/pal/linux/mbuf.h
+++ b/src/pal/linux/mbuf.h
@@ -65,6 +65,8 @@ typedef struct rte_mempool rte_mempool_t;
#define RTE_PKTMBUF_HEADROOM 0
+void utl_rte_mempool_delete(rte_mempool_t * &pool);
+
rte_mempool_t * utl_rte_mempool_create(const char *name,
unsigned n,
unsigned elt_size,
diff --git a/src/pal/linux_dpdk/mbuf.h b/src/pal/linux_dpdk/mbuf.h
index cde01077..339c0909 100755
--- a/src/pal/linux_dpdk/mbuf.h
+++ b/src/pal/linux_dpdk/mbuf.h
@@ -30,6 +30,10 @@ typedef struct rte_mbuf rte_mbuf_t;
typedef struct rte_mempool rte_mempool_t;
+inline void utl_rte_mempool_delete(rte_mempool_t * & pool){
+}
+
+
rte_mempool_t * utl_rte_mempool_create(const char *name,
unsigned n,
unsigned elt_size,
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index c8a15240..d1a44909 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -40,7 +40,7 @@ class TrexStream {
public:
TrexStream(uint8_t port_id, uint32_t stream_id);
- virtual ~TrexStream() = 0;
+ virtual ~TrexStream();
/* defines the min max per packet supported */
static const uint32_t MIN_PKT_SIZE_BYTES = 1;
@@ -88,6 +88,8 @@ public:
/* original template provided by requester */
Json::Value m_stream_json;
+
+
};
/**
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index 06c0119a..667da158 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -31,7 +31,7 @@ TrexStreamsCompiledObj::TrexStreamsCompiledObj(uint8_t port_id, double mul) : m_
TrexStreamsCompiledObj::~TrexStreamsCompiledObj() {
for (auto &obj : m_objs) {
- delete obj.m_pkt;
+ delete [] obj.m_pkt;
}
m_objs.clear();
}
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index b2bd0152..c9e47090 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -31,6 +31,18 @@ usec_to_sec(double usec) {
}
+
+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;
+ }
+}
+
+
+
void
TrexStatelessDpCore::create(uint8_t thread_id, CFlowGenListPerThread *core) {
m_thread_id = thread_id;
@@ -79,16 +91,41 @@ TrexStatelessDpCore::start_scheduler() {
m_core->m_node_gen.close_file(m_core);
}
+
+void
+TrexStatelessDpCore::run_once(){
+
+ idle_state_loop();
+ start_scheduler();
+}
+
+
void
TrexStatelessDpCore::start() {
while (true) {
- idle_state_loop();
+ run_once();
+ }
+}
+
+void
+TrexStatelessDpCore::add_duration(uint8_t port_id,
+ double duration){
+ if (duration > 0.0) {
+
+ CGenNode *node = m_core->create_node() ;
+
+ node->m_type = CGenNode::EXIT_SCHED;
+
+ /* make sure it will be scheduled after the current node */
+ node->m_time = m_core->m_cur_time_sec + duration ;
+
+ m_core->m_node_gen.add_node(node);
- start_scheduler();
}
}
+
void
TrexStatelessDpCore::add_cont_stream(uint8_t port_id,
double isg_usec,
@@ -155,6 +192,9 @@ TrexStatelessDpCore::start_traffic(TrexStreamsCompiledObj *obj) {
single_stream.m_pkt,
single_stream.m_pkt_len);
}
+
+ /* TBD need to fix this */
+ add_duration(0,10.0);
}
void
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index f4dbad08..a23e81c9 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -45,6 +45,7 @@ public:
TrexStatelessDpCore() {
m_thread_id = 0;
m_core = NULL;
+ m_duration = -1;
}
/**
@@ -61,6 +62,10 @@ public:
*/
void start();
+
+ /* exit after batch of commands */
+ void run_once();
+
/**
* dummy traffic creator
*
@@ -126,6 +131,9 @@ private:
*/
void handle_cp_msg(TrexStatelessCpToDpMsgBase *msg);
+ void add_duration(uint8_t port_id,
+ double duration);
+
void add_cont_stream(uint8_t dir,
double isg,
double pps,
@@ -142,6 +150,8 @@ private:
/* pointer to the main object */
CFlowGenListPerThread *m_core;
+
+ double m_duration;
};
#endif /* __TREX_STATELESS_DP_CORE_H__ */
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index 92b428ab..2ffe04c3 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -22,6 +22,7 @@ limitations under the License.
#define __TREX_STREAM_NODE_H__
#include <bp_sim.h>
+#include <stdio.h>
class TrexStatelessDpCore;
@@ -42,6 +43,7 @@ private:
public:
+
inline bool is_active() {
return m_is_stream_active;
}
@@ -82,8 +84,6 @@ public:
return ((pkt_dir_t)( m_flags &1));
}
-
-
inline void set_cache_mbuf(rte_mbuf_t * m){
m_cache_mbuf=(void *)m;
m_flags |= NODE_FLAGS_MBUF_CACHE;
@@ -97,6 +97,12 @@ public:
}
}
+ void free_stl_node();
+
+
+ void Dump(FILE *fd){
+ fprintf(fd," %f, %lu, %lu \n",m_time,(ulong)m_port_id,(ulong)get_mbuf_cache_dir());
+ }
} __rte_cache_aligned;
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
index 7978b7f9..d288fc83 100644
--- a/src/stateless/messaging/trex_stateless_messaging.h
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -74,6 +74,7 @@ public:
virtual TrexStatelessCpToDpMsgBase * clone();
+
private:
TrexStreamsCompiledObj *m_obj;
};