summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2015-11-11 22:10:05 +0200
committerHanoh Haim <hhaim@cisco.com>2015-11-11 22:10:05 +0200
commit151266e34245b99ce4cac70d82be79bfb5a3ebf9 (patch)
tree76bb6bad5d8b25e2918bc1e427c05618e647edec /src/stateless
parent6294136db42a3327049c67c12eab4684c4abbe47 (diff)
add support for multi-burst
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_stream.h42
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp29
-rw-r--r--src/stateless/cp/trex_streams_compiler.h13
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp61
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h7
-rw-r--r--src/stateless/dp/trex_stream_node.h90
6 files changed, 166 insertions, 76 deletions
diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h
index d1a44909..5e6ac19a 100644
--- a/src/stateless/cp/trex_stream.h
+++ b/src/stateless/cp/trex_stream.h
@@ -39,6 +39,15 @@ class TrexRpcCmdAddStream;
class TrexStream {
public:
+ enum STREAM_TYPE {
+ stNONE = 0,
+ stCONTINUOUS = 4,
+ stSINGLE_BURST = 5,
+ stMULTI_BURST = 6
+ };
+
+
+public:
TrexStream(uint8_t port_id, uint32_t stream_id);
virtual ~TrexStream();
@@ -52,8 +61,14 @@ public:
/* access the stream json */
const Json::Value & get_stream_json();
+ double get_pps() {
+ return m_pps;
+ }
+
+
public:
/* basic */
+ uint8_t m_type;
uint8_t m_port_id;
uint32_t m_stream_id;
@@ -85,6 +100,8 @@ public:
} m_rx_check;
+ double m_pps;
+
/* original template provided by requester */
Json::Value m_stream_json;
@@ -98,15 +115,10 @@ public:
*/
class TrexStreamContinuous : public TrexStream {
public:
- TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, double pps) : TrexStream(port_id, stream_id), m_pps(pps) {
+ TrexStreamContinuous(uint8_t port_id, uint32_t stream_id, double pps) : TrexStream(port_id, stream_id) {
+ m_type= TrexStream::stCONTINUOUS;
+ m_pps=pps;
}
-
- double get_pps() {
- return m_pps;
- }
-
-protected:
- double m_pps;
};
/**
@@ -117,13 +129,14 @@ class TrexStreamBurst : public TrexStream {
public:
TrexStreamBurst(uint8_t port_id, uint32_t stream_id, uint32_t total_pkts, double pps) :
TrexStream(port_id, stream_id),
- m_total_pkts(total_pkts),
- m_pps(pps) {
+ m_total_pkts(total_pkts){
+ m_type= TrexStream::stSINGLE_BURST;
+ m_pps=pps;
+
}
-protected:
+public:
uint32_t m_total_pkts;
- double m_pps;
};
/**
@@ -138,9 +151,10 @@ public:
double pps,
uint32_t num_bursts,
double ibg_usec) : TrexStreamBurst(port_id, stream_id, pkts_per_burst, pps), m_num_bursts(num_bursts), m_ibg_usec(ibg_usec) {
-
+ m_type= TrexStream::stMULTI_BURST;
}
-protected:
+
+public:
uint32_t m_num_bursts;
double m_ibg_usec;
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index 7891077b..c7b881c5 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -30,24 +30,15 @@ TrexStreamsCompiledObj::TrexStreamsCompiledObj(uint8_t port_id, double mul) : m_
}
TrexStreamsCompiledObj::~TrexStreamsCompiledObj() {
- for (auto &obj : m_objs) {
- delete [] obj.m_pkt;
- }
m_objs.clear();
m_duration_sim=-1.0;
}
void
-TrexStreamsCompiledObj::add_compiled_stream(double isg_usec, double pps, uint8_t *pkt, uint16_t pkt_len) {
+TrexStreamsCompiledObj::add_compiled_stream(TrexStream * stream) {
obj_st obj;
- obj.m_isg_usec = isg_usec;
- obj.m_port_id = m_port_id;
- obj.m_pps = pps * m_mul;
- obj.m_pkt_len = pkt_len;
-
- obj.m_pkt = new uint8_t[pkt_len];
- memcpy(obj.m_pkt, pkt, pkt_len);
+ obj.m_stream = stream;
m_objs.push_back(obj);
}
@@ -62,10 +53,7 @@ TrexStreamsCompiledObj::clone() {
* clone each element
*/
for (auto obj : m_objs) {
- new_compiled_obj->add_compiled_stream(obj.m_isg_usec,
- obj.m_pps,
- obj.m_pkt,
- obj.m_pkt_len);
+ new_compiled_obj->add_compiled_stream(obj.m_stream);
}
new_compiled_obj->m_mul = m_mul;
@@ -93,17 +81,8 @@ TrexStreamsCompiler::compile(const std::vector<TrexStream *> &streams, TrexStrea
continue;
}
- /* for now support only continous ... */
- TrexStreamContinuous *cont_stream = dynamic_cast<TrexStreamContinuous *>(stream);
- if (!cont_stream) {
- continue;
- }
-
/* add it */
- obj.add_compiled_stream(cont_stream->m_isg_usec,
- cont_stream->get_pps(),
- cont_stream->m_pkt.binary,
- cont_stream->m_pkt.len);
+ obj.add_compiled_stream(stream);
}
return true;
diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h
index d86d16c6..78ac1ac7 100644
--- a/src/stateless/cp/trex_streams_compiler.h
+++ b/src/stateless/cp/trex_streams_compiler.h
@@ -40,11 +40,8 @@ public:
~TrexStreamsCompiledObj();
struct obj_st {
- double m_isg_usec;
- double m_pps;
- uint8_t *m_pkt;
- uint16_t m_pkt_len;
- uint8_t m_port_id;
+
+ TrexStream * m_stream;
};
const std::vector<obj_st> & get_objects() {
@@ -64,8 +61,12 @@ public:
*/
TrexStreamsCompiledObj * clone();
+ double get_multiplier(){
+ return (m_mul);
+ }
+
private:
- void add_compiled_stream(double isg_usec, double pps, uint8_t *pkt, uint16_t pkt_len);
+ void add_compiled_stream(TrexStream * stream);
std::vector<obj_st> m_objs;
uint8_t m_port_id;
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index e1664bd9..899e14be 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -22,6 +22,7 @@ limitations under the License.
#include <trex_stateless_messaging.h>
#include <trex_streams_compiler.h>
#include <trex_stream_node.h>
+#include <trex_stream.h>
#include <bp_sim.h>
@@ -124,33 +125,64 @@ TrexStatelessDpCore::add_duration(double duration){
void
-TrexStatelessDpCore::add_cont_stream(uint8_t port_id,
- double isg_usec,
- double pps,
- const uint8_t *pkt,
- uint16_t pkt_len) {
+TrexStatelessDpCore::add_cont_stream(TrexStream * stream,
+ TrexStreamsCompiledObj *comp) {
CGenNodeStateless *node = m_core->create_node_sl();
/* add periodic */
node->m_type = CGenNode::STATELESS_PKT;
- node->m_time = m_core->m_cur_time_sec + usec_to_sec(isg_usec);
+ node->m_time = m_core->m_cur_time_sec + usec_to_sec(stream->m_isg_usec);
- pkt_dir_t dir = m_core->m_node_gen.m_v_if->port_id_to_dir(port_id);
+ pkt_dir_t dir = m_core->m_node_gen.m_v_if->port_id_to_dir(stream->m_port_id);
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;
+
+ uint16_t pkt_size = stream->m_pkt.len;
+ const uint8_t *stream_pkt = stream->m_pkt.binary;
+
+ TrexStreamBurst * lpburst;
+ TrexStreamMultiBurst * lpmulti;
+
+ node->m_stream_type = stream->m_type;
+ node->m_next_time_offset = 1.0 / (stream->get_pps() * comp->get_multiplier()) ;
+
/* stateless specific fields */
- node->m_next_time_offset = 1.0 / pps;
+ switch ( stream->m_type ) {
+
+ case TrexStream::stCONTINUOUS :
+ break;
+
+ case TrexStream::stSINGLE_BURST :
+ node->m_stream_type = TrexStream::stMULTI_BURST;
+ lpburst = (TrexStreamBurst *)stream;
+ node->m_single_burst = lpburst->m_total_pkts;
+ node->m_single_burst_refill = lpburst->m_total_pkts;
+ node->m_multi_bursts = 1; /* single burst in multi burst of 1 */
+ node->m_ibg_sec = 0.0;
+ break;
+
+ case TrexStream::stMULTI_BURST :
+ lpmulti =(TrexStreamMultiBurst *)stream;
+
+ node->m_single_burst = lpmulti->m_total_pkts;
+ node->m_single_burst_refill = lpmulti->m_total_pkts ;
+ node->m_multi_bursts = lpmulti->m_num_bursts;
+ node->m_ibg_sec = usec_to_sec( lpmulti->m_ibg_usec );
+ break;
+ default:
+
+ assert(0);
+ };
+
node->m_is_stream_active = 1;
- node->m_port_id = port_id;
+ node->m_port_id = stream->m_port_id;
/* allocate const mbuf */
rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc(node->get_socket_id(), pkt_size);
@@ -183,15 +215,10 @@ TrexStatelessDpCore::add_cont_stream(uint8_t port_id,
void
TrexStatelessDpCore::start_traffic(TrexStreamsCompiledObj *obj) {
for (auto single_stream : obj->get_objects()) {
- add_cont_stream(single_stream.m_port_id,
- single_stream.m_isg_usec,
- single_stream.m_pps,
- single_stream.m_pkt,
- single_stream.m_pkt_len);
+ add_cont_stream(single_stream.m_stream,obj);
}
double duration=obj->get_simulation_duration();
- printf("duration %f \n",duration);
if ( duration >0.0){
add_duration( duration );
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index 51f882b2..1029213d 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -31,6 +31,7 @@ class TrexStatelessDpStart;
class CFlowGenListPerThread;
class CGenNodeStateless;
class TrexStreamsCompiledObj;
+class TrexStream;
class TrexStatelessDpCore {
@@ -134,11 +135,7 @@ private:
/* add global exit */
void add_duration(double duration);
- void add_cont_stream(uint8_t dir,
- double isg,
- double pps,
- const uint8_t *pkt,
- uint16_t pkt_len);
+ void add_cont_stream(TrexStream * stream,TrexStreamsCompiledObj *comp);
uint8_t m_thread_id;
state_e m_state;
diff --git a/src/stateless/dp/trex_stream_node.h b/src/stateless/dp/trex_stream_node.h
index 2ffe04c3..e4cf964d 100644
--- a/src/stateless/dp/trex_stream_node.h
+++ b/src/stateless/dp/trex_stream_node.h
@@ -25,6 +25,7 @@ limitations under the License.
#include <stdio.h>
class TrexStatelessDpCore;
+#include <trex_stream.h>
/* this is a event for stateless */
struct CGenNodeStateless : public CGenNodeBase {
@@ -33,28 +34,51 @@ friend class TrexStatelessDpCore;
private:
void * m_cache_mbuf;
- double m_next_time_offset;
+ double m_next_time_offset; /* in sec */
+ double m_ibg_sec; /* inter burst time in sec */
+
+
uint8_t m_is_stream_active;
uint8_t m_port_id;
+ uint8_t m_stream_type; /* TrexStream::STREAM_TYPE */
+ uint8_t m_pad;
+
+ uint32_t m_single_burst; /* the number of bursts in case of burst */
+ uint32_t m_single_burst_refill;
+
+ uint32_t m_multi_bursts; /* in case of multi_burst how many bursts */
+
+
/* pad to match the size of CGenNode */
- uint8_t m_pad_end[87];
+ uint8_t m_pad_end[65];
public:
+ inline uint8_t get_stream_type(){
+ return (m_stream_type);
+ }
+
+ inline uint32_t get_single_burst_cnt(){
+ return (m_single_burst);
+ }
+
+ inline double get_multi_ibg_sec(){
+ return (m_ibg_sec);
+ }
+
+ inline uint32_t get_multi_burst_cnt(){
+ return (m_multi_bursts);
+ }
+
inline bool is_active() {
return m_is_stream_active;
}
-
- /**
- * main function to handle an event of a packet tx
- *
- */
- inline void handle(CFlowGenListPerThread *thread) {
+ inline void handle_continues(CFlowGenListPerThread *thread) {
thread->m_node_gen.m_v_if->send_node( (CGenNode *)this);
/* in case of continues */
@@ -64,6 +88,51 @@ public:
thread->m_node_gen.m_p_queue.push( (CGenNode *)this);
}
+ inline void handle_multi_burst(CFlowGenListPerThread *thread) {
+ thread->m_node_gen.m_v_if->send_node( (CGenNode *)this);
+
+ m_single_burst--;
+ if (m_single_burst > 0 ) {
+ /* in case of continues */
+ m_time += m_next_time_offset;
+
+ thread->m_node_gen.m_p_queue.push( (CGenNode *)this);
+ }else{
+ m_multi_bursts--;
+ if ( m_multi_bursts == 0 ) {
+ /* stop */
+ m_is_stream_active =0;
+ }else{
+ m_time += m_ibg_sec;
+ m_single_burst = m_single_burst_refill;
+
+ }
+ thread->m_node_gen.m_p_queue.push( (CGenNode *)this);
+ }
+ }
+
+
+ /**
+ * main function to handle an event of a packet tx
+ *
+ *
+ *
+ */
+
+ inline void handle(CFlowGenListPerThread *thread) {
+
+ if (m_stream_type == TrexStream::stCONTINUOUS ) {
+ handle_continues(thread) ;
+ }else{
+ if (m_stream_type == TrexStream::stMULTI_BURST) {
+ handle_multi_burst(thread);
+ }else{
+ assert(0);
+ }
+ }
+
+ }
+
void set_socket_id(socket_id_t socket){
m_socket_id=socket;
}
@@ -106,6 +175,9 @@ public:
} __rte_cache_aligned;
-static_assert(sizeof(CGenNodeStateless) == sizeof(CGenNode), "sizeof(CGenNodeStateless) != sizeof(CGenNode)");
+static_assert(sizeof(CGenNodeStateless) == sizeof(CGenNode), "sizeof(CGenNodeStateless) != sizeof(CGenNode)" );
+
+
+
#endif /* __TREX_STREAM_NODE_H__ */