From b77fef12a08d6d964e522eea6b2d846dfcc98b08 Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 26 Oct 2015 18:13:18 +0200 Subject: RPC control plane now integarted with DPDK --- linux/ws_main.py | 2 +- linux_dpdk/ws_main.py | 1 - src/bp_sim.h | 8 +- src/gtest/rpc_test.cpp | 9 +- src/internal_api/trex_platform_api.h | 130 ++++++++++++++++++ src/main_dpdk.cpp | 123 ++++++++++------- src/mock/trex_platform_api_mock.cpp | 49 +++++++ src/mock/trex_rpc_server_mock.cpp | 104 +++++++++++++-- src/pal/linux/mbuf.h | 2 + src/rpc-server/commands/trex_rpc_cmd_general.cpp | 18 +-- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 44 +++--- src/rpc-server/trex_rpc_async_server.cpp | 4 +- src/rpc-server/trex_rpc_cmd.cpp | 6 +- src/stateless/cp/trex_stateless.cpp | 162 +++++++++-------------- src/stateless/cp/trex_stateless.h | 74 ++++------- src/stateless/cp/trex_stateless_port.cpp | 98 ++------------ src/stateless/cp/trex_stateless_port.h | 74 ----------- src/stateless/dp/trex_stateless_dp_core.cpp | 135 ------------------- src/stateless/dp/trex_stateless_dp_core.h | 43 ------ 19 files changed, 498 insertions(+), 588 deletions(-) create mode 100644 src/internal_api/trex_platform_api.h create mode 100644 src/mock/trex_platform_api_mock.cpp delete mode 100644 src/stateless/dp/trex_stateless_dp_core.cpp delete mode 100644 src/stateless/dp/trex_stateless_dp_core.h diff --git a/linux/ws_main.py b/linux/ws_main.py index eac46ac7..a94e975c 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -146,7 +146,6 @@ 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' ]) # RPC code rpc_server_src = SrcGroup(dir='src/rpc-server/', @@ -168,6 +167,7 @@ rpc_server_src = SrcGroup(dir='src/rpc-server/', rpc_server_mock_src = SrcGroup(dir='src/mock/', src_list=[ 'trex_rpc_server_mock.cpp', + 'trex_platform_api_mock.cpp', '../gtest/rpc_test.cpp', '../pal/linux/mbuf.cpp', '../os_time.cpp', diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py index 61a9d4f3..d54531f3 100755 --- a/linux_dpdk/ws_main.py +++ b/linux_dpdk/ws_main.py @@ -158,7 +158,6 @@ 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' ]) # JSON package json_src = SrcGroup(dir='external_libs/json', diff --git a/src/bp_sim.h b/src/bp_sim.h index 0b1f91ae..8f5fe02f 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -1187,10 +1187,10 @@ public: public: static CRteMemPool m_mem_pool[MAX_SOCKETS_SUPPORTED]; - static uint32_t m_nodes_pool_size; - static CParserOption m_options; - static CGlobalMemory m_memory_cfg; - static CPlatformSocketInfo m_socket; + static uint32_t m_nodes_pool_size; + static CParserOption m_options; + static CGlobalMemory m_memory_cfg; + static CPlatformSocketInfo m_socket; }; static inline int get_is_stateless(){ diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp index 250d5342..6b8e3eff 100644 --- a/src/gtest/rpc_test.cpp +++ b/src/gtest/rpc_test.cpp @@ -30,6 +30,8 @@ limitations under the License. using namespace std; +uint16_t gtest_get_mock_server_port(); + class RpcTest : public testing::Test { protected: @@ -44,7 +46,12 @@ protected: m_context = zmq_ctx_new (); m_socket = zmq_socket (m_context, ZMQ_REQ); - zmq_connect (m_socket, "tcp://localhost:5050"); + + std::stringstream ss; + ss << "tcp://localhost:"; + ss << gtest_get_mock_server_port(); + + zmq_connect (m_socket, ss.str().c_str()); } diff --git a/src/internal_api/trex_platform_api.h b/src/internal_api/trex_platform_api.h new file mode 100644 index 00000000..5c2d42d2 --- /dev/null +++ b/src/internal_api/trex_platform_api.h @@ -0,0 +1,130 @@ +/* + 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_PLATFORM_API_H__ +#define __TREX_PLATFORM_API_H__ + +#include + +/** + * Global stats + * + * @author imarom (06-Oct-15) + */ +class TrexPlatformGlobalStats { +public: + TrexPlatformGlobalStats() { + m_stats = {0}; + } + + struct { + double m_cpu_util; + + double m_tx_bps; + double m_rx_bps; + + double m_tx_pps; + double m_rx_pps; + + uint64_t m_total_tx_pkts; + uint64_t m_total_rx_pkts; + + uint64_t m_total_tx_bytes; + uint64_t m_total_rx_bytes; + + uint64_t m_tx_rx_errors; + } m_stats; +}; + +/** + * Per Interface stats + * + * @author imarom (26-Oct-15) + */ +class TrexPlatformInterfaceStats { + +public: + TrexPlatformInterfaceStats() { + m_stats = {0}; + } + +public: + + struct { + + double m_tx_bps; + double m_rx_bps; + + double m_tx_pps; + double m_rx_pps; + + uint64_t m_total_tx_pkts; + uint64_t m_total_rx_pkts; + + uint64_t m_total_tx_bytes; + uint64_t m_total_rx_bytes; + + uint64_t m_tx_rx_errors; + } m_stats; +}; + + +/** + * low level API interface + * can be implemented by DPDK or mock + * + * @author imarom (25-Oct-15) + */ + +class TrexPlatformApi { +public: + virtual void get_global_stats(TrexPlatformGlobalStats &stats) const = 0; + virtual void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const = 0; + virtual uint8_t get_dp_core_count() const = 0; + virtual ~TrexPlatformApi() {} +}; + + +/** + * DPDK implementation of the platform API + * + * @author imarom (26-Oct-15) + */ +class TrexDpdkPlatformApi : public TrexPlatformApi { +public: + void get_global_stats(TrexPlatformGlobalStats &stats) const; + void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const; + uint8_t get_dp_core_count() const; +}; + +/** + * MOCK implementation of the platform API + * + * @author imarom (26-Oct-15) + */ +class TrexMockPlatformApi : public TrexPlatformApi { +public: + void get_global_stats(TrexPlatformGlobalStats &stats) const; + void get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const; + uint8_t get_dp_core_count() const; +}; + +#endif /* __TREX_PLATFORM_API_H__ */ diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index fd2d01c3..c84bb9c1 100755 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -73,6 +73,7 @@ extern "C" { #include "msg_manager.h" #include "platform_cfg.h" +#include #define RX_CHECK_MIX_SAMPLE_RATE 8 #define RX_CHECK_MIX_SAMPLE_RATE_1G 2 @@ -104,8 +105,6 @@ extern "C" int vmxnet3_xmit_set_callback(rte_mbuf_convert_to_one_seg_t cb); #define RTE_TEST_TX_DESC_DEFAULT 512 #define RTE_TEST_RX_DESC_DROP 0 - - static inline int get_vm_one_queue_enable(){ return (CGlobalInfo::m_options.preview.get_vm_one_queue_enable() ?1:0); } @@ -2746,6 +2745,7 @@ public: m_expected_pps=0.0; m_expected_cps=0.0; m_expected_bps=0.0; + m_trex_stateless = NULL; } public: @@ -2905,6 +2905,9 @@ private: CLatencyPktInfo m_latency_pkt; CZMqPublisher m_zmq_publisher; + +public: + TrexStateless *m_trex_stateless; }; @@ -3426,20 +3429,31 @@ int CGlobalTRex::ixgbe_start(void){ bool CGlobalTRex::Create(){ + CFlowsYamlInfo pre_yaml_info; + + if (get_is_stateless()) { + + TrexStatelessCfg cfg; + + TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, global_platform_cfg_info.m_zmq_rpc_port); + + cfg.m_port_count = CGlobalInfo::m_options.m_expected_portd; + cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg; + cfg.m_rpc_async_cfg = NULL; + cfg.m_rpc_server_verbose = true; + cfg.m_platform_api = new TrexDpdkPlatformApi(); + + m_trex_stateless = new TrexStateless(cfg); + + } else { + pre_yaml_info.load_from_yaml_file(CGlobalInfo::m_options.cfg_file); + } - bool is_stateless = get_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; - 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); } @@ -3448,13 +3462,14 @@ bool CGlobalTRex::Create(){ ixgbe_prob_init(); cores_prob_init(); queues_prob_init(); - /* allocate rings */ - assert( CMsgIns::Ins()->Create(get_cores_tx()) ); - if ( sizeof(CGenNodeNatInfo) != sizeof(CGenNode) ) { - printf("ERROR sizeof(CGenNodeNatInfo) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeNatInfo),sizeof(CGenNode)); - assert(0); - } + /* allocate rings */ + assert( CMsgIns::Ins()->Create(get_cores_tx()) ); + + if ( sizeof(CGenNodeNatInfo) != sizeof(CGenNode) ) { + printf("ERROR sizeof(CGenNodeNatInfo) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeNatInfo),sizeof(CGenNode)); + assert(0); + } if ( sizeof(CGenNodeLatencyPktInfo) != sizeof(CGenNode) ) { printf("ERROR sizeof(CGenNodeLatencyPktInfo) %d != sizeof(CGenNode) %d must be the same size \n",sizeof(CGenNodeLatencyPktInfo),sizeof(CGenNode)); @@ -3916,6 +3931,8 @@ int CGlobalTRex::run_in_master(){ std::string json; bool was_stopped=false; + m_trex_stateless->launch_control_plane(); + while ( true ) { if ( CGlobalInfo::m_options.preview.get_no_keyboard() ==false ){ @@ -4023,6 +4040,10 @@ int CGlobalTRex::run_in_master(){ } + /* stateless info */ + m_trex_stateless->generate_publish_snapshot(json); + m_zmq_publisher.publish_json(json); + delay(500); if ( is_all_cores_finished() ) { @@ -4231,6 +4252,11 @@ int CGlobalTRex::start_send_master(){ static CGlobalTRex g_trex; + +TrexStateless * get_stateless_obj() { + return g_trex.m_trex_stateless; +} + static int latency_one_lcore(__attribute__((unused)) void *dummy) { CPlatformSocketInfo * lpsock=&CGlobalInfo::m_socket; @@ -4460,31 +4486,6 @@ int sim_load_list_of_cap_files(CParserOption * op){ } - - -static int -launch_stateless_trex_thread() { - CPlatformSocketInfo *lpsock=&CGlobalInfo::m_socket; - CParserOption *lpop= &CGlobalInfo::m_options; - CPlatformYamlInfo *cg=&global_platform_cfg_info; - - TrexStatelessCfg cfg; - - TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, global_platform_cfg_info.m_zmq_rpc_port); - - cfg.m_dp_core_count = lpop->preview.getCores(); - cfg.m_port_count = lpop->m_expected_portd; - cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg; - cfg.m_rpc_async_cfg = NULL; - cfg.m_rpc_server_verbose = true; - - TrexStateless::configure(cfg); - printf("Starting RPC Server...\n\n"); - return (0); -} - - - int main_test(int argc , char * argv[]){ utl_termio_init(); @@ -4544,17 +4545,10 @@ 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 ( !g_trex.Create() ){ exit(1); } - /* patch here */ - if (is_stateless) { - launch_stateless_trex_thread(); - } - 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()); @@ -5156,3 +5150,36 @@ struct rte_mbuf * rte_mbuf_convert_to_one_seg(struct rte_mbuf *m){ } +/*********************************************************** + * platfrom API object + * TODO: REMOVE THIS TO A SEPERATE FILE + * + **********************************************************/ +void +TrexDpdkPlatformApi::get_global_stats(TrexPlatformGlobalStats &stats) const { + CGlobalStats trex_stats; + g_trex.get_stats(trex_stats); + + stats.m_stats.m_cpu_util = trex_stats.m_cpu_util; + + stats.m_stats.m_tx_bps = trex_stats.m_tx_bps; + stats.m_stats.m_tx_pps = trex_stats.m_tx_pps; + stats.m_stats.m_total_tx_pkts = trex_stats.m_total_tx_pkts; + stats.m_stats.m_total_tx_bytes = trex_stats.m_total_tx_bytes; + + stats.m_stats.m_rx_bps = trex_stats.m_rx_bps; + stats.m_stats.m_rx_pps = /*trex_stats.m_rx_pps*/ 0; /* missing */ + stats.m_stats.m_total_rx_pkts = trex_stats.m_total_rx_pkts; + stats.m_stats.m_total_rx_bytes = trex_stats.m_total_rx_bytes; +} + +void +TrexDpdkPlatformApi::get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const { + +} + +uint8_t +TrexDpdkPlatformApi::get_dp_core_count() const { + return CGlobalInfo::m_options.preview.getCores(); +} + diff --git a/src/mock/trex_platform_api_mock.cpp b/src/mock/trex_platform_api_mock.cpp new file mode 100644 index 00000000..54f71e10 --- /dev/null +++ b/src/mock/trex_platform_api_mock.cpp @@ -0,0 +1,49 @@ +/* + 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 + +void +TrexMockPlatformApi::get_global_stats(TrexPlatformGlobalStats &stats) const { + + stats.m_stats.m_cpu_util = 0; + + stats.m_stats.m_tx_bps = 0; + stats.m_stats.m_tx_pps = 0; + stats.m_stats.m_total_tx_pkts = 0; + stats.m_stats.m_total_tx_bytes = 0; + + stats.m_stats.m_rx_bps = 0; + stats.m_stats.m_rx_pps = 0; + stats.m_stats.m_total_rx_pkts = 0; + stats.m_stats.m_total_rx_bytes = 0; +} + +void +TrexMockPlatformApi::get_interface_stats(uint8_t interface_id, TrexPlatformInterfaceStats &stats) const { + +} + +uint8_t +TrexMockPlatformApi::get_dp_core_count() const { + return (1); +} + diff --git a/src/mock/trex_rpc_server_mock.cpp b/src/mock/trex_rpc_server_mock.cpp index de43f92f..6e14390a 100644 --- a/src/mock/trex_rpc_server_mock.cpp +++ b/src/mock/trex_rpc_server_mock.cpp @@ -23,10 +23,65 @@ limitations under the License. #include #include +#include #include +#include +#include using namespace std; +static TrexStateless *g_trex_stateless; +static uint16_t g_rpc_port; + +static bool +verify_tcp_port_is_free(uint16_t port) { + void *m_context = zmq_ctx_new(); + void *m_socket = zmq_socket (m_context, ZMQ_REP); + std::stringstream ss; + ss << "tcp://*:"; + ss << port; + + int rc = zmq_bind (m_socket, ss.str().c_str()); + + zmq_close(m_socket); + zmq_term(m_context); + + return (rc == 0); +} + +static uint16_t +find_free_tcp_port(uint16_t start_port = 5050) { + void *m_context = zmq_ctx_new(); + void *m_socket = zmq_socket (m_context, ZMQ_REP); + + uint16_t port = start_port; + while (true) { + std::stringstream ss; + ss << "tcp://*:"; + ss << port; + + int rc = zmq_bind (m_socket, ss.str().c_str()); + if (rc == 0) { + break; + } + + port++; + } + + zmq_close(m_socket); + zmq_term(m_context); + + return port; +} + +TrexStateless * get_stateless_obj() { + return g_trex_stateless; +} + +uint16_t gtest_get_mock_server_port() { + return g_rpc_port; +} + /** * on simulation this is not rebuild every version * (improved stub) @@ -42,44 +97,66 @@ extern "C" const char * get_build_time(void){ int gtest_main(int argc, char **argv); -int main(int argc, char *argv[]) { +static bool parse_uint16(const string arg, uint16_t &port) { + stringstream ss(arg); + + bool x = (ss >> port); + + return (x); +} +int main(int argc, char *argv[]) { bool is_gtest = false; // gtest ? if (argc > 1) { - if (string(argv[1]) != "--ut") { - cout << "\n[Usage] " << argv[0] << ": " << " [--ut]\n\n"; + string arg = string(argv[1]); + + if (arg == "--ut") { + g_rpc_port = find_free_tcp_port(); + is_gtest = true; + } else if (parse_uint16(arg, g_rpc_port)) { + bool rc = verify_tcp_port_is_free(g_rpc_port); + if (!rc) { + cout << "port " << g_rpc_port << " is not available to use\n"; + exit(-1); + } + } else { + + cout << "\n[Usage] " << argv[0] << ": " << " [--ut] or [port number < 65535]\n\n"; exit(-1); } - is_gtest = true; + + } else { + g_rpc_port = find_free_tcp_port(); } /* configure the stateless object with 4 ports */ TrexStatelessCfg cfg; - TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050); - TrexRpcServerConfig rpc_async_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5051); + TrexRpcServerConfig rpc_req_resp_cfg(TrexRpcServerConfig::RPC_PROT_TCP, g_rpc_port); + //TrexRpcServerConfig rpc_async_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5051); cfg.m_port_count = 4; - cfg.m_dp_core_count = 2; cfg.m_rpc_req_resp_cfg = &rpc_req_resp_cfg; - cfg.m_rpc_async_cfg = &rpc_async_cfg; + cfg.m_rpc_async_cfg = NULL; cfg.m_rpc_server_verbose = (is_gtest ? false : true); + cfg.m_platform_api = new TrexMockPlatformApi(); - TrexStateless::configure(cfg); + g_trex_stateless = new TrexStateless(cfg); - TrexStateless::get_instance().launch_control_plane(); + g_trex_stateless->launch_control_plane(); /* gtest handling */ if (is_gtest) { int rc = gtest_main(argc, argv); - TrexStateless::destroy(); + delete g_trex_stateless; + g_trex_stateless = NULL; return rc; } cout << "\n-= Starting RPC Server Mock =-\n\n"; - cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n"; + cout << "Listening on tcp://localhost:" << g_rpc_port << " [ZMQ]\n\n"; cout << "Server Started\n\n"; @@ -87,6 +164,7 @@ int main(int argc, char *argv[]) { sleep(1); } - TrexStateless::destroy(); + delete g_trex_stateless; + g_trex_stateless = NULL; } diff --git a/src/pal/linux/mbuf.h b/src/pal/linux/mbuf.h index 693b095a..af01590e 100755 --- a/src/pal/linux/mbuf.h +++ b/src/pal/linux/mbuf.h @@ -187,6 +187,8 @@ static inline void utl_rte_pktmbuf_add_last(rte_mbuf_t *m,rte_mbuf_t *m_last){ #define CACHE_LINE_SIZE 64 +#define RTE_CACHE_LINE_SIZE (CACHE_LINE_SIZE) + #define SOCKET_ID_ANY 0 #endif diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index ae87d749..bb54e4a1 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -145,7 +145,7 @@ trex_rpc_cmd_rc_e TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { string hostname; - TrexStateless & instance = TrexStateless::get_instance(); + TrexStateless * main = get_stateless_obj(); Json::Value §ion = result["result"]; @@ -155,21 +155,21 @@ TrexRpcCmdGetSysInfo::_run(const Json::Value ¶ms, Json::Value &result) { section["uptime"] = TrexRpcServer::get_server_uptime(); /* FIXME: core count */ - section["dp_core_count"] = instance.get_dp_core_count(); + section["dp_core_count"] = main->get_dp_core_count(); section["core_type"] = get_cpu_model(); /* ports */ - section["port_count"] = instance.get_port_count(); + section["port_count"] = main->get_port_count(); section["ports"] = Json::arrayValue; - for (int i = 0; i < instance.get_port_count(); i++) { + for (int i = 0; i < main->get_port_count(); i++) { string driver; string speed; - TrexStatelessPort *port = instance.get_port_by_id(i); + TrexStatelessPort *port = main->get_port_by_id(i); port->get_properties(driver, speed); section["ports"][i]["index"] = i; @@ -201,7 +201,7 @@ TrexRpcCmdGetOwner::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); section["owner"] = port->get_owner(); return (TREX_RPC_CMD_OK); @@ -220,7 +220,7 @@ TrexRpcCmdAcquire::_run(const Json::Value ¶ms, Json::Value &result) { bool force = parse_bool(params, "force", result); /* if not free and not you and not force - fail */ - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); if ( (!port->is_free_to_aquire()) && (port->get_owner() != new_owner) && (!force)) { generate_execute_err(result, "port is already taken by '" + port->get_owner() + "'"); @@ -242,7 +242,7 @@ TrexRpcCmdRelease::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); if (port->get_state() == TrexStatelessPort::PORT_STATE_TRANSMITTING) { generate_execute_err(result, "cannot release a port during transmission"); @@ -264,7 +264,7 @@ TrexRpcCmdGetPortStats::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_port(params, result); - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); if (port->get_state() == TrexStatelessPort::PORT_STATE_DOWN) { generate_execute_err(result, "cannot get stats - port is down"); diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 20107411..4f697e3c 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -114,7 +114,7 @@ TrexRpcCmdAddStream::_run(const Json::Value ¶ms, Json::Value &result) { /* make sure this is a valid stream to add */ validate_stream(stream, result); - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(stream->m_port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(stream->m_port_id); port->get_stream_table()->add_stream(stream); result["result"] = "ACK"; @@ -282,15 +282,15 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu } /* port id should be between 0 and count - 1 */ - if (stream->m_port_id >= TrexStateless::get_instance().get_port_count()) { + if (stream->m_port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; delete stream; generate_execute_err(result, ss.str()); } /* add the stream to the port's stream table */ - TrexStatelessPort * port = TrexStateless::get_instance().get_port_by_id(stream->m_port_id); + TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id); /* does such a stream exists ? */ if (port->get_stream_table()->get_stream_by_id(stream->m_stream_id)) { @@ -312,13 +312,13 @@ TrexRpcCmdRemoveStream::_run(const Json::Value ¶ms, Json::Value &result) { uint32_t stream_id = parse_int(params, "stream_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id); if (!stream) { @@ -344,13 +344,13 @@ trex_rpc_cmd_rc_e TrexRpcCmdRemoveAllStreams::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_byte(params, "port_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); port->get_stream_table()->remove_and_delete_all_streams(); result["result"] = "ACK"; @@ -369,13 +369,13 @@ TrexRpcCmdGetStreamList::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_byte(params, "port_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); port->get_stream_table()->get_stream_list(stream_list); @@ -401,13 +401,13 @@ TrexRpcCmdGetStream::_run(const Json::Value ¶ms, Json::Value &result) { uint32_t stream_id = parse_int(params, "stream_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); TrexStream *stream = port->get_stream_table()->get_stream_by_id(stream_id); @@ -433,13 +433,13 @@ TrexRpcCmdStartTraffic::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_byte(params, "port_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); TrexStatelessPort::rc_e rc = port->start_traffic(); @@ -473,13 +473,13 @@ trex_rpc_cmd_rc_e TrexRpcCmdStopTraffic::_run(const Json::Value ¶ms, Json::Value &result) { uint8_t port_id = parse_byte(params, "port_id", result); - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); port->stop_traffic(); result["result"] = "ACK"; diff --git a/src/rpc-server/trex_rpc_async_server.cpp b/src/rpc-server/trex_rpc_async_server.cpp index f4d21f2f..46fe499b 100644 --- a/src/rpc-server/trex_rpc_async_server.cpp +++ b/src/rpc-server/trex_rpc_async_server.cpp @@ -79,7 +79,7 @@ TrexRpcServerAsync::_rpc_thread_cb() { } /* trigger a full update for stats */ - TrexStateless::get_instance().update_stats(); + //get_stateless_obj()->update_stats(); /* done with the lock */ if (m_lock) { @@ -87,7 +87,7 @@ TrexRpcServerAsync::_rpc_thread_cb() { } /* encode them to JSON */ - TrexStateless::get_instance().encode_stats(snapshot); + get_stateless_obj()->encode_stats(snapshot); /* write to string and publish */ std::string snapshot_str = writer.write(snapshot); diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp index 920a8d30..af0db3f4 100644 --- a/src/rpc-server/trex_rpc_cmd.cpp +++ b/src/rpc-server/trex_rpc_cmd.cpp @@ -61,7 +61,7 @@ TrexRpcCommand::verify_ownership(const Json::Value ¶ms, Json::Value &result) std::string handler = parse_string(params, "handler", result); uint8_t port_id = parse_port(params, result); - TrexStatelessPort *port = TrexStateless::get_instance().get_port_by_id(port_id); + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); if (!port->verify_owner_handler(handler)) { generate_execute_err(result, "invalid handler provided. please pass the handler given when calling 'acquire' or take ownership"); @@ -78,9 +78,9 @@ TrexRpcCommand::parse_port(const Json::Value ¶ms, Json::Value &result) { void TrexRpcCommand::validate_port_id(uint8_t port_id, Json::Value &result) { - if (port_id >= TrexStateless::get_instance().get_port_count()) { + if (port_id >= get_stateless_obj()->get_port_count()) { std::stringstream ss; - ss << "invalid port id - should be between 0 and " << (int)TrexStateless::get_instance().get_port_count() - 1; + ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1; generate_execute_err(result, ss.str()); } } diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp index 72762e26..e0e95450 100644 --- a/src/stateless/cp/trex_stateless.cpp +++ b/src/stateless/cp/trex_stateless.cpp @@ -31,55 +31,58 @@ using namespace std; * Trex stateless object * **********************************************************/ -TrexStateless::TrexStateless() { - m_is_configured = false; -} - /** - * configure the singleton stateless object * */ -void TrexStateless::configure(const TrexStatelessCfg &cfg) { - - TrexStateless& instance = get_instance_internal(); - - /* check status */ - if (instance.m_is_configured) { - throw TrexException("re-configuration of stateless object is not allowed"); - } +TrexStateless::TrexStateless(const TrexStatelessCfg &cfg) { /* create RPC servers */ /* 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); + m_rpc_server = new TrexRpcServer(cfg.m_rpc_req_resp_cfg, cfg.m_rpc_async_cfg, &m_global_cp_lock); + m_rpc_server->set_verbose(cfg.m_rpc_server_verbose); /* configure ports */ + m_port_count = cfg.m_port_count; - instance.m_port_count = cfg.m_port_count; - - for (int i = 0; i < instance.m_port_count; i++) { - instance.m_ports.push_back(new TrexStatelessPort(i)); + for (int i = 0; i < m_port_count; i++) { + m_ports.push_back(new TrexStatelessPort(i)); } - /* cores */ - instance.m_dp_core_count = cfg.m_dp_core_count; - for (int i = 0; i < instance.m_dp_core_count; i++) { - instance.m_dp_cores.push_back(new TrexStatelessDpCore(i)); + m_platform_api = cfg.m_platform_api; +} + +/** + * release all memory + * + * @author imarom (08-Oct-15) + */ +TrexStateless::~TrexStateless() { + + /* release memory for ports */ + for (auto port : m_ports) { + delete port; } + m_ports.clear(); + + /* stops the RPC server */ + m_rpc_server->stop(); + delete m_rpc_server; + + m_rpc_server = NULL; - /* done */ - instance.m_is_configured = true; + delete m_platform_api; + m_platform_api = NULL; } + /** * starts the control plane side * */ void TrexStateless::launch_control_plane() { - //std::cout << "\n on control/master core \n"; /* pin this process to the current running CPU any new thread will be called on the same CPU @@ -94,39 +97,6 @@ TrexStateless::launch_control_plane() { m_rpc_server->start(); } -void -TrexStateless::launch_on_dp_core(uint8_t core_id) { - m_dp_cores[core_id - 1]->run(); -} - -/** - * destroy the singleton and release all memory - * - * @author imarom (08-Oct-15) - */ -void -TrexStateless::destroy() { - TrexStateless& instance = get_instance_internal(); - - if (!instance.m_is_configured) { - return; - } - - /* release memory for ports */ - for (auto port : instance.m_ports) { - delete port; - } - instance.m_ports.clear(); - - /* stops the RPC server */ - instance.m_rpc_server->stop(); - delete instance.m_rpc_server; - - instance.m_rpc_server = NULL; - - /* done */ - instance.m_is_configured = false; -} /** * fetch a port by ID @@ -148,57 +118,32 @@ TrexStateless::get_port_count() { uint8_t TrexStateless::get_dp_core_count() { - return m_dp_core_count; -} - -void -TrexStateless::update_stats() { - - /* 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++) { - m_ports[i]->update_stats(); - - const TrexPortStats & port_stats = m_ports[i]->get_stats(); - - m_stats.m_stats.m_tx_bps += port_stats.m_stats.m_tx_bps; - m_stats.m_stats.m_rx_bps += port_stats.m_stats.m_rx_bps; - - m_stats.m_stats.m_tx_pps += port_stats.m_stats.m_tx_pps; - m_stats.m_stats.m_rx_pps += port_stats.m_stats.m_rx_pps; - - m_stats.m_stats.m_total_tx_pkts += port_stats.m_stats.m_total_tx_pkts; - m_stats.m_stats.m_total_rx_pkts += port_stats.m_stats.m_total_rx_pkts; - - m_stats.m_stats.m_total_tx_bytes += port_stats.m_stats.m_total_tx_bytes; - m_stats.m_stats.m_total_rx_bytes += port_stats.m_stats.m_total_rx_bytes; - - m_stats.m_stats.m_tx_rx_errors += port_stats.m_stats.m_tx_rx_errors; - } + return m_platform_api->get_dp_core_count(); } void TrexStateless::encode_stats(Json::Value &global) { - global["cpu_util"] = m_stats.m_stats.m_cpu_util; + const TrexPlatformApi *api = get_stateless_obj()->get_platform_api(); + + TrexPlatformGlobalStats stats; + api->get_global_stats(stats); - global["tx_bps"] = m_stats.m_stats.m_tx_bps; - global["rx_bps"] = m_stats.m_stats.m_rx_bps; + global["cpu_util"] = stats.m_stats.m_cpu_util; - global["tx_pps"] = m_stats.m_stats.m_tx_pps; - global["rx_pps"] = m_stats.m_stats.m_rx_pps; + global["tx_bps"] = stats.m_stats.m_tx_bps; + global["rx_bps"] = stats.m_stats.m_rx_bps; - global["total_tx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_pkts); - global["total_rx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_pkts); + global["tx_pps"] = stats.m_stats.m_tx_pps; + global["rx_pps"] = stats.m_stats.m_rx_pps; - global["total_tx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_bytes); - global["total_rx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_bytes); + global["total_tx_pkts"] = Json::Value::UInt64(stats.m_stats.m_total_tx_pkts); + global["total_rx_pkts"] = Json::Value::UInt64(stats.m_stats.m_total_rx_pkts); - global["tx_rx_errors"] = Json::Value::UInt64(m_stats.m_stats.m_tx_rx_errors); + global["total_tx_bytes"] = Json::Value::UInt64(stats.m_stats.m_total_tx_bytes); + global["total_rx_bytes"] = Json::Value::UInt64(stats.m_stats.m_total_rx_bytes); + + global["tx_rx_errors"] = Json::Value::UInt64(stats.m_stats.m_tx_rx_errors); for (uint8_t i = 0; i < m_port_count; i++) { std::stringstream ss; @@ -210,3 +155,20 @@ TrexStateless::encode_stats(Json::Value &global) { } } +/** + * generate a snapshot for publish (async publish) + * + */ +void +TrexStateless::generate_publish_snapshot(std::string &snapshot) { + Json::FastWriter writer; + Json::Value root; + + root["name"] = "trex-stateless-info"; + root["type"] = 0; + + /* stateless specific info goes here */ + root["data"] = Json::nullValue; + + snapshot = writer.write(root); +} diff --git a/src/stateless/cp/trex_stateless.h b/src/stateless/cp/trex_stateless.h index 649b25dd..758707a2 100644 --- a/src/stateless/cp/trex_stateless.h +++ b/src/stateless/cp/trex_stateless.h @@ -29,9 +29,10 @@ limitations under the License. #include #include -#include #include +#include + /** * generic exception for errors * TODO: move this to a better place @@ -88,17 +89,17 @@ public: /* default values */ TrexStatelessCfg() { m_port_count = 0; - m_dp_core_count = 0; m_rpc_req_resp_cfg = NULL; m_rpc_async_cfg = NULL; - m_rpc_server_verbose = false; + m_rpc_server_verbose = false; + m_platform_api = NULL; } const TrexRpcServerConfig *m_rpc_req_resp_cfg; const TrexRpcServerConfig *m_rpc_async_cfg; + const TrexPlatformApi *m_platform_api; bool m_rpc_server_verbose; uint8_t m_port_count; - uint8_t m_dp_core_count; }; /** @@ -113,27 +114,8 @@ public: * reconfiguration is not allowed * an exception will be thrown */ - static void configure(const TrexStatelessCfg &cfg); - - /** - * destroy the instance - * - */ - static void destroy(); - - /** - * singleton public get instance - * - */ - static TrexStateless& get_instance() { - TrexStateless& instance = get_instance_internal(); - - if (!instance.m_is_configured) { - throw TrexException("object is not configured"); - } - - return instance; - } + TrexStateless(const TrexStatelessCfg &cfg); + ~TrexStateless(); /** * starts the control plane side @@ -152,12 +134,6 @@ public: uint8_t get_dp_core_count(); - /** - * update all the stats (deep update) - * (include all the ports and global stats) - * - */ - void update_stats(); /** * fetch all the stats @@ -165,22 +141,21 @@ public: */ void encode_stats(Json::Value &global); + /** + * generate a snapshot for publish + */ + void generate_publish_snapshot(std::string &snapshot); -protected: - TrexStateless(); - - static TrexStateless& get_instance_internal () { - static TrexStateless instance; - return instance; + const TrexPlatformApi * get_platform_api() { + return (m_platform_api); } - /* c++ 2011 style singleton */ +protected: + + /* no copy or assignment */ TrexStateless(TrexStateless const&) = delete; void operator=(TrexStateless const&) = delete; - /* status */ - bool m_is_configured; - /* RPC server array */ TrexRpcServer *m_rpc_server; @@ -188,15 +163,20 @@ protected: std::vector m_ports; uint8_t m_port_count; - /* cores */ - std::vector m_dp_cores; - uint8_t m_dp_core_count; - - /* stats */ - TrexStatelessStats m_stats; + /* platform API */ + const TrexPlatformApi *m_platform_api; std::mutex m_global_cp_lock; }; +/** + * an anchor function + * + * @author imarom (25-Oct-15) + * + * @return TrexStateless& + */ +TrexStateless * get_stateless_obj(); + #endif /* __TREX_STATELESS_H__ */ diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index a31847a5..6b77b107 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -130,99 +130,27 @@ TrexStatelessPort::generate_handler() { return (ss.str()); } -/** - * update stats for the port - * - */ -void -TrexStatelessPort::update_stats() { - struct rte_eth_stats stats; - rte_eth_stats_get(m_port_id, &stats); - - /* 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; - - /* 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_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); - -} - -const TrexPortStats & -TrexStatelessPort::get_stats() { - return m_stats; -} void TrexStatelessPort::encode_stats(Json::Value &port) { - port["tx_bps"] = m_stats.m_stats.m_tx_bps; - port["rx_bps"] = m_stats.m_stats.m_rx_bps; - - port["tx_pps"] = m_stats.m_stats.m_tx_pps; - port["rx_pps"] = m_stats.m_stats.m_rx_pps; - - port["total_tx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_pkts); - port["total_rx_pkts"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_pkts); - - port["total_tx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_tx_bytes); - port["total_rx_bytes"] = Json::Value::UInt64(m_stats.m_stats.m_total_rx_bytes); - - port["tx_rx_errors"] = Json::Value::UInt64(m_stats.m_stats.m_tx_rx_errors); -} + const TrexPlatformApi *api = get_stateless_obj()->get_platform_api(); + TrexPlatformInterfaceStats stats; + api->get_interface_stats(m_port_id, stats); + port["tx_bps"] = stats.m_stats.m_tx_bps; + port["rx_bps"] = stats.m_stats.m_rx_bps; -/*************************** - * BW measurement - * - **************************/ -/* TODO: move this to a common place */ -BWMeasure::BWMeasure() { - reset(); -} + port["tx_pps"] = stats.m_stats.m_tx_pps; + port["rx_pps"] = stats.m_stats.m_rx_pps; -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); -} + port["total_tx_pkts"] = Json::Value::UInt64(stats.m_stats.m_total_tx_pkts); + port["total_rx_pkts"] = Json::Value::UInt64(stats.m_stats.m_total_rx_pkts); -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) -/** - * 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) - */ -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; - double m_rx_bps; - - double m_tx_pps; - double m_rx_pps; - - uint64_t m_total_tx_pkts; - uint64_t m_total_rx_pkts; - - uint64_t m_total_tx_bytes; - uint64_t m_total_rx_bytes; - - uint64_t m_tx_rx_errors; - } m_stats; -}; - /** * describes a stateless port * @@ -202,14 +137,6 @@ public: } - /** - * update the values of the stats - * - */ - void update_stats(); - - const TrexPortStats & get_stats(); - /** * encode stats as JSON */ @@ -224,7 +151,6 @@ private: port_state_e m_port_state; std::string m_owner; std::string m_owner_handler; - TrexPortStats m_stats; }; #endif /* __TREX_STATELESS_PORT_H__ */ diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp deleted file mode 100644 index 3755b82c..00000000 --- a/src/stateless/dp/trex_stateless_dp_core.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - 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 -#include -#include -#include - -#include - -#ifndef TREX_RPC_MOCK_SERVER - -// DPDK c++ issue -#define UINT8_MAX 255 -#define UINT16_MAX 0xFFFF -// DPDK c++ issue -#endif - -#include -#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("\nOn DP core %d\n", m_core_id); - while (true) { - 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 deleted file mode 100644 index 4b09b752..00000000 --- a/src/stateless/dp/trex_stateless_dp_core.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -/** - * stateless DP core object - * - */ -class TrexStatelessDpCore { -public: - - TrexStatelessDpCore(uint8_t core_id); - - /* starts the DP core run */ - void run(); - -private: - void test_inject_dummy_pkt(); - uint8_t m_core_id; -}; - -#endif /* __TREX_STATELESS_DP_CORE_H__ */ -- cgit 1.2.3-korg