summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlinux/ws_main.py39
-rwxr-xr-xlinux_dpdk/ws_main.py3
-rwxr-xr-xsrc/bp_sim.cpp101
-rwxr-xr-xsrc/bp_sim.h8
-rw-r--r--src/mock/trex_rpc_server_mock.cpp18
-rwxr-xr-xsrc/msg_manager.h11
-rwxr-xr-xsrc/nat_check.h10
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp2
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp38
-rw-r--r--src/stateless/cp/trex_stream.h4
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp137
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h120
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.cpp60
-rw-r--r--src/stateless/messaging/trex_stateless_messaging.h88
-rw-r--r--src/stub/trex_stateless_stub.cpp13
15 files changed, 548 insertions, 104 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py
index a94e975c..00fd3f21 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -91,10 +91,11 @@ def configure(conf):
conf.load('g++')
verify_cc_version(conf.env)
-
+bp_sim_main = SrcGroup(dir='src',
+ src_list=['main.cpp'])
+
main_src = SrcGroup(dir='src',
src_list=[
- 'main.cpp',
'bp_sim.cpp',
'bp_gtest.cpp',
'os_time.cpp',
@@ -146,6 +147,8 @@ stateless_src = SrcGroup(dir='src/stateless/',
'cp/trex_stream_vm.cpp',
'cp/trex_stateless.cpp',
'cp/trex_stateless_port.cpp',
+ 'dp/trex_stateless_dp_core.cpp',
+ 'messaging/trex_stateless_messaging.cpp',
])
# RPC code
rpc_server_src = SrcGroup(dir='src/rpc-server/',
@@ -169,8 +172,6 @@ rpc_server_mock_src = SrcGroup(dir='src/mock/',
'trex_rpc_server_mock.cpp',
'trex_platform_api_mock.cpp',
'../gtest/rpc_test.cpp',
- '../pal/linux/mbuf.cpp',
- '../os_time.cpp',
])
# JSON package
@@ -179,12 +180,6 @@ json_src = SrcGroup(dir='external_libs/json',
'jsoncpp.cpp'
])
-rpc_server_mock = SrcGroups([cmn_src,
- rpc_server_src,
- rpc_server_mock_src,
- stateless_src,
- json_src
- ])
yaml_src = SrcGroup(dir='external_libs/yaml-cpp/src/',
src_list=[
@@ -216,11 +211,30 @@ yaml_src = SrcGroup(dir='external_libs/yaml-cpp/src/',
'stream.cpp',
'tag.cpp']);
+
+rpc_server_mock = SrcGroups([
+ main_src,
+ cmn_src,
+ rpc_server_src,
+ rpc_server_mock_src,
+ stateless_src,
+ json_src,
+ yaml_src,
+ net_src,
+ ])
+
+# REMOVE ME - need to decide if stateless is part of bp sim or not
+bp_hack_for_compile = SrcGroup(dir='/src/stub/',
+ src_list=['trex_stateless_stub.cpp'
+ ])
+
bp =SrcGroups([
+ bp_sim_main,
main_src,
cmn_src ,
net_src ,
yaml_src,
+ bp_hack_for_compile,
]);
@@ -242,6 +256,7 @@ includes_path =''' ../src/pal/linux/
../src/rpc-server/
../src/stateless/cp/
../src/stateless/dp/
+ ../src/stateless/messaging/
../external_libs/json/
../external_libs/zmq/include/
../external_libs/yaml-cpp/include/
@@ -372,13 +387,11 @@ class build_option:
build_types = [
- #build_option(name = "bp-sim", src = bp, debug_mode= DEBUG_, platform = PLATFORM_32, is_pie = False),
build_option(name = "bp-sim", src = bp, debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False),
- #build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_32, is_pie = False),
build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False),
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', '-Wno-sign-compare', '-Werror'],
+ flags = ['-DTREX_RPC_MOCK_SERVER', '-Wall', '-Wno-sign-compare'],
rpath = ['.']),
]
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index d54531f3..d8b1bc98 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -158,6 +158,8 @@ stateless_src = SrcGroup(dir='src/stateless/',
'cp/trex_stream_vm.cpp',
'cp/trex_stateless.cpp',
'cp/trex_stateless_port.cpp',
+ 'dp/trex_stateless_dp_core.cpp',
+ 'messaging/trex_stateless_messaging.cpp'
])
# JSON package
json_src = SrcGroup(dir='external_libs/json',
@@ -414,6 +416,7 @@ includes_path =''' ../src/pal/linux_dpdk/
../src/rpc-server/
../src/stateless/cp/
../src/stateless/dp/
+ ../src/stateless/messaging/
../external_libs/yaml-cpp/include/
../external_libs/zmq/include/
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index d72da70c..72da7089 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -25,7 +25,6 @@ limitations under the License.
#include "msg_manager.h"
#include <common/basic_utils.h>
-
#undef VALG
#ifdef VALG
@@ -279,7 +278,7 @@ void CPlatformSocketInfoConfig::dump(FILE *fd){
fprintf(fd," \n");
fprintf(fd," active sockets : %d \n",max_num_active_sockets());
- fprintf(fd," ports_sockets : \n",max_num_active_sockets());
+ fprintf(fd," ports_sockets : %d \n",max_num_active_sockets());
for (i=0; i<(MAX_LATENCY_PORTS); i++) {
fprintf(fd,"%d,",port_to_socket(i));
@@ -3200,6 +3199,10 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id,
assert(m_ring_from_rx);
assert(m_ring_to_rx);
+
+ /* create the info required for stateless DP core */
+ m_stateless_dp_info = new TrexStatelessDpCore(thread_id, this);
+
return (true);
}
@@ -3347,6 +3350,9 @@ void CFlowGenListPerThread::Delete(){
m_node_gen.Delete();
Clean();
m_cpu_cp_u.Delete();
+
+ delete m_stateless_dp_info;
+ m_stateless_dp_info = NULL;
}
@@ -3452,12 +3458,9 @@ int CNodeGenerator::flush_file(dsec_t max_time,
uint8_t type=node->m_type;
if ( type == CGenNode::STATELESS_PKT ) {
-
- flush_one_node_to_file(node);
- /* in case of continues */
- node->m_time += 0.0001; /*TBD PPS*/
- m_p_queue.push(node);
- /* no need per thread stats, it is too heavy */
+ m_p_queue.pop();
+ // TODO: should this be inlined ? with IPO is this important ?
+ thread->m_stateless_dp_info->handle_pkt_event(node);
}else{
if ( likely( type == CGenNode::FLOW_PKT ) ) {
@@ -3564,9 +3567,12 @@ void CNodeGenerator::handle_slow_messages(uint8_t type,
}else{
if ( type == CGenNode::FLOW_SYNC ){
+
+ m_p_queue.pop();
+
thread->check_msgs(); /* check messages */
m_v_if->flush_tx_queue(); /* flush pkt each timeout */
- m_p_queue.pop();
+
if ( always == false) {
node->m_time += SYNC_TIME_OUT;
m_p_queue.push(node);
@@ -3815,11 +3821,15 @@ void CFlowGenListPerThread::handel_nat_msg(CGenNodeNatInfo * msg){
}
}
+void CFlowGenListPerThread::check_msgs(void) {
+
+ /* inlined for performance */
+ m_stateless_dp_info->periodic_check_for_cp_messages();
-void CFlowGenListPerThread::check_msgs(void){
- if ( likely ( m_ring_from_rx->isEmpty() ) ){
+ if ( likely ( m_ring_from_rx->isEmpty() ) ) {
return;
}
+
#ifdef NAT_TRACE_
printf(" %.03f got message from RX \n",now_sec());
#endif
@@ -3839,9 +3849,11 @@ void CFlowGenListPerThread::check_msgs(void){
case CGenNodeMsgBase::NAT_FIRST:
handel_nat_msg((CGenNodeNatInfo * )msg);
break;
+
case CGenNodeMsgBase::LATENCY_PKT:
handel_latecy_pkt_msg((CGenNodeLatencyPktInfo *) msg);
break;
+
default:
printf("ERROR pkt-thread message type is not valid %d \n",msg_type);
assert(0);
@@ -3887,72 +3899,8 @@ const uint8_t test_udp_pkt[]={
0xe7
};
-
-
-
-void CFlowGenListPerThread::start_stateless_const_rate_demo(){
-
- CGenNodeStateless * node= create_node_sl();
-
- /* add periodic */
- node->m_type = CGenNode::STATELESS_PKT;
- node->m_time = m_cur_time_sec+ 0.0 /* STREAM ISG */;
- node->m_flags =0;
-
- /* set socket id */
- node->set_socket_id(m_node_gen.m_socket_id);
-
- /* build a mbuf from a packet */
- uint16_t pkt_size=sizeof(test_udp_pkt);
- uint8_t * stream_pkt=(uint8_t *)test_udp_pkt;
-
- /* 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 */
- pkt_dir_t dir=0;
- node->set_mbuf_cache_dir(dir);
-
- /* TBD repace the mac if req we should add flag */
- 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 0
- /* dump the packet */
- uint8_t *p1=rte_pktmbuf_mtod(m, uint8_t*);
- uint16_t pkt_size1=rte_pktmbuf_pkt_len(m);
- utl_DumpBuffer(stdout,p,pkt_size,0);
- #endif
-
- m_node_gen.add_node((CGenNode *)node);
-
-
- double old_offset=0.0;
-
- CGenNode * node_sync= create_node() ;
- node_sync->m_type = CGenNode::FLOW_SYNC;
- node_sync->m_time = m_cur_time_sec + SYNC_TIME_OUT ;
- m_node_gen.add_node(node_sync);
-
- // TBD time
- m_node_gen.flush_file(100000000,0.0, false,this,old_offset);
-}
-
void CFlowGenListPerThread::start_stateless_daemon(){
- /* todo sleep */
- start_stateless_const_rate_demo();
-
- while (1) {
- delay(100);
- }
- /* sleep , get message from queue, shecudule --> get message */
+ m_stateless_dp_info->start();
}
@@ -4073,6 +4021,7 @@ int CFlowGenList::load_from_mac_file(std::string file_name) {
exit(-1);
}
+ return (0);
}
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 2cdfccb2..5747c2da 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -57,6 +57,8 @@ limitations under the License.
#include <arpa/inet.h>
#include "platform_cfg.h"
+#include <trex_stateless_dp_core.h>
+
#undef NAT_TRACE_
@@ -1641,6 +1643,9 @@ public:
struct CGenNodeStateless : public CGenNodeBase {
public:
+ inline uint8_t *get_opaque_storage() {
+ return (uint8_t *)&m_pad_end;
+ }
private:
void * m_cache_mbuf;
@@ -3450,7 +3455,6 @@ public:
void Clean();
void start_generate_stateful(std::string erf_file_name,CPreviewMode &preview);
void start_stateless_daemon();
- void start_stateless_const_rate_demo();
void Dump(FILE *fd);
@@ -3465,6 +3469,7 @@ public:
private:
void check_msgs(void);
+
void handel_nat_msg(CGenNodeNatInfo * msg);
void handel_latecy_pkt_msg(CGenNodeLatencyPktInfo * msg);
@@ -3543,6 +3548,7 @@ private:
flow_id_node_t m_flow_id_to_node_lookup;
+ TrexStatelessDpCore *m_stateless_dp_info;
private:
uint8_t m_cacheline_pad[RTE_CACHE_LINE_SIZE][19]; // improve prefech
diff --git a/src/mock/trex_rpc_server_mock.cpp b/src/mock/trex_rpc_server_mock.cpp
index 6e14390a..6642e50e 100644
--- a/src/mock/trex_rpc_server_mock.cpp
+++ b/src/mock/trex_rpc_server_mock.cpp
@@ -82,6 +82,24 @@ uint16_t gtest_get_mock_server_port() {
return g_rpc_port;
}
+void delay(int msec){
+
+ if (msec == 0)
+ {//user that requested that probebly wanted the minimal delay
+ //but because of scaling problem he have got 0 so we will give the min delay
+ //printf("\n\n\nERROR-Task delay ticks == 0 found in task %s task id = %d\n\n\n\n",
+ // SANB_TaskName(SANB_TaskIdSelf()), SANB_TaskIdSelf());
+ msec =1;
+
+ }
+
+ struct timespec time1, remain; // 2 sec max delay
+ time1.tv_sec=msec/1000;
+ time1.tv_nsec=(msec - (time1.tv_sec*1000))*1000000;
+
+ nanosleep(&time1,&remain);
+}
+
/**
* on simulation this is not rebuild every version
* (improved stub)
diff --git a/src/msg_manager.h b/src/msg_manager.h
index 6308eb1b..8958f826 100755
--- a/src/msg_manager.h
+++ b/src/msg_manager.h
@@ -28,8 +28,15 @@ limitations under the License.
/* messages from CP->DP Ids */
-#define NAT_MSG (7)
-#define LATENCY_PKT_SEND_MSG (8)
+struct CGenNodeMsgBase {
+ enum {
+ NAT_FIRST = 7,
+ LATENCY_PKT = 8,
+ } msg_types;
+
+public:
+ uint8_t m_msg_type; /* msg type */
+};
/*
diff --git a/src/nat_check.h b/src/nat_check.h
index b67c523c..a500ddaf 100755
--- a/src/nat_check.h
+++ b/src/nat_check.h
@@ -59,16 +59,6 @@ struct CNatFlowInfo {
this struct should be in the same size of CGenNode beacuse allocator is global .
*/
-struct CGenNodeMsgBase {
- enum {
- NAT_FIRST = NAT_MSG,
- LATENCY_PKT = LATENCY_PKT_SEND_MSG
- } msg_types;
-
-public:
- uint8_t m_msg_type; /* msg type */
-};
-
struct CGenNodeNatInfo : public CGenNodeMsgBase {
uint8_t m_pad;
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 4f697e3c..51ac0f92 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -462,7 +462,7 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
generate_execute_err(result, ss.str());
}
- return (TREX_RPC_CMD_OK);
+ return (TREX_RPC_CMD_OK);
}
/***************************
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 6b77b107..92d0a7f8 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -18,8 +18,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+
#include <trex_stateless.h>
#include <trex_stateless_port.h>
+#include <trex_stateless_messaging.h>
+
#include <string>
#ifndef TREX_RPC_MOCK_SERVER
@@ -61,7 +64,32 @@ TrexStatelessPort::start_traffic(void) {
m_port_state = PORT_STATE_TRANSMITTING;
- /* real code goes here */
+
+ /* ************* A HACK FOR NOW *************/
+ /* we support only one stream continious */
+ if (get_stream_table()->size() != 1) {
+ return (RC_ERR_FAILED_TO_COMPILE_STREAMS);
+ }
+
+ TrexStream *stream;
+ for (auto it = get_stream_table()->begin(); it != get_stream_table()->end(); it++ ) {
+ stream = (*it).second;
+ }
+
+ /* support only cont streams */
+ TrexStreamContinuous *cont_stream = dynamic_cast<TrexStreamContinuous *>(stream);
+ if (!cont_stream) {
+ return (RC_ERR_FAILED_TO_COMPILE_STREAMS);
+ }
+
+ /* generate a message to all the relevant DP cores to start transmitting */
+ TrexStatelessCpToDpMsgBase *start_msg = new TrexStatelessDpStart(cont_stream->m_pkt.binary, cont_stream->m_pkt.len, cont_stream->get_pps());
+
+ // FIXME (add the right core list)
+ CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingCpToDp(0);
+
+ ring->Enqueue((CGenNode *)start_msg);
+
return (RC_OK);
}
@@ -72,6 +100,14 @@ TrexStatelessPort::stop_traffic(void) {
if (m_port_state == PORT_STATE_TRANSMITTING) {
m_port_state = PORT_STATE_UP_IDLE;
}
+
+ /* generate a message to all the relevant DP cores to start transmitting */
+ TrexStatelessCpToDpMsgBase *stop_msg = new TrexStatelessDpStop();
+
+ // FIXME (add the right core list)
+ CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingCpToDp(0);
+
+ ring->Enqueue((CGenNode *)stop_msg);
}
/**
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index f5bc96ef..91e64d23 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -41,6 +41,7 @@ class TrexStream {
friend class TrexRpcCmdAddStream;
friend class TrexRpcCmdGetStream;
friend class TrexStreamTable;
+ friend class TrexStatelessPort;
public:
TrexStream(uint8_t port_id, uint32_t stream_id);
@@ -197,6 +198,9 @@ public:
*/
int size();
+ std::unordered_map<int, TrexStream *>::iterator begin() {return m_stream_table.begin();}
+ std::unordered_map<int, TrexStream *>::iterator end() {return m_stream_table.end();}
+
private:
/**
* holds all the stream in a hash table by stream id
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
new file mode 100644
index 00000000..20eadfc5
--- /dev/null
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -0,0 +1,137 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_stateless_dp_core.h>
+#include <trex_stateless_messaging.h>
+
+#include <bp_sim.h>
+
+typedef struct dp_node_extended_info_ {
+ double next_time_offset;
+} dp_node_extended_info_st;
+
+TrexStatelessDpCore::TrexStatelessDpCore(uint8_t thread_id, CFlowGenListPerThread *core) {
+ m_thread_id = thread_id;
+ m_core = core;
+
+ m_state = STATE_IDLE;
+
+ CMessagingManager * cp_dp = CMsgIns::Ins()->getCpDp();
+
+ m_ring_from_cp = cp_dp->getRingCpToDp(thread_id);
+ m_ring_to_cp = cp_dp->getRingDpToCp(thread_id);
+}
+
+void
+TrexStatelessDpCore::start() {
+
+ /* creates a maintenace job using the scheduler */
+ CGenNode * node_sync = m_core->create_node() ;
+ node_sync->m_type = CGenNode::FLOW_SYNC;
+ node_sync->m_time = m_core->m_cur_time_sec + SYNC_TIME_OUT;
+ m_core->m_node_gen.add_node(node_sync);
+
+ double old_offset = 0.0;
+ m_core->m_node_gen.flush_file(100000000, 0.0, false, m_core, old_offset);
+
+}
+
+void
+TrexStatelessDpCore::handle_pkt_event(CGenNode *node) {
+
+ /* if port has stopped - no transmition */
+ if (m_state == STATE_IDLE) {
+ return;
+ }
+
+ m_core->m_node_gen.m_v_if->send_node(node);
+
+ CGenNodeStateless *node_sl = (CGenNodeStateless *)node;
+
+ /* in case of continues */
+ dp_node_extended_info_st *opaque = (dp_node_extended_info_st *)node_sl->get_opaque_storage();
+ node->m_time += opaque->next_time_offset;
+
+ /* insert a new event */
+ m_core->m_node_gen.m_p_queue.push(node);
+}
+
+void
+TrexStatelessDpCore::start_const_traffic(const uint8_t *pkt,
+ uint16_t pkt_len,
+ double pps) {
+
+ CGenNodeStateless *node = m_core->create_node_sl();
+
+ /* add periodic */
+ node->m_type = CGenNode::STATELESS_PKT;
+ node->m_time = m_core->m_cur_time_sec + 0.0 /* STREAM ISG */;
+ node->m_flags = 0;
+
+ /* set socket id */
+ node->set_socket_id(m_core->m_node_gen.m_socket_id);
+
+ /* build a mbuf from a packet */
+ uint16_t pkt_size = pkt_len;
+ const uint8_t *stream_pkt = pkt;
+
+ dp_node_extended_info_st *opaque = (dp_node_extended_info_st *)node->get_opaque_storage();
+ opaque->next_time_offset = 1.0 / pps;
+
+ /* 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 */
+ pkt_dir_t dir = 0;
+ 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);
+
+ m_state = TrexStatelessDpCore::STATE_TRANSMITTING;
+
+ m_core->m_node_gen.add_node((CGenNode *)node);
+
+}
+
+void
+TrexStatelessDpCore::stop_traffic() {
+ m_state = STATE_IDLE;
+}
+
+/**
+ * handle a message from CP to DP
+ *
+ */
+void
+TrexStatelessDpCore::handle_cp_msg(TrexStatelessCpToDpMsgBase *msg) {
+ msg->handle(this);
+ delete msg;
+}
+
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
new file mode 100644
index 00000000..65d894d2
--- /dev/null
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -0,0 +1,120 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#ifndef __TREX_STATELESS_DP_CORE_H__
+#define __TREX_STATELESS_DP_CORE_H__
+
+#include <msg_manager.h>
+#include <pal_utl.h>
+
+class TrexStatelessCpToDpMsgBase;
+class TrexStatelessDpStart;
+class CFlowGenListPerThread;
+class CGenNode;
+
+class TrexStatelessDpCore {
+
+public:
+
+ /* states */
+ enum state_e {
+ STATE_IDLE,
+ STATE_TRANSMITTING
+ };
+
+ TrexStatelessDpCore(uint8_t thread_id, CFlowGenListPerThread *core);
+
+ /**
+ * launch the stateless DP core code
+ *
+ */
+ void start();
+
+ /**
+ * handle pkt event
+ *
+ * @author imarom (27-Oct-15)
+ */
+ void handle_pkt_event(CGenNode *node);
+
+ /**
+ * dummy traffic creator
+ *
+ * @author imarom (27-Oct-15)
+ *
+ * @param pkt
+ * @param pkt_len
+ */
+ void start_const_traffic(const uint8_t *pkt, uint16_t pkt_len, double pps);
+
+ /**
+ * stop all traffic for this core
+ *
+ */
+ void stop_traffic();
+
+ /**
+ * check for and handle messages from CP
+ *
+ * @author imarom (27-Oct-15)
+ */
+ void periodic_check_for_cp_messages() {
+ // doing this inline for performance reasons
+
+ /* fast path */
+ if ( likely ( m_ring_from_cp->isEmpty() ) ) {
+ return;
+ }
+
+ while ( true ) {
+ CGenNode * node;
+ if (m_ring_from_cp->Dequeue(node) != 0) {
+ break;
+ }
+
+ assert(node);
+
+ TrexStatelessCpToDpMsgBase * msg = (TrexStatelessCpToDpMsgBase *)node;
+ handle_cp_msg(msg);
+ }
+
+ }
+
+private:
+ /**
+ * handles a CP to DP message
+ *
+ * @author imarom (27-Oct-15)
+ *
+ * @param msg
+ */
+ void handle_cp_msg(TrexStatelessCpToDpMsgBase *msg);
+
+ uint8_t m_thread_id;
+ state_e m_state;
+ CNodeRing *m_ring_from_cp;
+ CNodeRing *m_ring_to_cp;
+
+ /* pointer to the main object */
+ CFlowGenListPerThread *m_core;
+};
+
+#endif /* __TREX_STATELESS_DP_CORE_H__ */
+
diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp
new file mode 100644
index 00000000..4cd5b416
--- /dev/null
+++ b/src/stateless/messaging/trex_stateless_messaging.cpp
@@ -0,0 +1,60 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <trex_stateless_messaging.h>
+#include <trex_stateless_dp_core.h>
+#include <string.h>
+
+/*************************
+ start traffic message
+ ************************/
+TrexStatelessDpStart::TrexStatelessDpStart(const uint8_t *pkt, uint16_t pkt_len, double pps) {
+ assert(pkt);
+ assert(pkt_len > 0);
+
+ m_pkt = new uint8_t[pkt_len];
+ memcpy(m_pkt, pkt, pkt_len);
+ m_pkt_len = pkt_len;
+
+ m_pps = pps;
+}
+
+TrexStatelessDpStart::~TrexStatelessDpStart() {
+ if (m_pkt) {
+ delete m_pkt;
+ }
+}
+
+bool
+TrexStatelessDpStart::handle(TrexStatelessDpCore *dp_core) {
+
+ dp_core->start_const_traffic(m_pkt, m_pkt_len, m_pps);
+ return true;
+}
+
+/*************************
+ stop traffic message
+ ************************/
+bool
+TrexStatelessDpStop::handle(TrexStatelessDpCore *dp_core) {
+ dp_core->stop_traffic();
+ return true;
+}
+
diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h
new file mode 100644
index 00000000..af05aa4c
--- /dev/null
+++ b/src/stateless/messaging/trex_stateless_messaging.h
@@ -0,0 +1,88 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#ifndef __TREX_STATELESS_MESSAGING_H__
+#define __TREX_STATELESS_MESSAGING_H__
+
+#include <msg_manager.h>
+
+class TrexStatelessDpCore;
+
+/**
+ * defines the base class for CP to DP messages
+ *
+ * @author imarom (27-Oct-15)
+ */
+class TrexStatelessCpToDpMsgBase {
+public:
+
+ TrexStatelessCpToDpMsgBase() {
+ }
+
+ virtual ~TrexStatelessCpToDpMsgBase() {
+ }
+
+ /**
+ * virtual function to handle a message
+ *
+ */
+ virtual bool handle(TrexStatelessDpCore *dp_core) = 0;
+};
+
+/**
+ * a message to start traffic
+ *
+ * @author imarom (27-Oct-15)
+ */
+class TrexStatelessDpStart : public TrexStatelessCpToDpMsgBase {
+public:
+
+ TrexStatelessDpStart(const uint8_t *pkt, uint16_t pkt_len, double pps);
+
+ ~TrexStatelessDpStart();
+
+ const uint8_t * get_pkt() {
+ return m_pkt;
+ }
+
+ uint16_t get_pkt_len() {
+ return m_pkt_len;
+ }
+
+ virtual bool handle(TrexStatelessDpCore *dp_core);
+
+private:
+ uint8_t *m_pkt;
+ uint16_t m_pkt_len;
+ double m_pps;
+};
+
+/**
+ * a message to stop traffic
+ *
+ * @author imarom (27-Oct-15)
+ */
+class TrexStatelessDpStop : public TrexStatelessCpToDpMsgBase {
+public:
+ virtual bool handle(TrexStatelessDpCore *dp_core);
+};
+
+
+#endif /* __TREX_STATELESS_MESSAGING_H__ */
diff --git a/src/stub/trex_stateless_stub.cpp b/src/stub/trex_stateless_stub.cpp
new file mode 100644
index 00000000..8e8d4fa8
--- /dev/null
+++ b/src/stub/trex_stateless_stub.cpp
@@ -0,0 +1,13 @@
+
+#include <trex_stateless_dp_core.h>
+
+class CFlowGenListPerThread;
+class TrexStatelessCpToDpMsgBase;
+
+TrexStatelessDpCore::TrexStatelessDpCore(unsigned char, CFlowGenListPerThread*) {}
+
+void TrexStatelessDpCore::start(){}
+
+void TrexStatelessDpCore::handle_cp_msg(TrexStatelessCpToDpMsgBase*) {}
+
+void TrexStatelessDpCore::handle_pkt_event(CGenNode*) {}