summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-10-11 14:42:24 +0200
committerimarom <imarom@cisco.com>2015-10-11 14:42:24 +0200
commit6c7880b9881ed6690954f0c29259dd0b584b3970 (patch)
treef8d23267dc0e086f1c622418e8bf68a04d38e64d
parent3b827c9584c28d3f1f573e372f646edfe9f5f007 (diff)
DP cores now inject a single packet as a dummy to see stats
-rwxr-xr-xlinux/ws_main.py17
-rwxr-xr-xsrc/bp_sim.h13
-rwxr-xr-xsrc/main_dpdk.cpp35
-rw-r--r--src/mock/rte_ethdev.h44
-rw-r--r--src/mock/trex_rpc_server_mock.cpp (renamed from src/rpc-server/trex_rpc_server_mock.cpp)0
-rw-r--r--src/rpc-server/trex_rpc_async_server.cpp12
-rw-r--r--src/rpc-server/trex_rpc_async_server.h2
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.cpp12
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.h2
-rw-r--r--src/rpc-server/trex_rpc_server.cpp9
-rw-r--r--src/rpc-server/trex_rpc_server_api.h7
-rw-r--r--src/stateless/cp/trex_stateless.cpp14
-rw-r--r--src/stateless/cp/trex_stateless.h4
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp77
-rw-r--r--src/stateless/cp/trex_stateless_port.h34
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp101
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.h1
-rwxr-xr-xsrc/tuple_gen.h5
18 files changed, 327 insertions, 62 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py
index 6dd0a813..eac46ac7 100755
--- a/linux/ws_main.py
+++ b/linux/ws_main.py
@@ -141,11 +141,12 @@ net_src = SrcGroup(dir='src/common/Network/Packet',
'VLANHeader.cpp']);
# stateless code
-stateless_src = SrcGroup(dir='src/stateless/cp/',
- src_list=['trex_stream.cpp',
- 'trex_stream_vm.cpp',
- 'trex_stateless.cpp',
- 'trex_stateless_port.cpp'
+stateless_src = SrcGroup(dir='src/stateless/',
+ src_list=['cp/trex_stream.cpp',
+ 'cp/trex_stream_vm.cpp',
+ 'cp/trex_stateless.cpp',
+ 'cp/trex_stateless_port.cpp',
+ 'dp/trex_stateless_dp_core.cpp'
])
# RPC code
rpc_server_src = SrcGroup(dir='src/rpc-server/',
@@ -164,10 +165,12 @@ rpc_server_src = SrcGroup(dir='src/rpc-server/',
])
# RPC mock server (test)
-rpc_server_mock_src = SrcGroup(dir='src/rpc-server/',
+rpc_server_mock_src = SrcGroup(dir='src/mock/',
src_list=[
'trex_rpc_server_mock.cpp',
'../gtest/rpc_test.cpp',
+ '../pal/linux/mbuf.cpp',
+ '../os_time.cpp',
])
# JSON package
@@ -235,8 +238,10 @@ cxxflags_base =['-DWIN_UCODE_SIM',
includes_path =''' ../src/pal/linux/
../src/
+ ../src/mock/
../src/rpc-server/
../src/stateless/cp/
+ ../src/stateless/dp/
../external_libs/json/
../external_libs/zmq/include/
../external_libs/yaml-cpp/include/
diff --git a/src/bp_sim.h b/src/bp_sim.h
index 2f445cb7..18cd9b97 100755
--- a/src/bp_sim.h
+++ b/src/bp_sim.h
@@ -221,7 +221,9 @@ private:
memset(m_pyload_mbuf_ptr+len+m_new_pkt_size,0xa,(-m_new_pkt_size));
}
+ return (0);
}
+
public:
int16_t m_new_pkt_size; /* New packet size after transform by plugin */
CFlowPktInfo * m_pkt_info;
@@ -302,7 +304,7 @@ public:
void CVirtualIFPerSideStats::Dump(FILE *fd){
- #define DP_B(f) if (f) printf(" %-40s : %llu \n",#f,f)
+ #define DP_B(f) if (f) printf(" %-40s : %lu \n",#f,f)
DP_B(m_tx_pkt);
DP_B(m_tx_rx_check_pkt);
DP_B(m_tx_bytes);
@@ -1440,7 +1442,7 @@ public:
inline bool is_eligible_from_server_side(){
- return ( (m_src_ip&1==1)?true:false);
+ return ( ( (m_src_ip&1) == 1)?true:false);
}
@@ -1647,7 +1649,7 @@ public:
*/
inline int check_objects_sizes(void){
if ( sizeof(CGenNodeDeferPort) != sizeof(CGenNode) ) {
- printf("ERROR sizeof(CGenNodeDeferPort) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeDeferPort),sizeof(CGenNode));
+ printf("ERROR sizeof(CGenNodeDeferPort) %lu != sizeof(CGenNode) %lu must be the same size \n",sizeof(CGenNodeDeferPort),sizeof(CGenNode));
assert(0);
}
if ( (int)offsetof(struct CGenNodeDeferPort,m_type)!=offsetof(struct CGenNode,m_type) ){
@@ -2587,6 +2589,8 @@ inline void CFlowPktInfo::update_pkt_info2(char *p,
EthernetHeader * et =
(EthernetHeader * )(p + m_pkt_indication.getFastEtherOffset());
+ (void)et;
+
if ( unlikely (m_pkt_indication.is_ipv6())) {
IPv6Header *ipv6= (IPv6Header *)ipv4;
@@ -2669,6 +2673,8 @@ inline void CFlowPktInfo::update_pkt_info(char *p,
EthernetHeader * et =
(EthernetHeader * )(p + m_pkt_indication.getFastEtherOffset());
+ (void)et;
+
uint16_t src_port = node->m_src_port;
pkt_dir_t ip_dir = node->cur_pkt_ip_addr_dir();
@@ -2869,6 +2875,7 @@ inline rte_mbuf_t * CFlowPktInfo::do_generate_new_mbuf_ex_vm(CGenNode * node,
/* need to update the mbuf size here .., this is not must but needed for accuracy */
uint16_t buf_adjust = len - vm.m_new_pkt_size;
int rc = rte_pktmbuf_trim(m, buf_adjust);
+ (void)rc;
/* update IP length , and TCP checksum , we can accelerate this using hardware ! */
uint16_t pkt_adjust = vm.m_new_pkt_size - m_packet->pkt_len;
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 36d5052e..fe972d2f 100755
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -2735,7 +2735,7 @@ public:
}
public:
- bool Create();
+ bool Create(bool is_stateless);
void Delete();
int ixgbe_prob_init();
@@ -3409,18 +3409,22 @@ int CGlobalPortCfg::ixgbe_start(void){
}
-bool CGlobalPortCfg::Create(){
-
- if ( !m_zmq_publisher.Create( CGlobalInfo::m_options.m_zmq_port,
- !CGlobalInfo::m_options.preview.get_zmq_publish_enable() ) ){
- return (false);
- }
+bool CGlobalPortCfg::Create(bool is_stateless){
+ /* hack - need to refactor */
+ if (!is_stateless) {
+ if ( !m_zmq_publisher.Create( CGlobalInfo::m_options.m_zmq_port,
+ !CGlobalInfo::m_options.preview.get_zmq_publish_enable() ) ){
+ return (false);
+ }
+ }
/* We load the YAML twice,
this is the first time. to update global flags */
CFlowsYamlInfo pre_yaml_info;
- pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file);
+ if (!is_stateless) {
+ pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file);
+ }
if ( pre_yaml_info.m_vlan_info.m_enable ){
CGlobalInfo::m_options.preview.set_vlan_mode_enable(true);
@@ -4513,12 +4517,6 @@ int main_test(int argc , char * argv[]){
rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
}
- /* patch here */
- if (CGlobalInfo::m_options.m_run_mode == CParserOption::RUN_MODE_INTERACTIVE) {
- return launch_stateless_trex();
- }
-
-
time_init();
/* check if we are in simulation mode */
@@ -4527,11 +4525,18 @@ int main_test(int argc , char * argv[]){
return ( sim_load_list_of_cap_files(&CGlobalInfo::m_options) );
}
+ bool is_stateless = (CGlobalInfo::m_options.m_run_mode == CParserOption::RUN_MODE_INTERACTIVE);
- if ( !ports_cfg.Create() ){
+ if ( !ports_cfg.Create(is_stateless) ){
exit(1);
}
+ /* patch here */
+ if (is_stateless) {
+ return launch_stateless_trex();
+ }
+
+
if (po->preview.get_is_rx_check_enable() && (po->m_rx_check_sampe< get_min_sample_rate()) ) {
po->m_rx_check_sampe = get_min_sample_rate();
printf("Warning rx check sample rate should be lower than %d setting it to %d\n",get_min_sample_rate(),get_min_sample_rate());
diff --git a/src/mock/rte_ethdev.h b/src/mock/rte_ethdev.h
new file mode 100644
index 00000000..046d8366
--- /dev/null
+++ b/src/mock/rte_ethdev.h
@@ -0,0 +1,44 @@
+/*
+ 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 __MOCK_FILE_RTE_ETHDEV_H__
+#define __MOCK_FILE_RTE_ETHDEV_H__
+
+#include <string.h>
+
+struct rte_eth_stats {
+ uint64_t obytes;
+ uint64_t ibytes;
+ uint64_t opackets;
+ uint64_t ipackets;
+};
+
+static inline void
+rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats) {
+ memset(stats, 0, sizeof(rte_eth_stats));
+}
+
+static inline uint16_t
+rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts) {
+ return (0);
+}
+
+#endif /* __MOCK_FILE_RTE_ETHDEV_H__ */
diff --git a/src/rpc-server/trex_rpc_server_mock.cpp b/src/mock/trex_rpc_server_mock.cpp
index de43f92f..de43f92f 100644
--- a/src/rpc-server/trex_rpc_server_mock.cpp
+++ b/src/mock/trex_rpc_server_mock.cpp
diff --git a/src/rpc-server/trex_rpc_async_server.cpp b/src/rpc-server/trex_rpc_async_server.cpp
index 3313e42e..f4d21f2f 100644
--- a/src/rpc-server/trex_rpc_async_server.cpp
+++ b/src/rpc-server/trex_rpc_async_server.cpp
@@ -36,7 +36,7 @@ limitations under the License.
* ZMQ based publisher server
*
*/
-TrexRpcServerAsync::TrexRpcServerAsync(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "publisher") {
+TrexRpcServerAsync::TrexRpcServerAsync(const TrexRpcServerConfig &cfg, std::mutex *lock) : TrexRpcServerInterface(cfg, "publisher", lock) {
/* ZMQ is not thread safe - this should be outside */
m_context = zmq_ctx_new();
}
@@ -73,9 +73,19 @@ TrexRpcServerAsync::_rpc_thread_cb() {
Json::Value snapshot;
Json::FastWriter writer;
+ /* if lock was provided - take it */
+ if (m_lock) {
+ m_lock->lock();
+ }
+
/* trigger a full update for stats */
TrexStateless::get_instance().update_stats();
+ /* done with the lock */
+ if (m_lock) {
+ m_lock->unlock();
+ }
+
/* encode them to JSON */
TrexStateless::get_instance().encode_stats(snapshot);
diff --git a/src/rpc-server/trex_rpc_async_server.h b/src/rpc-server/trex_rpc_async_server.h
index 13525c01..02d1490e 100644
--- a/src/rpc-server/trex_rpc_async_server.h
+++ b/src/rpc-server/trex_rpc_async_server.h
@@ -33,7 +33,7 @@ limitations under the License.
class TrexRpcServerAsync : public TrexRpcServerInterface {
public:
- TrexRpcServerAsync(const TrexRpcServerConfig &cfg);
+ TrexRpcServerAsync(const TrexRpcServerConfig &cfg, std::mutex *lock = NULL);
protected:
void _rpc_thread_cb();
diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp
index 3d52686c..9147f75d 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.cpp
+++ b/src/rpc-server/trex_rpc_req_resp_server.cpp
@@ -34,7 +34,7 @@ limitations under the License.
* ZMQ based request-response server
*
*/
-TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg) : TrexRpcServerInterface(cfg, "req resp") {
+TrexRpcServerReqRes::TrexRpcServerReqRes(const TrexRpcServerConfig &cfg, std::mutex *lock) : TrexRpcServerInterface(cfg, "req resp", lock) {
/* ZMQ is not thread safe - this should be outside */
m_context = zmq_ctx_new();
}
@@ -127,6 +127,11 @@ void TrexRpcServerReqRes::handle_request(const std::string &request) {
int index = 0;
+ /* if lock was provided, take it */
+ if (m_lock) {
+ m_lock->lock();
+ }
+
/* for every command parsed - launch it */
for (auto command : commands) {
Json::Value single_response;
@@ -138,6 +143,11 @@ void TrexRpcServerReqRes::handle_request(const std::string &request) {
}
+ /* done with the lock */
+ if (m_lock) {
+ m_lock->unlock();
+ }
+
/* write the JSON to string and sever on ZMQ */
std::string response_str;
diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h
index 7c1d66d1..1f638adf 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.h
+++ b/src/rpc-server/trex_rpc_req_resp_server.h
@@ -32,7 +32,7 @@ limitations under the License.
class TrexRpcServerReqRes : public TrexRpcServerInterface {
public:
- TrexRpcServerReqRes(const TrexRpcServerConfig &cfg);
+ TrexRpcServerReqRes(const TrexRpcServerConfig &cfg, std::mutex *lock = NULL);
protected:
void _rpc_thread_cb();
diff --git a/src/rpc-server/trex_rpc_server.cpp b/src/rpc-server/trex_rpc_server.cpp
index 8749c9b4..a14e6f97 100644
--- a/src/rpc-server/trex_rpc_server.cpp
+++ b/src/rpc-server/trex_rpc_server.cpp
@@ -30,7 +30,7 @@ limitations under the License.
/************** RPC server interface ***************/
-TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name) : m_cfg(cfg), m_name(name) {
+TrexRpcServerInterface::TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name, std::mutex *lock) : m_cfg(cfg), m_name(name), m_lock(lock) {
m_is_running = false;
m_is_verbose = false;
}
@@ -114,16 +114,17 @@ get_current_date_time() {
const std::string TrexRpcServer::s_server_uptime = get_current_date_time();
TrexRpcServer::TrexRpcServer(const TrexRpcServerConfig *req_resp_cfg,
- const TrexRpcServerConfig *async_cfg) {
+ const TrexRpcServerConfig *async_cfg,
+ std::mutex *lock) {
/* add the request response server */
if (req_resp_cfg) {
- m_servers.push_back(new TrexRpcServerReqRes(*req_resp_cfg));
+ m_servers.push_back(new TrexRpcServerReqRes(*req_resp_cfg, lock));
}
/* add async publisher */
if (async_cfg) {
- m_servers.push_back(new TrexRpcServerAsync(*async_cfg));
+ m_servers.push_back(new TrexRpcServerAsync(*async_cfg, lock));
}
}
diff --git a/src/rpc-server/trex_rpc_server_api.h b/src/rpc-server/trex_rpc_server_api.h
index 327c6eaa..ff876ac4 100644
--- a/src/rpc-server/trex_rpc_server_api.h
+++ b/src/rpc-server/trex_rpc_server_api.h
@@ -24,6 +24,7 @@ limitations under the License.
#include <stdint.h>
#include <vector>
+#include <mutex>
#include <thread>
#include <string>
#include <stdexcept>
@@ -68,7 +69,7 @@ private:
class TrexRpcServerInterface {
public:
- TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name);
+ TrexRpcServerInterface(const TrexRpcServerConfig &cfg, const std::string &name, std::mutex *m_lock = NULL);
virtual ~TrexRpcServerInterface();
/**
@@ -127,6 +128,7 @@ protected:
bool m_is_verbose;
std::thread *m_thread;
std::string m_name;
+ std::mutex *m_lock;
};
/**
@@ -141,7 +143,8 @@ public:
/* creates the collection of servers using configurations */
TrexRpcServer(const TrexRpcServerConfig *req_resp_cfg,
- const TrexRpcServerConfig *async_cfg);
+ const TrexRpcServerConfig *async_cfg,
+ std::mutex *m_lock = NULL);
~TrexRpcServer();
diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp
index 20e001c9..72762e26 100644
--- a/src/stateless/cp/trex_stateless.cpp
+++ b/src/stateless/cp/trex_stateless.cpp
@@ -50,7 +50,9 @@ void TrexStateless::configure(const TrexStatelessCfg &cfg) {
}
/* create RPC servers */
- instance.m_rpc_server = new TrexRpcServer(cfg.m_rpc_req_resp_cfg, cfg.m_rpc_async_cfg);
+
+ /* set both servers to mutex each other */
+ instance.m_rpc_server = new TrexRpcServer(cfg.m_rpc_req_resp_cfg, cfg.m_rpc_async_cfg, &instance.m_global_cp_lock);
instance.m_rpc_server->set_verbose(cfg.m_rpc_server_verbose);
/* configure ports */
@@ -152,12 +154,10 @@ TrexStateless::get_dp_core_count() {
void
TrexStateless::update_stats() {
- /* update CPU util. */
- #ifdef TREX_RPC_MOCK_SERVER
- m_stats.m_stats.m_cpu_util = 0;
- #else
- m_stats.m_stats.m_cpu_util = 0;
- #endif
+ /* update CPU util.
+ TODO
+ */
+ m_stats.m_stats.m_cpu_util = 0;
/* for every port update and accumulate */
for (uint8_t i = 0; i < m_port_count; i++) {
diff --git a/src/stateless/cp/trex_stateless.h b/src/stateless/cp/trex_stateless.h
index ef612e84..649b25dd 100644
--- a/src/stateless/cp/trex_stateless.h
+++ b/src/stateless/cp/trex_stateless.h
@@ -25,6 +25,8 @@ limitations under the License.
#include <string>
#include <stdexcept>
+#include <mutex>
+
#include <trex_stream.h>
#include <trex_stateless_port.h>
#include <trex_stateless_dp_core.h>
@@ -192,6 +194,8 @@ protected:
/* stats */
TrexStatelessStats m_stats;
+
+ std::mutex m_global_cp_lock;
};
#endif /* __TREX_STATELESS_H__ */
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 240b7582..f745bee9 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -28,6 +28,7 @@ limitations under the License.
// DPDK c++ issue
#include <rte_ethdev.h>
+#include <os_time.h>
using namespace std;
@@ -133,28 +134,23 @@ TrexStatelessPort::generate_handler() {
*/
void
TrexStatelessPort::update_stats() {
- #ifdef TREX_RPC_MOCK_SERVER
- /* do lies - its a mock */
- m_stats.m_stats.m_tx_bps = rand() % 10000;
- m_stats.m_stats.m_rx_bps = rand() % 10000;
+ struct rte_eth_stats stats;
+ rte_eth_stats_get(m_port_id, &stats);
- m_stats.m_stats.m_tx_pps = m_stats.m_stats.m_tx_bps / (64 + rand() % 1000);
- m_stats.m_stats.m_rx_pps = m_stats.m_stats.m_rx_bps / (64 + rand() % 1000);
+ /* copy straight values */
+ m_stats.m_stats.m_total_tx_bytes = stats.obytes;
+ m_stats.m_stats.m_total_rx_bytes = stats.ibytes;
+ m_stats.m_stats.m_total_tx_pkts = stats.opackets;
+ m_stats.m_stats.m_total_rx_pkts = stats.ipackets;
- m_stats.m_stats.m_total_tx_bytes += m_stats.m_stats.m_tx_bps;
- m_stats.m_stats.m_total_rx_bytes += m_stats.m_stats.m_rx_bps;
+ /* calculate stats */
+ m_stats.m_stats.m_tx_bps = m_stats.m_bw_tx_bps.add(stats.obytes);
+ m_stats.m_stats.m_rx_bps = m_stats.m_bw_rx_bps.add(stats.ibytes);
- m_stats.m_stats.m_total_tx_pkts += m_stats.m_stats.m_tx_pps;
- m_stats.m_stats.m_total_rx_pkts += m_stats.m_stats.m_rx_pps;
+ m_stats.m_stats.m_tx_pps = m_stats.m_bw_tx_pps.add(stats.opackets);
+ m_stats.m_stats.m_rx_pps = m_stats.m_bw_rx_pps.add(stats.ipackets);
- #else
- /* real update work */
- struct rte_eth_stats stats;
- rte_eth_stats_get(m_port_id, &stats);
- printf("ipackets is %u\n", stats.ipackets);
- printf("opackets is %u\n", stats.opackets);
- #endif
}
const TrexPortStats &
@@ -181,3 +177,50 @@ TrexStatelessPort::encode_stats(Json::Value &port) {
}
+
+/***************************
+ * BW measurement
+ *
+ **************************/
+/* TODO: move this to a common place */
+BWMeasure::BWMeasure() {
+ reset();
+}
+
+void BWMeasure::reset(void) {
+ m_start=false;
+ m_last_time_msec=0;
+ m_last_bytes=0;
+ m_last_result=0.0;
+};
+
+double BWMeasure::calc_MBsec(uint32_t dtime_msec,
+ uint64_t dbytes){
+ double rate=0.000008*( ( (double)dbytes*(double)os_get_time_freq())/((double)dtime_msec) );
+ return(rate);
+}
+
+double BWMeasure::add(uint64_t size) {
+ if ( false == m_start ) {
+ m_start=true;
+ m_last_time_msec = os_get_time_msec() ;
+ m_last_bytes=size;
+ return(0.0);
+ }
+
+ uint32_t ctime=os_get_time_msec();
+ if ((ctime - m_last_time_msec) <os_get_time_freq() ) {
+ return(m_last_result);
+ }
+
+ uint32_t dtime_msec = ctime-m_last_time_msec;
+ uint64_t dbytes = size - m_last_bytes;
+
+ m_last_time_msec = ctime;
+ m_last_bytes = size;
+
+ m_last_result= 0.5*calc_MBsec(dtime_msec,dbytes) +0.5*(m_last_result);
+ return( m_last_result );
+}
+
+
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index a19fd981..428d5aee 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -24,6 +24,27 @@ limitations under the License.
#include <trex_stream.h>
/**
+ * bandwidth measurement class
+ *
+ */
+class BWMeasure {
+public:
+ BWMeasure();
+ void reset(void);
+ double add(uint64_t size);
+
+private:
+ double calc_MBsec(uint32_t dtime_msec,
+ uint64_t dbytes);
+
+public:
+ bool m_start;
+ uint32_t m_last_time_msec;
+ uint64_t m_last_bytes;
+ double m_last_result;
+};
+
+/**
* TRex stateless port stats
*
* @author imarom (24-Sep-15)
@@ -33,9 +54,22 @@ class TrexPortStats {
public:
TrexPortStats() {
m_stats = {0};
+
+ m_bw_tx_bps.reset();
+ m_bw_rx_bps.reset();
+
+ m_bw_tx_pps.reset();
+ m_bw_rx_pps.reset();
}
public:
+
+ BWMeasure m_bw_tx_bps;
+ BWMeasure m_bw_rx_bps;
+
+ BWMeasure m_bw_tx_pps;
+ BWMeasure m_bw_rx_pps;
+
struct {
double m_tx_bps;
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index 4e9309ab..1c96487d 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -24,14 +24,109 @@ limitations under the License.
#include <unistd.h>
#include <trex_stateless.h>
+#include <bp_sim.h>
+
+// DPDK c++ issue
+#define UINT8_MAX 255
+#define UINT16_MAX 0xFFFF
+// DPDK c++ issue
+
+#include <rte_ethdev.h>
+#include "mbuf.h"
+
+/**
+ * TEST
+ *
+ */
+static const uint8_t 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
+};
+
+static int
+test_inject_pkt(uint8_t *pkt, uint32_t pkt_size) {
+
+ #ifndef TREX_RPC_MOCK_SERVER
+ rte_mempool_t * mp= CGlobalInfo::m_mem_pool[0].m_big_mbuf_pool ;
+ #else
+ rte_mempool_t * mp = NULL;
+ #endif
+
+ rte_mbuf_t *m = rte_pktmbuf_alloc(mp);
+ if ( unlikely(m==0) ) {
+ printf("ERROR no packets \n");
+ return (-1);
+ }
+ char *p = rte_pktmbuf_append(m, pkt_size);
+ assert(p);
+ /* set pkt data */
+ memcpy(p,pkt,pkt_size);
+
+ rte_mbuf_t *tx_pkts[32];
+ tx_pkts[0] = m;
+ uint8_t nb_pkts = 1;
+ uint16_t ret = rte_eth_tx_burst(0, 0, tx_pkts, nb_pkts);
+ (void)ret;
+ rte_pktmbuf_free(m);
+
+ return (0);
+}
+
+static int
+test_inject_udp_pkt(){
+ return (test_inject_pkt((uint8_t*)udp_pkt,sizeof(udp_pkt)));
+}
+
+void
+TrexStatelessDpCore::test_inject_dummy_pkt() {
+ test_inject_udp_pkt();
+}
+
+/***************************
+ * DP core
+ *
+ **************************/
TrexStatelessDpCore::TrexStatelessDpCore(uint8_t core_id) : m_core_id(core_id) {
}
+/**
+ * main function for DP core
+ *
+ */
void
TrexStatelessDpCore::run() {
- printf("On DP core %d\n", m_core_id);
+ printf("\nOn DP core %d\n", m_core_id);
while (true) {
- sleep(1);
- TrexStateless::get_instance().get_port_by_id(0)->update_stats();
+ test_inject_dummy_pkt();
+ rte_pause();
}
}
+
diff --git a/src/stateless/dp/trex_stateless_dp_core.h b/src/stateless/dp/trex_stateless_dp_core.h
index d428bac2..4b09b752 100644
--- a/src/stateless/dp/trex_stateless_dp_core.h
+++ b/src/stateless/dp/trex_stateless_dp_core.h
@@ -36,6 +36,7 @@ public:
void run();
private:
+ void test_inject_dummy_pkt();
uint8_t m_core_id;
};
diff --git a/src/tuple_gen.h b/src/tuple_gen.h
index fb856538..c0add0be 100755
--- a/src/tuple_gen.h
+++ b/src/tuple_gen.h
@@ -113,6 +113,9 @@ class CIpInfoBase {
void set_ip(uint32_t ip) {
m_ip = ip;
}
+
+ virtual ~CIpInfoBase() {}
+
public:
uint32_t m_ip;
};
@@ -388,7 +391,7 @@ class CIpPool {
(ip<=ip_back->get_ip())) {
return(true);
}
- printf("invalid ip:%x, min_ip:%x, max_ip:%x, this:%x\n",
+ printf("invalid ip:%x, min_ip:%x, max_ip:%x, this:%p\n",
ip, ip_front->get_ip(),
ip_back->get_ip(),this);
return(false);